diff options
Diffstat (limited to 'arch/arm/mach-s5pc100/clock.c')
-rw-r--r-- | arch/arm/mach-s5pc100/clock.c | 174 |
1 files changed, 112 insertions, 62 deletions
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c index 084abd13b0a5..2d4a761a5163 100644 --- a/arch/arm/mach-s5pc100/clock.c +++ b/arch/arm/mach-s5pc100/clock.c | |||
@@ -273,24 +273,6 @@ static struct clksrc_clk clk_div_hdmi = { | |||
273 | .reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 }, | 273 | .reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 }, |
274 | }; | 274 | }; |
275 | 275 | ||
276 | static int s5pc100_epll_enable(struct clk *clk, int enable) | ||
277 | { | ||
278 | unsigned int ctrlbit = clk->ctrlbit; | ||
279 | unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit; | ||
280 | |||
281 | if (enable) | ||
282 | __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON); | ||
283 | else | ||
284 | __raw_writel(epll_con, S5P_EPLL_CON); | ||
285 | |||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static unsigned long s5pc100_epll_get_rate(struct clk *clk) | ||
290 | { | ||
291 | return clk->rate; | ||
292 | } | ||
293 | |||
294 | static u32 epll_div[][4] = { | 276 | static u32 epll_div[][4] = { |
295 | { 32750000, 131, 3, 4 }, | 277 | { 32750000, 131, 3, 4 }, |
296 | { 32768000, 131, 3, 4 }, | 278 | { 32768000, 131, 3, 4 }, |
@@ -341,13 +323,16 @@ static int s5pc100_epll_set_rate(struct clk *clk, unsigned long rate) | |||
341 | 323 | ||
342 | __raw_writel(epll_con, S5P_EPLL_CON); | 324 | __raw_writel(epll_con, S5P_EPLL_CON); |
343 | 325 | ||
326 | printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n", | ||
327 | clk->rate, rate); | ||
328 | |||
344 | clk->rate = rate; | 329 | clk->rate = rate; |
345 | 330 | ||
346 | return 0; | 331 | return 0; |
347 | } | 332 | } |
348 | 333 | ||
349 | static struct clk_ops s5pc100_epll_ops = { | 334 | static struct clk_ops s5pc100_epll_ops = { |
350 | .get_rate = s5pc100_epll_get_rate, | 335 | .get_rate = s5p_epll_get_rate, |
351 | .set_rate = s5pc100_epll_set_rate, | 336 | .set_rate = s5pc100_epll_set_rate, |
352 | }; | 337 | }; |
353 | 338 | ||
@@ -691,55 +676,55 @@ static struct clk init_clocks_disable[] = { | |||
691 | }, { | 676 | }, { |
692 | .name = "iis", | 677 | .name = "iis", |
693 | .id = 0, | 678 | .id = 0, |
694 | .parent = &clk_div_d1_bus.clk, | 679 | .parent = &clk_div_pclkd1.clk, |
695 | .enable = s5pc100_d1_5_ctrl, | 680 | .enable = s5pc100_d1_5_ctrl, |
696 | .ctrlbit = (1 << 0), | 681 | .ctrlbit = (1 << 0), |
697 | }, { | 682 | }, { |
698 | .name = "iis", | 683 | .name = "iis", |
699 | .id = 1, | 684 | .id = 1, |
700 | .parent = &clk_div_d1_bus.clk, | 685 | .parent = &clk_div_pclkd1.clk, |
701 | .enable = s5pc100_d1_5_ctrl, | 686 | .enable = s5pc100_d1_5_ctrl, |
702 | .ctrlbit = (1 << 1), | 687 | .ctrlbit = (1 << 1), |
703 | }, { | 688 | }, { |
704 | .name = "iis", | 689 | .name = "iis", |
705 | .id = 2, | 690 | .id = 2, |
706 | .parent = &clk_div_d1_bus.clk, | 691 | .parent = &clk_div_pclkd1.clk, |
707 | .enable = s5pc100_d1_5_ctrl, | 692 | .enable = s5pc100_d1_5_ctrl, |
708 | .ctrlbit = (1 << 2), | 693 | .ctrlbit = (1 << 2), |
709 | }, { | 694 | }, { |
710 | .name = "ac97", | 695 | .name = "ac97", |
711 | .id = -1, | 696 | .id = -1, |
712 | .parent = &clk_div_d1_bus.clk, | 697 | .parent = &clk_div_pclkd1.clk, |
713 | .enable = s5pc100_d1_5_ctrl, | 698 | .enable = s5pc100_d1_5_ctrl, |
714 | .ctrlbit = (1 << 3), | 699 | .ctrlbit = (1 << 3), |
715 | }, { | 700 | }, { |
716 | .name = "pcm", | 701 | .name = "pcm", |
717 | .id = 0, | 702 | .id = 0, |
718 | .parent = &clk_div_d1_bus.clk, | 703 | .parent = &clk_div_pclkd1.clk, |
719 | .enable = s5pc100_d1_5_ctrl, | 704 | .enable = s5pc100_d1_5_ctrl, |
720 | .ctrlbit = (1 << 4), | 705 | .ctrlbit = (1 << 4), |
721 | }, { | 706 | }, { |
722 | .name = "pcm", | 707 | .name = "pcm", |
723 | .id = 1, | 708 | .id = 1, |
724 | .parent = &clk_div_d1_bus.clk, | 709 | .parent = &clk_div_pclkd1.clk, |
725 | .enable = s5pc100_d1_5_ctrl, | 710 | .enable = s5pc100_d1_5_ctrl, |
726 | .ctrlbit = (1 << 5), | 711 | .ctrlbit = (1 << 5), |
727 | }, { | 712 | }, { |
728 | .name = "spdif", | 713 | .name = "spdif", |
729 | .id = -1, | 714 | .id = -1, |
730 | .parent = &clk_div_d1_bus.clk, | 715 | .parent = &clk_div_pclkd1.clk, |
731 | .enable = s5pc100_d1_5_ctrl, | 716 | .enable = s5pc100_d1_5_ctrl, |
732 | .ctrlbit = (1 << 6), | 717 | .ctrlbit = (1 << 6), |
733 | }, { | 718 | }, { |
734 | .name = "adc", | 719 | .name = "adc", |
735 | .id = -1, | 720 | .id = -1, |
736 | .parent = &clk_div_d1_bus.clk, | 721 | .parent = &clk_div_pclkd1.clk, |
737 | .enable = s5pc100_d1_5_ctrl, | 722 | .enable = s5pc100_d1_5_ctrl, |
738 | .ctrlbit = (1 << 7), | 723 | .ctrlbit = (1 << 7), |
739 | }, { | 724 | }, { |
740 | .name = "keypad", | 725 | .name = "keypad", |
741 | .id = -1, | 726 | .id = -1, |
742 | .parent = &clk_div_d1_bus.clk, | 727 | .parent = &clk_div_pclkd1.clk, |
743 | .enable = s5pc100_d1_5_ctrl, | 728 | .enable = s5pc100_d1_5_ctrl, |
744 | .ctrlbit = (1 << 8), | 729 | .ctrlbit = (1 << 8), |
745 | }, { | 730 | }, { |
@@ -848,6 +833,18 @@ struct clksrc_sources clk_src_group3 = { | |||
848 | .nr_sources = ARRAY_SIZE(clk_src_group3_list), | 833 | .nr_sources = ARRAY_SIZE(clk_src_group3_list), |
849 | }; | 834 | }; |
850 | 835 | ||
836 | static struct clksrc_clk clk_sclk_audio0 = { | ||
837 | .clk = { | ||
838 | .name = "sclk_audio", | ||
839 | .id = 0, | ||
840 | .ctrlbit = (1 << 8), | ||
841 | .enable = s5pc100_sclk1_ctrl, | ||
842 | }, | ||
843 | .sources = &clk_src_group3, | ||
844 | .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 }, | ||
845 | .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 }, | ||
846 | }; | ||
847 | |||
851 | static struct clk *clk_src_group4_list[] = { | 848 | static struct clk *clk_src_group4_list[] = { |
852 | [0] = &clk_mout_epll.clk, | 849 | [0] = &clk_mout_epll.clk, |
853 | [1] = &clk_div_mpll.clk, | 850 | [1] = &clk_div_mpll.clk, |
@@ -862,6 +859,18 @@ struct clksrc_sources clk_src_group4 = { | |||
862 | .nr_sources = ARRAY_SIZE(clk_src_group4_list), | 859 | .nr_sources = ARRAY_SIZE(clk_src_group4_list), |
863 | }; | 860 | }; |
864 | 861 | ||
862 | static struct clksrc_clk clk_sclk_audio1 = { | ||
863 | .clk = { | ||
864 | .name = "sclk_audio", | ||
865 | .id = 1, | ||
866 | .ctrlbit = (1 << 9), | ||
867 | .enable = s5pc100_sclk1_ctrl, | ||
868 | }, | ||
869 | .sources = &clk_src_group4, | ||
870 | .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 }, | ||
871 | .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 }, | ||
872 | }; | ||
873 | |||
865 | static struct clk *clk_src_group5_list[] = { | 874 | static struct clk *clk_src_group5_list[] = { |
866 | [0] = &clk_mout_epll.clk, | 875 | [0] = &clk_mout_epll.clk, |
867 | [1] = &clk_div_mpll.clk, | 876 | [1] = &clk_div_mpll.clk, |
@@ -875,6 +884,18 @@ struct clksrc_sources clk_src_group5 = { | |||
875 | .nr_sources = ARRAY_SIZE(clk_src_group5_list), | 884 | .nr_sources = ARRAY_SIZE(clk_src_group5_list), |
876 | }; | 885 | }; |
877 | 886 | ||
887 | static struct clksrc_clk clk_sclk_audio2 = { | ||
888 | .clk = { | ||
889 | .name = "sclk_audio", | ||
890 | .id = 2, | ||
891 | .ctrlbit = (1 << 10), | ||
892 | .enable = s5pc100_sclk1_ctrl, | ||
893 | }, | ||
894 | .sources = &clk_src_group5, | ||
895 | .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 }, | ||
896 | .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 }, | ||
897 | }; | ||
898 | |||
878 | static struct clk *clk_src_group6_list[] = { | 899 | static struct clk *clk_src_group6_list[] = { |
879 | [0] = &s5p_clk_27m, | 900 | [0] = &s5p_clk_27m, |
880 | [1] = &clk_vclk54m, | 901 | [1] = &clk_vclk54m, |
@@ -944,6 +965,64 @@ struct clksrc_sources clk_src_pwi = { | |||
944 | .nr_sources = ARRAY_SIZE(clk_src_pwi_list), | 965 | .nr_sources = ARRAY_SIZE(clk_src_pwi_list), |
945 | }; | 966 | }; |
946 | 967 | ||
968 | static struct clk *clk_sclk_spdif_list[] = { | ||
969 | [0] = &clk_sclk_audio0.clk, | ||
970 | [1] = &clk_sclk_audio1.clk, | ||
971 | [2] = &clk_sclk_audio2.clk, | ||
972 | }; | ||
973 | |||
974 | struct clksrc_sources clk_src_sclk_spdif = { | ||
975 | .sources = clk_sclk_spdif_list, | ||
976 | .nr_sources = ARRAY_SIZE(clk_sclk_spdif_list), | ||
977 | }; | ||
978 | |||
979 | static int s5pc100_spdif_set_rate(struct clk *clk, unsigned long rate) | ||
980 | { | ||
981 | struct clk *pclk; | ||
982 | int ret; | ||
983 | |||
984 | pclk = clk_get_parent(clk); | ||
985 | if (IS_ERR(pclk)) | ||
986 | return -EINVAL; | ||
987 | |||
988 | ret = pclk->ops->set_rate(pclk, rate); | ||
989 | clk_put(pclk); | ||
990 | |||
991 | return ret; | ||
992 | } | ||
993 | |||
994 | static unsigned long s5pc100_spdif_get_rate(struct clk *clk) | ||
995 | { | ||
996 | struct clk *pclk; | ||
997 | int rate; | ||
998 | |||
999 | pclk = clk_get_parent(clk); | ||
1000 | if (IS_ERR(pclk)) | ||
1001 | return -EINVAL; | ||
1002 | |||
1003 | rate = pclk->ops->get_rate(clk); | ||
1004 | clk_put(pclk); | ||
1005 | |||
1006 | return rate; | ||
1007 | } | ||
1008 | |||
1009 | static struct clk_ops s5pc100_sclk_spdif_ops = { | ||
1010 | .set_rate = s5pc100_spdif_set_rate, | ||
1011 | .get_rate = s5pc100_spdif_get_rate, | ||
1012 | }; | ||
1013 | |||
1014 | static struct clksrc_clk clk_sclk_spdif = { | ||
1015 | .clk = { | ||
1016 | .name = "sclk_spdif", | ||
1017 | .id = -1, | ||
1018 | .ctrlbit = (1 << 11), | ||
1019 | .enable = s5pc100_sclk1_ctrl, | ||
1020 | .ops = &s5pc100_sclk_spdif_ops, | ||
1021 | }, | ||
1022 | .sources = &clk_src_sclk_spdif, | ||
1023 | .reg_src = { .reg = S5P_CLK_SRC3, .shift = 24, .size = 2 }, | ||
1024 | }; | ||
1025 | |||
947 | static struct clksrc_clk clksrcs[] = { | 1026 | static struct clksrc_clk clksrcs[] = { |
948 | { | 1027 | { |
949 | .clk = { | 1028 | .clk = { |
@@ -1001,39 +1080,6 @@ static struct clksrc_clk clksrcs[] = { | |||
1001 | .reg_src = { .reg = S5P_CLK_SRC2, .shift = 28, .size = 2 }, | 1080 | .reg_src = { .reg = S5P_CLK_SRC2, .shift = 28, .size = 2 }, |
1002 | }, { | 1081 | }, { |
1003 | .clk = { | 1082 | .clk = { |
1004 | .name = "sclk_audio", | ||
1005 | .id = 0, | ||
1006 | .ctrlbit = (1 << 8), | ||
1007 | .enable = s5pc100_sclk1_ctrl, | ||
1008 | |||
1009 | }, | ||
1010 | .sources = &clk_src_group3, | ||
1011 | .reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 3 }, | ||
1012 | .reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 }, | ||
1013 | }, { | ||
1014 | .clk = { | ||
1015 | .name = "sclk_audio", | ||
1016 | .id = 1, | ||
1017 | .ctrlbit = (1 << 9), | ||
1018 | .enable = s5pc100_sclk1_ctrl, | ||
1019 | |||
1020 | }, | ||
1021 | .sources = &clk_src_group4, | ||
1022 | .reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 3 }, | ||
1023 | .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 }, | ||
1024 | }, { | ||
1025 | .clk = { | ||
1026 | .name = "sclk_audio", | ||
1027 | .id = 2, | ||
1028 | .ctrlbit = (1 << 10), | ||
1029 | .enable = s5pc100_sclk1_ctrl, | ||
1030 | |||
1031 | }, | ||
1032 | .sources = &clk_src_group5, | ||
1033 | .reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 3 }, | ||
1034 | .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 }, | ||
1035 | }, { | ||
1036 | .clk = { | ||
1037 | .name = "sclk_lcd", | 1083 | .name = "sclk_lcd", |
1038 | .id = -1, | 1084 | .id = -1, |
1039 | .ctrlbit = (1 << 0), | 1085 | .ctrlbit = (1 << 0), |
@@ -1179,6 +1225,10 @@ static struct clksrc_clk *sysclks[] = { | |||
1179 | &clk_div_pclkd1, | 1225 | &clk_div_pclkd1, |
1180 | &clk_div_cam, | 1226 | &clk_div_cam, |
1181 | &clk_div_hdmi, | 1227 | &clk_div_hdmi, |
1228 | &clk_sclk_audio0, | ||
1229 | &clk_sclk_audio1, | ||
1230 | &clk_sclk_audio2, | ||
1231 | &clk_sclk_spdif, | ||
1182 | }; | 1232 | }; |
1183 | 1233 | ||
1184 | void __init_or_cpufreq s5pc100_setup_clocks(void) | 1234 | void __init_or_cpufreq s5pc100_setup_clocks(void) |
@@ -1196,7 +1246,7 @@ void __init_or_cpufreq s5pc100_setup_clocks(void) | |||
1196 | unsigned int ptr; | 1246 | unsigned int ptr; |
1197 | 1247 | ||
1198 | /* Set S5PC100 functions for clk_fout_epll */ | 1248 | /* Set S5PC100 functions for clk_fout_epll */ |
1199 | clk_fout_epll.enable = s5pc100_epll_enable; | 1249 | clk_fout_epll.enable = s5p_epll_enable; |
1200 | clk_fout_epll.ops = &s5pc100_epll_ops; | 1250 | clk_fout_epll.ops = &s5pc100_epll_ops; |
1201 | 1251 | ||
1202 | printk(KERN_DEBUG "%s: registering clocks\n", __func__); | 1252 | printk(KERN_DEBUG "%s: registering clocks\n", __func__); |