1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
6 #include <linux/clk-provider.h>
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
9 #include <linux/regmap.h>
11 #include <dt-bindings/clock/qcom,gpucc-sc7180.h>
13 #include "clk-alpha-pll.h"
14 #include "clk-branch.h"
16 #include "clk-regmap.h"
20 #define CX_GMU_CBCR_SLEEP_MASK 0xF
21 #define CX_GMU_CBCR_SLEEP_SHIFT 4
22 #define CX_GMU_CBCR_WAKE_MASK 0xF
23 #define CX_GMU_CBCR_WAKE_SHIFT 8
24 #define CLK_DIS_WAIT_SHIFT 12
25 #define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT)
29 P_CORE_BI_PLL_TEST_SE
,
32 P_GPU_CC_PLL1_OUT_EVEN
,
33 P_GPU_CC_PLL1_OUT_MAIN
,
34 P_GPU_CC_PLL1_OUT_ODD
,
37 static const struct pll_vco fabia_vco
[] = {
38 { 249600000, 2000000000, 0 },
41 static struct clk_alpha_pll gpu_cc_pll1
= {
43 .vco_table
= fabia_vco
,
44 .num_vco
= ARRAY_SIZE(fabia_vco
),
45 .regs
= clk_alpha_pll_regs
[CLK_ALPHA_PLL_TYPE_FABIA
],
47 .hw
.init
= &(struct clk_init_data
){
48 .name
= "gpu_cc_pll1",
49 .parent_data
= &(const struct clk_parent_data
){
53 .ops
= &clk_alpha_pll_fabia_ops
,
58 static const struct parent_map gpu_cc_parent_map_0
[] = {
60 { P_GPU_CC_PLL1_OUT_MAIN
, 3 },
61 { P_GPLL0_OUT_MAIN
, 5 },
62 { P_GPLL0_OUT_MAIN_DIV
, 6 },
65 static const struct clk_parent_data gpu_cc_parent_data_0
[] = {
66 { .fw_name
= "bi_tcxo" },
67 { .hw
= &gpu_cc_pll1
.clkr
.hw
},
68 { .fw_name
= "gcc_gpu_gpll0_clk_src" },
69 { .fw_name
= "gcc_gpu_gpll0_div_clk_src" },
72 static 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),
78 static struct clk_rcg2 gpu_cc_gmu_clk_src
= {
82 .parent_map
= gpu_cc_parent_map_0
,
83 .freq_tbl
= ftbl_gpu_cc_gmu_clk_src
,
84 .clkr
.hw
.init
= &(struct clk_init_data
){
85 .name
= "gpu_cc_gmu_clk_src",
86 .parent_data
= gpu_cc_parent_data_0
,
87 .num_parents
= ARRAY_SIZE(gpu_cc_parent_data_0
),
88 .flags
= CLK_SET_RATE_PARENT
,
89 .ops
= &clk_rcg2_shared_ops
,
93 static struct clk_branch gpu_cc_crc_ahb_clk
= {
95 .halt_check
= BRANCH_HALT_DELAY
,
98 .enable_mask
= BIT(0),
99 .hw
.init
= &(struct clk_init_data
){
100 .name
= "gpu_cc_crc_ahb_clk",
101 .ops
= &clk_branch2_ops
,
106 static struct clk_branch gpu_cc_cx_gmu_clk
= {
108 .halt_check
= BRANCH_HALT
,
110 .enable_reg
= 0x1098,
111 .enable_mask
= BIT(0),
112 .hw
.init
= &(struct clk_init_data
){
113 .name
= "gpu_cc_cx_gmu_clk",
114 .parent_data
= &(const struct clk_parent_data
){
115 .hw
= &gpu_cc_gmu_clk_src
.clkr
.hw
,
118 .flags
= CLK_SET_RATE_PARENT
,
119 .ops
= &clk_branch2_ops
,
124 static struct clk_branch gpu_cc_cx_snoc_dvm_clk
= {
126 .halt_check
= BRANCH_HALT_DELAY
,
128 .enable_reg
= 0x108c,
129 .enable_mask
= BIT(0),
130 .hw
.init
= &(struct clk_init_data
){
131 .name
= "gpu_cc_cx_snoc_dvm_clk",
132 .ops
= &clk_branch2_ops
,
137 static struct clk_branch gpu_cc_cxo_aon_clk
= {
139 .halt_check
= BRANCH_HALT_DELAY
,
141 .enable_reg
= 0x1004,
142 .enable_mask
= BIT(0),
143 .hw
.init
= &(struct clk_init_data
){
144 .name
= "gpu_cc_cxo_aon_clk",
145 .ops
= &clk_branch2_ops
,
150 static struct clk_branch gpu_cc_cxo_clk
= {
152 .halt_check
= BRANCH_HALT
,
154 .enable_reg
= 0x109c,
155 .enable_mask
= BIT(0),
156 .hw
.init
= &(struct clk_init_data
){
157 .name
= "gpu_cc_cxo_clk",
158 .ops
= &clk_branch2_ops
,
163 static struct gdsc cx_gdsc
= {
165 .gds_hw_ctrl
= 0x1540,
169 .pwrsts
= PWRSTS_OFF_ON
,
173 static struct gdsc gx_gdsc
= {
175 .clamp_io_ctrl
= 0x1508,
178 .power_on
= gdsc_gx_do_nothing_enable
,
180 .pwrsts
= PWRSTS_OFF_ON
,
184 static struct gdsc
*gpu_cc_sc7180_gdscs
[] = {
185 [CX_GDSC
] = &cx_gdsc
,
186 [GX_GDSC
] = &gx_gdsc
,
189 static struct clk_regmap
*gpu_cc_sc7180_clocks
[] = {
190 [GPU_CC_CXO_CLK
] = &gpu_cc_cxo_clk
.clkr
,
191 [GPU_CC_CRC_AHB_CLK
] = &gpu_cc_crc_ahb_clk
.clkr
,
192 [GPU_CC_CX_GMU_CLK
] = &gpu_cc_cx_gmu_clk
.clkr
,
193 [GPU_CC_CX_SNOC_DVM_CLK
] = &gpu_cc_cx_snoc_dvm_clk
.clkr
,
194 [GPU_CC_CXO_AON_CLK
] = &gpu_cc_cxo_aon_clk
.clkr
,
195 [GPU_CC_GMU_CLK_SRC
] = &gpu_cc_gmu_clk_src
.clkr
,
196 [GPU_CC_PLL1
] = &gpu_cc_pll1
.clkr
,
199 static const struct regmap_config gpu_cc_sc7180_regmap_config
= {
203 .max_register
= 0x8008,
207 static const struct qcom_cc_desc gpu_cc_sc7180_desc
= {
208 .config
= &gpu_cc_sc7180_regmap_config
,
209 .clks
= gpu_cc_sc7180_clocks
,
210 .num_clks
= ARRAY_SIZE(gpu_cc_sc7180_clocks
),
211 .gdscs
= gpu_cc_sc7180_gdscs
,
212 .num_gdscs
= ARRAY_SIZE(gpu_cc_sc7180_gdscs
),
215 static const struct of_device_id gpu_cc_sc7180_match_table
[] = {
216 { .compatible
= "qcom,sc7180-gpucc" },
219 MODULE_DEVICE_TABLE(of
, gpu_cc_sc7180_match_table
);
221 static int gpu_cc_sc7180_probe(struct platform_device
*pdev
)
223 struct regmap
*regmap
;
224 struct alpha_pll_config gpu_cc_pll_config
= {};
225 unsigned int value
, mask
;
227 regmap
= qcom_cc_map(pdev
, &gpu_cc_sc7180_desc
);
229 return PTR_ERR(regmap
);
231 /* 360MHz Configuration */
232 gpu_cc_pll_config
.l
= 0x12;
233 gpu_cc_pll_config
.alpha
= 0xc000;
234 gpu_cc_pll_config
.config_ctl_val
= 0x20485699;
235 gpu_cc_pll_config
.config_ctl_hi_val
= 0x00002067;
236 gpu_cc_pll_config
.user_ctl_val
= 0x00000001;
237 gpu_cc_pll_config
.user_ctl_hi_val
= 0x00004805;
238 gpu_cc_pll_config
.test_ctl_hi_val
= 0x40000000;
240 clk_fabia_pll_configure(&gpu_cc_pll1
, regmap
, &gpu_cc_pll_config
);
242 /* Recommended WAKEUP/SLEEP settings for the gpu_cc_cx_gmu_clk */
243 mask
= CX_GMU_CBCR_WAKE_MASK
<< CX_GMU_CBCR_WAKE_SHIFT
;
244 mask
|= CX_GMU_CBCR_SLEEP_MASK
<< CX_GMU_CBCR_SLEEP_SHIFT
;
245 value
= 0xF << CX_GMU_CBCR_WAKE_SHIFT
| 0xF << CX_GMU_CBCR_SLEEP_SHIFT
;
246 regmap_update_bits(regmap
, 0x1098, mask
, value
);
248 /* Configure clk_dis_wait for gpu_cx_gdsc */
249 regmap_update_bits(regmap
, 0x106c, CLK_DIS_WAIT_MASK
,
250 8 << CLK_DIS_WAIT_SHIFT
);
252 return qcom_cc_really_probe(pdev
, &gpu_cc_sc7180_desc
, regmap
);
255 static struct platform_driver gpu_cc_sc7180_driver
= {
256 .probe
= gpu_cc_sc7180_probe
,
258 .name
= "sc7180-gpucc",
259 .of_match_table
= gpu_cc_sc7180_match_table
,
263 static int __init
gpu_cc_sc7180_init(void)
265 return platform_driver_register(&gpu_cc_sc7180_driver
);
267 subsys_initcall(gpu_cc_sc7180_init
);
269 static void __exit
gpu_cc_sc7180_exit(void)
271 platform_driver_unregister(&gpu_cc_sc7180_driver
);
273 module_exit(gpu_cc_sc7180_exit
);
275 MODULE_DESCRIPTION("QTI GPU_CC SC7180 Driver");
276 MODULE_LICENSE("GPL v2");