]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/mach-sunxi/clock_sun8i_a83t.c
2 * A83 specific clock code
4 * (C) Copyright 2007-2012
5 * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
6 * Tom Cubie <tangliang@allwinnertech.com>
8 * (C) Copyright 2015 Vishnu Patekar <vishnupatekar0510@gmail.com>
10 * SPDX-License-Identifier: GPL-2.0+
15 #include <asm/arch/clock.h>
16 #include <asm/arch/prcm.h>
17 #include <asm/arch/sys_proto.h>
19 #ifdef CONFIG_SPL_BUILD
20 void clock_init_safe(void)
22 struct sunxi_ccm_reg
* const ccm
=
23 (struct sunxi_ccm_reg
*)SUNXI_CCM_BASE
;
25 clock_set_pll1(408000000);
26 /* enable pll_hsic, default is 480M */
27 writel(PLL8_CFG_DEFAULT
, &ccm
->pll8_cfg
);
28 writel(readl(&ccm
->pll8_cfg
) | (0x1 << 31), &ccm
->pll8_cfg
);
29 while (!(readl(&ccm
->pll_stable_status
) & (1 << 8))) {}
31 /* switch to default 24MHz before changing to hsic */
32 writel(0x0, &ccm
->cci400_cfg
);
34 writel(CCM_CCI400_CLK_SEL_HSIC
, &ccm
->cci400_cfg
);
37 /* switch before changing pll6 */
38 clrsetbits_le32(&ccm
->ahb1_apb1_div
, AHB1_CLK_SRC_MASK
,
40 writel(PLL6_CFG_DEFAULT
, &ccm
->pll6_cfg
);
41 while (!(readl(&ccm
->pll_stable_status
) & (1 << 6))) {}
43 writel(AHB1_ABP1_DIV_DEFAULT
, &ccm
->ahb1_apb1_div
);
44 writel(CCM_MBUS_RESET_RESET
, &ccm
->mbus_reset
);
45 writel(MBUS_CLK_DEFAULT
, &ccm
->mbus_clk_cfg
);
48 writel(1, 0x01720000);
52 void clock_init_uart(void)
54 struct sunxi_ccm_reg
*const ccm
=
55 (struct sunxi_ccm_reg
*)SUNXI_CCM_BASE
;
57 /* uart clock source is apb2 */
58 writel(APB2_CLK_SRC_OSC24M
|
63 /* open the clock for uart */
64 setbits_le32(&ccm
->apb2_gate
,
65 CLK_GATE_OPEN
<< (APB2_GATE_UART_SHIFT
+
66 CONFIG_CONS_INDEX
- 1));
68 /* deassert uart reset */
69 setbits_le32(&ccm
->apb2_reset_cfg
,
70 1 << (APB2_RESET_UART_SHIFT
+
71 CONFIG_CONS_INDEX
- 1));
74 #ifdef CONFIG_SPL_BUILD
75 void clock_set_pll1(unsigned int clk
)
77 struct sunxi_ccm_reg
* const ccm
=
78 (struct sunxi_ccm_reg
*)SUNXI_CCM_BASE
;
81 /* Switch to 24MHz clock while changing PLL1 */
82 writel(AXI_DIV_2
<< AXI0_DIV_SHIFT
|
83 AXI_DIV_2
<< AXI1_DIV_SHIFT
|
84 CPU_CLK_SRC_OSC24M
<< C0_CPUX_CLK_SRC_SHIFT
|
85 CPU_CLK_SRC_OSC24M
<< C1_CPUX_CLK_SRC_SHIFT
,
88 /* clk = 24*n/p, p is ignored if clock is >288MHz */
89 writel(CCM_PLL1_CTRL_EN
| CCM_PLL1_CTRL_P(p
) | CMM_PLL1_CLOCK_TIME_2
|
90 CCM_PLL1_CTRL_N(clk
/ 24000000),
92 while (!(readl(&ccm
->pll_stable_status
) & 0x01)) {}
94 writel(CCM_PLL1_CTRL_EN
| CCM_PLL1_CTRL_P(p
) | CMM_PLL1_CLOCK_TIME_2
|
95 CCM_PLL1_CTRL_N(clk
/ (24000000)),
97 while (!(readl(&ccm
->pll_stable_status
) & 0x02)) {}
99 /* Switch CPU to PLL1 */
100 writel(AXI_DIV_2
<< AXI0_DIV_SHIFT
|
101 AXI_DIV_2
<< AXI1_DIV_SHIFT
|
102 CPU_CLK_SRC_PLL1
<< C0_CPUX_CLK_SRC_SHIFT
|
103 CPU_CLK_SRC_PLL1
<< C1_CPUX_CLK_SRC_SHIFT
,
108 void clock_set_pll5(unsigned int clk
)
110 struct sunxi_ccm_reg
* const ccm
=
111 (struct sunxi_ccm_reg
*)SUNXI_CCM_BASE
;
112 unsigned int div1
= 0, div2
= 0;
114 /* A83T PLL5 DDR rate = 24000000 * (n+1)/(div1+1)/(div2+1) */
115 writel(CCM_PLL5_CTRL_EN
| CCM_PLL5_CTRL_UPD
|
116 CCM_PLL5_CTRL_N(clk
/ (24000000)) |
117 div2
<< CCM_PLL5_DIV2_SHIFT
|
118 div1
<< CCM_PLL5_DIV1_SHIFT
, &ccm
->pll5_cfg
);
124 unsigned int clock_get_pll6(void)
126 struct sunxi_ccm_reg
*const ccm
=
127 (struct sunxi_ccm_reg
*)SUNXI_CCM_BASE
;
129 uint32_t rval
= readl(&ccm
->pll6_cfg
);
130 int n
= ((rval
& CCM_PLL6_CTRL_N_MASK
) >> CCM_PLL6_CTRL_N_SHIFT
);
131 int div1
= ((rval
& CCM_PLL6_CTRL_DIV1_MASK
) >>
132 CCM_PLL6_CTRL_DIV1_SHIFT
) + 1;
133 int div2
= ((rval
& CCM_PLL6_CTRL_DIV2_MASK
) >>
134 CCM_PLL6_CTRL_DIV2_SHIFT
) + 1;
135 return 24000000 * n
/ div1
/ div2
;