mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Michael Tretter <m.tretter@pengutronix.de>
To: Sascha Hauer <s.hauer@pengutronix.de>,
	 BAREBOX <barebox@lists.infradead.org>
Cc: Michael Tretter <m.tretter@pengutronix.de>
Subject: [PATCH 4/4] arm: socfpga: iossm: wait for PLL lock from handoff table
Date: Thu, 03 Sep 2026 18:12:45 +0200	[thread overview]
Message-ID: <20260903-socfpga-fix-sdram-setup-v1-4-0daa166adbca@pengutronix.de> (raw)
In-Reply-To: <20260903-socfpga-fix-sdram-setup-v1-0-0daa166adbca@pengutronix.de>

The PLL setting in the handoff table tells barebox, for which PLL it
needs to wait to be locked before configuring the IOSSM.

While at it, fix the typo in the ECC_INTSTATUS_DERR register.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 arch/arm/mach-socfpga/agilex5-sdram.c |  6 ++++
 arch/arm/mach-socfpga/iossm_mailbox.c | 58 +++++++++++++++++++++++++----------
 arch/arm/mach-socfpga/iossm_mailbox.h |  2 ++
 3 files changed, 50 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-socfpga/agilex5-sdram.c b/arch/arm/mach-socfpga/agilex5-sdram.c
