1*30eb0e76SKonrad Dybcio // SPDX-License-Identifier: GPL-2.0-only
2*30eb0e76SKonrad Dybcio /*
3*30eb0e76SKonrad Dybcio * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved.
4*30eb0e76SKonrad Dybcio * Copyright (c) 2024, Linaro Limited
5*30eb0e76SKonrad Dybcio */
6*30eb0e76SKonrad Dybcio
7*30eb0e76SKonrad Dybcio #include <linux/clk-provider.h>
8*30eb0e76SKonrad Dybcio #include <linux/kernel.h>
9*30eb0e76SKonrad Dybcio #include <linux/module.h>
10*30eb0e76SKonrad Dybcio #include <linux/platform_device.h>
11*30eb0e76SKonrad Dybcio #include <linux/regmap.h>
12*30eb0e76SKonrad Dybcio
13*30eb0e76SKonrad Dybcio #include <dt-bindings/clock/qcom,sar2130p-gpucc.h>
14*30eb0e76SKonrad Dybcio #include <dt-bindings/reset/qcom,sar2130p-gpucc.h>
15*30eb0e76SKonrad Dybcio
16*30eb0e76SKonrad Dybcio #include "clk-alpha-pll.h"
17*30eb0e76SKonrad Dybcio #include "clk-branch.h"
18*30eb0e76SKonrad Dybcio #include "clk-rcg.h"
19*30eb0e76SKonrad Dybcio #include "common.h"
20*30eb0e76SKonrad Dybcio #include "gdsc.h"
21*30eb0e76SKonrad Dybcio #include "reset.h"
22*30eb0e76SKonrad Dybcio
23*30eb0e76SKonrad Dybcio enum {
24*30eb0e76SKonrad Dybcio DT_BI_TCXO,
25*30eb0e76SKonrad Dybcio DT_GPLL0_OUT_MAIN,
26*30eb0e76SKonrad Dybcio DT_GPLL0_OUT_MAIN_DIV,
27*30eb0e76SKonrad Dybcio };
28*30eb0e76SKonrad Dybcio
29*30eb0e76SKonrad Dybcio enum {
30*30eb0e76SKonrad Dybcio P_BI_TCXO,
31*30eb0e76SKonrad Dybcio P_GPLL0_OUT_MAIN,
32*30eb0e76SKonrad Dybcio P_GPLL0_OUT_MAIN_DIV,
33*30eb0e76SKonrad Dybcio P_GPU_CC_PLL0_OUT_MAIN,
34*30eb0e76SKonrad Dybcio P_GPU_CC_PLL1_OUT_MAIN,
35*30eb0e76SKonrad Dybcio };
36*30eb0e76SKonrad Dybcio
37*30eb0e76SKonrad Dybcio static const struct pll_vco lucid_ole_vco[] = {
38*30eb0e76SKonrad Dybcio { 249600000, 2000000000, 0 },
39*30eb0e76SKonrad Dybcio };
40*30eb0e76SKonrad Dybcio
41*30eb0e76SKonrad Dybcio /* 470MHz Configuration */
42*30eb0e76SKonrad Dybcio static const struct alpha_pll_config gpu_cc_pll0_config = {
43*30eb0e76SKonrad Dybcio .l = 0x18,
44*30eb0e76SKonrad Dybcio .alpha = 0x7aaa,
45*30eb0e76SKonrad Dybcio .config_ctl_val = 0x20485699,
46*30eb0e76SKonrad Dybcio .config_ctl_hi_val = 0x00182261,
47*30eb0e76SKonrad Dybcio .config_ctl_hi1_val = 0x82aa299c,
48*30eb0e76SKonrad Dybcio .test_ctl_val = 0x00000000,
49*30eb0e76SKonrad Dybcio .test_ctl_hi_val = 0x00000003,
50*30eb0e76SKonrad Dybcio .test_ctl_hi1_val = 0x00009000,
51*30eb0e76SKonrad Dybcio .test_ctl_hi2_val = 0x00000034,
52*30eb0e76SKonrad Dybcio .user_ctl_val = 0x00000000,
53*30eb0e76SKonrad Dybcio .user_ctl_hi_val = 0x00000005,
54*30eb0e76SKonrad Dybcio };
55*30eb0e76SKonrad Dybcio
56*30eb0e76SKonrad Dybcio static struct clk_alpha_pll gpu_cc_pll0 = {
57*30eb0e76SKonrad Dybcio .offset = 0x0,
58*30eb0e76SKonrad Dybcio .vco_table = lucid_ole_vco,
59*30eb0e76SKonrad Dybcio .num_vco = ARRAY_SIZE(lucid_ole_vco),
60*30eb0e76SKonrad Dybcio .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
61*30eb0e76SKonrad Dybcio .clkr = {
62*30eb0e76SKonrad Dybcio .hw.init = &(const struct clk_init_data) {
63*30eb0e76SKonrad Dybcio .name = "gpu_cc_pll0",
64*30eb0e76SKonrad Dybcio .parent_data = &(const struct clk_parent_data) {
65*30eb0e76SKonrad Dybcio .index = DT_BI_TCXO,
66*30eb0e76SKonrad Dybcio },
67*30eb0e76SKonrad Dybcio .num_parents = 1,
68*30eb0e76SKonrad Dybcio .ops = &clk_alpha_pll_lucid_evo_ops,
69*30eb0e76SKonrad Dybcio },
70*30eb0e76SKonrad Dybcio },
71*30eb0e76SKonrad Dybcio };
72*30eb0e76SKonrad Dybcio
73*30eb0e76SKonrad Dybcio /* 440MHz Configuration */
74*30eb0e76SKonrad Dybcio static const struct alpha_pll_config gpu_cc_pll1_config = {
75*30eb0e76SKonrad Dybcio .l = 0x16,
76*30eb0e76SKonrad Dybcio .alpha = 0xeaaa,
77*30eb0e76SKonrad Dybcio .config_ctl_val = 0x20485699,
78*30eb0e76SKonrad Dybcio .config_ctl_hi_val = 0x00182261,
79*30eb0e76SKonrad Dybcio .config_ctl_hi1_val = 0x82aa299c,
80*30eb0e76SKonrad Dybcio .test_ctl_val = 0x00000000,
81*30eb0e76SKonrad Dybcio .test_ctl_hi_val = 0x00000003,
82*30eb0e76SKonrad Dybcio .test_ctl_hi1_val = 0x00009000,
83*30eb0e76SKonrad Dybcio .test_ctl_hi2_val = 0x00000034,
84*30eb0e76SKonrad Dybcio .user_ctl_val = 0x00000000,
85*30eb0e76SKonrad Dybcio .user_ctl_hi_val = 0x00000005,
86*30eb0e76SKonrad Dybcio };
87*30eb0e76SKonrad Dybcio
88*30eb0e76SKonrad Dybcio static struct clk_alpha_pll gpu_cc_pll1 = {
89*30eb0e76SKonrad Dybcio .offset = 0x1000,
90*30eb0e76SKonrad Dybcio .vco_table = lucid_ole_vco,
91*30eb0e76SKonrad Dybcio .num_vco = ARRAY_SIZE(lucid_ole_vco),
92*30eb0e76SKonrad Dybcio .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
93*30eb0e76SKonrad Dybcio .clkr = {
94*30eb0e76SKonrad Dybcio .hw.init = &(const struct clk_init_data) {
95*30eb0e76SKonrad Dybcio .name = "gpu_cc_pll1",
96*30eb0e76SKonrad Dybcio .parent_data = &(const struct clk_parent_data) {
97*30eb0e76SKonrad Dybcio .index = DT_BI_TCXO,
98*30eb0e76SKonrad Dybcio },
99*30eb0e76SKonrad Dybcio .num_parents = 1,
100*30eb0e76SKonrad Dybcio .ops = &clk_alpha_pll_lucid_evo_ops,
101*30eb0e76SKonrad Dybcio },
102*30eb0e76SKonrad Dybcio },
103*30eb0e76SKonrad Dybcio };
104*30eb0e76SKonrad Dybcio
105*30eb0e76SKonrad Dybcio static const struct parent_map gpu_cc_parent_map_0[] = {
106*30eb0e76SKonrad Dybcio { P_BI_TCXO, 0 },
107*30eb0e76SKonrad Dybcio { P_GPLL0_OUT_MAIN, 5 },
108*30eb0e76SKonrad Dybcio { P_GPLL0_OUT_MAIN_DIV, 6 },
109*30eb0e76SKonrad Dybcio };
110*30eb0e76SKonrad Dybcio
111*30eb0e76SKonrad Dybcio static const struct clk_parent_data gpu_cc_parent_data_0[] = {
112*30eb0e76SKonrad Dybcio { .index = DT_BI_TCXO },
113*30eb0e76SKonrad Dybcio { .index = DT_GPLL0_OUT_MAIN },
114*30eb0e76SKonrad Dybcio { .index = DT_GPLL0_OUT_MAIN_DIV },
115*30eb0e76SKonrad Dybcio };
116*30eb0e76SKonrad Dybcio
117*30eb0e76SKonrad Dybcio static const struct parent_map gpu_cc_parent_map_1[] = {
118*30eb0e76SKonrad Dybcio { P_BI_TCXO, 0 },
119*30eb0e76SKonrad Dybcio { P_GPU_CC_PLL0_OUT_MAIN, 1 },
120*30eb0e76SKonrad Dybcio { P_GPU_CC_PLL1_OUT_MAIN, 3 },
121*30eb0e76SKonrad Dybcio { P_GPLL0_OUT_MAIN, 5 },
122*30eb0e76SKonrad Dybcio { P_GPLL0_OUT_MAIN_DIV, 6 },
123*30eb0e76SKonrad Dybcio };
124*30eb0e76SKonrad Dybcio
125*30eb0e76SKonrad Dybcio static const struct clk_parent_data gpu_cc_parent_data_1[] = {
126*30eb0e76SKonrad Dybcio { .index = DT_BI_TCXO },
127*30eb0e76SKonrad Dybcio { .hw = &gpu_cc_pll0.clkr.hw },
128*30eb0e76SKonrad Dybcio { .hw = &gpu_cc_pll1.clkr.hw },
129*30eb0e76SKonrad Dybcio { .index = DT_GPLL0_OUT_MAIN },
130*30eb0e76SKonrad Dybcio { .index = DT_GPLL0_OUT_MAIN_DIV },
131*30eb0e76SKonrad Dybcio };
132*30eb0e76SKonrad Dybcio
133*30eb0e76SKonrad Dybcio static const struct parent_map gpu_cc_parent_map_2[] = {
134*30eb0e76SKonrad Dybcio { P_BI_TCXO, 0 },
135*30eb0e76SKonrad Dybcio { P_GPU_CC_PLL1_OUT_MAIN, 3 },
136*30eb0e76SKonrad Dybcio { P_GPLL0_OUT_MAIN, 5 },
137*30eb0e76SKonrad Dybcio { P_GPLL0_OUT_MAIN_DIV, 6 },
138*30eb0e76SKonrad Dybcio };
139*30eb0e76SKonrad Dybcio
140*30eb0e76SKonrad Dybcio static const struct clk_parent_data gpu_cc_parent_data_2[] = {
141*30eb0e76SKonrad Dybcio { .index = DT_BI_TCXO },
142*30eb0e76SKonrad Dybcio { .hw = &gpu_cc_pll1.clkr.hw },
143*30eb0e76SKonrad Dybcio { .index = DT_GPLL0_OUT_MAIN },
144*30eb0e76SKonrad Dybcio { .index = DT_GPLL0_OUT_MAIN_DIV },
145*30eb0e76SKonrad Dybcio };
146*30eb0e76SKonrad Dybcio
147*30eb0e76SKonrad Dybcio static const struct freq_tbl ftbl_gpu_cc_ff_clk_src[] = {
148*30eb0e76SKonrad Dybcio F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
149*30eb0e76SKonrad Dybcio { }
150*30eb0e76SKonrad Dybcio };
151*30eb0e76SKonrad Dybcio
152*30eb0e76SKonrad Dybcio static struct clk_rcg2 gpu_cc_ff_clk_src = {
153*30eb0e76SKonrad Dybcio .cmd_rcgr = 0x9474,
154*30eb0e76SKonrad Dybcio .mnd_width = 0,
155*30eb0e76SKonrad Dybcio .hid_width = 5,
156*30eb0e76SKonrad Dybcio .parent_map = gpu_cc_parent_map_0,
157*30eb0e76SKonrad Dybcio .freq_tbl = ftbl_gpu_cc_ff_clk_src,
158*30eb0e76SKonrad Dybcio .clkr.hw.init = &(const struct clk_init_data) {
159*30eb0e76SKonrad Dybcio .name = "gpu_cc_ff_clk_src",
160*30eb0e76SKonrad Dybcio .parent_data = gpu_cc_parent_data_0,
161*30eb0e76SKonrad Dybcio .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
162*30eb0e76SKonrad Dybcio .ops = &clk_rcg2_shared_ops,
163*30eb0e76SKonrad Dybcio },
164*30eb0e76SKonrad Dybcio };
165*30eb0e76SKonrad Dybcio
166*30eb0e76SKonrad Dybcio static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
167*30eb0e76SKonrad Dybcio F(19200000, P_BI_TCXO, 1, 0, 0),
168*30eb0e76SKonrad Dybcio F(220000000, P_GPU_CC_PLL1_OUT_MAIN, 2, 0, 0),
169*30eb0e76SKonrad Dybcio F(550000000, P_GPU_CC_PLL1_OUT_MAIN, 2, 0, 0),
170*30eb0e76SKonrad Dybcio { }
171*30eb0e76SKonrad Dybcio };
172*30eb0e76SKonrad Dybcio
173*30eb0e76SKonrad Dybcio static struct clk_rcg2 gpu_cc_gmu_clk_src = {
174*30eb0e76SKonrad Dybcio .cmd_rcgr = 0x9318,
175*30eb0e76SKonrad Dybcio .mnd_width = 0,
176*30eb0e76SKonrad Dybcio .hid_width = 5,
177*30eb0e76SKonrad Dybcio .parent_map = gpu_cc_parent_map_1,
178*30eb0e76SKonrad Dybcio .freq_tbl = ftbl_gpu_cc_gmu_clk_src,
179*30eb0e76SKonrad Dybcio .clkr.hw.init = &(const struct clk_init_data) {
180*30eb0e76SKonrad Dybcio .name = "gpu_cc_gmu_clk_src",
181*30eb0e76SKonrad Dybcio .parent_data = gpu_cc_parent_data_1,
182*30eb0e76SKonrad Dybcio .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
183*30eb0e76SKonrad Dybcio .flags = CLK_SET_RATE_PARENT,
184*30eb0e76SKonrad Dybcio .ops = &clk_rcg2_shared_ops,
185*30eb0e76SKonrad Dybcio },
186*30eb0e76SKonrad Dybcio };
187*30eb0e76SKonrad Dybcio
188*30eb0e76SKonrad Dybcio static struct clk_rcg2 gpu_cc_hub_clk_src = {
189*30eb0e76SKonrad Dybcio .cmd_rcgr = 0x93ec,
190*30eb0e76SKonrad Dybcio .mnd_width = 0,
191*30eb0e76SKonrad Dybcio .hid_width = 5,
192*30eb0e76SKonrad Dybcio .parent_map = gpu_cc_parent_map_2,
193*30eb0e76SKonrad Dybcio .freq_tbl = ftbl_gpu_cc_ff_clk_src,
194*30eb0e76SKonrad Dybcio .clkr.hw.init = &(const struct clk_init_data) {
195*30eb0e76SKonrad Dybcio .name = "gpu_cc_hub_clk_src",
196*30eb0e76SKonrad Dybcio .parent_data = gpu_cc_parent_data_2,
197*30eb0e76SKonrad Dybcio .num_parents = ARRAY_SIZE(gpu_cc_parent_data_2),
198*30eb0e76SKonrad Dybcio .ops = &clk_rcg2_shared_ops,
199*30eb0e76SKonrad Dybcio },
200*30eb0e76SKonrad Dybcio };
201*30eb0e76SKonrad Dybcio
202*30eb0e76SKonrad Dybcio static struct clk_branch gpu_cc_ahb_clk = {
203*30eb0e76SKonrad Dybcio .halt_reg = 0x911c,
204*30eb0e76SKonrad Dybcio .halt_check = BRANCH_HALT_DELAY,
205*30eb0e76SKonrad Dybcio .clkr = {
206*30eb0e76SKonrad Dybcio .enable_reg = 0x911c,
207*30eb0e76SKonrad Dybcio .enable_mask = BIT(0),
208*30eb0e76SKonrad Dybcio .hw.init = &(const struct clk_init_data) {
209*30eb0e76SKonrad Dybcio .name = "gpu_cc_ahb_clk",
210*30eb0e76SKonrad Dybcio .parent_hws = (const struct clk_hw*[]) {
211*30eb0e76SKonrad Dybcio &gpu_cc_hub_clk_src.clkr.hw,
212*30eb0e76SKonrad Dybcio },
213*30eb0e76SKonrad Dybcio .num_parents = 1,
214*30eb0e76SKonrad Dybcio .flags = CLK_SET_RATE_PARENT,
215*30eb0e76SKonrad Dybcio .ops = &clk_branch2_ops,
216*30eb0e76SKonrad Dybcio },
217*30eb0e76SKonrad Dybcio },
218*30eb0e76SKonrad Dybcio };
219*30eb0e76SKonrad Dybcio
220*30eb0e76SKonrad Dybcio static struct clk_branch gpu_cc_crc_ahb_clk = {
221*30eb0e76SKonrad Dybcio .halt_reg = 0x9120,
222*30eb0e76SKonrad Dybcio .halt_check = BRANCH_HALT_VOTED,
223*30eb0e76SKonrad Dybcio .clkr = {
224*30eb0e76SKonrad Dybcio .enable_reg = 0x9120,
225*30eb0e76SKonrad Dybcio .enable_mask = BIT(0),
226*30eb0e76SKonrad Dybcio .hw.init = &(const struct clk_init_data) {
227*30eb0e76SKonrad Dybcio .name = "gpu_cc_crc_ahb_clk",
228*30eb0e76SKonrad Dybcio .parent_hws = (const struct clk_hw*[]) {
229*30eb0e76SKonrad Dybcio &gpu_cc_hub_clk_src.clkr.hw,
230*30eb0e76SKonrad Dybcio },
231*30eb0e76SKonrad Dybcio .num_parents = 1,
232*30eb0e76SKonrad Dybcio .flags = CLK_SET_RATE_PARENT,
233*30eb0e76SKonrad Dybcio .ops = &clk_branch2_ops,
234*30eb0e76SKonrad Dybcio },
235*30eb0e76SKonrad Dybcio },
236*30eb0e76SKonrad Dybcio };
237*30eb0e76SKonrad Dybcio
238*30eb0e76SKonrad Dybcio static struct clk_branch gpu_cc_cx_ff_clk = {
239*30eb0e76SKonrad Dybcio .halt_reg = 0x914c,
240*30eb0e76SKonrad Dybcio .halt_check = BRANCH_HALT,
241*30eb0e76SKonrad Dybcio .clkr = {
242*30eb0e76SKonrad Dybcio .enable_reg = 0x914c,
243*30eb0e76SKonrad Dybcio .enable_mask = BIT(0),
244*30eb0e76SKonrad Dybcio .hw.init = &(const struct clk_init_data) {
245*30eb0e76SKonrad Dybcio .name = "gpu_cc_cx_ff_clk",
246*30eb0e76SKonrad Dybcio .parent_hws = (const struct clk_hw*[]) {
247*30eb0e76SKonrad Dybcio &gpu_cc_ff_clk_src.clkr.hw,
248*30eb0e76SKonrad Dybcio },
249*30eb0e76SKonrad Dybcio .num_parents = 1,
250*30eb0e76SKonrad Dybcio .flags = CLK_SET_RATE_PARENT,
251*30eb0e76SKonrad Dybcio .ops = &clk_branch2_ops,
252*30eb0e76SKonrad Dybcio },
253*30eb0e76SKonrad Dybcio },
254*30eb0e76SKonrad Dybcio };
255*30eb0e76SKonrad Dybcio
256*30eb0e76SKonrad Dybcio static struct clk_branch gpu_cc_cx_gmu_clk = {
257*30eb0e76SKonrad Dybcio .halt_reg = 0x913c,
258*30eb0e76SKonrad Dybcio .halt_check = BRANCH_HALT_VOTED,
259*30eb0e76SKonrad Dybcio .clkr = {
260*30eb0e76SKonrad Dybcio .enable_reg = 0x913c,
261*30eb0e76SKonrad Dybcio .enable_mask = BIT(0),
262*30eb0e76SKonrad Dybcio .hw.init = &(const struct clk_init_data) {
263*30eb0e76SKonrad Dybcio .name = "gpu_cc_cx_gmu_clk",
264*30eb0e76SKonrad Dybcio .parent_hws = (const struct clk_hw*[]) {
265*30eb0e76SKonrad Dybcio &gpu_cc_gmu_clk_src.clkr.hw,
266*30eb0e76SKonrad Dybcio },
267*30eb0e76SKonrad Dybcio .num_parents = 1,
268*30eb0e76SKonrad Dybcio .flags = CLK_SET_RATE_PARENT,
269*30eb0e76SKonrad Dybcio .ops = &clk_branch2_aon_ops,
270*30eb0e76SKonrad Dybcio },
271*30eb0e76SKonrad Dybcio },
272*30eb0e76SKonrad Dybcio };
273*30eb0e76SKonrad Dybcio
274*30eb0e76SKonrad Dybcio static struct clk_branch gpu_cc_cxo_aon_clk = {
275*30eb0e76SKonrad Dybcio .halt_reg = 0x9004,
276*30eb0e76SKonrad Dybcio .halt_check = BRANCH_HALT_VOTED,
277*30eb0e76SKonrad Dybcio .clkr = {
278*30eb0e76SKonrad Dybcio .enable_reg = 0x9004,
279*30eb0e76SKonrad Dybcio .enable_mask = BIT(0),
280*30eb0e76SKonrad Dybcio .hw.init = &(const struct clk_init_data) {
281*30eb0e76SKonrad Dybcio .name = "gpu_cc_cxo_aon_clk",
282*30eb0e76SKonrad Dybcio .ops = &clk_branch2_ops,
283*30eb0e76SKonrad Dybcio },
284*30eb0e76SKonrad Dybcio },
285*30eb0e76SKonrad Dybcio };
286*30eb0e76SKonrad Dybcio
287*30eb0e76SKonrad Dybcio static struct clk_branch gpu_cc_cxo_clk = {
288*30eb0e76SKonrad Dybcio .halt_reg = 0x9144,
289*30eb0e76SKonrad Dybcio .halt_check = BRANCH_HALT,
290*30eb0e76SKonrad Dybcio .clkr = {
291*30eb0e76SKonrad Dybcio .enable_reg = 0x9144,
292*30eb0e76SKonrad Dybcio .enable_mask = BIT(0),
293*30eb0e76SKonrad Dybcio .hw.init = &(const struct clk_init_data) {
294*30eb0e76SKonrad Dybcio .name = "gpu_cc_cxo_clk",
295*30eb0e76SKonrad Dybcio .ops = &clk_branch2_ops,
296*30eb0e76SKonrad Dybcio },
297*30eb0e76SKonrad Dybcio },
298*30eb0e76SKonrad Dybcio };
299*30eb0e76SKonrad Dybcio
300*30eb0e76SKonrad Dybcio static struct clk_branch gpu_cc_gx_gmu_clk = {
301*30eb0e76SKonrad Dybcio .halt_reg = 0x90bc,
302*30eb0e76SKonrad Dybcio .halt_check = BRANCH_HALT,
303*30eb0e76SKonrad Dybcio .clkr = {
304*30eb0e76SKonrad Dybcio .enable_reg = 0x90bc,
305*30eb0e76SKonrad Dybcio .enable_mask = BIT(0),
306*30eb0e76SKonrad Dybcio .hw.init = &(const struct clk_init_data) {
307*30eb0e76SKonrad Dybcio .name = "gpu_cc_gx_gmu_clk",
308*30eb0e76SKonrad Dybcio .parent_hws = (const struct clk_hw*[]) {
309*30eb0e76SKonrad Dybcio &gpu_cc_gmu_clk_src.clkr.hw,
310*30eb0e76SKonrad Dybcio },
311*30eb0e76SKonrad Dybcio .num_parents = 1,
312*30eb0e76SKonrad Dybcio .flags = CLK_SET_RATE_PARENT,
313*30eb0e76SKonrad Dybcio .ops = &clk_branch2_ops,
314*30eb0e76SKonrad Dybcio },
315*30eb0e76SKonrad Dybcio },
316*30eb0e76SKonrad Dybcio };
317*30eb0e76SKonrad Dybcio
318*30eb0e76SKonrad Dybcio static struct clk_branch gpu_cc_hub_aon_clk = {
319*30eb0e76SKonrad Dybcio .halt_reg = 0x93e8,
320*30eb0e76SKonrad Dybcio .halt_check = BRANCH_HALT,
321*30eb0e76SKonrad Dybcio .clkr = {
322*30eb0e76SKonrad Dybcio .enable_reg = 0x93e8,
323*30eb0e76SKonrad Dybcio .enable_mask = BIT(0),
324*30eb0e76SKonrad Dybcio .hw.init = &(const struct clk_init_data) {
325*30eb0e76SKonrad Dybcio .name = "gpu_cc_hub_aon_clk",
326*30eb0e76SKonrad Dybcio .parent_hws = (const struct clk_hw*[]) {
327*30eb0e76SKonrad Dybcio &gpu_cc_hub_clk_src.clkr.hw,
328*30eb0e76SKonrad Dybcio },
329*30eb0e76SKonrad Dybcio .num_parents = 1,
330*30eb0e76SKonrad Dybcio .flags = CLK_SET_RATE_PARENT,
331*30eb0e76SKonrad Dybcio .ops = &clk_branch2_aon_ops,
332*30eb0e76SKonrad Dybcio },
333*30eb0e76SKonrad Dybcio },
334*30eb0e76SKonrad Dybcio };
335*30eb0e76SKonrad Dybcio
336*30eb0e76SKonrad Dybcio static struct clk_branch gpu_cc_hub_cx_int_clk = {
337*30eb0e76SKonrad Dybcio .halt_reg = 0x9148,
338*30eb0e76SKonrad Dybcio .halt_check = BRANCH_HALT_VOTED,
339*30eb0e76SKonrad Dybcio .clkr = {
340*30eb0e76SKonrad Dybcio .enable_reg = 0x9148,
341*30eb0e76SKonrad Dybcio .enable_mask = BIT(0),
342*30eb0e76SKonrad Dybcio .hw.init = &(const struct clk_init_data) {
343*30eb0e76SKonrad Dybcio .name = "gpu_cc_hub_cx_int_clk",
344*30eb0e76SKonrad Dybcio .parent_hws = (const struct clk_hw*[]) {
345*30eb0e76SKonrad Dybcio &gpu_cc_hub_clk_src.clkr.hw,
346*30eb0e76SKonrad Dybcio },
347*30eb0e76SKonrad Dybcio .num_parents = 1,
348*30eb0e76SKonrad Dybcio .flags = CLK_SET_RATE_PARENT,
349*30eb0e76SKonrad Dybcio .ops = &clk_branch2_aon_ops,
350*30eb0e76SKonrad Dybcio },
351*30eb0e76SKonrad Dybcio },
352*30eb0e76SKonrad Dybcio };
353*30eb0e76SKonrad Dybcio
354*30eb0e76SKonrad Dybcio static struct clk_branch gpu_cc_memnoc_gfx_clk = {
355*30eb0e76SKonrad Dybcio .halt_reg = 0x9150,
356*30eb0e76SKonrad Dybcio .halt_check = BRANCH_HALT_VOTED,
357*30eb0e76SKonrad Dybcio .clkr = {
358*30eb0e76SKonrad Dybcio .enable_reg = 0x9150,
359*30eb0e76SKonrad Dybcio .enable_mask = BIT(0),
360*30eb0e76SKonrad Dybcio .hw.init = &(const struct clk_init_data) {
361*30eb0e76SKonrad Dybcio .name = "gpu_cc_memnoc_gfx_clk",
362*30eb0e76SKonrad Dybcio .ops = &clk_branch2_ops,
363*30eb0e76SKonrad Dybcio },
364*30eb0e76SKonrad Dybcio },
365*30eb0e76SKonrad Dybcio };
366*30eb0e76SKonrad Dybcio
367*30eb0e76SKonrad Dybcio static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = {
368*30eb0e76SKonrad Dybcio .halt_reg = 0x7000,
369*30eb0e76SKonrad Dybcio .halt_check = BRANCH_HALT_VOTED,
370*30eb0e76SKonrad Dybcio .clkr = {
371*30eb0e76SKonrad Dybcio .enable_reg = 0x7000,
372*30eb0e76SKonrad Dybcio .enable_mask = BIT(0),
373*30eb0e76SKonrad Dybcio .hw.init = &(const struct clk_init_data) {
374*30eb0e76SKonrad Dybcio .name = "gpu_cc_hlos1_vote_gpu_smmu_clk",
375*30eb0e76SKonrad Dybcio .ops = &clk_branch2_ops,
376*30eb0e76SKonrad Dybcio },
377*30eb0e76SKonrad Dybcio },
378*30eb0e76SKonrad Dybcio };
379*30eb0e76SKonrad Dybcio
380*30eb0e76SKonrad Dybcio static struct clk_branch gpu_cc_sleep_clk = {
381*30eb0e76SKonrad Dybcio .halt_reg = 0x9134,
382*30eb0e76SKonrad Dybcio .halt_check = BRANCH_HALT_VOTED,
383*30eb0e76SKonrad Dybcio .clkr = {
384*30eb0e76SKonrad Dybcio .enable_reg = 0x9134,
385*30eb0e76SKonrad Dybcio .enable_mask = BIT(0),
386*30eb0e76SKonrad Dybcio .hw.init = &(const struct clk_init_data) {
387*30eb0e76SKonrad Dybcio .name = "gpu_cc_sleep_clk",
388*30eb0e76SKonrad Dybcio .ops = &clk_branch2_ops,
389*30eb0e76SKonrad Dybcio },
390*30eb0e76SKonrad Dybcio },
391*30eb0e76SKonrad Dybcio };
392*30eb0e76SKonrad Dybcio
393*30eb0e76SKonrad Dybcio static struct gdsc gpu_cx_gdsc = {
394*30eb0e76SKonrad Dybcio .gdscr = 0x9108,
395*30eb0e76SKonrad Dybcio .gds_hw_ctrl = 0x953c,
396*30eb0e76SKonrad Dybcio .clk_dis_wait_val = 8,
397*30eb0e76SKonrad Dybcio .pd = {
398*30eb0e76SKonrad Dybcio .name = "gpu_cx_gdsc",
399*30eb0e76SKonrad Dybcio },
400*30eb0e76SKonrad Dybcio .pwrsts = PWRSTS_OFF_ON,
401*30eb0e76SKonrad Dybcio .flags = VOTABLE | RETAIN_FF_ENABLE,
402*30eb0e76SKonrad Dybcio };
403*30eb0e76SKonrad Dybcio
404*30eb0e76SKonrad Dybcio static struct gdsc gpu_gx_gdsc = {
405*30eb0e76SKonrad Dybcio .gdscr = 0x905c,
406*30eb0e76SKonrad Dybcio .clamp_io_ctrl = 0x9504,
407*30eb0e76SKonrad Dybcio .resets = (unsigned int []){ GPUCC_GPU_CC_GX_BCR,
408*30eb0e76SKonrad Dybcio GPUCC_GPU_CC_ACD_BCR,
409*30eb0e76SKonrad Dybcio GPUCC_GPU_CC_GX_ACD_IROOT_BCR },
410*30eb0e76SKonrad Dybcio .reset_count = 3,
411*30eb0e76SKonrad Dybcio .pd = {
412*30eb0e76SKonrad Dybcio .name = "gpu_gx_gdsc",
413*30eb0e76SKonrad Dybcio .power_on = gdsc_gx_do_nothing_enable,
414*30eb0e76SKonrad Dybcio },
415*30eb0e76SKonrad Dybcio .pwrsts = PWRSTS_OFF_ON,
416*30eb0e76SKonrad Dybcio .flags = CLAMP_IO | AON_RESET | SW_RESET,
417*30eb0e76SKonrad Dybcio };
418*30eb0e76SKonrad Dybcio
419*30eb0e76SKonrad Dybcio static struct clk_regmap *gpu_cc_sar2130p_clocks[] = {
420*30eb0e76SKonrad Dybcio [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
421*30eb0e76SKonrad Dybcio [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
422*30eb0e76SKonrad Dybcio [GPU_CC_CX_FF_CLK] = &gpu_cc_cx_ff_clk.clkr,
423*30eb0e76SKonrad Dybcio [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
424*30eb0e76SKonrad Dybcio [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
425*30eb0e76SKonrad Dybcio [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
426*30eb0e76SKonrad Dybcio [GPU_CC_FF_CLK_SRC] = &gpu_cc_ff_clk_src.clkr,
427*30eb0e76SKonrad Dybcio [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
428*30eb0e76SKonrad Dybcio [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
429*30eb0e76SKonrad Dybcio [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr,
430*30eb0e76SKonrad Dybcio [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr,
431*30eb0e76SKonrad Dybcio [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr,
432*30eb0e76SKonrad Dybcio [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr,
433*30eb0e76SKonrad Dybcio [GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr,
434*30eb0e76SKonrad Dybcio [GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
435*30eb0e76SKonrad Dybcio [GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
436*30eb0e76SKonrad Dybcio [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr,
437*30eb0e76SKonrad Dybcio };
438*30eb0e76SKonrad Dybcio
439*30eb0e76SKonrad Dybcio static const struct qcom_reset_map gpu_cc_sar2130p_resets[] = {
440*30eb0e76SKonrad Dybcio [GPUCC_GPU_CC_ACD_BCR] = { 0x9358 },
441*30eb0e76SKonrad Dybcio [GPUCC_GPU_CC_GX_ACD_IROOT_BCR] = { 0x958c },
442*30eb0e76SKonrad Dybcio [GPUCC_GPU_CC_GX_BCR] = { 0x9058 },
443*30eb0e76SKonrad Dybcio };
444*30eb0e76SKonrad Dybcio
445*30eb0e76SKonrad Dybcio static struct gdsc *gpu_cc_sar2130p_gdscs[] = {
446*30eb0e76SKonrad Dybcio [GPU_CX_GDSC] = &gpu_cx_gdsc,
447*30eb0e76SKonrad Dybcio [GPU_GX_GDSC] = &gpu_gx_gdsc,
448*30eb0e76SKonrad Dybcio };
449*30eb0e76SKonrad Dybcio
450*30eb0e76SKonrad Dybcio static const struct regmap_config gpu_cc_sar2130p_regmap_config = {
451*30eb0e76SKonrad Dybcio .reg_bits = 32,
452*30eb0e76SKonrad Dybcio .reg_stride = 4,
453*30eb0e76SKonrad Dybcio .val_bits = 32,
454*30eb0e76SKonrad Dybcio .max_register = 0xa000,
455*30eb0e76SKonrad Dybcio .fast_io = true,
456*30eb0e76SKonrad Dybcio };
457*30eb0e76SKonrad Dybcio
458*30eb0e76SKonrad Dybcio static const struct qcom_cc_desc gpu_cc_sar2130p_desc = {
459*30eb0e76SKonrad Dybcio .config = &gpu_cc_sar2130p_regmap_config,
460*30eb0e76SKonrad Dybcio .clks = gpu_cc_sar2130p_clocks,
461*30eb0e76SKonrad Dybcio .num_clks = ARRAY_SIZE(gpu_cc_sar2130p_clocks),
462*30eb0e76SKonrad Dybcio .resets = gpu_cc_sar2130p_resets,
463*30eb0e76SKonrad Dybcio .num_resets = ARRAY_SIZE(gpu_cc_sar2130p_resets),
464*30eb0e76SKonrad Dybcio .gdscs = gpu_cc_sar2130p_gdscs,
465*30eb0e76SKonrad Dybcio .num_gdscs = ARRAY_SIZE(gpu_cc_sar2130p_gdscs),
466*30eb0e76SKonrad Dybcio };
467*30eb0e76SKonrad Dybcio
468*30eb0e76SKonrad Dybcio static const struct of_device_id gpu_cc_sar2130p_match_table[] = {
469*30eb0e76SKonrad Dybcio { .compatible = "qcom,sar2130p-gpucc" },
470*30eb0e76SKonrad Dybcio { }
471*30eb0e76SKonrad Dybcio };
472*30eb0e76SKonrad Dybcio MODULE_DEVICE_TABLE(of, gpu_cc_sar2130p_match_table);
473*30eb0e76SKonrad Dybcio
gpu_cc_sar2130p_probe(struct platform_device * pdev)474*30eb0e76SKonrad Dybcio static int gpu_cc_sar2130p_probe(struct platform_device *pdev)
475*30eb0e76SKonrad Dybcio {
476*30eb0e76SKonrad Dybcio struct device *dev = &pdev->dev;
477*30eb0e76SKonrad Dybcio struct regmap *regmap;
478*30eb0e76SKonrad Dybcio
479*30eb0e76SKonrad Dybcio regmap = qcom_cc_map(pdev, &gpu_cc_sar2130p_desc);
480*30eb0e76SKonrad Dybcio if (IS_ERR(regmap))
481*30eb0e76SKonrad Dybcio return dev_err_probe(dev, PTR_ERR(regmap), "Couldn't map GPU_CC\n");
482*30eb0e76SKonrad Dybcio
483*30eb0e76SKonrad Dybcio clk_lucid_ole_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
484*30eb0e76SKonrad Dybcio clk_lucid_ole_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
485*30eb0e76SKonrad Dybcio
486*30eb0e76SKonrad Dybcio /* Keep some clocks always-on */
487*30eb0e76SKonrad Dybcio qcom_branch_set_clk_en(regmap, 0x900c); /* GPU_CC_DEMET_CLK */
488*30eb0e76SKonrad Dybcio
489*30eb0e76SKonrad Dybcio return qcom_cc_really_probe(dev, &gpu_cc_sar2130p_desc, regmap);
490*30eb0e76SKonrad Dybcio }
491*30eb0e76SKonrad Dybcio
492*30eb0e76SKonrad Dybcio static struct platform_driver gpu_cc_sar2130p_driver = {
493*30eb0e76SKonrad Dybcio .probe = gpu_cc_sar2130p_probe,
494*30eb0e76SKonrad Dybcio .driver = {
495*30eb0e76SKonrad Dybcio .name = "gpu_cc-sar2130p",
496*30eb0e76SKonrad Dybcio .of_match_table = gpu_cc_sar2130p_match_table,
497*30eb0e76SKonrad Dybcio },
498*30eb0e76SKonrad Dybcio };
499*30eb0e76SKonrad Dybcio module_platform_driver(gpu_cc_sar2130p_driver);
500*30eb0e76SKonrad Dybcio
501*30eb0e76SKonrad Dybcio MODULE_DESCRIPTION("QTI GPU_CC SAR2130P Driver");
502*30eb0e76SKonrad Dybcio MODULE_LICENSE("GPL");
503