[PATCH 05/11] clock: a733: implement support for mmc/uart
Yixun Lan
dlan at gentoo.org
Sun Nov 16 15:43:56 CET 2025
Add clock initialization support to set UART/I2C/MMC clock frequency.
Signed-off-by: Yixun Lan <dlan at gentoo.org>
---
In this version, we create a dedicated clock_sun60i_a733.h file, maybe
we should further refactor the code to make it merged into exist
clock_sun50i_h6.h file.
---
arch/arm/include/asm/arch-sunxi/clock.h | 2 +
.../arm/include/asm/arch-sunxi/clock_sun60i_a733.h | 179 +++++++++++++++++++++
arch/arm/include/asm/arch-sunxi/cpu.h | 2 +
arch/arm/mach-sunxi/Makefile | 1 +
arch/arm/mach-sunxi/clock_sun60i_a733.c | 80 +++++++++
5 files changed, 264 insertions(+)
diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h
index fcc8966cb0b..105c3804102 100644
--- a/arch/arm/include/asm/arch-sunxi/clock.h
+++ b/arch/arm/include/asm/arch-sunxi/clock.h
@@ -19,6 +19,8 @@
#include <asm/arch/clock_sun8i_a83t.h>
#elif defined(CONFIG_SUN50I_GEN_H6) || defined(CONFIG_SUNXI_GEN_NCAT2)
#include <asm/arch/clock_sun50i_h6.h>
+#elif defined(CONFIG_MACH_SUN60I_A733)
+#include <asm/arch/clock_sun60i_a733.h>
#elif defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) || \
defined(CONFIG_MACH_SUN50I) || defined(CONFIG_MACH_SUNIV)
#include <asm/arch/clock_sun6i.h>
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun60i_a733.h b/arch/arm/include/asm/arch-sunxi/clock_sun60i_a733.h
new file mode 100644
index 00000000000..819a5c6cf8d
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun60i_a733.h
@@ -0,0 +1,179 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Allwinner A733 clock register definitions
+ */
+
+#ifndef _SUNXI_CLOCK_SUN60I_A733_H
+#define _SUNXI_CLOCK_SUN60I_A733_H
+
+#ifndef __ASSEMBLY__
+#include <linux/bitops.h>
+#endif
+
+/* Main CCU register offsets */
+#define CCU_H6_PLL1_CFG 0x000
+#define CCU_H6_PLL5_CFG 0x010
+#define CCU_H6_PLL6_CFG 0x0a0 /* PLL_PERI0_CTRL_REG */
+
+#define CCU_H6_CPU_AXI_CFG 0x500
+#define CCU_H6_PSI_AHB1_AHB2_CFG 0x510
+#define CCU_H6_AHB3_CFG 0x51c
+#define CCU_H6_APB1_CFG 0x520
+#define CCU_H6_APB2_CFG 0x524
+#define CCU_H6_MBUS_CFG 0x540
+#define CCU_H6_DRAM_CLK_CFG 0x800
+#define CCU_H6_DRAM_GATE_RESET 0x80c
+#define CCU_MMC0_CLK_CFG 0x830
+#define CCU_MMC1_CLK_CFG 0x834
+#define CCU_MMC2_CLK_CFG 0x838
+#define CCU_H6_MMC_GATE_RESET 0x84c
+#define CCU_H6_UART_GATE_RESET 0x90c
+#define CCU_H6_I2C_GATE_RESET 0x91c
+
+/* A523 CPU PLL offsets */
+#define CPC_CPUA_PLL_CTRL 0x04
+#define CPC_DSU_PLL_CTRL 0x08
+#define CPC_CPUB_PLL_CTRL 0x0c
+#define CPC_CPUA_CLK_REG 0x60
+#define CPC_CPUB_CLK_REG 0x64
+#define CPC_DSU_CLK_REG 0x6c
+
+/* A733 MISC offsets */
+#define CCU_A733_APB0_CFG 0x510
+#define CCU_A733_APB1_CFG 0x518
+#define CCU_A733_APB_UART_CLK_CFG 0x538
+#define CCU_A733_UART_GATE_RESET 0xe00
+
+/* PLL bit fields */
+#define CCM_PLL_CTRL_EN BIT(31)
+#define CCM_PLL_LDO_EN BIT(30)
+#define CCM_PLL_LOCK_EN BIT(29)
+#define CCM_PLL_LOCK BIT(28)
+#define CCM_PLL_OUT_EN BIT(27)
+#define CCM_PLL1_UPDATE BIT(26)
+#define CCM_PLL1_CTRL_P(p) ((p) << 16)
+#define CCM_PLL1_CTRL_N_MASK GENMASK(15, 8)
+#define CCM_PLL1_CTRL_N(n) (((n) - 1) << 8)
+
+/* A523 CPU clock fields */
+#define CPU_CLK_SRC_HOSC (0 << 24)
+#define CPU_CLK_SRC_CPUPLL (3 << 24)
+#define CPU_CLK_CTRL_P(p) ((p) << 16)
+#define CPU_CLK_APB_DIV(n) (((n) - 1) << 8)
+#define CPU_CLK_PERI_DIV(m1) (((m1) - 1) << 2)
+#define CPU_CLK_AXI_DIV(m) (((m) - 1) << 0)
+
+/* pll5 bit field */
+#define CCM_PLL5_CTRL_N(n) (((n) - 1) << 8)
+#define CCM_PLL5_CTRL_DIV1(div1) ((div1) << 0)
+#define CCM_PLL5_CTRL_DIV2(div0) ((div0) << 1)
+
+/* pll6 bit field */
+#define CCM_PLL6_CTRL_P0_SHIFT 20
+#define CCM_PLL6_CTRL_P0_MASK (0x7 << CCM_PLL6_CTRL_P0_SHIFT)
+#define CCM_PLL6_CTRL_N_SHIFT 8
+#define CCM_PLL6_CTRL_N_MASK (0xff << CCM_PLL6_CTRL_N_SHIFT)
+#define CCM_PLL6_CTRL_DIV1_SHIFT 0
+#define CCM_PLL6_CTRL_DIV1_MASK (0x1 << CCM_PLL6_CTRL_DIV1_SHIFT)
+#define CCM_PLL6_CTRL_DIV2_SHIFT 1
+#define CCM_PLL6_CTRL_DIV2_MASK (0x1 << CCM_PLL6_CTRL_DIV2_SHIFT)
+
+/* cpu_axi bit field*/
+#define CCM_CPU_AXI_MUX_MASK (0x3 << 24)
+#define CCM_CPU_AXI_MUX_OSC24M (0x0 << 24)
+#define CCM_CPU_AXI_MUX_PLL_CPUX (0x3 << 24)
+#define CCM_CPU_AXI_APB_MASK 0x300
+#define CCM_CPU_AXI_AXI_MASK 0x3
+#define CCM_CPU_AXI_DEFAULT_FACTORS 0x301
+
+#ifdef CONFIG_MACH_SUN50I_H6 /* H6 */
+
+#define CCM_PLL6_DEFAULT 0xa0006300
+#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000102
+#define CCM_AHB3_DEFAULT 0x03000002
+#define CCM_APB1_DEFAULT 0x03000102
+
+#elif CONFIG_MACH_SUN50I_H616 /* H616 */
+
+#define CCM_PLL6_DEFAULT 0xa8003100
+#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002
+#define CCM_AHB3_DEFAULT 0x03000002
+#define CCM_APB1_DEFAULT 0x03000102
+
+#elif CONFIG_MACH_SUN8I_R528 /* R528 */
+
+#define CCM_PLL6_DEFAULT 0xe8216300
+#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002
+#define CCM_APB1_DEFAULT 0x03000102
+
+#elif CONFIG_MACH_SUN55I_A523 /* A523 */
+
+#define CCM_PLL6_DEFAULT 0xe8116310 /* 1200 MHz */
+#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002 /* 200 MHz */
+#define CCM_APB1_DEFAULT 0x03000005 /* APB0 really */
+#define CCM_APB2_DEFAULT 0x03000005 /* APB1 really */
+
+#elif CONFIG_MACH_SUN60I_A733 /* A733 */
+
+#define CCM_PLL6_DEFAULT 0xe8116310 /* 1200 MHz */
+#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002 /* 200 MHz */
+#define CCM_APB1_DEFAULT 0x03000005 /* APB0 really */
+#define CCM_APB2_DEFAULT 0x03000005 /* APB1 really */
+
+#endif
+
+/* apb2 bit field */
+#define APB2_CLK_SRC_OSC24M (0x0 << 24)
+#define APB2_CLK_SRC_OSC32K (0x1 << 24)
+#define APB2_CLK_SRC_PSI (0x2 << 24)
+#define APB2_CLK_SRC_PLL6 (0x3 << 24)
+#define APB2_CLK_SRC_MASK (0x3 << 24)
+#define APB2_CLK_RATE_N_1 (0x0 << 8)
+#define APB2_CLK_RATE_N_2 (0x1 << 8)
+#define APB2_CLK_RATE_N_4 (0x2 << 8)
+#define APB2_CLK_RATE_N_8 (0x3 << 8)
+#define APB2_CLK_RATE_N_MASK (3 << 8)
+#define APB2_CLK_RATE_M(m) (((m) - 1) << 0)
+#define APB2_CLK_RATE_M_MASK (3 << 0)
+
+/* MBUS clock bit field */
+#define MBUS_ENABLE BIT(31)
+#define MBUS_RESET BIT(30)
+#define MBUS_UPDATE BIT(27)
+#define MBUS_CLK_SRC_MASK GENMASK(25, 24)
+#define MBUS_CLK_SRC_OSCM24 (0 << 24)
+#define MBUS_CLK_SRC_PLL6X2 (1 << 24)
+#define MBUS_CLK_SRC_PLL5 (2 << 24)
+#define MBUS_CLK_SRC_PLL6X4 (3 << 24)
+#define MBUS_CLK_M(m) (((m) - 1) << 0)
+
+/* Module gate/reset shift*/
+#define RESET_SHIFT (16)
+#define GATE_SHIFT (0)
+
+/* DRAM clock bit field */
+#define DRAM_CLK_ENABLE BIT(31)
+#define DRAM_MOD_RESET BIT(30)
+#define DRAM_CLK_UPDATE BIT(27)
+#define DRAM_CLK_SRC_MASK GENMASK(25, 24)
+#define DRAM_CLK_SRC_PLL5 (0 << 24)
+#define DRAM_CLK_M_MASK (0x1f)
+#define DRAM_CLK_M(m) (((m) - 1) << 0)
+
+/* MMC clock bit field */
+#define CCM_MMC_CTRL_M(x) ((x) - 1)
+#define CCM_MMC_CTRL_N(x) ((x) << 8)
+#define CCM_MMC_CTRL_OSCM24 (0x0 << 24)
+#define CCM_MMC_CTRL_PLL6 (0x1 << 24)
+#define CCM_MMC_CTRL_PLL_PERIPH2X2 (0x2 << 24)
+#define CCM_MMC_CTRL_ENABLE (0x1 << 31)
+/* H6 doesn't have these delays */
+#define CCM_MMC_CTRL_OCLK_DLY(a) ((void)(a), 0)
+#define CCM_MMC_CTRL_SCLK_DLY(a) ((void)(a), 0)
+
+#ifndef __ASSEMBLY__
+void clock_set_pll1(unsigned int hz);
+unsigned int clock_get_pll6(void);
+#endif
+
+#endif /* _SUNXI_CLOCK_SUN60I_A733_H */
diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h
index 768c6572d6b..3fd247e75a7 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu.h
@@ -12,6 +12,8 @@
#include <asm/arch/cpu_sun50i_h6.h>
#elif defined(CONFIG_SUNXI_GEN_NCAT2)
#include <asm/arch/cpu_sunxi_ncat2.h>
+#elif defined(CONFIG_MACH_SUN60I_A733)
+#include <asm/arch/cpu_sunxi_a733.h>
#else
#include <asm/arch/cpu_sun4i.h>
#endif
diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile
index 9c79b55abf3..8e37e3315ca 100644
--- a/arch/arm/mach-sunxi/Makefile
+++ b/arch/arm/mach-sunxi/Makefile
@@ -25,6 +25,7 @@ endif
obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o gtbus_sun9i.o
obj-$(CONFIG_SUN50I_GEN_H6) += clock_sun50i_h6.o
obj-$(CONFIG_SUNXI_GEN_NCAT2) += clock_sun50i_h6.o
+obj-$(CONFIG_MACH_SUN60I_A733) += clock_sun60i_a733.o
ifndef CONFIG_ARM64
obj-y += timer.o
endif
diff --git a/arch/arm/mach-sunxi/clock_sun60i_a733.c b/arch/arm/mach-sunxi/clock_sun60i_a733.c
new file mode 100644
index 00000000000..9e07ccefc32
--- /dev/null
+++ b/arch/arm/mach-sunxi/clock_sun60i_a733.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/prcm.h>
+#include <linux/delay.h>
+
+#ifndef SUNXI_CPU_PLL_CFG_BASE
+#define SUNXI_CPU_PLL_CFG_BASE 0
+#endif
+
+#ifdef CONFIG_XPL_BUILD
+void clock_init_safe(void)
+{
+}
+
+void clock_init_uart(void)
+{
+ void *const ccm = (void *)SUNXI_CCM_BASE;
+
+ /* uart clock source is apb2 */
+ writel(APB2_CLK_SRC_OSC24M |
+ APB2_CLK_RATE_N_1 |
+ APB2_CLK_RATE_M(1),
+ ccm + CCU_A733_APB1_CFG);
+
+ /* uart clock source */
+ writel(APB2_CLK_SRC_OSC24M |
+ APB2_CLK_RATE_N_1 |
+ APB2_CLK_RATE_M(1),
+ ccm + CCU_A733_APB_UART_CLK_CFG);
+
+ /* open the clock for uart */
+ setbits_le32(ccm + CCU_A733_UART_GATE_RESET,
+ 1 << (CONFIG_CONS_INDEX - 1));
+
+ /* deassert uart reset */
+ setbits_le32(ccm + CCU_A733_UART_GATE_RESET,
+ 1 << (RESET_SHIFT + CONFIG_CONS_INDEX - 1));
+}
+
+void clock_set_pll1(unsigned int clk)
+{
+ /* Do not support clocks < 288MHz as they need factor P */
+ if (clk < 288000000)
+ clk = 288000000;
+
+ clk /= 24000000;
+}
+
+int clock_twi_onoff(int port, int state)
+{
+ return 0;
+}
+#endif /* CONFIG_XPL_BUILD */
+
+/* PLL_PERIPH0 clock, used by the MMC driver */
+unsigned int clock_get_pll6(void)
+{
+ void *const ccm = (void *)SUNXI_CCM_BASE;
+ u32 rval = readl(ccm + CCU_H6_PLL6_CFG);
+ int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT) + 1;
+ int div1, m;
+
+ if (IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2) || IS_ENABLED(CONFIG_MACH_SUN60I_A733)) {
+ div1 = ((rval & CCM_PLL6_CTRL_P0_MASK) >>
+ CCM_PLL6_CTRL_P0_SHIFT) + 1;
+ m = ((rval >> 1) & 1) + 1;
+ } else {
+ div1 = ((rval & CCM_PLL6_CTRL_DIV1_MASK) >>
+ CCM_PLL6_CTRL_DIV1_SHIFT) + 1;
+ if (IS_ENABLED(CONFIG_MACH_SUN50I_H6))
+ m = 4;
+ else
+ m = 2;
+ }
+
+ return 24000000U * n / m / div1;
+}
--
2.51.2
More information about the U-Boot
mailing list