1490cd45a654acf87383b42e06fb38724ab6cac1
[releases.git] / gpucc-sc7280.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
4  */
5
6 #include <linux/clk-provider.h>
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
9 #include <linux/regmap.h>
10
11 #include <dt-bindings/clock/qcom,gpucc-sc7280.h>
12
13 #include "clk-alpha-pll.h"
14 #include "clk-branch.h"
15 #include "clk-rcg.h"
16 #include "clk-regmap-divider.h"
17 #include "common.h"
18 #include "reset.h"
19 #include "gdsc.h"
20
21 enum {
22         P_BI_TCXO,
23         P_GCC_GPU_GPLL0_CLK_SRC,
24         P_GCC_GPU_GPLL0_DIV_CLK_SRC,
25         P_GPU_CC_PLL0_OUT_MAIN,
26         P_GPU_CC_PLL1_OUT_MAIN,
27 };
28
29 static const struct pll_vco lucid_vco[] = {
30         { 249600000, 2000000000, 0 },
31 };
32
33 static struct clk_alpha_pll gpu_cc_pll0 = {
34         .offset = 0x0,
35         .vco_table = lucid_vco,
36         .num_vco = ARRAY_SIZE(lucid_vco),
37         .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
38         .clkr = {
39                 .hw.init = &(struct clk_init_data){
40                         .name = "gpu_cc_pll0",
41                         .parent_data = &(const struct clk_parent_data){
42                                 .fw_name = "bi_tcxo",
43                         },
44                         .num_parents = 1,
45                         .ops = &clk_alpha_pll_lucid_ops,
46                 },
47         },
48 };
49
50 /* 500MHz Configuration */
51 static const struct alpha_pll_config gpu_cc_pll1_config = {
52         .l = 0x1A,
53         .alpha = 0xAAA,
54         .config_ctl_val = 0x20485699,
55         .config_ctl_hi_val = 0x00002261,
56         .config_ctl_hi1_val = 0x329A299C,
57         .user_ctl_val = 0x00000001,
58         .user_ctl_hi_val = 0x00000805,
59         .user_ctl_hi1_val = 0x00000000,
60 };
61
62 static struct clk_alpha_pll gpu_cc_pll1 = {
63         .offset = 0x100,
64         .vco_table = lucid_vco,
65         .num_vco = ARRAY_SIZE(lucid_vco),
66         .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
67         .clkr = {
68                 .hw.init = &(struct clk_init_data){
69                         .name = "gpu_cc_pll1",
70                         .parent_data = &(const struct clk_parent_data){
71                                 .fw_name = "bi_tcxo",
72                         },
73                         .num_parents = 1,
74                         .ops = &clk_alpha_pll_lucid_ops,
75                 },
76         },
77 };
78
79 static const struct parent_map gpu_cc_parent_map_0[] = {
80         { P_BI_TCXO, 0 },
81         { P_GPU_CC_PLL0_OUT_MAIN, 1 },
82         { P_GPU_CC_PLL1_OUT_MAIN, 3 },
83         { P_GCC_GPU_GPLL0_CLK_SRC, 5 },
84         { P_GCC_GPU_GPLL0_DIV_CLK_SRC, 6 },
85 };
86
87 static const struct clk_parent_data gpu_cc_parent_data_0[] = {
88         { .fw_name = "bi_tcxo" },
89         { .hw = &gpu_cc_pll0.clkr.hw },
90         { .hw = &gpu_cc_pll1.clkr.hw },
91         { .fw_name = "gcc_gpu_gpll0_clk_src" },
92         { .fw_name = "gcc_gpu_gpll0_div_clk_src" },
93 };
94
95 static const struct parent_map gpu_cc_parent_map_1[] = {
96         { P_BI_TCXO, 0 },
97         { P_GPU_CC_PLL1_OUT_MAIN, 3 },
98         { P_GCC_GPU_GPLL0_CLK_SRC, 5 },
99         { P_GCC_GPU_GPLL0_DIV_CLK_SRC, 6 },
100 };
101
102 static const struct clk_parent_data gpu_cc_parent_data_1[] = {
103         { .fw_name = "bi_tcxo", },
104         { .hw = &gpu_cc_pll1.clkr.hw },
105         { .fw_name = "gcc_gpu_gpll0_clk_src", },
106         { .fw_name = "gcc_gpu_gpll0_div_clk_src", },
107 };
108
109 static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
110         F(19200000, P_BI_TCXO, 1, 0, 0),
111         F(200000000, P_GCC_GPU_GPLL0_DIV_CLK_SRC, 1.5, 0, 0),
112         F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
113         { }
114 };
115
116 static struct clk_rcg2 gpu_cc_gmu_clk_src = {
117         .cmd_rcgr = 0x1120,
118         .mnd_width = 0,
119         .hid_width = 5,
120         .parent_map = gpu_cc_parent_map_0,
121         .freq_tbl = ftbl_gpu_cc_gmu_clk_src,
122         .clkr.hw.init = &(struct clk_init_data){
123                 .name = "gpu_cc_gmu_clk_src",
124                 .parent_data = gpu_cc_parent_data_0,
125                 .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
126                 .ops = &clk_rcg2_shared_ops,
127         },
128 };
129
130 static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = {
131         F(150000000, P_GCC_GPU_GPLL0_DIV_CLK_SRC, 2, 0, 0),
132         F(240000000, P_GCC_GPU_GPLL0_CLK_SRC, 2.5, 0, 0),
133         F(300000000, P_GCC_GPU_GPLL0_CLK_SRC, 2, 0, 0),
134         { }
135 };
136
137 static struct clk_rcg2 gpu_cc_hub_clk_src = {
138         .cmd_rcgr = 0x117c,
139         .mnd_width = 0,
140         .hid_width = 5,
141         .parent_map = gpu_cc_parent_map_1,
142         .freq_tbl = ftbl_gpu_cc_hub_clk_src,
143         .clkr.hw.init = &(struct clk_init_data){
144                 .name = "gpu_cc_hub_clk_src",
145                 .parent_data = gpu_cc_parent_data_1,
146                 .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
147                 .ops = &clk_rcg2_shared_ops,
148         },
149 };
150
151 static struct clk_regmap_div gpu_cc_hub_ahb_div_clk_src = {
152         .reg = 0x11c0,
153         .shift = 0,
154         .width = 4,
155         .clkr.hw.init = &(struct clk_init_data) {
156                 .name = "gpu_cc_hub_ahb_div_clk_src",
157                 .parent_hws = (const struct clk_hw*[]){
158                         &gpu_cc_hub_clk_src.clkr.hw,
159                 },
160                 .num_parents = 1,
161                 .flags = CLK_SET_RATE_PARENT,
162                 .ops = &clk_regmap_div_ro_ops,
163         },
164 };
165
166 static struct clk_regmap_div gpu_cc_hub_cx_int_div_clk_src = {
167         .reg = 0x11bc,
168         .shift = 0,
169         .width = 4,
170         .clkr.hw.init = &(struct clk_init_data) {
171                 .name = "gpu_cc_hub_cx_int_div_clk_src",
172                 .parent_hws = (const struct clk_hw*[]){
173                         &gpu_cc_hub_clk_src.clkr.hw,
174                 },
175                 .num_parents = 1,
176                 .flags = CLK_SET_RATE_PARENT,
177                 .ops = &clk_regmap_div_ro_ops,
178         },
179 };
180
181 static struct clk_branch gpu_cc_ahb_clk = {
182         .halt_reg = 0x1078,
183         .halt_check = BRANCH_HALT_DELAY,
184         .clkr = {
185                 .enable_reg = 0x1078,
186                 .enable_mask = BIT(0),
187                 .hw.init = &(struct clk_init_data){
188                         .name = "gpu_cc_ahb_clk",
189                         .parent_hws = (const struct clk_hw*[]){
190                                 &gpu_cc_hub_ahb_div_clk_src.clkr.hw,
191                         },
192                         .num_parents = 1,
193                         .flags = CLK_SET_RATE_PARENT,
194                         .ops = &clk_branch2_ops,
195                 },
196         },
197 };
198
199 static struct clk_branch gpu_cc_crc_ahb_clk = {
200         .halt_reg = 0x107c,
201         .halt_check = BRANCH_HALT_VOTED,
202         .clkr = {
203                 .enable_reg = 0x107c,
204                 .enable_mask = BIT(0),
205                 .hw.init = &(struct clk_init_data){
206                         .name = "gpu_cc_crc_ahb_clk",
207                         .parent_hws = (const struct clk_hw*[]){
208                                 &gpu_cc_hub_ahb_div_clk_src.clkr.hw,
209                         },
210                         .num_parents = 1,
211                         .flags = CLK_SET_RATE_PARENT,
212                         .ops = &clk_branch2_ops,
213                 },
214         },
215 };
216
217 static struct clk_branch gpu_cc_cx_gmu_clk = {
218         .halt_reg = 0x1098,
219         .halt_check = BRANCH_HALT,
220         .clkr = {
221                 .enable_reg = 0x1098,
222                 .enable_mask = BIT(0),
223                 .hw.init = &(struct clk_init_data){
224                         .name = "gpu_cc_cx_gmu_clk",
225                         .parent_hws = (const struct clk_hw*[]){
226                                 &gpu_cc_gmu_clk_src.clkr.hw,
227                         },
228                         .num_parents = 1,
229                         .flags = CLK_SET_RATE_PARENT,
230                         .ops = &clk_branch2_aon_ops,
231                 },
232         },
233 };
234
235 static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
236         .halt_reg = 0x108c,
237         .halt_check = BRANCH_HALT_VOTED,
238         .clkr = {
239                 .enable_reg = 0x108c,
240                 .enable_mask = BIT(0),
241                 .hw.init = &(struct clk_init_data){
242                         .name = "gpu_cc_cx_snoc_dvm_clk",
243                         .ops = &clk_branch2_ops,
244                 },
245         },
246 };
247
248 static struct clk_branch gpu_cc_cxo_aon_clk = {
249         .halt_reg = 0x1004,
250         .halt_check = BRANCH_HALT_VOTED,
251         .clkr = {
252                 .enable_reg = 0x1004,
253                 .enable_mask = BIT(0),
254                 .hw.init = &(struct clk_init_data){
255                         .name = "gpu_cc_cxo_aon_clk",
256                         .ops = &clk_branch2_ops,
257                 },
258         },
259 };
260
261 static struct clk_branch gpu_cc_cxo_clk = {
262         .halt_reg = 0x109c,
263         .halt_check = BRANCH_HALT,
264         .clkr = {
265                 .enable_reg = 0x109c,
266                 .enable_mask = BIT(0),
267                 .hw.init = &(struct clk_init_data){
268                         .name = "gpu_cc_cxo_clk",
269                         .ops = &clk_branch2_aon_ops,
270                 },
271         },
272 };
273
274 static struct clk_branch gpu_cc_gx_gmu_clk = {
275         .halt_reg = 0x1064,
276         .halt_check = BRANCH_HALT,
277         .clkr = {
278                 .enable_reg = 0x1064,
279                 .enable_mask = BIT(0),
280                 .hw.init = &(struct clk_init_data){
281                         .name = "gpu_cc_gx_gmu_clk",
282                         .parent_hws = (const struct clk_hw*[]){
283                                 &gpu_cc_gmu_clk_src.clkr.hw,
284                         },
285                         .num_parents = 1,
286                         .flags = CLK_SET_RATE_PARENT,
287                         .ops = &clk_branch2_ops,
288                 },
289         },
290 };
291
292 static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = {
293         .halt_reg = 0x5000,
294         .halt_check = BRANCH_VOTED,
295         .clkr = {
296                 .enable_reg = 0x5000,
297                 .enable_mask = BIT(0),
298                 .hw.init = &(struct clk_init_data){
299                         .name = "gpu_cc_hlos1_vote_gpu_smmu_clk",
300                         .ops = &clk_branch2_ops,
301                 },
302         },
303 };
304
305 static struct clk_branch gpu_cc_hub_aon_clk = {
306         .halt_reg = 0x1178,
307         .halt_check = BRANCH_HALT,
308         .clkr = {
309                 .enable_reg = 0x1178,
310                 .enable_mask = BIT(0),
311                 .hw.init = &(struct clk_init_data){
312                         .name = "gpu_cc_hub_aon_clk",
313                         .parent_hws = (const struct clk_hw*[]){
314                                 &gpu_cc_hub_clk_src.clkr.hw,
315                         },
316                         .num_parents = 1,
317                         .flags = CLK_SET_RATE_PARENT,
318                         .ops = &clk_branch2_aon_ops,
319                 },
320         },
321 };
322
323 static struct clk_branch gpu_cc_hub_cx_int_clk = {
324         .halt_reg = 0x1204,
325         .halt_check = BRANCH_HALT,
326         .clkr = {
327                 .enable_reg = 0x1204,
328                 .enable_mask = BIT(0),
329                 .hw.init = &(struct clk_init_data){
330                         .name = "gpu_cc_hub_cx_int_clk",
331                         .parent_hws = (const struct clk_hw*[]){
332                                 &gpu_cc_hub_cx_int_div_clk_src.clkr.hw,
333                         },
334                         .num_parents = 1,
335                         .flags = CLK_SET_RATE_PARENT,
336                         .ops = &clk_branch2_aon_ops,
337                 },
338         },
339 };
340
341 static struct clk_branch gpu_cc_mnd1x_0_gfx3d_clk = {
342         .halt_reg = 0x802c,
343         .halt_check = BRANCH_HALT_SKIP,
344         .clkr = {
345                 .enable_reg = 0x802c,
346                 .enable_mask = BIT(0),
347                 .hw.init = &(struct clk_init_data){
348                         .name = "gpu_cc_mnd1x_0_gfx3d_clk",
349                         .ops = &clk_branch2_ops,
350                 },
351         },
352 };
353
354 static struct clk_branch gpu_cc_mnd1x_1_gfx3d_clk = {
355         .halt_reg = 0x8030,
356         .halt_check = BRANCH_HALT_SKIP,
357         .clkr = {
358                 .enable_reg = 0x8030,
359                 .enable_mask = BIT(0),
360                 .hw.init = &(struct clk_init_data){
361                         .name = "gpu_cc_mnd1x_1_gfx3d_clk",
362                         .ops = &clk_branch2_ops,
363                 },
364         },
365 };
366
367 static struct clk_branch gpu_cc_sleep_clk = {
368         .halt_reg = 0x1090,
369         .halt_check = BRANCH_HALT_VOTED,
370         .clkr = {
371                 .enable_reg = 0x1090,
372                 .enable_mask = BIT(0),
373                 .hw.init = &(struct clk_init_data){
374                         .name = "gpu_cc_sleep_clk",
375                         .ops = &clk_branch2_ops,
376                 },
377         },
378 };
379
380 static struct gdsc cx_gdsc = {
381         .gdscr = 0x106c,
382         .gds_hw_ctrl = 0x1540,
383         .pd = {
384                 .name = "cx_gdsc",
385         },
386         .pwrsts = PWRSTS_OFF_ON,
387         .flags = VOTABLE | RETAIN_FF_ENABLE,
388 };
389
390 static struct gdsc gx_gdsc = {
391         .gdscr = 0x100c,
392         .clamp_io_ctrl = 0x1508,
393         .pd = {
394                 .name = "gx_gdsc",
395                 .power_on = gdsc_gx_do_nothing_enable,
396         },
397         .pwrsts = PWRSTS_OFF_ON,
398         .flags = CLAMP_IO | RETAIN_FF_ENABLE,
399 };
400
401 static struct gdsc *gpu_cc_sc7180_gdscs[] = {
402         [GPU_CC_CX_GDSC] = &cx_gdsc,
403         [GPU_CC_GX_GDSC] = &gx_gdsc,
404 };
405
406 static struct clk_regmap *gpu_cc_sc7280_clocks[] = {
407         [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
408         [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
409         [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
410         [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
411         [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
412         [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
413         [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
414         [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
415         [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr,
416         [GPU_CC_HUB_AHB_DIV_CLK_SRC] = &gpu_cc_hub_ahb_div_clk_src.clkr,
417         [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr,
418         [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr,
419         [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr,
420         [GPU_CC_HUB_CX_INT_DIV_CLK_SRC] = &gpu_cc_hub_cx_int_div_clk_src.clkr,
421         [GPU_CC_MND1X_0_GFX3D_CLK] = &gpu_cc_mnd1x_0_gfx3d_clk.clkr,
422         [GPU_CC_MND1X_1_GFX3D_CLK] = &gpu_cc_mnd1x_1_gfx3d_clk.clkr,
423         [GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
424         [GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
425         [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr,
426 };
427
428 static const struct regmap_config gpu_cc_sc7280_regmap_config = {
429         .reg_bits = 32,
430         .reg_stride = 4,
431         .val_bits = 32,
432         .max_register = 0x8030,
433         .fast_io = true,
434 };
435
436 static const struct qcom_cc_desc gpu_cc_sc7280_desc = {
437         .config = &gpu_cc_sc7280_regmap_config,
438         .clks = gpu_cc_sc7280_clocks,
439         .num_clks = ARRAY_SIZE(gpu_cc_sc7280_clocks),
440         .gdscs = gpu_cc_sc7180_gdscs,
441         .num_gdscs = ARRAY_SIZE(gpu_cc_sc7180_gdscs),
442 };
443
444 static const struct of_device_id gpu_cc_sc7280_match_table[] = {
445         { .compatible = "qcom,sc7280-gpucc" },
446         { }
447 };
448 MODULE_DEVICE_TABLE(of, gpu_cc_sc7280_match_table);
449
450 static int gpu_cc_sc7280_probe(struct platform_device *pdev)
451 {
452         struct regmap *regmap;
453
454         regmap = qcom_cc_map(pdev, &gpu_cc_sc7280_desc);
455         if (IS_ERR(regmap))
456                 return PTR_ERR(regmap);
457
458         clk_lucid_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
459
460         /*
461          * Keep the clocks always-ON
462          * GPU_CC_CB_CLK, GPUCC_CX_GMU_CLK
463          */
464         regmap_update_bits(regmap, 0x1170, BIT(0), BIT(0));
465         regmap_update_bits(regmap, 0x1098, BIT(0), BIT(0));
466         regmap_update_bits(regmap, 0x1098, BIT(13), BIT(13));
467
468         return qcom_cc_really_probe(pdev, &gpu_cc_sc7280_desc, regmap);
469 }
470
471 static struct platform_driver gpu_cc_sc7280_driver = {
472         .probe = gpu_cc_sc7280_probe,
473         .driver = {
474                 .name = "gpu_cc-sc7280",
475                 .of_match_table = gpu_cc_sc7280_match_table,
476         },
477 };
478
479 static int __init gpu_cc_sc7280_init(void)
480 {
481         return platform_driver_register(&gpu_cc_sc7280_driver);
482 }
483 subsys_initcall(gpu_cc_sc7280_init);
484
485 static void __exit gpu_cc_sc7280_exit(void)
486 {
487         platform_driver_unregister(&gpu_cc_sc7280_driver);
488 }
489 module_exit(gpu_cc_sc7280_exit);
490
491 MODULE_DESCRIPTION("QTI GPU_CC SC7280 Driver");
492 MODULE_LICENSE("GPL v2");