aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-02-08 11:07:46 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-02-08 12:50:11 -0500
commitd5e6072b753041b56236b014ccfd72a0d3177e08 (patch)
tree9e922b16f7c84c063977d22c71385239fbd4e5c2
parent9a5fedac187f30116013a8420149d4ca11a44f0d (diff)
[ARM] omap: handle RATE_CKCTL via .set_rate/.round_rate methods
It makes no sense to have the CKCTL rate selection implemented as a flag and a special exception in the top level set_rate/round_rate methods. Provide CKCTL set_rate/round_rate methods, and use these for where ever RATE_CKCTL is used and they're not already overridden. This allows us to remove the RATE_CKCTL flag. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/mach-omap1/clock.c96
-rw-r--r--arch/arm/mach-omap1/clock.h38
-rw-r--r--arch/arm/plat-omap/include/mach/clock.h2
3 files changed, 72 insertions, 64 deletions
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index be500014dcb8..6b17da120e5f 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -216,9 +216,6 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate)
216 struct clk * parent; 216 struct clk * parent;
217 unsigned dsor_exp; 217 unsigned dsor_exp;
218 218
219 if (unlikely(!(clk->flags & RATE_CKCTL)))
220 return -EINVAL;
221
222 parent = clk->parent; 219 parent = clk->parent;
223 if (unlikely(parent == NULL)) 220 if (unlikely(parent == NULL))
224 return -EIO; 221 return -EIO;
@@ -307,26 +304,52 @@ static int omap1_select_table_rate(struct clk * clk, unsigned long rate)
307 304
308static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate) 305static int omap1_clk_set_rate_dsp_domain(struct clk *clk, unsigned long rate)
309{ 306{
310 int ret = -EINVAL; 307 int dsor_exp;
311 int dsor_exp; 308 u16 regval;
312 __u16 regval;
313
314 if (clk->flags & RATE_CKCTL) {
315 dsor_exp = calc_dsor_exp(clk, rate);
316 if (dsor_exp > 3)
317 dsor_exp = -EINVAL;
318 if (dsor_exp < 0)
319 return dsor_exp;
320
321 regval = __raw_readw(DSP_CKCTL);
322 regval &= ~(3 << clk->rate_offset);
323 regval |= dsor_exp << clk->rate_offset;
324 __raw_writew(regval, DSP_CKCTL);
325 clk->rate = clk->parent->rate / (1 << dsor_exp);
326 ret = 0;
327 }
328 309
329 return ret; 310 dsor_exp = calc_dsor_exp(clk, rate);
311 if (dsor_exp > 3)
312 dsor_exp = -EINVAL;
313 if (dsor_exp < 0)
314 return dsor_exp;
315
316 regval = __raw_readw(DSP_CKCTL);
317 regval &= ~(3 << clk->rate_offset);
318 regval |= dsor_exp << clk->rate_offset;
319 __raw_writew(regval, DSP_CKCTL);
320 clk->rate = clk->parent->rate / (1 << dsor_exp);
321
322 return 0;
323}
324
325static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate)
326{
327 int dsor_exp = calc_dsor_exp(clk, rate);
328 if (dsor_exp < 0)
329 return dsor_exp;
330 if (dsor_exp > 3)
331 dsor_exp = 3;
332 return clk->parent->rate / (1 << dsor_exp);
333}
334
335static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate)
336{
337 int dsor_exp;
338 u16 regval;
339
340 dsor_exp = calc_dsor_exp(clk, rate);
341 if (dsor_exp > 3)
342 dsor_exp = -EINVAL;
343 if (dsor_exp < 0)
344 return dsor_exp;
345
346 regval = omap_readw(ARM_CKCTL);
347 regval &= ~(3 << clk->rate_offset);
348 regval |= dsor_exp << clk->rate_offset;
349 regval = verify_ckctl_value(regval);
350 omap_writew(regval, ARM_CKCTL);
351 clk->rate = clk->parent->rate / (1 << dsor_exp);
352 return 0;
330} 353}
331 354
332static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate) 355static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate)
@@ -572,20 +595,9 @@ static const struct clkops clkops_generic = {
572 595
573static long omap1_clk_round_rate(struct clk *clk, unsigned long rate) 596static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
574{ 597{
575 int dsor_exp;
576
577 if (clk->flags & RATE_FIXED) 598 if (clk->flags & RATE_FIXED)
578 return clk->rate; 599 return clk->rate;
579 600
580 if (clk->flags & RATE_CKCTL) {
581 dsor_exp = calc_dsor_exp(clk, rate);
582 if (dsor_exp < 0)
583 return dsor_exp;
584 if (dsor_exp > 3)
585 dsor_exp = 3;
586 return clk->parent->rate / (1 << dsor_exp);
587 }
588
589 if (clk->round_rate != NULL) 601 if (clk->round_rate != NULL)
590 return clk->round_rate(clk, rate); 602 return clk->round_rate(clk, rate);
591 603
@@ -595,27 +607,9 @@ static long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
595static int omap1_clk_set_rate(struct clk *clk, unsigned long rate) 607static int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
596{ 608{
597 int ret = -EINVAL; 609 int ret = -EINVAL;
598 int dsor_exp;
599 __u16 regval;
600 610
601 if (clk->set_rate) 611 if (clk->set_rate)
602 ret = clk->set_rate(clk, rate); 612 ret = clk->set_rate(clk, rate);
603 else if (clk->flags & RATE_CKCTL) {
604 dsor_exp = calc_dsor_exp(clk, rate);
605 if (dsor_exp > 3)
606 dsor_exp = -EINVAL;
607 if (dsor_exp < 0)
608 return dsor_exp;
609
610 regval = omap_readw(ARM_CKCTL);
611 regval &= ~(3 << clk->rate_offset);
612 regval |= dsor_exp << clk->rate_offset;
613 regval = verify_ckctl_value(regval);
614 omap_writew(regval, ARM_CKCTL);
615 clk->rate = clk->parent->rate / (1 << dsor_exp);
616 ret = 0;
617 }
618
619 return ret; 613 return ret;
620} 614}
621 615
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index 8673832d829a..aa7b3d604ee9 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -27,6 +27,9 @@ static void omap1_init_ext_clk(struct clk * clk);
27static int omap1_select_table_rate(struct clk * clk, unsigned long rate); 27static int omap1_select_table_rate(struct clk * clk, unsigned long rate);
28static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate); 28static long omap1_round_to_table_rate(struct clk * clk, unsigned long rate);
29 29
30static int omap1_clk_set_rate_ckctl_arm(struct clk *clk, unsigned long rate);
31static long omap1_clk_round_rate_ckctl_arm(struct clk *clk, unsigned long rate);
32
30struct mpu_rate { 33struct mpu_rate {
31 unsigned long rate; 34 unsigned long rate;
32 unsigned long xtal; 35 unsigned long xtal;
@@ -189,9 +192,11 @@ static struct clk arm_ck = {
189 .ops = &clkops_null, 192 .ops = &clkops_null,
190 .parent = &ck_dpll1, 193 .parent = &ck_dpll1,
191 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 194 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
192 CLOCK_IN_OMAP310 | RATE_CKCTL | RATE_PROPAGATES, 195 CLOCK_IN_OMAP310 | RATE_PROPAGATES,
193 .rate_offset = CKCTL_ARMDIV_OFFSET, 196 .rate_offset = CKCTL_ARMDIV_OFFSET,
194 .recalc = &omap1_ckctl_recalc, 197 .recalc = &omap1_ckctl_recalc,
198 .round_rate = omap1_clk_round_rate_ckctl_arm,
199 .set_rate = omap1_clk_set_rate_ckctl_arm,
195}; 200};
196 201
197static struct arm_idlect1_clk armper_ck = { 202static struct arm_idlect1_clk armper_ck = {
@@ -200,12 +205,13 @@ static struct arm_idlect1_clk armper_ck = {
200 .ops = &clkops_generic, 205 .ops = &clkops_generic,
201 .parent = &ck_dpll1, 206 .parent = &ck_dpll1,
202 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 207 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
203 CLOCK_IN_OMAP310 | RATE_CKCTL | 208 CLOCK_IN_OMAP310 | CLOCK_IDLE_CONTROL,
204 CLOCK_IDLE_CONTROL,
205 .enable_reg = (void __iomem *)ARM_IDLECT2, 209 .enable_reg = (void __iomem *)ARM_IDLECT2,
206 .enable_bit = EN_PERCK, 210 .enable_bit = EN_PERCK,
207 .rate_offset = CKCTL_PERDIV_OFFSET, 211 .rate_offset = CKCTL_PERDIV_OFFSET,
208 .recalc = &omap1_ckctl_recalc, 212 .recalc = &omap1_ckctl_recalc,
213 .round_rate = omap1_clk_round_rate_ckctl_arm,
214 .set_rate = omap1_clk_set_rate_ckctl_arm,
209 }, 215 },
210 .idlect_shift = 2, 216 .idlect_shift = 2,
211}; 217};
@@ -279,22 +285,24 @@ static struct clk dsp_ck = {
279 .name = "dsp_ck", 285 .name = "dsp_ck",
280 .ops = &clkops_generic, 286 .ops = &clkops_generic,
281 .parent = &ck_dpll1, 287 .parent = &ck_dpll1,
282 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 288 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
283 RATE_CKCTL,
284 .enable_reg = (void __iomem *)ARM_CKCTL, 289 .enable_reg = (void __iomem *)ARM_CKCTL,
285 .enable_bit = EN_DSPCK, 290 .enable_bit = EN_DSPCK,
286 .rate_offset = CKCTL_DSPDIV_OFFSET, 291 .rate_offset = CKCTL_DSPDIV_OFFSET,
287 .recalc = &omap1_ckctl_recalc, 292 .recalc = &omap1_ckctl_recalc,
293 .round_rate = omap1_clk_round_rate_ckctl_arm,
294 .set_rate = omap1_clk_set_rate_ckctl_arm,
288}; 295};
289 296
290static struct clk dspmmu_ck = { 297static struct clk dspmmu_ck = {
291 .name = "dspmmu_ck", 298 .name = "dspmmu_ck",
292 .ops = &clkops_null, 299 .ops = &clkops_null,
293 .parent = &ck_dpll1, 300 .parent = &ck_dpll1,
294 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 301 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
295 RATE_CKCTL,
296 .rate_offset = CKCTL_DSPMMUDIV_OFFSET, 302 .rate_offset = CKCTL_DSPMMUDIV_OFFSET,
297 .recalc = &omap1_ckctl_recalc, 303 .recalc = &omap1_ckctl_recalc,
304 .round_rate = omap1_clk_round_rate_ckctl_arm,
305 .set_rate = omap1_clk_set_rate_ckctl_arm,
298}; 306};
299 307
300static struct clk dspper_ck = { 308static struct clk dspper_ck = {
@@ -302,11 +310,12 @@ static struct clk dspper_ck = {
302 .ops = &clkops_dspck, 310 .ops = &clkops_dspck,
303 .parent = &ck_dpll1, 311 .parent = &ck_dpll1,
304 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 312 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
305 RATE_CKCTL | VIRTUAL_IO_ADDRESS, 313 VIRTUAL_IO_ADDRESS,
306 .enable_reg = DSP_IDLECT2, 314 .enable_reg = DSP_IDLECT2,
307 .enable_bit = EN_PERCK, 315 .enable_bit = EN_PERCK,
308 .rate_offset = CKCTL_PERDIV_OFFSET, 316 .rate_offset = CKCTL_PERDIV_OFFSET,
309 .recalc = &omap1_ckctl_recalc_dsp_domain, 317 .recalc = &omap1_ckctl_recalc_dsp_domain,
318 .round_rate = omap1_clk_round_rate_ckctl_arm,
310 .set_rate = &omap1_clk_set_rate_dsp_domain, 319 .set_rate = &omap1_clk_set_rate_dsp_domain,
311}; 320};
312 321
@@ -340,10 +349,11 @@ static struct arm_idlect1_clk tc_ck = {
340 .parent = &ck_dpll1, 349 .parent = &ck_dpll1,
341 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | 350 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
342 CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 | 351 CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 |
343 RATE_CKCTL | RATE_PROPAGATES | 352 RATE_PROPAGATES | CLOCK_IDLE_CONTROL,
344 CLOCK_IDLE_CONTROL,
345 .rate_offset = CKCTL_TCDIV_OFFSET, 353 .rate_offset = CKCTL_TCDIV_OFFSET,
346 .recalc = &omap1_ckctl_recalc, 354 .recalc = &omap1_ckctl_recalc,
355 .round_rate = omap1_clk_round_rate_ckctl_arm,
356 .set_rate = omap1_clk_set_rate_ckctl_arm,
347 }, 357 },
348 .idlect_shift = 6, 358 .idlect_shift = 6,
349}; 359};
@@ -466,11 +476,13 @@ static struct clk lcd_ck_16xx = {
466 .name = "lcd_ck", 476 .name = "lcd_ck",
467 .ops = &clkops_generic, 477 .ops = &clkops_generic,
468 .parent = &ck_dpll1, 478 .parent = &ck_dpll1,
469 .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | RATE_CKCTL, 479 .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730,
470 .enable_reg = (void __iomem *)ARM_IDLECT2, 480 .enable_reg = (void __iomem *)ARM_IDLECT2,
471 .enable_bit = EN_LCDCK, 481 .enable_bit = EN_LCDCK,
472 .rate_offset = CKCTL_LCDDIV_OFFSET, 482 .rate_offset = CKCTL_LCDDIV_OFFSET,
473 .recalc = &omap1_ckctl_recalc, 483 .recalc = &omap1_ckctl_recalc,
484 .round_rate = omap1_clk_round_rate_ckctl_arm,
485 .set_rate = omap1_clk_set_rate_ckctl_arm,
474}; 486};
475 487
476static struct arm_idlect1_clk lcd_ck_1510 = { 488static struct arm_idlect1_clk lcd_ck_1510 = {
@@ -479,11 +491,13 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
479 .ops = &clkops_generic, 491 .ops = &clkops_generic,
480 .parent = &ck_dpll1, 492 .parent = &ck_dpll1,
481 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | 493 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 |
482 RATE_CKCTL | CLOCK_IDLE_CONTROL, 494 CLOCK_IDLE_CONTROL,
483 .enable_reg = (void __iomem *)ARM_IDLECT2, 495 .enable_reg = (void __iomem *)ARM_IDLECT2,
484 .enable_bit = EN_LCDCK, 496 .enable_bit = EN_LCDCK,
485 .rate_offset = CKCTL_LCDDIV_OFFSET, 497 .rate_offset = CKCTL_LCDDIV_OFFSET,
486 .recalc = &omap1_ckctl_recalc, 498 .recalc = &omap1_ckctl_recalc,
499 .round_rate = omap1_clk_round_rate_ckctl_arm,
500 .set_rate = omap1_clk_set_rate_ckctl_arm,
487 }, 501 },
488 .idlect_shift = 3, 502 .idlect_shift = 3,
489}; 503};
diff --git a/arch/arm/plat-omap/include/mach/clock.h b/arch/arm/plat-omap/include/mach/clock.h
index 06dd38a8a0c0..5a7411e71f20 100644
--- a/arch/arm/plat-omap/include/mach/clock.h
+++ b/arch/arm/plat-omap/include/mach/clock.h
@@ -124,7 +124,7 @@ extern void clk_enable_init_clocks(void);
124extern const struct clkops clkops_null; 124extern const struct clkops clkops_null;
125 125
126/* Clock flags */ 126/* Clock flags */
127#define RATE_CKCTL (1 << 0) /* Main fixed ratio clocks */ 127/* bit 0 is free */
128#define RATE_FIXED (1 << 1) /* Fixed clock rate */ 128#define RATE_FIXED (1 << 1) /* Fixed clock rate */
129#define RATE_PROPAGATES (1 << 2) /* Program children too */ 129#define RATE_PROPAGATES (1 << 2) /* Program children too */
130/* bits 3-4 are free */ 130/* bits 3-4 are free */