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