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 DISPCC driver support for SM4450

Add Display Clock Controller (DISPCC) support for SM4450 platform.

Signed-off-by: Ajit Pandey <quic_ajipan@quicinc.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://lore.kernel.org/r/20240611133752.2192401-4-quic_ajipan@quicinc.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>

authored by

Ajit Pandey and committed by
Bjorn Andersson
76f05f1e fff61797

+781
+10
drivers/clk/qcom/Kconfig
··· 867 867 Support for the camera clock controller on SM8650 devices. 868 868 Say Y if you want to support camera devices and camera functionality. 869 869 870 + config SM_DISPCC_4450 871 + tristate "SM4450 Display Clock Controller" 872 + depends on ARM64 || COMPILE_TEST 873 + depends on SM_GCC_4450 874 + help 875 + Support for the display clock controller on Qualcomm Technologies, Inc 876 + SM4450 devices. 877 + Say Y if you want to support display devices and functionality such as 878 + splash screen 879 + 870 880 config SM_DISPCC_6115 871 881 tristate "SM6115 Display Clock Controller" 872 882 depends on ARM64 || COMPILE_TEST
+1
drivers/clk/qcom/Makefile
··· 114 114 obj-$(CONFIG_SM_CAMCC_8450) += camcc-sm8450.o 115 115 obj-$(CONFIG_SM_CAMCC_8550) += camcc-sm8550.o 116 116 obj-$(CONFIG_SM_CAMCC_8650) += camcc-sm8650.o 117 + obj-$(CONFIG_SM_DISPCC_4450) += dispcc-sm4450.o 117 118 obj-$(CONFIG_SM_DISPCC_6115) += dispcc-sm6115.o 118 119 obj-$(CONFIG_SM_DISPCC_6125) += dispcc-sm6125.o 119 120 obj-$(CONFIG_SM_DISPCC_6350) += dispcc-sm6350.o
+770
drivers/clk/qcom/dispcc-sm4450.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. 4 + */ 5 + 6 + #include <linux/clk-provider.h> 7 + #include <linux/module.h> 8 + #include <linux/mod_devicetable.h> 9 + #include <linux/of.h> 10 + #include <linux/platform_device.h> 11 + #include <linux/regmap.h> 12 + 13 + #include <dt-bindings/clock/qcom,sm4450-dispcc.h> 14 + 15 + #include "clk-alpha-pll.h" 16 + #include "clk-branch.h" 17 + #include "clk-pll.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 + #include "reset.h" 24 + 25 + enum { 26 + DT_BI_TCXO, 27 + DT_BI_TCXO_AO, 28 + DT_AHB_CLK, 29 + DT_SLEEP_CLK, 30 + 31 + DT_DSI0_PHY_PLL_OUT_BYTECLK, 32 + DT_DSI0_PHY_PLL_OUT_DSICLK, 33 + }; 34 + 35 + enum { 36 + P_BI_TCXO, 37 + P_DISP_CC_PLL0_OUT_MAIN, 38 + P_DISP_CC_PLL1_OUT_EVEN, 39 + P_DISP_CC_PLL1_OUT_MAIN, 40 + P_DSI0_PHY_PLL_OUT_BYTECLK, 41 + P_DSI0_PHY_PLL_OUT_DSICLK, 42 + P_SLEEP_CLK, 43 + }; 44 + 45 + static const struct pll_vco lucid_evo_vco[] = { 46 + { 249600000, 2020000000, 0 }, 47 + }; 48 + 49 + /* 600.0 MHz Configuration */ 50 + static const struct alpha_pll_config disp_cc_pll0_config = { 51 + .l = 0x1f, 52 + .alpha = 0x4000, 53 + .config_ctl_val = 0x20485699, 54 + .config_ctl_hi_val = 0x00182261, 55 + .config_ctl_hi1_val = 0x32aa299c, 56 + .user_ctl_val = 0x00000000, 57 + .user_ctl_hi_val = 0x00000805, 58 + }; 59 + 60 + static struct clk_alpha_pll disp_cc_pll0 = { 61 + .offset = 0x0, 62 + .vco_table = lucid_evo_vco, 63 + .num_vco = ARRAY_SIZE(lucid_evo_vco), 64 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], 65 + .clkr = { 66 + .hw.init = &(const struct clk_init_data) { 67 + .name = "disp_cc_pll0", 68 + .parent_data = &(const struct clk_parent_data) { 69 + .index = DT_BI_TCXO, 70 + }, 71 + .num_parents = 1, 72 + .ops = &clk_alpha_pll_lucid_evo_ops, 73 + }, 74 + }, 75 + }; 76 + 77 + static struct clk_alpha_pll disp_cc_pll1 = { 78 + .offset = 0x1000, 79 + .vco_table = lucid_evo_vco, 80 + .num_vco = ARRAY_SIZE(lucid_evo_vco), 81 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], 82 + .clkr = { 83 + .hw.init = &(const struct clk_init_data) { 84 + .name = "disp_cc_pll1", 85 + .parent_data = &(const struct clk_parent_data) { 86 + .index = DT_BI_TCXO, 87 + }, 88 + .num_parents = 1, 89 + .ops = &clk_alpha_pll_lucid_evo_ops, 90 + }, 91 + }, 92 + }; 93 + 94 + static const struct parent_map disp_cc_parent_map_0[] = { 95 + { P_BI_TCXO, 0 }, 96 + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, 97 + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, 98 + }; 99 + 100 + static const struct clk_parent_data disp_cc_parent_data_0[] = { 101 + { .index = DT_BI_TCXO }, 102 + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, 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 + { P_DISP_CC_PLL0_OUT_MAIN, 1 }, 109 + { P_DISP_CC_PLL1_OUT_MAIN, 4 }, 110 + { P_DISP_CC_PLL1_OUT_EVEN, 6 }, 111 + }; 112 + 113 + static const struct clk_parent_data disp_cc_parent_data_1[] = { 114 + { .index = DT_BI_TCXO }, 115 + { .hw = &disp_cc_pll0.clkr.hw }, 116 + { .hw = &disp_cc_pll1.clkr.hw }, 117 + { .hw = &disp_cc_pll1.clkr.hw }, 118 + }; 119 + 120 + static const struct parent_map disp_cc_parent_map_2[] = { 121 + { P_BI_TCXO, 0 }, 122 + }; 123 + 124 + static const struct clk_parent_data disp_cc_parent_data_2[] = { 125 + { .index = DT_BI_TCXO }, 126 + }; 127 + 128 + static const struct clk_parent_data disp_cc_parent_data_2_ao[] = { 129 + { .index = DT_BI_TCXO_AO }, 130 + }; 131 + 132 + static const struct parent_map disp_cc_parent_map_3[] = { 133 + { P_BI_TCXO, 0 }, 134 + { P_DISP_CC_PLL1_OUT_MAIN, 4 }, 135 + { P_DISP_CC_PLL1_OUT_EVEN, 6 }, 136 + }; 137 + 138 + static const struct clk_parent_data disp_cc_parent_data_3[] = { 139 + { .index = DT_BI_TCXO }, 140 + { .hw = &disp_cc_pll1.clkr.hw }, 141 + { .hw = &disp_cc_pll1.clkr.hw }, 142 + }; 143 + 144 + static const struct parent_map disp_cc_parent_map_4[] = { 145 + { P_BI_TCXO, 0 }, 146 + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, 147 + }; 148 + 149 + static const struct clk_parent_data disp_cc_parent_data_4[] = { 150 + { .index = DT_BI_TCXO }, 151 + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, 152 + }; 153 + 154 + static const struct parent_map disp_cc_parent_map_5[] = { 155 + { P_SLEEP_CLK, 0 }, 156 + }; 157 + 158 + static const struct clk_parent_data disp_cc_parent_data_5[] = { 159 + { .index = DT_SLEEP_CLK }, 160 + }; 161 + 162 + static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { 163 + F(19200000, P_BI_TCXO, 1, 0, 0), 164 + F(37500000, P_DISP_CC_PLL1_OUT_MAIN, 16, 0, 0), 165 + F(75000000, P_DISP_CC_PLL1_OUT_MAIN, 8, 0, 0), 166 + { } 167 + }; 168 + 169 + static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { 170 + .cmd_rcgr = 0x82a4, 171 + .mnd_width = 0, 172 + .hid_width = 5, 173 + .parent_map = disp_cc_parent_map_3, 174 + .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, 175 + .clkr.hw.init = &(const struct clk_init_data) { 176 + .name = "disp_cc_mdss_ahb_clk_src", 177 + .parent_data = disp_cc_parent_data_3, 178 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), 179 + .flags = CLK_SET_RATE_PARENT, 180 + .ops = &clk_rcg2_shared_ops, 181 + }, 182 + }; 183 + 184 + static const struct freq_tbl ftbl_disp_cc_mdss_byte0_clk_src[] = { 185 + F(19200000, P_BI_TCXO, 1, 0, 0), 186 + { } 187 + }; 188 + 189 + static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { 190 + .cmd_rcgr = 0x80f8, 191 + .mnd_width = 0, 192 + .hid_width = 5, 193 + .parent_map = disp_cc_parent_map_0, 194 + .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src, 195 + .clkr.hw.init = &(const struct clk_init_data) { 196 + .name = "disp_cc_mdss_byte0_clk_src", 197 + .parent_data = disp_cc_parent_data_0, 198 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 199 + .flags = CLK_SET_RATE_PARENT, 200 + .ops = &clk_byte2_ops, 201 + }, 202 + }; 203 + 204 + static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { 205 + .cmd_rcgr = 0x8114, 206 + .mnd_width = 0, 207 + .hid_width = 5, 208 + .parent_map = disp_cc_parent_map_4, 209 + .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src, 210 + .clkr.hw.init = &(const struct clk_init_data) { 211 + .name = "disp_cc_mdss_esc0_clk_src", 212 + .parent_data = disp_cc_parent_data_4, 213 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), 214 + .flags = CLK_SET_RATE_PARENT, 215 + .ops = &clk_rcg2_shared_ops, 216 + }, 217 + }; 218 + 219 + static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { 220 + F(200000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 221 + F(325000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 222 + F(380000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 223 + F(506000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 224 + F(608000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), 225 + { } 226 + }; 227 + 228 + static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { 229 + .cmd_rcgr = 0x80b0, 230 + .mnd_width = 0, 231 + .hid_width = 5, 232 + .parent_map = disp_cc_parent_map_1, 233 + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, 234 + .clkr.hw.init = &(const struct clk_init_data) { 235 + .name = "disp_cc_mdss_mdp_clk_src", 236 + .parent_data = disp_cc_parent_data_1, 237 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), 238 + .flags = CLK_SET_RATE_PARENT, 239 + .ops = &clk_rcg2_shared_ops, 240 + }, 241 + }; 242 + 243 + static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { 244 + .cmd_rcgr = 0x8098, 245 + .mnd_width = 8, 246 + .hid_width = 5, 247 + .parent_map = disp_cc_parent_map_0, 248 + .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src, 249 + .clkr.hw.init = &(const struct clk_init_data) { 250 + .name = "disp_cc_mdss_pclk0_clk_src", 251 + .parent_data = disp_cc_parent_data_0, 252 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), 253 + .flags = CLK_SET_RATE_PARENT, 254 + .ops = &clk_pixel_ops, 255 + }, 256 + }; 257 + 258 + static const struct freq_tbl ftbl_disp_cc_mdss_rot_clk_src[] = { 259 + F(200000000, P_DISP_CC_PLL1_OUT_MAIN, 3, 0, 0), 260 + F(300000000, P_DISP_CC_PLL1_OUT_MAIN, 2, 0, 0), 261 + { } 262 + }; 263 + 264 + static struct clk_rcg2 disp_cc_mdss_rot_clk_src = { 265 + .cmd_rcgr = 0x80c8, 266 + .mnd_width = 0, 267 + .hid_width = 5, 268 + .parent_map = disp_cc_parent_map_1, 269 + .freq_tbl = ftbl_disp_cc_mdss_rot_clk_src, 270 + .clkr.hw.init = &(const struct clk_init_data) { 271 + .name = "disp_cc_mdss_rot_clk_src", 272 + .parent_data = disp_cc_parent_data_1, 273 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), 274 + .flags = CLK_SET_RATE_PARENT, 275 + .ops = &clk_rcg2_shared_ops, 276 + }, 277 + }; 278 + 279 + static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { 280 + .cmd_rcgr = 0x80e0, 281 + .mnd_width = 0, 282 + .hid_width = 5, 283 + .parent_map = disp_cc_parent_map_2, 284 + .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src, 285 + .clkr.hw.init = &(const struct clk_init_data) { 286 + .name = "disp_cc_mdss_vsync_clk_src", 287 + .parent_data = disp_cc_parent_data_2, 288 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), 289 + .flags = CLK_SET_RATE_PARENT, 290 + .ops = &clk_rcg2_shared_ops, 291 + }, 292 + }; 293 + 294 + static const struct freq_tbl ftbl_disp_cc_sleep_clk_src[] = { 295 + F(32000, P_SLEEP_CLK, 1, 0, 0), 296 + { } 297 + }; 298 + 299 + static struct clk_rcg2 disp_cc_sleep_clk_src = { 300 + .cmd_rcgr = 0xe058, 301 + .mnd_width = 0, 302 + .hid_width = 5, 303 + .parent_map = disp_cc_parent_map_5, 304 + .freq_tbl = ftbl_disp_cc_sleep_clk_src, 305 + .clkr.hw.init = &(const struct clk_init_data) { 306 + .name = "disp_cc_sleep_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, 310 + .ops = &clk_rcg2_shared_ops, 311 + }, 312 + }; 313 + 314 + static struct clk_rcg2 disp_cc_xo_clk_src = { 315 + .cmd_rcgr = 0xe03c, 316 + .mnd_width = 0, 317 + .hid_width = 5, 318 + .parent_map = disp_cc_parent_map_2, 319 + .freq_tbl = ftbl_disp_cc_mdss_byte0_clk_src, 320 + .clkr.hw.init = &(const struct clk_init_data) { 321 + .name = "disp_cc_xo_clk_src", 322 + .parent_data = disp_cc_parent_data_2_ao, 323 + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2_ao), 324 + .flags = CLK_SET_RATE_PARENT, 325 + .ops = &clk_rcg2_shared_ops, 326 + }, 327 + }; 328 + 329 + static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { 330 + .reg = 0x8110, 331 + .shift = 0, 332 + .width = 4, 333 + .clkr.hw.init = &(const struct clk_init_data) { 334 + .name = "disp_cc_mdss_byte0_div_clk_src", 335 + .parent_hws = (const struct clk_hw*[]) { 336 + &disp_cc_mdss_byte0_clk_src.clkr.hw, 337 + }, 338 + .num_parents = 1, 339 + .flags = CLK_SET_RATE_PARENT, 340 + .ops = &clk_regmap_div_ops, 341 + }, 342 + }; 343 + 344 + static struct clk_branch disp_cc_mdss_ahb1_clk = { 345 + .halt_reg = 0xa020, 346 + .halt_check = BRANCH_HALT, 347 + .clkr = { 348 + .enable_reg = 0xa020, 349 + .enable_mask = BIT(0), 350 + .hw.init = &(const struct clk_init_data) { 351 + .name = "disp_cc_mdss_ahb1_clk", 352 + .parent_hws = (const struct clk_hw*[]) { 353 + &disp_cc_mdss_ahb_clk_src.clkr.hw, 354 + }, 355 + .num_parents = 1, 356 + .flags = CLK_SET_RATE_PARENT, 357 + .ops = &clk_branch2_ops, 358 + }, 359 + }, 360 + }; 361 + 362 + static struct clk_branch disp_cc_mdss_ahb_clk = { 363 + .halt_reg = 0x8094, 364 + .halt_check = BRANCH_HALT, 365 + .clkr = { 366 + .enable_reg = 0x8094, 367 + .enable_mask = BIT(0), 368 + .hw.init = &(const struct clk_init_data) { 369 + .name = "disp_cc_mdss_ahb_clk", 370 + .parent_hws = (const struct clk_hw*[]) { 371 + &disp_cc_mdss_ahb_clk_src.clkr.hw, 372 + }, 373 + .num_parents = 1, 374 + .flags = CLK_SET_RATE_PARENT, 375 + .ops = &clk_branch2_ops, 376 + }, 377 + }, 378 + }; 379 + 380 + static struct clk_branch disp_cc_mdss_byte0_clk = { 381 + .halt_reg = 0x8024, 382 + .halt_check = BRANCH_HALT, 383 + .clkr = { 384 + .enable_reg = 0x8024, 385 + .enable_mask = BIT(0), 386 + .hw.init = &(const struct clk_init_data) { 387 + .name = "disp_cc_mdss_byte0_clk", 388 + .parent_hws = (const struct clk_hw*[]) { 389 + &disp_cc_mdss_byte0_clk_src.clkr.hw, 390 + }, 391 + .num_parents = 1, 392 + .flags = CLK_SET_RATE_PARENT, 393 + .ops = &clk_branch2_ops, 394 + }, 395 + }, 396 + }; 397 + 398 + static struct clk_branch disp_cc_mdss_byte0_intf_clk = { 399 + .halt_reg = 0x8028, 400 + .halt_check = BRANCH_HALT, 401 + .clkr = { 402 + .enable_reg = 0x8028, 403 + .enable_mask = BIT(0), 404 + .hw.init = &(const struct clk_init_data) { 405 + .name = "disp_cc_mdss_byte0_intf_clk", 406 + .parent_hws = (const struct clk_hw*[]) { 407 + &disp_cc_mdss_byte0_div_clk_src.clkr.hw, 408 + }, 409 + .num_parents = 1, 410 + .flags = CLK_SET_RATE_PARENT, 411 + .ops = &clk_branch2_ops, 412 + }, 413 + }, 414 + }; 415 + 416 + static struct clk_branch disp_cc_mdss_esc0_clk = { 417 + .halt_reg = 0x802c, 418 + .halt_check = BRANCH_HALT, 419 + .clkr = { 420 + .enable_reg = 0x802c, 421 + .enable_mask = BIT(0), 422 + .hw.init = &(const struct clk_init_data) { 423 + .name = "disp_cc_mdss_esc0_clk", 424 + .parent_hws = (const struct clk_hw*[]) { 425 + &disp_cc_mdss_esc0_clk_src.clkr.hw, 426 + }, 427 + .num_parents = 1, 428 + .flags = CLK_SET_RATE_PARENT, 429 + .ops = &clk_branch2_ops, 430 + }, 431 + }, 432 + }; 433 + 434 + static struct clk_branch disp_cc_mdss_mdp1_clk = { 435 + .halt_reg = 0xa004, 436 + .halt_check = BRANCH_HALT, 437 + .clkr = { 438 + .enable_reg = 0xa004, 439 + .enable_mask = BIT(0), 440 + .hw.init = &(const struct clk_init_data) { 441 + .name = "disp_cc_mdss_mdp1_clk", 442 + .parent_hws = (const struct clk_hw*[]) { 443 + &disp_cc_mdss_mdp_clk_src.clkr.hw, 444 + }, 445 + .num_parents = 1, 446 + .flags = CLK_SET_RATE_PARENT, 447 + .ops = &clk_branch2_ops, 448 + }, 449 + }, 450 + }; 451 + 452 + static struct clk_branch disp_cc_mdss_mdp_clk = { 453 + .halt_reg = 0x8008, 454 + .halt_check = BRANCH_HALT, 455 + .clkr = { 456 + .enable_reg = 0x8008, 457 + .enable_mask = BIT(0), 458 + .hw.init = &(const struct clk_init_data) { 459 + .name = "disp_cc_mdss_mdp_clk", 460 + .parent_hws = (const struct clk_hw*[]) { 461 + &disp_cc_mdss_mdp_clk_src.clkr.hw, 462 + }, 463 + .num_parents = 1, 464 + .flags = CLK_SET_RATE_PARENT, 465 + .ops = &clk_branch2_ops, 466 + }, 467 + }, 468 + }; 469 + 470 + static struct clk_branch disp_cc_mdss_mdp_lut1_clk = { 471 + .halt_reg = 0xa014, 472 + .halt_check = BRANCH_HALT, 473 + .clkr = { 474 + .enable_reg = 0xa014, 475 + .enable_mask = BIT(0), 476 + .hw.init = &(const struct clk_init_data) { 477 + .name = "disp_cc_mdss_mdp_lut1_clk", 478 + .parent_hws = (const struct clk_hw*[]) { 479 + &disp_cc_mdss_mdp_clk_src.clkr.hw, 480 + }, 481 + .num_parents = 1, 482 + .flags = CLK_SET_RATE_PARENT, 483 + .ops = &clk_branch2_ops, 484 + }, 485 + }, 486 + }; 487 + 488 + static struct clk_branch disp_cc_mdss_mdp_lut_clk = { 489 + .halt_reg = 0x8018, 490 + .halt_check = BRANCH_HALT_VOTED, 491 + .clkr = { 492 + .enable_reg = 0x8018, 493 + .enable_mask = BIT(0), 494 + .hw.init = &(const struct clk_init_data) { 495 + .name = "disp_cc_mdss_mdp_lut_clk", 496 + .parent_hws = (const struct clk_hw*[]) { 497 + &disp_cc_mdss_mdp_clk_src.clkr.hw, 498 + }, 499 + .num_parents = 1, 500 + .flags = CLK_SET_RATE_PARENT, 501 + .ops = &clk_branch2_ops, 502 + }, 503 + }, 504 + }; 505 + 506 + static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = { 507 + .halt_reg = 0xc004, 508 + .halt_check = BRANCH_HALT_VOTED, 509 + .clkr = { 510 + .enable_reg = 0xc004, 511 + .enable_mask = BIT(0), 512 + .hw.init = &(const struct clk_init_data) { 513 + .name = "disp_cc_mdss_non_gdsc_ahb_clk", 514 + .parent_hws = (const struct clk_hw*[]) { 515 + &disp_cc_mdss_ahb_clk_src.clkr.hw, 516 + }, 517 + .num_parents = 1, 518 + .flags = CLK_SET_RATE_PARENT, 519 + .ops = &clk_branch2_ops, 520 + }, 521 + }, 522 + }; 523 + 524 + static struct clk_branch disp_cc_mdss_pclk0_clk = { 525 + .halt_reg = 0x8004, 526 + .halt_check = BRANCH_HALT, 527 + .clkr = { 528 + .enable_reg = 0x8004, 529 + .enable_mask = BIT(0), 530 + .hw.init = &(const struct clk_init_data) { 531 + .name = "disp_cc_mdss_pclk0_clk", 532 + .parent_hws = (const struct clk_hw*[]) { 533 + &disp_cc_mdss_pclk0_clk_src.clkr.hw, 534 + }, 535 + .num_parents = 1, 536 + .flags = CLK_SET_RATE_PARENT, 537 + .ops = &clk_branch2_ops, 538 + }, 539 + }, 540 + }; 541 + 542 + static struct clk_branch disp_cc_mdss_rot1_clk = { 543 + .halt_reg = 0xa00c, 544 + .halt_check = BRANCH_HALT, 545 + .clkr = { 546 + .enable_reg = 0xa00c, 547 + .enable_mask = BIT(0), 548 + .hw.init = &(const struct clk_init_data) { 549 + .name = "disp_cc_mdss_rot1_clk", 550 + .parent_hws = (const struct clk_hw*[]) { 551 + &disp_cc_mdss_rot_clk_src.clkr.hw, 552 + }, 553 + .num_parents = 1, 554 + .flags = CLK_SET_RATE_PARENT, 555 + .ops = &clk_branch2_ops, 556 + }, 557 + }, 558 + }; 559 + 560 + static struct clk_branch disp_cc_mdss_rot_clk = { 561 + .halt_reg = 0x8010, 562 + .halt_check = BRANCH_HALT, 563 + .clkr = { 564 + .enable_reg = 0x8010, 565 + .enable_mask = BIT(0), 566 + .hw.init = &(const struct clk_init_data) { 567 + .name = "disp_cc_mdss_rot_clk", 568 + .parent_hws = (const struct clk_hw*[]) { 569 + &disp_cc_mdss_rot_clk_src.clkr.hw, 570 + }, 571 + .num_parents = 1, 572 + .flags = CLK_SET_RATE_PARENT, 573 + .ops = &clk_branch2_ops, 574 + }, 575 + }, 576 + }; 577 + 578 + static struct clk_branch disp_cc_mdss_rscc_ahb_clk = { 579 + .halt_reg = 0xc00c, 580 + .halt_check = BRANCH_HALT, 581 + .clkr = { 582 + .enable_reg = 0xc00c, 583 + .enable_mask = BIT(0), 584 + .hw.init = &(const struct clk_init_data) { 585 + .name = "disp_cc_mdss_rscc_ahb_clk", 586 + .parent_hws = (const struct clk_hw*[]) { 587 + &disp_cc_mdss_ahb_clk_src.clkr.hw, 588 + }, 589 + .num_parents = 1, 590 + .flags = CLK_SET_RATE_PARENT, 591 + .ops = &clk_branch2_ops, 592 + }, 593 + }, 594 + }; 595 + 596 + static struct clk_branch disp_cc_mdss_rscc_vsync_clk = { 597 + .halt_reg = 0xc008, 598 + .halt_check = BRANCH_HALT, 599 + .clkr = { 600 + .enable_reg = 0xc008, 601 + .enable_mask = BIT(0), 602 + .hw.init = &(const struct clk_init_data) { 603 + .name = "disp_cc_mdss_rscc_vsync_clk", 604 + .parent_hws = (const struct clk_hw*[]) { 605 + &disp_cc_mdss_vsync_clk_src.clkr.hw, 606 + }, 607 + .num_parents = 1, 608 + .flags = CLK_SET_RATE_PARENT, 609 + .ops = &clk_branch2_ops, 610 + }, 611 + }, 612 + }; 613 + 614 + static struct clk_branch disp_cc_mdss_vsync1_clk = { 615 + .halt_reg = 0xa01c, 616 + .halt_check = BRANCH_HALT, 617 + .clkr = { 618 + .enable_reg = 0xa01c, 619 + .enable_mask = BIT(0), 620 + .hw.init = &(const struct clk_init_data) { 621 + .name = "disp_cc_mdss_vsync1_clk", 622 + .parent_hws = (const struct clk_hw*[]) { 623 + &disp_cc_mdss_vsync_clk_src.clkr.hw, 624 + }, 625 + .num_parents = 1, 626 + .flags = CLK_SET_RATE_PARENT, 627 + .ops = &clk_branch2_ops, 628 + }, 629 + }, 630 + }; 631 + 632 + static struct clk_branch disp_cc_mdss_vsync_clk = { 633 + .halt_reg = 0x8020, 634 + .halt_check = BRANCH_HALT, 635 + .clkr = { 636 + .enable_reg = 0x8020, 637 + .enable_mask = BIT(0), 638 + .hw.init = &(const struct clk_init_data) { 639 + .name = "disp_cc_mdss_vsync_clk", 640 + .parent_hws = (const struct clk_hw*[]) { 641 + &disp_cc_mdss_vsync_clk_src.clkr.hw, 642 + }, 643 + .num_parents = 1, 644 + .flags = CLK_SET_RATE_PARENT, 645 + .ops = &clk_branch2_ops, 646 + }, 647 + }, 648 + }; 649 + 650 + static struct gdsc disp_cc_mdss_core_gdsc = { 651 + .gdscr = 0x9000, 652 + .en_rest_wait_val = 0x2, 653 + .en_few_wait_val = 0x2, 654 + .clk_dis_wait_val = 0xf, 655 + .pd = { 656 + .name = "disp_cc_mdss_core_gdsc", 657 + }, 658 + .pwrsts = PWRSTS_OFF_ON, 659 + .flags = HW_CTRL | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, 660 + }; 661 + 662 + static struct gdsc disp_cc_mdss_core_int2_gdsc = { 663 + .gdscr = 0xb000, 664 + .en_rest_wait_val = 0x2, 665 + .en_few_wait_val = 0x2, 666 + .clk_dis_wait_val = 0xf, 667 + .pd = { 668 + .name = "disp_cc_mdss_core_int2_gdsc", 669 + }, 670 + .pwrsts = PWRSTS_OFF_ON, 671 + .flags = HW_CTRL | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, 672 + }; 673 + 674 + static struct clk_regmap *disp_cc_sm4450_clocks[] = { 675 + [DISP_CC_MDSS_AHB1_CLK] = &disp_cc_mdss_ahb1_clk.clkr, 676 + [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, 677 + [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr, 678 + [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, 679 + [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, 680 + [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr, 681 + [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, 682 + [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, 683 + [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, 684 + [DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr, 685 + [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, 686 + [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, 687 + [DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr, 688 + [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, 689 + [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr, 690 + [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, 691 + [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, 692 + [DISP_CC_MDSS_ROT1_CLK] = &disp_cc_mdss_rot1_clk.clkr, 693 + [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr, 694 + [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr, 695 + [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr, 696 + [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr, 697 + [DISP_CC_MDSS_VSYNC1_CLK] = &disp_cc_mdss_vsync1_clk.clkr, 698 + [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, 699 + [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, 700 + [DISP_CC_PLL0] = &disp_cc_pll0.clkr, 701 + [DISP_CC_PLL1] = &disp_cc_pll1.clkr, 702 + [DISP_CC_SLEEP_CLK_SRC] = &disp_cc_sleep_clk_src.clkr, 703 + [DISP_CC_XO_CLK_SRC] = &disp_cc_xo_clk_src.clkr, 704 + }; 705 + 706 + static struct gdsc *disp_cc_sm4450_gdscs[] = { 707 + [DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc, 708 + [DISP_CC_MDSS_CORE_INT2_GDSC] = &disp_cc_mdss_core_int2_gdsc, 709 + }; 710 + 711 + static const struct qcom_reset_map disp_cc_sm4450_resets[] = { 712 + [DISP_CC_MDSS_CORE_BCR] = { 0x8000 }, 713 + [DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 }, 714 + [DISP_CC_MDSS_RSCC_BCR] = { 0xc000 }, 715 + }; 716 + 717 + static const struct regmap_config disp_cc_sm4450_regmap_config = { 718 + .reg_bits = 32, 719 + .reg_stride = 4, 720 + .val_bits = 32, 721 + .max_register = 0x11008, 722 + .fast_io = true, 723 + }; 724 + 725 + static struct qcom_cc_desc disp_cc_sm4450_desc = { 726 + .config = &disp_cc_sm4450_regmap_config, 727 + .clks = disp_cc_sm4450_clocks, 728 + .num_clks = ARRAY_SIZE(disp_cc_sm4450_clocks), 729 + .resets = disp_cc_sm4450_resets, 730 + .num_resets = ARRAY_SIZE(disp_cc_sm4450_resets), 731 + .gdscs = disp_cc_sm4450_gdscs, 732 + .num_gdscs = ARRAY_SIZE(disp_cc_sm4450_gdscs), 733 + }; 734 + 735 + static const struct of_device_id disp_cc_sm4450_match_table[] = { 736 + { .compatible = "qcom,sm4450-dispcc" }, 737 + { } 738 + }; 739 + MODULE_DEVICE_TABLE(of, disp_cc_sm4450_match_table); 740 + 741 + static int disp_cc_sm4450_probe(struct platform_device *pdev) 742 + { 743 + struct regmap *regmap; 744 + 745 + regmap = qcom_cc_map(pdev, &disp_cc_sm4450_desc); 746 + if (IS_ERR(regmap)) 747 + return PTR_ERR(regmap); 748 + 749 + clk_lucid_evo_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); 750 + clk_lucid_evo_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll0_config); 751 + 752 + /* Keep some clocks always enabled */ 753 + qcom_branch_set_clk_en(regmap, 0xe070); /* DISP_CC_SLEEP_CLK */ 754 + qcom_branch_set_clk_en(regmap, 0xe054); /* DISP_CC_XO_CLK */ 755 + 756 + return qcom_cc_really_probe(&pdev->dev, &disp_cc_sm4450_desc, regmap); 757 + } 758 + 759 + static struct platform_driver disp_cc_sm4450_driver = { 760 + .probe = disp_cc_sm4450_probe, 761 + .driver = { 762 + .name = "dispcc-sm4450", 763 + .of_match_table = disp_cc_sm4450_match_table, 764 + }, 765 + }; 766 + 767 + module_platform_driver(disp_cc_sm4450_driver); 768 + 769 + MODULE_DESCRIPTION("QTI DISPCC SM4450 Driver"); 770 + MODULE_LICENSE("GPL");