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