public inbox for barebox@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH 00/10] arm: socfpga: iossm: add support for mailbox v1
@ 2026-04-07 17:09 Michael Tretter
  2026-04-07 17:09 ` [PATCH 01/10] arm: socfpga: iossm: remove uninitialized variable Michael Tretter
                   ` (9 more replies)
  0 siblings, 10 replies; 13+ messages in thread
From: Michael Tretter @ 2026-04-07 17:09 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

The IOSSM on the Agilex5 may have different mailbox versions depending
on the Quartus version that was used to generate the SoC configuration.
Up until now, barebox only supports mailbox version 0, which was
configured by versions before Quartus 25.3.0. With Quartus 25.3.0 and
later, the IOSSM provides mailbox version 1, which exposes many
configuration options as registers instead of mailbox responses.

Since the IOSSM is used for SDRAM setup, barebox didn't boot on devices
configured with Quartus 25.3.0 or later.

Refactor the iossm handling and add the handling of IOSSM mailbox
version 1.

While at it, also add inline ECC handling. If the memory interface of
the Agilex5 is configured for inline ECC (which is the current default)
the bootloader has to be aware of inline ECC, too.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
Michael Tretter (10):
      arm: socfpga: iossm: remove uninitialized variable
      arm: socfpga: iossm: add version check
      arm: socfpga: iossm: use local mb_ctrl variable
      arm: socfpga: iossm: store size in bytes
      arm: socfpga: iossm: refactor io96b_mb_init
      arm: socfpga: iossm: refactor return value handling
      arm: socfgpa: iossm: extract poll_bist_mem_init_status
      arm: socfgpa: iossm: extract initialization of one interface
      arm: socfpga: iossm: add memory initialization with inline ecc
      arm: socfpga: iossm: add support for mailbox v1

 arch/arm/mach-socfpga/agilex5-sdram.c |   9 +-
 arch/arm/mach-socfpga/iossm_mailbox.c | 359 ++++++++++++++++++++++++----------
 arch/arm/mach-socfpga/iossm_mailbox.h |   8 +-
 3 files changed, 272 insertions(+), 104 deletions(-)
---
base-commit: 0933e8f2ebf0d91dfcf177a4e4292b02921a53f1
change-id: 20260407-socfpga-iossm-v1-59c19e340a2b

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




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

