ARM: msm: fix compilation flags for MSM_SCM
[pandora-kernel.git] / arch / arm / plat-s5p / include / plat / pll.h
1 /* arch/arm/plat-s5p/include/plat/pll.h
2  *
3  * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4  *              http://www.samsung.com/
5  *
6  * S5P PLL code
7  *
8  * Based on arch/arm/plat-s3c64xx/include/plat/pll.h
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13 */
14
15 #define PLL45XX_MDIV_MASK       (0x3FF)
16 #define PLL45XX_PDIV_MASK       (0x3F)
17 #define PLL45XX_SDIV_MASK       (0x7)
18 #define PLL45XX_MDIV_SHIFT      (16)
19 #define PLL45XX_PDIV_SHIFT      (8)
20 #define PLL45XX_SDIV_SHIFT      (0)
21
22 #include <asm/div64.h>
23
24 enum pll45xx_type_t {
25         pll_4500,
26         pll_4502,
27         pll_4508
28 };
29
30 static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
31                                             enum pll45xx_type_t pll_type)
32 {
33         u32 mdiv, pdiv, sdiv;
34         u64 fvco = baseclk;
35
36         mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
37         pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
38         sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
39
40         if (pll_type == pll_4508)
41                 sdiv = sdiv - 1;
42
43         fvco *= mdiv;
44         do_div(fvco, (pdiv << sdiv));
45
46         return (unsigned long)fvco;
47 }
48
49 #define PLL46XX_KDIV_MASK       (0xFFFF)
50 #define PLL4650C_KDIV_MASK      (0xFFF)
51 #define PLL46XX_MDIV_MASK       (0x1FF)
52 #define PLL46XX_PDIV_MASK       (0x3F)
53 #define PLL46XX_SDIV_MASK       (0x7)
54 #define PLL46XX_MDIV_SHIFT      (16)
55 #define PLL46XX_PDIV_SHIFT      (8)
56 #define PLL46XX_SDIV_SHIFT      (0)
57
58 enum pll46xx_type_t {
59         pll_4600,
60         pll_4650,
61         pll_4650c,
62 };
63
64 static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
65                                             u32 pll_con0, u32 pll_con1,
66                                             enum pll46xx_type_t pll_type)
67 {
68         unsigned long result;
69         u32 mdiv, pdiv, sdiv, kdiv;
70         u64 tmp;
71
72         mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
73         pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
74         sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
75         kdiv = pll_con1 & PLL46XX_KDIV_MASK;
76
77         if (pll_type == pll_4650c)
78                 kdiv = pll_con1 & PLL4650C_KDIV_MASK;
79         else
80                 kdiv = pll_con1 & PLL46XX_KDIV_MASK;
81
82         tmp = baseclk;
83
84         if (pll_type == pll_4600) {
85                 tmp *= (mdiv << 16) + kdiv;
86                 do_div(tmp, (pdiv << sdiv));
87                 result = tmp >> 16;
88         } else {
89                 tmp *= (mdiv << 10) + kdiv;
90                 do_div(tmp, (pdiv << sdiv));
91                 result = tmp >> 10;
92         }
93
94         return result;
95 }
96
97 #define PLL90XX_MDIV_MASK       (0xFF)
98 #define PLL90XX_PDIV_MASK       (0x3F)
99 #define PLL90XX_SDIV_MASK       (0x7)
100 #define PLL90XX_KDIV_MASK       (0xffff)
101 #define PLL90XX_MDIV_SHIFT      (16)
102 #define PLL90XX_PDIV_SHIFT      (8)
103 #define PLL90XX_SDIV_SHIFT      (0)
104 #define PLL90XX_KDIV_SHIFT      (0)
105
106 static inline unsigned long s5p_get_pll90xx(unsigned long baseclk,
107                                             u32 pll_con, u32 pll_conk)
108 {
109         unsigned long result;
110         u32 mdiv, pdiv, sdiv, kdiv;
111         u64 tmp;
112
113         mdiv = (pll_con >> PLL90XX_MDIV_SHIFT) & PLL90XX_MDIV_MASK;
114         pdiv = (pll_con >> PLL90XX_PDIV_SHIFT) & PLL90XX_PDIV_MASK;
115         sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK;
116         kdiv = pll_conk & PLL90XX_KDIV_MASK;
117
118         /* We need to multiple baseclk by mdiv (the integer part) and kdiv
119          * which is in 2^16ths, so shift mdiv up (does not overflow) and
120          * add kdiv before multiplying. The use of tmp is to avoid any
121          * overflows before shifting bac down into result when multipling
122          * by the mdiv and kdiv pair.
123          */
124
125         tmp = baseclk;
126         tmp *= (mdiv << 16) + kdiv;
127         do_div(tmp, (pdiv << sdiv));
128         result = tmp >> 16;
129
130         return result;
131 }
132
133 #define PLL65XX_MDIV_MASK       (0x3FF)
134 #define PLL65XX_PDIV_MASK       (0x3F)
135 #define PLL65XX_SDIV_MASK       (0x7)
136 #define PLL65XX_MDIV_SHIFT      (16)
137 #define PLL65XX_PDIV_SHIFT      (8)
138 #define PLL65XX_SDIV_SHIFT      (0)
139
140 static inline unsigned long s5p_get_pll65xx(unsigned long baseclk, u32 pll_con)
141 {
142         u32 mdiv, pdiv, sdiv;
143         u64 fvco = baseclk;
144
145         mdiv = (pll_con >> PLL65XX_MDIV_SHIFT) & PLL65XX_MDIV_MASK;
146         pdiv = (pll_con >> PLL65XX_PDIV_SHIFT) & PLL65XX_PDIV_MASK;
147         sdiv = (pll_con >> PLL65XX_SDIV_SHIFT) & PLL65XX_SDIV_MASK;
148
149         fvco *= mdiv;
150         do_div(fvco, (pdiv << sdiv));
151
152         return (unsigned long)fvco;
153 }