diff options
Diffstat (limited to 'arch/arm/mach-shmobile/clock-sh73a0.c')
| -rw-r--r-- | arch/arm/mach-shmobile/clock-sh73a0.c | 113 |
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 */ | ||
| 369 | static 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 | |||
| 391 | static long dsiphy_round_rate(struct clk *clk, unsigned long rate) | ||
| 392 | { | ||
| 393 | return clk_rate_mult_range_round(clk, 12, 33, rate); | ||
| 394 | } | ||
| 395 | |||
| 396 | static 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 | |||
| 406 | static 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 | |||
| 422 | static 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 | |||
| 441 | static 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 | |||
| 449 | static struct clk_mapping dsi0phy_clk_mapping = { | ||
| 450 | .phys = DSI0PHYCR, | ||
| 451 | .len = 4, | ||
| 452 | }; | ||
| 453 | |||
| 454 | static struct clk_mapping dsi1phy_clk_mapping = { | ||
| 455 | .phys = DSI1PHYCR, | ||
| 456 | .len = 4, | ||
| 457 | }; | ||
| 458 | |||
| 459 | static struct clk dsi0phy_clk = { | ||
| 460 | .ops = &dsiphy_clk_ops, | ||
| 461 | .parent = &div6_clks[DIV6_DSI0P], /* late install */ | ||
| 462 | .mapping = &dsi0phy_clk_mapping, | ||
| 463 | }; | ||
| 464 | |||
| 465 | static struct clk dsi1phy_clk = { | ||
| 466 | .ops = &dsiphy_clk_ops, | ||
| 467 | .parent = &div6_clks[DIV6_DSI1P], /* late install */ | ||
| 468 | .mapping = &dsi1phy_clk_mapping, | ||
| 469 | }; | ||
| 470 | |||
| 471 | static struct clk *late_main_clks[] = { | ||
| 472 | &dsi0phy_clk, | ||
| 473 | &dsi1phy_clk, | ||
| 474 | }; | ||
| 475 | |||
| 368 | enum { MSTP001, | 476 | enum { 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) |
