mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 0/5] arm: socfpga: agilex5: cleanup SDRAM initialization
@ 2026-06-04 11:06 Michael Tretter
  2026-06-04 11:06 ` [PATCH 1/5] arm: socfpga: agilex5: separate EL3 init function Michael Tretter
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Michael Tretter @ 2026-06-04 11:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

The Agilex5 SDRAM initialization contains some obscure and unclear
workarounds, which are supposedly necessary for a successful SDRAM
initialization.

I observed a race condition between the IOSSM firmware, which is
responsible for the SDRAM initialization, and barebox. I assume this
race is responsible for the observed initialization failures.

Add an explicit workaround including documentation for the race
condition and remove the other workarounds.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
Michael Tretter (5):
      arm: socfpga: agilex5: separate EL3 init function
      arm: socfpga: agilex5: panic if DDR init failed
      arm: socfpga: iossm: add delay to wait for firmware
      arm: socfpga: agilex5: drop dual port hack
      arm: socfpga: agilex5: drop bank select before ddr_init

 arch/arm/mach-socfpga/agilex5-sdram.c | 10 ++--------
 arch/arm/mach-socfpga/atf.c           | 32 +++++++++++++++++---------------
 arch/arm/mach-socfpga/iossm_mailbox.c | 23 ++++++++++++++++++++---
 3 files changed, 39 insertions(+), 26 deletions(-)
---
base-commit: 9f6b78063a365b5b2674663ba844fa928937f203
change-id: 20260604-socfpga-axe5-sdram-init-254ac55cd385

Best regards,
-- 
Michael Tretter <m.tretter@pengutronix.de>




^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/5] arm: socfpga: agilex5: separate EL3 init function
  2026-06-04 11:06 [PATCH 0/5] arm: socfpga: agilex5: cleanup SDRAM initialization Michael Tretter
@ 2026-06-04 11:06 ` Michael Tretter
  2026-06-04 11:06 ` [PATCH 2/5] arm: socfpga: agilex5: panic if DDR init failed Michael Tretter
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Tretter @ 2026-06-04 11:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

Extract the EL3 initialization from the entry function as cleanup and to
be able to adjust the el3_init code more easily.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 arch/arm/mach-socfpga/atf.c | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-socfpga/atf.c b/arch/arm/mach-socfpga/atf.c
index e1f0a3558b04..1fd11c426bc2 100644
--- a/arch/arm/mach-socfpga/atf.c
+++ b/arch/arm/mach-socfpga/atf.c
@@ -61,27 +61,32 @@ static void __noreturn agilex5_load_and_start_image_via_tfa(void)
 	__builtin_unreachable();
 }
 
+static void agilex5_el3_init(void)
+{
+	agilex5_initialize_security_policies();
+	pr_debug("Security policies initialized\n");
+
+	/*
+	 * need to set the bank select enable before the
+	 * agilex5_ddr_init_full() otherwise the serial doesn't show
+	 * anything.
+	 */
+	if (!IS_ENABLED(CONFIG_DEBUG_LL))
+		writel(LCR_BKSE, SOCFPGA_UART0_ADDRESS + LCR);
+	agilex5_ddr_init_full();
+
+	socfpga_agilex5_qspi_init();
+
+	agilex5_load_and_start_image_via_tfa();
+}
+
 void __noreturn agilex5_barebox_entry(void *fdt)
 {
 	phys_addr_t membase;
 	phys_size_t memsize;
 
 	if (current_el() == 3) {
-		agilex5_initialize_security_policies();
-		pr_debug("Security policies initialized\n");
-
-		/*
-		 * need to set the bank select enable before the
-		 * agilex5_ddr_init_full() otherwise the serial doesn't show
-		 * anything.
-		 */
-		if (!IS_ENABLED(CONFIG_DEBUG_LL))
-			writel(LCR_BKSE, SOCFPGA_UART0_ADDRESS + LCR);
-		agilex5_ddr_init_full();
-
-		socfpga_agilex5_qspi_init();
-
-		agilex5_load_and_start_image_via_tfa();
+		agilex5_el3_init();
 		__builtin_unreachable();
 	}
 

-- 
2.47.3




^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 2/5] arm: socfpga: agilex5: panic if DDR init failed
  2026-06-04 11:06 [PATCH 0/5] arm: socfpga: agilex5: cleanup SDRAM initialization Michael Tretter
  2026-06-04 11:06 ` [PATCH 1/5] arm: socfpga: agilex5: separate EL3 init function Michael Tretter
