mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: BAREBOX <barebox@lists.infradead.org>
Subject: [PATCH 1/6] ARM: rockchip: dmc: rework DRAM functions
Date: Fri, 20 Mar 2026 09:31:17 +0100	[thread overview]
Message-ID: <20260320-compressed-firmware-rockchip-v1-1-7d03c7e39d2f@pengutronix.de> (raw)
In-Reply-To: <20260320-compressed-firmware-rockchip-v1-0-7d03c7e39d2f@pengutronix.de>

The DRAM on Rockchip SoCs is split in several regions interrupted by the
internal register space. For the PBL we used to use only the lowest DRAM
region which is enough for barebox to fit into. This recently changed on
RK3588 where we pass a FDT blob to OP-TEE which needs the whole memory.

Streamline this for all SoCs. Replace the rk3*_ram0_size functions with
a rk3*_ram_sizes set of functions which can return all regions.

The functionality to split the whole DRAM into regions was previously
duplicated in rk3588_ram_sizes() and rockchip_dmc_probe(). This patch
reduces the duplication by merging them to rockchip_ram().

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-rockchip/atf.c |  33 +++++-----
 arch/arm/mach-rockchip/dmc.c | 152 ++++++++++++++++++++++---------------------
 include/mach/rockchip/dmc.h  |  10 +--
 3 files changed, 100 insertions(+), 95 deletions(-)

diff --git a/arch/arm/mach-rockchip/atf.c b/arch/arm/mach-rockchip/atf.c
index 3e0a14292b..cf232e4f6e 100644
--- a/arch/arm/mach-rockchip/atf.c
+++ b/arch/arm/mach-rockchip/atf.c
@@ -168,12 +168,13 @@ void rk3562_atf_load_bl31(void *fdt)
 
 void __noreturn rk3562_barebox_entry(void *fdt)
 {
-	unsigned long membase, endmem;
+	phys_addr_t membase, memend;
+	resource_size_t memsize;
 
-	membase = RK3562_DRAM_BOTTOM;
-	endmem = rk3562_ram0_size();
+	rk3562_ram_sizes(&membase, &memsize, 1);
+	memend = membase + memsize;
 
-	rk_scratch = (void *)arm_mem_scratch(endmem);
+	rk_scratch = (void *)arm_mem_scratch(memend);
 
 	if (current_el() == 3) {
 		rk3562_lowlevel_init();
@@ -195,7 +196,7 @@ void __noreturn rk3562_barebox_entry(void *fdt)
 	}
 
 	optee_set_membase(rk_scratch_get_optee_hdr());
-	barebox_arm_entry(membase, endmem - membase, fdt);
+	barebox_arm_entry(membase, memsize, fdt);
 }
 
 void rk3568_atf_load_bl31(void *fdt)
@@ -206,12 +207,13 @@ void rk3568_atf_load_bl31(void *fdt)
 
 void __noreturn rk3568_barebox_entry(void *fdt)
 {
-	unsigned long membase, endmem;
+	phys_addr_t membase, memend;
+	resource_size_t memsize;
 
-	membase = RK3568_DRAM_BOTTOM;
-	endmem = rk3568_ram0_size();
+	rk3568_ram_sizes(&membase, &memsize, 1);
+	memend = membase + memsize;
 
-	rk_scratch = (void *)arm_mem_scratch(endmem);
+	rk_scratch = (void *)arm_mem_scratch(memend);
 
 	if (current_el() == 3) {
 		rk3568_lowlevel_init();
@@ -233,7 +235,7 @@ void __noreturn rk3568_barebox_entry(void *fdt)
 	}
 
 	optee_set_membase(rk_scratch_get_optee_hdr());
-	barebox_arm_entry(membase, endmem - membase, fdt);
+	barebox_arm_entry(membase, memsize, fdt);
 }
 
 void rk3588_atf_load_bl31(void *fdt)
@@ -318,12 +320,13 @@ void rk3576_atf_load_bl31(void *fdt)
 
 void __noreturn rk3576_barebox_entry(void *fdt)
 {
-	unsigned long membase, endmem;
+	phys_addr_t membase, memend;
+	resource_size_t memsize;
 
-	membase = RK3576_DRAM_BOTTOM;
-	endmem = rk3576_ram0_size();
+	rk3576_ram_sizes(&membase, &memsize, 1);
+	memend = membase + memsize;
 
-	rk_scratch = (void *)arm_mem_scratch(endmem);
+	rk_scratch = (void *)arm_mem_scratch(memend);
 
 	if (current_el() == 3) {
 		void *fdt_scratch = NULL;
@@ -345,5 +348,5 @@ void __noreturn rk3576_barebox_entry(void *fdt)
 	}
 
 	optee_set_membase(rk_scratch_get_optee_hdr());
-	barebox_arm_entry(membase, endmem - membase, fdt);
+	barebox_arm_entry(membase, memsize, fdt);
 }
