1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2021, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org> 5 */ 6 7 #include <linux/clk-provider.h> 8 #include <linux/module.h> 9 #include <linux/platform_device.h> 10 #include <linux/regmap.h> 11 12 #include <dt-bindings/clock/qcom,dispcc-sm6350.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 enum { 24 P_BI_TCXO, 25 P_DISP_CC_PLL0_OUT_EVEN, 26 P_DISP_CC_PLL0_OUT_MAIN, 27 P_DP_PHY_PLL_LINK_CLK, 28 P_DP_PHY_PLL_VCO_DIV_CLK, 29 P_DSI0_PHY_PLL_OUT_BYTECLK, 30 P_DSI0_PHY_PLL_OUT_DSICLK, 31 P_GCC_DISP_GPLL0_CLK, 32 }; 33 34 static struct pll_vco fabia_vco[] = { 35 { 249600000, 2000000000, 0 }, 36 }; 37 38 static const struct alpha_pll_config disp_cc_pll0_config = { 39 .l = 0x3a, 40 .alpha = 0x5555, 41 .config_ctl_val = 0x20485699, 42 .config_ctl_hi_val = 0x00002067, 43 .test_ctl_val = 0x40000000, 44 .test_ctl_hi_val = 0x00000002, 45 .user_ctl_val = 0x00000000, 46 .user_ctl_hi_val = 0x00004805, 47 }; 48 49 static struct clk_alpha_pll disp_cc_pll0 = { 50 .offset = 0x0, 51 .vco_table = fabia_vco, 52 .num_vco = ARRAY_SIZE(fabia_vco), 53 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], 54 .clkr = { 55 .hw.init = &(struct clk_init_data){ 56 .name = "disp_cc_pll0", 57 .parent_data = &(const struct clk_parent_data){ 58 .fw_name = "bi_tcxo", 59 }, 60 .num_parents = 1, 61 .ops = &clk_alpha_pll_fabia_ops, 62 }, 63 }, 64 }; 65 66 static const struct parent_map disp_cc_parent_map_0[] = { 67 { P_BI_TCXO, 0 }, 68 { P_DP_PHY_PLL_LINK_CLK, 1 }, 69 { P_DP_PHY_PLL_VCO_DIV_CLK, 2 }, 70 }; 71 72 static const struct clk_parent_data disp_cc_parent_data_0[] = { 73 { .fw_name = "bi_tcxo" }, 74 { .fw_name = "dp_phy_pll_link_clk" }, 75 { .fw_name = "dp_phy_pll_vco_div_clk" }, 76 }; 77 78 static const struct parent_map disp_cc_parent_map_1[] = { 79 { P_BI_TCXO, 0 }, 80 { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, 81 }; 82 83 static const struct clk_parent_data disp_cc_parent_data_1[] = { 84 { .fw_name = "bi_tcxo" }, 85 { .fw_name = "dsi0_phy_pll_out_byteclk" }, 86 }; 87 88 static const struct parent_map disp_cc_parent_map_3[] = { 89 { P_BI_TCXO, 0 }, 90 { P_DISP_CC_PLL0_OUT_MAIN, 1 }, 91 { P_GCC_DISP_GPLL0_CLK, 4 }, 92 { P_DISP_CC_PLL0_OUT_EVEN, 5 }, 93 }; 94 95 static const struct clk_parent_data disp_cc_parent_data_3[] = { 96 { .fw_name = "bi_tcxo" }, 97 { .hw = &disp_cc_pll0.clkr.hw }, 98 { .fw_name = "gcc_disp_gpll0_clk" }, 99 { .hw = &disp_cc_pll0.clkr.hw }, 100 }; 101 102 static const struct parent_map disp_cc_parent_map_4[] = { 103 { P_BI_TCXO, 0 }, 104 { P_GCC_DISP_GPLL0_CLK, 4 }, 105 }; 106 107 static const struct clk_parent_data disp_cc_parent_data_4[] = { 108 { .fw_name = "bi_tcxo" }, 109 { .fw_name = "gcc_disp_gpll0_clk" }, 110 }; 111 112 static const struct parent_map disp_cc_parent_map_5[] = { 113 { P_BI_TCXO, 0 }, 114 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, 115 }; 116 117 static const struct clk_parent_data disp_cc_parent_data_5[] = { 118 { .fw_name = "bi_tcxo" }, 119 { .fw_name = "dsi0_phy_pll_out_dsiclk" }, 120 }; 121 122 static const struct parent_map disp_cc_parent_map_6[] = { 123 { P_BI_TCXO, 0 }, 124 }; 125 126 static const struct clk_parent_data disp_cc_parent_data_6[] = { 127 { .fw_name = "bi_tcxo" }, 128 }; 129 130 static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { 131 F(19200000, P_BI_TCXO, 1, 0, 0), 132 F(37500000, P_GCC_DISP_GPLL0_CLK, 16, 0, 0), 133 F(75000000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0), 134 { } 135 }; 136 137 static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { 138 .cmd_rcgr = 0x115c, 139 .mnd_width = 0, 140 .hid_width = 5, 141 .parent_map = disp_cc_parent_map_4, 142 .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, 143 .clkr.hw.init = &(struct clk_init_data){ 144 .name = "disp_cc_mdss_ahb_clk_src", 145 .parent_data = disp_cc_parent_data_4, 146 .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), 147 .flags = CLK_SET_RATE_PARENT, 148 .ops = &clk_rcg2_ops, 149 }, 150 }; 151 152 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { 153 .cmd_rcgr = 0x10c4, 154 .mnd_width = 0, 155 .hid_width = 5, 156 .parent_map = disp_cc_parent_map_1, 157 .clkr.hw.init = &(struct clk_init_data){ 158 .name = "disp_cc_mdss_byte0_clk_src", 159 .parent_data = disp_cc_parent_data_1, 160 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), 161 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 162 .ops = &clk_byte2_ops, 163 }, 164 }; 165 166 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { 167 .reg = 0x10dc, 168 .shift = 0, 169 .width = 2, 170 .clkr.hw.init = &(struct clk_init_data) { 171 .name = "disp_cc_mdss_byte0_div_clk_src", 172 .parent_hws = (const struct clk_hw*[]){ 173 &disp_cc_mdss_byte0_clk_src.clkr.hw, 174 }, 175 .num_parents = 1, 176 .flags = CLK_GET_RATE_NOCACHE, 177 .ops = &clk_regmap_div_ro_ops, 178 }, 179 }; 180 181 static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = { 182 F(19200000, P_BI_TCXO, 1, 0, 0), 183 { } 184 }; 185 186 static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = { 187 .cmd_rcgr = 0x1144, 188 .mnd_width = 0, 189 .hid_width = 5, 190 .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, 191 .clkr.hw.init = &(struct clk_init_data){ 192 .name = "disp_cc_mdss_dp_aux_clk_src", 193 .parent_data = &(const struct clk_parent_data){ 194 .fw_name = "bi_tcxo", 195 }, 196 .num_parents = 1, 197 .ops = &clk_rcg2_ops, 198 }, 199 }; 200 201 static const struct freq_tbl ftbl_disp_cc_mdss_dp_crypto_clk_src[] = { 202 F(108000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0), 203 F(180000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0), 204 F(360000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0), 205 F(540000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0), 206 { } 207 }; 208 209 static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = { 210 .cmd_rcgr = 0x1114, 211 .mnd_width = 0, 212 .hid_width = 5, 213 .parent_map = disp_cc_parent_map_0, 214 .freq_tbl = ftbl_disp_cc_mdss_dp_crypto_clk_src, 215 .clkr.hw.init = &(struct clk_init_data){ 216 .name = "disp_cc_mdss_dp_crypto_clk_src", 217 .parent_data = disp_cc_parent_data_0, 218 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 219 .flags = CLK_GET_RATE_NOCACHE, 220 .ops = &clk_rcg2_ops, 221 }, 222 }; 223 224 static const struct freq_tbl ftbl_disp_cc_mdss_dp_link_clk_src[] = { 225 F(162000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), 226 F(270000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), 227 F(540000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), 228 F(810000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), 229 { } 230 }; 231 232 static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = { 233 .cmd_rcgr = 0x10f8, 234 .mnd_width = 0, 235 .hid_width = 5, 236 .parent_map = disp_cc_parent_map_0, 237 .freq_tbl = ftbl_disp_cc_mdss_dp_link_clk_src, 238 .clkr.hw.init = &(struct clk_init_data){ 239 .name = "disp_cc_mdss_dp_link_clk_src", 240 .parent_data = disp_cc_parent_data_0, 241 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 242 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 243 .ops = &clk_rcg2_ops, 244 }, 245 }; 246 247 static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = { 248 .cmd_rcgr = 0x112c, 249 .mnd_width = 16, 250 .hid_width = 5, 251 .parent_map = disp_cc_parent_map_0, 252 .clkr.hw.init = &(struct clk_init_data){ 253 .name = "disp_cc_mdss_dp_pixel_clk_src", 254 .parent_data = disp_cc_parent_data_0, 255 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 256 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 257 .ops = &clk_dp_ops, 258 }, 259 }; 260 261 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { 262 .cmd_rcgr = 0x10e0, 263 .mnd_width = 0, 264 .hid_width = 5, 265 .parent_map = disp_cc_parent_map_1, 266 .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, 267 .clkr.hw.init = &(struct clk_init_data){ 268 .name = "disp_cc_mdss_esc0_clk_src", 269 .parent_data = disp_cc_parent_data_1, 270 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), 271 .ops = &clk_rcg2_ops, 272 }, 273 }; 274 275 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { 276 F(19200000, P_BI_TCXO, 1, 0, 0), 277 F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0), 278 F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0), 279 F(373333333, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 280 F(448000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), 281 F(560000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0), 282 { } 283 }; 284 285 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { 286 .cmd_rcgr = 0x107c, 287 .mnd_width = 0, 288 .hid_width = 5, 289 .parent_map = disp_cc_parent_map_3, 290 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, 291 .clkr.hw.init = &(struct clk_init_data){ 292 .name = "disp_cc_mdss_mdp_clk_src", 293 .parent_data = disp_cc_parent_data_3, 294 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), 295 .flags = CLK_SET_RATE_PARENT, 296 .ops = &clk_rcg2_ops, 297 }, 298 }; 299 300 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { 301 .cmd_rcgr = 0x1064, 302 .mnd_width = 8, 303 .hid_width = 5, 304 .parent_map = disp_cc_parent_map_5, 305 .clkr.hw.init = &(struct clk_init_data){ 306 .name = "disp_cc_mdss_pclk0_clk_src", 307 .parent_data = disp_cc_parent_data_5, 308 .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), 309 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 310 .ops = &clk_pixel_ops, 311 }, 312 }; 313 314 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = { 315 .cmd_rcgr = 0x1094, 316 .mnd_width = 0, 317 .hid_width = 5, 318 .parent_map = disp_cc_parent_map_3, 319 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, 320 .clkr.hw.init = &(struct clk_init_data){ 321 .name = "disp_cc_mdss_rot_clk_src", 322 .parent_data = disp_cc_parent_data_3, 323 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), 324 .flags = CLK_SET_RATE_PARENT, 325 .ops = &clk_rcg2_ops, 326 }, 327 }; 328 329 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { 330 .cmd_rcgr = 0x10ac, 331 .mnd_width = 0, 332 .hid_width = 5, 333 .parent_map = disp_cc_parent_map_6, 334 .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, 335 .clkr.hw.init = &(struct clk_init_data){ 336 .name = "disp_cc_mdss_vsync_clk_src", 337 .parent_data = disp_cc_parent_data_6, 338 .num_parents = ARRAY_SIZE(disp_cc_parent_data_6), 339 .ops = &clk_rcg2_ops, 340 }, 341 }; 342 343 static struct clk_regmap_div disp_cc_mdss_dp_link_div_clk_src = { 344 .reg = 0x1110, 345 .shift = 0, 346 .width = 2, 347 .clkr.hw.init = &(struct clk_init_data) { 348 .name = "disp_cc_mdss_dp_link_div_clk_src", 349 .parent_hws = (const struct clk_hw*[]){ 350 &disp_cc_mdss_dp_link_clk_src.clkr.hw, 351 }, 352 .num_parents = 1, 353 .flags = CLK_GET_RATE_NOCACHE, 354 .ops = &clk_regmap_div_ro_ops, 355 }, 356 }; 357 358 static struct clk_branch disp_cc_mdss_ahb_clk = { 359 .halt_reg = 0x104c, 360 .halt_check = BRANCH_HALT, 361 .clkr = { 362 .enable_reg = 0x104c, 363 .enable_mask = BIT(0), 364 .hw.init = &(struct clk_init_data){ 365 .name = "disp_cc_mdss_ahb_clk", 366 .parent_hws = (const struct clk_hw*[]){ 367 &disp_cc_mdss_ahb_clk_src.clkr.hw, 368 }, 369 .num_parents = 1, 370 .flags = CLK_SET_RATE_PARENT, 371 .ops = &clk_branch2_ops, 372 }, 373 }, 374 }; 375 376 static struct clk_branch disp_cc_mdss_byte0_clk = { 377 .halt_reg = 0x102c, 378 .halt_check = BRANCH_HALT, 379 .clkr = { 380 .enable_reg = 0x102c, 381 .enable_mask = BIT(0), 382 .hw.init = &(struct clk_init_data){ 383 .name = "disp_cc_mdss_byte0_clk", 384 .parent_hws = (const struct clk_hw*[]){ 385 &disp_cc_mdss_byte0_clk_src.clkr.hw, 386 }, 387 .num_parents = 1, 388 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 389 .ops = &clk_branch2_ops, 390 }, 391 }, 392 }; 393 394 static struct clk_branch disp_cc_mdss_byte0_intf_clk = { 395 .halt_reg = 0x1030, 396 .halt_check = BRANCH_HALT, 397 .clkr = { 398 .enable_reg = 0x1030, 399 .enable_mask = BIT(0), 400 .hw.init = &(struct clk_init_data){ 401 .name = "disp_cc_mdss_byte0_intf_clk", 402 .parent_hws = (const struct clk_hw*[]){ 403 &disp_cc_mdss_byte0_div_clk_src.clkr.hw, 404 }, 405 .num_parents = 1, 406 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 407 .ops = &clk_branch2_ops, 408 }, 409 }, 410 }; 411 412 static struct clk_branch disp_cc_mdss_dp_aux_clk = { 413 .halt_reg = 0x1048, 414 .halt_check = BRANCH_HALT, 415 .clkr = { 416 .enable_reg = 0x1048, 417 .enable_mask = BIT(0), 418 .hw.init = &(struct clk_init_data){ 419 .name = "disp_cc_mdss_dp_aux_clk", 420 .parent_hws = (const struct clk_hw*[]){ 421 &disp_cc_mdss_dp_aux_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_crypto_clk = { 431 .halt_reg = 0x1040, 432 .halt_check = BRANCH_HALT, 433 .clkr = { 434 .enable_reg = 0x1040, 435 .enable_mask = BIT(0), 436 .hw.init = &(struct clk_init_data){ 437 .name = "disp_cc_mdss_dp_crypto_clk", 438 .parent_hws = (const struct clk_hw*[]){ 439 &disp_cc_mdss_dp_crypto_clk_src.clkr.hw, 440 }, 441 .num_parents = 1, 442 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 443 .ops = &clk_branch2_ops, 444 }, 445 }, 446 }; 447 448 static struct clk_branch disp_cc_mdss_dp_link_clk = { 449 .halt_reg = 0x1038, 450 .halt_check = BRANCH_HALT, 451 .clkr = { 452 .enable_reg = 0x1038, 453 .enable_mask = BIT(0), 454 .hw.init = &(struct clk_init_data){ 455 .name = "disp_cc_mdss_dp_link_clk", 456 .parent_hws = (const struct clk_hw*[]){ 457 &disp_cc_mdss_dp_link_clk_src.clkr.hw, 458 }, 459 .num_parents = 1, 460 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 461 .ops = &clk_branch2_ops, 462 }, 463 }, 464 }; 465 466 static struct clk_branch disp_cc_mdss_dp_link_intf_clk = { 467 .halt_reg = 0x103c, 468 .halt_check = BRANCH_HALT, 469 .clkr = { 470 .enable_reg = 0x103c, 471 .enable_mask = BIT(0), 472 .hw.init = &(struct clk_init_data){ 473 .name = "disp_cc_mdss_dp_link_intf_clk", 474 .parent_hws = (const struct clk_hw*[]){ 475 &disp_cc_mdss_dp_link_div_clk_src.clkr.hw, 476 }, 477 .num_parents = 1, 478 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 479 .ops = &clk_branch2_ops, 480 }, 481 }, 482 }; 483 484 static struct clk_branch disp_cc_mdss_dp_pixel_clk = { 485 .halt_reg = 0x1044, 486 .halt_check = BRANCH_HALT, 487 .clkr = { 488 .enable_reg = 0x1044, 489 .enable_mask = BIT(0), 490 .hw.init = &(struct clk_init_data){ 491 .name = "disp_cc_mdss_dp_pixel_clk", 492 .parent_hws = (const struct clk_hw*[]){ 493 &disp_cc_mdss_dp_pixel_clk_src.clkr.hw, 494 }, 495 .num_parents = 1, 496 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 497 .ops = &clk_branch2_ops, 498 }, 499 }, 500 }; 501 502 static struct clk_branch disp_cc_mdss_esc0_clk = { 503 .halt_reg = 0x1034, 504 .halt_check = BRANCH_HALT, 505 .clkr = { 506 .enable_reg = 0x1034, 507 .enable_mask = BIT(0), 508 .hw.init = &(struct clk_init_data){ 509 .name = "disp_cc_mdss_esc0_clk", 510 .parent_hws = (const struct clk_hw*[]){ 511 &disp_cc_mdss_esc0_clk_src.clkr.hw, 512 }, 513 .num_parents = 1, 514 .flags = CLK_SET_RATE_PARENT, 515 .ops = &clk_branch2_ops, 516 }, 517 }, 518 }; 519 520 static struct clk_branch disp_cc_mdss_mdp_clk = { 521 .halt_reg = 0x1010, 522 .halt_check = BRANCH_HALT, 523 .clkr = { 524 .enable_reg = 0x1010, 525 .enable_mask = BIT(0), 526 .hw.init = &(struct clk_init_data){ 527 .name = "disp_cc_mdss_mdp_clk", 528 .parent_hws = (const struct clk_hw*[]){ 529 &disp_cc_mdss_mdp_clk_src.clkr.hw, 530 }, 531 .num_parents = 1, 532 .flags = CLK_SET_RATE_PARENT, 533 .ops = &clk_branch2_ops, 534 }, 535 }, 536 }; 537 538 static struct clk_branch disp_cc_mdss_mdp_lut_clk = { 539 .halt_reg = 0x1020, 540 .halt_check = BRANCH_HALT_VOTED, 541 .clkr = { 542 .enable_reg = 0x1020, 543 .enable_mask = BIT(0), 544 .hw.init = &(struct clk_init_data){ 545 .name = "disp_cc_mdss_mdp_lut_clk", 546 .parent_hws = (const struct clk_hw*[]){ 547 &disp_cc_mdss_mdp_clk_src.clkr.hw, 548 }, 549 .num_parents = 1, 550 .flags = CLK_SET_RATE_PARENT, 551 .ops = &clk_branch2_ops, 552 }, 553 }, 554 }; 555 556 static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = { 557 .halt_reg = 0x2004, 558 .halt_check = BRANCH_HALT_VOTED, 559 .clkr = { 560 .enable_reg = 0x2004, 561 .enable_mask = BIT(0), 562 .hw.init = &(struct clk_init_data){ 563 .name = "disp_cc_mdss_non_gdsc_ahb_clk", 564 .parent_hws = (const struct clk_hw*[]){ 565 &disp_cc_mdss_ahb_clk_src.clkr.hw, 566 }, 567 .num_parents = 1, 568 .flags = CLK_SET_RATE_PARENT, 569 .ops = &clk_branch2_ops, 570 }, 571 }, 572 }; 573 574 static struct clk_branch disp_cc_mdss_pclk0_clk = { 575 .halt_reg = 0x100c, 576 .halt_check = BRANCH_HALT, 577 .clkr = { 578 .enable_reg = 0x100c, 579 .enable_mask = BIT(0), 580 .hw.init = &(struct clk_init_data){ 581 .name = "disp_cc_mdss_pclk0_clk", 582 .parent_hws = (const struct clk_hw*[]){ 583 &disp_cc_mdss_pclk0_clk_src.clkr.hw, 584 }, 585 .num_parents = 1, 586 .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 587 .ops = &clk_branch2_ops, 588 }, 589 }, 590 }; 591 592 static struct clk_branch disp_cc_mdss_rot_clk = { 593 .halt_reg = 0x1018, 594 .halt_check = BRANCH_HALT, 595 .clkr = { 596 .enable_reg = 0x1018, 597 .enable_mask = BIT(0), 598 .hw.init = &(struct clk_init_data){ 599 .name = "disp_cc_mdss_rot_clk", 600 .parent_hws = (const struct clk_hw*[]){ 601 &disp_cc_mdss_rot_clk_src.clkr.hw, 602 }, 603 .num_parents = 1, 604 .flags = CLK_SET_RATE_PARENT, 605 .ops = &clk_branch2_ops, 606 }, 607 }, 608 }; 609 610 static struct clk_branch disp_cc_mdss_rscc_ahb_clk = { 611 .halt_reg = 0x200c, 612 .halt_check = BRANCH_HALT, 613 .clkr = { 614 .enable_reg = 0x200c, 615 .enable_mask = BIT(0), 616 .hw.init = &(struct clk_init_data){ 617 .name = "disp_cc_mdss_rscc_ahb_clk", 618 .parent_hws = (const struct clk_hw*[]){ 619 &disp_cc_mdss_ahb_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 clk_branch disp_cc_mdss_rscc_vsync_clk = { 629 .halt_reg = 0x2008, 630 .halt_check = BRANCH_HALT, 631 .clkr = { 632 .enable_reg = 0x2008, 633 .enable_mask = BIT(0), 634 .hw.init = &(struct clk_init_data){ 635 .name = "disp_cc_mdss_rscc_vsync_clk", 636 .parent_hws = (const struct clk_hw*[]){ 637 &disp_cc_mdss_vsync_clk_src.clkr.hw, 638 }, 639 .num_parents = 1, 640 .flags = CLK_SET_RATE_PARENT, 641 .ops = &clk_branch2_ops, 642 }, 643 }, 644 }; 645 646 static struct clk_branch disp_cc_mdss_vsync_clk = { 647 .halt_reg = 0x1028, 648 .halt_check = BRANCH_HALT, 649 .clkr = { 650 .enable_reg = 0x1028, 651 .enable_mask = BIT(0), 652 .hw.init = &(struct clk_init_data){ 653 .name = "disp_cc_mdss_vsync_clk", 654 .parent_hws = (const struct clk_hw*[]){ 655 &disp_cc_mdss_vsync_clk_src.clkr.hw, 656 }, 657 .num_parents = 1, 658 .flags = CLK_SET_RATE_PARENT, 659 .ops = &clk_branch2_ops, 660 }, 661 }, 662 }; 663 664 static struct clk_branch disp_cc_sleep_clk = { 665 .halt_reg = 0x5004, 666 .halt_check = BRANCH_HALT, 667 .clkr = { 668 .enable_reg = 0x5004, 669 .enable_mask = BIT(0), 670 .hw.init = &(struct clk_init_data){ 671 .name = "disp_cc_sleep_clk", 672 .ops = &clk_branch2_ops, 673 }, 674 }, 675 }; 676 677 static struct clk_branch disp_cc_xo_clk = { 678 .halt_reg = 0x5008, 679 .halt_check = BRANCH_HALT, 680 .clkr = { 681 .enable_reg = 0x5008, 682 .enable_mask = BIT(0), 683 .hw.init = &(struct clk_init_data){ 684 .name = "disp_cc_xo_clk", 685 .flags = CLK_IS_CRITICAL, 686 .ops = &clk_branch2_ops, 687 }, 688 }, 689 }; 690 691 static struct gdsc mdss_gdsc = { 692 .gdscr = 0x1004, 693 .pd = { 694 .name = "mdss_gdsc", 695 }, 696 .pwrsts = PWRSTS_OFF_ON, 697 .flags = RETAIN_FF_ENABLE, 698 }; 699 700 static struct clk_regmap *disp_cc_sm6350_clocks[] = { 701 [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, 702 [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr, 703 [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, 704 [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, 705 [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr, 706 [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, 707 [DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr, 708 [DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr, 709 [DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr, 710 [DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr, 711 [DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr, 712 [DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr, 713 [DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC] = 714 &disp_cc_mdss_dp_link_div_clk_src.clkr, 715 [DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr, 716 [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr, 717 [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr, 718 [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, 719 [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, 720 [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, 721 [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, 722 [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, 723 [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr, 724 [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, 725 [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, 726 [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, 727 [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, 728 [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr, 729 [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, 730 [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, 731 [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, 732 [DISP_CC_PLL0] = &disp_cc_pll0.clkr, 733 [DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr, 734 [DISP_CC_XO_CLK] = &disp_cc_xo_clk.clkr, 735 }; 736 737 static struct gdsc *disp_cc_sm6350_gdscs[] = { 738 [MDSS_GDSC] = &mdss_gdsc, 739 }; 740 741 static const struct regmap_config disp_cc_sm6350_regmap_config = { 742 .reg_bits = 32, 743 .reg_stride = 4, 744 .val_bits = 32, 745 .max_register = 0x10000, 746 .fast_io = true, 747 }; 748 749 static const struct qcom_cc_desc disp_cc_sm6350_desc = { 750 .config = &disp_cc_sm6350_regmap_config, 751 .clks = disp_cc_sm6350_clocks, 752 .num_clks = ARRAY_SIZE(disp_cc_sm6350_clocks), 753 .gdscs = disp_cc_sm6350_gdscs, 754 .num_gdscs = ARRAY_SIZE(disp_cc_sm6350_gdscs), 755 }; 756 757 static const struct of_device_id disp_cc_sm6350_match_table[] = { 758 { .compatible = "qcom,sm6350-dispcc" }, 759 { } 760 }; 761 MODULE_DEVICE_TABLE(of, disp_cc_sm6350_match_table); 762 763 static int disp_cc_sm6350_probe(struct platform_device *pdev) 764 { 765 struct regmap *regmap; 766 767 regmap = qcom_cc_map(pdev, &disp_cc_sm6350_desc); 768 if (IS_ERR(regmap)) 769 return PTR_ERR(regmap); 770 771 clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); 772 773 return qcom_cc_really_probe(pdev, &disp_cc_sm6350_desc, regmap); 774 } 775 776 static struct platform_driver disp_cc_sm6350_driver = { 777 .probe = disp_cc_sm6350_probe, 778 .driver = { 779 .name = "disp_cc-sm6350", 780 .of_match_table = disp_cc_sm6350_match_table, 781 }, 782 }; 783 784 static int __init disp_cc_sm6350_init(void) 785 { 786 return platform_driver_register(&disp_cc_sm6350_driver); 787 } 788 subsys_initcall(disp_cc_sm6350_init); 789 790 static void __exit disp_cc_sm6350_exit(void) 791 { 792 platform_driver_unregister(&disp_cc_sm6350_driver); 793 } 794 module_exit(disp_cc_sm6350_exit); 795 796 MODULE_DESCRIPTION("QTI DISP_CC SM6350 Driver"); 797 MODULE_LICENSE("GPL v2"); 798