1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 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,kaanapali-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 #define ACCU_CFG_MASK GENMASK(25, 21) 24 25 enum { 26 DT_BI_TCXO, 27 DT_AHB_CLK, 28 }; 29 30 enum { 31 P_BI_TCXO, 32 P_VIDEO_CC_PLL0_OUT_MAIN, 33 P_VIDEO_CC_PLL1_OUT_MAIN, 34 P_VIDEO_CC_PLL2_OUT_MAIN, 35 P_VIDEO_CC_PLL3_OUT_MAIN, 36 }; 37 38 static const struct pll_vco taycan_eko_t_vco[] = { 39 { 249600000, 2500000000, 0 }, 40 }; 41 42 /* 360.0 MHz Configuration */ 43 static const struct alpha_pll_config video_cc_pll0_config = { 44 .l = 0x12, 45 .cal_l = 0x48, 46 .alpha = 0xc000, 47 .config_ctl_val = 0x25c400e7, 48 .config_ctl_hi_val = 0x0a8062e0, 49 .config_ctl_hi1_val = 0xf51dea20, 50 .user_ctl_val = 0x00000008, 51 .user_ctl_hi_val = 0x00000002, 52 }; 53 54 static struct clk_alpha_pll video_cc_pll0 = { 55 .offset = 0x0, 56 .config = &video_cc_pll0_config, 57 .vco_table = taycan_eko_t_vco, 58 .num_vco = ARRAY_SIZE(taycan_eko_t_vco), 59 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], 60 .clkr = { 61 .hw.init = &(const struct clk_init_data) { 62 .name = "video_cc_pll0", 63 .parent_data = &(const struct clk_parent_data) { 64 .index = DT_BI_TCXO, 65 }, 66 .num_parents = 1, 67 .ops = &clk_alpha_pll_taycan_eko_t_ops, 68 }, 69 }, 70 }; 71 72 /* 480.0 MHz Configuration */ 73 static const struct alpha_pll_config video_cc_pll1_config = { 74 .l = 0x19, 75 .cal_l = 0x48, 76 .alpha = 0x0, 77 .config_ctl_val = 0x25c400e7, 78 .config_ctl_hi_val = 0x0a8062e0, 79 .config_ctl_hi1_val = 0xf51dea20, 80 .user_ctl_val = 0x00000008, 81 .user_ctl_hi_val = 0x00000002, 82 }; 83 84 static struct clk_alpha_pll video_cc_pll1 = { 85 .offset = 0x1000, 86 .config = &video_cc_pll1_config, 87 .vco_table = taycan_eko_t_vco, 88 .num_vco = ARRAY_SIZE(taycan_eko_t_vco), 89 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], 90 .clkr = { 91 .hw.init = &(const struct clk_init_data) { 92 .name = "video_cc_pll1", 93 .parent_data = &(const struct clk_parent_data) { 94 .index = DT_BI_TCXO, 95 }, 96 .num_parents = 1, 97 .ops = &clk_alpha_pll_taycan_eko_t_ops, 98 }, 99 }, 100 }; 101 102 /* 480.0 MHz Configuration */ 103 static const struct alpha_pll_config video_cc_pll2_config = { 104 .l = 0x19, 105 .cal_l = 0x48, 106 .alpha = 0x0, 107 .config_ctl_val = 0x25c400e7, 108 .config_ctl_hi_val = 0x0a8062e0, 109 .config_ctl_hi1_val = 0xf51dea20, 110 .user_ctl_val = 0x00000008, 111 .user_ctl_hi_val = 0x00000002, 112 }; 113 114 static struct clk_alpha_pll video_cc_pll2 = { 115 .offset = 0x2000, 116 .config = &video_cc_pll2_config, 117 .vco_table = taycan_eko_t_vco, 118 .num_vco = ARRAY_SIZE(taycan_eko_t_vco), 119 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], 120 .clkr = { 121 .hw.init = &(const struct clk_init_data) { 122 .name = "video_cc_pll2", 123 .parent_data = &(const struct clk_parent_data) { 124 .index = DT_BI_TCXO, 125 }, 126 .num_parents = 1, 127 .ops = &clk_alpha_pll_taycan_eko_t_ops, 128 }, 129 }, 130 }; 131 132 /* 480.0 MHz Configuration */ 133 static const struct alpha_pll_config video_cc_pll3_config = { 134 .l = 0x19, 135 .cal_l = 0x48, 136 .alpha = 0x0, 137 .config_ctl_val = 0x25c400e7, 138 .config_ctl_hi_val = 0x0a8062e0, 139 .config_ctl_hi1_val = 0xf51dea20, 140 .user_ctl_val = 0x00000008, 141 .user_ctl_hi_val = 0x00000002, 142 }; 143 144 static struct clk_alpha_pll video_cc_pll3 = { 145 .offset = 0x3000, 146 .config = &video_cc_pll3_config, 147 .vco_table = taycan_eko_t_vco, 148 .num_vco = ARRAY_SIZE(taycan_eko_t_vco), 149 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], 150 .clkr = { 151 .hw.init = &(const struct clk_init_data) { 152 .name = "video_cc_pll3", 153 .parent_data = &(const struct clk_parent_data) { 154 .index = DT_BI_TCXO, 155 }, 156 .num_parents = 1, 157 .ops = &clk_alpha_pll_taycan_eko_t_ops, 158 }, 159 }, 160 }; 161 162 static const struct parent_map video_cc_parent_map_0[] = { 163 { P_BI_TCXO, 0 }, 164 }; 165 166 static const struct clk_parent_data video_cc_parent_data_0[] = { 167 { .index = DT_BI_TCXO }, 168 }; 169 170 static const struct parent_map video_cc_parent_map_1[] = { 171 { P_BI_TCXO, 0 }, 172 { P_VIDEO_CC_PLL1_OUT_MAIN, 1 }, 173 }; 174 175 static const struct clk_parent_data video_cc_parent_data_1[] = { 176 { .index = DT_BI_TCXO }, 177 { .hw = &video_cc_pll1.clkr.hw }, 178 }; 179 180 static const struct parent_map video_cc_parent_map_2[] = { 181 { P_BI_TCXO, 0 }, 182 { P_VIDEO_CC_PLL3_OUT_MAIN, 1 }, 183 }; 184 185 static const struct clk_parent_data video_cc_parent_data_2[] = { 186 { .index = DT_BI_TCXO }, 187 { .hw = &video_cc_pll3.clkr.hw }, 188 }; 189 190 static const struct parent_map video_cc_parent_map_3[] = { 191 { P_BI_TCXO, 0 }, 192 { P_VIDEO_CC_PLL2_OUT_MAIN, 1 }, 193 }; 194 195 static const struct clk_parent_data video_cc_parent_data_3[] = { 196 { .index = DT_BI_TCXO }, 197 { .hw = &video_cc_pll2.clkr.hw }, 198 }; 199 200 static const struct parent_map video_cc_parent_map_4[] = { 201 { P_BI_TCXO, 0 }, 202 { P_VIDEO_CC_PLL0_OUT_MAIN, 1 }, 203 }; 204 205 static const struct clk_parent_data video_cc_parent_data_4[] = { 206 { .index = DT_BI_TCXO }, 207 { .hw = &video_cc_pll0.clkr.hw }, 208 }; 209 210 static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = { 211 F(19200000, P_BI_TCXO, 1, 0, 0), 212 { } 213 }; 214 215 static struct clk_rcg2 video_cc_ahb_clk_src = { 216 .cmd_rcgr = 0x8060, 217 .mnd_width = 0, 218 .hid_width = 5, 219 .parent_map = video_cc_parent_map_0, 220 .freq_tbl = ftbl_video_cc_ahb_clk_src, 221 .clkr.hw.init = &(const struct clk_init_data) { 222 .name = "video_cc_ahb_clk_src", 223 .parent_data = video_cc_parent_data_0, 224 .num_parents = ARRAY_SIZE(video_cc_parent_data_0), 225 .flags = CLK_SET_RATE_PARENT, 226 .ops = &clk_rcg2_shared_ops, 227 }, 228 }; 229 230 static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { 231 F(240000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), 232 F(338000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), 233 F(420000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), 234 F(444000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), 235 F(533000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), 236 F(630000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), 237 F(800000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), 238 F(1000000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), 239 { } 240 }; 241 242 static struct clk_rcg2 video_cc_mvs0_clk_src = { 243 .cmd_rcgr = 0x8030, 244 .mnd_width = 0, 245 .hid_width = 5, 246 .parent_map = video_cc_parent_map_1, 247 .freq_tbl = ftbl_video_cc_mvs0_clk_src, 248 .hw_clk_ctrl = true, 249 .clkr.hw.init = &(const struct clk_init_data) { 250 .name = "video_cc_mvs0_clk_src", 251 .parent_data = video_cc_parent_data_1, 252 .num_parents = ARRAY_SIZE(video_cc_parent_data_1), 253 .flags = CLK_SET_RATE_PARENT, 254 .ops = &clk_rcg2_shared_ops, 255 }, 256 }; 257 258 static const struct freq_tbl ftbl_video_cc_mvs0a_clk_src[] = { 259 F(240000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), 260 F(338000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), 261 F(420000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), 262 F(444000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), 263 F(533000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), 264 F(630000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), 265 { } 266 }; 267 268 static struct clk_rcg2 video_cc_mvs0a_clk_src = { 269 .cmd_rcgr = 0x8000, 270 .mnd_width = 0, 271 .hid_width = 5, 272 .parent_map = video_cc_parent_map_2, 273 .freq_tbl = ftbl_video_cc_mvs0a_clk_src, 274 .hw_clk_ctrl = true, 275 .clkr.hw.init = &(const struct clk_init_data) { 276 .name = "video_cc_mvs0a_clk_src", 277 .parent_data = video_cc_parent_data_2, 278 .num_parents = ARRAY_SIZE(video_cc_parent_data_2), 279 .flags = CLK_SET_RATE_PARENT, 280 .ops = &clk_rcg2_shared_ops, 281 }, 282 }; 283 284 static const struct freq_tbl ftbl_video_cc_mvs0b_clk_src[] = { 285 F(240000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), 286 F(338000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), 287 F(420000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), 288 F(444000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), 289 F(533000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), 290 F(630000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), 291 F(850000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), 292 { } 293 }; 294 295 static struct clk_rcg2 video_cc_mvs0b_clk_src = { 296 .cmd_rcgr = 0x8018, 297 .mnd_width = 0, 298 .hid_width = 5, 299 .parent_map = video_cc_parent_map_3, 300 .freq_tbl = ftbl_video_cc_mvs0b_clk_src, 301 .hw_clk_ctrl = true, 302 .clkr.hw.init = &(const struct clk_init_data) { 303 .name = "video_cc_mvs0b_clk_src", 304 .parent_data = video_cc_parent_data_3, 305 .num_parents = ARRAY_SIZE(video_cc_parent_data_3), 306 .flags = CLK_SET_RATE_PARENT, 307 .ops = &clk_rcg2_shared_ops, 308 }, 309 }; 310 311 static const struct freq_tbl ftbl_video_cc_mvs0c_clk_src[] = { 312 F(360000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 313 F(507000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 314 F(630000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 315 F(666000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 316 F(800000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 317 F(1104000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 318 F(1260000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), 319 { } 320 }; 321 322 static struct clk_rcg2 video_cc_mvs0c_clk_src = { 323 .cmd_rcgr = 0x8048, 324 .mnd_width = 0, 325 .hid_width = 5, 326 .parent_map = video_cc_parent_map_4, 327 .freq_tbl = ftbl_video_cc_mvs0c_clk_src, 328 .hw_clk_ctrl = true, 329 .clkr.hw.init = &(const struct clk_init_data) { 330 .name = "video_cc_mvs0c_clk_src", 331 .parent_data = video_cc_parent_data_4, 332 .num_parents = ARRAY_SIZE(video_cc_parent_data_4), 333 .flags = CLK_SET_RATE_PARENT, 334 .ops = &clk_rcg2_shared_ops, 335 }, 336 }; 337 338 static struct clk_rcg2 video_cc_xo_clk_src = { 339 .cmd_rcgr = 0x8194, 340 .mnd_width = 0, 341 .hid_width = 5, 342 .parent_map = video_cc_parent_map_0, 343 .freq_tbl = ftbl_video_cc_ahb_clk_src, 344 .clkr.hw.init = &(const struct clk_init_data) { 345 .name = "video_cc_xo_clk_src", 346 .parent_data = video_cc_parent_data_0, 347 .num_parents = ARRAY_SIZE(video_cc_parent_data_0), 348 .flags = CLK_SET_RATE_PARENT, 349 .ops = &clk_rcg2_ops, 350 }, 351 }; 352 353 static struct clk_branch video_cc_mvs0_clk = { 354 .halt_reg = 0x80d0, 355 .halt_check = BRANCH_HALT_VOTED, 356 .hwcg_reg = 0x80d0, 357 .hwcg_bit = 1, 358 .clkr = { 359 .enable_reg = 0x80d0, 360 .enable_mask = BIT(0), 361 .hw.init = &(const struct clk_init_data) { 362 .name = "video_cc_mvs0_clk", 363 .parent_hws = (const struct clk_hw*[]) { 364 &video_cc_mvs0_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_mem_branch video_cc_mvs0_freerun_clk = { 374 .mem_enable_reg = 0x80e4, 375 .mem_ack_reg = 0x80e4, 376 .mem_enable_mask = BIT(3), 377 .mem_enable_ack_mask = GENMASK(11, 10), 378 .mem_enable_invert = true, 379 .branch = { 380 .halt_reg = 0x80e0, 381 .halt_check = BRANCH_HALT, 382 .clkr = { 383 .enable_reg = 0x80e0, 384 .enable_mask = BIT(0), 385 .hw.init = &(const struct clk_init_data) { 386 .name = "video_cc_mvs0_freerun_clk", 387 .parent_hws = (const struct clk_hw*[]) { 388 &video_cc_mvs0_clk_src.clkr.hw, 389 }, 390 .num_parents = 1, 391 .flags = CLK_SET_RATE_PARENT, 392 .ops = &clk_branch2_ops, 393 }, 394 }, 395 }, 396 }; 397 398 static struct clk_branch video_cc_mvs0_shift_clk = { 399 .halt_reg = 0x81b4, 400 .halt_check = BRANCH_HALT_VOTED, 401 .hwcg_reg = 0x81b4, 402 .hwcg_bit = 1, 403 .clkr = { 404 .enable_reg = 0x81b4, 405 .enable_mask = BIT(0), 406 .hw.init = &(const struct clk_init_data) { 407 .name = "video_cc_mvs0_shift_clk", 408 .parent_hws = (const struct clk_hw*[]) { 409 &video_cc_xo_clk_src.clkr.hw, 410 }, 411 .num_parents = 1, 412 .flags = CLK_SET_RATE_PARENT, 413 .ops = &clk_branch2_ops, 414 }, 415 }, 416 }; 417 418 static struct clk_branch video_cc_mvs0_vpp0_clk = { 419 .halt_reg = 0x8134, 420 .halt_check = BRANCH_HALT_VOTED, 421 .hwcg_reg = 0x8134, 422 .hwcg_bit = 1, 423 .clkr = { 424 .enable_reg = 0x8134, 425 .enable_mask = BIT(0), 426 .hw.init = &(const struct clk_init_data) { 427 .name = "video_cc_mvs0_vpp0_clk", 428 .parent_hws = (const struct clk_hw*[]) { 429 &video_cc_mvs0_clk_src.clkr.hw, 430 }, 431 .num_parents = 1, 432 .flags = CLK_SET_RATE_PARENT, 433 .ops = &clk_branch2_ops, 434 }, 435 }, 436 }; 437 438 static struct clk_branch video_cc_mvs0_vpp0_freerun_clk = { 439 .halt_reg = 0x8144, 440 .halt_check = BRANCH_HALT, 441 .clkr = { 442 .enable_reg = 0x8144, 443 .enable_mask = BIT(0), 444 .hw.init = &(const struct clk_init_data) { 445 .name = "video_cc_mvs0_vpp0_freerun_clk", 446 .parent_hws = (const struct clk_hw*[]) { 447 &video_cc_mvs0_clk_src.clkr.hw, 448 }, 449 .num_parents = 1, 450 .flags = CLK_SET_RATE_PARENT, 451 .ops = &clk_branch2_ops, 452 }, 453 }, 454 }; 455 456 static struct clk_branch video_cc_mvs0_vpp1_clk = { 457 .halt_reg = 0x8108, 458 .halt_check = BRANCH_HALT_VOTED, 459 .hwcg_reg = 0x8108, 460 .hwcg_bit = 1, 461 .clkr = { 462 .enable_reg = 0x8108, 463 .enable_mask = BIT(0), 464 .hw.init = &(const struct clk_init_data) { 465 .name = "video_cc_mvs0_vpp1_clk", 466 .parent_hws = (const struct clk_hw*[]) { 467 &video_cc_mvs0_clk_src.clkr.hw, 468 }, 469 .num_parents = 1, 470 .flags = CLK_SET_RATE_PARENT, 471 .ops = &clk_branch2_ops, 472 }, 473 }, 474 }; 475 476 static struct clk_branch video_cc_mvs0_vpp1_freerun_clk = { 477 .halt_reg = 0x8118, 478 .halt_check = BRANCH_HALT, 479 .clkr = { 480 .enable_reg = 0x8118, 481 .enable_mask = BIT(0), 482 .hw.init = &(const struct clk_init_data) { 483 .name = "video_cc_mvs0_vpp1_freerun_clk", 484 .parent_hws = (const struct clk_hw*[]) { 485 &video_cc_mvs0_clk_src.clkr.hw, 486 }, 487 .num_parents = 1, 488 .flags = CLK_SET_RATE_PARENT, 489 .ops = &clk_branch2_ops, 490 }, 491 }, 492 }; 493 494 static struct clk_branch video_cc_mvs0a_clk = { 495 .halt_reg = 0x8090, 496 .halt_check = BRANCH_HALT_VOTED, 497 .hwcg_reg = 0x8090, 498 .hwcg_bit = 1, 499 .clkr = { 500 .enable_reg = 0x8090, 501 .enable_mask = BIT(0), 502 .hw.init = &(const struct clk_init_data) { 503 .name = "video_cc_mvs0a_clk", 504 .parent_hws = (const struct clk_hw*[]) { 505 &video_cc_mvs0a_clk_src.clkr.hw, 506 }, 507 .num_parents = 1, 508 .flags = CLK_SET_RATE_PARENT, 509 .ops = &clk_branch2_ops, 510 }, 511 }, 512 }; 513 514 static struct clk_branch video_cc_mvs0a_freerun_clk = { 515 .halt_reg = 0x80a0, 516 .halt_check = BRANCH_HALT, 517 .clkr = { 518 .enable_reg = 0x80a0, 519 .enable_mask = BIT(0), 520 .hw.init = &(const struct clk_init_data) { 521 .name = "video_cc_mvs0a_freerun_clk", 522 .parent_hws = (const struct clk_hw*[]) { 523 &video_cc_mvs0a_clk_src.clkr.hw, 524 }, 525 .num_parents = 1, 526 .flags = CLK_SET_RATE_PARENT, 527 .ops = &clk_branch2_ops, 528 }, 529 }, 530 }; 531 532 static struct clk_branch video_cc_mvs0b_clk = { 533 .halt_reg = 0x80bc, 534 .halt_check = BRANCH_HALT_VOTED, 535 .hwcg_reg = 0x80bc, 536 .hwcg_bit = 1, 537 .clkr = { 538 .enable_reg = 0x80bc, 539 .enable_mask = BIT(0), 540 .hw.init = &(const struct clk_init_data) { 541 .name = "video_cc_mvs0b_clk", 542 .parent_hws = (const struct clk_hw*[]) { 543 &video_cc_mvs0b_clk_src.clkr.hw, 544 }, 545 .num_parents = 1, 546 .flags = CLK_SET_RATE_PARENT, 547 .ops = &clk_branch2_ops, 548 }, 549 }, 550 }; 551 552 static struct clk_branch video_cc_mvs0b_freerun_clk = { 553 .halt_reg = 0x80cc, 554 .halt_check = BRANCH_HALT, 555 .clkr = { 556 .enable_reg = 0x80cc, 557 .enable_mask = BIT(0), 558 .hw.init = &(const struct clk_init_data) { 559 .name = "video_cc_mvs0b_freerun_clk", 560 .parent_hws = (const struct clk_hw*[]) { 561 &video_cc_mvs0b_clk_src.clkr.hw, 562 }, 563 .num_parents = 1, 564 .flags = CLK_SET_RATE_PARENT, 565 .ops = &clk_branch2_ops, 566 }, 567 }, 568 }; 569 570 static struct clk_branch video_cc_mvs0c_clk = { 571 .halt_reg = 0x8164, 572 .halt_check = BRANCH_HALT_VOTED, 573 .hwcg_reg = 0x8164, 574 .hwcg_bit = 1, 575 .clkr = { 576 .enable_reg = 0x8164, 577 .enable_mask = BIT(0), 578 .hw.init = &(const struct clk_init_data) { 579 .name = "video_cc_mvs0c_clk", 580 .parent_hws = (const struct clk_hw*[]) { 581 &video_cc_mvs0c_clk_src.clkr.hw, 582 }, 583 .num_parents = 1, 584 .flags = CLK_SET_RATE_PARENT, 585 .ops = &clk_branch2_ops, 586 }, 587 }, 588 }; 589 590 static struct clk_branch video_cc_mvs0c_freerun_clk = { 591 .halt_reg = 0x8174, 592 .halt_check = BRANCH_HALT, 593 .clkr = { 594 .enable_reg = 0x8174, 595 .enable_mask = BIT(0), 596 .hw.init = &(const struct clk_init_data) { 597 .name = "video_cc_mvs0c_freerun_clk", 598 .parent_hws = (const struct clk_hw*[]) { 599 &video_cc_mvs0c_clk_src.clkr.hw, 600 }, 601 .num_parents = 1, 602 .flags = CLK_SET_RATE_PARENT, 603 .ops = &clk_branch2_ops, 604 }, 605 }, 606 }; 607 608 static struct clk_branch video_cc_mvs0c_shift_clk = { 609 .halt_reg = 0x81b8, 610 .halt_check = BRANCH_HALT_VOTED, 611 .hwcg_reg = 0x81b8, 612 .hwcg_bit = 1, 613 .clkr = { 614 .enable_reg = 0x81b8, 615 .enable_mask = BIT(0), 616 .hw.init = &(const struct clk_init_data) { 617 .name = "video_cc_mvs0c_shift_clk", 618 .parent_hws = (const struct clk_hw*[]) { 619 &video_cc_xo_clk_src.clkr.hw, 620 }, 621 .num_parents = 1, 622 .flags = CLK_SET_RATE_PARENT, 623 .ops = &clk_branch2_ops, 624 }, 625 }, 626 }; 627 628 static struct gdsc video_cc_mvs0_vpp0_gdsc = { 629 .gdscr = 0x8120, 630 .en_rest_wait_val = 0x2, 631 .en_few_wait_val = 0x2, 632 .clk_dis_wait_val = 0xf, 633 .pd = { 634 .name = "video_cc_mvs0_vpp0_gdsc", 635 }, 636 .pwrsts = PWRSTS_OFF_ON, 637 .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, 638 }; 639 640 static struct gdsc video_cc_mvs0_vpp1_gdsc = { 641 .gdscr = 0x80f4, 642 .en_rest_wait_val = 0x2, 643 .en_few_wait_val = 0x2, 644 .clk_dis_wait_val = 0xf, 645 .pd = { 646 .name = "video_cc_mvs0_vpp1_gdsc", 647 }, 648 .pwrsts = PWRSTS_OFF_ON, 649 .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, 650 }; 651 652 static struct gdsc video_cc_mvs0a_gdsc = { 653 .gdscr = 0x807c, 654 .en_rest_wait_val = 0x2, 655 .en_few_wait_val = 0x2, 656 .clk_dis_wait_val = 0xf, 657 .pd = { 658 .name = "video_cc_mvs0a_gdsc", 659 }, 660 .pwrsts = PWRSTS_OFF_ON, 661 .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, 662 }; 663 664 static struct gdsc video_cc_mvs0c_gdsc = { 665 .gdscr = 0x814c, 666 .en_rest_wait_val = 0x2, 667 .en_few_wait_val = 0x2, 668 .clk_dis_wait_val = 0x6, 669 .pd = { 670 .name = "video_cc_mvs0c_gdsc", 671 }, 672 .pwrsts = PWRSTS_OFF_ON, 673 .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, 674 }; 675 676 static struct gdsc video_cc_mvs0_gdsc = { 677 .gdscr = 0x80a8, 678 .en_rest_wait_val = 0x2, 679 .en_few_wait_val = 0x2, 680 .clk_dis_wait_val = 0x6, 681 .pd = { 682 .name = "video_cc_mvs0_gdsc", 683 }, 684 .pwrsts = PWRSTS_OFF_ON, 685 .parent = &video_cc_mvs0c_gdsc.pd, 686 .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, 687 }; 688 689 static struct clk_regmap *video_cc_kaanapali_clocks[] = { 690 [VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr, 691 [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr, 692 [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr, 693 [VIDEO_CC_MVS0_FREERUN_CLK] = &video_cc_mvs0_freerun_clk.branch.clkr, 694 [VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr, 695 [VIDEO_CC_MVS0_VPP0_CLK] = &video_cc_mvs0_vpp0_clk.clkr, 696 [VIDEO_CC_MVS0_VPP0_FREERUN_CLK] = &video_cc_mvs0_vpp0_freerun_clk.clkr, 697 [VIDEO_CC_MVS0_VPP1_CLK] = &video_cc_mvs0_vpp1_clk.clkr, 698 [VIDEO_CC_MVS0_VPP1_FREERUN_CLK] = &video_cc_mvs0_vpp1_freerun_clk.clkr, 699 [VIDEO_CC_MVS0A_CLK] = &video_cc_mvs0a_clk.clkr, 700 [VIDEO_CC_MVS0A_CLK_SRC] = &video_cc_mvs0a_clk_src.clkr, 701 [VIDEO_CC_MVS0A_FREERUN_CLK] = &video_cc_mvs0a_freerun_clk.clkr, 702 [VIDEO_CC_MVS0B_CLK] = &video_cc_mvs0b_clk.clkr, 703 [VIDEO_CC_MVS0B_CLK_SRC] = &video_cc_mvs0b_clk_src.clkr, 704 [VIDEO_CC_MVS0B_FREERUN_CLK] = &video_cc_mvs0b_freerun_clk.clkr, 705 [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, 706 [VIDEO_CC_MVS0C_CLK_SRC] = &video_cc_mvs0c_clk_src.clkr, 707 [VIDEO_CC_MVS0C_FREERUN_CLK] = &video_cc_mvs0c_freerun_clk.clkr, 708 [VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr, 709 [VIDEO_CC_PLL0] = &video_cc_pll0.clkr, 710 [VIDEO_CC_PLL1] = &video_cc_pll1.clkr, 711 [VIDEO_CC_PLL2] = &video_cc_pll2.clkr, 712 [VIDEO_CC_PLL3] = &video_cc_pll3.clkr, 713 [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, 714 }; 715 716 static struct gdsc *video_cc_kaanapali_gdscs[] = { 717 [VIDEO_CC_MVS0A_GDSC] = &video_cc_mvs0a_gdsc, 718 [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc, 719 [VIDEO_CC_MVS0_VPP1_GDSC] = &video_cc_mvs0_vpp1_gdsc, 720 [VIDEO_CC_MVS0_VPP0_GDSC] = &video_cc_mvs0_vpp0_gdsc, 721 [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc, 722 }; 723 724 static const struct qcom_reset_map video_cc_kaanapali_resets[] = { 725 [VIDEO_CC_INTERFACE_BCR] = { 0x8178 }, 726 [VIDEO_CC_MVS0_BCR] = { 0x80a4 }, 727 [VIDEO_CC_MVS0_VPP0_BCR] = { 0x811c }, 728 [VIDEO_CC_MVS0_VPP1_BCR] = { 0x80f0 }, 729 [VIDEO_CC_MVS0A_BCR] = { 0x8078 }, 730 [VIDEO_CC_MVS0C_CLK_ARES] = { 0x8164, 2 }, 731 [VIDEO_CC_MVS0C_BCR] = { 0x8148 }, 732 [VIDEO_CC_MVS0_FREERUN_CLK_ARES] = { 0x80e0, 2 }, 733 [VIDEO_CC_MVS0C_FREERUN_CLK_ARES] = { 0x8174, 2 }, 734 [VIDEO_CC_XO_CLK_ARES] = { 0x81ac, 2 }, 735 }; 736 737 static struct clk_alpha_pll *video_cc_kaanapali_plls[] = { 738 &video_cc_pll0, 739 &video_cc_pll1, 740 &video_cc_pll2, 741 &video_cc_pll3, 742 }; 743 744 static u32 video_cc_kaanapali_critical_cbcrs[] = { 745 0x817c, /* VIDEO_CC_AHB_CLK */ 746 0x81bc, /* VIDEO_CC_SLEEP_CLK */ 747 0x81b0, /* VIDEO_CC_TS_XO_CLK */ 748 0x81ac, /* VIDEO_CC_XO_CLK */ 749 }; 750 751 static const struct regmap_config video_cc_kaanapali_regmap_config = { 752 .reg_bits = 32, 753 .reg_stride = 4, 754 .val_bits = 32, 755 .max_register = 0xa010, 756 .fast_io = true, 757 }; 758 759 static void clk_kaanapali_regs_configure(struct device *dev, struct regmap *regmap) 760 { 761 /* 762 * Enable clk_on sync for MVS0 and VPP clocks via VIDEO_CC_SPARE1 763 * during core reset by default. 764 */ 765 regmap_set_bits(regmap, 0x9f24, BIT(0)); 766 767 /* 768 * As per HW design recommendation 769 * Update DLY_ACCU_RED_SHIFTER_DONE to 0xF for the below GDSCs 770 * MVS0A CFG3, MVS0 CFG3, MVS0 VPP1 CFG3, MVS0 VPP0 CFG3, MVS0C CFG3 771 */ 772 regmap_set_bits(regmap, 0x8088, ACCU_CFG_MASK); 773 regmap_set_bits(regmap, 0x80b4, ACCU_CFG_MASK); 774 regmap_set_bits(regmap, 0x8100, ACCU_CFG_MASK); 775 regmap_set_bits(regmap, 0x812c, ACCU_CFG_MASK); 776 regmap_set_bits(regmap, 0x8158, ACCU_CFG_MASK); 777 } 778 779 static struct qcom_cc_driver_data video_cc_kaanapali_driver_data = { 780 .alpha_plls = video_cc_kaanapali_plls, 781 .num_alpha_plls = ARRAY_SIZE(video_cc_kaanapali_plls), 782 .clk_cbcrs = video_cc_kaanapali_critical_cbcrs, 783 .num_clk_cbcrs = ARRAY_SIZE(video_cc_kaanapali_critical_cbcrs), 784 .clk_regs_configure = clk_kaanapali_regs_configure, 785 }; 786 787 static const struct qcom_cc_desc video_cc_kaanapali_desc = { 788 .config = &video_cc_kaanapali_regmap_config, 789 .clks = video_cc_kaanapali_clocks, 790 .num_clks = ARRAY_SIZE(video_cc_kaanapali_clocks), 791 .resets = video_cc_kaanapali_resets, 792 .num_resets = ARRAY_SIZE(video_cc_kaanapali_resets), 793 .gdscs = video_cc_kaanapali_gdscs, 794 .num_gdscs = ARRAY_SIZE(video_cc_kaanapali_gdscs), 795 .use_rpm = true, 796 .driver_data = &video_cc_kaanapali_driver_data, 797 }; 798 799 static const struct of_device_id video_cc_kaanapali_match_table[] = { 800 { .compatible = "qcom,kaanapali-videocc" }, 801 { } 802 }; 803 MODULE_DEVICE_TABLE(of, video_cc_kaanapali_match_table); 804 805 static int video_cc_kaanapali_probe(struct platform_device *pdev) 806 { 807 return qcom_cc_probe(pdev, &video_cc_kaanapali_desc); 808 } 809 810 static struct platform_driver video_cc_kaanapali_driver = { 811 .probe = video_cc_kaanapali_probe, 812 .driver = { 813 .name = "videocc-kaanapali", 814 .of_match_table = video_cc_kaanapali_match_table, 815 }, 816 }; 817 818 module_platform_driver(video_cc_kaanapali_driver); 819 820 MODULE_DESCRIPTION("QTI VIDEOCC Kaanapali Driver"); 821 MODULE_LICENSE("GPL"); 822