diff options
Diffstat (limited to 'drivers/cpufreq/exynos5250-cpufreq.c')
-rw-r--r-- | drivers/cpufreq/exynos5250-cpufreq.c | 43 |
1 files changed, 35 insertions, 8 deletions
diff --git a/drivers/cpufreq/exynos5250-cpufreq.c b/drivers/cpufreq/exynos5250-cpufreq.c index 363a0b3fe1b1..c91ce69dc631 100644 --- a/drivers/cpufreq/exynos5250-cpufreq.c +++ b/drivers/cpufreq/exynos5250-cpufreq.c | |||
@@ -16,8 +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 | 19 | #include <linux/of.h> | |
20 | #include <mach/map.h> | 20 | #include <linux/of_address.h> |
21 | 21 | ||
22 | #include "exynos-cpufreq.h" | 22 | #include "exynos-cpufreq.h" |
23 | 23 | ||
@@ -25,6 +25,7 @@ static struct clk *cpu_clk; | |||
25 | static struct clk *moutcore; | 25 | static struct clk *moutcore; |
26 | static struct clk *mout_mpll; | 26 | static struct clk *mout_mpll; |
27 | static struct clk *mout_apll; | 27 | static struct clk *mout_apll; |
28 | static struct exynos_dvfs_info *cpufreq; | ||
28 | 29 | ||
29 | static unsigned int exynos5250_volt_table[] = { | 30 | static unsigned int exynos5250_volt_table[] = { |
30 | 1300000, 1250000, 1225000, 1200000, 1150000, | 31 | 1300000, 1250000, 1225000, 1200000, 1150000, |
@@ -87,17 +88,18 @@ static void set_clkdiv(unsigned int div_index) | |||
87 | 88 | ||
88 | tmp = apll_freq_5250[div_index].clk_div_cpu0; | 89 | tmp = apll_freq_5250[div_index].clk_div_cpu0; |
89 | 90 | ||
90 | __raw_writel(tmp, EXYNOS5_CLKDIV_CPU0); | 91 | __raw_writel(tmp, cpufreq->cmu_regs + EXYNOS5_CLKDIV_CPU0); |
91 | 92 | ||
92 | while (__raw_readl(EXYNOS5_CLKDIV_STATCPU0) & 0x11111111) | 93 | while (__raw_readl(cpufreq->cmu_regs + EXYNOS5_CLKDIV_STATCPU0) |
94 | & 0x11111111) | ||
93 | cpu_relax(); | 95 | cpu_relax(); |
94 | 96 | ||
95 | /* Change Divider - CPU1 */ | 97 | /* Change Divider - CPU1 */ |
96 | tmp = apll_freq_5250[div_index].clk_div_cpu1; | 98 | tmp = apll_freq_5250[div_index].clk_div_cpu1; |
97 | 99 | ||
98 | __raw_writel(tmp, EXYNOS5_CLKDIV_CPU1); | 100 | __raw_writel(tmp, cpufreq->cmu_regs + EXYNOS5_CLKDIV_CPU1); |
99 | 101 | ||
100 | while (__raw_readl(EXYNOS5_CLKDIV_STATCPU1) & 0x11) | 102 | while (__raw_readl(cpufreq->cmu_regs + EXYNOS5_CLKDIV_STATCPU1) & 0x11) |
101 | cpu_relax(); | 103 | cpu_relax(); |
102 | } | 104 | } |
103 | 105 | ||
@@ -111,7 +113,8 @@ static void set_apll(unsigned int index) | |||
111 | 113 | ||
112 | do { | 114 | do { |
113 | cpu_relax(); | 115 | cpu_relax(); |
114 | tmp = (__raw_readl(EXYNOS5_CLKMUX_STATCPU) >> 16); | 116 | tmp = (__raw_readl(cpufreq->cmu_regs + EXYNOS5_CLKMUX_STATCPU) |
117 | >> 16); | ||
115 | tmp &= 0x7; | 118 | tmp &= 0x7; |
116 | } while (tmp != 0x2); | 119 | } while (tmp != 0x2); |
117 | 120 | ||
@@ -122,7 +125,7 @@ static void set_apll(unsigned int index) | |||
122 | 125 | ||
123 | do { | 126 | do { |
124 | cpu_relax(); | 127 | cpu_relax(); |
125 | tmp = __raw_readl(EXYNOS5_CLKMUX_STATCPU); | 128 | tmp = __raw_readl(cpufreq->cmu_regs + EXYNOS5_CLKMUX_STATCPU); |
126 | tmp &= (0x7 << 16); | 129 | tmp &= (0x7 << 16); |
127 | } while (tmp != (0x1 << 16)); | 130 | } while (tmp != (0x1 << 16)); |
128 | } | 131 | } |
@@ -141,8 +144,30 @@ static void exynos5250_set_frequency(unsigned int old_index, | |||
141 | 144 | ||
142 | int exynos5250_cpufreq_init(struct exynos_dvfs_info *info) | 145 | int exynos5250_cpufreq_init(struct exynos_dvfs_info *info) |
143 | { | 146 | { |
147 | struct device_node *np; | ||
144 | unsigned long rate; | 148 | unsigned long rate; |
145 | 149 | ||
150 | /* | ||
151 | * HACK: This is a temporary workaround to get access to clock | ||
152 | * controller registers directly and remove static mappings and | ||
153 | * dependencies on platform headers. It is necessary to enable | ||
154 | * Exynos multi-platform support and will be removed together with | ||
155 | * this whole driver as soon as Exynos gets migrated to use | ||
156 | * cpufreq-cpu0 driver. | ||
157 | */ | ||
158 | np = of_find_compatible_node(NULL, NULL, "samsung,exynos5250-clock"); | ||
159 | if (!np) { | ||
160 | pr_err("%s: failed to find clock controller DT node\n", | ||
161 | __func__); | ||
162 | return -ENODEV; | ||
163 | } | ||
164 | |||
165 | info->cmu_regs = of_iomap(np, 0); | ||
166 | if (!info->cmu_regs) { | ||
167 | pr_err("%s: failed to map CMU registers\n", __func__); | ||
168 | return -EFAULT; | ||
169 | } | ||
170 | |||
146 | cpu_clk = clk_get(NULL, "armclk"); | 171 | cpu_clk = clk_get(NULL, "armclk"); |
147 | if (IS_ERR(cpu_clk)) | 172 | if (IS_ERR(cpu_clk)) |
148 | return PTR_ERR(cpu_clk); | 173 | return PTR_ERR(cpu_clk); |
@@ -169,6 +194,8 @@ int exynos5250_cpufreq_init(struct exynos_dvfs_info *info) | |||
169 | info->freq_table = exynos5250_freq_table; | 194 | info->freq_table = exynos5250_freq_table; |
170 | info->set_freq = exynos5250_set_frequency; | 195 | info->set_freq = exynos5250_set_frequency; |
171 | 196 | ||
197 | cpufreq = info; | ||
198 | |||
172 | return 0; | 199 | return 0; |
173 | 200 | ||
174 | err_mout_apll: | 201 | err_mout_apll: |