blob: 4f133fc1e4eadf79fb045f019bf106719a4d1b30 [file] [log] [blame]
Saravana Kannanb60200c2012-10-09 23:44:10 -07001/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
2 *
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#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/platform_device.h>
17#include <linux/err.h>
18#include <linux/ctype.h>
19#include <linux/io.h>
20#include <linux/clk.h>
21#include <linux/regulator/consumer.h>
22#include <linux/of.h>
23#include <linux/cpumask.h>
24
25#include <asm/cputype.h>
26
27#include <mach/rpm-regulator-smd.h>
28#include <mach/clk-provider.h>
29#include <mach/clock-generic.h>
30#include <mach/clk.h>
31#include "clock-krait.h"
32#include "clock.h"
33
34/* Clock inputs coming into Krait subsystem */
35DEFINE_FIXED_DIV_CLK(hfpll_src_clk, 1, NULL);
36DEFINE_FIXED_DIV_CLK(acpu_aux_clk, 2, NULL);
37
38static int hfpll_uv[] = {
39 RPM_REGULATOR_CORNER_NONE, 0,
40 RPM_REGULATOR_CORNER_SVS_SOC, 1800000,
41 RPM_REGULATOR_CORNER_NORMAL, 1800000,
42 RPM_REGULATOR_CORNER_SUPER_TURBO, 1800000,
43};
44static DEFINE_VDD_REGULATORS(vdd_hfpll, ARRAY_SIZE(hfpll_uv)/2, 2,
45 hfpll_uv, NULL);
46
47static unsigned long hfpll_fmax[] = { 0, 998400000, 1996800000, 2900000000UL };
48
49static struct hfpll_data hdata = {
50 .mode_offset = 0x0,
51 .l_offset = 0x4,
52 .m_offset = 0x8,
53 .n_offset = 0xC,
54 .user_offset = 0x10,
55 .config_offset = 0x14,
56 .status_offset = 0x1C,
57
58 .user_val = 0x8,
Saravana Kannanb60200c2012-10-09 23:44:10 -070059 .low_vco_max_rate = 1248000000,
60 .min_rate = 537600000UL,
61 .max_rate = 2900000000UL,
62};
63
64static struct hfpll_clk hfpll0_clk = {
65 .d = &hdata,
66 .src_rate = 19200000,
67 .c = {
68 .parent = &hfpll_src_clk.c,
69 .dbg_name = "hfpll0_clk",
70 .ops = &clk_ops_hfpll,
71 .vdd_class = &vdd_hfpll,
72 .fmax = hfpll_fmax,
73 .num_fmax = ARRAY_SIZE(hfpll_fmax),
74 CLK_INIT(hfpll0_clk.c),
75 },
76};
77
Saravana Kannan17475962013-09-06 19:22:21 -070078DEFINE_KPSS_DIV2_CLK(hfpll0_div_clk, &hfpll0_clk.c, 0x4501, true);
Saravana Kannanb60200c2012-10-09 23:44:10 -070079
80static struct hfpll_clk hfpll1_clk = {
81 .d = &hdata,
82 .src_rate = 19200000,
83 .c = {
84 .parent = &hfpll_src_clk.c,
85 .dbg_name = "hfpll1_clk",
86 .ops = &clk_ops_hfpll,
87 .vdd_class = &vdd_hfpll,
88 .fmax = hfpll_fmax,
89 .num_fmax = ARRAY_SIZE(hfpll_fmax),
90 CLK_INIT(hfpll1_clk.c),
91 },
92};
93
Saravana Kannan17475962013-09-06 19:22:21 -070094DEFINE_KPSS_DIV2_CLK(hfpll1_div_clk, &hfpll1_clk.c, 0x5501, true);
Saravana Kannanb60200c2012-10-09 23:44:10 -070095
96static struct hfpll_clk hfpll2_clk = {
97 .d = &hdata,
98 .src_rate = 19200000,
99 .c = {
100 .parent = &hfpll_src_clk.c,
101 .dbg_name = "hfpll2_clk",
102 .ops = &clk_ops_hfpll,
103 .vdd_class = &vdd_hfpll,
104 .fmax = hfpll_fmax,
105 .num_fmax = ARRAY_SIZE(hfpll_fmax),
106 CLK_INIT(hfpll2_clk.c),
107 },
108};
109
Saravana Kannan17475962013-09-06 19:22:21 -0700110DEFINE_KPSS_DIV2_CLK(hfpll2_div_clk, &hfpll2_clk.c, 0x6501, true);
Saravana Kannanb60200c2012-10-09 23:44:10 -0700111
112static struct hfpll_clk hfpll3_clk = {
113 .d = &hdata,
114 .src_rate = 19200000,
115 .c = {
116 .parent = &hfpll_src_clk.c,
117 .dbg_name = "hfpll3_clk",
118 .ops = &clk_ops_hfpll,
119 .vdd_class = &vdd_hfpll,
120 .fmax = hfpll_fmax,
121 .num_fmax = ARRAY_SIZE(hfpll_fmax),
122 CLK_INIT(hfpll3_clk.c),
123 },
124};
125
Saravana Kannan17475962013-09-06 19:22:21 -0700126DEFINE_KPSS_DIV2_CLK(hfpll3_div_clk, &hfpll3_clk.c, 0x7501, true);
Saravana Kannanb60200c2012-10-09 23:44:10 -0700127
128static struct hfpll_clk hfpll_l2_clk = {
129 .d = &hdata,
130 .src_rate = 19200000,
131 .c = {
132 .parent = &hfpll_src_clk.c,
133 .dbg_name = "hfpll_l2_clk",
134 .ops = &clk_ops_hfpll,
135 .vdd_class = &vdd_hfpll,
136 .fmax = hfpll_fmax,
137 .num_fmax = ARRAY_SIZE(hfpll_fmax),
138 CLK_INIT(hfpll_l2_clk.c),
139 },
140};
141
Saravana Kannan17475962013-09-06 19:22:21 -0700142DEFINE_KPSS_DIV2_CLK(hfpll_l2_div_clk, &hfpll_l2_clk.c, 0x500, false);
Saravana Kannanb60200c2012-10-09 23:44:10 -0700143
144#define SEC_MUX_COMMON_DATA \
145 .safe_parent = &acpu_aux_clk.c, \
146 .ops = &clk_mux_ops_kpss, \
147 .mask = 0x3, \
148 .shift = 2, \
149 MUX_SRC_LIST( \
150 {&acpu_aux_clk.c, 2}, \
151 {NULL /* QSB */, 0}, \
152 )
153
154static struct mux_clk krait0_sec_mux_clk = {
155 .offset = 0x4501,
Saravana Kannan17475962013-09-06 19:22:21 -0700156 .priv = (void *) true,
Saravana Kannanb60200c2012-10-09 23:44:10 -0700157 SEC_MUX_COMMON_DATA,
158 .c = {
159 .dbg_name = "krait0_sec_mux_clk",
160 .ops = &clk_ops_gen_mux,
161 CLK_INIT(krait0_sec_mux_clk.c),
162 },
163};
164
165static struct mux_clk krait1_sec_mux_clk = {
166 .offset = 0x5501,
Saravana Kannan17475962013-09-06 19:22:21 -0700167 .priv = (void *) true,
Saravana Kannanb60200c2012-10-09 23:44:10 -0700168 SEC_MUX_COMMON_DATA,
169 .c = {
170 .dbg_name = "krait1_sec_mux_clk",
171 .ops = &clk_ops_gen_mux,
172 CLK_INIT(krait1_sec_mux_clk.c),
173 },
174};
175
176static struct mux_clk krait2_sec_mux_clk = {
177 .offset = 0x6501,
Saravana Kannan17475962013-09-06 19:22:21 -0700178 .priv = (void *) true,
Saravana Kannanb60200c2012-10-09 23:44:10 -0700179 SEC_MUX_COMMON_DATA,
180 .c = {
181 .dbg_name = "krait2_sec_mux_clk",
182 .ops = &clk_ops_gen_mux,
183 CLK_INIT(krait2_sec_mux_clk.c),
184 },
185};
186
187static struct mux_clk krait3_sec_mux_clk = {
188 .offset = 0x7501,
Saravana Kannan17475962013-09-06 19:22:21 -0700189 .priv = (void *) true,
Saravana Kannanb60200c2012-10-09 23:44:10 -0700190 SEC_MUX_COMMON_DATA,
191 .c = {
192 .dbg_name = "krait3_sec_mux_clk",
193 .ops = &clk_ops_gen_mux,
194 CLK_INIT(krait3_sec_mux_clk.c),
195 },
196};
197
198static struct mux_clk l2_sec_mux_clk = {
199 .offset = 0x500,
200 SEC_MUX_COMMON_DATA,
201 .c = {
202 .dbg_name = "l2_sec_mux_clk",
203 .ops = &clk_ops_gen_mux,
204 CLK_INIT(l2_sec_mux_clk.c),
205 },
206};
207
208#define PRI_MUX_COMMON_DATA \
209 .ops = &clk_mux_ops_kpss, \
210 .mask = 0x3, \
211 .shift = 0
212
213static struct mux_clk krait0_pri_mux_clk = {
214 .offset = 0x4501,
Saravana Kannan17475962013-09-06 19:22:21 -0700215 .priv = (void *) true,
Saravana Kannanb60200c2012-10-09 23:44:10 -0700216 MUX_SRC_LIST(
217 { &hfpll0_clk.c, 1 },
218 { &hfpll0_div_clk.c, 2 },
219 { &krait0_sec_mux_clk.c, 0 },
220 ),
221 .safe_parent = &krait0_sec_mux_clk.c,
222 PRI_MUX_COMMON_DATA,
223 .c = {
224 .dbg_name = "krait0_pri_mux_clk",
225 .ops = &clk_ops_gen_mux,
226 CLK_INIT(krait0_pri_mux_clk.c),
227 },
228};
229
230static struct mux_clk krait1_pri_mux_clk = {
231 .offset = 0x5501,
Saravana Kannan17475962013-09-06 19:22:21 -0700232 .priv = (void *) true,
Saravana Kannanb60200c2012-10-09 23:44:10 -0700233 MUX_SRC_LIST(
234 { &hfpll1_clk.c, 1 },
235 { &hfpll1_div_clk.c, 2 },
236 { &krait1_sec_mux_clk.c, 0 },
237 ),
238 .safe_parent = &krait1_sec_mux_clk.c,
239 PRI_MUX_COMMON_DATA,
240 .c = {
241 .dbg_name = "krait1_pri_mux_clk",
242 .ops = &clk_ops_gen_mux,
243 CLK_INIT(krait1_pri_mux_clk.c),
244 },
245};
246
247static struct mux_clk krait2_pri_mux_clk = {
248 .offset = 0x6501,
Saravana Kannan17475962013-09-06 19:22:21 -0700249 .priv = (void *) true,
Saravana Kannanb60200c2012-10-09 23:44:10 -0700250 MUX_SRC_LIST(
251 { &hfpll2_clk.c, 1 },
252 { &hfpll2_div_clk.c, 2 },
253 { &krait2_sec_mux_clk.c, 0 },
254 ),
255 .safe_parent = &krait2_sec_mux_clk.c,
256 PRI_MUX_COMMON_DATA,
257 .c = {
258 .dbg_name = "krait2_pri_mux_clk",
259 .ops = &clk_ops_gen_mux,
260 CLK_INIT(krait2_pri_mux_clk.c),
261 },
262};
263
264static struct mux_clk krait3_pri_mux_clk = {
265 .offset = 0x7501,
Saravana Kannan17475962013-09-06 19:22:21 -0700266 .priv = (void *) true,
Saravana Kannanb60200c2012-10-09 23:44:10 -0700267 MUX_SRC_LIST(
268 { &hfpll3_clk.c, 1 },
269 { &hfpll3_div_clk.c, 2 },
270 { &krait3_sec_mux_clk.c, 0 },
271 ),
272 .safe_parent = &krait3_sec_mux_clk.c,
273 PRI_MUX_COMMON_DATA,
274 .c = {
275 .dbg_name = "krait3_pri_mux_clk",
276 .ops = &clk_ops_gen_mux,
277 CLK_INIT(krait3_pri_mux_clk.c),
278 },
279};
280
281static struct mux_clk l2_pri_mux_clk = {
282 .offset = 0x500,
283 MUX_SRC_LIST(
284 {&hfpll_l2_clk.c, 1 },
285 {&hfpll_l2_div_clk.c, 2},
286 {&l2_sec_mux_clk.c, 0}
287 ),
288 .safe_parent = &l2_sec_mux_clk.c,
289 PRI_MUX_COMMON_DATA,
290 .c = {
291 .dbg_name = "l2_pri_mux_clk",
292 .ops = &clk_ops_gen_mux,
293 CLK_INIT(l2_pri_mux_clk.c),
294 },
295};
296
297static struct avs_data avs_table;
298
299static DEFINE_VDD_REGS_INIT(vdd_krait0, 1);
300static DEFINE_VDD_REGS_INIT(vdd_krait1, 1);
301static DEFINE_VDD_REGS_INIT(vdd_krait2, 1);
302static DEFINE_VDD_REGS_INIT(vdd_krait3, 1);
303static DEFINE_VDD_REGS_INIT(vdd_l2, 1);
304
305/*
306 * This clock is mostly a dummy clock in the sense it can't really gate the
307 * CPU/L2 clocks or affect their frequency. It exists solely to:
308 *
309 * - Capture the PVS requirements for each CPU.
310 * - Implement HW clock gating disable ops needed for measuring the freq of
311 * Krait/L2 properly.
312 * - Implement AVS requirement.
313 */
314static struct kpss_core_clk krait0_clk = {
315 .id = 0,
316 .avs_tbl = &avs_table,
317 .c = {
318 .parent = &krait0_pri_mux_clk.c,
319 .dbg_name = "krait0_clk",
320 .ops = &clk_ops_kpss_cpu,
321 .vdd_class = &vdd_krait0,
322 CLK_INIT(krait0_clk.c),
323 },
324};
325
326static struct kpss_core_clk krait1_clk = {
327 .id = 1,
328 .avs_tbl = &avs_table,
329 .c = {
330 .parent = &krait1_pri_mux_clk.c,
331 .dbg_name = "krait1_clk",
332 .ops = &clk_ops_kpss_cpu,
333 .vdd_class = &vdd_krait1,
334 CLK_INIT(krait1_clk.c),
335 },
336};
337
338static struct kpss_core_clk krait2_clk = {
339 .id = 2,
340 .avs_tbl = &avs_table,
341 .c = {
342 .parent = &krait2_pri_mux_clk.c,
343 .dbg_name = "krait2_clk",
344 .ops = &clk_ops_kpss_cpu,
345 .vdd_class = &vdd_krait2,
346 CLK_INIT(krait2_clk.c),
347 },
348};
349
350static struct kpss_core_clk krait3_clk = {
351 .id = 3,
352 .avs_tbl = &avs_table,
353 .c = {
354 .parent = &krait3_pri_mux_clk.c,
355 .dbg_name = "krait3_clk",
356 .ops = &clk_ops_kpss_cpu,
357 .vdd_class = &vdd_krait3,
358 CLK_INIT(krait3_clk.c),
359 },
360};
361
362static struct kpss_core_clk l2_clk = {
363 .cp15_iaddr = 0x0500,
364 .c = {
365 .parent = &l2_pri_mux_clk.c,
366 .dbg_name = "l2_clk",
367 .ops = &clk_ops_kpss_l2,
368 .vdd_class = &vdd_l2,
369 CLK_INIT(l2_clk.c),
370 },
371};
372
373static struct clk_lookup kpss_clocks_8974[] = {
374 CLK_LOOKUP("", hfpll_src_clk.c, ""),
375 CLK_LOOKUP("", acpu_aux_clk.c, ""),
376 CLK_LOOKUP("", hfpll0_clk.c, ""),
377 CLK_LOOKUP("", hfpll0_div_clk.c, ""),
378 CLK_LOOKUP("", hfpll0_clk.c, ""),
379 CLK_LOOKUP("", hfpll1_div_clk.c, ""),
380 CLK_LOOKUP("", hfpll1_clk.c, ""),
381 CLK_LOOKUP("", hfpll2_div_clk.c, ""),
382 CLK_LOOKUP("", hfpll2_clk.c, ""),
383 CLK_LOOKUP("", hfpll3_div_clk.c, ""),
384 CLK_LOOKUP("", hfpll3_clk.c, ""),
385 CLK_LOOKUP("", hfpll_l2_div_clk.c, ""),
386 CLK_LOOKUP("", hfpll_l2_clk.c, ""),
387 CLK_LOOKUP("", krait0_sec_mux_clk.c, ""),
388 CLK_LOOKUP("", krait1_sec_mux_clk.c, ""),
389 CLK_LOOKUP("", krait2_sec_mux_clk.c, ""),
390 CLK_LOOKUP("", krait3_sec_mux_clk.c, ""),
391 CLK_LOOKUP("", l2_sec_mux_clk.c, ""),
392 CLK_LOOKUP("", krait0_pri_mux_clk.c, ""),
393 CLK_LOOKUP("", krait1_pri_mux_clk.c, ""),
394 CLK_LOOKUP("", krait2_pri_mux_clk.c, ""),
395 CLK_LOOKUP("", krait3_pri_mux_clk.c, ""),
396 CLK_LOOKUP("", l2_pri_mux_clk.c, ""),
Saravana Kannanfd3ac302013-05-06 17:45:49 -0700397 CLK_LOOKUP("l2_clk", l2_clk.c, "0.qcom,msm-cpufreq"),
398 CLK_LOOKUP("cpu0_clk", krait0_clk.c, "0.qcom,msm-cpufreq"),
399 CLK_LOOKUP("cpu1_clk", krait1_clk.c, "0.qcom,msm-cpufreq"),
400 CLK_LOOKUP("cpu2_clk", krait2_clk.c, "0.qcom,msm-cpufreq"),
401 CLK_LOOKUP("cpu3_clk", krait3_clk.c, "0.qcom,msm-cpufreq"),
Saravana Kannanb60200c2012-10-09 23:44:10 -0700402 CLK_LOOKUP("l2_clk", l2_clk.c, "fe805664.qcom,pm-8x60"),
403 CLK_LOOKUP("cpu0_clk", krait0_clk.c, "fe805664.qcom,pm-8x60"),
404 CLK_LOOKUP("cpu1_clk", krait1_clk.c, "fe805664.qcom,pm-8x60"),
405 CLK_LOOKUP("cpu2_clk", krait2_clk.c, "fe805664.qcom,pm-8x60"),
406 CLK_LOOKUP("cpu3_clk", krait3_clk.c, "fe805664.qcom,pm-8x60"),
407};
408
409static struct clk *cpu_clk[] = {
410 &krait0_clk.c,
411 &krait1_clk.c,
412 &krait2_clk.c,
413 &krait3_clk.c,
414};
415
416static void get_krait_bin_format_b(struct platform_device *pdev,
Matt Wagantallc94c4702013-12-17 15:21:11 -0800417 int *speed, int *pvs, int *pvs_ver)
Saravana Kannanb60200c2012-10-09 23:44:10 -0700418{
419 u32 pte_efuse, redundant_sel;
420 struct resource *res;
421 void __iomem *base;
422
423 *speed = 0;
424 *pvs = 0;
Matt Wagantallc94c4702013-12-17 15:21:11 -0800425 *pvs_ver = 0;
Saravana Kannanb60200c2012-10-09 23:44:10 -0700426
427 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "efuse");
428 if (!res) {
429 dev_info(&pdev->dev,
430 "No speed/PVS binning available. Defaulting to 0!\n");
431 return;
432 }
433
434 base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
435 if (!base) {
436 dev_warn(&pdev->dev,
437 "Unable to read efuse data. Defaulting to 0!\n");
438 return;
439 }
440
441 pte_efuse = readl_relaxed(base);
442 redundant_sel = (pte_efuse >> 24) & 0x7;
443 *speed = pte_efuse & 0x7;
Saravana Kannan9ded77c2013-09-16 20:48:51 -0700444 /* 4 bits of PVS are in efuse register bits 31, 8-6. */
445 *pvs = ((pte_efuse >> 28) & 0x8) | ((pte_efuse >> 6) & 0x7);
Matt Wagantallc94c4702013-12-17 15:21:11 -0800446 *pvs_ver = (pte_efuse >> 4) & 0x3;
Saravana Kannanb60200c2012-10-09 23:44:10 -0700447
448 switch (redundant_sel) {
449 case 1:
Saravana Kannan9ded77c2013-09-16 20:48:51 -0700450 *speed = (pte_efuse >> 27) & 0xF;
Saravana Kannanb60200c2012-10-09 23:44:10 -0700451 break;
452 case 2:
Saravana Kannan9ded77c2013-09-16 20:48:51 -0700453 *pvs = (pte_efuse >> 27) & 0xF;
Saravana Kannanb60200c2012-10-09 23:44:10 -0700454 break;
455 }
456
457 /* Check SPEED_BIN_BLOW_STATUS */
458 if (pte_efuse & BIT(3)) {
459 dev_info(&pdev->dev, "Speed bin: %d\n", *speed);
460 } else {
461 dev_warn(&pdev->dev, "Speed bin not set. Defaulting to 0!\n");
462 *speed = 0;
463 }
464
465 /* Check PVS_BLOW_STATUS */
466 pte_efuse = readl_relaxed(base + 0x4) & BIT(21);
467 if (pte_efuse) {
468 dev_info(&pdev->dev, "PVS bin: %d\n", *pvs);
469 } else {
470 dev_warn(&pdev->dev, "PVS bin not set. Defaulting to 0!\n");
471 *pvs = 0;
472 }
473
Matt Wagantallc94c4702013-12-17 15:21:11 -0800474 dev_info(&pdev->dev, "PVS version: %d\n", *pvs_ver);
Saravana Kannanb60200c2012-10-09 23:44:10 -0700475
476 devm_iounmap(&pdev->dev, base);
477}
478
479static int parse_tbl(struct device *dev, char *prop, int num_cols,
480 u32 **col1, u32 **col2, u32 **col3)
481{
482 int ret, prop_len, num_rows, i, j, k;
483 u32 *prop_data;
484 u32 *col[num_cols];
485
486 if (!of_find_property(dev->of_node, prop, &prop_len))
487 return -EINVAL;
488
489 prop_len /= sizeof(*prop_data);
490
491 if (prop_len % num_cols || prop_len == 0)
492 return -EINVAL;
493
494 num_rows = prop_len / num_cols;
495
496 prop_data = devm_kzalloc(dev, prop_len * sizeof(*prop_data),
497 GFP_KERNEL);
498 if (!prop_data)
499 return -ENOMEM;
500
501 for (i = 0; i < num_cols; i++) {
502 col[i] = devm_kzalloc(dev, num_rows * sizeof(u32), GFP_KERNEL);
503 if (!col[i])
504 return -ENOMEM;
505 }
506
507 ret = of_property_read_u32_array(dev->of_node, prop, prop_data,
508 prop_len);
509 if (ret)
510 return ret;
511
512 k = 0;
513 for (i = 0; i < num_rows; i++) {
514 for (j = 0; j < num_cols; j++)
515 col[j][i] = prop_data[k++];
516 }
517 if (col1)
518 *col1 = col[0];
519 if (col2)
520 *col2 = col[1];
521 if (col3)
522 *col3 = col[2];
523
524 devm_kfree(dev, prop_data);
525
526 return num_rows;
527}
528
529static int clk_init_vdd_class(struct device *dev, struct clk *clk, int num,
530 unsigned long *fmax, int *uv, int *ua)
531{
532 struct clk_vdd_class *vdd = clk->vdd_class;
533
534 vdd->level_votes = devm_kzalloc(dev, num * sizeof(int), GFP_KERNEL);
535 if (!vdd->level_votes) {
536 dev_err(dev, "Out of memory!\n");
537 return -ENOMEM;
538 }
539 vdd->num_levels = num;
540 vdd->cur_level = num;
541 vdd->vdd_uv = uv;
542 vdd->vdd_ua = ua;
543 clk->fmax = fmax;
544 clk->num_fmax = num;
545
546 return 0;
547}
548
549static int hfpll_base_init(struct platform_device *pdev, struct hfpll_clk *h)
550{
551 struct resource *res;
552 struct device *dev = &pdev->dev;
553
554 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, h->c.dbg_name);
555 if (!res) {
556 dev_err(dev, "%s base addr not found!\n", h->c.dbg_name);
557 return -EINVAL;
558 }
559 h->base = devm_ioremap(dev, res->start, resource_size(res));
560 if (!h->base) {
561 dev_err(dev, "%s ioremap failed!\n", h->c.dbg_name);
562 return -ENOMEM;
563 }
564 return 0;
565}
566
567static bool enable_boost;
568module_param_named(boost, enable_boost, bool, S_IRUGO | S_IWUSR);
569
570static void krait_update_uv(int *uv, int num, int boost_uv)
571{
572 int i;
573
574 switch (read_cpuid_id()) {
575 case 0x511F04D0: /* KR28M2A20 */
576 case 0x511F04D1: /* KR28M2A21 */
577 case 0x510F06F0: /* KR28M4A10 */
578 for (i = 0; i < num; i++)
579 uv[i] = max(1150000, uv[i]);
580 };
581
582 if (enable_boost) {
583 for (i = 0; i < num; i++)
584 uv[i] += boost_uv;
585 }
586}
587
Matt Wagantallc94c4702013-12-17 15:21:11 -0800588static char table_name[] = "qcom,speedXX-pvsXX-bin-vXX";
589module_param_string(table_name, table_name, sizeof(table_name), S_IRUGO);
590static unsigned int pvs_config_ver;
591module_param(pvs_config_ver, uint, S_IRUGO);
592
Saravana Kannanb60200c2012-10-09 23:44:10 -0700593static int clock_krait_8974_driver_probe(struct platform_device *pdev)
594{
595 struct device *dev = &pdev->dev;
596 struct clk *c;
Matt Wagantallc94c4702013-12-17 15:21:11 -0800597 int speed, pvs, pvs_ver, config_ver, rows, cpu;
Saravana Kannanb60200c2012-10-09 23:44:10 -0700598 unsigned long *freq, cur_rate, aux_rate;
599 int *uv, *ua;
Vikram Mulukutla8e2750d2013-09-10 15:12:44 -0700600 u32 *dscr, vco_mask, config_val;
601 int ret;
Saravana Kannanb60200c2012-10-09 23:44:10 -0700602
603 vdd_l2.regulator[0] = devm_regulator_get(dev, "l2-dig");
604 if (IS_ERR(vdd_l2.regulator[0])) {
605 dev_err(dev, "Unable to get l2-dig regulator!\n");
606 return PTR_ERR(vdd_l2.regulator[0]);
607 }
608
609 vdd_hfpll.regulator[0] = devm_regulator_get(dev, "hfpll-dig");
610 if (IS_ERR(vdd_hfpll.regulator[0])) {
611 dev_err(dev, "Unable to get hfpll-dig regulator!\n");
612 return PTR_ERR(vdd_hfpll.regulator[0]);
613 }
614
615 vdd_hfpll.regulator[1] = devm_regulator_get(dev, "hfpll-analog");
616 if (IS_ERR(vdd_hfpll.regulator[1])) {
617 dev_err(dev, "Unable to get hfpll-analog regulator!\n");
618 return PTR_ERR(vdd_hfpll.regulator[1]);
619 }
620
621 vdd_krait0.regulator[0] = devm_regulator_get(dev, "cpu0");
622 if (IS_ERR(vdd_krait0.regulator[0])) {
623 dev_err(dev, "Unable to get cpu0 regulator!\n");
624 return PTR_ERR(vdd_krait0.regulator[0]);
625 }
626
627 vdd_krait1.regulator[0] = devm_regulator_get(dev, "cpu1");
628 if (IS_ERR(vdd_krait1.regulator[0])) {
629 dev_err(dev, "Unable to get cpu1 regulator!\n");
630 return PTR_ERR(vdd_krait1.regulator[0]);
631 }
632
633 vdd_krait2.regulator[0] = devm_regulator_get(dev, "cpu2");
634 if (IS_ERR(vdd_krait2.regulator[0])) {
635 dev_err(dev, "Unable to get cpu2 regulator!\n");
636 return PTR_ERR(vdd_krait2.regulator[0]);
637 }
638
639 vdd_krait3.regulator[0] = devm_regulator_get(dev, "cpu3");
640 if (IS_ERR(vdd_krait3.regulator[0])) {
641 dev_err(dev, "Unable to get cpu3 regulator!\n");
642 return PTR_ERR(vdd_krait3.regulator[0]);
643 }
644
645 c = devm_clk_get(dev, "hfpll_src");
646 if (IS_ERR(c)) {
647 dev_err(dev, "Unable to get HFPLL source\n");
648 return PTR_ERR(c);
649 }
650 hfpll_src_clk.c.parent = c;
651
652 c = devm_clk_get(dev, "aux_clk");
653 if (IS_ERR(c)) {
654 dev_err(dev, "Unable to get AUX source\n");
655 return PTR_ERR(c);
656 }
657 acpu_aux_clk.c.parent = c;
658
659 if (hfpll_base_init(pdev, &hfpll0_clk))
660 return -EINVAL;
661 if (hfpll_base_init(pdev, &hfpll1_clk))
662 return -EINVAL;
663 if (hfpll_base_init(pdev, &hfpll2_clk))
664 return -EINVAL;
665 if (hfpll_base_init(pdev, &hfpll3_clk))
666 return -EINVAL;
667 if (hfpll_base_init(pdev, &hfpll_l2_clk))
668 return -EINVAL;
669
Vikram Mulukutla8e2750d2013-09-10 15:12:44 -0700670 ret = of_property_read_u32(dev->of_node, "qcom,hfpll-config-val",
671 &config_val);
672 if (!ret)
673 hdata.config_val = config_val;
674
675 ret = of_property_read_u32(dev->of_node, "qcom,hfpll-user-vco-mask",
676 &vco_mask);
677 if (!ret)
678 hdata.user_vco_mask = vco_mask;
679
Matt Wagantallc94c4702013-12-17 15:21:11 -0800680 ret = of_property_read_u32(dev->of_node, "qcom,pvs-config-ver",
681 &config_ver);
682 if (!ret) {
683 pvs_config_ver = config_ver;
684 dev_info(&pdev->dev, "PVS config version: %d\n", config_ver);
685 }
Saravana Kannanb60200c2012-10-09 23:44:10 -0700686
Matt Wagantallc94c4702013-12-17 15:21:11 -0800687 get_krait_bin_format_b(pdev, &speed, &pvs, &pvs_ver);
688 snprintf(table_name, ARRAY_SIZE(table_name),
689 "qcom,speed%d-pvs%d-bin-v%d", speed, pvs, pvs_ver);
690
691 rows = parse_tbl(dev, table_name, 3,
Saravana Kannanb60200c2012-10-09 23:44:10 -0700692 (u32 **) &freq, (u32 **) &uv, (u32 **) &ua);
693 if (rows < 0) {
Junjie Wu68948a82013-10-02 22:52:34 -0700694 /* Fall back to most conservative PVS table */
Matt Wagantallc94c4702013-12-17 15:21:11 -0800695 dev_err(dev, "Unable to load voltage plan %s!\n", table_name);
Junjie Wu68948a82013-10-02 22:52:34 -0700696 ret = parse_tbl(dev, "qcom,speed0-pvs0-bin-v0", 3,
697 (u32 **) &freq, (u32 **) &uv, (u32 **) &ua);
698 if (ret < 0) {
699 dev_err(dev, "Unable to load safe voltage plan\n");
700 return rows;
701 } else {
702 dev_info(dev, "Safe voltage plan loaded.\n");
703 pvs = 0;
704 rows = ret;
705 }
Saravana Kannanb60200c2012-10-09 23:44:10 -0700706 }
707
708 krait_update_uv(uv, rows, pvs ? 25000 : 0);
709
710 if (clk_init_vdd_class(dev, &krait0_clk.c, rows, freq, uv, ua))
711 return -ENOMEM;
712 if (clk_init_vdd_class(dev, &krait1_clk.c, rows, freq, uv, ua))
713 return -ENOMEM;
714 if (clk_init_vdd_class(dev, &krait2_clk.c, rows, freq, uv, ua))
715 return -ENOMEM;
716 if (clk_init_vdd_class(dev, &krait3_clk.c, rows, freq, uv, ua))
717 return -ENOMEM;
718
719 /* AVS is optional */
720 rows = parse_tbl(dev, "qcom,avs-tbl", 2, (u32 **) &freq, &dscr, NULL);
721 if (rows > 0) {
722 avs_table.rate = freq;
723 avs_table.dscr = dscr;
724 avs_table.num = rows;
725 }
726
727 rows = parse_tbl(dev, "qcom,l2-fmax", 2, (u32 **) &freq, (u32 **) &uv,
728 NULL);
729 if (rows < 0) {
730 dev_err(dev, "Unable to find L2 Fmax table!\n");
731 return rows;
732 }
733
734 if (clk_init_vdd_class(dev, &l2_clk.c, rows, freq, uv, NULL))
735 return -ENOMEM;
736
737 msm_clock_register(kpss_clocks_8974, ARRAY_SIZE(kpss_clocks_8974));
738
739 /*
740 * We don't want the CPU or L2 clocks to be turned off at late init
741 * if CPUFREQ or HOTPLUG configs are disabled. So, bump up the
742 * refcount of these clocks. Any cpufreq/hotplug manager can assume
743 * that the clocks have already been prepared and enabled by the time
744 * they take over.
745 */
Saravana Kannanb60200c2012-10-09 23:44:10 -0700746 for_each_online_cpu(cpu) {
Mahesh Sivasubramanian3f4487f2013-11-21 17:40:45 -0700747 clk_prepare_enable(&l2_clk.c);
Saravana Kannanb60200c2012-10-09 23:44:10 -0700748 WARN(clk_prepare_enable(cpu_clk[cpu]),
749 "Unable to turn on CPU%d clock", cpu);
750 }
751
752 /*
753 * Force reinit of HFPLLs and muxes to overwrite any potential
754 * incorrect configuration of HFPLLs and muxes by the bootloader.
755 * While at it, also make sure the cores are running at known rates
756 * and print the current rate.
757 *
758 * The clocks are set to aux clock rate first to make sure the
759 * secondary mux is not sourcing off of QSB. The rate is then set to
760 * two different rates to force a HFPLL reinit under all
761 * circumstances.
762 */
763 cur_rate = clk_get_rate(&l2_clk.c);
764 aux_rate = clk_get_rate(&acpu_aux_clk.c);
765 if (!cur_rate) {
766 pr_info("L2 @ unknown rate. Forcing new rate.\n");
767 cur_rate = aux_rate;
768 }
769 clk_set_rate(&l2_clk.c, aux_rate);
770 clk_set_rate(&l2_clk.c, clk_round_rate(&l2_clk.c, 1));
771 clk_set_rate(&l2_clk.c, cur_rate);
772 pr_info("L2 @ %lu KHz\n", clk_get_rate(&l2_clk.c) / 1000);
Saravana Kannand0adada2013-08-27 17:51:53 -0700773 for_each_possible_cpu(cpu) {
Saravana Kannanb60200c2012-10-09 23:44:10 -0700774 struct clk *c = cpu_clk[cpu];
775 cur_rate = clk_get_rate(c);
776 if (!cur_rate) {
777 pr_info("CPU%d @ unknown rate. Forcing new rate.\n",
778 cpu);
779 cur_rate = aux_rate;
780 }
781 clk_set_rate(c, aux_rate);
782 clk_set_rate(c, clk_round_rate(c, 1));
783 clk_set_rate(c, clk_round_rate(c, cur_rate));
784 pr_info("CPU%d @ %lu KHz\n", cpu, clk_get_rate(c) / 1000);
785 }
786
787 return 0;
788}
789
790static struct of_device_id match_table[] = {
791 { .compatible = "qcom,clock-krait-8974" },
792 {}
793};
794
795static struct platform_driver clock_krait_8974_driver = {
796 .probe = clock_krait_8974_driver_probe,
797 .driver = {
798 .name = "clock-krait-8974",
799 .of_match_table = match_table,
800 .owner = THIS_MODULE,
801 },
802};
803
804static int __init clock_krait_8974_init(void)
805{
806 return platform_driver_register(&clock_krait_8974_driver);
807}
808module_init(clock_krait_8974_init);
809
810static void __exit clock_krait_8974_exit(void)
811{
812 platform_driver_unregister(&clock_krait_8974_driver);
813}
814module_exit(clock_krait_8974_exit);
815
816MODULE_DESCRIPTION("Krait CPU clock driver for 8974");
817MODULE_LICENSE("GPL v2");