File Index
Files and directories
Sign in
FILE

gpucc-sar2130p.c

File preview with syntax highlighting.

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