123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- From a347e374cb338213632c6dde88dd226d64bd8b27 Mon Sep 17 00:00:00 2001
- From: Weijie Gao <[email protected]>
- 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 <[email protected]>
- ---
- 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 <[email protected]>
- + */
- +
- +#include <common.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,
- +};
|