1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. 4 * Copyright (c) 2025, Luca Weiss <luca.weiss@fairphone.com> 5 */ 6 7 #include <linux/clk-provider.h> 8 #include <linux/kernel.h> 9 #include <linux/module.h> 10 #include <linux/platform_device.h> 11 #include <linux/regmap.h> 12 13 #include <dt-bindings/clock/qcom,milos-dispcc.h> 14 15 #include "common.h" 16 #include "clk-alpha-pll.h" 17 #include "clk-branch.h" 18 #include "clk-pll.h" 19 #include "clk-rcg.h" 20 #include "clk-regmap.h" 21 #include "clk-regmap-divider.h" 22 #include "clk-regmap-mux.h" 23 #include "reset.h" 24 #include "gdsc.h" 25 26 /* Need to match the order of clocks in DT binding */ 27 enum { 28 DT_BI_TCXO, 29 DT_SLEEP_CLK, 30 DT_AHB_CLK, 31 DT_GCC_DISP_GPLL0_CLK, 32 DT_DSI0_PHY_PLL_OUT_BYTECLK, 33 DT_DSI0_PHY_PLL_OUT_DSICLK, 34 DT_DP0_PHY_PLL_LINK_CLK, 35 DT_DP0_PHY_PLL_VCO_DIV_CLK, 36 }; 37 38 #define DISP_CC_MISC_CMD 0xF000 39 40 enum { 41 P_BI_TCXO, 42 P_DISP_CC_PLL0_OUT_EVEN, 43 P_DISP_CC_PLL0_OUT_MAIN, 44 P_DP0_PHY_PLL_LINK_CLK, 45 P_DP0_PHY_PLL_VCO_DIV_CLK, 46 P_DSI0_PHY_PLL_OUT_BYTECLK, 47 P_DSI0_PHY_PLL_OUT_DSICLK, 48 P_GCC_DISP_GPLL0_CLK, 49 P_SLEEP_CLK, 50 }; 51 52 static const struct pll_vco lucid_ole_vco[] = { 53 { 249600000, 2300000000, 0 }, 54 }; 55 56 /* 257.142858 MHz Configuration */ 57 static const struct alpha_pll_config disp_cc_pll0_config = { 58 .l = 0xd, 59 .alpha = 0x6492, 60 .config_ctl_val = 0x20485699, 61 .config_ctl_hi_val = 0x00182261, 62 .config_ctl_hi1_val = 0x82aa299c, 63 .test_ctl_val = 0x00000000, 64 .test_ctl_hi_val = 0x00000003, 65 .test_ctl_hi1_val = 0x00009000, 66 .test_ctl_hi2_val = 0x00000034, 67 .user_ctl_val = 0x00000000, 68 .user_ctl_hi_val = 0x00000005, 69 }; 70 71 static struct clk_alpha_pll disp_cc_pll0 = { 72 .offset = 0x0, 73 .config = &disp_cc_pll0_config, 74 .vco_table = lucid_ole_vco, 75 .num_vco = ARRAY_SIZE(lucid_ole_vco), 76 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], 77 .clkr = { 78 .hw.init = &(const struct clk_init_data) { 79 .name = "disp_cc_pll0", 80 .parent_data = &(const struct clk_parent_data) { 81 .index = DT_BI_TCXO, 82 }, 83 .num_parents = 1, 84 .ops = &clk_alpha_pll_lucid_evo_ops, 85 }, 86 }, 87 }; 88 89 static const struct parent_map disp_cc_parent_map_0[] = { 90 { P_BI_TCXO, 0 }, 91 }; 92 93 static const struct clk_parent_data disp_cc_parent_data_0[] = { 94 { .index = DT_BI_TCXO }, 95 }; 96 97 static const struct parent_map disp_cc_parent_map_1[] = { 98 { P_BI_TCXO, 0 }, 99 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, 100 { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, 101 }; 102 103 static const struct clk_parent_data disp_cc_parent_data_1[] = { 104 { .index = DT_BI_TCXO }, 105 { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, 106 { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, 107 }; 108 109 static const struct parent_map disp_cc_parent_map_2[] = { 110 { P_BI_TCXO, 0 }, 111 { P_DP0_PHY_PLL_LINK_CLK, 1 }, 112 { P_DP0_PHY_PLL_VCO_DIV_CLK, 2 }, 113 }; 114 115 static const struct clk_parent_data disp_cc_parent_data_2[] = { 116 { .index = DT_BI_TCXO }, 117 { .index = DT_DP0_PHY_PLL_LINK_CLK }, 118 { .index = DT_DP0_PHY_PLL_VCO_DIV_CLK }, 119 }; 120 121 static const struct parent_map disp_cc_parent_map_3[] = { 122 { P_BI_TCXO, 0 }, 123 { P_GCC_DISP_GPLL0_CLK, 4 }, 124 }; 125 126 static const struct clk_parent_data disp_cc_parent_data_3[] = { 127 { .index = DT_BI_TCXO }, 128 { .index = DT_GCC_DISP_GPLL0_CLK }, 129 }; 130 131 static const struct parent_map disp_cc_parent_map_4[] = { 132 { P_BI_TCXO, 0 }, 133 { P_DP0_PHY_PLL_LINK_CLK, 1 }, 134 }; 135 136 static const struct clk_parent_data disp_cc_parent_data_4[] = { 137 { .index = DT_BI_TCXO }, 138 { .index = DT_DP0_PHY_PLL_LINK_CLK }, 139 }; 140 141 static const struct parent_map disp_cc_parent_map_5[] = { 142 { P_BI_TCXO, 0 }, 143 { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, 144 }; 145 146 static const struct clk_parent_data disp_cc_parent_data_5[] = { 147 { .index = DT_BI_TCXO }, 148 { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, 149 }; 150 151 static const struct parent_map disp_cc_parent_map_6[] = { 152 { P_BI_TCXO, 0 }, 153 { P_DISP_CC_PLL0_OUT_MAIN, 1 }, 154 { P_GCC_DISP_GPLL0_CLK, 4 }, 155 { P_DISP_CC_PLL0_OUT_EVEN, 6 }, 156 }; 157 158 static const struct clk_parent_data disp_cc_parent_data_6[] = { 159 { .index = DT_BI_TCXO }, 160 { .hw = &disp_cc_pll0.clkr.hw }, 161 { .index = DT_GCC_DISP_GPLL0_CLK }, 162 { .hw = &disp_cc_pll0.clkr.hw }, 163 }; 164 165 static const struct parent_map disp_cc_parent_map_7[] = { 166 { P_SLEEP_CLK, 0 }, 167 }; 168 169 static const struct clk_parent_data disp_cc_parent_data_7_ao[] = { 170 { .index = DT_SLEEP_CLK }, 171 }; 172 173 static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { 174 F(19200000, P_BI_TCXO, 1, 0, 0), 175 F(37500000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0), 176 F(75000000, P_GCC_DISP_GPLL0_CLK, 4, 0, 0), 177 { } 178 }; 179 180 static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { 181 .cmd_rcgr = 0x8130, 182 .mnd_width = 0, 183 .hid_width = 5, 184 .parent_map = disp_cc_parent_map_3, 185 .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, 186 .clkr.hw.init = &(const struct clk_init_data) { 187 .name = "disp_cc_mdss_ahb_clk_src", 188 .parent_data = disp_cc_parent_data_3, 189 .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), 190 .flags = CLK_SET_RATE_PARENT, 191 .ops = &clk_rcg2_shared_ops, 192 }, 193 }; 194 195 static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { 196 .cmd_rcgr = 0x8098, 197 .mnd_width = 0, 198 .hid_width = 5, 199 .parent_map = disp_cc_parent_map_1, 200 .clkr.hw.init = &(const struct clk_init_data) { 201 .name = "disp_cc_mdss_byte0_clk_src", 202 .parent_data = disp_cc_parent_data_1, 203 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), 204 .flags = CLK_SET_RATE_PARENT, 205 .ops = &clk_byte2_ops, 206 }, 207 }; 208 209 static const struct freq_tbl ftbl_disp_cc_mdss_dptx0_aux_clk_src[] = { 210 F(19200000, P_BI_TCXO, 1, 0, 0), 211 { } 212 }; 213 214 static struct clk_rcg2 disp_cc_mdss_dptx0_aux_clk_src = { 215 .cmd_rcgr = 0x8118, 216 .mnd_width = 0, 217 .hid_width = 5, 218 .parent_map = disp_cc_parent_map_0, 219 .freq_tbl = ftbl_disp_cc_mdss_dptx0_aux_clk_src, 220 .clkr.hw.init = &(const struct clk_init_data) { 221 .name = "disp_cc_mdss_dptx0_aux_clk_src", 222 .parent_data = disp_cc_parent_data_0, 223 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 224 .flags = CLK_SET_RATE_PARENT, 225 .ops = &clk_rcg2_ops, 226 }, 227 }; 228 229 static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = { 230 .cmd_rcgr = 0x80cc, 231 .mnd_width = 0, 232 .hid_width = 5, 233 .parent_map = disp_cc_parent_map_4, 234 .clkr.hw.init = &(const struct clk_init_data) { 235 .name = "disp_cc_mdss_dptx0_link_clk_src", 236 .parent_data = disp_cc_parent_data_4, 237 .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), 238 .flags = CLK_SET_RATE_PARENT, 239 .ops = &clk_byte2_ops, 240 }, 241 }; 242 243 static struct clk_rcg2 disp_cc_mdss_dptx0_pixel0_clk_src = { 244 .cmd_rcgr = 0x80e8, 245 .mnd_width = 16, 246 .hid_width = 5, 247 .parent_map = disp_cc_parent_map_2, 248 .clkr.hw.init = &(const struct clk_init_data) { 249 .name = "disp_cc_mdss_dptx0_pixel0_clk_src", 250 .parent_data = disp_cc_parent_data_2, 251 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), 252 .flags = CLK_SET_RATE_PARENT, 253 .ops = &clk_dp_ops, 254 }, 255 }; 256 257 static struct clk_rcg2 disp_cc_mdss_dptx0_pixel1_clk_src = { 258 .cmd_rcgr = 0x8100, 259 .mnd_width = 16, 260 .hid_width = 5, 261 .parent_map = disp_cc_parent_map_2, 262 .clkr.hw.init = &(const struct clk_init_data) { 263 .name = "disp_cc_mdss_dptx0_pixel1_clk_src", 264 .parent_data = disp_cc_parent_data_2, 265 .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), 266 .flags = CLK_SET_RATE_PARENT, 267 .ops = &clk_dp_ops, 268 }, 269 }; 270 271 static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = { 272 F(9600000, P_BI_TCXO, 2, 0, 0), 273 F(12800000, P_BI_TCXO, 1.5, 0, 0), 274 F(19200000, P_BI_TCXO, 1, 0, 0), 275 { } 276 }; 277 static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { 278 .cmd_rcgr = 0x80b4, 279 .mnd_width = 0, 280 .hid_width = 5, 281 .parent_map = disp_cc_parent_map_5, 282 .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, 283 .clkr.hw.init = &(const struct clk_init_data) { 284 .name = "disp_cc_mdss_esc0_clk_src", 285 .parent_data = disp_cc_parent_data_5, 286 .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), 287 .flags = CLK_SET_RATE_PARENT, 288 .ops = &clk_rcg2_ops, 289 }, 290 }; 291 292 static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { 293 F(19200000, P_BI_TCXO, 1, 0, 0), 294 F(85714286, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 295 F(100000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 296 F(200000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 297 F(342000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 298 F(402000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 299 F(535000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 300 F(600000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 301 F(630000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 302 { } 303 }; 304 305 static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { 306 .cmd_rcgr = 0x8068, 307 .mnd_width = 0, 308 .hid_width = 5, 309 .parent_map = disp_cc_parent_map_6, 310 .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, 311 .clkr.hw.init = &(const struct clk_init_data) { 312 .name = "disp_cc_mdss_mdp_clk_src", 313 .parent_data = disp_cc_parent_data_6, 314 .num_parents = ARRAY_SIZE(disp_cc_parent_data_6), 315 .flags = CLK_SET_RATE_PARENT, 316 .ops = &clk_rcg2_shared_ops, 317 }, 318 }; 319 320 static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { 321 .cmd_rcgr = 0x8050, 322 .mnd_width = 8, 323 .hid_width = 5, 324 .parent_map = disp_cc_parent_map_1, 325 .clkr.hw.init = &(const struct clk_init_data) { 326 .name = "disp_cc_mdss_pclk0_clk_src", 327 .parent_data = disp_cc_parent_data_1, 328 .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), 329 .flags = CLK_SET_RATE_PARENT, 330 .ops = &clk_pixel_ops, 331 }, 332 }; 333 334 static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { 335 .cmd_rcgr = 0x8080, 336 .mnd_width = 0, 337 .hid_width = 5, 338 .parent_map = disp_cc_parent_map_0, 339 .freq_tbl = ftbl_disp_cc_mdss_dptx0_aux_clk_src, 340 .clkr.hw.init = &(const struct clk_init_data) { 341 .name = "disp_cc_mdss_vsync_clk_src", 342 .parent_data = disp_cc_parent_data_0, 343 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 344 .flags = CLK_SET_RATE_PARENT, 345 .ops = &clk_rcg2_ops, 346 }, 347 }; 348 349 static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = { 350 F(32000, P_SLEEP_CLK, 1, 0, 0), 351 { } 352 }; 353 354 static struct clk_rcg2 disp_cc_sleep_clk_src = { 355 .cmd_rcgr = 0xe054, 356 .mnd_width = 0, 357 .hid_width = 5, 358 .parent_map = disp_cc_parent_map_7, 359 .freq_tbl = ftbl_disp_cc_sleep_clk_src, 360 .clkr.hw.init = &(const struct clk_init_data) { 361 .name = "disp_cc_sleep_clk_src", 362 .parent_data = disp_cc_parent_data_7_ao, 363 .num_parents = ARRAY_SIZE(disp_cc_parent_data_7_ao), 364 .flags = CLK_SET_RATE_PARENT, 365 .ops = &clk_rcg2_ops, 366 }, 367 }; 368 369 static struct clk_rcg2 disp_cc_xo_clk_src = { 370 .cmd_rcgr = 0xe034, 371 .mnd_width = 0, 372 .hid_width = 5, 373 .parent_map = disp_cc_parent_map_0, 374 .freq_tbl = ftbl_disp_cc_mdss_dptx0_aux_clk_src, 375 .clkr.hw.init = &(const struct clk_init_data) { 376 .name = "disp_cc_xo_clk_src", 377 .parent_data = disp_cc_parent_data_0, 378 .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 379 .flags = CLK_SET_RATE_PARENT, 380 .ops = &clk_rcg2_ops, 381 }, 382 }; 383 384 static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { 385 .reg = 0x80b0, 386 .shift = 0, 387 .width = 4, 388 .clkr.hw.init = &(const struct clk_init_data) { 389 .name = "disp_cc_mdss_byte0_div_clk_src", 390 .parent_hws = (const struct clk_hw*[]) { 391 &disp_cc_mdss_byte0_clk_src.clkr.hw, 392 }, 393 .num_parents = 1, 394 .ops = &clk_regmap_div_ops, 395 }, 396 }; 397 398 static struct clk_regmap_div disp_cc_mdss_dptx0_link_div_clk_src = { 399 .reg = 0x80e4, 400 .shift = 0, 401 .width = 4, 402 .clkr.hw.init = &(const struct clk_init_data) { 403 .name = "disp_cc_mdss_dptx0_link_div_clk_src", 404 .parent_hws = (const struct clk_hw*[]) { 405 &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, 406 }, 407 .num_parents = 1, 408 .flags = CLK_SET_RATE_PARENT, 409 .ops = &clk_regmap_div_ro_ops, 410 }, 411 }; 412 413 static struct clk_branch disp_cc_mdss_accu_clk = { 414 .halt_reg = 0xe050, 415 .halt_check = BRANCH_HALT_VOTED, 416 .clkr = { 417 .enable_reg = 0xe050, 418 .enable_mask = BIT(0), 419 .hw.init = &(const struct clk_init_data) { 420 .name = "disp_cc_mdss_accu_clk", 421 .parent_hws = (const struct clk_hw*[]) { 422 &disp_cc_xo_clk_src.clkr.hw, 423 }, 424 .num_parents = 1, 425 .flags = CLK_SET_RATE_PARENT, 426 .ops = &clk_branch2_ops, 427 }, 428 }, 429 }; 430 431 static struct clk_branch disp_cc_mdss_ahb1_clk = { 432 .halt_reg = 0xa020, 433 .halt_check = BRANCH_HALT, 434 .clkr = { 435 .enable_reg = 0xa020, 436 .enable_mask = BIT(0), 437 .hw.init = &(const struct clk_init_data) { 438 .name = "disp_cc_mdss_ahb1_clk", 439 .parent_hws = (const struct clk_hw*[]) { 440 &disp_cc_mdss_ahb_clk_src.clkr.hw, 441 }, 442 .num_parents = 1, 443 .flags = CLK_SET_RATE_PARENT, 444 .ops = &clk_branch2_ops, 445 }, 446 }, 447 }; 448 449 static struct clk_branch disp_cc_mdss_ahb_clk = { 450 .halt_reg = 0x804c, 451 .halt_check = BRANCH_HALT, 452 .clkr = { 453 .enable_reg = 0x804c, 454 .enable_mask = BIT(0), 455 .hw.init = &(const struct clk_init_data) { 456 .name = "disp_cc_mdss_ahb_clk", 457 .parent_hws = (const struct clk_hw*[]) { 458 &disp_cc_mdss_ahb_clk_src.clkr.hw, 459 }, 460 .num_parents = 1, 461 .flags = CLK_SET_RATE_PARENT, 462 .ops = &clk_branch2_ops, 463 }, 464 }, 465 }; 466 467 static struct clk_branch disp_cc_mdss_byte0_clk = { 468 .halt_reg = 0x8024, 469 .halt_check = BRANCH_HALT, 470 .clkr = { 471 .enable_reg = 0x8024, 472 .enable_mask = BIT(0), 473 .hw.init = &(const struct clk_init_data) { 474 .name = "disp_cc_mdss_byte0_clk", 475 .parent_hws = (const struct clk_hw*[]) { 476 &disp_cc_mdss_byte0_clk_src.clkr.hw, 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_byte0_intf_clk = { 486 .halt_reg = 0x8028, 487 .halt_check = BRANCH_HALT, 488 .clkr = { 489 .enable_reg = 0x8028, 490 .enable_mask = BIT(0), 491 .hw.init = &(const struct clk_init_data) { 492 .name = "disp_cc_mdss_byte0_intf_clk", 493 .parent_hws = (const struct clk_hw*[]) { 494 &disp_cc_mdss_byte0_div_clk_src.clkr.hw, 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_dptx0_aux_clk = { 504 .halt_reg = 0x8048, 505 .halt_check = BRANCH_HALT, 506 .clkr = { 507 .enable_reg = 0x8048, 508 .enable_mask = BIT(0), 509 .hw.init = &(const struct clk_init_data) { 510 .name = "disp_cc_mdss_dptx0_aux_clk", 511 .parent_hws = (const struct clk_hw*[]) { 512 &disp_cc_mdss_dptx0_aux_clk_src.clkr.hw, 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_dptx0_crypto_clk = { 522 .halt_reg = 0x803c, 523 .halt_check = BRANCH_HALT, 524 .clkr = { 525 .enable_reg = 0x803c, 526 .enable_mask = BIT(0), 527 .hw.init = &(const struct clk_init_data) { 528 .name = "disp_cc_mdss_dptx0_crypto_clk", 529 .parent_hws = (const struct clk_hw*[]) { 530 &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, 531 }, 532 .num_parents = 1, 533 .flags = CLK_SET_RATE_PARENT, 534 .ops = &clk_branch2_ops, 535 }, 536 }, 537 }; 538 539 static struct clk_branch disp_cc_mdss_dptx0_link_clk = { 540 .halt_reg = 0x8030, 541 .halt_check = BRANCH_HALT, 542 .clkr = { 543 .enable_reg = 0x8030, 544 .enable_mask = BIT(0), 545 .hw.init = &(const struct clk_init_data) { 546 .name = "disp_cc_mdss_dptx0_link_clk", 547 .parent_hws = (const struct clk_hw*[]) { 548 &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, 549 }, 550 .num_parents = 1, 551 .flags = CLK_SET_RATE_PARENT, 552 .ops = &clk_branch2_ops, 553 }, 554 }, 555 }; 556 557 static struct clk_branch disp_cc_mdss_dptx0_link_intf_clk = { 558 .halt_reg = 0x8038, 559 .halt_check = BRANCH_HALT, 560 .clkr = { 561 .enable_reg = 0x8038, 562 .enable_mask = BIT(0), 563 .hw.init = &(const struct clk_init_data) { 564 .name = "disp_cc_mdss_dptx0_link_intf_clk", 565 .parent_hws = (const struct clk_hw*[]) { 566 &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw, 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_dptx0_pixel0_clk = { 576 .halt_reg = 0x8040, 577 .halt_check = BRANCH_HALT, 578 .clkr = { 579 .enable_reg = 0x8040, 580 .enable_mask = BIT(0), 581 .hw.init = &(const struct clk_init_data) { 582 .name = "disp_cc_mdss_dptx0_pixel0_clk", 583 .parent_hws = (const struct clk_hw*[]) { 584 &disp_cc_mdss_dptx0_pixel0_clk_src.clkr.hw, 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_dptx0_pixel1_clk = { 594 .halt_reg = 0x8044, 595 .halt_check = BRANCH_HALT, 596 .clkr = { 597 .enable_reg = 0x8044, 598 .enable_mask = BIT(0), 599 .hw.init = &(const struct clk_init_data) { 600 .name = "disp_cc_mdss_dptx0_pixel1_clk", 601 .parent_hws = (const struct clk_hw*[]) { 602 &disp_cc_mdss_dptx0_pixel1_clk_src.clkr.hw, 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_dptx0_usb_router_link_intf_clk = { 612 .halt_reg = 0x8034, 613 .halt_check = BRANCH_HALT, 614 .clkr = { 615 .enable_reg = 0x8034, 616 .enable_mask = BIT(0), 617 .hw.init = &(const struct clk_init_data) { 618 .name = "disp_cc_mdss_dptx0_usb_router_link_intf_clk", 619 .parent_hws = (const struct clk_hw*[]) { 620 &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw, 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_esc0_clk = { 630 .halt_reg = 0x802c, 631 .halt_check = BRANCH_HALT, 632 .clkr = { 633 .enable_reg = 0x802c, 634 .enable_mask = BIT(0), 635 .hw.init = &(const struct clk_init_data) { 636 .name = "disp_cc_mdss_esc0_clk", 637 .parent_hws = (const struct clk_hw*[]) { 638 &disp_cc_mdss_esc0_clk_src.clkr.hw, 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_mdp1_clk = { 648 .halt_reg = 0xa004, 649 .halt_check = BRANCH_HALT, 650 .clkr = { 651 .enable_reg = 0xa004, 652 .enable_mask = BIT(0), 653 .hw.init = &(const struct clk_init_data) { 654 .name = "disp_cc_mdss_mdp1_clk", 655 .parent_hws = (const struct clk_hw*[]) { 656 &disp_cc_mdss_mdp_clk_src.clkr.hw, 657 }, 658 .num_parents = 1, 659 .flags = CLK_SET_RATE_PARENT, 660 .ops = &clk_branch2_ops, 661 }, 662 }, 663 }; 664 665 static struct clk_branch disp_cc_mdss_mdp_clk = { 666 .halt_reg = 0x8008, 667 .halt_check = BRANCH_HALT, 668 .clkr = { 669 .enable_reg = 0x8008, 670 .enable_mask = BIT(0), 671 .hw.init = &(const struct clk_init_data) { 672 .name = "disp_cc_mdss_mdp_clk", 673 .parent_hws = (const struct clk_hw*[]) { 674 &disp_cc_mdss_mdp_clk_src.clkr.hw, 675 }, 676 .num_parents = 1, 677 .flags = CLK_SET_RATE_PARENT, 678 .ops = &clk_branch2_ops, 679 }, 680 }, 681 }; 682 683 static struct clk_branch disp_cc_mdss_mdp_lut1_clk = { 684 .halt_reg = 0xa010, 685 .halt_check = BRANCH_HALT, 686 .clkr = { 687 .enable_reg = 0xa010, 688 .enable_mask = BIT(0), 689 .hw.init = &(const struct clk_init_data) { 690 .name = "disp_cc_mdss_mdp_lut1_clk", 691 .parent_hws = (const struct clk_hw*[]) { 692 &disp_cc_mdss_mdp_clk_src.clkr.hw, 693 }, 694 .num_parents = 1, 695 .flags = CLK_SET_RATE_PARENT, 696 .ops = &clk_branch2_ops, 697 }, 698 }, 699 }; 700 701 static struct clk_branch disp_cc_mdss_mdp_lut_clk = { 702 .halt_reg = 0x8014, 703 .halt_check = BRANCH_HALT_VOTED, 704 .clkr = { 705 .enable_reg = 0x8014, 706 .enable_mask = BIT(0), 707 .hw.init = &(const struct clk_init_data) { 708 .name = "disp_cc_mdss_mdp_lut_clk", 709 .parent_hws = (const struct clk_hw*[]) { 710 &disp_cc_mdss_mdp_clk_src.clkr.hw, 711 }, 712 .num_parents = 1, 713 .flags = CLK_SET_RATE_PARENT, 714 .ops = &clk_branch2_ops, 715 }, 716 }, 717 }; 718 719 static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = { 720 .halt_reg = 0xc004, 721 .halt_check = BRANCH_HALT_VOTED, 722 .clkr = { 723 .enable_reg = 0xc004, 724 .enable_mask = BIT(0), 725 .hw.init = &(const struct clk_init_data) { 726 .name = "disp_cc_mdss_non_gdsc_ahb_clk", 727 .parent_hws = (const struct clk_hw*[]) { 728 &disp_cc_mdss_ahb_clk_src.clkr.hw, 729 }, 730 .num_parents = 1, 731 .flags = CLK_SET_RATE_PARENT, 732 .ops = &clk_branch2_ops, 733 }, 734 }, 735 }; 736 737 static struct clk_branch disp_cc_mdss_pclk0_clk = { 738 .halt_reg = 0x8004, 739 .halt_check = BRANCH_HALT, 740 .clkr = { 741 .enable_reg = 0x8004, 742 .enable_mask = BIT(0), 743 .hw.init = &(const struct clk_init_data) { 744 .name = "disp_cc_mdss_pclk0_clk", 745 .parent_hws = (const struct clk_hw*[]) { 746 &disp_cc_mdss_pclk0_clk_src.clkr.hw, 747 }, 748 .num_parents = 1, 749 .flags = CLK_SET_RATE_PARENT, 750 .ops = &clk_branch2_ops, 751 }, 752 }, 753 }; 754 755 static struct clk_branch disp_cc_mdss_rscc_ahb_clk = { 756 .halt_reg = 0xc00c, 757 .halt_check = BRANCH_HALT, 758 .clkr = { 759 .enable_reg = 0xc00c, 760 .enable_mask = BIT(0), 761 .hw.init = &(const struct clk_init_data) { 762 .name = "disp_cc_mdss_rscc_ahb_clk", 763 .parent_hws = (const struct clk_hw*[]) { 764 &disp_cc_mdss_ahb_clk_src.clkr.hw, 765 }, 766 .num_parents = 1, 767 .flags = CLK_SET_RATE_PARENT, 768 .ops = &clk_branch2_ops, 769 }, 770 }, 771 }; 772 773 static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { 774 .halt_reg = 0xc008, 775 .halt_check = BRANCH_HALT, 776 .clkr = { 777 .enable_reg = 0xc008, 778 .enable_mask = BIT(0), 779 .hw.init = &(const struct clk_init_data) { 780 .name = "disp_cc_mdss_rscc_vsync_clk", 781 .parent_hws = (const struct clk_hw*[]) { 782 &disp_cc_mdss_vsync_clk_src.clkr.hw, 783 }, 784 .num_parents = 1, 785 .flags = CLK_SET_RATE_PARENT, 786 .ops = &clk_branch2_ops, 787 }, 788 }, 789 }; 790 791 static struct clk_branch disp_cc_mdss_vsync1_clk = { 792 .halt_reg = 0xa01c, 793 .halt_check = BRANCH_HALT, 794 .clkr = { 795 .enable_reg = 0xa01c, 796 .enable_mask = BIT(0), 797 .hw.init = &(const struct clk_init_data) { 798 .name = "disp_cc_mdss_vsync1_clk", 799 .parent_hws = (const struct clk_hw*[]) { 800 &disp_cc_mdss_vsync_clk_src.clkr.hw, 801 }, 802 .num_parents = 1, 803 .flags = CLK_SET_RATE_PARENT, 804 .ops = &clk_branch2_ops, 805 }, 806 }, 807 }; 808 809 static struct clk_branch disp_cc_mdss_vsync_clk = { 810 .halt_reg = 0x8020, 811 .halt_check = BRANCH_HALT, 812 .clkr = { 813 .enable_reg = 0x8020, 814 .enable_mask = BIT(0), 815 .hw.init = &(const struct clk_init_data) { 816 .name = "disp_cc_mdss_vsync_clk", 817 .parent_hws = (const struct clk_hw*[]) { 818 &disp_cc_mdss_vsync_clk_src.clkr.hw, 819 }, 820 .num_parents = 1, 821 .flags = CLK_SET_RATE_PARENT, 822 .ops = &clk_branch2_ops, 823 }, 824 }, 825 }; 826 827 static struct gdsc disp_cc_mdss_core_gdsc = { 828 .gdscr = 0x9000, 829 .en_rest_wait_val = 0x2, 830 .en_few_wait_val = 0x2, 831 .clk_dis_wait_val = 0xf, 832 .pd = { 833 .name = "disp_cc_mdss_core_gdsc", 834 }, 835 .pwrsts = PWRSTS_OFF_ON, 836 .flags = POLL_CFG_GDSCR | HW_CTRL | RETAIN_FF_ENABLE, 837 }; 838 839 static struct gdsc disp_cc_mdss_core_int2_gdsc = { 840 .gdscr = 0xb000, 841 .en_rest_wait_val = 0x2, 842 .en_few_wait_val = 0x2, 843 .clk_dis_wait_val = 0xf, 844 .pd = { 845 .name = "disp_cc_mdss_core_int2_gdsc", 846 }, 847 .pwrsts = PWRSTS_OFF_ON, 848 .flags = POLL_CFG_GDSCR | HW_CTRL | RETAIN_FF_ENABLE, 849 }; 850 851 static struct clk_regmap *disp_cc_milos_clocks[] = { 852 [DISP_CC_MDSS_ACCU_CLK] = &disp_cc_mdss_accu_clk.clkr, 853 [DISP_CC_MDSS_AHB1_CLK] = &disp_cc_mdss_ahb1_clk.clkr, 854 [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, 855 [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr, 856 [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, 857 [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, 858 [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr, 859 [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, 860 [DISP_CC_MDSS_DPTX0_AUX_CLK] = &disp_cc_mdss_dptx0_aux_clk.clkr, 861 [DISP_CC_MDSS_DPTX0_AUX_CLK_SRC] = &disp_cc_mdss_dptx0_aux_clk_src.clkr, 862 [DISP_CC_MDSS_DPTX0_CRYPTO_CLK] = &disp_cc_mdss_dptx0_crypto_clk.clkr, 863 [DISP_CC_MDSS_DPTX0_LINK_CLK] = &disp_cc_mdss_dptx0_link_clk.clkr, 864 [DISP_CC_MDSS_DPTX0_LINK_CLK_SRC] = &disp_cc_mdss_dptx0_link_clk_src.clkr, 865 [DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx0_link_div_clk_src.clkr, 866 [DISP_CC_MDSS_DPTX0_LINK_INTF_CLK] = &disp_cc_mdss_dptx0_link_intf_clk.clkr, 867 [DISP_CC_MDSS_DPTX0_PIXEL0_CLK] = &disp_cc_mdss_dptx0_pixel0_clk.clkr, 868 [DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx0_pixel0_clk_src.clkr, 869 [DISP_CC_MDSS_DPTX0_PIXEL1_CLK] = &disp_cc_mdss_dptx0_pixel1_clk.clkr, 870 [DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx0_pixel1_clk_src.clkr, 871 [DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK] = 872 &disp_cc_mdss_dptx0_usb_router_link_intf_clk.clkr, 873 [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, 874 [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, 875 [DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr, 876 [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, 877 [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, 878 [DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr, 879 [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, 880 [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr, 881 [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, 882 [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, 883 [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr, 884 [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, 885 [DISP_CC_MDSS_VSYNC1_CLK] = &disp_cc_mdss_vsync1_clk.clkr, 886 [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, 887 [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, 888 [DISP_CC_PLL0] = &disp_cc_pll0.clkr, 889 [DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr, 890 [DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr, 891 }; 892 893 static const struct qcom_reset_map disp_cc_milos_resets[] = { 894 [DISP_CC_MDSS_CORE_BCR] = { 0x8000 }, 895 [DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 }, 896 [DISP_CC_MDSS_RSCC_BCR] = { 0xc000 }, 897 }; 898 899 static struct gdsc *disp_cc_milos_gdscs[] = { 900 [DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc, 901 [DISP_CC_MDSS_CORE_INT2_GDSC] = &disp_cc_mdss_core_int2_gdsc, 902 }; 903 904 static struct clk_alpha_pll *disp_cc_milos_plls[] = { 905 &disp_cc_pll0, 906 }; 907 908 static const u32 disp_cc_milos_critical_cbcrs[] = { 909 0xe06c, /* DISP_CC_SLEEP_CLK */ 910 0xe04c, /* DISP_CC_XO_CLK */ 911 }; 912 913 static const struct regmap_config disp_cc_milos_regmap_config = { 914 .reg_bits = 32, 915 .reg_stride = 4, 916 .val_bits = 32, 917 .max_register = 0x11008, 918 .fast_io = true, 919 }; 920 921 static void disp_cc_milos_clk_regs_configure(struct device *dev, struct regmap *regmap) 922 { 923 /* Enable clock gating for MDP clocks */ 924 regmap_update_bits(regmap, DISP_CC_MISC_CMD, 0x10, 0x10); 925 } 926 927 928 static const struct qcom_cc_driver_data disp_cc_milos_driver_data = { 929 .alpha_plls = disp_cc_milos_plls, 930 .num_alpha_plls = ARRAY_SIZE(disp_cc_milos_plls), 931 .clk_cbcrs = disp_cc_milos_critical_cbcrs, 932 .num_clk_cbcrs = ARRAY_SIZE(disp_cc_milos_critical_cbcrs), 933 .clk_regs_configure = disp_cc_milos_clk_regs_configure, 934 }; 935 936 static const struct qcom_cc_desc disp_cc_milos_desc = { 937 .config = &disp_cc_milos_regmap_config, 938 .clks = disp_cc_milos_clocks, 939 .num_clks = ARRAY_SIZE(disp_cc_milos_clocks), 940 .resets = disp_cc_milos_resets, 941 .num_resets = ARRAY_SIZE(disp_cc_milos_resets), 942 .gdscs = disp_cc_milos_gdscs, 943 .num_gdscs = ARRAY_SIZE(disp_cc_milos_gdscs), 944 .use_rpm = true, 945 .driver_data = &disp_cc_milos_driver_data, 946 }; 947 948 static const struct of_device_id disp_cc_milos_match_table[] = { 949 { .compatible = "qcom,milos-dispcc" }, 950 { } 951 }; 952 MODULE_DEVICE_TABLE(of, disp_cc_milos_match_table); 953 954 static int disp_cc_milos_probe(struct platform_device *pdev) 955 { 956 return qcom_cc_probe(pdev, &disp_cc_milos_desc); 957 } 958 959 static struct platform_driver disp_cc_milos_driver = { 960 .probe = disp_cc_milos_probe, 961 .driver = { 962 .name = "disp_cc-milos", 963 .of_match_table = disp_cc_milos_match_table, 964 }, 965 }; 966 967 module_platform_driver(disp_cc_milos_driver); 968 969 MODULE_DESCRIPTION("QTI DISP_CC Milos Driver"); 970 MODULE_LICENSE("GPL"); 971