uboot-mediatek: additions from MTK SDK

* 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>
This commit is contained in:
Daniel Golle 2022-08-07 12:06:56 +02:00
parent c09eb08dad
commit d3a337a592
45 changed files with 10562 additions and 276 deletions

View File

@ -1,69 +0,0 @@
From 34ed9f6d3018d32c7c015e57c9985d3c4c07b706 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Thu, 11 Mar 2021 10:28:53 +0000
Subject: [PATCH 01/12] Revert "clk: Add debugging for return values"
This reverts commit 5c5992cb90cf9ca4d51e38d9a95a13c293904df5.
---
drivers/clk/clk-uclass.c | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -88,7 +88,7 @@ static int clk_get_by_index_tail(int ret
if (ret) {
debug("%s: uclass_get_device_by_of_offset failed: err=%d\n",
__func__, ret);
- return log_msg_ret("get", ret);
+ return ret;
}
clk->dev = dev_clk;
@@ -101,15 +101,14 @@ static int clk_get_by_index_tail(int ret
ret = clk_of_xlate_default(clk, args);
if (ret) {
debug("of_xlate() failed: %d\n", ret);
- return log_msg_ret("xlate", ret);
+ return ret;
}
return clk_request(dev_clk, clk);
err:
debug("%s: Node '%s', property '%s', failed to request CLK index %d: %d\n",
__func__, ofnode_get_name(node), list_name, index, ret);
-
- return log_msg_ret("prop", ret);
+ return ret;
}
static int clk_get_by_indexed_prop(struct udevice *dev, const char *prop_name,
@@ -128,7 +127,7 @@ static int clk_get_by_indexed_prop(struc
if (ret) {
debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n",
__func__, ret);
- return log_ret(ret);
+ return ret;
}
@@ -469,7 +468,6 @@ void clk_free(struct clk *clk)
ulong clk_get_rate(struct clk *clk)
{
const struct clk_ops *ops;
- int ret;
debug("%s(clk=%p)\n", __func__, clk);
if (!clk_valid(clk))
@@ -479,11 +477,7 @@ ulong clk_get_rate(struct clk *clk)
if (!ops->get_rate)
return -ENOSYS;
- ret = ops->get_rate(clk);
- if (ret)
- return log_ret(ret);
-
- return 0;
+ return ops->get_rate(clk);
}
struct clk *clk_get_parent(struct clk *clk)

View File

@ -21,7 +21,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
CONFIG_DEBUG_UART_BASE=0x11002000
CONFIG_DEBUG_UART_CLOCK=25000000
CONFIG_SYS_LOAD_ADDR=0x4007ff28
@@ -22,6 +24,9 @@ CONFIG_CMD_SF_TEST=y
@@ -21,6 +23,9 @@ CONFIG_CMD_SF_TEST=y
CONFIG_CMD_PING=y
CONFIG_CMD_SMC=y
CONFIG_ENV_OVERWRITE=y

View File

@ -34,7 +34,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
--- a/arch/arm/dts/mt7622-rfb.dts
+++ b/arch/arm/dts/mt7622-rfb.dts
@@ -196,8 +196,6 @@
@@ -189,8 +189,6 @@
};
&uart0 {

View File

@ -16,7 +16,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
--- a/arch/arm/dts/mt7622.dtsi
+++ b/arch/arm/dts/mt7622.dtsi
@@ -191,6 +191,7 @@
@@ -175,6 +175,7 @@
status = "disabled";
assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>;
assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>;

View File

@ -29,7 +29,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
};
&snfi {
@@ -249,3 +257,13 @@
@@ -242,3 +250,13 @@
&u3phy {
status = "okay";
};
@ -45,7 +45,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+};
--- a/arch/arm/dts/mt7622.dtsi
+++ b/arch/arm/dts/mt7622.dtsi
@@ -440,4 +440,28 @@
@@ -424,4 +424,28 @@
status = "disabled";
};

View File

@ -24,7 +24,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -148,6 +148,7 @@ dumpimage-mkimage-objs := aisimage.o \
@@ -147,6 +147,7 @@ dumpimage-mkimage-objs := aisimage.o \
gpimage.o \
gpimage-common.o \
mtk_image.o \

View File

