Ever since this commit:
Commit 9bb02f7f4533 ("mtd: spi-nor: Fix the spi_nor_read() when config
SPI_STACKED_PARALLEL is enabled")
booting a 7-series Zynq using the SPL flow is broken, the board is unable
to read u-boot.img from QSPI flash using the updated routines in SPL. In
U-Boot proper, reading QSPI flash works fine though.
When the Zynq boots from QSPI NOR flash, the ROM will have set up the
QSPI NOR in linear mode, and the contents are now memory mapped (the first
16MB/32MB at least). All that needs to be done at this stage is to memcpy
the u-boot code into DDR RAM. This is not only extremely simple, it's also
the fastest method to read QSPI flash on this platform.
This corresponds to a standard NOR boot, hence this mode is selected as
SPL_NOR_SUPPORT.
To accomplish this, first make the SPI support optional instead of
mandatory for the ZYNQ platform. In the bootmode detection, select the
NOR bootmode instead of SPI when SPL_NOR_SUPPORT has been enabled.
To boot from QSPI NOR, write "boot.bin" to offset 0 and write "u-boot.img"
to offset CONFIG_SPL_PAD_TO in the flash. Usually CONFIG_SPL_PAD_TO will
be 0x20000 as the SPL code easily fits in 128k. The offset must fit in the
accessible range for linear mode, which is 16MB for single and 32MB for
the dual chip modes.
Tested on topic_miami boards.
Signed-off-by: Mike Looijmans <[email protected]>
---
Changes in v2:
Reworded and amended commit text
Add #define for magic QSPI linear mode address
Use old method by default, use SPL_NOR_SUPPORT to switch to mmap
arch/arm/Kconfig | 4 ++--
arch/arm/mach-zynq/Kconfig | 4 ++--
arch/arm/mach-zynq/spl.c | 8 +++++++-
include/configs/zynq-common.h | 3 +++
4 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 514bf2000b4..f7eb9d94848 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1346,8 +1346,8 @@ config ARCH_ZYNQ
select SPL_SOC_INIT if SPL
select SPL_CLK if SPL
select SPL_DM if SPL
- select SPL_DM_SPI if SPL
- select SPL_DM_SPI_FLASH if SPL
+ select SPL_DM_SPI if SPL && !SPL_NOR_SUPPORT
+ select SPL_DM_SPI_FLASH if SPL && !SPL_NOR_SUPPORT
select SPL_OF_CONTROL if SPL
select SPL_SEPARATE_BSS if SPL
select SPL_TIMER if SPL
diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
index c3f505fa15c..2e6aa09fb53 100644
--- a/arch/arm/mach-zynq/Kconfig
+++ b/arch/arm/mach-zynq/Kconfig
@@ -19,10 +19,10 @@ config SPL_SERIAL
default y
config SPL_SPI_FLASH_SUPPORT
- default y if ZYNQ_QSPI
+ default y if ZYNQ_QSPI && !SPL_NOR_SUPPORT
config SPL_SPI
- default y if ZYNQ_QSPI
+ default y if ZYNQ_QSPI && !SPL_NOR_SUPPORT
config ZYNQ_DDRC_INIT
bool "Zynq DDRC initialization"
diff --git a/arch/arm/mach-zynq/spl.c b/arch/arm/mach-zynq/spl.c
index dc964dc2f9f..0332dcee402 100644
--- a/arch/arm/mach-zynq/spl.c
+++ b/arch/arm/mach-zynq/spl.c
@@ -47,10 +47,16 @@ u32 spl_boot_device(void)
u32 mode;
switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
-#ifdef CONFIG_SPL_SPI
+#ifdef CONFIG_SPL_NOR_SUPPORT
+ case ZYNQ_BM_QSPI:
+ mode = BOOT_DEVICE_NOR;
+ break;
+#else
+# ifdef CONFIG_SPL_SPI
case ZYNQ_BM_QSPI:
mode = BOOT_DEVICE_SPI;
break;
+# endif
#endif
case ZYNQ_BM_NAND:
mode = BOOT_DEVICE_NAND;
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h
index 94273d0deb9..4e14c74e31f 100644
--- a/include/configs/zynq-common.h
+++ b/include/configs/zynq-common.h
@@ -35,6 +35,9 @@
/* Ethernet driver */
/* NOR */
+/* Load address is mmap address of QSPI flash, plus the offset */
+#define ZYNQ_QSPI0_LINEAR_ADDR 0xfc000000
+#define CFG_SYS_UBOOT_BASE (ZYNQ_QSPI0_LINEAR_ADDR + CONFIG_SPL_PAD_TO)
#ifdef CONFIG_USB_EHCI_ZYNQ
# define DFU_DEFAULT_POLL_TIMEOUT 300
---
base-commit: fb2a4386029c5089c71d0d52caa3b09db9ee08ac
branch: upstream-topic-miami
--
2.43.0
Met vriendelijke groet / kind regards,
Mike Looijmans
System Expert
TOPIC Embedded Products B.V.
Materiaalweg 4, 5681 RJ Best
The Netherlands
T: +31 (0) 499 33 69 69
E: [email protected]
W: www.topic.nl
Please consider the environment before printing this e-mail