]>
Commit | Line | Data |
---|---|---|
1a0e8a52 KK |
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 | ||
c8bef140 CY |
49 | #define PLL46XX_KDIV_MASK (0xFFFF) |
50 | #define PLL46XX_MDIV_MASK (0x1FF) | |
51 | #define PLL46XX_PDIV_MASK (0x3F) | |
52 | #define PLL46XX_SDIV_MASK (0x7) | |
53 | #define PLL46XX_MDIV_SHIFT (16) | |
54 | #define PLL46XX_PDIV_SHIFT (8) | |
55 | #define PLL46XX_SDIV_SHIFT (0) | |
56 | ||
57 | enum pll46xx_type_t { | |
58 | pll_4600, | |
59 | pll_4650, | |
60 | }; | |
61 | ||
62 | static inline unsigned long s5p_get_pll46xx(unsigned long baseclk, | |
63 | u32 pll_con0, u32 pll_con1, | |
64 | enum pll46xx_type_t pll_type) | |
65 | { | |
66 | unsigned long result; | |
67 | u32 mdiv, pdiv, sdiv, kdiv; | |
68 | u64 tmp; | |
69 | ||
70 | mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK; | |
71 | pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK; | |
72 | sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK; | |
73 | kdiv = pll_con1 & PLL46XX_KDIV_MASK; | |
74 | ||
75 | tmp = baseclk; | |
76 | ||
77 | if (pll_type == pll_4600) { | |
78 | tmp *= (mdiv << 16) + kdiv; | |
79 | do_div(tmp, (pdiv << sdiv)); | |
80 | result = tmp >> 16; | |
81 | } else { | |
82 | tmp *= (mdiv << 10) + kdiv; | |
83 | do_div(tmp, (pdiv << sdiv)); | |
84 | result = tmp >> 10; | |
85 | } | |
86 | ||
87 | return result; | |
88 | } | |
89 | ||
1a0e8a52 KK |
90 | #define PLL90XX_MDIV_MASK (0xFF) |
91 | #define PLL90XX_PDIV_MASK (0x3F) | |
92 | #define PLL90XX_SDIV_MASK (0x7) | |
93 | #define PLL90XX_KDIV_MASK (0xffff) | |
94 | #define PLL90XX_MDIV_SHIFT (16) | |
95 | #define PLL90XX_PDIV_SHIFT (8) | |
96 | #define PLL90XX_SDIV_SHIFT (0) | |
97 | #define PLL90XX_KDIV_SHIFT (0) | |
98 | ||
99 | static inline unsigned long s5p_get_pll90xx(unsigned long baseclk, | |
100 | u32 pll_con, u32 pll_conk) | |
101 | { | |
102 | unsigned long result; | |
103 | u32 mdiv, pdiv, sdiv, kdiv; | |
104 | u64 tmp; | |
105 | ||
106 | mdiv = (pll_con >> PLL90XX_MDIV_SHIFT) & PLL90XX_MDIV_MASK; | |
107 | pdiv = (pll_con >> PLL90XX_PDIV_SHIFT) & PLL90XX_PDIV_MASK; | |
108 | sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK; | |
109 | kdiv = pll_conk & PLL90XX_KDIV_MASK; | |
110 | ||
111 | /* We need to multiple baseclk by mdiv (the integer part) and kdiv | |
112 | * which is in 2^16ths, so shift mdiv up (does not overflow) and | |
113 | * add kdiv before multiplying. The use of tmp is to avoid any | |
114 | * overflows before shifting bac down into result when multipling | |
115 | * by the mdiv and kdiv pair. | |
116 | */ | |
117 | ||
118 | tmp = baseclk; | |
119 | tmp *= (mdiv << 16) + kdiv; | |
120 | do_div(tmp, (pdiv << sdiv)); | |
121 | result = tmp >> 16; | |
122 | ||
123 | return result; | |
124 | } | |
a443a637 TA |
125 | |
126 | #define PLL65XX_MDIV_MASK (0x3FF) | |
127 | #define PLL65XX_PDIV_MASK (0x3F) | |
128 | #define PLL65XX_SDIV_MASK (0x7) | |
129 | #define PLL65XX_MDIV_SHIFT (16) | |
130 | #define PLL65XX_PDIV_SHIFT (8) | |
131 | #define PLL65XX_SDIV_SHIFT (0) | |
132 | ||
133 | static inline unsigned long s5p_get_pll65xx(unsigned long baseclk, u32 pll_con) | |
134 | { | |
135 | u32 mdiv, pdiv, sdiv; | |
136 | u64 fvco = baseclk; | |
137 | ||
138 | mdiv = (pll_con >> PLL65XX_MDIV_SHIFT) & PLL65XX_MDIV_MASK; | |
139 | pdiv = (pll_con >> PLL65XX_PDIV_SHIFT) & PLL65XX_PDIV_MASK; | |
140 | sdiv = (pll_con >> PLL65XX_SDIV_SHIFT) & PLL65XX_SDIV_MASK; | |
141 | ||
142 | fvco *= mdiv; | |
143 | do_div(fvco, (pdiv << sdiv)); | |
144 | ||
145 | return (unsigned long)fvco; | |
146 | } |