Rather then having effectively 2 copies of a function through function in 2 separate C-files, this is much easier to read and maintain.
Signed-off-by: Hans de Goede <[email protected]> --- arch/arm/cpu/armv7/sunxi/Makefile | 4 + arch/arm/cpu/armv7/sunxi/clock-sun4i.c | 160 +++++++++++++++++++++++++++ arch/arm/cpu/armv7/sunxi/clock-sun6i.c | 73 +++++++++++++ arch/arm/cpu/armv7/sunxi/clock.c | 185 +------------------------------- arch/arm/include/asm/arch-sunxi/clock.h | 2 + 5 files changed, 240 insertions(+), 184 deletions(-) create mode 100644 arch/arm/cpu/armv7/sunxi/clock-sun4i.c create mode 100644 arch/arm/cpu/armv7/sunxi/clock-sun6i.c diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index e9737a3..48c0565 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -12,6 +12,10 @@ obj-y += board.o obj-y += clock.o obj-y += pinmux.o obj-y += watchdog.o +obj-$(CONFIG_SUN4I) += clock-sun4i.o +obj-$(CONFIG_SUN5I) += clock-sun4i.o +obj-$(CONFIG_SUN6I) += clock-sun6i.o +obj-$(CONFIG_SUN7I) += clock-sun4i.o ifdef DEBUG obj-y += early_print.o endif diff --git a/arch/arm/cpu/armv7/sunxi/clock-sun4i.c b/arch/arm/cpu/armv7/sunxi/clock-sun4i.c new file mode 100644 index 0000000..a6bdd1a --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/clock-sun4i.c @@ -0,0 +1,160 @@ +/* + * sun4i, sun5i and sun7i specific clock code + * + * (C) Copyright 2007-2012 + * Allwinner Technology Co., Ltd. <www.allwinnertech.com> + * Tom Cubie <[email protected]> + * + * (C) Copyright 2013 Luke Kenneth Casson Leighton <[email protected]> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/gpio.h> +#include <asm/arch/sys_proto.h> + +#ifdef CONFIG_SPL_BUILD +void clock_init_safe(void) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + /* Set safe defaults until PMU is configured */ + writel(AXI_DIV_1 << AXI_DIV_SHIFT | + AHB_DIV_2 << AHB_DIV_SHIFT | + APB0_DIV_1 << APB0_DIV_SHIFT | + CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, + &ccm->cpu_ahb_apb0_cfg); + writel(PLL1_CFG_DEFAULT, &ccm->pll1_cfg); + sdelay(200); + writel(AXI_DIV_1 << AXI_DIV_SHIFT | + AHB_DIV_2 << AHB_DIV_SHIFT | + APB0_DIV_1 << APB0_DIV_SHIFT | + CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT, + &ccm->cpu_ahb_apb0_cfg); +#ifdef CONFIG_SUN7I + writel(0x1 << AHB_GATE_OFFSET_DMA | readl(&ccm->ahb_gate0), + &ccm->ahb_gate0); +#endif + writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); +} +#endif + +void clock_init_uart(void) +{ + struct sunxi_ccm_reg *const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + /* uart clock source is apb1 */ + sr32(&ccm->apb1_clk_div_cfg, 24, 2, APB1_CLK_SRC_OSC24M); + sr32(&ccm->apb1_clk_div_cfg, 16, 2, APB1_FACTOR_N); + sr32(&ccm->apb1_clk_div_cfg, 0, 5, APB1_FACTOR_M); + + /* open the clock for uart */ + sr32(&ccm->apb1_gate, 16 + CONFIG_CONS_INDEX - 1, 1, CLK_GATE_OPEN); +} + +int clock_twi_onoff(int port, int state) +{ + struct sunxi_ccm_reg *const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + if (port > 2) + return -1; + + /* set the apb clock gate for twi */ + sr32(&ccm->apb1_gate, 0 + port, 1, state); + + return 0; +} + +#ifdef CONFIG_SPL_BUILD +#define PLL1_CFG(N, K, M, P) (1 << 31 | 0 << 30 | 8 << 26 | 0 << 25 | \ + 16 << 20 | (P) << 16 | 2 << 13 | (N) << 8 | \ + (K) << 4 | 0 << 3 | 0 << 2 | (M) << 0) + +struct { + u32 pll1_cfg; + unsigned int freq; +} pll1_para[] = { + { PLL1_CFG(16, 0, 0, 0), 384000000 }, + { PLL1_CFG(16, 1, 0, 0), 768000000 }, + { PLL1_CFG(20, 1, 0, 0), 960000000 }, + { PLL1_CFG(21, 1, 0, 0), 1008000000}, + { PLL1_CFG(22, 1, 0, 0), 1056000000}, + { PLL1_CFG(23, 1, 0, 0), 1104000000}, + { PLL1_CFG(24, 1, 0, 0), 1152000000}, + { PLL1_CFG(25, 1, 0, 0), 1200000000}, + { PLL1_CFG(26, 1, 0, 0), 1248000000}, + { PLL1_CFG(27, 1, 0, 0), 1296000000}, + { PLL1_CFG(28, 1, 0, 0), 1344000000}, + { PLL1_CFG(29, 1, 0, 0), 1392000000}, + { PLL1_CFG(30, 1, 0, 0), 1440000000}, + { PLL1_CFG(31, 1, 0, 0), 1488000000}, + { PLL1_CFG(31, 1, 0, 0), ~0}, +}; + +void clock_set_pll1(int hz) +{ + int i = 0; + int axi, ahb, apb0; + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + /* Find target frequency */ + while (pll1_para[i].freq < hz) + i++; + + hz = pll1_para[i].freq; + + /* Calculate system clock divisors */ + axi = DIV_ROUND_UP(hz, 432000000); /* Max 450MHz */ + ahb = DIV_ROUND_UP(hz/axi, 204000000); /* Max 250MHz */ + apb0 = 2; /* Max 150MHz */ + + printf("CPU: %dHz, AXI/AHB/APB: %d/%d/%d\n", hz, axi, ahb, apb0); + + /* Map divisors to register values */ + axi = axi - 1; + if (ahb > 4) + ahb = 3; + else if (ahb > 2) + ahb = 2; + else if (ahb > 1) + ahb = 1; + else + ahb = 0; + + apb0 = apb0 - 1; + + /* Switch to 24MHz clock while changing PLL1 */ + writel(AXI_DIV_1 << AXI_DIV_SHIFT | + AHB_DIV_2 << AHB_DIV_SHIFT | + APB0_DIV_1 << APB0_DIV_SHIFT | + CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, + &ccm->cpu_ahb_apb0_cfg); + sdelay(20); + + /* Configure sys clock divisors */ + writel(axi << AXI_DIV_SHIFT | + ahb << AHB_DIV_SHIFT | + apb0 << APB0_DIV_SHIFT | + CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, + &ccm->cpu_ahb_apb0_cfg); + + /* Configure PLL1 at the desired frequency */ + writel(pll1_para[i].pll1_cfg, &ccm->pll1_cfg); + sdelay(200); + + /* Switch CPU to PLL1 */ + writel(axi << AXI_DIV_SHIFT | + ahb << AHB_DIV_SHIFT | + apb0 << APB0_DIV_SHIFT | + CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT, + &ccm->cpu_ahb_apb0_cfg); + sdelay(20); +} +#endif diff --git a/arch/arm/cpu/armv7/sunxi/clock-sun6i.c b/arch/arm/cpu/armv7/sunxi/clock-sun6i.c new file mode 100644 index 0000000..e44a460 --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/clock-sun6i.c @@ -0,0 +1,73 @@ +/* + * sun6i specific clock code + * + * (C) Copyright 2007-2012 + * Allwinner Technology Co., Ltd. <www.allwinnertech.com> + * Tom Cubie <[email protected]> + * + * (C) Copyright 2013 Luke Kenneth Casson Leighton <[email protected]> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/gpio.h> +#include <asm/arch/sys_proto.h> + +#ifdef CONFIG_SPL_BUILD +void clock_init_safe(void) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + /* AXI and PLL1 settings from boot0 / boot1, PLL1 set to 486 Mhz */ + writel(AXI_DIV_3 << AXI_DIV_SHIFT | + ATB_DIV_2 << ATB_DIV_SHIFT | + CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, + &ccm->cpu_axi_cfg); + writel(PLL1_CFG_DEFAULT, &ccm->pll1_cfg); + sdelay(200); + writel(AXI_DIV_3 << AXI_DIV_SHIFT | + ATB_DIV_2 << ATB_DIV_SHIFT | + CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT, + &ccm->cpu_axi_cfg); + + writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); +} +#endif + +void clock_init_uart(void) +{ + struct sunxi_ccm_reg *const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + /* uart clock source is apb2 */ + sr32(&ccm->apb2_div, 24, 2, APB2_CLK_SRC_OSC24M); + sr32(&ccm->apb2_div, 16, 2, APB2_FACTOR_N); + sr32(&ccm->apb2_div, 0, 5, APB2_FACTOR_M); + + /* open the clock for uart */ + sr32(&ccm->apb2_gate, 16 + CONFIG_CONS_INDEX - 1, 1, CLK_GATE_OPEN); + + /* deassert uart reset */ + sr32((u32 *)SUN6I_ABP2_RESET_BASE, 16 + CONFIG_CONS_INDEX - 1, 1, 1); + + /* Dup with clock_init_safe(), drop once sun6i SPL support lands */ + writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); +} + +int clock_twi_onoff(int port, int state) +{ + struct sunxi_ccm_reg *const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + if (port > 3) + return -1; + + /* set the apb clock gate for twi */ + sr32(&ccm->apb2_gate, 0 + port, 1, state); + + return 0; +} diff --git a/arch/arm/cpu/armv7/sunxi/clock.c b/arch/arm/cpu/armv7/sunxi/clock.c index 05b8d27..c07a975 100644 --- a/arch/arm/cpu/armv7/sunxi/clock.c +++ b/arch/arm/cpu/armv7/sunxi/clock.c @@ -14,89 +14,12 @@ #include <asm/arch/gpio.h> #include <asm/arch/sys_proto.h> -#ifdef CONFIG_SPL_BUILD -static void clock_init_safe(void) -{ - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - - /* Set safe defaults until PMU is configured */ -#if defined(CONFIG_SUN6I) - /* AXI and PLL1 settings from boot0 / boot1, PLL1 set to 486 Mhz */ - writel(AXI_DIV_3 << AXI_DIV_SHIFT | - ATB_DIV_2 << ATB_DIV_SHIFT | - CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, - &ccm->cpu_axi_cfg); - writel(PLL1_CFG_DEFAULT, &ccm->pll1_cfg); - sdelay(200); - writel(AXI_DIV_3 << AXI_DIV_SHIFT | - ATB_DIV_2 << ATB_DIV_SHIFT | - CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT, - &ccm->cpu_axi_cfg); -#else - writel(AXI_DIV_1 << AXI_DIV_SHIFT | - AHB_DIV_2 << AHB_DIV_SHIFT | - APB0_DIV_1 << APB0_DIV_SHIFT | - CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, - &ccm->cpu_ahb_apb0_cfg); - writel(PLL1_CFG_DEFAULT, &ccm->pll1_cfg); - sdelay(200); - writel(AXI_DIV_1 << AXI_DIV_SHIFT | - AHB_DIV_2 << AHB_DIV_SHIFT | - APB0_DIV_1 << APB0_DIV_SHIFT | - CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT, - &ccm->cpu_ahb_apb0_cfg); -#endif -#ifdef CONFIG_SUN7I - writel(0x1 << AHB_GATE_OFFSET_DMA | readl(&ccm->ahb_gate0), - &ccm->ahb_gate0); -#endif - writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); -} -#endif - int clock_init(void) { - struct sunxi_ccm_reg *const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - #ifdef CONFIG_SPL_BUILD clock_init_safe(); #endif - -#if defined(CONFIG_SUN6I) - /* uart clock source is apb2 */ - sr32(&ccm->apb2_div, 24, 2, APB2_CLK_SRC_OSC24M); - sr32(&ccm->apb2_div, 16, 2, APB2_FACTOR_N); - sr32(&ccm->apb2_div, 0, 5, APB2_FACTOR_M); - - /* open the clock for uart */ - sr32(&ccm->apb2_gate, 16 + CONFIG_CONS_INDEX - 1, 1, CLK_GATE_OPEN); - - /* deassert uart reset */ - sr32((u32 *)SUN6I_ABP2_RESET_BASE, 16 + CONFIG_CONS_INDEX - 1, 1, 1); - - /* Dup with clock_init_safe(), drop once sun6i SPL support lands */ - writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); -#else - /* uart clock source is apb1 */ - sr32(&ccm->apb1_clk_div_cfg, 24, 2, APB1_CLK_SRC_OSC24M); - sr32(&ccm->apb1_clk_div_cfg, 16, 2, APB1_FACTOR_N); - sr32(&ccm->apb1_clk_div_cfg, 0, 5, APB1_FACTOR_M); - - /* open the clock for uart */ - sr32(&ccm->apb1_gate, 16 + CONFIG_CONS_INDEX - 1, 1, CLK_GATE_OPEN); -#endif - -#ifdef CONFIG_NAND_SUNXI - /* nand clock source is osc24m */ - sr32(&ccm->nand_sclk_cfg, 24, 2, NAND_CLK_SRC_OSC24); - sr32(&ccm->nand_sclk_cfg, 16, 2, NAND_CLK_DIV_N); - sr32(&ccm->nand_sclk_cfg, 0, 4, NAND_CLK_DIV_M); - sr32(&ccm->nand_sclk_cfg, 31, 1, CLK_GATE_OPEN); - /* open clock for nand */ - sr32(&ccm->ahb_gate0, AHB_GATE_OFFSET_NAND, 1, CLK_GATE_OPEN); -#endif + clock_init_uart(); return 0; } @@ -124,109 +47,3 @@ unsigned int clock_get_pll6(void) int k = ((rval >> 4) & 3) + 1; return 24000000 * n * k / 2; } - -int clock_twi_onoff(int port, int state) -{ - struct sunxi_ccm_reg *const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - - if (port > 2) - return -1; - - /* set the apb clock gate for twi */ -#if defined(CONFIG_SUN6I) - sr32(&ccm->apb2_gate, 0 + port, 1, state); -#else - sr32(&ccm->apb1_gate, 0 + port, 1, state); -#endif - - return 0; -} - -#if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SUN6I) -#define PLL1_CFG(N, K, M, P) (1 << 31 | 0 << 30 | 8 << 26 | 0 << 25 | \ - 16 << 20 | (P) << 16 | 2 << 13 | (N) << 8 | \ - (K) << 4 | 0 << 3 | 0 << 2 | (M) << 0) - -struct { - u32 pll1_cfg; - unsigned int freq; -} pll1_para[] = { - { PLL1_CFG(16, 0, 0, 0), 384000000 }, - { PLL1_CFG(16, 1, 0, 0), 768000000 }, - { PLL1_CFG(20, 1, 0, 0), 960000000 }, - { PLL1_CFG(21, 1, 0, 0), 1008000000}, - { PLL1_CFG(22, 1, 0, 0), 1056000000}, - { PLL1_CFG(23, 1, 0, 0), 1104000000}, - { PLL1_CFG(24, 1, 0, 0), 1152000000}, - { PLL1_CFG(25, 1, 0, 0), 1200000000}, - { PLL1_CFG(26, 1, 0, 0), 1248000000}, - { PLL1_CFG(27, 1, 0, 0), 1296000000}, - { PLL1_CFG(28, 1, 0, 0), 1344000000}, - { PLL1_CFG(29, 1, 0, 0), 1392000000}, - { PLL1_CFG(30, 1, 0, 0), 1440000000}, - { PLL1_CFG(31, 1, 0, 0), 1488000000}, - { PLL1_CFG(31, 1, 0, 0), ~0}, -}; - -void clock_set_pll1(int hz) -{ - int i = 0; - int axi, ahb, apb0; - struct sunxi_ccm_reg * const ccm = - (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - - /* Find target frequency */ - while (pll1_para[i].freq < hz) - i++; - - hz = pll1_para[i].freq; - - /* Calculate system clock divisors */ - axi = DIV_ROUND_UP(hz, 432000000); /* Max 450MHz */ - ahb = DIV_ROUND_UP(hz/axi, 204000000); /* Max 250MHz */ - apb0 = 2; /* Max 150MHz */ - - printf("CPU: %dHz, AXI/AHB/APB: %d/%d/%d\n", hz, axi, ahb, apb0); - - /* Map divisors to register values */ - axi = axi - 1; - if (ahb > 4) - ahb = 3; - else if (ahb > 2) - ahb = 2; - else if (ahb > 1) - ahb = 1; - else - ahb = 0; - - apb0 = apb0 - 1; - - /* Switch to 24MHz clock while changing PLL1 */ - writel(AXI_DIV_1 << AXI_DIV_SHIFT | - AHB_DIV_2 << AHB_DIV_SHIFT | - APB0_DIV_1 << APB0_DIV_SHIFT | - CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, - &ccm->cpu_ahb_apb0_cfg); - sdelay(20); - - /* Configure sys clock divisors */ - writel(axi << AXI_DIV_SHIFT | - ahb << AHB_DIV_SHIFT | - apb0 << APB0_DIV_SHIFT | - CPU_CLK_SRC_OSC24M << CPU_CLK_SRC_SHIFT, - &ccm->cpu_ahb_apb0_cfg); - - /* Configure PLL1 at the desired frequency */ - writel(pll1_para[i].pll1_cfg, &ccm->pll1_cfg); - sdelay(200); - - /* Switch CPU to PLL1 */ - writel(axi << AXI_DIV_SHIFT | - ahb << AHB_DIV_SHIFT | - apb0 << APB0_DIV_SHIFT | - CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT, - &ccm->cpu_ahb_apb0_cfg); - sdelay(20); -} -#endif diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h index bfcc525..94fcaaa 100644 --- a/arch/arm/include/asm/arch-sunxi/clock.h +++ b/arch/arm/include/asm/arch-sunxi/clock.h @@ -27,6 +27,8 @@ int clock_twi_onoff(int port, int state); void clock_set_pll1(int hz); unsigned int clock_get_pll5(void); unsigned int clock_get_pll6(void); +void clock_init_safe(void); +void clock_init_uart(void); #endif #endif /* _SUNXI_CLOCK_H */ -- 1.9.0 -- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
