xref: /linux/drivers/clk/qcom/gpucc-qcs615.c (revision 8d2b0853add1d7534dc0794e3c8e0b9e8c4ec640)
1*f4b5b408STaniya Das // SPDX-License-Identifier: GPL-2.0-only
2*f4b5b408STaniya Das /*
3*f4b5b408STaniya Das  * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
4*f4b5b408STaniya Das  */
5*f4b5b408STaniya Das 
6*f4b5b408STaniya Das #include <linux/clk-provider.h>
7*f4b5b408STaniya Das #include <linux/module.h>
8*f4b5b408STaniya Das #include <linux/mod_devicetable.h>
9*f4b5b408STaniya Das #include <linux/of.h>
10*f4b5b408STaniya Das #include <linux/platform_device.h>
11*f4b5b408STaniya Das #include <linux/regmap.h>
12*f4b5b408STaniya Das 
13*f4b5b408STaniya Das #include <dt-bindings/clock/qcom,qcs615-gpucc.h>
14*f4b5b408STaniya Das 
15*f4b5b408STaniya Das #include "clk-alpha-pll.h"
16*f4b5b408STaniya Das #include "clk-branch.h"
17*f4b5b408STaniya Das #include "clk-pll.h"
18*f4b5b408STaniya Das #include "clk-rcg.h"
19*f4b5b408STaniya Das #include "clk-regmap.h"
20*f4b5b408STaniya Das #include "clk-regmap-divider.h"
21*f4b5b408STaniya Das #include "clk-regmap-mux.h"
22*f4b5b408STaniya Das #include "common.h"
23*f4b5b408STaniya Das #include "gdsc.h"
24*f4b5b408STaniya Das #include "reset.h"
25*f4b5b408STaniya Das 
26*f4b5b408STaniya Das enum {
27*f4b5b408STaniya Das 	DT_BI_TCXO,
28*f4b5b408STaniya Das 	DT_GPLL0_OUT_MAIN,
29*f4b5b408STaniya Das 	DT_GPLL0_OUT_MAIN_DIV,
30*f4b5b408STaniya Das };
31*f4b5b408STaniya Das 
32*f4b5b408STaniya Das enum {
33*f4b5b408STaniya Das 	P_BI_TCXO,
34*f4b5b408STaniya Das 	P_GPLL0_OUT_MAIN,
35*f4b5b408STaniya Das 	P_GPLL0_OUT_MAIN_DIV,
36*f4b5b408STaniya Das 	P_GPU_CC_PLL0_2X_CLK,
37*f4b5b408STaniya Das 	P_CRC_DIV_PLL0_OUT_AUX2,
38*f4b5b408STaniya Das 	P_GPU_CC_PLL0_OUT_MAIN,
39*f4b5b408STaniya Das 	P_GPU_CC_PLL1_OUT_AUX,
40*f4b5b408STaniya Das 	P_CRC_DIV_PLL1_OUT_AUX2,
41*f4b5b408STaniya Das 	P_GPU_CC_PLL1_OUT_MAIN,
42*f4b5b408STaniya Das };
43*f4b5b408STaniya Das 
44*f4b5b408STaniya Das static const struct pll_vco gpu_cc_pll0_vco[] = {
45*f4b5b408STaniya Das 	{ 1000000000, 2100000000, 0 },
46*f4b5b408STaniya Das };
47*f4b5b408STaniya Das 
48*f4b5b408STaniya Das static struct pll_vco gpu_cc_pll1_vco[] = {
49*f4b5b408STaniya Das 	{ 500000000,  1000000000, 2 },
50*f4b5b408STaniya Das };
51*f4b5b408STaniya Das 
52*f4b5b408STaniya Das /* 1020MHz configuration VCO - 0 */
53*f4b5b408STaniya Das static struct alpha_pll_config gpu_cc_pll0_config = {
54*f4b5b408STaniya Das 	.l = 0x35,
55*f4b5b408STaniya Das 	.config_ctl_val = 0x4001055b,
56*f4b5b408STaniya Das 	.test_ctl_hi_val = 0x1,
57*f4b5b408STaniya Das 	.test_ctl_hi_mask = 0x1,
58*f4b5b408STaniya Das 	.alpha_hi = 0x20,
59*f4b5b408STaniya Das 	.alpha = 0x00,
60*f4b5b408STaniya Das 	.alpha_en_mask = BIT(24),
61*f4b5b408STaniya Das 	.vco_val = 0x0,
62*f4b5b408STaniya Das 	.vco_mask = GENMASK(21, 20),
63*f4b5b408STaniya Das 	.aux2_output_mask = BIT(2),
64*f4b5b408STaniya Das };
65*f4b5b408STaniya Das 
66*f4b5b408STaniya Das static struct clk_alpha_pll gpu_cc_pll0 = {
67*f4b5b408STaniya Das 	.offset = 0x0,
68*f4b5b408STaniya Das 	.config = &gpu_cc_pll0_config,
69*f4b5b408STaniya Das 	.vco_table = gpu_cc_pll0_vco,
70*f4b5b408STaniya Das 	.num_vco = ARRAY_SIZE(gpu_cc_pll0_vco),
71*f4b5b408STaniya Das 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
72*f4b5b408STaniya Das 	.clkr = {
73*f4b5b408STaniya Das 		.hw.init = &(const struct clk_init_data) {
74*f4b5b408STaniya Das 			.name = "gpu_cc_pll0",
75*f4b5b408STaniya Das 			.parent_data = &(const struct clk_parent_data) {
76*f4b5b408STaniya Das 				.index = DT_BI_TCXO,
77*f4b5b408STaniya Das 			},
78*f4b5b408STaniya Das 			.num_parents = 1,
79*f4b5b408STaniya Das 			.ops = &clk_alpha_pll_slew_ops,
80*f4b5b408STaniya Das 		},
81*f4b5b408STaniya Das 	},
82*f4b5b408STaniya Das };
83*f4b5b408STaniya Das 
84*f4b5b408STaniya Das /* 930MHz configuration VCO - 2 */
85*f4b5b408STaniya Das static struct alpha_pll_config gpu_cc_pll1_config = {
86*f4b5b408STaniya Das 	.l = 0x30,
87*f4b5b408STaniya Das 	.config_ctl_val = 0x4001055b,
88*f4b5b408STaniya Das 	.test_ctl_hi_val = 0x1,
89*f4b5b408STaniya Das 	.test_ctl_hi_mask = 0x1,
90*f4b5b408STaniya Das 	.alpha_hi = 0x70,
91*f4b5b408STaniya Das 	.alpha = 0x00,
92*f4b5b408STaniya Das 	.alpha_en_mask = BIT(24),
93*f4b5b408STaniya Das 	.vco_val = BIT(21),
94*f4b5b408STaniya Das 	.vco_mask = GENMASK(21, 20),
95*f4b5b408STaniya Das 	.aux2_output_mask = BIT(2),
96*f4b5b408STaniya Das };
97*f4b5b408STaniya Das 
98*f4b5b408STaniya Das static struct clk_alpha_pll gpu_cc_pll1 = {
99*f4b5b408STaniya Das 	.offset = 0x100,
100*f4b5b408STaniya Das 	.config = &gpu_cc_pll1_config,
101*f4b5b408STaniya Das 	.vco_table = gpu_cc_pll1_vco,
102*f4b5b408STaniya Das 	.num_vco = ARRAY_SIZE(gpu_cc_pll1_vco),
103*f4b5b408STaniya Das 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
104*f4b5b408STaniya Das 	.clkr = {
105*f4b5b408STaniya Das 		.hw.init = &(const struct clk_init_data) {
106*f4b5b408STaniya Das 			.name = "gpu_cc_pll1",
107*f4b5b408STaniya Das 			.parent_data = &(const struct clk_parent_data) {
108*f4b5b408STaniya Das 				.index = DT_BI_TCXO,
109*f4b5b408STaniya Das 			},
110*f4b5b408STaniya Das 			.num_parents = 1,
111*f4b5b408STaniya Das 			.ops = &clk_alpha_pll_slew_ops,
112*f4b5b408STaniya Das 		},
113*f4b5b408STaniya Das 	}
114*f4b5b408STaniya Das };
115*f4b5b408STaniya Das 
116*f4b5b408STaniya Das /* Clock Ramp Controller */
117*f4b5b408STaniya Das static struct clk_fixed_factor crc_div_pll0 = {
118*f4b5b408STaniya Das 	.mult = 1,
119*f4b5b408STaniya Das 	.div = 2,
120*f4b5b408STaniya Das 	.hw.init = &(struct clk_init_data){
121*f4b5b408STaniya Das 		.name = "crc_div_pll0",
122*f4b5b408STaniya Das 			.parent_data = &(const struct clk_parent_data){
123*f4b5b408STaniya Das 				.hw = &gpu_cc_pll0.clkr.hw,
124*f4b5b408STaniya Das 			},
125*f4b5b408STaniya Das 		.num_parents = 1,
126*f4b5b408STaniya Das 		.flags = CLK_SET_RATE_PARENT,
127*f4b5b408STaniya Das 		.ops = &clk_fixed_factor_ops,
128*f4b5b408STaniya Das 	},
129*f4b5b408STaniya Das };
130*f4b5b408STaniya Das 
131*f4b5b408STaniya Das /* Clock Ramp Controller */
132*f4b5b408STaniya Das static struct clk_fixed_factor crc_div_pll1 = {
133*f4b5b408STaniya Das 	.mult = 1,
134*f4b5b408STaniya Das 	.div = 2,
135*f4b5b408STaniya Das 	.hw.init = &(struct clk_init_data){
136*f4b5b408STaniya Das 		.name = "crc_div_pll1",
137*f4b5b408STaniya Das 			.parent_data = &(const struct clk_parent_data){
138*f4b5b408STaniya Das 				.hw = &gpu_cc_pll1.clkr.hw,
139*f4b5b408STaniya Das 			},
140*f4b5b408STaniya Das 		.num_parents = 1,
141*f4b5b408STaniya Das 		.flags = CLK_SET_RATE_PARENT,
142*f4b5b408STaniya Das 		.ops = &clk_fixed_factor_ops,
143*f4b5b408STaniya Das 	},
144*f4b5b408STaniya Das };
145*f4b5b408STaniya Das 
146*f4b5b408STaniya Das static const struct parent_map gpu_cc_parent_map_0[] = {
147*f4b5b408STaniya Das 	{ P_BI_TCXO, 0 },
148*f4b5b408STaniya Das 	{ P_GPU_CC_PLL0_OUT_MAIN, 1 },
149*f4b5b408STaniya Das 	{ P_GPU_CC_PLL1_OUT_MAIN, 3 },
150*f4b5b408STaniya Das 	{ P_GPLL0_OUT_MAIN, 5 },
151*f4b5b408STaniya Das 	{ P_GPLL0_OUT_MAIN_DIV, 6 },
152*f4b5b408STaniya Das };
153*f4b5b408STaniya Das 
154*f4b5b408STaniya Das static const struct clk_parent_data gpu_cc_parent_data_0[] = {
155*f4b5b408STaniya Das 	{ .index = DT_BI_TCXO },
156*f4b5b408STaniya Das 	{ .hw = &gpu_cc_pll0.clkr.hw },
157*f4b5b408STaniya Das 	{ .hw = &gpu_cc_pll1.clkr.hw },
158*f4b5b408STaniya Das 	{ .index = DT_GPLL0_OUT_MAIN },
159*f4b5b408STaniya Das 	{ .index = DT_GPLL0_OUT_MAIN_DIV },
160*f4b5b408STaniya Das };
161*f4b5b408STaniya Das 
162*f4b5b408STaniya Das static const struct parent_map gpu_cc_parent_map_1[] = {
163*f4b5b408STaniya Das 	{ P_BI_TCXO, 0 },
164*f4b5b408STaniya Das 	{ P_GPU_CC_PLL0_2X_CLK, 1 },
165*f4b5b408STaniya Das 	{ P_CRC_DIV_PLL0_OUT_AUX2, 2 },
166*f4b5b408STaniya Das 	{ P_GPU_CC_PLL1_OUT_AUX, 3 },
167*f4b5b408STaniya Das 	{ P_CRC_DIV_PLL1_OUT_AUX2, 4 },
168*f4b5b408STaniya Das 	{ P_GPLL0_OUT_MAIN, 5 },
169*f4b5b408STaniya Das };
170*f4b5b408STaniya Das 
171*f4b5b408STaniya Das static const struct clk_parent_data gpu_cc_parent_data_1[] = {
172*f4b5b408STaniya Das 	{ .index = DT_BI_TCXO },
173*f4b5b408STaniya Das 	{ .hw = &gpu_cc_pll0.clkr.hw },
174*f4b5b408STaniya Das 	{ .hw = &crc_div_pll0.hw },
175*f4b5b408STaniya Das 	{ .hw = &gpu_cc_pll1.clkr.hw },
176*f4b5b408STaniya Das 	{ .hw = &crc_div_pll1.hw },
177*f4b5b408STaniya Das 	{ .index = DT_GPLL0_OUT_MAIN },
178*f4b5b408STaniya Das };
179*f4b5b408STaniya Das 
180*f4b5b408STaniya Das static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
181*f4b5b408STaniya Das 	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
182*f4b5b408STaniya Das 	{ }
183*f4b5b408STaniya Das };
184*f4b5b408STaniya Das 
185*f4b5b408STaniya Das static struct clk_rcg2 gpu_cc_gmu_clk_src = {
186*f4b5b408STaniya Das 	.cmd_rcgr = 0x1120,
187*f4b5b408STaniya Das 	.mnd_width = 0,
188*f4b5b408STaniya Das 	.hid_width = 5,
189*f4b5b408STaniya Das 	.parent_map = gpu_cc_parent_map_0,
190*f4b5b408STaniya Das 	.freq_tbl = ftbl_gpu_cc_gmu_clk_src,
191*f4b5b408STaniya Das 	.clkr.hw.init = &(const struct clk_init_data) {
192*f4b5b408STaniya Das 		.name = "gpu_cc_gmu_clk_src",
193*f4b5b408STaniya Das 		.parent_data = gpu_cc_parent_data_0,
194*f4b5b408STaniya Das 		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
195*f4b5b408STaniya Das 		.ops = &clk_rcg2_shared_ops,
196*f4b5b408STaniya Das 	},
197*f4b5b408STaniya Das };
198*f4b5b408STaniya Das 
199*f4b5b408STaniya Das static const struct freq_tbl ftbl_gpu_cc_gx_gfx3d_clk_src[] = {
200*f4b5b408STaniya Das 	F(290000000, P_CRC_DIV_PLL1_OUT_AUX2, 1, 0, 0),
201*f4b5b408STaniya Das 	F(350000000, P_CRC_DIV_PLL1_OUT_AUX2, 1, 0, 0),
202*f4b5b408STaniya Das 	F(435000000, P_CRC_DIV_PLL1_OUT_AUX2, 1, 0, 0),
203*f4b5b408STaniya Das 	F(500000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0),
204*f4b5b408STaniya Das 	F(550000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0),
205*f4b5b408STaniya Das 	F(650000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0),
206*f4b5b408STaniya Das 	F(700000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0),
207*f4b5b408STaniya Das 	F(745000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0),
208*f4b5b408STaniya Das 	F(845000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0),
209*f4b5b408STaniya Das 	F(895000000, P_CRC_DIV_PLL0_OUT_AUX2, 1, 0, 0),
210*f4b5b408STaniya Das 	{ }
211*f4b5b408STaniya Das };
212*f4b5b408STaniya Das 
213*f4b5b408STaniya Das static struct clk_rcg2 gpu_cc_gx_gfx3d_clk_src = {
214*f4b5b408STaniya Das 	.cmd_rcgr = 0x101c,
215*f4b5b408STaniya Das 	.mnd_width = 0,
216*f4b5b408STaniya Das 	.hid_width = 5,
217*f4b5b408STaniya Das 	.parent_map = gpu_cc_parent_map_1,
218*f4b5b408STaniya Das 	.freq_tbl = ftbl_gpu_cc_gx_gfx3d_clk_src,
219*f4b5b408STaniya Das 	.clkr.hw.init = &(const struct clk_init_data) {
220*f4b5b408STaniya Das 		.name = "gpu_cc_gx_gfx3d_clk_src",
221*f4b5b408STaniya Das 		.parent_data = gpu_cc_parent_data_1,
222*f4b5b408STaniya Das 		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
223*f4b5b408STaniya Das 		.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
224*f4b5b408STaniya Das 		.ops = &clk_rcg2_shared_ops,
225*f4b5b408STaniya Das 	},
226*f4b5b408STaniya Das };
227*f4b5b408STaniya Das 
228*f4b5b408STaniya Das static struct clk_branch gpu_cc_crc_ahb_clk = {
229*f4b5b408STaniya Das 	.halt_reg = 0x107c,
230*f4b5b408STaniya Das 	.halt_check = BRANCH_HALT_VOTED,
231*f4b5b408STaniya Das 	.clkr = {
232*f4b5b408STaniya Das 		.enable_reg = 0x107c,
233*f4b5b408STaniya Das 		.enable_mask = BIT(0),
234*f4b5b408STaniya Das 		.hw.init = &(const struct clk_init_data) {
235*f4b5b408STaniya Das 			.name = "gpu_cc_crc_ahb_clk",
236*f4b5b408STaniya Das 			.ops = &clk_branch2_ops,
237*f4b5b408STaniya Das 		},
238*f4b5b408STaniya Das 	},
239*f4b5b408STaniya Das };
240*f4b5b408STaniya Das 
241*f4b5b408STaniya Das static struct clk_branch gpu_cc_cx_gfx3d_clk = {
242*f4b5b408STaniya Das 	.halt_reg = 0x10a4,
243*f4b5b408STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
244*f4b5b408STaniya Das 	.clkr = {
245*f4b5b408STaniya Das 		.enable_reg = 0x10a4,
246*f4b5b408STaniya Das 		.enable_mask = BIT(0),
247*f4b5b408STaniya Das 		.hw.init = &(const struct clk_init_data) {
248*f4b5b408STaniya Das 			.name = "gpu_cc_cx_gfx3d_clk",
249*f4b5b408STaniya Das 			.parent_hws = (const struct clk_hw*[]) {
250*f4b5b408STaniya Das 				&gpu_cc_gx_gfx3d_clk_src.clkr.hw,
251*f4b5b408STaniya Das 			},
252*f4b5b408STaniya Das 			.num_parents = 1,
253*f4b5b408STaniya Das 			.flags = CLK_SET_RATE_PARENT,
254*f4b5b408STaniya Das 			.ops = &clk_branch2_ops,
255*f4b5b408STaniya Das 		},
256*f4b5b408STaniya Das 	},
257*f4b5b408STaniya Das };
258*f4b5b408STaniya Das 
259*f4b5b408STaniya Das static struct clk_branch gpu_cc_cx_gfx3d_slv_clk = {
260*f4b5b408STaniya Das 	.halt_reg = 0x10a8,
261*f4b5b408STaniya Das 	.halt_check = BRANCH_HALT_DELAY,
262*f4b5b408STaniya Das 	.clkr = {
263*f4b5b408STaniya Das 		.enable_reg = 0x10a8,
264*f4b5b408STaniya Das 		.enable_mask = BIT(0),
265*f4b5b408STaniya Das 		.hw.init = &(const struct clk_init_data) {
266*f4b5b408STaniya Das 			.name = "gpu_cc_cx_gfx3d_slv_clk",
267*f4b5b408STaniya Das 			.parent_hws = (const struct clk_hw*[]) {
268*f4b5b408STaniya Das 				&gpu_cc_gx_gfx3d_clk_src.clkr.hw,
269*f4b5b408STaniya Das 			},
270*f4b5b408STaniya Das 			.num_parents = 1,
271*f4b5b408STaniya Das 			.flags = CLK_SET_RATE_PARENT,
272*f4b5b408STaniya Das 			.ops = &clk_branch2_ops,
273*f4b5b408STaniya Das 		},
274*f4b5b408STaniya Das 	},
275*f4b5b408STaniya Das };
276*f4b5b408STaniya Das 
277*f4b5b408STaniya Das static struct clk_branch gpu_cc_cx_gmu_clk = {
278*f4b5b408STaniya Das 	.halt_reg = 0x1098,
279*f4b5b408STaniya Das 	.halt_check = BRANCH_HALT,
280*f4b5b408STaniya Das 	.clkr = {
281*f4b5b408STaniya Das 		.enable_reg = 0x1098,
282*f4b5b408STaniya Das 		.enable_mask = BIT(0),
283*f4b5b408STaniya Das 		.hw.init = &(const struct clk_init_data) {
284*f4b5b408STaniya Das 			.name = "gpu_cc_cx_gmu_clk",
285*f4b5b408STaniya Das 			.parent_hws = (const struct clk_hw*[]) {
286*f4b5b408STaniya Das 				&gpu_cc_gmu_clk_src.clkr.hw,
287*f4b5b408STaniya Das 			},
288*f4b5b408STaniya Das 			.num_parents = 1,
289*f4b5b408STaniya Das 			.flags = CLK_SET_RATE_PARENT,
290*f4b5b408STaniya Das 			.ops = &clk_branch2_ops,
291*f4b5b408STaniya Das 		},
292*f4b5b408STaniya Das 	},
293*f4b5b408STaniya Das };
294*f4b5b408STaniya Das 
295*f4b5b408STaniya Das static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
296*f4b5b408STaniya Das 	.halt_reg = 0x108c,
297*f4b5b408STaniya Das 	.halt_check = BRANCH_HALT_VOTED,
298*f4b5b408STaniya Das 	.clkr = {
299*f4b5b408STaniya Das 		.enable_reg = 0x108c,
300*f4b5b408STaniya Das 		.enable_mask = BIT(0),
301*f4b5b408STaniya Das 		.hw.init = &(const struct clk_init_data) {
302*f4b5b408STaniya Das 			.name = "gpu_cc_cx_snoc_dvm_clk",
303*f4b5b408STaniya Das 			.ops = &clk_branch2_ops,
304*f4b5b408STaniya Das 		},
305*f4b5b408STaniya Das 	},
306*f4b5b408STaniya Das };
307*f4b5b408STaniya Das 
308*f4b5b408STaniya Das static struct clk_branch gpu_cc_cxo_aon_clk = {
309*f4b5b408STaniya Das 	.halt_reg = 0x1004,
310*f4b5b408STaniya Das 	.halt_check = BRANCH_HALT_VOTED,
311*f4b5b408STaniya Das 	.clkr = {
312*f4b5b408STaniya Das 		.enable_reg = 0x1004,
313*f4b5b408STaniya Das 		.enable_mask = BIT(0),
314*f4b5b408STaniya Das 		.hw.init = &(struct clk_init_data){
315*f4b5b408STaniya Das 			.name = "gpu_cc_cxo_aon_clk",
316*f4b5b408STaniya Das 			.ops = &clk_branch2_ops,
317*f4b5b408STaniya Das 		},
318*f4b5b408STaniya Das 	},
319*f4b5b408STaniya Das };
320*f4b5b408STaniya Das 
321*f4b5b408STaniya Das static struct clk_branch gpu_cc_cxo_clk = {
322*f4b5b408STaniya Das 	.halt_reg = 0x109c,
323*f4b5b408STaniya Das 	.halt_check = BRANCH_HALT,
324*f4b5b408STaniya Das 	.clkr = {
325*f4b5b408STaniya Das 		.enable_reg = 0x109c,
326*f4b5b408STaniya Das 		.enable_mask = BIT(0),
327*f4b5b408STaniya Das 		.hw.init = &(const struct clk_init_data) {
328*f4b5b408STaniya Das 			.name = "gpu_cc_cxo_clk",
329*f4b5b408STaniya Das 			.ops = &clk_branch2_ops,
330*f4b5b408STaniya Das 		},
331*f4b5b408STaniya Das 	},
332*f4b5b408STaniya Das };
333*f4b5b408STaniya Das 
334*f4b5b408STaniya Das static struct clk_branch gpu_cc_gx_gfx3d_clk = {
335*f4b5b408STaniya Das 	.halt_reg = 0x1054,
336*f4b5b408STaniya Das 	.halt_check = BRANCH_HALT_SKIP,
337*f4b5b408STaniya Das 	.clkr = {
338*f4b5b408STaniya Das 		.enable_reg = 0x1054,
339*f4b5b408STaniya Das 		.enable_mask = BIT(0),
340*f4b5b408STaniya Das 		.hw.init = &(const struct clk_init_data) {
341*f4b5b408STaniya Das 			.name = "gpu_cc_gx_gfx3d_clk",
342*f4b5b408STaniya Das 			.parent_hws = (const struct clk_hw*[]) {
343*f4b5b408STaniya Das 				&gpu_cc_gx_gfx3d_clk_src.clkr.hw,
344*f4b5b408STaniya Das 			},
345*f4b5b408STaniya Das 			.num_parents = 1,
346*f4b5b408STaniya Das 			.flags = CLK_SET_RATE_PARENT,
347*f4b5b408STaniya Das 			.ops = &clk_branch2_ops,
348*f4b5b408STaniya Das 		},
349*f4b5b408STaniya Das 	},
350*f4b5b408STaniya Das };
351*f4b5b408STaniya Das 
352*f4b5b408STaniya Das static struct clk_branch gpu_cc_gx_gmu_clk = {
353*f4b5b408STaniya Das 	.halt_reg = 0x1064,
354*f4b5b408STaniya Das 	.halt_check = BRANCH_HALT,
355*f4b5b408STaniya Das 	.clkr = {
356*f4b5b408STaniya Das 		.enable_reg = 0x1064,
357*f4b5b408STaniya Das 		.enable_mask = BIT(0),
358*f4b5b408STaniya Das 		.hw.init = &(const struct clk_init_data) {
359*f4b5b408STaniya Das 			.name = "gpu_cc_gx_gmu_clk",
360*f4b5b408STaniya Das 			.parent_hws = (const struct clk_hw*[]) {
361*f4b5b408STaniya Das 				&gpu_cc_gmu_clk_src.clkr.hw,
362*f4b5b408STaniya Das 			},
363*f4b5b408STaniya Das 			.num_parents = 1,
364*f4b5b408STaniya Das 			.flags = CLK_SET_RATE_PARENT,
365*f4b5b408STaniya Das 			.ops = &clk_branch2_ops,
366*f4b5b408STaniya Das 		},
367*f4b5b408STaniya Das 	},
368*f4b5b408STaniya Das };
369*f4b5b408STaniya Das 
370*f4b5b408STaniya Das static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = {
371*f4b5b408STaniya Das 	.halt_reg = 0x5000,
372*f4b5b408STaniya Das 	.halt_check = BRANCH_VOTED,
373*f4b5b408STaniya Das 	.clkr = {
374*f4b5b408STaniya Das 		.enable_reg = 0x5000,
375*f4b5b408STaniya Das 		.enable_mask = BIT(0),
376*f4b5b408STaniya Das 		.hw.init = &(const struct clk_init_data) {
377*f4b5b408STaniya Das 			.name = "gpu_cc_hlos1_vote_gpu_smmu_clk",
378*f4b5b408STaniya Das 			.ops = &clk_branch2_ops,
379*f4b5b408STaniya Das 		},
380*f4b5b408STaniya Das 	},
381*f4b5b408STaniya Das };
382*f4b5b408STaniya Das 
383*f4b5b408STaniya Das static struct clk_branch gpu_cc_sleep_clk = {
384*f4b5b408STaniya Das 	.halt_reg = 0x1090,
385*f4b5b408STaniya Das 	.halt_check = BRANCH_HALT_VOTED,
386*f4b5b408STaniya Das 	.clkr = {
387*f4b5b408STaniya Das 		.enable_reg = 0x1090,
388*f4b5b408STaniya Das 		.enable_mask = BIT(0),
389*f4b5b408STaniya Das 		.hw.init = &(const struct clk_init_data) {
390*f4b5b408STaniya Das 			.name = "gpu_cc_sleep_clk",
391*f4b5b408STaniya Das 			.ops = &clk_branch2_ops,
392*f4b5b408STaniya Das 		},
393*f4b5b408STaniya Das 	},
394*f4b5b408STaniya Das };
395*f4b5b408STaniya Das 
396*f4b5b408STaniya Das static struct clk_hw *gpu_cc_qcs615_hws[] = {
397*f4b5b408STaniya Das 	[CRC_DIV_PLL0] = &crc_div_pll0.hw,
398*f4b5b408STaniya Das 	[CRC_DIV_PLL1] = &crc_div_pll1.hw,
399*f4b5b408STaniya Das };
400*f4b5b408STaniya Das 
401*f4b5b408STaniya Das static struct gdsc cx_gdsc = {
402*f4b5b408STaniya Das 	.gdscr = 0x106c,
403*f4b5b408STaniya Das 	.gds_hw_ctrl = 0x1540,
404*f4b5b408STaniya Das 	.en_rest_wait_val = 0x2,
405*f4b5b408STaniya Das 	.en_few_wait_val = 0x2,
406*f4b5b408STaniya Das 	.clk_dis_wait_val = 0x8,
407*f4b5b408STaniya Das 	.pd = {
408*f4b5b408STaniya Das 		.name = "cx_gdsc",
409*f4b5b408STaniya Das 	},
410*f4b5b408STaniya Das 	.pwrsts = PWRSTS_OFF_ON,
411*f4b5b408STaniya Das 	.flags = POLL_CFG_GDSCR,
412*f4b5b408STaniya Das };
413*f4b5b408STaniya Das 
414*f4b5b408STaniya Das static struct gdsc gx_gdsc = {
415*f4b5b408STaniya Das 	.gdscr = 0x100c,
416*f4b5b408STaniya Das 	.en_rest_wait_val = 0x2,
417*f4b5b408STaniya Das 	.en_few_wait_val = 0x2,
418*f4b5b408STaniya Das 	.clk_dis_wait_val = 0x2,
419*f4b5b408STaniya Das 	.pd = {
420*f4b5b408STaniya Das 		.name = "gx_gdsc",
421*f4b5b408STaniya Das 	},
422*f4b5b408STaniya Das 	.pwrsts = PWRSTS_OFF_ON,
423*f4b5b408STaniya Das 	.flags = POLL_CFG_GDSCR,
424*f4b5b408STaniya Das };
425*f4b5b408STaniya Das 
426*f4b5b408STaniya Das static struct clk_regmap *gpu_cc_qcs615_clocks[] = {
427*f4b5b408STaniya Das 	[GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
428*f4b5b408STaniya Das 	[GPU_CC_CX_GFX3D_CLK] = &gpu_cc_cx_gfx3d_clk.clkr,
429*f4b5b408STaniya Das 	[GPU_CC_CX_GFX3D_SLV_CLK] = &gpu_cc_cx_gfx3d_slv_clk.clkr,
430*f4b5b408STaniya Das 	[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
431*f4b5b408STaniya Das 	[GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
432*f4b5b408STaniya Das 	[GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
433*f4b5b408STaniya Das 	[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
434*f4b5b408STaniya Das 	[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
435*f4b5b408STaniya Das 	[GPU_CC_GX_GFX3D_CLK] = &gpu_cc_gx_gfx3d_clk.clkr,
436*f4b5b408STaniya Das 	[GPU_CC_GX_GFX3D_CLK_SRC] = &gpu_cc_gx_gfx3d_clk_src.clkr,
437*f4b5b408STaniya Das 	[GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
438*f4b5b408STaniya Das 	[GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr,
439*f4b5b408STaniya Das 	[GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
440*f4b5b408STaniya Das 	[GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
441*f4b5b408STaniya Das 	[GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr,
442*f4b5b408STaniya Das };
443*f4b5b408STaniya Das 
444*f4b5b408STaniya Das static struct gdsc *gpu_cc_qcs615_gdscs[] = {
445*f4b5b408STaniya Das 	[CX_GDSC] = &cx_gdsc,
446*f4b5b408STaniya Das 	[GX_GDSC] = &gx_gdsc,
447*f4b5b408STaniya Das };
448*f4b5b408STaniya Das 
449*f4b5b408STaniya Das static const struct qcom_reset_map gpu_cc_qcs615_resets[] = {
450*f4b5b408STaniya Das 	[GPU_CC_CX_BCR] = { 0x1068 },
451*f4b5b408STaniya Das 	[GPU_CC_GFX3D_AON_BCR] = { 0x10a0 },
452*f4b5b408STaniya Das 	[GPU_CC_GMU_BCR] = { 0x111c },
453*f4b5b408STaniya Das 	[GPU_CC_GX_BCR] = { 0x1008 },
454*f4b5b408STaniya Das 	[GPU_CC_XO_BCR] = { 0x1000 },
455*f4b5b408STaniya Das };
456*f4b5b408STaniya Das 
457*f4b5b408STaniya Das static struct clk_alpha_pll *gpu_cc_qcs615_plls[] = {
458*f4b5b408STaniya Das 	&gpu_cc_pll0,
459*f4b5b408STaniya Das 	&gpu_cc_pll1,
460*f4b5b408STaniya Das };
461*f4b5b408STaniya Das 
462*f4b5b408STaniya Das static u32 gpu_cc_qcs615_critical_cbcrs[] = {
463*f4b5b408STaniya Das 	0x1078, /* GPU_CC_AHB_CLK */
464*f4b5b408STaniya Das };
465*f4b5b408STaniya Das 
466*f4b5b408STaniya Das static const struct regmap_config gpu_cc_qcs615_regmap_config = {
467*f4b5b408STaniya Das 	.reg_bits = 32,
468*f4b5b408STaniya Das 	.reg_stride = 4,
469*f4b5b408STaniya Das 	.val_bits = 32,
470*f4b5b408STaniya Das 	.max_register = 0x7008,
471*f4b5b408STaniya Das 	.fast_io = true,
472*f4b5b408STaniya Das };
473*f4b5b408STaniya Das 
474*f4b5b408STaniya Das static void clk_qcs615_regs_crc_configure(struct device *dev, struct regmap *regmap)
475*f4b5b408STaniya Das {
476*f4b5b408STaniya Das 	/* Recommended WAKEUP/SLEEP settings for the gpu_cc_cx_gmu_clk */
477*f4b5b408STaniya Das 	regmap_update_bits(regmap, gpu_cc_cx_gmu_clk.clkr.enable_reg, 0xff0, 0xff0);
478*f4b5b408STaniya Das 
479*f4b5b408STaniya Das 	/*
480*f4b5b408STaniya Das 	 * After POR, Clock Ramp Controller(CRC) will be in bypass mode.
481*f4b5b408STaniya Das 	 * Software needs to do the following operation to enable the CRC
482*f4b5b408STaniya Das 	 * for GFX3D clock and divide the input clock by div by 2.
483*f4b5b408STaniya Das 	 */
484*f4b5b408STaniya Das 	regmap_update_bits(regmap, 0x1028, 0x00015011, 0x00015011);
485*f4b5b408STaniya Das 	regmap_update_bits(regmap, 0x1024, 0x00800000, 0x00800000);
486*f4b5b408STaniya Das }
487*f4b5b408STaniya Das 
488*f4b5b408STaniya Das static struct qcom_cc_driver_data gpu_cc_qcs615_driver_data = {
489*f4b5b408STaniya Das 	.alpha_plls = gpu_cc_qcs615_plls,
490*f4b5b408STaniya Das 	.num_alpha_plls = ARRAY_SIZE(gpu_cc_qcs615_plls),
491*f4b5b408STaniya Das 	.clk_cbcrs = gpu_cc_qcs615_critical_cbcrs,
492*f4b5b408STaniya Das 	.num_clk_cbcrs = ARRAY_SIZE(gpu_cc_qcs615_critical_cbcrs),
493*f4b5b408STaniya Das 	.clk_regs_configure = clk_qcs615_regs_crc_configure,
494*f4b5b408STaniya Das };
495*f4b5b408STaniya Das 
496*f4b5b408STaniya Das static const struct qcom_cc_desc gpu_cc_qcs615_desc = {
497*f4b5b408STaniya Das 	.config = &gpu_cc_qcs615_regmap_config,
498*f4b5b408STaniya Das 	.clks = gpu_cc_qcs615_clocks,
499*f4b5b408STaniya Das 	.num_clks = ARRAY_SIZE(gpu_cc_qcs615_clocks),
500*f4b5b408STaniya Das 	.clk_hws = gpu_cc_qcs615_hws,
501*f4b5b408STaniya Das 	.num_clk_hws = ARRAY_SIZE(gpu_cc_qcs615_hws),
502*f4b5b408STaniya Das 	.resets = gpu_cc_qcs615_resets,
503*f4b5b408STaniya Das 	.num_resets = ARRAY_SIZE(gpu_cc_qcs615_resets),
504*f4b5b408STaniya Das 	.gdscs = gpu_cc_qcs615_gdscs,
505*f4b5b408STaniya Das 	.num_gdscs = ARRAY_SIZE(gpu_cc_qcs615_gdscs),
506*f4b5b408STaniya Das 	.driver_data = &gpu_cc_qcs615_driver_data,
507*f4b5b408STaniya Das };
508*f4b5b408STaniya Das 
509*f4b5b408STaniya Das static const struct of_device_id gpu_cc_qcs615_match_table[] = {
510*f4b5b408STaniya Das 	{ .compatible = "qcom,qcs615-gpucc" },
511*f4b5b408STaniya Das 	{ }
512*f4b5b408STaniya Das };
513*f4b5b408STaniya Das MODULE_DEVICE_TABLE(of, gpu_cc_qcs615_match_table);
514*f4b5b408STaniya Das 
515*f4b5b408STaniya Das static int gpu_cc_qcs615_probe(struct platform_device *pdev)
516*f4b5b408STaniya Das {
517*f4b5b408STaniya Das 	return qcom_cc_probe(pdev, &gpu_cc_qcs615_desc);
518*f4b5b408STaniya Das }
519*f4b5b408STaniya Das 
520*f4b5b408STaniya Das static struct platform_driver gpu_cc_qcs615_driver = {
521*f4b5b408STaniya Das 	.probe = gpu_cc_qcs615_probe,
522*f4b5b408STaniya Das 	.driver = {
523*f4b5b408STaniya Das 		.name = "gpucc-qcs615",
524*f4b5b408STaniya Das 		.of_match_table = gpu_cc_qcs615_match_table,
525*f4b5b408STaniya Das 	},
526*f4b5b408STaniya Das };
527*f4b5b408STaniya Das 
528*f4b5b408STaniya Das module_platform_driver(gpu_cc_qcs615_driver);
529*f4b5b408STaniya Das 
530*f4b5b408STaniya Das MODULE_DESCRIPTION("QTI GPUCC QCS615 Driver");
531*f4b5b408STaniya Das MODULE_LICENSE("GPL");
532