aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile/clock-sh73a0.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-shmobile/clock-sh73a0.c')
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index afbead6a6e17..7727cca6136c 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -365,6 +365,114 @@ static struct clk div6_clks[DIV6_NR] = {
365 dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3), 365 dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
366}; 366};
367 367
368/* DSI DIV */
369static unsigned long dsiphy_recalc(struct clk *clk)
370{
371 u32 value;
372
373 value = __raw_readl(clk->mapping->base);
374
375 /* FIXME */
376 if (!(value & 0x000B8000))
377 return clk->parent->rate;
378
379 value &= 0x3f;
380 value += 1;
381
382 if ((value < 12) ||
383 (value > 33)) {
384 pr_err("DSIPHY has wrong value (%d)", value);
385 return 0;
386 }
387
388 return clk->parent->rate / value;
389}
390
391static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
392{
393 return clk_rate_mult_range_round(clk, 12, 33, rate);
394}
395
396static void dsiphy_disable(struct clk *clk)
397{
398 u32 value;
399
400 value = __raw_readl(clk->mapping->base);
401 value &= ~0x000B8000;
402
403 __raw_writel(value , clk->mapping->base);
404}
405
406static int dsiphy_enable(struct clk *clk)
407{
408 u32 value;
409 int multi;
410
411 value = __raw_readl(clk->mapping->base);
412 multi = (value & 0x3f) + 1;
413
414 if ((multi < 12) || (multi > 33))
415 return -EIO;
416
417 __raw_writel(value | 0x000B8000, clk->mapping->base);
418
419 return 0;
420}
421
422static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
423{
424 u32 value;
425 int idx;
426
427 idx = rate / clk->parent->rate;
428 if ((idx < 12) || (idx > 33))
429 return -EINVAL;
430
431 idx += -1;
432
433 value = __raw_readl(clk->mapping->base);
434 value = (value & ~0x3f) + idx;
435
436 __raw_writel(value, clk->mapping->base);
437
438 return 0;
439}
440
441static struct clk_ops dsiphy_clk_ops = {
442 .recalc = dsiphy_recalc,
443 .round_rate = dsiphy_round_rate,
444 .set_rate = dsiphy_set_rate,
445 .enable = dsiphy_enable,
446 .disable = dsiphy_disable,
447};
448
449static struct clk_mapping dsi0phy_clk_mapping = {
450 .phys = DSI0PHYCR,
451 .len = 4,
452};
453
454static struct clk_mapping dsi1phy_clk_mapping = {
455 .phys = DSI1PHYCR,
456 .len = 4,
457};
458
459static struct clk dsi0phy_clk = {
460 .ops = &dsiphy_clk_ops,
461 .parent = &div6_clks[DIV6_DSI0P], /* late install */
462 .mapping = &dsi0phy_clk_mapping,
463};
464
465static struct clk dsi1phy_clk = {
466 .ops = &dsiphy_clk_ops,
467 .parent = &div6_clks[DIV6_DSI1P], /* late install */
468 .mapping = &dsi1phy_clk_mapping,
469};
470
471static struct clk *late_main_clks[] = {
472 &dsi0phy_clk,
473 &dsi1phy_clk,
474};
475
368enum { MSTP001, 476enum { MSTP001,
369 MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100, 477 MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
370 MSTP219, 478 MSTP219,
@@ -429,6 +537,8 @@ static struct clk_lookup lookups[] = {
429 CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]), 537 CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
430 CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]), 538 CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
431 CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]), 539 CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
540 CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
541 CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
432 542
433 /* MSTP32 clocks */ 543 /* MSTP32 clocks */
434 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */ 544 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
@@ -504,6 +614,9 @@ void __init sh73a0_clock_init(void)
504 if (!ret) 614 if (!ret)
505 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); 615 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
506 616
617 for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
618 ret = clk_register(late_main_clks[k]);
619
507 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 620 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
508 621
509 if (!ret) 622 if (!ret)