aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mx5/clock-mx51.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-mx5/clock-mx51.c')
-rw-r--r--arch/arm/mach-mx5/clock-mx51.c244
1 files changed, 151 insertions, 93 deletions
diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c
index 21cecc040172..f2aae92cf0e2 100644
--- a/arch/arm/mach-mx5/clock-mx51.c
+++ b/arch/arm/mach-mx5/clock-mx51.c
@@ -41,6 +41,36 @@ static struct clk usboh3_clk;
41 41
42#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ 42#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
43 43
44/* calculate best pre and post dividers to get the required divider */
45static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post,
46 u32 max_pre, u32 max_post)
47{
48 if (div >= max_pre * max_post) {
49 *pre = max_pre;
50 *post = max_post;
51 } else if (div >= max_pre) {
52 u32 min_pre, temp_pre, old_err, err;
53 min_pre = DIV_ROUND_UP(div, max_post);
54 old_err = max_pre;
55 for (temp_pre = max_pre; temp_pre >= min_pre; temp_pre--) {
56 err = div % temp_pre;
57 if (err == 0) {
58 *pre = temp_pre;
59 break;
60 }
61 err = temp_pre - err;
62 if (err < old_err) {
63 old_err = err;
64 *pre = temp_pre;
65 }
66 }
67 *post = DIV_ROUND_UP(div, *pre);
68 } else {
69 *pre = div;
70 *post = 1;
71 }
72}
73
44static void _clk_ccgr_setclk(struct clk *clk, unsigned mode) 74static void _clk_ccgr_setclk(struct clk *clk, unsigned mode)
45{ 75{
46 u32 reg = __raw_readl(clk->enable_reg); 76 u32 reg = __raw_readl(clk->enable_reg);
@@ -544,35 +574,6 @@ static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
544 return 0; 574 return 0;
545} 575}
546 576
547static unsigned long clk_uart_get_rate(struct clk *clk)
548{
549 u32 reg, prediv, podf;
550 unsigned long parent_rate;
551
552 parent_rate = clk_get_rate(clk->parent);
553
554 reg = __raw_readl(MXC_CCM_CSCDR1);
555 prediv = ((reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >>
556 MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1;
557 podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
558 MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
559
560 return parent_rate / (prediv * podf);
561}
562
563static int _clk_uart_set_parent(struct clk *clk, struct clk *parent)
564{
565 u32 reg, mux;
566
567 mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
568 &lp_apm_clk);
569 reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_UART_CLK_SEL_MASK;
570 reg |= mux << MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET;
571 __raw_writel(reg, MXC_CCM_CSCMR1);
572
573 return 0;
574}
575
576#define clk_nfc_set_parent NULL 577#define clk_nfc_set_parent NULL
577 578
578static unsigned long clk_nfc_get_rate(struct clk *clk) 579static unsigned long clk_nfc_get_rate(struct clk *clk)
@@ -631,35 +632,6 @@ static int clk_nfc_set_rate(struct clk *clk, unsigned long rate)
631 return 0; 632 return 0;
632} 633}
633 634
634static unsigned long clk_usboh3_get_rate(struct clk *clk)
635{
636 u32 reg, prediv, podf;
637 unsigned long parent_rate;
638
639 parent_rate = clk_get_rate(clk->parent);
640
641 reg = __raw_readl(MXC_CCM_CSCDR1);
642 prediv = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK) >>
643 MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET) + 1;
644 podf = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK) >>
645 MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET) + 1;
646
647 return parent_rate / (prediv * podf);
648}
649
650static int _clk_usboh3_set_parent(struct clk *clk, struct clk *parent)
651{
652 u32 reg, mux;
653
654 mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
655 &lp_apm_clk);
656 reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK;
657 reg |= mux << MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET;
658 __raw_writel(reg, MXC_CCM_CSCMR1);
659
660 return 0;
661}
662
663static unsigned long get_high_reference_clock_rate(struct clk *clk) 635static unsigned long get_high_reference_clock_rate(struct clk *clk)
664{ 636{
665 return external_high_reference; 637 return external_high_reference;
@@ -786,18 +758,6 @@ static struct clk ipg_perclk = {
786 .set_parent = _clk_ipg_per_set_parent, 758 .set_parent = _clk_ipg_per_set_parent,
787}; 759};
788 760
789static struct clk uart_root_clk = {
790 .parent = &pll2_sw_clk,
791 .get_rate = clk_uart_get_rate,
792 .set_parent = _clk_uart_set_parent,
793};
794
795static struct clk usboh3_clk = {
796 .parent = &pll2_sw_clk,
797 .get_rate = clk_usboh3_get_rate,
798 .set_parent = _clk_usboh3_set_parent,
799};
800
801static struct clk ahb_max_clk = { 761static struct clk ahb_max_clk = {
802 .parent = &ahb_clk, 762 .parent = &ahb_clk,
803 .enable_reg = MXC_CCM_CCGR0, 763 .enable_reg = MXC_CCM_CCGR0,
@@ -842,7 +802,7 @@ static struct clk emi_slow_clk = {
842 .get_rate = clk_emi_slow_get_rate, 802 .get_rate = clk_emi_slow_get_rate,
843}; 803};
844 804
845#define DEFINE_CLOCK1(name, i, er, es, pfx, p, s) \ 805#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \
846 static struct clk name = { \ 806 static struct clk name = { \
847 .id = i, \ 807 .id = i, \
848 .enable_reg = er, \ 808 .enable_reg = er, \
@@ -857,35 +817,104 @@ static struct clk emi_slow_clk = {
857 .secondary = s, \ 817 .secondary = s, \
858 } 818 }
859 819
860/* eCSPI */ 820#define DEFINE_CLOCK_MAX(name, i, er, es, pfx, p, s) \
861static unsigned long clk_ecspi_get_rate(struct clk *clk) 821 static struct clk name = { \
862{ 822 .id = i, \
863 u32 reg, pred, podf; 823 .enable_reg = er, \
824 .enable_shift = es, \
825 .get_rate = pfx##_get_rate, \
826 .set_rate = pfx##_set_rate, \
827 .set_parent = pfx##_set_parent, \
828 .enable = _clk_max_enable, \
829 .disable = _clk_max_disable, \
830 .parent = p, \
831 .secondary = s, \
832 }
864 833
865 reg = __raw_readl(MXC_CCM_CSCDR2); 834#define CLK_GET_RATE(name, nr, bitsname) \
835static unsigned long clk_##name##_get_rate(struct clk *clk) \
836{ \
837 u32 reg, pred, podf; \
838 \
839 reg = __raw_readl(MXC_CCM_CSCDR##nr); \
840 pred = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK) \
841 >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \
842 podf = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK) \
843 >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \
844 \
845 return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), \
846 (pred + 1) * (podf + 1)); \
847}
866 848
867 pred = (reg & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) >> 849#define CLK_SET_PARENT(name, nr, bitsname) \
868 MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET; 850static int clk_##name##_set_parent(struct clk *clk, struct clk *parent) \
869 podf = (reg & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) >> 851{ \
870 MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET; 852 u32 reg, mux; \
853 \
854 mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, \
855 &pll3_sw_clk, &lp_apm_clk); \
856 reg = __raw_readl(MXC_CCM_CSCMR##nr) & \
857 ~MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_MASK; \
858 reg |= mux << MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_OFFSET; \
859 __raw_writel(reg, MXC_CCM_CSCMR##nr); \
860 \
861 return 0; \
862}
871 863
872 return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), 864#define CLK_SET_RATE(name, nr, bitsname) \
873 (pred + 1) * (podf + 1)); 865static int clk_##name##_set_rate(struct clk *clk, unsigned long rate) \
866{ \
867 u32 reg, div, parent_rate; \
868 u32 pre = 0, post = 0; \
869 \
870 parent_rate = clk_get_rate(clk->parent); \
871 div = parent_rate / rate; \
872 \
873 if ((parent_rate / div) != rate) \
874 return -EINVAL; \
875 \
876 __calc_pre_post_dividers(div, &pre, &post, \
877 (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK >> \
878 MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET) + 1, \
879 (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK >> \
880 MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET) + 1);\
881 \
882 /* Set sdhc1 clock divider */ \
883 reg = __raw_readl(MXC_CCM_CSCDR##nr) & \
884 ~(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK \
885 | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK); \
886 reg |= (post - 1) << \
887 MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET; \
888 reg |= (pre - 1) << \
889 MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET; \
890 __raw_writel(reg, MXC_CCM_CSCDR##nr); \
891 \
892 return 0; \
874} 893}
875 894
876static int clk_ecspi_set_parent(struct clk *clk, struct clk *parent) 895/* UART */
877{ 896CLK_GET_RATE(uart, 1, UART)
878 u32 reg, mux; 897CLK_SET_PARENT(uart, 1, UART)
879 898
880 mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, 899static struct clk uart_root_clk = {
881 &lp_apm_clk); 900 .parent = &pll2_sw_clk,
901 .get_rate = clk_uart_get_rate,
902 .set_parent = clk_uart_set_parent,
903};
882 904
883 reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK; 905/* USBOH3 */
884 reg |= mux << MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET; 906CLK_GET_RATE(usboh3, 1, USBOH3)
885 __raw_writel(reg, MXC_CCM_CSCMR1); 907CLK_SET_PARENT(usboh3, 1, USBOH3)
886 908
887 return 0; 909static struct clk usboh3_clk = {
888} 910 .parent = &pll2_sw_clk,
911 .get_rate = clk_usboh3_get_rate,
912 .set_parent = clk_usboh3_set_parent,
913};
914
915/* eCSPI */
916CLK_GET_RATE(ecspi, 2, CSPI)
917CLK_SET_PARENT(ecspi, 1, CSPI)
889 918
890static struct clk ecspi_main_clk = { 919static struct clk ecspi_main_clk = {
891 .parent = &pll3_sw_clk, 920 .parent = &pll3_sw_clk,
@@ -893,6 +922,15 @@ static struct clk ecspi_main_clk = {
893 .set_parent = clk_ecspi_set_parent, 922 .set_parent = clk_ecspi_set_parent,
894}; 923};
895 924
925/* eSDHC */
926CLK_GET_RATE(esdhc1, 1, ESDHC1_MSHC1)
927CLK_SET_PARENT(esdhc1, 1, ESDHC1_MSHC1)
928CLK_SET_RATE(esdhc1, 1, ESDHC1_MSHC1)
929
930CLK_GET_RATE(esdhc2, 1, ESDHC2_MSHC2)
931CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2)
932CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2)
933
896#define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \ 934#define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \
897 static struct clk name = { \ 935 static struct clk name = { \
898 .id = i, \ 936 .id = i, \
@@ -946,7 +984,7 @@ DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
946 NULL, NULL, &ipg_clk, NULL); 984 NULL, NULL, &ipg_clk, NULL);
947 985
948/* NFC */ 986/* NFC */
949DEFINE_CLOCK1(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET, 987DEFINE_CLOCK_CCGR(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET,
950 clk_nfc, &emi_slow_clk, NULL); 988 clk_nfc, &emi_slow_clk, NULL);
951 989
952/* SSI */ 990/* SSI */
@@ -981,6 +1019,16 @@ DEFINE_CLOCK(cspi_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG13_OFFSET,
981DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET, 1019DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET,
982 NULL, NULL, &ahb_clk, NULL); 1020 NULL, NULL, &ahb_clk, NULL);
983 1021
1022/* eSDHC */
1023DEFINE_CLOCK_FULL(esdhc1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG0_OFFSET,
1024 NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
1025DEFINE_CLOCK_MAX(esdhc1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG1_OFFSET,
1026 clk_esdhc1, &pll2_sw_clk, &esdhc1_ipg_clk);
1027DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET,
1028 NULL, NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
1029DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET,
1030 clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk);
1031
984#define _REGISTER_CLOCK(d, n, c) \ 1032#define _REGISTER_CLOCK(d, n, c) \
985 { \ 1033 { \
986 .dev_id = d, \ 1034 .dev_id = d, \
@@ -1014,6 +1062,8 @@ static struct clk_lookup lookups[] = {
1014 _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk) 1062 _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk)
1015 _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk) 1063 _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk)
1016 _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk) 1064 _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk)
1065 _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
1066 _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
1017}; 1067};
1018 1068
1019static void clk_tree_init(void) 1069static void clk_tree_init(void)
@@ -1057,6 +1107,14 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
1057 /* set the usboh3_clk parent to pll2_sw_clk */ 1107 /* set the usboh3_clk parent to pll2_sw_clk */
1058 clk_set_parent(&usboh3_clk, &pll2_sw_clk); 1108 clk_set_parent(&usboh3_clk, &pll2_sw_clk);
1059 1109
1110 /* Set SDHC parents to be PLL2 */
1111 clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
1112 clk_set_parent(&esdhc2_clk, &pll2_sw_clk);
1113
1114 /* set SDHC root clock as 166.25MHZ*/
1115 clk_set_rate(&esdhc1_clk, 166250000);
1116 clk_set_rate(&esdhc2_clk, 166250000);
1117
1060 /* System timer */ 1118 /* System timer */
1061 mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), 1119 mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
1062 MX51_MXC_INT_GPT); 1120 MX51_MXC_INT_GPT);