1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2018-2019, 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 P_DP_PHY_PLL_LINK_CLK, 33 P_DP_PHY_PLL_VCO_DIV_CLK, 34 }; 35 36 static const struct parent_map disp_cc_parent_map_0[] = { 37 { P_BI_TCXO, 0 }, 38 { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, 39 { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 }, 40 { P_CORE_BI_PLL_TEST_SE, 7 }, 41 }; 42 43 static const char * const disp_cc_parent_names_0[] = { 44 "bi_tcxo", 45 "dsi0_phy_pll_out_byteclk", 46 "dsi1_phy_pll_out_byteclk", 47 "core_bi_pll_test_se", 48 }; 49 50 static const struct parent_map disp_cc_parent_map_1[] = { 51 { P_BI_TCXO, 0 }, 52 { P_DP_PHY_PLL_LINK_CLK, 1 }, 53 { P_DP_PHY_PLL_VCO_DIV_CLK, 2 }, 54 { P_CORE_BI_PLL_TEST_SE, 7 }, 55 }; 56 57 static const char * const disp_cc_parent_names_1[] = { 58 "bi_tcxo", 59 "dp_link_clk_divsel_ten", 60 "dp_vco_divided_clk_src_mux", 61 "core_bi_pll_test_se", 62 }; 63 64 static const struct parent_map disp_cc_parent_map_2[] = { 65 { P_BI_TCXO, 0 }, 66 { P_CORE_BI_PLL_TEST_SE, 7 }, 67 }; 68 69 static const char * const disp_cc_parent_names_2[] = { 70 "bi_tcxo", 71 "core_bi_pll_test_se", 72 }; 73 74 static const struct parent_map disp_cc_parent_map_3[] = { 75 { P_BI_TCXO, 0 }, 76 { P_DISP_CC_PLL0_OUT_MAIN, 1 }, 77 { P_GPLL0_OUT_MAIN, 4 }, 78 { P_GPLL0_OUT_MAIN_DIV, 5 }, 79 { P_CORE_BI_PLL_TEST_SE, 7 }, 80 }; 81 82 static const char * const disp_cc_parent_names_3[] = { 83 "bi_tcxo", 84 "disp_cc_pll0", 85 "gcc_disp_gpll0_clk_src", 86 "gcc_disp_gpll0_div_clk_src", 87 "core_bi_pll_test_se", 88 }; 89 90 static const struct parent_map disp_cc_parent_map_4[] = { 91 { P_BI_TCXO, 0 }, 92 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, 93 { P_DSI1_PHY_PLL_OUT_DSICLK, 2 }, 94 { P_CORE_BI_PLL_TEST_SE, 7 }, 95 }; 96 97 static const char * const disp_cc_parent_names_4[] = { 98 "bi_tcxo", 99 "dsi0_phy_pll_out_dsiclk", 100 "dsi1_phy_pll_out_dsiclk", 101 "core_bi_pll_test_se", 102 }; 103 104 static struct clk_alpha_pll disp_cc_pll0 = { 105 .offset = 0x0, 106 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], 107 .clkr = { 108 .hw.init = &(struct clk_init_data){ 109 .name = "disp_cc_pll0", 110 .parent_names = (const char *[]){ "bi_tcxo" }, 111 .num_parents = 1, 112 .ops = &clk_alpha_pll_fabia_ops, 113 }, 114 }, 115 }; 116 117 /* Return the HW recalc rate for idle use case */ 118 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { 119 .cmd_rcgr = 0x20d0, 120 .mnd_width = 0, 121 .hid_width = 5, 122 .parent_map = disp_cc_parent_map_0, 123 .clkr.hw.init = &(struct clk_init_data){ 124 .name = "disp_cc_mdss_byte0_clk_src", 125 .parent_names = disp_cc_parent_names_0, 126 .num_parents = 4, 127 .flags = CLK_SET_RATE_PARENT, 128 .ops = &clk_byte2_ops, 129 }, 130 }; 131 132 /* Return the HW recalc rate for idle use case */ 133 static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = { 134 .cmd_rcgr = 0x20ec, 135 .mnd_width = 0, 136 .hid_width = 5, 137 .parent_map = disp_cc_parent_map_0, 138 .clkr.hw.init = &(struct clk_init_data){ 139 .name = "disp_cc_mdss_byte1_clk_src", 140 .parent_names = disp_cc_parent_names_0, 141 .num_parents = 4, 142 .flags = CLK_SET_RATE_PARENT, 143 .ops = &clk_byte2_ops, 144 }, 145 }; 146 147 static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = { 148 F(19200000, P_BI_TCXO, 1, 0, 0), 149 { } 150 }; 151 152 static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = { 153 .cmd_rcgr = 0x219c, 154 .mnd_width = 0, 155 .hid_width = 5, 156 .parent_map = disp_cc_parent_map_2, 157 .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, 158 .clkr.hw.init = &(struct clk_init_data){ 159 .name = "disp_cc_mdss_dp_aux_clk_src", 160 .parent_names = disp_cc_parent_names_2, 161 .num_parents = 2, 162 .flags = CLK_SET_RATE_PARENT, 163 .ops = &clk_rcg2_ops, 164 }, 165 }; 166 167 static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = { 168 .cmd_rcgr = 0x2154, 169 .mnd_width = 0, 170 .hid_width = 5, 171 .parent_map = disp_cc_parent_map_1, 172 .clkr.hw.init = &(struct clk_init_data){ 173 .name = "disp_cc_mdss_dp_crypto_clk_src", 174 .parent_names = disp_cc_parent_names_1, 175 .num_parents = 4, 176 .ops = &clk_byte2_ops, 177 }, 178 }; 179 180 static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = { 181 .cmd_rcgr = 0x2138, 182 .mnd_width = 0, 183 .hid_width = 5, 184 .parent_map = disp_cc_parent_map_1, 185 .clkr.hw.init = &(struct clk_init_data){ 186 .name = "disp_cc_mdss_dp_link_clk_src", 187 .parent_names = disp_cc_parent_names_1, 188 .num_parents = 4, 189 .flags = CLK_SET_RATE_PARENT, 190 .ops = &clk_byte2_ops, 191 }, 192 }; 193 194 static struct clk_rcg2 disp_cc_mdss_dp_pixel1_clk_src = { 195 .cmd_rcgr = 0x2184, 196 .mnd_width = 16, 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_pixel1_clk_src", 201 .parent_names = disp_cc_parent_names_1, 202 .num_parents = 4, 203 .flags = CLK_SET_RATE_PARENT, 204 .ops = &clk_dp_ops, 205 }, 206 }; 207 208 static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = { 209 .cmd_rcgr = 0x216c, 210 .mnd_width = 16, 211 .hid_width = 5, 212 .parent_map = disp_cc_parent_map_1, 213 .clkr.hw.init = &(struct clk_init_data){ 214 .name = "disp_cc_mdss_dp_pixel_clk_src", 215 .parent_names = disp_cc_parent_names_1, 216 .num_parents = 4, 217 .flags = CLK_SET_RATE_PARENT, 218 .ops = &clk_dp_ops, 219 }, 220 }; 221 222 static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = { 223 F(19200000, P_BI_TCXO, 1, 0, 0), 224 { } 225 }; 226 227 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { 228 .cmd_rcgr = 0x2108, 229 .mnd_width = 0, 230 .hid_width = 5, 231 .parent_map = disp_cc_parent_map_0, 232 .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, 233 .clkr.hw.init = &(struct clk_init_data){ 234 .name = "disp_cc_mdss_esc0_clk_src", 235 .parent_names = disp_cc_parent_names_0, 236 .num_parents = 4, 237 .ops = &clk_rcg2_ops, 238 }, 239 }; 240 241 static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = { 242 .cmd_rcgr = 0x2120, 243 .mnd_width = 0, 244 .hid_width = 5, 245 .parent_map = disp_cc_parent_map_0, 246 .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, 247 .clkr.hw.init = &(struct clk_init_data){ 248 .name = "disp_cc_mdss_esc1_clk_src", 249 .parent_names = disp_cc_parent_names_0, 250 .num_parents = 4, 251 .ops = &clk_rcg2_ops, 252 }, 253 }; 254 255 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { 256 F(19200000, P_BI_TCXO, 1, 0, 0), 257 F(85714286, P_GPLL0_OUT_MAIN, 7, 0, 0), 258 F(100000000, P_GPLL0_OUT_MAIN, 6, 0, 0), 259 F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0), 260 F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0), 261 F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), 262 F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), 263 F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), 264 F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0), 265 { } 266 }; 267 268 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { 269 .cmd_rcgr = 0x2088, 270 .mnd_width = 0, 271 .hid_width = 5, 272 .parent_map = disp_cc_parent_map_3, 273 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, 274 .clkr.hw.init = &(struct clk_init_data){ 275 .name = "disp_cc_mdss_mdp_clk_src", 276 .parent_names = disp_cc_parent_names_3, 277 .num_parents = 5, 278 .ops = &clk_rcg2_shared_ops, 279 }, 280 }; 281 282 /* Return the HW recalc rate for idle use case */ 283 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { 284 .cmd_rcgr = 0x2058, 285 .mnd_width = 8, 286 .hid_width = 5, 287 .parent_map = disp_cc_parent_map_4, 288 .clkr.hw.init = &(struct clk_init_data){ 289 .name = "disp_cc_mdss_pclk0_clk_src", 290 .parent_names = disp_cc_parent_names_4, 291 .num_parents = 4, 292 .flags = CLK_SET_RATE_PARENT, 293 .ops = &clk_pixel_ops, 294 }, 295 }; 296 297 /* Return the HW recalc rate for idle use case */ 298 static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = { 299 .cmd_rcgr = 0x2070, 300 .mnd_width = 8, 301 .hid_width = 5, 302 .parent_map = disp_cc_parent_map_4, 303 .clkr.hw.init = &(struct clk_init_data){ 304 .name = "disp_cc_mdss_pclk1_clk_src", 305 .parent_names = disp_cc_parent_names_4, 306 .num_parents = 4, 307 .flags = CLK_SET_RATE_PARENT, 308 .ops = &clk_pixel_ops, 309 }, 310 }; 311 312 static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = { 313 F(19200000, P_BI_TCXO, 1, 0, 0), 314 F(171428571, P_GPLL0_OUT_MAIN, 3.5, 0, 0), 315 F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), 316 F(344000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), 317 F(430000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0), 318 { } 319 }; 320 321 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = { 322 .cmd_rcgr = 0x20a0, 323 .mnd_width = 0, 324 .hid_width = 5, 325 .parent_map = disp_cc_parent_map_3, 326 .freq_tbl = ftbl_disp_cc_mdss_rot_clk_src, 327 .clkr.hw.init = &(struct clk_init_data){ 328 .name = "disp_cc_mdss_rot_clk_src", 329 .parent_names = disp_cc_parent_names_3, 330 .num_parents = 5, 331 .ops = &clk_rcg2_shared_ops, 332 }, 333 }; 334 335 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { 336 .cmd_rcgr = 0x20b8, 337 .mnd_width = 0, 338 .hid_width = 5, 339 .parent_map = disp_cc_parent_map_2, 340 .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, 341 .clkr.hw.init = &(struct clk_init_data){ 342 .name = "disp_cc_mdss_vsync_clk_src", 343 .parent_names = disp_cc_parent_names_2, 344 .num_parents = 2, 345 .ops = &clk_rcg2_ops, 346 }, 347 }; 348 349 static struct clk_branch disp_cc_mdss_ahb_clk = { 350 .halt_reg = 0x4004, 351 .halt_check = BRANCH_HALT, 352 .clkr = { 353 .enable_reg = 0x4004, 354 .enable_mask = BIT(0), 355 .hw.init = &(struct clk_init_data){ 356 .name = "disp_cc_mdss_ahb_clk", 357 .ops = &clk_branch2_ops, 358 }, 359 }, 360 }; 361 362 static struct clk_branch disp_cc_mdss_axi_clk = { 363 .halt_reg = 0x4008, 364 .halt_check = BRANCH_HALT, 365 .clkr = { 366 .enable_reg = 0x4008, 367 .enable_mask = BIT(0), 368 .hw.init = &(struct clk_init_data){ 369 .name = "disp_cc_mdss_axi_clk", 370 .ops = &clk_branch2_ops, 371 }, 372 }, 373 }; 374 375 /* Return the HW recalc rate for idle use case */ 376 static struct clk_branch disp_cc_mdss_byte0_clk = { 377 .halt_reg = 0x2028, 378 .halt_check = BRANCH_HALT, 379 .clkr = { 380 .enable_reg = 0x2028, 381 .enable_mask = BIT(0), 382 .hw.init = &(struct clk_init_data){ 383 .name = "disp_cc_mdss_byte0_clk", 384 .parent_names = (const char *[]){ 385 "disp_cc_mdss_byte0_clk_src", 386 }, 387 .num_parents = 1, 388 .flags = CLK_SET_RATE_PARENT, 389 .ops = &clk_branch2_ops, 390 }, 391 }, 392 }; 393 394 /* Return the HW recalc rate for idle use case */ 395 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { 396 .reg = 0x20e8, 397 .shift = 0, 398 .width = 2, 399 .clkr = { 400 .hw.init = &(struct clk_init_data){ 401 .name = "disp_cc_mdss_byte0_div_clk_src", 402 .parent_names = (const char *[]){ 403 "disp_cc_mdss_byte0_clk_src", 404 }, 405 .num_parents = 1, 406 .ops = &clk_regmap_div_ops, 407 }, 408 }, 409 }; 410 411 /* Return the HW recalc rate for idle use case */ 412 static struct clk_branch disp_cc_mdss_byte0_intf_clk = { 413 .halt_reg = 0x202c, 414 .halt_check = BRANCH_HALT, 415 .clkr = { 416 .enable_reg = 0x202c, 417 .enable_mask = BIT(0), 418 .hw.init = &(struct clk_init_data){ 419 .name = "disp_cc_mdss_byte0_intf_clk", 420 .parent_names = (const char *[]){ 421 "disp_cc_mdss_byte0_div_clk_src", 422 }, 423 .num_parents = 1, 424 .flags = CLK_SET_RATE_PARENT, 425 .ops = &clk_branch2_ops, 426 }, 427 }, 428 }; 429 430 /* Return the HW recalc rate for idle use case */ 431 static struct clk_branch disp_cc_mdss_byte1_clk = { 432 .halt_reg = 0x2030, 433 .halt_check = BRANCH_HALT, 434 .clkr = { 435 .enable_reg = 0x2030, 436 .enable_mask = BIT(0), 437 .hw.init = &(struct clk_init_data){ 438 .name = "disp_cc_mdss_byte1_clk", 439 .parent_names = (const char *[]){ 440 "disp_cc_mdss_byte1_clk_src", 441 }, 442 .num_parents = 1, 443 .flags = CLK_SET_RATE_PARENT, 444 .ops = &clk_branch2_ops, 445 }, 446 }, 447 }; 448 449 /* Return the HW recalc rate for idle use case */ 450 static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = { 451 .reg = 0x2104, 452 .shift = 0, 453 .width = 2, 454 .clkr = { 455 .hw.init = &(struct clk_init_data){ 456 .name = "disp_cc_mdss_byte1_div_clk_src", 457 .parent_names = (const char *[]){ 458 "disp_cc_mdss_byte1_clk_src", 459 }, 460 .num_parents = 1, 461 .ops = &clk_regmap_div_ops, 462 }, 463 }, 464 }; 465 466 /* Return the HW recalc rate for idle use case */ 467 static struct clk_branch disp_cc_mdss_byte1_intf_clk = { 468 .halt_reg = 0x2034, 469 .halt_check = BRANCH_HALT, 470 .clkr = { 471 .enable_reg = 0x2034, 472 .enable_mask = BIT(0), 473 .hw.init = &(struct clk_init_data){ 474 .name = "disp_cc_mdss_byte1_intf_clk", 475 .parent_names = (const char *[]){ 476 "disp_cc_mdss_byte1_div_clk_src", 477 }, 478 .num_parents = 1, 479 .flags = CLK_SET_RATE_PARENT, 480 .ops = &clk_branch2_ops, 481 }, 482 }, 483 }; 484 485 static struct clk_branch disp_cc_mdss_dp_aux_clk = { 486 .halt_reg = 0x2054, 487 .halt_check = BRANCH_HALT, 488 .clkr = { 489 .enable_reg = 0x2054, 490 .enable_mask = BIT(0), 491 .hw.init = &(struct clk_init_data){ 492 .name = "disp_cc_mdss_dp_aux_clk", 493 .parent_names = (const char *[]){ 494 "disp_cc_mdss_dp_aux_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_dp_crypto_clk = { 504 .halt_reg = 0x2048, 505 .halt_check = BRANCH_HALT, 506 .clkr = { 507 .enable_reg = 0x2048, 508 .enable_mask = BIT(0), 509 .hw.init = &(struct clk_init_data){ 510 .name = "disp_cc_mdss_dp_crypto_clk", 511 .parent_names = (const char *[]){ 512 "disp_cc_mdss_dp_crypto_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_dp_link_clk = { 522 .halt_reg = 0x2040, 523 .halt_check = BRANCH_HALT, 524 .clkr = { 525 .enable_reg = 0x2040, 526 .enable_mask = BIT(0), 527 .hw.init = &(struct clk_init_data){ 528 .name = "disp_cc_mdss_dp_link_clk", 529 .parent_names = (const char *[]){ 530 "disp_cc_mdss_dp_link_clk_src", 531 }, 532 .num_parents = 1, 533 .flags = CLK_SET_RATE_PARENT, 534 .ops = &clk_branch2_ops, 535 }, 536 }, 537 }; 538 539 /* reset state of disp_cc_mdss_dp_link_div_clk_src divider is 0x3 (div 4) */ 540 static struct clk_branch disp_cc_mdss_dp_link_intf_clk = { 541 .halt_reg = 0x2044, 542 .halt_check = BRANCH_HALT, 543 .clkr = { 544 .enable_reg = 0x2044, 545 .enable_mask = BIT(0), 546 .hw.init = &(struct clk_init_data){ 547 .name = "disp_cc_mdss_dp_link_intf_clk", 548 .parent_names = (const char *[]){ 549 "disp_cc_mdss_dp_link_clk_src", 550 }, 551 .num_parents = 1, 552 .ops = &clk_branch2_ops, 553 }, 554 }, 555 }; 556 557 static struct clk_branch disp_cc_mdss_dp_pixel1_clk = { 558 .halt_reg = 0x2050, 559 .halt_check = BRANCH_HALT, 560 .clkr = { 561 .enable_reg = 0x2050, 562 .enable_mask = BIT(0), 563 .hw.init = &(struct clk_init_data){ 564 .name = "disp_cc_mdss_dp_pixel1_clk", 565 .parent_names = (const char *[]){ 566 "disp_cc_mdss_dp_pixel1_clk_src", 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 disp_cc_mdss_dp_pixel_clk = { 576 .halt_reg = 0x204c, 577 .halt_check = BRANCH_HALT, 578 .clkr = { 579 .enable_reg = 0x204c, 580 .enable_mask = BIT(0), 581 .hw.init = &(struct clk_init_data){ 582 .name = "disp_cc_mdss_dp_pixel_clk", 583 .parent_names = (const char *[]){ 584 "disp_cc_mdss_dp_pixel_clk_src", 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 disp_cc_mdss_esc0_clk = { 594 .halt_reg = 0x2038, 595 .halt_check = BRANCH_HALT, 596 .clkr = { 597 .enable_reg = 0x2038, 598 .enable_mask = BIT(0), 599 .hw.init = &(struct clk_init_data){ 600 .name = "disp_cc_mdss_esc0_clk", 601 .parent_names = (const char *[]){ 602 "disp_cc_mdss_esc0_clk_src", 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 disp_cc_mdss_esc1_clk = { 612 .halt_reg = 0x203c, 613 .halt_check = BRANCH_HALT, 614 .clkr = { 615 .enable_reg = 0x203c, 616 .enable_mask = BIT(0), 617 .hw.init = &(struct clk_init_data){ 618 .name = "disp_cc_mdss_esc1_clk", 619 .parent_names = (const char *[]){ 620 "disp_cc_mdss_esc1_clk_src", 621 }, 622 .num_parents = 1, 623 .flags = CLK_SET_RATE_PARENT, 624 .ops = &clk_branch2_ops, 625 }, 626 }, 627 }; 628 629 static struct clk_branch disp_cc_mdss_mdp_clk = { 630 .halt_reg = 0x200c, 631 .halt_check = BRANCH_HALT, 632 .clkr = { 633 .enable_reg = 0x200c, 634 .enable_mask = BIT(0), 635 .hw.init = &(struct clk_init_data){ 636 .name = "disp_cc_mdss_mdp_clk", 637 .parent_names = (const char *[]){ 638 "disp_cc_mdss_mdp_clk_src", 639 }, 640 .num_parents = 1, 641 .flags = CLK_SET_RATE_PARENT, 642 .ops = &clk_branch2_ops, 643 }, 644 }, 645 }; 646 647 static struct clk_branch disp_cc_mdss_mdp_lut_clk = { 648 .halt_reg = 0x201c, 649 .halt_check = BRANCH_HALT, 650 .clkr = { 651 .enable_reg = 0x201c, 652 .enable_mask = BIT(0), 653 .hw.init = &(struct clk_init_data){ 654 .name = "disp_cc_mdss_mdp_lut_clk", 655 .parent_names = (const char *[]){ 656 "disp_cc_mdss_mdp_clk_src", 657 }, 658 .num_parents = 1, 659 .ops = &clk_branch2_ops, 660 }, 661 }, 662 }; 663 664 /* Return the HW recalc rate for idle use case */ 665 static struct clk_branch disp_cc_mdss_pclk0_clk = { 666 .halt_reg = 0x2004, 667 .halt_check = BRANCH_HALT, 668 .clkr = { 669 .enable_reg = 0x2004, 670 .enable_mask = BIT(0), 671 .hw.init = &(struct clk_init_data){ 672 .name = "disp_cc_mdss_pclk0_clk", 673 .parent_names = (const char *[]){ 674 "disp_cc_mdss_pclk0_clk_src", 675 }, 676 .num_parents = 1, 677 .flags = CLK_SET_RATE_PARENT, 678 .ops = &clk_branch2_ops, 679 }, 680 }, 681 }; 682 683 /* Return the HW recalc rate for idle use case */ 684 static struct clk_branch disp_cc_mdss_pclk1_clk = { 685 .halt_reg = 0x2008, 686 .halt_check = BRANCH_HALT, 687 .clkr = { 688 .enable_reg = 0x2008, 689 .enable_mask = BIT(0), 690 .hw.init = &(struct clk_init_data){ 691 .name = "disp_cc_mdss_pclk1_clk", 692 .parent_names = (const char *[]){ 693 "disp_cc_mdss_pclk1_clk_src", 694 }, 695 .num_parents = 1, 696 .flags = CLK_SET_RATE_PARENT, 697 .ops = &clk_branch2_ops, 698 }, 699 }, 700 }; 701 702 static struct clk_branch disp_cc_mdss_rot_clk = { 703 .halt_reg = 0x2014, 704 .halt_check = BRANCH_HALT, 705 .clkr = { 706 .enable_reg = 0x2014, 707 .enable_mask = BIT(0), 708 .hw.init = &(struct clk_init_data){ 709 .name = "disp_cc_mdss_rot_clk", 710 .parent_names = (const char *[]){ 711 "disp_cc_mdss_rot_clk_src", 712 }, 713 .num_parents = 1, 714 .flags = CLK_SET_RATE_PARENT, 715 .ops = &clk_branch2_ops, 716 }, 717 }, 718 }; 719 720 static struct clk_branch disp_cc_mdss_rscc_ahb_clk = { 721 .halt_reg = 0x5004, 722 .halt_check = BRANCH_HALT, 723 .clkr = { 724 .enable_reg = 0x5004, 725 .enable_mask = BIT(0), 726 .hw.init = &(struct clk_init_data){ 727 .name = "disp_cc_mdss_rscc_ahb_clk", 728 .ops = &clk_branch2_ops, 729 }, 730 }, 731 }; 732 733 static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { 734 .halt_reg = 0x5008, 735 .halt_check = BRANCH_HALT, 736 .clkr = { 737 .enable_reg = 0x5008, 738 .enable_mask = BIT(0), 739 .hw.init = &(struct clk_init_data){ 740 .name = "disp_cc_mdss_rscc_vsync_clk", 741 .parent_names = (const char *[]){ 742 "disp_cc_mdss_vsync_clk_src", 743 }, 744 .num_parents = 1, 745 .flags = CLK_SET_RATE_PARENT, 746 .ops = &clk_branch2_ops, 747 }, 748 }, 749 }; 750 751 static struct clk_branch disp_cc_mdss_vsync_clk = { 752 .halt_reg = 0x2024, 753 .halt_check = BRANCH_HALT, 754 .clkr = { 755 .enable_reg = 0x2024, 756 .enable_mask = BIT(0), 757 .hw.init = &(struct clk_init_data){ 758 .name = "disp_cc_mdss_vsync_clk", 759 .parent_names = (const char *[]){ 760 "disp_cc_mdss_vsync_clk_src", 761 }, 762 .num_parents = 1, 763 .flags = CLK_SET_RATE_PARENT, 764 .ops = &clk_branch2_ops, 765 }, 766 }, 767 }; 768 769 static struct gdsc mdss_gdsc = { 770 .gdscr = 0x3000, 771 .pd = { 772 .name = "mdss_gdsc", 773 }, 774 .pwrsts = PWRSTS_OFF_ON, 775 .flags = HW_CTRL | POLL_CFG_GDSCR, 776 }; 777 778 static struct clk_regmap *disp_cc_sdm845_clocks[] = { 779 [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, 780 [DISP_CC_MDSS_AXI_CLK] = &disp_cc_mdss_axi_clk.clkr, 781 [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, 782 [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, 783 [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, 784 [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = 785 &disp_cc_mdss_byte0_div_clk_src.clkr, 786 [DISP_CC_MDSS_BYTE1_CLK] = &disp_cc_mdss_byte1_clk.clkr, 787 [DISP_CC_MDSS_BYTE1_CLK_SRC] = &disp_cc_mdss_byte1_clk_src.clkr, 788 [DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr, 789 [DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = 790 &disp_cc_mdss_byte1_div_clk_src.clkr, 791 [DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr, 792 [DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr, 793 [DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr, 794 [DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = 795 &disp_cc_mdss_dp_crypto_clk_src.clkr, 796 [DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr, 797 [DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr, 798 [DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr, 799 [DISP_CC_MDSS_DP_PIXEL1_CLK] = &disp_cc_mdss_dp_pixel1_clk.clkr, 800 [DISP_CC_MDSS_DP_PIXEL1_CLK_SRC] = 801 &disp_cc_mdss_dp_pixel1_clk_src.clkr, 802 [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr, 803 [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr, 804 [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, 805 [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, 806 [DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr, 807 [DISP_CC_MDSS_ESC1_CLK_SRC] = &disp_cc_mdss_esc1_clk_src.clkr, 808 [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, 809 [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, 810 [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, 811 [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, 812 [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, 813 [DISP_CC_MDSS_PCLK1_CLK] = &disp_cc_mdss_pclk1_clk.clkr, 814 [DISP_CC_MDSS_PCLK1_CLK_SRC] = &disp_cc_mdss_pclk1_clk_src.clkr, 815 [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, 816 [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, 817 [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr, 818 [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, 819 [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, 820 [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, 821 [DISP_CC_PLL0] = &disp_cc_pll0.clkr, 822 }; 823 824 static const struct qcom_reset_map disp_cc_sdm845_resets[] = { 825 [DISP_CC_MDSS_RSCC_BCR] = { 0x5000 }, 826 }; 827 828 static struct gdsc *disp_cc_sdm845_gdscs[] = { 829 [MDSS_GDSC] = &mdss_gdsc, 830 }; 831 832 static const struct regmap_config disp_cc_sdm845_regmap_config = { 833 .reg_bits = 32, 834 .reg_stride = 4, 835 .val_bits = 32, 836 .max_register = 0x10000, 837 .fast_io = true, 838 }; 839 840 static const struct qcom_cc_desc disp_cc_sdm845_desc = { 841 .config = &disp_cc_sdm845_regmap_config, 842 .clks = disp_cc_sdm845_clocks, 843 .num_clks = ARRAY_SIZE(disp_cc_sdm845_clocks), 844 .resets = disp_cc_sdm845_resets, 845 .num_resets = ARRAY_SIZE(disp_cc_sdm845_resets), 846 .gdscs = disp_cc_sdm845_gdscs, 847 .num_gdscs = ARRAY_SIZE(disp_cc_sdm845_gdscs), 848 }; 849 850 static const struct of_device_id disp_cc_sdm845_match_table[] = { 851 { .compatible = "qcom,sdm845-dispcc" }, 852 { } 853 }; 854 MODULE_DEVICE_TABLE(of, disp_cc_sdm845_match_table); 855 856 static int disp_cc_sdm845_probe(struct platform_device *pdev) 857 { 858 struct regmap *regmap; 859 struct alpha_pll_config disp_cc_pll0_config = {}; 860 861 regmap = qcom_cc_map(pdev, &disp_cc_sdm845_desc); 862 if (IS_ERR(regmap)) 863 return PTR_ERR(regmap); 864 865 disp_cc_pll0_config.l = 0x2c; 866 disp_cc_pll0_config.alpha = 0xcaaa; 867 868 clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); 869 870 /* Enable hardware clock gating for DSI and MDP clocks */ 871 regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0); 872 873 return qcom_cc_really_probe(pdev, &disp_cc_sdm845_desc, regmap); 874 } 875 876 static struct platform_driver disp_cc_sdm845_driver = { 877 .probe = disp_cc_sdm845_probe, 878 .driver = { 879 .name = "disp_cc-sdm845", 880 .of_match_table = disp_cc_sdm845_match_table, 881 }, 882 }; 883 884 static int __init disp_cc_sdm845_init(void) 885 { 886 return platform_driver_register(&disp_cc_sdm845_driver); 887 } 888 subsys_initcall(disp_cc_sdm845_init); 889 890 static void __exit disp_cc_sdm845_exit(void) 891 { 892 platform_driver_unregister(&disp_cc_sdm845_driver); 893 } 894 module_exit(disp_cc_sdm845_exit); 895 896 MODULE_LICENSE("GPL v2"); 897 MODULE_DESCRIPTION("QTI DISPCC SDM845 Driver"); 898