[PATCH master 3/5] ARM: i.MX8M: feed A53 cores from ARM PLL via CORE_SEL_CFG in early clock init

Ahmad Fatoum a.fatoum at pengutronix.de
Fri Oct 2 04:35:48 PDT 2026


barebox runs the Cortex-A53 cores off the ARM PLL through the A53 root
slice, as the ROM does, but at 1.2GHz instead of the ROM's 1GHz.

The i.MX8MM, i.MX8MN and i.MX8MP reference manuals all list 1000MHz as
the maximum for ARM_A53_CLK_ROOT in Table 5-1, so the slice runs out of
spec until barebox proper applies the upstream device tree's
assigned-clock-parents: A53_SRC to sys_pll1_800m first, dropping the
cores to 800MHz, then A53_CORE to arm_pll_out.

U-Boot's clock_init() instead writes the A53 root slice in full, i.e.
sys_pll2_500m with all dividers cleared, and switches CORE_SEL_CFG to
arm_pll_out, so the cores are fed from the PLL directly and the slice
is left unused. U-Boot commit 46a8a28bf60b ("imx8m: configure arm clk
sources from PLL") introduced this for the same 1GHz reason. Let's do
the same: barebox proper's reparenting then only touches the unused
slice and the cores stay at 1.2GHz throughout.

CORE_SEL_CFG is target root 49 with only a mux bit, so it is written
without ENABLE, like U-Boot does.

Assisted-by: Claude:fable-5.1
Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 arch/arm/mach-imx/imx8m.c         | 21 ++++++---------------
 include/mach/imx/imx8m-ccm-regs.h |  1 +
 2 files changed, 7 insertions(+), 15 deletions(-)

diff --git a/arch/arm/mach-imx/imx8m.c b/arch/arm/mach-imx/imx8m.c
index 533e2877237f..66a3b376ed94 100644
--- a/arch/arm/mach-imx/imx8m.c
+++ b/arch/arm/mach-imx/imx8m.c
@@ -10,7 +10,6 @@
 #include <mach/imx/imx8m-ccm-regs.h>
 #include <soc/imx8m/clk-early.h>
 
-#include <linux/bitfield.h>
 #include <linux/iopoll.h>
 
 #define IMX_SIP_BUILDINFO			0xC2000003
@@ -49,8 +48,6 @@ void imx8m_ccgr_clock_disable(int index)
 #define INTPLL_DIV2_CLKE_MASK                   BIT(13)
 #define INTPLL_CLKE_MASK                        BIT(11)
 
-#define CCM_TARGET_ROOT0_DIV  GENMASK(1, 0)
-
 #define IMX8MM_CCM_ANALOG_ARM_PLL_GEN_CTRL	0x84
 #define IMX8MM_CCM_ANALOG_SYS_PLL1_GEN_CTRL	0x94
 #define IMX8MM_CCM_ANALOG_SYS_PLL2_GEN_CTRL	0x104
@@ -60,7 +57,6 @@ static void __imx8m_early_clock_init(int cpu_type)
 {
 	unsigned long pll3_freq;
 	void __iomem *ana = IOMEM(MX8M_ANATOP_BASE_ADDR);
-	void __iomem *ccm = IOMEM(MX8M_CCM_BASE_ADDR);
 	u32 val;
 
 	imx8m_ccgr_clock_disable(IMX8M_CCM_CCGR_DDR1);
@@ -131,22 +127,17 @@ static void __imx8m_early_clock_init(int cpu_type)
 					   IMX8M_CCM_TARGET_ROOTn_MUX(2));
 	}
 
-	clrsetbits_le32(ccm + IMX8M_CCM_TARGET_ROOTn(IMX8M_ARM_A53_CLK_ROOT),
-			IMX8M_CCM_TARGET_ROOTn_MUX(7),
-			IMX8M_CCM_TARGET_ROOTn_MUX(2));
+	imx8m_clock_set_target_val(IMX8M_ARM_A53_CLK_ROOT,
+				   IMX8M_CCM_TARGET_ROOTn_ENABLE |
+				   IMX8M_CCM_TARGET_ROOTn_MUX(2));
 
 	/* Configure ARM PLL to 1.2GHz */
 	clk_pll1416x_early_configure(ana + IMX8MM_CCM_ANALOG_ARM_PLL_GEN_CTRL,
 				     1200000000UL, 25000000UL);
 
-	clrsetbits_le32(ccm + IMX8M_CCM_TARGET_ROOTn(IMX8M_ARM_A53_CLK_ROOT),
-			IMX8M_CCM_TARGET_ROOTn_MUX(7),
-			IMX8M_CCM_TARGET_ROOTn_MUX(1));
-
-	/* Configure DIV to 1.2GHz */
-	clrsetbits_le32(ccm + IMX8M_CCM_TARGET_ROOTn(IMX8M_ARM_A53_CLK_ROOT),
-			CCM_TARGET_ROOT0_DIV,
-			FIELD_PREP(CCM_TARGET_ROOT0_DIV, 0));
+	/* Bypass the A53 root and feed the cores from arm_pll_out directly */
+	imx8m_clock_set_target_val(IMX8M_CORE_SEL_CFG,
+				   IMX8M_CCM_TARGET_ROOTn_MUX(1));
 }
 
 void imx8mm_early_clock_init(void)
diff --git a/include/mach/imx/imx8m-ccm-regs.h b/include/mach/imx/imx8m-ccm-regs.h
index 42d0c485f25b..bcd8b85f9f3e 100644
--- a/include/mach/imx/imx8m-ccm-regs.h
+++ b/include/mach/imx/imx8m-ccm-regs.h
@@ -25,6 +25,7 @@
 #define IMX8M_NOC_CLK_ROOT		26
 #define IMX8M_NOC_IO_CLK_ROOT           27
 #define IMX8M_DRAM_SEL_CFG		48
+#define IMX8M_CORE_SEL_CFG		49
 #define IMX8M_DRAM_ALT_CLK_ROOT		64
 #define IMX8M_DRAM_APB_CLK_ROOT		65
 #define IMX8M_UART1_CLK_ROOT		94
-- 
2.47.3




More information about the barebox mailing list