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

Configure Feed

Select the types of activity you want to include in your feed.

clk: qcom: Add display clock controller driver for SM6115

Add support for the display clock controller found in SM6115/SM4250
based devices. This clock controller feeds the Multimedia Display
SubSystem (MDSS).
This driver is based upon one submitted for QCM2290.

Signed-off-by: Adam Skladowski <a39.skl@gmail.com>
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Link: https://lore.kernel.org/r/20220911164635.182973-3-a39.skl@gmail.com

authored by

Adam Skladowski and committed by
Bjorn Andersson
9b518788 38557c6f

+618
+9
drivers/clk/qcom/Kconfig
··· 624 624 Support for the camera clock controller on SM8450 devices. 625 625 Say Y if you want to support camera devices and camera functionality. 626 626 627 + config SM_DISPCC_6115 628 + tristate "SM6115 Display Clock Controller" 629 + depends on SM_GCC_6115 630 + help 631 + Support for the display clock controller on Qualcomm Technologies, Inc 632 + SM6115/SM4250 devices. 633 + Say Y if you want to support display devices and functionality such as 634 + splash screen 635 + 627 636 config SM_DISPCC_6125 628 637 tristate "SM6125 Display Clock Controller" 629 638 depends on SM_GCC_6125
+1
drivers/clk/qcom/Makefile
··· 91 91 obj-$(CONFIG_SDX_GCC_65) += gcc-sdx65.o 92 92 obj-$(CONFIG_SM_CAMCC_8250) += camcc-sm8250.o 93 93 obj-$(CONFIG_SM_CAMCC_8450) += camcc-sm8450.o 94 + obj-$(CONFIG_SM_DISPCC_6115) += dispcc-sm6115.o 94 95 obj-$(CONFIG_SM_DISPCC_6125) += dispcc-sm6125.o 95 96 obj-$(CONFIG_SM_DISPCC_6350) += dispcc-sm6350.o 96 97 obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o
+608
drivers/clk/qcom/dispcc-sm6115.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Based on dispcc-qcm2290.c 4 + * Copyright (c) 2020, The Linux Foundation. All rights reserved. 5 + * Copyright (c) 2021, Linaro Ltd. 6 + */ 7 + 8 + #include <linux/err.h> 9 + #include <linux/kernel.h> 10 + #include <linux/module.h> 11 + #include <linux/of_device.h> 12 + #include <linux/of.h> 13 + #include <linux/regmap.h> 14 + 15 + #include <dt-bindings/clock/qcom,sm6115-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_SLEEP_CLK, 28 + DT_DSI0_PHY_PLL_OUT_BYTECLK, 29 + DT_DSI0_PHY_PLL_OUT_DSICLK, 30 + DT_GPLL0_DISP_DIV, 31 + }; 32 + 33 + enum { 34 + P_BI_TCXO, 35 + P_DISP_CC_PLL0_OUT_MAIN, 36 + P_DSI0_PHY_PLL_OUT_BYTECLK, 37 + P_DSI0_PHY_PLL_OUT_DSICLK, 38 + P_GPLL0_OUT_MAIN, 39 + P_SLEEP_CLK, 40 + }; 41 + 42 + static const struct clk_parent_data parent_data_tcxo = { .index = DT_BI_TCXO }; 43 + 44 + static const struct pll_vco spark_vco[] = { 45 + { 500000000, 1000000000, 2 }, 46 + }; 47 + 48 + /* 768MHz configuration */ 49 + static const struct alpha_pll_config disp_cc_pll0_config = { 50 + .l = 0x28, 51 + .alpha = 0x0, 52 + .alpha_en_mask = BIT(24), 53 + .vco_val = 0x2 << 20, 54 + .vco_mask = GENMASK(21, 20), 55 + .main_output_mask = BIT(0), 56 + .config_ctl_val = 0x4001055B, 57 + }; 58 + 59 + static struct clk_alpha_pll disp_cc_pll0 = { 60 + .offset = 0x0, 61 + .vco_table = spark_vco, 62 + .num_vco = ARRAY_SIZE(spark_vco), 63 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], 64 + .clkr = { 65 + .hw.init = &(struct clk_init_data){ 66 + .name = "disp_cc_pll0", 67 + .parent_data = &parent_data_tcxo, 68 + .num_parents = 1, 69 + .ops = &clk_alpha_pll_ops, 70 + }, 71 + }, 72 + }; 73 + 74 + static const struct clk_div_table post_div_table_disp_cc_pll0_out_main[] = { 75 + { 0x0, 1 }, 76 + { } 77 + }; 78 + static struct clk_alpha_pll_postdiv disp_cc_pll0_out_main = { 79 + .offset = 0x0, 80 + .post_div_shift = 8, 81 + .post_div_table = post_div_table_disp_cc_pll0_out_main, 82 + .num_post_div = ARRAY_SIZE(post_div_table_disp_cc_pll0_out_main), 83 + .width = 4, 84 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT], 85 + .clkr.hw.init = &(struct clk_init_data){ 86 + .name = "disp_cc_pll0_out_main", 87 + .parent_hws = (const struct clk_hw*[]){ 88 + &disp_cc_pll0.clkr.hw, 89 + }, 90 + .num_parents = 1, 91 + .flags = CLK_SET_RATE_PARENT, 92 + .ops = &clk_alpha_pll_postdiv_ops, 93 + }, 94 + }; 95 + 96 + static const struct parent_map disp_cc_parent_map_0[] = { 97 + { P_BI_TCXO, 0 }, 98 + { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 }, 99 + }; 100 + 101 + static const struct clk_parent_data disp_cc_parent_data_0[] = { 102 + { .index = DT_BI_TCXO }, 103 + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, 104 + }; 105 + 106 + static const struct parent_map disp_cc_parent_map_1[] = { 107 + { P_BI_TCXO, 0 }, 108 + }; 109 + 110 + static const struct clk_parent_data disp_cc_parent_data_1[] = { 111 + { .index = DT_BI_TCXO }, 112 + }; 113 + 114 + static const struct parent_map disp_cc_parent_map_2[] = { 115 + { P_BI_TCXO, 0 }, 116 + { P_GPLL0_OUT_MAIN, 4 }, 117 + }; 118 + 119 + static const struct clk_parent_data disp_cc_parent_data_2[] = { 120 + { .index = DT_BI_TCXO }, 121 + { .index = DT_GPLL0_DISP_DIV }, 122 + }; 123 + 124 + static const struct parent_map disp_cc_parent_map_3[] = { 125 + { P_BI_TCXO, 0 }, 126 + { P_DISP_CC_PLL0_OUT_MAIN, 1 }, 127 + }; 128 + 129 + static const struct clk_parent_data disp_cc_parent_data_3[] = { 130 + { .index = DT_BI_TCXO }, 131 + { .hw = &disp_cc_pll0_out_main.clkr.hw }, 132 + }; 133 + 134 + static const struct parent_map disp_cc_parent_map_4[] = { 135 + { P_BI_TCXO, 0 }, 136 + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, 137 + }; 138 + 139 + static const struct clk_parent_data disp_cc_parent_data_4[] = { 140 + { .index = DT_BI_TCXO }, 141 + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, 142 + }; 143 + 144 + static const struct parent_map disp_cc_parent_map_5[] = { 145 + { P_SLEEP_CLK, 0 }, 146 + }; 147 + 148 + static const struct clk_parent_data disp_cc_parent_data_5[] = { 149 + { .index = DT_SLEEP_CLK, }, 150 + }; 151 + 152 + static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { 153 + .cmd_rcgr = 0x20bc, 154 + .mnd_width = 0, 155 + .hid_width = 5, 156 + .parent_map = disp_cc_parent_map_0, 157 + .clkr.hw.init = &(struct clk_init_data){ 158 + .name = "disp_cc_mdss_byte0_clk_src", 159 + .parent_data = disp_cc_parent_data_0, 160 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 161 + /* For set_rate and set_parent to succeed, parent(s) must be enabled */ 162 + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE | CLK_GET_RATE_NOCACHE, 163 + .ops = &clk_byte2_ops, 164 + }, 165 + }; 166 + 167 + static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { 168 + .reg = 0x20d4, 169 + .shift = 0, 170 + .width = 2, 171 + .clkr.hw.init = &(struct clk_init_data) { 172 + .name = "disp_cc_mdss_byte0_div_clk_src", 173 + .parent_hws = (const struct clk_hw*[]){ 174 + &disp_cc_mdss_byte0_clk_src.clkr.hw, 175 + }, 176 + .num_parents = 1, 177 + .ops = &clk_regmap_div_ops, 178 + }, 179 + }; 180 + 181 + static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { 182 + F(19200000, P_BI_TCXO, 1, 0, 0), 183 + F(37500000, P_GPLL0_OUT_MAIN, 8, 0, 0), 184 + F(75000000, P_GPLL0_OUT_MAIN, 4, 0, 0), 185 + { } 186 + }; 187 + 188 + static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { 189 + .cmd_rcgr = 0x2154, 190 + .mnd_width = 0, 191 + .hid_width = 5, 192 + .parent_map = disp_cc_parent_map_2, 193 + .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, 194 + .clkr.hw.init = &(struct clk_init_data){ 195 + .name = "disp_cc_mdss_ahb_clk_src", 196 + .parent_data = disp_cc_parent_data_2, 197 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), 198 + .ops = &clk_rcg2_shared_ops, 199 + }, 200 + }; 201 + 202 + static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = { 203 + F(19200000, P_BI_TCXO, 1, 0, 0), 204 + { } 205 + }; 206 + 207 + static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { 208 + .cmd_rcgr = 0x20d8, 209 + .mnd_width = 0, 210 + .hid_width = 5, 211 + .parent_map = disp_cc_parent_map_0, 212 + .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, 213 + .clkr.hw.init = &(struct clk_init_data){ 214 + .name = "disp_cc_mdss_esc0_clk_src", 215 + .parent_data = disp_cc_parent_data_0, 216 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 217 + .ops = &clk_rcg2_ops, 218 + }, 219 + }; 220 + 221 + static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { 222 + F(19200000, P_BI_TCXO, 1, 0, 0), 223 + F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0), 224 + F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 225 + F(307200000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), 226 + F(384000000, P_DISP_CC_PLL0_OUT_MAIN, 2, 0, 0), 227 + { } 228 + }; 229 + 230 + static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { 231 + .cmd_rcgr = 0x2074, 232 + .mnd_width = 0, 233 + .hid_width = 5, 234 + .parent_map = disp_cc_parent_map_3, 235 + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, 236 + .clkr.hw.init = &(struct clk_init_data){ 237 + .name = "disp_cc_mdss_mdp_clk_src", 238 + .parent_data = disp_cc_parent_data_3, 239 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), 240 + .flags = CLK_SET_RATE_PARENT, 241 + .ops = &clk_rcg2_shared_ops, 242 + }, 243 + }; 244 + 245 + static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { 246 + .cmd_rcgr = 0x205c, 247 + .mnd_width = 8, 248 + .hid_width = 5, 249 + .parent_map = disp_cc_parent_map_4, 250 + .clkr.hw.init = &(struct clk_init_data){ 251 + .name = "disp_cc_mdss_pclk0_clk_src", 252 + .parent_data = disp_cc_parent_data_4, 253 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), 254 + /* For set_rate and set_parent to succeed, parent(s) must be enabled */ 255 + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE | CLK_GET_RATE_NOCACHE, 256 + .ops = &clk_pixel_ops, 257 + }, 258 + }; 259 + 260 + static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = { 261 + F(19200000, P_BI_TCXO, 1, 0, 0), 262 + F(192000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0), 263 + F(256000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 264 + F(307200000, P_DISP_CC_PLL0_OUT_MAIN, 2.5, 0, 0), 265 + { } 266 + }; 267 + 268 + static struct clk_rcg2 disp_cc_mdss_rot_clk_src = { 269 + .cmd_rcgr = 0x208c, 270 + .mnd_width = 0, 271 + .hid_width = 5, 272 + .parent_map = disp_cc_parent_map_3, 273 + .freq_tbl = ftbl_disp_cc_mdss_rot_clk_src, 274 + .clkr.hw.init = &(struct clk_init_data){ 275 + .name = "disp_cc_mdss_rot_clk_src", 276 + .parent_data = disp_cc_parent_data_3, 277 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), 278 + .flags = CLK_SET_RATE_PARENT, 279 + .ops = &clk_rcg2_shared_ops, 280 + }, 281 + }; 282 + 283 + static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { 284 + .cmd_rcgr = 0x20a4, 285 + .mnd_width = 0, 286 + .hid_width = 5, 287 + .parent_map = disp_cc_parent_map_1, 288 + .freq_tbl = ftbl_disp_cc_mdss_esc0_clk_src, 289 + .clkr.hw.init = &(struct clk_init_data){ 290 + .name = "disp_cc_mdss_vsync_clk_src", 291 + .parent_data = disp_cc_parent_data_1, 292 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), 293 + .flags = CLK_SET_RATE_PARENT, 294 + .ops = &clk_rcg2_shared_ops, 295 + }, 296 + }; 297 + 298 + static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = { 299 + F(32764, P_SLEEP_CLK, 1, 0, 0), 300 + { } 301 + }; 302 + 303 + static struct clk_rcg2 disp_cc_sleep_clk_src = { 304 + .cmd_rcgr = 0x6050, 305 + .mnd_width = 0, 306 + .hid_width = 5, 307 + .parent_map = disp_cc_parent_map_5, 308 + .freq_tbl = ftbl_disp_cc_sleep_clk_src, 309 + .clkr.hw.init = &(struct clk_init_data){ 310 + .name = "disp_cc_sleep_clk_src", 311 + .parent_data = disp_cc_parent_data_5, 312 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), 313 + .ops = &clk_rcg2_ops, 314 + }, 315 + }; 316 + 317 + static struct clk_branch disp_cc_mdss_ahb_clk = { 318 + .halt_reg = 0x2044, 319 + .halt_check = BRANCH_HALT, 320 + .clkr = { 321 + .enable_reg = 0x2044, 322 + .enable_mask = BIT(0), 323 + .hw.init = &(struct clk_init_data){ 324 + .name = "disp_cc_mdss_ahb_clk", 325 + .parent_hws = (const struct clk_hw*[]){ 326 + &disp_cc_mdss_ahb_clk_src.clkr.hw, 327 + }, 328 + .num_parents = 1, 329 + .flags = CLK_SET_RATE_PARENT, 330 + .ops = &clk_branch2_ops, 331 + }, 332 + }, 333 + }; 334 + 335 + static struct clk_branch disp_cc_mdss_byte0_clk = { 336 + .halt_reg = 0x2024, 337 + .halt_check = BRANCH_HALT, 338 + .clkr = { 339 + .enable_reg = 0x2024, 340 + .enable_mask = BIT(0), 341 + .hw.init = &(struct clk_init_data){ 342 + .name = "disp_cc_mdss_byte0_clk", 343 + .parent_hws = (const struct clk_hw*[]){ 344 + &disp_cc_mdss_byte0_clk_src.clkr.hw, 345 + }, 346 + .num_parents = 1, 347 + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 348 + .ops = &clk_branch2_ops, 349 + }, 350 + }, 351 + }; 352 + 353 + static struct clk_branch disp_cc_mdss_byte0_intf_clk = { 354 + .halt_reg = 0x2028, 355 + .halt_check = BRANCH_HALT, 356 + .clkr = { 357 + .enable_reg = 0x2028, 358 + .enable_mask = BIT(0), 359 + .hw.init = &(struct clk_init_data){ 360 + .name = "disp_cc_mdss_byte0_intf_clk", 361 + .parent_hws = (const struct clk_hw*[]){ 362 + &disp_cc_mdss_byte0_div_clk_src.clkr.hw, 363 + }, 364 + .num_parents = 1, 365 + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 366 + .ops = &clk_branch2_ops, 367 + }, 368 + }, 369 + }; 370 + 371 + static struct clk_branch disp_cc_mdss_esc0_clk = { 372 + .halt_reg = 0x202c, 373 + .halt_check = BRANCH_HALT, 374 + .clkr = { 375 + .enable_reg = 0x202c, 376 + .enable_mask = BIT(0), 377 + .hw.init = &(struct clk_init_data){ 378 + .name = "disp_cc_mdss_esc0_clk", 379 + .parent_hws = (const struct clk_hw*[]){ 380 + &disp_cc_mdss_esc0_clk_src.clkr.hw, 381 + }, 382 + .num_parents = 1, 383 + .flags = CLK_SET_RATE_PARENT, 384 + .ops = &clk_branch2_ops, 385 + }, 386 + }, 387 + }; 388 + 389 + static struct clk_branch disp_cc_mdss_mdp_clk = { 390 + .halt_reg = 0x2008, 391 + .halt_check = BRANCH_HALT, 392 + .clkr = { 393 + .enable_reg = 0x2008, 394 + .enable_mask = BIT(0), 395 + .hw.init = &(struct clk_init_data){ 396 + .name = "disp_cc_mdss_mdp_clk", 397 + .parent_hws = (const struct clk_hw*[]){ 398 + &disp_cc_mdss_mdp_clk_src.clkr.hw, 399 + }, 400 + .num_parents = 1, 401 + .flags = CLK_SET_RATE_PARENT, 402 + .ops = &clk_branch2_ops, 403 + }, 404 + }, 405 + }; 406 + 407 + static struct clk_branch disp_cc_mdss_mdp_lut_clk = { 408 + .halt_reg = 0x2018, 409 + .halt_check = BRANCH_HALT_VOTED, 410 + .clkr = { 411 + .enable_reg = 0x2018, 412 + .enable_mask = BIT(0), 413 + .hw.init = &(struct clk_init_data){ 414 + .name = "disp_cc_mdss_mdp_lut_clk", 415 + .parent_hws = (const struct clk_hw*[]){ 416 + &disp_cc_mdss_mdp_clk_src.clkr.hw, 417 + }, 418 + .num_parents = 1, 419 + .flags = CLK_SET_RATE_PARENT, 420 + .ops = &clk_branch2_ops, 421 + }, 422 + }, 423 + }; 424 + 425 + static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = { 426 + .halt_reg = 0x4004, 427 + .halt_check = BRANCH_HALT_VOTED, 428 + .clkr = { 429 + .enable_reg = 0x4004, 430 + .enable_mask = BIT(0), 431 + .hw.init = &(struct clk_init_data){ 432 + .name = "disp_cc_mdss_non_gdsc_ahb_clk", 433 + .parent_hws = (const struct clk_hw*[]){ 434 + &disp_cc_mdss_ahb_clk_src.clkr.hw, 435 + }, 436 + .num_parents = 1, 437 + .flags = CLK_SET_RATE_PARENT, 438 + .ops = &clk_branch2_ops, 439 + }, 440 + }, 441 + }; 442 + 443 + static struct clk_branch disp_cc_mdss_pclk0_clk = { 444 + .halt_reg = 0x2004, 445 + .halt_check = BRANCH_HALT, 446 + .clkr = { 447 + .enable_reg = 0x2004, 448 + .enable_mask = BIT(0), 449 + .hw.init = &(struct clk_init_data){ 450 + .name = "disp_cc_mdss_pclk0_clk", 451 + .parent_hws = (const struct clk_hw*[]){ 452 + &disp_cc_mdss_pclk0_clk_src.clkr.hw, 453 + }, 454 + .num_parents = 1, 455 + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 456 + .ops = &clk_branch2_ops, 457 + }, 458 + }, 459 + }; 460 + 461 + static struct clk_branch disp_cc_mdss_rot_clk = { 462 + .halt_reg = 0x2010, 463 + .halt_check = BRANCH_HALT, 464 + .clkr = { 465 + .enable_reg = 0x2010, 466 + .enable_mask = BIT(0), 467 + .hw.init = &(struct clk_init_data){ 468 + .name = "disp_cc_mdss_rot_clk", 469 + .parent_names = (const char *[]){ 470 + "disp_cc_mdss_rot_clk_src", 471 + }, 472 + .num_parents = 1, 473 + .flags = CLK_SET_RATE_PARENT, 474 + .ops = &clk_branch2_ops, 475 + }, 476 + }, 477 + }; 478 + 479 + static struct clk_branch disp_cc_mdss_vsync_clk = { 480 + .halt_reg = 0x2020, 481 + .halt_check = BRANCH_HALT, 482 + .clkr = { 483 + .enable_reg = 0x2020, 484 + .enable_mask = BIT(0), 485 + .hw.init = &(struct clk_init_data){ 486 + .name = "disp_cc_mdss_vsync_clk", 487 + .parent_hws = (const struct clk_hw*[]){ 488 + &disp_cc_mdss_vsync_clk_src.clkr.hw, 489 + }, 490 + .num_parents = 1, 491 + .flags = CLK_SET_RATE_PARENT, 492 + .ops = &clk_branch2_ops, 493 + }, 494 + }, 495 + }; 496 + 497 + static struct clk_branch disp_cc_sleep_clk = { 498 + .halt_reg = 0x6068, 499 + .halt_check = BRANCH_HALT, 500 + .clkr = { 501 + .enable_reg = 0x6068, 502 + .enable_mask = BIT(0), 503 + .hw.init = &(struct clk_init_data){ 504 + .name = "disp_cc_sleep_clk", 505 + .parent_hws = (const struct clk_hw*[]){ 506 + &disp_cc_sleep_clk_src.clkr.hw, 507 + }, 508 + .num_parents = 1, 509 + .flags = CLK_SET_RATE_PARENT, 510 + .ops = &clk_branch2_ops, 511 + }, 512 + }, 513 + }; 514 + 515 + static struct gdsc mdss_gdsc = { 516 + .gdscr = 0x3000, 517 + .pd = { 518 + .name = "mdss_gdsc", 519 + }, 520 + .pwrsts = PWRSTS_OFF_ON, 521 + .flags = HW_CTRL, 522 + }; 523 + 524 + static struct gdsc *disp_cc_sm6115_gdscs[] = { 525 + [MDSS_GDSC] = &mdss_gdsc, 526 + }; 527 + 528 + static struct clk_regmap *disp_cc_sm6115_clocks[] = { 529 + [DISP_CC_PLL0] = &disp_cc_pll0.clkr, 530 + [DISP_CC_PLL0_OUT_MAIN] = &disp_cc_pll0_out_main.clkr, 531 + [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, 532 + [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr, 533 + [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, 534 + [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, 535 + [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr, 536 + [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, 537 + [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, 538 + [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, 539 + [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, 540 + [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, 541 + [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, 542 + [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr, 543 + [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, 544 + [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, 545 + [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, 546 + [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, 547 + [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, 548 + [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, 549 + [DISP_CC_SLEEP_CLK] = &disp_cc_sleep_clk.clkr, 550 + [DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr, 551 + }; 552 + 553 + static const struct regmap_config disp_cc_sm6115_regmap_config = { 554 + .reg_bits = 32, 555 + .reg_stride = 4, 556 + .val_bits = 32, 557 + .max_register = 0x10000, 558 + .fast_io = true, 559 + }; 560 + 561 + static const struct qcom_cc_desc disp_cc_sm6115_desc = { 562 + .config = &disp_cc_sm6115_regmap_config, 563 + .clks = disp_cc_sm6115_clocks, 564 + .num_clks = ARRAY_SIZE(disp_cc_sm6115_clocks), 565 + .gdscs = disp_cc_sm6115_gdscs, 566 + .num_gdscs = ARRAY_SIZE(disp_cc_sm6115_gdscs), 567 + }; 568 + 569 + static const struct of_device_id disp_cc_sm6115_match_table[] = { 570 + { .compatible = "qcom,sm6115-dispcc" }, 571 + { } 572 + }; 573 + MODULE_DEVICE_TABLE(of, disp_cc_sm6115_match_table); 574 + 575 + static int disp_cc_sm6115_probe(struct platform_device *pdev) 576 + { 577 + struct regmap *regmap; 578 + int ret; 579 + 580 + regmap = qcom_cc_map(pdev, &disp_cc_sm6115_desc); 581 + if (IS_ERR(regmap)) 582 + return PTR_ERR(regmap); 583 + 584 + clk_alpha_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); 585 + 586 + /* Keep DISP_CC_XO_CLK always-ON */ 587 + regmap_update_bits(regmap, 0x604c, BIT(0), BIT(0)); 588 + 589 + ret = qcom_cc_really_probe(pdev, &disp_cc_sm6115_desc, regmap); 590 + if (ret) { 591 + dev_err(&pdev->dev, "Failed to register DISP CC clocks\n"); 592 + return ret; 593 + } 594 + 595 + return ret; 596 + } 597 + 598 + static struct platform_driver disp_cc_sm6115_driver = { 599 + .probe = disp_cc_sm6115_probe, 600 + .driver = { 601 + .name = "dispcc-sm6115", 602 + .of_match_table = disp_cc_sm6115_match_table, 603 + }, 604 + }; 605 + 606 + module_platform_driver(disp_cc_sm6115_driver); 607 + MODULE_DESCRIPTION("Qualcomm SM6115 Display Clock controller"); 608 + MODULE_LICENSE("GPL");