diff options
Diffstat (limited to 'drivers/cpufreq/exynos4x12-cpufreq.c')
-rw-r--r-- | drivers/cpufreq/exynos4x12-cpufreq.c | 69 |
1 files changed, 8 insertions, 61 deletions
diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c index 08b7477b0aa2..8683304ce62c 100644 --- a/drivers/cpufreq/exynos4x12-cpufreq.c +++ b/drivers/cpufreq/exynos4x12-cpufreq.c | |||
@@ -128,9 +128,9 @@ static void exynos4x12_set_clkdiv(unsigned int div_index) | |||
128 | 128 | ||
129 | static void exynos4x12_set_apll(unsigned int index) | 129 | static void exynos4x12_set_apll(unsigned int index) |
130 | { | 130 | { |
131 | unsigned int tmp, pdiv; | 131 | unsigned int tmp, freq = apll_freq_4x12[index].freq; |
132 | 132 | ||
133 | /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ | 133 | /* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ |
134 | clk_set_parent(moutcore, mout_mpll); | 134 | clk_set_parent(moutcore, mout_mpll); |
135 | 135 | ||
136 | do { | 136 | do { |
@@ -140,24 +140,9 @@ static void exynos4x12_set_apll(unsigned int index) | |||
140 | tmp &= 0x7; | 140 | tmp &= 0x7; |
141 | } while (tmp != 0x2); | 141 | } while (tmp != 0x2); |
142 | 142 | ||
143 | /* 2. Set APLL Lock time */ | 143 | clk_set_rate(mout_apll, freq * 1000); |
144 | pdiv = ((apll_freq_4x12[index].mps >> 8) & 0x3f); | ||
145 | 144 | ||
146 | __raw_writel((pdiv * 250), EXYNOS4_APLL_LOCK); | 145 | /* MUX_CORE_SEL = APLL */ |
147 | |||
148 | /* 3. Change PLL PMS values */ | ||
149 | tmp = __raw_readl(EXYNOS4_APLL_CON0); | ||
150 | tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0)); | ||
151 | tmp |= apll_freq_4x12[index].mps; | ||
152 | __raw_writel(tmp, EXYNOS4_APLL_CON0); | ||
153 | |||
154 | /* 4. wait_lock_time */ | ||
155 | do { | ||
156 | cpu_relax(); | ||
157 | tmp = __raw_readl(EXYNOS4_APLL_CON0); | ||
158 | } while (!(tmp & (0x1 << EXYNOS4_APLLCON0_LOCKED_SHIFT))); | ||
159 | |||
160 | /* 5. MUX_CORE_SEL = APLL */ | ||
161 | clk_set_parent(moutcore, mout_apll); | 146 | clk_set_parent(moutcore, mout_apll); |
162 | 147 | ||
163 | do { | 148 | do { |
@@ -167,52 +152,15 @@ static void exynos4x12_set_apll(unsigned int index) | |||
167 | } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT)); | 152 | } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT)); |
168 | } | 153 | } |
169 | 154 | ||
170 | static bool exynos4x12_pms_change(unsigned int old_index, unsigned int new_index) | ||
171 | { | ||
172 | unsigned int old_pm = apll_freq_4x12[old_index].mps >> 8; | ||
173 | unsigned int new_pm = apll_freq_4x12[new_index].mps >> 8; | ||
174 | |||
175 | return (old_pm == new_pm) ? 0 : 1; | ||
176 | } | ||
177 | |||
178 | static void exynos4x12_set_frequency(unsigned int old_index, | 155 | static void exynos4x12_set_frequency(unsigned int old_index, |
179 | unsigned int new_index) | 156 | unsigned int new_index) |
180 | { | 157 | { |
181 | unsigned int tmp; | ||
182 | |||
183 | if (old_index > new_index) { | 158 | if (old_index > new_index) { |
184 | if (!exynos4x12_pms_change(old_index, new_index)) { | 159 | exynos4x12_set_clkdiv(new_index); |
185 | /* 1. Change the system clock divider values */ | 160 | exynos4x12_set_apll(new_index); |
186 | exynos4x12_set_clkdiv(new_index); | ||
187 | /* 2. Change just s value in apll m,p,s value */ | ||
188 | tmp = __raw_readl(EXYNOS4_APLL_CON0); | ||
189 | tmp &= ~(0x7 << 0); | ||
190 | tmp |= apll_freq_4x12[new_index].mps & 0x7; | ||
191 | __raw_writel(tmp, EXYNOS4_APLL_CON0); | ||
192 | |||
193 | } else { | ||
194 | /* Clock Configuration Procedure */ | ||
195 | /* 1. Change the system clock divider values */ | ||
196 | exynos4x12_set_clkdiv(new_index); | ||
197 | /* 2. Change the apll m,p,s value */ | ||
198 | exynos4x12_set_apll(new_index); | ||
199 | } | ||
200 | } else if (old_index < new_index) { | 161 | } else if (old_index < new_index) { |
201 | if (!exynos4x12_pms_change(old_index, new_index)) { | 162 | exynos4x12_set_apll(new_index); |
202 | /* 1. Change just s value in apll m,p,s value */ | 163 | exynos4x12_set_clkdiv(new_index); |
203 | tmp = __raw_readl(EXYNOS4_APLL_CON0); | ||
204 | tmp &= ~(0x7 << 0); | ||
205 | tmp |= apll_freq_4x12[new_index].mps & 0x7; | ||
206 | __raw_writel(tmp, EXYNOS4_APLL_CON0); | ||
207 | /* 2. Change the system clock divider values */ | ||
208 | exynos4x12_set_clkdiv(new_index); | ||
209 | } else { | ||
210 | /* Clock Configuration Procedure */ | ||
211 | /* 1. Change the apll m,p,s value */ | ||
212 | exynos4x12_set_apll(new_index); | ||
213 | /* 2. Change the system clock divider values */ | ||
214 | exynos4x12_set_clkdiv(new_index); | ||
215 | } | ||
216 | } | 164 | } |
217 | } | 165 | } |
218 | 166 | ||
@@ -250,7 +198,6 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info) | |||
250 | info->volt_table = exynos4x12_volt_table; | 198 | info->volt_table = exynos4x12_volt_table; |
251 | info->freq_table = exynos4x12_freq_table; | 199 | info->freq_table = exynos4x12_freq_table; |
252 | info->set_freq = exynos4x12_set_frequency; | 200 | info->set_freq = exynos4x12_set_frequency; |
253 | info->need_apll_change = exynos4x12_pms_change; | ||
254 | 201 | ||
255 | return 0; | 202 | return 0; |
256 | 203 | ||