openwrt/package/boot/uboot-mediatek/patches/100-03-mtd-mtk-snand-add-support-for-SPL.patch

176 lines
4.5 KiB
Diff
Raw Normal View History

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,
+};