Linux-libre 5.4.49-gnu
[librecmc/linux-libre.git] / arch / unicore32 / kernel / clock.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * linux/arch/unicore32/kernel/clock.c
4  *
5  * Code specific to PKUnity SoC and UniCore ISA
6  *
7  *      Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
8  *      Copyright (C) 2001-2010 Guan Xuetao
9  */
10 #include <linux/module.h>
11 #include <linux/kernel.h>
12 #include <linux/device.h>
13 #include <linux/list.h>
14 #include <linux/errno.h>
15 #include <linux/err.h>
16 #include <linux/string.h>
17 #include <linux/clk.h>
18 #include <linux/mutex.h>
19 #include <linux/delay.h>
20 #include <linux/io.h>
21
22 #include <mach/hardware.h>
23
24 /*
25  * Very simple clock implementation
26  */
27 struct clk {
28         struct list_head        node;
29         unsigned long           rate;
30         const char              *name;
31 };
32
33 static struct clk clk_ost_clk = {
34         .name           = "OST_CLK",
35         .rate           = CLOCK_TICK_RATE,
36 };
37
38 static struct clk clk_mclk_clk = {
39         .name           = "MAIN_CLK",
40 };
41
42 static struct clk clk_bclk32_clk = {
43         .name           = "BUS32_CLK",
44 };
45
46 static struct clk clk_ddr_clk = {
47         .name           = "DDR_CLK",
48 };
49
50 static struct clk clk_vga_clk = {
51         .name           = "VGA_CLK",
52 };
53
54 static LIST_HEAD(clocks);
55 static DEFINE_MUTEX(clocks_mutex);
56
57 struct clk *clk_get(struct device *dev, const char *id)
58 {
59         struct clk *p, *clk = ERR_PTR(-ENOENT);
60
61         mutex_lock(&clocks_mutex);
62         list_for_each_entry(p, &clocks, node) {
63                 if (strcmp(id, p->name) == 0) {
64                         clk = p;
65                         break;
66                 }
67         }
68         mutex_unlock(&clocks_mutex);
69
70         return clk;
71 }
72 EXPORT_SYMBOL(clk_get);
73
74 void clk_put(struct clk *clk)
75 {
76 }
77 EXPORT_SYMBOL(clk_put);
78
79 int clk_enable(struct clk *clk)
80 {
81         return 0;
82 }
83 EXPORT_SYMBOL(clk_enable);
84
85 void clk_disable(struct clk *clk)
86 {
87 }
88 EXPORT_SYMBOL(clk_disable);
89
90 unsigned long clk_get_rate(struct clk *clk)
91 {
92         return clk->rate;
93 }
94 EXPORT_SYMBOL(clk_get_rate);
95
96 struct {
97         unsigned long rate;
98         unsigned long cfg;
99         unsigned long div;
100 } vga_clk_table[] = {
101         {.rate =  25175000, .cfg = 0x00002001, .div = 0x9},
102         {.rate =  31500000, .cfg = 0x00002001, .div = 0x7},
103         {.rate =  40000000, .cfg = 0x00003801, .div = 0x9},
104         {.rate =  49500000, .cfg = 0x00003801, .div = 0x7},
105         {.rate =  65000000, .cfg = 0x00002c01, .div = 0x4},
106         {.rate =  78750000, .cfg = 0x00002400, .div = 0x7},
107         {.rate = 108000000, .cfg = 0x00002c01, .div = 0x2},
108         {.rate = 106500000, .cfg = 0x00003c01, .div = 0x3},
109         {.rate =  50650000, .cfg = 0x00106400, .div = 0x9},
110         {.rate =  61500000, .cfg = 0x00106400, .div = 0xa},
111         {.rate =  85500000, .cfg = 0x00002800, .div = 0x6},
112 };
113
114 struct {
115         unsigned long mrate;
116         unsigned long prate;
117 } mclk_clk_table[] = {
118         {.mrate = 500000000, .prate = 0x00109801},
119         {.mrate = 525000000, .prate = 0x00104C00},
120         {.mrate = 550000000, .prate = 0x00105000},
121         {.mrate = 575000000, .prate = 0x00105400},
122         {.mrate = 600000000, .prate = 0x00105800},
123         {.mrate = 625000000, .prate = 0x00105C00},
124         {.mrate = 650000000, .prate = 0x00106000},
125         {.mrate = 675000000, .prate = 0x00106400},
126         {.mrate = 700000000, .prate = 0x00106800},
127         {.mrate = 725000000, .prate = 0x00106C00},
128         {.mrate = 750000000, .prate = 0x00107000},
129         {.mrate = 775000000, .prate = 0x00107400},
130         {.mrate = 800000000, .prate = 0x00107800},
131 };
132
133 int clk_set_rate(struct clk *clk, unsigned long rate)
134 {
135         if (clk == &clk_vga_clk) {
136                 unsigned long pll_vgacfg, pll_vgadiv;
137                 int ret, i;
138
139                 /* lookup vga_clk_table */
140                 ret = -EINVAL;
141                 for (i = 0; i < ARRAY_SIZE(vga_clk_table); i++) {
142                         if (rate == vga_clk_table[i].rate) {
143                                 pll_vgacfg = vga_clk_table[i].cfg;
144                                 pll_vgadiv = vga_clk_table[i].div;
145                                 ret = 0;
146                                 break;
147                         }
148                 }
149
150                 if (ret)
151                         return ret;
152
153                 if (readl(PM_PLLVGACFG) == pll_vgacfg)
154                         return 0;
155
156                 /* set pll vga cfg reg. */
157                 writel(pll_vgacfg, PM_PLLVGACFG);
158
159                 writel(PM_PMCR_CFBVGA, PM_PMCR);
160                 while ((readl(PM_PLLDFCDONE) & PM_PLLDFCDONE_VGADFC)
161                                 != PM_PLLDFCDONE_VGADFC)
162                         udelay(100); /* about 1ms */
163
164                 /* set div cfg reg. */
165                 writel(readl(PM_PCGR) | PM_PCGR_VGACLK, PM_PCGR);
166
167                 writel((readl(PM_DIVCFG) & ~PM_DIVCFG_VGACLK_MASK)
168                                 | PM_DIVCFG_VGACLK(pll_vgadiv), PM_DIVCFG);
169
170                 writel(readl(PM_SWRESET) | PM_SWRESET_VGADIV, PM_SWRESET);
171                 while ((readl(PM_SWRESET) & PM_SWRESET_VGADIV)
172                                 == PM_SWRESET_VGADIV)
173                         udelay(100); /* 65536 bclk32, about 320us */
174
175                 writel(readl(PM_PCGR) & ~PM_PCGR_VGACLK, PM_PCGR);
176         }
177 #ifdef CONFIG_CPU_FREQ
178         if (clk == &clk_mclk_clk) {
179                 u32 pll_rate, divstatus = readl(PM_DIVSTATUS);
180                 int ret, i;
181
182                 /* lookup mclk_clk_table */
183                 ret = -EINVAL;
184                 for (i = 0; i < ARRAY_SIZE(mclk_clk_table); i++) {
185                         if (rate == mclk_clk_table[i].mrate) {
186                                 pll_rate = mclk_clk_table[i].prate;
187                                 clk_mclk_clk.rate = mclk_clk_table[i].mrate;
188                                 ret = 0;
189                                 break;
190                         }
191                 }
192
193                 if (ret)
194                         return ret;
195
196                 if (clk_mclk_clk.rate)
197                         clk_bclk32_clk.rate = clk_mclk_clk.rate
198                                 / (((divstatus & 0x0000f000) >> 12) + 1);
199
200                 /* set pll sys cfg reg. */
201                 writel(pll_rate, PM_PLLSYSCFG);
202
203                 writel(PM_PMCR_CFBSYS, PM_PMCR);
204                 while ((readl(PM_PLLDFCDONE) & PM_PLLDFCDONE_SYSDFC)
205                                 != PM_PLLDFCDONE_SYSDFC)
206                         udelay(100);
207                         /* about 1ms */
208         }
209 #endif
210         return 0;
211 }
212 EXPORT_SYMBOL(clk_set_rate);
213
214 int clk_register(struct clk *clk)
215 {
216         mutex_lock(&clocks_mutex);
217         list_add(&clk->node, &clocks);
218         mutex_unlock(&clocks_mutex);
219         printk(KERN_DEFAULT "PKUnity PM: %s %lu.%02luM\n", clk->name,
220                 (clk->rate)/1000000, (clk->rate)/10000 % 100);
221         return 0;
222 }
223 EXPORT_SYMBOL(clk_register);
224
225 void clk_unregister(struct clk *clk)
226 {
227         mutex_lock(&clocks_mutex);
228         list_del(&clk->node);
229         mutex_unlock(&clocks_mutex);
230 }
231 EXPORT_SYMBOL(clk_unregister);
232
233 struct {
234         unsigned long prate;
235         unsigned long rate;
236 } pllrate_table[] = {
237         {.prate = 0x00002001, .rate = 250000000},
238         {.prate = 0x00104801, .rate = 250000000},
239         {.prate = 0x00104C01, .rate = 262500000},
240         {.prate = 0x00002401, .rate = 275000000},
241         {.prate = 0x00105001, .rate = 275000000},
242         {.prate = 0x00105401, .rate = 287500000},
243         {.prate = 0x00002801, .rate = 300000000},
244         {.prate = 0x00105801, .rate = 300000000},
245         {.prate = 0x00105C01, .rate = 312500000},
246         {.prate = 0x00002C01, .rate = 325000000},
247         {.prate = 0x00106001, .rate = 325000000},
248         {.prate = 0x00106401, .rate = 337500000},
249         {.prate = 0x00003001, .rate = 350000000},
250         {.prate = 0x00106801, .rate = 350000000},
251         {.prate = 0x00106C01, .rate = 362500000},
252         {.prate = 0x00003401, .rate = 375000000},
253         {.prate = 0x00107001, .rate = 375000000},
254         {.prate = 0x00107401, .rate = 387500000},
255         {.prate = 0x00003801, .rate = 400000000},
256         {.prate = 0x00107801, .rate = 400000000},
257         {.prate = 0x00107C01, .rate = 412500000},
258         {.prate = 0x00003C01, .rate = 425000000},
259         {.prate = 0x00108001, .rate = 425000000},
260         {.prate = 0x00108401, .rate = 437500000},
261         {.prate = 0x00004001, .rate = 450000000},
262         {.prate = 0x00108801, .rate = 450000000},
263         {.prate = 0x00108C01, .rate = 462500000},
264         {.prate = 0x00004401, .rate = 475000000},
265         {.prate = 0x00109001, .rate = 475000000},
266         {.prate = 0x00109401, .rate = 487500000},
267         {.prate = 0x00004801, .rate = 500000000},
268         {.prate = 0x00109801, .rate = 500000000},
269         {.prate = 0x00104C00, .rate = 525000000},
270         {.prate = 0x00002400, .rate = 550000000},
271         {.prate = 0x00105000, .rate = 550000000},
272         {.prate = 0x00105400, .rate = 575000000},
273         {.prate = 0x00002800, .rate = 600000000},
274         {.prate = 0x00105800, .rate = 600000000},
275         {.prate = 0x00105C00, .rate = 625000000},
276         {.prate = 0x00002C00, .rate = 650000000},
277         {.prate = 0x00106000, .rate = 650000000},
278         {.prate = 0x00106400, .rate = 675000000},
279         {.prate = 0x00003000, .rate = 700000000},
280         {.prate = 0x00106800, .rate = 700000000},
281         {.prate = 0x00106C00, .rate = 725000000},
282         {.prate = 0x00003400, .rate = 750000000},
283         {.prate = 0x00107000, .rate = 750000000},
284         {.prate = 0x00107400, .rate = 775000000},
285         {.prate = 0x00003800, .rate = 800000000},
286         {.prate = 0x00107800, .rate = 800000000},
287         {.prate = 0x00107C00, .rate = 825000000},
288         {.prate = 0x00003C00, .rate = 850000000},
289         {.prate = 0x00108000, .rate = 850000000},
290         {.prate = 0x00108400, .rate = 875000000},
291         {.prate = 0x00004000, .rate = 900000000},
292         {.prate = 0x00108800, .rate = 900000000},
293         {.prate = 0x00108C00, .rate = 925000000},
294         {.prate = 0x00004400, .rate = 950000000},
295         {.prate = 0x00109000, .rate = 950000000},
296         {.prate = 0x00109400, .rate = 975000000},
297         {.prate = 0x00004800, .rate = 1000000000},
298         {.prate = 0x00109800, .rate = 1000000000},
299 };
300
301 struct {
302         unsigned long prate;
303         unsigned long drate;
304 } pddr_table[] = {
305         {.prate = 0x00100800, .drate = 44236800},
306         {.prate = 0x00100C00, .drate = 66355200},
307         {.prate = 0x00101000, .drate = 88473600},
308         {.prate = 0x00101400, .drate = 110592000},
309         {.prate = 0x00101800, .drate = 132710400},
310         {.prate = 0x00101C01, .drate = 154828800},
311         {.prate = 0x00102001, .drate = 176947200},
312         {.prate = 0x00102401, .drate = 199065600},
313         {.prate = 0x00102801, .drate = 221184000},
314         {.prate = 0x00102C01, .drate = 243302400},
315         {.prate = 0x00103001, .drate = 265420800},
316         {.prate = 0x00103401, .drate = 287539200},
317         {.prate = 0x00103801, .drate = 309657600},
318         {.prate = 0x00103C01, .drate = 331776000},
319         {.prate = 0x00104001, .drate = 353894400},
320 };
321
322 static int __init clk_init(void)
323 {
324 #ifdef CONFIG_PUV3_PM
325         u32 pllrate, divstatus = readl(PM_DIVSTATUS);
326         u32 pcgr_val = readl(PM_PCGR);
327         int i;
328
329         pcgr_val |= PM_PCGR_BCLKMME | PM_PCGR_BCLKH264E | PM_PCGR_BCLKH264D
330                         | PM_PCGR_HECLK | PM_PCGR_HDCLK;
331         writel(pcgr_val, PM_PCGR);
332
333         pllrate = readl(PM_PLLSYSSTATUS);
334
335         /* lookup pmclk_table */
336         clk_mclk_clk.rate = 0;
337         for (i = 0; i < ARRAY_SIZE(pllrate_table); i++) {
338                 if (pllrate == pllrate_table[i].prate) {
339                         clk_mclk_clk.rate = pllrate_table[i].rate;
340                         break;
341                 }
342         }
343
344         if (clk_mclk_clk.rate)
345                 clk_bclk32_clk.rate = clk_mclk_clk.rate /
346                         (((divstatus & 0x0000f000) >> 12) + 1);
347
348         pllrate = readl(PM_PLLDDRSTATUS);
349
350         /* lookup pddr_table */
351         clk_ddr_clk.rate = 0;
352         for (i = 0; i < ARRAY_SIZE(pddr_table); i++) {
353                 if (pllrate == pddr_table[i].prate) {
354                         clk_ddr_clk.rate = pddr_table[i].drate;
355                         break;
356                 }
357         }
358
359         pllrate = readl(PM_PLLVGASTATUS);
360
361         /* lookup pvga_table */
362         clk_vga_clk.rate = 0;
363         for (i = 0; i < ARRAY_SIZE(pllrate_table); i++) {
364                 if (pllrate == pllrate_table[i].prate) {
365                         clk_vga_clk.rate = pllrate_table[i].rate;
366                         break;
367                 }
368         }
369
370         if (clk_vga_clk.rate)
371                 clk_vga_clk.rate = clk_vga_clk.rate /
372                         (((divstatus & 0x00f00000) >> 20) + 1);
373
374         clk_register(&clk_vga_clk);
375 #endif
376 #ifdef CONFIG_ARCH_FPGA
377         clk_ddr_clk.rate = 33000000;
378         clk_mclk_clk.rate = 33000000;
379         clk_bclk32_clk.rate = 33000000;
380 #endif
381         clk_register(&clk_ddr_clk);
382         clk_register(&clk_mclk_clk);
383         clk_register(&clk_bclk32_clk);
384         clk_register(&clk_ost_clk);
385         return 0;
386 }
387 core_initcall(clk_init);