diff options
-rw-r--r-- | arch/arm/mach-spear3xx/clock.c | 66 | ||||
-rw-r--r-- | arch/arm/mach-spear6xx/clock.c | 67 | ||||
-rw-r--r-- | arch/arm/plat-spear/clock.c | 59 | ||||
-rw-r--r-- | arch/arm/plat-spear/include/plat/clock.h | 68 |
4 files changed, 214 insertions, 46 deletions
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c index 18febf92f20a..7ea8749ddf28 100644 --- a/arch/arm/mach-spear3xx/clock.c +++ b/arch/arm/mach-spear3xx/clock.c | |||
@@ -39,10 +39,25 @@ static struct clk rtc_clk = { | |||
39 | }; | 39 | }; |
40 | 40 | ||
41 | /* clock derived from 24 MHz osc clk */ | 41 | /* clock derived from 24 MHz osc clk */ |
42 | /* pll masks structure */ | ||
43 | static struct pll_clk_masks pll1_masks = { | ||
44 | .mode_mask = PLL_MODE_MASK, | ||
45 | .mode_shift = PLL_MODE_SHIFT, | ||
46 | .norm_fdbk_m_mask = PLL_NORM_FDBK_M_MASK, | ||
47 | .norm_fdbk_m_shift = PLL_NORM_FDBK_M_SHIFT, | ||
48 | .dith_fdbk_m_mask = PLL_DITH_FDBK_M_MASK, | ||
49 | .dith_fdbk_m_shift = PLL_DITH_FDBK_M_SHIFT, | ||
50 | .div_p_mask = PLL_DIV_P_MASK, | ||
51 | .div_p_shift = PLL_DIV_P_SHIFT, | ||
52 | .div_n_mask = PLL_DIV_N_MASK, | ||
53 | .div_n_shift = PLL_DIV_N_SHIFT, | ||
54 | }; | ||
55 | |||
42 | /* pll1 configuration structure */ | 56 | /* pll1 configuration structure */ |
43 | static struct pll_clk_config pll1_config = { | 57 | static struct pll_clk_config pll1_config = { |
44 | .mode_reg = PLL1_CTR, | 58 | .mode_reg = PLL1_CTR, |
45 | .cfg_reg = PLL1_FRQ, | 59 | .cfg_reg = PLL1_FRQ, |
60 | .masks = &pll1_masks, | ||
46 | }; | 61 | }; |
47 | 62 | ||
48 | /* PLL1 clock */ | 63 | /* PLL1 clock */ |
@@ -50,7 +65,7 @@ static struct clk pll1_clk = { | |||
50 | .pclk = &osc_24m_clk, | 65 | .pclk = &osc_24m_clk, |
51 | .en_reg = PLL1_CTR, | 66 | .en_reg = PLL1_CTR, |
52 | .en_reg_bit = PLL_ENABLE, | 67 | .en_reg_bit = PLL_ENABLE, |
53 | .recalc = &pll1_clk_recalc, | 68 | .recalc = &pll_clk_recalc, |
54 | .private_data = &pll1_config, | 69 | .private_data = &pll1_config, |
55 | }; | 70 | }; |
56 | 71 | ||
@@ -76,11 +91,16 @@ static struct clk cpu_clk = { | |||
76 | .recalc = &follow_parent, | 91 | .recalc = &follow_parent, |
77 | }; | 92 | }; |
78 | 93 | ||
94 | /* ahb masks structure */ | ||
95 | static struct bus_clk_masks ahb_masks = { | ||
96 | .mask = PLL_HCLK_RATIO_MASK, | ||
97 | .shift = PLL_HCLK_RATIO_SHIFT, | ||
98 | }; | ||
99 | |||
79 | /* ahb configuration structure */ | 100 | /* ahb configuration structure */ |
80 | static struct bus_clk_config ahb_config = { | 101 | static struct bus_clk_config ahb_config = { |
81 | .reg = CORE_CLK_CFG, | 102 | .reg = CORE_CLK_CFG, |
82 | .mask = PLL_HCLK_RATIO_MASK, | 103 | .masks = &ahb_masks, |
83 | .shift = PLL_HCLK_RATIO_SHIFT, | ||
84 | }; | 104 | }; |
85 | 105 | ||
86 | /* ahb clock */ | 106 | /* ahb clock */ |
@@ -91,9 +111,22 @@ static struct clk ahb_clk = { | |||
91 | .private_data = &ahb_config, | 111 | .private_data = &ahb_config, |
92 | }; | 112 | }; |
93 | 113 | ||
114 | /* auxiliary synthesizers masks */ | ||
115 | static struct aux_clk_masks aux_masks = { | ||
116 | .eq_sel_mask = AUX_EQ_SEL_MASK, | ||
117 | .eq_sel_shift = AUX_EQ_SEL_SHIFT, | ||
118 | .eq1_mask = AUX_EQ1_SEL, | ||
119 | .eq2_mask = AUX_EQ2_SEL, | ||
120 | .xscale_sel_mask = AUX_XSCALE_MASK, | ||
121 | .xscale_sel_shift = AUX_XSCALE_SHIFT, | ||
122 | .yscale_sel_mask = AUX_YSCALE_MASK, | ||
123 | .yscale_sel_shift = AUX_YSCALE_SHIFT, | ||
124 | }; | ||
125 | |||
94 | /* uart configurations */ | 126 | /* uart configurations */ |
95 | static struct aux_clk_config uart_config = { | 127 | static struct aux_clk_config uart_config = { |
96 | .synth_reg = UART_CLK_SYNT, | 128 | .synth_reg = UART_CLK_SYNT, |
129 | .masks = &aux_masks, | ||
97 | }; | 130 | }; |
98 | 131 | ||
99 | /* uart parents */ | 132 | /* uart parents */ |
@@ -130,6 +163,7 @@ static struct clk uart_clk = { | |||
130 | /* firda configurations */ | 163 | /* firda configurations */ |
131 | static struct aux_clk_config firda_config = { | 164 | static struct aux_clk_config firda_config = { |
132 | .synth_reg = FIRDA_CLK_SYNT, | 165 | .synth_reg = FIRDA_CLK_SYNT, |
166 | .masks = &aux_masks, | ||
133 | }; | 167 | }; |
134 | 168 | ||
135 | /* firda parents */ | 169 | /* firda parents */ |
@@ -184,9 +218,18 @@ static struct pclk_sel gpt_pclk_sel = { | |||
184 | .pclk_sel_mask = GPT_CLK_MASK, | 218 | .pclk_sel_mask = GPT_CLK_MASK, |
185 | }; | 219 | }; |
186 | 220 | ||
221 | /* gpt synthesizer masks */ | ||
222 | static struct gpt_clk_masks gpt_masks = { | ||
223 | .mscale_sel_mask = GPT_MSCALE_MASK, | ||
224 | .mscale_sel_shift = GPT_MSCALE_SHIFT, | ||
225 | .nscale_sel_mask = GPT_NSCALE_MASK, | ||
226 | .nscale_sel_shift = GPT_NSCALE_SHIFT, | ||
227 | }; | ||
228 | |||
187 | /* gpt0 configurations */ | 229 | /* gpt0 configurations */ |
188 | static struct aux_clk_config gpt0_config = { | 230 | static struct gpt_clk_config gpt0_config = { |
189 | .synth_reg = PRSC1_CLK_CFG, | 231 | .synth_reg = PRSC1_CLK_CFG, |
232 | .masks = &gpt_masks, | ||
190 | }; | 233 | }; |
191 | 234 | ||
192 | /* gpt0 timer clock */ | 235 | /* gpt0 timer clock */ |
@@ -199,8 +242,9 @@ static struct clk gpt0_clk = { | |||
199 | }; | 242 | }; |
200 | 243 | ||
201 | /* gpt1 configurations */ | 244 | /* gpt1 configurations */ |
202 | static struct aux_clk_config gpt1_config = { | 245 | static struct gpt_clk_config gpt1_config = { |
203 | .synth_reg = PRSC2_CLK_CFG, | 246 | .synth_reg = PRSC2_CLK_CFG, |
247 | .masks = &gpt_masks, | ||
204 | }; | 248 | }; |
205 | 249 | ||
206 | /* gpt1 timer clock */ | 250 | /* gpt1 timer clock */ |
@@ -214,8 +258,9 @@ static struct clk gpt1_clk = { | |||
214 | }; | 258 | }; |
215 | 259 | ||
216 | /* gpt2 configurations */ | 260 | /* gpt2 configurations */ |
217 | static struct aux_clk_config gpt2_config = { | 261 | static struct gpt_clk_config gpt2_config = { |
218 | .synth_reg = PRSC3_CLK_CFG, | 262 | .synth_reg = PRSC3_CLK_CFG, |
263 | .masks = &gpt_masks, | ||
219 | }; | 264 | }; |
220 | 265 | ||
221 | /* gpt2 timer clock */ | 266 | /* gpt2 timer clock */ |
@@ -253,11 +298,16 @@ static struct clk clcd_clk = { | |||
253 | }; | 298 | }; |
254 | 299 | ||
255 | /* clock derived from ahb clk */ | 300 | /* clock derived from ahb clk */ |
301 | /* apb masks structure */ | ||
302 | static struct bus_clk_masks apb_masks = { | ||
303 | .mask = HCLK_PCLK_RATIO_MASK, | ||
304 | .shift = HCLK_PCLK_RATIO_SHIFT, | ||
305 | }; | ||
306 | |||
256 | /* apb configuration structure */ | 307 | /* apb configuration structure */ |
257 | static struct bus_clk_config apb_config = { | 308 | static struct bus_clk_config apb_config = { |
258 | .reg = CORE_CLK_CFG, | 309 | .reg = CORE_CLK_CFG, |
259 | .mask = HCLK_PCLK_RATIO_MASK, | 310 | .masks = &apb_masks, |
260 | .shift = HCLK_PCLK_RATIO_SHIFT, | ||
261 | }; | 311 | }; |
262 | 312 | ||
263 | /* apb clock */ | 313 | /* apb clock */ |
diff --git a/arch/arm/mach-spear6xx/clock.c b/arch/arm/mach-spear6xx/clock.c index 36ff056b7321..ef88922986e0 100644 --- a/arch/arm/mach-spear6xx/clock.c +++ b/arch/arm/mach-spear6xx/clock.c | |||
@@ -39,10 +39,25 @@ static struct clk rtc_clk = { | |||
39 | }; | 39 | }; |
40 | 40 | ||
41 | /* clock derived from 30 MHz osc clk */ | 41 | /* clock derived from 30 MHz osc clk */ |
42 | /* pll masks structure */ | ||
43 | static struct pll_clk_masks pll1_masks = { | ||
44 | .mode_mask = PLL_MODE_MASK, | ||
45 | .mode_shift = PLL_MODE_SHIFT, | ||
46 | .norm_fdbk_m_mask = PLL_NORM_FDBK_M_MASK, | ||
47 | .norm_fdbk_m_shift = PLL_NORM_FDBK_M_SHIFT, | ||
48 | .dith_fdbk_m_mask = PLL_DITH_FDBK_M_MASK, | ||
49 | .dith_fdbk_m_shift = PLL_DITH_FDBK_M_SHIFT, | ||
50 | .div_p_mask = PLL_DIV_P_MASK, | ||
51 | .div_p_shift = PLL_DIV_P_SHIFT, | ||
52 | .div_n_mask = PLL_DIV_N_MASK, | ||
53 | .div_n_shift = PLL_DIV_N_SHIFT, | ||
54 | }; | ||
55 | |||
42 | /* pll1 configuration structure */ | 56 | /* pll1 configuration structure */ |
43 | static struct pll_clk_config pll1_config = { | 57 | static struct pll_clk_config pll1_config = { |
44 | .mode_reg = PLL1_CTR, | 58 | .mode_reg = PLL1_CTR, |
45 | .cfg_reg = PLL1_FRQ, | 59 | .cfg_reg = PLL1_FRQ, |
60 | .masks = &pll1_masks, | ||
46 | }; | 61 | }; |
47 | 62 | ||
48 | /* PLL1 clock */ | 63 | /* PLL1 clock */ |
@@ -50,7 +65,7 @@ static struct clk pll1_clk = { | |||
50 | .pclk = &osc_30m_clk, | 65 | .pclk = &osc_30m_clk, |
51 | .en_reg = PLL1_CTR, | 66 | .en_reg = PLL1_CTR, |
52 | .en_reg_bit = PLL_ENABLE, | 67 | .en_reg_bit = PLL_ENABLE, |
53 | .recalc = &pll1_clk_recalc, | 68 | .recalc = &pll_clk_recalc, |
54 | .private_data = &pll1_config, | 69 | .private_data = &pll1_config, |
55 | }; | 70 | }; |
56 | 71 | ||
@@ -76,11 +91,16 @@ static struct clk cpu_clk = { | |||
76 | .recalc = &follow_parent, | 91 | .recalc = &follow_parent, |
77 | }; | 92 | }; |
78 | 93 | ||
94 | /* ahb masks structure */ | ||
95 | static struct bus_clk_masks ahb_masks = { | ||
96 | .mask = PLL_HCLK_RATIO_MASK, | ||
97 | .shift = PLL_HCLK_RATIO_SHIFT, | ||
98 | }; | ||
99 | |||
79 | /* ahb configuration structure */ | 100 | /* ahb configuration structure */ |
80 | static struct bus_clk_config ahb_config = { | 101 | static struct bus_clk_config ahb_config = { |
81 | .reg = CORE_CLK_CFG, | 102 | .reg = CORE_CLK_CFG, |
82 | .mask = PLL_HCLK_RATIO_MASK, | 103 | .masks = &ahb_masks, |
83 | .shift = PLL_HCLK_RATIO_SHIFT, | ||
84 | }; | 104 | }; |
85 | 105 | ||
86 | /* ahb clock */ | 106 | /* ahb clock */ |
@@ -112,9 +132,22 @@ static struct pclk_sel uart_pclk_sel = { | |||
112 | .pclk_sel_mask = UART_CLK_MASK, | 132 | .pclk_sel_mask = UART_CLK_MASK, |
113 | }; | 133 | }; |
114 | 134 | ||
135 | /* auxiliary synthesizers masks */ | ||
136 | static struct aux_clk_masks aux_masks = { | ||
137 | .eq_sel_mask = AUX_EQ_SEL_MASK, | ||
138 | .eq_sel_shift = AUX_EQ_SEL_SHIFT, | ||
139 | .eq1_mask = AUX_EQ1_SEL, | ||
140 | .eq2_mask = AUX_EQ2_SEL, | ||
141 | .xscale_sel_mask = AUX_XSCALE_MASK, | ||
142 | .xscale_sel_shift = AUX_XSCALE_SHIFT, | ||
143 | .yscale_sel_mask = AUX_YSCALE_MASK, | ||
144 | .yscale_sel_shift = AUX_YSCALE_SHIFT, | ||
145 | }; | ||
146 | |||
115 | /* uart configurations */ | 147 | /* uart configurations */ |
116 | static struct aux_clk_config uart_config = { | 148 | static struct aux_clk_config uart_config = { |
117 | .synth_reg = UART_CLK_SYNT, | 149 | .synth_reg = UART_CLK_SYNT, |
150 | .masks = &aux_masks, | ||
118 | }; | 151 | }; |
119 | 152 | ||
120 | /* uart0 clock */ | 153 | /* uart0 clock */ |
@@ -140,6 +173,7 @@ static struct clk uart1_clk = { | |||
140 | /* firda configurations */ | 173 | /* firda configurations */ |
141 | static struct aux_clk_config firda_config = { | 174 | static struct aux_clk_config firda_config = { |
142 | .synth_reg = FIRDA_CLK_SYNT, | 175 | .synth_reg = FIRDA_CLK_SYNT, |
176 | .masks = &aux_masks, | ||
143 | }; | 177 | }; |
144 | 178 | ||
145 | /* firda parents */ | 179 | /* firda parents */ |
@@ -176,6 +210,7 @@ static struct clk firda_clk = { | |||
176 | /* clcd configurations */ | 210 | /* clcd configurations */ |
177 | static struct aux_clk_config clcd_config = { | 211 | static struct aux_clk_config clcd_config = { |
178 | .synth_reg = CLCD_CLK_SYNT, | 212 | .synth_reg = CLCD_CLK_SYNT, |
213 | .masks = &aux_masks, | ||
179 | }; | 214 | }; |
180 | 215 | ||
181 | /* clcd parents */ | 216 | /* clcd parents */ |
@@ -230,9 +265,18 @@ static struct pclk_sel gpt_pclk_sel = { | |||
230 | .pclk_sel_mask = GPT_CLK_MASK, | 265 | .pclk_sel_mask = GPT_CLK_MASK, |
231 | }; | 266 | }; |
232 | 267 | ||
268 | /* gpt synthesizer masks */ | ||
269 | static struct gpt_clk_masks gpt_masks = { | ||
270 | .mscale_sel_mask = GPT_MSCALE_MASK, | ||
271 | .mscale_sel_shift = GPT_MSCALE_SHIFT, | ||
272 | .nscale_sel_mask = GPT_NSCALE_MASK, | ||
273 | .nscale_sel_shift = GPT_NSCALE_SHIFT, | ||
274 | }; | ||
275 | |||
233 | /* gpt0_1 configurations */ | 276 | /* gpt0_1 configurations */ |
234 | static struct aux_clk_config gpt0_1_config = { | 277 | static struct gpt_clk_config gpt0_1_config = { |
235 | .synth_reg = PRSC1_CLK_CFG, | 278 | .synth_reg = PRSC1_CLK_CFG, |
279 | .masks = &gpt_masks, | ||
236 | }; | 280 | }; |
237 | 281 | ||
238 | /* gpt0 ARM1 subsystem timer clock */ | 282 | /* gpt0 ARM1 subsystem timer clock */ |
@@ -254,8 +298,9 @@ static struct clk gpt1_clk = { | |||
254 | }; | 298 | }; |
255 | 299 | ||
256 | /* gpt2 configurations */ | 300 | /* gpt2 configurations */ |
257 | static struct aux_clk_config gpt2_config = { | 301 | static struct gpt_clk_config gpt2_config = { |
258 | .synth_reg = PRSC2_CLK_CFG, | 302 | .synth_reg = PRSC2_CLK_CFG, |
303 | .masks = &gpt_masks, | ||
259 | }; | 304 | }; |
260 | 305 | ||
261 | /* gpt2 timer clock */ | 306 | /* gpt2 timer clock */ |
@@ -269,8 +314,9 @@ static struct clk gpt2_clk = { | |||
269 | }; | 314 | }; |
270 | 315 | ||
271 | /* gpt3 configurations */ | 316 | /* gpt3 configurations */ |
272 | static struct aux_clk_config gpt3_config = { | 317 | static struct gpt_clk_config gpt3_config = { |
273 | .synth_reg = PRSC3_CLK_CFG, | 318 | .synth_reg = PRSC3_CLK_CFG, |
319 | .masks = &gpt_masks, | ||
274 | }; | 320 | }; |
275 | 321 | ||
276 | /* gpt3 timer clock */ | 322 | /* gpt3 timer clock */ |
@@ -309,11 +355,16 @@ static struct clk usbd_clk = { | |||
309 | }; | 355 | }; |
310 | 356 | ||
311 | /* clock derived from ahb clk */ | 357 | /* clock derived from ahb clk */ |
358 | /* apb masks structure */ | ||
359 | static struct bus_clk_masks apb_masks = { | ||
360 | .mask = HCLK_PCLK_RATIO_MASK, | ||
361 | .shift = HCLK_PCLK_RATIO_SHIFT, | ||
362 | }; | ||
363 | |||
312 | /* apb configuration structure */ | 364 | /* apb configuration structure */ |
313 | static struct bus_clk_config apb_config = { | 365 | static struct bus_clk_config apb_config = { |
314 | .reg = CORE_CLK_CFG, | 366 | .reg = CORE_CLK_CFG, |
315 | .mask = HCLK_PCLK_RATIO_MASK, | 367 | .masks = &apb_masks, |
316 | .shift = HCLK_PCLK_RATIO_SHIFT, | ||
317 | }; | 368 | }; |
318 | 369 | ||
319 | /* apb clock */ | 370 | /* apb clock */ |
diff --git a/arch/arm/plat-spear/clock.c b/arch/arm/plat-spear/clock.c index ee4f90e534d8..f1cf832e4e3b 100644 --- a/arch/arm/plat-spear/clock.c +++ b/arch/arm/plat-spear/clock.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/list.h> | 17 | #include <linux/list.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
20 | #include <mach/misc_regs.h> | ||
21 | #include <plat/clock.h> | 20 | #include <plat/clock.h> |
22 | 21 | ||
23 | static DEFINE_SPINLOCK(clocks_lock); | 22 | static DEFINE_SPINLOCK(clocks_lock); |
@@ -187,6 +186,20 @@ int clk_set_parent(struct clk *clk, struct clk *parent) | |||
187 | } | 186 | } |
188 | EXPORT_SYMBOL(clk_set_parent); | 187 | EXPORT_SYMBOL(clk_set_parent); |
189 | 188 | ||
189 | /** | ||
190 | * clk_set_rate - set the clock rate for a clock source | ||
191 | * @clk: clock source | ||
192 | * @rate: desired clock rate in Hz | ||
193 | * | ||
194 | * Returns success (0) or negative errno. | ||
195 | */ | ||
196 | int clk_set_rate(struct clk *clk, unsigned long rate) | ||
197 | { | ||
198 | /* TODO */ | ||
199 | return -EINVAL; | ||
200 | } | ||
201 | EXPORT_SYMBOL(clk_set_rate); | ||
202 | |||
190 | /* registers clock in platform clock framework */ | 203 | /* registers clock in platform clock framework */ |
191 | void clk_register(struct clk_lookup *cl) | 204 | void clk_register(struct clk_lookup *cl) |
192 | { | 205 | { |
@@ -212,6 +225,7 @@ void clk_register(struct clk_lookup *cl) | |||
212 | list_add(&clk->sibling, &clk->pclk->children); | 225 | list_add(&clk->sibling, &clk->pclk->children); |
213 | } else { | 226 | } else { |
214 | /* add clocks with > 1 parent to 1st parent's children list */ | 227 | /* add clocks with > 1 parent to 1st parent's children list */ |
228 | clk->pclk = clk->pclk_sel->pclk_info[0].pclk; | ||
215 | list_add(&clk->sibling, | 229 | list_add(&clk->sibling, |
216 | &clk->pclk_sel->pclk_info[0].pclk->children); | 230 | &clk->pclk_sel->pclk_info[0].pclk->children); |
217 | } | 231 | } |
@@ -283,29 +297,31 @@ static void change_parent(struct clk *cclk, struct clk *pclk) | |||
283 | * In Dithered mode | 297 | * In Dithered mode |
284 | * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P) | 298 | * rate = (2 * M[15:0] * Fin)/(256 * N * 2^P) |
285 | */ | 299 | */ |
286 | void pll1_clk_recalc(struct clk *clk) | 300 | void pll_clk_recalc(struct clk *clk) |
287 | { | 301 | { |
288 | struct pll_clk_config *config = clk->private_data; | 302 | struct pll_clk_config *config = clk->private_data; |
289 | unsigned int num = 2, den = 0, val, mode = 0; | 303 | unsigned int num = 2, den = 0, val, mode = 0; |
290 | unsigned long flags; | 304 | unsigned long flags; |
291 | 305 | ||
292 | spin_lock_irqsave(&clocks_lock, flags); | 306 | spin_lock_irqsave(&clocks_lock, flags); |
293 | mode = (readl(config->mode_reg) >> PLL_MODE_SHIFT) & | 307 | mode = (readl(config->mode_reg) >> config->masks->mode_shift) & |
294 | PLL_MODE_MASK; | 308 | config->masks->mode_mask; |
295 | 309 | ||
296 | val = readl(config->cfg_reg); | 310 | val = readl(config->cfg_reg); |
297 | /* calculate denominator */ | 311 | /* calculate denominator */ |
298 | den = (val >> PLL_DIV_P_SHIFT) & PLL_DIV_P_MASK; | 312 | den = (val >> config->masks->div_p_shift) & config->masks->div_p_mask; |
299 | den = 1 << den; | 313 | den = 1 << den; |
300 | den *= (val >> PLL_DIV_N_SHIFT) & PLL_DIV_N_MASK; | 314 | den *= (val >> config->masks->div_n_shift) & config->masks->div_n_mask; |
301 | 315 | ||
302 | /* calculate numerator & denominator */ | 316 | /* calculate numerator & denominator */ |
303 | if (!mode) { | 317 | if (!mode) { |
304 | /* Normal mode */ | 318 | /* Normal mode */ |
305 | num *= (val >> PLL_NORM_FDBK_M_SHIFT) & PLL_NORM_FDBK_M_MASK; | 319 | num *= (val >> config->masks->norm_fdbk_m_shift) & |
320 | config->masks->norm_fdbk_m_mask; | ||
306 | } else { | 321 | } else { |
307 | /* Dithered mode */ | 322 | /* Dithered mode */ |
308 | num *= (val >> PLL_DITH_FDBK_M_SHIFT) & PLL_DITH_FDBK_M_MASK; | 323 | num *= (val >> config->masks->dith_fdbk_m_shift) & |
324 | config->masks->dith_fdbk_m_mask; | ||
309 | den *= 256; | 325 | den *= 256; |
310 | } | 326 | } |
311 | 327 | ||
@@ -321,7 +337,8 @@ void bus_clk_recalc(struct clk *clk) | |||
321 | unsigned long flags; | 337 | unsigned long flags; |
322 | 338 | ||
323 | spin_lock_irqsave(&clocks_lock, flags); | 339 | spin_lock_irqsave(&clocks_lock, flags); |
324 | div = ((readl(config->reg) >> config->shift) & config->mask) + 1; | 340 | div = ((readl(config->reg) >> config->masks->shift) & |
341 | config->masks->mask) + 1; | ||
325 | clk->rate = (unsigned long)clk->pclk->rate / div; | 342 | clk->rate = (unsigned long)clk->pclk->rate / div; |
326 | spin_unlock_irqrestore(&clocks_lock, flags); | 343 | spin_unlock_irqrestore(&clocks_lock, flags); |
327 | } | 344 | } |
@@ -359,15 +376,18 @@ void aux_clk_recalc(struct clk *clk) | |||
359 | if (pclk_info->scalable) { | 376 | if (pclk_info->scalable) { |
360 | val = readl(config->synth_reg); | 377 | val = readl(config->synth_reg); |
361 | 378 | ||
362 | eqn = (val >> AUX_EQ_SEL_SHIFT) & AUX_EQ_SEL_MASK; | 379 | eqn = (val >> config->masks->eq_sel_shift) & |
363 | if (eqn == AUX_EQ1_SEL) | 380 | config->masks->eq_sel_mask; |
381 | if (eqn == config->masks->eq1_mask) | ||
364 | den *= 2; | 382 | den *= 2; |
365 | 383 | ||
366 | /* calculate numerator */ | 384 | /* calculate numerator */ |
367 | num = (val >> AUX_XSCALE_SHIFT) & AUX_XSCALE_MASK; | 385 | num = (val >> config->masks->xscale_sel_shift) & |
386 | config->masks->xscale_sel_mask; | ||
368 | 387 | ||
369 | /* calculate denominator */ | 388 | /* calculate denominator */ |
370 | den *= (val >> AUX_YSCALE_SHIFT) & AUX_YSCALE_MASK; | 389 | den *= (val >> config->masks->yscale_sel_shift) & |
390 | config->masks->yscale_sel_mask; | ||
371 | val = (((clk->pclk->rate/10000) * num) / den) * 10000; | 391 | val = (((clk->pclk->rate/10000) * num) / den) * 10000; |
372 | } else | 392 | } else |
373 | val = clk->pclk->rate; | 393 | val = clk->pclk->rate; |
@@ -383,7 +403,7 @@ void aux_clk_recalc(struct clk *clk) | |||
383 | */ | 403 | */ |
384 | void gpt_clk_recalc(struct clk *clk) | 404 | void gpt_clk_recalc(struct clk *clk) |
385 | { | 405 | { |
386 | struct aux_clk_config *config = clk->private_data; | 406 | struct gpt_clk_config *config = clk->private_data; |
387 | struct pclk_info *pclk_info = NULL; | 407 | struct pclk_info *pclk_info = NULL; |
388 | unsigned int div = 1, val; | 408 | unsigned int div = 1, val; |
389 | unsigned long flags; | 409 | unsigned long flags; |
@@ -402,8 +422,10 @@ void gpt_clk_recalc(struct clk *clk) | |||
402 | spin_lock_irqsave(&clocks_lock, flags); | 422 | spin_lock_irqsave(&clocks_lock, flags); |
403 | if (pclk_info->scalable) { | 423 | if (pclk_info->scalable) { |
404 | val = readl(config->synth_reg); | 424 | val = readl(config->synth_reg); |
405 | div += (val >> GPT_MSCALE_SHIFT) & GPT_MSCALE_MASK; | 425 | div += (val >> config->masks->mscale_sel_shift) & |
406 | div *= 1 << (((val >> GPT_NSCALE_SHIFT) & GPT_NSCALE_MASK) + 1); | 426 | config->masks->mscale_sel_mask; |
427 | div *= 1 << (((val >> config->masks->nscale_sel_shift) & | ||
428 | config->masks->nscale_sel_mask) + 1); | ||
407 | } | 429 | } |
408 | 430 | ||
409 | clk->rate = (unsigned long)clk->pclk->rate / div; | 431 | clk->rate = (unsigned long)clk->pclk->rate / div; |
@@ -411,15 +433,16 @@ void gpt_clk_recalc(struct clk *clk) | |||
411 | } | 433 | } |
412 | 434 | ||
413 | /* | 435 | /* |
414 | * Used for clocks that always have same value as the parent clock divided by a | 436 | * Used for clocks that always have value as the parent clock divided by a |
415 | * fixed divisor | 437 | * fixed divisor |
416 | */ | 438 | */ |
417 | void follow_parent(struct clk *clk) | 439 | void follow_parent(struct clk *clk) |
418 | { | 440 | { |
419 | unsigned long flags; | 441 | unsigned long flags; |
442 | unsigned int div_factor = (clk->div_factor < 1) ? 1 : clk->div_factor; | ||
420 | 443 | ||
421 | spin_lock_irqsave(&clocks_lock, flags); | 444 | spin_lock_irqsave(&clocks_lock, flags); |
422 | clk->rate = clk->pclk->rate; | 445 | clk->rate = clk->pclk->rate/div_factor; |
423 | spin_unlock_irqrestore(&clocks_lock, flags); | 446 | spin_unlock_irqrestore(&clocks_lock, flags); |
424 | } | 447 | } |
425 | 448 | ||
diff --git a/arch/arm/plat-spear/include/plat/clock.h b/arch/arm/plat-spear/include/plat/clock.h index 2572260f990f..863d9e983927 100644 --- a/arch/arm/plat-spear/include/plat/clock.h +++ b/arch/arm/plat-spear/include/plat/clock.h | |||
@@ -54,7 +54,7 @@ struct pclk_info { | |||
54 | struct pclk_sel { | 54 | struct pclk_sel { |
55 | struct pclk_info *pclk_info; | 55 | struct pclk_info *pclk_info; |
56 | u8 pclk_count; | 56 | u8 pclk_count; |
57 | unsigned int *pclk_sel_reg; | 57 | void __iomem *pclk_sel_reg; |
58 | unsigned int pclk_sel_mask; | 58 | unsigned int pclk_sel_mask; |
59 | }; | 59 | }; |
60 | 60 | ||
@@ -67,6 +67,7 @@ struct pclk_sel { | |||
67 | * @en_reg_bit: clk enable/disable bit | 67 | * @en_reg_bit: clk enable/disable bit |
68 | * @ops: clk enable/disable ops - generic_clkops selected if NULL | 68 | * @ops: clk enable/disable ops - generic_clkops selected if NULL |
69 | * @recalc: pointer to clock rate recalculate function | 69 | * @recalc: pointer to clock rate recalculate function |
70 | * @div_factor: division factor to parent clock. Only for recalc = follow_parent | ||
70 | * @pclk: current parent clk | 71 | * @pclk: current parent clk |
71 | * @pclk_sel: pointer to parent selection structure | 72 | * @pclk_sel: pointer to parent selection structure |
72 | * @pclk_sel_shift: register shift for selecting parent of this clock | 73 | * @pclk_sel_shift: register shift for selecting parent of this clock |
@@ -78,10 +79,11 @@ struct clk { | |||
78 | unsigned int usage_count; | 79 | unsigned int usage_count; |
79 | unsigned int flags; | 80 | unsigned int flags; |
80 | unsigned long rate; | 81 | unsigned long rate; |
81 | unsigned int *en_reg; | 82 | void __iomem *en_reg; |
82 | u8 en_reg_bit; | 83 | u8 en_reg_bit; |
83 | const struct clkops *ops; | 84 | const struct clkops *ops; |
84 | void (*recalc) (struct clk *); | 85 | void (*recalc) (struct clk *); |
86 | unsigned int div_factor; | ||
85 | 87 | ||
86 | struct clk *pclk; | 88 | struct clk *pclk; |
87 | struct pclk_sel *pclk_sel; | 89 | struct pclk_sel *pclk_sel; |
@@ -93,23 +95,65 @@ struct clk { | |||
93 | }; | 95 | }; |
94 | 96 | ||
95 | /* pll configuration structure */ | 97 | /* pll configuration structure */ |
98 | struct pll_clk_masks { | ||
99 | u32 mode_mask; | ||
100 | u32 mode_shift; | ||
101 | |||
102 | u32 norm_fdbk_m_mask; | ||
103 | u32 norm_fdbk_m_shift; | ||
104 | u32 dith_fdbk_m_mask; | ||
105 | u32 dith_fdbk_m_shift; | ||
106 | u32 div_p_mask; | ||
107 | u32 div_p_shift; | ||
108 | u32 div_n_mask; | ||
109 | u32 div_n_shift; | ||
110 | }; | ||
111 | |||
96 | struct pll_clk_config { | 112 | struct pll_clk_config { |
97 | unsigned int *mode_reg; | 113 | void __iomem *mode_reg; |
98 | unsigned int *cfg_reg; | 114 | void __iomem *cfg_reg; |
115 | struct pll_clk_masks *masks; | ||
99 | }; | 116 | }; |
100 | 117 | ||
101 | /* ahb and apb bus configuration structure */ | 118 | /* ahb and apb bus configuration structure */ |
119 | struct bus_clk_masks { | ||
120 | u32 mask; | ||
121 | u32 shift; | ||
122 | }; | ||
123 | |||
102 | struct bus_clk_config { | 124 | struct bus_clk_config { |
103 | unsigned int *reg; | 125 | void __iomem *reg; |
104 | unsigned int mask; | 126 | struct bus_clk_masks *masks; |
105 | unsigned int shift; | 127 | }; |
128 | |||
129 | /* Aux clk configuration structure: applicable to UART and FIRDA */ | ||
130 | struct aux_clk_masks { | ||
131 | u32 eq_sel_mask; | ||
132 | u32 eq_sel_shift; | ||
133 | u32 eq1_mask; | ||
134 | u32 eq2_mask; | ||
135 | u32 xscale_sel_mask; | ||
136 | u32 xscale_sel_shift; | ||
137 | u32 yscale_sel_mask; | ||
138 | u32 yscale_sel_shift; | ||
106 | }; | 139 | }; |
107 | 140 | ||
108 | /* | ||
109 | * Aux clk configuration structure: applicable to GPT, UART and FIRDA | ||
110 | */ | ||
111 | struct aux_clk_config { | 141 | struct aux_clk_config { |
112 | unsigned int *synth_reg; | 142 | void __iomem *synth_reg; |
143 | struct aux_clk_masks *masks; | ||
144 | }; | ||
145 | |||
146 | /* GPT clk configuration structure */ | ||
147 | struct gpt_clk_masks { | ||
148 | u32 mscale_sel_mask; | ||
149 | u32 mscale_sel_shift; | ||
150 | u32 nscale_sel_mask; | ||
151 | u32 nscale_sel_shift; | ||
152 | }; | ||
153 | |||
154 | struct gpt_clk_config { | ||
155 | void __iomem *synth_reg; | ||
156 | struct gpt_clk_masks *masks; | ||
113 | }; | 157 | }; |
114 | 158 | ||
115 | /* platform specific clock functions */ | 159 | /* platform specific clock functions */ |
@@ -118,7 +162,7 @@ void recalc_root_clocks(void); | |||
118 | 162 | ||
119 | /* clock recalc functions */ | 163 | /* clock recalc functions */ |
120 | void follow_parent(struct clk *clk); | 164 | void follow_parent(struct clk *clk); |
121 | void pll1_clk_recalc(struct clk *clk); | 165 | void pll_clk_recalc(struct clk *clk); |
122 | void bus_clk_recalc(struct clk *clk); | 166 | void bus_clk_recalc(struct clk *clk); |
123 | void gpt_clk_recalc(struct clk *clk); | 167 | void gpt_clk_recalc(struct clk *clk); |
124 | void aux_clk_recalc(struct clk *clk); | 168 | void aux_clk_recalc(struct clk *clk); |