1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2018, 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,videocc-sdm845.h>
14 #include "clk-alpha-pll.h"
15 #include "clk-branch.h"
17 #include "clk-regmap.h"
23 P_VIDEO_PLL0_OUT_MAIN
,
24 /* P_VIDEO_PLL0_OUT_EVEN, */
25 /* P_VIDEO_PLL0_OUT_ODD, */
28 static const struct alpha_pll_config video_pll0_config
= {
33 static struct clk_alpha_pll video_pll0
= {
35 .regs
= clk_alpha_pll_regs
[CLK_ALPHA_PLL_TYPE_FABIA
],
37 .hw
.init
= &(struct clk_init_data
){
39 .parent_data
= &(const struct clk_parent_data
){
40 .fw_name
= "bi_tcxo", .name
= "bi_tcxo",
43 .ops
= &clk_alpha_pll_fabia_ops
,
48 static const struct parent_map video_cc_parent_map_0
[] = {
50 { P_VIDEO_PLL0_OUT_MAIN
, 1 },
51 /* { P_VIDEO_PLL0_OUT_EVEN, 2 }, */
52 /* { P_VIDEO_PLL0_OUT_ODD, 3 }, */
55 static const struct clk_parent_data video_cc_parent_data_0
[] = {
56 { .fw_name
= "bi_tcxo", .name
= "bi_tcxo" },
57 { .hw
= &video_pll0
.clkr
.hw
},
58 /* { .name = "video_pll0_out_even" }, */
59 /* { .name = "video_pll0_out_odd" }, */
62 static const struct freq_tbl ftbl_video_cc_venus_clk_src
[] = {
63 F(100000000, P_VIDEO_PLL0_OUT_MAIN
, 4, 0, 0),
64 F(200000000, P_VIDEO_PLL0_OUT_MAIN
, 2, 0, 0),
65 F(330000000, P_VIDEO_PLL0_OUT_MAIN
, 1, 0, 0),
66 F(404000000, P_VIDEO_PLL0_OUT_MAIN
, 1, 0, 0),
67 F(444000000, P_VIDEO_PLL0_OUT_MAIN
, 1, 0, 0),
68 F(533000000, P_VIDEO_PLL0_OUT_MAIN
, 1, 0, 0),
72 static struct clk_rcg2 video_cc_venus_clk_src
= {
76 .parent_map
= video_cc_parent_map_0
,
77 .freq_tbl
= ftbl_video_cc_venus_clk_src
,
78 .clkr
.hw
.init
= &(struct clk_init_data
){
79 .name
= "video_cc_venus_clk_src",
80 .parent_data
= video_cc_parent_data_0
,
81 .num_parents
= ARRAY_SIZE(video_cc_parent_data_0
),
82 .flags
= CLK_SET_RATE_PARENT
,
83 .ops
= &clk_rcg2_shared_ops
,
87 static struct clk_branch video_cc_apb_clk
= {
89 .halt_check
= BRANCH_HALT
,
92 .enable_mask
= BIT(0),
93 .hw
.init
= &(struct clk_init_data
){
94 .name
= "video_cc_apb_clk",
95 .ops
= &clk_branch2_ops
,
100 static struct clk_branch video_cc_at_clk
= {
102 .halt_check
= BRANCH_HALT
,
105 .enable_mask
= BIT(0),
106 .hw
.init
= &(struct clk_init_data
){
107 .name
= "video_cc_at_clk",
108 .ops
= &clk_branch2_ops
,
113 static struct clk_branch video_cc_qdss_trig_clk
= {
115 .halt_check
= BRANCH_HALT
,
118 .enable_mask
= BIT(0),
119 .hw
.init
= &(struct clk_init_data
){
120 .name
= "video_cc_qdss_trig_clk",
121 .ops
= &clk_branch2_ops
,
126 static struct clk_branch video_cc_qdss_tsctr_div8_clk
= {
128 .halt_check
= BRANCH_HALT
,
131 .enable_mask
= BIT(0),
132 .hw
.init
= &(struct clk_init_data
){
133 .name
= "video_cc_qdss_tsctr_div8_clk",
134 .ops
= &clk_branch2_ops
,
139 static struct clk_branch video_cc_vcodec0_axi_clk
= {
141 .halt_check
= BRANCH_HALT
,
144 .enable_mask
= BIT(0),
145 .hw
.init
= &(struct clk_init_data
){
146 .name
= "video_cc_vcodec0_axi_clk",
147 .ops
= &clk_branch2_ops
,
152 static struct clk_branch video_cc_vcodec0_core_clk
= {
154 .halt_check
= BRANCH_VOTED
,
157 .enable_mask
= BIT(0),
158 .hw
.init
= &(struct clk_init_data
){
159 .name
= "video_cc_vcodec0_core_clk",
160 .parent_hws
= (const struct clk_hw
*[]){
161 &video_cc_venus_clk_src
.clkr
.hw
,
164 .flags
= CLK_SET_RATE_PARENT
,
165 .ops
= &clk_branch2_ops
,
170 static struct clk_branch video_cc_vcodec1_axi_clk
= {
172 .halt_check
= BRANCH_HALT
,
175 .enable_mask
= BIT(0),
176 .hw
.init
= &(struct clk_init_data
){
177 .name
= "video_cc_vcodec1_axi_clk",
178 .ops
= &clk_branch2_ops
,
183 static struct clk_branch video_cc_vcodec1_core_clk
= {
185 .halt_check
= BRANCH_VOTED
,
188 .enable_mask
= BIT(0),
189 .hw
.init
= &(struct clk_init_data
){
190 .name
= "video_cc_vcodec1_core_clk",
191 .parent_hws
= (const struct clk_hw
*[]){
192 &video_cc_venus_clk_src
.clkr
.hw
,
195 .flags
= CLK_SET_RATE_PARENT
,
196 .ops
= &clk_branch2_ops
,
201 static struct clk_branch video_cc_venus_ahb_clk
= {
203 .halt_check
= BRANCH_HALT
,
206 .enable_mask
= BIT(0),
207 .hw
.init
= &(struct clk_init_data
){
208 .name
= "video_cc_venus_ahb_clk",
209 .ops
= &clk_branch2_ops
,
214 static struct clk_branch video_cc_venus_ctl_axi_clk
= {
216 .halt_check
= BRANCH_HALT
,
219 .enable_mask
= BIT(0),
220 .hw
.init
= &(struct clk_init_data
){
221 .name
= "video_cc_venus_ctl_axi_clk",
222 .ops
= &clk_branch2_ops
,
227 static struct clk_branch video_cc_venus_ctl_core_clk
= {
229 .halt_check
= BRANCH_HALT
,
232 .enable_mask
= BIT(0),
233 .hw
.init
= &(struct clk_init_data
){
234 .name
= "video_cc_venus_ctl_core_clk",
235 .parent_hws
= (const struct clk_hw
*[]){
236 &video_cc_venus_clk_src
.clkr
.hw
,
239 .flags
= CLK_SET_RATE_PARENT
,
240 .ops
= &clk_branch2_ops
,
245 static struct gdsc venus_gdsc
= {
248 .name
= "venus_gdsc",
250 .cxcs
= (unsigned int []){ 0x850, 0x910 },
252 .pwrsts
= PWRSTS_OFF_ON
,
253 .flags
= POLL_CFG_GDSCR
,
256 static struct gdsc vcodec0_gdsc
= {
259 .name
= "vcodec0_gdsc",
261 .cxcs
= (unsigned int []){ 0x890, 0x930 },
263 .flags
= HW_CTRL
| POLL_CFG_GDSCR
,
264 .pwrsts
= PWRSTS_OFF_ON
,
267 static struct gdsc vcodec1_gdsc
= {
270 .name
= "vcodec1_gdsc",
272 .cxcs
= (unsigned int []){ 0x8d0, 0x950 },
274 .flags
= HW_CTRL
| POLL_CFG_GDSCR
,
275 .pwrsts
= PWRSTS_OFF_ON
,
278 static struct clk_regmap
*video_cc_sdm845_clocks
[] = {
279 [VIDEO_CC_APB_CLK
] = &video_cc_apb_clk
.clkr
,
280 [VIDEO_CC_AT_CLK
] = &video_cc_at_clk
.clkr
,
281 [VIDEO_CC_QDSS_TRIG_CLK
] = &video_cc_qdss_trig_clk
.clkr
,
282 [VIDEO_CC_QDSS_TSCTR_DIV8_CLK
] = &video_cc_qdss_tsctr_div8_clk
.clkr
,
283 [VIDEO_CC_VCODEC0_AXI_CLK
] = &video_cc_vcodec0_axi_clk
.clkr
,
284 [VIDEO_CC_VCODEC0_CORE_CLK
] = &video_cc_vcodec0_core_clk
.clkr
,
285 [VIDEO_CC_VCODEC1_AXI_CLK
] = &video_cc_vcodec1_axi_clk
.clkr
,
286 [VIDEO_CC_VCODEC1_CORE_CLK
] = &video_cc_vcodec1_core_clk
.clkr
,
287 [VIDEO_CC_VENUS_AHB_CLK
] = &video_cc_venus_ahb_clk
.clkr
,
288 [VIDEO_CC_VENUS_CLK_SRC
] = &video_cc_venus_clk_src
.clkr
,
289 [VIDEO_CC_VENUS_CTL_AXI_CLK
] = &video_cc_venus_ctl_axi_clk
.clkr
,
290 [VIDEO_CC_VENUS_CTL_CORE_CLK
] = &video_cc_venus_ctl_core_clk
.clkr
,
291 [VIDEO_PLL0
] = &video_pll0
.clkr
,
294 static struct gdsc
*video_cc_sdm845_gdscs
[] = {
295 [VENUS_GDSC
] = &venus_gdsc
,
296 [VCODEC0_GDSC
] = &vcodec0_gdsc
,
297 [VCODEC1_GDSC
] = &vcodec1_gdsc
,
300 static const struct regmap_config video_cc_sdm845_regmap_config
= {
304 .max_register
= 0xb90,
308 static const struct qcom_cc_desc video_cc_sdm845_desc
= {
309 .config
= &video_cc_sdm845_regmap_config
,
310 .clks
= video_cc_sdm845_clocks
,
311 .num_clks
= ARRAY_SIZE(video_cc_sdm845_clocks
),
312 .gdscs
= video_cc_sdm845_gdscs
,
313 .num_gdscs
= ARRAY_SIZE(video_cc_sdm845_gdscs
),
316 static const struct of_device_id video_cc_sdm845_match_table
[] = {
317 { .compatible
= "qcom,sdm845-videocc" },
320 MODULE_DEVICE_TABLE(of
, video_cc_sdm845_match_table
);
322 static int video_cc_sdm845_probe(struct platform_device
*pdev
)
324 struct regmap
*regmap
;
326 regmap
= qcom_cc_map(pdev
, &video_cc_sdm845_desc
);
328 return PTR_ERR(regmap
);
330 clk_fabia_pll_configure(&video_pll0
, regmap
, &video_pll0_config
);
332 return qcom_cc_really_probe(&pdev
->dev
, &video_cc_sdm845_desc
, regmap
);
335 static struct platform_driver video_cc_sdm845_driver
= {
336 .probe
= video_cc_sdm845_probe
,
338 .name
= "sdm845-videocc",
339 .of_match_table
= video_cc_sdm845_match_table
,
343 module_platform_driver(video_cc_sdm845_driver
);
345 MODULE_LICENSE("GPL v2");
346 MODULE_DESCRIPTION("QTI SDM845 VIDEOCC Driver");