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 pll_vco lucid_5lpe_vco_8280xp[] = { 45 { 249600000, 1800000000, 0 }, 46 }; 47 48 static const struct alpha_pll_config video_pll0_config = { 49 .l = 0x25, 50 .alpha = 0x8000, 51 .config_ctl_val = 0x20485699, 52 .config_ctl_hi_val = 0x00002261, 53 .config_ctl_hi1_val = 0x2a9a699c, 54 .test_ctl_val = 0x00000000, 55 .test_ctl_hi_val = 0x00000000, 56 .test_ctl_hi1_val = 0x01800000, 57 .user_ctl_val = 0x00000000, 58 .user_ctl_hi_val = 0x00000805, 59 .user_ctl_hi1_val = 0x00000000, 60 }; 61 62 static struct clk_alpha_pll video_pll0 = { 63 .offset = 0x42c, 64 .vco_table = lucid_5lpe_vco, 65 .num_vco = ARRAY_SIZE(lucid_5lpe_vco), 66 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], 67 .clkr = { 68 .hw.init = &(const struct clk_init_data) { 69 .name = "video_pll0", 70 .parent_data = &(const struct clk_parent_data){ 71 .index = DT_BI_TCXO, 72 }, 73 .num_parents = 1, 74 .ops = &clk_alpha_pll_lucid_5lpe_ops, 75 }, 76 }, 77 }; 78 79 static const struct alpha_pll_config video_pll1_config = { 80 .l = 0x2b, 81 .alpha = 0xc000, 82 .config_ctl_val = 0x20485699, 83 .config_ctl_hi_val = 0x00002261, 84 .config_ctl_hi1_val = 0x2a9a699c, 85 .test_ctl_val = 0x00000000, 86 .test_ctl_hi_val = 0x00000000, 87 .test_ctl_hi1_val = 0x01800000, 88 .user_ctl_val = 0x00000000, 89 .user_ctl_hi_val = 0x00000805, 90 .user_ctl_hi1_val = 0x00000000, 91 }; 92 93 static struct clk_alpha_pll video_pll1 = { 94 .offset = 0x7d0, 95 .vco_table = lucid_5lpe_vco, 96 .num_vco = ARRAY_SIZE(lucid_5lpe_vco), 97 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID], 98 .clkr = { 99 .hw.init = &(const struct clk_init_data) { 100 .name = "video_pll1", 101 .parent_data = &(const struct clk_parent_data){ 102 .index = DT_BI_TCXO, 103 }, 104 .num_parents = 1, 105 .ops = &clk_alpha_pll_lucid_5lpe_ops, 106 }, 107 }, 108 }; 109 110 static const struct parent_map video_cc_parent_map_0[] = { 111 { P_BI_TCXO_AO, 0 }, 112 }; 113 114 static const struct clk_parent_data video_cc_parent_data_0[] = { 115 { .index = DT_BI_TCXO_AO }, 116 }; 117 118 static const struct parent_map video_cc_parent_map_1[] = { 119 { P_BI_TCXO, 0 }, 120 { P_VIDEO_PLL0_OUT_MAIN, 1 }, 121 }; 122 123 static const struct clk_parent_data video_cc_parent_data_1[] = { 124 { .index = DT_BI_TCXO }, 125 { .hw = &video_pll0.clkr.hw }, 126 }; 127 128 static const struct parent_map video_cc_parent_map_2[] = { 129 { P_BI_TCXO, 0 }, 130 { P_VIDEO_PLL1_OUT_MAIN, 1 }, 131 }; 132 133 static const struct clk_parent_data video_cc_parent_data_2[] = { 134 { .index = DT_BI_TCXO }, 135 { .hw = &video_pll1.clkr.hw }, 136 }; 137 138 static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = { 139 F(19200000, P_BI_TCXO, 1, 0, 0), 140 { } 141 }; 142 143 static struct clk_rcg2 video_cc_ahb_clk_src = { 144 .cmd_rcgr = 0xbd4, 145 .mnd_width = 0, 146 .hid_width = 5, 147 .parent_map = video_cc_parent_map_0, 148 .freq_tbl = ftbl_video_cc_ahb_clk_src, 149 .clkr.hw.init = &(const struct clk_init_data) { 150 .name = "video_cc_ahb_clk_src", 151 .parent_data = video_cc_parent_data_0, 152 .num_parents = ARRAY_SIZE(video_cc_parent_data_0), 153 .flags = CLK_SET_RATE_PARENT, 154 .ops = &clk_rcg2_shared_ops, 155 }, 156 }; 157 158 static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { 159 F(720000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 160 F(1014000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 161 F(1098000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 162 F(1332000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 163 { } 164 }; 165 166 static const struct freq_tbl ftbl_video_cc_mvs0_clk_src_8280xp[] = { 167 F(720000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 168 F(1014000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 169 F(1098000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 170 F(1332000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 171 F(1599000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 172 F(1680000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 173 { } 174 }; 175 176 static struct clk_rcg2 video_cc_mvs0_clk_src = { 177 .cmd_rcgr = 0xb94, 178 .mnd_width = 0, 179 .hid_width = 5, 180 .parent_map = video_cc_parent_map_1, 181 .freq_tbl = ftbl_video_cc_mvs0_clk_src, 182 .clkr.hw.init = &(const struct clk_init_data) { 183 .name = "video_cc_mvs0_clk_src", 184 .parent_data = video_cc_parent_data_1, 185 .num_parents = ARRAY_SIZE(video_cc_parent_data_1), 186 .flags = CLK_SET_RATE_PARENT, 187 .ops = &clk_rcg2_shared_ops, 188 }, 189 }; 190 191 static const struct freq_tbl ftbl_video_cc_mvs1_clk_src[] = { 192 F(840000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 193 F(1098000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 194 F(1332000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 195 { } 196 }; 197 198 static const struct freq_tbl ftbl_video_cc_mvs1_clk_src_8280xp[] = { 199 F(840000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 200 F(1098000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 201 F(1332000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 202 F(1600000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 203 F(1800000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 204 { } 205 }; 206 207 static struct clk_rcg2 video_cc_mvs1_clk_src = { 208 .cmd_rcgr = 0xbb4, 209 .mnd_width = 0, 210 .hid_width = 5, 211 .parent_map = video_cc_parent_map_2, 212 .freq_tbl = ftbl_video_cc_mvs1_clk_src, 213 .clkr.hw.init = &(const struct clk_init_data) { 214 .name = "video_cc_mvs1_clk_src", 215 .parent_data = video_cc_parent_data_2, 216 .num_parents = ARRAY_SIZE(video_cc_parent_data_2), 217 .flags = CLK_SET_RATE_PARENT, 218 .ops = &clk_rcg2_shared_ops, 219 }, 220 }; 221 222 static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = { 223 F(32000, P_SLEEP_CLK, 1, 0, 0), 224 { } 225 }; 226 227 static struct clk_rcg2 video_cc_sleep_clk_src = { 228 .cmd_rcgr = 0xef0, 229 .mnd_width = 0, 230 .hid_width = 5, 231 .freq_tbl = ftbl_video_cc_sleep_clk_src, 232 .clkr.hw.init = &(const struct clk_init_data) { 233 .name = "video_cc_sleep_clk_src", 234 .parent_data = &(const struct clk_parent_data){ 235 .index = DT_SLEEP_CLK, 236 }, 237 .num_parents = 1, 238 .flags = CLK_SET_RATE_PARENT, 239 .ops = &clk_rcg2_ops, 240 }, 241 }; 242 243 static struct clk_rcg2 video_cc_xo_clk_src = { 244 .cmd_rcgr = 0xecc, 245 .mnd_width = 0, 246 .hid_width = 5, 247 .parent_map = video_cc_parent_map_0, 248 .freq_tbl = ftbl_video_cc_ahb_clk_src, 249 .clkr.hw.init = &(const struct clk_init_data) { 250 .name = "video_cc_xo_clk_src", 251 .parent_data = video_cc_parent_data_0, 252 .num_parents = ARRAY_SIZE(video_cc_parent_data_0), 253 .flags = CLK_SET_RATE_PARENT, 254 .ops = &clk_rcg2_ops, 255 }, 256 }; 257 258 static struct clk_regmap_div video_cc_mvs0_div_clk_src = { 259 .reg = 0xd54, 260 .shift = 0, 261 .width = 4, 262 .clkr.hw.init = &(const struct clk_init_data) { 263 .name = "video_cc_mvs0_div_clk_src", 264 .parent_hws = (const struct clk_hw*[]){ 265 &video_cc_mvs0_clk_src.clkr.hw, 266 }, 267 .num_parents = 1, 268 .flags = CLK_SET_RATE_PARENT, 269 .ops = &clk_regmap_div_ro_ops, 270 }, 271 }; 272 273 static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = { 274 .reg = 0xc54, 275 .shift = 0, 276 .width = 4, 277 .clkr.hw.init = &(const struct clk_init_data) { 278 .name = "video_cc_mvs0c_div2_div_clk_src", 279 .parent_hws = (const struct clk_hw*[]){ 280 &video_cc_mvs0_clk_src.clkr.hw, 281 }, 282 .num_parents = 1, 283 .flags = CLK_SET_RATE_PARENT, 284 .ops = &clk_regmap_div_ro_ops, 285 }, 286 }; 287 288 static struct clk_regmap_div video_cc_mvs1_div_clk_src = { 289 .reg = 0xdd4, 290 .shift = 0, 291 .width = 4, 292 .clkr.hw.init = &(const struct clk_init_data) { 293 .name = "video_cc_mvs1_div_clk_src", 294 .parent_hws = (const struct clk_hw*[]){ 295 &video_cc_mvs1_clk_src.clkr.hw, 296 }, 297 .num_parents = 1, 298 .flags = CLK_SET_RATE_PARENT, 299 .ops = &clk_regmap_div_ro_ops, 300 }, 301 }; 302 303 static struct clk_regmap_div video_cc_mvs1c_div2_div_clk_src = { 304 .reg = 0xcf4, 305 .shift = 0, 306 .width = 4, 307 .clkr.hw.init = &(const struct clk_init_data) { 308 .name = "video_cc_mvs1c_div2_div_clk_src", 309 .parent_hws = (const struct clk_hw*[]){ 310 &video_cc_mvs1_clk_src.clkr.hw, 311 }, 312 .num_parents = 1, 313 .flags = CLK_SET_RATE_PARENT, 314 .ops = &clk_regmap_div_ro_ops, 315 }, 316 }; 317 318 static struct clk_branch video_cc_mvs0_clk = { 319 .halt_reg = 0xd34, 320 .halt_check = BRANCH_HALT_VOTED, 321 .hwcg_reg = 0xd34, 322 .hwcg_bit = 1, 323 .clkr = { 324 .enable_reg = 0xd34, 325 .enable_mask = BIT(0), 326 .hw.init = &(const struct clk_init_data) { 327 .name = "video_cc_mvs0_clk", 328 .parent_hws = (const struct clk_hw*[]){ 329 &video_cc_mvs0_div_clk_src.clkr.hw, 330 }, 331 .num_parents = 1, 332 .flags = CLK_SET_RATE_PARENT, 333 .ops = &clk_branch2_ops, 334 }, 335 }, 336 }; 337 338 static struct clk_branch video_cc_mvs0c_clk = { 339 .halt_reg = 0xc34, 340 .halt_check = BRANCH_HALT, 341 .clkr = { 342 .enable_reg = 0xc34, 343 .enable_mask = BIT(0), 344 .hw.init = &(const struct clk_init_data) { 345 .name = "video_cc_mvs0c_clk", 346 .parent_hws = (const struct clk_hw*[]){ 347 &video_cc_mvs0c_div2_div_clk_src.clkr.hw, 348 }, 349 .num_parents = 1, 350 .flags = CLK_SET_RATE_PARENT, 351 .ops = &clk_branch2_ops, 352 }, 353 }, 354 }; 355 356 static struct clk_branch video_cc_mvs1_clk = { 357 .halt_reg = 0xdb4, 358 .halt_check = BRANCH_HALT_VOTED, 359 .hwcg_reg = 0xdb4, 360 .hwcg_bit = 1, 361 .clkr = { 362 .enable_reg = 0xdb4, 363 .enable_mask = BIT(0), 364 .hw.init = &(const struct clk_init_data) { 365 .name = "video_cc_mvs1_clk", 366 .parent_hws = (const struct clk_hw*[]){ 367 &video_cc_mvs1_div_clk_src.clkr.hw, 368 }, 369 .num_parents = 1, 370 .flags = CLK_SET_RATE_PARENT, 371 .ops = &clk_branch2_ops, 372 }, 373 }, 374 }; 375 376 static struct clk_branch video_cc_mvs1_div2_clk = { 377 .halt_reg = 0xdf4, 378 .halt_check = BRANCH_HALT_VOTED, 379 .hwcg_reg = 0xdf4, 380 .hwcg_bit = 1, 381 .clkr = { 382 .enable_reg = 0xdf4, 383 .enable_mask = BIT(0), 384 .hw.init = &(const struct clk_init_data) { 385 .name = "video_cc_mvs1_div2_clk", 386 .parent_hws = (const struct clk_hw*[]){ 387 &video_cc_mvs1c_div2_div_clk_src.clkr.hw, 388 }, 389 .num_parents = 1, 390 .flags = CLK_SET_RATE_PARENT, 391 .ops = &clk_branch2_ops, 392 }, 393 }, 394 }; 395 396 static struct clk_branch video_cc_mvs1c_clk = { 397 .halt_reg = 0xcd4, 398 .halt_check = BRANCH_HALT, 399 .clkr = { 400 .enable_reg = 0xcd4, 401 .enable_mask = BIT(0), 402 .hw.init = &(const struct clk_init_data) { 403 .name = "video_cc_mvs1c_clk", 404 .parent_hws = (const struct clk_hw*[]){ 405 &video_cc_mvs1c_div2_div_clk_src.clkr.hw, 406 }, 407 .num_parents = 1, 408 .flags = CLK_SET_RATE_PARENT, 409 .ops = &clk_branch2_ops, 410 }, 411 }, 412 }; 413 414 static struct clk_branch video_cc_sleep_clk = { 415 .halt_reg = 0xf10, 416 .halt_check = BRANCH_HALT, 417 .clkr = { 418 .enable_reg = 0xf10, 419 .enable_mask = BIT(0), 420 .hw.init = &(const struct clk_init_data) { 421 .name = "video_cc_sleep_clk", 422 .parent_hws = (const struct clk_hw*[]){ 423 &video_cc_sleep_clk_src.clkr.hw, 424 }, 425 .num_parents = 1, 426 .flags = CLK_SET_RATE_PARENT, 427 .ops = &clk_branch2_ops, 428 }, 429 }, 430 }; 431 432 static struct gdsc mvs0c_gdsc = { 433 .gdscr = 0xbf8, 434 .pd = { 435 .name = "mvs0c_gdsc", 436 }, 437 .flags = RETAIN_FF_ENABLE, 438 .pwrsts = PWRSTS_OFF_ON, 439 }; 440 441 static struct gdsc mvs1c_gdsc = { 442 .gdscr = 0xc98, 443 .pd = { 444 .name = "mvs1c_gdsc", 445 }, 446 .flags = RETAIN_FF_ENABLE, 447 .pwrsts = PWRSTS_OFF_ON, 448 }; 449 450 static struct gdsc mvs0_gdsc = { 451 .gdscr = 0xd18, 452 .pd = { 453 .name = "mvs0_gdsc", 454 }, 455 .flags = HW_CTRL_TRIGGER | RETAIN_FF_ENABLE, 456 .pwrsts = PWRSTS_OFF_ON, 457 }; 458 459 static struct gdsc mvs1_gdsc = { 460 .gdscr = 0xd98, 461 .pd = { 462 .name = "mvs1_gdsc", 463 }, 464 .flags = HW_CTRL_TRIGGER | RETAIN_FF_ENABLE, 465 .pwrsts = PWRSTS_OFF_ON, 466 }; 467 468 static struct clk_regmap *video_cc_sm8350_clocks[] = { 469 [VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr, 470 [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr, 471 [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr, 472 [VIDEO_CC_MVS0_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr, 473 [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, 474 [VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr, 475 [VIDEO_CC_MVS1_CLK] = &video_cc_mvs1_clk.clkr, 476 [VIDEO_CC_MVS1_CLK_SRC] = &video_cc_mvs1_clk_src.clkr, 477 [VIDEO_CC_MVS1_DIV2_CLK] = &video_cc_mvs1_div2_clk.clkr, 478 [VIDEO_CC_MVS1_DIV_CLK_SRC] = &video_cc_mvs1_div_clk_src.clkr, 479 [VIDEO_CC_MVS1C_CLK] = &video_cc_mvs1c_clk.clkr, 480 [VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC] = &video_cc_mvs1c_div2_div_clk_src.clkr, 481 [VIDEO_CC_SLEEP_CLK] = &video_cc_sleep_clk.clkr, 482 [VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr, 483 [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, 484 [VIDEO_PLL0] = &video_pll0.clkr, 485 [VIDEO_PLL1] = &video_pll1.clkr, 486 }; 487 488 static const struct qcom_reset_map video_cc_sm8350_resets[] = { 489 [VIDEO_CC_CVP_INTERFACE_BCR] = { 0xe54 }, 490 [VIDEO_CC_CVP_MVS0_BCR] = { 0xd14 }, 491 [VIDEO_CC_MVS0C_CLK_ARES] = { .reg = 0xc34, .bit = 2, .udelay = 400 }, 492 [VIDEO_CC_CVP_MVS0C_BCR] = { 0xbf4 }, 493 [VIDEO_CC_CVP_MVS1_BCR] = { 0xd94 }, 494 [VIDEO_CC_MVS1C_CLK_ARES] = { .reg = 0xcd4, .bit = 2, .udelay = 400 }, 495 [VIDEO_CC_CVP_MVS1C_BCR] = { 0xc94 }, 496 }; 497 498 static struct gdsc *video_cc_sm8350_gdscs[] = { 499 [MVS0C_GDSC] = &mvs0c_gdsc, 500 [MVS1C_GDSC] = &mvs1c_gdsc, 501 [MVS0_GDSC] = &mvs0_gdsc, 502 [MVS1_GDSC] = &mvs1_gdsc, 503 }; 504 505 static const struct regmap_config video_cc_sm8350_regmap_config = { 506 .reg_bits = 32, 507 .reg_stride = 4, 508 .val_bits = 32, 509 .max_register = 0x10000, 510 .fast_io = true, 511 }; 512 513 static struct qcom_cc_desc video_cc_sm8350_desc = { 514 .config = &video_cc_sm8350_regmap_config, 515 .clks = video_cc_sm8350_clocks, 516 .num_clks = ARRAY_SIZE(video_cc_sm8350_clocks), 517 .resets = video_cc_sm8350_resets, 518 .num_resets = ARRAY_SIZE(video_cc_sm8350_resets), 519 .gdscs = video_cc_sm8350_gdscs, 520 .num_gdscs = ARRAY_SIZE(video_cc_sm8350_gdscs), 521 }; 522 523 static int video_cc_sm8350_probe(struct platform_device *pdev) 524 { 525 u32 video_cc_xo_clk_cbcr = 0xeec; 526 struct regmap *regmap; 527 int ret; 528 529 ret = devm_pm_runtime_enable(&pdev->dev); 530 if (ret) 531 return ret; 532 533 ret = pm_runtime_resume_and_get(&pdev->dev); 534 if (ret) 535 return ret; 536 537 if (of_device_is_compatible(pdev->dev.of_node, "qcom,sc8280xp-videocc")) { 538 video_cc_sleep_clk_src.cmd_rcgr = 0xf38; 539 video_cc_sleep_clk.halt_reg = 0xf58; 540 video_cc_sleep_clk.clkr.enable_reg = 0xf58; 541 video_cc_xo_clk_src.cmd_rcgr = 0xf14; 542 video_cc_xo_clk_cbcr = 0xf34; 543 544 video_pll0.vco_table = video_pll1.vco_table = lucid_5lpe_vco_8280xp; 545 /* No change, but assign it for completeness */ 546 video_pll0.num_vco = video_pll1.num_vco = ARRAY_SIZE(lucid_5lpe_vco_8280xp); 547 548 video_cc_mvs0_clk_src.freq_tbl = ftbl_video_cc_mvs0_clk_src_8280xp; 549 video_cc_mvs1_clk_src.freq_tbl = ftbl_video_cc_mvs1_clk_src_8280xp; 550 } 551 552 regmap = qcom_cc_map(pdev, &video_cc_sm8350_desc); 553 if (IS_ERR(regmap)) { 554 pm_runtime_put(&pdev->dev); 555 return PTR_ERR(regmap); 556 } 557 558 clk_lucid_pll_configure(&video_pll0, regmap, &video_pll0_config); 559 clk_lucid_pll_configure(&video_pll1, regmap, &video_pll1_config); 560 561 /* Keep some clocks always-on */ 562 qcom_branch_set_clk_en(regmap, 0xe58); /* VIDEO_CC_AHB_CLK */ 563 qcom_branch_set_clk_en(regmap, video_cc_xo_clk_cbcr); /* VIDEO_CC_XO_CLK */ 564 565 ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sm8350_desc, regmap); 566 pm_runtime_put(&pdev->dev); 567 568 return ret; 569 } 570 571 static const struct of_device_id video_cc_sm8350_match_table[] = { 572 { .compatible = "qcom,sc8280xp-videocc" }, 573 { .compatible = "qcom,sm8350-videocc" }, 574 { } 575 }; 576 MODULE_DEVICE_TABLE(of, video_cc_sm8350_match_table); 577 578 static struct platform_driver video_cc_sm8350_driver = { 579 .probe = video_cc_sm8350_probe, 580 .driver = { 581 .name = "sm8350-videocc", 582 .of_match_table = video_cc_sm8350_match_table, 583 }, 584 }; 585 module_platform_driver(video_cc_sm8350_driver); 586 587 MODULE_DESCRIPTION("QTI SM8350 VIDEOCC Driver"); 588 MODULE_LICENSE("GPL"); 589