diff --git a/arch/arm/mach-rockchip/dmc.c b/arch/arm/mach-rockchip/dmc.c
index 8502859f4b..318e99d8ba 100644
--- a/arch/arm/mach-rockchip/dmc.c
+++ b/arch/arm/mach-rockchip/dmc.c
@@ -53,6 +53,9 @@ struct rockchip_dmc_drvdata {
 	resource_size_t membase;
 };
 
+/*
+ * Return the physical size of a single bank
+ */
 static resource_size_t rockchip_sdram_size(u32 sys_reg2, u32 sys_reg3)
 {
 	u32 rank, cs0_col, bk, cs0_row, cs1_row, bw, row_3_4;
@@ -143,73 +146,111 @@ static resource_size_t rockchip_sdram_size(u32 sys_reg2, u32 sys_reg3)
 	return (resource_size_t)size_mb << 20;
 }
 
-resource_size_t rk3399_ram0_size(void)
+/*
+ * Split the total DRAM size into regions
+ */
+static size_t rockchip_ram(phys_addr_t membase, resource_size_t memsize,
+			   phys_addr_t int_reg_start, phys_addr_t *base,
+			   resource_size_t *size, size_t n)
+{
+	int i = 0;
+
+	if (membase > int_reg_start) {
+		/*
+		 * RK3576 has internal registers below the DRAM start and thus
+		 * doesn't need any gaps in the DRAM space.
+		 */
+		base[0] = membase;
+		size[0] = memsize;
+
+		return 1;
+	}
+
+	base[i] = membase;
+	size[i] = min_t(resource_size_t, RK3588_INT_REG_START, memsize) - membase;
+	i++;
+
+	if (i < n && memsize > SZ_4G) {
+		base[i] = SZ_4G;
+		size[i] = min_t(unsigned long, DRAM_GAP1_START, memsize) - SZ_4G;
+		i++;
+	}
+	if (i < n && memsize > DRAM_GAP1_END) {
+		base[i] = DRAM_GAP1_END;
+		size[i] = min_t(unsigned long, DRAM_GAP2_START, memsize) - DRAM_GAP1_END;
+		i++;
+	}
+	if (i < n && memsize > DRAM_GAP2_END) {
+		base[i] = DRAM_GAP2_END;
+		size[i] = memsize - DRAM_GAP2_END;
+		i++;
+	}
+
+	return i;
+}
+
+size_t rk3399_ram_sizes(phys_addr_t *base, resource_size_t *size, size_t n)
 {
 	void __iomem *pmugrf = IOMEM(RK3399_PMUGRF_BASE);
 	u32 sys_reg2, sys_reg3;
-	resource_size_t size;
+	resource_size_t memsize;
 
 	sys_reg2 = readl(pmugrf + RK3399_PMUGRF_OS_REG2);
 	sys_reg3 = readl(pmugrf + RK3399_PMUGRF_OS_REG3);
 
-	size = rockchip_sdram_size(sys_reg2, sys_reg3);
-	size = min_t(resource_size_t, RK3399_INT_REG_START, size);
+	memsize = rockchip_sdram_size(sys_reg2, sys_reg3);
 
 	pr_debug("%s() = %llu\n", __func__, (u64)size);
 
-	return size;
+	return rockchip_ram(RK3399_DRAM_BOTTOM, memsize, RK3399_INT_REG_START, base, size, n);
 }
 
-resource_size_t rk3562_ram0_size(void)
+size_t rk3562_ram_sizes(phys_addr_t *base, resource_size_t *size, size_t n)
 {
 	void __iomem *pmugrf = IOMEM(RK3562_PMUGRF_BASE);
 	u32 sys_reg2, sys_reg3;
-	resource_size_t size;
+	resource_size_t memsize;
 
 	sys_reg2 = readl(pmugrf + RK3562_PMUGRF_OS_REG2);
 	sys_reg3 = readl(pmugrf + RK3562_PMUGRF_OS_REG3);
 
-	size = rockchip_sdram_size(sys_reg2, sys_reg3);
-	size = min_t(resource_size_t, RK3562_INT_REG_START, size);
+	memsize = rockchip_sdram_size(sys_reg2, sys_reg3);
 
-	pr_debug("%s() = %llu\n", __func__, (u64)size);
+	pr_debug("%s() = %llu\n", __func__, (u64)memsize);
 
-	return size;
+	return rockchip_ram(RK3562_DRAM_BOTTOM, memsize, RK3562_INT_REG_START, base, size, n);
 }
 
