Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
24enum {
25 DT_BI_TCXO,
26 DT_GPLL0_OUT_MAIN,
27 DT_GPLL0_OUT_MAIN_DIV,
28};
29
30enum {
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
42static const struct pll_vco lucid_evo_vco[] = {
43 { 249600000, 2020000000, 0 },
44};
45
46/* 680.0 MHz Configuration */
47static 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
57static 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 */
75static 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
85static 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
102static 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
108static 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
114static 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
122static 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
130static 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
139static 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
148static 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
155static 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
162static const struct parent_map gpu_cc_parent_map_4[] = {
163 { P_BI_TCXO, 0 },
164};
165
166static const struct clk_parent_data gpu_cc_parent_data_4[] = {
167 { .index = DT_BI_TCXO },
168};
169
170static 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
175static 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
190static 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
205static 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
216static 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
231static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = {
232 F(150000000, P_GPLL0_OUT_MAIN_DIV, 2, 0, 0),
233 { }
234};
235
236static 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
251static const struct freq_tbl ftbl_gpu_cc_xo_clk_src[] = {
252 F(19200000, P_BI_TCXO, 1, 0, 0),
253 { }
254};
255
256static 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
271static 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
286static 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
301static 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
316static 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
331static 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
349static 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
367static 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
385static 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
403static 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
421static 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
439static 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
452static 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
470static 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
488static 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
506static 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
524static 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
542static 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
560static 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
578static 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
591static 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
609static 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
627static 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
640static 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
658static 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
671static 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
682static 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
697static 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
731static 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
736static 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
750static 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
758static 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
768static const struct of_device_id gpu_cc_sm4450_match_table[] = {
769 { .compatible = "qcom,sm4450-gpucc" },
770 { }
771};
772MODULE_DEVICE_TABLE(of, gpu_cc_sm4450_match_table);
773
774static 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
793static 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
801module_platform_driver(gpu_cc_sm4450_driver);
802
803MODULE_DESCRIPTION("QTI GPUCC SM4450 Driver");
804MODULE_LICENSE("GPL");