u-boot (Allwinner): update patches for 2025.04

- drop upstreamed patches for 2024.04
- rebase patches for 2024.04
- rebase patches for 2024.10
  - a79fc7a79c
- H3: rebase patch for 2025.01
  - arm: Implement read_mpidr on armv7
  - 080be069f5 (diff-6e85273234514abfd8dd6193db1e9c0aa87531146b27098bc70e8010fa914079R396)
- H2-plus: rebase patch for 2025.01
- Switch PMIC connection to I2C
- Fix H6 DRAM size detection
This commit is contained in:
Rudi Heitbaum 2024-04-03 11:21:46 +00:00
parent 6f8c89bf2f
commit b6bcaf6fb8
12 changed files with 436 additions and 475 deletions

View File

@ -1,7 +1,7 @@
From 470309271de34eb8c24138f1ac15bd37966ed01a Mon Sep 17 00:00:00 2001
From 03db81bb312e8a9503f52779da4b2007bc08954a Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 9 Oct 2021 23:01:05 -0500
Subject: [PATCH 13/13] [DO NOT MERGE] sunxi: psci: Delegate PSCI to SCPI
Subject: [PATCH 12/13] [DO NOT MERGE] sunxi: psci: Delegate PSCI to SCPI
This adds a new PSCI implementation which communicates with SCP firmware
running on the AR100 using the SCPI protocol. This allows it to support
@ -10,53 +10,54 @@ suspend, and multiple reset methods.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/cpu/armv7/Kconfig | 2 +-
arch/arm/cpu/armv7/sunxi/Makefile | 2 +-
arch/arm/cpu/armv7/sunxi/psci-scpi.c | 451 +++++++++++++++++++++++++++
3 files changed, 453 insertions(+), 2 deletions(-)
arch/arm/cpu/armv7/Kconfig | 1 +
arch/arm/cpu/armv7/sunxi/Makefile | 4 +
arch/arm/cpu/armv7/sunxi/psci-scpi.c | 453 +++++++++++++++++++++++++++
3 files changed, 468 insertions(+)
create mode 100644 arch/arm/cpu/armv7/sunxi/psci-scpi.c
diff --git a/arch/arm/cpu/armv7/Kconfig b/arch/arm/cpu/armv7/Kconfig
index 06b477619334..948f4e8276fe 100644
index ec3d31e750..9dccc12253 100644
--- a/arch/arm/cpu/armv7/Kconfig
+++ b/arch/arm/cpu/armv7/Kconfig
@@ -44,7 +44,7 @@ config ARMV7_PSCI
@@ -86,6 +86,7 @@ config ARMV7_PSCI
choice
prompt "Supported PSCI version"
depends on ARMV7_PSCI
- default ARMV7_PSCI_0_1 if ARCH_SUNXI
+ default ARMV7_PSCI_1_1 if ARCH_SUNXI
+ default ARMV7_PSCI_1_1 if MACH_SUN8I_H3
default ARMV7_PSCI_0_1 if ARCH_SUNXI
default ARMV7_PSCI_1_0
help
Select the supported PSCI version.
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index 1d40d6a18dca..4a0c16deb459 100644
index 3e975b366c..6473b9acbd 100644
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_MACH_SUN6I) += tzpc.o
obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o
@@ -13,8 +13,12 @@ obj-$(CONFIG_MACH_SUN6I) += sram.o
obj-$(CONFIG_MACH_SUN8I) += sram.o
ifndef CONFIG_SPL_BUILD
-obj-$(CONFIG_ARMV7_PSCI) += psci.o
ifndef CONFIG_XPL_BUILD
+ifdef CONFIG_MACH_SUN8I_H3
+obj-$(CONFIG_ARMV7_PSCI) += psci-scpi.o
+else
obj-$(CONFIG_ARMV7_PSCI) += psci.o
endif
+endif
ifdef CONFIG_SPL_BUILD
ifdef CONFIG_XPL_BUILD
obj-y += fel_utils.o
diff --git a/arch/arm/cpu/armv7/sunxi/psci-scpi.c b/arch/arm/cpu/armv7/sunxi/psci-scpi.c
new file mode 100644
index 000000000000..b3849b366e31
index 0000000000..fea51eb456
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/psci-scpi.c
@@ -0,0 +1,451 @@
@@ -0,0 +1,453 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
+ * Copyright (C) 2018-2021 Samuel Holland <samuel@sholland.org>
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/cpucfg.h>
+#include <asm/armv7.h>
+#include <asm/gic.h>
+#include <asm/io.h>
@ -67,6 +68,19 @@ index 000000000000..b3849b366e31
+#define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET)
+#define GICC_BASE (SUNXI_GIC400_BASE + GIC_CPU_OFFSET_A15)
+
+/*
+ * Offsets into the CPUCFG block applicable to most SUNXIs.
+ */
+#define SUNXI_CPU_RST(cpu) (0x40 + (cpu) * 0x40 + 0x0)
+#define SUNXI_CPU_STATUS(cpu) (0x40 + (cpu) * 0x40 + 0x8)
+#define SUNXI_GEN_CTRL (0x184)
+#define SUNXI_SUPER_STANDY_FLAG (0x1a0)
+#define SUNXI_PRIV0 (0x1a4)
+#define SUNXI_PRIV1 (0x1a8)
+#define SUN7I_CPU1_PWR_CLAMP (0x1b0)
+#define SUN7I_CPU1_PWROFF (0x1b4)
+#define SUNXI_DBG_CTRL1 (0x1e4)
+
+#define HW_ON 0
+#define HW_OFF 1
+#define HW_STANDBY 2
@ -158,15 +172,6 @@ index 000000000000..b3849b366e31
+
+static u32 __secure_data lock;
+
+static inline u32 __secure read_mpidr(void)
+{
+ u32 val;
+
+ asm volatile ("mrc p15, 0, %0, c0, c0, 5" : "=r" (val));
+
+ return val;
+}
+
+static void __secure scpi_begin_command(void)
+{
+ u32 mpidr = read_mpidr();
@ -446,14 +451,14 @@ index 000000000000..b3849b366e31
+ struct sunxi_cpucfg_reg *cpucfg =
+ (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
+
+ writel((u32)entry, &cpucfg->priv0);
+ writel((u32)entry, SUNXI_CPUCFG_BASE + SUNXI_PRIV0);
+
+ if (IS_ENABLED(CONFIG_MACH_SUN8I_H3)) {
+ /* Redirect CPU 0 to the secure monitor via the resume shim. */
+ writel(0x16aaefe8, &cpucfg->super_standy_flag);
+ writel(0xaa16efe8, &cpucfg->super_standy_flag);
+ writel(SUNXI_RESUME_BASE, &cpucfg->priv1);
+ }
+#ifdef CONFIG_MACH_SUN8I_H3
+ /* Redirect CPU 0 to the secure monitor via the resume shim. */
+ writel(0x16aaefe8, SUNXI_CPUCFG_BASE + SUNXI_SUPER_STANDY_FLAG);
+ writel(0xaa16efe8, SUNXI_CPUCFG_BASE + SUNXI_SUPER_STANDY_FLAG);
+ writel(CONFIG_SUNXI_RESUME_BASE, SUNXI_CPUCFG_BASE + SUNXI_PRIV1);
+#endif
+}
+#endif
+
@ -500,5 +505,5 @@ index 000000000000..b3849b366e31
+ writel(0xff, GICC_BASE + GICC_PMR);
+}
--
2.33.0
2.34.1