* [PATCH 01/10] arm: socfpga: iossm: remove uninitialized variable
  2026-04-07 17:09 [PATCH 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
@ 2026-04-07 17:09 ` Michael Tretter
  2026-04-07 17:09 ` [PATCH 02/10] arm: socfpga: iossm: add version check Michael Tretter
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Tretter @ 2026-04-07 17:09 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

The variable i is not initialized. As the index when writing values to
cmd_resp_data is hard-coded, we may use a hard coded index in the print
statements, too.

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

diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
index 0e8c9e36017d..d89117da4fd4 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.c
+++ b/arch/arm/mach-socfpga/iossm_mailbox.c
@@ -82,7 +82,6 @@ int io96b_mb_req(phys_addr_t io96b_csr_addr, u32 ip_type, u32 instance_id,
 		 u32 cmd_param_4, u32 cmd_param_5, u32 cmd_param_6,
 		 struct io96b_mb_resp *resp)
 {
-	int i;
 	int ret;
 	u32 cmd_req, cmd_resp;
 
@@ -138,15 +137,15 @@ int io96b_mb_req(phys_addr_t io96b_csr_addr, u32 ip_type, u32 instance_id,
 	resp->cmd_resp_data[0] = readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_0_OFFSET);
 	pr_debug("%s: IOSSM_CMD_RESPONSE_DATA_0_OFFSET 0x%llx: 0x%x\n",
 		 __func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_0_OFFSET,
-		 resp->cmd_resp_data[i]);
+		 resp->cmd_resp_data[0]);
 	resp->cmd_resp_data[1] = readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_1_OFFSET);
 	pr_debug("%s: IOSSM_CMD_RESPONSE_DATA_1_OFFSET 0x%llx: 0x%x\n",
 		 __func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_1_OFFSET,
-		 resp->cmd_resp_data[i]);
+		 resp->cmd_resp_data[1]);
 	resp->cmd_resp_data[2] = readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_2_OFFSET);
 	pr_debug("%s: IOSSM_CMD_RESPONSE_DATA_2_OFFSET 0x%llx: 0x%x\n",
 		 __func__, io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_2_OFFSET,
-		 resp->cmd_resp_data[i]);
+		 resp->cmd_resp_data[2]);
 
 	resp->cmd_resp_status = readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
 	pr_debug("%s: CMD_RESPONSE_STATUS 0x%llx: 0x%x\n", __func__,

-- 
2.47.3




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

* [PATCH 02/10] arm: socfpga: iossm: add version check
  2026-04-07 17:09 [PATCH 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
  2026-04-07 17:09 ` [PATCH 01/10] arm: socfpga: iossm: remove uninitialized variable Michael Tretter
@ 2026-04-07 17:09 ` Michael Tretter
  2026-04-07 17:09 ` [PATCH 03/10] arm: socfpga: iossm: use local mb_ctrl variable Michael Tretter
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Tretter @ 2026-04-07 17:09 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

There is a version 1 of the IOSSM, which is used if the board
configuration was created with Quartus 25.3.0 or later.

Warn the user if barebox didn't detect the supported version 0.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 arch/arm/mach-socfpga/iossm_mailbox.c | 27 +++++++++++++++++++++++++++
 arch/arm/mach-socfpga/iossm_mailbox.h |  2 ++
 2 files changed, 29 insertions(+)

diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
index d89117da4fd4..d14399f305de 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.c
+++ b/arch/arm/mach-socfpga/iossm_mailbox.c
@@ -27,6 +27,9 @@
 #define INTF_IP_TYPE_MASK	GENMASK(31, 29)
 #define INTF_INSTANCE_ID_MASK	GENMASK(28, 24)
 
+#define IOSSM_MAILBOX_HEADER_OFFSET			0x0
+#define IOSSM_MAILBOX_SPEC_VERSION_MASK			GENMASK(2, 0)
+
 /* supported DDR type list */
 static const char *ddr_type_list[7] = {
 		"DDR4", "DDR5", "DDR5_RDIMM", "LPDDR4", "LPDDR5", "QDRIV", "UNKNOWN"
@@ -163,6 +166,18 @@ int io96b_mb_req(phys_addr_t io96b_csr_addr, u32 ip_type, u32 instance_id,
 	return 0;
 }
 
+static int io96b_mb_version(struct io96b_info *io96b_ctrl)
+{
+	phys_addr_t io96b_csr_addr = io96b_ctrl->io96b[0].io96b_csr_addr;
+	u32 mailbox_header;
+	int version;
+
+	mailbox_header = readl(io96b_csr_addr + IOSSM_MAILBOX_HEADER_OFFSET);
+	version = FIELD_GET(IOSSM_MAILBOX_SPEC_VERSION_MASK, mailbox_header);
+
+	return version;
+}
+
 /*
  * Initial function to be called to set memory interface IP type and instance ID
  * IP type and instance ID need to be determined before sending mailbox command
@@ -172,6 +187,18 @@ void io96b_mb_init(struct io96b_info *io96b_ctrl)
 	struct io96b_mb_resp usr_resp;
 	u8 ip_type_ret, instance_id_ret;
 	int i, j, k;
+	int version;
+
+	version = io96b_mb_version(io96b_ctrl);
+	switch (version) {
+	case 0:
+		pr_debug("IOSSM: mailbox version %d\n", version);
+		break;
+	default:
+		pr_warn("IOSSM: unsupported mailbox version %d\n", version);
+		break;
+	}
+	io96b_ctrl->version = version;
 
 	pr_debug("%s: num_instance %d\n", __func__, io96b_ctrl->num_instance);
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
diff --git a/arch/arm/mach-socfpga/iossm_mailbox.h b/arch/arm/mach-socfpga/iossm_mailbox.h
index 29b3f069072d..bd66621d5f70 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.h
+++ b/arch/arm/mach-socfpga/iossm_mailbox.h
@@ -110,6 +110,7 @@ struct io96b_instance {
 /*
  * Overall IO96B instance(s) information
  *
+ * @version:		Version of the IO96B
  * @num_instance:	Number of instance(s) assigned to HPS
  * @overall_cal_status: Overall calibration status for all IO96B instance(s)
  * @ddr_type:		DDR memory type
@@ -120,6 +121,7 @@ struct io96b_instance {
  * @num_port:		Number of IO96B port.
  */
 struct io96b_info {
+	int			 version;
 	u8			 num_instance;
 	bool			 overall_cal_status;
 	const char		*ddr_type;

-- 
2.47.3




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

* [PATCH 03/10] arm: socfpga: iossm: use local mb_ctrl variable
  2026-04-07 17:09 [PATCH 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
  2026-04-07 17:09 ` [PATCH 01/10] arm: socfpga: iossm: remove uninitialized variable Michael Tretter
  2026-04-07 17:09 ` [PATCH 02/10] arm: socfpga: iossm: add version check Michael Tretter
@ 2026-04-07 17:09 ` Michael Tretter
  2026-04-07 17:09 ` [PATCH 04/10] arm: socfpga: iossm: store size in bytes Michael Tretter
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Tretter @ 2026-04-07 17:09 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

Introduce a local variable to improve the readablility and avoid long
names when accessing the variables.

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

diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
index d14399f305de..9299fee71e0b 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.c
+++ b/arch/arm/mach-socfpga/iossm_mailbox.c
@@ -185,6 +185,7 @@ static int io96b_mb_version(struct io96b_info *io96b_ctrl)
 void io96b_mb_init(struct io96b_info *io96b_ctrl)
 {
 	struct io96b_mb_resp usr_resp;
+	struct io96b_mb_ctrl *mb_ctrl;
 	u8 ip_type_ret, instance_id_ret;
 	int i, j, k;
 	int version;
@@ -202,27 +203,28 @@ void io96b_mb_init(struct io96b_info *io96b_ctrl)
 
 	pr_debug("%s: num_instance %d\n", __func__, io96b_ctrl->num_instance);
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		mb_ctrl = &io96b_ctrl->io96b[i].mb_ctrl;
 		pr_debug("%s: get memory interface IO96B %d\n", __func__, i);
 		/* Get memory interface IP type and instance ID (IP identifier) */
 		io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr, 0, 0,
 				      CMD_GET_SYS_INFO, GET_MEM_INTF_INFO, &usr_resp);
 		pr_debug("%s: get response from memory interface IO96B %d\n", __func__, i);
 		/* Retrieve number of memory interface(s) */
-		io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface =
+		mb_ctrl->num_mem_interface =
 			IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) & 0x3;
-		pr_debug("%s: IO96B %d: num_mem_interface: 0x%x\n", __func__,
-			 i, io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface);
+		pr_debug("%s: IO96B %d: num_mem_interface: %d\n", __func__,
+			 i, mb_ctrl->num_mem_interface);
 
 		/* Retrieve memory interface IP type and instance ID (IP identifier) */
 		j = 0;
-		for (k = 0; k < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; k++) {
+		for (k = 0; k < mb_ctrl->num_mem_interface; k++) {
 			ip_type_ret = FIELD_GET(INTF_IP_TYPE_MASK, usr_resp.cmd_resp_data[k]);
 			instance_id_ret = FIELD_GET(INTF_INSTANCE_ID_MASK,
 						    usr_resp.cmd_resp_data[k]);
 
 			if (ip_type_ret) {
-				io96b_ctrl->io96b[i].mb_ctrl.ip_type[j] = ip_type_ret;
-				io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j] = instance_id_ret;
+				mb_ctrl->ip_type[j] = ip_type_ret;
+				mb_ctrl->ip_instance_id[j] = instance_id_ret;
 				pr_debug("%s: IO96B %d mem_interface %d: ip_type_ret: 0x%x\n",
 					 __func__, i, j, ip_type_ret);
 				pr_debug("%s: IO96B %d mem_interface %d: instance_id_ret: 0x%x\n",
@@ -297,6 +299,7 @@ void io96b_init_mem_cal(struct io96b_info *io96b_ctrl)
 int io96b_trig_mem_cal(struct io96b_info *io96b_ctrl)
 {
 	struct io96b_mb_resp usr_resp;
+	struct io96b_mb_ctrl *mb_ctrl;
 	bool recal_success;
 	int i, j, k;
 	u32 cal_stat_offset;
@@ -305,10 +308,12 @@ int io96b_trig_mem_cal(struct io96b_info *io96b_ctrl)
 	int count = 0;
 
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		mb_ctrl = &io96b_ctrl->io96b[i].mb_ctrl;
+
 		if (io96b_ctrl->io96b[i].cal_status)
 			continue;
 
-		for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) {
+		for (j = 0; j < mb_ctrl->num_mem_interface; j++) {
 			recal_success = false;
 
 			/* Re-calibration first memory interface with failed calibration */
@@ -326,8 +331,8 @@ int io96b_trig_mem_cal(struct io96b_info *io96b_ctrl)
 					break;
 				}
 				io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr,
-						      io96b_ctrl->io96b[i].mb_ctrl.ip_type[j],
-						      io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j],
+						      mb_ctrl->ip_type[j],
+						      mb_ctrl->ip_instance_id[j],
 						      CMD_TRIG_MEM_CAL_OP,
 						      TRIG_MEM_CAL, &usr_resp);
 
@@ -361,6 +366,7 @@ int io96b_trig_mem_cal(struct io96b_info *io96b_ctrl)
 int io96b_get_mem_technology(struct io96b_info *io96b_ctrl)
 {
 	struct io96b_mb_resp usr_resp;
+	struct io96b_mb_ctrl *mb_ctrl;
 	int i, j;
 	u8 ddr_type_ret;
 
@@ -369,10 +375,11 @@ int io96b_get_mem_technology(struct io96b_info *io96b_ctrl)
 
 	/* Get and ensure all memory interface(s) same DDR type */
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
-		for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) {
+		mb_ctrl = &io96b_ctrl->io96b[i].mb_ctrl;
+		for (j = 0; j < mb_ctrl->num_mem_interface; j++) {
 			io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr,
-					      io96b_ctrl->io96b[i].mb_ctrl.ip_type[j],
-					      io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j],
+					      mb_ctrl->ip_type[j],
+					      mb_ctrl->ip_instance_id[j],
 					      CMD_GET_MEM_INFO, GET_MEM_TECHNOLOGY, &usr_resp);
 
 			ddr_type_ret =
@@ -395,17 +402,19 @@ int io96b_get_mem_technology(struct io96b_info *io96b_ctrl)
 int io96b_get_mem_width_info(struct io96b_info *io96b_ctrl)
 {
 	struct io96b_mb_resp usr_resp;
+	struct io96b_mb_ctrl *mb_ctrl;
 	int i, j;
 	u16 memory_size;
 	u16 total_memory_size = 0;
 
 	/* Get all memory interface(s) total memory size on all instance(s) */
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		mb_ctrl = &io96b_ctrl->io96b[i].mb_ctrl;
 		memory_size = 0;
-		for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) {
+		for (j = 0; j < mb_ctrl->num_mem_interface; j++) {
 			io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr,
-					      io96b_ctrl->io96b[i].mb_ctrl.ip_type[j],
-					      io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j],
+					      mb_ctrl->ip_type[j],
+					      mb_ctrl->ip_instance_id[j],
 					      CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, &usr_resp);
 
 			memory_size = memory_size +
@@ -435,6 +444,7 @@ int io96b_get_mem_width_info(struct io96b_info *io96b_ctrl)
 int io96b_ecc_enable_status(struct io96b_info *io96b_ctrl)
 {
 	struct io96b_mb_resp usr_resp;
+	struct io96b_mb_ctrl *mb_ctrl;
 	int i, j;
 	bool ecc_stat_set = false;
 	bool ecc_stat;
@@ -444,10 +454,11 @@ int io96b_ecc_enable_status(struct io96b_info *io96b_ctrl)
 
 	/* Get and ensure all memory interface(s) same ECC status */
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
-		for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) {
+		mb_ctrl = &io96b_ctrl->io96b[i].mb_ctrl;
+		for (j = 0; j < mb_ctrl->num_mem_interface; j++) {
 			io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr,
-					      io96b_ctrl->io96b[i].mb_ctrl.ip_type[j],
-					      io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j],
+					      mb_ctrl->ip_type[j],
+					      mb_ctrl->ip_instance_id[j],
 					      CMD_TRIG_CONTROLLER_OP, ECC_ENABLE_STATUS,
 					      &usr_resp);
 

-- 
2.47.3




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

* [PATCH 04/10] arm: socfpga: iossm: store size in bytes
  2026-04-07 17:09 [PATCH 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
                   ` (2 preceding siblings ...)
  2026-04-07 17:09 ` [PATCH 03/10] arm: socfpga: iossm: use local mb_ctrl variable Michael Tretter
@ 2026-04-07 17:09 ` Michael Tretter
  2026-04-07 17:43   ` Ahmad Fatoum
  2026-04-07 17:09 ` [PATCH 05/10] arm: socfpga: iossm: refactor io96b_mb_init Michael Tretter
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 13+ messages in thread
From: Michael Tretter @ 2026-04-07 17:09 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

The mem_width_info is the memory size in gigabits. Convert it to bytes
before storing it for each bank to have a more convenient format and
simplify the conversion when reading the value.

Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
---
 arch/arm/mach-socfpga/agilex5-sdram.c |  7 +++----
 arch/arm/mach-socfpga/iossm_mailbox.c | 13 +++++++++----
 arch/arm/mach-socfpga/iossm_mailbox.h |  5 +++--
 3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mach-socfpga/agilex5-sdram.c b/arch/arm/mach-socfpga/agilex5-sdram.c
index 96b2b425315f..5fb59d413e8f 100644
--- a/arch/arm/mach-socfpga/agilex5-sdram.c
+++ b/arch/arm/mach-socfpga/agilex5-sdram.c
@@ -299,10 +299,6 @@ int agilex5_ddr_init_full(void)
 		return ret;
 	}
 
-	hw_size = (phys_size_t)io96b_ctrl.overall_size * SZ_1G / SZ_8;
-
-	pr_debug("%s: %lld MiB\n", io96b_ctrl.ddr_type, hw_size >> 20);
-
 	ret = io96b_ecc_enable_status(&io96b_ctrl);
 	if (ret) {
 		pr_debug("DDR: Failed to get DDR ECC status\n");
@@ -326,6 +322,9 @@ int agilex5_ddr_init_full(void)
 		pr_debug("SDRAM-ECC: Initialized success\n");
 	}
 
+	hw_size = io96b_ctrl.overall_size;
+	pr_debug("%s: %lld MiB\n", io96b_ctrl.ddr_type, hw_size / SZ_1M);
+
 	sdram_set_firewall(hw_size);
 
 	/* Firewall setting for MPFE CSR */
diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
index 9299fee71e0b..042ea4a99e5c 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.c
+++ b/arch/arm/mach-socfpga/iossm_mailbox.c
@@ -9,6 +9,7 @@
 #include <common.h>
 #include <io.h>
 #include <linux/bitfield.h>
+#include <linux/sizes.h>
 #include "iossm_mailbox.h"
 #include <mach/socfpga/generic.h>
 #include <mach/socfpga/soc64-regs.h>
@@ -404,21 +405,25 @@ int io96b_get_mem_width_info(struct io96b_info *io96b_ctrl)
 	struct io96b_mb_resp usr_resp;
 	struct io96b_mb_ctrl *mb_ctrl;
 	int i, j;
-	u16 memory_size;
-	u16 total_memory_size = 0;
+	phys_size_t memory_size;
+	u32 mem_width_info;
+	phys_size_t total_memory_size = 0;
 
 	/* Get all memory interface(s) total memory size on all instance(s) */
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
 		mb_ctrl = &io96b_ctrl->io96b[i].mb_ctrl;
 		memory_size = 0;
+
 		for (j = 0; j < mb_ctrl->num_mem_interface; j++) {
 			io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr,
 					      mb_ctrl->ip_type[j],
 					      mb_ctrl->ip_instance_id[j],
 					      CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, &usr_resp);
+			mem_width_info = usr_resp.cmd_resp_data[1] & GENMASK(7, 0);
 
-			memory_size = memory_size +
-				(usr_resp.cmd_resp_data[1] & GENMASK(7, 0));
+			mb_ctrl->memory_size[j] = mem_width_info * (SZ_1G / SZ_8);
+
+			memory_size += mb_ctrl->memory_size[j];
 		}
 
 		if (!memory_size) {
diff --git a/arch/arm/mach-socfpga/iossm_mailbox.h b/arch/arm/mach-socfpga/iossm_mailbox.h
index bd66621d5f70..1b1bb1c7a19a 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.h
+++ b/arch/arm/mach-socfpga/iossm_mailbox.h
@@ -79,6 +79,7 @@ struct io96b_mb_ctrl {
 	u32 num_mem_interface;
 	u32 ip_type[2];
 	u32 ip_instance_id[2];
+	u32 memory_size[2];
 };
 
 /*
@@ -101,7 +102,7 @@ struct io96b_mb_resp {
  * @mb_ctrl:		IOSSM mailbox required information
  */
 struct io96b_instance {
-	u16 size;
+	phys_size_t size;
 	phys_addr_t io96b_csr_addr;
 	bool cal_status;
 	struct io96b_mb_ctrl mb_ctrl;
@@ -126,7 +127,7 @@ struct io96b_info {
 	bool			 overall_cal_status;
 	const char		*ddr_type;
 	bool			 ecc_status;
-	u16			 overall_size;
+	phys_size_t		 overall_size;
 	struct io96b_instance	 io96b[MAX_IO96B_SUPPORTED];
 	bool			 ckgen_lock;
 	u8			 num_port;

-- 
2.47.3




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

* [PATCH 05/10] arm: socfpga: iossm: refactor io96b_mb_init
  2026-04-07 17:09 [PATCH 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
                   ` (3 preceding siblings ...)
  2026-04-07 17:09 ` [PATCH 04/10] arm: socfpga: iossm: store size in bytes Michael Tretter
@ 2026-04-07 17:09 ` Michael Tretter
  2026-04-07 17:10 ` [PATCH 06/10] arm: socfpga: iossm: refactor return value handling Michael Tretter
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Tretter @ 2026-04-07 17:09 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

Keep the returned number of interfaces in a local variable and store it
only after checking the type of the memory.

This brings the behavior closer to the behavior of the iossm v1 API and
simplifies the addition of the iossm v1 implementation.

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

diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
index 042ea4a99e5c..53c8687f4db8 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.c
+++ b/arch/arm/mach-socfpga/iossm_mailbox.c
@@ -204,26 +204,27 @@ void io96b_mb_init(struct io96b_info *io96b_ctrl)
 
 	pr_debug("%s: num_instance %d\n", __func__, io96b_ctrl->num_instance);
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
+		int num_mem_interface = 0;
+		u32 mem_intf_info[2];
+
 		mb_ctrl = &io96b_ctrl->io96b[i].mb_ctrl;
 		pr_debug("%s: get memory interface IO96B %d\n", __func__, i);
 		/* Get memory interface IP type and instance ID (IP identifier) */
 		io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr, 0, 0,
 				      CMD_GET_SYS_INFO, GET_MEM_INTF_INFO, &usr_resp);
-		pr_debug("%s: get response from memory interface IO96B %d\n", __func__, i);
-		/* Retrieve number of memory interface(s) */
-		mb_ctrl->num_mem_interface =
+		num_mem_interface =
 			IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) & 0x3;
-		pr_debug("%s: IO96B %d: num_mem_interface: %d\n", __func__,
-			 i, mb_ctrl->num_mem_interface);
+		for (j = 0; j < num_mem_interface; j++)
+			mem_intf_info[j] = usr_resp.cmd_resp_data[j];
 
 		/* Retrieve memory interface IP type and instance ID (IP identifier) */
 		j = 0;
-		for (k = 0; k < mb_ctrl->num_mem_interface; k++) {
-			ip_type_ret = FIELD_GET(INTF_IP_TYPE_MASK, usr_resp.cmd_resp_data[k]);
-			instance_id_ret = FIELD_GET(INTF_INSTANCE_ID_MASK,
-						    usr_resp.cmd_resp_data[k]);
+		for (k = 0; k < num_mem_interface; k++) {
+			ip_type_ret = FIELD_GET(INTF_IP_TYPE_MASK, mem_intf_info[k]);
+			instance_id_ret = FIELD_GET(INTF_INSTANCE_ID_MASK, mem_intf_info[k]);
 
 			if (ip_type_ret) {
+				mb_ctrl->num_mem_interface++;
 				mb_ctrl->ip_type[j] = ip_type_ret;
 				mb_ctrl->ip_instance_id[j] = instance_id_ret;
 				pr_debug("%s: IO96B %d mem_interface %d: ip_type_ret: 0x%x\n",

-- 
2.47.3




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

* [PATCH 06/10] arm: socfpga: iossm: refactor return value handling
  2026-04-07 17:09 [PATCH 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
                   ` (4 preceding siblings ...)
  2026-04-07 17:09 ` [PATCH 05/10] arm: socfpga: iossm: refactor io96b_mb_init Michael Tretter
@ 2026-04-07 17:10 ` Michael Tretter
  2026-04-07 17:10 ` [PATCH 07/10] arm: socfgpa: iossm: extract poll_bist_mem_init_status Michael Tretter
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Tretter @ 2026-04-07 17:10 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

Separate the read of the short return value from the iossm response and
the access of the actual response bits into two separate statements.

This makes the code more readable and helps transitioning to the iossm
v1 API, which uses register reads instead of response messages for these
values.

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

diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
index 53c8687f4db8..2c598a6c192a 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.c
+++ b/arch/arm/mach-socfpga/iossm_mailbox.c
@@ -370,6 +370,7 @@ int io96b_get_mem_technology(struct io96b_info *io96b_ctrl)
 	struct io96b_mb_resp usr_resp;
 	struct io96b_mb_ctrl *mb_ctrl;
 	int i, j;
+	u32 mem_technology_intf;
 	u8 ddr_type_ret;
 
 	/* Initialize ddr type */
@@ -384,9 +385,9 @@ int io96b_get_mem_technology(struct io96b_info *io96b_ctrl)
 					      mb_ctrl->ip_instance_id[j],
 					      CMD_GET_MEM_INFO, GET_MEM_TECHNOLOGY, &usr_resp);
 
-			ddr_type_ret =
-				IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
-				& GENMASK(2, 0);
+			mem_technology_intf = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status);
+
+			ddr_type_ret = mem_technology_intf & GENMASK(2, 0);
 
 			if (!strcmp(io96b_ctrl->ddr_type, "UNKNOWN"))
 				io96b_ctrl->ddr_type = ddr_type_list[ddr_type_ret];
@@ -452,6 +453,7 @@ int io96b_ecc_enable_status(struct io96b_info *io96b_ctrl)
 	struct io96b_mb_resp usr_resp;
 	struct io96b_mb_ctrl *mb_ctrl;
 	int i, j;
+	u32 ecc_enable_intf;
 	bool ecc_stat_set = false;
 	bool ecc_stat;
 
@@ -467,9 +469,9 @@ int io96b_ecc_enable_status(struct io96b_info *io96b_ctrl)
 					      mb_ctrl->ip_instance_id[j],
 					      CMD_TRIG_CONTROLLER_OP, ECC_ENABLE_STATUS,
 					      &usr_resp);
+			ecc_enable_intf = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
 
-			ecc_stat = ((IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
-				     & GENMASK(1, 0)) == 0 ? false : true);
+			ecc_stat = (ecc_enable_intf & GENMASK(1, 0)) == 0 ? false : true;
 
 			if (!ecc_stat_set) {
 				io96b_ctrl->ecc_status = ecc_stat;
@@ -495,6 +497,7 @@ int io96b_bist_mem_init_start(struct io96b_info *io96b_ctrl)
 	int i, j;
 	bool bist_start, bist_success;
 	int timeout = 1000000;
+	u32 mem_init_status_intf;
 
 	/* Full memory initialization BIST performed on all memory interface(s) */
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
@@ -508,18 +511,15 @@ int io96b_bist_mem_init_start(struct io96b_info *io96b_ctrl)
 				     io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j],
 				     CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START,
 				     0x40, 0, 0, 0, 0, 0, 0, &usr_resp);
+			mem_init_status_intf = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status);
 
-			bist_start =
-				(IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
-				 & BIT(0));
+			bist_start = mem_init_status_intf & BIT(0);
 
 			if (!bist_start) {
 				pr_err("%s: Failed to initialized memory on IO96B_%d\n",
 				       __func__, i);
 				pr_err("%s: BIST_MEM_INIT_START Error code 0x%x\n",
-				       __func__,
-				       (IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
-					& GENMASK(2, 1)) > 0x1);
+				       __func__, (mem_init_status_intf & GENMASK(2, 1)) > 0x1);
 				return -ENOEXEC;
 			}
 
@@ -530,9 +530,9 @@ int io96b_bist_mem_init_start(struct io96b_info *io96b_ctrl)
 						      io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j],
 						      CMD_TRIG_CONTROLLER_OP,
 						      BIST_MEM_INIT_STATUS, &usr_resp);
