xref: /linux/drivers/clk/qcom/gpucc-milos.c (revision 8d2b0853add1d7534dc0794e3c8e0b9e8c4ec640)
1*980d7c84SLuca Weiss // SPDX-License-Identifier: GPL-2.0-only
2*980d7c84SLuca Weiss /*
3*980d7c84SLuca Weiss  * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved.
4*980d7c84SLuca Weiss  * Copyright (c) 2025, Luca Weiss <luca.weiss@fairphone.com>
5*980d7c84SLuca Weiss  */
6*980d7c84SLuca Weiss 
7*980d7c84SLuca Weiss #include <linux/clk-provider.h>
8*980d7c84SLuca Weiss #include <linux/mod_devicetable.h>
9*980d7c84SLuca Weiss #include <linux/module.h>
10*980d7c84SLuca Weiss #include <linux/platform_device.h>
11*980d7c84SLuca Weiss #include <linux/regmap.h>
12*980d7c84SLuca Weiss 
13*980d7c84SLuca Weiss #include <dt-bindings/clock/qcom,milos-gpucc.h>
14*980d7c84SLuca Weiss 
15*980d7c84SLuca Weiss #include "clk-alpha-pll.h"
16*980d7c84SLuca Weiss #include "clk-branch.h"
17*980d7c84SLuca Weiss #include "clk-pll.h"
18*980d7c84SLuca Weiss #include "clk-rcg.h"
19*980d7c84SLuca Weiss #include "clk-regmap.h"
20*980d7c84SLuca Weiss #include "clk-regmap-divider.h"
21*980d7c84SLuca Weiss #include "clk-regmap-mux.h"
22*980d7c84SLuca Weiss #include "common.h"
23*980d7c84SLuca Weiss #include "gdsc.h"
24*980d7c84SLuca Weiss #include "reset.h"
25*980d7c84SLuca Weiss 
26*980d7c84SLuca Weiss /* Need to match the order of clocks in DT binding */
27*980d7c84SLuca Weiss enum {
28*980d7c84SLuca Weiss 	DT_BI_TCXO,
29*980d7c84SLuca Weiss 	DT_GPLL0_OUT_MAIN,
30*980d7c84SLuca Weiss 	DT_GPLL0_OUT_MAIN_DIV,
31*980d7c84SLuca Weiss };
32*980d7c84SLuca Weiss 
33*980d7c84SLuca Weiss enum {
34*980d7c84SLuca Weiss 	P_BI_TCXO,
35*980d7c84SLuca Weiss 	P_GPLL0_OUT_MAIN,
36*980d7c84SLuca Weiss 	P_GPLL0_OUT_MAIN_DIV,
37*980d7c84SLuca Weiss 	P_GPU_CC_PLL0_OUT_EVEN,
38*980d7c84SLuca Weiss 	P_GPU_CC_PLL0_OUT_MAIN,
39*980d7c84SLuca Weiss 	P_GPU_CC_PLL0_OUT_ODD,
40*980d7c84SLuca Weiss };
41*980d7c84SLuca Weiss 
42*980d7c84SLuca Weiss static const struct pll_vco lucid_ole_vco[] = {
43*980d7c84SLuca Weiss 	{ 249600000, 2300000000, 0 },
44*980d7c84SLuca Weiss };
45*980d7c84SLuca Weiss 
46*980d7c84SLuca Weiss /* 700.0 MHz Configuration */
47*980d7c84SLuca Weiss static const struct alpha_pll_config gpu_cc_pll0_config = {
48*980d7c84SLuca Weiss 	.l = 0x24,
49*980d7c84SLuca Weiss 	.alpha = 0x7555,
50*980d7c84SLuca Weiss 	.config_ctl_val = 0x20485699,
51*980d7c84SLuca Weiss 	.config_ctl_hi_val = 0x00182261,
52*980d7c84SLuca Weiss 	.config_ctl_hi1_val = 0x82aa299c,
53*980d7c84SLuca Weiss 	.test_ctl_val = 0x00000000,
54*980d7c84SLuca Weiss 	.test_ctl_hi_val = 0x00000003,
55*980d7c84SLuca Weiss 	.test_ctl_hi1_val = 0x00009000,
56*980d7c84SLuca Weiss 	.test_ctl_hi2_val = 0x00000034,
57*980d7c84SLuca Weiss 	.user_ctl_val = 0x00000400,
58*980d7c84SLuca Weiss 	.user_ctl_hi_val = 0x00000005,
59*980d7c84SLuca Weiss };
60*980d7c84SLuca Weiss 
61*980d7c84SLuca Weiss static struct clk_alpha_pll gpu_cc_pll0 = {
62*980d7c84SLuca Weiss 	.offset = 0x0,
63*980d7c84SLuca Weiss 	.config = &gpu_cc_pll0_config,
64*980d7c84SLuca Weiss 	.vco_table = lucid_ole_vco,
65*980d7c84SLuca Weiss 	.num_vco = ARRAY_SIZE(lucid_ole_vco),
66*980d7c84SLuca Weiss 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
67*980d7c84SLuca Weiss 	.clkr = {
68*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
69*980d7c84SLuca Weiss 			.name = "gpu_cc_pll0",
70*980d7c84SLuca Weiss 			.parent_data = &(const struct clk_parent_data) {
71*980d7c84SLuca Weiss 				.index = DT_BI_TCXO,
72*980d7c84SLuca Weiss 			},
73*980d7c84SLuca Weiss 			.num_parents = 1,
74*980d7c84SLuca Weiss 			.ops = &clk_alpha_pll_lucid_evo_ops,
75*980d7c84SLuca Weiss 		},
76*980d7c84SLuca Weiss 	},
77*980d7c84SLuca Weiss };
78*980d7c84SLuca Weiss 
79*980d7c84SLuca Weiss static const struct clk_div_table post_div_table_gpu_cc_pll0_out_even[] = {
80*980d7c84SLuca Weiss 	{ 0x1, 2 },
81*980d7c84SLuca Weiss 	{ }
82*980d7c84SLuca Weiss };
83*980d7c84SLuca Weiss 
84*980d7c84SLuca Weiss static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = {
85*980d7c84SLuca Weiss 	.offset = 0x0,
86*980d7c84SLuca Weiss 	.post_div_shift = 10,
87*980d7c84SLuca Weiss 	.post_div_table = post_div_table_gpu_cc_pll0_out_even,
88*980d7c84SLuca Weiss 	.num_post_div = ARRAY_SIZE(post_div_table_gpu_cc_pll0_out_even),
89*980d7c84SLuca Weiss 	.width = 4,
90*980d7c84SLuca Weiss 	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE],
91*980d7c84SLuca Weiss 	.clkr.hw.init = &(const struct clk_init_data) {
92*980d7c84SLuca Weiss 		.name = "gpu_cc_pll0_out_even",
93*980d7c84SLuca Weiss 		.parent_hws = (const struct clk_hw*[]) {
94*980d7c84SLuca Weiss 			&gpu_cc_pll0.clkr.hw,
95*980d7c84SLuca Weiss 		},
96*980d7c84SLuca Weiss 		.num_parents = 1,
97*980d7c84SLuca Weiss 		.flags = CLK_SET_RATE_PARENT,
98*980d7c84SLuca Weiss 		.ops = &clk_alpha_pll_postdiv_lucid_ole_ops,
99*980d7c84SLuca Weiss 	},
100*980d7c84SLuca Weiss };
101*980d7c84SLuca Weiss 
102*980d7c84SLuca Weiss static const struct parent_map gpu_cc_parent_map_0[] = {
103*980d7c84SLuca Weiss 	{ P_BI_TCXO, 0 },
104*980d7c84SLuca Weiss 	{ P_GPLL0_OUT_MAIN, 5 },
105*980d7c84SLuca Weiss 	{ P_GPLL0_OUT_MAIN_DIV, 6 },
106*980d7c84SLuca Weiss };
107*980d7c84SLuca Weiss 
108*980d7c84SLuca Weiss static const struct clk_parent_data gpu_cc_parent_data_0[] = {
109*980d7c84SLuca Weiss 	{ .index = DT_BI_TCXO },
110*980d7c84SLuca Weiss 	{ .index = DT_GPLL0_OUT_MAIN },
111*980d7c84SLuca Weiss 	{ .index = DT_GPLL0_OUT_MAIN_DIV },
112*980d7c84SLuca Weiss };
113*980d7c84SLuca Weiss 
114*980d7c84SLuca Weiss static const struct parent_map gpu_cc_parent_map_1[] = {
115*980d7c84SLuca Weiss 	{ P_BI_TCXO, 0 },
116*980d7c84SLuca Weiss 	{ P_GPU_CC_PLL0_OUT_MAIN, 1 },
117*980d7c84SLuca Weiss 	{ P_GPU_CC_PLL0_OUT_EVEN, 2 },
118*980d7c84SLuca Weiss 	{ P_GPU_CC_PLL0_OUT_ODD, 3 },
119*980d7c84SLuca Weiss 	{ P_GPLL0_OUT_MAIN, 5 },
120*980d7c84SLuca Weiss 	{ P_GPLL0_OUT_MAIN_DIV, 6 },
121*980d7c84SLuca Weiss };
122*980d7c84SLuca Weiss 
123*980d7c84SLuca Weiss static const struct clk_parent_data gpu_cc_parent_data_1[] = {
124*980d7c84SLuca Weiss 	{ .index = DT_BI_TCXO },
125*980d7c84SLuca Weiss 	{ .hw = &gpu_cc_pll0.clkr.hw },
126*980d7c84SLuca Weiss 	{ .hw = &gpu_cc_pll0_out_even.clkr.hw },
127*980d7c84SLuca Weiss 	{ .hw = &gpu_cc_pll0.clkr.hw },
128*980d7c84SLuca Weiss 	{ .index = DT_GPLL0_OUT_MAIN },
129*980d7c84SLuca Weiss 	{ .index = DT_GPLL0_OUT_MAIN_DIV },
130*980d7c84SLuca Weiss };
131*980d7c84SLuca Weiss 
132*980d7c84SLuca Weiss static const struct freq_tbl ftbl_gpu_cc_ff_clk_src[] = {
133*980d7c84SLuca Weiss 	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
134*980d7c84SLuca Weiss 	{ }
135*980d7c84SLuca Weiss };
136*980d7c84SLuca Weiss 
137*980d7c84SLuca Weiss static struct clk_rcg2 gpu_cc_ff_clk_src = {
138*980d7c84SLuca Weiss 	.cmd_rcgr = 0x9474,
139*980d7c84SLuca Weiss 	.mnd_width = 0,
140*980d7c84SLuca Weiss 	.hid_width = 5,
141*980d7c84SLuca Weiss 	.parent_map = gpu_cc_parent_map_0,
142*980d7c84SLuca Weiss 	.freq_tbl = ftbl_gpu_cc_ff_clk_src,
143*980d7c84SLuca Weiss 	.clkr.hw.init = &(const struct clk_init_data) {
144*980d7c84SLuca Weiss 		.name = "gpu_cc_ff_clk_src",
145*980d7c84SLuca Weiss 		.parent_data = gpu_cc_parent_data_0,
146*980d7c84SLuca Weiss 		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
147*980d7c84SLuca Weiss 		.flags = CLK_SET_RATE_PARENT,
148*980d7c84SLuca Weiss 		.ops = &clk_rcg2_shared_ops,
149*980d7c84SLuca Weiss 	},
150*980d7c84SLuca Weiss };
151*980d7c84SLuca Weiss 
152*980d7c84SLuca Weiss static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
153*980d7c84SLuca Weiss 	F(19200000, P_BI_TCXO, 1, 0, 0),
154*980d7c84SLuca Weiss 	F(350000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0),
155*980d7c84SLuca Weiss 	F(650000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0),
156*980d7c84SLuca Weiss 	F(687500000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0),
157*980d7c84SLuca Weiss 	{ }
158*980d7c84SLuca Weiss };
159*980d7c84SLuca Weiss 
160*980d7c84SLuca Weiss static struct clk_rcg2 gpu_cc_gmu_clk_src = {
161*980d7c84SLuca Weiss 	.cmd_rcgr = 0x9318,
162*980d7c84SLuca Weiss 	.mnd_width = 0,
163*980d7c84SLuca Weiss 	.hid_width = 5,
164*980d7c84SLuca Weiss 	.parent_map = gpu_cc_parent_map_1,
165*980d7c84SLuca Weiss 	.freq_tbl = ftbl_gpu_cc_gmu_clk_src,
166*980d7c84SLuca Weiss 	.clkr.hw.init = &(const struct clk_init_data) {
167*980d7c84SLuca Weiss 		.name = "gpu_cc_gmu_clk_src",
168*980d7c84SLuca Weiss 		.parent_data = gpu_cc_parent_data_1,
169*980d7c84SLuca Weiss 		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
170*980d7c84SLuca Weiss 		.flags = CLK_SET_RATE_PARENT,
171*980d7c84SLuca Weiss 		.ops = &clk_rcg2_shared_ops,
172*980d7c84SLuca Weiss 	},
173*980d7c84SLuca Weiss };
174*980d7c84SLuca Weiss 
175*980d7c84SLuca Weiss static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = {
176*980d7c84SLuca Weiss 	F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
177*980d7c84SLuca Weiss 	F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
178*980d7c84SLuca Weiss 	F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0),
179*980d7c84SLuca Weiss 	{ }
180*980d7c84SLuca Weiss };
181*980d7c84SLuca Weiss 
182*980d7c84SLuca Weiss static struct clk_rcg2 gpu_cc_hub_clk_src = {
183*980d7c84SLuca Weiss 	.cmd_rcgr = 0x93ec,
184*980d7c84SLuca Weiss 	.mnd_width = 0,
185*980d7c84SLuca Weiss 	.hid_width = 5,
186*980d7c84SLuca Weiss 	.parent_map = gpu_cc_parent_map_1,
187*980d7c84SLuca Weiss 	.freq_tbl = ftbl_gpu_cc_hub_clk_src,
188*980d7c84SLuca Weiss 	.clkr.hw.init = &(const struct clk_init_data) {
189*980d7c84SLuca Weiss 		.name = "gpu_cc_hub_clk_src",
190*980d7c84SLuca Weiss 		.parent_data = gpu_cc_parent_data_1,
191*980d7c84SLuca Weiss 		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_1),
192*980d7c84SLuca Weiss 		.flags = CLK_SET_RATE_PARENT,
193*980d7c84SLuca Weiss 		.ops = &clk_rcg2_shared_ops,
194*980d7c84SLuca Weiss 	},
195*980d7c84SLuca Weiss };
196*980d7c84SLuca Weiss 
197*980d7c84SLuca Weiss static struct clk_regmap_div gpu_cc_hub_div_clk_src = {
198*980d7c84SLuca Weiss 	.reg = 0x942c,
199*980d7c84SLuca Weiss 	.shift = 0,
200*980d7c84SLuca Weiss 	.width = 4,
201*980d7c84SLuca Weiss 	.clkr.hw.init = &(const struct clk_init_data) {
202*980d7c84SLuca Weiss 		.name = "gpu_cc_hub_div_clk_src",
203*980d7c84SLuca Weiss 		.parent_hws = (const struct clk_hw*[]) {
204*980d7c84SLuca Weiss 			&gpu_cc_hub_clk_src.clkr.hw,
205*980d7c84SLuca Weiss 		},
206*980d7c84SLuca Weiss 		.num_parents = 1,
207*980d7c84SLuca Weiss 		.flags = CLK_SET_RATE_PARENT,
208*980d7c84SLuca Weiss 		.ops = &clk_regmap_div_ro_ops,
209*980d7c84SLuca Weiss 	},
210*980d7c84SLuca Weiss };
211*980d7c84SLuca Weiss 
212*980d7c84SLuca Weiss static struct clk_branch gpu_cc_ahb_clk = {
213*980d7c84SLuca Weiss 	.halt_reg = 0x90bc,
214*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT_DELAY,
215*980d7c84SLuca Weiss 	.clkr = {
216*980d7c84SLuca Weiss 		.enable_reg = 0x90bc,
217*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
218*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
219*980d7c84SLuca Weiss 			.name = "gpu_cc_ahb_clk",
220*980d7c84SLuca Weiss 			.parent_hws = (const struct clk_hw*[]) {
221*980d7c84SLuca Weiss 				&gpu_cc_hub_div_clk_src.clkr.hw,
222*980d7c84SLuca Weiss 			},
223*980d7c84SLuca Weiss 			.num_parents = 1,
224*980d7c84SLuca Weiss 			.flags = CLK_SET_RATE_PARENT,
225*980d7c84SLuca Weiss 			.ops = &clk_branch2_ops,
226*980d7c84SLuca Weiss 		},
227*980d7c84SLuca Weiss 	},
228*980d7c84SLuca Weiss };
229*980d7c84SLuca Weiss 
230*980d7c84SLuca Weiss static struct clk_branch gpu_cc_cx_accu_shift_clk = {
231*980d7c84SLuca Weiss 	.halt_reg = 0x910c,
232*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT_VOTED,
233*980d7c84SLuca Weiss 	.clkr = {
234*980d7c84SLuca Weiss 		.enable_reg = 0x910c,
235*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
236*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
237*980d7c84SLuca Weiss 			.name = "gpu_cc_cx_accu_shift_clk",
238*980d7c84SLuca Weiss 			.ops = &clk_branch2_ops,
239*980d7c84SLuca Weiss 		},
240*980d7c84SLuca Weiss 	},
241*980d7c84SLuca Weiss };
242*980d7c84SLuca Weiss 
243*980d7c84SLuca Weiss static struct clk_branch gpu_cc_cx_ff_clk = {
244*980d7c84SLuca Weiss 	.halt_reg = 0x90ec,
245*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT,
246*980d7c84SLuca Weiss 	.clkr = {
247*980d7c84SLuca Weiss 		.enable_reg = 0x90ec,
248*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
249*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
250*980d7c84SLuca Weiss 			.name = "gpu_cc_cx_ff_clk",
251*980d7c84SLuca Weiss 			.parent_hws = (const struct clk_hw*[]) {
252*980d7c84SLuca Weiss 				&gpu_cc_ff_clk_src.clkr.hw,
253*980d7c84SLuca Weiss 			},
254*980d7c84SLuca Weiss 			.num_parents = 1,
255*980d7c84SLuca Weiss 			.flags = CLK_SET_RATE_PARENT,
256*980d7c84SLuca Weiss 			.ops = &clk_branch2_ops,
257*980d7c84SLuca Weiss 		},
258*980d7c84SLuca Weiss 	},
259*980d7c84SLuca Weiss };
260*980d7c84SLuca Weiss 
261*980d7c84SLuca Weiss static struct clk_branch gpu_cc_cx_gmu_clk = {
262*980d7c84SLuca Weiss 	.halt_reg = 0x90d4,
263*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT_VOTED,
264*980d7c84SLuca Weiss 	.clkr = {
265*980d7c84SLuca Weiss 		.enable_reg = 0x90d4,
266*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
267*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
268*980d7c84SLuca Weiss 			.name = "gpu_cc_cx_gmu_clk",
269*980d7c84SLuca Weiss 			.parent_hws = (const struct clk_hw*[]) {
270*980d7c84SLuca Weiss 				&gpu_cc_gmu_clk_src.clkr.hw,
271*980d7c84SLuca Weiss 			},
272*980d7c84SLuca Weiss 			.num_parents = 1,
273*980d7c84SLuca Weiss 			.flags = CLK_SET_RATE_PARENT,
274*980d7c84SLuca Weiss 			.ops = &clk_branch2_aon_ops,
275*980d7c84SLuca Weiss 		},
276*980d7c84SLuca Weiss 	},
277*980d7c84SLuca Weiss };
278*980d7c84SLuca Weiss 
279*980d7c84SLuca Weiss static struct clk_branch gpu_cc_cxo_clk = {
280*980d7c84SLuca Weiss 	.halt_reg = 0x90e4,
281*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT,
282*980d7c84SLuca Weiss 	.clkr = {
283*980d7c84SLuca Weiss 		.enable_reg = 0x90e4,
284*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
285*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
286*980d7c84SLuca Weiss 			.name = "gpu_cc_cxo_clk",
287*980d7c84SLuca Weiss 			.ops = &clk_branch2_ops,
288*980d7c84SLuca Weiss 		},
289*980d7c84SLuca Weiss 	},
290*980d7c84SLuca Weiss };
291*980d7c84SLuca Weiss 
292*980d7c84SLuca Weiss static struct clk_branch gpu_cc_dpm_clk = {
293*980d7c84SLuca Weiss 	.halt_reg = 0x9110,
294*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT,
295*980d7c84SLuca Weiss 	.clkr = {
296*980d7c84SLuca Weiss 		.enable_reg = 0x9110,
297*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
298*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
299*980d7c84SLuca Weiss 			.name = "gpu_cc_dpm_clk",
300*980d7c84SLuca Weiss 			.ops = &clk_branch2_ops,
301*980d7c84SLuca Weiss 		},
302*980d7c84SLuca Weiss 	},
303*980d7c84SLuca Weiss };
304*980d7c84SLuca Weiss 
305*980d7c84SLuca Weiss static struct clk_branch gpu_cc_freq_measure_clk = {
306*980d7c84SLuca Weiss 	.halt_reg = 0x900c,
307*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT,
308*980d7c84SLuca Weiss 	.clkr = {
309*980d7c84SLuca Weiss 		.enable_reg = 0x900c,
310*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
311*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
312*980d7c84SLuca Weiss 			.name = "gpu_cc_freq_measure_clk",
313*980d7c84SLuca Weiss 			.ops = &clk_branch2_ops,
314*980d7c84SLuca Weiss 		},
315*980d7c84SLuca Weiss 	},
316*980d7c84SLuca Weiss };
317*980d7c84SLuca Weiss 
318*980d7c84SLuca Weiss static struct clk_branch gpu_cc_gx_accu_shift_clk = {
319*980d7c84SLuca Weiss 	.halt_reg = 0x9070,
320*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT_VOTED,
321*980d7c84SLuca Weiss 	.clkr = {
322*980d7c84SLuca Weiss 		.enable_reg = 0x9070,
323*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
324*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
325*980d7c84SLuca Weiss 			.name = "gpu_cc_gx_accu_shift_clk",
326*980d7c84SLuca Weiss 			.ops = &clk_branch2_ops,
327*980d7c84SLuca Weiss 		},
328*980d7c84SLuca Weiss 	},
329*980d7c84SLuca Weiss };
330*980d7c84SLuca Weiss 
331*980d7c84SLuca Weiss static struct clk_branch gpu_cc_gx_acd_ahb_ff_clk = {
332*980d7c84SLuca Weiss 	.halt_reg = 0x9068,
333*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT,
334*980d7c84SLuca Weiss 	.clkr = {
335*980d7c84SLuca Weiss 		.enable_reg = 0x9068,
336*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
337*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
338*980d7c84SLuca Weiss 			.name = "gpu_cc_gx_acd_ahb_ff_clk",
339*980d7c84SLuca Weiss 			.parent_hws = (const struct clk_hw*[]) {
340*980d7c84SLuca Weiss 				&gpu_cc_ff_clk_src.clkr.hw,
341*980d7c84SLuca Weiss 			},
342*980d7c84SLuca Weiss 			.num_parents = 1,
343*980d7c84SLuca Weiss 			.flags = CLK_SET_RATE_PARENT,
344*980d7c84SLuca Weiss 			.ops = &clk_branch2_ops,
345*980d7c84SLuca Weiss 		},
346*980d7c84SLuca Weiss 	},
347*980d7c84SLuca Weiss };
348*980d7c84SLuca Weiss 
349*980d7c84SLuca Weiss static struct clk_branch gpu_cc_gx_gmu_clk = {
350*980d7c84SLuca Weiss 	.halt_reg = 0x9060,
351*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT,
352*980d7c84SLuca Weiss 	.clkr = {
353*980d7c84SLuca Weiss 		.enable_reg = 0x9060,
354*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
355*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
356*980d7c84SLuca Weiss 			.name = "gpu_cc_gx_gmu_clk",
357*980d7c84SLuca Weiss 			.parent_hws = (const struct clk_hw*[]) {
358*980d7c84SLuca Weiss 				&gpu_cc_gmu_clk_src.clkr.hw,
359*980d7c84SLuca Weiss 			},
360*980d7c84SLuca Weiss 			.num_parents = 1,
361*980d7c84SLuca Weiss 			.flags = CLK_SET_RATE_PARENT,
362*980d7c84SLuca Weiss 			.ops = &clk_branch2_ops,
363*980d7c84SLuca Weiss 		},
364*980d7c84SLuca Weiss 	},
365*980d7c84SLuca Weiss };
366*980d7c84SLuca Weiss 
367*980d7c84SLuca Weiss static struct clk_branch gpu_cc_gx_rcg_ahb_ff_clk = {
368*980d7c84SLuca Weiss 	.halt_reg = 0x906c,
369*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT_VOTED,
370*980d7c84SLuca Weiss 	.clkr = {
371*980d7c84SLuca Weiss 		.enable_reg = 0x906c,
372*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
373*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
374*980d7c84SLuca Weiss 			.name = "gpu_cc_gx_rcg_ahb_ff_clk",
375*980d7c84SLuca Weiss 			.parent_hws = (const struct clk_hw*[]) {
376*980d7c84SLuca Weiss 				&gpu_cc_ff_clk_src.clkr.hw,
377*980d7c84SLuca Weiss 			},
378*980d7c84SLuca Weiss 			.num_parents = 1,
379*980d7c84SLuca Weiss 			.flags = CLK_SET_RATE_PARENT,
380*980d7c84SLuca Weiss 			.ops = &clk_branch2_ops,
381*980d7c84SLuca Weiss 		},
382*980d7c84SLuca Weiss 	},
383*980d7c84SLuca Weiss };
384*980d7c84SLuca Weiss 
385*980d7c84SLuca Weiss static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = {
386*980d7c84SLuca Weiss 	.halt_reg = 0x7000,
387*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT_VOTED,
388*980d7c84SLuca Weiss 	.clkr = {
389*980d7c84SLuca Weiss 		.enable_reg = 0x7000,
390*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
391*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
392*980d7c84SLuca Weiss 			.name = "gpu_cc_hlos1_vote_gpu_smmu_clk",
393*980d7c84SLuca Weiss 			.ops = &clk_branch2_ops,
394*980d7c84SLuca Weiss 		},
395*980d7c84SLuca Weiss 	},
396*980d7c84SLuca Weiss };
397*980d7c84SLuca Weiss 
398*980d7c84SLuca Weiss static struct clk_branch gpu_cc_hub_aon_clk = {
399*980d7c84SLuca Weiss 	.halt_reg = 0x93e8,
400*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT_VOTED,
401*980d7c84SLuca Weiss 	.clkr = {
402*980d7c84SLuca Weiss 		.enable_reg = 0x93e8,
403*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
404*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
405*980d7c84SLuca Weiss 			.name = "gpu_cc_hub_aon_clk",
406*980d7c84SLuca Weiss 			.parent_hws = (const struct clk_hw*[]) {
407*980d7c84SLuca Weiss 				&gpu_cc_hub_clk_src.clkr.hw,
408*980d7c84SLuca Weiss 			},
409*980d7c84SLuca Weiss 			.num_parents = 1,
410*980d7c84SLuca Weiss 			.flags = CLK_SET_RATE_PARENT,
411*980d7c84SLuca Weiss 			.ops = &clk_branch2_aon_ops,
412*980d7c84SLuca Weiss 		},
413*980d7c84SLuca Weiss 	},
414*980d7c84SLuca Weiss };
415*980d7c84SLuca Weiss 
416*980d7c84SLuca Weiss static struct clk_branch gpu_cc_hub_cx_int_clk = {
417*980d7c84SLuca Weiss 	.halt_reg = 0x90e8,
418*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT_VOTED,
419*980d7c84SLuca Weiss 	.clkr = {
420*980d7c84SLuca Weiss 		.enable_reg = 0x90e8,
421*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
422*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
423*980d7c84SLuca Weiss 			.name = "gpu_cc_hub_cx_int_clk",
424*980d7c84SLuca Weiss 			.parent_hws = (const struct clk_hw*[]) {
425*980d7c84SLuca Weiss 				&gpu_cc_hub_clk_src.clkr.hw,
426*980d7c84SLuca Weiss 			},
427*980d7c84SLuca Weiss 			.num_parents = 1,
428*980d7c84SLuca Weiss 			.flags = CLK_SET_RATE_PARENT,
429*980d7c84SLuca Weiss 			.ops = &clk_branch2_aon_ops,
430*980d7c84SLuca Weiss 		},
431*980d7c84SLuca Weiss 	},
432*980d7c84SLuca Weiss };
433*980d7c84SLuca Weiss 
434*980d7c84SLuca Weiss static struct clk_branch gpu_cc_memnoc_gfx_clk = {
435*980d7c84SLuca Weiss 	.halt_reg = 0x90f4,
436*980d7c84SLuca Weiss 	.halt_check = BRANCH_HALT_VOTED,
437*980d7c84SLuca Weiss 	.clkr = {
438*980d7c84SLuca Weiss 		.enable_reg = 0x90f4,
439*980d7c84SLuca Weiss 		.enable_mask = BIT(0),
440*980d7c84SLuca Weiss 		.hw.init = &(const struct clk_init_data) {
441*980d7c84SLuca Weiss 			.name = "gpu_cc_memnoc_gfx_clk",
442*980d7c84SLuca Weiss 			.ops = &clk_branch2_ops,
443*980d7c84SLuca Weiss 		},
444*980d7c84SLuca Weiss 	},
445*980d7c84SLuca Weiss };
446*980d7c84SLuca Weiss 
447*980d7c84SLuca Weiss static struct gdsc gpu_cc_cx_gdsc = {
448*980d7c84SLuca Weiss 	.gdscr = 0x9080,
449*980d7c84SLuca Weiss 	.gds_hw_ctrl = 0x9094,
450*980d7c84SLuca Weiss 	.en_rest_wait_val = 0x2,
451*980d7c84SLuca Weiss 	.en_few_wait_val = 0x2,
452*980d7c84SLuca Weiss 	.clk_dis_wait_val = 0x8,
453*980d7c84SLuca Weiss 	.pd = {
454*980d7c84SLuca Weiss 		.name = "gpu_cc_cx_gdsc",
455*980d7c84SLuca Weiss 	},
456*980d7c84SLuca Weiss 	.pwrsts = PWRSTS_OFF_ON,
457*980d7c84SLuca Weiss 	.flags = RETAIN_FF_ENABLE | VOTABLE,
458*980d7c84SLuca Weiss };
459*980d7c84SLuca Weiss 
460*980d7c84SLuca Weiss static struct clk_regmap *gpu_cc_milos_clocks[] = {
461*980d7c84SLuca Weiss 	[GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
462*980d7c84SLuca Weiss 	[GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_clk.clkr,
463*980d7c84SLuca Weiss 	[GPU_CC_CX_FF_CLK] = &gpu_cc_cx_ff_clk.clkr,
464*980d7c84SLuca Weiss 	[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
465*980d7c84SLuca Weiss 	[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
466*980d7c84SLuca Weiss 	[GPU_CC_DPM_CLK] = &gpu_cc_dpm_clk.clkr,
467*980d7c84SLuca Weiss 	[GPU_CC_FF_CLK_SRC] = &gpu_cc_ff_clk_src.clkr,
468*980d7c84SLuca Weiss 	[GPU_CC_FREQ_MEASURE_CLK] = &gpu_cc_freq_measure_clk.clkr,
469*980d7c84SLuca Weiss 	[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
470*980d7c84SLuca Weiss 	[GPU_CC_GX_ACCU_SHIFT_CLK] = &gpu_cc_gx_accu_shift_clk.clkr,
471*980d7c84SLuca Weiss 	[GPU_CC_GX_ACD_AHB_FF_CLK] = &gpu_cc_gx_acd_ahb_ff_clk.clkr,
472*980d7c84SLuca Weiss 	[GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
473*980d7c84SLuca Weiss 	[GPU_CC_GX_RCG_AHB_FF_CLK] = &gpu_cc_gx_rcg_ahb_ff_clk.clkr,
474*980d7c84SLuca Weiss 	[GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr,
475*980d7c84SLuca Weiss 	[GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr,
476*980d7c84SLuca Weiss 	[GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr,
477*980d7c84SLuca Weiss 	[GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr,
478*980d7c84SLuca Weiss 	[GPU_CC_HUB_DIV_CLK_SRC] = &gpu_cc_hub_div_clk_src.clkr,
479*980d7c84SLuca Weiss 	[GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr,
480*980d7c84SLuca Weiss 	[GPU_CC_PLL0] = &gpu_cc_pll0.clkr,
481*980d7c84SLuca Weiss 	[GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr,
482*980d7c84SLuca Weiss };
483*980d7c84SLuca Weiss 
484*980d7c84SLuca Weiss static struct gdsc *gpu_cc_milos_gdscs[] = {
485*980d7c84SLuca Weiss 	[GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc,
486*980d7c84SLuca Weiss };
487*980d7c84SLuca Weiss 
488*980d7c84SLuca Weiss static const struct qcom_reset_map gpu_cc_milos_resets[] = {
489*980d7c84SLuca Weiss 	[GPU_CC_CB_BCR] = { 0x93a0 },
490*980d7c84SLuca Weiss 	[GPU_CC_CX_BCR] = { 0x907c },
491*980d7c84SLuca Weiss 	[GPU_CC_FAST_HUB_BCR] = { 0x93e4 },
492*980d7c84SLuca Weiss 	[GPU_CC_FF_BCR] = { 0x9470 },
493*980d7c84SLuca Weiss 	[GPU_CC_GMU_BCR] = { 0x9314 },
494*980d7c84SLuca Weiss 	[GPU_CC_GX_BCR] = { 0x905c },
495*980d7c84SLuca Weiss 	[GPU_CC_RBCPR_BCR] = { 0x91e0 },
496*980d7c84SLuca Weiss 	[GPU_CC_XO_BCR] = { 0x9000 },
497*980d7c84SLuca Weiss };
498*980d7c84SLuca Weiss 
499*980d7c84SLuca Weiss static struct clk_alpha_pll *gpu_cc_milos_plls[] = {
500*980d7c84SLuca Weiss 	&gpu_cc_pll0,
501*980d7c84SLuca Weiss };
502*980d7c84SLuca Weiss 
503*980d7c84SLuca Weiss static u32 gpu_cc_milos_critical_cbcrs[] = {
504*980d7c84SLuca Weiss 	0x93a4, /* GPU_CC_CB_CLK */
505*980d7c84SLuca Weiss 	0x9008, /* GPU_CC_CXO_AON_CLK */
506*980d7c84SLuca Weiss 	0x9010, /* GPU_CC_DEMET_CLK */
507*980d7c84SLuca Weiss 	0x9064, /* GPU_CC_GX_AHB_FF_CLK */
508*980d7c84SLuca Weiss 	0x93a8, /* GPU_CC_RSCC_HUB_AON_CLK */
509*980d7c84SLuca Weiss 	0x9004, /* GPU_CC_RSCC_XO_AON_CLK */
510*980d7c84SLuca Weiss 	0x90cc, /* GPU_CC_SLEEP_CLK */
511*980d7c84SLuca Weiss };
512*980d7c84SLuca Weiss 
513*980d7c84SLuca Weiss static const struct regmap_config gpu_cc_milos_regmap_config = {
514*980d7c84SLuca Weiss 	.reg_bits = 32,
515*980d7c84SLuca Weiss 	.reg_stride = 4,
516*980d7c84SLuca Weiss 	.val_bits = 32,
517*980d7c84SLuca Weiss 	.max_register = 0x95e8,
518*980d7c84SLuca Weiss 	.fast_io = true,
519*980d7c84SLuca Weiss };
520*980d7c84SLuca Weiss 
521*980d7c84SLuca Weiss static struct qcom_cc_driver_data gpu_cc_milos_driver_data = {
522*980d7c84SLuca Weiss 	.alpha_plls = gpu_cc_milos_plls,
523*980d7c84SLuca Weiss 	.num_alpha_plls = ARRAY_SIZE(gpu_cc_milos_plls),
524*980d7c84SLuca Weiss 	.clk_cbcrs = gpu_cc_milos_critical_cbcrs,
525*980d7c84SLuca Weiss 	.num_clk_cbcrs = ARRAY_SIZE(gpu_cc_milos_critical_cbcrs),
526*980d7c84SLuca Weiss };
527*980d7c84SLuca Weiss 
528*980d7c84SLuca Weiss static const struct qcom_cc_desc gpu_cc_milos_desc = {
529*980d7c84SLuca Weiss 	.config = &gpu_cc_milos_regmap_config,
530*980d7c84SLuca Weiss 	.clks = gpu_cc_milos_clocks,
531*980d7c84SLuca Weiss 	.num_clks = ARRAY_SIZE(gpu_cc_milos_clocks),
532*980d7c84SLuca Weiss 	.resets = gpu_cc_milos_resets,
533*980d7c84SLuca Weiss 	.num_resets = ARRAY_SIZE(gpu_cc_milos_resets),
534*980d7c84SLuca Weiss 	.gdscs = gpu_cc_milos_gdscs,
535*980d7c84SLuca Weiss 	.num_gdscs = ARRAY_SIZE(gpu_cc_milos_gdscs),
536*980d7c84SLuca Weiss 	.use_rpm = true,
537*980d7c84SLuca Weiss 	.driver_data = &gpu_cc_milos_driver_data,
538*980d7c84SLuca Weiss };
539*980d7c84SLuca Weiss 
540*980d7c84SLuca Weiss static const struct of_device_id gpu_cc_milos_match_table[] = {
541*980d7c84SLuca Weiss 	{ .compatible = "qcom,milos-gpucc" },
542*980d7c84SLuca Weiss 	{ }
543*980d7c84SLuca Weiss };
544*980d7c84SLuca Weiss MODULE_DEVICE_TABLE(of, gpu_cc_milos_match_table);
545*980d7c84SLuca Weiss 
546*980d7c84SLuca Weiss static int gpu_cc_milos_probe(struct platform_device *pdev)
547*980d7c84SLuca Weiss {
548*980d7c84SLuca Weiss 	return qcom_cc_probe(pdev, &gpu_cc_milos_desc);
549*980d7c84SLuca Weiss }
550*980d7c84SLuca Weiss 
551*980d7c84SLuca Weiss static struct platform_driver gpu_cc_milos_driver = {
552*980d7c84SLuca Weiss 	.probe = gpu_cc_milos_probe,
553*980d7c84SLuca Weiss 	.driver = {
554*980d7c84SLuca Weiss 		.name = "gpu_cc-milos",
555*980d7c84SLuca Weiss 		.of_match_table = gpu_cc_milos_match_table,
556*980d7c84SLuca Weiss 	},
557*980d7c84SLuca Weiss };
558*980d7c84SLuca Weiss 
559*980d7c84SLuca Weiss module_platform_driver(gpu_cc_milos_driver);
560*980d7c84SLuca Weiss 
561*980d7c84SLuca Weiss MODULE_DESCRIPTION("QTI GPU_CC Milos Driver");
562*980d7c84SLuca Weiss MODULE_LICENSE("GPL");
563