View File

@ -1,7 +1,7 @@
From f15f4f36e023aaaeacdbebe16736119d1be3ac6b Mon Sep 17 00:00:00 2001
From e814c64fcbd08fb588b7e52b7e968ed9feb2d747 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 9 Oct 2021 17:12:57 -0500
Subject: [PATCH 07/13] sunxi: psci: Add support for H3 CPU 0 hotplug
Subject: [PATCH 06/13] sunxi: psci: Add support for H3 CPU 0 hotplug
Due to a bug in the H3 SoC, where the CPU 0 hotplug flag cannot be
written, resuming CPU 0 requires using the "Super Standby" code path in
@ -21,17 +21,17 @@ PLL_PERIPH0 must be bypassed to prevent AHB1 from temporarily running at
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
Makefile | 17 +++++++++++++++++
arch/arm/cpu/armv7/sunxi/psci.c | 31 +++++++++++++++++++++++++++++++
arch/arm/dts/sunxi-u-boot.dtsi | 23 ++++++++++++++++++++++-
include/configs/sun8i.h | 4 ++++
4 files changed, 74 insertions(+), 1 deletion(-)
arch/arm/cpu/armv7/sunxi/psci.c | 32 ++++++++++++++++++++++++++++++++
arch/arm/dts/sunxi-u-boot.dtsi | 23 ++++++++++++++++++++---
arch/arm/mach-sunxi/Kconfig | 7 +++++++
4 files changed, 76 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
index f911f7034430..9edcadfa9c47 100644
index 8a04dfcf36..670c87c2ff 100644
--- a/Makefile
+++ b/Makefile
@@ -984,6 +984,23 @@ endif
endif
@@ -1024,6 +1024,23 @@ ifeq ($(CONFIG_ARCH_ROCKCHIP)_$(CONFIG_SPL_FRAMEWORK),y_)
INPUTS-y += u-boot.img
endif
+ifeq ($(CONFIG_MACH_SUN8I_H3)$(CONFIG_ARMV7_PSCI),yy)
@ -55,7 +55,7 @@ index f911f7034430..9edcadfa9c47 100644
$(if $(CONFIG_SPL_X86_16BIT_INIT),spl/u-boot-spl.bin) \
$(if $(CONFIG_TPL_X86_16BIT_INIT),tpl/u-boot-tpl.bin)
diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
index 3448fe2edcaa..299bd3ba65e0 100644
index 098e2b12bf..d76266d9c2 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -10,6 +10,7 @@
@ -64,38 +64,45 @@ index 3448fe2edcaa..299bd3ba65e0 100644
+#include <asm/arch/clock.h>
#include <asm/arch/cpu.h>
#include <asm/arch/cpucfg.h>
#include <asm/arch/prcm.h>
@@ -141,6 +142,13 @@ static void __secure sunxi_set_entry_address(void *entry)
(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
writel((u32)entry, &cpucfg->priv0);
#include <asm/armv7.h>
#include <asm/gic.h>
@@ -31,7 +32,9 @@
#define SUNXI_CPU_RST(cpu) (0x40 + (cpu) * 0x40 + 0x0)
#define SUNXI_CPU_STATUS(cpu) (0x40 + (cpu) * 0x40 + 0x8)
#define SUNXI_GEN_CTRL (0x184)
+#define SUNXI_SUPER_STANDBY_FLAG (0x1a0)
#define SUNXI_PRIV0 (0x1a4)
+#define SUNXI_PRIV1 (0x1a8)
#define SUN7I_CPU1_PWR_CLAMP (0x1b0)
#define SUN7I_CPU1_PWROFF (0x1b4)
#define SUNXI_DBG_CTRL1 (0x1e4)
@@ -139,6 +142,13 @@ static void __secure sunxi_cpu_set_entry(int __always_unused cpu, void *entry)
} else {
writel((u32)entry, SUNXI_CPUCFG_BASE + SUNXI_PRIV0);
}
+
+ if (IS_ENABLED(CONFIG_MACH_SUN8I_H3)) {
+ if (CONFIG_SUNXI_RESUME_BASE) {
+ /* Redirect CPU 0 to the secure monitor via the resume shim. */
+ writel(0x16aaefe8, &cpucfg->super_standy_flag);
+ writel(0xaa16efe8, &cpucfg->super_standy_flag);
+ writel(SUNXI_RESUME_BASE, &cpucfg->priv1);
+ writel(0x16aaefe8, SUNXI_R_CPUCFG_BASE + SUNXI_SUPER_STANDBY_FLAG);
+ writel(0xaa16efe8, SUNXI_R_CPUCFG_BASE + SUNXI_SUPER_STANDBY_FLAG);
+ writel(CONFIG_SUNXI_RESUME_BASE, SUNXI_R_CPUCFG_BASE + SUNXI_PRIV1);
+ }
}
#endif
@@ -255,9 +263,12 @@ out:
static void __secure sunxi_cpu_set_power(int cpu, bool on)
@@ -307,7 +317,9 @@ out:
int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc,
u32 context_id)
{
+ struct sunxi_ccm_reg *ccu = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
struct sunxi_cpucfg_reg *cpucfg =
(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
u32 cpu = (mpidr & 0x3);
+ u32 cpu_clk;
+ u32 bus_clk;
+ u32 bus_clk, cpu_clk;
/* store target PC and context id */
psci_save(cpu, pc, context_id);
@@ -274,12 +285,32 @@ int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc,
@@ -324,12 +336,32 @@ int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc,
/* Lock CPU (Disable external debug access) */
clrbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
sunxi_cpu_set_locking(cpu, true);
+ if (IS_ENABLED(CONFIG_MACH_SUN8I_H3) && cpu == 0) {
+ /* Save registers that will be clobbered by the BROM. */
@ -110,7 +117,7 @@ index 3448fe2edcaa..299bd3ba65e0 100644
sunxi_cpu_set_power(cpu, true);
/* De-assert reset on target CPU */
writel(BIT(1) | BIT(0), &cpucfg->cpu[cpu].rst);
sunxi_cpu_set_reset(cpu, false);
+ if (IS_ENABLED(CONFIG_MACH_SUN8I_H3) && cpu == 0) {
+ /* Spin until the BROM has clobbered the clock registers. */
@ -123,37 +130,24 @@ index 3448fe2edcaa..299bd3ba65e0 100644
+ clrbits_le32(&ccu->pll6_cfg, BIT(25));
+ }
+
/* Unlock CPU (Disable external debug access) */
setbits_le32(&cpucfg->dbg_ctrl1, BIT(cpu));
/* Unlock CPU (Reenable external debug access) */
sunxi_cpu_set_locking(cpu, false);
diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi
index ad1f97632979..a2c74da81aa9 100644
index ed1cb91eeb..8c6d36d4ac 100644
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -6,7 +6,11 @@
#define ARCH "arm"
#endif
-#if defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H5)
+#if defined(CONFIG_MACH_SUN8I_H3)
+#ifdef CONFIG_ARMV7_PSCI
+#define RESUME_ADDR SUNXI_RESUME_BASE
+#endif
+#elif defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H5)
#define BL31_ADDR 0x00044000
#define SCP_ADDR 0x00050000
#elif defined(CONFIG_MACH_SUN50I_H6)
@@ -74,6 +78,20 @@
@@ -77,6 +77,20 @@
};
#endif
+#ifdef RESUME_ADDR
+#if CONFIG_SUNXI_RESUME_BASE
+ resume {
+ description = "Super Standby resume image";
+ type = "standalone";
+ arch = ARCH;
+ compression = "none";
+ load = <RESUME_ADDR>;
+ load = <CONFIG_SUNXI_RESUME_BASE>;
+
+ blob-ext {
+ filename = "u-boot-resume.img";
@ -161,36 +155,46 @@ index ad1f97632979..a2c74da81aa9 100644
+ };
+#endif
+
#ifdef SCP_ADDR
#if CONFIG_SUNXI_SCP_BASE
scp {
description = "SCP firmware";
@@ -107,6 +125,9 @@
@@ -108,12 +122,15 @@
firmware = "atf";
#else
firmware = "uboot";
#endif
loadables =
+#ifdef RESUME_ADDR
+#endif
+ loadables =
+#if CONFIG_SUNXI_RESUME_BASE
+ "resume",
+#endif
#ifdef SCP_ADDR
"scp",
#endif
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 563635636624..2f0d69bdfce2 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -15,6 +15,12 @@
#include <asm/arch/cpu.h>
#include <linux/stringify.h>
#if CONFIG_SUNXI_SCP_BASE
- loadables = "scp", "uboot";
-#else
- loadables = "uboot";
+ "scp",
#endif
+ "uboot";
fdt = "fdt-SEQ";
};
};
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index b0fbda0aa0..48e750d070 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -164,6 +164,13 @@ config SUNXI_BL31_BASE
help
Address where BL31 (TF-A) is loaded, or zero if BL31 is not used.
+#ifdef SUNXI_SRAM_A2_SIZE
+#define SUNXI_RESUME_BASE (CONFIG_ARMV7_SECURE_BASE + \
+ CONFIG_ARMV7_SECURE_MAX_SIZE)
+#define SUNXI_RESUME_SIZE 1024
+#endif
+config SUNXI_RESUME_BASE
+ hex
+ default 0x00047c00 if MACH_SUN8I_H3
+ default 0x0
+ help
+ Address where the resume shim is loaded, or zero if it is not used.
+
/* Serial & console */
#define CONFIG_SYS_NS16550_SERIAL
/* ns16550 reg in the low bits of cpu reg */
config SUNXI_SCP_BASE
hex
default 0x00050000 if MACH_SUN50I || MACH_SUN50I_H5
--
2.33.0
2.34.1

View File

@ -1,7 +1,7 @@
From 92657de6d2ac3ae100a4d78cc37c729142f1a59b Mon Sep 17 00:00:00 2001
From 2f330ad98dfb70c245b285d4d2d2a1fe5029fda8 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sat, 17 Apr 2021 13:33:54 -0500
Subject: [PATCH 10/13] sunxi: Enable support for SCP firmware on H3
Subject: [PATCH 09/13] sunxi: Enable support for SCP firmware on H3
Now that issues with the BROM have been sorted out, we can implement
PSCI system suspend on H3 by delegating to SCP firmware. Let's start by
@ -10,28 +10,27 @@ valid firmware is loaded.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/dts/sunxi-u-boot.dtsi | 1 +
board/sunxi/board.c | 8 ++++++++
include/configs/sun8i.h | 3 +++
3 files changed, 12 insertions(+)
arch/arm/mach-sunxi/Kconfig | 1 +
board/sunxi/board.c | 8 ++++++++
2 files changed, 9 insertions(+)
diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi
index a2c74da81aa9..ce062fe94052 100644
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -9,6 +9,7 @@
#if defined(CONFIG_MACH_SUN8I_H3)
#ifdef CONFIG_ARMV7_PSCI
#define RESUME_ADDR SUNXI_RESUME_BASE
+#define SCP_ADDR SUNXI_SCP_BASE
#endif
#elif defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUN50I_H5)
#define BL31_ADDR 0x00044000
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 48e750d070..a6d5de9e3b 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -173,6 +173,7 @@ config SUNXI_RESUME_BASE
config SUNXI_SCP_BASE
hex
+ default 0x00048000 if MACH_SUN8I_H3
default 0x00050000 if MACH_SUN50I || MACH_SUN50I_H5
default 0x00114000 if MACH_SUN50I_H6
default 0x0
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 2b7d655678d0..a25cd11f1124 100644
index 39ecbe988f..b83d21ef08 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -18,6 +18,7 @@
@@ -19,6 +19,7 @@
#include <init.h>
#include <log.h>
#include <mmc.h>
@ -39,12 +38,12 @@ index 2b7d655678d0..a25cd11f1124 100644
#include <axp_pmic.h>
#include <generic-phy.h>
#include <phy-sun4i-usb.h>
@@ -957,6 +958,13 @@ int board_late_init(void)
@@ -851,6 +852,13 @@ int board_late_init(void)
usb_ether_init();
#endif
+#ifdef SUNXI_SCP_BASE
+ if (!rproc_load(0, SUNXI_SCP_BASE, SUNXI_SCP_MAX_SIZE)) {
+#ifdef CONFIG_REMOTEPROC_SUN6I_AR100
+ if (!rproc_load(0, CONFIG_SUNXI_SCP_BASE, 1)) {
+ puts("Starting SCP...\n");
+ rproc_start(0);
+ }
@ -53,20 +52,6 @@ index 2b7d655678d0..a25cd11f1124 100644
return 0;
}
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 2f0d69bdfce2..fda5b235a3e0 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -26,6 +26,9 @@
#define SUNXI_RESUME_BASE (CONFIG_ARMV7_SECURE_BASE + \
CONFIG_ARMV7_SECURE_MAX_SIZE)
#define SUNXI_RESUME_SIZE 1024
+
+#define SUNXI_SCP_BASE (SUNXI_RESUME_BASE + SUNXI_RESUME_SIZE)
+#define SUNXI_SCP_MAX_SIZE (16 * 1024)
#endif
/*
--
2.33.0
2.34.1

View File

@ -12,7 +12,7 @@ Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/cpu/armv7/Kconfig | 1 +
arch/arm/cpu/armv7/sunxi/Makefile | 4 +
arch/arm/cpu/armv7/sunxi/psci-scpi.c | 463 +++++++++++++++++++++++++++
arch/arm/cpu/armv7/sunxi/psci-scpi.c | 453 +++++++++++++++++++++++++++
3 files changed, 468 insertions(+)
create mode 100644 arch/arm/cpu/armv7/sunxi/psci-scpi.c
@ -35,7 +35,7 @@ index 3e975b366c..6473b9acbd 100644
@@ -13,8 +13,12 @@ obj-$(CONFIG_MACH_SUN6I) += sram.o
obj-$(CONFIG_MACH_SUN8I) += sram.o
ifndef CONFIG_SPL_BUILD
ifndef CONFIG_XPL_BUILD
+ifdef CONFIG_MACH_SUN8I_H3
+obj-$(CONFIG_ARMV7_PSCI) += psci-scpi.o
+else
@ -43,21 +43,20 @@ index 3e975b366c..6473b9acbd 100644
endif
+endif
ifdef CONFIG_SPL_BUILD
ifdef CONFIG_XPL_BUILD
obj-y += fel_utils.o
diff --git a/arch/arm/cpu/armv7/sunxi/psci-scpi.c b/arch/arm/cpu/armv7/sunxi/psci-scpi.c
new file mode 100644
index 0000000000..fea51eb456
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/psci-scpi.c
@@ -0,0 +1,463 @@
@@ -0,0 +1,453 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
+ * Copyright (C) 2018-2021 Samuel Holland <samuel@sholland.org>
+ */
+
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/armv7.h>
+#include <asm/gic.h>
@ -173,15 +172,6 @@ index 0000000000..fea51eb456
+
+static u32 __secure_data lock;
+
+static inline u32 __secure read_mpidr(void)
+{
+ u32 val;
+
+ asm volatile ("mrc p15, 0, %0, c0, c0, 5" : "=r" (val));
+
+ return val;
+}
+
+static void __secure scpi_begin_command(void)
+{
+ u32 mpidr = read_mpidr();

View File

@ -32,7 +32,7 @@ index 6473b9acbd..033042666f 100644
@@ -13,7 +13,7 @@ obj-$(CONFIG_MACH_SUN6I) += sram.o
obj-$(CONFIG_MACH_SUN8I) += sram.o
ifndef CONFIG_SPL_BUILD
ifndef CONFIG_XPL_BUILD
-ifdef CONFIG_MACH_SUN8I_H3
+ifneq ($(CONFIG_MACH_SUN8I_A33)$(CONFIG_MACH_SUN8I_H3),)
obj-$(CONFIG_ARMV7_PSCI) += psci-scpi.o

View File

@ -0,0 +1,157 @@
From dec5528de024e8ddd1dafd8461df3a1bdcfc4bad Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sat, 15 Mar 2025 09:57:57 +0100
Subject: [PATCH] Revert "arm64: dts: allwinner: h6: Use RSB for AXP805 PMIC
connection"
Hardware that uses I2C wasn't designed with high speeds in mind, so
communication with PMIC via RSB can intermittently fail. Go back to I2C
as higher speed and efficiency isn't worth the trouble.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
arch/arm/dts/sun50i-h6-beelink-gs1.dts | 38 +++++++++++++-------------
arch/arm/dts/sun50i-h6-orangepi-3.dts | 14 +++++-----
arch/arm/dts/sun50i-h6-orangepi.dtsi | 22 +++++++--------
3 files changed, 37 insertions(+), 37 deletions(-)
diff --git a/arch/arm/dts/sun50i-h6-beelink-gs1.dts b/arch/arm/dts/sun50i-h6-beelink-gs1.dts
index 529285fc34fd..8359a8ac2a33 100644
--- a/arch/arm/dts/sun50i-h6-beelink-gs1.dts
+++ b/arch/arm/dts/sun50i-h6-beelink-gs1.dts
@@ -151,28 +151,12 @@
vcc-pg-supply = <&reg_aldo1>;
};
-&r_ir {
- linux,rc-map-name = "rc-beelink-gs1";
+&r_i2c {
status = "okay";
-};
-&r_pio {
- /*
- * FIXME: We can't add that supply for now since it would
- * create a circular dependency between pinctrl, the regulator
- * and the RSB Bus.
- *
- * vcc-pl-supply = <&reg_aldo1>;
- */
- vcc-pm-supply = <&reg_aldo1>;
-};
-
-&r_rsb {
- status = "okay";
-
- axp805: pmic@745 {
+ axp805: pmic@36 {
compatible = "x-powers,axp805", "x-powers,axp806";
- reg = <0x745>;
+ reg = <0x36>;
interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
@@ -290,6 +274,22 @@
};
};
+&r_ir {
+ linux,rc-map-name = "rc-beelink-gs1";
+ status = "okay";
+};
+
+&r_pio {
+ /*
+ * PL0 and PL1 are used for PMIC I2C
+ * don't enable the pl-supply else
+ * it will fail at boot
+ *
+ * vcc-pl-supply = <&reg_aldo1>;
+ */
+ vcc-pm-supply = <&reg_aldo1>;
+};
+
&spdif {
pinctrl-names = "default";
pinctrl-0 = <&spdif_tx_pin>;
diff --git a/arch/arm/dts/sun50i-h6-orangepi-3.dts b/arch/arm/dts/sun50i-h6-orangepi-3.dts
index bdcec466246f..f920f8f0a4dd 100644
--- a/arch/arm/dts/sun50i-h6-orangepi-3.dts
+++ b/arch/arm/dts/sun50i-h6-orangepi-3.dts
@@ -175,16 +175,12 @@
vcc-pg-supply = <&reg_vcc_wifi_io>;
};
-&r_ir {
+&r_i2c {
status = "okay";
-};
-&r_rsb {
- status = "okay";
-
- axp805: pmic@745 {
+ axp805: pmic@36 {
compatible = "x-powers,axp805", "x-powers,axp806";
- reg = <0x745>;
+ reg = <0x36>;
interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
@@ -295,6 +291,10 @@
};
};
+&r_ir {
+ status = "okay";
+};
+
&rtc {
clocks = <&ext_osc32k>;
};
diff --git a/arch/arm/dts/sun50i-h6-orangepi.dtsi b/arch/arm/dts/sun50i-h6-orangepi.dtsi
index 4403769fc36e..6846797a8afd 100644
--- a/arch/arm/dts/sun50i-h6-orangepi.dtsi
+++ b/arch/arm/dts/sun50i-h6-orangepi.dtsi
@@ -112,20 +112,12 @@
vcc-pg-supply = <&reg_aldo1>;
};
-&r_ir {
+&r_i2c {
status = "okay";
-};
-&r_pio {
- vcc-pm-supply = <&reg_bldo3>;
-};
-
-&r_rsb {
- status = "okay";
-
- axp805: pmic@745 {
+ axp805: pmic@36 {
compatible = "x-powers,axp805", "x-powers,axp806";
- reg = <0x745>;
+ reg = <0x36>;
interrupt-parent = <&r_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
@@ -240,6 +232,14 @@
};
};
+&r_ir {
+ status = "okay";
+};
+
+&r_pio {
+ vcc-pm-supply = <&reg_bldo3>;
+};
+
&rtc {
clocks = <&ext_osc32k>;
};
--
2.48.1

View File

@ -1,41 +0,0 @@
From 8674b92c48a528ec82a548bb677d0231316f5aa4 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 22 Jan 2023 14:29:17 -0600
Subject: [PATCH 01/13] sunxi: spl: Disable padding from SPL_PAD_TO
Starting with H6, Allwinner removed the artificial 32 KiB SPL size limit
from the boot ROM. Now SPL size is only limited by the available SRAM.
This limit ranges from 152 KiB on H6 to a whopping 2052 KiB on R329. To
take advantage of this additional space, we must increase SPL_MAX_SIZE.
Since we do not want to unnecessarily pad SPL out to these giant sizes,
we must set SPL_PAD_TO to zero. This causes no problems because binman
already takes care of appending the SPL payload at the right offset.
Commit-changes: 2
- New patch for v2
Cover-changes: 2
- Disable padding from SPL_PAD_TO
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
common/spl/Kconfig | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 25cd18afda..a0968ff106 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -97,8 +97,7 @@ config SPL_PAD_TO
default 0x31000 if ARCH_MX6 && MX6_OCRAM_256KB
default 0x11000 if ARCH_MX7 || (ARCH_MX6 && !MX6_OCRAM_256KB)
default 0x10000 if ARCH_KEYSTONE
- default 0x8000 if ARCH_SUNXI && !MACH_SUN50I_H616
- default 0x0 if ARCH_MTMIPS
+ default 0x0 if ARCH_MTMIPS || ARCH_SUNXI
default TPL_MAX_SIZE if TPL_MAX_SIZE > SPL_MAX_SIZE
default SPL_MAX_SIZE
help
--
2.34.1

View File

@ -1,112 +0,0 @@
From fa31297e5f79d6eb97aed3cf94326124b308e337 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 22 Jan 2023 11:46:34 -0600
Subject: [PATCH 02/13] sunxi: binman: Move BL31 and SCP firmware addresses to
Kconfig
This is easier to read than the #ifdef staircase, provides better
visibility into the memory map (alongside the other Kconfig
definitions), and allows these addresses to be reused from code.
Commit-changes: 2
- New patch for v2, split from the .dtsi changes
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/dts/sunxi-u-boot.dtsi | 24 +++++++-----------------
arch/arm/mach-sunxi/Kconfig | 17 +++++++++++++++++
2 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi
index a0c8abb703..7a8764e463 100644
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -1,15 +1,5 @@
#include <config.h>
-#ifdef CONFIG_MACH_SUN50I_H6
-#define BL31_ADDR 0x104000
-#define SCP_ADDR 0x114000
-#elif defined(CONFIG_MACH_SUN50I_H616)
-#define BL31_ADDR 0x40000000
-#else
-#define BL31_ADDR 0x44000
-#define SCP_ADDR 0x50000
-#endif
-
/ {
aliases {
mmc0 = &mmc0;
@@ -69,8 +59,8 @@
os = "arm-trusted-firmware";
arch = "arm64";
compression = "none";
- load = <BL31_ADDR>;
- entry = <BL31_ADDR>;
+ load = <CONFIG_SUNXI_BL31_BASE>;
+ entry = <CONFIG_SUNXI_BL31_BASE>;
atf-bl31 {
filename = "bl31.bin";
@@ -78,13 +68,13 @@
};
};
-#ifdef SCP_ADDR
+#if CONFIG_SUNXI_SCP_BASE
scp {
description = "SCP firmware";
type = "firmware";
arch = "or1k";
compression = "none";
- load = <SCP_ADDR>;
+ load = <CONFIG_SUNXI_SCP_BASE>;
scp {
filename = "scp.bin";
@@ -106,10 +96,10 @@
@config-SEQ {
description = "NAME";
firmware = "atf";
-#ifndef SCP_ADDR
- loadables = "uboot";
-#else
+#if CONFIG_SUNXI_SCP_BASE
loadables = "scp", "uboot";
+#else
+ loadables = "uboot";
#endif
fdt = "fdt-SEQ";
};
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index a10e4c06b6..b0fbda0aa0 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -155,6 +155,23 @@ config SUNXI_RVBAR_ALTERNATIVE
for all other SoCs, so the content of the SRAM_VER_REG becomes
irrelevant there, and we can use the same code.
+config SUNXI_BL31_BASE
+ hex
+ default 0x00044000 if MACH_SUN50I || MACH_SUN50I_H5
+ default 0x00104000 if MACH_SUN50I_H6
+ default 0x40000000 if MACH_SUN50I_H616
+ default 0x0
+ help
+ Address where BL31 (TF-A) is loaded, or zero if BL31 is not used.
+
+config SUNXI_SCP_BASE
+ hex
+ default 0x00050000 if MACH_SUN50I || MACH_SUN50I_H5
+ default 0x00114000 if MACH_SUN50I_H6
+ default 0x0
+ help
+ Address where SCP firmware is loaded, or zero if it is not used.
+
config SUNXI_A64_TIMER_ERRATUM
bool
--
2.34.1

View File

@ -1,99 +0,0 @@
From 50ec5566a9eb50288c7aca9d85182e152aaf47d9 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Sun, 22 Jan 2023 11:57:42 -0600
Subject: [PATCH 03/13] sunxi: binman: Support FIT generation for 32-bit SoCs
Some 32-bit SoCs can use SCP firmware to implement additional PSCI
functionality, such as system suspend. In order to load this firmware
from SPL, we need to generate and use a FIT instead of a legacy image.
Adjust the binman FIT definition so it does not rely on TF-A BL31, as
this is not used on 32-bit SoCs. Instead, after loading the firmware,
U-Boot proper is executed directly.
Series-changes: 2
- Rely on binman min-size instead of using explicit offsets
- Use Kconfig for firmware addresses instead of an #ifdef staircase
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm/dts/sunxi-u-boot.dtsi | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi
index 7a8764e463..ed1cb91eeb 100644
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -1,5 +1,11 @@
#include <config.h>
+#ifdef CONFIG_ARM64
+#define ARCH "arm64"
+#else
+#define ARCH "arm"
+#endif
+
/ {
aliases {
mmc0 = &mmc0;
@@ -34,30 +40,32 @@
filename = "spl/sunxi-spl.bin";
};
-#ifdef CONFIG_ARM64
+#ifdef CONFIG_SPL_LOAD_FIT
fit {
- description = "Configuration to load ATF before U-Boot";
+ description = "Configuration to load U-Boot and firmware";
#address-cells = <1>;
fit,fdt-list = "of-list";
images {
uboot {
- description = "U-Boot (64-bit)";
+ description = "U-Boot";
type = "standalone";
os = "u-boot";
- arch = "arm64";
+ arch = ARCH;
compression = "none";
load = <CONFIG_TEXT_BASE>;
+ entry = <CONFIG_TEXT_BASE>;
u-boot-nodtb {
};
};
+#if CONFIG_SUNXI_BL31_BASE
atf {
description = "ARM Trusted Firmware";
type = "firmware";
os = "arm-trusted-firmware";
- arch = "arm64";
+ arch = ARCH;
compression = "none";
load = <CONFIG_SUNXI_BL31_BASE>;
entry = <CONFIG_SUNXI_BL31_BASE>;
@@ -67,6 +75,7 @@
missing-msg = "atf-bl31-sunxi";
};
};
+#endif
#if CONFIG_SUNXI_SCP_BASE
scp {
@@ -95,7 +104,11 @@
@config-SEQ {
description = "NAME";
+#if CONFIG_SUNXI_BL31_BASE
firmware = "atf";
+#else
+ firmware = "uboot";
+#endif
#if CONFIG_SUNXI_SCP_BASE
loadables = "scp", "uboot";
#else
--
2.34.1

View File

@ -58,20 +58,6 @@ index d812685c98..42781d02f0 100644
imply SPL_MMC if MMC
imply SPL_POWER
imply SPL_SERIAL
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index a0968ff106..aebbfbf99d 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -567,8 +567,7 @@ config SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION
config SPL_FIT_IMAGE_TINY
bool "Remove functionality from SPL FIT loading to reduce size"
depends on SPL_FIT
- default y if MACH_SUN50I || MACH_SUN50I_H5 || SUN50I_GEN_H6
- default y if ARCH_IMX8M || ARCH_IMX9
+ default y if ARCH_IMX8M || ARCH_IMX9 || ARCH_SUNXI
help
Enable this to reduce the size of the FIT image loading code
in SPL, if space for the SPL binary is very tight.
--
2.34.1

View File

@ -1,46 +0,0 @@
From: Gunjan Gupta <viraniac@gmail.com>
Subject: [PATCH 1/1] sunxi: dram: Fix incorrect ram size detection for some H6
boards
Date: Sun, 1 Oct 2023 21:43:32 +0530
On some H6 boards like Orange Pi 3 LTS, some times U-Boot fails to detect
ram size correctly. Instead of 2GB thats available, it detects 4GB of ram
and then SPL just hangs there making board not to boot further.
On debugging, I found that the rows value were being determined correctly,
but columns were sometimes off by one value. I found that adding some
delay after the mctl_core_init call along with making use of dsb in the
start of the mctl_mem_matches solves the issue.
Signed-off-by: Gunjan Gupta <viraniac@gmail.com>
---
arch/arm/mach-sunxi/dram_helpers.c | 1 +
arch/arm/mach-sunxi/dram_sun50i_h6.c | 2 ++
2 files changed, 3 insertions(+)
diff --git a/arch/arm/mach-sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c
index cdf2750f1c..5758c58e07 100644
--- a/arch/arm/mach-sunxi/dram_helpers.c
+++ b/arch/arm/mach-sunxi/dram_helpers.c
@@ -32,6 +32,7 @@ void mctl_await_completion(u32 *reg, u32 mask, u32 val)
#ifndef CONFIG_MACH_SUNIV
bool mctl_mem_matches(u32 offset)
{
+ dsb();
/* Try to write different values to RAM at two addresses */
writel(0, CFG_SYS_SDRAM_BASE);
writel(0xaa55aa55, (ulong)CFG_SYS_SDRAM_BASE + offset);
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h6.c b/arch/arm/mach-sunxi/dram_sun50i_h6.c
index bff2e42513..a031a845f5 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h6.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h6.c
@@ -623,6 +623,8 @@ static void mctl_auto_detect_dram_size(struct dram_para *para)
para->cols = 11;
mctl_core_init(para);
+ udelay(50);
+
for (para->cols = 8; para->cols < 11; para->cols++) {
/* 8 bits per byte and 16/32 bit width */
if (mctl_mem_matches(1 << (para->cols + 1 +

View File

@ -0,0 +1,132 @@
From dacaffdf195c924b33c6ad0a7f93de18dfed92b4 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@gmail.com>
Date: Sat, 15 Mar 2025 19:52:31 +0100
Subject: [PATCH] sunxi: h6: Fix DRAM size detection
This is based on submitted patches for newer SoCs. It needs to be
properly reworked once they are merged.
Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com>
---
arch/arm/mach-sunxi/dram_sun50i_h6.c | 97 ++++++++++++++++++++++------
1 file changed, 79 insertions(+), 18 deletions(-)
diff --git a/arch/arm/mach-sunxi/dram_sun50i_h6.c b/arch/arm/mach-sunxi/dram_sun50i_h6.c
index e7862bd06ea3..f5ee64cfead4 100644
--- a/arch/arm/mach-sunxi/dram_sun50i_h6.c
+++ b/arch/arm/mach-sunxi/dram_sun50i_h6.c
@@ -601,32 +601,93 @@ static void mctl_auto_detect_rank_width(struct dram_para *para)
panic("This DRAM setup is currently not supported.\n");
}
+static void mctl_write_pattern(void)
+{
+ unsigned int i;
+ u32 *ptr, val;
+
+ ptr = (u32*)CFG_SYS_SDRAM_BASE;
+ for (i = 0; i < 16; ptr++, i++) {
+ if (i & 1)
+ val = ~(ulong)ptr;
+ else
+ val = (ulong)ptr;
+ writel(val, ptr);
+ }
+}
+
+static bool mctl_check_pattern(ulong offset)
+{
+ unsigned int i;
+ u32 *ptr, val;
+
+ ptr = (u32*)CFG_SYS_SDRAM_BASE;
+ for (i = 0; i < 16; ptr++, i++) {
+ if (i & 1)
+ val = ~(ulong)ptr;
+ else
+ val = (ulong)ptr;
+ if (val != *(ptr + offset / 4))
+ return false;
+ }
+
+ return true;
+}
+
static void mctl_auto_detect_dram_size(struct dram_para *para)
{
- /* TODO: non-(LP)DDR3 */
+ unsigned int shift, cols, rows;
+ u32 buffer[16];
- /* detect row address bits */
- para->cols = 8;
- para->rows = 18;
- mctl_core_init(para);
-
- for (para->rows = 13; para->rows < 18; para->rows++) {
- /* 8 banks, 8 bit per byte and 16/32 bit width */
- if (mctl_mem_matches((1 << (para->rows + para->cols +
- 4 + para->bus_full_width))))
- break;
- }
-
- /* detect column address bits */
+ /* max. config for columns, but not rows */
para->cols = 11;
+ para->rows = 13;
mctl_core_init(para);
- for (para->cols = 8; para->cols < 11; para->cols++) {
- /* 8 bits per byte and 16/32 bit width */
- if (mctl_mem_matches(1 << (para->cols + 1 +
- para->bus_full_width)))
+ /*
+ * Store content so it can be restored later. This is important
+ * if controller was already initialized and holds any data
+ * which is important for restoring system.
+ */
+ memcpy(buffer, (u32*)CFG_SYS_SDRAM_BASE, sizeof(buffer));
+
+ mctl_write_pattern();
+
+ shift = para->bus_full_width + 1;
+
+ /* detect column address bits */
+ for (cols = 8; cols < 11; cols++) {
+ if (mctl_check_pattern(1ULL << (cols + shift)))
break;
}
+ debug("detected %u columns\n", cols);
+
+ /* restore data */
+ memcpy((u32*)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer));
+
+ /* reconfigure to make sure that all active rows are accessible */
+ para->cols = 8;
+ para->rows = 17;
+ mctl_core_init(para);
+
+ /* store data again as it might be moved */
+ memcpy(buffer, (u32*)CFG_SYS_SDRAM_BASE, sizeof(buffer));
+
+ mctl_write_pattern();
+
+ /* detect row address bits */
+ shift = para->bus_full_width + 4 + para->cols;
+ for (rows = 13; rows < 17; rows++) {
+ if (mctl_check_pattern(1ULL << (rows + shift)))
+ break;
+ }
+ debug("detected %u rows\n", rows);
+
+ /* restore data again */
+ memcpy((u32*)CFG_SYS_SDRAM_BASE, buffer, sizeof(buffer));
+
+ para->cols = cols;
+ para->rows = rows;
}
unsigned long mctl_calc_size(struct dram_para *para)
--
2.48.1