+				mem_init_status_intf = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
 
-				bist_success = (IOSSM_CMD_RESPONSE_DATA_SHORT
-						(usr_resp.cmd_resp_status) & BIT(0));
+				bist_success = mem_init_status_intf & BIT(0);
 
 				if (!bist_success && (timeout-- < 0)) {
 					pr_err("%s: Timeout initialize memory on IO96B_%d\n",

-- 
2.47.3




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

* [PATCH 07/10] arm: socfgpa: iossm: extract poll_bist_mem_init_status
  2026-04-07 17:09 [PATCH 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
                   ` (5 preceding siblings ...)
  2026-04-07 17:10 ` [PATCH 06/10] arm: socfpga: iossm: refactor return value handling Michael Tretter
@ 2026-04-07 17:10 ` Michael Tretter
  2026-04-07 17:10 ` [PATCH 08/10] arm: socfgpa: iossm: extract initialization of one interface Michael Tretter
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Tretter @ 2026-04-07 17:10 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

Extract the final polling for the finish of the memory initialization to
make the code more readable by reducing the nesting.

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

diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
index 2c598a6c192a..67000d2cf300 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.c
+++ b/arch/arm/mach-socfpga/iossm_mailbox.c
@@ -491,19 +491,53 @@ int io96b_ecc_enable_status(struct io96b_info *io96b_ctrl)
 	return 0;
 }
 
+static int io96b_poll_bist_mem_init_status(struct io96b_info *io96b_ctrl,
+					   int instance, int interface)
+{
+	phys_addr_t io96b_csr_addr = io96b_ctrl->io96b[instance].io96b_csr_addr;
+	struct io96b_mb_ctrl *mb_ctrl = &io96b_ctrl->io96b[instance].mb_ctrl;
+	int timeout = 1 * USEC_PER_SEC;
+	bool bist_success = false;
+	int bist_error = 0;
+	struct io96b_mb_resp usr_resp;
+	u32 mem_init_status;
+
+	/* Polling for the initiated memory initialization BIST status */
+	while (!bist_success) {
+		io96b_mb_req_no_param(io96b_csr_addr,
+				      mb_ctrl->ip_type[interface],
+				      mb_ctrl->ip_instance_id[interface],
+				      CMD_TRIG_CONTROLLER_OP,
+				      BIST_MEM_INIT_STATUS, &usr_resp);
+		mem_init_status = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status);
+
+		bist_success = FIELD_GET(BIT(0), mem_init_status);
+		bist_error = FIELD_GET(GENMASK(2, 1), mem_init_status);
+
+		if (!bist_success && (timeout-- < 0)) {
+			pr_err("%s: Timeout initialize memory on IO96B_%d (Error 0x%x)\n",
+			       __func__, instance, bist_error);
+			return -ETIMEDOUT;
+		}
+
+		__udelay(1);
+	}
+
+	return 0;
+}
+
 int io96b_bist_mem_init_start(struct io96b_info *io96b_ctrl)
 {
 	struct io96b_mb_resp usr_resp;
 	int i, j;
-	bool bist_start, bist_success;
-	int timeout = 1000000;
+	bool bist_start;
 	u32 mem_init_status_intf;
+	int ret = 0;
 
 	/* Full memory initialization BIST performed on all memory interface(s) */
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
 		for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) {
 			bist_start = false;
-			bist_success = false;
 
 			/* Start memory initialization BIST on full memory address */
 			io96b_mb_req(io96b_ctrl->io96b[i].io96b_csr_addr,
@@ -523,29 +557,9 @@ int io96b_bist_mem_init_start(struct io96b_info *io96b_ctrl)
 				return -ENOEXEC;
 			}
 
-			/* Polling for the initiated memory initialization BIST status */
-			while (!bist_success) {
-				io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr,
-						      io96b_ctrl->io96b[i].mb_ctrl.ip_type[j],
-						      io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j],
-						      CMD_TRIG_CONTROLLER_OP,
-						      BIST_MEM_INIT_STATUS, &usr_resp);
-				mem_init_status_intf = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
-
-				bist_success = mem_init_status_intf & BIT(0);
-
-				if (!bist_success && (timeout-- < 0)) {
-					pr_err("%s: Timeout initialize memory on IO96B_%d\n",
-					       __func__, i);
-					pr_err("%s: BIST_MEM_INIT_STATUS Error code 0x%x\n",
-					       __func__, (IOSSM_CMD_RESPONSE_DATA_SHORT
-							  (usr_resp.cmd_resp_status) &
-							  GENMASK(2, 1)) > 0x1);
-					return -ETIMEDOUT;
-				}
-
-				__udelay(1);
-			}
+			ret = io96b_poll_bist_mem_init_status(io96b_ctrl, i, j);
+			if (ret)
+				return ret;
 		}
 
 		pr_debug("%s: Memory initialized successfully on IO96B_%d\n", __func__, i);

