]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/am33xx/clock_am33xx.c
ARM: AM33xx: Cleanup dplls data
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / am33xx / clock_am33xx.c
1 /*
2  * clock_am33xx.c
3  *
4  * clocks for AM33XX based boards
5  *
6  * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/
7  *
8  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 #include <common.h>
12 #include <asm/arch/cpu.h>
13 #include <asm/arch/clock.h>
14 #include <asm/arch/hardware.h>
15 #include <asm/io.h>
16
17 #define PRCM_MOD_EN             0x2
18 #define PRCM_FORCE_WAKEUP       0x2
19 #define PRCM_FUNCTL             0x0
20
21 #define CPGMAC0_IDLE            0x30000
22 #define OSC     (V_OSCK/1000000)
23
24 const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
25 const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
26 const struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
27 const struct cm_rtc *cmrtc = (struct cm_rtc *)CM_RTC;
28
29 const struct dpll_regs dpll_mpu_regs = {
30         .cm_clkmode_dpll        = CM_WKUP + 0x88,
31         .cm_idlest_dpll         = CM_WKUP + 0x20,
32         .cm_clksel_dpll         = CM_WKUP + 0x2C,
33         .cm_div_m2_dpll         = CM_WKUP + 0xA8,
34 };
35
36 const struct dpll_regs dpll_core_regs = {
37         .cm_clkmode_dpll        = CM_WKUP + 0x90,
38         .cm_idlest_dpll         = CM_WKUP + 0x5C,
39         .cm_clksel_dpll         = CM_WKUP + 0x68,
40         .cm_div_m4_dpll         = CM_WKUP + 0x80,
41         .cm_div_m5_dpll         = CM_WKUP + 0x84,
42         .cm_div_m6_dpll         = CM_WKUP + 0xD8,
43 };
44
45 const struct dpll_regs dpll_per_regs = {
46         .cm_clkmode_dpll        = CM_WKUP + 0x8C,
47         .cm_idlest_dpll         = CM_WKUP + 0x70,
48         .cm_clksel_dpll         = CM_WKUP + 0x9C,
49         .cm_div_m2_dpll         = CM_WKUP + 0xAC,
50 };
51
52 const struct dpll_regs dpll_ddr_regs = {
53         .cm_clkmode_dpll        = CM_WKUP + 0x94,
54         .cm_idlest_dpll         = CM_WKUP + 0x34,
55         .cm_clksel_dpll         = CM_WKUP + 0x40,
56         .cm_div_m2_dpll         = CM_WKUP + 0xA0,
57 };
58
59 const struct dpll_params dpll_mpu = {
60                 CONFIG_SYS_MPUCLK, OSC-1, 1, -1, -1, -1, -1};
61 const struct dpll_params dpll_core = {
62                 1000, OSC-1, -1, -1, 10, 8, 4};
63 const struct dpll_params dpll_per = {
64                 960, OSC-1, 5, -1, -1, -1, -1};
65
66 static void enable_interface_clocks(void)
67 {
68         /* Enable all the Interconnect Modules */
69         writel(PRCM_MOD_EN, &cmper->l3clkctrl);
70         while (readl(&cmper->l3clkctrl) != PRCM_MOD_EN)
71                 ;
72
73         writel(PRCM_MOD_EN, &cmper->l4lsclkctrl);
74         while (readl(&cmper->l4lsclkctrl) != PRCM_MOD_EN)
75                 ;
76
77         writel(PRCM_MOD_EN, &cmper->l4fwclkctrl);
78         while (readl(&cmper->l4fwclkctrl) != PRCM_MOD_EN)
79                 ;
80
81         writel(PRCM_MOD_EN, &cmwkup->wkl4wkclkctrl);
82         while (readl(&cmwkup->wkl4wkclkctrl) != PRCM_MOD_EN)
83                 ;
84
85         writel(PRCM_MOD_EN, &cmper->l3instrclkctrl);
86         while (readl(&cmper->l3instrclkctrl) != PRCM_MOD_EN)
87                 ;
88
89         writel(PRCM_MOD_EN, &cmper->l4hsclkctrl);
90         while (readl(&cmper->l4hsclkctrl) != PRCM_MOD_EN)
91                 ;
92
93         writel(PRCM_MOD_EN, &cmwkup->wkgpio0clkctrl);
94         while (readl(&cmwkup->wkgpio0clkctrl) != PRCM_MOD_EN)
95                 ;
96 }
97
98 /*
99  * Force power domain wake up transition
100  * Ensure that the corresponding interface clock is active before
101  * using the peripheral
102  */
103 static void power_domain_wkup_transition(void)
104 {
105         writel(PRCM_FORCE_WAKEUP, &cmper->l3clkstctrl);
106         writel(PRCM_FORCE_WAKEUP, &cmper->l4lsclkstctrl);
107         writel(PRCM_FORCE_WAKEUP, &cmwkup->wkclkstctrl);
108         writel(PRCM_FORCE_WAKEUP, &cmper->l4fwclkstctrl);
109         writel(PRCM_FORCE_WAKEUP, &cmper->l3sclkstctrl);
110 }
111
112 /*
113  * Enable the peripheral clock for required peripherals
114  */
115 static void enable_per_clocks(void)
116 {
117         /* Enable the control module though RBL would have done it*/
118         writel(PRCM_MOD_EN, &cmwkup->wkctrlclkctrl);
119         while (readl(&cmwkup->wkctrlclkctrl) != PRCM_MOD_EN)
120                 ;
121
122         /* Enable the module clock */
123         writel(PRCM_MOD_EN, &cmper->timer2clkctrl);
124         while (readl(&cmper->timer2clkctrl) != PRCM_MOD_EN)
125                 ;
126
127         /* Select the Master osc 24 MHZ as Timer2 clock source */
128         writel(0x1, &cmdpll->clktimer2clk);
129
130         /* UART0 */
131         writel(PRCM_MOD_EN, &cmwkup->wkup_uart0ctrl);
132         while (readl(&cmwkup->wkup_uart0ctrl) != PRCM_MOD_EN)
133                 ;
134
135         /* UART1 */
136 #ifdef CONFIG_SERIAL2
137         writel(PRCM_MOD_EN, &cmper->uart1clkctrl);
138         while (readl(&cmper->uart1clkctrl) != PRCM_MOD_EN)
139                 ;
140 #endif /* CONFIG_SERIAL2 */
141
142         /* UART2 */
143 #ifdef CONFIG_SERIAL3
144         writel(PRCM_MOD_EN, &cmper->uart2clkctrl);
145         while (readl(&cmper->uart2clkctrl) != PRCM_MOD_EN)
146                 ;
147 #endif /* CONFIG_SERIAL3 */
148
149         /* UART3 */
150 #ifdef CONFIG_SERIAL4
151         writel(PRCM_MOD_EN, &cmper->uart3clkctrl);
152         while (readl(&cmper->uart3clkctrl) != PRCM_MOD_EN)
153                 ;
154 #endif /* CONFIG_SERIAL4 */
155
156         /* UART4 */
157 #ifdef CONFIG_SERIAL5
158         writel(PRCM_MOD_EN, &cmper->uart4clkctrl);
159         while (readl(&cmper->uart4clkctrl) != PRCM_MOD_EN)
160                 ;
161 #endif /* CONFIG_SERIAL5 */
162
163         /* UART5 */
164 #ifdef CONFIG_SERIAL6
165         writel(PRCM_MOD_EN, &cmper->uart5clkctrl);
166         while (readl(&cmper->uart5clkctrl) != PRCM_MOD_EN)
167                 ;
168 #endif /* CONFIG_SERIAL6 */
169
170         /* GPMC */
171         writel(PRCM_MOD_EN, &cmper->gpmcclkctrl);
172         while (readl(&cmper->gpmcclkctrl) != PRCM_MOD_EN)
173                 ;
174
175         /* ELM */
176         writel(PRCM_MOD_EN, &cmper->elmclkctrl);
177         while (readl(&cmper->elmclkctrl) != PRCM_MOD_EN)
178                 ;
179
180         /* MMC0*/
181         writel(PRCM_MOD_EN, &cmper->mmc0clkctrl);
182         while (readl(&cmper->mmc0clkctrl) != PRCM_MOD_EN)
183                 ;
184
185         /* MMC1 */
186         writel(PRCM_MOD_EN, &cmper->mmc1clkctrl);
187         while (readl(&cmper->mmc1clkctrl) != PRCM_MOD_EN)
188                 ;
189
190         /* i2c0 */
191         writel(PRCM_MOD_EN, &cmwkup->wkup_i2c0ctrl);
192         while (readl(&cmwkup->wkup_i2c0ctrl) != PRCM_MOD_EN)
193                 ;
194
195         /* gpio1 module */
196         writel(PRCM_MOD_EN, &cmper->gpio1clkctrl);
197         while (readl(&cmper->gpio1clkctrl) != PRCM_MOD_EN)
198                 ;
199
200         /* gpio2 module */
201         writel(PRCM_MOD_EN, &cmper->gpio2clkctrl);
202         while (readl(&cmper->gpio2clkctrl) != PRCM_MOD_EN)
203                 ;
204
205         /* gpio3 module */
206         writel(PRCM_MOD_EN, &cmper->gpio3clkctrl);
207         while (readl(&cmper->gpio3clkctrl) != PRCM_MOD_EN)
208                 ;
209
210         /* i2c1 */
211         writel(PRCM_MOD_EN, &cmper->i2c1clkctrl);
212         while (readl(&cmper->i2c1clkctrl) != PRCM_MOD_EN)
213                 ;
214
215         /* Ethernet */
216         writel(PRCM_MOD_EN, &cmper->cpgmac0clkctrl);
217         while ((readl(&cmper->cpgmac0clkctrl) & CPGMAC0_IDLE) != PRCM_FUNCTL)
218                 ;
219
220         /* spi0 */
221         writel(PRCM_MOD_EN, &cmper->spi0clkctrl);
222         while (readl(&cmper->spi0clkctrl) != PRCM_MOD_EN)
223                 ;
224
225         /* RTC */
226         writel(PRCM_MOD_EN, &cmrtc->rtcclkctrl);
227         while (readl(&cmrtc->rtcclkctrl) != PRCM_MOD_EN)
228                 ;
229
230         /* MUSB */
231         writel(PRCM_MOD_EN, &cmper->usb0clkctrl);
232         while (readl(&cmper->usb0clkctrl) != PRCM_MOD_EN)
233                 ;
234 }
235
236 void enable_emif_clocks(void)
237 {
238         /* Enable the  EMIF_FW Functional clock */
239         writel(PRCM_MOD_EN, &cmper->emiffwclkctrl);
240         /* Enable EMIF0 Clock */
241         writel(PRCM_MOD_EN, &cmper->emifclkctrl);
242         /* Poll if module is functional */
243         while ((readl(&cmper->emifclkctrl)) != PRCM_MOD_EN)
244                 ;
245 }
246
247 /*
248  * Configure the PLL/PRCM for necessary peripherals
249  */
250 void pll_init()
251 {
252         setup_dplls();
253         /* Enable the required interconnect clocks */
254         enable_interface_clocks();
255
256         /* Power domain wake up transition */
257         power_domain_wkup_transition();
258
259         /* Enable the required peripherals */
260         enable_per_clocks();
261 }