uboot-mediatek: update to U-Boot 2023.01
[openwrt/staging/nbd.git] / package / boot / uboot-mediatek / patches / 100-03-mtd-mtk-snand-add-support-for-SPL.patch
1 From a347e374cb338213632c6dde88dd226d64bd8b27 Mon Sep 17 00:00:00 2001
2 From: Weijie Gao <weijie.gao@mediatek.com>
3 Date: Wed, 3 Mar 2021 08:57:29 +0800
4 Subject: [PATCH 37/71] mtd: mtk-snand: add support for SPL
5
6 Add support to initialize SPI-NAND in SPL.
7 Add implementation for SPL NAND loader.
8
9 Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
10 ---
11 drivers/mtd/mtk-snand/Kconfig | 6 ++
12 drivers/mtd/mtk-snand/Makefile | 4 +
13 drivers/mtd/mtk-snand/mtk-snand-spl.c | 133 ++++++++++++++++++++++++++
14 3 files changed, 143 insertions(+)
15 create mode 100644 drivers/mtd/mtk-snand/mtk-snand-spl.c
16
17 --- a/drivers/mtd/mtk-snand/Kconfig
18 +++ b/drivers/mtd/mtk-snand/Kconfig
19 @@ -19,3 +19,9 @@ config MTK_SPI_NAND_MTD
20 help
21 This option enables access to SPI-NAND flashes through the
22 MTD interface of MediaTek SPI NAND Flash Controller
23 +
24 +config SPL_MTK_SPI_NAND
25 + tristate "SPL support for MediaTek SPI NAND flash controller"
26 + depends on MTK_SPI_NAND
27 + help
28 + This option enables access to SPI-NAND flashes in the SPL stage
29 --- a/drivers/mtd/mtk-snand/Makefile
30 +++ b/drivers/mtd/mtk-snand/Makefile
31 @@ -8,4 +8,8 @@
32 obj-y += mtk-snand.o mtk-snand-ecc.o mtk-snand-ids.o mtk-snand-os.o
33 obj-$(CONFIG_MTK_SPI_NAND_MTD) += mtk-snand-mtd.o
34
35 +ifdef CONFIG_SPL_BUILD
36 +obj-$(CONFIG_SPL_MTK_SPI_NAND) += mtk-snand-spl.o
37 +endif
38 +
39 ccflags-y += -DPRIVATE_MTK_SNAND_HEADER
40 --- /dev/null
41 +++ b/drivers/mtd/mtk-snand/mtk-snand-spl.c
42 @@ -0,0 +1,133 @@
43 +// SPDX-License-Identifier: GPL-2.0
44 +/*
45 + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
46 + *
47 + * Author: Weijie Gao <weijie.gao@mediatek.com>
48 + */
49 +
50 +#include <common.h>
51 +#include <dm.h>
52 +#include <dm/uclass.h>
53 +#include <malloc.h>
54 +#include <mapmem.h>
55 +#include <mtd.h>
56 +#include <watchdog.h>
57 +
58 +#include "mtk-snand.h"
59 +
60 +static struct mtk_snand *snf;
61 +static struct mtk_snand_chip_info cinfo;
62 +static u32 oobavail;
63 +
64 +static u8 *page_cache;
65 +
66 +int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
67 +{
68 + u32 sizeremain = size, chunksize, leading;
69 + uint32_t off = offs, writesize_mask = cinfo.pagesize - 1;
70 + uint8_t *ptr = dst;
71 + int ret;
72 +
73 + if (!snf)
74 + return -ENODEV;
75 +
76 + while (sizeremain) {
77 + schedule();
78 +
79 + leading = off & writesize_mask;
80 + chunksize = cinfo.pagesize - leading;
81 + if (chunksize > sizeremain)
82 + chunksize = sizeremain;
83 +
84 + if (chunksize == cinfo.pagesize) {
85 + ret = mtk_snand_read_page(snf, off - leading, ptr,
86 + NULL, false);
87 + if (ret)
88 + break;
89 + } else {
90 + ret = mtk_snand_read_page(snf, off - leading,
91 + page_cache, NULL, false);
92 + if (ret)
93 + break;
94 +
95 + memcpy(ptr, page_cache + leading, chunksize);
96 + }
97 +
98 + off += chunksize;
99 + ptr += chunksize;
100 + sizeremain -= chunksize;
101 + }
102 +
103 + return ret;
104 +}
105 +
106 +void nand_init(void)
107 +{
108 + struct mtk_snand_platdata mtk_snand_pdata = {};
109 + struct udevice *dev;
110 + fdt_addr_t base;
111 + int ret;
112 +
113 + ret = uclass_get_device_by_driver(UCLASS_MTD, DM_DRIVER_GET(mtk_snand),
114 + &dev);
115 + if (ret) {
116 + printf("mtk-snand-spl: Device instance not found!\n");
117 + return;
118 + }
119 +
120 + base = dev_read_addr_name(dev, "nfi");
121 + if (base == FDT_ADDR_T_NONE) {
122 + printf("mtk-snand-spl: NFI base not set\n");
123 + return;
124 + }
125 + mtk_snand_pdata.nfi_base = map_sysmem(base, 0);
126 +
127 + base = dev_read_addr_name(dev, "ecc");
128 + if (base == FDT_ADDR_T_NONE) {
129 + printf("mtk-snand-spl: ECC base not set\n");
130 + return;
131 + }
132 + mtk_snand_pdata.ecc_base = map_sysmem(base, 0);
133 +
134 + mtk_snand_pdata.soc = dev_get_driver_data(dev);
135 + mtk_snand_pdata.quad_spi = dev_read_bool(dev, "quad-spi");
136 +
137 + ret = mtk_snand_init(NULL, &mtk_snand_pdata, &snf);
138 + if (ret) {
139 + printf("mtk-snand-spl: failed to initialize SPI-NAND\n");
140 + return;
141 + }
142 +
143 + mtk_snand_get_chip_info(snf, &cinfo);
144 +
145 + oobavail = cinfo.num_sectors * (cinfo.fdm_size - 1);
146 +
147 + printf("SPI-NAND: %s (%uMB)\n", cinfo.model,
148 + (u32)(cinfo.chipsize >> 20));
149 +
150 + page_cache = malloc(cinfo.pagesize + cinfo.sparesize);
151 + if (!page_cache) {
152 + mtk_snand_cleanup(snf);
153 + printf("mtk-snand-spl: failed to allocate page cache\n");
154 + }
155 +}
156 +
157 +void nand_deselect(void)
158 +{
159 +
160 +}
161 +
162 +static const struct udevice_id mtk_snand_ids[] = {
163 + { .compatible = "mediatek,mt7622-snand", .data = SNAND_SOC_MT7622 },
164 + { .compatible = "mediatek,mt7629-snand", .data = SNAND_SOC_MT7629 },
165 + { .compatible = "mediatek,mt7981-snand", .data = SNAND_SOC_MT7981 },
166 + { .compatible = "mediatek,mt7986-snand", .data = SNAND_SOC_MT7986 },
167 + { /* sentinel */ },
168 +};
169 +
170 +U_BOOT_DRIVER(mtk_snand) = {
171 + .name = "mtk-snand",
172 + .id = UCLASS_MTD,
173 + .of_match = mtk_snand_ids,
174 + .flags = DM_FLAG_PRE_RELOC,
175 +};