blob: cf4a8a5602303f37062d8ff6621ca3c7344bdcf8 [file] [log] [blame]
Vicky Wallacece2159e2016-12-27 15:58:35 -08001/*
2 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
Deepak Katragadda9abd7942017-06-13 14:20:09 -070014#define pr_fmt(fmt) "clk: %s: " fmt, __func__
15
Vicky Wallacece2159e2016-12-27 15:58:35 -080016#include <linux/kernel.h>
17#include <linux/bitops.h>
18#include <linux/err.h>
19#include <linux/platform_device.h>
20#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/of_device.h>
23#include <linux/clk-provider.h>
24#include <linux/regmap.h>
25#include <linux/reset-controller.h>
26#include <linux/clk.h>
27#include <linux/clk/qcom.h>
28#include <dt-bindings/clock/qcom,gpucc-sdm845.h>
29
30#include "common.h"
31#include "clk-regmap.h"
32#include "clk-pll.h"
33#include "clk-rcg.h"
34#include "clk-branch.h"
35#include "reset.h"
36#include "clk-alpha-pll.h"
37#include "vdd-level-sdm845.h"
38
Vicky Wallace8b61d162017-07-19 18:52:26 -070039#define CX_GMU_CBCR_SLEEP_MASK 0xF
40#define CX_GMU_CBCR_SLEEP_SHIFT 4
41#define CX_GMU_CBCR_WAKE_MASK 0xF
42#define CX_GMU_CBCR_WAKE_SHIFT 8
43
Vicky Wallacece2159e2016-12-27 15:58:35 -080044#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
Vicky Wallacece2159e2016-12-27 15:58:35 -080045
46static int vdd_gx_corner[] = {
47 RPMH_REGULATOR_LEVEL_OFF, /* VDD_GX_NONE */
48 RPMH_REGULATOR_LEVEL_MIN_SVS, /* VDD_GX_MIN */
49 RPMH_REGULATOR_LEVEL_LOW_SVS, /* VDD_GX_LOWER */
50 RPMH_REGULATOR_LEVEL_SVS, /* VDD_GX_LOW */
51 RPMH_REGULATOR_LEVEL_SVS_L1, /* VDD_GX_LOW_L1 */
52 RPMH_REGULATOR_LEVEL_NOM, /* VDD_GX_NOMINAL */
53 RPMH_REGULATOR_LEVEL_NOM_L1, /* VDD_GX_NOMINAL_L1 */
54 RPMH_REGULATOR_LEVEL_TURBO, /* VDD_GX_HIGH */
55 RPMH_REGULATOR_LEVEL_TURBO_L1, /* VDD_GX_HIGH_L1 */
56 RPMH_REGULATOR_LEVEL_MAX, /* VDD_GX_MAX */
57};
58
59static DEFINE_VDD_REGULATORS(vdd_cx, VDD_CX_NUM, 1, vdd_corner);
60static DEFINE_VDD_REGULATORS(vdd_mx, VDD_CX_NUM, 1, vdd_corner);
61static DEFINE_VDD_REGULATORS(vdd_gfx, VDD_GX_NUM, 1, vdd_gx_corner);
62
63enum {
64 P_BI_TCXO,
65 P_CORE_BI_PLL_TEST_SE,
66 P_GPLL0_OUT_MAIN,
67 P_GPLL0_OUT_MAIN_DIV,
68 P_GPU_CC_PLL0_OUT_EVEN,
69 P_GPU_CC_PLL0_OUT_MAIN,
70 P_GPU_CC_PLL0_OUT_ODD,
71 P_GPU_CC_PLL1_OUT_EVEN,
72 P_GPU_CC_PLL1_OUT_MAIN,
73 P_GPU_CC_PLL1_OUT_ODD,
Vicky Wallace60d41682017-06-05 19:34:56 -070074 P_CRC_DIV,
Vicky Wallacece2159e2016-12-27 15:58:35 -080075};
76
77static const struct parent_map gpu_cc_parent_map_0[] = {
78 { P_BI_TCXO, 0 },
79 { P_GPU_CC_PLL0_OUT_MAIN, 1 },
80 { P_GPU_CC_PLL1_OUT_MAIN, 3 },
81 { P_GPLL0_OUT_MAIN, 5 },
82 { P_GPLL0_OUT_MAIN_DIV, 6 },
83 { P_CORE_BI_PLL_TEST_SE, 7 },
84};
85
86static const char * const gpu_cc_parent_names_0[] = {
87 "bi_tcxo",
88 "gpu_cc_pll0",
89 "gpu_cc_pll1",
Deepak Katragaddad012b4d2017-04-10 12:03:37 -070090 "gcc_gpu_gpll0_clk_src",
91 "gcc_gpu_gpll0_div_clk_src",
Vicky Wallacece2159e2016-12-27 15:58:35 -080092 "core_bi_pll_test_se",
93};
94
95static const struct parent_map gpu_cc_parent_map_1[] = {
96 { P_BI_TCXO, 0 },
97 { P_GPU_CC_PLL0_OUT_EVEN, 1 },
98 { P_GPU_CC_PLL0_OUT_ODD, 2 },
99 { P_GPU_CC_PLL1_OUT_EVEN, 3 },
100 { P_GPU_CC_PLL1_OUT_ODD, 4 },
101 { P_GPLL0_OUT_MAIN, 5 },
102 { P_CORE_BI_PLL_TEST_SE, 7 },
103};
104
105static const char * const gpu_cc_parent_names_1[] = {
106 "bi_tcxo",
107 "gpu_cc_pll0_out_even",
108 "gpu_cc_pll0_out_odd",
109 "gpu_cc_pll1_out_even",
110 "gpu_cc_pll1_out_odd",
Deepak Katragaddad012b4d2017-04-10 12:03:37 -0700111 "gcc_gpu_gpll0_clk_src",
Vicky Wallacece2159e2016-12-27 15:58:35 -0800112 "core_bi_pll_test_se",
113};
114
Vicky Wallace60d41682017-06-05 19:34:56 -0700115static const struct parent_map gpu_cc_parent_map_2[] = {
116 { P_BI_TCXO, 0 },
117 { P_CRC_DIV, 1 },
118 { P_GPU_CC_PLL0_OUT_ODD, 2 },
119 { P_GPU_CC_PLL1_OUT_EVEN, 3 },
120 { P_GPU_CC_PLL1_OUT_ODD, 4 },
121 { P_GPLL0_OUT_MAIN, 5 },
122 { P_CORE_BI_PLL_TEST_SE, 7 },
123};
124
125static const char * const gpu_cc_parent_names_2[] = {
126 "bi_tcxo",
127 "crc_div",
128 "gpu_cc_pll0_out_odd",
129 "gpu_cc_pll1_out_even",
130 "gpu_cc_pll1_out_odd",
131 "gcc_gpu_gpll0_clk_src",
132 "core_bi_pll_test_se",
133};
134
Vicky Wallacece2159e2016-12-27 15:58:35 -0800135static struct pll_vco fabia_vco[] = {
Vicky Wallace60d41682017-06-05 19:34:56 -0700136 { 249600000, 2000000000, 0 },
Vicky Wallacece2159e2016-12-27 15:58:35 -0800137 { 125000000, 1000000000, 1 },
138};
139
140static const struct pll_config gpu_cc_pll0_config = {
141 .l = 0x1d,
142 .frac = 0x2aaa,
143};
144
Vicky Wallace442e2952017-07-12 18:46:26 -0700145static const struct pll_config gpu_cc_pll1_config = {
146 .l = 0x1a,
147 .frac = 0xaaaa,
148};
149
Vicky Wallacece2159e2016-12-27 15:58:35 -0800150static struct clk_alpha_pll gpu_cc_pll0 = {
151 .offset = 0x0,
152 .vco_table = fabia_vco,
153 .num_vco = ARRAY_SIZE(fabia_vco),
154 .type = FABIA_PLL,
155 .clkr = {
156 .hw.init = &(struct clk_init_data){
157 .name = "gpu_cc_pll0",
158 .parent_names = (const char *[]){ "bi_tcxo" },
159 .num_parents = 1,
160 .ops = &clk_fabia_pll_ops,
161 VDD_MX_FMAX_MAP4(
162 MIN, 615000000,
163 LOW, 1066000000,
164 LOW_L1, 1600000000,
165 NOMINAL, 2000000000),
166 },
167 },
168};
169
170static const struct clk_div_table post_div_table_fabia_even[] = {
171 { 0x0, 1 },
172 { 0x1, 2 },
173 { 0x3, 4 },
174 { 0x7, 8 },
175 {},
176};
177
178static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = {
179 .offset = 0x0,
180 .post_div_shift = 8,
181 .post_div_table = post_div_table_fabia_even,
182 .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
183 .width = 4,
184 .clkr.hw.init = &(struct clk_init_data){
185 .name = "gpu_cc_pll0_out_even",
186 .parent_names = (const char *[]){ "gpu_cc_pll0" },
187 .num_parents = 1,
188 .flags = CLK_SET_RATE_PARENT,
189 .ops = &clk_generic_pll_postdiv_ops,
190 },
191};
192
Vicky Wallace442e2952017-07-12 18:46:26 -0700193static struct clk_alpha_pll gpu_cc_pll1 = {
194 .offset = 0x100,
195 .vco_table = fabia_vco,
196 .num_vco = ARRAY_SIZE(fabia_vco),
197 .type = FABIA_PLL,
198 .clkr = {
199 .hw.init = &(struct clk_init_data){
200 .name = "gpu_cc_pll1",
201 .parent_names = (const char *[]){ "bi_tcxo" },
202 .num_parents = 1,
203 .ops = &clk_fabia_pll_ops,
204 VDD_MX_FMAX_MAP4(
205 MIN, 615000000,
206 LOW, 1066000000,
207 LOW_L1, 1600000000,
208 NOMINAL, 2000000000),
209 },
210 },
211};
212
Vicky Wallacece2159e2016-12-27 15:58:35 -0800213static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
214 F(19200000, P_BI_TCXO, 1, 0, 0),
215 F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
216 F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0),
217 { }
218};
219
Vicky Wallace442e2952017-07-12 18:46:26 -0700220static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src_sdm845_v2[] = {
221 F(19200000, P_BI_TCXO, 1, 0, 0),
222 F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
223 F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
224 { }
225};
226
Vicky Wallacece2159e2016-12-27 15:58:35 -0800227static struct clk_rcg2 gpu_cc_gmu_clk_src = {
228 .cmd_rcgr = 0x1120,
229 .mnd_width = 0,
230 .hid_width = 5,
231 .enable_safe_config = true,
232 .parent_map = gpu_cc_parent_map_0,
233 .freq_tbl = ftbl_gpu_cc_gmu_clk_src,
234 .clkr.hw.init = &(struct clk_init_data){
235 .name = "gpu_cc_gmu_clk_src",
236 .parent_names = gpu_cc_parent_names_0,
237 .num_parents = 6,
238 .flags = CLK_SET_RATE_PARENT,
239 .ops = &clk_rcg2_ops,
240 VDD_CX_FMAX_MAP2(
241 MIN, 200000000,
242 LOW, 400000000),
243 },
244};
245
Vicky Wallace60d41682017-06-05 19:34:56 -0700246static struct clk_fixed_factor crc_div = {
247 .mult = 1,
248 .div = 1,
249 .hw.init = &(struct clk_init_data){
250 .name = "crc_div",
251 .parent_names = (const char *[]){ "gpu_cc_pll0_out_even" },
252 .num_parents = 1,
253 .flags = CLK_SET_RATE_PARENT,
254 .ops = &clk_fixed_factor_ops,
255 },
256};
257
Vicky Wallacece2159e2016-12-27 15:58:35 -0800258static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = {
Vicky Wallace60d41682017-06-05 19:34:56 -0700259 F(147000000, P_CRC_DIV, 1, 0, 0),
260 F(210000000, P_CRC_DIV, 1, 0, 0),
261 F(280000000, P_CRC_DIV, 1, 0, 0),
262 F(338000000, P_CRC_DIV, 1, 0, 0),
263 F(425000000, P_CRC_DIV, 1, 0, 0),
264 F(487000000, P_CRC_DIV, 1, 0, 0),
265 F(548000000, P_CRC_DIV, 1, 0, 0),
266 F(600000000, P_CRC_DIV, 1, 0, 0),
Vicky Wallacece2159e2016-12-27 15:58:35 -0800267 { }
268};
269
Vicky Wallace442e2952017-07-12 18:46:26 -0700270static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src_sdm845_v2[] = {
271 F(180000000, P_CRC_DIV, 1, 0, 0),
272 F(257000000, P_CRC_DIV, 1, 0, 0),
273 F(342000000, P_CRC_DIV, 1, 0, 0),
274 F(414000000, P_CRC_DIV, 1, 0, 0),
275 F(520000000, P_CRC_DIV, 1, 0, 0),
276 F(596000000, P_CRC_DIV, 1, 0, 0),
Vicky Wallace799871c2017-08-09 16:39:09 -0700277 F(675000000, P_CRC_DIV, 1, 0, 0),
Vicky Wallace442e2952017-07-12 18:46:26 -0700278 F(710000000, P_CRC_DIV, 1, 0, 0),
279 { }
280};
281
Vicky Wallacece2159e2016-12-27 15:58:35 -0800282static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = {
283 .cmd_rcgr = 0x101c,
284 .mnd_width = 0,
285 .hid_width = 5,
Vicky Wallace60d41682017-06-05 19:34:56 -0700286 .parent_map = gpu_cc_parent_map_2,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800287 .freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src,
Deepak Katragadda6c7e8e12017-04-05 13:21:16 -0700288 .flags = FORCE_ENABLE_RCG,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800289 .clkr.hw.init = &(struct clk_init_data){
290 .name = "gpu_cc_gx_gfx3d_clk_src",
Vicky Wallace60d41682017-06-05 19:34:56 -0700291 .parent_names = gpu_cc_parent_names_2,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800292 .num_parents = 7,
293 .flags = CLK_SET_RATE_PARENT,
294 .ops = &clk_rcg2_ops,
295 VDD_GX_FMAX_MAP8(
296 MIN, 147000000,
297 LOWER, 210000000,
298 LOW, 280000000,
299 LOW_L1, 338000000,
300 NOMINAL, 425000000,
301 NOMINAL_L1, 487000000,
302 HIGH, 548000000,
303 HIGH_L1, 600000000),
304 },
305};
306
Vicky Wallacece2159e2016-12-27 15:58:35 -0800307static struct clk_branch gpu_cc_acd_ahb_clk = {
308 .halt_reg = 0x1168,
309 .halt_check = BRANCH_HALT,
310 .clkr = {
311 .enable_reg = 0x1168,
312 .enable_mask = BIT(0),
313 .hw.init = &(struct clk_init_data){
314 .name = "gpu_cc_acd_ahb_clk",
315 .ops = &clk_branch2_ops,
316 },
317 },
318};
319
320static struct clk_branch gpu_cc_acd_cxo_clk = {
321 .halt_reg = 0x1164,
322 .halt_check = BRANCH_HALT,
323 .clkr = {
324 .enable_reg = 0x1164,
325 .enable_mask = BIT(0),
326 .hw.init = &(struct clk_init_data){
327 .name = "gpu_cc_acd_cxo_clk",
328 .ops = &clk_branch2_ops,
329 },
330 },
331};
332
333static struct clk_branch gpu_cc_ahb_clk = {
334 .halt_reg = 0x1078,
335 .halt_check = BRANCH_HALT,
336 .clkr = {
337 .enable_reg = 0x1078,
338 .enable_mask = BIT(0),
339 .hw.init = &(struct clk_init_data){
340 .name = "gpu_cc_ahb_clk",
341 .ops = &clk_branch2_ops,
342 },
343 },
344};
345
346static struct clk_branch gpu_cc_crc_ahb_clk = {
347 .halt_reg = 0x107c,
348 .halt_check = BRANCH_HALT,
349 .clkr = {
350 .enable_reg = 0x107c,
351 .enable_mask = BIT(0),
352 .hw.init = &(struct clk_init_data){
353 .name = "gpu_cc_crc_ahb_clk",
354 .ops = &clk_branch2_ops,
355 },
356 },
357};
358
359static struct clk_branch gpu_cc_cx_apb_clk = {
360 .halt_reg = 0x1088,
361 .halt_check = BRANCH_HALT,
362 .clkr = {
363 .enable_reg = 0x1088,
364 .enable_mask = BIT(0),
365 .hw.init = &(struct clk_init_data){
366 .name = "gpu_cc_cx_apb_clk",
367 .ops = &clk_branch2_ops,
368 },
369 },
370};
371
372static struct clk_branch gpu_cc_cx_gfx3d_clk = {
373 .halt_reg = 0x10a4,
374 .halt_check = BRANCH_HALT,
375 .clkr = {
376 .enable_reg = 0x10a4,
377 .enable_mask = BIT(0),
378 .hw.init = &(struct clk_init_data){
379 .name = "gpu_cc_cx_gfx3d_clk",
380 .parent_names = (const char *[]){
381 "gpu_cc_gx_gfx3d_clk_src",
382 },
383 .num_parents = 1,
384 .flags = CLK_SET_RATE_PARENT,
385 .ops = &clk_branch2_ops,
386 },
387 },
388};
389
390static struct clk_branch gpu_cc_cx_gfx3d_slv_clk = {
391 .halt_reg = 0x10a8,
392 .halt_check = BRANCH_HALT,
393 .clkr = {
394 .enable_reg = 0x10a8,
395 .enable_mask = BIT(0),
396 .hw.init = &(struct clk_init_data){
397 .name = "gpu_cc_cx_gfx3d_slv_clk",
398 .parent_names = (const char *[]){
399 "gpu_cc_gx_gfx3d_clk_src",
400 },
401 .num_parents = 1,
402 .flags = CLK_SET_RATE_PARENT,
403 .ops = &clk_branch2_ops,
404 },
405 },
406};
407
408static struct clk_branch gpu_cc_cx_gmu_clk = {
409 .halt_reg = 0x1098,
410 .halt_check = BRANCH_HALT,
411 .clkr = {
412 .enable_reg = 0x1098,
413 .enable_mask = BIT(0),
414 .hw.init = &(struct clk_init_data){
415 .name = "gpu_cc_cx_gmu_clk",
416 .parent_names = (const char *[]){
417 "gpu_cc_gmu_clk_src",
418 },
419 .num_parents = 1,
420 .flags = CLK_SET_RATE_PARENT,
421 .ops = &clk_branch2_ops,
422 },
423 },
424};
425
426static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
427 .halt_reg = 0x108c,
428 .halt_check = BRANCH_HALT,
429 .clkr = {
430 .enable_reg = 0x108c,
431 .enable_mask = BIT(0),
432 .hw.init = &(struct clk_init_data){
433 .name = "gpu_cc_cx_snoc_dvm_clk",
434 .ops = &clk_branch2_ops,
435 },
436 },
437};
438
439static struct clk_branch gpu_cc_cxo_aon_clk = {
440 .halt_reg = 0x1004,
441 .halt_check = BRANCH_HALT,
442 .clkr = {
443 .enable_reg = 0x1004,
444 .enable_mask = BIT(0),
445 .hw.init = &(struct clk_init_data){
446 .name = "gpu_cc_cxo_aon_clk",
447 .ops = &clk_branch2_ops,
448 },
449 },
450};
451
452static struct clk_branch gpu_cc_cxo_clk = {
453 .halt_reg = 0x109c,
454 .halt_check = BRANCH_HALT,
455 .clkr = {
456 .enable_reg = 0x109c,
457 .enable_mask = BIT(0),
458 .hw.init = &(struct clk_init_data){
459 .name = "gpu_cc_cxo_clk",
460 .ops = &clk_branch2_ops,
461 },
462 },
463};
464
Vicky Wallacece2159e2016-12-27 15:58:35 -0800465static struct clk_branch gpu_cc_gx_gfx3d_clk = {
466 .halt_reg = 0x1054,
467 .halt_check = BRANCH_HALT,
468 .clkr = {
469 .enable_reg = 0x1054,
470 .enable_mask = BIT(0),
471 .hw.init = &(struct clk_init_data){
472 .name = "gpu_cc_gx_gfx3d_clk",
473 .parent_names = (const char *[]){
474 "gpu_cc_gx_gfx3d_clk_src",
475 },
476 .num_parents = 1,
477 .flags = CLK_SET_RATE_PARENT,
478 .ops = &clk_branch2_ops,
479 },
480 },
481};
482
483static struct clk_branch gpu_cc_gx_gmu_clk = {
484 .halt_reg = 0x1064,
485 .halt_check = BRANCH_HALT,
486 .clkr = {
487 .enable_reg = 0x1064,
488 .enable_mask = BIT(0),
489 .hw.init = &(struct clk_init_data){
490 .name = "gpu_cc_gx_gmu_clk",
491 .parent_names = (const char *[]){
492 "gpu_cc_gmu_clk_src",
493 },
494 .num_parents = 1,
495 .flags = CLK_SET_RATE_PARENT,
496 .ops = &clk_branch2_ops,
497 },
498 },
499};
500
501static struct clk_branch gpu_cc_gx_vsense_clk = {
502 .halt_reg = 0x1058,
503 .halt_check = BRANCH_HALT,
504 .clkr = {
505 .enable_reg = 0x1058,
506 .enable_mask = BIT(0),
507 .hw.init = &(struct clk_init_data){
508 .name = "gpu_cc_gx_vsense_clk",
509 .ops = &clk_branch2_ops,
510 },
511 },
512};
513
514static struct clk_branch gpu_cc_pll_test_clk = {
515 .halt_reg = 0x110c,
516 .halt_check = BRANCH_HALT,
517 .clkr = {
518 .enable_reg = 0x110c,
519 .enable_mask = BIT(0),
520 .hw.init = &(struct clk_init_data){
521 .name = "gpu_cc_pll_test_clk",
522 .ops = &clk_branch2_ops,
523 },
524 },
525};
526
Vicky Wallacece2159e2016-12-27 15:58:35 -0800527static struct clk_regmap *gpu_cc_sdm845_clocks[] = {
528 [GPU_CC_ACD_AHB_CLK] = &gpu_cc_acd_ahb_clk.clkr,
529 [GPU_CC_ACD_CXO_CLK] = &gpu_cc_acd_cxo_clk.clkr,
530 [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
531 [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
532 [GPU_CC_CX_APB_CLK] = &gpu_cc_cx_apb_clk.clkr,
533 [GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr,
534 [GPU_CC_CX_GFX3D_SLV_CLK] = &gpu_cc_cx_gfx3d_slv_clk.clkr,
535 [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
536 [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
537 [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
538 [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800539 [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800540 [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
541 [GPU_CC_GX_VSENSE_CLK] = &gpu_cc_gx_vsense_clk.clkr,
542 [GPU_CC_PLL_TEST_CLK] = &gpu_cc_pll_test_clk.clkr,
Vicky Wallaced1401ac2017-08-07 18:34:28 -0700543 [GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
544 [GPU_CC_PLL1] = NULL,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800545};
546
547static struct clk_regmap *gpu_cc_gfx_sdm845_clocks[] = {
Vicky Wallacece2159e2016-12-27 15:58:35 -0800548 [GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr,
549 [GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr,
550 [GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr,
551};
552
553static const struct qcom_reset_map gpu_cc_sdm845_resets[] = {
554 [GPUCC_GPU_CC_ACD_BCR] = { 0x1160 },
555 [GPUCC_GPU_CC_CX_BCR] = { 0x1068 },
556 [GPUCC_GPU_CC_GFX3D_AON_BCR] = { 0x10a0 },
557 [GPUCC_GPU_CC_GMU_BCR] = { 0x111c },
558 [GPUCC_GPU_CC_GX_BCR] = { 0x1008 },
Vicky Wallacece2159e2016-12-27 15:58:35 -0800559 [GPUCC_GPU_CC_SPDM_BCR] = { 0x1110 },
560 [GPUCC_GPU_CC_XO_BCR] = { 0x1000 },
561};
562
563static const struct regmap_config gpu_cc_sdm845_regmap_config = {
564 .reg_bits = 32,
565 .reg_stride = 4,
566 .val_bits = 32,
567 .max_register = 0x8008,
568 .fast_io = true,
569};
570
571static const struct qcom_cc_desc gpu_cc_sdm845_desc = {
572 .config = &gpu_cc_sdm845_regmap_config,
573 .clks = gpu_cc_sdm845_clocks,
574 .num_clks = ARRAY_SIZE(gpu_cc_sdm845_clocks),
575 .resets = gpu_cc_sdm845_resets,
576 .num_resets = ARRAY_SIZE(gpu_cc_sdm845_resets),
577};
578
579static const struct qcom_cc_desc gpu_cc_gfx_sdm845_desc = {
580 .config = &gpu_cc_sdm845_regmap_config,
581 .clks = gpu_cc_gfx_sdm845_clocks,
582 .num_clks = ARRAY_SIZE(gpu_cc_gfx_sdm845_clocks),
583};
584
585static const struct of_device_id gpu_cc_sdm845_match_table[] = {
586 { .compatible = "qcom,gpucc-sdm845" },
Vicky Wallace442e2952017-07-12 18:46:26 -0700587 { .compatible = "qcom,gpucc-sdm845-v2" },
Vicky Wallacece2159e2016-12-27 15:58:35 -0800588 { }
589};
590MODULE_DEVICE_TABLE(of, gpu_cc_sdm845_match_table);
591
592static const struct of_device_id gpu_cc_gfx_sdm845_match_table[] = {
593 { .compatible = "qcom,gfxcc-sdm845" },
Vicky Wallace442e2952017-07-12 18:46:26 -0700594 { .compatible = "qcom,gfxcc-sdm845-v2" },
Vicky Wallacece2159e2016-12-27 15:58:35 -0800595 {},
596};
597MODULE_DEVICE_TABLE(of, gpu_cc_gfx_sdm845_match_table);
598
Vicky Wallace442e2952017-07-12 18:46:26 -0700599static void gpu_cc_sdm845_fixup_sdm845v2(struct regmap *regmap)
600{
Vicky Wallace442e2952017-07-12 18:46:26 -0700601 gpu_cc_sdm845_clocks[GPU_CC_PLL1] = &gpu_cc_pll1.clkr;
Vicky Wallaced1401ac2017-08-07 18:34:28 -0700602 clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
603
Vicky Wallace442e2952017-07-12 18:46:26 -0700604 gpu_cc_gmu_clk_src.freq_tbl = ftbl_gpu_cc_gmu_clk_src_sdm845_v2;
605 gpu_cc_gmu_clk_src.clkr.hw.init->rate_max[VDD_CX_LOW] = 500000000;
606}
607
608static void gpu_cc_gfx_sdm845_fixup_sdm845v2(void)
609{
610 gpu_cc_gx_gfx3d_clk_src.freq_tbl =
611 ftbl_gpu_cc_gx_gfx3d_clk_src_sdm845_v2;
612 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_MIN] = 180000000;
613 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_LOWER] =
614 257000000;
615 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_LOW] = 342000000;
616 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_LOW_L1] =
617 414000000;
618 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_NOMINAL] =
619 520000000;
620 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_NOMINAL_L1] =
621 596000000;
622 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_HIGH] = 675000000;
623 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_HIGH_L1] =
624 710000000;
625}
626
627static int gpu_cc_gfx_sdm845_fixup(struct platform_device *pdev)
628{
629 const char *compat = NULL;
630 int compatlen = 0;
631
632 compat = of_get_property(pdev->dev.of_node, "compatible", &compatlen);
633 if (!compat || (compatlen <= 0))
634 return -EINVAL;
635
636 if (!strcmp(compat, "qcom,gfxcc-sdm845-v2"))
637 gpu_cc_gfx_sdm845_fixup_sdm845v2();
638
639 return 0;
640}
641
642static int gpu_cc_sdm845_fixup(struct platform_device *pdev,
643 struct regmap *regmap)
644{
645 const char *compat = NULL;
646 int compatlen = 0;
647
648 compat = of_get_property(pdev->dev.of_node, "compatible", &compatlen);
649 if (!compat || (compatlen <= 0))
650 return -EINVAL;
651
652 if (!strcmp(compat, "qcom,gpucc-sdm845-v2"))
653 gpu_cc_sdm845_fixup_sdm845v2(regmap);
654
655 return 0;
656}
657
Vicky Wallacece2159e2016-12-27 15:58:35 -0800658static int gpu_cc_gfx_sdm845_probe(struct platform_device *pdev)
659{
660 struct regmap *regmap;
661 struct resource *res;
662 void __iomem *base;
663 int ret = 0;
664
665 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
666 if (res == NULL) {
Vicky Wallace60d41682017-06-05 19:34:56 -0700667 dev_err(&pdev->dev, "Failed to get resources for clock_gfxcc\n");
Vicky Wallacece2159e2016-12-27 15:58:35 -0800668 return -EINVAL;
669 }
670
671 base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
672 if (IS_ERR(base)) {
Vicky Wallace60d41682017-06-05 19:34:56 -0700673 dev_err(&pdev->dev, "Failed to ioremap the GFX CC base\n");
Vicky Wallacece2159e2016-12-27 15:58:35 -0800674 return PTR_ERR(base);
675 }
676
Vicky Wallace60d41682017-06-05 19:34:56 -0700677 /* Register clock fixed factor for CRC divide. */
678 ret = devm_clk_hw_register(&pdev->dev, &crc_div.hw);
679 if (ret) {
680 dev_err(&pdev->dev, "Failed to register hardware clock\n");
681 return ret;
682 }
683
Vicky Wallacece2159e2016-12-27 15:58:35 -0800684 regmap = devm_regmap_init_mmio(&pdev->dev, base,
685 gpu_cc_gfx_sdm845_desc.config);
686 if (IS_ERR(regmap)) {
687 dev_err(&pdev->dev, "Failed to init regmap\n");
688 return PTR_ERR(regmap);
689 }
690
Vicky Wallacece2159e2016-12-27 15:58:35 -0800691 /* GFX voltage regulators for GFX3D graphic clock. */
692 vdd_gfx.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_gfx");
693 if (IS_ERR(vdd_gfx.regulator[0])) {
694 if (PTR_ERR(vdd_gfx.regulator[0]) != -EPROBE_DEFER)
695 dev_err(&pdev->dev, "Unable to get vdd_gfx regulator\n");
696 return PTR_ERR(vdd_gfx.regulator[0]);
697 }
698
Deepak Katragadda21afc872017-05-30 14:05:59 -0700699 /* Avoid turning on the rail during clock registration */
700 vdd_gfx.skip_handoff = true;
701
Vicky Wallace442e2952017-07-12 18:46:26 -0700702 ret = gpu_cc_gfx_sdm845_fixup(pdev);
703 if (ret) {
704 dev_err(&pdev->dev, "Failed to do GFX clock fixup\n");
705 return ret;
706 }
707
Vicky Wallacece2159e2016-12-27 15:58:35 -0800708 clk_fabia_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
709
710 ret = qcom_cc_really_probe(pdev, &gpu_cc_gfx_sdm845_desc, regmap);
711 if (ret) {
712 dev_err(&pdev->dev, "Failed to register GFX CC clocks\n");
713 return ret;
714 }
715
Vicky Wallace60d41682017-06-05 19:34:56 -0700716 dev_info(&pdev->dev, "Registered GFX CC clocks\n");
Vicky Wallacece2159e2016-12-27 15:58:35 -0800717
718 return ret;
719}
720
721static struct platform_driver gpu_cc_gfx_sdm845_driver = {
722 .probe = gpu_cc_gfx_sdm845_probe,
723 .driver = {
724 .name = "gfxcc-sdm845",
725 .of_match_table = gpu_cc_gfx_sdm845_match_table,
726 },
727};
728
729static int __init gpu_cc_gfx_sdm845_init(void)
730{
731 return platform_driver_register(&gpu_cc_gfx_sdm845_driver);
732}
Deepak Katragaddaef44e102017-06-21 10:30:46 -0700733subsys_initcall(gpu_cc_gfx_sdm845_init);
Vicky Wallacece2159e2016-12-27 15:58:35 -0800734
735static void __exit gpu_cc_gfx_sdm845_exit(void)
736{
737 platform_driver_unregister(&gpu_cc_gfx_sdm845_driver);
738}
739module_exit(gpu_cc_gfx_sdm845_exit);
740
741static int gpu_cc_sdm845_probe(struct platform_device *pdev)
742{
743 struct regmap *regmap;
744 int ret = 0;
Vicky Wallace8b61d162017-07-19 18:52:26 -0700745 unsigned int value, mask;
Vicky Wallacece2159e2016-12-27 15:58:35 -0800746
747 regmap = qcom_cc_map(pdev, &gpu_cc_sdm845_desc);
748 if (IS_ERR(regmap))
749 return PTR_ERR(regmap);
750
751 /* Get CX voltage regulator for CX and GMU clocks. */
752 vdd_cx.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_cx");
753 if (IS_ERR(vdd_cx.regulator[0])) {
754 if (!(PTR_ERR(vdd_cx.regulator[0]) == -EPROBE_DEFER))
755 dev_err(&pdev->dev,
756 "Unable to get vdd_cx regulator\n");
757 return PTR_ERR(vdd_cx.regulator[0]);
758 }
759
Vicky Wallaced1401ac2017-08-07 18:34:28 -0700760 /* Get MX voltage regulator for GPU PLL graphic clock. */
761 vdd_mx.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_mx");
762 if (IS_ERR(vdd_mx.regulator[0])) {
763 if (!(PTR_ERR(vdd_mx.regulator[0]) == -EPROBE_DEFER))
764 dev_err(&pdev->dev,
765 "Unable to get vdd_mx regulator\n");
766 return PTR_ERR(vdd_mx.regulator[0]);
767 }
768
Vicky Wallace442e2952017-07-12 18:46:26 -0700769 ret = gpu_cc_sdm845_fixup(pdev, regmap);
770 if (ret) {
771 dev_err(&pdev->dev, "Failed to do GPU CC clock fixup\n");
772 return ret;
773 }
774
Vicky Wallacece2159e2016-12-27 15:58:35 -0800775 ret = qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap);
776 if (ret) {
777 dev_err(&pdev->dev, "Failed to register GPU CC clocks\n");
778 return ret;
779 }
780
Vicky Wallace8b61d162017-07-19 18:52:26 -0700781 mask = CX_GMU_CBCR_WAKE_MASK << CX_GMU_CBCR_WAKE_SHIFT;
782 mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT;
783 value = 0xF << CX_GMU_CBCR_WAKE_SHIFT | 0xF << CX_GMU_CBCR_SLEEP_SHIFT;
784 regmap_update_bits(regmap, gpu_cc_cx_gmu_clk.clkr.enable_reg,
785 mask, value);
786
Vicky Wallace60d41682017-06-05 19:34:56 -0700787 dev_info(&pdev->dev, "Registered GPU CC clocks\n");
Vicky Wallacece2159e2016-12-27 15:58:35 -0800788
789 return ret;
790}
791
792static struct platform_driver gpu_cc_sdm845_driver = {
793 .probe = gpu_cc_sdm845_probe,
794 .driver = {
795 .name = "gpu_cc-sdm845",
796 .of_match_table = gpu_cc_sdm845_match_table,
797 },
798};
799
800static int __init gpu_cc_sdm845_init(void)
801{
802 return platform_driver_register(&gpu_cc_sdm845_driver);
803}
Deepak Katragaddaef44e102017-06-21 10:30:46 -0700804subsys_initcall(gpu_cc_sdm845_init);
Vicky Wallacece2159e2016-12-27 15:58:35 -0800805
806static void __exit gpu_cc_sdm845_exit(void)
807{
808 platform_driver_unregister(&gpu_cc_sdm845_driver);
809}
810module_exit(gpu_cc_sdm845_exit);
811
812MODULE_DESCRIPTION("QTI GPU_CC SDM845 Driver");
813MODULE_LICENSE("GPL v2");
814MODULE_ALIAS("platform:gpu_cc-sdm845");