index 4a28713a3588..e3c6c414b261 100644
--- a/arch/arm/mach-socfpga/agilex5-sdram.c
+++ b/arch/arm/mach-socfpga/agilex5-sdram.c
@@ -107,6 +107,12 @@ static int populate_ddr_handoff(struct altera_sdram_plat *plat, struct io96b_inf
 	else
 		io96b_ctrl->num_instance = 1;
 
+	/* Read PLL from handoff */
+	io96b_ctrl->selected_plls = FIELD_GET(GENMASK(19, 16),
+					      handoff_table[PORT_EMIF_CONFIG_OFFSET]);
+	pr_debug("%s: selected PLLs from handoff: 0x%x\n",
+		 __func__, io96b_ctrl->selected_plls);
+
 	/* Assign IO96B CSR base address if it is valid */
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
 		io96b_ctrl->io96b[i].io96b_csr_addr = IOMEM(io96b_csr_reg_addr[i]);
diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
index 28070121ee6b..2822920ebdf0 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.c
+++ b/arch/arm/mach-socfpga/iossm_mailbox.c
@@ -17,7 +17,7 @@
 #include <mach/socfpga/soc64-system-manager.h>
 
 #define ECC_INTSTATUS_SERR				0x9C
-#define ECC_INISTATUS_DERR				0xA0
+#define ECC_INTSTATUS_DERR				0xA0
 
 #define DDR_CSR_CLKGEN_LOCKED_IO96B0_MASK		BIT(16)
 #define DDR_CSR_CLKGEN_LOCKED_IO96B1_MASK		BIT(17)
@@ -47,21 +47,49 @@
 #define IOSSM_MEM_INIT_STATUS_INTF0_OFFSET		0x260
 #define IOSSM_MEM_INIT_STATUS_INTF1_OFFSET		0x2E0
 
+#define IO96B0_PLL_A BIT(0)
+#define IO96B0_PLL_B BIT(1)
+#define IO96B1_PLL_A BIT(2)
+#define IO96B1_PLL_B BIT(3)
+
+static const unsigned int plls[] = {
+	IO96B0_PLL_A, IO96B0_PLL_B, IO96B1_PLL_A, IO96B1_PLL_B
+};
+
+#define IO96B_PLL_REG(pll) \
+	(pll & (IO96B0_PLL_A | IO96B1_PLL_A) ? ECC_INTSTATUS_SERR : ECC_INTSTATUS_DERR)
+#define IO96B_PLL_INSTANCE(pll) \
+	(pll & (IO96B0_PLL_A | IO96B0_PLL_B) ? 0 : 1)
+#define IO96B_PLL_LOCATION(pll) \
+	(pll & (IO96B0_PLL_A | IO96B1_PLL_A) ? "A" : "B")
+
 /* supported DDR type list */
 static const char *ddr_type_list[7] = {
 		"DDR4", "DDR5", "DDR5_RDIMM", "LPDDR4", "LPDDR5", "QDRIV", "UNKNOWN"
 };
 
-static int is_ddr_csr_clkgen_locked(u32 clkgen_mask)
+static int io96b_pll_locked_poll_timeout(unsigned int pll)
 {
-	int ret;
+	u32 mask = DDR_CSR_CLKGEN_LOCKED_IO96B_MASK(IO96B_PLL_INSTANCE(pll));
+	void __iomem *reg = IOMEM(SOCFPGA_SYSMGR_ADDRESS) + IO96B_PLL_REG(pll);
 	u32 tmp;
 
-	ret = readl_poll_timeout(IOMEM(SOCFPGA_SYSMGR_ADDRESS) + ECC_INTSTATUS_SERR,
-				 tmp, tmp & clkgen_mask, 10 * USEC_PER_SEC);
-	if (ret) {
-		pr_debug("%s: ddr csr clkgena locked is timeout\n", __func__);
-		return ret;
+	pr_debug("poll for locked PLL: instance %d, location %s\n",
+		 IO96B_PLL_INSTANCE(pll), IO96B_PLL_LOCATION(pll));
+	return readl_poll_timeout(reg, tmp, tmp & mask, 10 * USEC_PER_SEC);
+}
+
+static int is_ddr_csr_clkgen_locked(unsigned int selected_plls)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(plls); i++) {
+		if (!(selected_plls & plls[i]))
+			continue;
+		ret = io96b_pll_locked_poll_timeout(plls[i]);
+		if (ret)
+			return ret;
 	}
 
 	return 0;
@@ -288,17 +316,15 @@ void io96b_init_mem_cal(struct io96b_info *io96b_ctrl)
 	/* Initialize overall calibration status */
 	io96b_ctrl->overall_cal_status = false;
 
+	if (io96b_ctrl->ckgen_lock) {
+		ret = is_ddr_csr_clkgen_locked(io96b_ctrl->selected_plls);
+		if (ret)
+			hang();
+	}
+
 	/* Check initial calibration status for the assigned IO96B*/
 	count = 0;
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
-		if (io96b_ctrl->ckgen_lock) {
-			ret = is_ddr_csr_clkgen_locked(DDR_CSR_CLKGEN_LOCKED_IO96B_MASK(i));
-			if (ret) {
-				pr_err("%s: ckgena_lock iossm IO96B_%d is not locked\n",
-				       __func__, i);
-				hang();
-			}
-		}
 		ret = io96b_cal_status(io96b_ctrl->io96b[i].io96b_csr_addr);
 		if (ret) {
 			io96b_ctrl->io96b[i].cal_status = false;
diff --git a/arch/arm/mach-socfpga/iossm_mailbox.h b/arch/arm/mach-socfpga/iossm_mailbox.h
index 954bfcdf382e..55c51c2c091c 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.h
+++ b/arch/arm/mach-socfpga/iossm_mailbox.h
@@ -119,6 +119,7 @@ struct io96b_instance {
  * @overall_size:	Total DDR memory size
  * @io96b[]:		IO96B instance specific information
  * @ckgen_lock:		IO96B GEN PLL lock (false = not locked, true = locked)
+ * @selected_plls:	Selected IO96B PLLs
  */
 struct io96b_info {
 	int			 version;
@@ -130,6 +131,7 @@ struct io96b_info {
 	phys_size_t		 overall_size;
 	struct io96b_instance	 io96b[MAX_IO96B_SUPPORTED];
 	bool			 ckgen_lock;
+	unsigned int		 selected_plls;
 };
 
 int io96b_mb_req(void __iomem *io96b_csr_addr, u32 ip_type, u32 instance_id,

-- 
2.47.3




  parent reply	other threads:[~2026-09-03 16:14 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-03 16:12 [PATCH 0/4] arm: socfpga: iossm: cleanup and fix SDRAM setup Michael Tretter
2026-09-03 16:12 ` [PATCH 1/4] arm: socfpga: iossm: remove unused num_port Michael Tretter
2026-09-03 16:12 ` [PATCH 2/4] arm: socfpga: iossm: fix macro Michael Tretter
2026-09-03 16:12 ` [PATCH 3/4] arm: socfpga: iossm: refactor register access Michael Tretter
2026-09-03 16:12 ` Michael Tretter [this message]
2026-09-04  9:31 ` [PATCH 0/4] arm: socfpga: iossm: cleanup and fix SDRAM setup Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260903-socfpga-fix-sdram-setup-v1-4-0daa166adbca@pengutronix.de \
    --to=m.tretter@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    --cc=s.hauer@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox