* [PATCH 0/8] SUNIV SPI NAND support in SPL
@ 2022-10-14 3:05 Icenowy Zheng
2022-10-14 3:05 ` [PATCH 1/8] sunxi: SPL SPI: extract code for doing SPI transfer Icenowy Zheng
` (9 more replies)
0 siblings, 10 replies; 22+ messages in thread
From: Icenowy Zheng @ 2022-10-14 3:05 UTC (permalink / raw)
To: Jagan Teki, Andre Przywara, Hans de Goede, Samuel Holland,
Jesse Taube
Cc: u-boot, linux-sunxi, Icenowy Zheng
This patchset tries to extend SPI-based boot code in sunxi SPL to
support SPI NAND, following the same principle with current SPI NOR code
(mimicking the behavior of sunxi BROM). In addition, as part of test to
this patchset, some patches for Source Parts Inc. PopStick is attached,
although marked DO NOT MERGE because the DT should come from Linux after
it's ready.
To keep thr code that accesses SPI NAND as simple as possible, it
assumes fixed page size, which is also what sunxi BROM does. The SUNIV
SPL assumes 0x400 page size, but here to utilize the space better, in
the attached example of PopStick, U-Boot main part is assumed to be
with 0x800 page size (which is the real situation of the W25N01 flash
used by PopStick).
Icenowy Zheng (8):
sunxi: SPL SPI: extract code for doing SPI transfer
sunxi: SPL SPI: add support for read command with 2 byte address
sunxi: SPL SPI: allow multiple boot attempt
sunxi: SPL SPI: add initial support for booting from SPI NAND
sunxi: enable support for SPI NAND booting on SUNIV
[DO NOT MERGE] sunxi: sync DT from my tree for PopStick
[DO NOT MERGE, DIRTY HACK] sunxi: use UBI for environement storage
[DO NOT MERGE] sunxi: add a defconfig for PopStick
arch/arm/dts/Makefile | 3 +-
arch/arm/dts/suniv-f1c100s-licheepi-nano.dts | 16 ++
arch/arm/dts/suniv-f1c100s.dtsi | 26 ++
arch/arm/dts/suniv-f1c200s-popstick-v1.1.dts | 101 ++++++++
arch/arm/mach-sunxi/Kconfig | 16 ++
arch/arm/mach-sunxi/board.c | 4 +-
arch/arm/mach-sunxi/spl_spi_sunxi.c | 247 ++++++++++++++-----
board/sunxi/board.c | 1 +
configs/popstick_defconfig | 35 +++
9 files changed, 377 insertions(+), 72 deletions(-)
create mode 100644 arch/arm/dts/suniv-f1c200s-popstick-v1.1.dts
create mode 100644 configs/popstick_defconfig
--
2.37.1
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 1/8] sunxi: SPL SPI: extract code for doing SPI transfer
2022-10-14 3:05 [PATCH 0/8] SUNIV SPI NAND support in SPL Icenowy Zheng
@ 2022-10-14 3:05 ` Icenowy Zheng
2023-01-14 19:32 ` Samuel Holland
2023-12-12 18:12 ` Andre Przywara
2022-10-14 3:05 ` [PATCH 2/8] sunxi: SPL SPI: add support for read command with 2 byte address Icenowy Zheng
` (8 subsequent siblings)
9 siblings, 2 replies; 22+ messages in thread
From: Icenowy Zheng @ 2022-10-14 3:05 UTC (permalink / raw)
To: Jagan Teki, Andre Przywara, Hans de Goede, Samuel Holland,
Jesse Taube
Cc: u-boot, linux-sunxi, Icenowy Zheng
To support SPI NAND flashes, more commands than Read (03h) are needed.
Extract the code for doing SPI transfer from the reading code for code
reuse.
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
---
arch/arm/mach-sunxi/spl_spi_sunxi.c | 105 ++++++++++++++++------------
1 file changed, 59 insertions(+), 46 deletions(-)
diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
index 925bf85f2d..7975457758 100644
--- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
+++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
@@ -243,77 +243,90 @@ static void spi0_deinit(void)
#define SPI_READ_MAX_SIZE 60 /* FIFO size, minus 4 bytes of the header */
-static void sunxi_spi0_read_data(u8 *buf, u32 addr, u32 bufsize,
- ulong spi_ctl_reg,
- ulong spi_ctl_xch_bitmask,
- ulong spi_fifo_reg,
- ulong spi_tx_reg,
- ulong spi_rx_reg,
- ulong spi_bc_reg,
- ulong spi_tc_reg,
- ulong spi_bcc_reg)
+static void sunxi_spi0_xfer(const u8 *txbuf, u32 txlen,
+ u8 *rxbuf, u32 rxlen,
+ ulong spi_ctl_reg,
+ ulong spi_ctl_xch_bitmask,
+ ulong spi_fifo_reg,
+ ulong spi_tx_reg,
+ ulong spi_rx_reg,
+ ulong spi_bc_reg,
+ ulong spi_tc_reg,
+ ulong spi_bcc_reg)
{
- writel(4 + bufsize, spi_bc_reg); /* Burst counter (total bytes) */
- writel(4, spi_tc_reg); /* Transfer counter (bytes to send) */
+ writel(txlen + rxlen, spi_bc_reg); /* Burst counter (total bytes) */
+ writel(txlen, spi_tc_reg); /* Transfer counter (bytes to send) */
if (spi_bcc_reg)
- writel(4, spi_bcc_reg); /* SUN6I also needs this */
+ writel(txlen, spi_bcc_reg); /* SUN6I also needs this */
- /* Send the Read Data Bytes (03h) command header */
- writeb(0x03, spi_tx_reg);
- writeb((u8)(addr >> 16), spi_tx_reg);
- writeb((u8)(addr >> 8), spi_tx_reg);
- writeb((u8)(addr), spi_tx_reg);
+ for (u32 i = 0; i < txlen; i++)
+ writeb(*(txbuf++), spi_tx_reg);
/* Start the data transfer */
setbits_le32(spi_ctl_reg, spi_ctl_xch_bitmask);
/* Wait until everything is received in the RX FIFO */
- while ((readl(spi_fifo_reg) & 0x7F) < 4 + bufsize)
+ while ((readl(spi_fifo_reg) & 0x7F) < txlen + rxlen)
;
- /* Skip 4 bytes */
- readl(spi_rx_reg);
+ /* Skip txlen bytes */
+ for (u32 i = 0; i < txlen; i++)
+ readb(spi_rx_reg);
/* Read the data */
- while (bufsize-- > 0)
- *buf++ = readb(spi_rx_reg);
+ while (rxlen-- > 0)
+ *rxbuf++ = readb(spi_rx_reg);
+}
+
+static void spi0_xfer(const u8 *txbuf, u32 txlen, u8 *rxbuf, u32 rxlen)
+{
+ uintptr_t base = spi0_base_address();
- /* tSHSL time is up to 100 ns in various SPI flash datasheets */
- udelay(1);
+ if (is_sun6i_gen_spi()) {
+ sunxi_spi0_xfer(txbuf, txlen, rxbuf, rxlen,
+ base + SUN6I_SPI0_TCR,
+ SUN6I_TCR_XCH,
+ base + SUN6I_SPI0_FIFO_STA,
+ base + SUN6I_SPI0_TXD,
+ base + SUN6I_SPI0_RXD,
+ base + SUN6I_SPI0_MBC,
+ base + SUN6I_SPI0_MTC,
+ base + SUN6I_SPI0_BCC);
+ } else {
+ sunxi_spi0_xfer(txbuf, txlen, rxbuf, rxlen,
+ base + SUN4I_SPI0_CTL,
+ SUN4I_CTL_XCH,
+ base + SUN4I_SPI0_FIFO_STA,
+ base + SUN4I_SPI0_TX,
+ base + SUN4I_SPI0_RX,
+ base + SUN4I_SPI0_BC,
+ base + SUN4I_SPI0_TC,
+ 0);
+ }
}
static void spi0_read_data(void *buf, u32 addr, u32 len)
{
u8 *buf8 = buf;
u32 chunk_len;
- uintptr_t base = spi0_base_address();
+ u8 txbuf[4];
while (len > 0) {
chunk_len = len;
+
+ /* Configure the Read Data Bytes (03h) command header */
+ txbuf[0] = 0x03;
+ txbuf[1] = (u8)(addr >> 16);
+ txbuf[2] = (u8)(addr >> 8);
+ txbuf[3] = (u8)(addr);
+
if (chunk_len > SPI_READ_MAX_SIZE)
chunk_len = SPI_READ_MAX_SIZE;
- if (is_sun6i_gen_spi()) {
- sunxi_spi0_read_data(buf8, addr, chunk_len,
- base + SUN6I_SPI0_TCR,
- SUN6I_TCR_XCH,
- base + SUN6I_SPI0_FIFO_STA,
- base + SUN6I_SPI0_TXD,
- base + SUN6I_SPI0_RXD,
- base + SUN6I_SPI0_MBC,
- base + SUN6I_SPI0_MTC,
- base + SUN6I_SPI0_BCC);
- } else {
- sunxi_spi0_read_data(buf8, addr, chunk_len,
- base + SUN4I_SPI0_CTL,
- SUN4I_CTL_XCH,
- base + SUN4I_SPI0_FIFO_STA,
- base + SUN4I_SPI0_TX,
- base + SUN4I_SPI0_RX,
- base + SUN4I_SPI0_BC,
- base + SUN4I_SPI0_TC,
- 0);
- }
+ spi0_xfer(txbuf, 4, buf8, chunk_len);
+
+ /* tSHSL time is up to 100 ns in various SPI flash datasheets */
+ udelay(1);
len -= chunk_len;
buf8 += chunk_len;
--
2.37.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 2/8] sunxi: SPL SPI: add support for read command with 2 byte address
2022-10-14 3:05 [PATCH 0/8] SUNIV SPI NAND support in SPL Icenowy Zheng
2022-10-14 3:05 ` [PATCH 1/8] sunxi: SPL SPI: extract code for doing SPI transfer Icenowy Zheng
@ 2022-10-14 3:05 ` Icenowy Zheng
2023-01-14 19:35 ` Samuel Holland
2022-10-14 3:05 ` [PATCH 3/8] sunxi: SPL SPI: allow multiple boot attempt Icenowy Zheng
` (7 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Icenowy Zheng @ 2022-10-14 3:05 UTC (permalink / raw)
To: Jagan Teki, Andre Przywara, Hans de Goede, Samuel Holland,
Jesse Taube
Cc: u-boot, linux-sunxi, Icenowy Zheng
This kind of read command is utilized in SPI NANDs for reading data
inside a selected page, which is obviously smaller than how much 2
byte address can address. So 2 bytes are used for the address and one
dummy byte is needed after the real address. As the address is sent out
in bit endian, this makes it not compatible with usual 3 byte address.
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
---
arch/arm/mach-sunxi/spl_spi_sunxi.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
index 7975457758..88c15a3ee9 100644
--- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
+++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
@@ -305,7 +305,7 @@ static void spi0_xfer(const u8 *txbuf, u32 txlen, u8 *rxbuf, u32 rxlen)
}
}
-static void spi0_read_data(void *buf, u32 addr, u32 len)
+static void spi0_read_data(void *buf, u32 addr, u32 len, u32 addr_len)
{
u8 *buf8 = buf;
u32 chunk_len;
@@ -316,9 +316,15 @@ static void spi0_read_data(void *buf, u32 addr, u32 len)
/* Configure the Read Data Bytes (03h) command header */
txbuf[0] = 0x03;
- txbuf[1] = (u8)(addr >> 16);
- txbuf[2] = (u8)(addr >> 8);
- txbuf[3] = (u8)(addr);
+ if (addr_len == 3) {
+ txbuf[1] = (u8)(addr >> 16);
+ txbuf[2] = (u8)(addr >> 8);
+ txbuf[3] = (u8)(addr);
+ } else if (addr_len == 2) {
+ txbuf[1] = (u8)(addr >> 8);
+ txbuf[2] = (u8)(addr);
+ txbuf[3] = 0; /* dummy */
+ }
if (chunk_len > SPI_READ_MAX_SIZE)
chunk_len = SPI_READ_MAX_SIZE;
@@ -337,7 +343,7 @@ static void spi0_read_data(void *buf, u32 addr, u32 len)
static ulong spi_load_read(struct spl_load_info *load, ulong sector,
ulong count, void *buf)
{
- spi0_read_data(buf, sector, count);
+ spi0_read_data(buf, sector, count, 3);
return count;
}
@@ -356,7 +362,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image,
spi0_init();
- spi0_read_data((void *)header, load_offset, 0x40);
+ spi0_read_data((void *)header, load_offset, 0x40, 3);
if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
image_get_magic(header) == FDT_MAGIC) {
@@ -376,7 +382,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image,
return ret;
spi0_read_data((void *)spl_image->load_addr,
- load_offset, spl_image->size);
+ load_offset, spl_image->size, 3);
}
spi0_deinit();
--
2.37.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 3/8] sunxi: SPL SPI: allow multiple boot attempt
2022-10-14 3:05 [PATCH 0/8] SUNIV SPI NAND support in SPL Icenowy Zheng
2022-10-14 3:05 ` [PATCH 1/8] sunxi: SPL SPI: extract code for doing SPI transfer Icenowy Zheng
2022-10-14 3:05 ` [PATCH 2/8] sunxi: SPL SPI: add support for read command with 2 byte address Icenowy Zheng
@ 2022-10-14 3:05 ` Icenowy Zheng
2023-01-14 19:56 ` Samuel Holland
2022-10-14 3:05 ` [PATCH 4/8] sunxi: SPL SPI: add initial support for booting from SPI NAND Icenowy Zheng
` (6 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Icenowy Zheng @ 2022-10-14 3:05 UTC (permalink / raw)
To: Jagan Teki, Andre Przywara, Hans de Goede, Samuel Holland,
Jesse Taube
Cc: u-boot, linux-sunxi, Icenowy Zheng
As we're going to add support for SPI NAND to this code, add code that
allows multiple boot attempts with different load offsets and functions.
To keep compatibility with loading raw binary on SPI NOR, a bool
parameter is used to allow booting without valid magic number when
booting with SPI NOR.
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
---
arch/arm/mach-sunxi/spl_spi_sunxi.c | 58 +++++++++++++++++++----------
1 file changed, 38 insertions(+), 20 deletions(-)
diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
index 88c15a3ee9..21be33a23f 100644
--- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
+++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
@@ -340,8 +340,8 @@ static void spi0_read_data(void *buf, u32 addr, u32 len, u32 addr_len)
}
}
-static ulong spi_load_read(struct spl_load_info *load, ulong sector,
- ulong count, void *buf)
+static ulong spi_load_read_nor(struct spl_load_info *load, ulong sector,
+ ulong count, void *buf)
{
spi0_read_data(buf, sector, count, 3);
@@ -350,41 +350,59 @@ static ulong spi_load_read(struct spl_load_info *load, ulong sector,
/*****************************************************************************/
-static int spl_spi_load_image(struct spl_image_info *spl_image,
- struct spl_boot_device *bootdev)
+static int spl_spi_try_load(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev,
+ struct spl_load_info *load, u32 offset,
+ bool allow_raw)
{
int ret = 0;
struct legacy_img_hdr *header;
- uint32_t load_offset = sunxi_get_spl_size();
-
header = (struct legacy_img_hdr *)CONFIG_SYS_TEXT_BASE;
- load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
-
- spi0_init();
- spi0_read_data((void *)header, load_offset, 0x40, 3);
+ if (load->read(load, offset, 0x40, (void *)header) == 0)
+ return -EINVAL;
if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
image_get_magic(header) == FDT_MAGIC) {
- struct spl_load_info load;
debug("Found FIT image\n");
- load.dev = NULL;
- load.priv = NULL;
- load.filename = NULL;
- load.bl_len = 1;
- load.read = spi_load_read;
- ret = spl_load_simple_fit(spl_image, &load,
- load_offset, header);
+ ret = spl_load_simple_fit(spl_image, load,
+ offset, header);
} else {
+ if (!allow_raw && image_get_magic(header) != IH_MAGIC)
+ return -EINVAL;
+
ret = spl_parse_image_header(spl_image, bootdev, header);
if (ret)
return ret;
- spi0_read_data((void *)spl_image->load_addr,
- load_offset, spl_image->size, 3);
+ if (load->read(load, offset, spl_image->size,
+ (void *)spl_image->load_addr) == 0)
+ ret = -EINVAL;
}
+ return ret;
+}
+
+static int spl_spi_load_image(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ int ret = 0;
+ uint32_t load_offset = sunxi_get_spl_size();
+ struct spl_load_info load;
+
+ load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
+
+ load.dev = NULL;
+ load.priv = NULL;
+ load.filename = NULL;
+ load.bl_len = 1;
+
+ spi0_init();
+
+ load.read = spi_load_read_nor;
+ ret = spl_spi_try_load(spl_image, bootdev, &load, load_offset, true);
+
spi0_deinit();
return ret;
--
2.37.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 4/8] sunxi: SPL SPI: add initial support for booting from SPI NAND
2022-10-14 3:05 [PATCH 0/8] SUNIV SPI NAND support in SPL Icenowy Zheng
` (2 preceding siblings ...)
2022-10-14 3:05 ` [PATCH 3/8] sunxi: SPL SPI: allow multiple boot attempt Icenowy Zheng
@ 2022-10-14 3:05 ` Icenowy Zheng
2023-01-14 20:08 ` Samuel Holland
2022-10-14 3:05 ` [PATCH 5/8] sunxi: enable support for SPI NAND booting on SUNIV Icenowy Zheng
` (5 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Icenowy Zheng @ 2022-10-14 3:05 UTC (permalink / raw)
To: Jagan Teki, Andre Przywara, Hans de Goede, Samuel Holland,
Jesse Taube
Cc: u-boot, linux-sunxi, Icenowy Zheng
This commit adds support for booting from SPI NAND to SPL SPI code by
mimicing the behavior of boot ROM (use fixed page size and sequentially
try SPI NOR and NAND).
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
---
arch/arm/mach-sunxi/Kconfig | 16 +++++++
arch/arm/mach-sunxi/spl_spi_sunxi.c | 74 +++++++++++++++++++++++++++++
2 files changed, 90 insertions(+)
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 840bbc19b3..6afbb4acb5 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -1018,6 +1018,22 @@ config SPL_SPI_SUNXI
sunxi SPI Flash. It uses the same method as the boot ROM, so does
not need any extra configuration.
+config SPL_SPI_SUNXI_NAND
+ bool "Support for SPI NAND Flash on Allwinner SoCs in SPL"
+ depends on SPL_SPI_SUNXI
+ help
+ Enable support for SPI NAND Flash. This option allows SPL to mimic
+ Allwinner boot ROM's behavior to gain support for SPI NAND Flash;
+ a fixed page size needs to be assumed when building the SPL image.
+
+config SPL_SPI_SUNXI_NAND_ASSUMED_PAGESIZE
+ hex "Assumed pagesize for SPI NAND Flash in SPL"
+ depends on SPL_SPI_SUNXI_NAND
+ default 0x400 if MACH_SUNIV
+ help
+ Set the page size assumed by the SPL SPI NAND code, the default
+ value is the same with the boot ROM.
+
config PINE64_DT_SELECTION
bool "Enable Pine64 device tree selection code"
depends on MACH_SUN50I
diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
index 21be33a23f..5178908327 100644
--- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
+++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
@@ -305,6 +305,49 @@ static void spi0_xfer(const u8 *txbuf, u32 txlen, u8 *rxbuf, u32 rxlen)
}
}
+#if defined(CONFIG_SPL_SPI_SUNXI_NAND)
+static int spi0_nand_switch_page(u32 page)
+{
+ unsigned count;
+ u8 buf[4];
+
+ /* Configure the Page Data Read (13h) command header */
+ buf[0] = 0x13;
+ buf[1] = (u8)(page >> 16);
+ buf[2] = (u8)(page >> 8);
+ buf[3] = (u8)(page);
+
+ spi0_xfer(buf, 4, NULL, 0);
+
+ /* Wait for NAND chip to exit busy state */
+ buf[0] = 0x0f;
+ buf[1] = 0xc0;
+
+ /* Load a NAND page can take up to 2-decimal-digit microseconds */
+ for (count = 0; count < 100; count ++) {
+ udelay(1);
+ spi0_xfer(buf, 2, buf+2, 1);
+ if (!(buf[2] & 0x1))
+ return 0;
+ }
+
+ return -ETIMEDOUT;
+}
+
+static void spi0_nand_reset(void)
+{
+ u8 buf[1];
+
+ /* Configure the Device RESET (ffh) command */
+ buf[0] = 0xff;
+
+ spi0_xfer(buf, 1, NULL, 0);
+
+ /* Wait for the NAND to finish resetting */
+ udelay(10);
+}
+#endif
+
static void spi0_read_data(void *buf, u32 addr, u32 len, u32 addr_len)
{
u8 *buf8 = buf;
@@ -348,6 +391,28 @@ static ulong spi_load_read_nor(struct spl_load_info *load, ulong sector,
return count;
}
+#if defined(CONFIG_SPL_SPI_SUNXI_NAND)
+static ulong spi_load_read_nand(struct spl_load_info *load, ulong sector,
+ ulong count, void *buf)
+{
+ const ulong pagesize = CONFIG_SPL_SPI_SUNXI_NAND_ASSUMED_PAGESIZE;
+ ulong remain = count;
+
+ while (remain) {
+ ulong count_in_page = min(remain, pagesize - (sector % pagesize));
+ ulong current_page = sector / pagesize;
+ if (spi0_nand_switch_page(current_page) != 0)
+ return 0;
+ spi0_read_data(buf, sector % pagesize, count_in_page, 2);
+ remain -= count_in_page;
+ sector += count_in_page;
+ buf += count_in_page;
+ }
+
+ return count;
+}
+#endif
+
/*****************************************************************************/
static int spl_spi_try_load(struct spl_image_info *spl_image,
@@ -400,9 +465,18 @@ static int spl_spi_load_image(struct spl_image_info *spl_image,
spi0_init();
+#if defined(CONFIG_SPL_SPI_SUNXI_NAND)
+ spi0_nand_reset();
+ load.read = spi_load_read_nand;
+ ret = spl_spi_try_load(spl_image, bootdev, &load, load_offset, false);
+ if (!ret)
+ goto out;
+#endif
+
load.read = spi_load_read_nor;
ret = spl_spi_try_load(spl_image, bootdev, &load, load_offset, true);
+out:
spi0_deinit();
return ret;
--
2.37.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 5/8] sunxi: enable support for SPI NAND booting on SUNIV
2022-10-14 3:05 [PATCH 0/8] SUNIV SPI NAND support in SPL Icenowy Zheng
` (3 preceding siblings ...)
2022-10-14 3:05 ` [PATCH 4/8] sunxi: SPL SPI: add initial support for booting from SPI NAND Icenowy Zheng
@ 2022-10-14 3:05 ` Icenowy Zheng
2023-01-14 20:18 ` Samuel Holland
2022-10-14 3:05 ` [PATCH 6/8] [DO NOT MERGE] sunxi: sync DT from my tree for PopStick Icenowy Zheng
` (4 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Icenowy Zheng @ 2022-10-14 3:05 UTC (permalink / raw)
To: Jagan Teki, Andre Przywara, Hans de Goede, Samuel Holland,
Jesse Taube
Cc: u-boot, linux-sunxi, Icenowy Zheng
As we added support for SPI NAND to the existing SPL SPI codepath, route
the boot code to it when it detects the BROM loads SPL from SPI NAND, as
for SoCs with both SPI NAND and boot media indicator support, the boot
media indicator is the same for SPI NOR and NAND.
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
---
arch/arm/mach-sunxi/board.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 220ed80ba7..3a81743e8f 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -210,12 +210,10 @@ static int suniv_get_boot_source(void)
case SUNIV_BOOTED_FROM_MMC0:
return SUNXI_BOOTED_FROM_MMC0;
case SUNIV_BOOTED_FROM_SPI:
+ case SUNIV_BOOTED_FROM_NAND:
return SUNXI_BOOTED_FROM_SPI;
case SUNIV_BOOTED_FROM_MMC1:
return SUNXI_BOOTED_FROM_MMC2;
- /* SPI NAND is not supported yet. */
- case SUNIV_BOOTED_FROM_NAND:
- return SUNXI_INVALID_BOOT_SOURCE;
}
/* If we get here something went wrong try to boot from FEL.*/
printf("Unknown boot source from BROM: 0x%x\n", brom_call);
--
2.37.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 6/8] [DO NOT MERGE] sunxi: sync DT from my tree for PopStick
2022-10-14 3:05 [PATCH 0/8] SUNIV SPI NAND support in SPL Icenowy Zheng
` (4 preceding siblings ...)
2022-10-14 3:05 ` [PATCH 5/8] sunxi: enable support for SPI NAND booting on SUNIV Icenowy Zheng
@ 2022-10-14 3:05 ` Icenowy Zheng
2022-10-14 3:05 ` [PATCH 7/8] [DO NOT MERGE, DIRTY HACK] sunxi: use UBI for environement storage Icenowy Zheng
` (3 subsequent siblings)
9 siblings, 0 replies; 22+ messages in thread
From: Icenowy Zheng @ 2022-10-14 3:05 UTC (permalink / raw)
To: Jagan Teki, Andre Przywara, Hans de Goede, Samuel Holland,
Jesse Taube
Cc: u-boot, linux-sunxi, Icenowy Zheng
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
---
arch/arm/dts/Makefile | 3 +-
arch/arm/dts/suniv-f1c100s-licheepi-nano.dts | 16 +++
arch/arm/dts/suniv-f1c100s.dtsi | 26 +++++
arch/arm/dts/suniv-f1c200s-popstick-v1.1.dts | 101 +++++++++++++++++++
4 files changed, 145 insertions(+), 1 deletion(-)
create mode 100644 arch/arm/dts/suniv-f1c200s-popstick-v1.1.dts
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 9b00b64509..ef7fff3559 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -529,7 +529,8 @@ dtb-$(CONFIG_STM32H7) += stm32h743i-disco.dtb \
stm32h750i-art-pi.dtb
dtb-$(CONFIG_MACH_SUNIV) += \
- suniv-f1c100s-licheepi-nano.dtb
+ suniv-f1c100s-licheepi-nano.dtb \
+ suniv-f1c200s-popstick-v1.1.dtb
dtb-$(CONFIG_MACH_SUN4I) += \
sun4i-a10-a1000.dtb \
sun4i-a10-ba10-tvbox.dtb \
diff --git a/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts b/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts
index 04e59b8381..1935d8c885 100644
--- a/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts
+++ b/arch/arm/dts/suniv-f1c100s-licheepi-nano.dts
@@ -6,6 +6,8 @@
/dts-v1/;
#include "suniv-f1c100s.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
/ {
model = "Lichee Pi Nano";
compatible = "licheepi,licheepi-nano", "allwinner,suniv-f1c100s";
@@ -50,8 +52,22 @@
};
};
+&otg_sram {
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pe_pins>;
status = "okay";
};
+
+&usb_otg {
+ dr_mode = "otg";
+ status = "okay";
+};
+
+&usbphy {
+ usb0_id_det-gpio = <&pio 4 2 GPIO_ACTIVE_HIGH>; /* PE2 */
+ status = "okay";
+};
diff --git a/arch/arm/dts/suniv-f1c100s.dtsi b/arch/arm/dts/suniv-f1c100s.dtsi
index bc563c12e9..6d7b120da2 100644
--- a/arch/arm/dts/suniv-f1c100s.dtsi
+++ b/arch/arm/dts/suniv-f1c100s.dtsi
@@ -133,6 +133,32 @@
#size-cells = <0>;
};
+ usb_otg: usb@1c13000 {
+ compatible = "allwinner,suniv-f1c100s-musb";
+ reg = <0x01c13000 0x0400>;
+ clocks = <&ccu CLK_BUS_OTG>;
+ resets = <&ccu RST_BUS_OTG>;
+ interrupts = <26>;
+ interrupt-names = "mc";
+ phys = <&usbphy 0>;
+ phy-names = "usb";
+ extcon = <&usbphy 0>;
+ allwinner,sram = <&otg_sram 1>;
+ status = "disabled";
+ };
+
+ usbphy: phy@1c13400 {
+ compatible = "allwinner,suniv-f1c100s-usb-phy";
+ reg = <0x01c13400 0x10>;
+ reg-names = "phy_ctrl";
+ clocks = <&ccu CLK_USB_PHY0>;
+ clock-names = "usb0_phy";
+ resets = <&ccu RST_USB_PHY0>;
+ reset-names = "usb0_reset";
+ #phy-cells = <1>;
+ status = "disabled";
+ };
+
ccu: clock@1c20000 {
compatible = "allwinner,suniv-f1c100s-ccu";
reg = <0x01c20000 0x400>;
diff --git a/arch/arm/dts/suniv-f1c200s-popstick-v1.1.dts b/arch/arm/dts/suniv-f1c200s-popstick-v1.1.dts
new file mode 100644
index 0000000000..121dfc6f60
--- /dev/null
+++ b/arch/arm/dts/suniv-f1c200s-popstick-v1.1.dts
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022 Icenowy Zheng <uwu@icenowy.me>
+ */
+
+/dts-v1/;
+#include "suniv-f1c100s.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+ model = "Popcorn Computer PopStick v1.1";
+ compatible = "sourceparts,popstick-v1.1", "sourceparts,popstick",
+ "allwinner,suniv-f1c200s", "allwinner,suniv-f1c100s";
+
+ aliases {
+ mmc0 = &mmc0;
+ serial0 = &uart0;
+ spi0 = &spi0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led {
+ function = LED_FUNCTION_STATUS;
+ color = <LED_COLOR_ID_GREEN>;
+ gpios = <&pio 4 6 GPIO_ACTIVE_HIGH>; /* PE6 */
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ reg_vcc3v3: vcc3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&mmc0 {
+ cd-gpios = <&pio 4 3 GPIO_ACTIVE_LOW>; /* PE3 */
+ bus-width = <4>;
+ disable-wp;
+ status = "okay";
+ vmmc-supply = <®_vcc3v3>;
+};
+
+&spi0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pc_pins>;
+ status = "okay";
+
+ flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-nand";
+ reg = <0>;
+ spi-max-frequency = <40000000>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot-with-spl";
+ reg = <0x0 0x100000>;
+ };
+
+ ubi@100000 {
+ label = "ubi";
+ reg = <0x100000 0x7f00000>;
+ };
+ };
+ };
+};
+
+&otg_sram {
+ status = "okay";
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pe_pins>;
+ status = "okay";
+};
+
+&usb_otg {
+ dr_mode = "peripheral";
+ status = "okay";
+};
+
+&usbphy {
+ status = "okay";
+};
--
2.37.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 7/8] [DO NOT MERGE, DIRTY HACK] sunxi: use UBI for environement storage
2022-10-14 3:05 [PATCH 0/8] SUNIV SPI NAND support in SPL Icenowy Zheng
` (5 preceding siblings ...)
2022-10-14 3:05 ` [PATCH 6/8] [DO NOT MERGE] sunxi: sync DT from my tree for PopStick Icenowy Zheng
@ 2022-10-14 3:05 ` Icenowy Zheng
2023-01-15 17:19 ` Icenowy Zheng
2022-10-14 3:05 ` [PATCH 8/8] [DO NOT MERGE] sunxi: add a defconfig for PopStick Icenowy Zheng
` (2 subsequent siblings)
9 siblings, 1 reply; 22+ messages in thread
From: Icenowy Zheng @ 2022-10-14 3:05 UTC (permalink / raw)
To: Jagan Teki, Andre Przywara, Hans de Goede, Samuel Holland,
Jesse Taube
Cc: u-boot, linux-sunxi, Icenowy Zheng
Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
---
board/sunxi/board.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 21a2407e06..f4138573d4 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -133,6 +133,7 @@ void i2c_init_board(void)
*/
enum env_location env_get_location(enum env_operation op, int prio)
{
+ return prio ? ENVL_UNKNOWN : ENVL_UBI;
if (prio > 1)
return ENVL_UNKNOWN;
--
2.37.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 8/8] [DO NOT MERGE] sunxi: add a defconfig for PopStick
2022-10-14 3:05 [PATCH 0/8] SUNIV SPI NAND support in SPL Icenowy Zheng
` (6 preceding siblings ...)
2022-10-14 3:05 ` [PATCH 7/8] [DO NOT MERGE, DIRTY HACK] sunxi: use UBI for environement storage Icenowy Zheng
@ 2022-10-14 3:05 ` Icenowy Zheng
2023-06-05 21:03 ` [PATCH 0/8] SUNIV SPI NAND support in SPL Sam Edwards
2024-04-11 4:32 ` John Watts
9 siblings, 0 replies; 22+ messages in thread
From: Icenowy Zheng @ 2022-10-14 3:05 UTC (permalink / raw)
To: Jagan Teki, Andre Przywara, Hans de Goede, Samuel Holland,
Jesse Taube
Cc: u-boot, linux-sunxi, Icenowy Zheng
---
configs/popstick_defconfig | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
create mode 100644 configs/popstick_defconfig
diff --git a/configs/popstick_defconfig b/configs/popstick_defconfig
new file mode 100644
index 0000000000..6dc21695b7
--- /dev/null
+++ b/configs/popstick_defconfig
@@ -0,0 +1,35 @@
+CONFIG_ARM=y
+CONFIG_ARCH_SUNXI=y
+CONFIG_SYS_MALLOC_LEN=0x120000
+CONFIG_ENV_SIZE=0x1f000
+CONFIG_DEFAULT_DEVICE_TREE="suniv-f1c200s-popstick-v1.1"
+CONFIG_SPL=y
+CONFIG_MACH_SUNIV=y
+CONFIG_DRAM_CLK=156
+CONFIG_DRAM_ZQ=0
+CONFIG_SUNXI_MINIMUM_DRAM_MB=64
+CONFIG_MMC0_CD_PIN="PE3"
+# CONFIG_VIDEO_SUNXI is not set
+CONFIG_SPL_SPI_SUNXI=y
+CONFIG_SPL_SPI_SUNXI_NAND=y
+CONFIG_SPL_SPI_SUNXI_NAND_ASSUMED_PAGESIZE=0x800
+CONFIG_SPL_STACK=0x8000
+CONFIG_SYS_SPI_U_BOOT_OFFS=0x20000
+CONFIG_CMD_MTD=y
+# CONFIG_CMD_SF is not set
+CONFIG_CMD_MTDPARTS=y
+CONFIG_CMD_UBI=y
+# CONFIG_ENV_IS_IN_FAT is not set
+# CONFIG_ENV_IS_IN_SPI_FLASH is not set
+CONFIG_ENV_IS_IN_UBI=y
+CONFIG_ENV_UBI_PART="ubi"
+CONFIG_ENV_UBI_VOLUME="env"
+# CONFIG_NET is not set
+CONFIG_MTD=y
+CONFIG_DM_MTD=y
+CONFIG_MTD_SPI_NAND=y
+# CONFIG_SPI_FLASH is not set
+CONFIG_SF_DEFAULT_SPEED=25000000
+# CONFIG_UBI_SILENCE_MSG is not set
+CONFIG_SPI=y
+# CONFIG_UBIFS_SILENCE_MSG is not set
--
2.37.1
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 1/8] sunxi: SPL SPI: extract code for doing SPI transfer
2022-10-14 3:05 ` [PATCH 1/8] sunxi: SPL SPI: extract code for doing SPI transfer Icenowy Zheng
@ 2023-01-14 19:32 ` Samuel Holland
2023-12-12 18:12 ` Andre Przywara
1 sibling, 0 replies; 22+ messages in thread
From: Samuel Holland @ 2023-01-14 19:32 UTC (permalink / raw)
To: Icenowy Zheng, Jagan Teki, Andre Przywara, Hans de Goede,
Jesse Taube
Cc: u-boot, linux-sunxi
On 10/13/22 22:05, Icenowy Zheng wrote:
> To support SPI NAND flashes, more commands than Read (03h) are needed.
>
> Extract the code for doing SPI transfer from the reading code for code
> reuse.
>
> Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
One comment below.
Reviewed-by: Samuel Holland <samuel@sholland.org>
Tested-by: Samuel Holland <samuel@sholland.org> # Orange Pi Zero Plus
> ---
> arch/arm/mach-sunxi/spl_spi_sunxi.c | 105 ++++++++++++++++------------
> 1 file changed, 59 insertions(+), 46 deletions(-)
>
> diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
> index 925bf85f2d..7975457758 100644
> --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
> +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
> @@ -243,77 +243,90 @@ static void spi0_deinit(void)
>
> #define SPI_READ_MAX_SIZE 60 /* FIFO size, minus 4 bytes of the header */
>
> -static void sunxi_spi0_read_data(u8 *buf, u32 addr, u32 bufsize,
> - ulong spi_ctl_reg,
> - ulong spi_ctl_xch_bitmask,
> - ulong spi_fifo_reg,
> - ulong spi_tx_reg,
> - ulong spi_rx_reg,
> - ulong spi_bc_reg,
> - ulong spi_tc_reg,
> - ulong spi_bcc_reg)
> +static void sunxi_spi0_xfer(const u8 *txbuf, u32 txlen,
> + u8 *rxbuf, u32 rxlen,
> + ulong spi_ctl_reg,
> + ulong spi_ctl_xch_bitmask,
> + ulong spi_fifo_reg,
> + ulong spi_tx_reg,
> + ulong spi_rx_reg,
> + ulong spi_bc_reg,
> + ulong spi_tc_reg,
> + ulong spi_bcc_reg)
> {
> - writel(4 + bufsize, spi_bc_reg); /* Burst counter (total bytes) */
> - writel(4, spi_tc_reg); /* Transfer counter (bytes to send) */
> + writel(txlen + rxlen, spi_bc_reg); /* Burst counter (total bytes) */
> + writel(txlen, spi_tc_reg); /* Transfer counter (bytes to send) */
> if (spi_bcc_reg)
> - writel(4, spi_bcc_reg); /* SUN6I also needs this */
> + writel(txlen, spi_bcc_reg); /* SUN6I also needs this */
>
> - /* Send the Read Data Bytes (03h) command header */
> - writeb(0x03, spi_tx_reg);
> - writeb((u8)(addr >> 16), spi_tx_reg);
> - writeb((u8)(addr >> 8), spi_tx_reg);
> - writeb((u8)(addr), spi_tx_reg);
> + for (u32 i = 0; i < txlen; i++)
> + writeb(*(txbuf++), spi_tx_reg);
I think txbuf[i] would be a bit clearer here.
Regards,
Samuel
>
> /* Start the data transfer */
> setbits_le32(spi_ctl_reg, spi_ctl_xch_bitmask);
>
> /* Wait until everything is received in the RX FIFO */
> - while ((readl(spi_fifo_reg) & 0x7F) < 4 + bufsize)
> + while ((readl(spi_fifo_reg) & 0x7F) < txlen + rxlen)
> ;
>
> - /* Skip 4 bytes */
> - readl(spi_rx_reg);
> + /* Skip txlen bytes */
> + for (u32 i = 0; i < txlen; i++)
> + readb(spi_rx_reg);
>
> /* Read the data */
> - while (bufsize-- > 0)
> - *buf++ = readb(spi_rx_reg);
> + while (rxlen-- > 0)
> + *rxbuf++ = readb(spi_rx_reg);
> +}
> +
> +static void spi0_xfer(const u8 *txbuf, u32 txlen, u8 *rxbuf, u32 rxlen)
> +{
> + uintptr_t base = spi0_base_address();
>
> - /* tSHSL time is up to 100 ns in various SPI flash datasheets */
> - udelay(1);
> + if (is_sun6i_gen_spi()) {
> + sunxi_spi0_xfer(txbuf, txlen, rxbuf, rxlen,
> + base + SUN6I_SPI0_TCR,
> + SUN6I_TCR_XCH,
> + base + SUN6I_SPI0_FIFO_STA,
> + base + SUN6I_SPI0_TXD,
> + base + SUN6I_SPI0_RXD,
> + base + SUN6I_SPI0_MBC,
> + base + SUN6I_SPI0_MTC,
> + base + SUN6I_SPI0_BCC);
> + } else {
> + sunxi_spi0_xfer(txbuf, txlen, rxbuf, rxlen,
> + base + SUN4I_SPI0_CTL,
> + SUN4I_CTL_XCH,
> + base + SUN4I_SPI0_FIFO_STA,
> + base + SUN4I_SPI0_TX,
> + base + SUN4I_SPI0_RX,
> + base + SUN4I_SPI0_BC,
> + base + SUN4I_SPI0_TC,
> + 0);
> + }
> }
>
> static void spi0_read_data(void *buf, u32 addr, u32 len)
> {
> u8 *buf8 = buf;
> u32 chunk_len;
> - uintptr_t base = spi0_base_address();
> + u8 txbuf[4];
>
> while (len > 0) {
> chunk_len = len;
> +
> + /* Configure the Read Data Bytes (03h) command header */
> + txbuf[0] = 0x03;
> + txbuf[1] = (u8)(addr >> 16);
> + txbuf[2] = (u8)(addr >> 8);
> + txbuf[3] = (u8)(addr);
> +
> if (chunk_len > SPI_READ_MAX_SIZE)
> chunk_len = SPI_READ_MAX_SIZE;
>
> - if (is_sun6i_gen_spi()) {
> - sunxi_spi0_read_data(buf8, addr, chunk_len,
> - base + SUN6I_SPI0_TCR,
> - SUN6I_TCR_XCH,
> - base + SUN6I_SPI0_FIFO_STA,
> - base + SUN6I_SPI0_TXD,
> - base + SUN6I_SPI0_RXD,
> - base + SUN6I_SPI0_MBC,
> - base + SUN6I_SPI0_MTC,
> - base + SUN6I_SPI0_BCC);
> - } else {
> - sunxi_spi0_read_data(buf8, addr, chunk_len,
> - base + SUN4I_SPI0_CTL,
> - SUN4I_CTL_XCH,
> - base + SUN4I_SPI0_FIFO_STA,
> - base + SUN4I_SPI0_TX,
> - base + SUN4I_SPI0_RX,
> - base + SUN4I_SPI0_BC,
> - base + SUN4I_SPI0_TC,
> - 0);
> - }
> + spi0_xfer(txbuf, 4, buf8, chunk_len);
> +
> + /* tSHSL time is up to 100 ns in various SPI flash datasheets */
> + udelay(1);
>
> len -= chunk_len;
> buf8 += chunk_len;
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/8] sunxi: SPL SPI: add support for read command with 2 byte address
2022-10-14 3:05 ` [PATCH 2/8] sunxi: SPL SPI: add support for read command with 2 byte address Icenowy Zheng
@ 2023-01-14 19:35 ` Samuel Holland
0 siblings, 0 replies; 22+ messages in thread
From: Samuel Holland @ 2023-01-14 19:35 UTC (permalink / raw)
To: Icenowy Zheng, Jagan Teki, Andre Przywara, Hans de Goede,
Jesse Taube
Cc: u-boot, linux-sunxi
On 10/13/22 22:05, Icenowy Zheng wrote:
> This kind of read command is utilized in SPI NANDs for reading data
> inside a selected page, which is obviously smaller than how much 2
> byte address can address. So 2 bytes are used for the address and one
> dummy byte is needed after the real address. As the address is sent out
> in bit endian, this makes it not compatible with usual 3 byte address.
typo: big
> Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
> ---
> arch/arm/mach-sunxi/spl_spi_sunxi.c | 20 +++++++++++++-------
> 1 file changed, 13 insertions(+), 7 deletions(-)
Reviewed-by: Samuel Holland <samuel@sholland.org>
Tested-by: Samuel Holland <samuel@sholland.org> # Orange Pi Zero Plus
> diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
> index 7975457758..88c15a3ee9 100644
> --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
> +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
> @@ -305,7 +305,7 @@ static void spi0_xfer(const u8 *txbuf, u32 txlen, u8 *rxbuf, u32 rxlen)
> }
> }
>
> -static void spi0_read_data(void *buf, u32 addr, u32 len)
> +static void spi0_read_data(void *buf, u32 addr, u32 len, u32 addr_len)
> {
> u8 *buf8 = buf;
> u32 chunk_len;
> @@ -316,9 +316,15 @@ static void spi0_read_data(void *buf, u32 addr, u32 len)
>
> /* Configure the Read Data Bytes (03h) command header */
> txbuf[0] = 0x03;
> - txbuf[1] = (u8)(addr >> 16);
> - txbuf[2] = (u8)(addr >> 8);
> - txbuf[3] = (u8)(addr);
> + if (addr_len == 3) {
> + txbuf[1] = (u8)(addr >> 16);
> + txbuf[2] = (u8)(addr >> 8);
> + txbuf[3] = (u8)(addr);
> + } else if (addr_len == 2) {
> + txbuf[1] = (u8)(addr >> 8);
> + txbuf[2] = (u8)(addr);
> + txbuf[3] = 0; /* dummy */
> + }
>
> if (chunk_len > SPI_READ_MAX_SIZE)
> chunk_len = SPI_READ_MAX_SIZE;
> @@ -337,7 +343,7 @@ static void spi0_read_data(void *buf, u32 addr, u32 len)
> static ulong spi_load_read(struct spl_load_info *load, ulong sector,
> ulong count, void *buf)
> {
> - spi0_read_data(buf, sector, count);
> + spi0_read_data(buf, sector, count, 3);
>
> return count;
> }
> @@ -356,7 +362,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image,
>
> spi0_init();
>
> - spi0_read_data((void *)header, load_offset, 0x40);
> + spi0_read_data((void *)header, load_offset, 0x40, 3);
>
> if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
> image_get_magic(header) == FDT_MAGIC) {
> @@ -376,7 +382,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image,
> return ret;
>
> spi0_read_data((void *)spl_image->load_addr,
> - load_offset, spl_image->size);
> + load_offset, spl_image->size, 3);
> }
>
> spi0_deinit();
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 3/8] sunxi: SPL SPI: allow multiple boot attempt
2022-10-14 3:05 ` [PATCH 3/8] sunxi: SPL SPI: allow multiple boot attempt Icenowy Zheng
@ 2023-01-14 19:56 ` Samuel Holland
2023-01-15 0:26 ` Icenowy Zheng
0 siblings, 1 reply; 22+ messages in thread
From: Samuel Holland @ 2023-01-14 19:56 UTC (permalink / raw)
To: Icenowy Zheng, Jagan Teki, Andre Przywara, Hans de Goede,
Jesse Taube
Cc: u-boot, linux-sunxi
On 10/13/22 22:05, Icenowy Zheng wrote:
> As we're going to add support for SPI NAND to this code, add code that
> allows multiple boot attempts with different load offsets and functions.
>
> To keep compatibility with loading raw binary on SPI NOR, a bool
> parameter is used to allow booting without valid magic number when
> booting with SPI NOR.
So the issue is that when CONFIG_SPL_RAW_IMAGE_SUPPORT=y, then
spl_parse_image_header() will return 0 even when using the wrong NAND
parameters? I don't see a better solution, so:
Reviewed-by: Samuel Holland <samuel@sholland.org>
Tested-by: Samuel Holland <samuel@sholland.org> # Orange Pi Zero Plus
> Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
> ---
> arch/arm/mach-sunxi/spl_spi_sunxi.c | 58 +++++++++++++++++++----------
> 1 file changed, 38 insertions(+), 20 deletions(-)
>
> diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
> index 88c15a3ee9..21be33a23f 100644
> --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
> +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
> @@ -340,8 +340,8 @@ static void spi0_read_data(void *buf, u32 addr, u32 len, u32 addr_len)
> }
> }
>
> -static ulong spi_load_read(struct spl_load_info *load, ulong sector,
> - ulong count, void *buf)
> +static ulong spi_load_read_nor(struct spl_load_info *load, ulong sector,
> + ulong count, void *buf)
> {
> spi0_read_data(buf, sector, count, 3);
>
> @@ -350,41 +350,59 @@ static ulong spi_load_read(struct spl_load_info *load, ulong sector,
>
> /*****************************************************************************/
>
> -static int spl_spi_load_image(struct spl_image_info *spl_image,
> - struct spl_boot_device *bootdev)
> +static int spl_spi_try_load(struct spl_image_info *spl_image,
> + struct spl_boot_device *bootdev,
> + struct spl_load_info *load, u32 offset,
> + bool allow_raw)
> {
> int ret = 0;
> struct legacy_img_hdr *header;
> - uint32_t load_offset = sunxi_get_spl_size();
> -
nit: keep this blank line
> header = (struct legacy_img_hdr *)CONFIG_SYS_TEXT_BASE;
> - load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
> -
> - spi0_init();
>
> - spi0_read_data((void *)header, load_offset, 0x40, 3);
> + if (load->read(load, offset, 0x40, (void *)header) == 0)
> + return -EINVAL;
>
> if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
> image_get_magic(header) == FDT_MAGIC) {
> - struct spl_load_info load;
>
> debug("Found FIT image\n");
> - load.dev = NULL;
> - load.priv = NULL;
> - load.filename = NULL;
> - load.bl_len = 1;
> - load.read = spi_load_read;
> - ret = spl_load_simple_fit(spl_image, &load,
> - load_offset, header);
> + ret = spl_load_simple_fit(spl_image, load,
> + offset, header);
> } else {
> + if (!allow_raw && image_get_magic(header) != IH_MAGIC)
> + return -EINVAL;
> +
> ret = spl_parse_image_header(spl_image, bootdev, header);
> if (ret)
> return ret;
>
> - spi0_read_data((void *)spl_image->load_addr,
> - load_offset, spl_image->size, 3);
> + if (load->read(load, offset, spl_image->size,
> + (void *)spl_image->load_addr) == 0)
> + ret = -EINVAL;
> }
>
> + return ret;
> +}
> +
> +static int spl_spi_load_image(struct spl_image_info *spl_image,
> + struct spl_boot_device *bootdev)
> +{
> + int ret = 0;
> + uint32_t load_offset = sunxi_get_spl_size();
> + struct spl_load_info load;
> +
> + load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
> +
> + load.dev = NULL;
> + load.priv = NULL;
> + load.filename = NULL;
> + load.bl_len = 1;
> +
> + spi0_init();
> +
> + load.read = spi_load_read_nor;
> + ret = spl_spi_try_load(spl_image, bootdev, &load, load_offset, true);
> +
> spi0_deinit();
>
> return ret;
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 4/8] sunxi: SPL SPI: add initial support for booting from SPI NAND
2022-10-14 3:05 ` [PATCH 4/8] sunxi: SPL SPI: add initial support for booting from SPI NAND Icenowy Zheng
@ 2023-01-14 20:08 ` Samuel Holland
0 siblings, 0 replies; 22+ messages in thread
From: Samuel Holland @ 2023-01-14 20:08 UTC (permalink / raw)
To: Icenowy Zheng, Jagan Teki, Andre Przywara, Hans de Goede,
Jesse Taube
Cc: u-boot, linux-sunxi
On 10/13/22 22:05, Icenowy Zheng wrote:
> This commit adds support for booting from SPI NAND to SPL SPI code by
> mimicing the behavior of boot ROM (use fixed page size and sequentially
> try SPI NOR and NAND).
One warning generated when SPL_SPI_SUNXI_NAND is disabled. Otherwise, it
looks fine to me. I verified that NOR booting still works when
SPL_SPI_SUNXI_NAND is enabled, so:
Tested-by: Samuel Holland <samuel@sholland.org> # Orange Pi Zero Plus
> Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
> ---
> arch/arm/mach-sunxi/Kconfig | 16 +++++++
> arch/arm/mach-sunxi/spl_spi_sunxi.c | 74 +++++++++++++++++++++++++++++
> 2 files changed, 90 insertions(+)
>
> diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
> index 840bbc19b3..6afbb4acb5 100644
> --- a/arch/arm/mach-sunxi/Kconfig
> +++ b/arch/arm/mach-sunxi/Kconfig
> @@ -1018,6 +1018,22 @@ config SPL_SPI_SUNXI
> sunxi SPI Flash. It uses the same method as the boot ROM, so does
> not need any extra configuration.
>
> +config SPL_SPI_SUNXI_NAND
> + bool "Support for SPI NAND Flash on Allwinner SoCs in SPL"
> + depends on SPL_SPI_SUNXI
> + help
> + Enable support for SPI NAND Flash. This option allows SPL to mimic
> + Allwinner boot ROM's behavior to gain support for SPI NAND Flash;
> + a fixed page size needs to be assumed when building the SPL image.
> +
> +config SPL_SPI_SUNXI_NAND_ASSUMED_PAGESIZE
> + hex "Assumed pagesize for SPI NAND Flash in SPL"
> + depends on SPL_SPI_SUNXI_NAND
> + default 0x400 if MACH_SUNIV
> + help
> + Set the page size assumed by the SPL SPI NAND code, the default
> + value is the same with the boot ROM.
> +
> config PINE64_DT_SELECTION
> bool "Enable Pine64 device tree selection code"
> depends on MACH_SUN50I
> diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
> index 21be33a23f..5178908327 100644
> --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
> +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
> @@ -305,6 +305,49 @@ static void spi0_xfer(const u8 *txbuf, u32 txlen, u8 *rxbuf, u32 rxlen)
> }
> }
>
> +#if defined(CONFIG_SPL_SPI_SUNXI_NAND)
> +static int spi0_nand_switch_page(u32 page)
> +{
> + unsigned count;
> + u8 buf[4];
> +
> + /* Configure the Page Data Read (13h) command header */
> + buf[0] = 0x13;
> + buf[1] = (u8)(page >> 16);
> + buf[2] = (u8)(page >> 8);
> + buf[3] = (u8)(page);
> +
> + spi0_xfer(buf, 4, NULL, 0);
> +
> + /* Wait for NAND chip to exit busy state */
> + buf[0] = 0x0f;
> + buf[1] = 0xc0;
> +
> + /* Load a NAND page can take up to 2-decimal-digit microseconds */
> + for (count = 0; count < 100; count ++) {
> + udelay(1);
> + spi0_xfer(buf, 2, buf+2, 1);
> + if (!(buf[2] & 0x1))
> + return 0;
> + }
> +
> + return -ETIMEDOUT;
> +}
> +
> +static void spi0_nand_reset(void)
> +{
> + u8 buf[1];
> +
> + /* Configure the Device RESET (ffh) command */
> + buf[0] = 0xff;
> +
> + spi0_xfer(buf, 1, NULL, 0);
> +
> + /* Wait for the NAND to finish resetting */
> + udelay(10);
> +}
> +#endif
> +
> static void spi0_read_data(void *buf, u32 addr, u32 len, u32 addr_len)
> {
> u8 *buf8 = buf;
> @@ -348,6 +391,28 @@ static ulong spi_load_read_nor(struct spl_load_info *load, ulong sector,
> return count;
> }
>
> +#if defined(CONFIG_SPL_SPI_SUNXI_NAND)
> +static ulong spi_load_read_nand(struct spl_load_info *load, ulong sector,
> + ulong count, void *buf)
> +{
> + const ulong pagesize = CONFIG_SPL_SPI_SUNXI_NAND_ASSUMED_PAGESIZE;
> + ulong remain = count;
> +
> + while (remain) {
> + ulong count_in_page = min(remain, pagesize - (sector % pagesize));
> + ulong current_page = sector / pagesize;
> + if (spi0_nand_switch_page(current_page) != 0)
> + return 0;
> + spi0_read_data(buf, sector % pagesize, count_in_page, 2);
> + remain -= count_in_page;
> + sector += count_in_page;
> + buf += count_in_page;
> + }
> +
> + return count;
> +}
> +#endif
> +
> /*****************************************************************************/
>
> static int spl_spi_try_load(struct spl_image_info *spl_image,
> @@ -400,9 +465,18 @@ static int spl_spi_load_image(struct spl_image_info *spl_image,
>
> spi0_init();
>
> +#if defined(CONFIG_SPL_SPI_SUNXI_NAND)
> + spi0_nand_reset();
> + load.read = spi_load_read_nand;
> + ret = spl_spi_try_load(spl_image, bootdev, &load, load_offset, false);
> + if (!ret)
> + goto out;
> +#endif
> +
> load.read = spi_load_read_nor;
> ret = spl_spi_try_load(spl_image, bootdev, &load, load_offset, true);
>
> +out:
arch/arm/mach-sunxi/spl_spi_sunxi.c: In function 'spl_spi_load_image':
arch/arm/mach-sunxi/spl_spi_sunxi.c:482:1: warning: label 'out' defined
but not used [-Wunused-label]
482 | out:
| ^~~
> spi0_deinit();
>
> return ret;
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 5/8] sunxi: enable support for SPI NAND booting on SUNIV
2022-10-14 3:05 ` [PATCH 5/8] sunxi: enable support for SPI NAND booting on SUNIV Icenowy Zheng
@ 2023-01-14 20:18 ` Samuel Holland
0 siblings, 0 replies; 22+ messages in thread
From: Samuel Holland @ 2023-01-14 20:18 UTC (permalink / raw)
To: Icenowy Zheng, Jagan Teki, Andre Przywara, Hans de Goede,
Jesse Taube
Cc: u-boot, linux-sunxi
On 10/13/22 22:05, Icenowy Zheng wrote:
> As we added support for SPI NAND to the existing SPL SPI codepath, route
> the boot code to it when it detects the BROM loads SPL from SPI NAND, as
> for SoCs with both SPI NAND and boot media indicator support, the boot
> media indicator is the same for SPI NOR and NAND.
>
> Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
> ---
> arch/arm/mach-sunxi/board.c | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
Reviewed-by: Samuel Holland <samuel@sholland.org>
> diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
> index 220ed80ba7..3a81743e8f 100644
> --- a/arch/arm/mach-sunxi/board.c
> +++ b/arch/arm/mach-sunxi/board.c
> @@ -210,12 +210,10 @@ static int suniv_get_boot_source(void)
> case SUNIV_BOOTED_FROM_MMC0:
> return SUNXI_BOOTED_FROM_MMC0;
> case SUNIV_BOOTED_FROM_SPI:
> + case SUNIV_BOOTED_FROM_NAND:
> return SUNXI_BOOTED_FROM_SPI;
> case SUNIV_BOOTED_FROM_MMC1:
> return SUNXI_BOOTED_FROM_MMC2;
> - /* SPI NAND is not supported yet. */
> - case SUNIV_BOOTED_FROM_NAND:
> - return SUNXI_INVALID_BOOT_SOURCE;
> }
> /* If we get here something went wrong try to boot from FEL.*/
> printf("Unknown boot source from BROM: 0x%x\n", brom_call);
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 3/8] sunxi: SPL SPI: allow multiple boot attempt
2023-01-14 19:56 ` Samuel Holland
@ 2023-01-15 0:26 ` Icenowy Zheng
0 siblings, 0 replies; 22+ messages in thread
From: Icenowy Zheng @ 2023-01-15 0:26 UTC (permalink / raw)
To: Samuel Holland, Jagan Teki, Andre Przywara, Hans de Goede,
Jesse Taube
Cc: u-boot, linux-sunxi
于 2023年1月15日 GMT+08:00 上午3:56:08, Samuel Holland <samuel@sholland.org> 写到:
>On 10/13/22 22:05, Icenowy Zheng wrote:
>> As we're going to add support for SPI NAND to this code, add code that
>> allows multiple boot attempts with different load offsets and functions.
>>
>> To keep compatibility with loading raw binary on SPI NOR, a bool
>> parameter is used to allow booting without valid magic number when
>> booting with SPI NOR.
>
>So the issue is that when CONFIG_SPL_RAW_IMAGE_SUPPORT=y, then
>spl_parse_image_header() will return 0 even when using the wrong NAND
>parameters? I don't see a better solution, so:
Good point, maybe the next patch needs to add some dependency
of raw image support to SPI NAND support option.
>
>Reviewed-by: Samuel Holland <samuel@sholland.org>
>Tested-by: Samuel Holland <samuel@sholland.org> # Orange Pi Zero Plus
>
>> Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
>> ---
>> arch/arm/mach-sunxi/spl_spi_sunxi.c | 58 +++++++++++++++++++----------
>> 1 file changed, 38 insertions(+), 20 deletions(-)
>>
>> diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
>> index 88c15a3ee9..21be33a23f 100644
>> --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
>> +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
>> @@ -340,8 +340,8 @@ static void spi0_read_data(void *buf, u32 addr, u32 len, u32 addr_len)
>> }
>> }
>>
>> -static ulong spi_load_read(struct spl_load_info *load, ulong sector,
>> - ulong count, void *buf)
>> +static ulong spi_load_read_nor(struct spl_load_info *load, ulong sector,
>> + ulong count, void *buf)
>> {
>> spi0_read_data(buf, sector, count, 3);
>>
>> @@ -350,41 +350,59 @@ static ulong spi_load_read(struct spl_load_info *load, ulong sector,
>>
>> /*****************************************************************************/
>>
>> -static int spl_spi_load_image(struct spl_image_info *spl_image,
>> - struct spl_boot_device *bootdev)
>> +static int spl_spi_try_load(struct spl_image_info *spl_image,
>> + struct spl_boot_device *bootdev,
>> + struct spl_load_info *load, u32 offset,
>> + bool allow_raw)
>> {
>> int ret = 0;
>> struct legacy_img_hdr *header;
>> - uint32_t load_offset = sunxi_get_spl_size();
>> -
>
>nit: keep this blank line
>
>> header = (struct legacy_img_hdr *)CONFIG_SYS_TEXT_BASE;
>> - load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
>> -
>> - spi0_init();
>>
>> - spi0_read_data((void *)header, load_offset, 0x40, 3);
>> + if (load->read(load, offset, 0x40, (void *)header) == 0)
>> + return -EINVAL;
>>
>> if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
>> image_get_magic(header) == FDT_MAGIC) {
>> - struct spl_load_info load;
>>
>> debug("Found FIT image\n");
>> - load.dev = NULL;
>> - load.priv = NULL;
>> - load.filename = NULL;
>> - load.bl_len = 1;
>> - load.read = spi_load_read;
>> - ret = spl_load_simple_fit(spl_image, &load,
>> - load_offset, header);
>> + ret = spl_load_simple_fit(spl_image, load,
>> + offset, header);
>> } else {
>> + if (!allow_raw && image_get_magic(header) != IH_MAGIC)
>> + return -EINVAL;
>> +
>> ret = spl_parse_image_header(spl_image, bootdev, header);
>> if (ret)
>> return ret;
>>
>> - spi0_read_data((void *)spl_image->load_addr,
>> - load_offset, spl_image->size, 3);
>> + if (load->read(load, offset, spl_image->size,
>> + (void *)spl_image->load_addr) == 0)
>> + ret = -EINVAL;
>> }
>>
>> + return ret;
>> +}
>> +
>> +static int spl_spi_load_image(struct spl_image_info *spl_image,
>> + struct spl_boot_device *bootdev)
>> +{
>> + int ret = 0;
>> + uint32_t load_offset = sunxi_get_spl_size();
>> + struct spl_load_info load;
>> +
>> + load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS);
>> +
>> + load.dev = NULL;
>> + load.priv = NULL;
>> + load.filename = NULL;
>> + load.bl_len = 1;
>> +
>> + spi0_init();
>> +
>> + load.read = spi_load_read_nor;
>> + ret = spl_spi_try_load(spl_image, bootdev, &load, load_offset, true);
>> +
>> spi0_deinit();
>>
>> return ret;
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 7/8] [DO NOT MERGE, DIRTY HACK] sunxi: use UBI for environement storage
2022-10-14 3:05 ` [PATCH 7/8] [DO NOT MERGE, DIRTY HACK] sunxi: use UBI for environement storage Icenowy Zheng
@ 2023-01-15 17:19 ` Icenowy Zheng
0 siblings, 0 replies; 22+ messages in thread
From: Icenowy Zheng @ 2023-01-15 17:19 UTC (permalink / raw)
To: Jagan Teki, Andre Przywara, Hans de Goede, Samuel Holland,
Jesse Taube
Cc: u-boot, linux-sunxi
在 2022-10-14星期五的 11:05 +0800,Icenowy Zheng写道:
> Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
By the way should we have some better way to handle the placement of
environments?
> ---
> board/sunxi/board.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/board/sunxi/board.c b/board/sunxi/board.c
> index 21a2407e06..f4138573d4 100644
> --- a/board/sunxi/board.c
> +++ b/board/sunxi/board.c
> @@ -133,6 +133,7 @@ void i2c_init_board(void)
> */
> enum env_location env_get_location(enum env_operation op, int prio)
> {
> + return prio ? ENVL_UNKNOWN : ENVL_UBI;
> if (prio > 1)
> return ENVL_UNKNOWN;
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/8] SUNIV SPI NAND support in SPL
2022-10-14 3:05 [PATCH 0/8] SUNIV SPI NAND support in SPL Icenowy Zheng
` (7 preceding siblings ...)
2022-10-14 3:05 ` [PATCH 8/8] [DO NOT MERGE] sunxi: add a defconfig for PopStick Icenowy Zheng
@ 2023-06-05 21:03 ` Sam Edwards
2023-06-06 6:39 ` Icenowy Zheng
2024-04-11 4:32 ` John Watts
9 siblings, 1 reply; 22+ messages in thread
From: Sam Edwards @ 2023-06-05 21:03 UTC (permalink / raw)
To: u-boot, Icenowy Zheng; +Cc: Andre Przywara
Hey hey Icenowy,
On 10/13/22 21:05, Icenowy Zheng wrote:
> This patchset tries to extend SPI-based boot code in sunxi SPL to
> support SPI NAND, following the same principle with current SPI NOR code
> (mimicking the behavior of sunxi BROM).
Thank you for your work on this patchset; it works great on T113 as
well! Note that I have had to apply an extra patch to resolve a bootloop
of "Unknown boot source 4" (find the patch below).
Also, since on both SUNXI and SUNIV the SPL knows whether it came from
NOR or NAND, perhaps it would be better to break apart
BOOT_DEVICE_SPI/spl_spi_load_image into specific NOR and NAND variants,
as opposed to the current try-NAND-then-NOR approach?
Cheers (and thanks again),
Sam
--
diff --git a/arch/arm/include/asm/arch-sunxi/spl.h
b/arch/arm/include/asm/arch-sunxi/spl.h
index 14944a20ea..703aa70a49 100644
--- a/arch/arm/include/asm/arch-sunxi/spl.h
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -12,10 +12,11 @@
#define SPL_ADDR CONFIG_SUNXI_SRAM_ADDRESS
/* The low 8-bits of the 'boot_media' field in the SPL header */
-#define SUNXI_BOOTED_FROM_MMC0 0
-#define SUNXI_BOOTED_FROM_NAND 1
-#define SUNXI_BOOTED_FROM_MMC2 2
-#define SUNXI_BOOTED_FROM_SPI 3
+#define SUNXI_BOOTED_FROM_MMC0 0
+#define SUNXI_BOOTED_FROM_NAND 1
+#define SUNXI_BOOTED_FROM_MMC2 2
+#define SUNXI_BOOTED_FROM_SPI 3
+#define SUNXI_BOOTED_FROM_SPI_NAND 4
#define SUNXI_BOOTED_FROM_MMC0_HIGH 0x10
#define SUNXI_BOOTED_FROM_MMC2_HIGH 0x12
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index a48f5aaa05..9bbd0753e6 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -298,6 +298,7 @@ uint32_t sunxi_get_boot_device(void)
case SUNXI_BOOTED_FROM_MMC2_HIGH:
return BOOT_DEVICE_MMC2;
case SUNXI_BOOTED_FROM_SPI:
+ case SUNXI_BOOTED_FROM_SPI_NAND:
return BOOT_DEVICE_SPI;
}
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 0/8] SUNIV SPI NAND support in SPL
2023-06-05 21:03 ` [PATCH 0/8] SUNIV SPI NAND support in SPL Sam Edwards
@ 2023-06-06 6:39 ` Icenowy Zheng
2023-06-06 23:09 ` Sam Edwards
0 siblings, 1 reply; 22+ messages in thread
From: Icenowy Zheng @ 2023-06-06 6:39 UTC (permalink / raw)
To: Sam Edwards, u-boot; +Cc: Andre Przywara
在 2023-06-05星期一的 15:03 -0600,Sam Edwards写道:
> Hey hey Icenowy,
>
> On 10/13/22 21:05, Icenowy Zheng wrote:
> > This patchset tries to extend SPI-based boot code in sunxi SPL to
> > support SPI NAND, following the same principle with current SPI NOR
> > code
> > (mimicking the behavior of sunxi BROM).
>
> Thank you for your work on this patchset; it works great on T113 as
> well! Note that I have had to apply an extra patch to resolve a
> bootloop
> of "Unknown boot source 4" (find the patch below).
>
> Also, since on both SUNXI and SUNIV the SPL knows whether it came
> from
> NOR or NAND, perhaps it would be better to break apart
> BOOT_DEVICE_SPI/spl_spi_load_image into specific NOR and NAND
> variants,
> as opposed to the current try-NAND-then-NOR approach?
Well it depends on whether all SoCs differienate between SPI NOR and
SPI NAND.
Do you have any suggestion on as many chips models as possible boards
with SPI NAND?
>
> Cheers (and thanks again),
> Sam
>
> --
>
> diff --git a/arch/arm/include/asm/arch-sunxi/spl.h
> b/arch/arm/include/asm/arch-sunxi/spl.h
> index 14944a20ea..703aa70a49 100644
> --- a/arch/arm/include/asm/arch-sunxi/spl.h
> +++ b/arch/arm/include/asm/arch-sunxi/spl.h
> @@ -12,10 +12,11 @@
> #define SPL_ADDR CONFIG_SUNXI_SRAM_ADDRESS
>
> /* The low 8-bits of the 'boot_media' field in the SPL header */
> -#define SUNXI_BOOTED_FROM_MMC0 0
> -#define SUNXI_BOOTED_FROM_NAND 1
> -#define SUNXI_BOOTED_FROM_MMC2 2
> -#define SUNXI_BOOTED_FROM_SPI 3
> +#define SUNXI_BOOTED_FROM_MMC0 0
> +#define SUNXI_BOOTED_FROM_NAND 1
> +#define SUNXI_BOOTED_FROM_MMC2 2
> +#define SUNXI_BOOTED_FROM_SPI 3
> +#define SUNXI_BOOTED_FROM_SPI_NAND 4
> #define SUNXI_BOOTED_FROM_MMC0_HIGH 0x10
> #define SUNXI_BOOTED_FROM_MMC2_HIGH 0x12
>
> diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-
> sunxi/board.c
> index a48f5aaa05..9bbd0753e6 100644
> --- a/arch/arm/mach-sunxi/board.c
> +++ b/arch/arm/mach-sunxi/board.c
> @@ -298,6 +298,7 @@ uint32_t sunxi_get_boot_device(void)
> case SUNXI_BOOTED_FROM_MMC2_HIGH:
> return BOOT_DEVICE_MMC2;
> case SUNXI_BOOTED_FROM_SPI:
> + case SUNXI_BOOTED_FROM_SPI_NAND:
> return BOOT_DEVICE_SPI;
> }
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/8] SUNIV SPI NAND support in SPL
2023-06-06 6:39 ` Icenowy Zheng
@ 2023-06-06 23:09 ` Sam Edwards
2023-06-17 20:59 ` Sam Edwards
0 siblings, 1 reply; 22+ messages in thread
From: Sam Edwards @ 2023-06-06 23:09 UTC (permalink / raw)
To: Icenowy Zheng, u-boot; +Cc: Andre Przywara
On 6/6/23 00:39, Icenowy Zheng wrote:
> Well it depends on whether all SoCs differienate between SPI NOR and
> SPI NAND.
Allwinner chips that (have datasheets saying they) support boot from
SPI-NAND seem quite few and far between, but I've learned that the
answer is "not all": the V3s, at least, appears to use 0x03 in the boot
field when booting from SPI-NAND. (Note: I do not have a V3s that I
tested with; I studied a dumped BROM.)
Still, I believe it's sensible that, when we know for sure we're coming
from SPI-NAND (because it's a newer sunxi that reports 0x04, or we know
from the suniv stack-checking hack), we should call that its own SPL
load method, which does not fall back to SPI-NOR. The SPI(-NOR) load
method naturally has to implement the try-NAND-first logic for some of
these SoCs, but perhaps we could call it a "quirk" and only do that for
chips that aren't known to report SPI-NAND directly?
> Do you have any suggestion on as many chips models as possible boards
> with SPI NAND?
I know of only one: the Turing Pi 2, which is the only target I'm trying
to support. I'm guessing you're looking for some such boards so you can
identify which of them report 0x03 and which report 0x04? I'd be happy
to analyze some BROMs from chips known to support SPI-NAND boot if you
know where I can find them.
Thanks,
Sam
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/8] SUNIV SPI NAND support in SPL
2023-06-06 23:09 ` Sam Edwards
@ 2023-06-17 20:59 ` Sam Edwards
0 siblings, 0 replies; 22+ messages in thread
From: Sam Edwards @ 2023-06-17 20:59 UTC (permalink / raw)
To: Icenowy Zheng, u-boot; +Cc: Andre Przywara
Hi again Icenowy,
On 6/6/23 17:09, Sam Edwards wrote:
> Still, I believe it's sensible that, when we know for sure we're coming
> from SPI-NAND (because it's a newer sunxi that reports 0x04, or we know
> from the suniv stack-checking hack), we should call that its own SPL
> load method, which does not fall back to SPI-NOR. The SPI(-NOR) load
> method naturally has to implement the try-NAND-first logic for some of
> these SoCs, but perhaps we could call it a "quirk" and only do that for
> chips that aren't known to report SPI-NAND directly?
Since other methods that care about flash type (e.g. env_get_location)
don't understand BOOT_DEVICE_SPI to mean "SPI, but the actual flash type
is ambiguous," I'm starting to think we need to resolve the ambiguity
*before* the load method runs.
What are your thoughts on this:
1. Introduce SUNXI_BOOTED_FROM_SPI_NAND, value 4 (matching the value
used by Allwinner's newer BROMs).
2. Map SUNIV_BOOTED_FROM_NAND to SUNXI_BOOTED_FROM_SPI_NAND.
3. Map SUNXI_BOOTED_FROM_SPI_NAND to BOOT_DEVICE_NAND (and not _SPI).
4. Implement the SPI-NAND stuff to provide `nand_spl_load_image` (so
that the common SPL framework's NAND loader can take care of it).
Possibly go even further and implement the methods needed by the UBI
loader too.
5. On sunxis (e.g. V3s) which are known to report SUNXI_BOOTED_FROM_SPI
for SPI-NAND, add a small check to sunxi_get_boot_device() which
disambiguates this situation by probing for SPI-NAND.
If #4 isn't really feasible, we might instead want to introduce a
BOOT_DEVICE_SPI_NAND, but I don't know if adding sunxi to the list of
platforms that have their own BOOT_DEVICE_ names is a great call.
In any case, I'd hope also to see some kind of bad block handling in
here -- a simple check for a bad block each time we get to page 0 (which
skips to the next block) should be pretty easy, don't you think?
Any thoughts? Any other way I can be of service? (Feel free to delegate
some of these ideas to me if you think they're good but don't have the
time to execute them!)
Warm regards,
Sam
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 1/8] sunxi: SPL SPI: extract code for doing SPI transfer
2022-10-14 3:05 ` [PATCH 1/8] sunxi: SPL SPI: extract code for doing SPI transfer Icenowy Zheng
2023-01-14 19:32 ` Samuel Holland
@ 2023-12-12 18:12 ` Andre Przywara
1 sibling, 0 replies; 22+ messages in thread
From: Andre Przywara @ 2023-12-12 18:12 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Jagan Teki, Hans de Goede, Samuel Holland, Jesse Taube, u-boot,
linux-sunxi@lists.linux.dev, John Watts
On Fri, 14 Oct 2022 11:05:13 +0800
Icenowy Zheng <uwu@icenowy.me> wrote:
Hi,
> To support SPI NAND flashes, more commands than Read (03h) are needed.
>
> Extract the code for doing SPI transfer from the reading code for code
> reuse.
I was looking for a better solution than this inflated function parameter
list, but everything I came up with is actually worse. So it's fine like
you wrote it here.
I think it now even looks a bit better, since that long list is now
wrapped completely by the spi0_xfer() function.
It increases the code size by 20 (Thumb2) and 28 bytes (AArch64), that's
not great, but acceptable.
> Signed-off-by: Icenowy Zheng <uwu@icenowy.me>
With that one array index change that Samuel suggested (I can fix this up
myself):
Acked-by: Andre Przywara <andre.przywara@arm.com>
Cheers,
Andre
> ---
> arch/arm/mach-sunxi/spl_spi_sunxi.c | 105 ++++++++++++++++------------
> 1 file changed, 59 insertions(+), 46 deletions(-)
>
> diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
> index 925bf85f2d..7975457758 100644
> --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
> +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
> @@ -243,77 +243,90 @@ static void spi0_deinit(void)
>
> #define SPI_READ_MAX_SIZE 60 /* FIFO size, minus 4 bytes of the header */
>
> -static void sunxi_spi0_read_data(u8 *buf, u32 addr, u32 bufsize,
> - ulong spi_ctl_reg,
> - ulong spi_ctl_xch_bitmask,
> - ulong spi_fifo_reg,
> - ulong spi_tx_reg,
> - ulong spi_rx_reg,
> - ulong spi_bc_reg,
> - ulong spi_tc_reg,
> - ulong spi_bcc_reg)
> +static void sunxi_spi0_xfer(const u8 *txbuf, u32 txlen,
> + u8 *rxbuf, u32 rxlen,
> + ulong spi_ctl_reg,
> + ulong spi_ctl_xch_bitmask,
> + ulong spi_fifo_reg,
> + ulong spi_tx_reg,
> + ulong spi_rx_reg,
> + ulong spi_bc_reg,
> + ulong spi_tc_reg,
> + ulong spi_bcc_reg)
> {
> - writel(4 + bufsize, spi_bc_reg); /* Burst counter (total bytes) */
> - writel(4, spi_tc_reg); /* Transfer counter (bytes to send) */
> + writel(txlen + rxlen, spi_bc_reg); /* Burst counter (total bytes) */
> + writel(txlen, spi_tc_reg); /* Transfer counter (bytes to send) */
> if (spi_bcc_reg)
> - writel(4, spi_bcc_reg); /* SUN6I also needs this */
> + writel(txlen, spi_bcc_reg); /* SUN6I also needs this */
>
> - /* Send the Read Data Bytes (03h) command header */
> - writeb(0x03, spi_tx_reg);
> - writeb((u8)(addr >> 16), spi_tx_reg);
> - writeb((u8)(addr >> 8), spi_tx_reg);
> - writeb((u8)(addr), spi_tx_reg);
> + for (u32 i = 0; i < txlen; i++)
> + writeb(*(txbuf++), spi_tx_reg);
>
> /* Start the data transfer */
> setbits_le32(spi_ctl_reg, spi_ctl_xch_bitmask);
>
> /* Wait until everything is received in the RX FIFO */
> - while ((readl(spi_fifo_reg) & 0x7F) < 4 + bufsize)
> + while ((readl(spi_fifo_reg) & 0x7F) < txlen + rxlen)
> ;
>
> - /* Skip 4 bytes */
> - readl(spi_rx_reg);
> + /* Skip txlen bytes */
> + for (u32 i = 0; i < txlen; i++)
> + readb(spi_rx_reg);
>
> /* Read the data */
> - while (bufsize-- > 0)
> - *buf++ = readb(spi_rx_reg);
> + while (rxlen-- > 0)
> + *rxbuf++ = readb(spi_rx_reg);
> +}
> +
> +static void spi0_xfer(const u8 *txbuf, u32 txlen, u8 *rxbuf, u32 rxlen)
> +{
> + uintptr_t base = spi0_base_address();
>
> - /* tSHSL time is up to 100 ns in various SPI flash datasheets */
> - udelay(1);
> + if (is_sun6i_gen_spi()) {
> + sunxi_spi0_xfer(txbuf, txlen, rxbuf, rxlen,
> + base + SUN6I_SPI0_TCR,
> + SUN6I_TCR_XCH,
> + base + SUN6I_SPI0_FIFO_STA,
> + base + SUN6I_SPI0_TXD,
> + base + SUN6I_SPI0_RXD,
> + base + SUN6I_SPI0_MBC,
> + base + SUN6I_SPI0_MTC,
> + base + SUN6I_SPI0_BCC);
> + } else {
> + sunxi_spi0_xfer(txbuf, txlen, rxbuf, rxlen,
> + base + SUN4I_SPI0_CTL,
> + SUN4I_CTL_XCH,
> + base + SUN4I_SPI0_FIFO_STA,
> + base + SUN4I_SPI0_TX,
> + base + SUN4I_SPI0_RX,
> + base + SUN4I_SPI0_BC,
> + base + SUN4I_SPI0_TC,
> + 0);
> + }
> }
>
> static void spi0_read_data(void *buf, u32 addr, u32 len)
> {
> u8 *buf8 = buf;
> u32 chunk_len;
> - uintptr_t base = spi0_base_address();
> + u8 txbuf[4];
>
> while (len > 0) {
> chunk_len = len;
> +
> + /* Configure the Read Data Bytes (03h) command header */
> + txbuf[0] = 0x03;
> + txbuf[1] = (u8)(addr >> 16);
> + txbuf[2] = (u8)(addr >> 8);
> + txbuf[3] = (u8)(addr);
> +
> if (chunk_len > SPI_READ_MAX_SIZE)
> chunk_len = SPI_READ_MAX_SIZE;
>
> - if (is_sun6i_gen_spi()) {
> - sunxi_spi0_read_data(buf8, addr, chunk_len,
> - base + SUN6I_SPI0_TCR,
> - SUN6I_TCR_XCH,
> - base + SUN6I_SPI0_FIFO_STA,
> - base + SUN6I_SPI0_TXD,
> - base + SUN6I_SPI0_RXD,
> - base + SUN6I_SPI0_MBC,
> - base + SUN6I_SPI0_MTC,
> - base + SUN6I_SPI0_BCC);
> - } else {
> - sunxi_spi0_read_data(buf8, addr, chunk_len,
> - base + SUN4I_SPI0_CTL,
> - SUN4I_CTL_XCH,
> - base + SUN4I_SPI0_FIFO_STA,
> - base + SUN4I_SPI0_TX,
> - base + SUN4I_SPI0_RX,
> - base + SUN4I_SPI0_BC,
> - base + SUN4I_SPI0_TC,
> - 0);
> - }
> + spi0_xfer(txbuf, 4, buf8, chunk_len);
> +
> + /* tSHSL time is up to 100 ns in various SPI flash datasheets */
> + udelay(1);
>
> len -= chunk_len;
> buf8 += chunk_len;
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 0/8] SUNIV SPI NAND support in SPL
2022-10-14 3:05 [PATCH 0/8] SUNIV SPI NAND support in SPL Icenowy Zheng
` (8 preceding siblings ...)
2023-06-05 21:03 ` [PATCH 0/8] SUNIV SPI NAND support in SPL Sam Edwards
@ 2024-04-11 4:32 ` John Watts
9 siblings, 0 replies; 22+ messages in thread
From: John Watts @ 2024-04-11 4:32 UTC (permalink / raw)
To: Icenowy Zheng
Cc: Jagan Teki, Andre Przywara, Hans de Goede, Samuel Holland,
Jesse Taube, u-boot, linux-sunxi
Hello,
I've used this code extensively, incorporated it in to an RFC branch of
mine during development and reviewed it in the process.
John.
Reviewed-by: John Watts <contact@jookia.org>
Tested-by: John Watts <contact@jookia.org>
On Fri, Oct 14, 2022 at 11:05:12AM +0800, Icenowy Zheng wrote:
> This patchset tries to extend SPI-based boot code in sunxi SPL to
> support SPI NAND, following the same principle with current SPI NOR code
> (mimicking the behavior of sunxi BROM). In addition, as part of test to
> this patchset, some patches for Source Parts Inc. PopStick is attached,
> although marked DO NOT MERGE because the DT should come from Linux after
> it's ready.
>
> To keep thr code that accesses SPI NAND as simple as possible, it
> assumes fixed page size, which is also what sunxi BROM does. The SUNIV
> SPL assumes 0x400 page size, but here to utilize the space better, in
> the attached example of PopStick, U-Boot main part is assumed to be
> with 0x800 page size (which is the real situation of the W25N01 flash
> used by PopStick).
>
> Icenowy Zheng (8):
> sunxi: SPL SPI: extract code for doing SPI transfer
> sunxi: SPL SPI: add support for read command with 2 byte address
> sunxi: SPL SPI: allow multiple boot attempt
> sunxi: SPL SPI: add initial support for booting from SPI NAND
> sunxi: enable support for SPI NAND booting on SUNIV
> [DO NOT MERGE] sunxi: sync DT from my tree for PopStick
> [DO NOT MERGE, DIRTY HACK] sunxi: use UBI for environement storage
> [DO NOT MERGE] sunxi: add a defconfig for PopStick
>
> arch/arm/dts/Makefile | 3 +-
> arch/arm/dts/suniv-f1c100s-licheepi-nano.dts | 16 ++
> arch/arm/dts/suniv-f1c100s.dtsi | 26 ++
> arch/arm/dts/suniv-f1c200s-popstick-v1.1.dts | 101 ++++++++
> arch/arm/mach-sunxi/Kconfig | 16 ++
> arch/arm/mach-sunxi/board.c | 4 +-
> arch/arm/mach-sunxi/spl_spi_sunxi.c | 247 ++++++++++++++-----
> board/sunxi/board.c | 1 +
> configs/popstick_defconfig | 35 +++
> 9 files changed, 377 insertions(+), 72 deletions(-)
> create mode 100644 arch/arm/dts/suniv-f1c200s-popstick-v1.1.dts
> create mode 100644 configs/popstick_defconfig
>
> --
> 2.37.1
>
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2024-04-11 4:33 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-10-14 3:05 [PATCH 0/8] SUNIV SPI NAND support in SPL Icenowy Zheng
2022-10-14 3:05 ` [PATCH 1/8] sunxi: SPL SPI: extract code for doing SPI transfer Icenowy Zheng
2023-01-14 19:32 ` Samuel Holland
2023-12-12 18:12 ` Andre Przywara
2022-10-14 3:05 ` [PATCH 2/8] sunxi: SPL SPI: add support for read command with 2 byte address Icenowy Zheng
2023-01-14 19:35 ` Samuel Holland
2022-10-14 3:05 ` [PATCH 3/8] sunxi: SPL SPI: allow multiple boot attempt Icenowy Zheng
2023-01-14 19:56 ` Samuel Holland
2023-01-15 0:26 ` Icenowy Zheng
2022-10-14 3:05 ` [PATCH 4/8] sunxi: SPL SPI: add initial support for booting from SPI NAND Icenowy Zheng
2023-01-14 20:08 ` Samuel Holland
2022-10-14 3:05 ` [PATCH 5/8] sunxi: enable support for SPI NAND booting on SUNIV Icenowy Zheng
2023-01-14 20:18 ` Samuel Holland
2022-10-14 3:05 ` [PATCH 6/8] [DO NOT MERGE] sunxi: sync DT from my tree for PopStick Icenowy Zheng
2022-10-14 3:05 ` [PATCH 7/8] [DO NOT MERGE, DIRTY HACK] sunxi: use UBI for environement storage Icenowy Zheng
2023-01-15 17:19 ` Icenowy Zheng
2022-10-14 3:05 ` [PATCH 8/8] [DO NOT MERGE] sunxi: add a defconfig for PopStick Icenowy Zheng
2023-06-05 21:03 ` [PATCH 0/8] SUNIV SPI NAND support in SPL Sam Edwards
2023-06-06 6:39 ` Icenowy Zheng
2023-06-06 23:09 ` Sam Edwards
2023-06-17 20:59 ` Sam Edwards
2024-04-11 4:32 ` John Watts
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox