aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/exynos5250-cpufreq.c
diff options
context:
space:
mode:
authorSachin Kamat <sachin.kamat@linaro.org>2013-12-24 05:05:24 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-01-05 19:26:00 -0500
commit26ab1c62b6e1ed4720d533320d646866027ade09 (patch)
tree4b6a83c6c097ad2c5b2ad856f366eb1fb6629bfa /drivers/cpufreq/exynos5250-cpufreq.c
parent6f1e4efd882eccca10bac45b77e14bcb4979dc54 (diff)
cpufreq: exynos5250: Set APLL rate using CCF API
Use common clock framework (CCF) APIs to set the clock rates instead of direct register manipulation. This now updates the sysfs entry (cpuinfo_cur_freq) correctly which did not reflect the correct value until now. While at it clean up the PLL s-div parameter setting as it is handled by the PLL driver. Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org> Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Lukasz Majewski <l.majewski@samsung.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq/exynos5250-cpufreq.c')
-rw-r--r--drivers/cpufreq/exynos5250-cpufreq.c74
1 files changed, 10 insertions, 64 deletions
diff --git a/drivers/cpufreq/exynos5250-cpufreq.c b/drivers/cpufreq/exynos5250-cpufreq.c
index 8feda86fe42c..86fb1a105601 100644
--- a/drivers/cpufreq/exynos5250-cpufreq.c
+++ b/drivers/cpufreq/exynos5250-cpufreq.c
@@ -102,12 +102,12 @@ static void set_clkdiv(unsigned int div_index)
102 cpu_relax(); 102 cpu_relax();
103} 103}
104 104
105static void set_apll(unsigned int new_index, 105static void set_apll(unsigned int index)
106 unsigned int old_index)
107{ 106{
108 unsigned int tmp, pdiv; 107 unsigned int tmp;
108 unsigned int freq = apll_freq_5250[index].freq;
109 109
110 /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ 110 /* MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */
111 clk_set_parent(moutcore, mout_mpll); 111 clk_set_parent(moutcore, mout_mpll);
112 112
113 do { 113 do {
@@ -116,24 +116,9 @@ static void set_apll(unsigned int new_index,
116 tmp &= 0x7; 116 tmp &= 0x7;
117 } while (tmp != 0x2); 117 } while (tmp != 0x2);
118 118
119 /* 2. Set APLL Lock time */ 119 clk_set_rate(mout_apll, freq * 1000);
120 pdiv = ((apll_freq_5250[new_index].mps >> 8) & 0x3f);
121
122 __raw_writel((pdiv * 250), EXYNOS5_APLL_LOCK);
123 120
124 /* 3. Change PLL PMS values */ 121 /* MUX_CORE_SEL = APLL */
125 tmp = __raw_readl(EXYNOS5_APLL_CON0);
126 tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0));
127 tmp |= apll_freq_5250[new_index].mps;
128 __raw_writel(tmp, EXYNOS5_APLL_CON0);
129
130 /* 4. wait_lock_time */
131 do {
132 cpu_relax();
133 tmp = __raw_readl(EXYNOS5_APLL_CON0);
134 } while (!(tmp & (0x1 << 29)));
135
136 /* 5. MUX_CORE_SEL = APLL */
137 clk_set_parent(moutcore, mout_apll); 122 clk_set_parent(moutcore, mout_apll);
138 123
139 do { 124 do {
@@ -141,55 +126,17 @@ static void set_apll(unsigned int new_index,
141 tmp = __raw_readl(EXYNOS5_CLKMUX_STATCPU); 126 tmp = __raw_readl(EXYNOS5_CLKMUX_STATCPU);
142 tmp &= (0x7 << 16); 127 tmp &= (0x7 << 16);
143 } while (tmp != (0x1 << 16)); 128 } while (tmp != (0x1 << 16));
144
145}
146
147static bool exynos5250_pms_change(unsigned int old_index, unsigned int new_index)
148{
149 unsigned int old_pm = apll_freq_5250[old_index].mps >> 8;
150 unsigned int new_pm = apll_freq_5250[new_index].mps >> 8;
151
152 return (old_pm == new_pm) ? 0 : 1;
153} 129}
154 130
155static void exynos5250_set_frequency(unsigned int old_index, 131static void exynos5250_set_frequency(unsigned int old_index,
156 unsigned int new_index) 132 unsigned int new_index)
157{ 133{
158 unsigned int tmp;
159
160 if (old_index > new_index) { 134 if (old_index > new_index) {
161 if (!exynos5250_pms_change(old_index, new_index)) { 135 set_clkdiv(new_index);
162 /* 1. Change the system clock divider values */ 136 set_apll(new_index);
163 set_clkdiv(new_index);
164 /* 2. Change just s value in apll m,p,s value */
165 tmp = __raw_readl(EXYNOS5_APLL_CON0);
166 tmp &= ~(0x7 << 0);
167 tmp |= apll_freq_5250[new_index].mps & 0x7;
168 __raw_writel(tmp, EXYNOS5_APLL_CON0);
169
170 } else {
171 /* Clock Configuration Procedure */
172 /* 1. Change the system clock divider values */
173 set_clkdiv(new_index);
174 /* 2. Change the apll m,p,s value */
175 set_apll(new_index, old_index);
176 }
177 } else if (old_index < new_index) { 137 } else if (old_index < new_index) {
178 if (!exynos5250_pms_change(old_index, new_index)) { 138 set_apll(new_index);
179 /* 1. Change just s value in apll m,p,s value */ 139 set_clkdiv(new_index);
180 tmp = __raw_readl(EXYNOS5_APLL_CON0);
181 tmp &= ~(0x7 << 0);
182 tmp |= apll_freq_5250[new_index].mps & 0x7;
183 __raw_writel(tmp, EXYNOS5_APLL_CON0);
184 /* 2. Change the system clock divider values */
185 set_clkdiv(new_index);
186 } else {
187 /* Clock Configuration Procedure */
188 /* 1. Change the apll m,p,s value */
189 set_apll(new_index, old_index);
190 /* 2. Change the system clock divider values */
191 set_clkdiv(new_index);
192 }
193 } 140 }
194} 141}
195 142
@@ -222,7 +169,6 @@ int exynos5250_cpufreq_init(struct exynos_dvfs_info *info)
222 info->volt_table = exynos5250_volt_table; 169 info->volt_table = exynos5250_volt_table;
223 info->freq_table = exynos5250_freq_table; 170 info->freq_table = exynos5250_freq_table;
224 info->set_freq = exynos5250_set_frequency; 171 info->set_freq = exynos5250_set_frequency;
225 info->need_apll_change = exynos5250_pms_change;
226 172
227 return 0; 173 return 0;
228 174