Linux Audio

Check our new training course

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