X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=arch%2Farm%2Fmach-sunxi%2Fclock_sun6i.c;h=b46083e9db91c1184b0627046bef943ceeaedec8;hb=c05ed00afb95fa5237f16962fccf5810437317bf;hp=d123b3acb2f1c8bd579637ef4509694878518baa;hpb=0675f992dbf4a785a05a1baf149c2bce6aa5fe90;p=oweals%2Fu-boot.git diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c index d123b3acb2..b46083e9db 100644 --- a/arch/arm/mach-sunxi/clock_sun6i.c +++ b/arch/arm/mach-sunxi/clock_sun6i.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * sun6i specific clock code * @@ -6,8 +7,6 @@ * Tom Cubie * * (C) Copyright 2013 Luke Kenneth Casson Leighton - * - * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -15,6 +14,7 @@ #include #include #include +#include #ifdef CONFIG_SPL_BUILD void clock_init_safe(void) @@ -22,7 +22,7 @@ void clock_init_safe(void) struct sunxi_ccm_reg * const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; -#if !defined(CONFIG_MACH_SUN8I_H3) && !defined(CONFIG_MACH_SUN50I) +#if !defined(CONFIG_MACH_SUNXI_H3_H5) && !defined(CONFIG_MACH_SUN50I) struct sunxi_prcm_reg * const prcm = (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE; @@ -35,6 +35,11 @@ void clock_init_safe(void) clrbits_le32(&prcm->pll_ctrl1, PRCM_PLL_CTRL_LDO_KEY_MASK); #endif +#if defined(CONFIG_MACH_SUN8I_R40) || defined(CONFIG_MACH_SUN50I) + /* Set PLL lock enable bits and switch to old lock mode */ + writel(GENMASK(12, 0), &ccm->pll_lock_ctrl); +#endif + clock_set_pll1(408000000); writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); @@ -46,19 +51,32 @@ void clock_init_safe(void) writel(MBUS_CLK_DEFAULT, &ccm->mbus0_clk_cfg); if (IS_ENABLED(CONFIG_MACH_SUN6I)) writel(MBUS_CLK_DEFAULT, &ccm->mbus1_clk_cfg); + +#if defined(CONFIG_MACH_SUN8I_R40) && defined(CONFIG_SUNXI_AHCI) + setbits_le32(&ccm->sata_pll_cfg, CCM_SATA_PLL_DEFAULT); + setbits_le32(&ccm->ahb_reset0_cfg, 0x1 << AHB_GATE_OFFSET_SATA); + setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_SATA); + setbits_le32(&ccm->sata_clk_cfg, CCM_SATA_CTRL_ENABLE); +#endif } #endif void clock_init_sec(void) { -#ifdef CONFIG_MACH_SUN8I_H3 +#ifdef CONFIG_MACH_SUNXI_H3_H5 struct sunxi_ccm_reg * const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + struct sunxi_prcm_reg * const prcm = + (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE; setbits_le32(&ccm->ccu_sec_switch, CCM_SEC_SWITCH_MBUS_NONSEC | CCM_SEC_SWITCH_BUS_NONSEC | CCM_SEC_SWITCH_PLL_NONSEC); + setbits_le32(&prcm->prcm_sec_switch, + PRCM_SEC_SWITCH_APB0_CLK_NONSEC | + PRCM_SEC_SWITCH_PLL_CFG_NONSEC | + PRCM_SEC_SWITCH_PWR_GATE_NONSEC); #endif } @@ -101,7 +119,7 @@ void clock_set_pll1(unsigned int clk) if (clk > 1152000000) { k = 2; } else if (clk > 768000000) { - k = 3; + k = 4; m = 2; } @@ -132,7 +150,11 @@ void clock_set_pll3(unsigned int clk) { struct sunxi_ccm_reg * const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; +#ifdef CONFIG_SUNXI_DE2 + const int m = 4; /* 6 MHz steps to allow higher frequency for DE2 */ +#else const int m = 8; /* 3 MHz steps just like sun4i, sun5i and sun7i */ +#endif if (clk == 0) { clrbits_le32(&ccm->pll3_cfg, CCM_PLL3_CTRL_EN); @@ -145,6 +167,22 @@ void clock_set_pll3(unsigned int clk) &ccm->pll3_cfg); } +#ifdef CONFIG_SUNXI_DE2 +void clock_set_pll3_factors(int m, int n) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + /* PLL3 rate = 24000000 * n / m */ + writel(CCM_PLL3_CTRL_EN | CCM_PLL3_CTRL_INTEGER_MODE | + CCM_PLL3_CTRL_N(n) | CCM_PLL3_CTRL_M(m), + &ccm->pll3_cfg); + + while (!(readl(&ccm->pll3_cfg) & CCM_PLL3_CTRL_LOCK)) + ; +} +#endif + void clock_set_pll5(unsigned int clk, bool sigma_delta_enable) { struct sunxi_ccm_reg * const ccm = @@ -152,7 +190,7 @@ void clock_set_pll5(unsigned int clk, bool sigma_delta_enable) const int max_n = 32; int k = 1, m = 2; -#ifdef CONFIG_MACH_SUN8I_H3 +#ifdef CONFIG_MACH_SUNXI_H3_H5 clrsetbits_le32(&ccm->pll5_tuning_cfg, CCM_PLL5_TUN_LOCK_TIME_MASK | CCM_PLL5_TUN_INIT_FREQ_MASK, CCM_PLL5_TUN_LOCK_TIME(2) | CCM_PLL5_TUN_INIT_FREQ(16)); @@ -217,7 +255,31 @@ done: } #endif -#if defined(CONFIG_MACH_SUN8I_A33) || defined(CONFIG_MACH_SUN50I) +#ifdef CONFIG_SUNXI_DE2 +void clock_set_pll10(unsigned int clk) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + const int m = 2; /* 12 MHz steps */ + + if (clk == 0) { + clrbits_le32(&ccm->pll10_cfg, CCM_PLL10_CTRL_EN); + return; + } + + /* PLL10 rate = 24000000 * n / m */ + writel(CCM_PLL10_CTRL_EN | CCM_PLL10_CTRL_INTEGER_MODE | + CCM_PLL10_CTRL_N(clk / (24000000 / m)) | CCM_PLL10_CTRL_M(m), + &ccm->pll10_cfg); + + while (!(readl(&ccm->pll10_cfg) & CCM_PLL10_CTRL_LOCK)) + ; +} +#endif + +#if defined(CONFIG_MACH_SUN8I_A33) || \ + defined(CONFIG_MACH_SUN8I_R40) || \ + defined(CONFIG_MACH_SUN50I) void clock_set_pll11(unsigned int clk, bool sigma_delta_enable) { struct sunxi_ccm_reg * const ccm =