aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2012-06-12 05:35:36 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2012-06-20 06:27:47 -0400
commitc6750acb3b54c77c011045467770d5143be749ee (patch)
treebaf2f96a65ae8380be691ea62708858e1899c24d /arch
parent7d7136cabcad632a81cd568a9c1135db276fe0f2 (diff)
ARM: shmobile: r8a7740: add HDMI clock support
It is required from sh_mobile_hdmi driver. This patch is based on v1.0 manual Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Acked-by: Magnus Damm <damm@opensource.se> Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7740.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index 26eea5f21054..b09534352f97 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -54,6 +54,7 @@
54#define MSTPSR2 0xe6150040 54#define MSTPSR2 0xe6150040
55#define MSTPSR3 0xe6150048 55#define MSTPSR3 0xe6150048
56#define MSTPSR4 0xe615004c 56#define MSTPSR4 0xe615004c
57#define HDMICKCR 0xe6150094
57#define SMSTPCR0 0xe6150130 58#define SMSTPCR0 0xe6150130
58#define SMSTPCR1 0xe6150134 59#define SMSTPCR1 0xe6150134
59#define SMSTPCR2 0xe6150138 60#define SMSTPCR2 0xe6150138
@@ -313,6 +314,79 @@ static struct clk_div4_table div4_table = {
313 .kick = div4_kick, 314 .kick = div4_kick,
314}; 315};
315 316
317/* DIV6 reparent */
318enum {
319 DIV6_HDMI,
320 DIV6_REPARENT_NR,
321};
322
323static struct clk *hdmi_parent[] = {
324 [0] = &pllc1_div2_clk,
325 [1] = &system_clk,
326 [2] = &dv_clk
327};
328
329static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
330 [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
331 hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
332};
333
334/* HDMI1/2 clock */
335static unsigned long hdmi12_recalc(struct clk *clk)
336{
337 u32 val = __raw_readl(HDMICKCR);
338 int shift = (int)clk->priv;
339
340 val >>= shift;
341 val &= 0x3;
342
343 return clk->parent->rate / (1 << val);
344};
345
346static int hdmi12_set_rate(struct clk *clk, unsigned long rate)
347{
348 u32 val, mask;
349 int i, shift;
350
351 for (i = 0; i < 3; i++)
352 if (rate == clk->parent->rate / (1 << i))
353 goto find;
354 return -ENODEV;
355
356find:
357 shift = (int)clk->priv;
358
359 val = __raw_readl(HDMICKCR);
360 mask = ~(0x3 << shift);
361 val = (val & mask) | i << shift;
362 __raw_writel(val, HDMICKCR);
363
364 return 0;
365};
366
367static struct sh_clk_ops hdmi12_clk_ops = {
368 .recalc = hdmi12_recalc,
369 .set_rate = hdmi12_set_rate,
370};
371
372static struct clk hdmi1_clk = {
373 .ops = &hdmi12_clk_ops,
374 .priv = (void *)9,
375 .parent = &div6_reparent_clks[DIV6_HDMI], /* late install */
376};
377
378static struct clk hdmi2_clk = {
379 .ops = &hdmi12_clk_ops,
380 .priv = (void *)11,
381 .parent = &div6_reparent_clks[DIV6_HDMI], /* late install */
382};
383
384static struct clk *late_main_clks[] = {
385 &hdmi1_clk,
386 &hdmi2_clk,
387};
388
389/* MSTP */
316enum { 390enum {
317 DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP, 391 DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP,
318 DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP, 392 DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
@@ -408,6 +482,8 @@ static struct clk_lookup lookups[] = {
408 CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), 482 CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
409 CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), 483 CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
410 CLKDEV_CON_ID("usb24s", &usb24s_clk), 484 CLKDEV_CON_ID("usb24s", &usb24s_clk),
485 CLKDEV_CON_ID("hdmi1", &hdmi1_clk),
486 CLKDEV_CON_ID("hdmi2", &hdmi2_clk),
411 487
412 /* DIV4 clocks */ 488 /* DIV4 clocks */
413 CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), 489 CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
@@ -459,6 +535,7 @@ static struct clk_lookup lookups[] = {
459 CLKDEV_ICK_ID("phy", "renesas_usbhs", &mstp_clks[MSTP406]), 535 CLKDEV_ICK_ID("phy", "renesas_usbhs", &mstp_clks[MSTP406]),
460 CLKDEV_ICK_ID("pci", "renesas_usbhs", &div4_clks[DIV4_USBP]), 536 CLKDEV_ICK_ID("pci", "renesas_usbhs", &div4_clks[DIV4_USBP]),
461 CLKDEV_ICK_ID("usb24", "renesas_usbhs", &usb24_clk), 537 CLKDEV_ICK_ID("usb24", "renesas_usbhs", &usb24_clk),
538 CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
462}; 539};
463 540
464void __init r8a7740_clock_init(u8 md_ck) 541void __init r8a7740_clock_init(u8 md_ck)
@@ -495,8 +572,15 @@ void __init r8a7740_clock_init(u8 md_ck)
495 ret = sh_clk_div6_register(div6_clks, DIV6_NR); 572 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
496 573
497 if (!ret) 574 if (!ret)
575 ret = sh_clk_div6_reparent_register(div6_reparent_clks,
576 DIV6_REPARENT_NR);
577
578 if (!ret)
498 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); 579 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
499 580
581 for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
582 ret = clk_register(late_main_clks[k]);
583
500 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 584 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
501 585
502 if (!ret) 586 if (!ret)