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