-- 
2.47.3




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

* [PATCH 08/10] arm: socfgpa: iossm: extract initialization of one interface
  2026-04-07 17:09 [PATCH 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
                   ` (6 preceding siblings ...)
  2026-04-07 17:10 ` [PATCH 07/10] arm: socfgpa: iossm: extract poll_bist_mem_init_status Michael Tretter
@ 2026-04-07 17:10 ` Michael Tretter
  2026-04-07 17:10 ` [PATCH 09/10] arm: socfpga: iossm: add memory initialization with inline ecc Michael Tretter
  2026-04-07 17:10 ` [PATCH 10/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Tretter @ 2026-04-07 17:10 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

Each memory interface of each instance has to be initialized. Extract
the code that initializes exactly one interface to reduce the nesting
level and make the code more readable.

While at it, prepare the initialize function to handle situations which
need a different initialization than full memory initialization like
inline_ecc. Simplify the error handling and reporting, too.

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

diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
index 67000d2cf300..6be1119724d6 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.c
+++ b/arch/arm/mach-socfpga/iossm_mailbox.c
@@ -526,43 +526,67 @@ static int io96b_poll_bist_mem_init_status(struct io96b_info *io96b_ctrl,
 	return 0;
 }
 
+static int bist_mem_init_by_addr(struct io96b_info *io96b_ctrl,
+				 int instance, int interface,
+				 phys_addr_t base_addr, phys_size_t size)
+{
+	phys_addr_t io96b_csr_addr = io96b_ctrl->io96b[instance].io96b_csr_addr;
+	struct io96b_mb_ctrl *mb_ctrl = &io96b_ctrl->io96b[instance].mb_ctrl;
+	struct io96b_mb_resp usr_resp;
+	bool bist_start = false;
+	int bist_error = 0;
+	u32 mem_init_status;
+	int ret = 0;
+	u32 mem_exp;
+
+	pr_debug("%s: Start memory initialization BIST on full memory address",
+		 __func__);
+	mem_exp = 0x40;
+
+	ret = io96b_mb_req(io96b_csr_addr,
+			   mb_ctrl->ip_type[interface],
+			   mb_ctrl->ip_instance_id[interface],
+			   CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START,
+			   FIELD_PREP(GENMASK(5, 0), mem_exp),
+			   FIELD_GET(GENMASK(31, 0), base_addr),
+			   FIELD_GET(GENMASK(37, 32), base_addr),
+			   0, 0, 0, 0, &usr_resp);
+	if (ret)
+		return ret;
+
+	mem_init_status = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status);
+
+	bist_start = FIELD_GET(BIT(0), mem_init_status);
+	bist_error = FIELD_GET(GENMASK(2, 1), mem_init_status);
+
+	if (!bist_start) {
+		pr_err("%s: Failed to initialize memory on IO96B_%d (Error 0x%x)\n",
+		       __func__, instance, bist_error);
+		return -ENOEXEC;
+	}
+
+	return io96b_poll_bist_mem_init_status(io96b_ctrl, instance, interface);
+}
+
 int io96b_bist_mem_init_start(struct io96b_info *io96b_ctrl)
 {
-	struct io96b_mb_resp usr_resp;
 	int i, j;
-	bool bist_start;
-	u32 mem_init_status_intf;
 	int ret = 0;
 
-	/* Full memory initialization BIST performed on all memory interface(s) */
+	/* Memory initialization BIST performed on all memory interface(s) */
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
 		for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) {
-			bist_start = false;
-
-			/* Start memory initialization BIST on full memory address */
-			io96b_mb_req(io96b_ctrl->io96b[i].io96b_csr_addr,
-				     io96b_ctrl->io96b[i].mb_ctrl.ip_type[j],
-				     io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j],
-				     CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START,
-				     0x40, 0, 0, 0, 0, 0, 0, &usr_resp);
-			mem_init_status_intf = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status);
-
-			bist_start = mem_init_status_intf & BIT(0);
-
-			if (!bist_start) {
-				pr_err("%s: Failed to initialized memory on IO96B_%d\n",
-				       __func__, i);
-				pr_err("%s: BIST_MEM_INIT_START Error code 0x%x\n",
-				       __func__, (mem_init_status_intf & GENMASK(2, 1)) > 0x1);
-				return -ENOEXEC;
-			}
-
-			ret = io96b_poll_bist_mem_init_status(io96b_ctrl, i, j);
-			if (ret)
+			ret = bist_mem_init_by_addr(io96b_ctrl, i, j, 0x0,
+						    io96b_ctrl->io96b[i].mb_ctrl.memory_size[j]);
+			if (ret) {
+				pr_err("%s: Memory init failed at Instance %d, Interface %d\n",
+				       __func__, i, j);
 				return ret;
+			}
 		}
 
 		pr_debug("%s: Memory initialized successfully on IO96B_%d\n", __func__, i);
 	}
+
 	return 0;
 }

-- 
2.47.3




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

* [PATCH 09/10] arm: socfpga: iossm: add memory initialization with inline ecc
  2026-04-07 17:09 [PATCH 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
                   ` (7 preceding siblings ...)
  2026-04-07 17:10 ` [PATCH 08/10] arm: socfgpa: iossm: extract initialization of one interface Michael Tretter
@ 2026-04-07 17:10 ` Michael Tretter
  2026-04-07 17:10 ` [PATCH 10/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Tretter @ 2026-04-07 17:10 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

The memory interfaces may support for inline ECC and report their
configuration via the ECC status. The software is responsible for
initializing the memory accordingly.

Check the memory interface configuration and initialize the memory if
necessary.

Inline ECC uses 1/8 of the available memory for error correction. Thus,
only 7/8 of the reported memory size is actually available.

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

diff --git a/arch/arm/mach-socfpga/agilex5-sdram.c b/arch/arm/mach-socfpga/agilex5-sdram.c
index 5fb59d413e8f..4e7994985d26 100644
--- a/arch/arm/mach-socfpga/agilex5-sdram.c
+++ b/arch/arm/mach-socfpga/agilex5-sdram.c
@@ -323,6 +323,8 @@ int agilex5_ddr_init_full(void)
 	}
 
 	hw_size = io96b_ctrl.overall_size;
+	if (io96b_ctrl.inline_ecc)
+		hw_size -= hw_size / 8;
 	pr_debug("%s: %lld MiB\n", io96b_ctrl.ddr_type, hw_size / SZ_1M);
 
 	sdram_set_firewall(hw_size);
diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
index 6be1119724d6..4c6a84feccc5 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.c
+++ b/arch/arm/mach-socfpga/iossm_mailbox.c
@@ -456,6 +456,7 @@ int io96b_ecc_enable_status(struct io96b_info *io96b_ctrl)
 	u32 ecc_enable_intf;
 	bool ecc_stat_set = false;
 	bool ecc_stat;
+	bool inline_ecc = false;
 
 	/* Initialize ECC status */
 	io96b_ctrl->ecc_status = false;
@@ -472,13 +473,19 @@ int io96b_ecc_enable_status(struct io96b_info *io96b_ctrl)
 			ecc_enable_intf = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
 
 			ecc_stat = (ecc_enable_intf & GENMASK(1, 0)) == 0 ? false : true;
+			inline_ecc = FIELD_GET(BIT(8), ecc_enable_intf);
 
 			if (!ecc_stat_set) {
 				io96b_ctrl->ecc_status = ecc_stat;
+
+				if (io96b_ctrl->ecc_status)
+					io96b_ctrl->inline_ecc = inline_ecc;
+
 				ecc_stat_set = true;
 			}
 
-			if (ecc_stat != io96b_ctrl->ecc_status) {
+			if (ecc_stat != io96b_ctrl->ecc_status ||
+			    (io96b_ctrl->ecc_status && inline_ecc != io96b_ctrl->inline_ecc)) {
 				pr_err("%s: Mismatch DDR ECC status on IO96B_%d\n",
 				       __func__, i);
 				return -ENOEXEC;
@@ -539,9 +546,25 @@ static int bist_mem_init_by_addr(struct io96b_info *io96b_ctrl,
 	int ret = 0;
 	u32 mem_exp;
 
-	pr_debug("%s: Start memory initialization BIST on full memory address",
-		 __func__);
-	mem_exp = 0x40;
+	if (io96b_ctrl->inline_ecc) {
+		phys_size_t chunk_size;
+
+		/* Check if size is a power of 2 */
+		if (size == 0 || (size & (size - 1)) != 0)
+			return -EINVAL;
+
+		mem_exp = 0;
+		chunk_size = size;
+		while (chunk_size >>= 1)
+			mem_exp++;
+
+		pr_debug("%s: Initializing memory: Addr=0x%llx, Size=2^%u\n",
+			 __func__, base_addr, mem_exp);
+	} else {
+		pr_debug("%s: Start memory initialization BIST on full memory address",
+			 __func__);
+		mem_exp = 0x40;
+	}
 
 	ret = io96b_mb_req(io96b_csr_addr,
 			   mb_ctrl->ip_type[interface],
diff --git a/arch/arm/mach-socfpga/iossm_mailbox.h b/arch/arm/mach-socfpga/iossm_mailbox.h
index 1b1bb1c7a19a..940678fa9d2b 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.h
+++ b/arch/arm/mach-socfpga/iossm_mailbox.h
@@ -127,6 +127,7 @@ struct io96b_info {
 	bool			 overall_cal_status;
 	const char		*ddr_type;
 	bool			 ecc_status;
+	bool			 inline_ecc;
 	phys_size_t		 overall_size;
 	struct io96b_instance	 io96b[MAX_IO96B_SUPPORTED];
 	bool			 ckgen_lock;

-- 
2.47.3




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

* [PATCH 10/10] arm: socfpga: iossm: add support for mailbox v1
  2026-04-07 17:09 [PATCH 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
                   ` (8 preceding siblings ...)
  2026-04-07 17:10 ` [PATCH 09/10] arm: socfpga: iossm: add memory initialization with inline ecc Michael Tretter
@ 2026-04-07 17:10 ` Michael Tretter
  9 siblings, 0 replies; 13+ messages in thread
From: Michael Tretter @ 2026-04-07 17:10 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar, Michael Tretter

The iossm mailbox v1 exposes the interface configuration as registers
instead of mailbox messages.

Use either mailbox messages or register accessed depending on the
detected iossm mailbox version.

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

diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
index 4c6a84feccc5..9fd50fe042de 100644
--- a/arch/arm/mach-socfpga/iossm_mailbox.c
+++ b/arch/arm/mach-socfpga/iossm_mailbox.c
@@ -30,6 +30,18 @@
 
 #define IOSSM_MAILBOX_HEADER_OFFSET			0x0
 #define IOSSM_MAILBOX_SPEC_VERSION_MASK			GENMASK(2, 0)
+#define IOSSM_MEM_INTF_INFO_0_OFFSET			0x200
+#define IOSSM_MEM_TECHNOLOGY_INTF0_OFFSET               0x210
+#define IOSSM_MEM_WIDTH_INFO_INTF0_OFFSET               0x230
+#define IOSSM_MEM_TOTAL_CAPACITY_INTF0_OFFSET           0x234
+#define IOSSM_MEM_INTF_INFO_1_OFFSET			0x280
+#define IOSSM_MEM_TECHNOLOGY_INTF1_OFFSET               0x290
+#define IOSSM_MEM_TOTAL_CAPACITY_INTF1_OFFSET           0x2B4
+#define IOSSM_MEM_WIDTH_INFO_INTF1_OFFSET               0x2B0
+#define IOSSM_ECC_ENABLE_INTF0_OFFSET			0x240
+#define IOSSM_ECC_ENABLE_INTF1_OFFSET			0x2C0
+#define IOSSM_MEM_INIT_STATUS_INTF0_OFFSET		0x260
+#define IOSSM_MEM_INIT_STATUS_INTF1_OFFSET		0x2E0
 
 /* supported DDR type list */
 static const char *ddr_type_list[7] = {
@@ -194,6 +206,7 @@ void io96b_mb_init(struct io96b_info *io96b_ctrl)
 	version = io96b_mb_version(io96b_ctrl);
 	switch (version) {
 	case 0:
+	case 1:
 		pr_debug("IOSSM: mailbox version %d\n", version);
 		break;
 	default:
@@ -210,12 +223,20 @@ void io96b_mb_init(struct io96b_info *io96b_ctrl)
 		mb_ctrl = &io96b_ctrl->io96b[i].mb_ctrl;
 		pr_debug("%s: get memory interface IO96B %d\n", __func__, i);
 		/* Get memory interface IP type and instance ID (IP identifier) */
-		io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr, 0, 0,
-				      CMD_GET_SYS_INFO, GET_MEM_INTF_INFO, &usr_resp);
-		num_mem_interface =
-			IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) & 0x3;
-		for (j = 0; j < num_mem_interface; j++)
-			mem_intf_info[j] = usr_resp.cmd_resp_data[j];
+		if (io96b_ctrl->version == 1) {
+			mem_intf_info[0] = readl(io96b_ctrl->io96b[i].io96b_csr_addr +
+						 IOSSM_MEM_INTF_INFO_0_OFFSET);
+			mem_intf_info[1] = readl(io96b_ctrl->io96b[i].io96b_csr_addr +
+						 IOSSM_MEM_INTF_INFO_1_OFFSET);
+			num_mem_interface = 2;
+		} else {
+			io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr, 0, 0,
+					      CMD_GET_SYS_INFO, GET_MEM_INTF_INFO, &usr_resp);
+			num_mem_interface =
+				IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) & 0x3;
+			for (j = 0; j < num_mem_interface; j++)
+				mem_intf_info[j] = usr_resp.cmd_resp_data[j];
+		}
 
 		/* Retrieve memory interface IP type and instance ID (IP identifier) */
 		j = 0;
