1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2018, 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 #include <linux/reset-controller.h> 11 12 #include <dt-bindings/clock/qcom,dispcc-sdm845.h> 13 14 #include "clk-alpha-pll.h" 15 #include "clk-branch.h" 16 #include "clk-rcg.h" 17 #include "clk-regmap-divider.h" 18 #include "common.h" 19 #include "gdsc.h" 20 #include "reset.h" 21 22 enum { 23 P_BI_TCXO, 24 P_CORE_BI_PLL_TEST_SE, 25 P_DISP_CC_PLL0_OUT_MAIN, 26 P_DSI0_PHY_PLL_OUT_BYTECLK, 27 P_DSI0_PHY_PLL_OUT_DSICLK, 28 P_DSI1_PHY_PLL_OUT_BYTECLK, 29 P_DSI1_PHY_PLL_OUT_DSICLK, 30 P_GPLL0_OUT_MAIN, 31 P_GPLL0_OUT_MAIN_DIV, 32 }; 33 34 static const struct parent_map disp_cc_parent_map_0[] = { 35 { P_BI_TCXO, 0 }, 36 { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, 37 { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 }, 38 { P_CORE_BI_PLL_TEST_SE, 7 }, 39 }; 40 41 static const char * const disp_cc_parent_names_0[] = { 42 "bi_tcxo", 43 "dsi0_phy_pll_out_byteclk", 44 "dsi1_phy_pll_out_byteclk", 45 "core_bi_pll_test_se", 46 }; 47 48 static const struct parent_map disp_cc_parent_map_2[] = { 49 { P_BI_TCXO, 0 }, 50 { P_CORE_BI_PLL_TEST_SE, 7 }, 51 }; 52 53 static const char * const disp_cc_parent_names_2[] = { 54 "bi_tcxo", 55 "core_bi_pll_test_se", 56 }; 57 58 static const struct parent_map disp_cc_parent_map_3[] = { 59 { P_BI_TCXO, 0 }, 60 { P_DISP_CC_PLL0_OUT_MAIN, 1 }, 61 { P_GPLL0_OUT_MAIN, 4 }, 62 { P_GPLL0_OUT_MAIN_DIV, 5 }, 63 { P_CORE_BI_PLL_TEST_SE, 7 }, 64 }; 65 66 static const char * const disp_cc_parent_names_3[] = { 67 "bi_tcxo", 68 "disp_cc_pll0", 69 "gcc_disp_gpll0_clk_src", 70 "gcc_disp_gpll0_div_clk_src", 71 "core_bi_pll_test_se", 72 }; 73 74 static const struct parent_map disp_cc_parent_map_4[] = { 75 { P_BI_TCXO, 0 }, 76 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, 77 { P_DSI1_PHY_PLL_OUT_DSICLK, 2 }, 78 { P_CORE_BI_PLL_TEST_SE, 7 }, 79 }; 80 81 static const char * const disp_cc_parent_names_4[] = { 82 "bi_tcxo", 83 "dsi0_phy_pll_out_dsiclk", 84 "dsi1_phy_pll_out_dsiclk", 85 "core_bi_pll_test_se", 86 }; 87 88 static struct clk_alpha_pll disp_cc_pll0 = { 89 .offset = 0x0, 90 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], 91 .clkr = { 92 .hw.init = &(struct clk_init_data){ 93 .name = "disp_cc_pll0", 94 .parent_names = (const char *[]){ "bi_tcxo" }, 95 .num_parents = 1, 96 .ops = &clk_alpha_pll_fabia_ops, 97 }, 98 }, 99 }; 100 101 /* Return the HW recalc rate for idle use case */ 102 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { 103 .cmd_rcgr = 0x20d0, 104 .mnd_width = 0, 105 .hid_width = 5, 106 .parent_map = disp_cc_parent_map_0, 107 .clkr.hw.init = &(struct clk_init_data){ 108 .name = "disp_cc_mdss_byte0_clk_src", 109 .parent_names = disp_cc_parent_names_0, 110 .num_parents = 4, 111 .flags = CLK_SET_RATE_PARENT, 112 .ops = &clk_byte2_ops, 113 }, 114 }; 115 116 /* Return the HW recalc rate for idle use case */ 117 static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = { 118 .cmd_rcgr = 0x20ec, 119 .mnd_width = 0, 120 .hid_width = 5, 121 .parent_map = disp_cc_parent_map_0, 122 .clkr.hw.init = &(struct clk_init_data){ 123 .name = "disp_cc_mdss_byte1_clk_src", 124 .parent_names = disp_cc_parent_names_0, 125 .num_parents = 4, 126 .flags = CLK_SET_RATE_PARENT, 127 .ops = &clk_byte2_ops, 128 }, 129 }; 130 131 static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = { 132 F(19200000, P_BI_TCXO, 1, 0, 0), 133 { } 134 }; 135 136 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { 137 .cmd_rcgr = 0x2108, 138 .mnd_width = 0, 139 .hid_width = 5, 140 .parent_map = disp_cc_parent_map_0, 141 .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, 142 .clkr.hw.init = &(struct clk_init_data){ 143 .name = "disp_cc_mdss_esc0_clk_src", 144 .parent_names = disp_cc_parent_names_0, 145 .num_parents = 4, 146 .ops = &clk_rcg2_ops, 147 }, 148 }; 149 150 static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = { 151 .cmd_rcgr = 0x2120, 152 .mnd_width = 0, 153 .hid_width = 5, 154 .parent_map = disp_cc_parent_map_0, 155 .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, 156 .clkr.hw.init = &(struct clk_init_data){ 157 .name = "disp_cc_mdss_esc1_clk_src", 158 .parent_names = disp_cc_parent_names_0, 159 .num_parents = 4, 160 .ops = &clk_rcg2_ops, 161 }, 162 }; 163 164 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { 165 F(19200000, P_BI_TCXO, 1, 0, 0), 166 F(85714286, P_GPLL0_OUT_MAIN, 7, 0, 0), 167 F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), 168 F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), 169 F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0), 170 F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), 171 F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), 172 F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), 173 F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0), 174 { } 175 }; 176 177 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { 178 .cmd_rcgr = 0x2088, 179 .mnd_width = 0, 180 .hid_width = 5, 181 .parent_map = disp_cc_parent_map_3, 182 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, 183 .clkr.hw.init = &(struct clk_init_data){ 184 .name = "disp_cc_mdss_mdp_clk_src", 185 .parent_names = disp_cc_parent_names_3, 186 .num_parents = 5, 187 .ops = &clk_rcg2_shared_ops, 188 }, 189 }; 190 191 /* Return the HW recalc rate for idle use case */ 192 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { 193 .cmd_rcgr = 0x2058, 194 .mnd_width = 8, 195 .hid_width = 5, 196 .parent_map = disp_cc_parent_map_4, 197 .clkr.hw.init = &(struct clk_init_data){ 198 .name = "disp_cc_mdss_pclk0_clk_src", 199 .parent_names = disp_cc_parent_names_4, 200 .num_parents = 4, 201 .flags = CLK_SET_RATE_PARENT, 202 .ops = &clk_pixel_ops, 203 }, 204 }; 205 206 /* Return the HW recalc rate for idle use case */ 207 static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = { 208 .cmd_rcgr = 0x2070, 209 .mnd_width = 8, 210 .hid_width = 5, 211 .parent_map = disp_cc_parent_map_4, 212 .clkr.hw.init = &(struct clk_init_data){ 213 .name = "disp_cc_mdss_pclk1_clk_src", 214 .parent_names = disp_cc_parent_names_4, 215 .num_parents = 4, 216 .flags = CLK_SET_RATE_PARENT, 217 .ops = &clk_pixel_ops, 218 }, 219 }; 220 221 static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = { 222 F(19200000, P_BI_TCXO, 1, 0, 0), 223 F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0), 224 F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), 225 F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), 226 F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0), 227 { } 228 }; 229 230 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = { 231 .cmd_rcgr = 0x20a0, 232 .mnd_width = 0, 233 .hid_width = 5, 234 .parent_map = disp_cc_parent_map_3, 235 .freq_tbl = ftbl_disp_cc_mdss_rot_clk_src, 236 .clkr.hw.init = &(struct clk_init_data){ 237 .name = "disp_cc_mdss_rot_clk_src", 238 .parent_names = disp_cc_parent_names_3, 239 .num_parents = 5, 240 .ops = &clk_rcg2_shared_ops, 241 }, 242 }; 243 244 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { 245 .cmd_rcgr = 0x20b8, 246 .mnd_width = 0, 247 .hid_width = 5, 248 .parent_map = disp_cc_parent_map_2, 249 .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, 250 .clkr.hw.init = &(struct clk_init_data){ 251 .name = "disp_cc_mdss_vsync_clk_src", 252 .parent_names = disp_cc_parent_names_2, 253 .num_parents = 2, 254 .ops = &clk_rcg2_ops, 255 }, 256 }; 257 258 static struct clk_branch disp_cc_mdss_ahb_clk = { 259 .halt_reg = 0x4004, 260 .halt_check = BRANCH_HALT, 261 .clkr = { 262 .enable_reg = 0x4004, 263 .enable_mask = BIT(0), 264 .hw.init = &(struct clk_init_data){ 265 .name = "disp_cc_mdss_ahb_clk", 266 .ops = &clk_branch2_ops, 267 }, 268 }, 269 }; 270 271 static struct clk_branch disp_cc_mdss_axi_clk = { 272 .halt_reg = 0x4008, 273 .halt_check = BRANCH_HALT, 274 .clkr = { 275 .enable_reg = 0x4008, 276 .enable_mask = BIT(0), 277 .hw.init = &(struct clk_init_data){ 278 .name = "disp_cc_mdss_axi_clk", 279 .ops = &clk_branch2_ops, 280 }, 281 }, 282 }; 283 284 /* Return the HW recalc rate for idle use case */ 285 static struct clk_branch disp_cc_mdss_byte0_clk = { 286 .halt_reg = 0x2028, 287 .halt_check = BRANCH_HALT, 288 .clkr = { 289 .enable_reg = 0x2028, 290 .enable_mask = BIT(0), 291 .hw.init = &(struct clk_init_data){ 292 .name = "disp_cc_mdss_byte0_clk", 293 .parent_names = (const char *[]){ 294 "disp_cc_mdss_byte0_clk_src", 295 }, 296 .num_parents = 1, 297 .flags = CLK_SET_RATE_PARENT, 298 .ops = &clk_branch2_ops, 299 }, 300 }, 301 }; 302 303 /* Return the HW recalc rate for idle use case */ 304 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { 305 .reg = 0x20e8, 306 .shift = 0, 307 .width = 2, 308 .clkr = { 309 .hw.init = &(struct clk_init_data){ 310 .name = "disp_cc_mdss_byte0_div_clk_src", 311 .parent_names = (const char *[]){ 312 "disp_cc_mdss_byte0_clk_src", 313 }, 314 .num_parents = 1, 315 .ops = &clk_regmap_div_ops, 316 }, 317 }, 318 }; 319 320 /* Return the HW recalc rate for idle use case */ 321 static struct clk_branch disp_cc_mdss_byte0_intf_clk = { 322 .halt_reg = 0x202c, 323 .halt_check = BRANCH_HALT, 324 .clkr = { 325 .enable_reg = 0x202c, 326 .enable_mask = BIT(0), 327 .hw.init = &(struct clk_init_data){ 328 .name = "disp_cc_mdss_byte0_intf_clk", 329 .parent_names = (const char *[]){ 330 "disp_cc_mdss_byte0_div_clk_src", 331 }, 332 .num_parents = 1, 333 .flags = CLK_SET_RATE_PARENT, 334 .ops = &clk_branch2_ops, 335 }, 336 }, 337 }; 338 339 /* Return the HW recalc rate for idle use case */ 340 static struct clk_branch disp_cc_mdss_byte1_clk = { 341 .halt_reg = 0x2030, 342 .halt_check = BRANCH_HALT, 343 .clkr = { 344 .enable_reg = 0x2030, 345 .enable_mask = BIT(0), 346 .hw.init = &(struct clk_init_data){ 347 .name = "disp_cc_mdss_byte1_clk", 348 .parent_names = (const char *[]){ 349 "disp_cc_mdss_byte1_clk_src", 350 }, 351 .num_parents = 1, 352 .flags = CLK_SET_RATE_PARENT, 353 .ops = &clk_branch2_ops, 354 }, 355 }, 356 }; 357 358 /* Return the HW recalc rate for idle use case */ 359 static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = { 360 .reg = 0x2104, 361 .shift = 0, 362 .width = 2, 363 .clkr = { 364 .hw.init = &(struct clk_init_data){ 365 .name = "disp_cc_mdss_byte1_div_clk_src", 366 .parent_names = (const char *[]){ 367 "disp_cc_mdss_byte1_clk_src", 368 }, 369 .num_parents = 1, 370 .ops = &clk_regmap_div_ops, 371 }, 372 }, 373 }; 374 375 /* Return the HW recalc rate for idle use case */ 376 static struct clk_branch disp_cc_mdss_byte1_intf_clk = { 377 .halt_reg = 0x2034, 378 .halt_check = BRANCH_HALT, 379 .clkr = { 380 .enable_reg = 0x2034, 381 .enable_mask = BIT(0), 382 .hw.init = &(struct clk_init_data){ 383 .name = "disp_cc_mdss_byte1_intf_clk", 384 .parent_names = (const char *[]){ 385 "disp_cc_mdss_byte1_div_clk_src", 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_esc0_clk = { 395 .halt_reg = 0x2038, 396 .halt_check = BRANCH_HALT, 397 .clkr = { 398 .enable_reg = 0x2038, 399 .enable_mask = BIT(0), 400 .hw.init = &(struct clk_init_data){ 401 .name = "disp_cc_mdss_esc0_clk", 402 .parent_names = (const char *[]){ 403 "disp_cc_mdss_esc0_clk_src", 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_esc1_clk = { 413 .halt_reg = 0x203c, 414 .halt_check = BRANCH_HALT, 415 .clkr = { 416 .enable_reg = 0x203c, 417 .enable_mask = BIT(0), 418 .hw.init = &(struct clk_init_data){ 419 .name = "disp_cc_mdss_esc1_clk", 420 .parent_names = (const char *[]){ 421 "disp_cc_mdss_esc1_clk_src", 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_mdp_clk = { 431 .halt_reg = 0x200c, 432 .halt_check = BRANCH_HALT, 433 .clkr = { 434 .enable_reg = 0x200c, 435 .enable_mask = BIT(0), 436 .hw.init = &(struct clk_init_data){ 437 .name = "disp_cc_mdss_mdp_clk", 438 .parent_names = (const char *[]){ 439 "disp_cc_mdss_mdp_clk_src", 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_mdp_lut_clk = { 449 .halt_reg = 0x201c, 450 .halt_check = BRANCH_HALT, 451 .clkr = { 452 .enable_reg = 0x201c, 453 .enable_mask = BIT(0), 454 .hw.init = &(struct clk_init_data){ 455 .name = "disp_cc_mdss_mdp_lut_clk", 456 .parent_names = (const char *[]){ 457 "disp_cc_mdss_mdp_clk_src", 458 }, 459 .num_parents = 1, 460 .ops = &clk_branch2_ops, 461 }, 462 }, 463 }; 464 465 /* Return the HW recalc rate for idle use case */ 466 static struct clk_branch disp_cc_mdss_pclk0_clk = { 467 .halt_reg = 0x2004, 468 .halt_check = BRANCH_HALT, 469 .clkr = { 470 .enable_reg = 0x2004, 471 .enable_mask = BIT(0), 472 .hw.init = &(struct clk_init_data){ 473 .name = "disp_cc_mdss_pclk0_clk", 474 .parent_names = (const char *[]){ 475 "disp_cc_mdss_pclk0_clk_src", 476 }, 477 .num_parents = 1, 478 .flags = CLK_SET_RATE_PARENT, 479 .ops = &clk_branch2_ops, 480 }, 481 }, 482 }; 483 484 /* Return the HW recalc rate for idle use case */ 485 static struct clk_branch disp_cc_mdss_pclk1_clk = { 486 .halt_reg = 0x2008, 487 .halt_check = BRANCH_HALT, 488 .clkr = { 489 .enable_reg = 0x2008, 490 .enable_mask = BIT(0), 491 .hw.init = &(struct clk_init_data){ 492 .name = "disp_cc_mdss_pclk1_clk", 493 .parent_names = (const char *[]){ 494 "disp_cc_mdss_pclk1_clk_src", 495 }, 496 .num_parents = 1, 497 .flags = CLK_SET_RATE_PARENT, 498 .ops = &clk_branch2_ops, 499 }, 500 }, 501 }; 502 503 static struct clk_branch disp_cc_mdss_rot_clk = { 504 .halt_reg = 0x2014, 505 .halt_check = BRANCH_HALT, 506 .clkr = { 507 .enable_reg = 0x2014, 508 .enable_mask = BIT(0), 509 .hw.init = &(struct clk_init_data){ 510 .name = "disp_cc_mdss_rot_clk", 511 .parent_names = (const char *[]){ 512 "disp_cc_mdss_rot_clk_src", 513 }, 514 .num_parents = 1, 515 .flags = CLK_SET_RATE_PARENT, 516 .ops = &clk_branch2_ops, 517 }, 518 }, 519 }; 520 521 static struct clk_branch disp_cc_mdss_rscc_ahb_clk = { 522 .halt_reg = 0x5004, 523 .halt_check = BRANCH_HALT, 524 .clkr = { 525 .enable_reg = 0x5004, 526 .enable_mask = BIT(0), 527 .hw.init = &(struct clk_init_data){ 528 .name = "disp_cc_mdss_rscc_ahb_clk", 529 .ops = &clk_branch2_ops, 530 }, 531 }, 532 }; 533 534 static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { 535 .halt_reg = 0x5008, 536 .halt_check = BRANCH_HALT, 537 .clkr = { 538 .enable_reg = 0x5008, 539 .enable_mask = BIT(0), 540 .hw.init = &(struct clk_init_data){ 541 .name = "disp_cc_mdss_rscc_vsync_clk", 542 .parent_names = (const char *[]){ 543 "disp_cc_mdss_vsync_clk_src", 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 disp_cc_mdss_vsync_clk = { 553 .halt_reg = 0x2024, 554 .halt_check = BRANCH_HALT, 555 .clkr = { 556 .enable_reg = 0x2024, 557 .enable_mask = BIT(0), 558 .hw.init = &(struct clk_init_data){ 559 .name = "disp_cc_mdss_vsync_clk", 560 .parent_names = (const char *[]){ 561 "disp_cc_mdss_vsync_clk_src", 562 }, 563 .num_parents = 1, 564 .flags = CLK_SET_RATE_PARENT, 565 .ops = &clk_branch2_ops, 566 }, 567 }, 568 }; 569 570 static struct gdsc mdss_gdsc = { 571 .gdscr = 0x3000, 572 .pd = { 573 .name = "mdss_gdsc", 574 }, 575 .pwrsts = PWRSTS_OFF_ON, 576 .flags = HW_CTRL | POLL_CFG_GDSCR, 577 }; 578 579 static struct clk_regmap *disp_cc_sdm845_clocks[] = { 580 [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, 581 [DISP_CC_MDSS_AXI_CLK] = &disp_cc_mdss_axi_clk.clkr, 582 [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, 583 [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, 584 [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, 585 [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = 586 &disp_cc_mdss_byte0_div_clk_src.clkr, 587 [DISP_CC_MDSS_BYTE1_CLK] = &disp_cc_mdss_byte1_clk.clkr, 588 [DISP_CC_MDSS_BYTE1_CLK_SRC] = &disp_cc_mdss_byte1_clk_src.clkr, 589 [DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr, 590 [DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = 591 &disp_cc_mdss_byte1_div_clk_src.clkr, 592 [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, 593 [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, 594 [DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr, 595 [DISP_CC_MDSS_ESC1_CLK_SRC] = &disp_cc_mdss_esc1_clk_src.clkr, 596 [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, 597 [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, 598 [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, 599 [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, 600 [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, 601 [DISP_CC_MDSS_PCLK1_CLK] = &disp_cc_mdss_pclk1_clk.clkr, 602 [DISP_CC_MDSS_PCLK1_CLK_SRC] = &disp_cc_mdss_pclk1_clk_src.clkr, 603 [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, 604 [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, 605 [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr, 606 [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, 607 [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, 608 [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, 609 [DISP_CC_PLL0] = &disp_cc_pll0.clkr, 610 }; 611 612 static const struct qcom_reset_map disp_cc_sdm845_resets[] = { 613 [DISP_CC_MDSS_RSCC_BCR] = { 0x5000 }, 614 }; 615 616 static struct gdsc *disp_cc_sdm845_gdscs[] = { 617 [MDSS_GDSC] = &mdss_gdsc, 618 }; 619 620 static const struct regmap_config disp_cc_sdm845_regmap_config = { 621 .reg_bits = 32, 622 .reg_stride = 4, 623 .val_bits = 32, 624 .max_register = 0x10000, 625 .fast_io = true, 626 }; 627 628 static const struct qcom_cc_desc disp_cc_sdm845_desc = { 629 .config = &disp_cc_sdm845_regmap_config, 630 .clks = disp_cc_sdm845_clocks, 631 .num_clks = ARRAY_SIZE(disp_cc_sdm845_clocks), 632 .resets = disp_cc_sdm845_resets, 633 .num_resets = ARRAY_SIZE(disp_cc_sdm845_resets), 634 .gdscs = disp_cc_sdm845_gdscs, 635 .num_gdscs = ARRAY_SIZE(disp_cc_sdm845_gdscs), 636 }; 637 638 static const struct of_device_id disp_cc_sdm845_match_table[] = { 639 { .compatible = "qcom,sdm845-dispcc" }, 640 { } 641 }; 642 MODULE_DEVICE_TABLE(of, disp_cc_sdm845_match_table); 643 644 static int disp_cc_sdm845_probe(struct platform_device *pdev) 645 { 646 struct regmap *regmap; 647 struct alpha_pll_config disp_cc_pll0_config = {}; 648 649 regmap = qcom_cc_map(pdev, &disp_cc_sdm845_desc); 650 if (IS_ERR(regmap)) 651 return PTR_ERR(regmap); 652 653 disp_cc_pll0_config.l = 0x2c; 654 disp_cc_pll0_config.alpha = 0xcaaa; 655 656 clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); 657 658 /* Enable hardware clock gating for DSI and MDP clocks */ 659 regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0); 660 661 return qcom_cc_really_probe(pdev, &disp_cc_sdm845_desc, regmap); 662 } 663 664 static struct platform_driver disp_cc_sdm845_driver = { 665 .probe = disp_cc_sdm845_probe, 666 .driver = { 667 .name = "disp_cc-sdm845", 668 .of_match_table = disp_cc_sdm845_match_table, 669 }, 670 }; 671 672 static int __init disp_cc_sdm845_init(void) 673 { 674 return platform_driver_register(&disp_cc_sdm845_driver); 675 } 676 subsys_initcall(disp_cc_sdm845_init); 677 678 static void __exit disp_cc_sdm845_exit(void) 679 { 680 platform_driver_unregister(&disp_cc_sdm845_driver); 681 } 682 module_exit(disp_cc_sdm845_exit); 683 684 MODULE_LICENSE("GPL v2"); 685 MODULE_DESCRIPTION("QTI DISPCC SDM845 Driver"); 686