@ 2026-06-04 11:06 ` Michael Tretter
  2026-06-04 11:06 ` [PATCH 3/5] arm: socfpga: iossm: add delay to wait for firmware Michael Tretter
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Tretter @ 2026-06-04 11:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

There is no point in continuing booting if the DDR initialization has
failed. Panic early to avoid obscure subsequent faults.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 arch/arm/mach-socfpga/atf.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-socfpga/atf.c b/arch/arm/mach-socfpga/atf.c
index 1fd11c426bc2..6ddfef34632f 100644
--- a/arch/arm/mach-socfpga/atf.c
+++ b/arch/arm/mach-socfpga/atf.c
@@ -63,6 +63,8 @@ static void __noreturn agilex5_load_and_start_image_via_tfa(void)
 
 static void agilex5_el3_init(void)
 {
+	int ret;
+
 	agilex5_initialize_security_policies();
 	pr_debug("Security policies initialized\n");
 
@@ -73,7 +75,9 @@ static void agilex5_el3_init(void)
 	 */
 	if (!IS_ENABLED(CONFIG_DEBUG_LL))
 		writel(LCR_BKSE, SOCFPGA_UART0_ADDRESS + LCR);
-	agilex5_ddr_init_full();
+	ret = agilex5_ddr_init_full();
+	if (ret)
+		panic("DDR initialization failed\n");
 
 	socfpga_agilex5_qspi_init();
 

-- 
2.47.3




^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 3/5] arm: socfpga: iossm: add delay to wait for firmware
  2026-06-04 11:06 [PATCH 0/5] arm: socfpga: agilex5: cleanup SDRAM initialization Michael Tretter
  2026-06-04 11:06 ` [PATCH 1/5] arm: socfpga: agilex5: separate EL3 init function Michael Tretter
  2026-06-04 11:06 ` [PATCH 2/5] arm: socfpga: agilex5: panic if DDR init failed Michael Tretter
@ 2026-06-04 11:06 ` Michael Tretter
  2026-06-04 11:06 ` [PATCH 4/5] arm: socfpga: agilex5: drop dual port hack Michael Tretter
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Tretter @ 2026-06-04 11:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

Depending on the boot time of barebox, I observed cases, where the IOSSM
version register reported mailbox version 0 even though its version 0.
If this happens, barebox uses the wrong interface to read the SDRAM
configuration, is not able to detect and configure the SDRAM, and fails
to boot.

Unfortunately, the IOSSM firmware does not provide a proper
synchronization point to detect if the firmware finished its
initialization.

Add a workaround to delay the boot until the firmware initialized the
version register or a delay for mailbox version 0.

Don't use readl_poll_timeout, because in the PBL readl_poll_timeout
polls indefinitely and the polling needs to run into the timeout in case
of mailbox version 0.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 arch/arm/mach-socfpga/iossm_mailbox.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
index 168bef3faeeb..6a9a7a489b75 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.c
+++ b/arch/arm/mach-socfpga/iossm_mailbox.c
@@ -158,10 +158,27 @@ static int io96b_mb_version(struct io96b_info *io96b_ctrl)
 {
 	void __iomem *io96b_csr_addr = io96b_ctrl->io96b[0].io96b_csr_addr;
 	u32 mailbox_header;
-	int version;
+	int version = 0;
+	int retry;
 
-	mailbox_header = readl(io96b_csr_addr + IOSSM_MAILBOX_HEADER_OFFSET);
-	version = FIELD_GET(IOSSM_MAILBOX_SPEC_VERSION_MASK, mailbox_header);
+	/*
+	 * There is a race between barebox on the HPS and the IOSSM firmware
+	 * initialization, which may cause barebox to read a mailbox version 0
+	 * from the IOSSM even though it's actually mailbox version 1, but the
+	 * register has not been updated, yet. Unfortunately, there is no
+	 * reliable synchronization point.
+	 *
+	 * Workaround this issue by reading the mailbox version more often. On
+	 * mailbox version 1, barebox waits until the firmware wrote the
+	 * version register. On mailbox version 0, barebox runs into the
+	 * timeout caused by the number of retries.
+	 *
+	 * The number of retries has been experimentally determined.
+	 */
+	for (retry = 100; version == 0 && retry > 0; retry--) {
+		mailbox_header = readl(io96b_csr_addr + IOSSM_MAILBOX_HEADER_OFFSET);
+		version = FIELD_GET(IOSSM_MAILBOX_SPEC_VERSION_MASK, mailbox_header);
+	}
 
 	return version;
 }

