diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-shmobile/board-ag5evm.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh73a0.c | 113 |
2 files changed, 125 insertions, 4 deletions
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index 729eaee5a151..2e1334f56995 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c | |||
@@ -314,12 +314,11 @@ static struct resource mipidsi0_resources[] = { | |||
314 | }, | 314 | }, |
315 | }; | 315 | }; |
316 | 316 | ||
317 | #define DSI0PHYCR 0xe615006c | ||
318 | static int sh_mipi_set_dot_clock(struct platform_device *pdev, | 317 | static int sh_mipi_set_dot_clock(struct platform_device *pdev, |
319 | void __iomem *base, | 318 | void __iomem *base, |
320 | int enable) | 319 | int enable) |
321 | { | 320 | { |
322 | struct clk *pck; | 321 | struct clk *pck, *phy; |
323 | int ret; | 322 | int ret; |
324 | 323 | ||
325 | pck = clk_get(&pdev->dev, "dsip_clk"); | 324 | pck = clk_get(&pdev->dev, "dsip_clk"); |
@@ -328,18 +327,27 @@ static int sh_mipi_set_dot_clock(struct platform_device *pdev, | |||
328 | goto sh_mipi_set_dot_clock_pck_err; | 327 | goto sh_mipi_set_dot_clock_pck_err; |
329 | } | 328 | } |
330 | 329 | ||
330 | phy = clk_get(&pdev->dev, "dsiphy_clk"); | ||
331 | if (IS_ERR(phy)) { | ||
332 | ret = PTR_ERR(phy); | ||
333 | goto sh_mipi_set_dot_clock_phy_err; | ||
334 | } | ||
335 | |||
331 | if (enable) { | 336 | if (enable) { |
332 | clk_set_rate(pck, clk_round_rate(pck, 24000000)); | 337 | clk_set_rate(pck, clk_round_rate(pck, 24000000)); |
333 | __raw_writel(0x2a809010, DSI0PHYCR); | 338 | clk_set_rate(phy, clk_round_rate(pck, 510000000)); |
334 | clk_enable(pck); | 339 | clk_enable(pck); |
340 | clk_enable(phy); | ||
335 | } else { | 341 | } else { |
336 | clk_disable(pck); | 342 | clk_disable(pck); |
343 | clk_disable(phy); | ||
337 | } | 344 | } |
338 | 345 | ||
339 | ret = 0; | 346 | ret = 0; |
340 | 347 | ||
348 | clk_put(phy); | ||
349 | sh_mipi_set_dot_clock_phy_err: | ||
341 | clk_put(pck); | 350 | clk_put(pck); |
342 | |||
343 | sh_mipi_set_dot_clock_pck_err: | 351 | sh_mipi_set_dot_clock_pck_err: |
344 | return ret; | 352 | return ret; |
345 | } | 353 | } |
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) |