d3a337a592
* updated SNAND/SNFI driver brings support for MT7981 * add support for MediaTek NAND Memory bad Block Management (NMBM) (not used for any boards atm, but could be useful in future) * wire up NMBM support for MT7622, MT7629, MT7981 and MT7986 * replace some local patches with updated version from SDK * bring some legacy precompiler symbols which haven't been converted into Kconfig symbols in U-Boot 2022.07, remove when bumbping to U-Boot 2022.10: 100-28-include-configs-mt7986-h-from-SDK.patch Source: https://github.com/mtk-openwrt/u-boot Signed-off-by: Daniel Golle <daniel@makrotopia.org>
174 lines
3.9 KiB
Diff
174 lines
3.9 KiB
Diff
From 9e8ac4fc7125795ac5e8834aaf454fd45b99c580 Mon Sep 17 00:00:00 2001
|
|
From: Weijie Gao <weijie.gao@mediatek.com>
|
|
Date: Mon, 25 Jul 2022 10:53:03 +0800
|
|
Subject: [PATCH 46/71] mtd: mtk-snand: add NMBM support for SPL
|
|
|
|
Add NMBM support for mtk-snand SPL loader
|
|
|
|
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
|
|
---
|
|
drivers/mtd/mtk-snand/mtk-snand-spl.c | 127 ++++++++++++++++++++++++++
|
|
1 file changed, 127 insertions(+)
|
|
|
|
--- a/drivers/mtd/mtk-snand/mtk-snand-spl.c
|
|
+++ b/drivers/mtd/mtk-snand/mtk-snand-spl.c
|
|
@@ -13,12 +13,134 @@
|
|
#include <mtd.h>
|
|
#include <watchdog.h>
|
|
|
|
+#include <nmbm/nmbm.h>
|
|
+
|
|
#include "mtk-snand.h"
|
|
|
|
static struct mtk_snand *snf;
|
|
static struct mtk_snand_chip_info cinfo;
|
|
static u32 oobavail;
|
|
|
|
+#ifdef CONFIG_ENABLE_NAND_NMBM
|
|
+static struct nmbm_instance *ni;
|
|
+
|
|
+static int nmbm_lower_read_page(void *arg, uint64_t addr, void *buf, void *oob,
|
|
+ enum nmbm_oob_mode mode)
|
|
+{
|
|
+ int ret;
|
|
+ bool raw = mode == NMBM_MODE_RAW ? true : false;
|
|
+
|
|
+ if (mode == NMBM_MODE_AUTO_OOB) {
|
|
+ ret = mtk_snand_read_page_auto_oob(snf, addr, buf, oob,
|
|
+ oobavail, NULL, false);
|
|
+ } else {
|
|
+ ret = mtk_snand_read_page(snf, addr, buf, oob, raw);
|
|
+ }
|
|
+
|
|
+ if (ret == -EBADMSG)
|
|
+ return 1;
|
|
+ else if (ret >= 0)
|
|
+ return 0;
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int nmbm_lower_write_page(void *arg, uint64_t addr, const void *buf,
|
|
+ const void *oob, enum nmbm_oob_mode mode)
|
|
+{
|
|
+ bool raw = mode == NMBM_MODE_RAW ? true : false;
|
|
+
|
|
+ if (mode == NMBM_MODE_AUTO_OOB) {
|
|
+ return mtk_snand_write_page_auto_oob(snf, addr, buf, oob,
|
|
+ oobavail, NULL, false);
|
|
+ }
|
|
+
|
|
+ return mtk_snand_write_page(snf, addr, buf, oob, raw);
|
|
+}
|
|
+
|
|
+static int nmbm_lower_erase_block(void *arg, uint64_t addr)
|
|
+{
|
|
+ return mtk_snand_erase_block(snf, addr);
|
|
+}
|
|
+
|
|
+static int nmbm_lower_is_bad_block(void *arg, uint64_t addr)
|
|
+{
|
|
+ return mtk_snand_block_isbad(snf, addr);
|
|
+}
|
|
+
|
|
+static int nmbm_lower_mark_bad_block(void *arg, uint64_t addr)
|
|
+{
|
|
+ return mtk_snand_block_markbad(snf, addr);
|
|
+}
|
|
+
|
|
+static void nmbm_lower_log(void *arg, enum nmbm_log_category level,
|
|
+ const char *fmt, va_list ap)
|
|
+{
|
|
+ vprintf(fmt, ap);
|
|
+}
|
|
+
|
|
+static int nmbm_init(void)
|
|
+{
|
|
+ struct nmbm_lower_device nld;
|
|
+ size_t ni_size;
|
|
+ int ret;
|
|
+
|
|
+ memset(&nld, 0, sizeof(nld));
|
|
+
|
|
+ nld.flags = NMBM_F_CREATE;
|
|
+ nld.max_ratio = CONFIG_NMBM_MAX_RATIO;
|
|
+ nld.max_reserved_blocks = CONFIG_NMBM_MAX_BLOCKS;
|
|
+
|
|
+ nld.size = cinfo.chipsize;
|
|
+ nld.erasesize = cinfo.blocksize;
|
|
+ nld.writesize = cinfo.pagesize;
|
|
+ nld.oobsize = cinfo.sparesize;
|
|
+ nld.oobavail = oobavail;
|
|
+
|
|
+ nld.read_page = nmbm_lower_read_page;
|
|
+ nld.write_page = nmbm_lower_write_page;
|
|
+ nld.erase_block = nmbm_lower_erase_block;
|
|
+ nld.is_bad_block = nmbm_lower_is_bad_block;
|
|
+ nld.mark_bad_block = nmbm_lower_mark_bad_block;
|
|
+
|
|
+ nld.logprint = nmbm_lower_log;
|
|
+
|
|
+ ni_size = nmbm_calc_structure_size(&nld);
|
|
+ ni = malloc(ni_size);
|
|
+ if (!ni) {
|
|
+ printf("Failed to allocate memory (0x%u) for NMBM instance\n",
|
|
+ ni_size);
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+
|
|
+ memset(ni, 0, ni_size);
|
|
+
|
|
+ printf("Initializing NMBM ...\n");
|
|
+
|
|
+ ret = nmbm_attach(&nld, ni);
|
|
+ if (ret) {
|
|
+ ni = NULL;
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
|
|
+{
|
|
+ size_t retlen;
|
|
+
|
|
+ if (!ni)
|
|
+ return -ENODEV;
|
|
+
|
|
+ nmbm_read_range(ni, offs, size, dst, NMBM_MODE_PLACE_OOB, &retlen);
|
|
+ if (retlen != size)
|
|
+ return -EIO;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#else
|
|
static u8 *page_cache;
|
|
|
|
int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
|
|
@@ -60,6 +182,7 @@ int nand_spl_load_image(uint32_t offs, u
|
|
|
|
return ret;
|
|
}
|
|
+#endif
|
|
|
|
void nand_init(void)
|
|
{
|
|
@@ -105,11 +228,15 @@ void nand_init(void)
|
|
printf("SPI-NAND: %s (%uMB)\n", cinfo.model,
|
|
(u32)(cinfo.chipsize >> 20));
|
|
|
|
+#ifdef CONFIG_ENABLE_NAND_NMBM
|
|
+ nmbm_init();
|
|
+#else
|
|
page_cache = malloc(cinfo.pagesize + cinfo.sparesize);
|
|
if (!page_cache) {
|
|
mtk_snand_cleanup(snf);
|
|
printf("mtk-snand-spl: failed to allocate page cache\n");
|
|
}
|
|
+#endif
|
|
}
|
|
|
|
void nand_deselect(void)
|