ext4: fix up a undefined error in ext4_free_blocks in debugging code
[pandora-kernel.git] / arch / arm / plat-samsung / include / plat / pll.h
1 /* linux/arch/arm/plat-samsung/include/plat/pll.h
2  *
3  * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
4  *              http://www.samsung.com/
5  *
6  * Copyright 2008 Openmoko, Inc.
7  * Copyright 2008 Simtec Electronics
8  *      Ben Dooks <ben@simtec.co.uk>
9  *      http://armlinux.simtec.co.uk/
10  *
11  * Samsung PLL codes
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License version 2 as
15  * published by the Free Software Foundation.
16 */
17
18 #include <asm/div64.h>
19
20 #define S3C24XX_PLL_MDIV_MASK           (0xFF)
21 #define S3C24XX_PLL_PDIV_MASK           (0x1F)
22 #define S3C24XX_PLL_SDIV_MASK           (0x3)
23 #define S3C24XX_PLL_MDIV_SHIFT          (12)
24 #define S3C24XX_PLL_PDIV_SHIFT          (4)
25 #define S3C24XX_PLL_SDIV_SHIFT          (0)
26
27 static inline unsigned int s3c24xx_get_pll(unsigned int pllval,
28                                            unsigned int baseclk)
29 {
30         unsigned int mdiv, pdiv, sdiv;
31         uint64_t fvco;
32
33         mdiv = (pllval >> S3C24XX_PLL_MDIV_SHIFT) & S3C24XX_PLL_MDIV_MASK;
34         pdiv = (pllval >> S3C24XX_PLL_PDIV_SHIFT) & S3C24XX_PLL_PDIV_MASK;
35         sdiv = (pllval >> S3C24XX_PLL_SDIV_SHIFT) & S3C24XX_PLL_SDIV_MASK;
36
37         fvco = (uint64_t)baseclk * (mdiv + 8);
38         do_div(fvco, (pdiv + 2) << sdiv);
39
40         return (unsigned int)fvco;
41 }
42
43 #define S3C2416_PLL_MDIV_MASK           (0x3FF)
44 #define S3C2416_PLL_PDIV_MASK           (0x3F)
45 #define S3C2416_PLL_SDIV_MASK           (0x7)
46 #define S3C2416_PLL_MDIV_SHIFT          (14)
47 #define S3C2416_PLL_PDIV_SHIFT          (5)
48 #define S3C2416_PLL_SDIV_SHIFT          (0)
49
50 static inline unsigned int s3c2416_get_pll(unsigned int pllval,
51                                            unsigned int baseclk)
52 {
53         unsigned int mdiv, pdiv, sdiv;
54         uint64_t fvco;
55
56         mdiv = (pllval >> S3C2416_PLL_MDIV_SHIFT) & S3C2416_PLL_MDIV_MASK;
57         pdiv = (pllval >> S3C2416_PLL_PDIV_SHIFT) & S3C2416_PLL_PDIV_MASK;
58         sdiv = (pllval >> S3C2416_PLL_SDIV_SHIFT) & S3C2416_PLL_SDIV_MASK;
59
60         fvco = (uint64_t)baseclk * mdiv;
61         do_div(fvco, (pdiv << sdiv));
62
63         return (unsigned int)fvco;
64 }
65
66 #define S3C6400_PLL_MDIV_MASK           (0x3FF)
67 #define S3C6400_PLL_PDIV_MASK           (0x3F)
68 #define S3C6400_PLL_SDIV_MASK           (0x7)
69 #define S3C6400_PLL_MDIV_SHIFT          (16)
70 #define S3C6400_PLL_PDIV_SHIFT          (8)
71 #define S3C6400_PLL_SDIV_SHIFT          (0)
72
73 static inline unsigned long s3c6400_get_pll(unsigned long baseclk,
74                                             u32 pllcon)
75 {
76         u32 mdiv, pdiv, sdiv;
77         u64 fvco = baseclk;
78
79         mdiv = (pllcon >> S3C6400_PLL_MDIV_SHIFT) & S3C6400_PLL_MDIV_MASK;
80         pdiv = (pllcon >> S3C6400_PLL_PDIV_SHIFT) & S3C6400_PLL_PDIV_MASK;
81         sdiv = (pllcon >> S3C6400_PLL_SDIV_SHIFT) & S3C6400_PLL_SDIV_MASK;
82
83         fvco *= mdiv;
84         do_div(fvco, (pdiv << sdiv));
85
86         return (unsigned long)fvco;
87 }
88
89 #define PLL6553X_MDIV_MASK      (0x7F)
90 #define PLL6553X_PDIV_MASK      (0x1F)
91 #define PLL6553X_SDIV_MASK      (0x3)
92 #define PLL6553X_KDIV_MASK      (0xFFFF)
93 #define PLL6553X_MDIV_SHIFT     (16)
94 #define PLL6553X_PDIV_SHIFT     (8)
95 #define PLL6553X_SDIV_SHIFT     (0)
96
97 static inline unsigned long s3c_get_pll6553x(unsigned long baseclk,
98                                              u32 pll_con0, u32 pll_con1)
99 {
100         unsigned long result;
101         u32 mdiv, pdiv, sdiv, kdiv;
102         u64 tmp;
103
104         mdiv = (pll_con0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK;
105         pdiv = (pll_con0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK;
106         sdiv = (pll_con0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK;
107         kdiv = pll_con1 & PLL6553X_KDIV_MASK;
108
109         /*
110          * We need to multiple baseclk by mdiv (the integer part) and kdiv
111          * which is in 2^16ths, so shift mdiv up (does not overflow) and
112          * add kdiv before multiplying. The use of tmp is to avoid any
113          * overflows before shifting bac down into result when multipling
114          * by the mdiv and kdiv pair.
115          */
116
117         tmp = baseclk;
118         tmp *= (mdiv << 16) + kdiv;
119         do_div(tmp, (pdiv << sdiv));
120         result = tmp >> 16;
121
122         return result;
123 }
124
125 #define PLL35XX_MDIV_MASK       (0x3FF)
126 #define PLL35XX_PDIV_MASK       (0x3F)
127 #define PLL35XX_SDIV_MASK       (0x7)
128 #define PLL35XX_MDIV_SHIFT      (16)
129 #define PLL35XX_PDIV_SHIFT      (8)
130 #define PLL35XX_SDIV_SHIFT      (0)
131
132 static inline unsigned long s5p_get_pll35xx(unsigned long baseclk, u32 pll_con)
133 {
134         u32 mdiv, pdiv, sdiv;
135         u64 fvco = baseclk;
136
137         mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
138         pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
139         sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
140
141         fvco *= mdiv;
142         do_div(fvco, (pdiv << sdiv));
143
144         return (unsigned long)fvco;
145 }
146
147 #define PLL36XX_KDIV_MASK       (0xFFFF)
148 #define PLL36XX_MDIV_MASK       (0x1FF)
149 #define PLL36XX_PDIV_MASK       (0x3F)
150 #define PLL36XX_SDIV_MASK       (0x7)
151 #define PLL36XX_MDIV_SHIFT      (16)
152 #define PLL36XX_PDIV_SHIFT      (8)
153 #define PLL36XX_SDIV_SHIFT      (0)
154
155 static inline unsigned long s5p_get_pll36xx(unsigned long baseclk,
156                                             u32 pll_con0, u32 pll_con1)
157 {
158         unsigned long result;
159         u32 mdiv, pdiv, sdiv, kdiv;
160         u64 tmp;
161
162         mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
163         pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
164         sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
165         kdiv = pll_con1 & PLL36XX_KDIV_MASK;
166
167         tmp = baseclk;
168
169         tmp *= (mdiv << 16) + kdiv;
170         do_div(tmp, (pdiv << sdiv));
171         result = tmp >> 16;
172
173         return result;
174 }
175
176 #define PLL45XX_MDIV_MASK       (0x3FF)
177 #define PLL45XX_PDIV_MASK       (0x3F)
178 #define PLL45XX_SDIV_MASK       (0x7)
179 #define PLL45XX_MDIV_SHIFT      (16)
180 #define PLL45XX_PDIV_SHIFT      (8)
181 #define PLL45XX_SDIV_SHIFT      (0)
182
183 enum pll45xx_type_t {
184         pll_4500,
185         pll_4502,
186         pll_4508
187 };
188
189 static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
190                                             enum pll45xx_type_t pll_type)
191 {
192         u32 mdiv, pdiv, sdiv;
193         u64 fvco = baseclk;
194
195         mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
196         pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
197         sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
198
199         if (pll_type == pll_4508)
200                 sdiv = sdiv - 1;
201
202         fvco *= mdiv;
203         do_div(fvco, (pdiv << sdiv));
204
205         return (unsigned long)fvco;
206 }
207
208 /* CON0 bit-fields */
209 #define PLL46XX_MDIV_MASK       (0x1FF)
210 #define PLL46XX_PDIV_MASK       (0x3F)
211 #define PLL46XX_SDIV_MASK       (0x7)
212 #define PLL46XX_LOCKED_SHIFT    (29)
213 #define PLL46XX_MDIV_SHIFT      (16)
214 #define PLL46XX_PDIV_SHIFT      (8)
215 #define PLL46XX_SDIV_SHIFT      (0)
216
217 /* CON1 bit-fields */
218 #define PLL46XX_MRR_MASK        (0x1F)
219 #define PLL46XX_MFR_MASK        (0x3F)
220 #define PLL46XX_KDIV_MASK       (0xFFFF)
221 #define PLL4650C_KDIV_MASK      (0xFFF)
222 #define PLL46XX_MRR_SHIFT       (24)
223 #define PLL46XX_MFR_SHIFT       (16)
224 #define PLL46XX_KDIV_SHIFT      (0)
225
226 enum pll46xx_type_t {
227         pll_4600,
228         pll_4650,
229         pll_4650c,
230 };
231
232 static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
233                                             u32 pll_con0, u32 pll_con1,
234                                             enum pll46xx_type_t pll_type)
235 {
236         unsigned long result;
237         u32 mdiv, pdiv, sdiv, kdiv;
238         u64 tmp;
239
240         mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
241         pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
242         sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
243         kdiv = pll_con1 & PLL46XX_KDIV_MASK;
244
245         if (pll_type == pll_4650c)
246                 kdiv = pll_con1 & PLL4650C_KDIV_MASK;
247         else
248                 kdiv = pll_con1 & PLL46XX_KDIV_MASK;
249
250         tmp = baseclk;
251
252         if (pll_type == pll_4600) {
253                 tmp *= (mdiv << 16) + kdiv;
254                 do_div(tmp, (pdiv << sdiv));
255                 result = tmp >> 16;
256         } else {
257                 tmp *= (mdiv << 10) + kdiv;
258                 do_div(tmp, (pdiv << sdiv));
259                 result = tmp >> 10;
260         }
261
262         return result;
263 }
264
265 #define PLL90XX_MDIV_MASK       (0xFF)
266 #define PLL90XX_PDIV_MASK       (0x3F)
267 #define PLL90XX_SDIV_MASK       (0x7)
268 #define PLL90XX_KDIV_MASK       (0xffff)
269 #define PLL90XX_LOCKED_SHIFT    (29)
270 #define PLL90XX_MDIV_SHIFT      (16)
271 #define PLL90XX_PDIV_SHIFT      (8)
272 #define PLL90XX_SDIV_SHIFT      (0)
273 #define PLL90XX_KDIV_SHIFT      (0)
274
275 static inline unsigned long s5p_get_pll90xx(unsigned long baseclk,
276                                             u32 pll_con, u32 pll_conk)
277 {
278         unsigned long result;
279         u32 mdiv, pdiv, sdiv, kdiv;
280         u64 tmp;
281
282         mdiv = (pll_con >> PLL90XX_MDIV_SHIFT) & PLL90XX_MDIV_MASK;
283         pdiv = (pll_con >> PLL90XX_PDIV_SHIFT) & PLL90XX_PDIV_MASK;
284         sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK;
285         kdiv = pll_conk & PLL90XX_KDIV_MASK;
286
287         /*
288          * We need to multiple baseclk by mdiv (the integer part) and kdiv
289          * which is in 2^16ths, so shift mdiv up (does not overflow) and
290          * add kdiv before multiplying. The use of tmp is to avoid any
291          * overflows before shifting bac down into result when multipling
292          * by the mdiv and kdiv pair.
293          */
294
295         tmp = baseclk;
296         tmp *= (mdiv << 16) + kdiv;
297         do_div(tmp, (pdiv << sdiv));
298         result = tmp >> 16;
299
300         return result;
301 }
302
303 #define PLL65XX_MDIV_MASK       (0x3FF)
304 #define PLL65XX_PDIV_MASK       (0x3F)
305 #define PLL65XX_SDIV_MASK       (0x7)
306 #define PLL65XX_MDIV_SHIFT      (16)
307 #define PLL65XX_PDIV_SHIFT      (8)
308 #define PLL65XX_SDIV_SHIFT      (0)
309
310 static inline unsigned long s5p_get_pll65xx(unsigned long baseclk, u32 pll_con)
311 {
312         u32 mdiv, pdiv, sdiv;
313         u64 fvco = baseclk;
314
315         mdiv = (pll_con >> PLL65XX_MDIV_SHIFT) & PLL65XX_MDIV_MASK;
316         pdiv = (pll_con >> PLL65XX_PDIV_SHIFT) & PLL65XX_PDIV_MASK;
317         sdiv = (pll_con >> PLL65XX_SDIV_SHIFT) & PLL65XX_SDIV_MASK;
318
319         fvco *= mdiv;
320         do_div(fvco, (pdiv << sdiv));
321
322         return (unsigned long)fvco;
323 }