Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

clk: qcom: Add display clock controller driver for SM6350

Add support for the display clock controller found on SM6350.

Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/20220222011534.3502-2-konrad.dybcio@somainline.org

authored by

Konrad Dybcio and committed by
Bjorn Andersson
83751977 6914b82f

+807
+9
drivers/clk/qcom/Kconfig
··· 598 598 Say Y if you want to support display devices and functionality such as 599 599 splash screen. 600 600 601 + config SM_DISPCC_6350 602 + tristate "SM6350 Display Clock Controller" 603 + depends on SM_GCC_6350 604 + help 605 + Support for the display clock controller on Qualcomm Technologies, Inc 606 + SM6350 devices. 607 + Say Y if you want to support display devices and functionality such as 608 + splash screen. 609 + 601 610 config SM_GCC_6115 602 611 tristate "SM6115 and SM4250 Global Clock Controller" 603 612 help
+1
drivers/clk/qcom/Makefile
··· 86 86 obj-$(CONFIG_SDX_GCC_55) += gcc-sdx55.o 87 87 obj-$(CONFIG_SM_CAMCC_8250) += camcc-sm8250.o 88 88 obj-$(CONFIG_SDX_GCC_65) += gcc-sdx65.o 89 + obj-$(CONFIG_SM_DISPCC_6350) += dispcc-sm6350.o 89 90 obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o 90 91 obj-$(CONFIG_SM_GCC_6115) += gcc-sm6115.o 91 92 obj-$(CONFIG_SM_GCC_6125) += gcc-sm6125.o
+797
drivers/clk/qcom/dispcc-sm6350.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2021, The Linux Foundation. All rights reserved. 4 + * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org> 5 + */ 6 + 7 + #include <linux/clk-provider.h> 8 + #include <linux/module.h> 9 + #include <linux/platform_device.h> 10 + #include <linux/regmap.h> 11 + 12 + #include <dt-bindings/clock/qcom,dispcc-sm6350.h> 13 + 14 + #include "clk-alpha-pll.h" 15 + #include "clk-branch.h" 16 + #include "clk-rcg.h" 17 + #include "clk-regmap.h" 18 + #include "clk-regmap-divider.h" 19 + #include "common.h" 20 + #include "gdsc.h" 21 + #include "reset.h" 22 + 23 + enum { 24 + P_BI_TCXO, 25 + P_DISP_CC_PLL0_OUT_EVEN, 26 + P_DISP_CC_PLL0_OUT_MAIN, 27 + P_DP_PHY_PLL_LINK_CLK, 28 + P_DP_PHY_PLL_VCO_DIV_CLK, 29 + P_DSI0_PHY_PLL_OUT_BYTECLK, 30 + P_DSI0_PHY_PLL_OUT_DSICLK, 31 + P_GCC_DISP_GPLL0_CLK, 32 + }; 33 + 34 + static struct pll_vco fabia_vco[] = { 35 + { 249600000, 2000000000, 0 }, 36 + }; 37 + 38 + static const struct alpha_pll_config disp_cc_pll0_config = { 39 + .l = 0x3a, 40 + .alpha = 0x5555, 41 + .config_ctl_val = 0x20485699, 42 + .config_ctl_hi_val = 0x00002067, 43 + .test_ctl_val = 0x40000000, 44 + .test_ctl_hi_val = 0x00000002, 45 + .user_ctl_val = 0x00000000, 46 + .user_ctl_hi_val = 0x00004805, 47 + }; 48 + 49 + static struct clk_alpha_pll disp_cc_pll0 = { 50 + .offset = 0x0, 51 + .vco_table = fabia_vco, 52 + .num_vco = ARRAY_SIZE(fabia_vco), 53 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA], 54 + .clkr = { 55 + .hw.init = &(struct clk_init_data){ 56 + .name = "disp_cc_pll0", 57 + .parent_data = &(const struct clk_parent_data){ 58 + .fw_name = "bi_tcxo", 59 + }, 60 + .num_parents = 1, 61 + .ops = &clk_alpha_pll_fabia_ops, 62 + }, 63 + }, 64 + }; 65 + 66 + static const struct parent_map disp_cc_parent_map_0[] = { 67 + { P_BI_TCXO, 0 }, 68 + { P_DP_PHY_PLL_LINK_CLK, 1 }, 69 + { P_DP_PHY_PLL_VCO_DIV_CLK, 2 }, 70 + }; 71 + 72 + static const struct clk_parent_data disp_cc_parent_data_0[] = { 73 + { .fw_name = "bi_tcxo" }, 74 + { .fw_name = "dp_phy_pll_link_clk" }, 75 + { .fw_name = "dp_phy_pll_vco_div_clk" }, 76 + }; 77 + 78 + static const struct parent_map disp_cc_parent_map_1[] = { 79 + { P_BI_TCXO, 0 }, 80 + { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, 81 + }; 82 + 83 + static const struct clk_parent_data disp_cc_parent_data_1[] = { 84 + { .fw_name = "bi_tcxo" }, 85 + { .fw_name = "dsi0_phy_pll_out_byteclk" }, 86 + }; 87 + 88 + static const struct parent_map disp_cc_parent_map_3[] = { 89 + { P_BI_TCXO, 0 }, 90 + { P_DISP_CC_PLL0_OUT_MAIN, 1 }, 91 + { P_GCC_DISP_GPLL0_CLK, 4 }, 92 + { P_DISP_CC_PLL0_OUT_EVEN, 5 }, 93 + }; 94 + 95 + static const struct clk_parent_data disp_cc_parent_data_3[] = { 96 + { .fw_name = "bi_tcxo" }, 97 + { .hw = &disp_cc_pll0.clkr.hw }, 98 + { .fw_name = "gcc_disp_gpll0_clk" }, 99 + { .hw = &disp_cc_pll0.clkr.hw }, 100 + }; 101 + 102 + static const struct parent_map disp_cc_parent_map_4[] = { 103 + { P_BI_TCXO, 0 }, 104 + { P_GCC_DISP_GPLL0_CLK, 4 }, 105 + }; 106 + 107 + static const struct clk_parent_data disp_cc_parent_data_4[] = { 108 + { .fw_name = "bi_tcxo" }, 109 + { .fw_name = "gcc_disp_gpll0_clk" }, 110 + }; 111 + 112 + static const struct parent_map disp_cc_parent_map_5[] = { 113 + { P_BI_TCXO, 0 }, 114 + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, 115 + }; 116 + 117 + static const struct clk_parent_data disp_cc_parent_data_5[] = { 118 + { .fw_name = "bi_tcxo" }, 119 + { .fw_name = "dsi0_phy_pll_out_dsiclk" }, 120 + }; 121 + 122 + static const struct parent_map disp_cc_parent_map_6[] = { 123 + { P_BI_TCXO, 0 }, 124 + }; 125 + 126 + static const struct clk_parent_data disp_cc_parent_data_6[] = { 127 + { .fw_name = "bi_tcxo" }, 128 + }; 129 + 130 + static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { 131 + F(19200000, P_BI_TCXO, 1, 0, 0), 132 + F(37500000, P_GCC_DISP_GPLL0_CLK, 16, 0, 0), 133 + F(75000000, P_GCC_DISP_GPLL0_CLK, 8, 0, 0), 134 + { } 135 + }; 136 + 137 + static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { 138 + .cmd_rcgr = 0x115c, 139 + .mnd_width = 0, 140 + .hid_width = 5, 141 + .parent_map = disp_cc_parent_map_4, 142 + .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, 143 + .clkr.hw.init = &(struct clk_init_data){ 144 + .name = "disp_cc_mdss_ahb_clk_src", 145 + .parent_data = disp_cc_parent_data_4, 146 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), 147 + .flags = CLK_SET_RATE_PARENT, 148 + .ops = &clk_rcg2_ops, 149 + }, 150 + }; 151 + 152 + static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { 153 + .cmd_rcgr = 0x10c4, 154 + .mnd_width = 0, 155 + .hid_width = 5, 156 + .parent_map = disp_cc_parent_map_1, 157 + .clkr.hw.init = &(struct clk_init_data){ 158 + .name = "disp_cc_mdss_byte0_clk_src", 159 + .parent_data = disp_cc_parent_data_1, 160 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), 161 + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 162 + .ops = &clk_byte2_ops, 163 + }, 164 + }; 165 + 166 + static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { 167 + .reg = 0x10dc, 168 + .shift = 0, 169 + .width = 2, 170 + .clkr.hw.init = &(struct clk_init_data) { 171 + .name = "disp_cc_mdss_byte0_div_clk_src", 172 + .parent_hws = (const struct clk_hw*[]){ 173 + &disp_cc_mdss_byte0_clk_src.clkr.hw, 174 + }, 175 + .num_parents = 1, 176 + .flags = CLK_GET_RATE_NOCACHE, 177 + .ops = &clk_regmap_div_ro_ops, 178 + }, 179 + }; 180 + 181 + static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = { 182 + F(19200000, P_BI_TCXO, 1, 0, 0), 183 + { } 184 + }; 185 + 186 + static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = { 187 + .cmd_rcgr = 0x1144, 188 + .mnd_width = 0, 189 + .hid_width = 5, 190 + .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, 191 + .clkr.hw.init = &(struct clk_init_data){ 192 + .name = "disp_cc_mdss_dp_aux_clk_src", 193 + .parent_data = &(const struct clk_parent_data){ 194 + .fw_name = "bi_tcxo", 195 + }, 196 + .num_parents = 1, 197 + .ops = &clk_rcg2_ops, 198 + }, 199 + }; 200 + 201 + static const struct freq_tbl ftbl_disp_cc_mdss_dp_crypto_clk_src[] = { 202 + F(108000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0), 203 + F(180000, P_DP_PHY_PLL_LINK_CLK, 3, 0, 0), 204 + F(360000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0), 205 + F(540000, P_DP_PHY_PLL_LINK_CLK, 1.5, 0, 0), 206 + { } 207 + }; 208 + 209 + static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = { 210 + .cmd_rcgr = 0x1114, 211 + .mnd_width = 0, 212 + .hid_width = 5, 213 + .parent_map = disp_cc_parent_map_0, 214 + .freq_tbl = ftbl_disp_cc_mdss_dp_crypto_clk_src, 215 + .clkr.hw.init = &(struct clk_init_data){ 216 + .name = "disp_cc_mdss_dp_crypto_clk_src", 217 + .parent_data = disp_cc_parent_data_0, 218 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 219 + .flags = CLK_GET_RATE_NOCACHE, 220 + .ops = &clk_rcg2_ops, 221 + }, 222 + }; 223 + 224 + static const struct freq_tbl ftbl_disp_cc_mdss_dp_link_clk_src[] = { 225 + F(162000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), 226 + F(270000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), 227 + F(540000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), 228 + F(810000, P_DP_PHY_PLL_LINK_CLK, 1, 0, 0), 229 + { } 230 + }; 231 + 232 + static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = { 233 + .cmd_rcgr = 0x10f8, 234 + .mnd_width = 0, 235 + .hid_width = 5, 236 + .parent_map = disp_cc_parent_map_0, 237 + .freq_tbl = ftbl_disp_cc_mdss_dp_link_clk_src, 238 + .clkr.hw.init = &(struct clk_init_data){ 239 + .name = "disp_cc_mdss_dp_link_clk_src", 240 + .parent_data = disp_cc_parent_data_0, 241 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 242 + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 243 + .ops = &clk_rcg2_ops, 244 + }, 245 + }; 246 + 247 + static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = { 248 + .cmd_rcgr = 0x112c, 249 + .mnd_width = 16, 250 + .hid_width = 5, 251 + .parent_map = disp_cc_parent_map_0, 252 + .clkr.hw.init = &(struct clk_init_data){ 253 + .name = "disp_cc_mdss_dp_pixel_clk_src", 254 + .parent_data = disp_cc_parent_data_0, 255 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 256 + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 257 + .ops = &clk_dp_ops, 258 + }, 259 + }; 260 + 261 + static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { 262 + .cmd_rcgr = 0x10e0, 263 + .mnd_width = 0, 264 + .hid_width = 5, 265 + .parent_map = disp_cc_parent_map_1, 266 + .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, 267 + .clkr.hw.init = &(struct clk_init_data){ 268 + .name = "disp_cc_mdss_esc0_clk_src", 269 + .parent_data = disp_cc_parent_data_1, 270 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), 271 + .ops = &clk_rcg2_ops, 272 + }, 273 + }; 274 + 275 + static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { 276 + F(19200000, P_BI_TCXO, 1, 0, 0), 277 + F(200000000, P_GCC_DISP_GPLL0_CLK, 3, 0, 0), 278 + F(300000000, P_GCC_DISP_GPLL0_CLK, 2, 0, 0), 279 + F(373333333, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 280 + F(448000000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), 281 + F(560000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0), 282 + { } 283 + }; 284 + 285 + static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { 286 + .cmd_rcgr = 0x107c, 287 + .mnd_width = 0, 288 + .hid_width = 5, 289 + .parent_map = disp_cc_parent_map_3, 290 + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, 291 + .clkr.hw.init = &(struct clk_init_data){ 292 + .name = "disp_cc_mdss_mdp_clk_src", 293 + .parent_data = disp_cc_parent_data_3, 294 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), 295 + .flags = CLK_SET_RATE_PARENT, 296 + .ops = &clk_rcg2_ops, 297 + }, 298 + }; 299 + 300 + static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { 301 + .cmd_rcgr = 0x1064, 302 + .mnd_width = 8, 303 + .hid_width = 5, 304 + .parent_map = disp_cc_parent_map_5, 305 + .clkr.hw.init = &(struct clk_init_data){ 306 + .name = "disp_cc_mdss_pclk0_clk_src", 307 + .parent_data = disp_cc_parent_data_5, 308 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), 309 + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 310 + .ops = &clk_pixel_ops, 311 + }, 312 + }; 313 + 314 + static struct clk_rcg2 disp_cc_mdss_rot_clk_src = { 315 + .cmd_rcgr = 0x1094, 316 + .mnd_width = 0, 317 + .hid_width = 5, 318 + .parent_map = disp_cc_parent_map_3, 319 + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, 320 + .clkr.hw.init = &(struct clk_init_data){ 321 + .name = "disp_cc_mdss_rot_clk_src", 322 + .parent_data = disp_cc_parent_data_3, 323 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), 324 + .flags = CLK_SET_RATE_PARENT, 325 + .ops = &clk_rcg2_ops, 326 + }, 327 + }; 328 + 329 + static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { 330 + .cmd_rcgr = 0x10ac, 331 + .mnd_width = 0, 332 + .hid_width = 5, 333 + .parent_map = disp_cc_parent_map_6, 334 + .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src, 335 + .clkr.hw.init = &(struct clk_init_data){ 336 + .name = "disp_cc_mdss_vsync_clk_src", 337 + .parent_data = disp_cc_parent_data_6, 338 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_6), 339 + .ops = &clk_rcg2_ops, 340 + }, 341 + }; 342 + 343 + static struct clk_regmap_div disp_cc_mdss_dp_link_div_clk_src = { 344 + .reg = 0x1110, 345 + .shift = 0, 346 + .width = 2, 347 + .clkr.hw.init = &(struct clk_init_data) { 348 + .name = "disp_cc_mdss_dp_link_div_clk_src", 349 + .parent_hws = (const struct clk_hw*[]){ 350 + &disp_cc_mdss_dp_link_clk_src.clkr.hw, 351 + }, 352 + .num_parents = 1, 353 + .flags = CLK_GET_RATE_NOCACHE, 354 + .ops = &clk_regmap_div_ro_ops, 355 + }, 356 + }; 357 + 358 + static struct clk_branch disp_cc_mdss_ahb_clk = { 359 + .halt_reg = 0x104c, 360 + .halt_check = BRANCH_HALT, 361 + .clkr = { 362 + .enable_reg = 0x104c, 363 + .enable_mask = BIT(0), 364 + .hw.init = &(struct clk_init_data){ 365 + .name = "disp_cc_mdss_ahb_clk", 366 + .parent_hws = (const struct clk_hw*[]){ 367 + &disp_cc_mdss_ahb_clk_src.clkr.hw, 368 + }, 369 + .num_parents = 1, 370 + .flags = CLK_SET_RATE_PARENT, 371 + .ops = &clk_branch2_ops, 372 + }, 373 + }, 374 + }; 375 + 376 + static struct clk_branch disp_cc_mdss_byte0_clk = { 377 + .halt_reg = 0x102c, 378 + .halt_check = BRANCH_HALT, 379 + .clkr = { 380 + .enable_reg = 0x102c, 381 + .enable_mask = BIT(0), 382 + .hw.init = &(struct clk_init_data){ 383 + .name = "disp_cc_mdss_byte0_clk", 384 + .parent_hws = (const struct clk_hw*[]){ 385 + &disp_cc_mdss_byte0_clk_src.clkr.hw, 386 + }, 387 + .num_parents = 1, 388 + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 389 + .ops = &clk_branch2_ops, 390 + }, 391 + }, 392 + }; 393 + 394 + static struct clk_branch disp_cc_mdss_byte0_intf_clk = { 395 + .halt_reg = 0x1030, 396 + .halt_check = BRANCH_HALT, 397 + .clkr = { 398 + .enable_reg = 0x1030, 399 + .enable_mask = BIT(0), 400 + .hw.init = &(struct clk_init_data){ 401 + .name = "disp_cc_mdss_byte0_intf_clk", 402 + .parent_hws = (const struct clk_hw*[]){ 403 + &disp_cc_mdss_byte0_div_clk_src.clkr.hw, 404 + }, 405 + .num_parents = 1, 406 + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 407 + .ops = &clk_branch2_ops, 408 + }, 409 + }, 410 + }; 411 + 412 + static struct clk_branch disp_cc_mdss_dp_aux_clk = { 413 + .halt_reg = 0x1048, 414 + .halt_check = BRANCH_HALT, 415 + .clkr = { 416 + .enable_reg = 0x1048, 417 + .enable_mask = BIT(0), 418 + .hw.init = &(struct clk_init_data){ 419 + .name = "disp_cc_mdss_dp_aux_clk", 420 + .parent_hws = (const struct clk_hw*[]){ 421 + &disp_cc_mdss_dp_aux_clk_src.clkr.hw, 422 + }, 423 + .num_parents = 1, 424 + .flags = CLK_SET_RATE_PARENT, 425 + .ops = &clk_branch2_ops, 426 + }, 427 + }, 428 + }; 429 + 430 + static struct clk_branch disp_cc_mdss_dp_crypto_clk = { 431 + .halt_reg = 0x1040, 432 + .halt_check = BRANCH_HALT, 433 + .clkr = { 434 + .enable_reg = 0x1040, 435 + .enable_mask = BIT(0), 436 + .hw.init = &(struct clk_init_data){ 437 + .name = "disp_cc_mdss_dp_crypto_clk", 438 + .parent_hws = (const struct clk_hw*[]){ 439 + &disp_cc_mdss_dp_crypto_clk_src.clkr.hw, 440 + }, 441 + .num_parents = 1, 442 + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 443 + .ops = &clk_branch2_ops, 444 + }, 445 + }, 446 + }; 447 + 448 + static struct clk_branch disp_cc_mdss_dp_link_clk = { 449 + .halt_reg = 0x1038, 450 + .halt_check = BRANCH_HALT, 451 + .clkr = { 452 + .enable_reg = 0x1038, 453 + .enable_mask = BIT(0), 454 + .hw.init = &(struct clk_init_data){ 455 + .name = "disp_cc_mdss_dp_link_clk", 456 + .parent_hws = (const struct clk_hw*[]){ 457 + &disp_cc_mdss_dp_link_clk_src.clkr.hw, 458 + }, 459 + .num_parents = 1, 460 + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 461 + .ops = &clk_branch2_ops, 462 + }, 463 + }, 464 + }; 465 + 466 + static struct clk_branch disp_cc_mdss_dp_link_intf_clk = { 467 + .halt_reg = 0x103c, 468 + .halt_check = BRANCH_HALT, 469 + .clkr = { 470 + .enable_reg = 0x103c, 471 + .enable_mask = BIT(0), 472 + .hw.init = &(struct clk_init_data){ 473 + .name = "disp_cc_mdss_dp_link_intf_clk", 474 + .parent_hws = (const struct clk_hw*[]){ 475 + &disp_cc_mdss_dp_link_div_clk_src.clkr.hw, 476 + }, 477 + .num_parents = 1, 478 + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 479 + .ops = &clk_branch2_ops, 480 + }, 481 + }, 482 + }; 483 + 484 + static struct clk_branch disp_cc_mdss_dp_pixel_clk = { 485 + .halt_reg = 0x1044, 486 + .halt_check = BRANCH_HALT, 487 + .clkr = { 488 + .enable_reg = 0x1044, 489 + .enable_mask = BIT(0), 490 + .hw.init = &(struct clk_init_data){ 491 + .name = "disp_cc_mdss_dp_pixel_clk", 492 + .parent_hws = (const struct clk_hw*[]){ 493 + &disp_cc_mdss_dp_pixel_clk_src.clkr.hw, 494 + }, 495 + .num_parents = 1, 496 + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 497 + .ops = &clk_branch2_ops, 498 + }, 499 + }, 500 + }; 501 + 502 + static struct clk_branch disp_cc_mdss_esc0_clk = { 503 + .halt_reg = 0x1034, 504 + .halt_check = BRANCH_HALT, 505 + .clkr = { 506 + .enable_reg = 0x1034, 507 + .enable_mask = BIT(0), 508 + .hw.init = &(struct clk_init_data){ 509 + .name = "disp_cc_mdss_esc0_clk", 510 + .parent_hws = (const struct clk_hw*[]){ 511 + &disp_cc_mdss_esc0_clk_src.clkr.hw, 512 + }, 513 + .num_parents = 1, 514 + .flags = CLK_SET_RATE_PARENT, 515 + .ops = &clk_branch2_ops, 516 + }, 517 + }, 518 + }; 519 + 520 + static struct clk_branch disp_cc_mdss_mdp_clk = { 521 + .halt_reg = 0x1010, 522 + .halt_check = BRANCH_HALT, 523 + .clkr = { 524 + .enable_reg = 0x1010, 525 + .enable_mask = BIT(0), 526 + .hw.init = &(struct clk_init_data){ 527 + .name = "disp_cc_mdss_mdp_clk", 528 + .parent_hws = (const struct clk_hw*[]){ 529 + &disp_cc_mdss_mdp_clk_src.clkr.hw, 530 + }, 531 + .num_parents = 1, 532 + .flags = CLK_SET_RATE_PARENT, 533 + .ops = &clk_branch2_ops, 534 + }, 535 + }, 536 + }; 537 + 538 + static struct clk_branch disp_cc_mdss_mdp_lut_clk = { 539 + .halt_reg = 0x1020, 540 + .halt_check = BRANCH_HALT_VOTED, 541 + .clkr = { 542 + .enable_reg = 0x1020, 543 + .enable_mask = BIT(0), 544 + .hw.init = &(struct clk_init_data){ 545 + .name = "disp_cc_mdss_mdp_lut_clk", 546 + .parent_hws = (const struct clk_hw*[]){ 547 + &disp_cc_mdss_mdp_clk_src.clkr.hw, 548 + }, 549 + .num_parents = 1, 550 + .flags = CLK_SET_RATE_PARENT, 551 + .ops = &clk_branch2_ops, 552 + }, 553 + }, 554 + }; 555 + 556 + static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = { 557 + .halt_reg = 0x2004, 558 + .halt_check = BRANCH_HALT_VOTED, 559 + .clkr = { 560 + .enable_reg = 0x2004, 561 + .enable_mask = BIT(0), 562 + .hw.init = &(struct clk_init_data){ 563 + .name = "disp_cc_mdss_non_gdsc_ahb_clk", 564 + .parent_hws = (const struct clk_hw*[]){ 565 + &disp_cc_mdss_ahb_clk_src.clkr.hw, 566 + }, 567 + .num_parents = 1, 568 + .flags = CLK_SET_RATE_PARENT, 569 + .ops = &clk_branch2_ops, 570 + }, 571 + }, 572 + }; 573 + 574 + static struct clk_branch disp_cc_mdss_pclk0_clk = { 575 + .halt_reg = 0x100c, 576 + .halt_check = BRANCH_HALT, 577 + .clkr = { 578 + .enable_reg = 0x100c, 579 + .enable_mask = BIT(0), 580 + .hw.init = &(struct clk_init_data){ 581 + .name = "disp_cc_mdss_pclk0_clk", 582 + .parent_hws = (const struct clk_hw*[]){ 583 + &disp_cc_mdss_pclk0_clk_src.clkr.hw, 584 + }, 585 + .num_parents = 1, 586 + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 587 + .ops = &clk_branch2_ops, 588 + }, 589 + }, 590 + }; 591 + 592 + static struct clk_branch disp_cc_mdss_rot_clk = { 593 + .halt_reg = 0x1018, 594 + .halt_check = BRANCH_HALT, 595 + .clkr = { 596 + .enable_reg = 0x1018, 597 + .enable_mask = BIT(0), 598 + .hw.init = &(struct clk_init_data){ 599 + .name = "disp_cc_mdss_rot_clk", 600 + .parent_hws = (const struct clk_hw*[]){ 601 + &disp_cc_mdss_rot_clk_src.clkr.hw, 602 + }, 603 + .num_parents = 1, 604 + .flags = CLK_SET_RATE_PARENT, 605 + .ops = &clk_branch2_ops, 606 + }, 607 + }, 608 + }; 609 + 610 + static struct clk_branch disp_cc_mdss_rscc_ahb_clk = { 611 + .halt_reg = 0x200c, 612 + .halt_check = BRANCH_HALT, 613 + .clkr = { 614 + .enable_reg = 0x200c, 615 + .enable_mask = BIT(0), 616 + .hw.init = &(struct clk_init_data){ 617 + .name = "disp_cc_mdss_rscc_ahb_clk", 618 + .parent_hws = (const struct clk_hw*[]){ 619 + &disp_cc_mdss_ahb_clk_src.clkr.hw, 620 + }, 621 + .num_parents = 1, 622 + .flags = CLK_SET_RATE_PARENT, 623 + .ops = &clk_branch2_ops, 624 + }, 625 + }, 626 + }; 627 + 628 + static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { 629 + .halt_reg = 0x2008, 630 + .halt_check = BRANCH_HALT, 631 + .clkr = { 632 + .enable_reg = 0x2008, 633 + .enable_mask = BIT(0), 634 + .hw.init = &(struct clk_init_data){ 635 + .name = "disp_cc_mdss_rscc_vsync_clk", 636 + .parent_hws = (const struct clk_hw*[]){ 637 + &disp_cc_mdss_vsync_clk_src.clkr.hw, 638 + }, 639 + .num_parents = 1, 640 + .flags = CLK_SET_RATE_PARENT, 641 + .ops = &clk_branch2_ops, 642 + }, 643 + }, 644 + }; 645 + 646 + static struct clk_branch disp_cc_mdss_vsync_clk = { 647 + .halt_reg = 0x1028, 648 + .halt_check = BRANCH_HALT, 649 + .clkr = { 650 + .enable_reg = 0x1028, 651 + .enable_mask = BIT(0), 652 + .hw.init = &(struct clk_init_data){ 653 + .name = "disp_cc_mdss_vsync_clk", 654 + .parent_hws = (const struct clk_hw*[]){ 655 + &disp_cc_mdss_vsync_clk_src.clkr.hw, 656 + }, 657 + .num_parents = 1, 658 + .flags = CLK_SET_RATE_PARENT, 659 + .ops = &clk_branch2_ops, 660 + }, 661 + }, 662 + }; 663 + 664 + static struct clk_branch disp_cc_sleep_clk = { 665 + .halt_reg = 0x5004, 666 + .halt_check = BRANCH_HALT, 667 + .clkr = { 668 + .enable_reg = 0x5004, 669 + .enable_mask = BIT(0), 670 + .hw.init = &(struct clk_init_data){ 671 + .name = "disp_cc_sleep_clk", 672 + .ops = &clk_branch2_ops, 673 + }, 674 + }, 675 + }; 676 + 677 + static struct clk_branch disp_cc_xo_clk = { 678 + .halt_reg = 0x5008, 679 + .halt_check = BRANCH_HALT, 680 + .clkr = { 681 + .enable_reg = 0x5008, 682 + .enable_mask = BIT(0), 683 + .hw.init = &(struct clk_init_data){ 684 + .name = "disp_cc_xo_clk", 685 + .flags = CLK_IS_CRITICAL, 686 + .ops = &clk_branch2_ops, 687 + }, 688 + }, 689 + }; 690 + 691 + static struct gdsc mdss_gdsc = { 692 + .gdscr = 0x1004, 693 + .pd = { 694 + .name = "mdss_gdsc", 695 + }, 696 + .pwrsts = PWRSTS_OFF_ON, 697 + .flags = RETAIN_FF_ENABLE, 698 + }; 699 + 700 + static struct clk_regmap *disp_cc_sm6350_clocks[] = { 701 + [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, 702 + [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr, 703 + [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, 704 + [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, 705 + [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr, 706 + [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, 707 + [DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr, 708 + [DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr, 709 + [DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr, 710 + [DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr, 711 + [DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr, 712 + [DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr, 713 + [DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC] = 714 + &disp_cc_mdss_dp_link_div_clk_src.clkr, 715 + [DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr, 716 + [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr, 717 + [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr, 718 + [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, 719 + [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, 720 + [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, 721 + [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, 722 + [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, 723 + [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr, 724 + [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, 725 + [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, 726 + [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, 727 + [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, 728 + [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr, 729 + [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, 730 + [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, 731 + [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, 732 + [DISP_CC_PLL0] = &disp_cc_pll0.clkr, 733 + [DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr, 734 + [DISP_CC_XO_CLK] = &disp_cc_xo_clk.clkr, 735 + }; 736 + 737 + static struct gdsc *disp_cc_sm6350_gdscs[] = { 738 + [MDSS_GDSC] = &mdss_gdsc, 739 + }; 740 + 741 + static const struct regmap_config disp_cc_sm6350_regmap_config = { 742 + .reg_bits = 32, 743 + .reg_stride = 4, 744 + .val_bits = 32, 745 + .max_register = 0x10000, 746 + .fast_io = true, 747 + }; 748 + 749 + static const struct qcom_cc_desc disp_cc_sm6350_desc = { 750 + .config = &disp_cc_sm6350_regmap_config, 751 + .clks = disp_cc_sm6350_clocks, 752 + .num_clks = ARRAY_SIZE(disp_cc_sm6350_clocks), 753 + .gdscs = disp_cc_sm6350_gdscs, 754 + .num_gdscs = ARRAY_SIZE(disp_cc_sm6350_gdscs), 755 + }; 756 + 757 + static const struct of_device_id disp_cc_sm6350_match_table[] = { 758 + { .compatible = "qcom,sm6350-dispcc" }, 759 + { } 760 + }; 761 + MODULE_DEVICE_TABLE(of, disp_cc_sm6350_match_table); 762 + 763 + static int disp_cc_sm6350_probe(struct platform_device *pdev) 764 + { 765 + struct regmap *regmap; 766 + 767 + regmap = qcom_cc_map(pdev, &disp_cc_sm6350_desc); 768 + if (IS_ERR(regmap)) 769 + return PTR_ERR(regmap); 770 + 771 + clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); 772 + 773 + return qcom_cc_really_probe(pdev, &disp_cc_sm6350_desc, regmap); 774 + } 775 + 776 + static struct platform_driver disp_cc_sm6350_driver = { 777 + .probe = disp_cc_sm6350_probe, 778 + .driver = { 779 + .name = "disp_cc-sm6350", 780 + .of_match_table = disp_cc_sm6350_match_table, 781 + }, 782 + }; 783 + 784 + static int __init disp_cc_sm6350_init(void) 785 + { 786 + return platform_driver_register(&disp_cc_sm6350_driver); 787 + } 788 + subsys_initcall(disp_cc_sm6350_init); 789 + 790 + static void __exit disp_cc_sm6350_exit(void) 791 + { 792 + platform_driver_unregister(&disp_cc_sm6350_driver); 793 + } 794 + module_exit(disp_cc_sm6350_exit); 795 + 796 + MODULE_DESCRIPTION("QTI DISP_CC SM6350 Driver"); 797 + MODULE_LICENSE("GPL v2");