From: Steffen Trumtrar <s.trumtrar@pengutronix.de>
To: barebox@lists.infradead.org, Sascha Hauer <s.hauer@pengutronix.de>
Cc: Steffen Trumtrar <s.trumtrar@pengutronix.de>,
David Jander <david@protonic.nl>
Subject: [PATCH 2/4] arm: mach-imx: esdctl.c: Add support for imx8mp inline ECC
Date: Wed, 04 Mar 2026 12:23:43 +0100 [thread overview]
Message-ID: <20260304-v2026-02-0-topic-imx8-ecc-v1-2-700698530c5c@pengutronix.de> (raw)
In-Reply-To: <20260304-v2026-02-0-topic-imx8-ecc-v1-0-700698530c5c@pengutronix.de>
From: David Jander <david@protonic.nl>
This adds support for detecting the use of inline ECC and compute the
correct memory bank(s) in that case.
In case inline ECC is active the memory map is modified as follows:
The total memory size is reduced to 7/8th of the raw memory size.
If a reduced-address-space type RAM is used (0.75, 1.5, 3, 6... GiB), then
the whole address space is split up into 3 equal parts, separated by 1/3rd
of the raw address space, but each 7/8th that size.
The ECC area at the end of each part is not addressable and must be
excluded from the map.
Signed-off-by: David Jander <david@protonic.nl>
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
arch/arm/mach-imx/esdctl.c | 72 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 71 insertions(+), 1 deletion(-)
diff --git a/arch/arm/mach-imx/esdctl.c b/arch/arm/mach-imx/esdctl.c
index b6689b7ffc..ada79fb709 100644
--- a/arch/arm/mach-imx/esdctl.c
+++ b/arch/arm/mach-imx/esdctl.c
@@ -332,6 +332,9 @@ static int vf610_ddrmc_add_mem(void *mmdcbase, const struct imx_esdctl_data *dat
#define DDRC_MSTR_ACTIVE_RANKS GENMASK(27, 24)
#define DDRC_MSTR_DEVICE_CONFIG GENMASK(31, 30)
+#define DDRC_ECCCFG0 0x0070
+#define DDRC_ECCCFG0_ECC_MODE GENMASK(2, 0)
+
#define DDRC_ADDRMAP0_CS_BIT1 GENMASK(12, 8)
#define DDRC_ADDRMAP1_BANK_B2 GENMASK(20, 16)
@@ -519,6 +522,33 @@ static resource_size_t imx8m_ddrc_sdram_size(void __iomem *ddrc, unsigned buswid
reduced_address_space, mstr);
}
+static resource_size_t imx8mp_ddrc_sdram_size(void __iomem *ddrc,
+ unsigned int *chunks, resource_size_t *stride)
+{
+ resource_size_t size = imx8m_ddrc_sdram_size(ddrc, 32);
+ const bool reduced_address_space = FIELD_GET(
+ DDRC_ADDRMAP6_LPDDR4_6GB_12GB_24GB, readl(ddrc + DDRC_ADDRMAP(6)));
+
+ /* ECC devides the accessible address space into 1 or 3 contiguous
+ * regions depending on reduced_address_space. For simplicity, give
+ * barebox only one contiguous region to use.
+ * Each region is only 7/8th the raw size due to ECC data.
+ */
+ if (chunks)
+ *chunks = 1;
+ if (FIELD_GET(DDRC_ECCCFG0_ECC_MODE, readl(ddrc + DDRC_ECCCFG0))) {
+ if (reduced_address_space) {
+ size /= 3;
+ if (chunks)
+ *chunks = 3;
+ if (stride)
+ *stride = size;
+ }
+ size = (size * 7) / 8;
+ }
+ return size;
+}
+
static int _imx8m_ddrc_add_mem(void *mmdcbase, const struct imx_esdctl_data *data,
unsigned int buswidth)
{
@@ -559,6 +589,29 @@ static int imx8m_ddrc_add_mem(void *mmdcbase, const struct imx_esdctl_data *data
return _imx8m_ddrc_add_mem(mmdcbase, data, 32);
}
+static int imx8mp_ddrc_add_mem(void *mmdcbase, const struct imx_esdctl_data *data)
+{
+ unsigned int chunks;
+ unsigned long base;
+ resource_size_t chunksize = 0, stride = 0;
+ int ret = -ENOMEM;
+ int i;
+ char name[5];
+
+ chunksize = imx8mp_ddrc_sdram_size(mmdcbase, &chunks, &stride);
+
+ base = data->base0;
+ for (i = 0; i < chunks; i++) {
+ snprintf(name, 5, "ram%d", i);
+ ret = arm_add_mem_device(name, base, chunksize);
+ if (ret)
+ break;
+ base += stride;
+ }
+
+ return ret;
+}
+
static int imx8mn_ddrc_add_mem(void *mmdcbase, const struct imx_esdctl_data *data)
{
return _imx8m_ddrc_add_mem(mmdcbase, data, 16);
@@ -742,6 +795,11 @@ static __maybe_unused const struct imx_esdctl_data imx8mn_data = {
.add_mem = imx8mn_ddrc_add_mem,
};
+static __maybe_unused const struct imx_esdctl_data imx8mp_data = {
+ .base0 = MX8M_DDR_CSD1_BASE_ADDR,
+ .add_mem = imx8mp_ddrc_add_mem,
+};
+
static __maybe_unused const struct imx_esdctl_data imx9_data = {
.base0 = MX9_DDR_CSD1_BASE_ADDR,
.add_mem = imx9_ddrc_add_mem,
@@ -822,6 +880,12 @@ static __maybe_unused struct of_device_id imx_esdctl_dt_ids[] = {
}, {
.compatible = "fsl,imx8mn-ddrc",
.data = &imx8mn_data
+ }, {
+ .compatible = "fsl,imx8mp-ddrc",
+ .data = &imx8mp_data
+ }, {
+ .compatible = "fsl,imx8mq-ddrc",
+ .data = &imx8mp_data
}, {
.compatible = "fsl,imx93-ddrc",
.data = &imx9_data
@@ -1000,9 +1064,15 @@ void __noreturn vf610_barebox_entry(void *boarddata)
resource_size_t imx8m_barebox_earlymem_size(unsigned buswidth)
{
+ unsigned int chunks;
+ resource_size_t stride = 0;
resource_size_t size;
- size = imx8m_ddrc_sdram_size(IOMEM(MX8M_DDRC_CTL_BASE_ADDR), buswidth);
+ if (IS_ENABLED(CONFIG_IMX8MP_DRAM_ECC))
+ size = imx8mp_ddrc_sdram_size(IOMEM(MX8M_DDRC_CTL_BASE_ADDR), &chunks,
+ &stride);
+ else
+ size = imx8m_ddrc_sdram_size(IOMEM(MX8M_DDRC_CTL_BASE_ADDR), buswidth);
/*
* We artificially limit detected memory size to force malloc
* pool placement to be within 4GiB address space, so as to
--
2.52.0
next prev parent reply other threads:[~2026-03-04 11:24 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-04 11:23 [PATCH 0/4] ARM: i.MX8: add DDRC-ECC support Steffen Trumtrar
2026-03-04 11:23 ` [PATCH 1/4] ARM: i.MX: esdctl: fix spelling of ad(d)ress Steffen Trumtrar
2026-03-04 11:23 ` Steffen Trumtrar [this message]
2026-03-04 11:23 ` [PATCH 3/4] drivers: ddr: imx8m: ddr_init.c: support ECC scrubbing Steffen Trumtrar
2026-03-04 11:43 ` Ahmad Fatoum
2026-03-04 12:23 ` David Jander
2026-03-04 12:33 ` Ahmad Fatoum
2026-03-04 13:14 ` David Jander
2026-03-04 11:23 ` [PATCH 4/4] arm: boards: protonic-imx8ml: Add ECC + scrubbing Steffen Trumtrar
2026-03-04 11:34 ` Ahmad Fatoum
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260304-v2026-02-0-topic-imx8-ecc-v1-2-700698530c5c@pengutronix.de \
--to=s.trumtrar@pengutronix.de \
--cc=barebox@lists.infradead.org \
--cc=david@protonic.nl \
--cc=s.hauer@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox