On Sun, 16 Nov 2025 14:43:56 +0000 Yixun Lan <[email protected]> wrote:
Hi, > Add clock initialization support to set UART/I2C/MMC clock frequency. > > Signed-off-by: Yixun Lan <[email protected]> > > --- > 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 This new file looks like mostly a copy of clock_sun50i_h6.h. Can you please merge both, and define differently just the very few register offsets that actually differ? This includes clock_sun50i_h6.c and clock_sun60i_a733.c. Cheers, Andre > @@ -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; > +} >

