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) 2018, 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-sdm845.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 "gdsc.h"
 20
 21#define CX_GMU_CBCR_SLEEP_MASK		0xf
 22#define CX_GMU_CBCR_SLEEP_SHIFT		4
 23#define CX_GMU_CBCR_WAKE_MASK		0xf
 24#define CX_GMU_CBCR_WAKE_SHIFT		8
 25#define CLK_DIS_WAIT_SHIFT		12
 26#define CLK_DIS_WAIT_MASK		(0xf << CLK_DIS_WAIT_SHIFT)
 27
 28enum {
 29	P_BI_TCXO,
 30	P_CORE_BI_PLL_TEST_SE,
 31	P_GPLL0_OUT_MAIN,
 32	P_GPLL0_OUT_MAIN_DIV,
 33	P_GPU_CC_PLL1_OUT_EVEN,
 34	P_GPU_CC_PLL1_OUT_MAIN,
 35	P_GPU_CC_PLL1_OUT_ODD,
 36};
 37
 38static const struct parent_map gpu_cc_parent_map_0[] = {
 39	{ P_BI_TCXO, 0 },
 40	{ P_GPU_CC_PLL1_OUT_MAIN, 3 },
 41	{ P_GPLL0_OUT_MAIN, 5 },
 42	{ P_GPLL0_OUT_MAIN_DIV, 6 },
 43	{ P_CORE_BI_PLL_TEST_SE, 7 },
 44};
 45
 46static const char * const gpu_cc_parent_names_0[] = {
 47	"bi_tcxo",
 48	"gpu_cc_pll1",
 49	"gcc_gpu_gpll0_clk_src",
 50	"gcc_gpu_gpll0_div_clk_src",
 51	"core_bi_pll_test_se",
 52};
 53
 54static const struct alpha_pll_config gpu_cc_pll1_config = {
 55	.l = 0x1a,
 56	.alpha = 0xaab,
 57};
 58
 59static struct clk_alpha_pll gpu_cc_pll1 = {
 60	.offset = 0x100,
 61	.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
 62	.clkr = {
 63		.hw.init = &(struct clk_init_data){
 64			.name = "gpu_cc_pll1",
 65			.parent_names = (const char *[]){ "bi_tcxo" },
 66			.num_parents = 1,
 67			.ops = &clk_alpha_pll_fabia_ops,
 68		},
 69	},
 70};
 71
 72static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
 73	F(19200000, P_BI_TCXO, 1, 0, 0),
 74	F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
 75	F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
 76	{ }
 77};
 78
 79static struct clk_rcg2 gpu_cc_gmu_clk_src = {
 80	.cmd_rcgr = 0x1120,
 81	.mnd_width = 0,
 82	.hid_width = 5,
 83	.parent_map = gpu_cc_parent_map_0,
 84	.freq_tbl = ftbl_gpu_cc_gmu_clk_src,
 85	.clkr.hw.init = &(struct clk_init_data){
 86		.name = "gpu_cc_gmu_clk_src",
 87		.parent_names = gpu_cc_parent_names_0,
 88		.num_parents = 5,
 89		.ops = &clk_rcg2_shared_ops,
 90	},
 91};
 92
 93static struct clk_branch gpu_cc_cx_gmu_clk = {
 94	.halt_reg = 0x1098,
 95	.halt_check = BRANCH_HALT,
 96	.clkr = {
 97		.enable_reg = 0x1098,
 98		.enable_mask = BIT(0),
 99		.hw.init = &(struct clk_init_data){
100			.name = "gpu_cc_cx_gmu_clk",
101			.parent_names = (const char *[]){
102				"gpu_cc_gmu_clk_src",
103			},
104			.num_parents = 1,
105			.flags = CLK_SET_RATE_PARENT,
106			.ops = &clk_branch2_ops,
107		},
108	},
109};
110
111static struct clk_branch gpu_cc_cxo_clk = {
112	.halt_reg = 0x109c,
113	.halt_check = BRANCH_HALT,
114	.clkr = {
115		.enable_reg = 0x109c,
116		.enable_mask = BIT(0),
117		.hw.init = &(struct clk_init_data){
118			.name = "gpu_cc_cxo_clk",
119			.ops = &clk_branch2_ops,
120		},
121	},
122};
123
124static struct gdsc gpu_cx_gdsc = {
125	.gdscr = 0x106c,
126	.gds_hw_ctrl = 0x1540,
127	.pd = {
128		.name = "gpu_cx_gdsc",
129	},
130	.pwrsts = PWRSTS_OFF_ON,
131	.flags = VOTABLE,
132};
133
134static struct gdsc gpu_gx_gdsc = {
135	.gdscr = 0x100c,
136	.clamp_io_ctrl = 0x1508,
137	.pd = {
138		.name = "gpu_gx_gdsc",
139		.power_on = gdsc_gx_do_nothing_enable,
140	},
141	.pwrsts = PWRSTS_OFF_ON,
142	.flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR,
143};
144
145static struct clk_regmap *gpu_cc_sdm845_clocks[] = {
146	[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
147	[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
148	[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
149	[GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
150};
151
152static struct gdsc *gpu_cc_sdm845_gdscs[] = {
153	[GPU_CX_GDSC] = &gpu_cx_gdsc,
154	[GPU_GX_GDSC] = &gpu_gx_gdsc,
155};
156
157static const struct regmap_config gpu_cc_sdm845_regmap_config = {
158	.reg_bits	= 32,
159	.reg_stride	= 4,
160	.val_bits	= 32,
161	.max_register	= 0x8008,
162	.fast_io	= true,
163};
164
165static const struct qcom_cc_desc gpu_cc_sdm845_desc = {
166	.config = &gpu_cc_sdm845_regmap_config,
167	.clks = gpu_cc_sdm845_clocks,
168	.num_clks = ARRAY_SIZE(gpu_cc_sdm845_clocks),
169	.gdscs = gpu_cc_sdm845_gdscs,
170	.num_gdscs = ARRAY_SIZE(gpu_cc_sdm845_gdscs),
171};
172
173static const struct of_device_id gpu_cc_sdm845_match_table[] = {
174	{ .compatible = "qcom,sdm845-gpucc" },
175	{ }
176};
177MODULE_DEVICE_TABLE(of, gpu_cc_sdm845_match_table);
178
179static int gpu_cc_sdm845_probe(struct platform_device *pdev)
180{
181	struct regmap *regmap;
182	unsigned int value, mask;
183
184	regmap = qcom_cc_map(pdev, &gpu_cc_sdm845_desc);
185	if (IS_ERR(regmap))
186		return PTR_ERR(regmap);
187
188	clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
189
190	/*
191	 * Configure gpu_cc_cx_gmu_clk with recommended
192	 * wakeup/sleep settings
193	 */
194	mask = CX_GMU_CBCR_WAKE_MASK << CX_GMU_CBCR_WAKE_SHIFT;
195	mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT;
196	value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT;
197	regmap_update_bits(regmap, 0x1098, mask, value);
198
199	/* Configure clk_dis_wait for gpu_cx_gdsc */
200	regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK,
201						8 << CLK_DIS_WAIT_SHIFT);
202
203	return qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap);
204}
205
206static struct platform_driver gpu_cc_sdm845_driver = {
207	.probe = gpu_cc_sdm845_probe,
208	.driver = {
209		.name = "sdm845-gpucc",
210		.of_match_table = gpu_cc_sdm845_match_table,
211	},
212};
213
214static int __init gpu_cc_sdm845_init(void)
215{
216	return platform_driver_register(&gpu_cc_sdm845_driver);
217}
218subsys_initcall(gpu_cc_sdm845_init);
219
220static void __exit gpu_cc_sdm845_exit(void)
221{
222	platform_driver_unregister(&gpu_cc_sdm845_driver);
223}
224module_exit(gpu_cc_sdm845_exit);
225
226MODULE_DESCRIPTION("QTI GPUCC SDM845 Driver");
227MODULE_LICENSE("GPL v2");