]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/arm1176/tnetv107x/clock.c
board/ls1021aqds: Add DDR4 support
[karo-tx-uboot.git] / arch / arm / cpu / arm1176 / tnetv107x / clock.c
1 /*
2  * TNETV107X: Clock management APIs
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6
7 #include <common.h>
8 #include <asm-generic/errno.h>
9 #include <asm/io.h>
10 #include <asm/processor.h>
11 #include <asm/arch/clock.h>
12
13 #define CLOCK_BASE              TNETV107X_CLOCK_CONTROL_BASE
14 #define PSC_BASE                TNETV107X_PSC_BASE
15
16 #define BIT(x)                  (1 << (x))
17
18 #define MAX_PREDIV              64
19 #define MAX_POSTDIV             8
20 #define MAX_MULT                512
21 #define MAX_DIV                 (MAX_PREDIV * MAX_POSTDIV)
22
23 /* LPSC registers */
24 #define PSC_PTCMD               0x120
25 #define PSC_PTSTAT              0x128
26 #define PSC_MDSTAT(n)           (0x800 + (n) * 4)
27 #define PSC_MDCTL(n)            (0xA00 + (n) * 4)
28
29 #define PSC_MDCTL_LRSTZ         BIT(8)
30
31 #define psc_reg_read(reg)       __raw_readl((u32 *)(PSC_BASE + (reg)))
32 #define psc_reg_write(reg, val) __raw_writel(val, (u32 *)(PSC_BASE + (reg)))
33
34 /* SSPLL registers */
35 struct sspll_regs {
36         u32     modes;
37         u32     postdiv;
38         u32     prediv;
39         u32     mult_factor;
40         u32     divider_range;
41         u32     bw_divider;
42         u32     spr_amount;
43         u32     spr_rate_div;
44         u32     diag;
45 };
46
47 /* SSPLL base addresses */
48 static struct sspll_regs *sspll_regs[] = {
49         (struct sspll_regs *)(CLOCK_BASE + 0x040),
50         (struct sspll_regs *)(CLOCK_BASE + 0x080),
51         (struct sspll_regs *)(CLOCK_BASE + 0x0c0),
52 };
53
54 #define sspll_reg(pll, reg)             (&(sspll_regs[pll]->reg))
55 #define sspll_reg_read(pll, reg)        __raw_readl(sspll_reg(pll, reg))
56 #define sspll_reg_write(pll, reg, val)  __raw_writel(val, sspll_reg(pll, reg))
57
58
59 /* PLL Control Registers */
60 struct pllctl_regs {
61         u32     ctl;            /* 00 */
62         u32     ocsel;          /* 04 */
63         u32     secctl;         /* 08 */
64         u32     __pad0;
65         u32     mult;           /* 10 */
66         u32     prediv;         /* 14 */
67         u32     div1;           /* 18 */
68         u32     div2;           /* 1c */
69         u32     div3;           /* 20 */
70         u32     oscdiv1;        /* 24 */
71         u32     postdiv;        /* 28 */
72         u32     bpdiv;          /* 2c */
73         u32     wakeup;         /* 30 */
74         u32     __pad1;
75         u32     cmd;            /* 38 */
76         u32     stat;           /* 3c */
77         u32     alnctl;         /* 40 */
78         u32     dchange;        /* 44 */
79         u32     cken;           /* 48 */
80         u32     ckstat;         /* 4c */
81         u32     systat;         /* 50 */
82         u32     ckctl;          /* 54 */
83         u32     __pad2[2];
84         u32     div4;           /* 60 */
85         u32     div5;           /* 64 */
86         u32     div6;           /* 68 */
87         u32     div7;           /* 6c */
88         u32     div8;           /* 70 */
89 };
90
91 struct lpsc_map {
92         int     pll, div;
93 };
94
95 static struct pllctl_regs *pllctl_regs[] = {
96         (struct pllctl_regs *)(CLOCK_BASE + 0x700),
97         (struct pllctl_regs *)(CLOCK_BASE + 0x300),
98         (struct pllctl_regs *)(CLOCK_BASE + 0x500),
99 };
100
101 #define pllctl_reg(pll, reg)            (&(pllctl_regs[pll]->reg))
102 #define pllctl_reg_read(pll, reg)       __raw_readl(pllctl_reg(pll, reg))
103 #define pllctl_reg_write(pll, reg, val) __raw_writel(val, pllctl_reg(pll, reg))
104
105 #define pllctl_reg_rmw(pll, reg, mask, val)                     \
106         pllctl_reg_write(pll, reg,                              \
107                 (pllctl_reg_read(pll, reg) & ~(mask)) | val)
108
109 #define pllctl_reg_setbits(pll, reg, mask)                      \
110         pllctl_reg_rmw(pll, reg, 0, mask)
111
112 #define pllctl_reg_clrbits(pll, reg, mask)                      \
113         pllctl_reg_rmw(pll, reg, mask, 0)
114
115 /* PLLCTL Bits */
116 #define PLLCTL_CLKMODE          BIT(8)
117 #define PLLCTL_PLLSELB          BIT(7)
118 #define PLLCTL_PLLENSRC         BIT(5)
119 #define PLLCTL_PLLDIS           BIT(4)
120 #define PLLCTL_PLLRST           BIT(3)
121 #define PLLCTL_PLLPWRDN         BIT(1)
122 #define PLLCTL_PLLEN            BIT(0)
123
124 #define PLLDIV_ENABLE           BIT(15)
125
126 static int pll_div_offset[] = {
127 #define div_offset(reg) offsetof(struct pllctl_regs, reg)
128         div_offset(div1), div_offset(div2), div_offset(div3),
129         div_offset(div4), div_offset(div5), div_offset(div6),
130         div_offset(div7), div_offset(div8),
131 };
132
133 static unsigned long pll_bypass_mask[] = { 1, 4, 2 };
134 static unsigned long pll_div_mask[] = { 0x01ff, 0x00ff, 0x00ff };
135
136 /* Mappings from PLL+DIV to subsystem clocks */
137 #define sys_arm1176_clk         {SYS_PLL, 0}
138 #define sys_dsp_clk             {SYS_PLL, 1}
139 #define sys_ddr_clk             {SYS_PLL, 2}
140 #define sys_full_clk            {SYS_PLL, 3}
141 #define sys_lcd_clk             {SYS_PLL, 4}
142 #define sys_vlynq_ref_clk       {SYS_PLL, 5}
143 #define sys_tsc_clk             {SYS_PLL, 6}
144 #define sys_half_clk            {SYS_PLL, 7}
145
146 #define eth_clk_5               {ETH_PLL, 0}
147 #define eth_clk_50              {ETH_PLL, 1}
148 #define eth_clk_125             {ETH_PLL, 2}
149 #define eth_clk_250             {ETH_PLL, 3}
150 #define eth_clk_25              {ETH_PLL, 4}
151
152 #define tdm_clk                 {TDM_PLL, 0}
153 #define tdm_extra_clk           {TDM_PLL, 1}
154 #define tdm1_clk                {TDM_PLL, 2}
155
156 static const struct lpsc_map lpsc_clk_map[] = {
157         [TNETV107X_LPSC_ARM]                    = sys_arm1176_clk,
158         [TNETV107X_LPSC_GEM]                    = sys_dsp_clk,
159         [TNETV107X_LPSC_DDR2_PHY]               = sys_ddr_clk,
160         [TNETV107X_LPSC_TPCC]                   = sys_full_clk,
161         [TNETV107X_LPSC_TPTC0]                  = sys_full_clk,
162         [TNETV107X_LPSC_TPTC1]                  = sys_full_clk,
163         [TNETV107X_LPSC_RAM]                    = sys_full_clk,
164         [TNETV107X_LPSC_MBX_LITE]               = sys_arm1176_clk,
165         [TNETV107X_LPSC_LCD]                    = sys_lcd_clk,
166         [TNETV107X_LPSC_ETHSS]                  = eth_clk_125,
167         [TNETV107X_LPSC_AEMIF]                  = sys_full_clk,
168         [TNETV107X_LPSC_CHIP_CFG]               = sys_half_clk,
169         [TNETV107X_LPSC_TSC]                    = sys_tsc_clk,
170         [TNETV107X_LPSC_ROM]                    = sys_half_clk,
171         [TNETV107X_LPSC_UART2]                  = sys_half_clk,
172         [TNETV107X_LPSC_PKTSEC]                 = sys_half_clk,
173         [TNETV107X_LPSC_SECCTL]                 = sys_half_clk,
174         [TNETV107X_LPSC_KEYMGR]                 = sys_half_clk,
175         [TNETV107X_LPSC_KEYPAD]                 = sys_half_clk,
176         [TNETV107X_LPSC_GPIO]                   = sys_half_clk,
177         [TNETV107X_LPSC_MDIO]                   = sys_half_clk,
178         [TNETV107X_LPSC_SDIO0]                  = sys_half_clk,
179         [TNETV107X_LPSC_UART0]                  = sys_half_clk,
180         [TNETV107X_LPSC_UART1]                  = sys_half_clk,
181         [TNETV107X_LPSC_TIMER0]                 = sys_half_clk,
182         [TNETV107X_LPSC_TIMER1]                 = sys_half_clk,
183         [TNETV107X_LPSC_WDT_ARM]                = sys_half_clk,
184         [TNETV107X_LPSC_WDT_DSP]                = sys_half_clk,
185         [TNETV107X_LPSC_SSP]                    = sys_half_clk,
186         [TNETV107X_LPSC_TDM0]                   = tdm_clk,
187         [TNETV107X_LPSC_VLYNQ]                  = sys_vlynq_ref_clk,
188         [TNETV107X_LPSC_MCDMA]                  = sys_half_clk,
189         [TNETV107X_LPSC_USB0]                   = sys_half_clk,
190         [TNETV107X_LPSC_TDM1]                   = tdm1_clk,
191         [TNETV107X_LPSC_DEBUGSS]                = sys_half_clk,
192         [TNETV107X_LPSC_ETHSS_RGMII]            = eth_clk_250,
193         [TNETV107X_LPSC_SYSTEM]                 = sys_half_clk,
194         [TNETV107X_LPSC_IMCOP]                  = sys_dsp_clk,
195         [TNETV107X_LPSC_SPARE]                  = sys_half_clk,
196         [TNETV107X_LPSC_SDIO1]                  = sys_half_clk,
197         [TNETV107X_LPSC_USB1]                   = sys_half_clk,
198         [TNETV107X_LPSC_USBSS]                  = sys_half_clk,
199         [TNETV107X_LPSC_DDR2_EMIF1_VRST]        = sys_ddr_clk,
200         [TNETV107X_LPSC_DDR2_EMIF2_VCTL_RST]    = sys_ddr_clk,
201 };
202
203 static const unsigned long pll_ext_freq[] = {
204         [SYS_PLL] = CONFIG_PLL_SYS_EXT_FREQ,
205         [ETH_PLL] = CONFIG_PLL_ETH_EXT_FREQ,
206         [TDM_PLL] = CONFIG_PLL_TDM_EXT_FREQ,
207 };
208
209 static unsigned long pll_freq_get(int pll)
210 {
211         unsigned long mult = 1, prediv = 1, postdiv = 1;
212         unsigned long ref = CONFIG_SYS_INT_OSC_FREQ;
213         unsigned long ret;
214         u32 bypass;
215
216         bypass = __raw_readl((u32 *)(CLOCK_BASE));
217         if (!(bypass & pll_bypass_mask[pll])) {
218                 mult    = sspll_reg_read(pll, mult_factor);
219                 prediv  = sspll_reg_read(pll, prediv) + 1;
220                 postdiv = sspll_reg_read(pll, postdiv) + 1;
221         }
222
223         if (pllctl_reg_read(pll, ctl) & PLLCTL_CLKMODE)
224                 ref = pll_ext_freq[pll];
225
226         if (!(pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN))
227                 return ref;
228
229         ret = (unsigned long)(ref + ((unsigned long long)ref * mult) / 256);
230         ret /= (prediv * postdiv);
231
232         return ret;
233 }
234
235 static unsigned long __pll_div_freq_get(int pll, unsigned int fpll,
236                                         int div)
237 {
238         int divider = 1;
239         unsigned long divreg;
240
241         divreg = __raw_readl((void *)pllctl_regs[pll] + pll_div_offset[div]);
242
243         if (divreg & PLLDIV_ENABLE)
244                 divider = (divreg & pll_div_mask[pll]) + 1;
245
246         return fpll / divider;
247 }
248
249 static unsigned long pll_div_freq_get(int pll, int div)
250 {
251         unsigned int fpll = pll_freq_get(pll);
252
253         return __pll_div_freq_get(pll, fpll, div);
254 }
255
256 static void __pll_div_freq_set(int pll, unsigned int fpll, int div,
257                                unsigned long hz)
258 {
259         int divider = (fpll / hz - 1);
260
261         divider &= pll_div_mask[pll];
262         divider |= PLLDIV_ENABLE;
263
264         __raw_writel(divider, (void *)pllctl_regs[pll] + pll_div_offset[div]);
265         pllctl_reg_setbits(pll, alnctl, (1 << div));
266         pllctl_reg_setbits(pll, dchange, (1 << div));
267 }
268
269 static unsigned long pll_div_freq_set(int pll, int div, unsigned long hz)
270 {
271         unsigned int fpll = pll_freq_get(pll);
272
273         __pll_div_freq_set(pll, fpll, div, hz);
274
275         pllctl_reg_write(pll, cmd, 1);
276
277         /* Wait until new divider takes effect */
278         while (pllctl_reg_read(pll, stat) & 0x01);
279
280         return __pll_div_freq_get(pll, fpll, div);
281 }
282
283 unsigned long clk_get_rate(unsigned int clk)
284 {
285         return pll_div_freq_get(lpsc_clk_map[clk].pll, lpsc_clk_map[clk].div);
286 }
287
288 unsigned long clk_round_rate(unsigned int clk, unsigned long hz)
289 {
290         unsigned long fpll, divider, pll;
291
292         pll = lpsc_clk_map[clk].pll;
293         fpll = pll_freq_get(pll);
294         divider = (fpll / hz - 1);
295         divider &= pll_div_mask[pll];
296
297         return fpll / (divider + 1);
298 }
299
300 int clk_set_rate(unsigned int clk, unsigned long _hz)
301 {
302         unsigned long hz;
303
304         hz = clk_round_rate(clk, _hz);
305         if (hz != _hz)
306                 return -EINVAL; /* Cannot set to target freq */
307
308         pll_div_freq_set(lpsc_clk_map[clk].pll, lpsc_clk_map[clk].div, hz);
309         return 0;
310 }
311
312 void lpsc_control(int mod, unsigned long state, int lrstz)
313 {
314         u32 mdctl;
315
316         mdctl = psc_reg_read(PSC_MDCTL(mod));
317         mdctl &= ~0x1f;
318         mdctl |= state;
319
320         if (lrstz == 0)
321                 mdctl &= ~PSC_MDCTL_LRSTZ;
322         else if (lrstz == 1)
323                 mdctl |= PSC_MDCTL_LRSTZ;
324
325         psc_reg_write(PSC_MDCTL(mod), mdctl);
326
327         psc_reg_write(PSC_PTCMD, 1);
328
329         /* wait for power domain transition to end */
330         while (psc_reg_read(PSC_PTSTAT) & 1);
331
332         /* Wait for module state change */
333         while ((psc_reg_read(PSC_MDSTAT(mod)) & 0x1f) != state);
334 }
335
336 int lpsc_status(unsigned int id)
337 {
338         return psc_reg_read(PSC_MDSTAT(id)) & 0x1f;
339 }
340
341 static void init_pll(const struct pll_init_data *data)
342 {
343         unsigned long fpll;
344         unsigned long best_pre = 0, best_post = 0, best_mult = 0;
345         unsigned long div, prediv, postdiv, mult;
346         unsigned long delta, actual;
347         long best_delta = -1;
348         int i;
349         u32 tmp;
350
351         if (data->pll == SYS_PLL)
352                 return; /* cannot reconfigure system pll on the fly */
353
354         tmp = pllctl_reg_read(data->pll, ctl);
355         if (data->internal_osc) {
356                 tmp &= ~PLLCTL_CLKMODE;
357                 fpll = CONFIG_SYS_INT_OSC_FREQ;
358         } else {
359                 tmp |= PLLCTL_CLKMODE;
360                 fpll = pll_ext_freq[data->pll];
361         }
362         pllctl_reg_write(data->pll, ctl, tmp);
363
364         mult = data->pll_freq / fpll;
365         for (mult = MAX(mult, 1); mult <= MAX_MULT; mult++) {
366                 div = (fpll * mult) / data->pll_freq;
367                 if (div < 1 || div > MAX_DIV)
368                         continue;
369
370                 for (postdiv = 1; postdiv <= min(div, MAX_POSTDIV); postdiv++) {
371                         prediv = div / postdiv;
372                         if (prediv < 1 || prediv > MAX_PREDIV)
373                                 continue;
374
375                         actual = (fpll / prediv) * (mult / postdiv);
376                         delta = (actual - data->pll_freq);
377                         if (delta < 0)
378                                 delta = -delta;
379                         if ((delta < best_delta) || (best_delta == -1)) {
380                                 best_delta = delta;
381                                 best_mult = mult;
382                                 best_pre = prediv;
383                                 best_post = postdiv;
384                                 if (delta == 0)
385                                         goto done;
386                         }
387                 }
388         }
389 done:
390
391         if (best_delta == -1) {
392                 printf("pll cannot derive %lu from %lu\n",
393                                 data->pll_freq, fpll);
394                 return;
395         }
396
397         fpll = fpll * best_mult;
398         fpll /= best_pre * best_post;
399
400         pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLENSRC);
401         pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLEN);
402
403         pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST);
404
405         pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN);
406         pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLDIS);
407
408         sspll_reg_write(data->pll, mult_factor, (best_mult - 1) << 8);
409         sspll_reg_write(data->pll, prediv,      best_pre - 1);
410         sspll_reg_write(data->pll, postdiv,     best_post - 1);
411
412         for (i = 0; i < 10; i++)
413                 if (data->div_freq[i])
414                         __pll_div_freq_set(data->pll, fpll, i,
415                                            data->div_freq[i]);
416
417         pllctl_reg_write(data->pll, cmd, 1);
418
419         /* Wait until pll "go" operation completes */
420         while (pllctl_reg_read(data->pll, stat) & 0x01);
421
422         pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST);
423         pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN);
424 }
425
426 void init_plls(int num_pll, struct pll_init_data *config)
427 {
428         int i;
429
430         for (i = 0; i < num_pll; i++)
431                 init_pll(&config[i]);
432 }