common: Drop linux/delay.h from common header
[oweals/u-boot.git] / arch / arm / mach-sunxi / clock_sun50i_h6.c
1 #include <common.h>
2 #include <asm/io.h>
3 #include <asm/arch/cpu.h>
4 #include <asm/arch/clock.h>
5
6 #ifdef CONFIG_SPL_BUILD
7 void clock_init_safe(void)
8 {
9         struct sunxi_ccm_reg *const ccm =
10                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
11         clock_set_pll1(408000000);
12
13         writel(CCM_PLL6_DEFAULT, &ccm->pll6_cfg);
14         while (!(readl(&ccm->pll6_cfg) & CCM_PLL6_LOCK))
15                 ;
16
17         clrsetbits_le32(&ccm->cpu_axi_cfg, CCM_CPU_AXI_APB_MASK | CCM_CPU_AXI_AXI_MASK,
18                         CCM_CPU_AXI_DEFAULT_FACTORS);
19
20         writel(CCM_PSI_AHB1_AHB2_DEFAULT, &ccm->psi_ahb1_ahb2_cfg);
21         writel(CCM_AHB3_DEFAULT, &ccm->ahb3_cfg);
22         writel(CCM_APB1_DEFAULT, &ccm->apb1_cfg);
23
24         /*
25          * The mux and factor are set, but the clock will be enabled in
26          * DRAM initialization code.
27          */
28         writel(MBUS_CLK_SRC_PLL6X2 | MBUS_CLK_M(3), &ccm->mbus_cfg);
29 }
30 #endif
31
32 void clock_init_uart(void)
33 {
34         struct sunxi_ccm_reg *const ccm =
35                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
36
37         /* uart clock source is apb2 */
38         writel(APB2_CLK_SRC_OSC24M|
39                APB2_CLK_RATE_N_1|
40                APB2_CLK_RATE_M(1),
41                &ccm->apb2_cfg);
42
43         /* open the clock for uart */
44         setbits_le32(&ccm->uart_gate_reset,
45                      1 << (CONFIG_CONS_INDEX - 1));
46
47         /* deassert uart reset */
48         setbits_le32(&ccm->uart_gate_reset,
49                      1 << (RESET_SHIFT + CONFIG_CONS_INDEX - 1));
50 }
51
52 #ifdef CONFIG_SPL_BUILD
53 void clock_set_pll1(unsigned int clk)
54 {
55         struct sunxi_ccm_reg * const ccm =
56                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
57         u32 val;
58
59         /* Do not support clocks < 288MHz as they need factor P */
60         if (clk < 288000000) clk = 288000000;
61
62         /* Switch to 24MHz clock while changing PLL1 */
63         val = readl(&ccm->cpu_axi_cfg);
64         val &= ~CCM_CPU_AXI_MUX_MASK;
65         val |= CCM_CPU_AXI_MUX_OSC24M;
66         writel(val, &ccm->cpu_axi_cfg);
67
68         /* clk = 24*n/p, p is ignored if clock is >288MHz */
69         writel(CCM_PLL1_CTRL_EN | CCM_PLL1_LOCK_EN | CCM_PLL1_CLOCK_TIME_2 |
70                CCM_PLL1_CTRL_N(clk / 24000000), &ccm->pll1_cfg);
71         while (!(readl(&ccm->pll1_cfg) & CCM_PLL1_LOCK)) {}
72
73         /* Switch CPU to PLL1 */
74         val = readl(&ccm->cpu_axi_cfg);
75         val &= ~CCM_CPU_AXI_MUX_MASK;
76         val |= CCM_CPU_AXI_MUX_PLL_CPUX;
77         writel(val, &ccm->cpu_axi_cfg);
78 }
79 #endif
80
81 unsigned int clock_get_pll6(void)
82 {
83         struct sunxi_ccm_reg *const ccm =
84                 (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
85
86         uint32_t rval = readl(&ccm->pll6_cfg);
87         int n = ((rval & CCM_PLL6_CTRL_N_MASK) >> CCM_PLL6_CTRL_N_SHIFT);
88         int div1 = ((rval & CCM_PLL6_CTRL_DIV1_MASK) >>
89                         CCM_PLL6_CTRL_DIV1_SHIFT) + 1;
90         int div2 = ((rval & CCM_PLL6_CTRL_DIV2_MASK) >>
91                         CCM_PLL6_CTRL_DIV2_SHIFT) + 1;
92         /* The register defines PLL6-4X, not plain PLL6 */
93         return 24000000 / 4 * n / div1 / div2;
94 }