1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2018, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2024, Danila Tikhonov <danila@jiaxyga.com> 5 * Copyright (c) 2024, David Wronek <david@mainlining.org> 6 */ 7 8 #include <linux/clk-provider.h> 9 #include <linux/mod_devicetable.h> 10 #include <linux/module.h> 11 #include <linux/platform_device.h> 12 #include <linux/regmap.h> 13 14 #include <dt-bindings/clock/qcom,sm7150-dispcc.h> 15 16 #include "clk-alpha-pll.h" 17 #include "clk-branch.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 24 enum { 25 DT_BI_TCXO, 26 DT_BI_TCXO_AO, 27 DT_GCC_DISP_GPLL0_CLK, 28 DT_CHIP_SLEEP_CLK, 29 DT_DSI0_PHY_PLL_OUT_BYTECLK, 30 DT_DSI0_PHY_PLL_OUT_DSICLK, 31 DT_DSI1_PHY_PLL_OUT_BYTECLK, 32 DT_DSI1_PHY_PLL_OUT_DSICLK, 33 DT_DP_PHY_PLL_LINK_CLK, 34 DT_DP_PHY_PLL_VCO_DIV_CLK, 35 }; 36 37 enum { 38 P_BI_TCXO, 39 P_CHIP_SLEEP_CLK, 40 P_DISPCC_PLL0_OUT_EVEN, 41 P_DISPCC_PLL0_OUT_MAIN, 42 P_DP_PHY_PLL_LINK_CLK, 43 P_DP_PHY_PLL_VCO_DIV_CLK, 44 P_DSI0_PHY_PLL_OUT_BYTECLK, 45 P_DSI0_PHY_PLL_OUT_DSICLK, 46 P_DSI1_PHY_PLL_OUT_BYTECLK, 47 P_DSI1_PHY_PLL_OUT_DSICLK, 48 P_GCC_DISP_GPLL0_CLK, 49 }; 50 51 static const struct pll_vco fabia_vco[] = { 52 { 249600000, 2000000000, 0 }, 53 { 125000000, 1000000000, 1 }, 54 }; 55 56 /* 860MHz configuration */ 57 static const struct alpha_pll_config dispcc_pll0_config = { 58 .l = 0x2c, 59 .alpha = 0xcaaa, 60 .test_ctl_val = 0x40000000, 61 }; 62 63 static struct clk_alpha_pll dispcc_pll0 = { 64 .offset = 0x0, 65 .vco_table = fabia_vco, 66 .num_vco = ARRAY_SIZE(fabia_vco), 67 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], 68 .clkr = { 69 .hw.init = &(const struct clk_init_data) { 70 .name = "dispcc_pll0", 71 .parent_data = &(const struct clk_parent_data) { 72 .index = DT_BI_TCXO, 73 }, 74 .num_parents = 1, 75 .ops = &clk_alpha_pll_fabia_ops, 76 }, 77 }, 78 }; 79 80 static const struct parent_map dispcc_parent_map_0[] = { 81 { P_BI_TCXO, 0 }, 82 { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, 83 { P_DSI1_PHY_PLL_OUT_BYTECLK, 2 }, 84 }; 85 86 static const struct clk_parent_data dispcc_parent_data_0[] = { 87 { .index = DT_BI_TCXO }, 88 { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, 89 { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK }, 90 }; 91 92 static const struct parent_map dispcc_parent_map_1[] = { 93 { P_BI_TCXO, 0 }, 94 { P_DP_PHY_PLL_LINK_CLK, 1 }, 95 { P_DP_PHY_PLL_VCO_DIV_CLK, 2 }, 96 }; 97 98 static const struct clk_parent_data dispcc_parent_data_1[] = { 99 { .index = DT_BI_TCXO }, 100 { .index = DT_DP_PHY_PLL_LINK_CLK }, 101 { .index = DT_DP_PHY_PLL_VCO_DIV_CLK }, 102 }; 103 104 static const struct parent_map dispcc_parent_map_2[] = { 105 { P_BI_TCXO, 0 }, 106 }; 107 108 static const struct clk_parent_data dispcc_parent_data_2[] = { 109 { .index = DT_BI_TCXO }, 110 }; 111 112 static const struct clk_parent_data dispcc_parent_data_2_ao[] = { 113 { .index = DT_BI_TCXO_AO }, 114 }; 115 116 static const struct parent_map dispcc_parent_map_3[] = { 117 { P_BI_TCXO, 0 }, 118 { P_DISPCC_PLL0_OUT_MAIN, 1 }, 119 { P_GCC_DISP_GPLL0_CLK, 4 }, 120 { P_DISPCC_PLL0_OUT_EVEN, 5 }, 121 }; 122 123 static const struct clk_parent_data dispcc_parent_data_3[] = { 124 { .index = DT_BI_TCXO }, 125 { .hw = &dispcc_pll0.clkr.hw }, 126 { .index = DT_GCC_DISP_GPLL0_CLK }, 127 { .hw = &dispcc_pll0.clkr.hw }, 128 }; 129 130 static const struct parent_map dispcc_parent_map_4[] = { 131 { P_BI_TCXO, 0 }, 132 { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, 133 { P_DSI1_PHY_PLL_OUT_DSICLK, 2 }, 134 }; 135 136 static const struct clk_parent_data dispcc_parent_data_4[] = { 137 { .index = DT_BI_TCXO }, 138 { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, 139 { .index = DT_DSI1_PHY_PLL_OUT_DSICLK }, 140 }; 141 142 static const struct parent_map dispcc_parent_map_5[] = { 143 { P_BI_TCXO, 0 }, 144 { P_GCC_DISP_GPLL0_CLK, 4 }, 145 }; 146 147 static const struct clk_parent_data dispcc_parent_data_5[] = { 148 { .index = DT_BI_TCXO }, 149 { .index = DT_GCC_DISP_GPLL0_CLK }, 150 }; 151 152 static const struct parent_map dispcc_parent_map_6[] = { 153 { P_CHIP_SLEEP_CLK, 0 }, 154 }; 155 156 static const struct clk_parent_data dispcc_parent_data_6[] = { 157 { .index = DT_CHIP_SLEEP_CLK }, 158 }; 159 160 static const struct freq_tbl ftbl_dispcc_mdss_ahb_clk_src[] = { 161 F(19200000, P_BI_TCXO, 1, 0, 0), 162 F(37500000, P_GCC_DISP_GPLL0_CLK, 16, 0, 0), 163 F(75000000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0), 164 { } 165 }; 166 167 static struct clk_rcg2 dispcc_mdss_ahb_clk_src = { 168 .cmd_rcgr = 0x22bc, 169 .mnd_width = 0, 170 .hid_width = 5, 171 .parent_map = dispcc_parent_map_5, 172 .freq_tbl = ftbl_dispcc_mdss_ahb_clk_src, 173 .clkr.hw.init = &(const struct clk_init_data) { 174 .name = "dispcc_mdss_ahb_clk_src", 175 .parent_data = dispcc_parent_data_5, 176 .num_parents = ARRAY_SIZE(dispcc_parent_data_5), 177 .flags = CLK_SET_RATE_PARENT, 178 .ops = &clk_rcg2_shared_ops, 179 }, 180 }; 181 182 static const struct freq_tbl ftbl_dispcc_mdss_byte0_clk_src[] = { 183 F(19200000, P_BI_TCXO, 1, 0, 0), 184 { } 185 }; 186 187 static struct clk_rcg2 dispcc_mdss_byte0_clk_src = { 188 .cmd_rcgr = 0x2110, 189 .mnd_width = 0, 190 .hid_width = 5, 191 .parent_map = dispcc_parent_map_0, 192 .clkr.hw.init = &(const struct clk_init_data) { 193 .name = "dispcc_mdss_byte0_clk_src", 194 .parent_data = dispcc_parent_data_0, 195 .num_parents = ARRAY_SIZE(dispcc_parent_data_0), 196 .flags = CLK_SET_RATE_PARENT, 197 .ops = &clk_byte2_ops, 198 }, 199 }; 200 201 static struct clk_rcg2 dispcc_mdss_byte1_clk_src = { 202 .cmd_rcgr = 0x212c, 203 .mnd_width = 0, 204 .hid_width = 5, 205 .parent_map = dispcc_parent_map_0, 206 .clkr.hw.init = &(const struct clk_init_data) { 207 .name = "dispcc_mdss_byte1_clk_src", 208 .parent_data = dispcc_parent_data_0, 209 .num_parents = ARRAY_SIZE(dispcc_parent_data_0), 210 .flags = CLK_SET_RATE_PARENT, 211 .ops = &clk_byte2_ops, 212 }, 213 }; 214 215 static struct clk_rcg2 dispcc_mdss_dp_aux_clk_src = { 216 .cmd_rcgr = 0x21dc, 217 .mnd_width = 0, 218 .hid_width = 5, 219 .parent_map = dispcc_parent_map_2, 220 .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src, 221 .clkr.hw.init = &(const struct clk_init_data) { 222 .name = "dispcc_mdss_dp_aux_clk_src", 223 .parent_data = dispcc_parent_data_2, 224 .num_parents = ARRAY_SIZE(dispcc_parent_data_2), 225 .ops = &clk_rcg2_ops, 226 }, 227 }; 228 229 static const struct freq_tbl ftbl_dispcc_mdss_dp_crypto_clk_src[] = { 230 F(108000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0), 231 F(180000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0), 232 F(360000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0), 233 F(540000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0), 234 { } 235 }; 236 237 static struct clk_rcg2 dispcc_mdss_dp_crypto_clk_src = { 238 .cmd_rcgr = 0x2194, 239 .mnd_width = 0, 240 .hid_width = 5, 241 .parent_map = dispcc_parent_map_1, 242 .freq_tbl = ftbl_dispcc_mdss_dp_crypto_clk_src, 243 .clkr.hw.init = &(const struct clk_init_data) { 244 .name = "dispcc_mdss_dp_crypto_clk_src", 245 .parent_data = dispcc_parent_data_1, 246 .num_parents = ARRAY_SIZE(dispcc_parent_data_1), 247 .ops = &clk_rcg2_ops, 248 }, 249 }; 250 251 static struct clk_rcg2 dispcc_mdss_dp_link_clk_src = { 252 .cmd_rcgr = 0x2178, 253 .mnd_width = 0, 254 .hid_width = 5, 255 .parent_map = dispcc_parent_map_1, 256 .clkr.hw.init = &(const struct clk_init_data) { 257 .name = "dispcc_mdss_dp_link_clk_src", 258 .parent_data = dispcc_parent_data_1, 259 .num_parents = ARRAY_SIZE(dispcc_parent_data_1), 260 .flags = CLK_SET_RATE_PARENT, 261 .ops = &clk_byte2_ops, 262 }, 263 }; 264 265 static struct clk_rcg2 dispcc_mdss_dp_pixel1_clk_src = { 266 .cmd_rcgr = 0x21c4, 267 .mnd_width = 16, 268 .hid_width = 5, 269 .parent_map = dispcc_parent_map_1, 270 .clkr.hw.init = &(const struct clk_init_data) { 271 .name = "dispcc_mdss_dp_pixel1_clk_src", 272 .parent_data = dispcc_parent_data_1, 273 .num_parents = ARRAY_SIZE(dispcc_parent_data_1), 274 .flags = CLK_SET_RATE_PARENT, 275 .ops = &clk_dp_ops, 276 }, 277 }; 278 279 static struct clk_rcg2 dispcc_mdss_dp_pixel_clk_src = { 280 .cmd_rcgr = 0x21ac, 281 .mnd_width = 16, 282 .hid_width = 5, 283 .parent_map = dispcc_parent_map_1, 284 .clkr.hw.init = &(const struct clk_init_data) { 285 .name = "dispcc_mdss_dp_pixel_clk_src", 286 .parent_data = dispcc_parent_data_1, 287 .num_parents = ARRAY_SIZE(dispcc_parent_data_1), 288 .flags = CLK_SET_RATE_PARENT, 289 .ops = &clk_dp_ops, 290 }, 291 }; 292 293 static struct clk_rcg2 dispcc_mdss_esc0_clk_src = { 294 .cmd_rcgr = 0x2148, 295 .mnd_width = 0, 296 .hid_width = 5, 297 .parent_map = dispcc_parent_map_0, 298 .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src, 299 .clkr.hw.init = &(const struct clk_init_data) { 300 .name = "dispcc_mdss_esc0_clk_src", 301 .parent_data = dispcc_parent_data_0, 302 .num_parents = ARRAY_SIZE(dispcc_parent_data_0), 303 .ops = &clk_rcg2_ops, 304 }, 305 }; 306 307 static struct clk_rcg2 dispcc_mdss_esc1_clk_src = { 308 .cmd_rcgr = 0x2160, 309 .mnd_width = 0, 310 .hid_width = 5, 311 .parent_map = dispcc_parent_map_0, 312 .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src, 313 .clkr.hw.init = &(const struct clk_init_data) { 314 .name = "dispcc_mdss_esc1_clk_src", 315 .parent_data = dispcc_parent_data_0, 316 .num_parents = ARRAY_SIZE(dispcc_parent_data_0), 317 .ops = &clk_rcg2_ops, 318 }, 319 }; 320 321 static const struct freq_tbl ftbl_dispcc_mdss_mdp_clk_src[] = { 322 F(19200000, P_BI_TCXO, 1, 0, 0), 323 F(85714286, P_GCC_DISP_GPLL0_CLK, 7, 0, 0), 324 F(100000000, P_GCC_DISP_GPLL0_CLK, 6, 0, 0), 325 F(150000000, P_GCC_DISP_GPLL0_CLK, 4, 0, 0), 326 F(172000000, P_DISPCC_PLL0_OUT_MAIN, 5, 0, 0), 327 F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0), 328 F(286666667, P_DISPCC_PLL0_OUT_MAIN, 3, 0, 0), 329 F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0), 330 F(344000000, P_DISPCC_PLL0_OUT_MAIN, 2.5, 0, 0), 331 F(430000000, P_DISPCC_PLL0_OUT_MAIN, 2, 0, 0), 332 { } 333 }; 334 335 static struct clk_rcg2 dispcc_mdss_mdp_clk_src = { 336 .cmd_rcgr = 0x20c8, 337 .mnd_width = 0, 338 .hid_width = 5, 339 .parent_map = dispcc_parent_map_3, 340 .freq_tbl = ftbl_dispcc_mdss_mdp_clk_src, 341 .clkr.hw.init = &(const struct clk_init_data) { 342 .name = "dispcc_mdss_mdp_clk_src", 343 .parent_data = dispcc_parent_data_3, 344 .num_parents = ARRAY_SIZE(dispcc_parent_data_3), 345 .flags = CLK_SET_RATE_PARENT, 346 .ops = &clk_rcg2_shared_ops, 347 }, 348 }; 349 350 static struct clk_rcg2 dispcc_mdss_pclk0_clk_src = { 351 .cmd_rcgr = 0x2098, 352 .mnd_width = 8, 353 .hid_width = 5, 354 .parent_map = dispcc_parent_map_4, 355 .clkr.hw.init = &(const struct clk_init_data) { 356 .name = "dispcc_mdss_pclk0_clk_src", 357 .parent_data = dispcc_parent_data_4, 358 .num_parents = ARRAY_SIZE(dispcc_parent_data_4), 359 .flags = CLK_SET_RATE_PARENT, 360 .ops = &clk_pixel_ops, 361 }, 362 }; 363 364 static struct clk_rcg2 dispcc_mdss_pclk1_clk_src = { 365 .cmd_rcgr = 0x20b0, 366 .mnd_width = 8, 367 .hid_width = 5, 368 .parent_map = dispcc_parent_map_4, 369 .clkr.hw.init = &(const struct clk_init_data) { 370 .name = "dispcc_mdss_pclk1_clk_src", 371 .parent_data = dispcc_parent_data_4, 372 .num_parents = ARRAY_SIZE(dispcc_parent_data_4), 373 .flags = CLK_SET_RATE_PARENT, 374 .ops = &clk_pixel_ops, 375 }, 376 }; 377 378 static const struct freq_tbl ftbl_dispcc_mdss_rot_clk_src[] = { 379 F(19200000, P_BI_TCXO, 1, 0, 0), 380 F(171428571, P_GCC_DISP_GPLL0_CLK, 3.5, 0, 0), 381 F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0), 382 F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0), 383 F(344000000, P_DISPCC_PLL0_OUT_MAIN, 2.5, 0, 0), 384 F(430000000, P_DISPCC_PLL0_OUT_MAIN, 2, 0, 0), 385 { } 386 }; 387 388 static struct clk_rcg2 dispcc_mdss_rot_clk_src = { 389 .cmd_rcgr = 0x20e0, 390 .mnd_width = 0, 391 .hid_width = 5, 392 .parent_map = dispcc_parent_map_3, 393 .freq_tbl = ftbl_dispcc_mdss_rot_clk_src, 394 .clkr.hw.init = &(const struct clk_init_data) { 395 .name = "dispcc_mdss_rot_clk_src", 396 .parent_data = dispcc_parent_data_3, 397 .num_parents = ARRAY_SIZE(dispcc_parent_data_3), 398 .ops = &clk_rcg2_shared_ops, 399 }, 400 }; 401 402 static struct clk_rcg2 dispcc_mdss_vsync_clk_src = { 403 .cmd_rcgr = 0x20f8, 404 .mnd_width = 0, 405 .hid_width = 5, 406 .parent_map = dispcc_parent_map_2, 407 .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src, 408 .clkr.hw.init = &(const struct clk_init_data) { 409 .name = "dispcc_mdss_vsync_clk_src", 410 .parent_data = dispcc_parent_data_2, 411 .num_parents = ARRAY_SIZE(dispcc_parent_data_2), 412 .ops = &clk_rcg2_ops, 413 }, 414 }; 415 416 static const struct freq_tbl ftbl_dispcc_sleep_clk_src[] = { 417 F(32000, P_CHIP_SLEEP_CLK, 1, 0, 0), 418 { } 419 }; 420 421 static struct clk_rcg2 dispcc_sleep_clk_src = { 422 .cmd_rcgr = 0x6060, 423 .mnd_width = 0, 424 .hid_width = 5, 425 .parent_map = dispcc_parent_map_6, 426 .freq_tbl = ftbl_dispcc_sleep_clk_src, 427 .clkr.hw.init = &(const struct clk_init_data) { 428 .name = "dispcc_sleep_clk_src", 429 .parent_data = dispcc_parent_data_6, 430 .num_parents = ARRAY_SIZE(dispcc_parent_data_6), 431 .ops = &clk_rcg2_ops, 432 }, 433 }; 434 435 static struct clk_rcg2 dispcc_xo_clk_src = { 436 .cmd_rcgr = 0x6044, 437 .mnd_width = 0, 438 .hid_width = 5, 439 .parent_map = dispcc_parent_map_2, 440 .freq_tbl = ftbl_dispcc_mdss_byte0_clk_src, 441 .clkr.hw.init = &(const struct clk_init_data) { 442 .name = "dispcc_xo_clk_src", 443 .parent_data = dispcc_parent_data_2_ao, 444 .num_parents = ARRAY_SIZE(dispcc_parent_data_2_ao), 445 .ops = &clk_rcg2_ops, 446 }, 447 }; 448 449 static struct clk_branch dispcc_mdss_ahb_clk = { 450 .halt_reg = 0x2080, 451 .halt_check = BRANCH_HALT, 452 .clkr = { 453 .enable_reg = 0x2080, 454 .enable_mask = BIT(0), 455 .hw.init = &(const struct clk_init_data) { 456 .name = "dispcc_mdss_ahb_clk", 457 .parent_hws = (const struct clk_hw*[]) { 458 &dispcc_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 dispcc_mdss_byte0_clk = { 468 .halt_reg = 0x2028, 469 .halt_check = BRANCH_HALT, 470 .clkr = { 471 .enable_reg = 0x2028, 472 .enable_mask = BIT(0), 473 .hw.init = &(const struct clk_init_data) { 474 .name = "dispcc_mdss_byte0_clk", 475 .parent_hws = (const struct clk_hw*[]) { 476 &dispcc_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_regmap_div dispcc_mdss_byte0_div_clk_src = { 486 .reg = 0x2128, 487 .shift = 0, 488 .width = 2, 489 .clkr = { 490 .hw.init = &(const struct clk_init_data) { 491 .name = "dispcc_mdss_byte0_div_clk_src", 492 .parent_hws = (const struct clk_hw*[]) { 493 &dispcc_mdss_byte0_clk_src.clkr.hw, 494 }, 495 .num_parents = 1, 496 .ops = &clk_regmap_div_ops, 497 }, 498 }, 499 }; 500 501 static struct clk_branch dispcc_mdss_byte0_intf_clk = { 502 .halt_reg = 0x202c, 503 .halt_check = BRANCH_HALT, 504 .clkr = { 505 .enable_reg = 0x202c, 506 .enable_mask = BIT(0), 507 .hw.init = &(const struct clk_init_data) { 508 .name = "dispcc_mdss_byte0_intf_clk", 509 .parent_hws = (const struct clk_hw*[]) { 510 &dispcc_mdss_byte0_div_clk_src.clkr.hw, 511 }, 512 .num_parents = 1, 513 .ops = &clk_branch2_ops, 514 }, 515 }, 516 }; 517 518 static struct clk_branch dispcc_mdss_byte1_clk = { 519 .halt_reg = 0x2030, 520 .halt_check = BRANCH_HALT, 521 .clkr = { 522 .enable_reg = 0x2030, 523 .enable_mask = BIT(0), 524 .hw.init = &(const struct clk_init_data) { 525 .name = "dispcc_mdss_byte1_clk", 526 .parent_hws = (const struct clk_hw*[]) { 527 &dispcc_mdss_byte1_clk_src.clkr.hw, 528 }, 529 .num_parents = 1, 530 .flags = CLK_SET_RATE_PARENT, 531 .ops = &clk_branch2_ops, 532 }, 533 }, 534 }; 535 536 static struct clk_regmap_div dispcc_mdss_byte1_div_clk_src = { 537 .reg = 0x2144, 538 .shift = 0, 539 .width = 2, 540 .clkr = { 541 .hw.init = &(const struct clk_init_data) { 542 .name = "dispcc_mdss_byte1_div_clk_src", 543 .parent_hws = (const struct clk_hw*[]) { 544 &dispcc_mdss_byte1_clk_src.clkr.hw, 545 }, 546 .num_parents = 1, 547 .ops = &clk_regmap_div_ops, 548 }, 549 }, 550 }; 551 552 static struct clk_branch dispcc_mdss_byte1_intf_clk = { 553 .halt_reg = 0x2034, 554 .halt_check = BRANCH_HALT, 555 .clkr = { 556 .enable_reg = 0x2034, 557 .enable_mask = BIT(0), 558 .hw.init = &(const struct clk_init_data) { 559 .name = "dispcc_mdss_byte1_intf_clk", 560 .parent_hws = (const struct clk_hw*[]) { 561 &dispcc_mdss_byte1_div_clk_src.clkr.hw, 562 }, 563 .num_parents = 1, 564 .flags = CLK_SET_RATE_PARENT, 565 .ops = &clk_branch2_ops, 566 }, 567 }, 568 }; 569 570 static struct clk_branch dispcc_mdss_dp_aux_clk = { 571 .halt_reg = 0x2054, 572 .halt_check = BRANCH_HALT, 573 .clkr = { 574 .enable_reg = 0x2054, 575 .enable_mask = BIT(0), 576 .hw.init = &(const struct clk_init_data) { 577 .name = "dispcc_mdss_dp_aux_clk", 578 .parent_hws = (const struct clk_hw*[]) { 579 &dispcc_mdss_dp_aux_clk_src.clkr.hw, 580 }, 581 .num_parents = 1, 582 .flags = CLK_SET_RATE_PARENT, 583 .ops = &clk_branch2_ops, 584 }, 585 }, 586 }; 587 588 static struct clk_branch dispcc_mdss_dp_crypto_clk = { 589 .halt_reg = 0x2048, 590 .halt_check = BRANCH_HALT, 591 .clkr = { 592 .enable_reg = 0x2048, 593 .enable_mask = BIT(0), 594 .hw.init = &(const struct clk_init_data) { 595 .name = "dispcc_mdss_dp_crypto_clk", 596 .parent_hws = (const struct clk_hw*[]) { 597 &dispcc_mdss_dp_crypto_clk_src.clkr.hw, 598 }, 599 .num_parents = 1, 600 .flags = CLK_SET_RATE_PARENT, 601 .ops = &clk_branch2_ops, 602 }, 603 }, 604 }; 605 606 static struct clk_branch dispcc_mdss_dp_link_clk = { 607 .halt_reg = 0x2040, 608 .halt_check = BRANCH_HALT, 609 .clkr = { 610 .enable_reg = 0x2040, 611 .enable_mask = BIT(0), 612 .hw.init = &(const struct clk_init_data) { 613 .name = "dispcc_mdss_dp_link_clk", 614 .parent_hws = (const struct clk_hw*[]) { 615 &dispcc_mdss_dp_link_clk_src.clkr.hw, 616 }, 617 .num_parents = 1, 618 .flags = CLK_SET_RATE_PARENT, 619 .ops = &clk_branch2_ops, 620 }, 621 }, 622 }; 623 624 static struct clk_branch dispcc_mdss_dp_link_intf_clk = { 625 .halt_reg = 0x2044, 626 .halt_check = BRANCH_HALT, 627 .clkr = { 628 .enable_reg = 0x2044, 629 .enable_mask = BIT(0), 630 .hw.init = &(const struct clk_init_data) { 631 .name = "dispcc_mdss_dp_link_intf_clk", 632 .parent_hws = (const struct clk_hw*[]) { 633 &dispcc_mdss_dp_link_clk_src.clkr.hw, 634 }, 635 .num_parents = 1, 636 .ops = &clk_branch2_ops, 637 }, 638 }, 639 }; 640 641 static struct clk_branch dispcc_mdss_dp_pixel1_clk = { 642 .halt_reg = 0x2050, 643 .halt_check = BRANCH_HALT, 644 .clkr = { 645 .enable_reg = 0x2050, 646 .enable_mask = BIT(0), 647 .hw.init = &(const struct clk_init_data) { 648 .name = "dispcc_mdss_dp_pixel1_clk", 649 .parent_hws = (const struct clk_hw*[]) { 650 &dispcc_mdss_dp_pixel1_clk_src.clkr.hw, 651 }, 652 .num_parents = 1, 653 .flags = CLK_SET_RATE_PARENT, 654 .ops = &clk_branch2_ops, 655 }, 656 }, 657 }; 658 659 static struct clk_branch dispcc_mdss_dp_pixel_clk = { 660 .halt_reg = 0x204c, 661 .halt_check = BRANCH_HALT, 662 .clkr = { 663 .enable_reg = 0x204c, 664 .enable_mask = BIT(0), 665 .hw.init = &(const struct clk_init_data) { 666 .name = "dispcc_mdss_dp_pixel_clk", 667 .parent_hws = (const struct clk_hw*[]) { 668 &dispcc_mdss_dp_pixel_clk_src.clkr.hw, 669 }, 670 .num_parents = 1, 671 .flags = CLK_SET_RATE_PARENT, 672 .ops = &clk_branch2_ops, 673 }, 674 }, 675 }; 676 677 static struct clk_branch dispcc_mdss_esc0_clk = { 678 .halt_reg = 0x2038, 679 .halt_check = BRANCH_HALT, 680 .clkr = { 681 .enable_reg = 0x2038, 682 .enable_mask = BIT(0), 683 .hw.init = &(const struct clk_init_data) { 684 .name = "dispcc_mdss_esc0_clk", 685 .parent_hws = (const struct clk_hw*[]) { 686 &dispcc_mdss_esc0_clk_src.clkr.hw, 687 }, 688 .num_parents = 1, 689 .flags = CLK_SET_RATE_PARENT, 690 .ops = &clk_branch2_ops, 691 }, 692 }, 693 }; 694 695 static struct clk_branch dispcc_mdss_esc1_clk = { 696 .halt_reg = 0x203c, 697 .halt_check = BRANCH_HALT, 698 .clkr = { 699 .enable_reg = 0x203c, 700 .enable_mask = BIT(0), 701 .hw.init = &(const struct clk_init_data) { 702 .name = "dispcc_mdss_esc1_clk", 703 .parent_hws = (const struct clk_hw*[]) { 704 &dispcc_mdss_esc1_clk_src.clkr.hw, 705 }, 706 .num_parents = 1, 707 .flags = CLK_SET_RATE_PARENT, 708 .ops = &clk_branch2_ops, 709 }, 710 }, 711 }; 712 713 static struct clk_branch dispcc_mdss_mdp_clk = { 714 .halt_reg = 0x200c, 715 .halt_check = BRANCH_HALT, 716 .clkr = { 717 .enable_reg = 0x200c, 718 .enable_mask = BIT(0), 719 .hw.init = &(const struct clk_init_data) { 720 .name = "dispcc_mdss_mdp_clk", 721 .parent_hws = (const struct clk_hw*[]) { 722 &dispcc_mdss_mdp_clk_src.clkr.hw, 723 }, 724 .num_parents = 1, 725 .flags = CLK_SET_RATE_PARENT, 726 .ops = &clk_branch2_ops, 727 }, 728 }, 729 }; 730 731 static struct clk_branch dispcc_mdss_mdp_lut_clk = { 732 .halt_reg = 0x201c, 733 .halt_check = BRANCH_VOTED, 734 .clkr = { 735 .enable_reg = 0x201c, 736 .enable_mask = BIT(0), 737 .hw.init = &(const struct clk_init_data) { 738 .name = "dispcc_mdss_mdp_lut_clk", 739 .parent_hws = (const struct clk_hw*[]) { 740 &dispcc_mdss_mdp_clk_src.clkr.hw, 741 }, 742 .num_parents = 1, 743 .ops = &clk_branch2_ops, 744 }, 745 }, 746 }; 747 748 static struct clk_branch dispcc_mdss_non_gdsc_ahb_clk = { 749 .halt_reg = 0x4004, 750 .halt_check = BRANCH_VOTED, 751 .clkr = { 752 .enable_reg = 0x4004, 753 .enable_mask = BIT(0), 754 .hw.init = &(const struct clk_init_data) { 755 .name = "dispcc_mdss_non_gdsc_ahb_clk", 756 .parent_hws = (const struct clk_hw*[]) { 757 &dispcc_mdss_ahb_clk_src.clkr.hw, 758 }, 759 .num_parents = 1, 760 .flags = CLK_SET_RATE_PARENT, 761 .ops = &clk_branch2_ops, 762 }, 763 }, 764 }; 765 766 static struct clk_branch dispcc_mdss_pclk0_clk = { 767 .halt_reg = 0x2004, 768 .halt_check = BRANCH_HALT, 769 .clkr = { 770 .enable_reg = 0x2004, 771 .enable_mask = BIT(0), 772 .hw.init = &(const struct clk_init_data) { 773 .name = "dispcc_mdss_pclk0_clk", 774 .parent_hws = (const struct clk_hw*[]) { 775 &dispcc_mdss_pclk0_clk_src.clkr.hw, 776 }, 777 .num_parents = 1, 778 .flags = CLK_SET_RATE_PARENT, 779 .ops = &clk_branch2_ops, 780 }, 781 }, 782 }; 783 784 static struct clk_branch dispcc_mdss_pclk1_clk = { 785 .halt_reg = 0x2008, 786 .halt_check = BRANCH_HALT, 787 .clkr = { 788 .enable_reg = 0x2008, 789 .enable_mask = BIT(0), 790 .hw.init = &(const struct clk_init_data) { 791 .name = "dispcc_mdss_pclk1_clk", 792 .parent_hws = (const struct clk_hw*[]) { 793 &dispcc_mdss_pclk1_clk_src.clkr.hw, 794 }, 795 .num_parents = 1, 796 .flags = CLK_SET_RATE_PARENT, 797 .ops = &clk_branch2_ops, 798 }, 799 }, 800 }; 801 802 static struct clk_branch dispcc_mdss_rot_clk = { 803 .halt_reg = 0x2014, 804 .halt_check = BRANCH_HALT, 805 .clkr = { 806 .enable_reg = 0x2014, 807 .enable_mask = BIT(0), 808 .hw.init = &(const struct clk_init_data) { 809 .name = "dispcc_mdss_rot_clk", 810 .parent_hws = (const struct clk_hw*[]) { 811 &dispcc_mdss_rot_clk_src.clkr.hw, 812 }, 813 .num_parents = 1, 814 .flags = CLK_SET_RATE_PARENT, 815 .ops = &clk_branch2_ops, 816 }, 817 }, 818 }; 819 820 static struct clk_branch dispcc_mdss_rscc_ahb_clk = { 821 .halt_reg = 0x400c, 822 .halt_check = BRANCH_HALT, 823 .clkr = { 824 .enable_reg = 0x400c, 825 .enable_mask = BIT(0), 826 .hw.init = &(const struct clk_init_data) { 827 .name = "dispcc_mdss_rscc_ahb_clk", 828 .parent_names = (const char *[]) { 829 "dispcc_mdss_ahb_clk_src", 830 }, 831 .num_parents = 1, 832 .flags = CLK_SET_RATE_PARENT, 833 .ops = &clk_branch2_ops, 834 }, 835 }, 836 }; 837 838 static struct clk_branch dispcc_mdss_rscc_vsync_clk = { 839 .halt_reg = 0x4008, 840 .halt_check = BRANCH_HALT, 841 .clkr = { 842 .enable_reg = 0x4008, 843 .enable_mask = BIT(0), 844 .hw.init = &(const struct clk_init_data) { 845 .name = "dispcc_mdss_rscc_vsync_clk", 846 .parent_hws = (const struct clk_hw*[]) { 847 &dispcc_mdss_vsync_clk_src.clkr.hw, 848 }, 849 .num_parents = 1, 850 .flags = CLK_SET_RATE_PARENT, 851 .ops = &clk_branch2_ops, 852 }, 853 }, 854 }; 855 856 static struct clk_branch dispcc_mdss_vsync_clk = { 857 .halt_reg = 0x2024, 858 .halt_check = BRANCH_HALT, 859 .clkr = { 860 .enable_reg = 0x2024, 861 .enable_mask = BIT(0), 862 .hw.init = &(const struct clk_init_data) { 863 .name = "dispcc_mdss_vsync_clk", 864 .parent_hws = (const struct clk_hw*[]) { 865 &dispcc_mdss_vsync_clk_src.clkr.hw, 866 }, 867 .num_parents = 1, 868 .flags = CLK_SET_RATE_PARENT, 869 .ops = &clk_branch2_ops, 870 }, 871 }, 872 }; 873 874 static struct clk_branch dispcc_sleep_clk = { 875 .halt_reg = 0x6078, 876 .halt_check = BRANCH_HALT, 877 .clkr = { 878 .enable_reg = 0x6078, 879 .enable_mask = BIT(0), 880 .hw.init = &(const struct clk_init_data) { 881 .name = "dispcc_sleep_clk", 882 .parent_names = (const char *[]) { 883 "dispcc_sleep_clk_src", 884 }, 885 .num_parents = 1, 886 .flags = CLK_SET_RATE_PARENT, 887 .ops = &clk_branch2_ops, 888 }, 889 }, 890 }; 891 892 static struct gdsc mdss_gdsc = { 893 .gdscr = 0x3000, 894 .en_rest_wait_val = 0x2, 895 .en_few_wait_val = 0x2, 896 .clk_dis_wait_val = 0xf, 897 .pd = { 898 .name = "mdss_gdsc", 899 }, 900 .pwrsts = PWRSTS_OFF_ON, 901 .flags = HW_CTRL, 902 }; 903 904 static struct clk_regmap *dispcc_sm7150_clocks[] = { 905 [DISPCC_MDSS_AHB_CLK] = &dispcc_mdss_ahb_clk.clkr, 906 [DISPCC_MDSS_AHB_CLK_SRC] = &dispcc_mdss_ahb_clk_src.clkr, 907 [DISPCC_MDSS_BYTE0_CLK] = &dispcc_mdss_byte0_clk.clkr, 908 [DISPCC_MDSS_BYTE0_CLK_SRC] = &dispcc_mdss_byte0_clk_src.clkr, 909 [DISPCC_MDSS_BYTE0_DIV_CLK_SRC] = &dispcc_mdss_byte0_div_clk_src.clkr, 910 [DISPCC_MDSS_BYTE0_INTF_CLK] = &dispcc_mdss_byte0_intf_clk.clkr, 911 [DISPCC_MDSS_BYTE1_CLK] = &dispcc_mdss_byte1_clk.clkr, 912 [DISPCC_MDSS_BYTE1_CLK_SRC] = &dispcc_mdss_byte1_clk_src.clkr, 913 [DISPCC_MDSS_BYTE1_DIV_CLK_SRC] = &dispcc_mdss_byte1_div_clk_src.clkr, 914 [DISPCC_MDSS_BYTE1_INTF_CLK] = &dispcc_mdss_byte1_intf_clk.clkr, 915 [DISPCC_MDSS_DP_AUX_CLK] = &dispcc_mdss_dp_aux_clk.clkr, 916 [DISPCC_MDSS_DP_AUX_CLK_SRC] = &dispcc_mdss_dp_aux_clk_src.clkr, 917 [DISPCC_MDSS_DP_CRYPTO_CLK] = &dispcc_mdss_dp_crypto_clk.clkr, 918 [DISPCC_MDSS_DP_CRYPTO_CLK_SRC] = &dispcc_mdss_dp_crypto_clk_src.clkr, 919 [DISPCC_MDSS_DP_LINK_CLK] = &dispcc_mdss_dp_link_clk.clkr, 920 [DISPCC_MDSS_DP_LINK_CLK_SRC] = &dispcc_mdss_dp_link_clk_src.clkr, 921 [DISPCC_MDSS_DP_LINK_INTF_CLK] = &dispcc_mdss_dp_link_intf_clk.clkr, 922 [DISPCC_MDSS_DP_PIXEL1_CLK] = &dispcc_mdss_dp_pixel1_clk.clkr, 923 [DISPCC_MDSS_DP_PIXEL1_CLK_SRC] = &dispcc_mdss_dp_pixel1_clk_src.clkr, 924 [DISPCC_MDSS_DP_PIXEL_CLK] = &dispcc_mdss_dp_pixel_clk.clkr, 925 [DISPCC_MDSS_DP_PIXEL_CLK_SRC] = &dispcc_mdss_dp_pixel_clk_src.clkr, 926 [DISPCC_MDSS_ESC0_CLK] = &dispcc_mdss_esc0_clk.clkr, 927 [DISPCC_MDSS_ESC0_CLK_SRC] = &dispcc_mdss_esc0_clk_src.clkr, 928 [DISPCC_MDSS_ESC1_CLK] = &dispcc_mdss_esc1_clk.clkr, 929 [DISPCC_MDSS_ESC1_CLK_SRC] = &dispcc_mdss_esc1_clk_src.clkr, 930 [DISPCC_MDSS_MDP_CLK] = &dispcc_mdss_mdp_clk.clkr, 931 [DISPCC_MDSS_MDP_CLK_SRC] = &dispcc_mdss_mdp_clk_src.clkr, 932 [DISPCC_MDSS_MDP_LUT_CLK] = &dispcc_mdss_mdp_lut_clk.clkr, 933 [DISPCC_MDSS_NON_GDSC_AHB_CLK] = &dispcc_mdss_non_gdsc_ahb_clk.clkr, 934 [DISPCC_MDSS_PCLK0_CLK] = &dispcc_mdss_pclk0_clk.clkr, 935 [DISPCC_MDSS_PCLK0_CLK_SRC] = &dispcc_mdss_pclk0_clk_src.clkr, 936 [DISPCC_MDSS_PCLK1_CLK] = &dispcc_mdss_pclk1_clk.clkr, 937 [DISPCC_MDSS_PCLK1_CLK_SRC] = &dispcc_mdss_pclk1_clk_src.clkr, 938 [DISPCC_MDSS_ROT_CLK] = &dispcc_mdss_rot_clk.clkr, 939 [DISPCC_MDSS_ROT_CLK_SRC] = &dispcc_mdss_rot_clk_src.clkr, 940 [DISPCC_MDSS_RSCC_AHB_CLK] = &dispcc_mdss_rscc_ahb_clk.clkr, 941 [DISPCC_MDSS_RSCC_VSYNC_CLK] = &dispcc_mdss_rscc_vsync_clk.clkr, 942 [DISPCC_MDSS_VSYNC_CLK] = &dispcc_mdss_vsync_clk.clkr, 943 [DISPCC_MDSS_VSYNC_CLK_SRC] = &dispcc_mdss_vsync_clk_src.clkr, 944 [DISPCC_PLL0] = &dispcc_pll0.clkr, 945 [DISPCC_SLEEP_CLK] = &dispcc_sleep_clk.clkr, 946 [DISPCC_SLEEP_CLK_SRC] = &dispcc_sleep_clk_src.clkr, 947 [DISPCC_XO_CLK_SRC] = &dispcc_xo_clk_src.clkr, 948 }; 949 950 static struct gdsc *dispcc_sm7150_gdscs[] = { 951 [MDSS_GDSC] = &mdss_gdsc, 952 }; 953 954 static const struct regmap_config dispcc_sm7150_regmap_config = { 955 .reg_bits = 32, 956 .reg_stride = 4, 957 .val_bits = 32, 958 .max_register = 0x10000, 959 .fast_io = true, 960 }; 961 962 static const struct qcom_cc_desc dispcc_sm7150_desc = { 963 .config = &dispcc_sm7150_regmap_config, 964 .clks = dispcc_sm7150_clocks, 965 .num_clks = ARRAY_SIZE(dispcc_sm7150_clocks), 966 .gdscs = dispcc_sm7150_gdscs, 967 .num_gdscs = ARRAY_SIZE(dispcc_sm7150_gdscs), 968 }; 969 970 static const struct of_device_id dispcc_sm7150_match_table[] = { 971 { .compatible = "qcom,sm7150-dispcc" }, 972 { } 973 }; 974 MODULE_DEVICE_TABLE(of, dispcc_sm7150_match_table); 975 976 static int dispcc_sm7150_probe(struct platform_device *pdev) 977 { 978 struct regmap *regmap; 979 980 regmap = qcom_cc_map(pdev, &dispcc_sm7150_desc); 981 if (IS_ERR(regmap)) 982 return PTR_ERR(regmap); 983 984 clk_fabia_pll_configure(&dispcc_pll0, regmap, &dispcc_pll0_config); 985 /* Enable clock gating for DSI and MDP clocks */ 986 regmap_update_bits(regmap, 0x8000, 0x7f0, 0x7f0); 987 988 /* Keep some clocks always-on */ 989 qcom_branch_set_clk_en(regmap, 0x605c); /* DISPCC_XO_CLK */ 990 991 return qcom_cc_really_probe(&pdev->dev, &dispcc_sm7150_desc, regmap); 992 } 993 994 static struct platform_driver dispcc_sm7150_driver = { 995 .probe = dispcc_sm7150_probe, 996 .driver = { 997 .name = "dispcc-sm7150", 998 .of_match_table = dispcc_sm7150_match_table, 999 }, 1000 }; 1001 1002 module_platform_driver(dispcc_sm7150_driver); 1003 1004 MODULE_DESCRIPTION("Qualcomm SM7150 Display Clock Controller"); 1005 MODULE_LICENSE("GPL"); 1006