blob: 598b7c56600496386253d12904b3ea75a4ba4c02 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/*
2 *
3 * Copyright (C) 2007 Google, Inc.
Trilok Sonief18f6c2012-03-07 12:33:40 +05304 * Copyright (c) 2007-2012, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/version.h>
18#include <linux/kernel.h>
19#include <linux/init.h>
20#include <linux/errno.h>
21#include <linux/string.h>
22#include <linux/delay.h>
23#include <linux/clk.h>
24#include <linux/cpufreq.h>
25#include <linux/mutex.h>
26#include <linux/io.h>
27#include <linux/sort.h>
28#include <mach/board.h>
29#include <mach/msm_iomap.h>
30#include <asm/mach-types.h>
31
32#include "smd_private.h"
33#include "clock.h"
34#include "acpuclock.h"
35#include "spm.h"
36
Taniya Das298de8c2012-02-16 11:45:31 +053037#define SCSS_CLK_CTL_ADDR (MSM_ACC0_BASE + 0x04)
38#define SCSS_CLK_SEL_ADDR (MSM_ACC0_BASE + 0x08)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070039
40#define PLL2_L_VAL_ADDR (MSM_CLK_CTL_BASE + 0x33C)
41#define PLL2_M_VAL_ADDR (MSM_CLK_CTL_BASE + 0x340)
42#define PLL2_N_VAL_ADDR (MSM_CLK_CTL_BASE + 0x344)
43#define PLL2_CONFIG_ADDR (MSM_CLK_CTL_BASE + 0x34C)
44
45#define VREF_SEL 1 /* 0: 0.625V (50mV step), 1: 0.3125V (25mV step). */
46#define V_STEP (25 * (2 - VREF_SEL)) /* Minimum voltage step size. */
47#define VREG_DATA (VREG_CONFIG | (VREF_SEL << 5))
48#define VREG_CONFIG (BIT(7) | BIT(6)) /* Enable VREG, pull-down if disabled. */
49/* Cause a compile error if the voltage is not a multiple of the step size. */
50#define MV(mv) ((mv) / (!((mv) % V_STEP)))
51/* mv = (750mV + (raw * 25mV)) * (2 - VREF_SEL) */
52#define VDD_RAW(mv) (((MV(mv) / V_STEP) - 30) | VREG_DATA)
53
54#define MAX_AXI_KHZ 192000
55
56struct clock_state {
57 struct clkctl_acpu_speed *current_speed;
58 struct mutex lock;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070059 struct clk *ebi1_clk;
60};
61
62struct pll {
63 unsigned int l;
64 unsigned int m;
65 unsigned int n;
66 unsigned int pre_div;
67};
68
69struct clkctl_acpu_speed {
70 unsigned int use_for_scaling;
71 unsigned int acpu_clk_khz;
72 int src;
73 unsigned int acpu_src_sel;
74 unsigned int acpu_src_div;
75 unsigned int axi_clk_hz;
76 unsigned int vdd_mv;
77 unsigned int vdd_raw;
78 struct pll *pll_rate;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070079};
80
81static struct clock_state drv_state = { 0 };
82
83/* Switch to this when reprogramming PLL2 */
84static struct clkctl_acpu_speed *backup_s;
85
86static struct pll pll2_tbl[] = {
87 { 42, 0, 1, 0 }, /* 806 MHz */
88 { 53, 1, 3, 0 }, /* 1024 MHz */
89 { 125, 0, 1, 1 }, /* 1200 MHz */
90 { 73, 0, 1, 0 }, /* 1401 MHz */
91};
92
93/* Use negative numbers for sources that can't be enabled/disabled */
94
95enum acpuclk_source {
96 LPXO = -2,
97 AXI = -1,
98 PLL_0 = 0,
99 PLL_1,
100 PLL_2,
101 PLL_3,
102 MAX_SOURCE
103};
104
105static struct clk *acpuclk_sources[MAX_SOURCE];
106
107/*
108 * Each ACPU frequency has a certain minimum MSMC1 voltage requirement
109 * that is implicitly met by voting for a specific minimum AXI frequency.
110 * Do NOT change the AXI frequency unless you are _absoulutely_ sure you
111 * know all the h/w requirements.
112 */
113static struct clkctl_acpu_speed acpu_freq_tbl[] = {
114 { 0, 24576, LPXO, 0, 0, 30720000, 900, VDD_RAW(900) },
115 { 0, 61440, PLL_3, 5, 11, 61440000, 900, VDD_RAW(900) },
116 { 1, 122880, PLL_3, 5, 5, 61440000, 900, VDD_RAW(900) },
117 { 0, 184320, PLL_3, 5, 4, 61440000, 900, VDD_RAW(900) },
118 { 0, MAX_AXI_KHZ, AXI, 1, 0, 61440000, 900, VDD_RAW(900) },
119 { 1, 245760, PLL_3, 5, 2, 61440000, 900, VDD_RAW(900) },
120 { 1, 368640, PLL_3, 5, 1, 122800000, 900, VDD_RAW(900) },
121 /* AXI has MSMC1 implications. See above. */
122 { 1, 768000, PLL_1, 2, 0, 153600000, 1050, VDD_RAW(1050) },
123 /*
124 * AXI has MSMC1 implications. See above.
125 */
126 { 1, 806400, PLL_2, 3, 0, UINT_MAX, 1100, VDD_RAW(1100), &pll2_tbl[0]},
127 { 1, 1024000, PLL_2, 3, 0, UINT_MAX, 1200, VDD_RAW(1200), &pll2_tbl[1]},
128 { 1, 1200000, PLL_2, 3, 0, UINT_MAX, 1200, VDD_RAW(1200), &pll2_tbl[2]},
129 { 1, 1401600, PLL_2, 3, 0, UINT_MAX, 1250, VDD_RAW(1250), &pll2_tbl[3]},
130 { 0 }
131};
132
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700133static int acpuclk_set_acpu_vdd(struct clkctl_acpu_speed *s)
134{
135 int ret = msm_spm_set_vdd(0, s->vdd_raw);
136 if (ret)
137 return ret;
138
139 /* Wait for voltage to stabilize. */
Matt Wagantallec57f062011-08-16 23:54:46 -0700140 udelay(62);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700141 return 0;
142}
143
144/* Assumes PLL2 is off and the acpuclock isn't sourced from PLL2 */
145static void acpuclk_config_pll2(struct pll *pll)
146{
147 uint32_t config = readl_relaxed(PLL2_CONFIG_ADDR);
148
149 /* Make sure write to disable PLL_2 has completed
150 * before reconfiguring that PLL. */
151 mb();
152 writel_relaxed(pll->l, PLL2_L_VAL_ADDR);
153 writel_relaxed(pll->m, PLL2_M_VAL_ADDR);
154 writel_relaxed(pll->n, PLL2_N_VAL_ADDR);
155 if (pll->pre_div)
156 config |= BIT(15);
157 else
158 config &= ~BIT(15);
159 writel_relaxed(config, PLL2_CONFIG_ADDR);
160 /* Make sure PLL is programmed before returning. */
161 mb();
162}
163
164/* Set clock source and divider given a clock speed */
165static void acpuclk_set_src(const struct clkctl_acpu_speed *s)
166{
167 uint32_t reg_clksel, reg_clkctl, src_sel;
168
169 reg_clksel = readl_relaxed(SCSS_CLK_SEL_ADDR);
170
171 /* CLK_SEL_SRC1NO */
172 src_sel = reg_clksel & 1;
173
174 /* Program clock source and divider. */
175 reg_clkctl = readl_relaxed(SCSS_CLK_CTL_ADDR);
176 reg_clkctl &= ~(0xFF << (8 * src_sel));
177 reg_clkctl |= s->acpu_src_sel << (4 + 8 * src_sel);
178 reg_clkctl |= s->acpu_src_div << (0 + 8 * src_sel);
179 writel_relaxed(reg_clkctl, SCSS_CLK_CTL_ADDR);
180
181 /* Toggle clock source. */
182 reg_clksel ^= 1;
183
184 /* Program clock source selection. */
185 writel_relaxed(reg_clksel, SCSS_CLK_SEL_ADDR);
186
187 /* Make sure switch to new source is complete. */
188 mb();
189}
190
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700191static int acpuclk_7x30_set_rate(int cpu, unsigned long rate,
192 enum setrate_reason reason)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700193{
194 struct clkctl_acpu_speed *tgt_s, *strt_s;
195 int res, rc = 0;
196
197 if (reason == SETRATE_CPUFREQ)
198 mutex_lock(&drv_state.lock);
199
200 strt_s = drv_state.current_speed;
201
202 if (rate == strt_s->acpu_clk_khz)
203 goto out;
204
205 for (tgt_s = acpu_freq_tbl; tgt_s->acpu_clk_khz != 0; tgt_s++) {
206 if (tgt_s->acpu_clk_khz == rate)
207 break;
208 }
209 if (tgt_s->acpu_clk_khz == 0) {
210 rc = -EINVAL;
211 goto out;
212 }
213
214 if (reason == SETRATE_CPUFREQ) {
215 /* Increase VDD if needed. */
216 if (tgt_s->vdd_mv > strt_s->vdd_mv) {
217 rc = acpuclk_set_acpu_vdd(tgt_s);
218 if (rc < 0) {
219 pr_err("ACPU VDD increase to %d mV failed "
220 "(%d)\n", tgt_s->vdd_mv, rc);
221 goto out;
222 }
223 }
224 }
225
226 pr_debug("Switching from ACPU rate %u KHz -> %u KHz\n",
227 strt_s->acpu_clk_khz, tgt_s->acpu_clk_khz);
228
229 /* Increase the AXI bus frequency if needed. This must be done before
230 * increasing the ACPU frequency, since voting for high AXI rates
231 * implicitly takes care of increasing the MSMC1 voltage, as needed. */
232 if (tgt_s->axi_clk_hz > strt_s->axi_clk_hz) {
Matt Wagantalle0eecf02011-11-08 14:07:54 -0800233 rc = clk_set_rate(drv_state.ebi1_clk, tgt_s->axi_clk_hz);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700234 if (rc < 0) {
235 pr_err("Setting AXI min rate failed (%d)\n", rc);
236 goto out;
237 }
238 }
239
240 /* Move off of PLL2 if we're reprogramming it */
241 if (tgt_s->src == PLL_2 && strt_s->src == PLL_2) {
242 clk_enable(acpuclk_sources[backup_s->src]);
243 acpuclk_set_src(backup_s);
244 clk_disable(acpuclk_sources[strt_s->src]);
245 }
246
247 /* Reconfigure PLL2 if we're moving to it */
248 if (tgt_s->src == PLL_2)
249 acpuclk_config_pll2(tgt_s->pll_rate);
250
251 /* Make sure target PLL is on. */
252 if ((strt_s->src != tgt_s->src && tgt_s->src >= 0) ||
253 (tgt_s->src == PLL_2 && strt_s->src == PLL_2)) {
254 pr_debug("Enabling PLL %d\n", tgt_s->src);
255 clk_enable(acpuclk_sources[tgt_s->src]);
256 }
257
258 /* Perform the frequency switch */
259 acpuclk_set_src(tgt_s);
260 drv_state.current_speed = tgt_s;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700261
262 if (tgt_s->src == PLL_2 && strt_s->src == PLL_2)
263 clk_disable(acpuclk_sources[backup_s->src]);
264
265 /* Nothing else to do for SWFI. */
266 if (reason == SETRATE_SWFI)
267 goto out;
268
269 /* Turn off previous PLL if not used. */
270 if (strt_s->src != tgt_s->src && strt_s->src >= 0) {
271 pr_debug("Disabling PLL %d\n", strt_s->src);
272 clk_disable(acpuclk_sources[strt_s->src]);
273 }
274
275 /* Decrease the AXI bus frequency if we can. */
276 if (tgt_s->axi_clk_hz < strt_s->axi_clk_hz) {
Matt Wagantalle0eecf02011-11-08 14:07:54 -0800277 res = clk_set_rate(drv_state.ebi1_clk, tgt_s->axi_clk_hz);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700278 if (res < 0)
279 pr_warning("Setting AXI min rate failed (%d)\n", res);
280 }
281
282 /* Nothing else to do for power collapse. */
283 if (reason == SETRATE_PC)
284 goto out;
285
286 /* Drop VDD level if we can. */
287 if (tgt_s->vdd_mv < strt_s->vdd_mv) {
288 res = acpuclk_set_acpu_vdd(tgt_s);
289 if (res)
290 pr_warning("ACPU VDD decrease to %d mV failed (%d)\n",
291 tgt_s->vdd_mv, res);
292 }
293
294 pr_debug("ACPU speed change complete\n");
295out:
296 if (reason == SETRATE_CPUFREQ)
297 mutex_unlock(&drv_state.lock);
298
299 return rc;
300}
301
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700302static unsigned long acpuclk_7x30_get_rate(int cpu)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700303{
304 WARN_ONCE(drv_state.current_speed == NULL,
305 "acpuclk_get_rate: not initialized\n");
306 if (drv_state.current_speed)
307 return drv_state.current_speed->acpu_clk_khz;
308 else
309 return 0;
310}
311
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700312/*----------------------------------------------------------------------------
313 * Clock driver initialization
314 *---------------------------------------------------------------------------*/
315
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700316static void __init acpuclk_hw_init(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700317{
318 struct clkctl_acpu_speed *s;
319 uint32_t div, sel, src_num;
320 uint32_t reg_clksel, reg_clkctl;
321 int res;
322 u8 pll2_l = readl_relaxed(PLL2_L_VAL_ADDR) & 0xFF;
323
324 drv_state.ebi1_clk = clk_get(NULL, "ebi1_clk");
325 BUG_ON(IS_ERR(drv_state.ebi1_clk));
326
327 reg_clksel = readl_relaxed(SCSS_CLK_SEL_ADDR);
328
329 /* Determine the ACPU clock rate. */
330 switch ((reg_clksel >> 1) & 0x3) {
331 case 0: /* Running off the output of the raw clock source mux. */
332 reg_clkctl = readl_relaxed(SCSS_CLK_CTL_ADDR);
333 src_num = reg_clksel & 0x1;
334 sel = (reg_clkctl >> (12 - (8 * src_num))) & 0x7;
335 div = (reg_clkctl >> (8 - (8 * src_num))) & 0xF;
336
337 /* Check frequency table for matching sel/div pair. */
338 for (s = acpu_freq_tbl; s->acpu_clk_khz != 0; s++) {
339 if (s->acpu_src_sel == sel && s->acpu_src_div == div)
340 break;
341 }
342 if (s->acpu_clk_khz == 0) {
343 pr_err("Error - ACPU clock reports invalid speed\n");
344 return;
345 }
346 break;
347 case 2: /* Running off of the SCPLL selected through the core mux. */
348 /* Switch to run off of the SCPLL selected through the raw
349 * clock source mux. */
350 for (s = acpu_freq_tbl; s->acpu_clk_khz != 0
351 && s->src != PLL_2 && s->acpu_src_div == 0; s++)
352 ;
353 if (s->acpu_clk_khz != 0) {
354 /* Program raw clock source mux. */
355 acpuclk_set_src(s);
356
357 /* Switch to raw clock source input of the core mux. */
358 reg_clksel = readl_relaxed(SCSS_CLK_SEL_ADDR);
359 reg_clksel &= ~(0x3 << 1);
360 writel_relaxed(reg_clksel, SCSS_CLK_SEL_ADDR);
361 break;
362 }
363 /* else fall through */
364 default:
365 pr_err("Error - ACPU clock reports invalid source\n");
366 return;
367 }
368
369 /* Look at PLL2's L val to determine what speed PLL2 is running at */
370 if (s->src == PLL_2)
371 for ( ; s->acpu_clk_khz; s++)
372 if (s->pll_rate && s->pll_rate->l == pll2_l)
373 break;
374
375 /* Set initial ACPU VDD. */
376 acpuclk_set_acpu_vdd(s);
377
378 drv_state.current_speed = s;
379
380 /* Initialize current PLL's reference count. */
381 if (s->src >= 0)
382 clk_enable(acpuclk_sources[s->src]);
383
Matt Wagantalle0eecf02011-11-08 14:07:54 -0800384 res = clk_set_rate(drv_state.ebi1_clk, s->axi_clk_hz);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700385 if (res < 0)
386 pr_warning("Setting AXI min rate failed!\n");
387
388 pr_info("ACPU running at %d KHz\n", s->acpu_clk_khz);
389
390 return;
391}
392
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700393#ifdef CONFIG_CPU_FREQ_MSM
394static struct cpufreq_frequency_table cpufreq_tbl[ARRAY_SIZE(acpu_freq_tbl)];
395
396static void setup_cpufreq_table(void)
397{
398 unsigned i = 0;
399 const struct clkctl_acpu_speed *speed;
400
401 for (speed = acpu_freq_tbl; speed->acpu_clk_khz; speed++)
402 if (speed->use_for_scaling) {
403 cpufreq_tbl[i].index = i;
404 cpufreq_tbl[i].frequency = speed->acpu_clk_khz;
405 i++;
406 }
407 cpufreq_tbl[i].frequency = CPUFREQ_TABLE_END;
408
409 cpufreq_frequency_table_get_attr(cpufreq_tbl, smp_processor_id());
410}
411#else
412static inline void setup_cpufreq_table(void) { }
413#endif
414
415/*
416 * Truncate the frequency table at the current PLL2 rate and determine the
417 * backup PLL to use when scaling PLL2.
418 */
419void __init pll2_fixup(void)
420{
421 struct clkctl_acpu_speed *speed = acpu_freq_tbl;
422 u8 pll2_l = readl_relaxed(PLL2_L_VAL_ADDR) & 0xFF;
423
424 for ( ; speed->acpu_clk_khz; speed++) {
425 if (speed->src != PLL_2)
426 backup_s = speed;
427 if (speed->pll_rate && speed->pll_rate->l == pll2_l) {
428 speed++;
429 speed->acpu_clk_khz = 0;
430 return;
431 }
432 }
433
434 pr_err("Unknown PLL2 lval %d\n", pll2_l);
435 BUG();
436}
437
438#define RPM_BYPASS_MASK (1 << 3)
439#define PMIC_MODE_MASK (1 << 4)
440
441static void __init populate_plls(void)
442{
443 acpuclk_sources[PLL_1] = clk_get_sys("acpu", "pll1_clk");
444 BUG_ON(IS_ERR(acpuclk_sources[PLL_1]));
445 acpuclk_sources[PLL_2] = clk_get_sys("acpu", "pll2_clk");
446 BUG_ON(IS_ERR(acpuclk_sources[PLL_2]));
447 acpuclk_sources[PLL_3] = clk_get_sys("acpu", "pll3_clk");
448 BUG_ON(IS_ERR(acpuclk_sources[PLL_3]));
449}
450
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700451static struct acpuclk_data acpuclk_7x30_data = {
452 .set_rate = acpuclk_7x30_set_rate,
453 .get_rate = acpuclk_7x30_get_rate,
454 .power_collapse_khz = MAX_AXI_KHZ,
455 .wait_for_irq_khz = MAX_AXI_KHZ,
Matt Wagantallec57f062011-08-16 23:54:46 -0700456 .switch_time_us = 50,
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700457};
458
Matt Wagantallec57f062011-08-16 23:54:46 -0700459static int __init acpuclk_7x30_init(struct acpuclk_soc_data *soc_data)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700460{
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700461 pr_info("%s()\n", __func__);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700462
463 mutex_init(&drv_state.lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700464 pll2_fixup();
465 populate_plls();
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700466 acpuclk_hw_init();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700467 setup_cpufreq_table();
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700468 acpuclk_register(&acpuclk_7x30_data);
469
470 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700471}
Matt Wagantallec57f062011-08-16 23:54:46 -0700472
473struct acpuclk_soc_data acpuclk_7x30_soc_data __initdata = {
474 .init = acpuclk_7x30_init,
475};