* [PATCH v2 01/10] arm: socfpga: iossm: remove uninitialized variable
2026-04-09 13:52 [PATCH v2 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
@ 2026-04-09 13:52 ` Michael Tretter
2026-04-09 13:52 ` [PATCH v2 02/10] arm: socfpga: iossm: add version check Michael Tretter
` (9 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Michael Tretter @ 2026-04-09 13:52 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>
---
Changes in v2:
- none
---
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] 18+ messages in thread* [PATCH v2 02/10] arm: socfpga: iossm: add version check
2026-04-09 13:52 [PATCH v2 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
2026-04-09 13:52 ` [PATCH v2 01/10] arm: socfpga: iossm: remove uninitialized variable Michael Tretter
@ 2026-04-09 13:52 ` Michael Tretter
2026-04-10 8:18 ` Ahmad Fatoum
2026-04-09 13:52 ` [PATCH v2 03/10] arm: socfpga: iossm: use local mb_ctrl variable Michael Tretter
` (8 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: Michael Tretter @ 2026-04-09 13:52 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>
---
Changes in v2:
- none
---
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] 18+ messages in thread* Re: [PATCH v2 02/10] arm: socfpga: iossm: add version check
2026-04-09 13:52 ` [PATCH v2 02/10] arm: socfpga: iossm: add version check Michael Tretter
@ 2026-04-10 8:18 ` Ahmad Fatoum
2026-04-10 13:24 ` Michael Tretter
0 siblings, 1 reply; 18+ messages in thread
From: Ahmad Fatoum @ 2026-04-10 8:18 UTC (permalink / raw)
To: Michael Tretter, Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar
Hello,
On 4/9/26 3:52 PM, Michael Tretter wrote:
> 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>
> ---
> Changes in v2:
>
> - none
> ---
> 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);
Nitpick: readl() is supposed to take void __iomem * (virtual addresses),
not physical addresses, so a phys_to_virt is missing here.
They currently expands to the same value (with different types) though
on ARM.
You don't have to resend just for this though.
Thanks,
Ahmad
> + 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;
>
--
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] 18+ messages in thread* Re: [PATCH v2 02/10] arm: socfpga: iossm: add version check
2026-04-10 8:18 ` Ahmad Fatoum
@ 2026-04-10 13:24 ` Michael Tretter
0 siblings, 0 replies; 18+ messages in thread
From: Michael Tretter @ 2026-04-10 13:24 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: BAREBOX, Steffen Trumtrar
On Fri, 10 Apr 2026 10:18:58 +0200, Ahmad Fatoum wrote:
> On 4/9/26 3:52 PM, Michael Tretter wrote:
> > 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>
> > ---
> > Changes in v2:
> >
> > - none
> > ---
> > 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);
>
> Nitpick: readl() is supposed to take void __iomem * (virtual addresses),
> not physical addresses, so a phys_to_virt is missing here.
>
> They currently expands to the same value (with different types) though
> on ARM.
The entire driver uses readl() with io96b_csr_addr as phys_addr_t
without calling phys_to_virt. There are occasionally sprinkled casts
using IOMEM(), but it's not consistent. It may be worth doing a cleanup
across the entire driver, but that should be a separate patch series.
Michael
>
> You don't have to resend just for this though.
>
> Thanks,
> Ahmad
>
> > + 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;
> >
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 03/10] arm: socfpga: iossm: use local mb_ctrl variable
2026-04-09 13:52 [PATCH v2 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
2026-04-09 13:52 ` [PATCH v2 01/10] arm: socfpga: iossm: remove uninitialized variable Michael Tretter
2026-04-09 13:52 ` [PATCH v2 02/10] arm: socfpga: iossm: add version check Michael Tretter
@ 2026-04-09 13:52 ` Michael Tretter
2026-04-09 13:52 ` [PATCH v2 04/10] arm: socfpga: iossm: store size in bytes Michael Tretter
` (7 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Michael Tretter @ 2026-04-09 13:52 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>
---
Changes in v2:
- none
---
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] 18+ messages in thread* [PATCH v2 04/10] arm: socfpga: iossm: store size in bytes
2026-04-09 13:52 [PATCH v2 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
` (2 preceding siblings ...)
2026-04-09 13:52 ` [PATCH v2 03/10] arm: socfpga: iossm: use local mb_ctrl variable Michael Tretter
@ 2026-04-09 13:52 ` Michael Tretter
2026-04-10 8:13 ` Ahmad Fatoum
2026-04-09 13:52 ` [PATCH v2 05/10] arm: socfpga: iossm: refactor io96b_mb_init Michael Tretter
` (6 subsequent siblings)
10 siblings, 1 reply; 18+ messages in thread
From: Michael Tretter @ 2026-04-09 13:52 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>
---
Changes in v2:
- Change memory_size in io96b_mb_ctrl to phys_size_t to prevent overflow
---
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..0c15c92bb867 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];
+ phys_size_t 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] 18+ messages in thread* Re: [PATCH v2 04/10] arm: socfpga: iossm: store size in bytes
2026-04-09 13:52 ` [PATCH v2 04/10] arm: socfpga: iossm: store size in bytes Michael Tretter
@ 2026-04-10 8:13 ` Ahmad Fatoum
2026-04-10 8:31 ` Michael Tretter
0 siblings, 1 reply; 18+ messages in thread
From: Ahmad Fatoum @ 2026-04-10 8:13 UTC (permalink / raw)
To: Michael Tretter, Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar
Hello,
On 4/9/26 3:52 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>
> ---
> Changes in v2:
>
> - Change memory_size in io96b_mb_ctrl to phys_size_t to prevent overflow
Thanks for addressing the concern. I looked it over and there's still a
chance for overflow.
> 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);
I assume this is the RAM memory width in bytes, e.g. 2 or 4 bytes, but
the mask allows it to be up to 255.
>
> - 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);
SZ_4G / (SZ_1G / 8) = 32
So the maximum value permitted in mem_width_info without overflowing is
31, but the code accepts up to 255. As all types on the left hand side
are 32-bit only.
Worth a check or adaptation of the mask?
Cheers,
Ahmad
> +
> + 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..0c15c92bb867 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];
> + phys_size_t 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;
>
--
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] 18+ messages in thread* Re: [PATCH v2 04/10] arm: socfpga: iossm: store size in bytes
2026-04-10 8:13 ` Ahmad Fatoum
@ 2026-04-10 8:31 ` Michael Tretter
2026-04-10 8:37 ` Ahmad Fatoum
0 siblings, 1 reply; 18+ messages in thread
From: Michael Tretter @ 2026-04-10 8:31 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: BAREBOX, Steffen Trumtrar
On Fri, 10 Apr 2026 10:13:41 +0200, Ahmad Fatoum wrote:
> On 4/9/26 3:52 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>
> > ---
> > Changes in v2:
> >
> > - Change memory_size in io96b_mb_ctrl to phys_size_t to prevent overflow
>
> Thanks for addressing the concern. I looked it over and there's still a
> chance for overflow.
>
> > 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);
>
> I assume this is the RAM memory width in bytes, e.g. 2 or 4 bytes, but
> the mask allows it to be up to 255.
mem_width_info is in Giga bits.
>
> >
> > - 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);
>
> SZ_4G / (SZ_1G / 8) = 32
>
> So the maximum value permitted in mem_width_info without overflowing is
> 31, but the code accepts up to 255. As all types on the left hand side
> are 32-bit only.
This driver is only available on Agilex5, which is arm64 and selects
PHYS_ADDR_T_64BIT. Thus, phys_size_t has 64 bits and doesn't result in
an overflow.
Michael
>
> Worth a check or adaptation of the mask?
>
> Cheers,
> Ahmad
>
> > +
> > + 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..0c15c92bb867 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];
> > + phys_size_t 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;
> >
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 04/10] arm: socfpga: iossm: store size in bytes
2026-04-10 8:31 ` Michael Tretter
@ 2026-04-10 8:37 ` Ahmad Fatoum
2026-04-10 12:06 ` Michael Tretter
0 siblings, 1 reply; 18+ messages in thread
From: Ahmad Fatoum @ 2026-04-10 8:37 UTC (permalink / raw)
To: Michael Tretter; +Cc: BAREBOX, Steffen Trumtrar
Hello Michael,
On 4/10/26 10:31 AM, Michael Tretter wrote:
> On Fri, 10 Apr 2026 10:13:41 +0200, Ahmad Fatoum wrote:
>> On 4/9/26 3:52 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>
>>> ---
>>> Changes in v2:
>>>
>>> - Change memory_size in io96b_mb_ctrl to phys_size_t to prevent overflow
>>
>> Thanks for addressing the concern. I looked it over and there's still a
>> chance for overflow.
>>
>>> 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);
>>
>> I assume this is the RAM memory width in bytes, e.g. 2 or 4 bytes, but
>> the mask allows it to be up to 255.
>
> mem_width_info is in Giga bits.
Uh, is memory width here not the number of bits transferred per clock
cycle..?
>
>>
>>>
>>> - 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);
>>
>> SZ_4G / (SZ_1G / 8) = 32
>>
>> So the maximum value permitted in mem_width_info without overflowing is
>> 31, but the code accepts up to 255. As all types on the left hand side
>> are 32-bit only.
>
> This driver is only available on Agilex5, which is arm64 and selects
> PHYS_ADDR_T_64BIT. Thus, phys_size_t has 64 bits and doesn't result in
> an overflow.
Sorry, left-right confusion. The right had size is all 32-bit integers,
so they may wrap around and are truncated before assignment to the
64-bit left hand side.
Cheers,
Ahmad
>
> Michael
>
>>
>> Worth a check or adaptation of the mask?
>>
>> Cheers,
>> Ahmad
>>
>>> +
>>> + 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..0c15c92bb867 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];
>>> + phys_size_t 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;
>>>
>
--
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] 18+ messages in thread* Re: [PATCH v2 04/10] arm: socfpga: iossm: store size in bytes
2026-04-10 8:37 ` Ahmad Fatoum
@ 2026-04-10 12:06 ` Michael Tretter
0 siblings, 0 replies; 18+ messages in thread
From: Michael Tretter @ 2026-04-10 12:06 UTC (permalink / raw)
To: Ahmad Fatoum; +Cc: BAREBOX, Steffen Trumtrar
On Fri, 10 Apr 2026 10:37:09 +0200, Ahmad Fatoum wrote:
> On 4/10/26 10:31 AM, Michael Tretter wrote:
> > On Fri, 10 Apr 2026 10:13:41 +0200, Ahmad Fatoum wrote:
> >> On 4/9/26 3:52 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>
> >>> ---
> >>> Changes in v2:
> >>>
> >>> - Change memory_size in io96b_mb_ctrl to phys_size_t to prevent overflow
> >>
> >> Thanks for addressing the concern. I looked it over and there's still a
> >> chance for overflow.
> >>
> >>> 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);
> >>
> >> I assume this is the RAM memory width in bytes, e.g. 2 or 4 bytes, but
> >> the mask allows it to be up to 255.
> >
> > mem_width_info is in Giga bits.
>
> Uh, is memory width here not the number of bits transferred per clock
> cycle..?
Maybe I'm confused, but I understand that it's not the bits transferred
per clock cycle (the memory bus interface width), but information about
the memory geometry under the assumption of a memory depth of 1 Giga
bits. My understanding could be wrong, though.
>
> >
> >>
> >>>
> >>> - 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);
> >>
> >> SZ_4G / (SZ_1G / 8) = 32
> >>
> >> So the maximum value permitted in mem_width_info without overflowing is
> >> 31, but the code accepts up to 255. As all types on the left hand side
> >> are 32-bit only.
> >
> > This driver is only available on Agilex5, which is arm64 and selects
> > PHYS_ADDR_T_64BIT. Thus, phys_size_t has 64 bits and doesn't result in
> > an overflow.
>
> Sorry, left-right confusion. The right had size is all 32-bit integers,
> so they may wrap around and are truncated before assignment to the
> 64-bit left hand side.
Ah, indeed. I'll add the necessary cast to the right hand side.
> >> Worth a check or adaptation of the mask?
According to the register definition [0], the mask is correct.
[0] https://docs.altera.com/r/docs/817467/25.3/external-memory-interfaces-emif-ip-user-guide-agilextm-5-fpgas-and-socs/agilextm-5-mailbox-structure-and-register-definitions
Michael
> >>> +
> >>> + 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..0c15c92bb867 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];
> >>> + phys_size_t 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;
> >>>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 05/10] arm: socfpga: iossm: refactor io96b_mb_init
2026-04-09 13:52 [PATCH v2 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
` (3 preceding siblings ...)
2026-04-09 13:52 ` [PATCH v2 04/10] arm: socfpga: iossm: store size in bytes Michael Tretter
@ 2026-04-09 13:52 ` Michael Tretter
2026-04-09 13:52 ` [PATCH v2 06/10] arm: socfpga: iossm: refactor return value handling Michael Tretter
` (5 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Michael Tretter @ 2026-04-09 13:52 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>
---
Changes in v2:
- none
---
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] 18+ messages in thread* [PATCH v2 06/10] arm: socfpga: iossm: refactor return value handling
2026-04-09 13:52 [PATCH v2 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
` (4 preceding siblings ...)
2026-04-09 13:52 ` [PATCH v2 05/10] arm: socfpga: iossm: refactor io96b_mb_init Michael Tretter
@ 2026-04-09 13:52 ` Michael Tretter
2026-04-09 13:52 ` [PATCH v2 07/10] arm: socfgpa: iossm: extract poll_bist_mem_init_status Michael Tretter
` (4 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Michael Tretter @ 2026-04-09 13:52 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>
---
Changes in v2:
- none
---
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] 18+ messages in thread* [PATCH v2 07/10] arm: socfgpa: iossm: extract poll_bist_mem_init_status
2026-04-09 13:52 [PATCH v2 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
` (5 preceding siblings ...)
2026-04-09 13:52 ` [PATCH v2 06/10] arm: socfpga: iossm: refactor return value handling Michael Tretter
@ 2026-04-09 13:52 ` Michael Tretter
2026-04-09 13:52 ` [PATCH v2 08/10] arm: socfgpa: iossm: extract initialization of one interface Michael Tretter
` (3 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Michael Tretter @ 2026-04-09 13:52 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>
---
Changes in v2:
- none
---
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] 18+ messages in thread* [PATCH v2 08/10] arm: socfgpa: iossm: extract initialization of one interface
2026-04-09 13:52 [PATCH v2 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
` (6 preceding siblings ...)
2026-04-09 13:52 ` [PATCH v2 07/10] arm: socfgpa: iossm: extract poll_bist_mem_init_status Michael Tretter
@ 2026-04-09 13:52 ` Michael Tretter
2026-04-09 13:52 ` [PATCH v2 09/10] arm: socfpga: iossm: add memory initialization with inline ecc Michael Tretter
` (2 subsequent siblings)
10 siblings, 0 replies; 18+ messages in thread
From: Michael Tretter @ 2026-04-09 13:52 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>
---
Changes in v2:
- none
---
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] 18+ messages in thread* [PATCH v2 09/10] arm: socfpga: iossm: add memory initialization with inline ecc
2026-04-09 13:52 [PATCH v2 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
` (7 preceding siblings ...)
2026-04-09 13:52 ` [PATCH v2 08/10] arm: socfgpa: iossm: extract initialization of one interface Michael Tretter
@ 2026-04-09 13:52 ` Michael Tretter
2026-04-09 13:52 ` [PATCH v2 10/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
2026-04-10 8:19 ` [PATCH v2 00/10] " Ahmad Fatoum
10 siblings, 0 replies; 18+ messages in thread
From: Michael Tretter @ 2026-04-09 13:52 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>
---
Changes in v2:
- none
---
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 0c15c92bb867..febe51591ca0 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] 18+ messages in thread* [PATCH v2 10/10] arm: socfpga: iossm: add support for mailbox v1
2026-04-09 13:52 [PATCH v2 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
` (8 preceding siblings ...)
2026-04-09 13:52 ` [PATCH v2 09/10] arm: socfpga: iossm: add memory initialization with inline ecc Michael Tretter
@ 2026-04-09 13:52 ` Michael Tretter
2026-04-10 8:19 ` [PATCH v2 00/10] " Ahmad Fatoum
10 siblings, 0 replies; 18+ messages in thread
From: Michael Tretter @ 2026-04-09 13:52 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>
---
Changes in v2:
- none
---
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] 18+ messages in thread* Re: [PATCH v2 00/10] arm: socfpga: iossm: add support for mailbox v1
2026-04-09 13:52 [PATCH v2 00/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
` (9 preceding siblings ...)
2026-04-09 13:52 ` [PATCH v2 10/10] arm: socfpga: iossm: add support for mailbox v1 Michael Tretter
@ 2026-04-10 8:19 ` Ahmad Fatoum
10 siblings, 0 replies; 18+ messages in thread
From: Ahmad Fatoum @ 2026-04-10 8:19 UTC (permalink / raw)
To: Michael Tretter, Sascha Hauer, BAREBOX; +Cc: Steffen Trumtrar
On 4/9/26 3:52 PM, Michael Tretter wrote:
> 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>
Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> ---
> Changes in v2:
> - Patch 4: Change memory_size in io96b_mb_ctrl to phys_size_t to prevent overflow
> - Link to v1: https://patch.msgid.link/20260407-socfpga-iossm-v1-v1-0-6440a5337eff@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,
--
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] 18+ messages in thread