1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. 4 */ 5 6 #include <linux/clk-provider.h> 7 #include <linux/module.h> 8 #include <linux/mod_devicetable.h> 9 #include <linux/of.h> 10 #include <linux/platform_device.h> 11 #include <linux/regmap.h> 12 13 #include <dt-bindings/clock/qcom,sm4450-dispcc.h> 14 15 #include "clk-alpha-pll.h" 16 #include "clk-branch.h" 17 #include "clk-pll.h" 18 #include "clk-rcg.h" 19 #include "clk-regmap.h" 20 #include "clk-regmap-divider.h" 21 #include "common.h" 22 #include "gdsc.h" 23 #include "reset.h" 24 25 enum { 26 DT_BI_TCXO, 27 DT_BI_TCXO_AO, 28 DT_AHB_CLK, 29 DT_SLEEP_CLK, 30 31 DT_DSI0_PHY_PLL_OUT_BYTECLK, 32 DT_DSI0_PHY_PLL_OUT_DSICLK, 33 }; 34 35 enum { 36 P_BI_TCXO, 37 P_DISP_CC_PLL0_OUT_MAIN, 38 P_DISP_CC_PLL1_OUT_EVEN, 39 P_DISP_CC_PLL1_OUT_MAIN, 40 P_DSI0_PHY_PLL_OUT_BYTECLK, 41 P_DSI0_PHY_PLL_OUT_DSICLK, 42 P_SLEEP_CLK, 43 }; 44 45 static const struct pll_vco lucid_evo_vco[] = { 46 { 249600000, 2020000000, 0 }, 47 }; 48 49 /* 600.0 MHz Configuration */ 50 static const struct alpha_pll_config disp_cc_pll0_config = { 51 .l = 0x1f, 52 .alpha = 0x4000, 53 .config_ctl_val = 0x20485699, 54 .config_ctl_hi_val = 0x00182261, 55 .config_ctl_hi1_val = 0x32aa299c, 56 .user_ctl_val = 0x00000000, 57 .user_ctl_hi_val = 0x00000805, 58 }; 59 60 static struct clk_alpha_pll disp_cc_pll0 = { 61 .offset = 0x0, 62 .vco_table = lucid_evo_vco, 63 .num_vco = ARRAY_SIZE(lucid_evo_vco), 64 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], 65 .clkr = { 66 .hw.init = &(const struct clk_init_data) { 67 .name = "disp_cc_pll0", 68 .parent_data = &(const struct clk_parent_data) { 69 .index = DT_BI_TCXO, 70 }, 71 .num_parents = 1, 72 .ops = &clk_alpha_pll_lucid_evo_ops, 73 }, 74 }, 75 }; 76 77 static struct clk_alpha_pll disp_cc_pll1 = { 78 .offset = 0x1000, 79 .vco_table = lucid_evo_vco, 80 .num_vco = ARRAY_SIZE(lucid_evo_vco), 81 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], 82 .clkr = { 83 .hw.init = &(const struct clk_init_data) { 84 .name = "disp_cc_pll1", 85 .parent_data = &(const struct clk_parent_data) { 86 .index = DT_BI_TCXO, 87 }, 88 .num_parents = 1, 89 .ops = &clk_alpha_pll_lucid_evo_ops, 90 }, 91 }, 92 }; 93 94 static const struct parent_map disp_cc_parent_map_0[] = { 95 { P_BI_TCXO, 0 }, 96 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, 97 { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, 98 }; 99 100 static const struct clk_parent_data disp_cc_parent_data_0[] = { 101 { .index = DT_BI_TCXO }, 102 { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, 103 { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, 104 }; 105 106 static const struct parent_map disp_cc_parent_map_1[] = { 107 { P_BI_TCXO, 0 }, 108 { P_DISP_CC_PLL0_OUT_MAIN, 1 }, 109 { P_DISP_CC_PLL1_OUT_MAIN, 4 }, 110 { P_DISP_CC_PLL1_OUT_EVEN, 6 }, 111 }; 112 113 static const struct clk_parent_data disp_cc_parent_data_1[] = { 114 { .index = DT_BI_TCXO }, 115 { .hw = &disp_cc_pll0.clkr.hw }, 116 { .hw = &disp_cc_pll1.clkr.hw }, 117 { .hw = &disp_cc_pll1.clkr.hw }, 118 }; 119 120 static const struct parent_map disp_cc_parent_map_2[] = { 121 { P_BI_TCXO, 0 }, 122 }; 123 124 static const struct clk_parent_data disp_cc_parent_data_2[] = { 125 { .index = DT_BI_TCXO }, 126 }; 127 128 static const struct clk_parent_data disp_cc_parent_data_2_ao[] = { 129 { .index = DT_BI_TCXO_AO }, 130 }; 131 132 static const struct parent_map disp_cc_parent_map_3[] = { 133 { P_BI_TCXO, 0 }, 134 { P_DISP_CC_PLL1_OUT_MAIN, 4 }, 135 { P_DISP_CC_PLL1_OUT_EVEN, 6 }, 136 }; 137 138 static const struct clk_parent_data disp_cc_parent_data_3[] = { 139 { .index = DT_BI_TCXO }, 140 { .hw = &disp_cc_pll1.clkr.hw }, 141 { .hw = &disp_cc_pll1.clkr.hw }, 142 }; 143 144 static const struct parent_map disp_cc_parent_map_4[] = { 145 { P_BI_TCXO, 0 }, 146 { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, 147 }; 148 149 static const struct clk_parent_data disp_cc_parent_data_4[] = { 150 { .index = DT_BI_TCXO }, 151 { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, 152 }; 153 154 static const struct parent_map disp_cc_parent_map_5[] = { 155 { P_SLEEP_CLK, 0 }, 156 }; 157 158 static const struct clk_parent_data disp_cc_parent_data_5[] = { 159 { .index = DT_SLEEP_CLK }, 160 }; 161 162 static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { 163 F(19200000, P_BI_TCXO, 1, 0, 0), 164 F(37500000, P_DISP_CC_PLL1_OUT_MAIN, 16, 0, 0), 165 F(75000000, P_DISP_CC_PLL1_OUT_MAIN, 8, 0, 0), 166 { } 167 }; 168 169 static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { 170 .cmd_rcgr = 0x82a4, 171 .mnd_width = 0, 172 .hid_width = 5, 173 .parent_map = disp_cc_parent_map_3, 174 .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, 175 .clkr.hw.init = &(const struct clk_init_data) { 176 .name = "disp_cc_mdss_ahb_clk_src", 177 .parent_data = disp_cc_parent_data_3, 178 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), 179 .flags = CLK_SET_RATE_PARENT, 180 .ops = &clk_rcg2_shared_ops, 181 }, 182 }; 183 184 static const struct freq_tbl ftbl_disp_cc_mdss_byte0_clk_src[] = { 185 F(19200000, P_BI_TCXO, 1, 0, 0), 186 { } 187 }; 188 189 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { 190 .cmd_rcgr = 0x80f8, 191 .mnd_width = 0, 192 .hid_width = 5, 193 .parent_map = disp_cc_parent_map_0, 194 .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src, 195 .clkr.hw.init = &(const struct clk_init_data) { 196 .name = "disp_cc_mdss_byte0_clk_src", 197 .parent_data = disp_cc_parent_data_0, 198 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 199 .flags = CLK_SET_RATE_PARENT, 200 .ops = &clk_byte2_ops, 201 }, 202 }; 203 204 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { 205 .cmd_rcgr = 0x8114, 206 .mnd_width = 0, 207 .hid_width = 5, 208 .parent_map = disp_cc_parent_map_4, 209 .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src, 210 .clkr.hw.init = &(const struct clk_init_data) { 211 .name = "disp_cc_mdss_esc0_clk_src", 212 .parent_data = disp_cc_parent_data_4, 213 .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), 214 .flags = CLK_SET_RATE_PARENT, 215 .ops = &clk_rcg2_shared_ops, 216 }, 217 }; 218 219 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { 220 F(200000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 221 F(325000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 222 F(380000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 223 F(506000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 224 F(608000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 225 { } 226 }; 227 228 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { 229 .cmd_rcgr = 0x80b0, 230 .mnd_width = 0, 231 .hid_width = 5, 232 .parent_map = disp_cc_parent_map_1, 233 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, 234 .clkr.hw.init = &(const struct clk_init_data) { 235 .name = "disp_cc_mdss_mdp_clk_src", 236 .parent_data = disp_cc_parent_data_1, 237 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), 238 .flags = CLK_SET_RATE_PARENT, 239 .ops = &clk_rcg2_shared_ops, 240 }, 241 }; 242 243 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { 244 .cmd_rcgr = 0x8098, 245 .mnd_width = 8, 246 .hid_width = 5, 247 .parent_map = disp_cc_parent_map_0, 248 .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src, 249 .clkr.hw.init = &(const struct clk_init_data) { 250 .name = "disp_cc_mdss_pclk0_clk_src", 251 .parent_data = disp_cc_parent_data_0, 252 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 253 .flags = CLK_SET_RATE_PARENT, 254 .ops = &clk_pixel_ops, 255 }, 256 }; 257 258 static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = { 259 F(200000000, P_DISP_CC_PLL1_OUT_MAIN, 3, 0, 0), 260 F(300000000, P_DISP_CC_PLL1_OUT_MAIN, 2, 0, 0), 261 { } 262 }; 263 264 static struct clk_rcg2 disp_cc_mdss_rot_clk_src = { 265 .cmd_rcgr = 0x80c8, 266 .mnd_width = 0, 267 .hid_width = 5, 268 .parent_map = disp_cc_parent_map_1, 269 .freq_tbl = ftbl_disp_cc_mdss_rot_clk_src, 270 .clkr.hw.init = &(const struct clk_init_data) { 271 .name = "disp_cc_mdss_rot_clk_src", 272 .parent_data = disp_cc_parent_data_1, 273 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), 274 .flags = CLK_SET_RATE_PARENT, 275 .ops = &clk_rcg2_shared_ops, 276 }, 277 }; 278 279 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { 280 .cmd_rcgr = 0x80e0, 281 .mnd_width = 0, 282 .hid_width = 5, 283 .parent_map = disp_cc_parent_map_2, 284 .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src, 285 .clkr.hw.init = &(const struct clk_init_data) { 286 .name = "disp_cc_mdss_vsync_clk_src", 287 .parent_data = disp_cc_parent_data_2, 288 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), 289 .flags = CLK_SET_RATE_PARENT, 290 .ops = &clk_rcg2_shared_ops, 291 }, 292 }; 293 294 static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = { 295 F(32000, P_SLEEP_CLK, 1, 0, 0), 296 { } 297 }; 298 299 static struct clk_rcg2 disp_cc_sleep_clk_src = { 300 .cmd_rcgr = 0xe058, 301 .mnd_width = 0, 302 .hid_width = 5, 303 .parent_map = disp_cc_parent_map_5, 304 .freq_tbl = ftbl_disp_cc_sleep_clk_src, 305 .clkr.hw.init = &(const struct clk_init_data) { 306 .name = "disp_cc_sleep_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, 310 .ops = &clk_rcg2_shared_ops, 311 }, 312 }; 313 314 static struct clk_rcg2 disp_cc_xo_clk_src = { 315 .cmd_rcgr = 0xe03c, 316 .mnd_width = 0, 317 .hid_width = 5, 318 .parent_map = disp_cc_parent_map_2, 319 .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src, 320 .clkr.hw.init = &(const struct clk_init_data) { 321 .name = "disp_cc_xo_clk_src", 322 .parent_data = disp_cc_parent_data_2_ao, 323 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2_ao), 324 .flags = CLK_SET_RATE_PARENT, 325 .ops = &clk_rcg2_shared_ops, 326 }, 327 }; 328 329 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { 330 .reg = 0x8110, 331 .shift = 0, 332 .width = 4, 333 .clkr.hw.init = &(const struct clk_init_data) { 334 .name = "disp_cc_mdss_byte0_div_clk_src", 335 .parent_hws = (const struct clk_hw*[]) { 336 &disp_cc_mdss_byte0_clk_src.clkr.hw, 337 }, 338 .num_parents = 1, 339 .flags = CLK_SET_RATE_PARENT, 340 .ops = &clk_regmap_div_ops, 341 }, 342 }; 343 344 static struct clk_branch disp_cc_mdss_ahb1_clk = { 345 .halt_reg = 0xa020, 346 .halt_check = BRANCH_HALT, 347 .clkr = { 348 .enable_reg = 0xa020, 349 .enable_mask = BIT(0), 350 .hw.init = &(const struct clk_init_data) { 351 .name = "disp_cc_mdss_ahb1_clk", 352 .parent_hws = (const struct clk_hw*[]) { 353 &disp_cc_mdss_ahb_clk_src.clkr.hw, 354 }, 355 .num_parents = 1, 356 .flags = CLK_SET_RATE_PARENT, 357 .ops = &clk_branch2_ops, 358 }, 359 }, 360 }; 361 362 static struct clk_branch disp_cc_mdss_ahb_clk = { 363 .halt_reg = 0x8094, 364 .halt_check = BRANCH_HALT, 365 .clkr = { 366 .enable_reg = 0x8094, 367 .enable_mask = BIT(0), 368 .hw.init = &(const struct clk_init_data) { 369 .name = "disp_cc_mdss_ahb_clk", 370 .parent_hws = (const struct clk_hw*[]) { 371 &disp_cc_mdss_ahb_clk_src.clkr.hw, 372 }, 373 .num_parents = 1, 374 .flags = CLK_SET_RATE_PARENT, 375 .ops = &clk_branch2_ops, 376 }, 377 }, 378 }; 379 380 static struct clk_branch disp_cc_mdss_byte0_clk = { 381 .halt_reg = 0x8024, 382 .halt_check = BRANCH_HALT, 383 .clkr = { 384 .enable_reg = 0x8024, 385 .enable_mask = BIT(0), 386 .hw.init = &(const struct clk_init_data) { 387 .name = "disp_cc_mdss_byte0_clk", 388 .parent_hws = (const struct clk_hw*[]) { 389 &disp_cc_mdss_byte0_clk_src.clkr.hw, 390 }, 391 .num_parents = 1, 392 .flags = CLK_SET_RATE_PARENT, 393 .ops = &clk_branch2_ops, 394 }, 395 }, 396 }; 397 398 static struct clk_branch disp_cc_mdss_byte0_intf_clk = { 399 .halt_reg = 0x8028, 400 .halt_check = BRANCH_HALT, 401 .clkr = { 402 .enable_reg = 0x8028, 403 .enable_mask = BIT(0), 404 .hw.init = &(const struct clk_init_data) { 405 .name = "disp_cc_mdss_byte0_intf_clk", 406 .parent_hws = (const struct clk_hw*[]) { 407 &disp_cc_mdss_byte0_div_clk_src.clkr.hw, 408 }, 409 .num_parents = 1, 410 .flags = CLK_SET_RATE_PARENT, 411 .ops = &clk_branch2_ops, 412 }, 413 }, 414 }; 415 416 static struct clk_branch disp_cc_mdss_esc0_clk = { 417 .halt_reg = 0x802c, 418 .halt_check = BRANCH_HALT, 419 .clkr = { 420 .enable_reg = 0x802c, 421 .enable_mask = BIT(0), 422 .hw.init = &(const struct clk_init_data) { 423 .name = "disp_cc_mdss_esc0_clk", 424 .parent_hws = (const struct clk_hw*[]) { 425 &disp_cc_mdss_esc0_clk_src.clkr.hw, 426 }, 427 .num_parents = 1, 428 .flags = CLK_SET_RATE_PARENT, 429 .ops = &clk_branch2_ops, 430 }, 431 }, 432 }; 433 434 static struct clk_branch disp_cc_mdss_mdp1_clk = { 435 .halt_reg = 0xa004, 436 .halt_check = BRANCH_HALT, 437 .clkr = { 438 .enable_reg = 0xa004, 439 .enable_mask = BIT(0), 440 .hw.init = &(const struct clk_init_data) { 441 .name = "disp_cc_mdss_mdp1_clk", 442 .parent_hws = (const struct clk_hw*[]) { 443 &disp_cc_mdss_mdp_clk_src.clkr.hw, 444 }, 445 .num_parents = 1, 446 .flags = CLK_SET_RATE_PARENT, 447 .ops = &clk_branch2_ops, 448 }, 449 }, 450 }; 451 452 static struct clk_branch disp_cc_mdss_mdp_clk = { 453 .halt_reg = 0x8008, 454 .halt_check = BRANCH_HALT, 455 .clkr = { 456 .enable_reg = 0x8008, 457 .enable_mask = BIT(0), 458 .hw.init = &(const struct clk_init_data) { 459 .name = "disp_cc_mdss_mdp_clk", 460 .parent_hws = (const struct clk_hw*[]) { 461 &disp_cc_mdss_mdp_clk_src.clkr.hw, 462 }, 463 .num_parents = 1, 464 .flags = CLK_SET_RATE_PARENT, 465 .ops = &clk_branch2_ops, 466 }, 467 }, 468 }; 469 470 static struct clk_branch disp_cc_mdss_mdp_lut1_clk = { 471 .halt_reg = 0xa014, 472 .halt_check = BRANCH_HALT, 473 .clkr = { 474 .enable_reg = 0xa014, 475 .enable_mask = BIT(0), 476 .hw.init = &(const struct clk_init_data) { 477 .name = "disp_cc_mdss_mdp_lut1_clk", 478 .parent_hws = (const struct clk_hw*[]) { 479 &disp_cc_mdss_mdp_clk_src.clkr.hw, 480 }, 481 .num_parents = 1, 482 .flags = CLK_SET_RATE_PARENT, 483 .ops = &clk_branch2_ops, 484 }, 485 }, 486 }; 487 488 static struct clk_branch disp_cc_mdss_mdp_lut_clk = { 489 .halt_reg = 0x8018, 490 .halt_check = BRANCH_HALT_VOTED, 491 .clkr = { 492 .enable_reg = 0x8018, 493 .enable_mask = BIT(0), 494 .hw.init = &(const struct clk_init_data) { 495 .name = "disp_cc_mdss_mdp_lut_clk", 496 .parent_hws = (const struct clk_hw*[]) { 497 &disp_cc_mdss_mdp_clk_src.clkr.hw, 498 }, 499 .num_parents = 1, 500 .flags = CLK_SET_RATE_PARENT, 501 .ops = &clk_branch2_ops, 502 }, 503 }, 504 }; 505 506 static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = { 507 .halt_reg = 0xc004, 508 .halt_check = BRANCH_HALT_VOTED, 509 .clkr = { 510 .enable_reg = 0xc004, 511 .enable_mask = BIT(0), 512 .hw.init = &(const struct clk_init_data) { 513 .name = "disp_cc_mdss_non_gdsc_ahb_clk", 514 .parent_hws = (const struct clk_hw*[]) { 515 &disp_cc_mdss_ahb_clk_src.clkr.hw, 516 }, 517 .num_parents = 1, 518 .flags = CLK_SET_RATE_PARENT, 519 .ops = &clk_branch2_ops, 520 }, 521 }, 522 }; 523 524 static struct clk_branch disp_cc_mdss_pclk0_clk = { 525 .halt_reg = 0x8004, 526 .halt_check = BRANCH_HALT, 527 .clkr = { 528 .enable_reg = 0x8004, 529 .enable_mask = BIT(0), 530 .hw.init = &(const struct clk_init_data) { 531 .name = "disp_cc_mdss_pclk0_clk", 532 .parent_hws = (const struct clk_hw*[]) { 533 &disp_cc_mdss_pclk0_clk_src.clkr.hw, 534 }, 535 .num_parents = 1, 536 .flags = CLK_SET_RATE_PARENT, 537 .ops = &clk_branch2_ops, 538 }, 539 }, 540 }; 541 542 static struct clk_branch disp_cc_mdss_rot1_clk = { 543 .halt_reg = 0xa00c, 544 .halt_check = BRANCH_HALT, 545 .clkr = { 546 .enable_reg = 0xa00c, 547 .enable_mask = BIT(0), 548 .hw.init = &(const struct clk_init_data) { 549 .name = "disp_cc_mdss_rot1_clk", 550 .parent_hws = (const struct clk_hw*[]) { 551 &disp_cc_mdss_rot_clk_src.clkr.hw, 552 }, 553 .num_parents = 1, 554 .flags = CLK_SET_RATE_PARENT, 555 .ops = &clk_branch2_ops, 556 }, 557 }, 558 }; 559 560 static struct clk_branch disp_cc_mdss_rot_clk = { 561 .halt_reg = 0x8010, 562 .halt_check = BRANCH_HALT, 563 .clkr = { 564 .enable_reg = 0x8010, 565 .enable_mask = BIT(0), 566 .hw.init = &(const struct clk_init_data) { 567 .name = "disp_cc_mdss_rot_clk", 568 .parent_hws = (const struct clk_hw*[]) { 569 &disp_cc_mdss_rot_clk_src.clkr.hw, 570 }, 571 .num_parents = 1, 572 .flags = CLK_SET_RATE_PARENT, 573 .ops = &clk_branch2_ops, 574 }, 575 }, 576 }; 577 578 static struct clk_branch disp_cc_mdss_rscc_ahb_clk = { 579 .halt_reg = 0xc00c, 580 .halt_check = BRANCH_HALT, 581 .clkr = { 582 .enable_reg = 0xc00c, 583 .enable_mask = BIT(0), 584 .hw.init = &(const struct clk_init_data) { 585 .name = "disp_cc_mdss_rscc_ahb_clk", 586 .parent_hws = (const struct clk_hw*[]) { 587 &disp_cc_mdss_ahb_clk_src.clkr.hw, 588 }, 589 .num_parents = 1, 590 .flags = CLK_SET_RATE_PARENT, 591 .ops = &clk_branch2_ops, 592 }, 593 }, 594 }; 595 596 static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { 597 .halt_reg = 0xc008, 598 .halt_check = BRANCH_HALT, 599 .clkr = { 600 .enable_reg = 0xc008, 601 .enable_mask = BIT(0), 602 .hw.init = &(const struct clk_init_data) { 603 .name = "disp_cc_mdss_rscc_vsync_clk", 604 .parent_hws = (const struct clk_hw*[]) { 605 &disp_cc_mdss_vsync_clk_src.clkr.hw, 606 }, 607 .num_parents = 1, 608 .flags = CLK_SET_RATE_PARENT, 609 .ops = &clk_branch2_ops, 610 }, 611 }, 612 }; 613 614 static struct clk_branch disp_cc_mdss_vsync1_clk = { 615 .halt_reg = 0xa01c, 616 .halt_check = BRANCH_HALT, 617 .clkr = { 618 .enable_reg = 0xa01c, 619 .enable_mask = BIT(0), 620 .hw.init = &(const struct clk_init_data) { 621 .name = "disp_cc_mdss_vsync1_clk", 622 .parent_hws = (const struct clk_hw*[]) { 623 &disp_cc_mdss_vsync_clk_src.clkr.hw, 624 }, 625 .num_parents = 1, 626 .flags = CLK_SET_RATE_PARENT, 627 .ops = &clk_branch2_ops, 628 }, 629 }, 630 }; 631 632 static struct clk_branch disp_cc_mdss_vsync_clk = { 633 .halt_reg = 0x8020, 634 .halt_check = BRANCH_HALT, 635 .clkr = { 636 .enable_reg = 0x8020, 637 .enable_mask = BIT(0), 638 .hw.init = &(const struct clk_init_data) { 639 .name = "disp_cc_mdss_vsync_clk", 640 .parent_hws = (const struct clk_hw*[]) { 641 &disp_cc_mdss_vsync_clk_src.clkr.hw, 642 }, 643 .num_parents = 1, 644 .flags = CLK_SET_RATE_PARENT, 645 .ops = &clk_branch2_ops, 646 }, 647 }, 648 }; 649 650 static struct gdsc disp_cc_mdss_core_gdsc = { 651 .gdscr = 0x9000, 652 .en_rest_wait_val = 0x2, 653 .en_few_wait_val = 0x2, 654 .clk_dis_wait_val = 0xf, 655 .pd = { 656 .name = "disp_cc_mdss_core_gdsc", 657 }, 658 .pwrsts = PWRSTS_OFF_ON, 659 .flags = HW_CTRL | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, 660 }; 661 662 static struct gdsc disp_cc_mdss_core_int2_gdsc = { 663 .gdscr = 0xb000, 664 .en_rest_wait_val = 0x2, 665 .en_few_wait_val = 0x2, 666 .clk_dis_wait_val = 0xf, 667 .pd = { 668 .name = "disp_cc_mdss_core_int2_gdsc", 669 }, 670 .pwrsts = PWRSTS_OFF_ON, 671 .flags = HW_CTRL | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, 672 }; 673 674 static struct clk_regmap *disp_cc_sm4450_clocks[] = { 675 [DISP_CC_MDSS_AHB1_CLK] = &disp_cc_mdss_ahb1_clk.clkr, 676 [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, 677 [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr, 678 [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, 679 [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, 680 [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr, 681 [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, 682 [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, 683 [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, 684 [DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr, 685 [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, 686 [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, 687 [DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr, 688 [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, 689 [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr, 690 [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, 691 [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, 692 [DISP_CC_MDSS_ROT1_CLK] = &disp_cc_mdss_rot1_clk.clkr, 693 [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, 694 [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, 695 [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr, 696 [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, 697 [DISP_CC_MDSS_VSYNC1_CLK] = &disp_cc_mdss_vsync1_clk.clkr, 698 [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, 699 [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, 700 [DISP_CC_PLL0] = &disp_cc_pll0.clkr, 701 [DISP_CC_PLL1] = &disp_cc_pll1.clkr, 702 [DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr, 703 [DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr, 704 }; 705 706 static struct gdsc *disp_cc_sm4450_gdscs[] = { 707 [DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc, 708 [DISP_CC_MDSS_CORE_INT2_GDSC] = &disp_cc_mdss_core_int2_gdsc, 709 }; 710 711 static const struct qcom_reset_map disp_cc_sm4450_resets[] = { 712 [DISP_CC_MDSS_CORE_BCR] = { 0x8000 }, 713 [DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 }, 714 [DISP_CC_MDSS_RSCC_BCR] = { 0xc000 }, 715 }; 716 717 static const struct regmap_config disp_cc_sm4450_regmap_config = { 718 .reg_bits = 32, 719 .reg_stride = 4, 720 .val_bits = 32, 721 .max_register = 0x11008, 722 .fast_io = true, 723 }; 724 725 static struct qcom_cc_desc disp_cc_sm4450_desc = { 726 .config = &disp_cc_sm4450_regmap_config, 727 .clks = disp_cc_sm4450_clocks, 728 .num_clks = ARRAY_SIZE(disp_cc_sm4450_clocks), 729 .resets = disp_cc_sm4450_resets, 730 .num_resets = ARRAY_SIZE(disp_cc_sm4450_resets), 731 .gdscs = disp_cc_sm4450_gdscs, 732 .num_gdscs = ARRAY_SIZE(disp_cc_sm4450_gdscs), 733 }; 734 735 static const struct of_device_id disp_cc_sm4450_match_table[] = { 736 { .compatible = "qcom,sm4450-dispcc" }, 737 { } 738 }; 739 MODULE_DEVICE_TABLE(of, disp_cc_sm4450_match_table); 740 741 static int disp_cc_sm4450_probe(struct platform_device *pdev) 742 { 743 struct regmap *regmap; 744 745 regmap = qcom_cc_map(pdev, &disp_cc_sm4450_desc); 746 if (IS_ERR(regmap)) 747 return PTR_ERR(regmap); 748 749 clk_lucid_evo_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); 750 clk_lucid_evo_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll0_config); 751 752 /* Keep some clocks always enabled */ 753 qcom_branch_set_clk_en(regmap, 0xe070); /* DISP_CC_SLEEP_CLK */ 754 qcom_branch_set_clk_en(regmap, 0xe054); /* DISP_CC_XO_CLK */ 755 756 return qcom_cc_really_probe(&pdev->dev, &disp_cc_sm4450_desc, regmap); 757 } 758 759 static struct platform_driver disp_cc_sm4450_driver = { 760 .probe = disp_cc_sm4450_probe, 761 .driver = { 762 .name = "dispcc-sm4450", 763 .of_match_table = disp_cc_sm4450_match_table, 764 }, 765 }; 766 767 module_platform_driver(disp_cc_sm4450_driver); 768 769 MODULE_DESCRIPTION("QTI DISPCC SM4450 Driver"); 770 MODULE_LICENSE("GPL"); 771