1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
4 */
5
6 #include <linux/clk-provider.h>
7 #include <linux/module.h>
8 #include <linux/mod_devicetable.h>
9 #include <linux/of.h>
10 #include <linux/platform_device.h>
11 #include <linux/regmap.h>
12
13 #include <dt-bindings/clock/qcom,sm4450-gpucc.h>
14
15 #include "clk-alpha-pll.h"
16 #include "clk-branch.h"
17 #include "clk-pll.h"
18 #include "clk-rcg.h"
19 #include "clk-regmap.h"
20 #include "clk-regmap-divider.h"
21 #include "common.h"
22 #include "gdsc.h"
23 #include "reset.h"
24
25 enum {
26 DT_BI_TCXO,
27 DT_GPLL0_OUT_MAIN,
28 DT_GPLL0_OUT_MAIN_DIV,
29 };
30
31 enum {
32 P_BI_TCXO,
33 P_GPLL0_OUT_MAIN,
34 P_GPLL0_OUT_MAIN_DIV,
35 P_GPU_CC_PLL0_OUT_EVEN,
36 P_GPU_CC_PLL0_OUT_MAIN,
37 P_GPU_CC_PLL0_OUT_ODD,
38 P_GPU_CC_PLL1_OUT_EVEN,
39 P_GPU_CC_PLL1_OUT_MAIN,
40 P_GPU_CC_PLL1_OUT_ODD,
41 };
42
43 static const struct pll_vco lucid_evo_vco[] = {
44 { 249600000, 2020000000, 0 },
45 };
46
47 /* 680.0 MHz Configuration */
48 static const struct alpha_pll_config gpu_cc_pll0_config = {
49 .l = 0x23,
50 .alpha = 0x6aaa,
51 .config_ctl_val = 0x20485699,
52 .config_ctl_hi_val = 0x00182261,
53 .config_ctl_hi1_val = 0x32aa299c,
54 .user_ctl_val = 0x00000000,
55 .user_ctl_hi_val = 0x00000805,
56 };
57
58 static struct clk_alpha_pll gpu_cc_pll0 = {
59 .offset = 0x0,
60 .vco_table = lucid_evo_vco,
61 .num_vco = ARRAY_SIZE(lucid_evo_vco),
62 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
63 .clkr = {
64 .hw.init = &(const struct clk_init_data) {
65 .name = "gpu_cc_pll0",
66 .parent_data = &(const struct clk_parent_data) {
67 .index = DT_BI_TCXO,
68 },
69 .num_parents = 1,
70 .ops = &clk_alpha_pll_lucid_evo_ops,
71 },
72 },
73 };
74
75 /* 500.0 MHz Configuration */
76 static const struct alpha_pll_config gpu_cc_pll1_config = {
77 .l = 0x1a,
78 .alpha = 0xaaa,
79 .config_ctl_val = 0x20485699,
80 .config_ctl_hi_val = 0x00182261,
81 .config_ctl_hi1_val = 0x32aa299c,
82 .user_ctl_val = 0x00000000,
83 .user_ctl_hi_val = 0x00000805,
84 };
85
86 static struct clk_alpha_pll gpu_cc_pll1 = {
87 .offset = 0x1000,
88 .vco_table = lucid_evo_vco,
89 .num_vco = ARRAY_SIZE(lucid_evo_vco),
90 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO],
91 .clkr = {
92 .hw.init = &(const struct clk_init_data) {
93 .name = "gpu_cc_pll1",
94 .parent_data = &(const struct clk_parent_data) {
95 .index = DT_BI_TCXO,
96 },
97 .num_parents = 1,
98 .ops = &clk_alpha_pll_lucid_evo_ops,
99 },
100 },
101 };
102
103 static const struct parent_map gpu_cc_parent_map_0[] = {
104 { P_BI_TCXO, 0 },
105 { P_GPLL0_OUT_MAIN, 5 },
106 { P_GPLL0_OUT_MAIN_DIV, 6 },
107 };
108
109 static const struct clk_parent_data gpu_cc_parent_data_0[] = {
110 { .index = DT_BI_TCXO },
111 { .index = DT_GPLL0_OUT_MAIN },
112 { .index = DT_GPLL0_OUT_MAIN_DIV },
113 };
114
115 static const struct parent_map gpu_cc_parent_map_1[] = {
116 { P_BI_TCXO, 0 },
117 { P_GPU_CC_PLL0_OUT_MAIN, 1 },
118 { P_GPU_CC_PLL1_OUT_MAIN, 3 },
119 { P_GPLL0_OUT_MAIN, 5 },
120 { P_GPLL0_OUT_MAIN_DIV, 6 },
121 };
122
123 static const struct clk_parent_data gpu_cc_parent_data_1[] = {
124 { .index = DT_BI_TCXO },
125 { .hw = &gpu_cc_pll0.clkr.hw },
126 { .hw = &gpu_cc_pll1.clkr.hw },
127 { .index = DT_GPLL0_OUT_MAIN },
128 { .index = DT_GPLL0_OUT_MAIN_DIV },
129 };
130
131 static const struct parent_map gpu_cc_parent_map_2[] = {
132 { P_BI_TCXO, 0 },
133 { P_GPU_CC_PLL0_OUT_EVEN, 1 },
134 { P_GPU_CC_PLL0_OUT_ODD, 2 },
135 { P_GPU_CC_PLL1_OUT_EVEN, 3 },
136 { P_GPU_CC_PLL1_OUT_ODD, 4 },
137 { P_GPLL0_OUT_MAIN, 5 },
138 };
139
140 static const struct clk_parent_data gpu_cc_parent_data_2[] = {
141 { .index = DT_BI_TCXO },
142 { .hw = &gpu_cc_pll0.clkr.hw },
143 { .hw = &gpu_cc_pll0.clkr.hw },
144 { .hw = &gpu_cc_pll1.clkr.hw },
145 { .hw = &gpu_cc_pll1.clkr.hw },
146 { .index = DT_GPLL0_OUT_MAIN },
147 };
148
149 static const struct parent_map gpu_cc_parent_map_3[] = {
150 { P_BI_TCXO, 0 },
151 { P_GPU_CC_PLL1_OUT_MAIN, 3 },
152 { P_GPLL0_OUT_MAIN, 5 },
153 { P_GPLL0_OUT_MAIN_DIV, 6 },
154 };
155
156 static const struct clk_parent_data gpu_cc_parent_data_3[] = {
157 { .index = DT_BI_TCXO },
158 { .hw = &gpu_cc_pll1.clkr.hw },
159 { .index = DT_GPLL0_OUT_MAIN },
160 { .index = DT_GPLL0_OUT_MAIN_DIV },
161 };
162
163 static const struct parent_map gpu_cc_parent_map_4[] = {
164 { P_BI_TCXO, 0 },
165 };
166
167 static const struct clk_parent_data gpu_cc_parent_data_4[] = {
168 { .index = DT_BI_TCXO },
169 };
170
171 static const struct freq_tbl ftbl_gpu_cc_ff_clk_src[] = {
172 F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
173 { }
174 };
175
176 static struct clk_rcg2 gpu_cc_ff_clk_src = {
177 .cmd_rcgr = 0x9474,
178 .mnd_width = 0,
179 .hid_width = 5,
180 .parent_map = gpu_cc_parent_map_0,
181 .freq_tbl = ftbl_gpu_cc_ff_clk_src,
182 .clkr.hw.init = &(const struct clk_init_data) {
183 .name = "gpu_cc_ff_clk_src",
184 .parent_data = gpu_cc_parent_data_0,
185 .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
186 .flags = CLK_SET_RATE_PARENT,
187 .ops = &clk_rcg2_shared_ops,
188 },
189 };
190
191 static struct clk_rcg2 gpu_cc_gmu_clk_src = {
192 .cmd_rcgr = 0x9318,
193 .mnd_width = 0,
194 .hid_width = 5,
195 .parent_map = gpu_cc_parent_map_1,
196 .freq_tbl = ftbl_gpu_cc_ff_clk_src,
197 .clkr.hw.init = &(const struct clk_init_data) {
198 .name = "gpu_cc_gmu_clk_src",
199 .parent_data = gpu_cc_parent_data_1,
200 .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
201 .flags = CLK_SET_RATE_PARENT,
202 .ops = &clk_rcg2_shared_ops,
203 },
204 };
205
206 static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = {
207 F(340000000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
208 F(500000000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
209 F(605000000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
210 F(765000000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
211 F(850000000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
212 F(955000000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
213 F(1010000000, P_GPU_CC_PLL0_OUT_EVEN, 2, 0, 0),
214 { }
215 };
216
217 static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = {
218 .cmd_rcgr = 0x9070,
219 .mnd_width = 0,
220 .hid_width = 5,
221 .parent_map = gpu_cc_parent_map_2,
222 .freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src,
223 .clkr.hw.init = &(const struct clk_init_data) {
224 .name = "gpu_cc_gx_gfx3d_clk_src",
225 .parent_data = gpu_cc_parent_data_2,
226 .num_parents = ARRAY_SIZE(gpu_cc_parent_data_2),
227 .flags = CLK_SET_RATE_PARENT,
228 .ops = &clk_rcg2_shared_ops,
229 },
230 };
231
232 static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = {
233 F(150000000, P_GPLL0_OUT_MAIN_DIV, 2, 0, 0),
234 { }
235 };
236
237 static struct clk_rcg2 gpu_cc_hub_clk_src = {
238 .cmd_rcgr = 0x93ec,
239 .mnd_width = 0,
240 .hid_width = 5,
241 .parent_map = gpu_cc_parent_map_3,
242 .freq_tbl = ftbl_gpu_cc_hub_clk_src,
243 .clkr.hw.init = &(const struct clk_init_data) {
244 .name = "gpu_cc_hub_clk_src",
245 .parent_data = gpu_cc_parent_data_3,
246 .num_parents = ARRAY_SIZE(gpu_cc_parent_data_3),
247 .flags = CLK_SET_RATE_PARENT,
248 .ops = &clk_rcg2_shared_ops,
249 },
250 };
251
252 static const struct freq_tbl ftbl_gpu_cc_xo_clk_src[] = {
253 F(19200000, P_BI_TCXO, 1, 0, 0),
254 { }
255 };
256
257 static struct clk_rcg2 gpu_cc_xo_clk_src = {
258 .cmd_rcgr = 0x9010,
259 .mnd_width = 0,
260 .hid_width = 5,
261 .parent_map = gpu_cc_parent_map_4,
262 .freq_tbl = ftbl_gpu_cc_xo_clk_src,
263 .clkr.hw.init = &(const struct clk_init_data) {
264 .name = "gpu_cc_xo_clk_src",
265 .parent_data = gpu_cc_parent_data_4,
266 .num_parents = ARRAY_SIZE(gpu_cc_parent_data_4),
267 .flags = CLK_SET_RATE_PARENT,
268 .ops = &clk_rcg2_shared_ops,
269 },
270 };
271
272 static struct clk_regmap_div gpu_cc_demet_div_clk_src = {
273 .reg = 0x9054,
274 .shift = 0,
275 .width = 4,
276 .clkr.hw.init = &(const struct clk_init_data) {
277 .name = "gpu_cc_demet_div_clk_src",
278 .parent_hws = (const struct clk_hw*[]) {
279 &gpu_cc_xo_clk_src.clkr.hw,
280 },
281 .num_parents = 1,
282 .flags = CLK_SET_RATE_PARENT,
283 .ops = &clk_regmap_div_ro_ops,
284 },
285 };
286
287 static struct clk_regmap_div gpu_cc_hub_ahb_div_clk_src = {
288 .reg = 0x9430,
289 .shift = 0,
290 .width = 4,
291 .clkr.hw.init = &(const struct clk_init_data) {
292 .name = "gpu_cc_hub_ahb_div_clk_src",
293 .parent_hws = (const struct clk_hw*[]) {
294 &gpu_cc_hub_clk_src.clkr.hw,
295 },
296 .num_parents = 1,
297 .flags = CLK_SET_RATE_PARENT,
298 .ops = &clk_regmap_div_ro_ops,
299 },
300 };
301
302 static struct clk_regmap_div gpu_cc_hub_cx_int_div_clk_src = {
303 .reg = 0x942c,
304 .shift = 0,
305 .width = 4,
306 .clkr.hw.init = &(const struct clk_init_data) {
307 .name = "gpu_cc_hub_cx_int_div_clk_src",
308 .parent_hws = (const struct clk_hw*[]) {
309 &gpu_cc_hub_clk_src.clkr.hw,
310 },
311 .num_parents = 1,
312 .flags = CLK_SET_RATE_PARENT,
313 .ops = &clk_regmap_div_ro_ops,
314 },
315 };
316
317 static struct clk_regmap_div gpu_cc_xo_div_clk_src = {
318 .reg = 0x9050,
319 .shift = 0,
320 .width = 4,
321 .clkr.hw.init = &(const struct clk_init_data) {
322 .name = "gpu_cc_xo_div_clk_src",
323 .parent_hws = (const struct clk_hw*[]) {
324 &gpu_cc_xo_clk_src.clkr.hw,
325 },
326 .num_parents = 1,
327 .flags = CLK_SET_RATE_PARENT,
328 .ops = &clk_regmap_div_ro_ops,
329 },
330 };
331
332 static struct clk_branch gpu_cc_ahb_clk = {
333 .halt_reg = 0x911c,
334 .halt_check = BRANCH_HALT_DELAY,
335 .clkr = {
336 .enable_reg = 0x911c,
337 .enable_mask = BIT(0),
338 .hw.init = &(const struct clk_init_data) {
339 .name = "gpu_cc_ahb_clk",
340 .parent_hws = (const struct clk_hw*[]) {
341 &gpu_cc_hub_ahb_div_clk_src.clkr.hw,
342 },
343 .num_parents = 1,
344 .flags = CLK_SET_RATE_PARENT,
345 .ops = &clk_branch2_ops,
346 },
347 },
348 };
349
350 static struct clk_branch gpu_cc_crc_ahb_clk = {
351 .halt_reg = 0x9120,
352 .halt_check = BRANCH_HALT,
353 .clkr = {
354 .enable_reg = 0x9120,
355 .enable_mask = BIT(0),
356 .hw.init = &(const struct clk_init_data) {
357 .name = "gpu_cc_crc_ahb_clk",
358 .parent_hws = (const struct clk_hw*[]) {
359 &gpu_cc_hub_ahb_div_clk_src.clkr.hw,
360 },
361 .num_parents = 1,
362 .flags = CLK_SET_RATE_PARENT,
363 .ops = &clk_branch2_ops,
364 },
365 },
366 };
367
368 static struct clk_branch gpu_cc_cx_ff_clk = {
369 .halt_reg = 0x914c,
370 .halt_check = BRANCH_HALT,
371 .clkr = {
372 .enable_reg = 0x914c,
373 .enable_mask = BIT(0),
374 .hw.init = &(const struct clk_init_data) {
375 .name = "gpu_cc_cx_ff_clk",
376 .parent_hws = (const struct clk_hw*[]) {
377 &gpu_cc_ff_clk_src.clkr.hw,
378 },
379 .num_parents = 1,
380 .flags = CLK_SET_RATE_PARENT,
381 .ops = &clk_branch2_ops,
382 },
383 },
384 };
385
386 static struct clk_branch gpu_cc_cx_gfx3d_clk = {
387 .halt_reg = 0x919c,
388 .halt_check = BRANCH_HALT,
389 .clkr = {
390 .enable_reg = 0x919c,
391 .enable_mask = BIT(0),
392 .hw.init = &(const struct clk_init_data) {
393 .name = "gpu_cc_cx_gfx3d_clk",
394 .parent_hws = (const struct clk_hw*[]) {
395 &gpu_cc_gx_gfx3d_clk_src.clkr.hw,
396 },
397 .num_parents = 1,
398 .flags = CLK_SET_RATE_PARENT,
399 .ops = &clk_branch2_ops,
400 },
401 },
402 };
403
404 static struct clk_branch gpu_cc_cx_gfx3d_slv_clk = {
405 .halt_reg = 0x91a0,
406 .halt_check = BRANCH_HALT,
407 .clkr = {
408 .enable_reg = 0x91a0,
409 .enable_mask = BIT(0),
410 .hw.init = &(const struct clk_init_data) {
411 .name = "gpu_cc_cx_gfx3d_slv_clk",
412 .parent_hws = (const struct clk_hw*[]) {
413 &gpu_cc_gx_gfx3d_clk_src.clkr.hw,
414 },
415 .num_parents = 1,
416 .flags = CLK_SET_RATE_PARENT,
417 .ops = &clk_branch2_ops,
418 },
419 },
420 };
421
422 static struct clk_branch gpu_cc_cx_gmu_clk = {
423 .halt_reg = 0x913c,
424 .halt_check = BRANCH_HALT,
425 .clkr = {
426 .enable_reg = 0x913c,
427 .enable_mask = BIT(0),
428 .hw.init = &(const struct clk_init_data) {
429 .name = "gpu_cc_cx_gmu_clk",
430 .parent_hws = (const struct clk_hw*[]) {
431 &gpu_cc_gmu_clk_src.clkr.hw,
432 },
433 .num_parents = 1,
434 .flags = CLK_SET_RATE_PARENT,
435 .ops = &clk_branch2_aon_ops,
436 },
437 },
438 };
439
440 static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
441 .halt_reg = 0x9130,
442 .halt_check = BRANCH_HALT,
443 .clkr = {
444 .enable_reg = 0x9130,
445 .enable_mask = BIT(0),
446 .hw.init = &(const struct clk_init_data) {
447 .name = "gpu_cc_cx_snoc_dvm_clk",
448 .ops = &clk_branch2_ops,
449 },
450 },
451 };
452
453 static struct clk_branch gpu_cc_cxo_clk = {
454 .halt_reg = 0x9144,
455 .halt_check = BRANCH_HALT,
456 .clkr = {
457 .enable_reg = 0x9144,
458 .enable_mask = BIT(0),
459 .hw.init = &(const struct clk_init_data) {
460 .name = "gpu_cc_cxo_clk",
461 .parent_hws = (const struct clk_hw*[]) {
462 &gpu_cc_xo_clk_src.clkr.hw,
463 },
464 .num_parents = 1,
465 .flags = CLK_SET_RATE_PARENT,
466 .ops = &clk_branch2_ops,
467 },
468 },
469 };
470
471 static struct clk_branch gpu_cc_freq_measure_clk = {
472 .halt_reg = 0x9008,
473 .halt_check = BRANCH_HALT,
474 .clkr = {
475 .enable_reg = 0x9008,
476 .enable_mask = BIT(0),
477 .hw.init = &(const struct clk_init_data) {
478 .name = "gpu_cc_freq_measure_clk",
479 .parent_hws = (const struct clk_hw*[]) {
480 &gpu_cc_xo_div_clk_src.clkr.hw,
481 },
482 .num_parents = 1,
483 .flags = CLK_SET_RATE_PARENT,
484 .ops = &clk_branch2_ops,
485 },
486 },
487 };
488
489 static struct clk_branch gpu_cc_gx_cxo_clk = {
490 .halt_reg = 0x90b8,
491 .halt_check = BRANCH_HALT,
492 .clkr = {
493 .enable_reg = 0x90b8,
494 .enable_mask = BIT(0),
495 .hw.init = &(const struct clk_init_data) {
496 .name = "gpu_cc_gx_cxo_clk",
497 .parent_hws = (const struct clk_hw*[]) {
498 &gpu_cc_xo_clk_src.clkr.hw,
499 },
500 .num_parents = 1,
501 .flags = CLK_SET_RATE_PARENT,
502 .ops = &clk_branch2_ops,
503 },
504 },
505 };
506
507 static struct clk_branch gpu_cc_gx_ff_clk = {
508 .halt_reg = 0x90c0,
509 .halt_check = BRANCH_HALT,
510 .clkr = {
511 .enable_reg = 0x90c0,
512 .enable_mask = BIT(0),
513 .hw.init = &(const struct clk_init_data) {
514 .name = "gpu_cc_gx_ff_clk",
515 .parent_hws = (const struct clk_hw*[]) {
516 &gpu_cc_ff_clk_src.clkr.hw,
517 },
518 .num_parents = 1,
519 .flags = CLK_SET_RATE_PARENT,
520 .ops = &clk_branch2_ops,
521 },
522 },
523 };
524
525 static struct clk_branch gpu_cc_gx_gfx3d_clk = {
526 .halt_reg = 0x90a8,
527 .halt_check = BRANCH_HALT,
528 .clkr = {
529 .enable_reg = 0x90a8,
530 .enable_mask = BIT(0),
531 .hw.init = &(const struct clk_init_data) {
532 .name = "gpu_cc_gx_gfx3d_clk",
533 .parent_hws = (const struct clk_hw*[]) {
534 &gpu_cc_gx_gfx3d_clk_src.clkr.hw,
535 },
536 .num_parents = 1,
537 .flags = CLK_SET_RATE_PARENT,
538 .ops = &clk_branch2_ops,
539 },
540 },
541 };
542
543 static struct clk_branch gpu_cc_gx_gfx3d_rdvm_clk = {
544 .halt_reg = 0x90c8,
545 .halt_check = BRANCH_HALT,
546 .clkr = {
547 .enable_reg = 0x90c8,
548 .enable_mask = BIT(0),
549 .hw.init = &(const struct clk_init_data) {
550 .name = "gpu_cc_gx_gfx3d_rdvm_clk",
551 .parent_hws = (const struct clk_hw*[]) {
552 &gpu_cc_gx_gfx3d_clk_src.clkr.hw,
553 },
554 .num_parents = 1,
555 .flags = CLK_SET_RATE_PARENT,
556 .ops = &clk_branch2_ops,
557 },
558 },
559 };
560
561 static struct clk_branch gpu_cc_gx_gmu_clk = {
562 .halt_reg = 0x90bc,
563 .halt_check = BRANCH_HALT,
564 .clkr = {
565 .enable_reg = 0x90bc,
566 .enable_mask = BIT(0),
567 .hw.init = &(const struct clk_init_data) {
568 .name = "gpu_cc_gx_gmu_clk",
569 .parent_hws = (const struct clk_hw*[]) {
570 &gpu_cc_gmu_clk_src.clkr.hw,
571 },
572 .num_parents = 1,
573 .flags = CLK_SET_RATE_PARENT,
574 .ops = &clk_branch2_ops,
575 },
576 },
577 };
578
579 static struct clk_branch gpu_cc_gx_vsense_clk = {
580 .halt_reg = 0x90b0,
581 .halt_check = BRANCH_HALT,
582 .clkr = {
583 .enable_reg = 0x90b0,
584 .enable_mask = BIT(0),
585 .hw.init = &(const struct clk_init_data) {
586 .name = "gpu_cc_gx_vsense_clk",
587 .ops = &clk_branch2_ops,
588 },
589 },
590 };
591
592 static struct clk_branch gpu_cc_hub_aon_clk = {
593 .halt_reg = 0x93e8,
594 .halt_check = BRANCH_HALT,
595 .clkr = {
596 .enable_reg = 0x93e8,
597 .enable_mask = BIT(0),
598 .hw.init = &(const struct clk_init_data) {
599 .name = "gpu_cc_hub_aon_clk",
600 .parent_hws = (const struct clk_hw*[]) {
601 &gpu_cc_hub_clk_src.clkr.hw,
602 },
603 .num_parents = 1,
604 .flags = CLK_SET_RATE_PARENT,
605 .ops = &clk_branch2_aon_ops,
606 },
607 },
608 };
609
610 static struct clk_branch gpu_cc_hub_cx_int_clk = {
611 .halt_reg = 0x9148,
612 .halt_check = BRANCH_HALT,
613 .clkr = {
614 .enable_reg = 0x9148,
615 .enable_mask = BIT(0),
616 .hw.init = &(const struct clk_init_data) {
617 .name = "gpu_cc_hub_cx_int_clk",
618 .parent_hws = (const struct clk_hw*[]) {
619 &gpu_cc_hub_cx_int_div_clk_src.clkr.hw,
620 },
621 .num_parents = 1,
622 .flags = CLK_SET_RATE_PARENT,
623 .ops = &clk_branch2_aon_ops,
624 },
625 },
626 };
627
628 static struct clk_branch gpu_cc_memnoc_gfx_clk = {
629 .halt_reg = 0x9150,
630 .halt_check = BRANCH_HALT,
631 .clkr = {
632 .enable_reg = 0x9150,
633 .enable_mask = BIT(0),
634 .hw.init = &(const struct clk_init_data) {
635 .name = "gpu_cc_memnoc_gfx_clk",
636 .ops = &clk_branch2_ops,
637 },
638 },
639 };
640
641 static struct clk_branch gpu_cc_mnd1x_0_gfx3d_clk = {
642 .halt_reg = 0x9288,
643 .halt_check = BRANCH_HALT,
644 .clkr = {
645 .enable_reg = 0x9288,
646 .enable_mask = BIT(0),
647 .hw.init = &(const struct clk_init_data) {
648 .name = "gpu_cc_mnd1x_0_gfx3d_clk",
649 .parent_hws = (const struct clk_hw*[]) {
650 &gpu_cc_gx_gfx3d_clk_src.clkr.hw,
651 },
652 .num_parents = 1,
653 .flags = CLK_SET_RATE_PARENT,
654 .ops = &clk_branch2_ops,
655 },
656 },
657 };
658
659 static struct clk_branch gpu_cc_sleep_clk = {
660 .halt_reg = 0x9134,
661 .halt_check = BRANCH_HALT,
662 .clkr = {
663 .enable_reg = 0x9134,
664 .enable_mask = BIT(0),
665 .hw.init = &(const struct clk_init_data) {
666 .name = "gpu_cc_sleep_clk",
667 .ops = &clk_branch2_ops,
668 },
669 },
670 };
671
672 static struct gdsc gpu_cc_cx_gdsc = {
673 .gdscr = 0x9108,
674 .gds_hw_ctrl = 0x953c,
675 .clk_dis_wait_val = 8,
676 .pd = {
677 .name = "gpu_cx_gdsc",
678 },
679 .pwrsts = PWRSTS_OFF_ON,
680 .flags = VOTABLE | RETAIN_FF_ENABLE,
681 };
682
683 static struct gdsc gpu_cc_gx_gdsc = {
684 .gdscr = 0x905c,
685 .clamp_io_ctrl = 0x9504,
686 .resets = (unsigned int []){ GPU_CC_GX_BCR,
687 GPU_CC_ACD_BCR,
688 GPU_CC_GX_ACD_IROOT_BCR },
689 .reset_count = 3,
690 .pd = {
691 .name = "gpu_gx_gdsc",
692 .power_on = gdsc_gx_do_nothing_enable,
693 },
694 .pwrsts = PWRSTS_OFF_ON,
695 .flags = CLAMP_IO | AON_RESET | SW_RESET | POLL_CFG_GDSCR,
696 };
697
698 static struct clk_regmap *gpu_cc_sm4450_clocks[] = {
699 [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
700 [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
701 [GPU_CC_CX_FF_CLK] = &gpu_cc_cx_ff_clk.clkr,
702 [GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr,
703 [GPU_CC_CX_GFX3D_SLV_CLK] = &gpu_cc_cx_gfx3d_slv_clk.clkr,
704 [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
705 [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
706 [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
707 [GPU_CC_DEMET_DIV_CLK_SRC] = &gpu_cc_demet_div_clk_src.clkr,
708 [GPU_CC_FF_CLK_SRC] = &gpu_cc_ff_clk_src.clkr,
709 [GPU_CC_FREQ_MEASURE_CLK] = &gpu_cc_freq_measure_clk.clkr,
710 [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
711 [GPU_CC_GX_CXO_CLK] = &gpu_cc_gx_cxo_clk.clkr,
712 [GPU_CC_GX_FF_CLK] = &gpu_cc_gx_ff_clk.clkr,
713 [GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr,
714 [GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr,
715 [GPU_CC_GX_GFX3D_RDVM_CLK] = &gpu_cc_gx_gfx3d_rdvm_clk.clkr,
716 [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
717 [GPU_CC_GX_VSENSE_CLK] = &gpu_cc_gx_vsense_clk.clkr,
718 [GPU_CC_HUB_AHB_DIV_CLK_SRC] = &gpu_cc_hub_ahb_div_clk_src.clkr,
719 [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr,
720 [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr,
721 [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr,
722 [GPU_CC_HUB_CX_INT_DIV_CLK_SRC] = &gpu_cc_hub_cx_int_div_clk_src.clkr,
723 [GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr,
724 [GPU_CC_MND1X_0_GFX3D_CLK] = &gpu_cc_mnd1x_0_gfx3d_clk.clkr,
725 [GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
726 [GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
727 [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr,
728 [GPU_CC_XO_CLK_SRC] = &gpu_cc_xo_clk_src.clkr,
729 [GPU_CC_XO_DIV_CLK_SRC] = &gpu_cc_xo_div_clk_src.clkr,
730 };
731
732 static struct gdsc *gpu_cc_sm4450_gdscs[] = {
733 [GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc,
734 [GPU_CC_GX_GDSC] = &gpu_cc_gx_gdsc,
735 };
736
737 static const struct qcom_reset_map gpu_cc_sm4450_resets[] = {
738 [GPU_CC_CB_BCR] = { 0x93a0 },
739 [GPU_CC_CX_BCR] = { 0x9104 },
740 [GPU_CC_GX_BCR] = { 0x9058 },
741 [GPU_CC_FAST_HUB_BCR] = { 0x93e4 },
742 [GPU_CC_ACD_BCR] = { 0x9358 },
743 [GPU_CC_FF_BCR] = { 0x9470 },
744 [GPU_CC_GFX3D_AON_BCR] = { 0x9198 },
745 [GPU_CC_GMU_BCR] = { 0x9314 },
746 [GPU_CC_RBCPR_BCR] = { 0x91e0 },
747 [GPU_CC_XO_BCR] = { 0x9000 },
748 [GPU_CC_GX_ACD_IROOT_BCR] = { 0x958c },
749 };
750
751 static const struct regmap_config gpu_cc_sm4450_regmap_config = {
752 .reg_bits = 32,
753 .reg_stride = 4,
754 .val_bits = 32,
755 .max_register = 0x95c0,
756 .fast_io = true,
757 };
758
759 static const struct qcom_cc_desc gpu_cc_sm4450_desc = {
760 .config = &gpu_cc_sm4450_regmap_config,
761 .clks = gpu_cc_sm4450_clocks,
762 .num_clks = ARRAY_SIZE(gpu_cc_sm4450_clocks),
763 .resets = gpu_cc_sm4450_resets,
764 .num_resets = ARRAY_SIZE(gpu_cc_sm4450_resets),
765 .gdscs = gpu_cc_sm4450_gdscs,
766 .num_gdscs = ARRAY_SIZE(gpu_cc_sm4450_gdscs),
767 };
768
769 static const struct of_device_id gpu_cc_sm4450_match_table[] = {
770 { .compatible = "qcom,sm4450-gpucc" },
771 { }
772 };
773 MODULE_DEVICE_TABLE(of, gpu_cc_sm4450_match_table);
774
gpu_cc_sm4450_probe(struct platform_device * pdev)775 static int gpu_cc_sm4450_probe(struct platform_device *pdev)
776 {
777 struct regmap *regmap;
778
779 regmap = qcom_cc_map(pdev, &gpu_cc_sm4450_desc);
780 if (IS_ERR(regmap))
781 return PTR_ERR(regmap);
782
783 clk_lucid_evo_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
784 clk_lucid_evo_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
785
786 /* Keep some clocks always enabled */
787 qcom_branch_set_clk_en(regmap, 0x93a4); /* GPU_CC_CB_CLK */
788 qcom_branch_set_clk_en(regmap, 0x9004); /* GPU_CC_CXO_AON_CLK */
789 qcom_branch_set_clk_en(regmap, 0x900c); /* GPU_CC_DEMET_CLK */
790
791 return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm4450_desc, regmap);
792 }
793
794 static struct platform_driver gpu_cc_sm4450_driver = {
795 .probe = gpu_cc_sm4450_probe,
796 .driver = {
797 .name = "gpucc-sm4450",
798 .of_match_table = gpu_cc_sm4450_match_table,
799 },
800 };
801
802 module_platform_driver(gpu_cc_sm4450_driver);
803
804 MODULE_DESCRIPTION("QTI GPUCC SM4450 Driver");
805 MODULE_LICENSE("GPL");
806