1
2
3
4
5
6
7
8
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
26
27struct clk {
28 struct list_head node;
29 unsigned long rate;
30 const char *name;
31};
32
33static struct clk clk_ost_clk = {
34 .name = "OST_CLK",
35 .rate = CLOCK_TICK_RATE,
36};
37
38static struct clk clk_mclk_clk = {
39 .name = "MAIN_CLK",
40};
41
42static struct clk clk_bclk32_clk = {
43 .name = "BUS32_CLK",
44};
45
46static struct clk clk_ddr_clk = {
47 .name = "DDR_CLK",
48};
49
50static struct clk clk_vga_clk = {
51 .name = "VGA_CLK",
52};
53
54static LIST_HEAD(clocks);
55static DEFINE_MUTEX(clocks_mutex);
56
57struct 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}
72EXPORT_SYMBOL(clk_get);
73
74void clk_put(struct clk *clk)
75{
76}
77EXPORT_SYMBOL(clk_put);
78
79int clk_enable(struct clk *clk)
80{
81 return 0;
82}
83EXPORT_SYMBOL(clk_enable);
84
85void clk_disable(struct clk *clk)
86{
87}
88EXPORT_SYMBOL(clk_disable);
89
90unsigned long clk_get_rate(struct clk *clk)
91{
92 return clk->rate;
93}
94EXPORT_SYMBOL(clk_get_rate);
95
96struct {
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
114struct {
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
133int 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
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
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);
163
164
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);
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
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
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
208 }
209#endif
210 return 0;
211}
212EXPORT_SYMBOL(clk_set_rate);
213
214int 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}
223EXPORT_SYMBOL(clk_register);
224
225void clk_unregister(struct clk *clk)
226{
227 mutex_lock(&clocks_mutex);
228 list_del(&clk->node);
229 mutex_unlock(&clocks_mutex);
230}
231EXPORT_SYMBOL(clk_unregister);
232
233struct {
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
301struct {
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
322static 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
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
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
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}
387core_initcall(clk_init);
388