-resource_size_t rk3568_ram0_size(void)
+size_t rk3568_ram_sizes(phys_addr_t *base, resource_size_t *size, size_t n)
 {
 	void __iomem *pmugrf = IOMEM(RK3568_PMUGRF_BASE);
 	u32 sys_reg2, sys_reg3;
-	resource_size_t size;
+	resource_size_t memsize;
 
 	sys_reg2 = readl(pmugrf + RK3568_PMUGRF_OS_REG2);
 	sys_reg3 = readl(pmugrf + RK3568_PMUGRF_OS_REG3);
 
-	size = rockchip_sdram_size(sys_reg2, sys_reg3);
-	size = min_t(resource_size_t, RK3568_INT_REG_START, size);
+	memsize = rockchip_sdram_size(sys_reg2, sys_reg3);
 
-	pr_debug("%s() = %llu\n", __func__, (u64)size);
+	pr_debug("%s() = %llu\n", __func__, (u64)memsize);
 
-	return size;
+	return rockchip_ram(RK3568_DRAM_BOTTOM, memsize, RK3568_INT_REG_START, base, size, n);
 }
 
-resource_size_t rk3576_ram0_size(void)
+size_t rk3576_ram_sizes(phys_addr_t *base, resource_size_t *size, size_t n)
 {
 	void __iomem *pmugrf = IOMEM(RK3576_PMUGRF_BASE);
 	u32 sys_reg2, sys_reg3;
-	resource_size_t size;
+	resource_size_t memsize;
 
 	sys_reg2 = readl(pmugrf + RK3576_PMUGRF_OS_REG2);
 	sys_reg3 = readl(pmugrf + RK3576_PMUGRF_OS_REG3);
 
-	size = rockchip_sdram_size(sys_reg2, sys_reg3);
-	/* RK3576 has a different memory map...? */
-	/* size = min_t(resource_size_t, RK3576_INT_REG_START, size); */
+	memsize = rockchip_sdram_size(sys_reg2, sys_reg3);
 
 	pr_debug("%s() = %llu\n", __func__, (u64)size);
 
-	return size;
+	return rockchip_ram(RK3576_DRAM_BOTTOM, memsize, RK3576_INT_REG_START, base, size, n);
 }
 
 #define RK3588_PMUGRF_BASE 0xfd58a000
@@ -223,7 +264,6 @@ size_t rk3588_ram_sizes(phys_addr_t *base, resource_size_t *size, size_t n)
 	void __iomem *pmugrf = IOMEM(RK3588_PMUGRF_BASE);
 	u32 sys_reg2, sys_reg3, sys_reg4, sys_reg5;
 	resource_size_t memsize, size1, size2;
-	size_t i = 0;
 
 	sys_reg2 = readl(pmugrf + RK3588_PMUGRF_OS_REG2);
 	sys_reg3 = readl(pmugrf + RK3588_PMUGRF_OS_REG3);
@@ -237,45 +277,18 @@ size_t rk3588_ram_sizes(phys_addr_t *base, resource_size_t *size, size_t n)
 
 	memsize = size1 + size2;
 