-- 
2.47.3




^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 4/5] arm: socfpga: agilex5: drop dual port hack
  2026-06-04 11:06 [PATCH 0/5] arm: socfpga: agilex5: cleanup SDRAM initialization Michael Tretter
                   ` (2 preceding siblings ...)
  2026-06-04 11:06 ` [PATCH 3/5] arm: socfpga: iossm: add delay to wait for firmware Michael Tretter
@ 2026-06-04 11:06 ` Michael Tretter
  2026-06-04 11:06 ` [PATCH 5/5] arm: socfpga: agilex5: drop bank select before ddr_init Michael Tretter
  2026-06-05  6:13 ` [PATCH 0/5] arm: socfpga: agilex5: cleanup SDRAM initialization Sascha Hauer
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Tretter @ 2026-06-04 11:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

On Agilex 5 with a firmware generated by Quartus 25.3, the dualport
value in the handoff_table is correctly set to 0. In this case, the
workaround is not necessary.

If the Agilex 5 is configured with dual port DDR access, the hack is not
correct either, because while the firmware is configured for dual port,
barebox would incorrectly initialize the IOSSM controller.

Remove the hack.

If the dualport issues become apparent, either use this as a test case
to fix dualport support correctly or implement a proper workaround with
documentation and warning.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 arch/arm/mach-socfpga/agilex5-sdram.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mach-socfpga/agilex5-sdram.c b/arch/arm/mach-socfpga/agilex5-sdram.c
index 7a82dc6a6ad4..fa940958d104 100644
--- a/arch/arm/mach-socfpga/agilex5-sdram.c
+++ b/arch/arm/mach-socfpga/agilex5-sdram.c
@@ -94,14 +94,8 @@ static int populate_ddr_handoff(struct altera_sdram_plat *plat, struct io96b_inf
 	/* Read handoff for DDR configuration */
 	socfpga_handoff_read((void *)SOC64_HANDOFF_SDRAM, handoff_table, len);
 
-	/* Read handoff - dual port
-	   FIXME: Intel u-boot has a patch that HACKs this to 0
-	   https://github.com/altera-opensource/meta-intel-fpga-refdes/ \
-	   blob/master/recipes-bsp/u-boot/files/v1-0001-HSD-15015933655-ddr-altera-agilex5-Hack-dual-port-DO-NOT-MERGE.patch
-	   Patch doesn't say why or what is broken here: handoff files? dualport RAM access?
-	 */
-	//plat->dualport = FIELD_GET(BIT(0), handoff_table[PORT_EMIF_CONFIG_OFFSET]);
-	plat->dualport = 0;
+	/* Read handoff - dual port */
+	plat->dualport = FIELD_GET(BIT(0), handoff_table[PORT_EMIF_CONFIG_OFFSET]);
 	pr_debug("%s: dualport from handoff: 0x%x\n", __func__, plat->dualport);
 
 	if (plat->dualport)

-- 
2.47.3




^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 5/5] arm: socfpga: agilex5: drop bank select before ddr_init
  2026-06-04 11:06 [PATCH 0/5] arm: socfpga: agilex5: cleanup SDRAM initialization Michael Tretter
                   ` (3 preceding siblings ...)
  2026-06-04 11:06 ` [PATCH 4/5] arm: socfpga: agilex5: drop dual port hack Michael Tretter
@ 2026-06-04 11:06 ` Michael Tretter
  2026-06-05  6:13 ` [PATCH 0/5] arm: socfpga: agilex5: cleanup SDRAM initialization Sascha Hauer
  5 siblings, 0 replies; 7+ messages in thread
From: Michael Tretter @ 2026-06-04 11:06 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

I verified that the bank select on UART0 is not necessary for the
ddr_initialization. Thus, the documentation why the bank select is
necessary is not valid anymore.

Furthermore, depending on the UART used by the board, using UART0 may
not be general enough, anyway.

It seems like the bank select rather added a delay before the SDRAM
initialization and without the bank select, the serial didn't show
anything because the SDRAM initialization failed.

Remove the workaround.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 arch/arm/mach-socfpga/atf.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/arch/arm/mach-socfpga/atf.c b/arch/arm/mach-socfpga/atf.c
index 6ddfef34632f..ac69fb7776ca 100644
--- a/arch/arm/mach-socfpga/atf.c
+++ b/arch/arm/mach-socfpga/atf.c
@@ -68,13 +68,6 @@ static void agilex5_el3_init(void)
 	agilex5_initialize_security_policies();
 	pr_debug("Security policies initialized\n");
 
-	/*
-	 * need to set the bank select enable before the
-	 * agilex5_ddr_init_full() otherwise the serial doesn't show
-	 * anything.
-	 */
-	if (!IS_ENABLED(CONFIG_DEBUG_LL))
-		writel(LCR_BKSE, SOCFPGA_UART0_ADDRESS + LCR);
 	ret = agilex5_ddr_init_full();
 	if (ret)
 		panic("DDR initialization failed\n");

-- 
2.47.3




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/5] arm: socfpga: agilex5: cleanup SDRAM initialization
  2026-06-04 11:06 [PATCH 0/5] arm: socfpga: agilex5: cleanup SDRAM initialization Michael Tretter
                   ` (4 preceding siblings ...)
  2026-06-04 11:06 ` [PATCH 5/5] arm: socfpga: agilex5: drop bank select before ddr_init Michael Tretter
@ 2026-06-05  6:13 ` Sascha Hauer
  5 siblings, 0 replies; 7+ messages in thread
