md/RAID1: Add missing case for attempting to repair known bad blocks.
[firefly-linux-kernel-4.4.55.git] / arch / blackfin / mach-bf609 / clock.c
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/list.h>
4 #include <linux/errno.h>
5 #include <linux/err.h>
6 #include <linux/string.h>
7 #include <linux/clk.h>
8 #include <linux/mutex.h>
9 #include <linux/spinlock.h>
10 #include <linux/debugfs.h>
11 #include <linux/device.h>
12 #include <linux/init.h>
13 #include <linux/timer.h>
14 #include <linux/io.h>
15 #include <linux/seq_file.h>
16 #include <linux/clkdev.h>
17
18 #include <asm/clocks.h>
19
20 #define CGU0_CTL_DF (1 << 0)
21
22 #define CGU0_CTL_MSEL_SHIFT 8
23 #define CGU0_CTL_MSEL_MASK (0x7f << 8)
24
25 #define CGU0_STAT_PLLEN (1 << 0)
26 #define CGU0_STAT_PLLBP (1 << 1)
27 #define CGU0_STAT_PLLLK (1 << 2)
28 #define CGU0_STAT_CLKSALGN (1 << 3)
29 #define CGU0_STAT_CCBF0 (1 << 4)
30 #define CGU0_STAT_CCBF1 (1 << 5)
31 #define CGU0_STAT_SCBF0 (1 << 6)
32 #define CGU0_STAT_SCBF1 (1 << 7)
33 #define CGU0_STAT_DCBF (1 << 8)
34 #define CGU0_STAT_OCBF (1 << 9)
35 #define CGU0_STAT_ADDRERR (1 << 16)
36 #define CGU0_STAT_LWERR (1 << 17)
37 #define CGU0_STAT_DIVERR (1 << 18)
38 #define CGU0_STAT_WDFMSERR (1 << 19)
39 #define CGU0_STAT_WDIVERR (1 << 20)
40 #define CGU0_STAT_PLOCKERR (1 << 21)
41
42 #define CGU0_DIV_CSEL_SHIFT 0
43 #define CGU0_DIV_CSEL_MASK 0x0000001F
44 #define CGU0_DIV_S0SEL_SHIFT 5
45 #define CGU0_DIV_S0SEL_MASK (0x3 << CGU0_DIV_S0SEL_SHIFT)
46 #define CGU0_DIV_SYSSEL_SHIFT 8
47 #define CGU0_DIV_SYSSEL_MASK (0x1f << CGU0_DIV_SYSSEL_SHIFT)
48 #define CGU0_DIV_S1SEL_SHIFT 13
49 #define CGU0_DIV_S1SEL_MASK (0x3 << CGU0_DIV_S1SEL_SHIFT)
50 #define CGU0_DIV_DSEL_SHIFT 16
51 #define CGU0_DIV_DSEL_MASK (0x1f << CGU0_DIV_DSEL_SHIFT)
52 #define CGU0_DIV_OSEL_SHIFT 22
53 #define CGU0_DIV_OSEL_MASK (0x7f << CGU0_DIV_OSEL_SHIFT)
54
55 #define CLK(_clk, _devname, _conname)                   \
56         {                                               \
57                 .clk    = &_clk,                  \
58                 .dev_id = _devname,                     \
59                 .con_id = _conname,                     \
60         }
61
62 #define NEEDS_INITIALIZATION 0x11
63
64 static LIST_HEAD(clk_list);
65
66 static void clk_reg_write_mask(u32 reg, uint32_t val, uint32_t mask)
67 {
68         u32 val2;
69
70         val2 = bfin_read32(reg);
71         val2 &= ~mask;
72         val2 |= val;
73         bfin_write32(reg, val2);
74 }
75
76 static void clk_reg_set_bits(u32 reg, uint32_t mask)
77 {
78         u32 val;
79
80         val = bfin_read32(reg);
81         val |= mask;
82         bfin_write32(reg, val);
83 }
84
85 static void clk_reg_clear_bits(u32 reg, uint32_t mask)
86 {
87         u32 val;
88
89         val = bfin_read32(reg);
90         val &= ~mask;
91         bfin_write32(reg, val);
92 }
93
94 int wait_for_pll_align(void)
95 {
96         int i = 10000;
97         while (i-- && (bfin_read32(CGU0_STAT) & CGU0_STAT_CLKSALGN));
98
99         if (bfin_read32(CGU0_STAT) & CGU0_STAT_CLKSALGN) {
100                 printk(KERN_DEBUG "fail to align clk\n");
101                 return -1;
102         }
103         return 0;
104 }
105
106 int clk_enable(struct clk *clk)
107 {
108         int ret = -EIO;
109         if (clk->ops && clk->ops->enable)
110                 ret = clk->ops->enable(clk);
111         return ret;
112 }
113 EXPORT_SYMBOL(clk_enable);
114
115 void clk_disable(struct clk *clk)
116 {
117         if (clk->ops && clk->ops->disable)
118                 clk->ops->disable(clk);
119 }
120 EXPORT_SYMBOL(clk_disable);
121
122 unsigned long clk_get_rate(struct clk *clk)
123 {
124         unsigned long ret = 0;
125         if (clk->ops && clk->ops->get_rate)
126                 ret = clk->ops->get_rate(clk);
127         return ret;
128 }
129 EXPORT_SYMBOL(clk_get_rate);
130
131 long clk_round_rate(struct clk *clk, unsigned long rate)
132 {
133         long ret = -EIO;
134         if (clk->ops && clk->ops->round_rate)
135                 ret = clk->ops->round_rate(clk, rate);
136         return ret;
137 }
138 EXPORT_SYMBOL(clk_round_rate);
139
140 int clk_set_rate(struct clk *clk, unsigned long rate)
141 {
142         int ret = -EIO;
143         if (clk->ops && clk->ops->set_rate)
144                 ret = clk->ops->set_rate(clk, rate);
145         return ret;
146 }
147 EXPORT_SYMBOL(clk_set_rate);
148
149 unsigned long vco_get_rate(struct clk *clk)
150 {
151         return clk->rate;
152 }
153
154 unsigned long pll_get_rate(struct clk *clk)
155 {
156         u32 df;
157         u32 msel;
158         u32 ctl = bfin_read32(CGU0_CTL);
159         u32 stat = bfin_read32(CGU0_STAT);
160         if (stat & CGU0_STAT_PLLBP)
161                 return 0;
162         msel = (ctl & CGU0_CTL_MSEL_MASK) >> CGU0_CTL_MSEL_SHIFT;
163         df = (ctl &  CGU0_CTL_DF);
164         clk->parent->rate = clk_get_rate(clk->parent);
165         return clk->parent->rate / (df + 1) * msel * 2;
166 }
167
168 unsigned long pll_round_rate(struct clk *clk, unsigned long rate)
169 {
170         u32 div;
171         div = rate / clk->parent->rate;
172         return clk->parent->rate * div;
173 }
174
175 int pll_set_rate(struct clk *clk, unsigned long rate)
176 {
177         u32 msel;
178         u32 stat = bfin_read32(CGU0_STAT);
179         if (!(stat & CGU0_STAT_PLLEN))
180                 return -EBUSY;
181         if (!(stat & CGU0_STAT_PLLLK))
182                 return -EBUSY;
183         if (wait_for_pll_align())
184                 return -EBUSY;
185         msel = rate / clk->parent->rate / 2;
186         clk_reg_write_mask(CGU0_CTL, msel << CGU0_CTL_MSEL_SHIFT,
187                 CGU0_CTL_MSEL_MASK);
188         clk->rate = rate;
189         return 0;
190 }
191
192 unsigned long cclk_get_rate(struct clk *clk)
193 {
194         if (clk->parent)
195                 return clk->parent->rate;
196         else
197                 return 0;
198 }
199
200 unsigned long sys_clk_get_rate(struct clk *clk)
201 {
202         unsigned long drate;
203         u32 msel;
204         u32 df;
205         u32 ctl = bfin_read32(CGU0_CTL);
206         u32 div = bfin_read32(CGU0_DIV);
207         div = (div & clk->mask) >> clk->shift;
208         msel = (ctl & CGU0_CTL_MSEL_MASK) >> CGU0_CTL_MSEL_SHIFT;
209         df = (ctl &  CGU0_CTL_DF);
210
211         if (!strcmp(clk->parent->name, "SYS_CLKIN")) {
212                 drate = clk->parent->rate / (df + 1);
213                 drate *=  msel;
214                 drate /= div;
215                 return drate;
216         } else {
217                 clk->parent->rate = clk_get_rate(clk->parent);
218                 return clk->parent->rate / div;
219         }
220 }
221
222 unsigned long sys_clk_round_rate(struct clk *clk, unsigned long rate)
223 {
224         unsigned long max_rate;
225         unsigned long drate;
226         int i;
227         u32 msel;
228         u32 df;
229         u32 ctl = bfin_read32(CGU0_CTL);
230
231         msel = (ctl & CGU0_CTL_MSEL_MASK) >> CGU0_CTL_MSEL_SHIFT;
232         df = (ctl &  CGU0_CTL_DF);
233         max_rate = clk->parent->rate / (df + 1) * msel;
234
235         if (rate > max_rate)
236                 return 0;
237
238         for (i = 1; i < clk->mask; i++) {
239                 drate = max_rate / i;
240                 if (rate >= drate)
241                         return drate;
242         }
243         return 0;
244 }
245
246 int sys_clk_set_rate(struct clk *clk, unsigned long rate)
247 {
248         u32 div = bfin_read32(CGU0_DIV);
249         div = (div & clk->mask) >> clk->shift;
250
251         rate = clk_round_rate(clk, rate);
252
253         if (!rate)
254                 return -EINVAL;
255
256         div = (clk_get_rate(clk) * div) / rate;
257
258         if (wait_for_pll_align())
259                 return -EBUSY;
260         clk_reg_write_mask(CGU0_DIV, div << clk->shift,
261                         clk->mask);
262         clk->rate = rate;
263         return 0;
264 }
265
266 static struct clk_ops vco_ops = {
267         .get_rate = vco_get_rate,
268 };
269
270 static struct clk_ops pll_ops = {
271         .get_rate = pll_get_rate,
272         .set_rate = pll_set_rate,
273 };
274
275 static struct clk_ops cclk_ops = {
276         .get_rate = cclk_get_rate,
277 };
278
279 static struct clk_ops sys_clk_ops = {
280         .get_rate = sys_clk_get_rate,
281         .set_rate = sys_clk_set_rate,
282         .round_rate = sys_clk_round_rate,
283 };
284
285 static struct clk sys_clkin = {
286         .name       = "SYS_CLKIN",
287         .rate       = CONFIG_CLKIN_HZ,
288         .ops        = &vco_ops,
289 };
290
291 static struct clk pll_clk = {
292         .name       = "PLLCLK",
293         .rate       = 500000000,
294         .parent     = &sys_clkin,
295         .ops = &pll_ops,
296         .flags = NEEDS_INITIALIZATION,
297 };
298
299 static struct clk cclk = {
300         .name       = "CCLK",
301         .rate       = 500000000,
302         .mask       = CGU0_DIV_CSEL_MASK,
303         .shift      = CGU0_DIV_CSEL_SHIFT,
304         .parent     = &sys_clkin,
305         .ops        = &sys_clk_ops,
306         .flags = NEEDS_INITIALIZATION,
307 };
308
309 static struct clk cclk0 = {
310         .name       = "CCLK0",
311         .parent     = &cclk,
312         .ops        = &cclk_ops,
313 };
314
315 static struct clk cclk1 = {
316         .name       = "CCLK1",
317         .parent     = &cclk,
318         .ops        = &cclk_ops,
319 };
320
321 static struct clk sysclk = {
322         .name       = "SYSCLK",
323         .rate       = 500000000,
324         .mask       = CGU0_DIV_SYSSEL_MASK,
325         .shift      = CGU0_DIV_SYSSEL_SHIFT,
326         .parent     = &sys_clkin,
327         .ops        = &sys_clk_ops,
328         .flags = NEEDS_INITIALIZATION,
329 };
330
331 static struct clk sclk0 = {
332         .name       = "SCLK0",
333         .rate       = 500000000,
334         .mask       = CGU0_DIV_S0SEL_MASK,
335         .shift      = CGU0_DIV_S0SEL_SHIFT,
336         .parent     = &sysclk,
337         .ops        = &sys_clk_ops,
338 };
339
340 static struct clk sclk1 = {
341         .name       = "SCLK1",
342         .rate       = 500000000,
343         .mask       = CGU0_DIV_S1SEL_MASK,
344         .shift      = CGU0_DIV_S1SEL_SHIFT,
345         .parent     = &sysclk,
346         .ops        = &sys_clk_ops,
347 };
348
349 static struct clk dclk = {
350         .name       = "DCLK",
351         .rate       = 500000000,
352         .mask       = CGU0_DIV_DSEL_MASK,
353         .shift       = CGU0_DIV_DSEL_SHIFT,
354         .parent     = &sys_clkin,
355         .ops        = &sys_clk_ops,
356 };
357
358 static struct clk oclk = {
359         .name       = "OCLK",
360         .rate       = 500000000,
361         .mask       = CGU0_DIV_OSEL_MASK,
362         .shift      = CGU0_DIV_OSEL_SHIFT,
363         .parent     = &pll_clk,
364 };
365
366 static struct clk_lookup bf609_clks[] = {
367         CLK(sys_clkin, NULL, "SYS_CLKIN"),
368         CLK(pll_clk, NULL, "PLLCLK"),
369         CLK(cclk, NULL, "CCLK"),
370         CLK(cclk0, NULL, "CCLK0"),
371         CLK(cclk1, NULL, "CCLK1"),
372         CLK(sysclk, NULL, "SYSCLK"),
373         CLK(sclk0, NULL, "SCLK0"),
374         CLK(sclk1, NULL, "SCLK1"),
375         CLK(dclk, NULL, "DCLK"),
376         CLK(oclk, NULL, "OCLK"),
377 };
378
379 int __init clk_init(void)
380 {
381         int i;
382         struct clk *clkp;
383         for (i = 0; i < ARRAY_SIZE(bf609_clks); i++) {
384                 clkp = bf609_clks[i].clk;
385                 if (clkp->flags & NEEDS_INITIALIZATION)
386                         clk_get_rate(clkp);
387         }
388         clkdev_add_table(bf609_clks, ARRAY_SIZE(bf609_clks));
389         return 0;
390 }