1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2019, 2022, The Linux Foundation. All rights reserved. 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,dispcc-sc7180.h> 12 13 #include "clk-alpha-pll.h" 14 #include "clk-branch.h" 15 #include "clk-rcg.h" 16 #include "clk-regmap-divider.h" 17 #include "common.h" 18 #include "gdsc.h" 19 20 enum { 21 P_BI_TCXO, 22 P_DISP_CC_PLL0_OUT_EVEN, 23 P_DISP_CC_PLL0_OUT_MAIN, 24 P_DP_PHY_PLL_LINK_CLK, 25 P_DP_PHY_PLL_VCO_DIV_CLK, 26 P_DSI0_PHY_PLL_OUT_BYTECLK, 27 P_DSI0_PHY_PLL_OUT_DSICLK, 28 P_GPLL0_OUT_MAIN, 29 }; 30 31 static const struct pll_vco fabia_vco[] = { 32 { 249600000, 2000000000, 0 }, 33 }; 34 35 static struct clk_alpha_pll disp_cc_pll0 = { 36 .offset = 0x0, 37 .vco_table = fabia_vco, 38 .num_vco = ARRAY_SIZE(fabia_vco), 39 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], 40 .clkr = { 41 .hw.init = &(struct clk_init_data){ 42 .name = "disp_cc_pll0", 43 .parent_data = &(const struct clk_parent_data){ 44 .fw_name = "bi_tcxo", 45 }, 46 .num_parents = 1, 47 .ops = &clk_alpha_pll_fabia_ops, 48 }, 49 }, 50 }; 51 52 static const struct clk_div_table post_div_table_disp_cc_pll0_out_even[] = { 53 { 0x0, 1 }, 54 { } 55 }; 56 57 static struct clk_alpha_pll_postdiv disp_cc_pll0_out_even = { 58 .offset = 0x0, 59 .post_div_shift = 8, 60 .post_div_table = post_div_table_disp_cc_pll0_out_even, 61 .num_post_div = ARRAY_SIZE(post_div_table_disp_cc_pll0_out_even), 62 .width = 4, 63 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], 64 .clkr.hw.init = &(struct clk_init_data){ 65 .name = "disp_cc_pll0_out_even", 66 .parent_hws = (const struct clk_hw*[]){ 67 &disp_cc_pll0.clkr.hw, 68 }, 69 .num_parents = 1, 70 .flags = CLK_SET_RATE_PARENT, 71 .ops = &clk_alpha_pll_postdiv_fabia_ops, 72 }, 73 }; 74 75 static const struct parent_map disp_cc_parent_map_0[] = { 76 { P_BI_TCXO, 0 }, 77 }; 78 79 static const struct clk_parent_data disp_cc_parent_data_0[] = { 80 { .fw_name = "bi_tcxo" }, 81 }; 82 83 static const struct parent_map disp_cc_parent_map_1[] = { 84 { P_BI_TCXO, 0 }, 85 { P_DP_PHY_PLL_LINK_CLK, 1 }, 86 { P_DP_PHY_PLL_VCO_DIV_CLK, 2 }, 87 }; 88 89 static const struct clk_parent_data disp_cc_parent_data_1[] = { 90 { .fw_name = "bi_tcxo" }, 91 { .fw_name = "dp_phy_pll_link_clk" }, 92 { .fw_name = "dp_phy_pll_vco_div_clk" }, 93 }; 94 95 static const struct parent_map disp_cc_parent_map_2[] = { 96 { P_BI_TCXO, 0 }, 97 { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, 98 }; 99 100 static const struct clk_parent_data disp_cc_parent_data_2[] = { 101 { .fw_name = "bi_tcxo" }, 102 { .fw_name = "dsi0_phy_pll_out_byteclk" }, 103 }; 104 105 static const struct parent_map disp_cc_parent_map_3[] = { 106 { P_BI_TCXO, 0 }, 107 { P_DISP_CC_PLL0_OUT_MAIN, 1 }, 108 { P_GPLL0_OUT_MAIN, 4 }, 109 { P_DISP_CC_PLL0_OUT_EVEN, 5 }, 110 }; 111 112 static const struct clk_parent_data disp_cc_parent_data_3[] = { 113 { .fw_name = "bi_tcxo" }, 114 { .hw = &disp_cc_pll0.clkr.hw }, 115 { .fw_name = "gcc_disp_gpll0_clk_src" }, 116 { .hw = &disp_cc_pll0_out_even.clkr.hw }, 117 }; 118 119 static const struct parent_map disp_cc_parent_map_4[] = { 120 { P_BI_TCXO, 0 }, 121 { P_GPLL0_OUT_MAIN, 4 }, 122 }; 123 124 static const struct clk_parent_data disp_cc_parent_data_4[] = { 125 { .fw_name = "bi_tcxo" }, 126 { .fw_name = "gcc_disp_gpll0_clk_src" }, 127 }; 128 129 static const struct parent_map disp_cc_parent_map_5[] = { 130 { P_BI_TCXO, 0 }, 131 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, 132 }; 133 134 static const struct clk_parent_data disp_cc_parent_data_5[] = { 135 { .fw_name = "bi_tcxo" }, 136 { .fw_name = "dsi0_phy_pll_out_dsiclk" }, 137 }; 138 139 static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { 140 F(19200000, P_BI_TCXO, 1, 0, 0), 141 F(37500000, P_GPLL0_OUT_MAIN, 16, 0, 0), 142 F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0), 143 { } 144 }; 145 146 static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { 147 .cmd_rcgr = 0x22bc, 148 .mnd_width = 0, 149 .hid_width = 5, 150 .parent_map = disp_cc_parent_map_4, 151 .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, 152 .clkr.hw.init = &(struct clk_init_data){ 153 .name = "disp_cc_mdss_ahb_clk_src", 154 .parent_data = disp_cc_parent_data_4, 155 .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), 156 .flags = CLK_SET_RATE_PARENT, 157 .ops = &clk_rcg2_shared_ops, 158 }, 159 }; 160 161 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { 162 .cmd_rcgr = 0x2110, 163 .mnd_width = 0, 164 .hid_width = 5, 165 .parent_map = disp_cc_parent_map_2, 166 .clkr.hw.init = &(struct clk_init_data){ 167 .name = "disp_cc_mdss_byte0_clk_src", 168 .parent_data = disp_cc_parent_data_2, 169 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), 170 .flags = CLK_SET_RATE_PARENT, 171 .ops = &clk_byte2_ops, 172 }, 173 }; 174 175 static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = { 176 F(19200000, P_BI_TCXO, 1, 0, 0), 177 { } 178 }; 179 180 static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = { 181 .cmd_rcgr = 0x21dc, 182 .mnd_width = 0, 183 .hid_width = 5, 184 .parent_map = disp_cc_parent_map_0, 185 .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, 186 .clkr.hw.init = &(struct clk_init_data){ 187 .name = "disp_cc_mdss_dp_aux_clk_src", 188 .parent_data = disp_cc_parent_data_0, 189 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 190 .ops = &clk_rcg2_ops, 191 }, 192 }; 193 194 static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = { 195 .cmd_rcgr = 0x2194, 196 .mnd_width = 0, 197 .hid_width = 5, 198 .parent_map = disp_cc_parent_map_1, 199 .clkr.hw.init = &(struct clk_init_data){ 200 .name = "disp_cc_mdss_dp_crypto_clk_src", 201 .parent_data = disp_cc_parent_data_1, 202 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), 203 .ops = &clk_byte2_ops, 204 }, 205 }; 206 207 static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = { 208 .cmd_rcgr = 0x2178, 209 .mnd_width = 0, 210 .hid_width = 5, 211 .parent_map = disp_cc_parent_map_1, 212 .clkr.hw.init = &(struct clk_init_data){ 213 .name = "disp_cc_mdss_dp_link_clk_src", 214 .parent_data = disp_cc_parent_data_1, 215 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), 216 .ops = &clk_byte2_ops, 217 }, 218 }; 219 220 static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = { 221 .cmd_rcgr = 0x21ac, 222 .mnd_width = 16, 223 .hid_width = 5, 224 .parent_map = disp_cc_parent_map_1, 225 .clkr.hw.init = &(struct clk_init_data){ 226 .name = "disp_cc_mdss_dp_pixel_clk_src", 227 .parent_data = disp_cc_parent_data_1, 228 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), 229 .ops = &clk_dp_ops, 230 }, 231 }; 232 233 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { 234 .cmd_rcgr = 0x2148, 235 .mnd_width = 0, 236 .hid_width = 5, 237 .parent_map = disp_cc_parent_map_2, 238 .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, 239 .clkr.hw.init = &(struct clk_init_data){ 240 .name = "disp_cc_mdss_esc0_clk_src", 241 .parent_data = disp_cc_parent_data_2, 242 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), 243 .ops = &clk_rcg2_ops, 244 }, 245 }; 246 247 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { 248 F(19200000, P_BI_TCXO, 1, 0, 0), 249 F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), 250 F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), 251 F(345000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0), 252 F(460000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 253 { } 254 }; 255 256 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { 257 .cmd_rcgr = 0x20c8, 258 .mnd_width = 0, 259 .hid_width = 5, 260 .parent_map = disp_cc_parent_map_3, 261 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, 262 .clkr.hw.init = &(struct clk_init_data){ 263 .name = "disp_cc_mdss_mdp_clk_src", 264 .parent_data = disp_cc_parent_data_3, 265 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), 266 .ops = &clk_rcg2_shared_ops, 267 }, 268 }; 269 270 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { 271 .cmd_rcgr = 0x2098, 272 .mnd_width = 8, 273 .hid_width = 5, 274 .parent_map = disp_cc_parent_map_5, 275 .clkr.hw.init = &(struct clk_init_data){ 276 .name = "disp_cc_mdss_pclk0_clk_src", 277 .parent_data = disp_cc_parent_data_5, 278 .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), 279 .flags = CLK_SET_RATE_PARENT, 280 .ops = &clk_pixel_ops, 281 }, 282 }; 283 284 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = { 285 .cmd_rcgr = 0x20e0, 286 .mnd_width = 0, 287 .hid_width = 5, 288 .parent_map = disp_cc_parent_map_3, 289 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, 290 .clkr.hw.init = &(struct clk_init_data){ 291 .name = "disp_cc_mdss_rot_clk_src", 292 .parent_data = disp_cc_parent_data_3, 293 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), 294 .ops = &clk_rcg2_shared_ops, 295 }, 296 }; 297 298 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { 299 .cmd_rcgr = 0x20f8, 300 .mnd_width = 0, 301 .hid_width = 5, 302 .parent_map = disp_cc_parent_map_0, 303 .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, 304 .clkr.hw.init = &(struct clk_init_data){ 305 .name = "disp_cc_mdss_vsync_clk_src", 306 .parent_data = disp_cc_parent_data_0, 307 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 308 .ops = &clk_rcg2_shared_ops, 309 }, 310 }; 311 312 static struct clk_branch disp_cc_mdss_ahb_clk = { 313 .halt_reg = 0x2080, 314 .halt_check = BRANCH_HALT, 315 .clkr = { 316 .enable_reg = 0x2080, 317 .enable_mask = BIT(0), 318 .hw.init = &(struct clk_init_data){ 319 .name = "disp_cc_mdss_ahb_clk", 320 .parent_hws = (const struct clk_hw*[]){ 321 &disp_cc_mdss_ahb_clk_src.clkr.hw, 322 }, 323 .num_parents = 1, 324 .flags = CLK_SET_RATE_PARENT, 325 .ops = &clk_branch2_ops, 326 }, 327 }, 328 }; 329 330 static struct clk_branch disp_cc_mdss_byte0_clk = { 331 .halt_reg = 0x2028, 332 .halt_check = BRANCH_HALT, 333 .clkr = { 334 .enable_reg = 0x2028, 335 .enable_mask = BIT(0), 336 .hw.init = &(struct clk_init_data){ 337 .name = "disp_cc_mdss_byte0_clk", 338 .parent_hws = (const struct clk_hw*[]){ 339 &disp_cc_mdss_byte0_clk_src.clkr.hw, 340 }, 341 .num_parents = 1, 342 .flags = CLK_SET_RATE_PARENT, 343 .ops = &clk_branch2_ops, 344 }, 345 }, 346 }; 347 348 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { 349 .reg = 0x2128, 350 .shift = 0, 351 .width = 2, 352 .clkr.hw.init = &(struct clk_init_data) { 353 .name = "disp_cc_mdss_byte0_div_clk_src", 354 .parent_hws = (const struct clk_hw*[]) { 355 &disp_cc_mdss_byte0_clk_src.clkr.hw, 356 }, 357 .num_parents = 1, 358 .ops = &clk_regmap_div_ops, 359 }, 360 }; 361 362 static struct clk_regmap_div disp_cc_mdss_dp_link_div_clk_src = { 363 .reg = 0x2190, 364 .shift = 0, 365 .width = 2, 366 .clkr.hw.init = &(struct clk_init_data) { 367 .name = "disp_cc_mdss_dp_link_div_clk_src", 368 .parent_hws = (const struct clk_hw*[]) { 369 &disp_cc_mdss_dp_link_clk_src.clkr.hw, 370 }, 371 .num_parents = 1, 372 .ops = &clk_regmap_div_ops, 373 }, 374 }; 375 376 static struct clk_branch disp_cc_mdss_byte0_intf_clk = { 377 .halt_reg = 0x202c, 378 .halt_check = BRANCH_HALT, 379 .clkr = { 380 .enable_reg = 0x202c, 381 .enable_mask = BIT(0), 382 .hw.init = &(struct clk_init_data){ 383 .name = "disp_cc_mdss_byte0_intf_clk", 384 .parent_hws = (const struct clk_hw*[]){ 385 &disp_cc_mdss_byte0_div_clk_src.clkr.hw, 386 }, 387 .num_parents = 1, 388 .flags = CLK_SET_RATE_PARENT, 389 .ops = &clk_branch2_ops, 390 }, 391 }, 392 }; 393 394 static struct clk_branch disp_cc_mdss_dp_aux_clk = { 395 .halt_reg = 0x2054, 396 .halt_check = BRANCH_HALT, 397 .clkr = { 398 .enable_reg = 0x2054, 399 .enable_mask = BIT(0), 400 .hw.init = &(struct clk_init_data){ 401 .name = "disp_cc_mdss_dp_aux_clk", 402 .parent_hws = (const struct clk_hw*[]){ 403 &disp_cc_mdss_dp_aux_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 disp_cc_mdss_dp_crypto_clk = { 413 .halt_reg = 0x2048, 414 .halt_check = BRANCH_HALT, 415 .clkr = { 416 .enable_reg = 0x2048, 417 .enable_mask = BIT(0), 418 .hw.init = &(struct clk_init_data){ 419 .name = "disp_cc_mdss_dp_crypto_clk", 420 .parent_hws = (const struct clk_hw*[]){ 421 &disp_cc_mdss_dp_crypto_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 disp_cc_mdss_dp_link_clk = { 431 .halt_reg = 0x2040, 432 .halt_check = BRANCH_HALT, 433 .clkr = { 434 .enable_reg = 0x2040, 435 .enable_mask = BIT(0), 436 .hw.init = &(struct clk_init_data){ 437 .name = "disp_cc_mdss_dp_link_clk", 438 .parent_hws = (const struct clk_hw*[]){ 439 &disp_cc_mdss_dp_link_clk_src.clkr.hw, 440 }, 441 .num_parents = 1, 442 .flags = CLK_SET_RATE_PARENT, 443 .ops = &clk_branch2_ops, 444 }, 445 }, 446 }; 447 448 static struct clk_branch disp_cc_mdss_dp_link_intf_clk = { 449 .halt_reg = 0x2044, 450 .halt_check = BRANCH_HALT, 451 .clkr = { 452 .enable_reg = 0x2044, 453 .enable_mask = BIT(0), 454 .hw.init = &(struct clk_init_data){ 455 .name = "disp_cc_mdss_dp_link_intf_clk", 456 .parent_hws = (const struct clk_hw*[]){ 457 &disp_cc_mdss_dp_link_div_clk_src.clkr.hw, 458 }, 459 .num_parents = 1, 460 .ops = &clk_branch2_ops, 461 }, 462 }, 463 }; 464 465 static struct clk_branch disp_cc_mdss_dp_pixel_clk = { 466 .halt_reg = 0x204c, 467 .halt_check = BRANCH_HALT, 468 .clkr = { 469 .enable_reg = 0x204c, 470 .enable_mask = BIT(0), 471 .hw.init = &(struct clk_init_data){ 472 .name = "disp_cc_mdss_dp_pixel_clk", 473 .parent_hws = (const struct clk_hw*[]){ 474 &disp_cc_mdss_dp_pixel_clk_src.clkr.hw, 475 }, 476 .num_parents = 1, 477 .flags = CLK_SET_RATE_PARENT, 478 .ops = &clk_branch2_ops, 479 }, 480 }, 481 }; 482 483 static struct clk_branch disp_cc_mdss_esc0_clk = { 484 .halt_reg = 0x2038, 485 .halt_check = BRANCH_HALT, 486 .clkr = { 487 .enable_reg = 0x2038, 488 .enable_mask = BIT(0), 489 .hw.init = &(struct clk_init_data){ 490 .name = "disp_cc_mdss_esc0_clk", 491 .parent_hws = (const struct clk_hw*[]){ 492 &disp_cc_mdss_esc0_clk_src.clkr.hw, 493 }, 494 .num_parents = 1, 495 .flags = CLK_SET_RATE_PARENT, 496 .ops = &clk_branch2_ops, 497 }, 498 }, 499 }; 500 501 static struct clk_branch disp_cc_mdss_mdp_clk = { 502 .halt_reg = 0x200c, 503 .halt_check = BRANCH_HALT, 504 .clkr = { 505 .enable_reg = 0x200c, 506 .enable_mask = BIT(0), 507 .hw.init = &(struct clk_init_data){ 508 .name = "disp_cc_mdss_mdp_clk", 509 .parent_hws = (const struct clk_hw*[]){ 510 &disp_cc_mdss_mdp_clk_src.clkr.hw, 511 }, 512 .num_parents = 1, 513 .flags = CLK_SET_RATE_PARENT, 514 .ops = &clk_branch2_ops, 515 }, 516 }, 517 }; 518 519 static struct clk_branch disp_cc_mdss_mdp_lut_clk = { 520 .halt_reg = 0x201c, 521 .halt_check = BRANCH_VOTED, 522 .clkr = { 523 .enable_reg = 0x201c, 524 .enable_mask = BIT(0), 525 .hw.init = &(struct clk_init_data){ 526 .name = "disp_cc_mdss_mdp_lut_clk", 527 .parent_hws = (const struct clk_hw*[]){ 528 &disp_cc_mdss_mdp_clk_src.clkr.hw, 529 }, 530 .num_parents = 1, 531 .ops = &clk_branch2_ops, 532 }, 533 }, 534 }; 535 536 static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = { 537 .halt_reg = 0x4004, 538 .halt_check = BRANCH_VOTED, 539 .clkr = { 540 .enable_reg = 0x4004, 541 .enable_mask = BIT(0), 542 .hw.init = &(struct clk_init_data){ 543 .name = "disp_cc_mdss_non_gdsc_ahb_clk", 544 .parent_hws = (const struct clk_hw*[]){ 545 &disp_cc_mdss_ahb_clk_src.clkr.hw, 546 }, 547 .num_parents = 1, 548 .flags = CLK_SET_RATE_PARENT, 549 .ops = &clk_branch2_ops, 550 }, 551 }, 552 }; 553 554 static struct clk_branch disp_cc_mdss_pclk0_clk = { 555 .halt_reg = 0x2004, 556 .halt_check = BRANCH_HALT, 557 .clkr = { 558 .enable_reg = 0x2004, 559 .enable_mask = BIT(0), 560 .hw.init = &(struct clk_init_data){ 561 .name = "disp_cc_mdss_pclk0_clk", 562 .parent_hws = (const struct clk_hw*[]){ 563 &disp_cc_mdss_pclk0_clk_src.clkr.hw, 564 }, 565 .num_parents = 1, 566 .flags = CLK_SET_RATE_PARENT, 567 .ops = &clk_branch2_ops, 568 }, 569 }, 570 }; 571 572 static struct clk_branch disp_cc_mdss_rot_clk = { 573 .halt_reg = 0x2014, 574 .halt_check = BRANCH_HALT, 575 .clkr = { 576 .enable_reg = 0x2014, 577 .enable_mask = BIT(0), 578 .hw.init = &(struct clk_init_data){ 579 .name = "disp_cc_mdss_rot_clk", 580 .parent_hws = (const struct clk_hw*[]){ 581 &disp_cc_mdss_rot_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 disp_cc_mdss_rscc_vsync_clk = { 591 .halt_reg = 0x4008, 592 .halt_check = BRANCH_HALT, 593 .clkr = { 594 .enable_reg = 0x4008, 595 .enable_mask = BIT(0), 596 .hw.init = &(struct clk_init_data){ 597 .name = "disp_cc_mdss_rscc_vsync_clk", 598 .parent_hws = (const struct clk_hw*[]){ 599 &disp_cc_mdss_vsync_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 disp_cc_mdss_vsync_clk = { 609 .halt_reg = 0x2024, 610 .halt_check = BRANCH_HALT, 611 .clkr = { 612 .enable_reg = 0x2024, 613 .enable_mask = BIT(0), 614 .hw.init = &(struct clk_init_data){ 615 .name = "disp_cc_mdss_vsync_clk", 616 .parent_hws = (const struct clk_hw*[]){ 617 &disp_cc_mdss_vsync_clk_src.clkr.hw, 618 }, 619 .num_parents = 1, 620 .flags = CLK_SET_RATE_PARENT, 621 .ops = &clk_branch2_ops, 622 }, 623 }, 624 }; 625 626 static struct gdsc mdss_gdsc = { 627 .gdscr = 0x3000, 628 .en_rest_wait_val = 0x2, 629 .en_few_wait_val = 0x2, 630 .clk_dis_wait_val = 0xf, 631 .pd = { 632 .name = "mdss_gdsc", 633 }, 634 .pwrsts = PWRSTS_OFF_ON, 635 .flags = HW_CTRL, 636 }; 637 638 static struct gdsc *disp_cc_sc7180_gdscs[] = { 639 [MDSS_GDSC] = &mdss_gdsc, 640 }; 641 642 static struct clk_regmap *disp_cc_sc7180_clocks[] = { 643 [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, 644 [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr, 645 [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, 646 [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, 647 [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr, 648 [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, 649 [DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr, 650 [DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr, 651 [DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr, 652 [DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr, 653 [DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr, 654 [DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr, 655 [DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC] = 656 &disp_cc_mdss_dp_link_div_clk_src.clkr, 657 [DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr, 658 [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr, 659 [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr, 660 [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, 661 [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, 662 [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, 663 [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, 664 [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, 665 [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr, 666 [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, 667 [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, 668 [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, 669 [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, 670 [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, 671 [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, 672 [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, 673 [DISP_CC_PLL0] = &disp_cc_pll0.clkr, 674 [DISP_CC_PLL0_OUT_EVEN] = &disp_cc_pll0_out_even.clkr, 675 }; 676 677 static const struct regmap_config disp_cc_sc7180_regmap_config = { 678 .reg_bits = 32, 679 .reg_stride = 4, 680 .val_bits = 32, 681 .max_register = 0x10000, 682 .fast_io = true, 683 }; 684 685 static const struct qcom_cc_desc disp_cc_sc7180_desc = { 686 .config = &disp_cc_sc7180_regmap_config, 687 .clks = disp_cc_sc7180_clocks, 688 .num_clks = ARRAY_SIZE(disp_cc_sc7180_clocks), 689 .gdscs = disp_cc_sc7180_gdscs, 690 .num_gdscs = ARRAY_SIZE(disp_cc_sc7180_gdscs), 691 }; 692 693 static const struct of_device_id disp_cc_sc7180_match_table[] = { 694 { .compatible = "qcom,sc7180-dispcc" }, 695 { } 696 }; 697 MODULE_DEVICE_TABLE(of, disp_cc_sc7180_match_table); 698 699 static int disp_cc_sc7180_probe(struct platform_device *pdev) 700 { 701 struct regmap *regmap; 702 struct alpha_pll_config disp_cc_pll_config = {}; 703 704 regmap = qcom_cc_map(pdev, &disp_cc_sc7180_desc); 705 if (IS_ERR(regmap)) 706 return PTR_ERR(regmap); 707 708 /* 1380MHz configuration */ 709 disp_cc_pll_config.l = 0x47; 710 disp_cc_pll_config.alpha = 0xe000; 711 disp_cc_pll_config.user_ctl_val = 0x00000001; 712 disp_cc_pll_config.user_ctl_hi_val = 0x00004805; 713 714 clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll_config); 715 716 return qcom_cc_really_probe(pdev, &disp_cc_sc7180_desc, regmap); 717 } 718 719 static struct platform_driver disp_cc_sc7180_driver = { 720 .probe = disp_cc_sc7180_probe, 721 .driver = { 722 .name = "sc7180-dispcc", 723 .of_match_table = disp_cc_sc7180_match_table, 724 }, 725 }; 726 727 static int __init disp_cc_sc7180_init(void) 728 { 729 return platform_driver_register(&disp_cc_sc7180_driver); 730 } 731 subsys_initcall(disp_cc_sc7180_init); 732 733 static void __exit disp_cc_sc7180_exit(void) 734 { 735 platform_driver_unregister(&disp_cc_sc7180_driver); 736 } 737 module_exit(disp_cc_sc7180_exit); 738 739 MODULE_DESCRIPTION("QTI DISP_CC SC7180 Driver"); 740 MODULE_LICENSE("GPL v2"); 741