From: Sascha Hauer @ 2026-06-05  6:13 UTC (permalink / raw)
  To: BAREBOX, Michael Tretter; +Cc: Steffen Trumtrar


On Thu, 04 Jun 2026 13:06:53 +0200, Michael Tretter wrote:
> The Agilex5 SDRAM initialization contains some obscure and unclear
> workarounds, which are supposedly necessary for a successful SDRAM
> initialization.
> 
> I observed a race condition between the IOSSM firmware, which is
> responsible for the SDRAM initialization, and barebox. I assume this
> race is responsible for the observed initialization failures.
> 
> [...]

Applied, thanks!

[1/5] arm: socfpga: agilex5: separate EL3 init function
      https://git.pengutronix.de/cgit/barebox/commit/?id=f615446b218f (link may not be stable)
[2/5] arm: socfpga: agilex5: panic if DDR init failed
      https://git.pengutronix.de/cgit/barebox/commit/?id=3791fb227199 (link may not be stable)
[3/5] arm: socfpga: iossm: add delay to wait for firmware
      https://git.pengutronix.de/cgit/barebox/commit/?id=4296d8ae1181 (link may not be stable)
[4/5] arm: socfpga: agilex5: drop dual port hack
      https://git.pengutronix.de/cgit/barebox/commit/?id=36ad90f489fb (link may not be stable)
[5/5] arm: socfpga: agilex5: drop bank select before ddr_init
      https://git.pengutronix.de/cgit/barebox/commit/?id=6685029a7c78 (link may not be stable)

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-06-05  6:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-04 11:06 [PATCH 0/5] arm: socfpga: agilex5: cleanup SDRAM initialization Michael Tretter
2026-06-04 11:06 ` [PATCH 1/5] arm: socfpga: agilex5: separate EL3 init function Michael Tretter
2026-06-04 11:06 ` [PATCH 2/5] arm: socfpga: agilex5: panic if DDR init failed Michael Tretter
2026-06-04 11:06 ` [PATCH 3/5] arm: socfpga: iossm: add delay to wait for firmware Michael Tretter
2026-06-04 11:06 ` [PATCH 4/5] arm: socfpga: agilex5: drop dual port hack Michael Tretter
2026-06-04 11:06 ` [PATCH 5/5] arm: socfpga: agilex5: drop bank select before ddr_init Michael Tretter
2026-06-05  6:13 ` [PATCH 0/5] arm: socfpga: agilex5: cleanup SDRAM initialization Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox