blob: db0dad1b241565da7eef540acf799ae7193bf364 [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
Deepak Katragadda443bd8d2017-08-28 22:30:19 +0530227static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src_sdm670[] = {
228 F(19200000, P_BI_TCXO, 1, 0, 0),
229 F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
230 { }
231};
232
Vicky Wallacece2159e2016-12-27 15:58:35 -0800233static struct clk_rcg2 gpu_cc_gmu_clk_src = {
234 .cmd_rcgr = 0x1120,
235 .mnd_width = 0,
236 .hid_width = 5,
237 .enable_safe_config = true,
238 .parent_map = gpu_cc_parent_map_0,
239 .freq_tbl = ftbl_gpu_cc_gmu_clk_src,
240 .clkr.hw.init = &(struct clk_init_data){
241 .name = "gpu_cc_gmu_clk_src",
242 .parent_names = gpu_cc_parent_names_0,
243 .num_parents = 6,
244 .flags = CLK_SET_RATE_PARENT,
245 .ops = &clk_rcg2_ops,
246 VDD_CX_FMAX_MAP2(
247 MIN, 200000000,
248 LOW, 400000000),
249 },
250};
251
Vicky Wallace60d41682017-06-05 19:34:56 -0700252static struct clk_fixed_factor crc_div = {
253 .mult = 1,
254 .div = 1,
255 .hw.init = &(struct clk_init_data){
256 .name = "crc_div",
257 .parent_names = (const char *[]){ "gpu_cc_pll0_out_even" },
258 .num_parents = 1,
259 .flags = CLK_SET_RATE_PARENT,
260 .ops = &clk_fixed_factor_ops,
261 },
262};
263
Vicky Wallacece2159e2016-12-27 15:58:35 -0800264static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = {
Vicky Wallace60d41682017-06-05 19:34:56 -0700265 F(147000000, P_CRC_DIV, 1, 0, 0),
266 F(210000000, P_CRC_DIV, 1, 0, 0),
267 F(280000000, P_CRC_DIV, 1, 0, 0),
268 F(338000000, P_CRC_DIV, 1, 0, 0),
269 F(425000000, P_CRC_DIV, 1, 0, 0),
270 F(487000000, P_CRC_DIV, 1, 0, 0),
271 F(548000000, P_CRC_DIV, 1, 0, 0),
272 F(600000000, P_CRC_DIV, 1, 0, 0),
Vicky Wallacece2159e2016-12-27 15:58:35 -0800273 { }
274};
275
Vicky Wallace442e2952017-07-12 18:46:26 -0700276static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src_sdm845_v2[] = {
277 F(180000000, P_CRC_DIV, 1, 0, 0),
278 F(257000000, P_CRC_DIV, 1, 0, 0),
279 F(342000000, P_CRC_DIV, 1, 0, 0),
280 F(414000000, P_CRC_DIV, 1, 0, 0),
281 F(520000000, P_CRC_DIV, 1, 0, 0),
282 F(596000000, P_CRC_DIV, 1, 0, 0),
Vicky Wallace799871c2017-08-09 16:39:09 -0700283 F(675000000, P_CRC_DIV, 1, 0, 0),
Vicky Wallace442e2952017-07-12 18:46:26 -0700284 F(710000000, P_CRC_DIV, 1, 0, 0),
285 { }
286};
287
Deepak Katragadda443bd8d2017-08-28 22:30:19 +0530288static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src_sdm670[] = {
289 F(180000000, P_CRC_DIV, 1, 0, 0),
290 F(267000000, P_CRC_DIV, 1, 0, 0),
291 F(355000000, P_CRC_DIV, 1, 0, 0),
292 F(430000000, P_CRC_DIV, 1, 0, 0),
293 F(565000000, P_CRC_DIV, 1, 0, 0),
294 F(650000000, P_CRC_DIV, 1, 0, 0),
295 F(750000000, P_CRC_DIV, 1, 0, 0),
296 F(780000000, P_CRC_DIV, 1, 0, 0),
297 { }
298};
299
Vicky Wallacece2159e2016-12-27 15:58:35 -0800300static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = {
301 .cmd_rcgr = 0x101c,
302 .mnd_width = 0,
303 .hid_width = 5,
Vicky Wallace60d41682017-06-05 19:34:56 -0700304 .parent_map = gpu_cc_parent_map_2,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800305 .freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src,
Deepak Katragadda6c7e8e12017-04-05 13:21:16 -0700306 .flags = FORCE_ENABLE_RCG,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800307 .clkr.hw.init = &(struct clk_init_data){
308 .name = "gpu_cc_gx_gfx3d_clk_src",
Vicky Wallace60d41682017-06-05 19:34:56 -0700309 .parent_names = gpu_cc_parent_names_2,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800310 .num_parents = 7,
311 .flags = CLK_SET_RATE_PARENT,
312 .ops = &clk_rcg2_ops,
313 VDD_GX_FMAX_MAP8(
314 MIN, 147000000,
315 LOWER, 210000000,
316 LOW, 280000000,
317 LOW_L1, 338000000,
318 NOMINAL, 425000000,
319 NOMINAL_L1, 487000000,
320 HIGH, 548000000,
321 HIGH_L1, 600000000),
322 },
323};
324
Vicky Wallacece2159e2016-12-27 15:58:35 -0800325static struct clk_branch gpu_cc_acd_ahb_clk = {
326 .halt_reg = 0x1168,
327 .halt_check = BRANCH_HALT,
328 .clkr = {
329 .enable_reg = 0x1168,
330 .enable_mask = BIT(0),
331 .hw.init = &(struct clk_init_data){
332 .name = "gpu_cc_acd_ahb_clk",
333 .ops = &clk_branch2_ops,
334 },
335 },
336};
337
338static struct clk_branch gpu_cc_acd_cxo_clk = {
339 .halt_reg = 0x1164,
340 .halt_check = BRANCH_HALT,
341 .clkr = {
342 .enable_reg = 0x1164,
343 .enable_mask = BIT(0),
344 .hw.init = &(struct clk_init_data){
345 .name = "gpu_cc_acd_cxo_clk",
346 .ops = &clk_branch2_ops,
347 },
348 },
349};
350
351static struct clk_branch gpu_cc_ahb_clk = {
352 .halt_reg = 0x1078,
353 .halt_check = BRANCH_HALT,
354 .clkr = {
355 .enable_reg = 0x1078,
356 .enable_mask = BIT(0),
357 .hw.init = &(struct clk_init_data){
358 .name = "gpu_cc_ahb_clk",
359 .ops = &clk_branch2_ops,
360 },
361 },
362};
363
364static struct clk_branch gpu_cc_crc_ahb_clk = {
365 .halt_reg = 0x107c,
366 .halt_check = BRANCH_HALT,
367 .clkr = {
368 .enable_reg = 0x107c,
369 .enable_mask = BIT(0),
370 .hw.init = &(struct clk_init_data){
371 .name = "gpu_cc_crc_ahb_clk",
372 .ops = &clk_branch2_ops,
373 },
374 },
375};
376
377static struct clk_branch gpu_cc_cx_apb_clk = {
378 .halt_reg = 0x1088,
379 .halt_check = BRANCH_HALT,
380 .clkr = {
381 .enable_reg = 0x1088,
382 .enable_mask = BIT(0),
383 .hw.init = &(struct clk_init_data){
384 .name = "gpu_cc_cx_apb_clk",
385 .ops = &clk_branch2_ops,
386 },
387 },
388};
389
390static struct clk_branch gpu_cc_cx_gfx3d_clk = {
391 .halt_reg = 0x10a4,
392 .halt_check = BRANCH_HALT,
393 .clkr = {
394 .enable_reg = 0x10a4,
395 .enable_mask = BIT(0),
396 .hw.init = &(struct clk_init_data){
397 .name = "gpu_cc_cx_gfx3d_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_gfx3d_slv_clk = {
409 .halt_reg = 0x10a8,
410 .halt_check = BRANCH_HALT,
411 .clkr = {
412 .enable_reg = 0x10a8,
413 .enable_mask = BIT(0),
414 .hw.init = &(struct clk_init_data){
415 .name = "gpu_cc_cx_gfx3d_slv_clk",
416 .parent_names = (const char *[]){
417 "gpu_cc_gx_gfx3d_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_gmu_clk = {
427 .halt_reg = 0x1098,
428 .halt_check = BRANCH_HALT,
429 .clkr = {
430 .enable_reg = 0x1098,
431 .enable_mask = BIT(0),
432 .hw.init = &(struct clk_init_data){
433 .name = "gpu_cc_cx_gmu_clk",
434 .parent_names = (const char *[]){
435 "gpu_cc_gmu_clk_src",
436 },
437 .num_parents = 1,
438 .flags = CLK_SET_RATE_PARENT,
439 .ops = &clk_branch2_ops,
440 },
441 },
442};
443
444static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
445 .halt_reg = 0x108c,
446 .halt_check = BRANCH_HALT,
447 .clkr = {
448 .enable_reg = 0x108c,
449 .enable_mask = BIT(0),
450 .hw.init = &(struct clk_init_data){
451 .name = "gpu_cc_cx_snoc_dvm_clk",
452 .ops = &clk_branch2_ops,
453 },
454 },
455};
456
457static struct clk_branch gpu_cc_cxo_aon_clk = {
458 .halt_reg = 0x1004,
459 .halt_check = BRANCH_HALT,
460 .clkr = {
461 .enable_reg = 0x1004,
462 .enable_mask = BIT(0),
463 .hw.init = &(struct clk_init_data){
464 .name = "gpu_cc_cxo_aon_clk",
465 .ops = &clk_branch2_ops,
466 },
467 },
468};
469
470static struct clk_branch gpu_cc_cxo_clk = {
471 .halt_reg = 0x109c,
472 .halt_check = BRANCH_HALT,
473 .clkr = {
474 .enable_reg = 0x109c,
475 .enable_mask = BIT(0),
476 .hw.init = &(struct clk_init_data){
477 .name = "gpu_cc_cxo_clk",
478 .ops = &clk_branch2_ops,
479 },
480 },
481};
482
Vicky Wallacece2159e2016-12-27 15:58:35 -0800483static struct clk_branch gpu_cc_gx_gfx3d_clk = {
484 .halt_reg = 0x1054,
485 .halt_check = BRANCH_HALT,
486 .clkr = {
487 .enable_reg = 0x1054,
488 .enable_mask = BIT(0),
489 .hw.init = &(struct clk_init_data){
490 .name = "gpu_cc_gx_gfx3d_clk",
491 .parent_names = (const char *[]){
492 "gpu_cc_gx_gfx3d_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_gmu_clk = {
502 .halt_reg = 0x1064,
503 .halt_check = BRANCH_HALT,
504 .clkr = {
505 .enable_reg = 0x1064,
506 .enable_mask = BIT(0),
507 .hw.init = &(struct clk_init_data){
508 .name = "gpu_cc_gx_gmu_clk",
509 .parent_names = (const char *[]){
510 "gpu_cc_gmu_clk_src",
511 },
512 .num_parents = 1,
513 .flags = CLK_SET_RATE_PARENT,
514 .ops = &clk_branch2_ops,
515 },
516 },
517};
518
519static struct clk_branch gpu_cc_gx_vsense_clk = {
520 .halt_reg = 0x1058,
521 .halt_check = BRANCH_HALT,
522 .clkr = {
523 .enable_reg = 0x1058,
524 .enable_mask = BIT(0),
525 .hw.init = &(struct clk_init_data){
526 .name = "gpu_cc_gx_vsense_clk",
527 .ops = &clk_branch2_ops,
528 },
529 },
530};
531
532static struct clk_branch gpu_cc_pll_test_clk = {
533 .halt_reg = 0x110c,
534 .halt_check = BRANCH_HALT,
535 .clkr = {
536 .enable_reg = 0x110c,
537 .enable_mask = BIT(0),
538 .hw.init = &(struct clk_init_data){
539 .name = "gpu_cc_pll_test_clk",
540 .ops = &clk_branch2_ops,
541 },
542 },
543};
544
Vicky Wallacece2159e2016-12-27 15:58:35 -0800545static struct clk_regmap *gpu_cc_sdm845_clocks[] = {
546 [GPU_CC_ACD_AHB_CLK] = &gpu_cc_acd_ahb_clk.clkr,
547 [GPU_CC_ACD_CXO_CLK] = &gpu_cc_acd_cxo_clk.clkr,
548 [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
549 [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
550 [GPU_CC_CX_APB_CLK] = &gpu_cc_cx_apb_clk.clkr,
551 [GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr,
552 [GPU_CC_CX_GFX3D_SLV_CLK] = &gpu_cc_cx_gfx3d_slv_clk.clkr,
553 [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
554 [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
555 [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
556 [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800557 [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800558 [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
559 [GPU_CC_GX_VSENSE_CLK] = &gpu_cc_gx_vsense_clk.clkr,
560 [GPU_CC_PLL_TEST_CLK] = &gpu_cc_pll_test_clk.clkr,
Vicky Wallaced1401ac2017-08-07 18:34:28 -0700561 [GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
562 [GPU_CC_PLL1] = NULL,
Vicky Wallacece2159e2016-12-27 15:58:35 -0800563};
564
565static struct clk_regmap *gpu_cc_gfx_sdm845_clocks[] = {
Vicky Wallacece2159e2016-12-27 15:58:35 -0800566 [GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr,
567 [GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr,
568 [GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr,
569};
570
571static const struct qcom_reset_map gpu_cc_sdm845_resets[] = {
572 [GPUCC_GPU_CC_ACD_BCR] = { 0x1160 },
573 [GPUCC_GPU_CC_CX_BCR] = { 0x1068 },
574 [GPUCC_GPU_CC_GFX3D_AON_BCR] = { 0x10a0 },
575 [GPUCC_GPU_CC_GMU_BCR] = { 0x111c },
576 [GPUCC_GPU_CC_GX_BCR] = { 0x1008 },
Vicky Wallacece2159e2016-12-27 15:58:35 -0800577 [GPUCC_GPU_CC_SPDM_BCR] = { 0x1110 },
578 [GPUCC_GPU_CC_XO_BCR] = { 0x1000 },
579};
580
581static const struct regmap_config gpu_cc_sdm845_regmap_config = {
582 .reg_bits = 32,
583 .reg_stride = 4,
584 .val_bits = 32,
585 .max_register = 0x8008,
586 .fast_io = true,
587};
588
589static const struct qcom_cc_desc gpu_cc_sdm845_desc = {
590 .config = &gpu_cc_sdm845_regmap_config,
591 .clks = gpu_cc_sdm845_clocks,
592 .num_clks = ARRAY_SIZE(gpu_cc_sdm845_clocks),
593 .resets = gpu_cc_sdm845_resets,
594 .num_resets = ARRAY_SIZE(gpu_cc_sdm845_resets),
595};
596
597static const struct qcom_cc_desc gpu_cc_gfx_sdm845_desc = {
598 .config = &gpu_cc_sdm845_regmap_config,
599 .clks = gpu_cc_gfx_sdm845_clocks,
600 .num_clks = ARRAY_SIZE(gpu_cc_gfx_sdm845_clocks),
601};
602
603static const struct of_device_id gpu_cc_sdm845_match_table[] = {
604 { .compatible = "qcom,gpucc-sdm845" },
Vicky Wallace442e2952017-07-12 18:46:26 -0700605 { .compatible = "qcom,gpucc-sdm845-v2" },
Deepak Katragadda443bd8d2017-08-28 22:30:19 +0530606 { .compatible = "qcom,gpucc-sdm670" },
Vicky Wallacece2159e2016-12-27 15:58:35 -0800607 { }
608};
609MODULE_DEVICE_TABLE(of, gpu_cc_sdm845_match_table);
610
611static const struct of_device_id gpu_cc_gfx_sdm845_match_table[] = {
612 { .compatible = "qcom,gfxcc-sdm845" },
Vicky Wallace442e2952017-07-12 18:46:26 -0700613 { .compatible = "qcom,gfxcc-sdm845-v2" },
Deepak Katragadda443bd8d2017-08-28 22:30:19 +0530614 { .compatible = "qcom,gfxcc-sdm670" },
Vicky Wallacece2159e2016-12-27 15:58:35 -0800615 {},
616};
617MODULE_DEVICE_TABLE(of, gpu_cc_gfx_sdm845_match_table);
618
Vicky Wallace442e2952017-07-12 18:46:26 -0700619static void gpu_cc_sdm845_fixup_sdm845v2(struct regmap *regmap)
620{
Vicky Wallace442e2952017-07-12 18:46:26 -0700621 gpu_cc_sdm845_clocks[GPU_CC_PLL1] = &gpu_cc_pll1.clkr;
Vicky Wallaced1401ac2017-08-07 18:34:28 -0700622 clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
623
Vicky Wallace442e2952017-07-12 18:46:26 -0700624 gpu_cc_gmu_clk_src.freq_tbl = ftbl_gpu_cc_gmu_clk_src_sdm845_v2;
625 gpu_cc_gmu_clk_src.clkr.hw.init->rate_max[VDD_CX_LOW] = 500000000;
626}
627
Deepak Katragadda443bd8d2017-08-28 22:30:19 +0530628static void gpu_cc_sdm845_fixup_sdm670(struct regmap *regmap)
629{
630 gpu_cc_sdm845_clocks[GPU_CC_PLL1] = &gpu_cc_pll1.clkr;
631 clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
632
633 gpu_cc_gmu_clk_src.freq_tbl = ftbl_gpu_cc_gmu_clk_src_sdm670;
634 gpu_cc_gmu_clk_src.clkr.hw.init->rate_max[VDD_CX_LOW] = 0;
635}
636
Vicky Wallace442e2952017-07-12 18:46:26 -0700637static void gpu_cc_gfx_sdm845_fixup_sdm845v2(void)
638{
639 gpu_cc_gx_gfx3d_clk_src.freq_tbl =
640 ftbl_gpu_cc_gx_gfx3d_clk_src_sdm845_v2;
641 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_MIN] = 180000000;
642 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_LOWER] =
643 257000000;
644 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_LOW] = 342000000;
645 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_LOW_L1] =
646 414000000;
647 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_NOMINAL] =
648 520000000;
649 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_NOMINAL_L1] =
650 596000000;
651 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_HIGH] = 675000000;
652 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_HIGH_L1] =
653 710000000;
654}
655
Deepak Katragadda443bd8d2017-08-28 22:30:19 +0530656static void gpu_cc_gfx_sdm845_fixup_sdm670(void)
657{
658 gpu_cc_gx_gfx3d_clk_src.freq_tbl =
659 ftbl_gpu_cc_gx_gfx3d_clk_src_sdm670;
660 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_MIN] =
661 180000000;
662 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_LOWER] =
663 267000000;
664 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_LOW] =
665 355000000;
666 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_LOW_L1] =
667 430000000;
668 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_NOMINAL] =
669 565000000;
670 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_NOMINAL_L1] =
671 650000000;
672 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_HIGH] =
673 750000000;
674 gpu_cc_gx_gfx3d_clk_src.clkr.hw.init->rate_max[VDD_GX_HIGH_L1] =
675 780000000;
676}
677
Vicky Wallace442e2952017-07-12 18:46:26 -0700678static int gpu_cc_gfx_sdm845_fixup(struct platform_device *pdev)
679{
680 const char *compat = NULL;
681 int compatlen = 0;
682
683 compat = of_get_property(pdev->dev.of_node, "compatible", &compatlen);
684 if (!compat || (compatlen <= 0))
685 return -EINVAL;
686
687 if (!strcmp(compat, "qcom,gfxcc-sdm845-v2"))
688 gpu_cc_gfx_sdm845_fixup_sdm845v2();
Deepak Katragadda443bd8d2017-08-28 22:30:19 +0530689 else if (!strcmp(compat, "qcom,gfxcc-sdm670"))
690 gpu_cc_gfx_sdm845_fixup_sdm670();
Vicky Wallace442e2952017-07-12 18:46:26 -0700691
692 return 0;
693}
694
695static int gpu_cc_sdm845_fixup(struct platform_device *pdev,
696 struct regmap *regmap)
697{
698 const char *compat = NULL;
699 int compatlen = 0;
700
701 compat = of_get_property(pdev->dev.of_node, "compatible", &compatlen);
702 if (!compat || (compatlen <= 0))
703 return -EINVAL;
704
705 if (!strcmp(compat, "qcom,gpucc-sdm845-v2"))
706 gpu_cc_sdm845_fixup_sdm845v2(regmap);
Deepak Katragadda443bd8d2017-08-28 22:30:19 +0530707 else if (!strcmp(compat, "qcom,gpucc-sdm670"))
708 gpu_cc_sdm845_fixup_sdm670(regmap);
Vicky Wallace442e2952017-07-12 18:46:26 -0700709
710 return 0;
711}
712
Vicky Wallacece2159e2016-12-27 15:58:35 -0800713static int gpu_cc_gfx_sdm845_probe(struct platform_device *pdev)
714{
715 struct regmap *regmap;
716 struct resource *res;
717 void __iomem *base;
718 int ret = 0;
719
720 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
721 if (res == NULL) {
Vicky Wallace60d41682017-06-05 19:34:56 -0700722 dev_err(&pdev->dev, "Failed to get resources for clock_gfxcc\n");
Vicky Wallacece2159e2016-12-27 15:58:35 -0800723 return -EINVAL;
724 }
725
726 base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
727 if (IS_ERR(base)) {
Vicky Wallace60d41682017-06-05 19:34:56 -0700728 dev_err(&pdev->dev, "Failed to ioremap the GFX CC base\n");
Vicky Wallacece2159e2016-12-27 15:58:35 -0800729 return PTR_ERR(base);
730 }
731
Vicky Wallace60d41682017-06-05 19:34:56 -0700732 /* Register clock fixed factor for CRC divide. */
733 ret = devm_clk_hw_register(&pdev->dev, &crc_div.hw);
734 if (ret) {
735 dev_err(&pdev->dev, "Failed to register hardware clock\n");
736 return ret;
737 }
738
Vicky Wallacece2159e2016-12-27 15:58:35 -0800739 regmap = devm_regmap_init_mmio(&pdev->dev, base,
740 gpu_cc_gfx_sdm845_desc.config);
741 if (IS_ERR(regmap)) {
742 dev_err(&pdev->dev, "Failed to init regmap\n");
743 return PTR_ERR(regmap);
744 }
745
Vicky Wallacece2159e2016-12-27 15:58:35 -0800746 /* GFX voltage regulators for GFX3D graphic clock. */
747 vdd_gfx.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_gfx");
748 if (IS_ERR(vdd_gfx.regulator[0])) {
749 if (PTR_ERR(vdd_gfx.regulator[0]) != -EPROBE_DEFER)
750 dev_err(&pdev->dev, "Unable to get vdd_gfx regulator\n");
751 return PTR_ERR(vdd_gfx.regulator[0]);
752 }
753
Deepak Katragadda21afc872017-05-30 14:05:59 -0700754 /* Avoid turning on the rail during clock registration */
755 vdd_gfx.skip_handoff = true;
756
Vicky Wallace442e2952017-07-12 18:46:26 -0700757 ret = gpu_cc_gfx_sdm845_fixup(pdev);
758 if (ret) {
759 dev_err(&pdev->dev, "Failed to do GFX clock fixup\n");
760 return ret;
761 }
762
Vicky Wallacece2159e2016-12-27 15:58:35 -0800763 clk_fabia_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
764
765 ret = qcom_cc_really_probe(pdev, &gpu_cc_gfx_sdm845_desc, regmap);
766 if (ret) {
767 dev_err(&pdev->dev, "Failed to register GFX CC clocks\n");
768 return ret;
769 }
770
Vicky Wallace60d41682017-06-05 19:34:56 -0700771 dev_info(&pdev->dev, "Registered GFX CC clocks\n");
Vicky Wallacece2159e2016-12-27 15:58:35 -0800772
773 return ret;
774}
775
776static struct platform_driver gpu_cc_gfx_sdm845_driver = {
777 .probe = gpu_cc_gfx_sdm845_probe,
778 .driver = {
779 .name = "gfxcc-sdm845",
780 .of_match_table = gpu_cc_gfx_sdm845_match_table,
781 },
782};
783
784static int __init gpu_cc_gfx_sdm845_init(void)
785{
786 return platform_driver_register(&gpu_cc_gfx_sdm845_driver);
787}
Deepak Katragaddaef44e102017-06-21 10:30:46 -0700788subsys_initcall(gpu_cc_gfx_sdm845_init);
Vicky Wallacece2159e2016-12-27 15:58:35 -0800789
790static void __exit gpu_cc_gfx_sdm845_exit(void)
791{
792 platform_driver_unregister(&gpu_cc_gfx_sdm845_driver);
793}
794module_exit(gpu_cc_gfx_sdm845_exit);
795
796static int gpu_cc_sdm845_probe(struct platform_device *pdev)
797{
798 struct regmap *regmap;
799 int ret = 0;
Vicky Wallace8b61d162017-07-19 18:52:26 -0700800 unsigned int value, mask;
Vicky Wallacece2159e2016-12-27 15:58:35 -0800801
802 regmap = qcom_cc_map(pdev, &gpu_cc_sdm845_desc);
803 if (IS_ERR(regmap))
804 return PTR_ERR(regmap);
805
806 /* Get CX voltage regulator for CX and GMU clocks. */
807 vdd_cx.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_cx");
808 if (IS_ERR(vdd_cx.regulator[0])) {
809 if (!(PTR_ERR(vdd_cx.regulator[0]) == -EPROBE_DEFER))
810 dev_err(&pdev->dev,
811 "Unable to get vdd_cx regulator\n");
812 return PTR_ERR(vdd_cx.regulator[0]);
813 }
814
Vicky Wallaced1401ac2017-08-07 18:34:28 -0700815 /* Get MX voltage regulator for GPU PLL graphic clock. */
816 vdd_mx.regulator[0] = devm_regulator_get(&pdev->dev, "vdd_mx");
817 if (IS_ERR(vdd_mx.regulator[0])) {
818 if (!(PTR_ERR(vdd_mx.regulator[0]) == -EPROBE_DEFER))
819 dev_err(&pdev->dev,
820 "Unable to get vdd_mx regulator\n");
821 return PTR_ERR(vdd_mx.regulator[0]);
822 }
823
Vicky Wallace442e2952017-07-12 18:46:26 -0700824 ret = gpu_cc_sdm845_fixup(pdev, regmap);
825 if (ret) {
826 dev_err(&pdev->dev, "Failed to do GPU CC clock fixup\n");
827 return ret;
828 }
829
Vicky Wallacece2159e2016-12-27 15:58:35 -0800830 ret = qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap);
831 if (ret) {
832 dev_err(&pdev->dev, "Failed to register GPU CC clocks\n");
833 return ret;
834 }
835
Vicky Wallace8b61d162017-07-19 18:52:26 -0700836 mask = CX_GMU_CBCR_WAKE_MASK << CX_GMU_CBCR_WAKE_SHIFT;
837 mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT;
838 value = 0xF << CX_GMU_CBCR_WAKE_SHIFT | 0xF << CX_GMU_CBCR_SLEEP_SHIFT;
839 regmap_update_bits(regmap, gpu_cc_cx_gmu_clk.clkr.enable_reg,
840 mask, value);
841
Vicky Wallace60d41682017-06-05 19:34:56 -0700842 dev_info(&pdev->dev, "Registered GPU CC clocks\n");
Vicky Wallacece2159e2016-12-27 15:58:35 -0800843
844 return ret;
845}
846
847static struct platform_driver gpu_cc_sdm845_driver = {
848 .probe = gpu_cc_sdm845_probe,
849 .driver = {
850 .name = "gpu_cc-sdm845",
851 .of_match_table = gpu_cc_sdm845_match_table,
852 },
853};
854
855static int __init gpu_cc_sdm845_init(void)
856{
857 return platform_driver_register(&gpu_cc_sdm845_driver);
858}
Deepak Katragaddaef44e102017-06-21 10:30:46 -0700859subsys_initcall(gpu_cc_sdm845_init);
Vicky Wallacece2159e2016-12-27 15:58:35 -0800860
861static void __exit gpu_cc_sdm845_exit(void)
862{
863 platform_driver_unregister(&gpu_cc_sdm845_driver);
864}
865module_exit(gpu_cc_sdm845_exit);
866
867MODULE_DESCRIPTION("QTI GPU_CC SDM845 Driver");
868MODULE_LICENSE("GPL v2");
869MODULE_ALIAS("platform:gpu_cc-sdm845");