aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/exynos4x12-cpufreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq/exynos4x12-cpufreq.c')
-rw-r--r--drivers/cpufreq/exynos4x12-cpufreq.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/drivers/cpufreq/exynos4x12-cpufreq.c b/drivers/cpufreq/exynos4x12-cpufreq.c
index 63a3907ce578..351a2074cfea 100644
--- a/drivers/cpufreq/exynos4x12-cpufreq.c
+++ b/drivers/cpufreq/exynos4x12-cpufreq.c
@@ -16,6 +16,8 @@
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/cpufreq.h> 18#include <linux/cpufreq.h>
19#include <linux/of.h>
20#include <linux/of_address.h>
19 21
20#include "exynos-cpufreq.h" 22#include "exynos-cpufreq.h"
21 23
@@ -23,6 +25,7 @@ static struct clk *cpu_clk;
23static struct clk *moutcore; 25static struct clk *moutcore;
24static struct clk *mout_mpll; 26static struct clk *mout_mpll;
25static struct clk *mout_apll; 27static struct clk *mout_apll;
28static struct exynos_dvfs_info *cpufreq;
26 29
27static unsigned int exynos4x12_volt_table[] = { 30static unsigned int exynos4x12_volt_table[] = {
28 1350000, 1287500, 1250000, 1187500, 1137500, 1087500, 1037500, 31 1350000, 1287500, 1250000, 1187500, 1137500, 1087500, 1037500,
@@ -105,19 +108,20 @@ static void exynos4x12_set_clkdiv(unsigned int div_index)
105 108
106 tmp = apll_freq_4x12[div_index].clk_div_cpu0; 109 tmp = apll_freq_4x12[div_index].clk_div_cpu0;
107 110
108 __raw_writel(tmp, EXYNOS4_CLKDIV_CPU); 111 __raw_writel(tmp, cpufreq->cmu_regs + EXYNOS4_CLKDIV_CPU);
109 112
110 while (__raw_readl(EXYNOS4_CLKDIV_STATCPU) & 0x11111111) 113 while (__raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKDIV_STATCPU)
114 & 0x11111111)
111 cpu_relax(); 115 cpu_relax();
112 116
113 /* Change Divider - CPU1 */ 117 /* Change Divider - CPU1 */
114 tmp = apll_freq_4x12[div_index].clk_div_cpu1; 118 tmp = apll_freq_4x12[div_index].clk_div_cpu1;
115 119
116 __raw_writel(tmp, EXYNOS4_CLKDIV_CPU1); 120 __raw_writel(tmp, cpufreq->cmu_regs + EXYNOS4_CLKDIV_CPU1);
117 121
118 do { 122 do {
119 cpu_relax(); 123 cpu_relax();
120 tmp = __raw_readl(EXYNOS4_CLKDIV_STATCPU1); 124 tmp = __raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKDIV_STATCPU1);
121 } while (tmp != 0x0); 125 } while (tmp != 0x0);
122} 126}
123 127
@@ -130,7 +134,7 @@ static void exynos4x12_set_apll(unsigned int index)
130 134
131 do { 135 do {
132 cpu_relax(); 136 cpu_relax();
133 tmp = (__raw_readl(EXYNOS4_CLKMUX_STATCPU) 137 tmp = (__raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKMUX_STATCPU)
134 >> EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT); 138 >> EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT);
135 tmp &= 0x7; 139 tmp &= 0x7;
136 } while (tmp != 0x2); 140 } while (tmp != 0x2);
@@ -142,7 +146,7 @@ static void exynos4x12_set_apll(unsigned int index)
142 146
143 do { 147 do {
144 cpu_relax(); 148 cpu_relax();
145 tmp = __raw_readl(EXYNOS4_CLKMUX_STATCPU); 149 tmp = __raw_readl(cpufreq->cmu_regs + EXYNOS4_CLKMUX_STATCPU);
146 tmp &= EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK; 150 tmp &= EXYNOS4_CLKMUX_STATCPU_MUXCORE_MASK;
147 } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT)); 151 } while (tmp != (0x1 << EXYNOS4_CLKSRC_CPU_MUXCORE_SHIFT));
148} 152}
@@ -161,8 +165,30 @@ static void exynos4x12_set_frequency(unsigned int old_index,
161 165
162int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info) 166int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
163{ 167{
168 struct device_node *np;
164 unsigned long rate; 169 unsigned long rate;
165 170
171 /*
172 * HACK: This is a temporary workaround to get access to clock
173 * controller registers directly and remove static mappings and
174 * dependencies on platform headers. It is necessary to enable
175 * Exynos multi-platform support and will be removed together with
176 * this whole driver as soon as Exynos gets migrated to use
177 * cpufreq-cpu0 driver.
178 */
179 np = of_find_compatible_node(NULL, NULL, "samsung,exynos4412-clock");
180 if (!np) {
181 pr_err("%s: failed to find clock controller DT node\n",
182 __func__);
183 return -ENODEV;
184 }
185
186 info->cmu_regs = of_iomap(np, 0);
187 if (!info->cmu_regs) {
188 pr_err("%s: failed to map CMU registers\n", __func__);
189 return -EFAULT;
190 }
191
166 cpu_clk = clk_get(NULL, "armclk"); 192 cpu_clk = clk_get(NULL, "armclk");
167 if (IS_ERR(cpu_clk)) 193 if (IS_ERR(cpu_clk))
168 return PTR_ERR(cpu_clk); 194 return PTR_ERR(cpu_clk);
@@ -194,6 +220,8 @@ int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
194 info->freq_table = exynos4x12_freq_table; 220 info->freq_table = exynos4x12_freq_table;
195 info->set_freq = exynos4x12_set_frequency; 221 info->set_freq = exynos4x12_set_frequency;
196 222
223 cpufreq = info;
224
197 return 0; 225 return 0;
198 226
199err_mout_apll: 227err_mout_apll: