diff options
Diffstat (limited to 'arch/arm/mach-s5pv210/clock.c')
-rw-r--r-- | arch/arm/mach-s5pv210/clock.c | 151 |
1 files changed, 136 insertions, 15 deletions
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index f5f8fa89679c..4c5ac7a69e9e 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c | |||
@@ -174,6 +174,16 @@ static int s5pv210_clk_mask1_ctrl(struct clk *clk, int enable) | |||
174 | return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable); | 174 | return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable); |
175 | } | 175 | } |
176 | 176 | ||
177 | static int exynos4_clk_hdmiphy_ctrl(struct clk *clk, int enable) | ||
178 | { | ||
179 | return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable); | ||
180 | } | ||
181 | |||
182 | static int exynos4_clk_dac_ctrl(struct clk *clk, int enable) | ||
183 | { | ||
184 | return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable); | ||
185 | } | ||
186 | |||
177 | static struct clk clk_sclk_hdmi27m = { | 187 | static struct clk clk_sclk_hdmi27m = { |
178 | .name = "sclk_hdmi27m", | 188 | .name = "sclk_hdmi27m", |
179 | .rate = 27000000, | 189 | .rate = 27000000, |
@@ -203,6 +213,11 @@ static struct clk clk_pcmcdclk2 = { | |||
203 | .name = "pcmcdclk", | 213 | .name = "pcmcdclk", |
204 | }; | 214 | }; |
205 | 215 | ||
216 | static struct clk dummy_apb_pclk = { | ||
217 | .name = "apb_pclk", | ||
218 | .id = -1, | ||
219 | }; | ||
220 | |||
206 | static struct clk *clkset_vpllsrc_list[] = { | 221 | static struct clk *clkset_vpllsrc_list[] = { |
207 | [0] = &clk_fin_vpll, | 222 | [0] = &clk_fin_vpll, |
208 | [1] = &clk_sclk_hdmi27m, | 223 | [1] = &clk_sclk_hdmi27m, |
@@ -289,14 +304,14 @@ static struct clk_ops clk_fout_apll_ops = { | |||
289 | 304 | ||
290 | static struct clk init_clocks_off[] = { | 305 | static struct clk init_clocks_off[] = { |
291 | { | 306 | { |
292 | .name = "pdma", | 307 | .name = "dma", |
293 | .devname = "s3c-pl330.0", | 308 | .devname = "dma-pl330.0", |
294 | .parent = &clk_hclk_psys.clk, | 309 | .parent = &clk_hclk_psys.clk, |
295 | .enable = s5pv210_clk_ip0_ctrl, | 310 | .enable = s5pv210_clk_ip0_ctrl, |
296 | .ctrlbit = (1 << 3), | 311 | .ctrlbit = (1 << 3), |
297 | }, { | 312 | }, { |
298 | .name = "pdma", | 313 | .name = "dma", |
299 | .devname = "s3c-pl330.1", | 314 | .devname = "dma-pl330.1", |
300 | .parent = &clk_hclk_psys.clk, | 315 | .parent = &clk_hclk_psys.clk, |
301 | .enable = s5pv210_clk_ip0_ctrl, | 316 | .enable = s5pv210_clk_ip0_ctrl, |
302 | .ctrlbit = (1 << 4), | 317 | .ctrlbit = (1 << 4), |
@@ -330,6 +345,40 @@ static struct clk init_clocks_off[] = { | |||
330 | .enable = s5pv210_clk_ip0_ctrl, | 345 | .enable = s5pv210_clk_ip0_ctrl, |
331 | .ctrlbit = (1 << 16), | 346 | .ctrlbit = (1 << 16), |
332 | }, { | 347 | }, { |
348 | .name = "dac", | ||
349 | .devname = "s5p-sdo", | ||
350 | .parent = &clk_hclk_dsys.clk, | ||
351 | .enable = s5pv210_clk_ip1_ctrl, | ||
352 | .ctrlbit = (1 << 10), | ||
353 | }, { | ||
354 | .name = "mixer", | ||
355 | .devname = "s5p-mixer", | ||
356 | .parent = &clk_hclk_dsys.clk, | ||
357 | .enable = s5pv210_clk_ip1_ctrl, | ||
358 | .ctrlbit = (1 << 9), | ||
359 | }, { | ||
360 | .name = "vp", | ||
361 | .devname = "s5p-mixer", | ||
362 | .parent = &clk_hclk_dsys.clk, | ||
363 | .enable = s5pv210_clk_ip1_ctrl, | ||
364 | .ctrlbit = (1 << 8), | ||
365 | }, { | ||
366 | .name = "hdmi", | ||
367 | .devname = "s5pv210-hdmi", | ||
368 | .parent = &clk_hclk_dsys.clk, | ||
369 | .enable = s5pv210_clk_ip1_ctrl, | ||
370 | .ctrlbit = (1 << 11), | ||
371 | }, { | ||
372 | .name = "hdmiphy", | ||
373 | .devname = "s5pv210-hdmi", | ||
374 | .enable = exynos4_clk_hdmiphy_ctrl, | ||
375 | .ctrlbit = (1 << 0), | ||
376 | }, { | ||
377 | .name = "dacphy", | ||
378 | .devname = "s5p-sdo", | ||
379 | .enable = exynos4_clk_dac_ctrl, | ||
380 | .ctrlbit = (1 << 0), | ||
381 | }, { | ||
333 | .name = "otg", | 382 | .name = "otg", |
334 | .parent = &clk_hclk_psys.clk, | 383 | .parent = &clk_hclk_psys.clk, |
335 | .enable = s5pv210_clk_ip1_ctrl, | 384 | .enable = s5pv210_clk_ip1_ctrl, |
@@ -407,6 +456,12 @@ static struct clk init_clocks_off[] = { | |||
407 | .enable = s5pv210_clk_ip3_ctrl, | 456 | .enable = s5pv210_clk_ip3_ctrl, |
408 | .ctrlbit = (1<<9), | 457 | .ctrlbit = (1<<9), |
409 | }, { | 458 | }, { |
459 | .name = "i2c", | ||
460 | .devname = "s3c2440-hdmiphy-i2c", | ||
461 | .parent = &clk_pclk_psys.clk, | ||
462 | .enable = s5pv210_clk_ip3_ctrl, | ||
463 | .ctrlbit = (1 << 11), | ||
464 | }, { | ||
410 | .name = "spi", | 465 | .name = "spi", |
411 | .devname = "s3c64xx-spi.0", | 466 | .devname = "s3c64xx-spi.0", |
412 | .parent = &clk_pclk_psys.clk, | 467 | .parent = &clk_pclk_psys.clk, |
@@ -594,6 +649,23 @@ static struct clksrc_sources clkset_sclk_mixer = { | |||
594 | .nr_sources = ARRAY_SIZE(clkset_sclk_mixer_list), | 649 | .nr_sources = ARRAY_SIZE(clkset_sclk_mixer_list), |
595 | }; | 650 | }; |
596 | 651 | ||
652 | static struct clksrc_clk clk_sclk_mixer = { | ||
653 | .clk = { | ||
654 | .name = "sclk_mixer", | ||
655 | .enable = s5pv210_clk_mask0_ctrl, | ||
656 | .ctrlbit = (1 << 1), | ||
657 | }, | ||
658 | .sources = &clkset_sclk_mixer, | ||
659 | .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 }, | ||
660 | }; | ||
661 | |||
662 | static struct clksrc_clk *sclk_tv[] = { | ||
663 | &clk_sclk_dac, | ||
664 | &clk_sclk_pixel, | ||
665 | &clk_sclk_hdmi, | ||
666 | &clk_sclk_mixer, | ||
667 | }; | ||
668 | |||
597 | static struct clk *clkset_sclk_audio0_list[] = { | 669 | static struct clk *clkset_sclk_audio0_list[] = { |
598 | [0] = &clk_ext_xtal_mux, | 670 | [0] = &clk_ext_xtal_mux, |
599 | [1] = &clk_pcmcdclk0, | 671 | [1] = &clk_pcmcdclk0, |
@@ -777,14 +849,6 @@ static struct clksrc_clk clksrcs[] = { | |||
777 | .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 }, | 849 | .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 }, |
778 | }, { | 850 | }, { |
779 | .clk = { | 851 | .clk = { |
780 | .name = "sclk_mixer", | ||
781 | .enable = s5pv210_clk_mask0_ctrl, | ||
782 | .ctrlbit = (1 << 1), | ||
783 | }, | ||
784 | .sources = &clkset_sclk_mixer, | ||
785 | .reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 }, | ||
786 | }, { | ||
787 | .clk = { | ||
788 | .name = "sclk_fimc", | 852 | .name = "sclk_fimc", |
789 | .devname = "s5pv210-fimc.0", | 853 | .devname = "s5pv210-fimc.0", |
790 | .enable = s5pv210_clk_mask1_ctrl, | 854 | .enable = s5pv210_clk_mask1_ctrl, |
@@ -973,9 +1037,6 @@ static struct clksrc_clk *sysclks[] = { | |||
973 | &clk_pclk_psys, | 1037 | &clk_pclk_psys, |
974 | &clk_vpllsrc, | 1038 | &clk_vpllsrc, |
975 | &clk_sclk_vpll, | 1039 | &clk_sclk_vpll, |
976 | &clk_sclk_dac, | ||
977 | &clk_sclk_pixel, | ||
978 | &clk_sclk_hdmi, | ||
979 | &clk_mout_dmc0, | 1040 | &clk_mout_dmc0, |
980 | &clk_sclk_dmc0, | 1041 | &clk_sclk_dmc0, |
981 | &clk_sclk_audio0, | 1042 | &clk_sclk_audio0, |
@@ -1060,6 +1121,61 @@ static struct clk_ops s5pv210_epll_ops = { | |||
1060 | .get_rate = s5p_epll_get_rate, | 1121 | .get_rate = s5p_epll_get_rate, |
1061 | }; | 1122 | }; |
1062 | 1123 | ||
1124 | static u32 vpll_div[][5] = { | ||
1125 | { 54000000, 3, 53, 3, 0 }, | ||
1126 | { 108000000, 3, 53, 2, 0 }, | ||
1127 | }; | ||
1128 | |||
1129 | static unsigned long s5pv210_vpll_get_rate(struct clk *clk) | ||
1130 | { | ||
1131 | return clk->rate; | ||
1132 | } | ||
1133 | |||
1134 | static int s5pv210_vpll_set_rate(struct clk *clk, unsigned long rate) | ||
1135 | { | ||
1136 | unsigned int vpll_con; | ||
1137 | unsigned int i; | ||
1138 | |||
1139 | /* Return if nothing changed */ | ||
1140 | if (clk->rate == rate) | ||
1141 | return 0; | ||
1142 | |||
1143 | vpll_con = __raw_readl(S5P_VPLL_CON); | ||
1144 | vpll_con &= ~(0x1 << 27 | \ | ||
1145 | PLL90XX_MDIV_MASK << PLL90XX_MDIV_SHIFT | \ | ||
1146 | PLL90XX_PDIV_MASK << PLL90XX_PDIV_SHIFT | \ | ||
1147 | PLL90XX_SDIV_MASK << PLL90XX_SDIV_SHIFT); | ||
1148 | |||
1149 | for (i = 0; i < ARRAY_SIZE(vpll_div); i++) { | ||
1150 | if (vpll_div[i][0] == rate) { | ||
1151 | vpll_con |= vpll_div[i][1] << PLL90XX_PDIV_SHIFT; | ||
1152 | vpll_con |= vpll_div[i][2] << PLL90XX_MDIV_SHIFT; | ||
1153 | vpll_con |= vpll_div[i][3] << PLL90XX_SDIV_SHIFT; | ||
1154 | vpll_con |= vpll_div[i][4] << 27; | ||
1155 | break; | ||
1156 | } | ||
1157 | } | ||
1158 | |||
1159 | if (i == ARRAY_SIZE(vpll_div)) { | ||
1160 | printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n", | ||
1161 | __func__); | ||
1162 | return -EINVAL; | ||
1163 | } | ||
1164 | |||
1165 | __raw_writel(vpll_con, S5P_VPLL_CON); | ||
1166 | |||
1167 | /* Wait for VPLL lock */ | ||
1168 | while (!(__raw_readl(S5P_VPLL_CON) & (1 << PLL90XX_LOCKED_SHIFT))) | ||
1169 | continue; | ||
1170 | |||
1171 | clk->rate = rate; | ||
1172 | return 0; | ||
1173 | } | ||
1174 | static struct clk_ops s5pv210_vpll_ops = { | ||
1175 | .get_rate = s5pv210_vpll_get_rate, | ||
1176 | .set_rate = s5pv210_vpll_set_rate, | ||
1177 | }; | ||
1178 | |||
1063 | void __init_or_cpufreq s5pv210_setup_clocks(void) | 1179 | void __init_or_cpufreq s5pv210_setup_clocks(void) |
1064 | { | 1180 | { |
1065 | struct clk *xtal_clk; | 1181 | struct clk *xtal_clk; |
@@ -1108,6 +1224,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) | |||
1108 | clk_fout_apll.ops = &clk_fout_apll_ops; | 1224 | clk_fout_apll.ops = &clk_fout_apll_ops; |
1109 | clk_fout_mpll.rate = mpll; | 1225 | clk_fout_mpll.rate = mpll; |
1110 | clk_fout_epll.rate = epll; | 1226 | clk_fout_epll.rate = epll; |
1227 | clk_fout_vpll.ops = &s5pv210_vpll_ops; | ||
1111 | clk_fout_vpll.rate = vpll; | 1228 | clk_fout_vpll.rate = vpll; |
1112 | 1229 | ||
1113 | printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld", | 1230 | printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld", |
@@ -1153,11 +1270,15 @@ void __init s5pv210_register_clocks(void) | |||
1153 | for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) | 1270 | for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) |
1154 | s3c_register_clksrc(sysclks[ptr], 1); | 1271 | s3c_register_clksrc(sysclks[ptr], 1); |
1155 | 1272 | ||
1273 | for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++) | ||
1274 | s3c_register_clksrc(sclk_tv[ptr], 1); | ||
1275 | |||
1156 | s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); | 1276 | s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); |
1157 | s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); | 1277 | s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); |
1158 | 1278 | ||
1159 | s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); | 1279 | s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); |
1160 | s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); | 1280 | s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); |
1161 | 1281 | ||
1282 | s3c24xx_register_clock(&dummy_apb_pclk); | ||
1162 | s3c_pwmclk_init(); | 1283 | s3c_pwmclk_init(); |
1163 | } | 1284 | } |