diff options
| author | Sascha Hauer <s.hauer@pengutronix.de> | 2010-12-06 03:13:21 -0500 |
|---|---|---|
| committer | Sascha Hauer <s.hauer@pengutronix.de> | 2011-01-03 10:30:56 -0500 |
| commit | b848169b37f71c494ea59b260ba665290c23c350 (patch) | |
| tree | f12c9815603bb94af5e5b08df3ea8244319f55b0 | |
| parent | c67a3e09a5316bb34a14e2751cee719339934235 (diff) | |
ARM i.MX51: Add ipu clock support
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
| -rw-r--r-- | arch/arm/mach-mx5/clock-mx51-mx53.c | 140 |
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 2f9eae213094..ba9432c8f843 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; | |||
| 39 | static struct clk ahb_clk; | 39 | static struct clk ahb_clk; |
| 40 | static struct clk ipg_clk; | 40 | static struct clk ipg_clk; |
| 41 | static struct clk usboh3_clk; | 41 | static struct clk usboh3_clk; |
| 42 | static struct clk emi_fast_clk; | ||
| 43 | static struct clk ipu_clk; | ||
| 44 | static 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 | ||
| 694 | static 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 */ |
| 692 | static struct clk ckih_clk = { | 708 | static 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 | ||
| 865 | static 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 | |||
| 884 | static 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 | |||
| 901 | static 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 | |||
| 910 | static struct clk ipu_sec_clk = { | ||
| 911 | .parent = &emi_fast_clk, | ||
| 912 | .secondary = &ahbmux1_clk, | ||
| 913 | }; | ||
| 914 | |||
| 915 | static struct clk ddr_hf_clk = { | ||
| 916 | .parent = &pll1_sw_clk, | ||
| 917 | .get_rate = _clk_ddr_hf_get_rate, | ||
| 918 | }; | ||
| 919 | |||
| 920 | static 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 | */ | ||
| 927 | static 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 | |||
| 944 | static 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 | |||
| 959 | static 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, | |||
| 1112 | DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET, | 1231 | DEFINE_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 | ||
| 1234 | DEFINE_CLOCK(mipi_esc_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG5_OFFSET, NULL, NULL, NULL, &pll2_sw_clk); | ||
| 1235 | DEFINE_CLOCK(mipi_hsc2_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG4_OFFSET, NULL, NULL, &mipi_esc_clk, &pll2_sw_clk); | ||
| 1236 | DEFINE_CLOCK(mipi_hsc1_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG3_OFFSET, NULL, NULL, &mipi_hsc2_clk, &pll2_sw_clk); | ||
| 1237 | |||
| 1238 | /* IPU */ | ||
| 1239 | DEFINE_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 | |||
| 1242 | DEFINE_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 | |||
| 1246 | DEFINE_CLOCK(ipu_di0_clk, 0, MXC_CCM_CCGR6, MXC_CCM_CCGRx_CG5_OFFSET, | ||
| 1247 | NULL, NULL, &pll3_sw_clk, NULL); | ||
| 1248 | DEFINE_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 | ||
| 1160 | static struct clk_lookup mx53_lookups[] = { | 1300 | static struct clk_lookup mx53_lookups[] = { |
