mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-24 07:46:48 +00:00
f8c22c9bff
Update to latest U-Boot release. Patches refreshed and fixed when needed. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
176 lines
4.5 KiB
Diff
176 lines
4.5 KiB
Diff
From a347e374cb338213632c6dde88dd226d64bd8b27 Mon Sep 17 00:00:00 2001
|
|
From: Weijie Gao <weijie.gao@mediatek.com>
|
|
Date: Wed, 3 Mar 2021 08:57:29 +0800
|
|
Subject: [PATCH 37/71] mtd: mtk-snand: add support for SPL
|
|
|
|
Add support to initialize SPI-NAND in SPL.
|
|
Add implementation for SPL NAND loader.
|
|
|
|
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
|
|
---
|
|
drivers/mtd/mtk-snand/Kconfig | 6 ++
|
|
drivers/mtd/mtk-snand/Makefile | 4 +
|
|
drivers/mtd/mtk-snand/mtk-snand-spl.c | 133 ++++++++++++++++++++++++++
|
|
3 files changed, 143 insertions(+)
|
|
create mode 100644 drivers/mtd/mtk-snand/mtk-snand-spl.c
|
|
|
|
--- a/drivers/mtd/mtk-snand/Kconfig
|
|
+++ b/drivers/mtd/mtk-snand/Kconfig
|
|
@@ -19,3 +19,9 @@ config MTK_SPI_NAND_MTD
|
|
help
|
|
This option enables access to SPI-NAND flashes through the
|
|
MTD interface of MediaTek SPI NAND Flash Controller
|
|
+
|
|
+config SPL_MTK_SPI_NAND
|
|
+ tristate "SPL support for MediaTek SPI NAND flash controller"
|
|
+ depends on MTK_SPI_NAND
|
|
+ help
|
|
+ This option enables access to SPI-NAND flashes in the SPL stage
|
|
--- a/drivers/mtd/mtk-snand/Makefile
|
|
+++ b/drivers/mtd/mtk-snand/Makefile
|
|
@@ -8,4 +8,8 @@
|
|
obj-y += mtk-snand.o mtk-snand-ecc.o mtk-snand-ids.o mtk-snand-os.o
|
|
obj-$(CONFIG_MTK_SPI_NAND_MTD) += mtk-snand-mtd.o
|
|
|
|
+ifdef CONFIG_SPL_BUILD
|
|
+obj-$(CONFIG_SPL_MTK_SPI_NAND) += mtk-snand-spl.o
|
|
+endif
|
|
+
|
|
ccflags-y += -DPRIVATE_MTK_SNAND_HEADER
|
|
--- /dev/null
|
|
+++ b/drivers/mtd/mtk-snand/mtk-snand-spl.c
|
|
@@ -0,0 +1,133 @@
|
|
+// SPDX-License-Identifier: GPL-2.0
|
|
+/*
|
|
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
|
|
+ *
|
|
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
|
|
+ */
|
|
+
|
|
+#include <config.h>
|
|
+#include <dm.h>
|
|
+#include <dm/uclass.h>
|
|
+#include <malloc.h>
|
|
+#include <mapmem.h>
|
|
+#include <mtd.h>
|
|
+#include <watchdog.h>
|
|
+
|
|
+#include "mtk-snand.h"
|
|
+
|
|
+static struct mtk_snand *snf;
|
|
+static struct mtk_snand_chip_info cinfo;
|
|
+static u32 oobavail;
|
|
+
|
|
+static u8 *page_cache;
|
|
+
|
|
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
|
|
+{
|
|
+ u32 sizeremain = size, chunksize, leading;
|
|
+ uint32_t off = offs, writesize_mask = cinfo.pagesize - 1;
|
|
+ uint8_t *ptr = dst;
|
|
+ int ret;
|
|
+
|
|
+ if (!snf)
|
|
+ return -ENODEV;
|
|
+
|
|
+ while (sizeremain) {
|
|
+ schedule();
|
|
+
|
|
+ leading = off & writesize_mask;
|
|
+ chunksize = cinfo.pagesize - leading;
|
|
+ if (chunksize > sizeremain)
|
|
+ chunksize = sizeremain;
|
|
+
|
|
+ if (chunksize == cinfo.pagesize) {
|
|
+ ret = mtk_snand_read_page(snf, off - leading, ptr,
|
|
+ NULL, false);
|
|
+ if (ret)
|
|
+ break;
|
|
+ } else {
|
|
+ ret = mtk_snand_read_page(snf, off - leading,
|
|
+ page_cache, NULL, false);
|
|
+ if (ret)
|
|
+ break;
|
|
+
|
|
+ memcpy(ptr, page_cache + leading, chunksize);
|
|
+ }
|
|
+
|
|
+ off += chunksize;
|
|
+ ptr += chunksize;
|
|
+ sizeremain -= chunksize;
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+void nand_init(void)
|
|
+{
|
|
+ struct mtk_snand_platdata mtk_snand_pdata = {};
|
|
+ struct udevice *dev;
|
|
+ fdt_addr_t base;
|
|
+ int ret;
|
|
+
|
|
+ ret = uclass_get_device_by_driver(UCLASS_MTD, DM_DRIVER_GET(mtk_snand),
|
|
+ &dev);
|
|
+ if (ret) {
|
|
+ printf("mtk-snand-spl: Device instance not found!\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ base = dev_read_addr_name(dev, "nfi");
|
|
+ if (base == FDT_ADDR_T_NONE) {
|
|
+ printf("mtk-snand-spl: NFI base not set\n");
|
|
+ return;
|
|
+ }
|
|
+ mtk_snand_pdata.nfi_base = map_sysmem(base, 0);
|
|
+
|
|
+ base = dev_read_addr_name(dev, "ecc");
|
|
+ if (base == FDT_ADDR_T_NONE) {
|
|
+ printf("mtk-snand-spl: ECC base not set\n");
|
|
+ return;
|
|
+ }
|
|
+ mtk_snand_pdata.ecc_base = map_sysmem(base, 0);
|
|
+
|
|
+ mtk_snand_pdata.soc = dev_get_driver_data(dev);
|
|
+ mtk_snand_pdata.quad_spi = dev_read_bool(dev, "quad-spi");
|
|
+
|
|
+ ret = mtk_snand_init(NULL, &mtk_snand_pdata, &snf);
|
|
+ if (ret) {
|
|
+ printf("mtk-snand-spl: failed to initialize SPI-NAND\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ mtk_snand_get_chip_info(snf, &cinfo);
|
|
+
|
|
+ oobavail = cinfo.num_sectors * (cinfo.fdm_size - 1);
|
|
+
|
|
+ printf("SPI-NAND: %s (%uMB)\n", cinfo.model,
|
|
+ (u32)(cinfo.chipsize >> 20));
|
|
+
|
|
+ page_cache = malloc(cinfo.pagesize + cinfo.sparesize);
|
|
+ if (!page_cache) {
|
|
+ mtk_snand_cleanup(snf);
|
|
+ printf("mtk-snand-spl: failed to allocate page cache\n");
|
|
+ }
|
|
+}
|
|
+
|
|
+void nand_deselect(void)
|
|
+{
|
|
+
|
|
+}
|
|
+
|
|
+static const struct udevice_id mtk_snand_ids[] = {
|
|
+ { .compatible = "mediatek,mt7622-snand", .data = SNAND_SOC_MT7622 },
|
|
+ { .compatible = "mediatek,mt7629-snand", .data = SNAND_SOC_MT7629 },
|
|
+ { .compatible = "mediatek,mt7981-snand", .data = SNAND_SOC_MT7981 },
|
|
+ { .compatible = "mediatek,mt7986-snand", .data = SNAND_SOC_MT7986 },
|
|
+ { /* sentinel */ },
|
|
+};
|
|
+
|
|
+U_BOOT_DRIVER(mtk_snand) = {
|
|
+ .name = "mtk-snand",
|
|
+ .id = UCLASS_MTD,
|
|
+ .of_match = mtk_snand_ids,
|
|
+ .flags = DM_FLAG_PRE_RELOC,
|
|
+};
|