@@ -373,6 +394,11 @@ int io96b_get_mem_technology(struct io96b_info *io96b_ctrl)
 	u32 mem_technology_intf;
 	u8 ddr_type_ret;
 
+	u32 mem_technology_intf_offset[] = {
+		IOSSM_MEM_TECHNOLOGY_INTF0_OFFSET,
+		IOSSM_MEM_TECHNOLOGY_INTF1_OFFSET
+	};
+
 	/* Initialize ddr type */
 	io96b_ctrl->ddr_type = ddr_type_list[6];
 
@@ -380,12 +406,17 @@ int io96b_get_mem_technology(struct io96b_info *io96b_ctrl)
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
 		mb_ctrl = &io96b_ctrl->io96b[i].mb_ctrl;
 		for (j = 0; j < mb_ctrl->num_mem_interface; j++) {
-			io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr,
-					      mb_ctrl->ip_type[j],
-					      mb_ctrl->ip_instance_id[j],
-					      CMD_GET_MEM_INFO, GET_MEM_TECHNOLOGY, &usr_resp);
+			if (io96b_ctrl->version == 1) {
+				mem_technology_intf = readl(io96b_ctrl->io96b[i].io96b_csr_addr +
+							    mem_technology_intf_offset[j]);
+			} else {
+				io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr,
+						      mb_ctrl->ip_type[j],
+						      mb_ctrl->ip_instance_id[j],
+						      CMD_GET_MEM_INFO, GET_MEM_TECHNOLOGY, &usr_resp);
 
