blob: be0cf5ba20c763ed63e6819944197ec4bf6168c6 [file] [log] [blame]
Matt Wagantall6d9ebee2011-08-26 12:15:24 -07001/* Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/io.h>
17#include <linux/delay.h>
18#include <linux/mutex.h>
19#include <linux/errno.h>
20#include <linux/cpufreq.h>
21#include <linux/clk.h>
22
23#include <mach/board.h>
24#include <mach/msm_iomap.h>
25
26#include "acpuclock.h"
27#include "avs.h"
28
29#define SHOT_SWITCH 4
30#define HOP_SWITCH 5
31#define SIMPLE_SLEW 6
32#define COMPLEX_SLEW 7
33
34#define SPSS_CLK_CNTL_ADDR (MSM_CSR_BASE + 0x100)
35#define SPSS_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104)
36
37/* Scorpion PLL registers */
38#define SCPLL_CTL_ADDR (MSM_SCPLL_BASE + 0x4)
39#define SCPLL_STATUS_ADDR (MSM_SCPLL_BASE + 0x18)
40#define SCPLL_FSM_CTL_EXT_ADDR (MSM_SCPLL_BASE + 0x10)
41
42enum {
43 ACPU_PLL_TCXO = -1,
44 ACPU_PLL_0 = 0,
45 ACPU_PLL_1,
46 ACPU_PLL_2,
47 ACPU_PLL_3,
48 ACPU_PLL_END,
49};
50
51struct clkctl_acpu_speed {
52 unsigned int use_for_scaling;
53 unsigned int acpuclk_khz;
54 int pll;
55 unsigned int acpuclk_src_sel;
56 unsigned int acpuclk_src_div;
57 unsigned int ahbclk_khz;
58 unsigned int ahbclk_div;
59 unsigned int axiclk_khz;
60 unsigned int sc_core_src_sel_mask;
61 unsigned int sc_l_value;
62 int vdd;
63 unsigned long lpj; /* loops_per_jiffy */
64};
65
66struct clkctl_acpu_speed acpu_freq_tbl_998[] = {
67 { 0, 19200, ACPU_PLL_TCXO, 0, 0, 0, 0, 14000, 0, 0, 1000},
68 { 0, 128000, ACPU_PLL_1, 1, 5, 0, 0, 14000, 2, 0, 1000},
69 { 1, 245760, ACPU_PLL_0, 4, 0, 0, 0, 29000, 0, 0, 1000},
70 /* Update AXI_S and PLL0_S macros if above row numbers change. */
71 { 1, 384000, ACPU_PLL_3, 0, 0, 0, 0, 58000, 1, 0xA, 1000},
72 { 0, 422400, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0xB, 1000},
73 { 0, 460800, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0xC, 1000},
74 { 0, 499200, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0xD, 1050},
75 { 0, 537600, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0xE, 1050},
76 { 1, 576000, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0xF, 1050},
77 { 0, 614400, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0x10, 1075},
78 { 0, 652800, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0x11, 1100},
79 { 0, 691200, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0x12, 1125},
80 { 0, 729600, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0x13, 1150},
81 { 1, 768000, ACPU_PLL_3, 0, 0, 0, 0, 128000, 1, 0x14, 1150},
82 { 0, 806400, ACPU_PLL_3, 0, 0, 0, 0, 128000, 1, 0x15, 1175},
83 { 0, 844800, ACPU_PLL_3, 0, 0, 0, 0, 128000, 1, 0x16, 1225},
84 { 0, 883200, ACPU_PLL_3, 0, 0, 0, 0, 128000, 1, 0x17, 1250},
85 { 0, 921600, ACPU_PLL_3, 0, 0, 0, 0, 128000, 1, 0x18, 1300},
86 { 0, 960000, ACPU_PLL_3, 0, 0, 0, 0, 128000, 1, 0x19, 1300},
87 { 1, 998400, ACPU_PLL_3, 0, 0, 0, 0, 128000, 1, 0x1A, 1300},
88 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
89};
90
91struct clkctl_acpu_speed acpu_freq_tbl_768[] = {
92 { 0, 19200, ACPU_PLL_TCXO, 0, 0, 0, 0, 14000, 0, 0, 1000},
93 { 0, 128000, ACPU_PLL_1, 1, 5, 0, 0, 14000, 2, 0, 1000},
94 { 1, 245760, ACPU_PLL_0, 4, 0, 0, 0, 29000, 0, 0, 1000},
95 /* Update AXI_S and PLL0_S macros if above row numbers change. */
96 { 1, 384000, ACPU_PLL_3, 0, 0, 0, 0, 58000, 1, 0xA, 1075},
97 { 0, 422400, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0xB, 1100},
98 { 0, 460800, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0xC, 1125},
99 { 0, 499200, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0xD, 1150},
100 { 0, 537600, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0xE, 1150},
101 { 1, 576000, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0xF, 1150},
102 { 0, 614400, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0x10, 1175},
103 { 0, 652800, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0x11, 1200},
104 { 0, 691200, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0x12, 1225},
105 { 0, 729600, ACPU_PLL_3, 0, 0, 0, 0, 117000, 1, 0x13, 1250},
106 { 1, 768000, ACPU_PLL_3, 0, 0, 0, 0, 128000, 1, 0x14, 1250},
107 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
108};
109
110static struct clkctl_acpu_speed *acpu_freq_tbl = acpu_freq_tbl_998;
111#define AXI_S (&acpu_freq_tbl[1])
112#define PLL0_S (&acpu_freq_tbl[2])
113
114/* Use 128MHz for PC since ACPU will auto-switch to AXI (128MHz) before
115 * coming back up. This allows detection of return-from-PC, since 128MHz
116 * is only used for power collapse. */
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700117#define POWER_COLLAPSE_KHZ 128000
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700118/* Use 245MHz (not 128MHz) for SWFI to avoid unnecessary steps between
119 * 128MHz<->245MHz. Jumping to high frequencies from 128MHz directly
120 * is not allowed. */
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700121#define WAIT_FOR_IRQ_KHZ 245760
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700122
123#ifdef CONFIG_CPU_FREQ_MSM
124static struct cpufreq_frequency_table freq_table[20];
125
126static void __init cpufreq_table_init(void)
127{
128 unsigned int i;
129 unsigned int freq_cnt = 0;
130
131 /* Construct the freq_table table from acpu_freq_tbl since the
132 * freq_table values need to match frequencies specified in
133 * acpu_freq_tbl and acpu_freq_tbl needs to be fixed up during init.
134 */
135 for (i = 0; acpu_freq_tbl[i].acpuclk_khz != 0
136 && freq_cnt < ARRAY_SIZE(freq_table)-1; i++) {
137 if (acpu_freq_tbl[i].use_for_scaling) {
138 freq_table[freq_cnt].index = freq_cnt;
139 freq_table[freq_cnt].frequency
140 = acpu_freq_tbl[i].acpuclk_khz;
141 freq_cnt++;
142 }
143 }
144
145 /* freq_table not big enough to store all usable freqs. */
146 BUG_ON(acpu_freq_tbl[i].acpuclk_khz != 0);
147
148 freq_table[freq_cnt].index = freq_cnt;
149 freq_table[freq_cnt].frequency = CPUFREQ_TABLE_END;
150
151 pr_info("%d scaling frequencies supported.\n", freq_cnt);
152}
153#endif
154
155struct clock_state {
156 struct clkctl_acpu_speed *current_speed;
157 struct mutex lock;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700158 uint32_t vdd_switch_time_us;
159 unsigned int max_vdd;
160 struct clk *ebi1_clk;
161 int (*acpu_set_vdd) (int mvolts);
162};
163
164static struct clock_state drv_state = { 0 };
165
166static void scpll_set_freq(uint32_t lval, unsigned freq_switch)
167{
168 uint32_t regval;
169
170 if (lval > 33)
171 lval = 33;
172 if (lval < 10)
173 lval = 10;
174
175 /* wait for any calibrations or frequency switches to finish */
176 while (readl(SCPLL_STATUS_ADDR) & 0x3)
177 ;
178
179 /* write the new L val and switch mode */
180 regval = readl(SCPLL_FSM_CTL_EXT_ADDR);
181 regval &= ~(0x3f << 3);
182 regval |= (lval << 3);
183 if (freq_switch == SIMPLE_SLEW)
184 regval |= (0x1 << 9);
185
186 regval &= ~(0x3 << 0);
187 regval |= (freq_switch << 0);
188 writel(regval, SCPLL_FSM_CTL_EXT_ADDR);
189
190 dmb();
191
192 /* put in normal mode */
193 regval = readl(SCPLL_CTL_ADDR);
194 regval |= 0x7;
195 writel(regval, SCPLL_CTL_ADDR);
196
197 dmb();
198
199 /* wait for frequency switch to finish */
200 while (readl(SCPLL_STATUS_ADDR) & 0x1)
201 ;
202
203 /* status bit seems to clear early, using
204 * 100us to handle the worst case. */
205 udelay(100);
206}
207
208static void scpll_apps_enable(bool state)
209{
210 uint32_t regval;
211
212 if (state)
213 pr_debug("Enabling PLL 3\n");
214 else
215 pr_debug("Disabling PLL 3\n");
216
217 /* Wait for any frequency switches to finish. */
218 while (readl(SCPLL_STATUS_ADDR) & 0x1)
219 ;
220
221 /* put the pll in standby mode */
222 regval = readl(SCPLL_CTL_ADDR);
223 regval &= ~(0x7);
224 regval |= (0x2);
225 writel(regval, SCPLL_CTL_ADDR);
226
227 dmb();
228
229 if (state) {
230 /* put the pll in normal mode */
231 regval = readl(SCPLL_CTL_ADDR);
232 regval |= (0x7);
233 writel(regval, SCPLL_CTL_ADDR);
234 udelay(200);
235 } else {
236 /* put the pll in power down mode */
237 regval = readl(SCPLL_CTL_ADDR);
238 regval &= ~(0x7);
239 writel(regval, SCPLL_CTL_ADDR);
240 }
241 udelay(drv_state.vdd_switch_time_us);
242
243 if (state)
244 pr_debug("PLL 3 Enabled\n");
245 else
246 pr_debug("PLL 3 Disabled\n");
247}
248
249static void scpll_init(void)
250{
251 uint32_t regval;
252#define L_VAL_384MHZ 0xA
253#define L_VAL_768MHZ 0x14
254
255 pr_debug("Initializing PLL 3\n");
256
257 /* power down scpll */
258 writel(0x0, SCPLL_CTL_ADDR);
259
260 dmb();
261
262 /* set bypassnl, put into standby */
263 writel(0x00400002, SCPLL_CTL_ADDR);
264
265 /* set bypassnl, reset_n, full calibration */
266 writel(0x00600004, SCPLL_CTL_ADDR);
267
268 /* Ensure register write to initiate calibration has taken
269 effect before reading status flag */
270 dmb();
271
272 /* wait for cal_all_done */
273 while (readl(SCPLL_STATUS_ADDR) & 0x2)
274 ;
275
276 /* Start: Set of experimentally derived steps
277 * to work around a h/w bug. */
278
279 /* Put the pll in normal mode */
280 scpll_apps_enable(1);
281
282 /* SHOT switch to 384 MHz */
283 regval = readl(SCPLL_FSM_CTL_EXT_ADDR);
284 regval &= ~(0x3f << 3);
285 regval |= (L_VAL_384MHZ << 3);
286
287 regval &= ~0x7;
288 regval |= SHOT_SWITCH;
289 writel(regval, SCPLL_FSM_CTL_EXT_ADDR);
290
291 /* Trigger the freq switch by putting pll in normal mode. */
292 regval = readl(SCPLL_CTL_ADDR);
293 regval |= (0x7);
294 writel(regval, SCPLL_CTL_ADDR);
295
296 /* Wait for frequency switch to finish */
297 while (readl(SCPLL_STATUS_ADDR) & 0x1)
298 ;
299
300 /* Status bit seems to clear early, using
301 * 800 microseconds for the worst case. */
302 udelay(800);
303
304 /* HOP switch to 768 MHz. */
305 regval = readl(SCPLL_FSM_CTL_EXT_ADDR);
306 regval &= ~(0x3f << 3);
307 regval |= (L_VAL_768MHZ << 3);
308
309 regval &= ~0x7;
310 regval |= HOP_SWITCH;
311 writel(regval, SCPLL_FSM_CTL_EXT_ADDR);
312
313 /* Trigger the freq switch by putting pll in normal mode. */
314 regval = readl(SCPLL_CTL_ADDR);
315 regval |= (0x7);
316 writel(regval, SCPLL_CTL_ADDR);
317
318 /* Wait for frequency switch to finish */
319 while (readl(SCPLL_STATUS_ADDR) & 0x1)
320 ;
321
322 /* Status bit seems to clear early, using
323 * 100 microseconds for the worst case. */
324 udelay(100);
325
326 /* End: Work around for h/w bug */
327
328 /* Power down scpll */
329 scpll_apps_enable(0);
330}
331
332static void config_pll(struct clkctl_acpu_speed *s)
333{
334 uint32_t regval;
335
336 if (s->pll == ACPU_PLL_3)
337 scpll_set_freq(s->sc_l_value, HOP_SWITCH);
338 /* Configure the PLL divider mux if we plan to use it. */
339 else if (s->sc_core_src_sel_mask == 0) {
340 /* get the current clock source selection */
341 regval = readl(SPSS_CLK_SEL_ADDR) & 0x1;
342
343 /* configure the other clock source, then switch to it,
344 * using the glitch free mux */
345 switch (regval) {
346 case 0x0:
347 regval = readl(SPSS_CLK_CNTL_ADDR);
348 regval &= ~(0x7 << 4 | 0xf);
349 regval |= (s->acpuclk_src_sel << 4);
350 regval |= (s->acpuclk_src_div << 0);
351 writel(regval, SPSS_CLK_CNTL_ADDR);
352
353 regval = readl(SPSS_CLK_SEL_ADDR);
354 regval |= 0x1;
355 writel(regval, SPSS_CLK_SEL_ADDR);
356 break;
357
358 case 0x1:
359 regval = readl(SPSS_CLK_CNTL_ADDR);
360 regval &= ~(0x7 << 12 | 0xf << 8);
361 regval |= (s->acpuclk_src_sel << 12);
362 regval |= (s->acpuclk_src_div << 8);
363 writel(regval, SPSS_CLK_CNTL_ADDR);
364
365 regval = readl(SPSS_CLK_SEL_ADDR);
366 regval &= ~0x1;
367 writel(regval, SPSS_CLK_SEL_ADDR);
368 break;
369 }
370 dmb();
371 }
372
373 regval = readl(SPSS_CLK_SEL_ADDR);
374 regval &= ~(0x3 << 1);
375 regval |= (s->sc_core_src_sel_mask << 1);
376 writel(regval, SPSS_CLK_SEL_ADDR);
377}
378
379static int acpuclk_set_vdd_level(int vdd)
380{
381 if (drv_state.acpu_set_vdd) {
382 pr_debug("Switching VDD to %d mV\n", vdd);
383 return drv_state.acpu_set_vdd(vdd);
384 } else {
385 /* Assume that the PMIC supports scaling the processor
386 * to its maximum frequency at its default voltage.
387 */
388 return 0;
389 }
390}
391
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700392static int acpuclk_8x50_set_rate(int cpu, unsigned long rate,
393 enum setrate_reason reason)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700394{
395 struct clkctl_acpu_speed *tgt_s, *strt_s;
396 int res, rc = 0;
397 int freq_index = 0;
398
399 if (reason == SETRATE_CPUFREQ)
400 mutex_lock(&drv_state.lock);
401
402 strt_s = drv_state.current_speed;
403
404 if (rate == strt_s->acpuclk_khz)
405 goto out;
406
407 for (tgt_s = acpu_freq_tbl; tgt_s->acpuclk_khz != 0; tgt_s++) {
408 if (tgt_s->acpuclk_khz == rate)
409 break;
410 freq_index++;
411 }
412
413 if (tgt_s->acpuclk_khz == 0) {
414 rc = -EINVAL;
415 goto out;
416 }
417
418 if (reason == SETRATE_CPUFREQ) {
419#ifdef CONFIG_MSM_CPU_AVS
420 /* Notify avs before changing frequency */
421 rc = avs_adjust_freq(freq_index, 1);
422 if (rc) {
423 pr_err("Unable to increase ACPU vdd (%d)\n", rc);
424 goto out;
425 }
426#endif
427 /* Increase VDD if needed. */
428 if (tgt_s->vdd > strt_s->vdd) {
429 rc = acpuclk_set_vdd_level(tgt_s->vdd);
430 if (rc) {
431 pr_err("Unable to increase ACPU vdd (%d)\n",
432 rc);
433 goto out;
434 }
435 }
436 } else if (reason == SETRATE_PC
437 && rate != POWER_COLLAPSE_KHZ) {
438 /* Returning from PC. ACPU is running on AXI source.
439 * Step up to PLL0 before ramping up higher. */
440 config_pll(PLL0_S);
441 }
442
443 pr_debug("Switching from ACPU rate %u KHz -> %u KHz\n",
444 strt_s->acpuclk_khz, tgt_s->acpuclk_khz);
445
446 if (strt_s->pll != ACPU_PLL_3 && tgt_s->pll != ACPU_PLL_3) {
447 config_pll(tgt_s);
448 } else if (strt_s->pll != ACPU_PLL_3 && tgt_s->pll == ACPU_PLL_3) {
449 scpll_apps_enable(1);
450 config_pll(tgt_s);
451 } else if (strt_s->pll == ACPU_PLL_3 && tgt_s->pll != ACPU_PLL_3) {
452 config_pll(tgt_s);
453 scpll_apps_enable(0);
454 } else {
455 /* Temporarily switch to PLL0 while reconfiguring PLL3. */
456 config_pll(PLL0_S);
457 config_pll(tgt_s);
458 }
459
460 /* Update the driver state with the new clock freq */
461 drv_state.current_speed = tgt_s;
462
463 /* Re-adjust lpj for the new clock speed. */
464 loops_per_jiffy = tgt_s->lpj;
465
466 /* Nothing else to do for SWFI. */
467 if (reason == SETRATE_SWFI)
468 goto out;
469
470 if (strt_s->axiclk_khz != tgt_s->axiclk_khz) {
471 res = clk_set_rate(drv_state.ebi1_clk,
472 tgt_s->axiclk_khz * 1000);
473 if (res < 0)
474 pr_warning("Setting AXI min rate failed (%d)\n", res);
475 }
476
477 /* Nothing else to do for power collapse */
478 if (reason == SETRATE_PC)
479 goto out;
480
481#ifdef CONFIG_MSM_CPU_AVS
482 /* notify avs after changing frequency */
483 res = avs_adjust_freq(freq_index, 0);
484 if (res)
485 pr_warning("Unable to drop ACPU vdd (%d)\n", res);
486#endif
487
488 /* Drop VDD level if we can. */
489 if (tgt_s->vdd < strt_s->vdd) {
490 res = acpuclk_set_vdd_level(tgt_s->vdd);
491 if (res)
492 pr_warning("Unable to drop ACPU vdd (%d)\n", res);
493 }
494
495 pr_debug("ACPU speed change complete\n");
496out:
497 if (reason == SETRATE_CPUFREQ)
498 mutex_unlock(&drv_state.lock);
499 return rc;
500}
501
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700502static void __init acpuclk_hw_init(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700503{
504 struct clkctl_acpu_speed *speed;
505 uint32_t div, sel, regval;
506 int res;
507
508 /* Determine the source of the Scorpion clock. */
509 regval = readl(SPSS_CLK_SEL_ADDR);
510 switch ((regval & 0x6) >> 1) {
511 case 0: /* raw source clock */
512 case 3: /* low jitter PLL1 (768Mhz) */
513 if (regval & 0x1) {
514 sel = ((readl(SPSS_CLK_CNTL_ADDR) >> 4) & 0x7);
515 div = ((readl(SPSS_CLK_CNTL_ADDR) >> 0) & 0xf);
516 } else {
517 sel = ((readl(SPSS_CLK_CNTL_ADDR) >> 12) & 0x7);
518 div = ((readl(SPSS_CLK_CNTL_ADDR) >> 8) & 0xf);
519 }
520
521 /* Find the matching clock rate. */
522 for (speed = acpu_freq_tbl; speed->acpuclk_khz != 0; speed++) {
523 if (speed->acpuclk_src_sel == sel &&
524 speed->acpuclk_src_div == div)
525 break;
526 }
527 break;
528
529 case 1: /* unbuffered scorpion pll (384Mhz to 998.4Mhz) */
530 sel = ((readl(SCPLL_FSM_CTL_EXT_ADDR) >> 3) & 0x3f);
531
532 /* Find the matching clock rate. */
533 for (speed = acpu_freq_tbl; speed->acpuclk_khz != 0; speed++) {
534 if (speed->sc_l_value == sel &&
535 speed->sc_core_src_sel_mask == 1)
536 break;
537 }
538 break;
539
540 case 2: /* AXI bus clock (128Mhz) */
541 speed = AXI_S;
542 break;
543 default:
544 BUG();
545 }
546
547 /* Initialize scpll only if it wasn't already initialized by the boot
548 * loader. If the CPU is already running on scpll, then the scpll was
549 * initialized by the boot loader. */
550 if (speed->pll != ACPU_PLL_3)
551 scpll_init();
552
553 if (speed->acpuclk_khz == 0) {
554 pr_err("Error - ACPU clock reports invalid speed\n");
555 return;
556 }
557
558 drv_state.current_speed = speed;
559 res = clk_set_rate(drv_state.ebi1_clk, speed->axiclk_khz * 1000);
560 if (res < 0)
561 pr_warning("Setting AXI min rate failed (%d)\n", res);
562 res = clk_enable(drv_state.ebi1_clk);
563 if (res < 0)
564 pr_warning("Enabling AXI clock failed (%d)\n", res);
565
566 pr_info("ACPU running at %d KHz\n", speed->acpuclk_khz);
567}
568
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700569static unsigned long acpuclk_8x50_get_rate(int cpu)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700570{
571 return drv_state.current_speed->acpuclk_khz;
572}
573
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700574/* Spare register populated with efuse data on max ACPU freq. */
575#define CT_CSR_PHYS 0xA8700000
576#define TCSR_SPARE2_ADDR (ct_csr_base + 0x60)
577
578#define PLL0_M_VAL_ADDR (MSM_CLK_CTL_BASE + 0x308)
579
580static void __init acpu_freq_tbl_fixup(void)
581{
582 void __iomem *ct_csr_base;
583 uint32_t tcsr_spare2, pll0_m_val;
584 unsigned int max_acpu_khz;
585 unsigned int i;
586
587 ct_csr_base = ioremap(CT_CSR_PHYS, PAGE_SIZE);
588 BUG_ON(ct_csr_base == NULL);
589
590 tcsr_spare2 = readl(TCSR_SPARE2_ADDR);
591
592 /* Check if the register is supported and meaningful. */
593 if ((tcsr_spare2 & 0xF000) != 0xA000) {
594 pr_info("Efuse data on Max ACPU freq not present.\n");
595 goto skip_efuse_fixup;
596 }
597
598 switch (tcsr_spare2 & 0xF0) {
599 case 0x70:
600 acpu_freq_tbl = acpu_freq_tbl_768;
601 max_acpu_khz = 768000;
602 break;
603 case 0x30:
604 case 0x00:
605 max_acpu_khz = 998400;
606 break;
607 case 0x10:
608 max_acpu_khz = 1267200;
609 break;
610 default:
611 pr_warning("Invalid efuse data (%x) on Max ACPU freq!\n",
612 tcsr_spare2);
613 goto skip_efuse_fixup;
614 }
615
616 pr_info("Max ACPU freq from efuse data is %d KHz\n", max_acpu_khz);
617
618 for (i = 0; acpu_freq_tbl[i].acpuclk_khz != 0; i++) {
619 if (acpu_freq_tbl[i].acpuclk_khz > max_acpu_khz) {
620 acpu_freq_tbl[i].acpuclk_khz = 0;
621 break;
622 }
623 }
624
625skip_efuse_fixup:
626 iounmap(ct_csr_base);
627 BUG_ON(drv_state.max_vdd == 0);
628
629 /* pll0_m_val will be 36 when PLL0 is run at 235MHz
630 * instead of the usual 245MHz. */
631 pll0_m_val = readl(PLL0_M_VAL_ADDR) & 0x7FFFF;
632 if (pll0_m_val == 36)
633 PLL0_S->acpuclk_khz = 235930;
634
635 for (i = 0; acpu_freq_tbl[i].acpuclk_khz != 0; i++) {
636 if (acpu_freq_tbl[i].vdd > drv_state.max_vdd) {
637 acpu_freq_tbl[i].acpuclk_khz = 0;
638 break;
639 }
640 }
641}
642
643/* Initalize the lpj field in the acpu_freq_tbl. */
644static void __init lpj_init(void)
645{
646 int i;
647 const struct clkctl_acpu_speed *base_clk = drv_state.current_speed;
648 for (i = 0; acpu_freq_tbl[i].acpuclk_khz; i++) {
649 acpu_freq_tbl[i].lpj = cpufreq_scale(loops_per_jiffy,
650 base_clk->acpuclk_khz,
651 acpu_freq_tbl[i].acpuclk_khz);
652 }
653}
654
655#ifdef CONFIG_MSM_CPU_AVS
656static int __init acpu_avs_init(int (*set_vdd) (int), int khz)
657{
658 int i;
659 int freq_count = 0;
660 int freq_index = -1;
661
662 for (i = 0; acpu_freq_tbl[i].acpuclk_khz; i++) {
663 freq_count++;
664 if (acpu_freq_tbl[i].acpuclk_khz == khz)
665 freq_index = i;
666 }
667
668 return avs_init(set_vdd, freq_count, freq_index);
669}
670#endif
671
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700672static struct acpuclk_data acpuclk_8x50_data = {
673 .set_rate = acpuclk_8x50_set_rate,
674 .get_rate = acpuclk_8x50_get_rate,
675 .power_collapse_khz = POWER_COLLAPSE_KHZ,
676 .wait_for_irq_khz = WAIT_FOR_IRQ_KHZ,
677};
678
679int __init acpuclk_8x50_init(struct acpuclk_platform_data *clkdata)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700680{
681 mutex_init(&drv_state.lock);
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700682 acpuclk_8x50_data.switch_time_us = clkdata->acpu_switch_time_us;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700683 drv_state.vdd_switch_time_us = clkdata->vdd_switch_time_us;
684 drv_state.max_vdd = clkdata->max_vdd;
685 drv_state.acpu_set_vdd = clkdata->acpu_set_vdd;
686
687 drv_state.ebi1_clk = clk_get(NULL, "ebi1_acpu_clk");
688 BUG_ON(IS_ERR(drv_state.ebi1_clk));
689
690 acpu_freq_tbl_fixup();
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700691 acpuclk_hw_init();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700692 lpj_init();
693 /* Set a lower bound for ACPU rate for boot. This limits the
694 * maximum frequency hop caused by the first CPUFREQ switch. */
695 if (drv_state.current_speed->acpuclk_khz < PLL0_S->acpuclk_khz)
696 acpuclk_set_rate(0, PLL0_S->acpuclk_khz, SETRATE_CPUFREQ);
697
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700698 acpuclk_register(&acpuclk_8x50_data);
699
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700700#ifdef CONFIG_CPU_FREQ_MSM
701 cpufreq_table_init();
702 cpufreq_frequency_table_get_attr(freq_table, smp_processor_id());
703#endif
704#ifdef CONFIG_MSM_CPU_AVS
705 if (!acpu_avs_init(drv_state.acpu_set_vdd,
706 drv_state.current_speed->acpuclk_khz)) {
707 /* avs init successful. avs will handle voltage changes */
708 drv_state.acpu_set_vdd = NULL;
709 }
710#endif
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700711 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700712}