1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2017-2020, 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/pm_runtime.h>
10 #include <linux/regmap.h>
12 #include <dt-bindings/clock/qcom,videocc-sm8150.h>
15 #include "clk-alpha-pll.h"
16 #include "clk-branch.h"
18 #include "clk-regmap.h"
24 P_VIDEO_PLL0_OUT_MAIN
,
27 static const struct pll_vco trion_vco
[] = {
28 { 249600000, 2000000000, 0 },
31 static struct alpha_pll_config video_pll0_config
= {
34 .config_ctl_val
= 0x20485699,
35 .config_ctl_hi_val
= 0x00002267,
36 .config_ctl_hi1_val
= 0x00000024,
37 .test_ctl_hi1_val
= 0x00000020,
38 .user_ctl_val
= 0x00000000,
39 .user_ctl_hi_val
= 0x00000805,
40 .user_ctl_hi1_val
= 0x000000D0,
43 static struct clk_alpha_pll video_pll0
= {
45 .vco_table
= trion_vco
,
46 .num_vco
= ARRAY_SIZE(trion_vco
),
47 .regs
= clk_alpha_pll_regs
[CLK_ALPHA_PLL_TYPE_TRION
],
49 .hw
.init
= &(struct clk_init_data
){
51 .parent_data
= &(const struct clk_parent_data
){
55 .ops
= &clk_alpha_pll_trion_ops
,
60 static const struct parent_map video_cc_parent_map_0
[] = {
62 { P_VIDEO_PLL0_OUT_MAIN
, 1 },
65 static const struct clk_parent_data video_cc_parent_data_0
[] = {
66 { .fw_name
= "bi_tcxo" },
67 { .hw
= &video_pll0
.clkr
.hw
},
70 static const struct freq_tbl ftbl_video_cc_iris_clk_src
[] = {
71 F(19200000, P_BI_TCXO
, 1, 0, 0),
72 F(200000000, P_VIDEO_PLL0_OUT_MAIN
, 2, 0, 0),
73 F(240000000, P_VIDEO_PLL0_OUT_MAIN
, 2, 0, 0),
74 F(338000000, P_VIDEO_PLL0_OUT_MAIN
, 2, 0, 0),
75 F(365000000, P_VIDEO_PLL0_OUT_MAIN
, 2, 0, 0),
76 F(444000000, P_VIDEO_PLL0_OUT_MAIN
, 2, 0, 0),
77 F(533000000, P_VIDEO_PLL0_OUT_MAIN
, 2, 0, 0),
81 static struct clk_rcg2 video_cc_iris_clk_src
= {
85 .parent_map
= video_cc_parent_map_0
,
86 .freq_tbl
= ftbl_video_cc_iris_clk_src
,
87 .clkr
.hw
.init
= &(struct clk_init_data
){
88 .name
= "video_cc_iris_clk_src",
89 .parent_data
= video_cc_parent_data_0
,
90 .num_parents
= ARRAY_SIZE(video_cc_parent_data_0
),
91 .flags
= CLK_SET_RATE_PARENT
,
92 .ops
= &clk_rcg2_shared_ops
,
96 static struct clk_branch video_cc_iris_ahb_clk
= {
98 .halt_check
= BRANCH_VOTED
,
101 .enable_mask
= BIT(0),
102 .hw
.init
= &(struct clk_init_data
){
103 .name
= "video_cc_iris_ahb_clk",
104 .parent_hws
= (const struct clk_hw
*[]){
105 &video_cc_iris_clk_src
.clkr
.hw
,
108 .flags
= CLK_SET_RATE_PARENT
,
109 .ops
= &clk_branch2_ops
,
114 static struct clk_branch video_cc_mvs0_core_clk
= {
116 .halt_check
= BRANCH_VOTED
,
119 .enable_mask
= BIT(0),
120 .hw
.init
= &(struct clk_init_data
){
121 .name
= "video_cc_mvs0_core_clk",
122 .parent_hws
= (const struct clk_hw
*[]){
123 &video_cc_iris_clk_src
.clkr
.hw
,
126 .flags
= CLK_SET_RATE_PARENT
,
127 .ops
= &clk_branch2_ops
,
132 static struct clk_branch video_cc_mvs1_core_clk
= {
134 .halt_check
= BRANCH_VOTED
,
137 .enable_mask
= BIT(0),
138 .hw
.init
= &(struct clk_init_data
){
139 .name
= "video_cc_mvs1_core_clk",
140 .parent_hws
= (const struct clk_hw
*[]){
141 &video_cc_iris_clk_src
.clkr
.hw
,
144 .flags
= CLK_SET_RATE_PARENT
,
145 .ops
= &clk_branch2_ops
,
150 static struct clk_branch video_cc_mvsc_core_clk
= {
152 .halt_check
= BRANCH_HALT
,
155 .enable_mask
= BIT(0),
156 .hw
.init
= &(struct clk_init_data
){
157 .name
= "video_cc_mvsc_core_clk",
158 .parent_hws
= (const struct clk_hw
*[]){
159 &video_cc_iris_clk_src
.clkr
.hw
,
162 .flags
= CLK_SET_RATE_PARENT
,
163 .ops
= &clk_branch2_ops
,
168 static struct gdsc venus_gdsc
= {
171 .name
= "venus_gdsc",
174 .pwrsts
= PWRSTS_OFF_ON
,
177 static struct gdsc vcodec0_gdsc
= {
180 .name
= "vcodec0_gdsc",
183 .pwrsts
= PWRSTS_OFF_ON
,
186 static struct gdsc vcodec1_gdsc
= {
189 .name
= "vcodec1_gdsc",
192 .pwrsts
= PWRSTS_OFF_ON
,
194 static struct clk_regmap
*video_cc_sm8150_clocks
[] = {
195 [VIDEO_CC_IRIS_AHB_CLK
] = &video_cc_iris_ahb_clk
.clkr
,
196 [VIDEO_CC_IRIS_CLK_SRC
] = &video_cc_iris_clk_src
.clkr
,
197 [VIDEO_CC_MVS0_CORE_CLK
] = &video_cc_mvs0_core_clk
.clkr
,
198 [VIDEO_CC_MVS1_CORE_CLK
] = &video_cc_mvs1_core_clk
.clkr
,
199 [VIDEO_CC_MVSC_CORE_CLK
] = &video_cc_mvsc_core_clk
.clkr
,
200 [VIDEO_CC_PLL0
] = &video_pll0
.clkr
,
203 static struct gdsc
*video_cc_sm8150_gdscs
[] = {
204 [VENUS_GDSC
] = &venus_gdsc
,
205 [VCODEC0_GDSC
] = &vcodec0_gdsc
,
206 [VCODEC1_GDSC
] = &vcodec1_gdsc
,
209 static const struct regmap_config video_cc_sm8150_regmap_config
= {
213 .max_register
= 0xb94,
217 static const struct qcom_reset_map video_cc_sm8150_resets
[] = {
218 [VIDEO_CC_MVSC_CORE_CLK_BCR
] = { .reg
= 0x850, .bit
= 2, .udelay
= 150 },
219 [VIDEO_CC_INTERFACE_BCR
] = { 0x8f0 },
220 [VIDEO_CC_MVS0_BCR
] = { 0x870 },
221 [VIDEO_CC_MVS1_BCR
] = { 0x8b0 },
222 [VIDEO_CC_MVSC_BCR
] = { 0x810 },
225 static const struct qcom_cc_desc video_cc_sm8150_desc
= {
226 .config
= &video_cc_sm8150_regmap_config
,
227 .clks
= video_cc_sm8150_clocks
,
228 .num_clks
= ARRAY_SIZE(video_cc_sm8150_clocks
),
229 .resets
= video_cc_sm8150_resets
,
230 .num_resets
= ARRAY_SIZE(video_cc_sm8150_resets
),
231 .gdscs
= video_cc_sm8150_gdscs
,
232 .num_gdscs
= ARRAY_SIZE(video_cc_sm8150_gdscs
),
235 static const struct of_device_id video_cc_sm8150_match_table
[] = {
236 { .compatible
= "qcom,sm8150-videocc" },
239 MODULE_DEVICE_TABLE(of
, video_cc_sm8150_match_table
);
241 static int video_cc_sm8150_probe(struct platform_device
*pdev
)
243 struct regmap
*regmap
;
246 ret
= devm_pm_runtime_enable(&pdev
->dev
);
250 ret
= pm_runtime_resume_and_get(&pdev
->dev
);
254 regmap
= qcom_cc_map(pdev
, &video_cc_sm8150_desc
);
255 if (IS_ERR(regmap
)) {
256 pm_runtime_put_sync(&pdev
->dev
);
257 return PTR_ERR(regmap
);
260 clk_trion_pll_configure(&video_pll0
, regmap
, &video_pll0_config
);
262 /* Keep VIDEO_CC_XO_CLK ALWAYS-ON */
263 regmap_update_bits(regmap
, 0x984, 0x1, 0x1);
265 ret
= qcom_cc_really_probe(&pdev
->dev
, &video_cc_sm8150_desc
, regmap
);
267 pm_runtime_put_sync(&pdev
->dev
);
272 static struct platform_driver video_cc_sm8150_driver
= {
273 .probe
= video_cc_sm8150_probe
,
275 .name
= "video_cc-sm8150",
276 .of_match_table
= video_cc_sm8150_match_table
,
280 module_platform_driver(video_cc_sm8150_driver
);
282 MODULE_LICENSE("GPL v2");
283 MODULE_DESCRIPTION("QTI VIDEOCC SM8150 Driver");