-			mem_technology_intf = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status);
+				mem_technology_intf = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status);
+			}
 
 			ddr_type_ret = mem_technology_intf & GENMASK(2, 0);
 
@@ -411,17 +442,27 @@ int io96b_get_mem_width_info(struct io96b_info *io96b_ctrl)
 	u32 mem_width_info;
 	phys_size_t total_memory_size = 0;
 
+	u32 mem_total_capacity_intf_offset[] = {
+		IOSSM_MEM_TOTAL_CAPACITY_INTF0_OFFSET,
+		IOSSM_MEM_TOTAL_CAPACITY_INTF1_OFFSET
+	};
+
 	/* Get all memory interface(s) total memory size on all instance(s) */
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
 		mb_ctrl = &io96b_ctrl->io96b[i].mb_ctrl;
 		memory_size = 0;
 
 		for (j = 0; j < mb_ctrl->num_mem_interface; j++) {
-			io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr,
-					      mb_ctrl->ip_type[j],
-					      mb_ctrl->ip_instance_id[j],
-					      CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, &usr_resp);
-			mem_width_info = usr_resp.cmd_resp_data[1] & GENMASK(7, 0);
+			if (io96b_ctrl->version == 1) {
+				mem_width_info = readl(io96b_ctrl->io96b[i].io96b_csr_addr +
+						       mem_total_capacity_intf_offset[j]);
+			} else {
+				io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr,
+						      mb_ctrl->ip_type[j],
+						      mb_ctrl->ip_instance_id[j],
+						      CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, &usr_resp);
+				mem_width_info = usr_resp.cmd_resp_data[1] & GENMASK(7, 0);
+			}
 
 			mb_ctrl->memory_size[j] = mem_width_info * (SZ_1G / SZ_8);
 
