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