aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mx5/clock-mx51-mx53.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2010-12-06 03:13:21 -0500
committerSascha Hauer <s.hauer@pengutronix.de>2011-01-03 10:30:56 -0500
commitb848169b37f71c494ea59b260ba665290c23c350 (patch)
treef12c9815603bb94af5e5b08df3ea8244319f55b0 /arch/arm/mach-mx5/clock-mx51-mx53.c
parentc67a3e09a5316bb34a14e2751cee719339934235 (diff)
ARM i.MX51: Add ipu clock support
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-mx5/clock-mx51-mx53.c')
-rw-r--r--arch/arm/mach-mx5/clock-mx51-mx53.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
index 2f9eae21309..ba9432c8f84 100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -39,6 +39,9 @@ static struct clk periph_apm_clk;
39static struct clk ahb_clk; 39static struct clk ahb_clk;
40static struct clk ipg_clk; 40static struct clk ipg_clk;
41static struct clk usboh3_clk; 41static struct clk usboh3_clk;
42static struct clk emi_fast_clk;
43static struct clk ipu_clk;
44static struct clk mipi_hsc1_clk;
42 45
43#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ 46#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */
44 47
@@ -688,6 +691,19 @@ static unsigned long clk_emi_slow_get_rate(struct clk *clk)
688 return clk_get_rate(clk->parent) / div; 691 return clk_get_rate(clk->parent) / div;
689} 692}
690 693
694static unsigned long _clk_ddr_hf_get_rate(struct clk *clk)
695{
696 unsigned long rate;
697 u32 reg, div;
698
699 reg = __raw_readl(MXC_CCM_CBCDR);
700 div = ((reg & MXC_CCM_CBCDR_DDR_PODF_MASK) >>
701 MXC_CCM_CBCDR_DDR_PODF_OFFSET) + 1;
702 rate = clk_get_rate(clk->parent) / div;
703
704 return rate;
705}
706
691/* External high frequency clock */ 707/* External high frequency clock */
692static struct clk ckih_clk = { 708static struct clk ckih_clk = {
693 .get_rate = get_high_reference_clock_rate, 709 .get_rate = get_high_reference_clock_rate,
@@ -846,6 +862,109 @@ static struct clk emi_slow_clk = {
846 .get_rate = clk_emi_slow_get_rate, 862 .get_rate = clk_emi_slow_get_rate,
847}; 863};
848 864
865static int clk_ipu_enable(struct clk *clk)
866{
867 u32 reg;
868
869 _clk_ccgr_enable(clk);
870
871 /* Enable handshake with IPU when certain clock rates are changed */
872 reg = __raw_readl(MXC_CCM_CCDR);
873 reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
874 __raw_writel(reg, MXC_CCM_CCDR);
875
876 /* Enable handshake with IPU when LPM is entered */
877 reg = __raw_readl(MXC_CCM_CLPCR);
878 reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
879 __raw_writel(reg, MXC_CCM_CLPCR);
880
881 return 0;
882}
883
884static void clk_ipu_disable(struct clk *clk)
885{
886 u32 reg;
887
888 _clk_ccgr_disable(clk);
889
890 /* Disable handshake with IPU whe dividers are changed */
891 reg = __raw_readl(MXC_CCM_CCDR);
892 reg |= MXC_CCM_CCDR_IPU_HS_MASK;
893 __raw_writel(reg, MXC_CCM_CCDR);
894
895 /* Disable handshake with IPU when LPM is entered */
896 reg = __raw_readl(MXC_CCM_CLPCR);
897 reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
898 __raw_writel(reg, MXC_CCM_CLPCR);
899}
900
901static struct clk ahbmux1_clk = {
902 .parent = &ahb_clk,
903 .secondary = &ahb_max_clk,
904 .enable_reg = MXC_CCM_CCGR0,
905 .enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
906 .enable = _clk_ccgr_enable,
907 .disable = _clk_ccgr_disable_inwait,
908};
909
910static struct clk ipu_sec_clk = {
911 .parent = &emi_fast_clk,
912 .secondary = &ahbmux1_clk,
913};
914
915static struct clk ddr_hf_clk = {
916 .parent = &pll1_sw_clk,
917 .get_rate = _clk_ddr_hf_get_rate,
918};
919
920static struct clk ddr_clk = {
921 .parent = &ddr_hf_clk,
922};
923
924/* clock definitions for MIPI HSC unit which has been removed
925 * from documentation, but not from hardware
926 */
927static int _clk_hsc_enable(struct clk *clk)
928{
929 u32 reg;
930
931 _clk_ccgr_enable(clk);
932 /* Handshake with IPU when certain clock rates are changed. */
933 reg = __raw_readl(MXC_CCM_CCDR);
934 reg &= ~MXC_CCM_CCDR_HSC_HS_MASK;
935 __raw_writel(reg, MXC_CCM_CCDR);
936
937 reg = __raw_readl(MXC_CCM_CLPCR);
938 reg &= ~MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
939 __raw_writel(reg, MXC_CCM_CLPCR);
940
941 return 0;
942}
943
944static void _clk_hsc_disable(struct clk *clk)
945{
946 u32 reg;
947
948 _clk_ccgr_disable(clk);
949 /* No handshake with HSC as its not enabled. */
950 reg = __raw_readl(MXC_CCM_CCDR);
951 reg |= MXC_CCM_CCDR_HSC_HS_MASK;
952 __raw_writel(reg, MXC_CCM_CCDR);
953
954 reg = __raw_readl(MXC_CCM_CLPCR);
955 reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
956 __raw_writel(reg, MXC_CCM_CLPCR);
957}
958
959static struct clk mipi_hsp_clk = {
960 .parent = &ipu_clk,
961 .enable_reg = MXC_CCM_CCGR4,
962 .enable_shift = MXC_CCM_CCGRx_CG6_OFFSET,
963 .enable = _clk_hsc_enable,
964 .disable = _clk_hsc_disable,
965 .secondary = &mipi_hsc1_clk,
966};
967
849#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \ 968#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \
850 static struct clk name = { \ 969 static struct clk name = { \
851 .id = i, \ 970 .id = i, \
@@ -1112,6 +1231,23 @@ DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET,
1112DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET, 1231DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET,
1113 clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk); 1232 clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk);
1114 1233
1234DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk);
1235DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk);
1236DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk);
1237
1238/* IPU */
1239DEFINE_CLOCK_FULL(ipu_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG5_OFFSET,
1240 NULL, NULL, clk_ipu_enable, clk_ipu_disable, &ahb_clk, &ipu_sec_clk);
1241
1242DEFINE_CLOCK_FULL(emi_fast_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG7_OFFSET,
1243 NULL, NULL, _clk_ccgr_enable, _clk_ccgr_disable_inwait,
1244 &ddr_clk, NULL);
1245
1246DEFINE_CLOCK(ipu_di0_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG5_OFFSET,
1247 NULL, NULL, &pll3_sw_clk, NULL);
1248DEFINE_CLOCK(ipu_di1_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG6_OFFSET,
1249 NULL, NULL, &pll3_sw_clk, NULL);
1250
1115#define _REGISTER_CLOCK(d, n, c) \ 1251#define _REGISTER_CLOCK(d, n, c) \
1116 { \ 1252 { \
1117 .dev_id = d, \ 1253 .dev_id = d, \
@@ -1155,6 +1291,10 @@ static struct clk_lookup mx51_lookups[] = {
1155 _REGISTER_CLOCK(NULL, "iim_clk", iim_clk) 1291 _REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
1156 _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk) 1292 _REGISTER_CLOCK("imx2-wdt.0", NULL, dummy_clk)
1157 _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk) 1293 _REGISTER_CLOCK("imx2-wdt.1", NULL, dummy_clk)
1294 _REGISTER_CLOCK(NULL, "mipi_hsp", mipi_hsp_clk)
1295 _REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk)
1296 _REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk)
1297 _REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk)
1158}; 1298};
1159 1299
1160static struct clk_lookup mx53_lookups[] = { 1300static struct clk_lookup mx53_lookups[] = {