@ -0,0 +1,182 @@
From baef13ec9d592a27b5d3bf03967bfd2bebd65157 Mon Sep 17 00:00:00 2001
From: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
Date: Wed, 25 May 2022 10:47:12 +0530
Subject: [PATCH] mtd: spi-nor-ids: Add support for flashes tested by xilinx
Add support for various flashes from below manufacturers which are tested
by xilinx for years.
EON:
en25q128b
GIGA:
gd25lx256e
ISSI:
is25lp008
is25lp016
is25lp01g
is25wp008
is25wp016
is25wp01g
is25wx256
MACRONIX:
mx25u51245f
mx66u1g45g
mx66l2g45g
MICRON:
mt35xl512aba
mt35xu01g
SPANSION:
s70fs01gs_256k
SST:
sst26wf016b
WINBOND:
w25q16dw
w25q16jv
w25q512jv
w25q32bv
w25h02jv
Signed-off-by: Ashok Reddy Soma <ashok.reddy.soma@xilinx.com>
Link: https://lore.kernel.org/r/1653455832-14763-1-git-send-email-ashok.reddy.soma@xilinx.com
Signed-off-by: Michal Simek <michal.simek@amd.com>
---
drivers/mtd/spi/spi-nor-ids.c | 37 +++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -82,6 +82,7 @@ const struct flash_info spi_nor_ids[] =
/* EON -- en25xxx */
{ INFO("en25q32b", 0x1c3016, 0, 64 * 1024, 64, 0) },
{ INFO("en25q64", 0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
+ { INFO("en25q128b", 0x1c3018, 0, 64 * 1024, 256, 0) },
{ INFO("en25qh128", 0x1c7018, 0, 64 * 1024, 256, 0) },
{ INFO("en25s64", 0x1c3817, 0, 64 * 1024, 128, SECT_4K) },
#endif
@@ -127,11 +128,17 @@ const struct flash_info spi_nor_ids[] =
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
+ {
+ INFO("gd25lx256e", 0xc86819, 0, 64 * 1024, 512,
+ SECT_4K | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES)
+ },
#endif
#ifdef CONFIG_SPI_FLASH_ISSI /* ISSI */
/* ISSI */
{ INFO("is25lq040b", 0x9d4013, 0, 64 * 1024, 8,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("is25lp008", 0x9d6014, 0, 64 * 1024, 16, SPI_NOR_QUAD_READ) },
+ { INFO("is25lp016", 0x9d6015, 0, 64 * 1024, 32, SPI_NOR_QUAD_READ) },
{ INFO("is25lp032", 0x9d6016, 0, 64 * 1024, 64, 0) },
{ INFO("is25lp064", 0x9d6017, 0, 64 * 1024, 128, 0) },
{ INFO("is25lp128", 0x9d6018, 0, 64 * 1024, 256,
@@ -140,6 +147,10 @@ const struct flash_info spi_nor_ids[] =
SECT_4K | SPI_NOR_DUAL_READ) },
{ INFO("is25lp512", 0x9d601a, 0, 64 * 1024, 1024,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("is25lp01g", 0x9d601b, 0, 64 * 1024, 2048,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("is25wp008", 0x9d7014, 0, 64 * 1024, 16, SPI_NOR_QUAD_READ) },
+ { INFO("is25wp016", 0x9d7015, 0, 64 * 1024, 32, SPI_NOR_QUAD_READ) },
{ INFO("is25wp032", 0x9d7016, 0, 64 * 1024, 64,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("is25wp064", 0x9d7017, 0, 64 * 1024, 128,
@@ -151,6 +162,10 @@ const struct flash_info spi_nor_ids[] =
SPI_NOR_4B_OPCODES) },
{ INFO("is25wp512", 0x9d701a, 0, 64 * 1024, 1024,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("is25wp01g", 0x9d701b, 0, 64 * 1024, 2048,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("is25wx256", 0x9d5b19, 0, 128 * 1024, 256,
+ SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) },
#endif
#ifdef CONFIG_SPI_FLASH_MACRONIX /* MACRONIX */
/* Macronix */
@@ -176,8 +191,11 @@ const struct flash_info spi_nor_ids[] =
{ INFO("mx25l25655e", 0xc22619, 0, 64 * 1024, 512, 0) },
{ INFO("mx66l51235l", 0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx66u51235f", 0xc2253a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx25u51245f", 0xc2953a, 0, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx66u1g45g", 0xc2253b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx66u2g45g", 0xc2253c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx66l1g45g", 0xc2201b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("mx66l2g45g", 0xc2201c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx25l1633e", 0xc22415, 0, 64 * 1024, 32, SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | SECT_4K) },
{ INFO("mx25r6435f", 0xc22817, 0, 64 * 1024, 128, SECT_4K) },
{ INFO("mx66uw2g345g", 0xc2943c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) },
@@ -208,8 +226,10 @@ const struct flash_info spi_nor_ids[] =
{ INFO("mt25qu02g", 0x20bb22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
{ INFO("mt25ql02g", 0x20ba22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE | SPI_NOR_4B_OPCODES) },
#ifdef CONFIG_SPI_FLASH_MT35XU
+ { INFO("mt35xl512aba", 0x2c5a1a, 0, 128 * 1024, 512, USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES | SPI_NOR_OCTAL_DTR_READ) },
{ INFO("mt35xu512aba", 0x2c5b1a, 0, 128 * 1024, 512, USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES | SPI_NOR_OCTAL_DTR_READ) },
#endif /* CONFIG_SPI_FLASH_MT35XU */
+ { INFO6("mt35xu01g", 0x2c5b1b, 0x104100, 128 * 1024, 1024, USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mt35xu02g", 0x2c5b1c, 0, 128 * 1024, 2048, USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) },
#endif
#ifdef CONFIG_SPI_FLASH_SPANSION /* SPANSION */
@@ -225,6 +245,7 @@ const struct flash_info spi_nor_ids[] =
{ INFO("s25fl512s_256k", 0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
{ INFO("s25fl512s_64k", 0x010220, 0x4d01, 64 * 1024, 1024, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
{ INFO("s25fl512s_512k", 0x010220, 0x4f00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
+ { INFO("s70fs01gs_256k", 0x010221, 0x4d00, 256 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("s25sl12800", 0x012018, 0x0300, 256 * 1024, 64, 0) },
{ INFO("s25sl12801", 0x012018, 0x0301, 64 * 1024, 256, 0) },
{ INFO6("s25fl128s", 0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) },
@@ -275,6 +296,7 @@ const struct flash_info spi_nor_ids[] =
{ INFO("sst25wf040", 0xbf2504, 0, 64 * 1024, 8, SECT_4K | SST_WRITE) },
{ INFO("sst25wf080", 0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
{ INFO("sst26vf064b", 0xbf2643, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_HAS_SST26LOCK | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("sst26wf016b", 0xbf2641, 0, 64 * 1024, 32, SECT_4K) },
{ INFO("sst26wf016", 0xbf2651, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_HAS_SST26LOCK) },
{ INFO("sst26wf032", 0xbf2622, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_SST26LOCK) },
{ INFO("sst26wf064", 0xbf2643, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_HAS_SST26LOCK) },
@@ -312,11 +334,19 @@ const struct flash_info spi_nor_ids[] =
{ INFO("w25q20ew", 0xef6012, 0, 64 * 1024, 4, SECT_4K) },
{ INFO("w25q32", 0xef4016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{
+ INFO("w25q16dw", 0xef6015, 0, 64 * 1024, 32,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+ },
+ {
INFO("w25q32dw", 0xef6016, 0, 64 * 1024, 64,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
{
+ INFO("w25q16jv", 0xef7015, 0, 64 * 1024, 32,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+ },
+ {
INFO("w25q32jv", 0xef7016, 0, 64 * 1024, 64,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
@@ -363,6 +393,11 @@ const struct flash_info spi_nor_ids[] =
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
{
+ INFO("w25q512jv", 0xef7119, 0, 64 * 1024, 512,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
+ {
INFO("w25q01jv", 0xef4021, 0, 64 * 1024, 2048,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
@@ -370,6 +405,7 @@ const struct flash_info spi_nor_ids[] =
{ INFO("w25q80", 0xef5014, 0, 64 * 1024, 16, SECT_4K) },
{ INFO("w25q80bl", 0xef4014, 0, 64 * 1024, 16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25q16cl", 0xef4015, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("w25q32bv", 0xef4016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25q64cv", 0xef4017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25q128", 0xef4018, 0, 64 * 1024, 256,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
@@ -378,6 +414,7 @@ const struct flash_info spi_nor_ids[] =
{ INFO("w25q256", 0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25m512jw", 0xef6119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25m512jv", 0xef7119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("w25h02jv", 0xef9022, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
#endif
#ifdef CONFIG_SPI_FLASH_XMC
/* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */

View File

@ -0,0 +1,614 @@
From 4290ed7835e0a76792b8e554ae79e3f6d52ac800 Mon Sep 17 00:00:00 2001
From: JaimeLiao <jaimeliao.tw@gmail.com>
Date: Mon, 18 Jul 2022 14:49:22 +0800
Subject: [PATCH] mtd: spi-nor-core: Add support for Macronix Octal flash
Adding Macronix Octal flash for Octal DTR support.
The octaflash series can be divided into the following types:
MX25 series : Serial NOR Flash.
MX66 series : Serial NOR Flash with stacked die.(Size larger than 1Gb)
LM/UM series : Up to 250MHz clock frequency with both DTR/STR operation.
LW/UW series : Support simultaneous Read-while-Write operation in multiple
bank architecture. Read-while-write feature which means read
data one bank while another bank is programing or erasing.
MX25LM : 3.0V Octal I/O
-https://www.mxic.com.tw/Lists/Datasheet/Attachments/7841/MX25LM51245G,%203V,%20512Mb,%20v1.1.pdf
MX25UM : 1.8V Octal I/O
-https://www.mxic.com.tw/Lists/Datasheet/Attachments/7525/MX25UM51245G%20Extreme%20Speed,%201.8V,%20512Mb,%20v1.0.pdf
MX66LM : 3.0V Octal I/O with stacked die
-https://www.mxic.com.tw/Lists/Datasheet/Attachments/7929/MX66LM1G45G,%203V,%201Gb,%20v1.1.pdf
MX66UM : 1.8V Octal I/O with stacked die
-https://www.mxic.com.tw/Lists/Datasheet/Attachments/7721/MX66UM1G45G,%201.8V,%201Gb,%20v1.1.pdf
MX25LW : 3.0V Octal I/O with Read-while-Write
MX25UW : 1.8V Octal I/O with Read-while-Write
MX66LW : 3.0V Octal I/O with Read-while-Write and stack die
MX66UW : 1.8V Octal I/O with Read-while-Write and stack die
About LW/UW series, please contact us freely if you have any
questions. For adding Octal NOR Flash IDs, we have validated
each Flash on plateform zynq-picozed.
As below are the SFDP table dump.
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c2943c
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx66uw2g345gx0
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx66uw2g345gx0
zynq> hexdump mx66uw2g345gx0
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 7fff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 7987 0001 1284 e200 04cc 4667
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 237c 0048 0000 0000 8888
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0a00 0000
0000130 4514 8098 0643 001f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c2853b
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx66lm1g45g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx66lm1g45g
zynq> hexdump mx66lm1g45g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 3fff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 6987 0001 1282 e200 02cc 3867
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 a37c 0048 0000 0000 6666
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0000 0000
0000130 3514 001c 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c2853a
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx25lm51245g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx25lm51245g
zynq> hexdump mx25lm51245g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 1fff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 7989 0001 128d e200 02cc 4467
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 a37c 0048 0000 0000 6666
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0000 0000
0000130 3514 001c 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c2863a
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx25lw51245g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx25lw51245g
zynq> hexdump mx25lw51245g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 0000 0000 0000 0000
0000040 20e5 ff8a ffff 1fff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 798b 0001 128f e200 04cc 4667
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 a37c 0048 0000 0000 6666
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0000 0000
0000130 3514 001c 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c28539
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx25lm25645g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx25lm25645g
zynq> hexdump mx25lm25645g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 0fff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 6987 0001 1282 d200 02cc 3867
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 a37c 0048 0000 0000 6666
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0000 0000
0000130 3514 001c 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c2843c
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx66uw2g345g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx66uw2g345g
zynq> hexdump mx66uw2g345g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 7fff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 7987 0001 1284 e200 04cc 4667
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 237c 0048 0000 0000 8888
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0a00 0000
0000130 4514 8098 0643 001f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c2803b
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx66um1g45g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx66um1g45g
zynq> hexdump mx66um1g45g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 3fff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 7989 0001 128d e200 02cc 4467
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 a37c 0048 0000 0000 8888
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0a00 0000
0000130 3514 809c 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c2813b
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx66uw1g45g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx66uw1g45g
zynq> hexdump mx66uw1g45g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 3fff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 798b 0001 128f e200 04cc 4667
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 a37c 0048 0000 0000 8888
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0a00 0000
0000130 4514 8098 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c2813a
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx25uw51245g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx25uw51245g
zynq> hexdump mx25uw51245g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 1fff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 798b 0001 128f e200 04cc 4667
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 a37c 0048 0000 0000 7777
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0000 0000
0000130 4514 8098 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c2843a
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx25uw51345g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx25uw51345g
zynq> hexdump mx25uw51345g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 1fff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 798b 0001 128f e200 04cc 4667
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 237c 0048 0000 0000 8888
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0a00 0000
0000130 4514 8098 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c28039
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx25um25645g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx25um25645g
zynq> random: fast init done
zynq> hexdump mx25um25645g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 0fff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 7987 0001 1284 d200 02cc 3867
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 a37c 0048 0000 0000 8888
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0a00 0000
0000130 3514 809c 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c28139
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx25uw25645g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx25uw25645g
zynq> hexdump mx25uw25645g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 0fff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 7989 0001 128d d200 04cc 4667
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 a37c 0048 0000 0000 8888
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0a00 0000
0000130 4514 8098 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c28339
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx25um25345g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx25um25345g
zynq> hexdump mx25um25345g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 0fff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 6987 0001 1282 d200 02cc 3867
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 237c 0048 0000 0000 8888
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0904 0000
0000130 4514 8098 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c28439
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx25uw25345g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx25uw25345g
zynq> hexdump mx25uw25345g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 0fff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 7987 0001 1284 d200 04cc 4667
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 237c 0048 0000 0000 8888
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0a00 0000
0000130 4514 8098 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c28138
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx25uw12845g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx25uw12845g
zynq> hexdump mx25uw12845g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 0000 0000 0000 0000
0000040 20e5 ff8a ffff 07ff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 798b 0001 128f c900 04cc 4667
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 a37c 0048 0000 0000 8888
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0a00 0000
0000130 4514 8098 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c28438
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx25uw12345g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx25uw12345g
zynq> hexdump mx25uw12345g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 07ff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 798b 0001 128f c900 04cc 4667
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 237c 0048 0000 0000 8888
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0a00 0000
0000130 4514 8098 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c28137
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx25uw6445g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx25uw6445g
zynq> hexdump mx25uw6445g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 03ff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 7989 0001 128d c400 04cc 4667
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 a37c 0048 0000 0000 8888
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0a00 0000
0000130 4514 8098 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/jedec_id
c28437
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/manufacturer
macronix
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/partname
mx25uw6345g
zynq> cat /sys/bus/spi/devices/spi0.0/spi-nor/sfdp > mx25uw6345g
zynq> hexdump mx25uw6345g
0000000 4653 5044 0108 fd04 0700 1401 0040 ff00
0000010 0187 1c01 0090 ff00 000a 0801 0100 ff00
0000020 0005 0501 0120 ff00 0084 0201 0134 ff00
0000030 0000 0000 0000 0000 ffff ffff ffff ffff
0000040 20e5 ff8a ffff 03ff ff00 ff00 ff00 ff00
0000050 ffee ffff ffff ff00 ffff ff00 200c d810
0000060 ff00 ff00 798b 0001 128f c400 04cc 4667
0000070 b030 b030 bdf4 5cd5 0000 ff00 1010 2000
0000080 0000 0000 0000 237c 0048 0000 0000 8888
0000090 0000 0000 0000 4000 d10f f3ff d10f f3ff
00000a0 0500 9000 0500 b100 2b00 9500 2b00 9600
00000b0 7172 b803 7172 b803 0000 0000 a390 8218
00000c0 c000 9669 0000 0000 0000 0000 7172 9800
00000d0 7172 b800 7172 9900 0000 0000 7172 9800
00000e0 7172 f800 7172 9900 7172 f900 0000 0000
00000f0 0000 0000 1501 d001 7172 d806 0000 5086
0000100 0000 0106 0000 0000 0002 0301 0200 0000
0000110 0000 0106 0000 0000 0000 0672 0200 0000
0000120 ee00 69c0 7272 7171 d800 f6f7 0a00 0000
0000130 4514 8098 0643 000f dc21 ffff ffff ffff
0000140 ffff ffff ffff ffff ffff ffff ffff ffff
Signed-off-by: JaimeLiao <jaimeliao.tw@gmail.com>
Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
---
drivers/mtd/spi/spi-nor-ids.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -198,7 +198,24 @@ const struct flash_info spi_nor_ids[] =
{ INFO("mx66l2g45g", 0xc2201c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
{ INFO("mx25l1633e", 0xc22415, 0, 64 * 1024, 32, SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | SECT_4K) },
{ INFO("mx25r6435f", 0xc22817, 0, 64 * 1024, 128, SECT_4K) },
- { INFO("mx66uw2g345g", 0xc2943c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx66uw2g345gx0", 0xc2943c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx66lm1g45g", 0xc2853b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx25lm51245g", 0xc2853a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx25lw51245g", 0xc2863a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx25lm25645g", 0xc28539, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx66uw2g345g", 0xc2843c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx66um1g45g", 0xc2803b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx66uw1g45g", 0xc2813b, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx25uw51245g", 0xc2813a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx25uw51345g", 0xc2843a, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx25um25645g", 0xc28039, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx25uw25645g", 0xc28139, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx25um25345g", 0xc28339, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx25uw25345g", 0xc28439, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx25uw12845g", 0xc28138, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx25uw12345g", 0xc28438, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx25uw6445g", 0xc28137, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("mx25uw6345g", 0xc28437, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES) },
#endif
#ifdef CONFIG_SPI_FLASH_STMICRO /* STMICRO */

View File

@ -0,0 +1,39 @@
From 47ed8b22fd561b65e8541919becc76ab3d86f7a3 Mon Sep 17 00:00:00 2001
From: Jae Hyun Yoo <quic_jaehyoo@quicinc.com>
Date: Fri, 8 Jul 2022 12:03:19 -0700
Subject: [PATCH] mtd: spi-nor-ids: add winbond w25q512nw family support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add Winbond w25q512nwq/n and w25q512nwm support.
datasheet:
https://www.winbond.com/resource-files/W25Q512NW%20RevB%2007192021.pdf
Signed-off-by: Jae Hyun Yoo <quic_jaehyoo@quicinc.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Jagan Teki <jagan@amarulasolutions.com>
---
drivers/mtd/spi/spi-nor-ids.c | 10 ++++++++++
1 file changed, 10 insertions(+)
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -415,6 +415,16 @@ const struct flash_info spi_nor_ids[] =
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
{
+ INFO("w25q512nwq", 0xef6020, 0, 64 * 1024, 1024,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
+ {
+ INFO("w25q512nwm", 0xef8020, 0, 64 * 1024, 1024,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
+ {
INFO("w25q01jv", 0xef4021, 0, 64 * 1024, 2048,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)

View File

@ -0,0 +1,43 @@
From 19f2aa053d5531a9ca0ece04dca172a522d58b90 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Fri, 29 Jul 2022 11:32:28 +0800
Subject: [PATCH 32/71] clk: remove log_ret from clk_get_rate
The return value of clk_get_rate is ulong, an unsigned type. The size of
ulong depends on the cpu architecture, i.e. 4 bytes on 32-bit CPUs and
8 bytes on 64-bit CPUs.
However log_ret only accepts and returns value in int type, a fixed 4-byte
type. This may truncate the real clock value and cause unexpected error on
64-bit platforms.
This patch removes log_ret to solve this issue.
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
drivers/clk/clk-uclass.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -469,7 +469,6 @@ void clk_free(struct clk *clk)
ulong clk_get_rate(struct clk *clk)
{
const struct clk_ops *ops;
- int ret;
debug("%s(clk=%p)\n", __func__, clk);
if (!clk_valid(clk))
@@ -479,11 +478,7 @@ ulong clk_get_rate(struct clk *clk)
if (!ops->get_rate)
return -ENOSYS;
- ret = ops->get_rate(clk);
- if (ret)
- return log_ret(ret);
-
- return 0;
+ return ops->get_rate(clk);
}
struct clk *clk_get_parent(struct clk *clk)

View File

@ -1,7 +1,7 @@
From 938ba7ed996a86c9cc7af08b69df57b8b4c09510 Mon Sep 17 00:00:00 2001
From 97df847f8f895cc2692bb0e4e933269c275da378 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Tue, 2 Mar 2021 15:47:45 +0800
Subject: [PATCH 02/12] board: mediatek: add more network configurations
Subject: [PATCH 35/71] board: mediatek: add more network configurations
Make the network configurations uniform for mediatek boards
@ -10,7 +10,9 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
include/configs/mt7622.h | 3 ++-
include/configs/mt7623.h | 1 +
include/configs/mt7629.h | 1 +
3 files changed, 4 insertions(+), 1 deletion(-)
include/configs/mt7981.h | 5 +++++
include/configs/mt7986.h | 5 +++++
5 files changed, 14 insertions(+), 1 deletion(-)
--- a/include/configs/mt7622.h
+++ b/include/configs/mt7622.h
@ -42,3 +44,27 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+#define CONFIG_NETMASK 255.255.255.0
#endif
--- a/include/configs/mt7981.h
+++ b/include/configs/mt7981.h
@@ -23,4 +23,9 @@
/* DRAM */
#define CONFIG_SYS_SDRAM_BASE 0x40000000
+/* Ethernet */
+#define CONFIG_IPADDR 192.168.1.1
+#define CONFIG_SERVERIP 192.168.1.2
+#define CONFIG_NETMASK 255.255.255.0
+
#endif
--- a/include/configs/mt7986.h
+++ b/include/configs/mt7986.h
@@ -23,4 +23,9 @@
/* DRAM */
#define CONFIG_SYS_SDRAM_BASE 0x40000000
+/* Ethernet */
+#define CONFIG_IPADDR 192.168.1.1
+#define CONFIG_SERVERIP 192.168.1.2
+#define CONFIG_NETMASK 255.255.255.0
+
#endif

View File

@ -1,7 +1,7 @@
From d6c5309185aae3d9ecf80eae8b248522d11a6136 Mon Sep 17 00:00:00 2001
From f7704275957852cd4c4632d6da126979ef24b83a Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Tue, 2 Mar 2021 16:58:01 +0800
Subject: [PATCH 04/12] drivers: mtd: add support for MediaTek SPI-NAND flash
Subject: [PATCH 36/71] drivers: mtd: add support for MediaTek SPI-NAND flash
controller
Add mtd driver for MediaTek SPI-NAND flash controller
@ -16,15 +16,15 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
drivers/mtd/Makefile | 2 +
drivers/mtd/mtk-snand/Kconfig | 21 +
drivers/mtd/mtk-snand/Makefile | 11 +
drivers/mtd/mtk-snand/mtk-snand-def.h | 266 ++++
drivers/mtd/mtk-snand/mtk-snand-ecc.c | 264 ++++
drivers/mtd/mtk-snand/mtk-snand-def.h | 271 ++++
drivers/mtd/mtk-snand/mtk-snand-ecc.c | 395 +++++
drivers/mtd/mtk-snand/mtk-snand-ids.c | 511 +++++++
drivers/mtd/mtk-snand/mtk-snand-mtd.c | 526 ++++++++
drivers/mtd/mtk-snand/mtk-snand-mtd.c | 535 +++++++
drivers/mtd/mtk-snand/mtk-snand-os.c | 39 +
drivers/mtd/mtk-snand/mtk-snand-os.h | 120 ++
drivers/mtd/mtk-snand/mtk-snand.c | 1776 +++++++++++++++++++++++++
drivers/mtd/mtk-snand/mtk-snand.h | 77 ++
12 files changed, 3615 insertions(+)
drivers/mtd/mtk-snand/mtk-snand.c | 1933 +++++++++++++++++++++++++
drivers/mtd/mtk-snand/mtk-snand.h | 77 +
12 files changed, 3917 insertions(+)
create mode 100644 drivers/mtd/mtk-snand/Kconfig
create mode 100644 drivers/mtd/mtk-snand/Makefile
create mode 100644 drivers/mtd/mtk-snand/mtk-snand-def.h
@ -95,7 +95,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ccflags-y += -DPRIVATE_MTK_SNAND_HEADER
--- /dev/null
+++ b/drivers/mtd/mtk-snand/mtk-snand-def.h
@@ -0,0 +1,266 @@
@@ -0,0 +1,271 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
@ -213,6 +213,9 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+
+ const uint8_t *spare_sizes;
+ uint32_t num_spare_size;
+
+ uint16_t latch_lat;
+ uint16_t sample_delay;
+};
+
+enum mtk_ecc_regs {
@ -272,6 +275,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+
+ uint8_t *page_cache; /* Used by read/write page */
+ uint8_t *buf_cache; /* Used by block bad/markbad & auto_oob */
+ int *sect_bf; /* Used by ECC correction */
+};
+
+enum mtk_snand_log_category {
@ -290,7 +294,8 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+int mtk_snand_ecc_decoder_start(struct mtk_snand *snf);
+void mtk_snand_ecc_decoder_stop(struct mtk_snand *snf);
+int mtk_ecc_wait_decoder_done(struct mtk_snand *snf);
+int mtk_ecc_check_decode_error(struct mtk_snand *snf, uint32_t page);
+int mtk_ecc_check_decode_error(struct mtk_snand *snf);
+int mtk_ecc_fixup_empty_sector(struct mtk_snand *snf, uint32_t sect);
+
+int mtk_snand_mac_io(struct mtk_snand *snf, const uint8_t *out, uint32_t outlen,
+ uint8_t *in, uint32_t inlen);
@ -364,7 +369,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+#endif /* _MTK_SNAND_DEF_H_ */
--- /dev/null
+++ b/drivers/mtd/mtk-snand/mtk-snand-ecc.c
@@ -0,0 +1,264 @@
@@ -0,0 +1,395 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
@ -599,7 +604,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ return ret;
+}
+
+int mtk_ecc_check_decode_error(struct mtk_snand *snf, uint32_t page)
+int mtk_ecc_check_decode_error(struct mtk_snand *snf)
+{
+ uint32_t i, regi, fi, errnum;
+ uint32_t errnum_shift = snf->ecc_soc->errnum_shift;
@ -612,23 +617,154 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+
+ errnum = ecc_read32(snf, ECC_DECENUM(regi));
+ errnum = (errnum >> (fi * errnum_shift)) & errnum_mask;
+ if (!errnum)
+ continue;
+
+ if (errnum <= snf->ecc_strength) {
+ if (ret >= 0)
+ ret += errnum;
+ continue;
+ snf->sect_bf[i] = errnum;
+ } else {
+ snf->sect_bf[i] = -1;
+ ret = -EBADMSG;
+ }
+
+ snand_log_ecc(snf->pdev,
+ "Uncorrectable bitflips in page %u sect %u\n",
+ page, i);
+ ret = -EBADMSG;
+ }
+
+ return ret;
+}
+
+static int mtk_ecc_check_buf_bitflips(struct mtk_snand *snf, const void *buf,
+ size_t len, uint32_t bitflips)
+{
+ const uint8_t *buf8 = buf;
+ const uint32_t *buf32;
+ uint32_t d, weight;
+
+ while (len && ((uintptr_t)buf8) % sizeof(uint32_t)) {
+ weight = hweight8(*buf8);
+ bitflips += BITS_PER_BYTE - weight;
+ buf8++;
+ len--;
+
+ if (bitflips > snf->ecc_strength)
+ return -EBADMSG;
+ }
+
+ buf32 = (const uint32_t *)buf8;
+ while (len >= sizeof(uint32_t)) {
+ d = *buf32;
+
+ if (d != ~0) {
+ weight = hweight32(d);
+ bitflips += sizeof(uint32_t) * BITS_PER_BYTE - weight;
+ }
+
+ buf32++;
+ len -= sizeof(uint32_t);
+
+ if (bitflips > snf->ecc_strength)
+ return -EBADMSG;
+ }
+
+ buf8 = (const uint8_t *)buf32;
+ while (len) {
+ weight = hweight8(*buf8);
+ bitflips += BITS_PER_BYTE - weight;
+ buf8++;
+ len--;
+
+ if (bitflips > snf->ecc_strength)
+ return -EBADMSG;
+ }
+
+ return bitflips;
+}
+
+static int mtk_ecc_check_parity_bitflips(struct mtk_snand *snf, const void *buf,
+ uint32_t bits, uint32_t bitflips)
+{
+ uint32_t len, i;
+ uint8_t b;
+ int rc;
+
+ len = bits >> 3;
+ bits &= 7;
+
+ rc = mtk_ecc_check_buf_bitflips(snf, buf, len, bitflips);
+ if (!bits || rc < 0)
+ return rc;
+
+ bitflips = rc;
+
+ /* We want a precise count of bits */
+ b = ((const uint8_t *)buf)[len];
+ for (i = 0; i < bits; i++) {
+ if (!(b & BIT(i)))
+ bitflips++;
+ }
+
+ if (bitflips > snf->ecc_strength)
+ return -EBADMSG;
+
+ return bitflips;
+}
+
+static void mtk_ecc_reset_parity(void *buf, uint32_t bits)
+{
+ uint32_t len;
+
+ len = bits >> 3;
+ bits &= 7;
+
+ memset(buf, 0xff, len);
+
+ /* Only reset bits protected by ECC to 1 */
+ if (bits)
+ ((uint8_t *)buf)[len] |= GENMASK(bits - 1, 0);
+}
+
+int mtk_ecc_fixup_empty_sector(struct mtk_snand *snf, uint32_t sect)
+{
+ uint32_t ecc_bytes = snf->spare_per_sector - snf->nfi_soc->fdm_size;
+ uint8_t *oob = snf->page_cache + snf->writesize;
+ uint8_t *data_ptr, *fdm_ptr, *ecc_ptr;
+ int bitflips = 0, ecc_bits, parity_bits;
+
+ parity_bits = fls(snf->nfi_soc->sector_size * 8);
+ ecc_bits = snf->ecc_strength * parity_bits;
+
+ data_ptr = snf->page_cache + sect * snf->nfi_soc->sector_size;
+ fdm_ptr = oob + sect * snf->nfi_soc->fdm_size;
+ ecc_ptr = oob + snf->ecc_steps * snf->nfi_soc->fdm_size +
+ sect * ecc_bytes;
+
+ /*
+ * Check whether DATA + FDM + ECC of a sector contains correctable
+ * bitflips
+ */
+ bitflips = mtk_ecc_check_buf_bitflips(snf, data_ptr,
+ snf->nfi_soc->sector_size,
+ bitflips);
+ if (bitflips < 0)
+ return -EBADMSG;
+
+ bitflips = mtk_ecc_check_buf_bitflips(snf, fdm_ptr,
+ snf->nfi_soc->fdm_ecc_size,
+ bitflips);
+ if (bitflips < 0)
+ return -EBADMSG;
+
+ bitflips = mtk_ecc_check_parity_bitflips(snf, ecc_ptr, ecc_bits,
+ bitflips);
+ if (bitflips < 0)
+ return -EBADMSG;
+
+ if (!bitflips)
+ return 0;
+
+ /* Reset the data of this sector to 0xff */
+ memset(data_ptr, 0xff, snf->nfi_soc->sector_size);
+ memset(fdm_ptr, 0xff, snf->nfi_soc->fdm_ecc_size);
+ mtk_ecc_reset_parity(ecc_ptr, ecc_bits);
+
+ return bitflips;
+}
--- /dev/null
+++ b/drivers/mtd/mtk-snand/mtk-snand-ids.c
@@ -0,0 +1,511 @@
@ -1145,7 +1281,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+}
--- /dev/null
+++ b/drivers/mtd/mtk-snand/mtk-snand-mtd.c
@@ -0,0 +1,524 @@
@@ -0,0 +1,535 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
@ -1220,13 +1356,12 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ start_addr += mtd->erasesize;
+ }
+
+ if (ret)
+ instr->state = MTD_ERASE_FAILED;
+ else
+ if (!ret) {
+ instr->state = MTD_ERASE_DONE;
+
+ if (ret)
+ } else {
+ instr->state = MTD_ERASE_FAILED;
+ ret = -EIO;
+ }
+
+ return ret;
+}
@ -1238,8 +1373,8 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ size_t len, ooblen, maxooblen, chklen;
+ uint32_t col, ooboffs;
+ uint8_t *datcache, *oobcache;
+ bool raw = ops->mode == MTD_OPS_RAW ? true : false;
+ int ret;
+ bool ecc_failed = false, raw = ops->mode == MTD_OPS_RAW ? true : false;
+ int ret, max_bitflips = 0;
+
+ col = addr & mtd->writesize_mask;
+ addr &= ~mtd->writesize_mask;
@ -1264,9 +1399,20 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ ret = mtk_snand_read_page(msm->snf, addr, datcache,
+ oobcache, raw);
+
+ if (ret < 0)
+ if (ret < 0 && ret != -EBADMSG)
+ return ret;
+
+ if (ret == -EBADMSG) {
+ mtd->ecc_stats.failed++;
+ ecc_failed = true;
+ } else {
+ mtd->ecc_stats.corrected += ret;
+ max_bitflips = max_t(int, ret, max_bitflips);
+ }
+
+ mtd->ecc_stats.corrected += ret;
+ max_bitflips = max_t(int, ret, max_bitflips);
+
+ if (len) {
+ /* Move data */
+ chklen = mtd->writesize - col;
@ -1296,7 +1442,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ addr += mtd->writesize;
+ }
+
+ return 0;
+ return ecc_failed ? -EBADMSG : max_bitflips;
+}
+
+static int mtk_snand_mtd_read_oob(struct mtd_info *mtd, loff_t from,
@ -1620,7 +1766,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+
+ mtd->ooblayout = &mtk_snand_ooblayout;
+
+ mtd->ecc_strength = msm->cinfo.ecc_strength * msm->cinfo.num_sectors;
+ mtd->ecc_strength = msm->cinfo.ecc_strength;
+ mtd->bitflip_threshold = (mtd->ecc_strength * 3) / 4;
+ mtd->ecc_step_size = msm->cinfo.sector_size;
+
@ -1659,6 +1805,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+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 */ },
+};
@ -1837,7 +1984,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+#endif /* _MTK_SNAND_OS_H_ */
--- /dev/null
+++ b/drivers/mtd/mtk-snand/mtk-snand.c
@@ -0,0 +1,1776 @@
@@ -0,0 +1,1933 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
@ -1897,8 +2044,16 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+#define FIFO_WR_REMAIN_S 8
+#define FIFO_RD_REMAIN_S 0
+
+#define NFI_ADDRCNTR 0x070
+#define SEC_CNTR GENMASK(16, 12)
+#define SEC_CNTR_S 12
+#define NFI_SEC_CNTR(val) (((val) & SEC_CNTR) >> SEC_CNTR_S)
+
+#define NFI_STRADDR 0x080
+
+#define NFI_BYTELEN 0x084
+#define BUS_SEC_CNTR(val) (((val) & SEC_CNTR) >> SEC_CNTR_S)
+
+#define NFI_FDM0L 0x0a0
+#define NFI_FDM0M 0x0a4
+#define NFI_FDML(n) (NFI_FDM0L + (n) * 8)
@ -1915,6 +2070,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+#define NFI_MASTERSTA_MASK_7622 (MAS_ADDR | MAS_RD | MAS_WR | MAS_RDDLY)
+#define AHB_BUS_BUSY BIT(1)
+#define BUS_BUSY BIT(0)
+#define NFI_MASTERSTA_MASK_7981 (AHB_BUS_BUSY | BUS_BUSY)
+#define NFI_MASTERSTA_MASK_7986 (AHB_BUS_BUSY | BUS_BUSY)
+
+/* SNFI registers */
@ -1950,6 +2106,8 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+#define DATA_READ_MODE_X4 2
+#define DATA_READ_MODE_DUAL 5
+#define DATA_READ_MODE_QUAD 6
+#define LATCH_LAT_S 8
+#define LATCH_LAT GENMASK(9, 8)
+#define PG_LOAD_CUSTOM_EN BIT(7)
+#define DATARD_CUSTOM_EN BIT(6)
+#define CS_DESELECT_CYC_S 0
@ -1977,6 +2135,11 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+
+static const uint8_t mt7622_spare_sizes[] = { 16, 26, 27, 28 };
+
+static const uint8_t mt7981_spare_sizes[] = {
+ 16, 26, 27, 28, 32, 36, 40, 44, 48, 49, 50, 51, 52, 62, 61, 63, 64,
+ 67, 74
+};
+
+static const uint8_t mt7986_spare_sizes[] = {
+ 16, 26, 27, 28, 32, 36, 40, 44, 48, 49, 50, 51, 52, 62, 61, 63, 64,
+ 67, 74
@ -1993,7 +2156,9 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ .empty_page_check = false,
+ .mastersta_mask = NFI_MASTERSTA_MASK_7622,
+ .spare_sizes = mt7622_spare_sizes,
+ .num_spare_size = ARRAY_SIZE(mt7622_spare_sizes)
+ .num_spare_size = ARRAY_SIZE(mt7622_spare_sizes),
+ .latch_lat = 0,
+ .sample_delay = 40
+ },
+ [SNAND_SOC_MT7629] = {
+ .sector_size = 512,
@ -2005,7 +2170,23 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ .empty_page_check = false,
+ .mastersta_mask = NFI_MASTERSTA_MASK_7622,
+ .spare_sizes = mt7622_spare_sizes,
+ .num_spare_size = ARRAY_SIZE(mt7622_spare_sizes)
+ .num_spare_size = ARRAY_SIZE(mt7622_spare_sizes),
+ .latch_lat = 0,
+ .sample_delay = 40
+ },
+ [SNAND_SOC_MT7981] = {
+ .sector_size = 1024,
+ .max_sectors = 16,
+ .fdm_size = 8,
+ .fdm_ecc_size = 1,
+ .fifo_size = 64,
+ .bbm_swap = true,
+ .empty_page_check = true,
+ .mastersta_mask = NFI_MASTERSTA_MASK_7981,
+ .spare_sizes = mt7981_spare_sizes,
+ .num_spare_size = ARRAY_SIZE(mt7981_spare_sizes),
+ .latch_lat = 0,
+ .sample_delay = 40
+ },
+ [SNAND_SOC_MT7986] = {
+ .sector_size = 1024,
@ -2017,7 +2198,9 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ .empty_page_check = true,
+ .mastersta_mask = NFI_MASTERSTA_MASK_7986,
+ .spare_sizes = mt7986_spare_sizes,
+ .num_spare_size = ARRAY_SIZE(mt7986_spare_sizes)
+ .num_spare_size = ARRAY_SIZE(mt7986_spare_sizes),
+ .latch_lat = 0,
+ .sample_delay = 40
+ },
+};
+
@ -2189,7 +2372,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ snand_log_snfi(snf->pdev, "Failed to reset SNFI MAC\n");
+
+ nfi_write32(snf, SNF_MISC_CTL, (2 << FIFO_RD_LTC_S) |
+ (10 << CS_DESELECT_CYC_S));
+ (10 << CS_DESELECT_CYC_S) | (snf->nfi_soc->latch_lat << LATCH_LAT_S));
+
+ return ret;
+}
@ -2485,9 +2668,77 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ }
+}
+
+static int mtk_snand_read_ecc_parity(struct mtk_snand *snf, uint32_t page,
+ uint32_t sect, uint8_t *oob)
+{
+ uint32_t ecc_bytes = snf->spare_per_sector - snf->nfi_soc->fdm_size;
+ uint32_t coladdr, raw_offs, offs;
+ uint8_t op[4];
+
+ if (sizeof(op) + ecc_bytes > SNF_GPRAM_SIZE) {
+ snand_log_snfi(snf->pdev,
+ "ECC parity size does not fit the GPRAM\n");
+ return -ENOTSUPP;
+ }
+
+ raw_offs = sect * snf->raw_sector_size + snf->nfi_soc->sector_size +
+ snf->nfi_soc->fdm_size;
+ offs = snf->ecc_steps * snf->nfi_soc->fdm_size + sect * ecc_bytes;
+
+ /* Column address with plane bit */
+ coladdr = raw_offs | mtk_snand_get_plane_address(snf, page);
+
+ op[0] = SNAND_CMD_READ_FROM_CACHE;
+ op[1] = (coladdr >> 8) & 0xff;
+ op[2] = coladdr & 0xff;
+ op[3] = 0;
+
+ return mtk_snand_mac_io(snf, op, sizeof(op), oob + offs, ecc_bytes);
+}
+
+static int mtk_snand_check_ecc_result(struct mtk_snand *snf, uint32_t page)
+{
+ uint8_t *oob = snf->page_cache + snf->writesize;
+ int i, rc, ret = 0, max_bitflips = 0;
+
+ for (i = 0; i < snf->ecc_steps; i++) {
+ if (snf->sect_bf[i] >= 0) {
+ if (snf->sect_bf[i] > max_bitflips)
+ max_bitflips = snf->sect_bf[i];
+ continue;
+ }
+
+ rc = mtk_snand_read_ecc_parity(snf, page, i, oob);
+ if (rc)
+ return rc;
+
+ rc = mtk_ecc_fixup_empty_sector(snf, i);
+ if (rc < 0) {
+ ret = -EBADMSG;
+
+ snand_log_ecc(snf->pdev,
+ "Uncorrectable bitflips in page %u sect %u\n",
+ page, i);
+ } else if (rc) {
+ snf->sect_bf[i] = rc;
+
+ if (snf->sect_bf[i] > max_bitflips)
+ max_bitflips = snf->sect_bf[i];
+
+ snand_log_ecc(snf->pdev,
+ "%u bitflip%s corrected in page %u sect %u\n",
+ rc, rc > 1 ? "s" : "", page, i);
+ } else {
+ snf->sect_bf[i] = 0;
+ }
+ }
+
+ return ret ? ret : max_bitflips;
+}
+
+static int mtk_snand_read_cache(struct mtk_snand *snf, uint32_t page, bool raw)
+{
+ uint32_t coladdr, rwbytes, mode, len;
+ uint32_t coladdr, rwbytes, mode, len, val;
+ uintptr_t dma_addr;
+ int ret;
+
@ -2507,7 +2758,8 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+
+ /* Set read mode */
+ mode = (uint32_t)snf->mode_rfc << DATA_READ_MODE_S;
+ nfi_rmw32(snf, SNF_MISC_CTL, DATA_READ_MODE, mode | DATARD_CUSTOM_EN);
+ nfi_rmw32(snf, SNF_MISC_CTL, DATA_READ_MODE,
+ mode | DATARD_CUSTOM_EN | (snf->nfi_soc->latch_lat << LATCH_LAT_S));
+
+ /* Set bytes to read */
+ rwbytes = snf->ecc_steps * snf->raw_sector_size;
@ -2555,6 +2807,26 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ goto cleanup;
+ }
+
+ /* Wait for BUS_SEC_CNTR returning expected value */
+ ret = read32_poll_timeout(snf->nfi_base + NFI_BYTELEN, val,
+ BUS_SEC_CNTR(val) >= snf->ecc_steps,
+ 0, SNFI_POLL_INTERVAL);
+ if (ret) {
+ snand_log_nfi(snf->pdev,
+ "Timed out waiting for BUS_SEC_CNTR\n");
+ goto cleanup;
+ }
+
+ /* Wait for bus becoming idle */
+ ret = read32_poll_timeout(snf->nfi_base + NFI_MASTERSTA, val,
+ !(val & snf->nfi_soc->mastersta_mask),
+ 0, SNFI_POLL_INTERVAL);
+ if (ret) {
+ snand_log_nfi(snf->pdev,
+ "Timed out waiting for bus becoming idle\n");
+ goto cleanup;
+ }
+
+ if (!raw) {
+ ret = mtk_ecc_wait_decoder_done(snf);
+ if (ret)
@ -2562,17 +2834,10 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+
+ mtk_snand_read_fdm(snf, snf->page_cache + snf->writesize);
+
+ /*
+ * For new IPs, ecc error may occur on empty pages.
+ * Use an specific indication bit to check empty page.
+ */
+ if (snf->nfi_soc->empty_page_check &&
+ (nfi_read32(snf, NFI_STA) & READ_EMPTY))
+ ret = 0;
+ else
+ ret = mtk_ecc_check_decode_error(snf, page);
+
+ mtk_ecc_check_decode_error(snf);
+ mtk_snand_ecc_decoder_stop(snf);
+
+ ret = mtk_snand_check_ecc_result(snf, page);
+ }
+
+cleanup:
@ -2581,6 +2846,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+
+ /* Stop read */
+ nfi_write32(snf, NFI_CON, 0);
+ nfi_write16(snf, NFI_CNFG, 0);
+
+ /* Clear SNF done flag */
+ nfi_rmw32(snf, SNF_STA_CTL1, 0, CUS_READ_DONE);
@ -2590,7 +2856,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ nfi_read32(snf, NFI_INTR_STA);
+ nfi_write32(snf, NFI_INTR_EN, 0);
+
+ nfi_rmw32(snf, SNF_MISC_CTL, DATARD_CUSTOM_EN, 0);
+ nfi_rmw32(snf, SNF_MISC_CTL, DATARD_CUSTOM_EN | LATCH_LAT, 0);
+
+ return ret;
+}
@ -2626,12 +2892,14 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ void *buf, void *oob, bool raw, bool format)
+{
+ uint64_t die_addr;
+ uint32_t page;
+ int ret;
+ uint32_t page, dly_ctrl3;
+ int ret, retry_cnt = 0;
+
+ die_addr = mtk_snand_select_die_address(snf, addr);
+ page = die_addr >> snf->writesize_shift;
+
+ dly_ctrl3 = nfi_read32(snf, SNF_DLY_CTL3);
+
+ ret = mtk_snand_page_op(snf, page, SNAND_CMD_READ_TO_CACHE);
+ if (ret)
+ return ret;
@ -2642,10 +2910,30 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ return ret;
+ }
+
+retry:
+ ret = mtk_snand_read_cache(snf, page, raw);
+ if (ret < 0 && ret != -EBADMSG)
+ return ret;
+
+ if (ret == -EBADMSG && retry_cnt < 16) {
+ nfi_write32(snf, SNF_DLY_CTL3, retry_cnt * 2);
+ retry_cnt++;
+ goto retry;
+ }
+
+ if (retry_cnt) {
+ if(ret == -EBADMSG) {
+ nfi_write32(snf, SNF_DLY_CTL3, dly_ctrl3);
+ snand_log_chip(snf->pdev,
+ "NFI calibration failed. Original sample delay: 0x%x\n",
+ dly_ctrl3);
+ } else {
+ snand_log_chip(snf->pdev,
+ "NFI calibration passed. New sample delay: 0x%x\n",
+ nfi_read32(snf, SNF_DLY_CTL3));
+ }
+ }
+
+ if (raw) {
+ if (format) {
+ mtk_snand_bm_swap_raw(snf);
@ -2719,7 +3007,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+static int mtk_snand_program_load(struct mtk_snand *snf, uint32_t page,
+ bool raw)
+{
+ uint32_t coladdr, rwbytes, mode, len;
+ uint32_t coladdr, rwbytes, mode, len, val;
+ uintptr_t dma_addr;
+ int ret;
+
@ -2789,6 +3077,16 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ goto cleanup;
+ }
+
+ /* Wait for NFI_SEC_CNTR returning expected value */
+ ret = read32_poll_timeout(snf->nfi_base + NFI_ADDRCNTR, val,
+ NFI_SEC_CNTR(val) >= snf->ecc_steps,
+ 0, SNFI_POLL_INTERVAL);
+ if (ret) {
+ snand_log_nfi(snf->pdev,
+ "Timed out waiting for BUS_SEC_CNTR\n");
+ goto cleanup;
+ }
+
+ if (!raw)
+ mtk_snand_ecc_encoder_stop(snf);
+
@ -2797,7 +3095,8 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ dma_mem_unmap(snf->pdev, dma_addr, len, true);
+
+ /* Stop write */
+ nfi_write16(snf, NFI_CON, 0);
+ nfi_write32(snf, NFI_CON, 0);
+ nfi_write16(snf, NFI_CNFG, 0);
+
+ /* Clear SNF done flag */
+ nfi_rmw32(snf, SNF_STA_CTL1, 0, CUS_PG_DONE);
@ -3454,7 +3753,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+
+ /* Tuning options */
+ nfi_write16(snf, NFI_DEBUG_CON1, WBUF_EN);
+ nfi_write32(snf, SNF_DLY_CTL3, (40 << SFCK_SAM_DLY_S));
+ nfi_write32(snf, SNF_DLY_CTL3, (snf->nfi_soc->sample_delay << SFCK_SAM_DLY_S));
+
+ /* Interrupts */
+ nfi_read32(snf, NFI_INTR_STA);
@ -3523,8 +3822,8 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ struct mtk_snand **psnf)
+{
+ const struct snand_flash_info *snand_info;
+ uint32_t rawpage_size, sect_bf_size;
+ struct mtk_snand tmpsnf, *snf;
+ uint32_t rawpage_size;
+ int ret;
+
+ if (!pdata || !psnf)
@ -3565,14 +3864,19 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ rawpage_size = snand_info->memorg.pagesize +
+ snand_info->memorg.sparesize;
+
+ sect_bf_size = mtk_snand_socs[pdata->soc].max_sectors *
+ sizeof(*snf->sect_bf);
+
+ /* Allocate memory for instance and cache */
+ snf = generic_mem_alloc(dev, sizeof(*snf) + rawpage_size);
+ snf = generic_mem_alloc(dev,
+ sizeof(*snf) + rawpage_size + sect_bf_size);
+ if (!snf) {
+ snand_log_chip(dev, "Failed to allocate memory for instance\n");
+ return -ENOMEM;
+ }
+
+ snf->buf_cache = (uint8_t *)((uintptr_t)snf + sizeof(*snf));
+ snf->sect_bf = (int *)((uintptr_t)snf + sizeof(*snf));
+ snf->buf_cache = (uint8_t *)((uintptr_t)snf->sect_bf + sect_bf_size);
+
+ /* Allocate memory for DMA buffer */
+ snf->page_cache = dma_mem_alloc(dev, rawpage_size);
@ -3636,8 +3940,8 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+enum mtk_snand_soc {
+ SNAND_SOC_MT7622,
+ SNAND_SOC_MT7629,
+ SNAND_SOC_MT7981,
+ SNAND_SOC_MT7986,
+
+ __SNAND_SOC_MAX
+};
+

View File

@ -1,7 +1,7 @@
From b7fb0e0674db12bcf53df4b107a17c80758ee5d3 Mon Sep 17 00:00:00 2001
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 05/12] mtd: mtk-snand: add support for SPL
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.
@ -10,8 +10,8 @@ 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 | 132 ++++++++++++++++++++++++++
3 files changed, 142 insertions(+)
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
@ -39,7 +39,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
ccflags-y += -DPRIVATE_MTK_SNAND_HEADER
--- /dev/null
+++ b/drivers/mtd/mtk-snand/mtk-snand-spl.c
@@ -0,0 +1,132 @@
@@ -0,0 +1,133 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
@ -162,6 +162,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+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 */ },
+};

View File

@ -1,7 +1,7 @@
From a26620ec83fa3077f0c261046e82091f7455736f Mon Sep 17 00:00:00 2001
From efc3e6f5d29f87a433b42f15a0b87e04b7cd498d Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Wed, 3 Mar 2021 10:11:32 +0800
Subject: [PATCH 06/12] env: add support for generic MTD device
Subject: [PATCH 38/71] env: add support for generic MTD device
Add an env driver for generic MTD device.

View File

@ -0,0 +1,44 @@
From d26a789c451068caf4bbb4d1ac7bc1f592b5493e Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Mon, 25 Jul 2022 10:58:06 +0800
Subject: [PATCH 39/71] mtd: add a new mtd device type for NMBM
This patch adds a new mtd device type for NMBM so that mtdparts can be
correctly probed. And this also gives us an opportunity to add NMBM support
for filesystems in the future.
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
cmd/mtdparts.c | 3 +++
include/jffs2/load_kernel.h | 4 +++-
2 files changed, 6 insertions(+), 1 deletion(-)
--- a/cmd/mtdparts.c
+++ b/cmd/mtdparts.c
@@ -1060,6 +1060,9 @@ int mtd_id_parse(const char *id, const c
} else if (strncmp(p, "spi-nand", 8) == 0) {
*dev_type = MTD_DEV_TYPE_SPINAND;
p += 8;
+ } else if (strncmp(p, "nmbm", 4) == 0) {
+ *dev_type = MTD_DEV_TYPE_NMBM;
+ p += 4;
} else {
printf("incorrect device type in %s\n", id);
return 1;
--- a/include/jffs2/load_kernel.h
+++ b/include/jffs2/load_kernel.h
@@ -16,11 +16,13 @@
#define MTD_DEV_TYPE_NAND 0x0002
#define MTD_DEV_TYPE_ONENAND 0x0004
#define MTD_DEV_TYPE_SPINAND 0x0008
+#define MTD_DEV_TYPE_NMBM 0x0010
#define MTD_DEV_TYPE(type) (type == MTD_DEV_TYPE_NAND ? "nand" : \
(type == MTD_DEV_TYPE_NOR ? "nor" : \
(type == MTD_DEV_TYPE_ONENAND ? "onenand" : \
- "spi-nand"))) \
+ (type == MTD_DEV_TYPE_SPINAND ? "spi-nand" : \
+ "nmbm")))) \
struct mtd_device {
struct list_head link;

View File

@ -0,0 +1,958 @@
From 0524995f07fcd216a1a7e267fdb5cf2b0ede8489 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Mon, 25 Jul 2022 10:42:12 +0800
Subject: [PATCH 41/71] mtd: nmbm: add support for mtd
Add support to create NMBM based on MTD devices
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
drivers/mtd/nmbm/Kconfig | 5 +
drivers/mtd/nmbm/Makefile | 1 +
drivers/mtd/nmbm/nmbm-mtd.c | 890 ++++++++++++++++++++++++++++++++++++
include/nmbm/nmbm-mtd.h | 27 ++
4 files changed, 923 insertions(+)
create mode 100644 drivers/mtd/nmbm/nmbm-mtd.c
create mode 100644 include/nmbm/nmbm-mtd.h
--- a/drivers/mtd/nmbm/Kconfig
+++ b/drivers/mtd/nmbm/Kconfig
@@ -27,3 +27,8 @@ config NMBM_LOG_LEVEL_NONE
bool "5 - None"
endchoice
+
+config NMBM_MTD
+ bool "Enable MTD based NAND mapping block management"
+ default n
+ depends on NMBM
--- a/drivers/mtd/nmbm/Makefile
+++ b/drivers/mtd/nmbm/Makefile
@@ -3,3 +3,4 @@
# (C) Copyright 2020 MediaTek Inc. All rights reserved.
obj-$(CONFIG_NMBM) += nmbm-core.o
+obj-$(CONFIG_NMBM_MTD) += nmbm-mtd.o
--- /dev/null
+++ b/drivers/mtd/nmbm/nmbm-mtd.c
@@ -0,0 +1,890 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <linux/list.h>
+#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mtd/mtd.h>
+#include <jffs2/load_kernel.h>
+#include <watchdog.h>
+
+#include "nmbm-debug.h"
+
+#define NMBM_UPPER_MTD_NAME "nmbm"
+
+static uint32_t nmbm_id_cnt;
+static LIST_HEAD(nmbm_devs);
+
+struct nmbm_mtd {
+ struct mtd_info upper;
+ char *name;
+ uint32_t id;
+
+ struct mtd_info *lower;
+
+ struct nmbm_instance *ni;
+ uint8_t *page_cache;
+
+ struct list_head node;
+};
+
+static int nmbm_lower_read_page(void *arg, uint64_t addr, void *buf, void *oob,
+ enum nmbm_oob_mode mode)
+{
+ struct nmbm_mtd *nm = arg;
+ struct mtd_oob_ops ops;
+ int ret;
+
+ memset(&ops, 0, sizeof(ops));
+
+ switch (mode) {
+ case NMBM_MODE_PLACE_OOB:
+ ops.mode = MTD_OPS_PLACE_OOB;
+ break;
+ case NMBM_MODE_AUTO_OOB:
+ ops.mode = MTD_OPS_AUTO_OOB;
+ break;
+ case NMBM_MODE_RAW:
+ ops.mode = MTD_OPS_RAW;
+ break;
+ default:
+ pr_debug("%s: unsupported NMBM mode: %u\n", __func__, mode);
+ return -ENOTSUPP;
+ }
+
+ if (buf) {
+ ops.datbuf = buf;
+ ops.len = nm->lower->writesize;
+ }
+
+ if (oob) {
+ ops.oobbuf = oob;
+ ops.ooblen = mtd_oobavail(nm->lower, &ops);
+ }
+
+ ret = mtd_read_oob(nm->lower, addr, &ops);
+ nm->upper.ecc_stats.corrected = nm->lower->ecc_stats.corrected;
+ nm->upper.ecc_stats.failed = nm->lower->ecc_stats.failed;
+
+ /* Report error on failure (including ecc error) */
+ if (ret < 0 && ret != -EUCLEAN)
+ return ret;
+
+ /*
+ * Since mtd_read_oob() won't report exact bitflips, what we can know
+ * is whether bitflips exceeds the threshold.
+ * We want the -EUCLEAN to be passed to the upper layer, but not the
+ * error value itself. To achieve this, report bitflips above the
+ * threshold.
+ */
+
+ if (ret == -EUCLEAN) {
+ return min_t(u32, nm->lower->bitflip_threshold + 1,
+ nm->lower->ecc_strength);
+ }
+
+ /* For bitflips less than the threshold, return 0 */
+
+ return 0;
+}
+
+static int nmbm_lower_write_page(void *arg, uint64_t addr, const void *buf,
+ const void *oob, enum nmbm_oob_mode mode)
+{
+ struct nmbm_mtd *nm = arg;
+ struct mtd_oob_ops ops;
+
+ memset(&ops, 0, sizeof(ops));
+
+ switch (mode) {
+ case NMBM_MODE_PLACE_OOB:
+ ops.mode = MTD_OPS_PLACE_OOB;
+ break;
+ case NMBM_MODE_AUTO_OOB:
+ ops.mode = MTD_OPS_AUTO_OOB;
+ break;
+ case NMBM_MODE_RAW:
+ ops.mode = MTD_OPS_RAW;
+ break;
+ default:
+ pr_debug("%s: unsupported NMBM mode: %u\n", __func__, mode);
+ return -ENOTSUPP;
+ }
+
+ if (buf) {
+ ops.datbuf = (uint8_t *)buf;
+ ops.len = nm->lower->writesize;
+ }
+
+ if (oob) {
+ ops.oobbuf = (uint8_t *)oob;
+ ops.ooblen = mtd_oobavail(nm->lower, &ops);
+ }
+
+ return mtd_write_oob(nm->lower, addr, &ops);
+}
+
+static int nmbm_lower_erase_block(void *arg, uint64_t addr)
+{
+ struct nmbm_mtd *nm = arg;
+ struct erase_info ei;
+
+ memset(&ei, 0, sizeof(ei));
+
+ ei.mtd = nm->lower;
+ ei.addr = addr;
+ ei.len = nm->lower->erasesize;
+
+ return mtd_erase(nm->lower, &ei);
+}
+
+static int nmbm_lower_is_bad_block(void *arg, uint64_t addr)
+{
+ struct nmbm_mtd *nm = arg;
+
+ return mtd_block_isbad(nm->lower, addr);
+}
+
+static int nmbm_lower_mark_bad_block(void *arg, uint64_t addr)
+{
+ struct nmbm_mtd *nm = arg;
+
+ return mtd_block_markbad(nm->lower, 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_mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct nmbm_mtd *nm = container_of(mtd, struct nmbm_mtd, upper);
+
+ /* Do not allow read past end of device */
+ if ((from + len) > mtd->size) {
+ pr_debug("%s: attempt to write beyond end of device\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return nmbm_read_range(nm->ni, from, len, buf, MTD_OPS_PLACE_OOB,
+ retlen);
+}
+
+static int nmbm_mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
+ size_t *retlen, const u_char *buf)
+{
+ struct nmbm_mtd *nm = container_of(mtd, struct nmbm_mtd, upper);
+
+ /* Do not allow write past end of device */
+ if ((to + len) > mtd->size) {
+ pr_debug("%s: attempt to write beyond end of device\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return nmbm_write_range(nm->ni, to, len, buf, MTD_OPS_PLACE_OOB,
+ retlen);
+}
+
+static int nmbm_mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+ struct nmbm_mtd *nm = container_of(mtd, struct nmbm_mtd, upper);
+ int ret;
+
+ instr->state = MTD_ERASING;
+
+ ret = nmbm_erase_block_range(nm->ni, instr->addr, instr->len,
+ &instr->fail_addr);
+ if (ret)
+ instr->state = MTD_ERASE_FAILED;
+ else
+ instr->state = MTD_ERASE_DONE;
+
+ if (!ret)
+ /* FIXME */
+ /* mtd_erase_callback(instr); */
+ return ret;
+ else
+ ret = -EIO;
+
+ return ret;
+}
+
+static int nmbm_mtd_read_data(struct nmbm_mtd *nm, uint64_t addr,
+ struct mtd_oob_ops *ops, enum nmbm_oob_mode mode)
+{
+ size_t len, ooblen, maxooblen, chklen;
+ uint32_t col, ooboffs;
+ uint8_t *datcache, *oobcache;
+ bool has_ecc_err = false;
+ int ret, max_bitflips = 0;
+
+ col = addr & nm->lower->writesize_mask;
+ addr &= ~nm->lower->writesize_mask;
+ maxooblen = mtd_oobavail(nm->lower, ops);
+ ooboffs = ops->ooboffs;
+ ooblen = ops->ooblen;
+ len = ops->len;
+
+ datcache = len ? nm->page_cache : NULL;
+ oobcache = ooblen ? nm->page_cache + nm->lower->writesize : NULL;
+
+ ops->oobretlen = 0;
+ ops->retlen = 0;
+
+ while (len || ooblen) {
+ WATCHDOG_RESET();
+
+ ret = nmbm_read_single_page(nm->ni, addr, datcache, oobcache,
+ mode);
+ if (ret < 0 && ret != -EBADMSG)
+ return ret;
+
+ /* Continue reading on ecc error */
+ if (ret == -EBADMSG)
+ has_ecc_err = true;
+
+ /* Record the maximum bitflips between pages */
+ if (ret > max_bitflips)
+ max_bitflips = ret;
+
+ if (len) {
+ /* Move data */
+ chklen = nm->lower->writesize - col;
+ if (chklen > len)
+ chklen = len;
+
+ memcpy(ops->datbuf + ops->retlen, datcache + col,
+ chklen);
+ len -= chklen;
+ col = 0; /* (col + chklen) % */
+ ops->retlen += chklen;
+ }
+
+ if (ooblen) {
+ /* Move oob */
+ chklen = maxooblen - ooboffs;
+ if (chklen > ooblen)
+ chklen = ooblen;
+
+ memcpy(ops->oobbuf + ops->oobretlen, oobcache + ooboffs,
+ chklen);
+ ooblen -= chklen;
+ ooboffs = 0; /* (ooboffs + chklen) % maxooblen; */
+ ops->oobretlen += chklen;
+ }
+
+ addr += nm->lower->writesize;
+ }
+
+ if (has_ecc_err)
+ return -EBADMSG;
+
+ return max_bitflips;
+}
+
+static int nmbm_mtd_read_oob(struct mtd_info *mtd, loff_t from,
+ struct mtd_oob_ops *ops)
+{
+ struct nmbm_mtd *nm = container_of(mtd, struct nmbm_mtd, upper);
+ uint32_t maxooblen;
+ enum nmbm_oob_mode mode;
+
+ if (!ops->oobbuf && !ops->datbuf) {
+ if (ops->ooblen || ops->len)
+ return -EINVAL;
+
+ return 0;
+ }
+
+ switch (ops->mode) {
+ case MTD_OPS_PLACE_OOB:
+ mode = NMBM_MODE_PLACE_OOB;
+ break;
+ case MTD_OPS_AUTO_OOB:
+ mode = NMBM_MODE_AUTO_OOB;
+ break;
+ case MTD_OPS_RAW:
+ mode = NMBM_MODE_RAW;
+ break;
+ default:
+ pr_debug("%s: unsupported oob mode: %u\n", __func__, ops->mode);
+ return -ENOTSUPP;
+ }
+
+ maxooblen = mtd_oobavail(mtd, ops);
+
+ /* Do not allow read past end of device */
+ if (ops->datbuf && (from + ops->len) > mtd->size) {
+ pr_debug("%s: attempt to read beyond end of device\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (!ops->oobbuf) {
+ /* Optimized for reading data only */
+ return nmbm_read_range(nm->ni, from, ops->len, ops->datbuf,
+ mode, &ops->retlen);
+ }
+
+ if (unlikely(ops->ooboffs >= maxooblen)) {
+ pr_debug("%s: attempt to start read outside oob\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(from >= mtd->size ||
+ ops->ooboffs + ops->ooblen > ((mtd->size >> mtd->writesize_shift) -
+ (from >> mtd->writesize_shift)) * maxooblen)) {
+ pr_debug("%s: attempt to read beyond end of device\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return nmbm_mtd_read_data(nm, from, ops, mode);
+}
+
+static int nmbm_mtd_write_data(struct nmbm_mtd *nm, uint64_t addr,
+ struct mtd_oob_ops *ops, enum nmbm_oob_mode mode)
+{
+ size_t len, ooblen, maxooblen, chklen;
+ uint32_t col, ooboffs;
+ uint8_t *datcache, *oobcache;
+ int ret;
+
+ col = addr & nm->lower->writesize_mask;
+ addr &= ~nm->lower->writesize_mask;
+ maxooblen = mtd_oobavail(nm->lower, ops);
+ ooboffs = ops->ooboffs;
+ ooblen = ops->ooblen;
+ len = ops->len;
+
+ datcache = len ? nm->page_cache : NULL;
+ oobcache = ooblen ? nm->page_cache + nm->lower->writesize : NULL;
+
+ ops->oobretlen = 0;
+ ops->retlen = 0;
+
+ while (len || ooblen) {
+ WATCHDOG_RESET();
+
+ if (len) {
+ /* Move data */
+ chklen = nm->lower->writesize - col;
+ if (chklen > len)
+ chklen = len;
+
+ memset(datcache, 0xff, col);
+ memcpy(datcache + col, ops->datbuf + ops->retlen,
+ chklen);
+ memset(datcache + col + chklen, 0xff,
+ nm->lower->writesize - col - chklen);
+ len -= chklen;
+ col = 0; /* (col + chklen) % */
+ ops->retlen += chklen;
+ }
+
+ if (ooblen) {
+ /* Move oob */
+ chklen = maxooblen - ooboffs;
+ if (chklen > ooblen)
+ chklen = ooblen;
+
+ memset(oobcache, 0xff, ooboffs);
+ memcpy(oobcache + ooboffs,
+ ops->oobbuf + ops->oobretlen, chklen);
+ memset(oobcache + ooboffs + chklen, 0xff,
+ nm->lower->oobsize - ooboffs - chklen);
+ ooblen -= chklen;
+ ooboffs = 0; /* (ooboffs + chklen) % maxooblen; */
+ ops->oobretlen += chklen;
+ }
+
+ ret = nmbm_write_single_page(nm->ni, addr, datcache, oobcache,
+ mode);
+ if (ret)
+ return ret;
+
+ addr += nm->lower->writesize;
+ }
+
+ return 0;
+}
+
+static int nmbm_mtd_write_oob(struct mtd_info *mtd, loff_t to,
+ struct mtd_oob_ops *ops)
+{
+ struct nmbm_mtd *nm = container_of(mtd, struct nmbm_mtd, upper);
+ enum nmbm_oob_mode mode;
+ uint32_t maxooblen;
+
+ if (!ops->oobbuf && !ops->datbuf) {
+ if (ops->ooblen || ops->len)
+ return -EINVAL;
+
+ return 0;
+ }
+
+ switch (ops->mode) {
+ case MTD_OPS_PLACE_OOB:
+ mode = NMBM_MODE_PLACE_OOB;
+ break;
+ case MTD_OPS_AUTO_OOB:
+ mode = NMBM_MODE_AUTO_OOB;
+ break;
+ case MTD_OPS_RAW:
+ mode = NMBM_MODE_RAW;
+ break;
+ default:
+ pr_debug("%s: unsupported oob mode: %u\n", __func__,
+ ops->mode);
+ return -ENOTSUPP;
+ }
+
+ maxooblen = mtd_oobavail(mtd, ops);
+
+ /* Do not allow write past end of device */
+ if (ops->datbuf && (to + ops->len) > mtd->size) {
+ pr_debug("%s: attempt to write beyond end of device\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (!ops->oobbuf) {
+ /* Optimized for writing data only */
+ return nmbm_write_range(nm->ni, to, ops->len, ops->datbuf,
+ mode, &ops->retlen);
+ }
+
+ if (unlikely(ops->ooboffs >= maxooblen)) {
+ pr_debug("%s: attempt to start write outside oob\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (unlikely(to >= mtd->size ||
+ ops->ooboffs + ops->ooblen > ((mtd->size >> mtd->writesize_shift) -
+ (to >> mtd->writesize_shift)) * maxooblen)) {
+ pr_debug("%s: attempt to write beyond end of device\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ return nmbm_mtd_write_data(nm, to, ops, mode);
+}
+
+static int nmbm_mtd_block_isbad(struct mtd_info *mtd, loff_t offs)
+{
+ struct nmbm_mtd *nm = container_of(mtd, struct nmbm_mtd, upper);
+
+ return nmbm_check_bad_block(nm->ni, offs);
+}
+
+static int nmbm_mtd_block_markbad(struct mtd_info *mtd, loff_t offs)
+{
+ struct nmbm_mtd *nm = container_of(mtd, struct nmbm_mtd, upper);
+
+ return nmbm_mark_bad_block(nm->ni, offs);
+}
+
+int nmbm_attach_mtd(struct mtd_info *lower, int flags, uint32_t max_ratio,
+ uint32_t max_reserved_blocks, struct mtd_info **upper)
+{
+ struct nmbm_lower_device nld;
+ struct nmbm_instance *ni;
+ struct mtd_info *mtd;
+ struct nmbm_mtd *nm;
+ size_t namelen, alloc_size;
+ int ret;
+
+ if (!lower)
+ return -EINVAL;
+
+ if (lower->type != MTD_NANDFLASH || lower->flags != MTD_CAP_NANDFLASH)
+ return -ENOTSUPP;
+
+ namelen = strlen(NMBM_UPPER_MTD_NAME) + 16;
+
+ nm = calloc(sizeof(*nm) + lower->writesize + lower->oobsize + namelen + 1, 1);
+ if (!nm)
+ return -ENOMEM;
+
+ nm->lower = lower;
+ nm->name = (char *)nm + sizeof(*nm);
+ nm->page_cache = (uint8_t *)nm->name + namelen + 1;
+
+ nm->id = nmbm_id_cnt++;
+ snprintf(nm->name, namelen + 1, "%s%u", NMBM_UPPER_MTD_NAME, nm->id);
+
+ memset(&nld, 0, sizeof(nld));
+
+ nld.flags = flags;
+ nld.max_ratio = max_ratio;
+ nld.max_reserved_blocks = max_reserved_blocks;
+
+ nld.size = lower->size;
+ nld.erasesize = lower->erasesize;
+ nld.writesize = lower->writesize;
+ nld.oobsize = lower->oobsize;
+ nld.oobavail = lower->oobavail;
+
+ nld.arg = nm;
+ 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;
+
+ alloc_size = nmbm_calc_structure_size(&nld);
+ ni = calloc(alloc_size, 1);
+ if (!ni) {
+ free(nm);
+ return -ENOMEM;
+ }
+
+ ret = nmbm_attach(&nld, ni);
+ if (ret) {
+ free(ni);
+ free(nm);
+ return ret;
+ }
+
+ nm->ni = ni;
+
+ /* Initialize upper mtd */
+ mtd = &nm->upper;
+
+ mtd->name = nm->name;
+ mtd->type = MTD_DEV_TYPE_NMBM;
+ mtd->flags = lower->flags;
+
+ mtd->size = (uint64_t)ni->data_block_count * ni->lower.erasesize;
+ mtd->erasesize = lower->erasesize;
+ mtd->writesize = lower->writesize;
+ mtd->writebufsize = lower->writesize;
+ mtd->oobsize = lower->oobsize;
+ mtd->oobavail = lower->oobavail;
+
+ mtd->erasesize_shift = lower->erasesize_shift;
+ mtd->writesize_shift = lower->writesize_shift;
+ mtd->erasesize_mask = lower->erasesize_mask;
+ mtd->writesize_mask = lower->writesize_mask;
+
+ mtd->bitflip_threshold = lower->bitflip_threshold;
+
+ /* XXX: should this be duplicated? */
+ mtd->ooblayout = lower->ooblayout;
+ mtd->ecclayout = lower->ecclayout;
+
+ mtd->ecc_step_size = lower->ecc_step_size;
+ mtd->ecc_strength = lower->ecc_strength;
+
+ mtd->numeraseregions = lower->numeraseregions;
+ mtd->eraseregions = lower->eraseregions;
+
+ mtd->_read = nmbm_mtd_read;
+ mtd->_write = nmbm_mtd_write;
+ mtd->_erase = nmbm_mtd_erase;
+ mtd->_read_oob = nmbm_mtd_read_oob;
+ mtd->_write_oob = nmbm_mtd_write_oob;
+ mtd->_block_isbad = nmbm_mtd_block_isbad;
+ mtd->_block_markbad = nmbm_mtd_block_markbad;
+
+ *upper = mtd;
+
+ list_add_tail(&nm->node, &nmbm_devs);
+
+ return 0;
+}
+
+int nmbm_free_mtd(struct mtd_info *upper)
+{
+ struct nmbm_mtd *pos;
+
+ if (!upper)
+ return -EINVAL;
+
+ list_for_each_entry(pos, &nmbm_devs, node) {
+ if (&pos->upper == upper) {
+ list_del(&pos->node);
+
+ nmbm_detach(pos->ni);
+ free(pos->ni);
+ free(pos);
+
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
+struct mtd_info *nmbm_mtd_get_upper_by_index(uint32_t index)
+{
+ struct nmbm_mtd *nm;
+
+ list_for_each_entry(nm, &nmbm_devs, node) {
+ if (nm->id == index)
+ return &nm->upper;
+ }
+
+ return NULL;
+}
+
+struct mtd_info *nmbm_mtd_get_upper(struct mtd_info *lower)
+{
+ struct nmbm_mtd *nm;
+
+ list_for_each_entry(nm, &nmbm_devs, node) {
+ if (nm->lower == lower)
+ return &nm->upper;
+ }
+
+ return NULL;
+}
+
+void nmbm_mtd_list_devices(void)
+{
+ struct nmbm_mtd *nm;
+
+ printf("Index NMBM device Lower device\n");
+ printf("========================================\n");
+
+ list_for_each_entry(nm, &nmbm_devs, node) {
+ printf("%-8u%-20s%s\n", nm->id, nm->name, nm->lower->name);
+ }
+}
+
+int nmbm_mtd_print_info(const char *name)
+{
+ struct nmbm_mtd *nm;
+ bool found = false;
+
+ list_for_each_entry(nm, &nmbm_devs, node) {
+ if (!strcmp(nm->name, name)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ printf("Error: NMBM device '%s' not found\n", name);
+ return -ENODEV;
+ }
+
+ printf("%s:\n", name);
+ printf("Total blocks: %u\n", nm->ni->block_count);
+ printf("Data blocks: %u\n", nm->ni->data_block_count);
+ printf("Management start block: %u\n", nm->ni->mgmt_start_ba);
+ printf("Info table size: 0x%x\n", nm->ni->info_table_size);
+
+ if (nm->ni->main_table_ba)
+ printf("Main info table start block: %u\n", nm->ni->main_table_ba);
+ else
+ printf("Main info table start block: Not exist\n");
+
+ if (nm->ni->backup_table_ba)
+ printf("Backup info table start block: %u\n", nm->ni->backup_table_ba);
+ else
+ printf("Backup info table start block: Not exist\n");
+
+ printf("Signature block: %u\n", nm->ni->signature_ba);
+ printf("Mapping blocks top address: %u\n", nm->ni->mapping_blocks_top_ba);
+ printf("Mapping blocks limit address: %u\n", nm->ni->mapping_blocks_ba);
+
+ return 0;
+}
+
+static const char nmbm_block_legends[] = {
+ [NMBM_BLOCK_GOOD_DATA] = '-',
+ [NMBM_BLOCK_GOOD_MGMT] = '+',
+ [NMBM_BLOCK_BAD] = 'B',
+ [NMBM_BLOCK_MAIN_INFO_TABLE] = 'I',
+ [NMBM_BLOCK_BACKUP_INFO_TABLE] = 'i',
+ [NMBM_BLOCK_REMAPPED] = 'M',
+ [NMBM_BLOCK_SIGNATURE] = 'S',
+};
+
+int nmbm_mtd_print_states(const char *name)
+{
+ struct nmbm_mtd *nm;
+ enum nmmb_block_type bt;
+ bool found = false;
+ uint32_t i;
+
+ list_for_each_entry(nm, &nmbm_devs, node) {
+ if (!strcmp(nm->name, name)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ printf("Error: NMBM device '%s' not found\n", name);
+ return -ENODEV;
+ }
+
+ printf("Physical blocks:\n");
+ printf("\n");
+
+ printf("Legends:\n");
+ printf(" - Good data block\n");
+ printf(" + Good management block\n");
+ printf(" B Bad block\n");
+ printf(" I Main info table\n");
+ printf(" i Backup info table\n");
+ printf(" M Remapped spare block\n");
+ printf(" S Signature block\n");
+ printf("\n");
+
+ for (i = 0; i < nm->ni->block_count; i++) {
+ if (i % 64 == 0)
+ printf(" ");
+
+ bt = nmbm_debug_get_phys_block_type(nm->ni, i);
+ if (bt < __NMBM_BLOCK_TYPE_MAX)
+ putc(nmbm_block_legends[bt]);
+ else
+ putc('?');
+
+ if (i % 64 == 63)
+ printf("\n");
+ }
+
+ printf("\n");
+ printf("Logical blocks:\n");
+ printf("\n");
+
+ printf("Legends:\n");
+ printf(" - Good block\n");
+ printf(" + Initially remapped block\n");
+ printf(" M Remapped block\n");
+ printf(" B Bad/Unmapped block\n");
+ printf("\n");
+
+ for (i = 0; i < nm->ni->data_block_count; i++) {
+ if (i % 64 == 0)
+ printf(" ");
+
+ if (nm->ni->block_mapping[i] < 0)
+ putc('B');
+ else if (nm->ni->block_mapping[i] == i)
+ putc('-');
+ else if (nm->ni->block_mapping[i] < nm->ni->data_block_count)
+ putc('+');
+ else if (nm->ni->block_mapping[i] > nm->ni->mapping_blocks_top_ba &&
+ nm->ni->block_mapping[i] < nm->ni->signature_ba)
+ putc('M');
+ else
+ putc('?');
+
+ if (i % 64 == 63)
+ printf("\n");
+ }
+
+ return 0;
+}
+
+int nmbm_mtd_print_bad_blocks(const char *name)
+{
+ struct nmbm_mtd *nm;
+ bool found = false;
+ uint32_t i;
+
+ list_for_each_entry(nm, &nmbm_devs, node) {
+ if (!strcmp(nm->name, name)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ printf("Error: NMBM device '%s' not found\n", name);
+ return -ENODEV;
+ }
+
+ printf("Physical blocks:\n");
+
+ for (i = 0; i < nm->ni->block_count; i++) {
+ switch (nmbm_debug_get_block_state(nm->ni, i)) {
+ case BLOCK_ST_BAD:
+ printf("%-12u [0x%08llx] - Bad\n", i,
+ (uint64_t)i << nm->ni->erasesize_shift);
+ break;
+ case BLOCK_ST_NEED_REMAP:
+ printf("%-12u [0x%08llx] - Awaiting remapping\n", i,
+ (uint64_t)i << nm->ni->erasesize_shift);
+ break;
+ }
+ }
+
+ printf("\n");
+ printf("Logical blocks:\n");
+
+ for (i = 0; i < nm->ni->data_block_count; i++) {
+ if (nm->ni->block_mapping[i] < 0) {
+ printf("%-12u [0x%08llx] - Bad\n", i,
+ (uint64_t)i << nm->ni->erasesize_shift);
+ }
+ }
+
+ return 0;
+}
+
+int nmbm_mtd_print_mappings(const char *name, int printall)
+{
+ struct nmbm_mtd *nm;
+ bool found = false;
+ int32_t pb;
+ uint32_t i;
+
+ list_for_each_entry(nm, &nmbm_devs, node) {
+ if (!strcmp(nm->name, name)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ printf("Error: NMBM device '%s' not found\n", name);
+ return -ENODEV;
+ }
+
+ printf("Logical Block Physical Block\n");
+ printf("==================================\n");
+
+ if (!printall) {
+ for (i = 0; i < nm->ni->data_block_count; i++) {
+ pb = nm->ni->block_mapping[i];
+ if (pb < 0)
+ printf("%-20uUnmapped\n", i);
+ else if ((uint32_t)pb > nm->ni->mapping_blocks_top_ba &&
+ (uint32_t)pb < nm->ni->signature_ba)
+ printf("%-20u%u\n", i, pb);
+ }
+
+ return 0;
+ }
+
+ for (i = 0; i < nm->ni->data_block_count; i++) {
+ pb = nm->ni->block_mapping[i];
+
+ if (pb >= 0)
+ printf("%-20u%u\n", i, pb);
+ else
+ printf("%-20uUnmapped\n", i);
+ }
+
+ return 0;
+}
--- /dev/null
+++ b/include/nmbm/nmbm-mtd.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _NMBM_MTD_H_
+#define _NMBM_MTD_H_
+
+#include <linux/mtd/mtd.h>
+
+int nmbm_attach_mtd(struct mtd_info *lower, int flags, uint32_t max_ratio,
+ uint32_t max_reserved_blocks, struct mtd_info **upper);
+
+int nmbm_free_mtd(struct mtd_info *upper);
+
+struct mtd_info *nmbm_mtd_get_upper_by_index(uint32_t index);
+struct mtd_info *nmbm_mtd_get_upper(struct mtd_info *lower);
+
+void nmbm_mtd_list_devices(void);
+int nmbm_mtd_print_info(const char *name);
+int nmbm_mtd_print_states(const char *name);
+int nmbm_mtd_print_bad_blocks(const char *name);
+int nmbm_mtd_print_mappings(const char *name, int printall);
+
+#endif /* _NMBM_MTD_H_ */

View File

@ -0,0 +1,46 @@
From dcf24c8deeb43a4406ae18136c8700dc2f867415 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Mon, 25 Jul 2022 11:18:03 +0800
Subject: [PATCH 42/71] common: board_r: add support to initialize NMBM after
nand initialization
This patch add support to initialize NMBM after nand initialized.
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
common/board_r.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -382,6 +382,20 @@ static int initr_nand(void)
}
#endif
+#ifdef CONFIG_NMBM_MTD
+
+__weak int board_nmbm_init(void)
+{
+ return 0;
+}
+
+/* go init the NMBM */
+static int initr_nmbm(void)
+{
+ return board_nmbm_init();
+}
+#endif
+
#if defined(CONFIG_CMD_ONENAND)
/* go init the NAND */
static int initr_onenand(void)
@@ -703,6 +717,9 @@ static init_fnc_t init_sequence_r[] = {
#ifdef CONFIG_CMD_ONENAND
initr_onenand,
#endif
+#ifdef CONFIG_NMBM_MTD
+ initr_nmbm,
+#endif
#ifdef CONFIG_MMC
initr_mmc,
#endif

View File

@ -0,0 +1,370 @@
From 0af8d0aac77f4df4bc7dadbcdea5d9a16f5f3e45 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Mon, 25 Jul 2022 10:44:57 +0800
Subject: [PATCH 43/71] cmd: add nmbm command
Add nmbm command for debugging, data operations and image-booting support
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
cmd/Kconfig | 6 +
cmd/Makefile | 1 +
cmd/nmbm.c | 327 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 334 insertions(+)
create mode 100644 cmd/nmbm.c
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -1260,6 +1260,12 @@ config CMD_NAND_TORTURE
endif # CMD_NAND
+config CMD_NMBM
+ depends on NMBM_MTD
+ bool "nmbm"
+ help
+ NAND mapping block management (NMBM) utility
+
config CMD_NVME
bool "nvme"
depends on NVME
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -114,6 +114,7 @@ obj-y += legacy-mtd-utils.o
endif
obj-$(CONFIG_CMD_MUX) += mux.o
obj-$(CONFIG_CMD_NAND) += nand.o
+obj-$(CONFIG_CMD_NMBM) += nmbm.o
obj-$(CONFIG_CMD_NET) += net.o
obj-$(CONFIG_CMD_NVEDIT_EFI) += nvedit_efi.o
obj-$(CONFIG_CMD_ONENAND) += onenand.o
--- /dev/null
+++ b/cmd/nmbm.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <command.h>
+#include <image.h>
+#include <stdbool.h>
+#include <linux/types.h>
+#include <linux/mtd/mtd.h>
+#include <jffs2/load_kernel.h>
+
+#include <nmbm/nmbm-mtd.h>
+
+static int nmbm_parse_offset_size(struct mtd_info *mtd, char *off_str,
+ char *size_str, uint64_t *off,
+ uint64_t *size)
+{
+ char *end;
+
+ *off = simple_strtoull(off_str, &end, 16);
+ if (end == off_str) {
+ printf("Error: offset '%s' is invalid\n", off_str);
+ return -EINVAL;
+ }
+
+ if (*off >= mtd->size) {
+ printf("Error: offset '0x%llx' is beyond the end of device\n",
+ *off);
+ return -EINVAL;
+ }
+
+ *size = simple_strtoull(size_str, &end, 16);
+ if (end == off_str) {
+ printf("Error: size '%s' is invalid\n", off_str);
+ return -EINVAL;
+ }
+
+ if (*off + *size > mtd->size) {
+ printf("Error: size '0x%llx' is too large\n", *size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int do_nmbm_erase(struct mtd_info *mtd, uint64_t offset, uint64_t size)
+{
+ struct erase_info ei;
+ int ret;
+
+ memset(&ei, 0, sizeof(ei));
+
+ ei.mtd = mtd;
+ ei.addr = offset;
+ ei.len = size;
+
+ printf("Erasing from 0x%llx, size 0x%llx ...\n", offset, size);
+
+ ret = mtd_erase(mtd, &ei);
+
+ if (!ret) {
+ printf("Succeeded\n");
+ return CMD_RET_SUCCESS;
+ }
+
+ printf("Failed at 0x%llx\n", ei.fail_addr);
+
+ return CMD_RET_FAILURE;
+}
+
+static int do_nmbm_rw(int read, struct mtd_info *mtd, uintptr_t addr,
+ uint64_t offset, size_t size)
+{
+ size_t retlen;
+ int ret;
+
+ printf("%s 0x%llx, size 0x%zx\n", read ? "Reading from" : "Writing to",
+ offset, size);
+
+ if (read)
+ ret = mtd_read(mtd, offset, size, &retlen, (void *)addr);
+ else
+ ret = mtd_write(mtd, offset, size, &retlen, (void *)addr);
+
+ if (!ret) {
+ printf("Succeeded\n");
+ return CMD_RET_SUCCESS;
+ }
+
+ printf("Failed at 0x%llx\n", offset + retlen);
+
+ return CMD_RET_FAILURE;
+}
+
+static int do_nmbm_mtd_boot(struct cmd_tbl *cmdtp, struct mtd_info *mtd,
+ int argc, char *const argv[])
+{
+ bool print_image_contents = true;
+ uintptr_t loadaddr = image_load_addr;
+ char *end, *image_name;
+ const char *ep;
+ size_t retlen;
+ uint32_t size;
+ uint64_t off;
+ int ret;
+
+#if defined(CONFIG_CMD_MTDPARTS)
+ struct mtd_device *partdev;
+ struct mtd_info *partmtd;
+ struct part_info *part;
+ u8 pnum;
+#endif
+
+ ep = env_get("autostart");
+
+ if (ep && !strcmp(ep, "yes"))
+ print_image_contents = false;
+
+ if (argc == 2) {
+ loadaddr = simple_strtoul(argv[0], &end, 0);
+ if (*end || end == argv[0]) {
+ printf("'%s' is not a valid address\n", argv[0]);
+ return CMD_RET_FAILURE;
+ }
+
+ argc--;
+ argv++;
+ }
+
+ off = simple_strtoull(argv[0], &end, 0);
+ if (*end || end == argv[0]) {
+#if defined(CONFIG_CMD_MTDPARTS)
+ ret = mtdparts_init();
+ if (ret)
+ return CMD_RET_FAILURE;
+
+ ret = find_dev_and_part(argv[0], &partdev, &pnum, &part);
+ if (ret)
+ return CMD_RET_FAILURE;
+
+ if (partdev->id->type != MTD_DEV_TYPE_NMBM) {
+ printf("'%s' is not a NMBM device partition\n",
+ argv[0]);
+ return CMD_RET_FAILURE;
+ }
+
+ partmtd = nmbm_mtd_get_upper_by_index(partdev->id->num);
+
+ if (partmtd != mtd) {
+ printf("'%s' does not belong to this device\n",
+ argv[0]);
+ return CMD_RET_FAILURE;
+ }
+
+ off = part->offset;
+#else
+ printf("'%s' is not a valid offset\n", argv[0]);
+ return CMD_RET_FAILURE;
+#endif
+ }
+
+ ret = mtd_read(mtd, off, sizeof(image_header_t), &retlen,
+ (void *)loadaddr);
+ if (ret || retlen != sizeof(image_header_t)) {
+ printf("Failed to read NMBM at offset 0x%08llx\n", off);
+ return CMD_RET_FAILURE;
+ }
+
+ switch (genimg_get_format((void *)loadaddr)) {
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
+ case IMAGE_FORMAT_LEGACY:
+ size = image_get_image_size((image_header_t *)loadaddr);
+ image_name = "legacy";
+ break;
+#endif
+#if defined(CONFIG_FIT)
+ case IMAGE_FORMAT_FIT:
+ size = fit_get_size((const void *)loadaddr);
+ image_name = "FIT";
+ break;
+#endif
+ default:
+ printf("Error: no Image found at offset 0x%08llx\n", off);
+ return CMD_RET_FAILURE;
+ }
+
+ printf("Loading %s image at offset 0x%llx to memory 0x%08lx, size 0x%x ...\n",
+ image_name, off, loadaddr, size);
+
+ ret = mtd_read(mtd, off, size, &retlen, (void *)loadaddr);
+ if (ret || retlen != size) {
+ printf("Error: Failed to load image at offset 0x%08llx\n",
+ off + retlen);
+ return CMD_RET_FAILURE;
+ }
+
+ switch (genimg_get_format((void *)loadaddr)) {
+#if defined(CONFIG_LEGACY_IMAGE_FORMAT)
+ case IMAGE_FORMAT_LEGACY:
+ if (print_image_contents)
+ image_print_contents((void *)loadaddr);
+ break;
+#endif
+#if defined(CONFIG_FIT)
+ case IMAGE_FORMAT_FIT:
+ if (print_image_contents)
+ fit_print_contents((void *)loadaddr);
+ break;
+#endif
+ }
+
+ image_load_addr = loadaddr;
+
+ return bootm_maybe_autostart(cmdtp, "nmbm");
+}
+
+static int do_nmbm(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct mtd_info *mtd;
+ uint64_t offset, size;
+ char *end;
+ uintptr_t addr;
+ int ret, all = 0;
+
+ if (argc == 1)
+ return CMD_RET_USAGE;
+
+ if (!strcmp(argv[1], "list")) {
+ nmbm_mtd_list_devices();
+ return CMD_RET_SUCCESS;
+ }
+
+ if (argc < 3)
+ return CMD_RET_USAGE;
+
+ if (!strcmp(argv[2], "info"))
+ return !!nmbm_mtd_print_info(argv[1]);
+
+ if (!strcmp(argv[2], "state"))
+ return !!nmbm_mtd_print_states(argv[1]);
+
+ if (!strcmp(argv[2], "bad"))
+ return !!nmbm_mtd_print_bad_blocks(argv[1]);
+
+ if (!strcmp(argv[2], "mapping")) {
+ if (argc >= 4) {
+ if (!strcmp(argv[3], "all"))
+ all = 1;
+ }
+
+ return nmbm_mtd_print_mappings(argv[1], all);
+ }
+
+ if (argc < 4)
+ return CMD_RET_USAGE;
+
+ mtd = get_mtd_device_nm(argv[1]);
+ if (IS_ERR(mtd)) {
+ printf("Error: NMBM device '%s' not found\n", argv[1]);
+ return CMD_RET_FAILURE;
+ }
+
+ if (mtd->type != MTD_DEV_TYPE_NMBM) {
+ printf("Error: '%s' is not a NMBM device\n", argv[1]);
+ return CMD_RET_FAILURE;
+ }
+
+ if (!strcmp(argv[2], "boot"))
+ return do_nmbm_mtd_boot(cmdtp, mtd, argc - 3, argv + 3);
+
+ if (argc < 5)
+ return CMD_RET_USAGE;
+
+ if (!strcmp(argv[2], "erase")) {
+ ret = nmbm_parse_offset_size(mtd, argv[3], argv[4], &offset,
+ &size);
+ if (ret)
+ return CMD_RET_FAILURE;
+
+ return do_nmbm_erase(mtd, offset, size);
+ }
+
+ if (argc < 6)
+ return CMD_RET_USAGE;
+
+ ret = nmbm_parse_offset_size(mtd, argv[4], argv[5], &offset, &size);
+ if (ret)
+ return CMD_RET_FAILURE;
+
+ if (size > SIZE_MAX) {
+ printf("Error: size 0x%llx is too large\n", size);
+ return -EINVAL;
+ }
+
+ addr = simple_strtoul(argv[3], &end, 16);
+ if (end == argv[3]) {
+ printf("Error: addr '%s' is invalid\n", argv[3]);
+ return -EINVAL;
+ }
+
+ if (!strcmp(argv[2], "read"))
+ return do_nmbm_rw(1, mtd, addr, offset, (size_t)size);
+
+ if (!strcmp(argv[2], "write"))
+ return do_nmbm_rw(0, mtd, addr, offset, (size_t)size);
+
+ return CMD_RET_USAGE;
+}
+
+U_BOOT_CMD(
+ nmbm, CONFIG_SYS_MAXARGS, 0, do_nmbm,
+ "NMBM utility commands",
+ "\n"
+ "nmbm list - List NMBM devices\n"
+ "nmbm <name> info - Display NMBM information\n"
+ "nmbm <name> state - Display block states\n"
+ "nmbm <name> bad - Display bad blocks\n"
+ "nmbm <name> boot <part | [loadaddr] offset> - Boot from NMBM\n"
+ "nmbm <name> mapping [all] - Display block mapping\n"
+ "nmbm <name> erase <offset> <size> - Erase blocks\n"
+ "nmbm <name> read <addr> <offset> <size> - Read data\n"
+ "nmbm <name> write <addr> <offset> <size> - Write data\n"
+);

View File

@ -0,0 +1,80 @@
From 6dbbc8affb6ab22f940d13d0e928d5e881127ca4 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Mon, 25 Jul 2022 11:22:57 +0800
Subject: [PATCH 44/71] cmd: mtd: add markbad subcommand for NMBM testing
This patch adds:
* Mark bad block on lower mtd device and erase on upper mtd
device, which will trigger remapping:
$ mtd markbad spi-nand0 0x20000 (mark block1 as bad)
$ mtd erase nmbm0 0x20000 0x20000 (let nmbm detect the bad block and remap it)
* Clear bad block mark through:
$ mtd erase.dontskipbad spi-nand0 0x20000 0x20000
(After cleaning bad block mark, we need to rebuild nmbm manage table.)
Signed-off-by: SkyLake.Huang <skylake.huang@mediatek.com>
---
cmd/mtd.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
--- a/cmd/mtd.c
+++ b/cmd/mtd.c
@@ -492,6 +492,42 @@ out_put_mtd:
return CMD_RET_SUCCESS;
}
+static int do_mtd_markbad(struct cmd_tbl *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ struct mtd_info *mtd;
+ loff_t off;
+ int ret;
+
+ if (argc < 3)
+ return CMD_RET_USAGE;
+
+ mtd = get_mtd_by_name(argv[1]);
+ if (IS_ERR(mtd) || !mtd)
+ return CMD_RET_FAILURE;
+
+ if (!mtd_can_have_bb(mtd)) {
+ printf("Only NAND-based devices can have mark blocks\n");
+ goto out_put_mtd;
+ }
+
+ off = simple_strtoull(argv[2], NULL, 0);
+
+ ret = mtd_block_markbad(mtd, off);
+ if (!ret) {
+ printf("MTD device %s block at 0x%08llx marked bad\n",
+ mtd->name, off);
+ } else {
+ printf("MTD device %s block at 0x%08llx mark bad failed\n",
+ mtd->name, off);
+ }
+
+out_put_mtd:
+ put_mtd_device(mtd);
+
+ return CMD_RET_SUCCESS;
+}
+
#ifdef CONFIG_AUTO_COMPLETE
static int mtd_name_complete(int argc, char *const argv[], char last_char,
int maxv, char *cmdv[])
@@ -540,6 +576,7 @@ static char mtd_help_text[] =
"\n"
"Specific functions:\n"
"mtd bad <name>\n"
+ "mtd markbad <name> <off>\n"
"\n"
"With:\n"
"\t<name>: NAND partition/chip name (or corresponding DM device name or OF path)\n"
@@ -565,4 +602,6 @@ U_BOOT_CMD_WITH_SUBCMDS(mtd, "MTD utils"
U_BOOT_SUBCMD_MKENT_COMPLETE(erase, 4, 0, do_mtd_erase,
mtd_name_complete),
U_BOOT_SUBCMD_MKENT_COMPLETE(bad, 2, 1, do_mtd_bad,
+ mtd_name_complete),
+ U_BOOT_SUBCMD_MKENT_COMPLETE(markbad, 3, 1, do_mtd_markbad,
mtd_name_complete));

View File

@ -0,0 +1,280 @@
From 240d98e6ad0aed3c11236aa40a60bbd6fe01fae5 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Mon, 25 Jul 2022 10:50:46 +0800
Subject: [PATCH 45/71] env: add support for NMBM upper MTD layer
Add an env driver for NMBM upper MTD layer
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
cmd/nvedit.c | 3 +-
env/Kconfig | 19 ++++-
env/Makefile | 1 +
env/env.c | 3 +
env/nmbm.c | 155 +++++++++++++++++++++++++++++++++++++++++
include/env_internal.h | 1 +
tools/Makefile | 1 +
7 files changed, 180 insertions(+), 3 deletions(-)
create mode 100644 env/nmbm.c
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -50,6 +50,7 @@ DECLARE_GLOBAL_DATA_PTR;
defined(CONFIG_ENV_IS_IN_EXT4) || \
defined(CONFIG_ENV_IS_IN_MTD) || \
defined(CONFIG_ENV_IS_IN_NAND) || \
+ defined(CONFIG_ENV_IS_IN_NMBM) || \
defined(CONFIG_ENV_IS_IN_NVRAM) || \
defined(CONFIG_ENV_IS_IN_ONENAND) || \
defined(CONFIG_ENV_IS_IN_SATA) || \
@@ -64,7 +65,7 @@ DECLARE_GLOBAL_DATA_PTR;
#if !defined(ENV_IS_IN_DEVICE) && \
!defined(CONFIG_ENV_IS_NOWHERE)
# error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|MMC|FAT|EXT4|MTD|\
-NAND|NVRAM|ONENAND|SATA|SPI_FLASH|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE
+NAND|NMBM|NVRAM|ONENAND|SATA|SPI_FLASH|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE
#endif
/*
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -37,7 +37,7 @@ config ENV_IS_NOWHERE
!ENV_IS_IN_MMC && !ENV_IS_IN_NAND && \
!ENV_IS_IN_NVRAM && !ENV_IS_IN_ONENAND && \
!ENV_IS_IN_REMOTE && !ENV_IS_IN_SPI_FLASH && \
- !ENV_IS_IN_UBI && !ENV_IS_IN_MTD
+ !ENV_IS_IN_UBI && !ENV_IS_IN_NMBM && !ENV_IS_IN_MTD
help
Define this if you don't want to or can't have an environment stored
on a storage medium. In this case the environment will still exist
@@ -285,6 +285,21 @@ config ENV_IS_IN_NAND
Currently, CONFIG_ENV_OFFSET_REDUND is not supported when
using CONFIG_ENV_OFFSET_OOB.
+config ENV_IS_IN_NMBM
+ bool "Environment in a NMBM upper MTD layer"
+ depends on !CHAIN_OF_TRUST
+ depends on NMBM_MTD
+ help
+ Define this if you have a NMBM upper MTD which you want to use for
+ the environment.
+
+ - CONFIG_ENV_OFFSET:
+ - CONFIG_ENV_SIZE:
+
+ These two #defines specify the offset and size of the environment
+ area within the first NAND device. CONFIG_ENV_OFFSET must be
+ aligned to an erase block boundary.
+
config ENV_IS_IN_NVRAM
bool "Environment in a non-volatile RAM"
depends on !CHAIN_OF_TRUST
@@ -561,7 +576,7 @@ config ENV_MTD_NAME
config ENV_OFFSET
hex "Environment offset"
depends on ENV_IS_IN_EEPROM || ENV_IS_IN_MMC || ENV_IS_IN_NAND || \
- ENV_IS_IN_SPI_FLASH || ENV_IS_IN_MTD
+ ENV_IS_IN_SPI_FLASH || ENV_IS_IN_NMBM || ENV_IS_IN_MTD
default 0x3f8000 if ARCH_ROCKCHIP && ENV_IS_IN_MMC
default 0x140000 if ARCH_ROCKCHIP && ENV_IS_IN_SPI_FLASH
default 0xF0000 if ARCH_SUNXI
--- a/env/Makefile
+++ b/env/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_FAT) +
obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_EXT4) += ext4.o
obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_MTD) += mtd.o
obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_NAND) += nand.o
+obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_NMBM) += nmbm.o
obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_SPI_FLASH) += sf.o
obj-$(CONFIG_$(SPL_TPL_)ENV_IS_IN_FLASH) += flash.o
--- a/env/env.c
+++ b/env/env.c
@@ -75,6 +75,9 @@ static enum env_location env_locations[]
#ifdef CONFIG_ENV_IS_IN_NAND
ENVL_NAND,
#endif
+#ifdef CONFIG_ENV_IS_IN_NMBM
+ ENVL_NMBM,
+#endif
#ifdef CONFIG_ENV_IS_IN_NVRAM
ENVL_NVRAM,
#endif
--- /dev/null
+++ b/env/nmbm.c
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <command.h>
+#include <env.h>
+#include <env_internal.h>
+#include <errno.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <malloc.h>
+#include <memalign.h>
+#include <search.h>
+
+#include <nmbm/nmbm-mtd.h>
+
+#if defined(CONFIG_CMD_SAVEENV) && defined(CONFIG_NMBM_MTD)
+#define CMD_SAVEENV
+#endif
+
+#if defined(ENV_IS_EMBEDDED)
+env_t *env_ptr = &environment;
+#else /* ! ENV_IS_EMBEDDED */
+env_t *env_ptr;
+#endif /* ENV_IS_EMBEDDED */
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int env_nmbm_init(void)
+{
+#if defined(ENV_IS_EMBEDDED)
+ int crc1_ok = 0, crc2_ok = 0;
+ env_t *tmp_env1;
+
+ tmp_env1 = env_ptr;
+ crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc;
+
+ if (!crc1_ok && !crc2_ok) {
+ gd->env_addr = 0;
+ gd->env_valid = ENV_INVALID;
+
+ return 0;
+ } else if (crc1_ok && !crc2_ok) {
+ gd->env_valid = ENV_VALID;
+ }
+
+ if (gd->env_valid == ENV_VALID)
+ env_ptr = tmp_env1;
+
+ gd->env_addr = (ulong)env_ptr->data;
+
+#else /* ENV_IS_EMBEDDED */
+ gd->env_addr = (ulong)&default_environment[0];
+ gd->env_valid = ENV_VALID;
+#endif /* ENV_IS_EMBEDDED */
+
+ return 0;
+}
+
+#ifdef CMD_SAVEENV
+static int env_nmbm_save(void)
+{
+ ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
+ struct mtd_info *mtd;
+ struct erase_info ei;
+ int ret = 0;
+
+ ret = env_export(env_new);
+ if (ret)
+ return ret;
+
+ mtd = nmbm_mtd_get_upper_by_index(0);
+ if (!mtd)
+ return 1;
+
+ printf("Erasing on NMBM...\n");
+ memset(&ei, 0, sizeof(ei));
+
+ ei.mtd = mtd;
+ ei.addr = CONFIG_ENV_OFFSET;
+ ei.len = CONFIG_ENV_SIZE;
+
+ if (mtd_erase(mtd, &ei))
+ return 1;
+
+ printf("Writing on NMBM... ");
+ ret = mtd_write(mtd, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, NULL,
+ (u_char *)env_new);
+ puts(ret ? "FAILED!\n" : "OK\n");
+
+ return !!ret;
+}
+#endif /* CMD_SAVEENV */
+
+static int readenv(size_t offset, u_char *buf)
+{
+ struct mtd_info *mtd;
+ struct mtd_oob_ops ops;
+ int ret;
+ size_t len = CONFIG_ENV_SIZE;
+
+ mtd = nmbm_mtd_get_upper_by_index(0);
+ if (!mtd)
+ return 1;
+
+ ops.mode = MTD_OPS_AUTO_OOB;
+ ops.ooblen = 0;
+ while(len > 0) {
+ ops.datbuf = buf;
+ ops.len = min(len, (size_t)mtd->writesize);
+ ops.oobbuf = NULL;
+
+ ret = mtd_read_oob(mtd, offset, &ops);
+ if (ret)
+ return 1;
+
+ buf += mtd->writesize;
+ len -= mtd->writesize;
+ offset += mtd->writesize;
+ }
+
+ return 0;
+}
+
+static int env_nmbm_load(void)
+{
+#if !defined(ENV_IS_EMBEDDED)
+ ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
+ int ret;
+
+ ret = readenv(CONFIG_ENV_OFFSET, (u_char *)buf);
+ if (ret) {
+ env_set_default("readenv() failed", 0);
+ return -EIO;
+ }
+
+ return env_import(buf, 1, H_EXTERNAL);
+#endif /* ! ENV_IS_EMBEDDED */
+
+ return 0;
+}
+
+U_BOOT_ENV_LOCATION(nmbm) = {
+ .location = ENVL_NMBM,
+ ENV_NAME("NMBM")
+ .load = env_nmbm_load,
+#if defined(CMD_SAVEENV)
+ .save = env_save_ptr(env_nmbm_save),
+#endif
+ .init = env_nmbm_init,
+};
--- a/include/env_internal.h
+++ b/include/env_internal.h
@@ -132,6 +132,7 @@ enum env_location {
ENVL_MMC,
ENVL_MTD,
ENVL_NAND,
+ ENVL_NMBM,
ENVL_NVRAM,
ENVL_ONENAND,
ENVL_REMOTE,
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -43,6 +43,7 @@ ENVCRC-$(CONFIG_ENV_IS_IN_FLASH) = y
ENVCRC-$(CONFIG_ENV_IS_IN_ONENAND) = y
ENVCRC-$(CONFIG_ENV_IS_IN_MTD) = y
ENVCRC-$(CONFIG_ENV_IS_IN_NAND) = y
+ENVCRC-$(CONFIG_ENV_IS_IN_NMBM) = y
ENVCRC-$(CONFIG_ENV_IS_IN_NVRAM) = y
ENVCRC-$(CONFIG_ENV_IS_IN_SPI_FLASH) = y
CONFIG_BUILD_ENVCRC ?= $(ENVCRC-y)

View File

@ -0,0 +1,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)

View File

@ -0,0 +1,142 @@
From c4172a95df8a57a66c70a8b9948b9600a01c4cb7 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Mon, 25 Jul 2022 11:32:08 +0800
Subject: [PATCH 49/71] mtd: spi-nor: add support to read flash unique ID
This patch adds support to read unique ID from spi-nor flashes.
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
drivers/mtd/spi/spi-nor-core.c | 95 ++++++++++++++++++++++++++++++++++
include/linux/mtd/spi-nor.h | 2 +
2 files changed, 97 insertions(+)
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -2742,6 +2742,100 @@ static int spi_nor_init_params(struct sp
return 0;
}
+static int spi_nor_read_uuid(struct spi_nor *nor)
+{
+ u8 read_opcode, addr_width, read_dummy;
+ loff_t addr;
+ u8 *uuid;
+ u8 uuid_len;
+ int shift = 0;
+ int ret;
+ int i;
+ struct spi_mem_op op;
+
+ read_opcode = nor->read_opcode;
+ addr_width = nor->addr_width;
+ read_dummy = nor->read_dummy;
+
+ switch (JEDEC_MFR(nor->info)) {
+ case SNOR_MFR_WINBOND:
+ uuid_len = 8;
+ nor->read_opcode = 0x4b;
+ nor->addr_width = 0;
+ addr = 0x0;
+ nor->read_dummy = 4;
+ break;
+ case SNOR_MFR_GIGADEVICE:
+ uuid_len = 16;
+ nor->read_opcode = 0x4b;
+ nor->addr_width = 3;
+ addr = 0x0;
+ nor->read_dummy = 1;
+ break;
+ case CFI_MFR_ST:
+ case SNOR_MFR_MICRON:
+ uuid_len = 17;
+ shift = 3;
+ nor->read_opcode = 0x9f;
+ nor->addr_width = 0;
+ addr = 0x0;
+ nor->read_dummy = 0;
+ break;
+ case SNOR_MFR_EON:
+ uuid_len = 12;
+ nor->read_opcode = 0x5a;
+ nor->addr_width = 3;
+ addr = 0x80;
+ nor->read_dummy = 1;
+ break;
+ /* Automotive only in SPANSION's NOR devices */
+ case SNOR_MFR_SPANSION:
+ uuid_len = 11;
+ shift = 386;
+ nor->read_opcode = 0x9f;
+ nor->addr_width = 0;
+ addr = 0x0;
+ nor->read_dummy = 0;
+ break;
+ default:
+ printf("UUID not supported on this device.\n");
+ return -ENOTSUPP;
+ }
+
+ uuid = kmalloc((uuid_len + shift) * sizeof(*uuid), GFP_KERNEL);
+ if (!uuid) {
+ ret = -ENOMEM;
+ goto read_err;
+ }
+ memset(uuid, 0x0, (uuid_len + shift) * sizeof(*uuid));
+
+ op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0),
+ SPI_MEM_OP_ADDR(nor->addr_width, addr, 0),
+ SPI_MEM_OP_DUMMY(nor->read_dummy, 0),
+ SPI_MEM_OP_DATA_IN(uuid_len+shift, NULL, 0));
+
+ spi_nor_setup_op(nor, &op, nor->reg_proto);
+
+ ret = spi_nor_read_write_reg(nor, &op, uuid);
+ if (ret < 0) {
+ dev_dbg(nor->dev, "error %d reading %x\n", ret, nor->read_opcode);
+ goto read_err;
+ }
+
+ printf("UUID: 0x");
+ for(i = 0; i<uuid_len; i++)
+ printf("%02x", uuid[i+shift]);
+ puts("\n");
+
+read_err:
+ nor->read_opcode = read_opcode;
+ nor->addr_width = addr_width;
+ nor->read_dummy = read_dummy;
+ kfree(uuid);
+
+ return ret;
+}
+
static int spi_nor_hwcaps2cmd(u32 hwcaps, const int table[][2], size_t size)
{
size_t i;
@@ -3719,6 +3813,7 @@ int spi_nor_scan(struct spi_nor *nor)
nor->write = spi_nor_write_data;
nor->read_reg = spi_nor_read_reg;
nor->write_reg = spi_nor_write_reg;
+ nor->read_uuid = spi_nor_read_uuid;
nor->setup = spi_nor_default_setup;
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -28,6 +28,7 @@
#define SNOR_MFR_SPANSION CFI_MFR_AMD
#define SNOR_MFR_SST CFI_MFR_SST
#define SNOR_MFR_WINBOND 0xef /* Also used by some Spansion */
+#define SNOR_MFR_EON CFI_MFR_EON
#define SNOR_MFR_CYPRESS 0x34
/*
@@ -547,6 +548,7 @@ struct spi_nor {
void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);
int (*read_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);
int (*write_reg)(struct spi_nor *nor, u8 opcode, u8 *buf, int len);
+ int (*read_uuid)(struct spi_nor *nor);
ssize_t (*read)(struct spi_nor *nor, loff_t from,
size_t len, u_char *read_buf);

View File

@ -0,0 +1,48 @@
From e60939acbebd07161f3978d1c6f13123fdd2ebf2 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Mon, 25 Jul 2022 11:27:02 +0800
Subject: [PATCH 50/71] cmd: sf: add support to read flash unique ID
This patch adds support to display unique ID from spi-nor flashes
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
cmd/sf.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
--- a/cmd/sf.c
+++ b/cmd/sf.c
@@ -391,6 +391,14 @@ static int do_spi_protect(int argc, char
return ret == 0 ? 0 : 1;
}
+static int do_spi_flash_read_uuid(void)
+{
+ int ret = 0;
+ ret = flash->read_uuid(flash);
+
+ return ret == 0 ? 0 : 1;
+}
+
enum {
STAGE_ERASE,
STAGE_CHECK,
@@ -587,6 +595,8 @@ static int do_spi_flash(struct cmd_tbl *
ret = do_spi_flash_erase(argc, argv);
else if (strcmp(cmd, "protect") == 0)
ret = do_spi_protect(argc, argv);
+ else if (strcmp(cmd, "uuid") == 0)
+ ret = do_spi_flash_read_uuid();
else if (IS_ENABLED(CONFIG_CMD_SF_TEST) && !strcmp(cmd, "test"))
ret = do_spi_flash_test(argc, argv);
else
@@ -617,7 +627,8 @@ static const char long_help[] =
" at `addr' to flash at `offset'\n"
" or to start of mtd `partition'\n"
"sf protect lock/unlock sector len - protect/unprotect 'len' bytes starting\n"
- " at address 'sector'"
+ " at address 'sector'\n"
+ "sf uuid - read uuid from flash"
#ifdef CONFIG_CMD_SF_TEST
"\nsf test offset len - run a very basic destructive test"
#endif

View File

@ -1,26 +1,20 @@
From afea25576fc92d562b248b783cf03564eb4521da Mon Sep 17 00:00:00 2001
From 5a15437610e8e8c68dc347845a83d0cbad80ca08 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Tue, 19 Jan 2021 10:58:48 +0800
Subject: [PATCH 12/12] cmd: bootmenu: add ability to select item by shortkey
Subject: [PATCH 51/71] cmd: bootmenu: add ability to select item by shortkey
Add ability to use shortkey to select item for bootmenu command
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
cmd/bootmenu.c | 77 +++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 70 insertions(+), 7 deletions(-)
cmd/bootmenu.c | 34 ++++++++++++++++++++++++-----
common/menu.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++--
include/menu.h | 12 +++++++----
3 files changed, 93 insertions(+), 11 deletions(-)
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -14,6 +14,7 @@
#include <menu.h>
#include <watchdog.h>
#include <malloc.h>
+#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/string.h>
@@ -87,16 +88,17 @@ static char *bootmenu_choice_entry(void
@@ -87,16 +87,17 @@ static char *bootmenu_choice_entry(void
struct bootmenu_data *menu = data;
struct bootmenu_entry *iter;
enum bootmenu_key key = KEY_NONE;
@ -40,7 +34,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
}
switch (key) {
@@ -110,6 +112,12 @@ static char *bootmenu_choice_entry(void
@@ -110,6 +111,12 @@ static char *bootmenu_choice_entry(void
++menu->active;
/* no menu key selected, regenerate menu */
return NULL;
@ -53,28 +47,43 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
case KEY_SELECT:
iter = menu->first;
for (i = 0; i < menu->active; ++i)
@@ -181,12 +189,19 @@ static int prepare_bootmenu_entry(struct
@@ -167,6 +174,9 @@ static int prepare_bootmenu_entry(struct
unsigned short int i = *index;
struct bootmenu_entry *entry = NULL;
struct bootmenu_entry *iter = *current;
+ char *choice_option;
+ char choice_char;
+ int len;
while ((option = bootmenu_getoption(i))) {
@@ -181,11 +191,24 @@ static int prepare_bootmenu_entry(struct
if (!entry)
return -ENOMEM;
- entry->title = strndup(option, sep - option);
+ entry->title = malloc((sep - option) + 4);
+ /* Add KEY_CHOICE support: '%d. %s\0' : len --> len + 4 */
+ len = sep - option + 4;
+ choice_option = malloc(len);
+ if (!choice_option) {
+ free(entry->title);
+ free(entry);
+ return -ENOMEM;
+ }
+ if (!get_choice_char(i, &choice_char))
+ len = snprintf(choice_option, len, "%c. %s", choice_char, option);
+ else
+ len = snprintf(choice_option, len, " %s", option);
+ entry->title = strndup(choice_option, len);
if (!entry->title) {
free(entry);
return -ENOMEM;
}
+ free(choice_option);
+ if (i < ARRAY_SIZE(choice_chars)) {
+ sprintf(entry->title, "%c. %.*s", choice_chars[i],
+ (int)(sep - option), option);
+ } else {
+ sprintf(entry->title, " %.*s", (int)(sep - option), option);
+ }
+
entry->command = strdup(sep + 1);
if (!entry->command) {
free(entry->title);
@@ -331,6 +346,7 @@ static struct bootmenu_data *bootmenu_cr
@@ -331,6 +354,7 @@ static struct bootmenu_data *bootmenu_cr
menu->delay = delay;
menu->active = 0;
menu->first = NULL;
@ -82,7 +91,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
default_str = env_get("bootmenu_default");
if (default_str)
@@ -356,9 +372,9 @@ static struct bootmenu_data *bootmenu_cr
@@ -356,9 +380,9 @@ static struct bootmenu_data *bootmenu_cr
/* Add Quit entry if entering U-Boot console is disabled */
if (!IS_ENABLED(CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE))
@ -96,18 +105,17 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
free(entry);
--- a/common/menu.c
+++ b/common/menu.c
@@ -9,6 +9,7 @@
#include <cli.h>
#include <malloc.h>
#include <errno.h>
+#include <linux/ctype.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <watchdog.h>
@@ -47,6 +48,17 @@ struct menu {
@@ -47,6 +47,33 @@ struct menu {
int item_cnt;
};
+const char choice_chars[] = {
+ '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+ 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+ 'u', 'v', 'w', 'x', 'y', 'z'
+};
+
+static int find_choice(char choice)
+{
+ int i;
@ -118,11 +126,20 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+
+ return -1;
+}
+
+int get_choice_char(int index, char *result)
+{
+ if (index < ARRAY_SIZE(choice_chars))
+ *result = choice_chars[index];
+ else
+ return -1;
+ return 0;
+}
+
/*
* An iterator function for menu items. callback will be called for each item
* in m, with m, a pointer to the item, and extra being passed to callback. If
@@ -426,7 +438,7 @@ int menu_destroy(struct menu *m)
@@ -426,7 +453,7 @@ int menu_destroy(struct menu *m)
}
void bootmenu_autoboot_loop(struct bootmenu_data *menu,
@ -131,7 +148,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
{
int i, c;
@@ -456,6 +468,19 @@ void bootmenu_autoboot_loop(struct bootm
@@ -456,6 +483,19 @@ void bootmenu_autoboot_loop(struct bootm
break;
default:
*key = KEY_NONE;
@ -151,7 +168,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
break;
}
@@ -475,10 +500,16 @@ void bootmenu_autoboot_loop(struct bootm
@@ -475,10 +515,16 @@ void bootmenu_autoboot_loop(struct bootm
}
void bootmenu_loop(struct bootmenu_data *menu,
@ -169,7 +186,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
if (*esc == 1) {
if (tstc()) {
c = getchar();
@@ -504,6 +535,14 @@ void bootmenu_loop(struct bootmenu_data
@@ -504,6 +550,14 @@ void bootmenu_loop(struct bootmenu_data
if (c == '\e') {
*esc = 1;
*key = KEY_NONE;
@ -186,7 +203,29 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
case 1:
--- a/include/menu.h
+++ b/include/menu.h
@@ -40,6 +40,7 @@ struct bootmenu_data {
@@ -2,10 +2,11 @@
/*
* Copyright 2010-2011 Calxeda, Inc.
*/
-
#ifndef __MENU_H__
#define __MENU_H__
+#include <linux/ctype.h>
+
struct menu;
struct menu *menu_create(char *title, int timeout, int prompt,
@@ -18,6 +19,8 @@ int menu_get_choice(struct menu *m, void
int menu_item_add(struct menu *m, char *item_key, void *item_data);
int menu_destroy(struct menu *m);
int menu_default_choice(struct menu *m, void **choice);
+/* Add KEY_CHOICE support */
+int get_choice_char(int index, char *result);
/**
* menu_show() Show a boot menu
@@ -40,6 +43,7 @@ struct bootmenu_data {
int active; /* active menu entry */
int count; /* total count of menu entries */
struct bootmenu_entry *first; /* first menu entry */
@ -194,7 +233,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
};
enum bootmenu_key {
@@ -48,11 +49,19 @@ enum bootmenu_key {
@@ -48,11 +52,11 @@ enum bootmenu_key {
KEY_DOWN,
KEY_SELECT,
KEY_QUIT,
@ -206,13 +245,6 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+ enum bootmenu_key *key, int *esc, int *choice);
void bootmenu_loop(struct bootmenu_data *menu,
- enum bootmenu_key *key, int *esc);
-
+ enum bootmenu_key *key, int *esc, int *choice);
+
+static const char choice_chars[] = {
+ '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+ 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+ 'u', 'v', 'w', 'x', 'y', 'z'
+};
#endif /* __MENU_H__ */

View File

@ -0,0 +1,28 @@
From 7ab891faaaf2b6126694352d4503dc40605a6aec Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Mon, 25 Jul 2022 15:10:02 +0800
Subject: [PATCH 52/71] common: spl: spl_nand: enable
CONFIG_SYS_NAND_U_BOOT_OFFS undefined
Enable using spl_nand with CONFIG_SYS_NAND_U_BOOT_OFFS undefined since
mtk-snand does not require raw nand framework.
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
common/spl/spl_nand.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/common/spl/spl_nand.c
+++ b/common/spl/spl_nand.c
@@ -16,7 +16,11 @@
uint32_t __weak spl_nand_get_uboot_raw_page(void)
{
+#ifdef CONFIG_SYS_NAND_U_BOOT_OFFS
return CONFIG_SYS_NAND_U_BOOT_OFFS;
+#else
+ return 0;
+#endif
}
#if defined(CONFIG_SPL_NAND_RAW_ONLY)

View File

@ -1,7 +1,7 @@
From 3757223c3354b9feeffcbe916eb18eb8873bd133 Mon Sep 17 00:00:00 2001
From 452dc98572f8353f77551bcce5a2ca8cd050f498 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Wed, 3 Mar 2021 10:48:53 +0800
Subject: [PATCH 07/12] board: mt7629: add support for booting from SPI-NAND
Subject: [PATCH 53/71] board: mt7629: add support for booting from SPI-NAND
Add support for mt7629 to boot from SPI-NAND.
Add a new defconfig for mt7629+spi-nand configuration.
@ -11,10 +11,12 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
arch/arm/dts/mt7629-rfb-u-boot.dtsi | 8 ++
arch/arm/dts/mt7629-rfb.dts | 10 +++
arch/arm/dts/mt7629.dtsi | 16 ++++
board/mediatek/mt7629/Kconfig | 35 ++++++++-
configs/mt7629_nand_rfb_defconfig | 111 ++++++++++++++++++++++++++++
include/configs/mt7629.h | 7 ++
6 files changed, 186 insertions(+), 1 deletion(-)
arch/arm/mach-mediatek/Kconfig | 4 +-
board/mediatek/mt7629/Kconfig | 40 ++++++++++
board/mediatek/mt7629/mt7629_rfb.c | 5 ++
configs/mt7629_nand_rfb_defconfig | 113 ++++++++++++++++++++++++++++
7 files changed, 195 insertions(+), 1 deletion(-)
create mode 100644 board/mediatek/mt7629/Kconfig
create mode 100644 configs/mt7629_nand_rfb_defconfig
--- a/arch/arm/dts/mt7629-rfb-u-boot.dtsi
@ -85,9 +87,78 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
snor: snor@11014000 {
compatible = "mediatek,mtk-snor";
reg = <0x11014000 0x1000>;
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -131,9 +131,11 @@ config SYS_CONFIG_NAME
config MTK_BROM_HEADER_INFO
string
- default "media=nor" if TARGET_MT8518 || TARGET_MT8512 || TARGET_MT7629 || TARGET_MT7622
+ default "media=nor" if TARGET_MT8518 || TARGET_MT8512 || TARGET_MT7622
default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 || TARGET_MT8183
default "media=snand;nandinfo=2k+64" if TARGET_MT7981 || TARGET_MT7986
default "lk=1" if TARGET_MT7623
+source "board/mediatek/mt7629/Kconfig"
+
endif
--- /dev/null
+++ b/board/mediatek/mt7629/Kconfig
@@ -0,0 +1,40 @@
+if TARGET_MT7629
+
+config MTK_BROM_HEADER_INFO
+ string
+ default "media=nor" if BOOT_FROM_SNOR
+ default "media=snand;nandinfo=2k+64" if BOOT_FROM_SNAND_2K_64
+ default "media=snand;nandinfo=2k+128" if BOOT_FROM_SNAND_2K_128
+ default "media=snand;nandinfo=4k+128" if BOOT_FROM_SNAND_4K_128
+ default "media=snand;nandinfo=4k+256" if BOOT_FROM_SNAND_4K_256
+
+choice
+ prompt "Boot device"
+ default BOOT_FROM_SNOR
+
+config BOOT_FROM_SNOR
+ bool "SPI-NOR"
+
+config BOOT_FROM_SNAND_2K_64
+ bool "SPI-NAND (2K+64)"
+ select MT7629_BOOT_FROM_SNAND
+
+config BOOT_FROM_SNAND_2K_128
+ bool "SPI-NAND (2K+128)"
+ select MT7629_BOOT_FROM_SNAND
+
+config BOOT_FROM_SNAND_4K_128
+ bool "SPI-NAND (4K+128)"
+ select MT7629_BOOT_FROM_SNAND
+
+config BOOT_FROM_SNAND_4K_256
+ bool "SPI-NAND (4K+256)"
+ select MT7629_BOOT_FROM_SNAND
+
+endchoice
+
+config MT7629_BOOT_FROM_SNAND
+ bool
+ default n
+
+endif
--- a/board/mediatek/mt7629/mt7629_rfb.c
+++ b/board/mediatek/mt7629/mt7629_rfb.c
@@ -15,3 +15,8 @@ int board_init(void)
return 0;
}
+
+uint32_t spl_nand_get_uboot_raw_page(void)
+{
+ return CONFIG_SPL_PAD_TO;
+}
--- /dev/null
+++ b/configs/mt7629_nand_rfb_defconfig
@@ -0,0 +1,111 @@
@@ -0,0 +1,113 @@
+CONFIG_ARM=y
+CONFIG_SYS_ARCH_TIMER=y
+CONFIG_SYS_THUMB_BUILD=y
@ -96,36 +167,42 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x20000
+CONFIG_ENV_OFFSET=0x100000
+CONFIG_ENV_OFFSET=0x0
+CONFIG_DEFAULT_DEVICE_TREE="mt7629-rfb"
+CONFIG_SPL_TEXT_BASE=0x201000
+CONFIG_TARGET_MT7629=y
+CONFIG_BOOT_FROM_SNAND_2K_64=y
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_DRIVERS_MISC_SUPPORT=y
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL_STACK_R_ADDR=0x40800000
+CONFIG_SYS_LOAD_ADDR=0x42007f1c
+CONFIG_SPL_PAYLOAD="u-boot.img"
+CONFIG_BUILD_TARGET="u-boot-mtk.bin"
+CONFIG_DEFAULT_DEVICE_TREE="mt7629-rfb"
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x41fffef0
+CONFIG_SPL_IMAGE="spl/u-boot-spl-mtk.bin"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_BOOTDELAY=3
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7629-rfb"
+CONFIG_SYS_CONSOLE_IS_IN_ENV=y
+CONFIG_SYS_STDIO_DEREGISTER=y
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_SPL_MAX_SIZE=0x20000
+CONFIG_SPL_FOOTPRINT_LIMIT=y
+CONFIG_SPL_MAX_FOOTPRINT=0x20000
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK=0x106000
+CONFIG_SPL_STACK_R=y
+CONFIG_SPL_MTD_SUPPORT=y
+CONFIG_SPL_NAND_SUPPORT=y
+CONFIG_SPL_WATCHDOG_SUPPORT=y
+CONFIG_SPL_WATCHDOG=y
+CONFIG_HUSH_PARSER=y
+CONFIG_SYS_PROMPT="U-Boot> "
+CONFIG_CMD_BOOTMENU=y
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+CONFIG_SYS_BOOTM_LEN=0x4000000
+CONFIG_CMD_BOOTMENU=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_CMD_BIND=y
@ -140,13 +217,10 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_LOG=y
+CONFIG_EFI_PARTITION=y
+# CONFIG_SPL_PARTITION_UUIDS is not set
+CONFIG_PARTITION_TYPE_GUID=y
+CONFIG_OF_SPL_REMOVE_PROPS="interrupt-parent assigned-clocks assigned-clock-parents"
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MTD=y
+CONFIG_ENV_MTD_NAME="spi-nand0"
+CONFIG_ENV_MTD_NAME="u-boot-env"
+CONFIG_ENV_SIZE_REDUND=0x40000
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
@ -155,7 +229,6 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+CONFIG_SPL_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_SPL_SYSCON=y
+CONFIG_BLK=y
+CONFIG_CLK=y
+CONFIG_SPL_CLK=y
+# CONFIG_MMC is not set
@ -189,35 +262,13 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+CONFIG_SPL_SYSRESET=y
+CONFIG_SYSRESET_WATCHDOG=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+# CONFIG_SPL_DM_USB is not set
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_XHCI_MTK=y
+CONFIG_USB_STORAGE=y
+CONFIG_WDT_MTK=y
+CONFIG_FAT_WRITE=y
+# CONFIG_SHA256 is not set
+# CONFIG_SPL_SHA1 is not set
+CONFIG_LZMA=y
+CONFIG_SPL_LZMA=y
+# CONFIG_EFI_LOADER is not set
--- a/include/configs/mt7629.h
+++ b/include/configs/mt7629.h
@@ -25,12 +25,19 @@
/* Defines for SPL */
#define CONFIG_SPL_STACK 0x106000
+#ifdef CONFIG_MT7629_BOOT_FROM_SNAND
+#define CONFIG_SPL_MAX_SIZE SZ_128K
+#define CONFIG_SPL_MAX_FOOTPRINT SZ_128K
+#define CONFIG_SPL_PAD_TO 0x20000
+#define CONFIG_SYS_NAND_U_BOOT_OFFS CONFIG_SPL_PAD_TO
+#else
#define CONFIG_SPL_MAX_SIZE SZ_64K
#define CONFIG_SPL_MAX_FOOTPRINT SZ_64K
#define CONFIG_SPL_PAD_TO 0x10000
#define CONFIG_SPI_ADDR 0x30000000
#define CONFIG_SYS_UBOOT_BASE (CONFIG_SPI_ADDR + CONFIG_SPL_PAD_TO)
+#endif
/* SPL -> Uboot */
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + SZ_2M - \

View File

@ -1,7 +1,7 @@
From 6bcd65ed47844e747ff6db066b092632f1760256 Mon Sep 17 00:00:00 2001
From 4c1803cc08b1618d935c1386f43f43a4e9c97697 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Wed, 3 Mar 2021 10:51:43 +0800
Subject: [PATCH 08/12] board: mt7622: use new spi-nand driver
Subject: [PATCH 54/71] board: mt7622: use new spi-nand driver
Enable new spi-nand driver support for mt7622_rfb_defconfig
@ -14,7 +14,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
--- a/arch/arm/dts/mt7622-rfb.dts
+++ b/arch/arm/dts/mt7622-rfb.dts
@@ -188,6 +188,13 @@
@@ -196,6 +196,13 @@
};
};
@ -26,11 +26,11 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins>;
status = "okay";
};
--- a/arch/arm/dts/mt7622.dtsi
+++ b/arch/arm/dts/mt7622.dtsi
@@ -53,6 +53,22 @@
@@ -77,6 +77,22 @@
#size-cells = <0>;
};
@ -55,7 +55,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
reg = <0x11014000 0x1000>;
--- a/configs/mt7622_rfb_defconfig
+++ b/configs/mt7622_rfb_defconfig
@@ -16,6 +16,7 @@ CONFIG_LOG=y
@@ -18,6 +18,7 @@ CONFIG_LOG=y
CONFIG_SYS_PROMPT="MT7622> "
CONFIG_CMD_BOOTMENU=y
CONFIG_CMD_MMC=y
@ -63,7 +63,7 @@ Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
CONFIG_CMD_PCI=y
CONFIG_CMD_SF_TEST=y
CONFIG_CMD_PING=y
@@ -28,6 +29,10 @@ CONFIG_SYSCON=y
@@ -33,6 +34,10 @@ CONFIG_SYSCON=y
CONFIG_CLK=y
CONFIG_MMC_HS200_SUPPORT=y
CONFIG_MMC_MTK=y

View File

@ -0,0 +1,223 @@
From d5841f8707dcb7a1f73607de67ab45dba93a56a4 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Fri, 29 Jul 2022 17:04:12 +0800
Subject: [PATCH 55/71] board: mt7981: add reference board using new spi-nand
driver
Add a new reference board using new spi-nand driver for SPI-NAND flash on
SNFI interface
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
arch/arm/dts/Makefile | 1 +
arch/arm/dts/mt7981-snfi-nand-rfb.dts | 132 +++++++++++++++++++++++++
configs/mt7981_snfi_nand_rfb_defconfig | 57 +++++++++++
3 files changed, 190 insertions(+)
create mode 100644 arch/arm/dts/mt7981-snfi-nand-rfb.dts
create mode 100644 configs/mt7981_snfi_nand_rfb_defconfig
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1206,6 +1206,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
mt7623n-bananapi-bpi-r2.dtb \
mt7629-rfb.dtb \
mt7981-rfb.dtb \
+ mt7981-snfi-nand-rfb.dtb \
mt7981-emmc-rfb.dtb \
mt7981-sd-rfb.dtb \
mt7986a-rfb.dtb \
--- /dev/null
+++ b/arch/arm/dts/mt7981-snfi-nand-rfb.dts
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 MediaTek Inc.
+ * Author: Sam Shih <sam.shih@mediatek.com>
+ */
+
+/dts-v1/;
+#include "mt7981.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ model = "mt7981-rfb";
+ compatible = "mediatek,mt7981", "mediatek,mt7981-rfb";
+ chosen {
+ stdout-path = &uart0;
+ tick-timer = &timer0;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+ status = "disabled";
+};
+
+&eth {
+ status = "okay";
+ mediatek,gmac-id = <0>;
+ phy-mode = "sgmii";
+ mediatek,switch = "mt7531";
+ reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
+&pinctrl {
+ snfi_pins: snfi-pins-func-1 {
+ mux {
+ function = "flash";
+ groups = "snfi";
+ };
+
+ clk {
+ pins = "SPI0_CLK";
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+ };
+
+ conf-pu {
+ pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_00>;
+ };
+
+ conf-pd {
+ pins = "SPI0_MOSI", "SPI0_MISO";
+ drive-strength = <MTK_DRIVE_6mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_00>;
+ };
+ };
+
+ spic_pins: spi1-pins-func-1 {
+ mux {
+ function = "spi";
+ groups = "spi1_1";
+ };
+ };
+
+ uart1_pins: spi1-pins-func-3 {
+ mux {
+ function = "uart";
+ groups = "uart1_2";
+ };
+ };
+
+ /* pin15 as pwm0 */
+ one_pwm_pins: one-pwm-pins {
+ mux {
+ function = "pwm";
+ groups = "pwm0_1";
+ };
+ };
+
+ /* pin15 as pwm0 and pin14 as pwm1 */
+ two_pwm_pins: two-pwm-pins {
+ mux {
+ function = "pwm";
+ groups = "pwm0_1", "pwm1_0";
+ };
+ };
+
+ /* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */
+ three_pwm_pins: three-pwm-pins {
+ mux {
+ function = "pwm";
+ groups = "pwm0_1", "pwm1_0", "pwm2";
+ };
+ };
+
+ mmc0_pins_default: mmc0default {
+ mux {
+ function = "flash";
+ groups = "emmc_45";
+ };
+ };
+};
+
+&snand {
+ pinctrl-names = "default";
+ pinctrl-0 = <&snfi_pins>;
+ status = "okay";
+ quad-spi;
+};
+
+&pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&two_pwm_pins>;
+ status = "okay";
+};
+
+&watchdog {
+ status = "disabled";
+};
--- /dev/null
+++ b/configs/mt7981_snfi_nand_rfb_defconfig
@@ -0,0 +1,57 @@
+CONFIG_ARM=y
+CONFIG_POSITION_INDEPENDENT=y
+CONFIG_ARCH_MEDIATEK=y
+CONFIG_SYS_TEXT_BASE=0x41e00000
+CONFIG_SYS_MALLOC_F_LEN=0x4000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x20000
+CONFIG_DEFAULT_DEVICE_TREE="mt7981-snfi-nand-rfb"
+CONFIG_TARGET_MT7981=y
+CONFIG_DEBUG_UART_BASE=0x11002000
+CONFIG_DEBUG_UART_CLOCK=40000000
+CONFIG_SYS_LOAD_ADDR=0x46000000
+CONFIG_DEBUG_UART=y
+# CONFIG_AUTOBOOT is not set
+CONFIG_DEFAULT_FDT_FILE="mt7981-snfi-nand-rfb"
+CONFIG_LOGLEVEL=7
+CONFIG_LOG=y
+CONFIG_SYS_PROMPT="MT7981> "
+CONFIG_SYS_CBSIZE=512
+CONFIG_SYS_PBSIZE=1049
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_UNLZ4 is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_SMC=y
+CONFIG_MTDIDS_DEFAULT="spi-nand0=spi-nand0"
+CONFIG_MTDPARTS_DEFAULT="spi-nand0:1024k(bl2),512k(u-boot-env),2048k(factory),2048k(fip),65536k(ubi)"
+CONFIG_CMD_UBI=y
+CONFIG_CMD_UBI_RENAME=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_REGMAP=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTK_SPI_NAND=y
+CONFIG_MTK_SPI_NAND_MTD=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
+CONFIG_PINCTRL=y
+CONFIG_PINCONF=y
+CONFIG_PINCTRL_MT7981=y
+CONFIG_POWER_DOMAIN=y
+CONFIG_MTK_POWER_DOMAIN=y
+CONFIG_DM_SERIAL=y
+CONFIG_MTK_SERIAL=y
+CONFIG_HEXDUMP=y

View File

@ -0,0 +1,76 @@
From a2df2df6fd1aec32572c7b30ccf5a184ec1763fd Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Wed, 27 Jul 2022 16:32:17 +0800
Subject: [PATCH 56/71] mtd: spi-nor: add more flash ids
Add more spi-nor flash ids
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
drivers/mtd/spi/spi-nor-core.c | 1 +
drivers/mtd/spi/spi-nor-ids.c | 23 ++++++++++++++++++++++-
2 files changed, 23 insertions(+), 1 deletion(-)
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -641,6 +641,7 @@ static int set_4byte(struct spi_nor *nor
case SNOR_MFR_ISSI:
case SNOR_MFR_MACRONIX:
case SNOR_MFR_WINBOND:
+ case SNOR_MFR_EON:
if (need_wren)
write_enable(nor);
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -83,7 +83,8 @@ const struct flash_info spi_nor_ids[] =
{ INFO("en25q32b", 0x1c3016, 0, 64 * 1024, 64, 0) },
{ INFO("en25q64", 0x1c3017, 0, 64 * 1024, 128, SECT_4K) },
{ INFO("en25q128b", 0x1c3018, 0, 64 * 1024, 256, 0) },
- { INFO("en25qh128", 0x1c7018, 0, 64 * 1024, 256, 0) },
+ { INFO("en25qh128", 0x1c7018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("en25qh256", 0x1c7019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("en25s64", 0x1c3817, 0, 64 * 1024, 128, SECT_4K) },
#endif
#ifdef CONFIG_SPI_FLASH_GIGADEVICE /* GIGADEVICE */
@@ -119,6 +120,11 @@ const struct flash_info spi_nor_ids[] =
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
{
+ INFO("gd25q256", 0xc84019, 0, 64 * 1024, 512,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
+ {
INFO("gd25lq128", 0xc86018, 0, 64 * 1024, 256,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
@@ -395,6 +401,16 @@ const struct flash_info spi_nor_ids[] =
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
{
+ INFO("w25q256jv", 0xef7019, 0, 64 * 1024, 512,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
+ {
+ INFO("w25q512jv", 0xef7020, 0, 64 * 1024, 1024,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
+ {
INFO("w25q128jw", 0xef8018, 0, 64 * 1024, 256,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
@@ -439,6 +455,11 @@ const struct flash_info spi_nor_ids[] =
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
{ INFO("w25q256", 0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ {
+ INFO("w25q512", 0xef4020, 0, 64 * 1024, 1024,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+ SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
+ },
{ INFO("w25m512jw", 0xef6119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25m512jv", 0xef7119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25h02jv", 0xef9022, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },

View File

@ -0,0 +1,78 @@
From 793bed29e78cc54d989333d756fef51efaca4e56 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Tue, 26 Jul 2022 09:29:18 +0800
Subject: [PATCH 58/71] mmc: mtk-sd: add support to display verbose error log
Add an option to enable debug log, and also display verbose error log for
both command and data.
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
drivers/mmc/Kconfig | 8 ++++++++
drivers/mmc/Makefile | 4 ++++
drivers/mmc/mtk-sd.c | 24 +++++++++++++++---------
3 files changed, 27 insertions(+), 9 deletions(-)
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -789,6 +789,14 @@ config MMC_MTK
This is needed if support for any SD/SDIO/MMC devices is required.
If unsure, say N.
+config MMC_MTK_DEBUG
+ bool "Display verbose error log"
+ default n
+ depends on MMC_MTK
+ help
+ Enable this option to allow verbose error log being displayed for
+ debugging.
+
endif
config FSL_ESDHC
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -84,3 +84,7 @@ obj-$(CONFIG_RENESAS_SDHI) += tmio-comm
obj-$(CONFIG_MMC_BCM2835) += bcm2835_sdhost.o
obj-$(CONFIG_MMC_MTK) += mtk-sd.o
obj-$(CONFIG_MMC_SDHCI_F_SDH30) += f_sdh30.o
+
+ifdef CONFIG_MMC_MTK_DEBUG
+CFLAGS_mtk-sd.o += -DDEBUG
+endif
--- a/drivers/mmc/mtk-sd.c
+++ b/drivers/mmc/mtk-sd.c
@@ -778,18 +778,24 @@ static int msdc_ops_send_cmd(struct udev
if (cmd_ret &&
!(cmd_ret == -EIO &&
(cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK ||
- cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200)))
+ cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200))) {
+ dev_dbg(dev, "MSDC start command failure with %d, cmd=%d, arg=0x%x\n",
+ cmd_ret, cmd->cmdidx, cmd->cmdarg);
return cmd_ret;
-
- if (data) {
- data_ret = msdc_start_data(host, data);
- if (cmd_ret)
- return cmd_ret;
- else
- return data_ret;
}
- return 0;
+ if (!data)
+ return cmd_ret;
+
+ data_ret = msdc_start_data(host, data);
+ if (cmd_ret)
+ return cmd_ret;
+
+ if (data_ret)
+ dev_dbg(dev, "MSDC start data failure with %d, cmd=%d, arg=0x%x\n",
+ data_ret, cmd->cmdidx, cmd->cmdarg);
+
+ return data_ret;
}
static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks)

View File

@ -0,0 +1,58 @@
From dd66fc817f7ab7a4fcab9836a9251a8f64f329df Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Mon, 25 Jul 2022 16:58:36 +0800
Subject: [PATCH 59/71] cmd: ubi: make volume find/create/remove APIs public
Export ubi_create_vol/ubi_find_volume/ubi_remove_vol to public so that they
can be used by other programs.
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
cmd/ubi.c | 8 ++++----
include/ubi_uboot.h | 4 ++++
2 files changed, 8 insertions(+), 4 deletions(-)
--- a/cmd/ubi.c
+++ b/cmd/ubi.c
@@ -148,8 +148,8 @@ bad:
return err;
}
-static int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id,
- bool skipcheck)
+int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id,
+ bool skipcheck)
{
struct ubi_mkvol_req req;
int err;
@@ -182,7 +182,7 @@ static int ubi_create_vol(char *volume,
return ubi_create_volume(ubi, &req);
}
-static struct ubi_volume *ubi_find_volume(char *volume)
+struct ubi_volume *ubi_find_volume(char *volume)
{
struct ubi_volume *vol = NULL;
int i;
@@ -197,7 +197,7 @@ static struct ubi_volume *ubi_find_volum
return NULL;
}
-static int ubi_remove_vol(char *volume)
+int ubi_remove_vol(char *volume)
{
int err, reserved_pebs, i;
struct ubi_volume *vol;
--- a/include/ubi_uboot.h
+++ b/include/ubi_uboot.h
@@ -73,6 +73,10 @@ extern void ubi_exit(void);
extern int ubi_part(char *part_name, const char *vid_header_offset);
extern int ubi_volume_write(char *volume, void *buf, size_t size);
extern int ubi_volume_read(char *volume, char *buf, size_t size);
+extern int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id,
+ bool skipcheck);
+extern struct ubi_volume *ubi_find_volume(char *volume);
+extern int ubi_remove_vol(char *volume);
extern struct ubi_device *ubi_devices[];
int cmd_ubifs_mount(char *vol_name);

View File

@ -0,0 +1,27 @@
From f6a4130959af1e6d13d616203e42ed3c894666ad Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Mon, 25 Jul 2022 17:00:00 +0800
Subject: [PATCH 60/71] cmd: ubi: allow creating volume with all free spaces
Allow creating volume with all free spaces by giving a negative size value.
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
cmd/ubi.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/cmd/ubi.c
+++ b/cmd/ubi.c
@@ -161,7 +161,11 @@ int ubi_create_vol(char *volume, int64_t
req.vol_id = vol_id;
req.alignment = 1;
- req.bytes = size;
+
+ if (size < 0)
+ req.bytes = ubi->avail_pebs * ubi->leb_size;
+ else
+ req.bytes = size;
strcpy(req.name, volume);
req.name_len = strlen(volume);

View File

@ -0,0 +1,72 @@
From fc0c70a7c6a088072d0c77e5a59d5e9b7754c6db Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Mon, 25 Jul 2022 17:01:20 +0800
Subject: [PATCH 61/71] env: ubi: add support to create environment volume if
it does not exist
Add an option to allow environment volume being auto created if not exist.
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
env/Kconfig | 6 ++++++
env/ubi.c | 20 ++++++++++++++++++++
2 files changed, 26 insertions(+)
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -647,6 +647,12 @@ config ENV_UBI_VOLUME_REDUND
help
Name of the redundant volume that you want to store the environment in.
+config ENV_UBI_VOLUME_CREATE
+ bool "Create UBI volume if not exist"
+ depends on ENV_IS_IN_UBI
+ help
+ Create the UBI volume if it does not exist.
+
config ENV_UBI_VID_OFFSET
int "ubi environment VID offset"
depends on ENV_IS_IN_UBI
--- a/env/ubi.c
+++ b/env/ubi.c
@@ -100,6 +100,18 @@ static int env_ubi_save(void)
#endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */
#endif /* CONFIG_CMD_SAVEENV */
+int __weak env_ubi_volume_create(const char *volume)
+{
+ struct ubi_volume *vol;
+
+ vol = ubi_find_volume((char *)volume);
+ if (vol)
+ return 0;
+
+ return ubi_create_vol((char *)volume, CONFIG_ENV_SIZE, true,
+ UBI_VOL_NUM_AUTO, false);
+}
+
#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
static int env_ubi_load(void)
{
@@ -129,6 +141,11 @@ static int env_ubi_load(void)
return -EIO;
}
+ if (IS_ENABLED(CONFIG_ENV_UBI_VOLUME_CREATE)) {
+ env_ubi_volume_create(CONFIG_ENV_UBI_VOLUME);
+ env_ubi_volume_create(CONFIG_ENV_UBI_VOLUME_REDUND);
+ }
+
read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1,
CONFIG_ENV_SIZE);
if (read1_fail)
@@ -166,6 +183,9 @@ static int env_ubi_load(void)
return -EIO;
}
+ if (IS_ENABLED(CONFIG_ENV_UBI_VOLUME_CREATE))
+ env_ubi_volume_create(CONFIG_ENV_UBI_VOLUME);
+
if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, CONFIG_ENV_SIZE)) {
printf("\n** Unable to read env from %s:%s **\n",
CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);

View File

@ -1,3 +1,18 @@
From 189a2fe96931ef3ea0e187c8e9bfa589c2a0ae10 Mon Sep 17 00:00:00 2001
From: Weijie Gao <weijie.gao@mediatek.com>
Date: Mon, 25 Jul 2022 17:24:56 +0800
Subject: [PATCH 62/71] mtd: ubi: add support for UBI end-of-filesystem marker
used by OpenWrt
Add support for UBI end-of-filesystem marker used by OpenWrt to allow
attaching a new UBI mtd partition just upgraded.
Signed-off-by: Weijie Gao <weijie.gao@mediatek.com>
---
drivers/mtd/ubi/attach.c | 25 ++++++++++++++++++++++---
drivers/mtd/ubi/ubi.h | 1 +
2 files changed, 23 insertions(+), 3 deletions(-)
--- a/drivers/mtd/ubi/attach.c
+++ b/drivers/mtd/ubi/attach.c
@@ -802,6 +802,13 @@ out_unlock:

View File

@ -0,0 +1,26 @@
--- a/include/configs/mt7986.h
+++ b/include/configs/mt7986.h
@@ -11,6 +11,11 @@
#include <linux/sizes.h>
+#define CONFIG_SYS_MAXARGS 32
+#define CONFIG_SYS_BOOTM_LEN SZ_128M
+#define CONFIG_SYS_CBSIZE SZ_1K
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
+ sizeof(CONFIG_SYS_PROMPT) + 16)
#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M
#define CONFIG_SYS_MMC_ENV_DEV 0
@@ -19,6 +24,11 @@
/* SPL -> Uboot */
#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + SZ_2M - \
+ GENERATED_GBL_DATA_SIZE)
+
+/* Flash */
+#define CONFIG_SYS_NAND_MAX_CHIPS 1
/* DRAM */
#define CONFIG_SYS_SDRAM_BASE 0x40000000

View File

@ -0,0 +1,240 @@
From 6792b57b3ba61ca6d69ea4a13a58bed65fc5da87 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Sun, 7 Aug 2022 04:04:46 +0200
Subject: [PATCH] board: mediatek: wire-up NMBM support
---
board/mediatek/mt7622/mt7622_rfb.c | 38 +++++++++++++++++++++
board/mediatek/mt7629/mt7629_rfb.c | 38 +++++++++++++++++++++
board/mediatek/mt7981/mt7981_rfb.c | 52 ++++++++++++++++++++++++++++
board/mediatek/mt7986/mt7986_rfb.c | 54 ++++++++++++++++++++++++++++++
4 files changed, 182 insertions(+)
--- a/board/mediatek/mt7622/mt7622_rfb.c
+++ b/board/mediatek/mt7622/mt7622_rfb.c
@@ -10,6 +10,11 @@
#include <init.h>
#include <asm/global_data.h>
+#include <mtd.h>
+#include <linux/mtd/mtd.h>
+#include <nmbm/nmbm.h>
+#include <nmbm/nmbm-mtd.h>
+
DECLARE_GLOBAL_DATA_PTR;
int board_init(void)
@@ -24,3 +29,36 @@ int board_late_init(void)
env_relocate();
return 0;
}
+
+int board_nmbm_init(void)
+{
+#ifdef CONFIG_ENABLE_NAND_NMBM
+ struct mtd_info *lower, *upper;
+ int ret;
+
+ printf("\n");
+ printf("Initializing NMBM ...\n");
+
+ mtd_probe_devices();
+
+ lower = get_mtd_device_nm("spi-nand0");
+ if (IS_ERR(lower) || !lower) {
+ printf("Lower MTD device 'spi-nand0' not found\n");
+ return 0;
+ }
+
+ ret = nmbm_attach_mtd(lower,
+ NMBM_F_CREATE | NMBM_F_EMPTY_PAGE_ECC_OK,
+ CONFIG_NMBM_MAX_RATIO,
+ CONFIG_NMBM_MAX_BLOCKS, &upper);
+
+ printf("\n");
+
+ if (ret)
+ return 0;
+
+ add_mtd_device(upper);
+#endif
+
+ return 0;
+}
--- a/board/mediatek/mt7629/mt7629_rfb.c
+++ b/board/mediatek/mt7629/mt7629_rfb.c
@@ -6,6 +6,11 @@
#include <common.h>
#include <asm/global_data.h>
+#include <mtd.h>
+#include <linux/mtd/mtd.h>
+#include <nmbm/nmbm.h>
+#include <nmbm/nmbm-mtd.h>
+
DECLARE_GLOBAL_DATA_PTR;
int board_init(void)
@@ -20,3 +25,36 @@ uint32_t spl_nand_get_uboot_raw_page(voi
{
return CONFIG_SPL_PAD_TO;
}
+
+int board_nmbm_init(void)
+{
+#ifdef CONFIG_ENABLE_NAND_NMBM
+ struct mtd_info *lower, *upper;
+ int ret;
+
+ printf("\n");
+ printf("Initializing NMBM ...\n");
+
+ mtd_probe_devices();
+
+ lower = get_mtd_device_nm("spi-nand0");
+ if (IS_ERR(lower) || !lower) {
+ printf("Lower MTD device 'spi-nand0' not found\n");
+ return 0;
+ }
+
+ ret = nmbm_attach_mtd(lower,
+ NMBM_F_CREATE | NMBM_F_EMPTY_PAGE_ECC_OK,
+ CONFIG_NMBM_MAX_RATIO,
+ CONFIG_NMBM_MAX_BLOCKS, &upper);
+
+ printf("\n");
+
+ if (ret)
+ return 0;
+
+ add_mtd_device(upper);
+#endif
+
+ return 0;
+}
--- a/board/mediatek/mt7981/mt7981_rfb.c
+++ b/board/mediatek/mt7981/mt7981_rfb.c
@@ -4,7 +4,59 @@
* Author: Sam Shih <sam.shih@mediatek.com>
*/
+#include <common.h>
+#include <config.h>
+#include <env.h>
+#include <init.h>
+#include <asm/global_data.h>
+
+#include <mtd.h>
+#include <linux/mtd/mtd.h>
+#include <nmbm/nmbm.h>
+#include <nmbm/nmbm-mtd.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
int board_init(void)
{
+ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+ return 0;
+}
+
+int board_late_init(void)
+{
+ gd->env_valid = 1; //to load environment variable from persistent store
+ env_relocate();
+ return 0;
+}
+
+int board_nmbm_init(void)
+{
+#ifdef CONFIG_ENABLE_NAND_NMBM
+ struct mtd_info *lower, *upper;
+ int ret;
+
+ printf("\n");
+ printf("Initializing NMBM ...\n");
+
+ mtd_probe_devices();
+
+ lower = get_mtd_device_nm("spi-nand0");
+ if (IS_ERR(lower) || !lower) {
+ printf("Lower MTD device 'spi-nand0' not found\n");
+ return 0;
+ }
+
+ ret = nmbm_attach_mtd(lower, NMBM_F_CREATE, CONFIG_NMBM_MAX_RATIO,
+ CONFIG_NMBM_MAX_BLOCKS, &upper);
+
+ printf("\n");
+
+ if (ret)
+ return 0;
+
+ add_mtd_device(upper);
+#endif
+
return 0;
}
--- a/board/mediatek/mt7986/mt7986_rfb.c
+++ b/board/mediatek/mt7986/mt7986_rfb.c
@@ -4,7 +4,61 @@
* Author: Sam Shih <sam.shih@mediatek.com>
*/
+#include <common.h>
+#include <config.h>
+#include <env.h>
+#include <init.h>
+#include <asm/global_data.h>
+
+#include <mtd.h>
+#include <linux/mtd/mtd.h>
+#include <nmbm/nmbm.h>
+#include <nmbm/nmbm-mtd.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
int board_init(void)
{
+ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+ return 0;
+}
+
+int board_late_init(void)
+{
+ gd->env_valid = 1; //to load environment variable from persistent store
+ env_relocate();
+ return 0;
+}
+
+int board_nmbm_init(void)
+{
+#ifdef CONFIG_ENABLE_NAND_NMBM
+ struct mtd_info *lower, *upper;
+ int ret;
+
+ printf("\n");
+ printf("Initializing NMBM ...\n");
+
+ mtd_probe_devices();
+
+ lower = get_mtd_device_nm("spi-nand0");
+ if (IS_ERR(lower) || !lower) {
+ printf("Lower MTD device 'spi-nand0' not found\n");
+ return 0;
+ }
+
+ ret = nmbm_attach_mtd(lower,
+ NMBM_F_CREATE | NMBM_F_EMPTY_PAGE_ECC_OK,
+ CONFIG_NMBM_MAX_RATIO,
+ CONFIG_NMBM_MAX_BLOCKS, &upper);
+
+ printf("\n");
+
+ if (ret)
+ return 0;
+
+ add_mtd_device(upper);
+#endif
+
return 0;
}

View File

@ -1,6 +1,6 @@
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -120,7 +120,6 @@ dumpimage-mkimage-objs := aisimage.o \
@@ -121,7 +121,6 @@ dumpimage-mkimage-objs := aisimage.o \
imximage.o \
imx8image.o \
imx8mimage.o \

View File

@ -1,6 +1,6 @@
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -431,7 +431,11 @@ static void menu_display_statusline(stru
@@ -439,7 +439,11 @@ static void menu_display_statusline(stru
printf(ANSI_CURSOR_POSITION, 1, 1);
puts(ANSI_CLEAR_LINE);
printf(ANSI_CURSOR_POSITION, 2, 3);
@ -13,7 +13,7 @@
puts(ANSI_CLEAR_LINE_TO_END);
printf(ANSI_CURSOR_POSITION, 3, 1);
puts(ANSI_CLEAR_LINE);
@@ -516,6 +520,7 @@ static enum bootmenu_ret bootmenu_show(i
@@ -524,6 +528,7 @@ static enum bootmenu_ret bootmenu_show(i
return BOOTMENU_RET_FAIL;
}
@ -23,7 +23,7 @@
goto cleanup;
--- a/include/menu.h
+++ b/include/menu.h
@@ -40,6 +40,7 @@ struct bootmenu_data {
@@ -43,6 +43,7 @@ struct bootmenu_data {
int active; /* active menu entry */
int count; /* total count of menu entries */
struct bootmenu_entry *first; /* first menu entry */

View File

@ -15,7 +15,7 @@
help
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -408,6 +408,60 @@ int do_env_ask(struct cmd_tbl *cmdtp, in
@@ -409,6 +409,60 @@ int do_env_ask(struct cmd_tbl *cmdtp, in
}
#endif
@ -76,7 +76,7 @@
#if defined(CONFIG_CMD_ENV_CALLBACK)
static int print_static_binding(const char *var_name, const char *callback_name,
void *priv)
@@ -1231,6 +1285,9 @@ static struct cmd_tbl cmd_env_sub[] = {
@@ -1232,6 +1286,9 @@ static struct cmd_tbl cmd_env_sub[] = {
U_BOOT_CMD_MKENT(load, 1, 0, do_env_load, "", ""),
#endif
U_BOOT_CMD_MKENT(print, CONFIG_SYS_MAXARGS, 1, do_env_print, "", ""),
@ -86,7 +86,7 @@
#if defined(CONFIG_CMD_RUN)
U_BOOT_CMD_MKENT(run, CONFIG_SYS_MAXARGS, 1, do_run, "", ""),
#endif
@@ -1322,6 +1379,9 @@ static char env_help_text[] =
@@ -1323,6 +1380,9 @@ static char env_help_text[] =
#if defined(CONFIG_CMD_NVEDIT_EFI)
"env print -e [-guid guid] [-n] [name ...] - print UEFI environment\n"
#endif
@ -96,7 +96,7 @@
#if defined(CONFIG_CMD_RUN)
"env run var [...] - run commands in an environment variable\n"
#endif
@@ -1431,6 +1491,17 @@ U_BOOT_CMD(
@@ -1432,6 +1492,17 @@ U_BOOT_CMD(
);
#endif

View File

@ -15,9 +15,9 @@
+#define CONFIG_RESET_BUTTON_LABEL "reset"
+#endif
DECLARE_GLOBAL_DATA_PTR;
@@ -20,7 +27,19 @@ int board_init(void)
#include <mtd.h>
#include <linux/mtd/mtd.h>
@@ -25,7 +32,19 @@ int board_init(void)
int board_late_init(void)
{
@ -40,9 +40,9 @@
}
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -136,4 +136,8 @@ config MTK_BROM_HEADER_INFO
default "media=snand;nandinfo=2k+64" if TARGET_MT7981 || TARGET_MT7986
default "lk=1" if TARGET_MT7623
@@ -138,4 +138,8 @@ config MTK_BROM_HEADER_INFO
source "board/mediatek/mt7629/Kconfig"
+config RESET_BUTTON_LABEL
+ string "Button to trigger factory reset"

View File

@ -1,11 +0,0 @@
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -376,6 +376,8 @@ const struct flash_info spi_nor_ids[] =
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
{ INFO("w25q256", 0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("w25q512jv", 0xef4020, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ |
+ SPI_NOR_HAS_TB | SPI_NOR_HAS_LOCK) },
{ INFO("w25m512jw", 0xef6119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("w25m512jv", 0xef7119, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
#endif

View File

@ -406,7 +406,7 @@
DECLARE_GLOBAL_DATA_PTR;
@@ -392,6 +393,20 @@ static int initr_onenand(void)
@@ -406,6 +407,20 @@ static int initr_onenand(void)
}
#endif
@ -427,9 +427,9 @@
#ifdef CONFIG_MMC
static int initr_mmc(void)
{
@@ -703,6 +718,9 @@ static init_fnc_t init_sequence_r[] = {
#ifdef CONFIG_CMD_ONENAND
initr_onenand,
@@ -720,6 +735,9 @@ static init_fnc_t init_sequence_r[] = {
#ifdef CONFIG_NMBM_MTD
initr_nmbm,
#endif
+#ifdef CONFIG_SPI_FLASH
+ initr_spiflash,