summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2014-10-25 20:16:33 +0200
committerHans de Goede <hdegoede@redhat.com>2014-11-13 14:49:01 +0100
commit62c87ef2e988558edbf983c9344ceb9370dbbf02 (patch)
tree1eed8f441fac50de93d17aa77bf1e6b9cd9b1229 /arch/arm/cpu/armv7
parent5c7f10fda362db16a7bf3e571b4ae1e88fac2466 (diff)
sun6i: Add clock functions needed for SPL / DRAM init
Add clock_init_safe and clockset_pll5 functions, as these are needed for SPL support resp. DRAM init (which is needed for SPL too). Also add some extra clock register constant defines. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Ian Campbell <ijc@hellion.org.uk>
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r--arch/arm/cpu/armv7/sunxi/clock_sun6i.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c
index 1eae9767d0..16ab6f3729 100644
--- a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c
+++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c
@@ -16,6 +16,33 @@
#include <asm/arch/prcm.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;
+ struct sunxi_prcm_reg * const prcm =
+ (struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;
+
+ /* Set PLL ldo voltage without this PLL6 does not work properly */
+ clrsetbits_le32(&prcm->pll_ctrl1, PRCM_PLL_CTRL_LDO_KEY_MASK,
+ PRCM_PLL_CTRL_LDO_KEY);
+ clrsetbits_le32(&prcm->pll_ctrl1, ~PRCM_PLL_CTRL_LDO_KEY_MASK,
+ PRCM_PLL_CTRL_LDO_DIGITAL_EN | PRCM_PLL_CTRL_LDO_ANALOG_EN |
+ PRCM_PLL_CTRL_EXT_OSC_EN | PRCM_PLL_CTRL_LDO_OUT_L(1140));
+ clrbits_le32(&prcm->pll_ctrl1, PRCM_PLL_CTRL_LDO_KEY_MASK);
+
+ clock_set_pll1(408000000);
+
+ writel(AHB1_ABP1_DIV_DEFAULT, &ccm->ahb1_apb1_div);
+
+ writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg);
+
+ writel(MBUS_CLK_DEFAULT, &ccm->mbus0_clk_cfg);
+ writel(MBUS_CLK_DEFAULT, &ccm->mbus1_clk_cfg);
+}
+#endif
+
void clock_init_uart(void)
{
struct sunxi_ccm_reg *const ccm =
@@ -65,6 +92,56 @@ int clock_twi_onoff(int port, int state)
return 0;
}
+#ifdef CONFIG_SPL_BUILD
+void clock_set_pll1(unsigned int clk)
+{
+ struct sunxi_ccm_reg * const ccm =
+ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+ int k = 1;
+ int m = 1;
+
+ if (clk > 1152000000) {
+ k = 2;
+ } else if (clk > 768000000) {
+ k = 3;
+ m = 2;
+ }
+
+ /* Switch to 24MHz clock while changing PLL1 */
+ 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);
+
+ /* PLL1 rate = 24000000 * n * k / m */
+ writel(CCM_PLL1_CTRL_EN | CCM_PLL1_CTRL_MAGIC |
+ CCM_PLL1_CTRL_N(clk / (24000000 * k / m)) |
+ CCM_PLL1_CTRL_K(k) | CCM_PLL1_CTRL_M(m), &ccm->pll1_cfg);
+ sdelay(200);
+
+ /* Switch CPU to PLL1 */
+ 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);
+}
+#endif
+
+void clock_set_pll5(unsigned int clk)
+{
+ struct sunxi_ccm_reg * const ccm =
+ (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+ const int k = 2;
+ const int m = 1;
+
+ /* PLL5 rate = 24000000 * n * k / m */
+ writel(CCM_PLL5_CTRL_EN | CCM_PLL5_CTRL_UPD |
+ CCM_PLL5_CTRL_N(clk / (24000000 * k / m)) |
+ CCM_PLL5_CTRL_K(k) | CCM_PLL5_CTRL_M(m), &ccm->pll5_cfg);
+
+ udelay(5500);
+}
+
unsigned int clock_get_pll6(void)
{
struct sunxi_ccm_reg *const ccm =