aboutsummaryrefslogtreecommitdiffstats
path: root/package/boot/uboot-mediatek/patches/100-12-mtd-mtk-snand-add-NMBM-support-for-SPL.patch
blob: 32b21be255133620d665878cb39dc7ef58223a27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
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)