aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-11-26 17:17:16 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-11-26 17:17:16 -0500
commitd4d2ad948e9a9c316e72fdc09d7490dfda4773da (patch)
tree38c50fa58d76fa90004a3bab593a6fa353dc1a33 /arch/arm/mach-shmobile
parent5c3b9bac28c62151f133a944fe14df5e153ae493 (diff)
parent540565257101f7c52b6fc5a57651f7505f8d20fe (diff)
Merge branch 'rmobile-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
* 'rmobile-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6: ARM: mach-shmobile: clock-sh7372: remove bogus pllc2 clock toggling. ARM: mach-shmobile: clock-sh7372: remove unnecessary fsi clocks ARM: mach-shmobile: clock-sh7372: modify error code ARM: mach-shmobile: ap4evb: FSI clock use proper process for ak4642 ARM: mach-shmobile: ap4evb: FSI clock use proper process for HDMI ARM: mach-shmobile: clock-sh7372: remove fsidiv bogus disable ARM: mach-shmobile: sh7372 USB0/IIC1 MSTP fix
Diffstat (limited to 'arch/arm/mach-shmobile')
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c147
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c33
2 files changed, 119 insertions, 61 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index d3260542b943..d440e5f456ad 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -567,38 +567,127 @@ 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)
570static int __fsi_set_rate(struct clk *clk, long rate, int enable)
571{
572 int ret = 0;
573
574 if (rate <= 0)
575 return ret;
576
577 if (enable) {
578 ret = clk_set_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
588static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
589{
590 return __fsi_set_rate(clk, clk_round_rate(clk, rate), enable);
591}
570 592
571static int fsi_set_rate(int is_porta, int rate) 593static int fsi_ak4642_set_rate(struct device *dev, int rate, int enable)
594{
595 struct clk *fsia_ick;
596 struct clk *fsiack;
597 int ret = -EIO;
598
599 fsia_ick = clk_get(dev, "icka");
600 if (IS_ERR(fsia_ick))
601 return PTR_ERR(fsia_ick);
602
603 /*
604 * FSIACK is connected to AK4642,
605 * and use external clock pin from it.
606 * it is parent of fsia_ick now.
607 */
608 fsiack = clk_get_parent(fsia_ick);
609 if (!fsiack)
610 goto fsia_ick_out;
611
612 /*
613 * we get 1/1 divided clock by setting same rate to fsiack and fsia_ick
614 *
615 ** FIXME **
616 * Because the freq_table of external clk (fsiack) are all 0,
617 * the return value of clk_round_rate became 0.
618 * So, it use __fsi_set_rate here.
619 */
620 ret = __fsi_set_rate(fsiack, rate, enable);
621 if (ret < 0)
622 goto fsiack_out;
623
624 ret = __fsi_set_round_rate(fsia_ick, rate, enable);
625 if ((ret < 0) && enable)
626 __fsi_set_round_rate(fsiack, rate, 0); /* disable FSI ACK */
627
628fsiack_out:
629 clk_put(fsiack);
630
631fsia_ick_out:
632 clk_put(fsia_ick);
633
634 return 0;
635}
636
637static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
572{ 638{
573 struct clk *fsib_clk; 639 struct clk *fsib_clk;
574 struct clk *fdiv_clk = &sh7372_fsidivb_clk; 640 struct clk *fdiv_clk = &sh7372_fsidivb_clk;
641 long fsib_rate = 0;
642 long fdiv_rate = 0;
643 int ackmd_bpfmd;
575 int ret; 644 int ret;
576 645
577 /* set_rate is not needed if port A */
578 if (is_porta)
579 return 0;
580
581 fsib_clk = clk_get(NULL, "fsib_clk");
582 if (IS_ERR(fsib_clk))
583 return -EINVAL;
584
585 switch (rate) { 646 switch (rate) {
586 case 44100: 647 case 44100:
587 clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 11283000)); 648 fsib_rate = rate * 256;
588 ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; 649 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
589 break; 650 break;
590 case 48000: 651 case 48000:
591 clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 85428000)); 652 fsib_rate = 85428000; /* around 48kHz x 256 x 7 */
592 clk_set_rate(fdiv_clk, clk_round_rate(fdiv_clk, 12204000)); 653 fdiv_rate = rate * 256;
593 ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; 654 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
594 break; 655 break;
595 default: 656 default:
596 pr_err("unsupported rate in FSI2 port B\n"); 657 pr_err("unsupported rate in FSI2 port B\n");
597 ret = -EINVAL; 658 return -EINVAL;
598 break;
599 } 659 }
600 660
661 /* FSI B setting */
662 fsib_clk = clk_get(dev, "ickb");
663 if (IS_ERR(fsib_clk))
664 return -EIO;
665
666 ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
601 clk_put(fsib_clk); 667 clk_put(fsib_clk);
668 if (ret < 0)
669 return ret;
670
671 /* FSI DIV setting */
672 ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
673 if (ret < 0) {
674 /* disable FSI B */
675 if (enable)
676 __fsi_set_round_rate(fsib_clk, fsib_rate, 0);
677 return ret;
678 }
679
680 return ackmd_bpfmd;
681}
682
683static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
684{
685 int ret;
686
687 if (is_porta)
688 ret = fsi_ak4642_set_rate(dev, rate, enable);
689 else
690 ret = fsi_hdmi_set_rate(dev, rate, enable);
602 691
603 return ret; 692 return ret;
604} 693}
@@ -880,6 +969,11 @@ static int __init hdmi_init_pm_clock(void)
880 goto out; 969 goto out;
881 } 970 }
882 971
972 ret = clk_enable(&sh7372_pllc2_clk);
973 if (ret < 0) {
974 pr_err("Cannot enable pllc2 clock\n");
975 goto out;
976 }
883 pr_debug("PLLC2 set frequency %lu\n", rate); 977 pr_debug("PLLC2 set frequency %lu\n", rate);
884 978
885 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk); 979 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
@@ -896,23 +990,11 @@ out:
896 990
897device_initcall(hdmi_init_pm_clock); 991device_initcall(hdmi_init_pm_clock);
898 992
899#define FSIACK_DUMMY_RATE 48000
900static int __init fsi_init_pm_clock(void) 993static int __init fsi_init_pm_clock(void)
901{ 994{
902 struct clk *fsia_ick; 995 struct clk *fsia_ick;
903 int ret; 996 int ret;
904 997
905 /*
906 * FSIACK is connected to AK4642,
907 * and the rate is depend on playing sound rate.
908 * So, set dummy rate (= 48k) here
909 */
910 ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE);
911 if (ret < 0) {
912 pr_err("Cannot set FSIACK dummy rate: %d\n", ret);
913 return ret;
914 }
915
916 fsia_ick = clk_get(&fsi_device.dev, "icka"); 998 fsia_ick = clk_get(&fsi_device.dev, "icka");
917 if (IS_ERR(fsia_ick)) { 999 if (IS_ERR(fsia_ick)) {
918 ret = PTR_ERR(fsia_ick); 1000 ret = PTR_ERR(fsia_ick);
@@ -921,16 +1003,9 @@ static int __init fsi_init_pm_clock(void)
921 } 1003 }
922 1004
923 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk); 1005 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
924 if (ret < 0) {
925 pr_err("Cannot set FSI-A parent: %d\n", ret);
926 goto out;
927 }
928
929 ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE);
930 if (ret < 0) 1006 if (ret < 0)
931 pr_err("Cannot set FSI-A rate: %d\n", ret); 1007 pr_err("Cannot set FSI-A parent: %d\n", ret);
932 1008
933out:
934 clk_put(fsia_ick); 1009 clk_put(fsia_ick);
935 1010
936 return ret; 1011 return ret;
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index b25ce90a346e..3aa026069435 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -229,21 +229,13 @@ static int pllc2_set_rate(struct clk *clk, unsigned long rate)
229 if (idx < 0) 229 if (idx < 0)
230 return idx; 230 return idx;
231 231
232 if (rate == clk->parent->rate) { 232 if (rate == clk->parent->rate)
233 pllc2_disable(clk); 233 return -EINVAL;
234 return 0;
235 }
236 234
237 value = __raw_readl(PLLC2CR) & ~(0x3f << 24); 235 value = __raw_readl(PLLC2CR) & ~(0x3f << 24);
238 236
239 if (value & 0x80000000)
240 pllc2_disable(clk);
241
242 __raw_writel((value & ~0x80000000) | ((idx + 19) << 24), PLLC2CR); 237 __raw_writel((value & ~0x80000000) | ((idx + 19) << 24), PLLC2CR);
243 238
244 if (value & 0x80000000)
245 return pllc2_enable(clk);
246
247 return 0; 239 return 0;
248} 240}
249 241
@@ -452,10 +444,8 @@ static int fsidiv_enable(struct clk *clk)
452 unsigned long value; 444 unsigned long value;
453 445
454 value = __raw_readl(clk->mapping->base) >> 16; 446 value = __raw_readl(clk->mapping->base) >> 16;
455 if (value < 2) { 447 if (value < 2)
456 fsidiv_disable(clk); 448 return -EIO;
457 return -ENOENT;
458 }
459 449
460 __raw_writel((value << 16) | 0x3, clk->mapping->base); 450 __raw_writel((value << 16) | 0x3, clk->mapping->base);
461 451
@@ -466,17 +456,12 @@ static int fsidiv_set_rate(struct clk *clk, unsigned long rate)
466{ 456{
467 int idx; 457 int idx;
468 458
469 if (clk->parent->rate == rate) {
470 fsidiv_disable(clk);
471 return 0;
472 }
473
474 idx = (clk->parent->rate / rate) & 0xffff; 459 idx = (clk->parent->rate / rate) & 0xffff;
475 if (idx < 2) 460 if (idx < 2)
476 return -ENOENT; 461 return -EINVAL;
477 462
478 __raw_writel(idx << 16, clk->mapping->base); 463 __raw_writel(idx << 16, clk->mapping->base);
479 return fsidiv_enable(clk); 464 return 0;
480} 465}
481 466
482static struct clk_ops fsidiv_clk_ops = { 467static struct clk_ops fsidiv_clk_ops = {
@@ -607,8 +592,6 @@ static struct clk_lookup lookups[] = {
607 CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), 592 CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
608 CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]), 593 CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
609 CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]), 594 CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
610 CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FSIA]),
611 CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FSIB]),
612 CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), 595 CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
613 CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), 596 CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
614 CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), 597 CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
@@ -645,8 +628,8 @@ static struct clk_lookup lookups[] = {
645 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */ 628 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
646 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */ 629 CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI2 */
647 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */ 630 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
648 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */ 631 CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
649 CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP323]), /* USB0 */ 632 CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
650 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */ 633 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
651 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */ 634 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
652 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */ 635 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */