On 11/4/26 14:54, Michal Simek wrote:
On 9/15/26 15:47, Mike Looijmans wrote:
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.
Add a menu choice to select which method to use.
To boot from QSPI NOR, write "boot.bin" to offset 0 and write "u-boot.img"
to offset SYS_SPI_U_BOOT_OFFS in the flash. Usually SYS_SPI_U_BOOT_OFFS 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. This limitation is not checked explicitly in code.
Tested on topic_miami boards.
Signed-off-by: Mike Looijmans <[email protected]>
---
Changes in v4:
Disable SPL_SPI drivers when in memory-mapped mode
Use SYS_SPI_U_BOOT_OFFS as payload offset default
Explain why XIP mode is not feasible
Don't touch ARCH_ZYNQMP (yet)
Changes in v3:
Make the QSPI NOR mode a menu choice as suggested by Michal Simek
Obtain payload offset from device-tree config in spl_nor_get_uboot_base()
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 | 2 --
arch/arm/mach-zynq/Kconfig | 34 ++++++++++++++++++++++++++++++----
arch/arm/mach-zynq/spl.c | 20 ++++++++++++++++++++
common/spl/Kconfig | 5 ++++-
include/configs/zynq-common.h | 8 ++++++++
5 files changed, 62 insertions(+), 7 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 514bf2000b4..9473cbbb28b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1346,8 +1346,6 @@ 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_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..17514761530 100644
--- a/arch/arm/mach-zynq/Kconfig
+++ b/arch/arm/mach-zynq/Kconfig
@@ -18,11 +18,37 @@ config SPL_MMC
config SPL_SERIAL
default y
-config SPL_SPI_FLASH_SUPPORT
- default y if ZYNQ_QSPI
+choice
+ prompt "SPL QSPI boot access method"
+ depends on SPL && ZYNQ_QSPI
+ default ZYNQ_SPL_QSPI_DM_SPI
+ help
+ Select how to load u-boot.img (U-Boot proper) into memory from the SPL
+ loader when QSPI is the boot device.
+
+config ZYNQ_SPL_QSPI_DM_SPI
+ bool "DM SPI-NOR framework"
+ select SPL_DM_SPI
+ select SPL_DM_SPI_FLASH
+ select SPL_SPI
+ select SPL_SPI_FLASH_SUPPORT
+ help
+ Use the SPI-NOR drivers to transfer U-Boot proper into main memory
+ from the QSPI flash.
+
+config ZYNQ_SPL_QSPI_MMAP
+ bool "Memory-mapped linear (NOR) mode"
+ select SPL_NOR_SUPPORT
+ help
+ When the Zynq boots from QSPI NOR flash, the ROM will have set up the
+ QSPI NOR in linear mode. This option just uses memcpy to transfer
+ U-Boot proper into main memory. This reduces the SPL size by about 12k
+ and is the fastest boot method. For this to work, u-boot.img must be
+ within the first 16MB at offset SYS_SPI_U_BOOT_OFFS, or config value
+ "u-boot,spl-payload-offset" in the device-tree.
+
+endchoice
I don't like this and it seems to me overengineered.
At the end of day it is between SPL_SPI_FLASH_SUPPORT and SPL_NOR_SUPPORT
supports.
If both are selected SPI_FLASH wins because it it in the tree for longer time.
It means this patch should be about enabling SPL_NOR_SUPPORT and to get it
work you need to disable SPL_SPI_FLASH_SUPPORT first. Obviously make sense
to also disable drivers, etc.
I hope that doing it in this way will end up not having soc changes in
common/spl/Kconfig which are visible below.
I hoped that too, but it doesn't work that way. This is the smallest change I
could come up with to remain compatible and support a clear choice.
The cause of all the complexity is that the image to be loaded resides in a
SPI flash, but it gets fetched using the memory mapped NOR method.
If you disable SPI_FLASH, this also removes the code and defines that
calculate the position of the second stage, using the
"u-boot,spl-payload-offset" property or the CONFIG_SYS_SPI_U_BOOT_OFFS value.
If you run menuconfig and select ZYNQ_SPL_QSPI_MMAP, all the "overengineered"
stuff is about disabling the SPI controller in a way that it can still find
the location of the second stage.
-config SPL_SPI
- default y if ZYNQ_QSPI
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..0a536c6d98b 100644
--- a/arch/arm/mach-zynq/spl.c
+++ b/arch/arm/mach-zynq/spl.c
@@ -15,6 +15,8 @@
#include <asm/arch/sys_proto.h>
#include <asm/arch/ps7_init_gpl.h>
+#include <dm/ofnode.h>
not following u-boot rules about location.
+
#if defined(CONFIG_DEBUG_UART_BOARD_INIT)
void board_debug_uart_init(void)
{
@@ -42,6 +44,20 @@ void spl_soc_init(void)
}
#endif
+#ifdef CONFIG_SPL_NOR_SUPPORT
+unsigned long spl_nor_get_uboot_base(void)
+{
+ int payload_offs = CONFIG_SYS_SPI_U_BOOT_OFFS;
+
+ if (CONFIG_IS_ENABLED(OF_REAL)) {
+ payload_offs = ofnode_conf_read_int("u-boot,spl-payload-offset",
+ payload_offs);
+ }
+
+ return ZYNQ_QSPI0_LINEAR_ADDR + payload_offs;
+}
+#endif
+
u32 spl_boot_device(void)
{
u32 mode;
@@ -51,6 +67,10 @@ u32 spl_boot_device(void)
I think here there should be a change that insetad of SPL_SPI it actually
depends on SPL_SPI_LOAD which enables that functions which calls SPI.
-#ifdef CONFIG_SPL_SPI
+#if defined(CONFIG_SPL_SPI_LOAD)
case ZYNQ_BM_QSPI:
mode = BOOT_DEVICE_SPI;
break;
+#elif CONFIG_SPL_NOR_SUPPORT
+ case ZYNQ_BM_QSPI:
+ mode = BOOT_DEVICE_NOR;
+ break;
#endif
case ZYNQ_BM_NAND:
mode = BOOT_DEVICE_NAND;
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 5fa94098e49..fb179325f5f 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -1140,6 +1140,7 @@ endmenu
config SPL_DM_SPI
bool "Support SPI DM drivers in SPL"
depends on SPL_DM
+ depends on !ZYNQ_SPL_QSPI_MMAP
I don't like this in generic file.
help
Enable support for SPI DM drivers in SPL.
@@ -1526,6 +1527,7 @@ config SPL_SERIAL
config SPL_SPI
bool "Support SPI drivers"
+ depends on !ZYNQ_SPL_QSPI_MMAP
I don't like this in generic file.
Without this, the SPL_SPI option will end up getting selected anyway,
selecting ZYNQ_SPL_QSPI_MMAP is incapable of turning it off.
help
Enable support for using SPI in SPL. This is used for connecting
to SPI flash for loading U-Boot. See SPL_SPI_FLASH_SUPPORT for
@@ -1581,8 +1583,9 @@ endif # SPL_SPI_FLASH_SUPPORT
config SYS_SPI_U_BOOT_OFFS
hex "address of u-boot payload in SPI flash"
default 0x8000 if ARCH_SUNXI
+ default 0x20000 if ARCH_ZYNQ
I don't think this is really necessary. Map will cover the first 16MB and
you can place it whereever you like that's why make no sense to enforce any
offset.
Just define it in your board defconfig.
This just provides a sensible default, it doesn't enforce it. Without this, it
will default to "0" which is guaranteed to fail.
default 0x0
- depends on SPL_SPI_LOAD || SPL_SPI_SUNXI
+ depends on SPL_SPI_LOAD || SPL_SPI_SUNXI || ZYNQ_SPL_QSPI_MMAP
This is wrong and likely break image creation for brcp1 board.
arch/arm/dts/zynq-binman-brcp1.dtsi:23: offset =
<CONFIG_SYS_SPI_U_BOOT_OFFS>;
37 unsigned int __weak spl_spi_get_uboot_offs(struct spi_flash *flash)
38 {
39 return CONFIG_SYS_SPI_U_BOOT_OFFS;
40 }
help
Address within SPI-Flash from where the u-boot payload is fetched
from.
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h
index 94273d0deb9..f59af92f3ae 100644
--- a/include/configs/zynq-common.h
+++ b/include/configs/zynq-common.h
@@ -35,6 +35,14 @@
/* Ethernet driver */
/* NOR */
#ifdef CONFIG_SPL_NOR_SUPPORT
+/*
+ * Memory-mapped address of QSPI flash when in SPL "NOR" mode. The method
used
+ * is "NOR" boot, but the data is on SPI media, hence using the SPI offset.
+ * Access to the QSPI controller will break XIP mode, so this cannot be
used for
+ * XIP mode when using the QSPI controller in its regular mode.
+ */
+#define ZYNQ_QSPI0_LINEAR_ADDR 0xfc000000
+#define CFG_SYS_UBOOT_BASE (ZYNQ_QSPI0_LINEAR_ADDR +
CONFIG_SYS_SPI_U_BOOT_OFFS)
#endif
#ifdef CONFIG_USB_EHCI_ZYNQ
# define DFU_DEFAULT_POLL_TIMEOUT 300
---
base-commit: f7fac14ea6c885eef319f0b97bc4fa6ae462f150
branch: upstream-topic-miami
M
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