@@ -458,6 +499,11 @@ int io96b_ecc_enable_status(struct io96b_info *io96b_ctrl)
 	bool ecc_stat;
 	bool inline_ecc = false;
 
+	u32 ecc_enable_intf_offset[] = {
+		IOSSM_ECC_ENABLE_INTF0_OFFSET,
+		IOSSM_ECC_ENABLE_INTF1_OFFSET
+	};
+
 	/* Initialize ECC status */
 	io96b_ctrl->ecc_status = false;
 
@@ -465,13 +511,17 @@ int io96b_ecc_enable_status(struct io96b_info *io96b_ctrl)
 	for (i = 0; i < io96b_ctrl->num_instance; i++) {
 		mb_ctrl = &io96b_ctrl->io96b[i].mb_ctrl;
 		for (j = 0; j < mb_ctrl->num_mem_interface; j++) {
-			io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr,
-					      mb_ctrl->ip_type[j],
-					      mb_ctrl->ip_instance_id[j],
-					      CMD_TRIG_CONTROLLER_OP, ECC_ENABLE_STATUS,
-					      &usr_resp);
-			ecc_enable_intf = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
-
+			if (io96b_ctrl->version == 1) {
+				ecc_enable_intf = readl(io96b_ctrl->io96b[i].io96b_csr_addr +
+							ecc_enable_intf_offset[j]);
+			} else {
+				io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr,
+						      mb_ctrl->ip_type[j],
+						      mb_ctrl->ip_instance_id[j],
+						      CMD_TRIG_CONTROLLER_OP, ECC_ENABLE_STATUS,
+						      &usr_resp);
+				ecc_enable_intf = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status);
+			}
 			ecc_stat = (ecc_enable_intf & GENMASK(1, 0)) == 0 ? false : true;
 			inline_ecc = FIELD_GET(BIT(8), ecc_enable_intf);
 
@@ -509,14 +559,23 @@ static int io96b_poll_bist_mem_init_status(struct io96b_info *io96b_ctrl,
 	struct io96b_mb_resp usr_resp;
 	u32 mem_init_status;
 
+	u32 mem_init_status_offset[] = {
+		IOSSM_MEM_INIT_STATUS_INTF0_OFFSET,
+		IOSSM_MEM_INIT_STATUS_INTF1_OFFSET
+	};
+
 	/* Polling for the initiated memory initialization BIST status */
 	while (!bist_success) {
-		io96b_mb_req_no_param(io96b_csr_addr,
-				      mb_ctrl->ip_type[interface],
-				      mb_ctrl->ip_instance_id[interface],
-				      CMD_TRIG_CONTROLLER_OP,
-				      BIST_MEM_INIT_STATUS, &usr_resp);
-		mem_init_status = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status);
+		if (io96b_ctrl->version == 1) {
+			mem_init_status = readl(io96b_csr_addr + mem_init_status_offset[interface]);
+		} else {
+			io96b_mb_req_no_param(io96b_csr_addr,
+					      mb_ctrl->ip_type[interface],
+					      mb_ctrl->ip_instance_id[interface],
+					      CMD_TRIG_CONTROLLER_OP,
+					      BIST_MEM_INIT_STATUS, &usr_resp);
+			mem_init_status = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status);
+		}
 
 		bist_success = FIELD_GET(BIT(0), mem_init_status);
 		bist_error = FIELD_GET(GENMASK(2, 1), mem_init_status);

-- 
2.47.3




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

* Re: [PATCH 04/10] arm: socfpga: iossm: store size in bytes
  2026-04-07 17:09 ` [PATCH 04/10] arm: socfpga: iossm: store size in bytes Michael Tretter
@ 2026-04-07 17:43   ` Ahmad Fatoum
  2026-04-08  7:12     ` Michael Tretter
  0 siblings, 1 reply; 13+ messages in thread
From: Ahmad Fatoum @ 2026-04-07 17:43 UTC (permalink / raw)
  To: Michael Tretter, Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar



On 4/7/26 7:09 PM, Michael Tretter wrote:
> The mem_width_info is the memory size in gigabits. Convert it to bytes
> before storing it for each bank to have a more convenient format and
> simplify the conversion when reading the value.
> 
> Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
> ---
>  arch/arm/mach-socfpga/agilex5-sdram.c |  7 +++----
>  arch/arm/mach-socfpga/iossm_mailbox.c | 13 +++++++++----
>  arch/arm/mach-socfpga/iossm_mailbox.h |  5 +++--
>  3 files changed, 15 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/arm/mach-socfpga/agilex5-sdram.c b/arch/arm/mach-socfpga/agilex5-sdram.c
> index 96b2b425315f..5fb59d413e8f 100644
> --- a/arch/arm/mach-socfpga/agilex5-sdram.c
> +++ b/arch/arm/mach-socfpga/agilex5-sdram.c
> @@ -299,10 +299,6 @@ int agilex5_ddr_init_full(void)
>  		return ret;
>  	}
>  
> -	hw_size = (phys_size_t)io96b_ctrl.overall_size * SZ_1G / SZ_8;
> -
> -	pr_debug("%s: %lld MiB\n", io96b_ctrl.ddr_type, hw_size >> 20);
> -
>  	ret = io96b_ecc_enable_status(&io96b_ctrl);
>  	if (ret) {
>  		pr_debug("DDR: Failed to get DDR ECC status\n");
> @@ -326,6 +322,9 @@ int agilex5_ddr_init_full(void)
>  		pr_debug("SDRAM-ECC: Initialized success\n");
>  	}
>  
> +	hw_size = io96b_ctrl.overall_size;
> +	pr_debug("%s: %lld MiB\n", io96b_ctrl.ddr_type, hw_size / SZ_1M);
> +
>  	sdram_set_firewall(hw_size);
>  
>  	/* Firewall setting for MPFE CSR */
> diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
> index 9299fee71e0b..042ea4a99e5c 100644
> --- a/arch/arm/mach-socfpga/iossm_mailbox.c
> +++ b/arch/arm/mach-socfpga/iossm_mailbox.c
> @@ -9,6 +9,7 @@
>  #include <common.h>
>  #include <io.h>
>  #include <linux/bitfield.h>
> +#include <linux/sizes.h>
>  #include "iossm_mailbox.h"
>  #include <mach/socfpga/generic.h>
>  #include <mach/socfpga/soc64-regs.h>
> @@ -404,21 +405,25 @@ int io96b_get_mem_width_info(struct io96b_info *io96b_ctrl)
>  	struct io96b_mb_resp usr_resp;
>  	struct io96b_mb_ctrl *mb_ctrl;
>  	int i, j;
> -	u16 memory_size;
> -	u16 total_memory_size = 0;
> +	phys_size_t memory_size;
> +	u32 mem_width_info;
> +	phys_size_t total_memory_size = 0;
>  
>  	/* Get all memory interface(s) total memory size on all instance(s) */
>  	for (i = 0; i < io96b_ctrl->num_instance; i++) {
>  		mb_ctrl = &io96b_ctrl->io96b[i].mb_ctrl;
>  		memory_size = 0;
> +
>  		for (j = 0; j < mb_ctrl->num_mem_interface; j++) {
>  			io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr,
>  					      mb_ctrl->ip_type[j],
>  					      mb_ctrl->ip_instance_id[j],
>  					      CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, &usr_resp);
> +			mem_width_info = usr_resp.cmd_resp_data[1] & GENMASK(7, 0);
>  
> -			memory_size = memory_size +
> -				(usr_resp.cmd_resp_data[1] & GENMASK(7, 0));
> +			mb_ctrl->memory_size[j] = mem_width_info * (SZ_1G / SZ_8);
> +
> +			memory_size += mb_ctrl->memory_size[j];
>  		}
>  
>  		if (!memory_size) {
> diff --git a/arch/arm/mach-socfpga/iossm_mailbox.h b/arch/arm/mach-socfpga/iossm_mailbox.h
> index bd66621d5f70..1b1bb1c7a19a 100644
> --- a/arch/arm/mach-socfpga/iossm_mailbox.h
> +++ b/arch/arm/mach-socfpga/iossm_mailbox.h
> @@ -79,6 +79,7 @@ struct io96b_mb_ctrl {
>  	u32 num_mem_interface;
>  	u32 ip_type[2];
>  	u32 ip_instance_id[2];
> +	u32 memory_size[2];

This overflows for >= SZ_8G memory. That looks odd.

Thanks,
Ahmad

>  };
>  
>  /*
> @@ -101,7 +102,7 @@ struct io96b_mb_resp {
>   * @mb_ctrl:		IOSSM mailbox required information
>   */
>  struct io96b_instance {
> -	u16 size;
> +	phys_size_t size;
>  	phys_addr_t io96b_csr_addr;
>  	bool cal_status;
>  	struct io96b_mb_ctrl mb_ctrl;
> @@ -126,7 +127,7 @@ struct io96b_info {
>  	bool			 overall_cal_status;
>  	const char		*ddr_type;
>  	bool			 ecc_status;
> -	u16			 overall_size;
> +	phys_size_t		 overall_size;
>  	struct io96b_instance	 io96b[MAX_IO96B_SUPPORTED];
>  	bool			 ckgen_lock;
>  	u8			 num_port;
> 

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




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

* Re: [PATCH 04/10] arm: socfpga: iossm: store size in bytes
  2026-04-07 17:43   ` Ahmad Fatoum
