diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2010-11-23 21:44:06 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-11-24 01:29:56 -0500 |
commit | d4bc99b977e3a1dd10a84a01ebe59ac2ccebf0cd (patch) | |
tree | 441a72709a1dd40ac84b89cec8b036f00960a96b /arch | |
parent | e8ee13a818db4954517cea7da6e7c15b9656eb00 (diff) |
ARM: mach-shmobile: ap4evb: FSI clock use proper process for HDMI
Current AP4 FSI set_rate function used bogus clock process
which didn't care enable/disable and clk->usecound.
To solve this issue, this patch also modify FSI driver to call
set_rate with enough options.
This patch modify it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-shmobile/board-ap4evb.c | 58 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh7372.c | 2 |
2 files changed, 46 insertions, 14 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index d3260542b943..61c1068198ec 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
@@ -567,40 +567,72 @@ static struct platform_device *qhd_devices[] __initdata = { | |||
567 | 567 | ||
568 | /* FSI */ | 568 | /* FSI */ |
569 | #define IRQ_FSI evt2irq(0x1840) | 569 | #define IRQ_FSI evt2irq(0x1840) |
570 | static int __fsi_set_rate(struct clk *clk, long rate, int enable) | ||
571 | { | ||
572 | int ret = 0; | ||
573 | |||
574 | if (rate <= 0) | ||
575 | return ret; | ||
570 | 576 | ||
571 | static int fsi_set_rate(int is_porta, int rate) | 577 | if (enable) { |
578 | ret = clk_set_rate(clk, clk_round_rate(clk, rate)); | ||
579 | if (0 == ret) | ||
580 | ret = clk_enable(clk); | ||
581 | } else { | ||
582 | clk_disable(clk); | ||
583 | } | ||
584 | |||
585 | return ret; | ||
586 | } | ||
587 | |||
588 | static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable) | ||
572 | { | 589 | { |
573 | struct clk *fsib_clk; | 590 | struct clk *fsib_clk; |
574 | struct clk *fdiv_clk = &sh7372_fsidivb_clk; | 591 | struct clk *fdiv_clk = &sh7372_fsidivb_clk; |
592 | long fsib_rate = 0; | ||
593 | long fdiv_rate = 0; | ||
594 | int ackmd_bpfmd; | ||
575 | int ret; | 595 | int ret; |
576 | 596 | ||
577 | /* set_rate is not needed if port A */ | 597 | /* set_rate is not needed if port A */ |
578 | if (is_porta) | 598 | if (is_porta) |
579 | return 0; | 599 | return 0; |
580 | 600 | ||
581 | fsib_clk = clk_get(NULL, "fsib_clk"); | ||
582 | if (IS_ERR(fsib_clk)) | ||
583 | return -EINVAL; | ||
584 | |||
585 | switch (rate) { | 601 | switch (rate) { |
586 | case 44100: | 602 | case 44100: |
587 | clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 11283000)); | 603 | fsib_rate = rate * 256; |
588 | ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; | 604 | ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; |
589 | break; | 605 | break; |
590 | case 48000: | 606 | case 48000: |
591 | clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 85428000)); | 607 | fsib_rate = 85428000; /* around 48kHz x 256 x 7 */ |
592 | clk_set_rate(fdiv_clk, clk_round_rate(fdiv_clk, 12204000)); | 608 | fdiv_rate = rate * 256; |
593 | ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; | 609 | ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; |
594 | break; | 610 | break; |
595 | default: | 611 | default: |
596 | pr_err("unsupported rate in FSI2 port B\n"); | 612 | pr_err("unsupported rate in FSI2 port B\n"); |
597 | ret = -EINVAL; | 613 | return -EINVAL; |
598 | break; | ||
599 | } | 614 | } |
600 | 615 | ||
616 | /* FSI B setting */ | ||
617 | fsib_clk = clk_get(dev, "ickb"); | ||
618 | if (IS_ERR(fsib_clk)) | ||
619 | return -EIO; | ||
620 | |||
621 | ret = __fsi_set_rate(fsib_clk, fsib_rate, enable); | ||
601 | clk_put(fsib_clk); | 622 | clk_put(fsib_clk); |
623 | if (ret < 0) | ||
624 | return ret; | ||
602 | 625 | ||
603 | return ret; | 626 | /* FSI DIV setting */ |
627 | ret = __fsi_set_rate(fdiv_clk, fdiv_rate, enable); | ||
628 | if (ret < 0) { | ||
629 | /* disable FSI B */ | ||
630 | if (enable) | ||
631 | __fsi_set_rate(fsib_clk, fsib_rate, 0); | ||
632 | return ret; | ||
633 | } | ||
634 | |||
635 | return ackmd_bpfmd; | ||
604 | } | 636 | } |
605 | 637 | ||
606 | static struct sh_fsi_platform_info fsi_info = { | 638 | static struct sh_fsi_platform_info fsi_info = { |
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 13226323e4e0..4191e2921127 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c | |||
@@ -471,7 +471,7 @@ static int fsidiv_set_rate(struct clk *clk, | |||
471 | return -ENOENT; | 471 | return -ENOENT; |
472 | 472 | ||
473 | __raw_writel(idx << 16, clk->mapping->base); | 473 | __raw_writel(idx << 16, clk->mapping->base); |
474 | return fsidiv_enable(clk); | 474 | return 0; |
475 | } | 475 | } |
476 | 476 | ||
477 | static struct clk_ops fsidiv_clk_ops = { | 477 | static struct clk_ops fsidiv_clk_ops = { |