diff options
Diffstat (limited to 'drivers/cpufreq/exynos5250-cpufreq.c')
-rw-r--r-- | drivers/cpufreq/exynos5250-cpufreq.c | 74 |
1 files changed, 10 insertions, 64 deletions
diff --git a/drivers/cpufreq/exynos5250-cpufreq.c b/drivers/cpufreq/exynos5250-cpufreq.c index 5ee2ce1ad424..5f90b82a4082 100644 --- a/drivers/cpufreq/exynos5250-cpufreq.c +++ b/drivers/cpufreq/exynos5250-cpufreq.c | |||
@@ -101,12 +101,12 @@ static void set_clkdiv(unsigned int div_index) | |||
101 | cpu_relax(); | 101 | cpu_relax(); |
102 | } | 102 | } |
103 | 103 | ||
104 | static void set_apll(unsigned int new_index, | 104 | static void set_apll(unsigned int index) |
105 | unsigned int old_index) | ||
106 | { | 105 | { |
107 | unsigned int tmp, pdiv; | 106 | unsigned int tmp; |
107 | unsigned int freq = apll_freq_5250[index].freq; | ||
108 | 108 | ||
109 | /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ | 109 | /* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ |
110 | clk_set_parent(moutcore, mout_mpll); | 110 | clk_set_parent(moutcore, mout_mpll); |
111 | 111 | ||
112 | do { | 112 | do { |
@@ -115,24 +115,9 @@ static void set_apll(unsigned int new_index, | |||
115 | tmp &= 0x7; | 115 | tmp &= 0x7; |
116 | } while (tmp != 0x2); | 116 | } while (tmp != 0x2); |
117 | 117 | ||
118 | /* 2. Set APLL Lock time */ | 118 | clk_set_rate(mout_apll, freq * 1000); |
119 | pdiv = ((apll_freq_5250[new_index].mps >> 8) & 0x3f); | ||
120 | |||
121 | __raw_writel((pdiv * 250), EXYNOS5_APLL_LOCK); | ||
122 | 119 | ||
123 | /* 3. Change PLL PMS values */ | 120 | /* MUX_CORE_SEL = APLL */ |
124 | tmp = __raw_readl(EXYNOS5_APLL_CON0); | ||
125 | tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0)); | ||
126 | tmp |= apll_freq_5250[new_index].mps; | ||
127 | __raw_writel(tmp, EXYNOS5_APLL_CON0); | ||
128 | |||
129 | /* 4. wait_lock_time */ | ||
130 | do { | ||
131 | cpu_relax(); | ||
132 | tmp = __raw_readl(EXYNOS5_APLL_CON0); | ||
133 | } while (!(tmp & (0x1 << 29))); | ||
134 | |||
135 | /* 5. MUX_CORE_SEL = APLL */ | ||
136 | clk_set_parent(moutcore, mout_apll); | 121 | clk_set_parent(moutcore, mout_apll); |
137 | 122 | ||
138 | do { | 123 | do { |
@@ -140,55 +125,17 @@ static void set_apll(unsigned int new_index, | |||
140 | tmp = __raw_readl(EXYNOS5_CLKMUX_STATCPU); | 125 | tmp = __raw_readl(EXYNOS5_CLKMUX_STATCPU); |
141 | tmp &= (0x7 << 16); | 126 | tmp &= (0x7 << 16); |
142 | } while (tmp != (0x1 << 16)); | 127 | } while (tmp != (0x1 << 16)); |
143 | |||
144 | } | ||
145 | |||
146 | static bool exynos5250_pms_change(unsigned int old_index, unsigned int new_index) | ||
147 | { | ||
148 | unsigned int old_pm = apll_freq_5250[old_index].mps >> 8; | ||
149 | unsigned int new_pm = apll_freq_5250[new_index].mps >> 8; | ||
150 | |||
151 | return (old_pm == new_pm) ? 0 : 1; | ||
152 | } | 128 | } |
153 | 129 | ||
154 | static void exynos5250_set_frequency(unsigned int old_index, | 130 | static void exynos5250_set_frequency(unsigned int old_index, |
155 | unsigned int new_index) | 131 | unsigned int new_index) |
156 | { | 132 | { |
157 | unsigned int tmp; | ||
158 | |||
159 | if (old_index > new_index) { | 133 | if (old_index > new_index) { |
160 | if (!exynos5250_pms_change(old_index, new_index)) { | 134 | set_clkdiv(new_index); |
161 | /* 1. Change the system clock divider values */ | 135 | set_apll(new_index); |
162 | set_clkdiv(new_index); | ||
163 | /* 2. Change just s value in apll m,p,s value */ | ||
164 | tmp = __raw_readl(EXYNOS5_APLL_CON0); | ||
165 | tmp &= ~(0x7 << 0); | ||
166 | tmp |= apll_freq_5250[new_index].mps & 0x7; | ||
167 | __raw_writel(tmp, EXYNOS5_APLL_CON0); | ||
168 | |||
169 | } else { | ||
170 | /* Clock Configuration Procedure */ | ||
171 | /* 1. Change the system clock divider values */ | ||
172 | set_clkdiv(new_index); | ||
173 | /* 2. Change the apll m,p,s value */ | ||
174 | set_apll(new_index, old_index); | ||
175 | } | ||
176 | } else if (old_index < new_index) { | 136 | } else if (old_index < new_index) { |
177 | if (!exynos5250_pms_change(old_index, new_index)) { | 137 | set_apll(new_index); |
178 | /* 1. Change just s value in apll m,p,s value */ | 138 | set_clkdiv(new_index); |
179 | tmp = __raw_readl(EXYNOS5_APLL_CON0); | ||
180 | tmp &= ~(0x7 << 0); | ||
181 | tmp |= apll_freq_5250[new_index].mps & 0x7; | ||
182 | __raw_writel(tmp, EXYNOS5_APLL_CON0); | ||
183 | /* 2. Change the system clock divider values */ | ||
184 | set_clkdiv(new_index); | ||
185 | } else { | ||
186 | /* Clock Configuration Procedure */ | ||
187 | /* 1. Change the apll m,p,s value */ | ||
188 | set_apll(new_index, old_index); | ||
189 | /* 2. Change the system clock divider values */ | ||
190 | set_clkdiv(new_index); | ||
191 | } | ||
192 | } | 139 | } |
193 | } | 140 | } |
194 | 141 | ||
@@ -221,7 +168,6 @@ int exynos5250_cpufreq_init(struct exynos_dvfs_info *info) | |||
221 | info->volt_table = exynos5250_volt_table; | 168 | info->volt_table = exynos5250_volt_table; |
222 | info->freq_table = exynos5250_freq_table; | 169 | info->freq_table = exynos5250_freq_table; |
223 | info->set_freq = exynos5250_set_frequency; | 170 | info->set_freq = exynos5250_set_frequency; |
224 | info->need_apll_change = exynos5250_pms_change; | ||
225 | 171 | ||
226 | return 0; | 172 | return 0; |
227 | 173 | ||