Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

clk: qcom: Introduce SM8350 VIDEOCC

Add support for the Video Clock Controller found on the SM8350 SoC.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Signed-off-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Link: https://lore.kernel.org/r/20230413-topic-lahaina_vidcc-v4-2-86c714a66a81@linaro.org

authored by

Konrad Dybcio and committed by
Bjorn Andersson
fd0b5b10 6d6a98aa

+562
+9
drivers/clk/qcom/Kconfig
··· 925 925 Say Y if you want to support video devices and functionality such as 926 926 video encode and decode. 927 927 928 + config SM_VIDEOCC_8350 929 + tristate "SM8350 Video Clock Controller" 930 + select SM_GCC_8350 931 + select QCOM_GDSC 932 + help 933 + Support for the video clock controller on SM8350 devices. 934 + Say Y if you want to support video devices and functionality such as 935 + video encode and decode. 936 + 928 937 config SPMI_PMIC_CLKDIV 929 938 tristate "SPMI PMIC clkdiv Support" 930 939 depends on SPMI || COMPILE_TEST
+1
drivers/clk/qcom/Makefile
··· 127 127 obj-$(CONFIG_SM_TCSRCC_8550) += tcsrcc-sm8550.o 128 128 obj-$(CONFIG_SM_VIDEOCC_8150) += videocc-sm8150.o 129 129 obj-$(CONFIG_SM_VIDEOCC_8250) += videocc-sm8250.o 130 + obj-$(CONFIG_SM_VIDEOCC_8350) += videocc-sm8350.o 130 131 obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o 131 132 obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o 132 133 obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
+552
drivers/clk/qcom/videocc-sm8350.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. 4 + * Copyright (c) 2023, Linaro Limited 5 + */ 6 + 7 + #include <linux/clk-provider.h> 8 + #include <linux/module.h> 9 + #include <linux/platform_device.h> 10 + #include <linux/pm_clock.h> 11 + #include <linux/pm_runtime.h> 12 + #include <linux/regmap.h> 13 + 14 + #include <dt-bindings/clock/qcom,sm8350-videocc.h> 15 + #include <dt-bindings/reset/qcom,sm8350-videocc.h> 16 + 17 + #include "clk-alpha-pll.h" 18 + #include "clk-branch.h" 19 + #include "clk-rcg.h" 20 + #include "clk-regmap.h" 21 + #include "clk-regmap-divider.h" 22 + #include "common.h" 23 + #include "reset.h" 24 + #include "gdsc.h" 25 + 26 + enum { 27 + DT_BI_TCXO, 28 + DT_BI_TCXO_AO, 29 + DT_SLEEP_CLK, 30 + }; 31 + 32 + enum { 33 + P_BI_TCXO, 34 + P_BI_TCXO_AO, 35 + P_SLEEP_CLK, 36 + P_VIDEO_PLL0_OUT_MAIN, 37 + P_VIDEO_PLL1_OUT_MAIN, 38 + }; 39 + 40 + static const struct pll_vco lucid_5lpe_vco[] = { 41 + { 249600000, 1750000000, 0 }, 42 + }; 43 + 44 + static const struct alpha_pll_config video_pll0_config = { 45 + .l = 0x25, 46 + .alpha = 0x8000, 47 + .config_ctl_val = 0x20485699, 48 + .config_ctl_hi_val = 0x00002261, 49 + .config_ctl_hi1_val = 0x2a9a699c, 50 + .test_ctl_val = 0x00000000, 51 + .test_ctl_hi_val = 0x00000000, 52 + .test_ctl_hi1_val = 0x01800000, 53 + .user_ctl_val = 0x00000000, 54 + .user_ctl_hi_val = 0x00000805, 55 + .user_ctl_hi1_val = 0x00000000, 56 + }; 57 + 58 + static struct clk_alpha_pll video_pll0 = { 59 + .offset = 0x42c, 60 + .vco_table = lucid_5lpe_vco, 61 + .num_vco = ARRAY_SIZE(lucid_5lpe_vco), 62 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], 63 + .clkr = { 64 + .hw.init = &(const struct clk_init_data) { 65 + .name = "video_pll0", 66 + .parent_data = &(const struct clk_parent_data){ 67 + .index = DT_BI_TCXO, 68 + }, 69 + .num_parents = 1, 70 + .ops = &clk_alpha_pll_lucid_5lpe_ops, 71 + }, 72 + }, 73 + }; 74 + 75 + static const struct alpha_pll_config video_pll1_config = { 76 + .l = 0x2b, 77 + .alpha = 0xc000, 78 + .config_ctl_val = 0x20485699, 79 + .config_ctl_hi_val = 0x00002261, 80 + .config_ctl_hi1_val = 0x2a9a699c, 81 + .test_ctl_val = 0x00000000, 82 + .test_ctl_hi_val = 0x00000000, 83 + .test_ctl_hi1_val = 0x01800000, 84 + .user_ctl_val = 0x00000000, 85 + .user_ctl_hi_val = 0x00000805, 86 + .user_ctl_hi1_val = 0x00000000, 87 + }; 88 + 89 + static struct clk_alpha_pll video_pll1 = { 90 + .offset = 0x7d0, 91 + .vco_table = lucid_5lpe_vco, 92 + .num_vco = ARRAY_SIZE(lucid_5lpe_vco), 93 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], 94 + .clkr = { 95 + .hw.init = &(const struct clk_init_data) { 96 + .name = "video_pll1", 97 + .parent_data = &(const struct clk_parent_data){ 98 + .index = DT_BI_TCXO, 99 + }, 100 + .num_parents = 1, 101 + .ops = &clk_alpha_pll_lucid_5lpe_ops, 102 + }, 103 + }, 104 + }; 105 + 106 + static const struct parent_map video_cc_parent_map_0[] = { 107 + { P_BI_TCXO_AO, 0 }, 108 + }; 109 + 110 + static const struct clk_parent_data video_cc_parent_data_0[] = { 111 + { .index = DT_BI_TCXO_AO }, 112 + }; 113 + 114 + static const struct parent_map video_cc_parent_map_1[] = { 115 + { P_BI_TCXO, 0 }, 116 + { P_VIDEO_PLL0_OUT_MAIN, 1 }, 117 + }; 118 + 119 + static const struct clk_parent_data video_cc_parent_data_1[] = { 120 + { .index = DT_BI_TCXO }, 121 + { .hw = &video_pll0.clkr.hw }, 122 + }; 123 + 124 + static const struct parent_map video_cc_parent_map_2[] = { 125 + { P_BI_TCXO, 0 }, 126 + { P_VIDEO_PLL1_OUT_MAIN, 1 }, 127 + }; 128 + 129 + static const struct clk_parent_data video_cc_parent_data_2[] = { 130 + { .index = DT_BI_TCXO }, 131 + { .hw = &video_pll1.clkr.hw }, 132 + }; 133 + 134 + static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = { 135 + F(19200000, P_BI_TCXO, 1, 0, 0), 136 + { } 137 + }; 138 + 139 + static struct clk_rcg2 video_cc_ahb_clk_src = { 140 + .cmd_rcgr = 0xbd4, 141 + .mnd_width = 0, 142 + .hid_width = 5, 143 + .parent_map = video_cc_parent_map_0, 144 + .freq_tbl = ftbl_video_cc_ahb_clk_src, 145 + .clkr.hw.init = &(const struct clk_init_data) { 146 + .name = "video_cc_ahb_clk_src", 147 + .parent_data = video_cc_parent_data_0, 148 + .num_parents = ARRAY_SIZE(video_cc_parent_data_0), 149 + .flags = CLK_SET_RATE_PARENT, 150 + .ops = &clk_rcg2_shared_ops, 151 + }, 152 + }; 153 + 154 + static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { 155 + F(720000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 156 + F(1014000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 157 + F(1098000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 158 + F(1332000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 159 + { } 160 + }; 161 + 162 + static struct clk_rcg2 video_cc_mvs0_clk_src = { 163 + .cmd_rcgr = 0xb94, 164 + .mnd_width = 0, 165 + .hid_width = 5, 166 + .parent_map = video_cc_parent_map_1, 167 + .freq_tbl = ftbl_video_cc_mvs0_clk_src, 168 + .clkr.hw.init = &(const struct clk_init_data) { 169 + .name = "video_cc_mvs0_clk_src", 170 + .parent_data = video_cc_parent_data_1, 171 + .num_parents = ARRAY_SIZE(video_cc_parent_data_1), 172 + .flags = CLK_SET_RATE_PARENT, 173 + .ops = &clk_rcg2_shared_ops, 174 + }, 175 + }; 176 + 177 + static const struct freq_tbl ftbl_video_cc_mvs1_clk_src[] = { 178 + F(840000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 179 + F(1098000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 180 + F(1332000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 181 + { } 182 + }; 183 + 184 + static struct clk_rcg2 video_cc_mvs1_clk_src = { 185 + .cmd_rcgr = 0xbb4, 186 + .mnd_width = 0, 187 + .hid_width = 5, 188 + .parent_map = video_cc_parent_map_2, 189 + .freq_tbl = ftbl_video_cc_mvs1_clk_src, 190 + .clkr.hw.init = &(const struct clk_init_data) { 191 + .name = "video_cc_mvs1_clk_src", 192 + .parent_data = video_cc_parent_data_2, 193 + .num_parents = ARRAY_SIZE(video_cc_parent_data_2), 194 + .flags = CLK_SET_RATE_PARENT, 195 + .ops = &clk_rcg2_shared_ops, 196 + }, 197 + }; 198 + 199 + static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = { 200 + F(32000, P_SLEEP_CLK, 1, 0, 0), 201 + { } 202 + }; 203 + 204 + static struct clk_rcg2 video_cc_sleep_clk_src = { 205 + .cmd_rcgr = 0xef0, 206 + .mnd_width = 0, 207 + .hid_width = 5, 208 + .freq_tbl = ftbl_video_cc_sleep_clk_src, 209 + .clkr.hw.init = &(const struct clk_init_data) { 210 + .name = "video_cc_sleep_clk_src", 211 + .parent_data = &(const struct clk_parent_data){ 212 + .index = DT_SLEEP_CLK, 213 + }, 214 + .num_parents = 1, 215 + .flags = CLK_SET_RATE_PARENT, 216 + .ops = &clk_rcg2_ops, 217 + }, 218 + }; 219 + 220 + static struct clk_rcg2 video_cc_xo_clk_src = { 221 + .cmd_rcgr = 0xecc, 222 + .mnd_width = 0, 223 + .hid_width = 5, 224 + .parent_map = video_cc_parent_map_0, 225 + .freq_tbl = ftbl_video_cc_ahb_clk_src, 226 + .clkr.hw.init = &(const struct clk_init_data) { 227 + .name = "video_cc_xo_clk_src", 228 + .parent_data = video_cc_parent_data_0, 229 + .num_parents = ARRAY_SIZE(video_cc_parent_data_0), 230 + .flags = CLK_SET_RATE_PARENT, 231 + .ops = &clk_rcg2_ops, 232 + }, 233 + }; 234 + 235 + static struct clk_regmap_div video_cc_mvs0_div_clk_src = { 236 + .reg = 0xd54, 237 + .shift = 0, 238 + .width = 4, 239 + .clkr.hw.init = &(const struct clk_init_data) { 240 + .name = "video_cc_mvs0_div_clk_src", 241 + .parent_hws = (const struct clk_hw*[]){ 242 + &video_cc_mvs0_clk_src.clkr.hw, 243 + }, 244 + .num_parents = 1, 245 + .flags = CLK_SET_RATE_PARENT, 246 + .ops = &clk_regmap_div_ro_ops, 247 + }, 248 + }; 249 + 250 + static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = { 251 + .reg = 0xc54, 252 + .shift = 0, 253 + .width = 4, 254 + .clkr.hw.init = &(const struct clk_init_data) { 255 + .name = "video_cc_mvs0c_div2_div_clk_src", 256 + .parent_hws = (const struct clk_hw*[]){ 257 + &video_cc_mvs0_clk_src.clkr.hw, 258 + }, 259 + .num_parents = 1, 260 + .flags = CLK_SET_RATE_PARENT, 261 + .ops = &clk_regmap_div_ro_ops, 262 + }, 263 + }; 264 + 265 + static struct clk_regmap_div video_cc_mvs1_div_clk_src = { 266 + .reg = 0xdd4, 267 + .shift = 0, 268 + .width = 4, 269 + .clkr.hw.init = &(const struct clk_init_data) { 270 + .name = "video_cc_mvs1_div_clk_src", 271 + .parent_hws = (const struct clk_hw*[]){ 272 + &video_cc_mvs1_clk_src.clkr.hw, 273 + }, 274 + .num_parents = 1, 275 + .flags = CLK_SET_RATE_PARENT, 276 + .ops = &clk_regmap_div_ro_ops, 277 + }, 278 + }; 279 + 280 + static struct clk_regmap_div video_cc_mvs1c_div2_div_clk_src = { 281 + .reg = 0xcf4, 282 + .shift = 0, 283 + .width = 4, 284 + .clkr.hw.init = &(const struct clk_init_data) { 285 + .name = "video_cc_mvs1c_div2_div_clk_src", 286 + .parent_hws = (const struct clk_hw*[]){ 287 + &video_cc_mvs1_clk_src.clkr.hw, 288 + }, 289 + .num_parents = 1, 290 + .flags = CLK_SET_RATE_PARENT, 291 + .ops = &clk_regmap_div_ro_ops, 292 + }, 293 + }; 294 + 295 + static struct clk_branch video_cc_mvs0_clk = { 296 + .halt_reg = 0xd34, 297 + .halt_check = BRANCH_HALT_VOTED, 298 + .hwcg_reg = 0xd34, 299 + .hwcg_bit = 1, 300 + .clkr = { 301 + .enable_reg = 0xd34, 302 + .enable_mask = BIT(0), 303 + .hw.init = &(const struct clk_init_data) { 304 + .name = "video_cc_mvs0_clk", 305 + .parent_hws = (const struct clk_hw*[]){ 306 + &video_cc_mvs0_div_clk_src.clkr.hw, 307 + }, 308 + .num_parents = 1, 309 + .flags = CLK_SET_RATE_PARENT, 310 + .ops = &clk_branch2_ops, 311 + }, 312 + }, 313 + }; 314 + 315 + static struct clk_branch video_cc_mvs0c_clk = { 316 + .halt_reg = 0xc34, 317 + .halt_check = BRANCH_HALT, 318 + .clkr = { 319 + .enable_reg = 0xc34, 320 + .enable_mask = BIT(0), 321 + .hw.init = &(const struct clk_init_data) { 322 + .name = "video_cc_mvs0c_clk", 323 + .parent_hws = (const struct clk_hw*[]){ 324 + &video_cc_mvs0c_div2_div_clk_src.clkr.hw, 325 + }, 326 + .num_parents = 1, 327 + .flags = CLK_SET_RATE_PARENT, 328 + .ops = &clk_branch2_ops, 329 + }, 330 + }, 331 + }; 332 + 333 + static struct clk_branch video_cc_mvs1_clk = { 334 + .halt_reg = 0xdb4, 335 + .halt_check = BRANCH_HALT_VOTED, 336 + .hwcg_reg = 0xdb4, 337 + .hwcg_bit = 1, 338 + .clkr = { 339 + .enable_reg = 0xdb4, 340 + .enable_mask = BIT(0), 341 + .hw.init = &(const struct clk_init_data) { 342 + .name = "video_cc_mvs1_clk", 343 + .parent_hws = (const struct clk_hw*[]){ 344 + &video_cc_mvs1_div_clk_src.clkr.hw, 345 + }, 346 + .num_parents = 1, 347 + .flags = CLK_SET_RATE_PARENT, 348 + .ops = &clk_branch2_ops, 349 + }, 350 + }, 351 + }; 352 + 353 + static struct clk_branch video_cc_mvs1_div2_clk = { 354 + .halt_reg = 0xdf4, 355 + .halt_check = BRANCH_HALT_VOTED, 356 + .hwcg_reg = 0xdf4, 357 + .hwcg_bit = 1, 358 + .clkr = { 359 + .enable_reg = 0xdf4, 360 + .enable_mask = BIT(0), 361 + .hw.init = &(const struct clk_init_data) { 362 + .name = "video_cc_mvs1_div2_clk", 363 + .parent_hws = (const struct clk_hw*[]){ 364 + &video_cc_mvs1c_div2_div_clk_src.clkr.hw, 365 + }, 366 + .num_parents = 1, 367 + .flags = CLK_SET_RATE_PARENT, 368 + .ops = &clk_branch2_ops, 369 + }, 370 + }, 371 + }; 372 + 373 + static struct clk_branch video_cc_mvs1c_clk = { 374 + .halt_reg = 0xcd4, 375 + .halt_check = BRANCH_HALT, 376 + .clkr = { 377 + .enable_reg = 0xcd4, 378 + .enable_mask = BIT(0), 379 + .hw.init = &(const struct clk_init_data) { 380 + .name = "video_cc_mvs1c_clk", 381 + .parent_hws = (const struct clk_hw*[]){ 382 + &video_cc_mvs1c_div2_div_clk_src.clkr.hw, 383 + }, 384 + .num_parents = 1, 385 + .flags = CLK_SET_RATE_PARENT, 386 + .ops = &clk_branch2_ops, 387 + }, 388 + }, 389 + }; 390 + 391 + static struct clk_branch video_cc_sleep_clk = { 392 + .halt_reg = 0xf10, 393 + .halt_check = BRANCH_HALT, 394 + .clkr = { 395 + .enable_reg = 0xf10, 396 + .enable_mask = BIT(0), 397 + .hw.init = &(const struct clk_init_data) { 398 + .name = "video_cc_sleep_clk", 399 + .parent_hws = (const struct clk_hw*[]){ 400 + &video_cc_sleep_clk_src.clkr.hw, 401 + }, 402 + .num_parents = 1, 403 + .flags = CLK_SET_RATE_PARENT, 404 + .ops = &clk_branch2_ops, 405 + }, 406 + }, 407 + }; 408 + 409 + static struct gdsc mvs0c_gdsc = { 410 + .gdscr = 0xbf8, 411 + .pd = { 412 + .name = "mvs0c_gdsc", 413 + }, 414 + .flags = RETAIN_FF_ENABLE, 415 + .pwrsts = PWRSTS_OFF_ON, 416 + }; 417 + 418 + static struct gdsc mvs1c_gdsc = { 419 + .gdscr = 0xc98, 420 + .pd = { 421 + .name = "mvs1c_gdsc", 422 + }, 423 + .flags = RETAIN_FF_ENABLE, 424 + .pwrsts = PWRSTS_OFF_ON, 425 + }; 426 + 427 + static struct gdsc mvs0_gdsc = { 428 + .gdscr = 0xd18, 429 + .pd = { 430 + .name = "mvs0_gdsc", 431 + }, 432 + .flags = HW_CTRL | RETAIN_FF_ENABLE, 433 + .pwrsts = PWRSTS_OFF_ON, 434 + }; 435 + 436 + static struct gdsc mvs1_gdsc = { 437 + .gdscr = 0xd98, 438 + .pd = { 439 + .name = "mvs1_gdsc", 440 + }, 441 + .flags = HW_CTRL | RETAIN_FF_ENABLE, 442 + .pwrsts = PWRSTS_OFF_ON, 443 + }; 444 + 445 + static struct clk_regmap *video_cc_sm8350_clocks[] = { 446 + [VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr, 447 + [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr, 448 + [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr, 449 + [VIDEO_CC_MVS0_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr, 450 + [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, 451 + [VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr, 452 + [VIDEO_CC_MVS1_CLK] = &video_cc_mvs1_clk.clkr, 453 + [VIDEO_CC_MVS1_CLK_SRC] = &video_cc_mvs1_clk_src.clkr, 454 + [VIDEO_CC_MVS1_DIV2_CLK] = &video_cc_mvs1_div2_clk.clkr, 455 + [VIDEO_CC_MVS1_DIV_CLK_SRC] = &video_cc_mvs1_div_clk_src.clkr, 456 + [VIDEO_CC_MVS1C_CLK] = &video_cc_mvs1c_clk.clkr, 457 + [VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC] = &video_cc_mvs1c_div2_div_clk_src.clkr, 458 + [VIDEO_CC_SLEEP_CLK] = &video_cc_sleep_clk.clkr, 459 + [VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr, 460 + [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, 461 + [VIDEO_PLL0] = &video_pll0.clkr, 462 + [VIDEO_PLL1] = &video_pll1.clkr, 463 + }; 464 + 465 + static const struct qcom_reset_map video_cc_sm8350_resets[] = { 466 + [VIDEO_CC_CVP_INTERFACE_BCR] = { 0xe54 }, 467 + [VIDEO_CC_CVP_MVS0_BCR] = { 0xd14 }, 468 + [VIDEO_CC_MVS0C_CLK_ARES] = { 0xc34, 2 }, 469 + [VIDEO_CC_CVP_MVS0C_BCR] = { 0xbf4 }, 470 + [VIDEO_CC_CVP_MVS1_BCR] = { 0xd94 }, 471 + [VIDEO_CC_MVS1C_CLK_ARES] = { 0xcd4, 2 }, 472 + [VIDEO_CC_CVP_MVS1C_BCR] = { 0xc94 }, 473 + }; 474 + 475 + static struct gdsc *video_cc_sm8350_gdscs[] = { 476 + [MVS0C_GDSC] = &mvs0c_gdsc, 477 + [MVS1C_GDSC] = &mvs1c_gdsc, 478 + [MVS0_GDSC] = &mvs0_gdsc, 479 + [MVS1_GDSC] = &mvs1_gdsc, 480 + }; 481 + 482 + static const struct regmap_config video_cc_sm8350_regmap_config = { 483 + .reg_bits = 32, 484 + .reg_stride = 4, 485 + .val_bits = 32, 486 + .max_register = 0x10000, 487 + .fast_io = true, 488 + }; 489 + 490 + static struct qcom_cc_desc video_cc_sm8350_desc = { 491 + .config = &video_cc_sm8350_regmap_config, 492 + .clks = video_cc_sm8350_clocks, 493 + .num_clks = ARRAY_SIZE(video_cc_sm8350_clocks), 494 + .resets = video_cc_sm8350_resets, 495 + .num_resets = ARRAY_SIZE(video_cc_sm8350_resets), 496 + .gdscs = video_cc_sm8350_gdscs, 497 + .num_gdscs = ARRAY_SIZE(video_cc_sm8350_gdscs), 498 + }; 499 + 500 + static int video_cc_sm8350_probe(struct platform_device *pdev) 501 + { 502 + struct regmap *regmap; 503 + int ret; 504 + 505 + ret = devm_pm_runtime_enable(&pdev->dev); 506 + if (ret) 507 + return ret; 508 + 509 + ret = pm_runtime_resume_and_get(&pdev->dev); 510 + if (ret) 511 + return ret; 512 + 513 + regmap = qcom_cc_map(pdev, &video_cc_sm8350_desc); 514 + if (IS_ERR(regmap)) { 515 + pm_runtime_put(&pdev->dev); 516 + return PTR_ERR(regmap); 517 + } 518 + 519 + clk_lucid_pll_configure(&video_pll0, regmap, &video_pll0_config); 520 + clk_lucid_pll_configure(&video_pll1, regmap, &video_pll1_config); 521 + 522 + /* 523 + * Keep clocks always enabled: 524 + * video_cc_ahb_clk 525 + * video_cc_xo_clk 526 + */ 527 + regmap_update_bits(regmap, 0xe58, BIT(0), BIT(0)); 528 + regmap_update_bits(regmap, 0xeec, BIT(0), BIT(0)); 529 + 530 + ret = qcom_cc_really_probe(pdev, &video_cc_sm8350_desc, regmap); 531 + pm_runtime_put(&pdev->dev); 532 + 533 + return ret; 534 + } 535 + 536 + static const struct of_device_id video_cc_sm8350_match_table[] = { 537 + { .compatible = "qcom,sm8350-videocc" }, 538 + { } 539 + }; 540 + MODULE_DEVICE_TABLE(of, video_cc_sm8350_match_table); 541 + 542 + static struct platform_driver video_cc_sm8350_driver = { 543 + .probe = video_cc_sm8350_probe, 544 + .driver = { 545 + .name = "sm8350-videocc", 546 + .of_match_table = video_cc_sm8350_match_table, 547 + }, 548 + }; 549 + module_platform_driver(video_cc_sm8350_driver); 550 + 551 + MODULE_DESCRIPTION("QTI SM8350 VIDEOCC Driver"); 552 + MODULE_LICENSE("GPL");