1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. 4 */ 5 6 #include <linux/clk-provider.h> 7 #include <linux/mod_devicetable.h> 8 #include <linux/module.h> 9 #include <linux/platform_device.h> 10 #include <linux/regmap.h> 11 12 #include <dt-bindings/clock/qcom,sm8650-videocc.h> 13 14 #include "clk-alpha-pll.h" 15 #include "clk-branch.h" 16 #include "clk-rcg.h" 17 #include "clk-regmap.h" 18 #include "clk-regmap-divider.h" 19 #include "common.h" 20 #include "gdsc.h" 21 #include "reset.h" 22 23 enum { 24 DT_BI_TCXO, 25 }; 26 27 enum { 28 P_BI_TCXO, 29 P_VIDEO_CC_PLL0_OUT_MAIN, 30 P_VIDEO_CC_PLL1_OUT_MAIN, 31 }; 32 33 static const struct pll_vco lucid_ole_vco[] = { 34 { 249600000, 2300000000, 0 }, 35 }; 36 37 static struct alpha_pll_config video_cc_pll0_config = { 38 .l = 0x25, 39 .alpha = 0x8000, 40 .config_ctl_val = 0x20485699, 41 .config_ctl_hi_val = 0x00182261, 42 .config_ctl_hi1_val = 0x82aa299c, 43 .test_ctl_val = 0x00000000, 44 .test_ctl_hi_val = 0x00000003, 45 .test_ctl_hi1_val = 0x00009000, 46 .test_ctl_hi2_val = 0x00000034, 47 .user_ctl_val = 0x00000000, 48 .user_ctl_hi_val = 0x00000005, 49 }; 50 51 static struct clk_alpha_pll video_cc_pll0 = { 52 .offset = 0x0, 53 .config = &video_cc_pll0_config, 54 .vco_table = lucid_ole_vco, 55 .num_vco = ARRAY_SIZE(lucid_ole_vco), 56 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], 57 .clkr = { 58 .hw.init = &(const struct clk_init_data) { 59 .name = "video_cc_pll0", 60 .parent_data = &(const struct clk_parent_data) { 61 .index = DT_BI_TCXO, 62 }, 63 .num_parents = 1, 64 .ops = &clk_alpha_pll_lucid_evo_ops, 65 }, 66 }, 67 }; 68 69 static struct alpha_pll_config video_cc_pll1_config = { 70 .l = 0x36, 71 .alpha = 0xb000, 72 .config_ctl_val = 0x20485699, 73 .config_ctl_hi_val = 0x00182261, 74 .config_ctl_hi1_val = 0x82aa299c, 75 .test_ctl_val = 0x00000000, 76 .test_ctl_hi_val = 0x00000003, 77 .test_ctl_hi1_val = 0x00009000, 78 .test_ctl_hi2_val = 0x00000034, 79 .user_ctl_val = 0x00000000, 80 .user_ctl_hi_val = 0x00000005, 81 }; 82 83 static struct clk_alpha_pll video_cc_pll1 = { 84 .offset = 0x1000, 85 .config = &video_cc_pll1_config, 86 .vco_table = lucid_ole_vco, 87 .num_vco = ARRAY_SIZE(lucid_ole_vco), 88 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], 89 .clkr = { 90 .hw.init = &(const struct clk_init_data) { 91 .name = "video_cc_pll1", 92 .parent_data = &(const struct clk_parent_data) { 93 .index = DT_BI_TCXO, 94 }, 95 .num_parents = 1, 96 .ops = &clk_alpha_pll_lucid_evo_ops, 97 }, 98 }, 99 }; 100 101 static const struct parent_map video_cc_parent_map_0[] = { 102 { P_BI_TCXO, 0 }, 103 { P_VIDEO_CC_PLL0_OUT_MAIN, 1 }, 104 }; 105 106 static const struct clk_parent_data video_cc_parent_data_0[] = { 107 { .index = DT_BI_TCXO }, 108 { .hw = &video_cc_pll0.clkr.hw }, 109 }; 110 111 static const struct parent_map video_cc_parent_map_1[] = { 112 { P_BI_TCXO, 0 }, 113 { P_VIDEO_CC_PLL1_OUT_MAIN, 1 }, 114 }; 115 116 static const struct clk_parent_data video_cc_parent_data_1[] = { 117 { .index = DT_BI_TCXO }, 118 { .hw = &video_cc_pll1.clkr.hw }, 119 }; 120 121 static const struct parent_map video_cc_parent_map_2[] = { 122 { P_BI_TCXO, 0 }, 123 }; 124 125 static const struct clk_parent_data video_cc_parent_data_2[] = { 126 { .index = DT_BI_TCXO }, 127 }; 128 129 static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { 130 F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 131 F(1014000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 132 F(1098000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 133 F(1332000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 134 F(1600000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 135 { } 136 }; 137 138 static const struct freq_tbl ftbl_video_cc_mvs0_clk_src_sm8650[] = { 139 F(588000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 140 F(900000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 141 F(1140000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 142 F(1305000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 143 F(1440000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 144 F(1600000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 145 { } 146 }; 147 148 static const struct freq_tbl ftbl_video_cc_mvs0_clk_src_x1e80100[] = { 149 F(576000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 150 F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 151 F(1014000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 152 F(1098000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 153 F(1332000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 154 F(1443000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 155 { } 156 }; 157 158 static struct clk_rcg2 video_cc_mvs0_clk_src = { 159 .cmd_rcgr = 0x8000, 160 .mnd_width = 0, 161 .hid_width = 5, 162 .parent_map = video_cc_parent_map_0, 163 .freq_tbl = ftbl_video_cc_mvs0_clk_src, 164 .clkr.hw.init = &(const struct clk_init_data) { 165 .name = "video_cc_mvs0_clk_src", 166 .parent_data = video_cc_parent_data_0, 167 .num_parents = ARRAY_SIZE(video_cc_parent_data_0), 168 .flags = CLK_SET_RATE_PARENT, 169 .ops = &clk_rcg2_shared_ops, 170 }, 171 }; 172 173 static const struct freq_tbl ftbl_video_cc_mvs1_clk_src[] = { 174 F(1050000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), 175 F(1350000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), 176 F(1500000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), 177 F(1650000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), 178 { } 179 }; 180 181 static const struct freq_tbl ftbl_video_cc_mvs1_clk_src_sm8650[] = { 182 F(840000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), 183 F(1110000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), 184 F(1350000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), 185 F(1500000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), 186 F(1650000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), 187 { } 188 }; 189 190 static const struct freq_tbl ftbl_video_cc_mvs1_clk_src_x1e80100[] = { 191 F(840000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), 192 F(1050000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), 193 F(1350000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), 194 F(1500000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), 195 F(1650000000, P_VIDEO_CC_PLL1_OUT_MAIN, 1, 0, 0), 196 { } 197 }; 198 199 static struct clk_rcg2 video_cc_mvs1_clk_src = { 200 .cmd_rcgr = 0x8018, 201 .mnd_width = 0, 202 .hid_width = 5, 203 .parent_map = video_cc_parent_map_1, 204 .freq_tbl = ftbl_video_cc_mvs1_clk_src, 205 .clkr.hw.init = &(const struct clk_init_data) { 206 .name = "video_cc_mvs1_clk_src", 207 .parent_data = video_cc_parent_data_1, 208 .num_parents = ARRAY_SIZE(video_cc_parent_data_1), 209 .flags = CLK_SET_RATE_PARENT, 210 .ops = &clk_rcg2_shared_ops, 211 }, 212 }; 213 214 static const struct freq_tbl ftbl_video_cc_xo_clk_src[] = { 215 F(19200000, P_BI_TCXO, 1, 0, 0), 216 { } 217 }; 218 219 static struct clk_rcg2 video_cc_xo_clk_src = { 220 .cmd_rcgr = 0x810c, 221 .mnd_width = 0, 222 .hid_width = 5, 223 .parent_map = video_cc_parent_map_2, 224 .freq_tbl = ftbl_video_cc_xo_clk_src, 225 .clkr.hw.init = &(const struct clk_init_data) { 226 .name = "video_cc_xo_clk_src", 227 .parent_data = video_cc_parent_data_2, 228 .num_parents = ARRAY_SIZE(video_cc_parent_data_2), 229 .flags = CLK_SET_RATE_PARENT, 230 .ops = &clk_rcg2_shared_ops, 231 }, 232 }; 233 234 static struct clk_regmap_div video_cc_mvs0_div_clk_src = { 235 .reg = 0x80c4, 236 .shift = 0, 237 .width = 4, 238 .clkr.hw.init = &(const struct clk_init_data) { 239 .name = "video_cc_mvs0_div_clk_src", 240 .parent_hws = (const struct clk_hw*[]) { 241 &video_cc_mvs0_clk_src.clkr.hw, 242 }, 243 .num_parents = 1, 244 .flags = CLK_SET_RATE_PARENT, 245 .ops = &clk_regmap_div_ro_ops, 246 }, 247 }; 248 249 static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = { 250 .reg = 0x8070, 251 .shift = 0, 252 .width = 4, 253 .clkr.hw.init = &(const struct clk_init_data) { 254 .name = "video_cc_mvs0c_div2_div_clk_src", 255 .parent_hws = (const struct clk_hw*[]) { 256 &video_cc_mvs0_clk_src.clkr.hw, 257 }, 258 .num_parents = 1, 259 .flags = CLK_SET_RATE_PARENT, 260 .ops = &clk_regmap_div_ro_ops, 261 }, 262 }; 263 264 static struct clk_regmap_div video_cc_mvs1_div_clk_src = { 265 .reg = 0x80ec, 266 .shift = 0, 267 .width = 4, 268 .clkr.hw.init = &(const struct clk_init_data) { 269 .name = "video_cc_mvs1_div_clk_src", 270 .parent_hws = (const struct clk_hw*[]) { 271 &video_cc_mvs1_clk_src.clkr.hw, 272 }, 273 .num_parents = 1, 274 .flags = CLK_SET_RATE_PARENT, 275 .ops = &clk_regmap_div_ro_ops, 276 }, 277 }; 278 279 static struct clk_regmap_div video_cc_mvs1c_div2_div_clk_src = { 280 .reg = 0x809c, 281 .shift = 0, 282 .width = 4, 283 .clkr.hw.init = &(const struct clk_init_data) { 284 .name = "video_cc_mvs1c_div2_div_clk_src", 285 .parent_hws = (const struct clk_hw*[]) { 286 &video_cc_mvs1_clk_src.clkr.hw, 287 }, 288 .num_parents = 1, 289 .flags = CLK_SET_RATE_PARENT, 290 .ops = &clk_regmap_div_ro_ops, 291 }, 292 }; 293 294 static struct clk_branch video_cc_mvs0_clk = { 295 .halt_reg = 0x80b8, 296 .halt_check = BRANCH_HALT_SKIP, 297 .hwcg_reg = 0x80b8, 298 .hwcg_bit = 1, 299 .clkr = { 300 .enable_reg = 0x80b8, 301 .enable_mask = BIT(0), 302 .hw.init = &(const struct clk_init_data) { 303 .name = "video_cc_mvs0_clk", 304 .parent_hws = (const struct clk_hw*[]) { 305 &video_cc_mvs0_div_clk_src.clkr.hw, 306 }, 307 .num_parents = 1, 308 .flags = CLK_SET_RATE_PARENT, 309 .ops = &clk_branch2_ops, 310 }, 311 }, 312 }; 313 314 static struct clk_branch video_cc_mvs0_shift_clk = { 315 .halt_reg = 0x8128, 316 .halt_check = BRANCH_HALT_VOTED, 317 .hwcg_reg = 0x8128, 318 .hwcg_bit = 1, 319 .clkr = { 320 .enable_reg = 0x8128, 321 .enable_mask = BIT(0), 322 .hw.init = &(const struct clk_init_data) { 323 .name = "video_cc_mvs0_shift_clk", 324 .parent_hws = (const struct clk_hw*[]) { 325 &video_cc_xo_clk_src.clkr.hw, 326 }, 327 .num_parents = 1, 328 .flags = CLK_SET_RATE_PARENT, 329 .ops = &clk_branch2_ops, 330 }, 331 }, 332 }; 333 334 static struct clk_branch video_cc_mvs0c_clk = { 335 .halt_reg = 0x8064, 336 .halt_check = BRANCH_HALT, 337 .clkr = { 338 .enable_reg = 0x8064, 339 .enable_mask = BIT(0), 340 .hw.init = &(const struct clk_init_data) { 341 .name = "video_cc_mvs0c_clk", 342 .parent_hws = (const struct clk_hw*[]) { 343 &video_cc_mvs0c_div2_div_clk_src.clkr.hw, 344 }, 345 .num_parents = 1, 346 .flags = CLK_SET_RATE_PARENT, 347 .ops = &clk_branch2_ops, 348 }, 349 }, 350 }; 351 352 static struct clk_branch video_cc_mvs0c_shift_clk = { 353 .halt_reg = 0x812c, 354 .halt_check = BRANCH_HALT_VOTED, 355 .hwcg_reg = 0x812c, 356 .hwcg_bit = 1, 357 .clkr = { 358 .enable_reg = 0x812c, 359 .enable_mask = BIT(0), 360 .hw.init = &(const struct clk_init_data) { 361 .name = "video_cc_mvs0c_shift_clk", 362 .parent_hws = (const struct clk_hw*[]) { 363 &video_cc_xo_clk_src.clkr.hw, 364 }, 365 .num_parents = 1, 366 .flags = CLK_SET_RATE_PARENT, 367 .ops = &clk_branch2_ops, 368 }, 369 }, 370 }; 371 372 static struct clk_branch video_cc_mvs1_clk = { 373 .halt_reg = 0x80e0, 374 .halt_check = BRANCH_HALT_SKIP, 375 .hwcg_reg = 0x80e0, 376 .hwcg_bit = 1, 377 .clkr = { 378 .enable_reg = 0x80e0, 379 .enable_mask = BIT(0), 380 .hw.init = &(const struct clk_init_data) { 381 .name = "video_cc_mvs1_clk", 382 .parent_hws = (const struct clk_hw*[]) { 383 &video_cc_mvs1_div_clk_src.clkr.hw, 384 }, 385 .num_parents = 1, 386 .flags = CLK_SET_RATE_PARENT, 387 .ops = &clk_branch2_ops, 388 }, 389 }, 390 }; 391 392 static struct clk_branch video_cc_mvs1_shift_clk = { 393 .halt_reg = 0x8130, 394 .halt_check = BRANCH_HALT_VOTED, 395 .hwcg_reg = 0x8130, 396 .hwcg_bit = 1, 397 .clkr = { 398 .enable_reg = 0x8130, 399 .enable_mask = BIT(0), 400 .hw.init = &(const struct clk_init_data) { 401 .name = "video_cc_mvs1_shift_clk", 402 .parent_hws = (const struct clk_hw*[]) { 403 &video_cc_xo_clk_src.clkr.hw, 404 }, 405 .num_parents = 1, 406 .flags = CLK_SET_RATE_PARENT, 407 .ops = &clk_branch2_ops, 408 }, 409 }, 410 }; 411 412 static struct clk_branch video_cc_mvs1c_clk = { 413 .halt_reg = 0x8090, 414 .halt_check = BRANCH_HALT, 415 .clkr = { 416 .enable_reg = 0x8090, 417 .enable_mask = BIT(0), 418 .hw.init = &(const struct clk_init_data) { 419 .name = "video_cc_mvs1c_clk", 420 .parent_hws = (const struct clk_hw*[]) { 421 &video_cc_mvs1c_div2_div_clk_src.clkr.hw, 422 }, 423 .num_parents = 1, 424 .flags = CLK_SET_RATE_PARENT, 425 .ops = &clk_branch2_ops, 426 }, 427 }, 428 }; 429 430 static struct clk_branch video_cc_mvs1c_shift_clk = { 431 .halt_reg = 0x8134, 432 .halt_check = BRANCH_HALT_VOTED, 433 .hwcg_reg = 0x8134, 434 .hwcg_bit = 1, 435 .clkr = { 436 .enable_reg = 0x8134, 437 .enable_mask = BIT(0), 438 .hw.init = &(const struct clk_init_data) { 439 .name = "video_cc_mvs1c_shift_clk", 440 .parent_hws = (const struct clk_hw*[]) { 441 &video_cc_xo_clk_src.clkr.hw, 442 }, 443 .num_parents = 1, 444 .flags = CLK_SET_RATE_PARENT, 445 .ops = &clk_branch2_ops, 446 }, 447 }, 448 }; 449 450 static struct gdsc video_cc_mvs0c_gdsc = { 451 .gdscr = 0x804c, 452 .en_rest_wait_val = 0x2, 453 .en_few_wait_val = 0x2, 454 .clk_dis_wait_val = 0x6, 455 .pd = { 456 .name = "video_cc_mvs0c_gdsc", 457 }, 458 .pwrsts = PWRSTS_OFF_ON, 459 .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, 460 }; 461 462 static struct gdsc video_cc_mvs0_gdsc = { 463 .gdscr = 0x80a4, 464 .en_rest_wait_val = 0x2, 465 .en_few_wait_val = 0x2, 466 .clk_dis_wait_val = 0x6, 467 .pd = { 468 .name = "video_cc_mvs0_gdsc", 469 }, 470 .pwrsts = PWRSTS_OFF_ON, 471 .parent = &video_cc_mvs0c_gdsc.pd, 472 .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, 473 }; 474 475 static struct gdsc video_cc_mvs1c_gdsc = { 476 .gdscr = 0x8078, 477 .en_rest_wait_val = 0x2, 478 .en_few_wait_val = 0x2, 479 .clk_dis_wait_val = 0x6, 480 .pd = { 481 .name = "video_cc_mvs1c_gdsc", 482 }, 483 .pwrsts = PWRSTS_OFF_ON, 484 .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, 485 }; 486 487 static struct gdsc video_cc_mvs1_gdsc = { 488 .gdscr = 0x80cc, 489 .en_rest_wait_val = 0x2, 490 .en_few_wait_val = 0x2, 491 .clk_dis_wait_val = 0x6, 492 .pd = { 493 .name = "video_cc_mvs1_gdsc", 494 }, 495 .pwrsts = PWRSTS_OFF_ON, 496 .parent = &video_cc_mvs1c_gdsc.pd, 497 .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, 498 }; 499 500 static struct clk_regmap *video_cc_sm8550_clocks[] = { 501 [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr, 502 [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr, 503 [VIDEO_CC_MVS0_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr, 504 [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, 505 [VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr, 506 [VIDEO_CC_MVS1_CLK] = &video_cc_mvs1_clk.clkr, 507 [VIDEO_CC_MVS1_CLK_SRC] = &video_cc_mvs1_clk_src.clkr, 508 [VIDEO_CC_MVS1_DIV_CLK_SRC] = &video_cc_mvs1_div_clk_src.clkr, 509 [VIDEO_CC_MVS1C_CLK] = &video_cc_mvs1c_clk.clkr, 510 [VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC] = &video_cc_mvs1c_div2_div_clk_src.clkr, 511 [VIDEO_CC_PLL0] = &video_cc_pll0.clkr, 512 [VIDEO_CC_PLL1] = &video_cc_pll1.clkr, 513 [VIDEO_CC_XO_CLK_SRC] = NULL, 514 }; 515 516 static struct gdsc *video_cc_sm8550_gdscs[] = { 517 [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc, 518 [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc, 519 [VIDEO_CC_MVS1C_GDSC] = &video_cc_mvs1c_gdsc, 520 [VIDEO_CC_MVS1_GDSC] = &video_cc_mvs1_gdsc, 521 }; 522 523 static const struct qcom_reset_map video_cc_sm8550_resets[] = { 524 [CVP_VIDEO_CC_INTERFACE_BCR] = { 0x80f0 }, 525 [CVP_VIDEO_CC_MVS0_BCR] = { 0x80a0 }, 526 [CVP_VIDEO_CC_MVS0C_BCR] = { 0x8048 }, 527 [CVP_VIDEO_CC_MVS1_BCR] = { 0x80c8 }, 528 [CVP_VIDEO_CC_MVS1C_BCR] = { 0x8074 }, 529 [VIDEO_CC_MVS0C_CLK_ARES] = { .reg = 0x8064, .bit = 2, .udelay = 1000 }, 530 [VIDEO_CC_MVS1C_CLK_ARES] = { .reg = 0x8090, .bit = 2, .udelay = 1000 }, 531 [VIDEO_CC_XO_CLK_ARES] = { .reg = 0x8124, .bit = 2, .udelay = 100 }, 532 }; 533 534 static struct clk_alpha_pll *video_cc_sm8550_plls[] = { 535 &video_cc_pll0, 536 &video_cc_pll1, 537 }; 538 539 static u32 video_cc_sm8550_critical_cbcrs[] = { 540 0x80f4, /* VIDEO_CC_AHB_CLK */ 541 0x8124, /* VIDEO_CC_XO_CLK */ 542 0x8140, /* VIDEO_CC_SLEEP_CLK */ 543 }; 544 545 static u32 video_cc_sm8650_critical_cbcrs[] = { 546 0x80f4, /* VIDEO_CC_AHB_CLK */ 547 0x8124, /* VIDEO_CC_XO_CLK */ 548 0x8150, /* VIDEO_CC_SLEEP_CLK */ 549 }; 550 551 static const struct regmap_config video_cc_sm8550_regmap_config = { 552 .reg_bits = 32, 553 .reg_stride = 4, 554 .val_bits = 32, 555 .max_register = 0x9f4c, 556 .fast_io = true, 557 }; 558 559 static struct qcom_cc_driver_data video_cc_sm8550_driver_data = { 560 .alpha_plls = video_cc_sm8550_plls, 561 .num_alpha_plls = ARRAY_SIZE(video_cc_sm8550_plls), 562 .clk_cbcrs = video_cc_sm8550_critical_cbcrs, 563 .num_clk_cbcrs = ARRAY_SIZE(video_cc_sm8550_critical_cbcrs), 564 }; 565 566 static const struct qcom_cc_desc video_cc_sm8550_desc = { 567 .config = &video_cc_sm8550_regmap_config, 568 .clks = video_cc_sm8550_clocks, 569 .num_clks = ARRAY_SIZE(video_cc_sm8550_clocks), 570 .resets = video_cc_sm8550_resets, 571 .num_resets = ARRAY_SIZE(video_cc_sm8550_resets), 572 .gdscs = video_cc_sm8550_gdscs, 573 .num_gdscs = ARRAY_SIZE(video_cc_sm8550_gdscs), 574 .use_rpm = true, 575 .driver_data = &video_cc_sm8550_driver_data, 576 }; 577 578 static const struct of_device_id video_cc_sm8550_match_table[] = { 579 { .compatible = "qcom,sm8550-videocc" }, 580 { .compatible = "qcom,sm8650-videocc" }, 581 { .compatible = "qcom,x1e80100-videocc" }, 582 { } 583 }; 584 MODULE_DEVICE_TABLE(of, video_cc_sm8550_match_table); 585 586 static int video_cc_sm8550_probe(struct platform_device *pdev) 587 { 588 if (of_device_is_compatible(pdev->dev.of_node, "qcom,x1e80100-videocc")) { 589 video_cc_pll0_config.l = 0x1e; 590 video_cc_pll0_config.alpha = 0x0000; 591 video_cc_pll1_config.l = 0x2b; 592 video_cc_pll1_config.alpha = 0xc000; 593 video_cc_mvs0_clk_src.freq_tbl = ftbl_video_cc_mvs0_clk_src_x1e80100; 594 video_cc_mvs1_clk_src.freq_tbl = ftbl_video_cc_mvs1_clk_src_x1e80100; 595 } 596 597 if (of_device_is_compatible(pdev->dev.of_node, "qcom,sm8650-videocc")) { 598 video_cc_pll0_config.l = 0x1e; 599 video_cc_pll0_config.alpha = 0xa000; 600 video_cc_pll1_config.l = 0x2b; 601 video_cc_pll1_config.alpha = 0xc000; 602 video_cc_mvs0_clk_src.freq_tbl = ftbl_video_cc_mvs0_clk_src_sm8650; 603 video_cc_mvs1_clk_src.freq_tbl = ftbl_video_cc_mvs1_clk_src_sm8650; 604 video_cc_sm8550_clocks[VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr; 605 video_cc_sm8550_clocks[VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr; 606 video_cc_sm8550_clocks[VIDEO_CC_MVS1_SHIFT_CLK] = &video_cc_mvs1_shift_clk.clkr; 607 video_cc_sm8550_clocks[VIDEO_CC_MVS1C_SHIFT_CLK] = &video_cc_mvs1c_shift_clk.clkr; 608 video_cc_sm8550_clocks[VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr; 609 610 video_cc_sm8550_driver_data.clk_cbcrs = video_cc_sm8650_critical_cbcrs; 611 video_cc_sm8550_driver_data.num_clk_cbcrs = 612 ARRAY_SIZE(video_cc_sm8650_critical_cbcrs); 613 } 614 615 return qcom_cc_probe(pdev, &video_cc_sm8550_desc); 616 } 617 618 static struct platform_driver video_cc_sm8550_driver = { 619 .probe = video_cc_sm8550_probe, 620 .driver = { 621 .name = "video_cc-sm8550", 622 .of_match_table = video_cc_sm8550_match_table, 623 }, 624 }; 625 626 module_platform_driver(video_cc_sm8550_driver); 627 628 MODULE_DESCRIPTION("QTI VIDEOCC SM8550 Driver"); 629 MODULE_LICENSE("GPL"); 630