blob: 0115bb1d73457e367005a9a1b6fc45abe4db9889 [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
14#include <linux/kernel.h>
15#include <linux/bitops.h>
16#include <linux/err.h>
17#include <linux/platform_device.h>
18#include <linux/module.h>
19#include <linux/of.h>
20#include <linux/of_device.h>
21#include <linux/clk-provider.h>
22#include <linux/regmap.h>
23#include <linux/reset-controller.h>
24#include <linux/clk.h>
25#include <linux/clk/qcom.h>
26#include <dt-bindings/clock/qcom,gpucc-sdm845.h>
27
28#include "common.h"
29#include "clk-regmap.h"
30#include "clk-pll.h"
31#include "clk-rcg.h"
32#include "clk-branch.h"
33#include "reset.h"
34#include "clk-alpha-pll.h"
35#include "vdd-level-sdm845.h"
36
37#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
38#define F_SLEW(f, s, h, m, n, sf) { (f), (s), (2 * (h) - 1), (m), (n), (sf) }
39
40static int vdd_gx_corner[] = {
41 RPMH_REGULATOR_LEVEL_OFF, /* VDD_GX_NONE */
42 RPMH_REGULATOR_LEVEL_MIN_SVS, /* VDD_GX_MIN */
43 RPMH_REGULATOR_LEVEL_LOW_SVS, /* VDD_GX_LOWER */
44 RPMH_REGULATOR_LEVEL_SVS, /* VDD_GX_LOW */
45 RPMH_REGULATOR_LEVEL_SVS_L1, /* VDD_GX_LOW_L1 */
46 RPMH_REGULATOR_LEVEL_NOM, /* VDD_GX_NOMINAL */
47 RPMH_REGULATOR_LEVEL_NOM_L1, /* VDD_GX_NOMINAL_L1 */
48 RPMH_REGULATOR_LEVEL_TURBO, /* VDD_GX_HIGH */
49 RPMH_REGULATOR_LEVEL_TURBO_L1, /* VDD_GX_HIGH_L1 */
50 RPMH_REGULATOR_LEVEL_MAX, /* VDD_GX_MAX */
51};
52
53static DEFINE_VDD_REGULATORS(vdd_cx, VDD_CX_NUM, 1, vdd_corner);
54static DEFINE_VDD_REGULATORS(vdd_mx, VDD_CX_NUM, 1, vdd_corner);
55static DEFINE_VDD_REGULATORS(vdd_gfx, VDD_GX_NUM, 1, vdd_gx_corner);
56
57enum {
58 P_BI_TCXO,
59 P_CORE_BI_PLL_TEST_SE,
60 P_GPLL0_OUT_MAIN,
61 P_GPLL0_OUT_MAIN_DIV,
62 P_GPU_CC_PLL0_OUT_EVEN,
63 P_GPU_CC_PLL0_OUT_MAIN,
64 P_GPU_CC_PLL0_OUT_ODD,
65 P_GPU_CC_PLL1_OUT_EVEN,
66 P_GPU_CC_PLL1_OUT_MAIN,
67 P_GPU_CC_PLL1_OUT_ODD,
68};
69
70static const struct parent_map gpu_cc_parent_map_0[] = {
71 { P_BI_TCXO, 0 },
72 { P_GPU_CC_PLL0_OUT_MAIN, 1 },
73 { P_GPU_CC_PLL1_OUT_MAIN, 3 },
74 { P_GPLL0_OUT_MAIN, 5 },
75 { P_GPLL0_OUT_MAIN_DIV, 6 },
76 { P_CORE_BI_PLL_TEST_SE, 7 },
77};
78
79static const char * const gpu_cc_parent_names_0[] = {
80 "bi_tcxo",
81 "gpu_cc_pll0",
82 "gpu_cc_pll1",
Deepak Katragaddad012b4d2017-04-10 12:03:37 -070083 "gcc_gpu_gpll0_clk_src",
84 "gcc_gpu_gpll0_div_clk_src",
Vicky Wallacece2159e2016-12-27 15:58:35 -080085 "core_bi_pll_test_se",
86};
87
88static const struct parent_map gpu_cc_parent_map_1[] = {
89 { P_BI_TCXO, 0 },
90 { P_GPU_CC_PLL0_OUT_EVEN, 1 },
91 { P_GPU_CC_PLL0_OUT_ODD, 2 },
92 { P_GPU_CC_PLL1_OUT_EVEN, 3 },
93 { P_GPU_CC_PLL1_OUT_ODD, 4 },
94 { P_GPLL0_OUT_MAIN, 5 },
95 { P_CORE_BI_PLL_TEST_SE, 7 },
96};
97
98static const char * const gpu_cc_parent_names_1[] = {
99 "bi_tcxo",
100 "gpu_cc_pll0_out_even",
101 "gpu_cc_pll0_out_odd",
102 "gpu_cc_pll1_out_even",
103 "gpu_cc_pll1_out_odd",
Deepak Katragaddad012b4d2017-04-10 12:03:37 -0700104 "gcc_gpu_gpll0_clk_src",
Vicky Wallacece2159e2016-12-27 15:58:35 -0800105 "core_bi_pll_test_se",
106};
107
108static const struct parent_map gpu_cc_parent_map_2[] = {
109 { P_BI_TCXO, 0 },
110 { P_GPLL0_OUT_MAIN, 5 },
111 { P_GPLL0_OUT_MAIN_DIV, 6 },
112 { P_CORE_BI_PLL_TEST_SE, 7 },
113};
114
115static const char * const gpu_cc_parent_names_2[] = {
116 "bi_tcxo",
Deepak Katragaddad012b4d2017-04-10 12:03:37 -0700117 "gcc_gpu_gpll0_clk_src",
118 "gcc_gpu_gpll0_div_clk_src",
Vicky Wallacece2159e2016-12-27 15:58:35 -0800119 "core_bi_pll_test_se",
120};
121
122static struct pll_vco fabia_vco[] = {
123 { 250000000, 2000000000, 0 },
124 { 125000000, 1000000000, 1 },
125};
126
127static const struct pll_config gpu_cc_pll0_config = {
128 .l = 0x1d,
129 .frac = 0x2aaa,
130};
131
132static struct clk_alpha_pll gpu_cc_pll0 = {
133 .offset = 0x0,
134 .vco_table = fabia_vco,
135 .num_vco = ARRAY_SIZE(fabia_vco),
136 .type = FABIA_PLL,
137 .clkr = {
138 .hw.init = &(struct clk_init_data){
139 .name = "gpu_cc_pll0",
140 .parent_names = (const char *[]){ "bi_tcxo" },
141 .num_parents = 1,
142 .ops = &clk_fabia_pll_ops,
143 VDD_MX_FMAX_MAP4(
144 MIN, 615000000,
145 LOW, 1066000000,
146 LOW_L1, 1600000000,
147 NOMINAL, 2000000000),
148 },
149 },
150};
151
152static const struct clk_div_table post_div_table_fabia_even[] = {
153 { 0x0, 1 },
154 { 0x1, 2 },
155 { 0x3, 4 },
156 { 0x7, 8 },
157 {},
158};
159
160static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = {
161 .offset = 0x0,
162 .post_div_shift = 8,
163 .post_div_table = post_div_table_fabia_even,
164 .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
165 .width = 4,
166 .clkr.hw.init = &(struct clk_init_data){
167 .name = "gpu_cc_pll0_out_even",
168 .parent_names = (const char *[]){ "gpu_cc_pll0" },
169 .num_parents = 1,
170 .flags = CLK_SET_RATE_PARENT,
171 .ops = &clk_generic_pll_postdiv_ops,
172 },
173};
174
175static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
176 F(19200000, P_BI_TCXO, 1, 0, 0),
177 F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
178 F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0),
179 { }
180};
181
182static struct clk_rcg2 gpu_cc_gmu_clk_src = {
183 .cmd_rcgr = 0x1120,
184 .mnd_width = 0,
185 .hid_width = 5,
186 .enable_safe_config = true,
187 .parent_map = gpu_cc_parent_map_0,
188 .freq_tbl = ftbl_gpu_cc_gmu_clk_src,
189 .clkr.hw.init = &(struct clk_init_data){
190 .name = "gpu_cc_gmu_clk_src",
191 .parent_names = gpu_cc_parent_names_0,
192 .num_parents = 6,
193 .flags = CLK_SET_RATE_PARENT,
194 .ops = &clk_rcg2_ops,
195 VDD_CX_FMAX_MAP2(
196 MIN, 200000000,
197 LOW, 400000000),
198 },
199};
200
201static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = {
202 F_SLEW(147000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0, 294000000),
203 F_SLEW(210000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0, 420000000),
204 F_SLEW(338000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0, 676000000),
205 F_SLEW(425000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0, 850000000),
206 F_SLEW(600000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0, 1200000000),
207 { }
208};
209
210static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = {
211 .cmd_rcgr = 0x101c,
212 .mnd_width = 0,
213 .hid_width = 5,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800214 .parent_map = gpu_cc_parent_map_1,
215 .freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src,
Deepak Katragadda6c7e8e12017-04-05 13:21:16 -0700216 .flags = FORCE_ENABLE_RCG,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800217 .clkr.hw.init = &(struct clk_init_data){
218 .name = "gpu_cc_gx_gfx3d_clk_src",
219 .parent_names = gpu_cc_parent_names_1,
220 .num_parents = 7,
221 .flags = CLK_SET_RATE_PARENT,
222 .ops = &clk_rcg2_ops,
223 VDD_GX_FMAX_MAP8(
224 MIN, 147000000,
225 LOWER, 210000000,
226 LOW, 280000000,
227 LOW_L1, 338000000,
228 NOMINAL, 425000000,
229 NOMINAL_L1, 487000000,
230 HIGH, 548000000,
231 HIGH_L1, 600000000),
232 },
233};
234
235static const struct freq_tbl ftbl_gpu_cc_rbcpr_clk_src[] = {
236 F(19200000, P_BI_TCXO, 1, 0, 0),
237 { }
238};
239
240static struct clk_rcg2 gpu_cc_rbcpr_clk_src = {
241 .cmd_rcgr = 0x10b0,
242 .mnd_width = 0,
243 .hid_width = 5,
244 .parent_map = gpu_cc_parent_map_2,
245 .freq_tbl = ftbl_gpu_cc_rbcpr_clk_src,
246 .clkr.hw.init = &(struct clk_init_data){
247 .name = "gpu_cc_rbcpr_clk_src",
248 .parent_names = gpu_cc_parent_names_2,
249 .num_parents = 4,
250 .flags = CLK_SET_RATE_PARENT,
251 .ops = &clk_rcg2_ops,
252 VDD_CX_FMAX_MAP2(
253 MIN, 19200000,
254 NOMINAL, 50000000),
255 },
256};
257
258static struct clk_branch gpu_cc_acd_ahb_clk = {
259 .halt_reg = 0x1168,
260 .halt_check = BRANCH_HALT,
261 .clkr = {
262 .enable_reg = 0x1168,
263 .enable_mask = BIT(0),
264 .hw.init = &(struct clk_init_data){
265 .name = "gpu_cc_acd_ahb_clk",
266 .ops = &clk_branch2_ops,
267 },
268 },
269};
270
271static struct clk_branch gpu_cc_acd_cxo_clk = {
272 .halt_reg = 0x1164,
273 .halt_check = BRANCH_HALT,
274 .clkr = {
275 .enable_reg = 0x1164,
276 .enable_mask = BIT(0),
277 .hw.init = &(struct clk_init_data){
278 .name = "gpu_cc_acd_cxo_clk",
279 .ops = &clk_branch2_ops,
280 },
281 },
282};
283
284static struct clk_branch gpu_cc_ahb_clk = {
285 .halt_reg = 0x1078,
286 .halt_check = BRANCH_HALT,
287 .clkr = {
288 .enable_reg = 0x1078,
289 .enable_mask = BIT(0),
290 .hw.init = &(struct clk_init_data){
291 .name = "gpu_cc_ahb_clk",
292 .ops = &clk_branch2_ops,
293 },
294 },
295};
296
297static struct clk_branch gpu_cc_crc_ahb_clk = {
298 .halt_reg = 0x107c,
299 .halt_check = BRANCH_HALT,
300 .clkr = {
301 .enable_reg = 0x107c,
302 .enable_mask = BIT(0),
303 .hw.init = &(struct clk_init_data){
304 .name = "gpu_cc_crc_ahb_clk",
305 .ops = &clk_branch2_ops,
306 },
307 },
308};
309
310static struct clk_branch gpu_cc_cx_apb_clk = {
311 .halt_reg = 0x1088,
312 .halt_check = BRANCH_HALT,
313 .clkr = {
314 .enable_reg = 0x1088,
315 .enable_mask = BIT(0),
316 .hw.init = &(struct clk_init_data){
317 .name = "gpu_cc_cx_apb_clk",
318 .ops = &clk_branch2_ops,
319 },
320 },
321};
322
323static struct clk_branch gpu_cc_cx_gfx3d_clk = {
324 .halt_reg = 0x10a4,
325 .halt_check = BRANCH_HALT,
326 .clkr = {
327 .enable_reg = 0x10a4,
328 .enable_mask = BIT(0),
329 .hw.init = &(struct clk_init_data){
330 .name = "gpu_cc_cx_gfx3d_clk",
331 .parent_names = (const char *[]){
332 "gpu_cc_gx_gfx3d_clk_src",
333 },
334 .num_parents = 1,
335 .flags = CLK_SET_RATE_PARENT,
336 .ops = &clk_branch2_ops,
337 },
338 },
339};
340
341static struct clk_branch gpu_cc_cx_gfx3d_slv_clk = {
342 .halt_reg = 0x10a8,
343 .halt_check = BRANCH_HALT,
344 .clkr = {
345 .enable_reg = 0x10a8,
346 .enable_mask = BIT(0),
347 .hw.init = &(struct clk_init_data){
348 .name = "gpu_cc_cx_gfx3d_slv_clk",
349 .parent_names = (const char *[]){
350 "gpu_cc_gx_gfx3d_clk_src",
351 },
352 .num_parents = 1,
353 .flags = CLK_SET_RATE_PARENT,
354 .ops = &clk_branch2_ops,
355 },
356 },
357};
358
359static struct clk_branch gpu_cc_cx_gmu_clk = {
360 .halt_reg = 0x1098,
361 .halt_check = BRANCH_HALT,
362 .clkr = {
363 .enable_reg = 0x1098,
364 .enable_mask = BIT(0),
365 .hw.init = &(struct clk_init_data){
366 .name = "gpu_cc_cx_gmu_clk",
367 .parent_names = (const char *[]){
368 "gpu_cc_gmu_clk_src",
369 },
370 .num_parents = 1,
371 .flags = CLK_SET_RATE_PARENT,
372 .ops = &clk_branch2_ops,
373 },
374 },
375};
376
377static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
378 .halt_reg = 0x108c,
379 .halt_check = BRANCH_HALT,
380 .clkr = {
381 .enable_reg = 0x108c,
382 .enable_mask = BIT(0),
383 .hw.init = &(struct clk_init_data){
384 .name = "gpu_cc_cx_snoc_dvm_clk",
385 .ops = &clk_branch2_ops,
386 },
387 },
388};
389
390static struct clk_branch gpu_cc_cxo_aon_clk = {
391 .halt_reg = 0x1004,
392 .halt_check = BRANCH_HALT,
393 .clkr = {
394 .enable_reg = 0x1004,
395 .enable_mask = BIT(0),
396 .hw.init = &(struct clk_init_data){
397 .name = "gpu_cc_cxo_aon_clk",
398 .ops = &clk_branch2_ops,
399 },
400 },
401};
402
403static struct clk_branch gpu_cc_cxo_clk = {
404 .halt_reg = 0x109c,
405 .halt_check = BRANCH_HALT,
406 .clkr = {
407 .enable_reg = 0x109c,
408 .enable_mask = BIT(0),
409 .hw.init = &(struct clk_init_data){
410 .name = "gpu_cc_cxo_clk",
411 .ops = &clk_branch2_ops,
412 },
413 },
414};
415
Vicky Wallacece2159e2016-12-27 15:58:35 -0800416static struct clk_branch gpu_cc_gx_cxo_clk = {
417 .halt_reg = 0x1060,
418 .halt_check = BRANCH_HALT,
419 .clkr = {
420 .enable_reg = 0x1060,
421 .enable_mask = BIT(0),
422 .hw.init = &(struct clk_init_data){
423 .name = "gpu_cc_gx_cxo_clk",
424 .ops = &clk_branch2_ops,
425 },
426 },
427};
428
429static struct clk_branch gpu_cc_gx_gfx3d_clk = {
430 .halt_reg = 0x1054,
431 .halt_check = BRANCH_HALT,
432 .clkr = {
433 .enable_reg = 0x1054,
434 .enable_mask = BIT(0),
435 .hw.init = &(struct clk_init_data){
436 .name = "gpu_cc_gx_gfx3d_clk",
437 .parent_names = (const char *[]){
438 "gpu_cc_gx_gfx3d_clk_src",
439 },
440 .num_parents = 1,
441 .flags = CLK_SET_RATE_PARENT,
442 .ops = &clk_branch2_ops,
443 },
444 },
445};
446
447static struct clk_branch gpu_cc_gx_gmu_clk = {
448 .halt_reg = 0x1064,
449 .halt_check = BRANCH_HALT,
450 .clkr = {
451 .enable_reg = 0x1064,
452 .enable_mask = BIT(0),
453 .hw.init = &(struct clk_init_data){
454 .name = "gpu_cc_gx_gmu_clk",
455 .parent_names = (const char *[]){
456 "gpu_cc_gmu_clk_src",
457 },
458 .num_parents = 1,
459 .flags = CLK_SET_RATE_PARENT,
460 .ops = &clk_branch2_ops,
461 },
462 },
463};
464
465static struct clk_branch gpu_cc_gx_vsense_clk = {
466 .halt_reg = 0x1058,
467 .halt_check = BRANCH_HALT,
468 .clkr = {
469 .enable_reg = 0x1058,
470 .enable_mask = BIT(0),
471 .hw.init = &(struct clk_init_data){
472 .name = "gpu_cc_gx_vsense_clk",
473 .ops = &clk_branch2_ops,
474 },
475 },
476};
477
478static struct clk_branch gpu_cc_pll_test_clk = {
479 .halt_reg = 0x110c,
480 .halt_check = BRANCH_HALT,
481 .clkr = {
482 .enable_reg = 0x110c,
483 .enable_mask = BIT(0),
484 .hw.init = &(struct clk_init_data){
485 .name = "gpu_cc_pll_test_clk",
486 .ops = &clk_branch2_ops,
487 },
488 },
489};
490
491static struct clk_branch gpu_cc_rbcpr_ahb_clk = {
492 .halt_reg = 0x10f4,
493 .halt_check = BRANCH_HALT,
494 .clkr = {
495 .enable_reg = 0x10f4,
496 .enable_mask = BIT(0),
497 .hw.init = &(struct clk_init_data){
498 .name = "gpu_cc_rbcpr_ahb_clk",
499 .ops = &clk_branch2_ops,
500 },
501 },
502};
503
504static struct clk_branch gpu_cc_rbcpr_clk = {
505 .halt_reg = 0x10f0,
506 .halt_check = BRANCH_HALT,
507 .clkr = {
508 .enable_reg = 0x10f0,
509 .enable_mask = BIT(0),
510 .hw.init = &(struct clk_init_data){
511 .name = "gpu_cc_rbcpr_clk",
512 .parent_names = (const char *[]){
513 "gpu_cc_rbcpr_clk_src",
514 },
515 .num_parents = 1,
516 .flags = CLK_SET_RATE_PARENT,
517 .ops = &clk_branch2_ops,
518 },
519 },
520};
521
522static struct clk_regmap *gpu_cc_sdm845_clocks[] = {
523 [GPU_CC_ACD_AHB_CLK] = &gpu_cc_acd_ahb_clk.clkr,
524 [GPU_CC_ACD_CXO_CLK] = &gpu_cc_acd_cxo_clk.clkr,
525 [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
526 [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
527 [GPU_CC_CX_APB_CLK] = &gpu_cc_cx_apb_clk.clkr,
528 [GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr,
529 [GPU_CC_CX_GFX3D_SLV_CLK] = &gpu_cc_cx_gfx3d_slv_clk.clkr,
530 [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
531 [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
532 [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
533 [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800534 [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
535 [GPU_CC_GX_CXO_CLK] = &gpu_cc_gx_cxo_clk.clkr,
536 [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
537 [GPU_CC_GX_VSENSE_CLK] = &gpu_cc_gx_vsense_clk.clkr,
538 [GPU_CC_PLL_TEST_CLK] = &gpu_cc_pll_test_clk.clkr,
539 [GPU_CC_RBCPR_AHB_CLK] = &gpu_cc_rbcpr_ahb_clk.clkr,
540 [GPU_CC_RBCPR_CLK] = &gpu_cc_rbcpr_clk.clkr,
541 [GPU_CC_RBCPR_CLK_SRC] = &gpu_cc_rbcpr_clk_src.clkr,
542};
543
544static struct clk_regmap *gpu_cc_gfx_sdm845_clocks[] = {
545 [GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
546 [GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr,
547 [GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr,
548 [GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr,
549};
550
551static const struct qcom_reset_map gpu_cc_sdm845_resets[] = {
552 [GPUCC_GPU_CC_ACD_BCR] = { 0x1160 },
553 [GPUCC_GPU_CC_CX_BCR] = { 0x1068 },
554 [GPUCC_GPU_CC_GFX3D_AON_BCR] = { 0x10a0 },
555 [GPUCC_GPU_CC_GMU_BCR] = { 0x111c },
556 [GPUCC_GPU_CC_GX_BCR] = { 0x1008 },
557 [GPUCC_GPU_CC_RBCPR_BCR] = { 0x10ac },
558 [GPUCC_GPU_CC_SPDM_BCR] = { 0x1110 },
559 [GPUCC_GPU_CC_XO_BCR] = { 0x1000 },
560};
561
562static const struct regmap_config gpu_cc_sdm845_regmap_config = {
563 .reg_bits = 32,
564 .reg_stride = 4,
565 .val_bits = 32,
566 .max_register = 0x8008,
567 .fast_io = true,
568};
569
570static const struct qcom_cc_desc gpu_cc_sdm845_desc = {
571 .config = &gpu_cc_sdm845_regmap_config,
572 .clks = gpu_cc_sdm845_clocks,
573 .num_clks = ARRAY_SIZE(gpu_cc_sdm845_clocks),
574 .resets = gpu_cc_sdm845_resets,
575 .num_resets = ARRAY_SIZE(gpu_cc_sdm845_resets),
576};
577
578static const struct qcom_cc_desc gpu_cc_gfx_sdm845_desc = {
579 .config = &gpu_cc_sdm845_regmap_config,
580 .clks = gpu_cc_gfx_sdm845_clocks,
581 .num_clks = ARRAY_SIZE(gpu_cc_gfx_sdm845_clocks),
582};
583
584static const struct of_device_id gpu_cc_sdm845_match_table[] = {
585 { .compatible = "qcom,gpucc-sdm845" },
586 { }
587};
588MODULE_DEVICE_TABLE(of, gpu_cc_sdm845_match_table);
589
590static const struct of_device_id gpu_cc_gfx_sdm845_match_table[] = {
591 { .compatible = "qcom,gfxcc-sdm845" },
592 {},
593};
594MODULE_DEVICE_TABLE(of, gpu_cc_gfx_sdm845_match_table);
595
596static int gpu_cc_gfx_sdm845_probe(struct platform_device *pdev)
597{
598 struct regmap *regmap;
599 struct resource *res;
600 void __iomem *base;
601 int ret = 0;
602
603 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
604 if (res == NULL) {
605 dev_err(&pdev->dev, "Failed to get resources for clock_gfxcc.\n");
606 return -EINVAL;
607 }
608
609 base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
610 if (IS_ERR(base)) {
611 dev_err(&pdev->dev, "Failed to ioremap the GFX CC base.\n");
612 return PTR_ERR(base);
613 }
614
615 regmap = devm_regmap_init_mmio(&pdev->dev, base,
616 gpu_cc_gfx_sdm845_desc.config);
617 if (IS_ERR(regmap)) {
618 dev_err(&pdev->dev, "Failed to init regmap\n");
619 return PTR_ERR(regmap);
620 }
621
622 /* Get MX voltage regulator for GPU PLL graphic clock. */
623 vdd_mx.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_mx");
624 if (IS_ERR(vdd_mx.regulator[0])) {
625 if (!(PTR_ERR(vdd_mx.regulator[0]) == -EPROBE_DEFER))
626 dev_err(&pdev->dev,
627 "Unable to get vdd_mx regulator\n");
628 return PTR_ERR(vdd_mx.regulator[0]);
629 }
630
631 /* GFX voltage regulators for GFX3D graphic clock. */
632 vdd_gfx.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_gfx");
633 if (IS_ERR(vdd_gfx.regulator[0])) {
634 if (PTR_ERR(vdd_gfx.regulator[0]) != -EPROBE_DEFER)
635 dev_err(&pdev->dev, "Unable to get vdd_gfx regulator\n");
636 return PTR_ERR(vdd_gfx.regulator[0]);
637 }
638
639 clk_fabia_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
640
641 ret = qcom_cc_really_probe(pdev, &gpu_cc_gfx_sdm845_desc, regmap);
642 if (ret) {
643 dev_err(&pdev->dev, "Failed to register GFX CC clocks\n");
644 return ret;
645 }
646
647 clk_prepare_enable(gpu_cc_cxo_clk.clkr.hw.clk);
648
649 dev_info(&pdev->dev, "Registered GFX CC clocks.\n");
650
651 return ret;
652}
653
654static struct platform_driver gpu_cc_gfx_sdm845_driver = {
655 .probe = gpu_cc_gfx_sdm845_probe,
656 .driver = {
657 .name = "gfxcc-sdm845",
658 .of_match_table = gpu_cc_gfx_sdm845_match_table,
659 },
660};
661
662static int __init gpu_cc_gfx_sdm845_init(void)
663{
664 return platform_driver_register(&gpu_cc_gfx_sdm845_driver);
665}
666arch_initcall(gpu_cc_gfx_sdm845_init);
667
668static void __exit gpu_cc_gfx_sdm845_exit(void)
669{
670 platform_driver_unregister(&gpu_cc_gfx_sdm845_driver);
671}
672module_exit(gpu_cc_gfx_sdm845_exit);
673
674static int gpu_cc_sdm845_probe(struct platform_device *pdev)
675{
676 struct regmap *regmap;
677 int ret = 0;
678
679 regmap = qcom_cc_map(pdev, &gpu_cc_sdm845_desc);
680 if (IS_ERR(regmap))
681 return PTR_ERR(regmap);
682
683 /* Get CX voltage regulator for CX and GMU clocks. */
684 vdd_cx.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_cx");
685 if (IS_ERR(vdd_cx.regulator[0])) {
686 if (!(PTR_ERR(vdd_cx.regulator[0]) == -EPROBE_DEFER))
687 dev_err(&pdev->dev,
688 "Unable to get vdd_cx regulator\n");
689 return PTR_ERR(vdd_cx.regulator[0]);
690 }
691
692 ret = qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap);
693 if (ret) {
694 dev_err(&pdev->dev, "Failed to register GPU CC clocks\n");
695 return ret;
696 }
697
698 dev_info(&pdev->dev, "Registered GPU CC clocks.\n");
699
700 return ret;
701}
702
703static struct platform_driver gpu_cc_sdm845_driver = {
704 .probe = gpu_cc_sdm845_probe,
705 .driver = {
706 .name = "gpu_cc-sdm845",
707 .of_match_table = gpu_cc_sdm845_match_table,
708 },
709};
710
711static int __init gpu_cc_sdm845_init(void)
712{
713 return platform_driver_register(&gpu_cc_sdm845_driver);
714}
715core_initcall(gpu_cc_sdm845_init);
716
717static void __exit gpu_cc_sdm845_exit(void)
718{
719 platform_driver_unregister(&gpu_cc_sdm845_driver);
720}
721module_exit(gpu_cc_sdm845_exit);
722
723MODULE_DESCRIPTION("QTI GPU_CC SDM845 Driver");
724MODULE_LICENSE("GPL v2");
725MODULE_ALIAS("platform:gpu_cc-sdm845");