xref: /linux/drivers/clk/qcom/gpucc-sm4450.c (revision d63c77c5)
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