aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorviresh kumar <viresh.kumar@st.com>2011-02-16 01:40:31 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-03-09 04:49:45 -0500
commitcf285434ac0880f94bf4afdd90b06a4655f56570 (patch)
tree6b7b0f6716c17147e45cca39d01f88570d368eb5 /arch
parent5c881d9ae9480171f01921585e1893863d7ab421 (diff)
ARM: 6679/1: SPEAr: make clk API functions more generic
- Add a dummy clk_set_rate() function. This is required for compilation of a few drivers. - Make functions in plat-spear/clock.c more generic over all SPEAr platforms. - Add div_factor in struct clk for clks with .recalc = follow_parent - Change type of register pointers to void __iomem * Reviewed-by: Stanley Miao <stanley.miao@windriver.com> Signed-off-by: Viresh Kumar <viresh.kumar@st.com> Signed-off-by: Rajeev Kumar <rajeev-dlh.kumar@st.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-spear3xx/clock.c66
-rw-r--r--arch/arm/mach-spear6xx/clock.c67
-rw-r--r--arch/arm/plat-spear/clock.c59
-rw-r--r--arch/arm/plat-spear/include/plat/clock.h68
4 files changed, 214 insertions, 46 deletions
diff --git a/arch/arm/mach-spear3xx/clock.c b/arch/arm/mach-spear3xx/clock.c
index 18febf92f20..7ea8749ddf2 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 */
43static 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 */
43static struct pll_clk_config pll1_config = { 57static 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 */
95static 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 */
80static struct bus_clk_config ahb_config = { 101static 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 */
115static 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 */
95static struct aux_clk_config uart_config = { 127static 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 */
131static struct aux_clk_config firda_config = { 164static 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 */
222static 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 */
188static struct aux_clk_config gpt0_config = { 230static 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 */
202static struct aux_clk_config gpt1_config = { 245static 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 */
217static struct aux_clk_config gpt2_config = { 261static 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 */
302static 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 */
257static struct bus_clk_config apb_config = { 308static 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 36ff056b732..ef88922986e 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 */
43static 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 */
43static struct pll_clk_config pll1_config = { 57static 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 */
95static 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 */
80static struct bus_clk_config ahb_config = { 101static 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 */
136static 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 */
116static struct aux_clk_config uart_config = { 148static 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 */
141static struct aux_clk_config firda_config = { 174static 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 */
177static struct aux_clk_config clcd_config = { 211static 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 */
269static 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 */
234static struct aux_clk_config gpt0_1_config = { 277static 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 */
257static struct aux_clk_config gpt2_config = { 301static 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 */
272static struct aux_clk_config gpt3_config = { 317static 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 */
359static 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 */
313static struct bus_clk_config apb_config = { 365static 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 ee4f90e534d..f1cf832e4e3 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
23static DEFINE_SPINLOCK(clocks_lock); 22static DEFINE_SPINLOCK(clocks_lock);
@@ -187,6 +186,20 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
187} 186}
188EXPORT_SYMBOL(clk_set_parent); 187EXPORT_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 */
196int clk_set_rate(struct clk *clk, unsigned long rate)
197{
198 /* TODO */
199 return -EINVAL;
200}
201EXPORT_SYMBOL(clk_set_rate);
202
190/* registers clock in platform clock framework */ 203/* registers clock in platform clock framework */
191void clk_register(struct clk_lookup *cl) 204void 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 */
286void pll1_clk_recalc(struct clk *clk) 300void 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 */
384void gpt_clk_recalc(struct clk *clk) 404void 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 */
417void follow_parent(struct clk *clk) 439void 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 2572260f990..863d9e98392 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 {
54struct pclk_sel { 54struct 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 */
98struct 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
96struct pll_clk_config { 112struct 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 */
119struct bus_clk_masks {
120 u32 mask;
121 u32 shift;
122};
123
102struct bus_clk_config { 124struct 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 */
130struct 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 */
111struct aux_clk_config { 141struct 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 */
147struct 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
154struct 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 */
120void follow_parent(struct clk *clk); 164void follow_parent(struct clk *clk);
121void pll1_clk_recalc(struct clk *clk); 165void pll_clk_recalc(struct clk *clk);
122void bus_clk_recalc(struct clk *clk); 166void bus_clk_recalc(struct clk *clk);
123void gpt_clk_recalc(struct clk *clk); 167void gpt_clk_recalc(struct clk *clk);
124void aux_clk_recalc(struct clk *clk); 168void aux_clk_recalc(struct clk *clk);