File Index
Files and directories
Sign in
FILE

gpucc-sm8150.c

File preview with syntax highlighting.

linux-6.19.14/drivers/clk/qcom/gpucc-sm8150.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
  4 */
  5
  6#include <linux/clk-provider.h>
  7#include <linux/mod_devicetable.h>
  8#include <linux/module.h>
  9#include <linux/platform_device.h>
 10#include <linux/regmap.h>
 11
 12#include <dt-bindings/clock/qcom,gpucc-sm8150.h>
 13
 14#include "common.h"
 15#include "clk-alpha-pll.h"
 16#include "clk-branch.h"
 17#include "clk-pll.h"
 18#include "clk-rcg.h"
 19#include "clk-regmap.h"
 20#include "reset.h"
 21#include "gdsc.h"
 22
 23enum {
 24	P_BI_TCXO,
 25	P_GPLL0_OUT_MAIN,
 26	P_GPLL0_OUT_MAIN_DIV,
 27	P_GPU_CC_PLL1_OUT_MAIN,
 28};
 29
 30static const struct pll_vco trion_vco[] = {
 31	{ 249600000, 2000000000, 0 },
 32};
 33
 34static struct alpha_pll_config gpu_cc_pll1_config = {
 35	.l = 0x1a,
 36	.alpha = 0xaaa,
 37	.config_ctl_val = 0x20485699,
 38	.config_ctl_hi_val = 0x00002267,
 39	.config_ctl_hi1_val = 0x00000024,
 40	.test_ctl_val = 0x00000000,
 41	.test_ctl_hi_val = 0x00000000,
 42	.test_ctl_hi1_val = 0x00000020,
 43	.user_ctl_val = 0x00000000,
 44	.user_ctl_hi_val = 0x00000805,
 45	.user_ctl_hi1_val = 0x000000d0,
 46};
 47
 48static struct clk_alpha_pll gpu_cc_pll1 = {
 49	.offset = 0x100,
 50	.vco_table = trion_vco,
 51	.num_vco = ARRAY_SIZE(trion_vco),
 52	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
 53	.clkr = {
 54		.hw.init = &(struct clk_init_data){
 55			.name = "gpu_cc_pll1",
 56			.parent_data = &(const struct clk_parent_data){
 57				.fw_name = "bi_tcxo",
 58			},
 59			.num_parents = 1,
 60			.ops = &clk_alpha_pll_trion_ops,
 61		},
 62	},
 63};
 64
 65static const struct parent_map gpu_cc_parent_map_0[] = {
 66	{ P_BI_TCXO, 0 },
 67	{ P_GPU_CC_PLL1_OUT_MAIN, 3 },
 68	{ P_GPLL0_OUT_MAIN, 5 },
 69	{ P_GPLL0_OUT_MAIN_DIV, 6 },
 70};
 71
 72static const struct clk_parent_data gpu_cc_parent_data_0[] = {
 73	{ .fw_name = "bi_tcxo" },
 74	{ .hw = &gpu_cc_pll1.clkr.hw },
 75	{ .fw_name = "gcc_gpu_gpll0_clk_src" },
 76	{ .fw_name = "gcc_gpu_gpll0_div_clk_src" },
 77};
 78
 79static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
 80	F(19200000, P_BI_TCXO, 1, 0, 0),
 81	F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
 82	F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
 83	{ }
 84};
 85
 86static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src_sc8180x[] = {
 87	F(19200000, P_BI_TCXO, 1, 0, 0),
 88	F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
 89	F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0),
 90	F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
 91	{ }
 92};
 93
 94static struct clk_rcg2 gpu_cc_gmu_clk_src = {
 95	.cmd_rcgr = 0x1120,
 96	.mnd_width = 0,
 97	.hid_width = 5,
 98	.parent_map = gpu_cc_parent_map_0,
 99	.freq_tbl = ftbl_gpu_cc_gmu_clk_src,
100	.clkr.hw.init = &(struct clk_init_data){
101		.name = "gpu_cc_gmu_clk_src",
102		.parent_data = gpu_cc_parent_data_0,
103		.num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
104		.flags = CLK_SET_RATE_PARENT,
105		.ops = &clk_rcg2_ops,
106	},
107};
108
109static struct clk_branch gpu_cc_ahb_clk = {
110	.halt_reg = 0x1078,
111	.halt_check = BRANCH_HALT_DELAY,
112	.clkr = {
113		.enable_reg = 0x1078,
114		.enable_mask = BIT(0),
115		.hw.init = &(struct clk_init_data){
116			.name = "gpu_cc_ahb_clk",
117			.ops = &clk_branch2_ops,
118		},
119	},
120};
121
122static struct clk_branch gpu_cc_crc_ahb_clk = {
123	.halt_reg = 0x107c,
124	.halt_check = BRANCH_HALT,
125	.clkr = {
126		.enable_reg = 0x107c,
127		.enable_mask = BIT(0),
128		.hw.init = &(struct clk_init_data){
129			.name = "gpu_cc_crc_ahb_clk",
130			.ops = &clk_branch2_ops,
131		},
132	},
133};
134
135static struct clk_branch gpu_cc_cx_apb_clk = {
136	.halt_reg = 0x1088,
137	.halt_check = BRANCH_HALT,
138	.clkr = {
139		.enable_reg = 0x1088,
140		.enable_mask = BIT(0),
141		.hw.init = &(struct clk_init_data){
142			.name = "gpu_cc_cx_apb_clk",
143			.ops = &clk_branch2_ops,
144		},
145	},
146};
147
148static struct clk_branch gpu_cc_cx_gmu_clk = {
149	.halt_reg = 0x1098,
150	.halt_check = BRANCH_HALT,
151	.clkr = {
152		.enable_reg = 0x1098,
153		.enable_mask = BIT(0),
154		.hw.init = &(struct clk_init_data){
155			.name = "gpu_cc_cx_gmu_clk",
156			.parent_hws = (const struct clk_hw*[]){
157				&gpu_cc_gmu_clk_src.clkr.hw,
158			},
159			.num_parents = 1,
160			.flags = CLK_SET_RATE_PARENT,
161			.ops = &clk_branch2_ops,
162		},
163	},
164};
165
166static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
167	.halt_reg = 0x108c,
168	.halt_check = BRANCH_HALT,
169	.clkr = {
170		.enable_reg = 0x108c,
171		.enable_mask = BIT(0),
172		.hw.init = &(struct clk_init_data){
173			.name = "gpu_cc_cx_snoc_dvm_clk",
174			.ops = &clk_branch2_ops,
175		},
176	},
177};
178
179static struct clk_branch gpu_cc_cxo_aon_clk = {
180	.halt_reg = 0x1004,
181	.halt_check = BRANCH_HALT,
182	.clkr = {
183		.enable_reg = 0x1004,
184		.enable_mask = BIT(0),
185		.hw.init = &(struct clk_init_data){
186			.name = "gpu_cc_cxo_aon_clk",
187			.ops = &clk_branch2_ops,
188		},
189	},
190};
191
192static struct clk_branch gpu_cc_cxo_clk = {
193	.halt_reg = 0x109c,
194	.halt_check = BRANCH_HALT,
195	.clkr = {
196		.enable_reg = 0x109c,
197		.enable_mask = BIT(0),
198		.hw.init = &(struct clk_init_data){
199			.name = "gpu_cc_cxo_clk",
200			.ops = &clk_branch2_ops,
201		},
202	},
203};
204
205static struct clk_branch gpu_cc_gx_gmu_clk = {
206	.halt_reg = 0x1064,
207	.halt_check = BRANCH_HALT,
208	.clkr = {
209		.enable_reg = 0x1064,
210		.enable_mask = BIT(0),
211		.hw.init = &(struct clk_init_data){
212			.name = "gpu_cc_gx_gmu_clk",
213			.parent_hws = (const struct clk_hw*[]){
214				&gpu_cc_gmu_clk_src.clkr.hw,
215			},
216			.num_parents = 1,
217			.flags = CLK_SET_RATE_PARENT,
218			.ops = &clk_branch2_ops,
219		},
220	},
221};
222
223static struct gdsc gpu_cx_gdsc = {
224	.gdscr = 0x106c,
225	.gds_hw_ctrl = 0x1540,
226	.pd = {
227		.name = "gpu_cx_gdsc",
228	},
229	.pwrsts = PWRSTS_OFF_ON,
230	.flags = VOTABLE,
231};
232
233static struct gdsc gpu_gx_gdsc = {
234	.gdscr = 0x100c,
235	.clamp_io_ctrl = 0x1508,
236	.pd = {
237		.name = "gpu_gx_gdsc",
238		.power_on = gdsc_gx_do_nothing_enable,
239	},
240	.pwrsts = PWRSTS_OFF_ON,
241	.flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR,
242};
243
244static struct clk_regmap *gpu_cc_sm8150_clocks[] = {
245	[GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr,
246	[GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
247	[GPU_CC_CX_APB_CLK] = &gpu_cc_cx_apb_clk.clkr,
248	[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
249	[GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
250	[GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
251	[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
252	[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
253	[GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr,
254	[GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
255};
256
257static const struct qcom_reset_map gpu_cc_sm8150_resets[] = {
258	[GPUCC_GPU_CC_CX_BCR] = { 0x1068 },
259	[GPUCC_GPU_CC_GMU_BCR] = { 0x111c },
260	[GPUCC_GPU_CC_GX_BCR] = { 0x1008 },
261	[GPUCC_GPU_CC_SPDM_BCR] = { 0x1110 },
262	[GPUCC_GPU_CC_XO_BCR] = { 0x1000 },
263};
264
265static struct gdsc *gpu_cc_sm8150_gdscs[] = {
266	[GPU_CX_GDSC] = &gpu_cx_gdsc,
267	[GPU_GX_GDSC] = &gpu_gx_gdsc,
268};
269
270static const struct regmap_config gpu_cc_sm8150_regmap_config = {
271	.reg_bits	= 32,
272	.reg_stride	= 4,
273	.val_bits	= 32,
274	.max_register	= 0x8008,
275	.fast_io	= true,
276};
277
278static const struct qcom_cc_desc gpu_cc_sm8150_desc = {
279	.config = &gpu_cc_sm8150_regmap_config,
280	.clks = gpu_cc_sm8150_clocks,
281	.num_clks = ARRAY_SIZE(gpu_cc_sm8150_clocks),
282	.resets = gpu_cc_sm8150_resets,
283	.num_resets = ARRAY_SIZE(gpu_cc_sm8150_resets),
284	.gdscs = gpu_cc_sm8150_gdscs,
285	.num_gdscs = ARRAY_SIZE(gpu_cc_sm8150_gdscs),
286};
287
288static const struct of_device_id gpu_cc_sm8150_match_table[] = {
289	{ .compatible = "qcom,sc8180x-gpucc" },
290	{ .compatible = "qcom,sm8150-gpucc" },
291	{ }
292};
293MODULE_DEVICE_TABLE(of, gpu_cc_sm8150_match_table);
294
295static int gpu_cc_sm8150_probe(struct platform_device *pdev)
296{
297	struct regmap *regmap;
298
299	regmap = qcom_cc_map(pdev, &gpu_cc_sm8150_desc);
300	if (IS_ERR(regmap))
301		return PTR_ERR(regmap);
302
303	if (of_device_is_compatible(pdev->dev.of_node, "qcom,sc8180x-gpucc"))
304		gpu_cc_gmu_clk_src.freq_tbl = ftbl_gpu_cc_gmu_clk_src_sc8180x;
305
306	clk_trion_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
307
308	return qcom_cc_really_probe(&pdev->dev, &gpu_cc_sm8150_desc, regmap);
309}
310
311static struct platform_driver gpu_cc_sm8150_driver = {
312	.probe = gpu_cc_sm8150_probe,
313	.driver = {
314		.name = "sm8150-gpucc",
315		.of_match_table = gpu_cc_sm8150_match_table,
316	},
317};
318
319module_platform_driver(gpu_cc_sm8150_driver);
320
321MODULE_DESCRIPTION("QTI GPUCC SM8150 Driver");
322MODULE_LICENSE("GPL v2");
~/ Read-only file preview.