@ 2026-04-08  7:12     ` Michael Tretter
  0 siblings, 0 replies; 13+ messages in thread
From: Michael Tretter @ 2026-04-08  7:12 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: BAREBOX, Steffen Trumtrar

On Tue, 07 Apr 2026 19:43:19 +0200, Ahmad Fatoum wrote:
> On 4/7/26 7:09 PM, Michael Tretter wrote:
> > The mem_width_info is the memory size in gigabits. Convert it to bytes
> > before storing it for each bank to have a more convenient format and
> > simplify the conversion when reading the value.
> > 
> > Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
> > ---
> >  arch/arm/mach-socfpga/agilex5-sdram.c |  7 +++----
> >  arch/arm/mach-socfpga/iossm_mailbox.c | 13 +++++++++----
> >  arch/arm/mach-socfpga/iossm_mailbox.h |  5 +++--
> >  3 files changed, 15 insertions(+), 10 deletions(-)
> > 
> > diff --git a/arch/arm/mach-socfpga/agilex5-sdram.c b/arch/arm/mach-socfpga/agilex5-sdram.c
> > index 96b2b425315f..5fb59d413e8f 100644
> > --- a/arch/arm/mach-socfpga/agilex5-sdram.c
> > +++ b/arch/arm/mach-socfpga/agilex5-sdram.c
> > @@ -299,10 +299,6 @@ int agilex5_ddr_init_full(void)
> >  		return ret;
> >  	}
> >  
> > -	hw_size = (phys_size_t)io96b_ctrl.overall_size * SZ_1G / SZ_8;
> > -
> > -	pr_debug("%s: %lld MiB\n", io96b_ctrl.ddr_type, hw_size >> 20);
> > -
> >  	ret = io96b_ecc_enable_status(&io96b_ctrl);
> >  	if (ret) {
> >  		pr_debug("DDR: Failed to get DDR ECC status\n");
> > @@ -326,6 +322,9 @@ int agilex5_ddr_init_full(void)
> >  		pr_debug("SDRAM-ECC: Initialized success\n");
> >  	}
> >  
> > +	hw_size = io96b_ctrl.overall_size;
> > +	pr_debug("%s: %lld MiB\n", io96b_ctrl.ddr_type, hw_size / SZ_1M);
> > +
> >  	sdram_set_firewall(hw_size);
> >  
> >  	/* Firewall setting for MPFE CSR */
> > diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
> > index 9299fee71e0b..042ea4a99e5c 100644
> > --- a/arch/arm/mach-socfpga/iossm_mailbox.c
> > +++ b/arch/arm/mach-socfpga/iossm_mailbox.c
> > @@ -9,6 +9,7 @@
> >  #include <common.h>
> >  #include <io.h>
> >  #include <linux/bitfield.h>
> > +#include <linux/sizes.h>
> >  #include "iossm_mailbox.h"
> >  #include <mach/socfpga/generic.h>
> >  #include <mach/socfpga/soc64-regs.h>
> > @@ -404,21 +405,25 @@ int io96b_get_mem_width_info(struct io96b_info *io96b_ctrl)
> >  	struct io96b_mb_resp usr_resp;
> >  	struct io96b_mb_ctrl *mb_ctrl;
> >  	int i, j;
> > -	u16 memory_size;
> > -	u16 total_memory_size = 0;
> > +	phys_size_t memory_size;
> > +	u32 mem_width_info;
> > +	phys_size_t total_memory_size = 0;
> >  
> >  	/* Get all memory interface(s) total memory size on all instance(s) */
> >  	for (i = 0; i < io96b_ctrl->num_instance; i++) {
> >  		mb_ctrl = &io96b_ctrl->io96b[i].mb_ctrl;
> >  		memory_size = 0;
> > +
> >  		for (j = 0; j < mb_ctrl->num_mem_interface; j++) {
> >  			io96b_mb_req_no_param(io96b_ctrl->io96b[i].io96b_csr_addr,
> >  					      mb_ctrl->ip_type[j],
> >  					      mb_ctrl->ip_instance_id[j],
> >  					      CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, &usr_resp);
> > +			mem_width_info = usr_resp.cmd_resp_data[1] & GENMASK(7, 0);
> >  
> > -			memory_size = memory_size +
> > -				(usr_resp.cmd_resp_data[1] & GENMASK(7, 0));
> > +			mb_ctrl->memory_size[j] = mem_width_info * (SZ_1G / SZ_8);
> > +
> > +			memory_size += mb_ctrl->memory_size[j];
> >  		}
> >  
> >  		if (!memory_size) {
> > diff --git a/arch/arm/mach-socfpga/iossm_mailbox.h b/arch/arm/mach-socfpga/iossm_mailbox.h
> > index bd66621d5f70..1b1bb1c7a19a 100644
> > --- a/arch/arm/mach-socfpga/iossm_mailbox.h
> > +++ b/arch/arm/mach-socfpga/iossm_mailbox.h
> > @@ -79,6 +79,7 @@ struct io96b_mb_ctrl {
> >  	u32 num_mem_interface;
> >  	u32 ip_type[2];
> >  	u32 ip_instance_id[2];
> > +	u32 memory_size[2];
> 
> This overflows for >= SZ_8G memory. That looks odd.

That should have been phys_size_t like the other uses, too. Thanks! I'll
send a v2.

Michael

> 
> Thanks,
> Ahmad
> 
> >  };
> >  
> >  /*
> > @@ -101,7 +102,7 @@ struct io96b_mb_resp {
> >   * @mb_ctrl:		IOSSM mailbox required information
> >   */
> >  struct io96b_instance {
> > -	u16 size;
> > +	phys_size_t size;
> >  	phys_addr_t io96b_csr_addr;
> >  	bool cal_status;
> >  	struct io96b_mb_ctrl mb_ctrl;
> > @@ -126,7 +127,7 @@ struct io96b_info {
> >  	bool			 overall_cal_status;
> >  	const char		*ddr_type;
> >  	bool			 ecc_status;
> > -	u16			 overall_size;
> > +	phys_size_t		 overall_size;
> >  	struct io96b_instance	 io96b[MAX_IO96B_SUPPORTED];
> >  	bool			 ckgen_lock;
> >  	u8			 num_port;
> > 



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

end of thread, other threads:[~2026-04-08  7:13 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-07 17:09 [PATCH 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
2026-04-07 17:09 ` [PATCH 01/10] arm: socfpga: iossm: remove uninitialized variable Michael Tretter
2026-04-07 17:09 ` [PATCH 02/10] arm: socfpga: iossm: add version check Michael Tretter
2026-04-07 17:09 ` [PATCH 03/10] arm: socfpga: iossm: use local mb_ctrl variable Michael Tretter
2026-04-07 17:09 ` [PATCH 04/10] arm: socfpga: iossm: store size in bytes Michael Tretter
2026-04-07 17:43   ` Ahmad Fatoum
2026-04-08  7:12     ` Michael Tretter
2026-04-07 17:09 ` [PATCH 05/10] arm: socfpga: iossm: refactor io96b_mb_init Michael Tretter
2026-04-07 17:10 ` [PATCH 06/10] arm: socfpga: iossm: refactor return value handling Michael Tretter
2026-04-07 17:10 ` [PATCH 07/10] arm: socfgpa: iossm: extract poll_bist_mem_init_status Michael Tretter
2026-04-07 17:10 ` [PATCH 08/10] arm: socfgpa: iossm: extract initialization of one interface Michael Tretter
2026-04-07 17:10 ` [PATCH 09/10] arm: socfpga: iossm: add memory initialization with inline ecc Michael Tretter
2026-04-07 17:10 ` [PATCH 10/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter

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