diff options
Diffstat (limited to 'arch/arm/mach-s5pv210')
-rw-r--r-- | arch/arm/mach-s5pv210/clock.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 00a721771a43..156aa8af9072 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c | |||
@@ -1046,6 +1046,79 @@ static struct clksrc_clk *sysclks[] = { | |||
1046 | &clk_sclk_spdif, | 1046 | &clk_sclk_spdif, |
1047 | }; | 1047 | }; |
1048 | 1048 | ||
1049 | static u32 epll_div[][6] = { | ||
1050 | { 48000000, 0, 48, 3, 3, 0 }, | ||
1051 | { 96000000, 0, 48, 3, 2, 0 }, | ||
1052 | { 144000000, 1, 72, 3, 2, 0 }, | ||
1053 | { 192000000, 0, 48, 3, 1, 0 }, | ||
1054 | { 288000000, 1, 72, 3, 1, 0 }, | ||
1055 | { 32750000, 1, 65, 3, 4, 35127 }, | ||
1056 | { 32768000, 1, 65, 3, 4, 35127 }, | ||
1057 | { 45158400, 0, 45, 3, 3, 10355 }, | ||
1058 | { 45000000, 0, 45, 3, 3, 10355 }, | ||
1059 | { 45158000, 0, 45, 3, 3, 10355 }, | ||
1060 | { 49125000, 0, 49, 3, 3, 9961 }, | ||
1061 | { 49152000, 0, 49, 3, 3, 9961 }, | ||
1062 | { 67737600, 1, 67, 3, 3, 48366 }, | ||
1063 | { 67738000, 1, 67, 3, 3, 48366 }, | ||
1064 | { 73800000, 1, 73, 3, 3, 47710 }, | ||
1065 | { 73728000, 1, 73, 3, 3, 47710 }, | ||
1066 | { 36000000, 1, 32, 3, 4, 0 }, | ||
1067 | { 60000000, 1, 60, 3, 3, 0 }, | ||
1068 | { 72000000, 1, 72, 3, 3, 0 }, | ||
1069 | { 80000000, 1, 80, 3, 3, 0 }, | ||
1070 | { 84000000, 0, 42, 3, 2, 0 }, | ||
1071 | { 50000000, 0, 50, 3, 3, 0 }, | ||
1072 | }; | ||
1073 | |||
1074 | static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate) | ||
1075 | { | ||
1076 | unsigned int epll_con, epll_con_k; | ||
1077 | unsigned int i; | ||
1078 | |||
1079 | /* Return if nothing changed */ | ||
1080 | if (clk->rate == rate) | ||
1081 | return 0; | ||
1082 | |||
1083 | epll_con = __raw_readl(S5P_EPLL_CON); | ||
1084 | epll_con_k = __raw_readl(S5P_EPLL_CON1); | ||
1085 | |||
1086 | epll_con_k &= ~PLL46XX_KDIV_MASK; | ||
1087 | epll_con &= ~(1 << 27 | | ||
1088 | PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | | ||
1089 | PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | | ||
1090 | PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT); | ||
1091 | |||
1092 | for (i = 0; i < ARRAY_SIZE(epll_div); i++) { | ||
1093 | if (epll_div[i][0] == rate) { | ||
1094 | epll_con_k |= epll_div[i][5] << 0; | ||
1095 | epll_con |= (epll_div[i][1] << 27 | | ||
1096 | epll_div[i][2] << PLL46XX_MDIV_SHIFT | | ||
1097 | epll_div[i][3] << PLL46XX_PDIV_SHIFT | | ||
1098 | epll_div[i][4] << PLL46XX_SDIV_SHIFT); | ||
1099 | break; | ||
1100 | } | ||
1101 | } | ||
1102 | |||
1103 | if (i == ARRAY_SIZE(epll_div)) { | ||
1104 | printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", | ||
1105 | __func__); | ||
1106 | return -EINVAL; | ||
1107 | } | ||
1108 | |||
1109 | __raw_writel(epll_con, S5P_EPLL_CON); | ||
1110 | __raw_writel(epll_con_k, S5P_EPLL_CON1); | ||
1111 | |||
1112 | clk->rate = rate; | ||
1113 | |||
1114 | return 0; | ||
1115 | } | ||
1116 | |||
1117 | static struct clk_ops s5pv210_epll_ops = { | ||
1118 | .set_rate = s5pv210_epll_set_rate, | ||
1119 | .get_rate = s5p_epll_get_rate, | ||
1120 | }; | ||
1121 | |||
1049 | void __init_or_cpufreq s5pv210_setup_clocks(void) | 1122 | void __init_or_cpufreq s5pv210_setup_clocks(void) |
1050 | { | 1123 | { |
1051 | struct clk *xtal_clk; | 1124 | struct clk *xtal_clk; |
@@ -1064,6 +1137,10 @@ void __init_or_cpufreq s5pv210_setup_clocks(void) | |||
1064 | unsigned int ptr; | 1137 | unsigned int ptr; |
1065 | u32 clkdiv0, clkdiv1; | 1138 | u32 clkdiv0, clkdiv1; |
1066 | 1139 | ||
1140 | /* Set functions for clk_fout_epll */ | ||
1141 | clk_fout_epll.enable = s5p_epll_enable; | ||
1142 | clk_fout_epll.ops = &s5pv210_epll_ops; | ||
1143 | |||
1067 | printk(KERN_DEBUG "%s: registering clocks\n", __func__); | 1144 | printk(KERN_DEBUG "%s: registering clocks\n", __func__); |
1068 | 1145 | ||
1069 | clkdiv0 = __raw_readl(S5P_CLK_DIV0); | 1146 | clkdiv0 = __raw_readl(S5P_CLK_DIV0); |