-	base[i] = RK3588_DRAM_BOTTOM;
-	size[i] = min_t(resource_size_t, RK3588_INT_REG_START, memsize) - RK3588_DRAM_BOTTOM;
-	i++;
-
-	if (i < n && memsize > SZ_4G) {
-		base[i] = SZ_4G;
-		size[i] = min_t(unsigned long, DRAM_GAP1_START, memsize) - SZ_4G;
-		i++;
-	}
-	if (i < n && memsize > DRAM_GAP1_END) {
-		base[i] = DRAM_GAP1_END;
-		size[i] = min_t(unsigned long, DRAM_GAP2_START, memsize) - DRAM_GAP1_END;
-		i++;
-	}
-	if (i < n && memsize > DRAM_GAP2_END) {
-		base[i] = DRAM_GAP2_END;
-		size[i] = memsize - DRAM_GAP2_END;
-		i++;
-	}
-
-	return i;
-}
-
-resource_size_t rk3588_ram0_size(void)
-{
-	phys_addr_t base;
-	resource_size_t size;
-
-	rk3588_ram_sizes(&base, &size, 1);
-
-	return size;
+	return rockchip_ram(RK3588_DRAM_BOTTOM, memsize, RK3588_INT_REG_START, base, size, n);
 }
 
 static int rockchip_dmc_probe(struct device *dev)
 {
 	const struct rockchip_dmc_drvdata *drvdata;
 	resource_size_t membase, memsize, regstart;
+	phys_addr_t base[ROCKCHIP_MAX_DRAM_RESOURCES];
+	resource_size_t size[ROCKCHIP_MAX_DRAM_RESOURCES];
 	struct regmap *regmap;
 	u32 sys_rega, sys_regb;
+	int i, n_res;
 
 	regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pmu");
 	if (IS_ERR(regmap))
@@ -304,26 +317,15 @@ static int rockchip_dmc_probe(struct device *dev)
 	membase = drvdata->membase;
 	regstart = drvdata->internal_registers_start;
 
-	if (membase < regstart) {
-		/* ram0, from 0xa00000 up to SoC internal register space start */
-		arm_add_mem_device("ram0", membase,
-			min_t(resource_size_t, drvdata->internal_registers_start, memsize) - membase);
-
-		/* ram1, RAM beyond 32bit space up to first gap */
-		if (memsize > SZ_4G)
-			arm_add_mem_device("ram1", SZ_4G,
-				min_t(resource_size_t, DRAM_GAP1_START, memsize) - SZ_4G);
-
-		/* ram2, RAM between first and second gap */
-		if (memsize > DRAM_GAP1_END)
-			arm_add_mem_device("ram2", DRAM_GAP1_END,
-				min_t(resource_size_t, DRAM_GAP2_START, memsize) - DRAM_GAP1_END);
-
-		/* ram3, remaining RAM after second gap */
-		if (memsize > DRAM_GAP2_END)
-			arm_add_mem_device("ram3", DRAM_GAP2_END, memsize - DRAM_GAP2_END);
-	} else {
-		arm_add_mem_device("ram0", membase, memsize - 0xa00000);
+	n_res = rockchip_ram(membase, memsize, regstart, base, size,
+			     ROCKCHIP_MAX_DRAM_RESOURCES);
+
+	for (i = 0; i < n_res; i++) {
+		char name[sizeof("ramx")];
+
+		sprintf(name, "ram%u", i);
+
+		arm_add_mem_device(name, base[i], size[i]);
 	}
 
 	return 0;
diff --git a/include/mach/rockchip/dmc.h b/include/mach/rockchip/dmc.h
index ddcf989a30..d1dde1cc65 100644
--- a/include/mach/rockchip/dmc.h
+++ b/include/mach/rockchip/dmc.h
@@ -83,12 +83,12 @@ enum {
 #define SYS_REG_CS1_COL_SHIFT(ch)		(0 + (ch) * 2)
 #define SYS_REG_CS1_COL_MASK			3
 
-resource_size_t rk3399_ram0_size(void);
-resource_size_t rk3562_ram0_size(void);
-resource_size_t rk3568_ram0_size(void);
-resource_size_t rk3576_ram0_size(void);
-resource_size_t rk3588_ram0_size(void);
+#define ROCKCHIP_MAX_DRAM_RESOURCES	4
 
+size_t rk3399_ram_sizes(phys_addr_t *base, resource_size_t *size, size_t n);
+size_t rk3562_ram_sizes(phys_addr_t *base, resource_size_t *size, size_t n);
+size_t rk3568_ram_sizes(phys_addr_t *base, resource_size_t *size, size_t n);
+size_t rk3576_ram_sizes(phys_addr_t *base, resource_size_t *size, size_t n);
 size_t rk3588_ram_sizes(phys_addr_t *base, resource_size_t *size, size_t n);
 
 #endif

-- 
2.47.3




  reply	other threads:[~2026-03-20  8:31 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-20  8:31 [PATCH 0/6] Rockchip: Enable MMU before uncompressing TF-A and OP-TEE Sascha Hauer
2026-03-20  8:31 ` Sascha Hauer [this message]
2026-03-20  8:31 ` [PATCH 2/6] ARM: rockchip: atf: make all memory banks available Sascha Hauer
2026-03-20  8:31 ` [PATCH 3/6] ARM: rockchip: atf: add OP-TEE fdt creation function for all SoCs Sascha Hauer
2026-03-20  8:31 ` [PATCH 4/6] ARM: Rockchip: Drop rk3xxx_atf_load_bl31() Sascha Hauer
2026-03-20  8:31 ` [PATCH 5/6] ARM: rockchip: separate physical DRAM start from usable start Sascha Hauer
2026-03-20  8:31 ` [PATCH 6/6] ARM: rockchip: atf: enable MMU in PBL Sascha Hauer

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20260320-compressed-firmware-rockchip-v1-1-7d03c7e39d2f@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /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