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 support for Video clock controller on SA8775P

Add support for Video Clock Controller for SA8775P platform.

Reviewed-by: Jagadeesh Kona <quic_jkona@quicinc.com>
Signed-off-by: Taniya Das <quic_tdas@quicinc.com>
Link: https://lore.kernel.org/r/20241011-sa8775p-mm-v4-resend-patches-v5-2-4a9f17dc683a@quicinc.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>

authored by

Taniya Das and committed by
Bjorn Andersson
9c28d1b9 bbee3fe1

+588
+11
drivers/clk/qcom/Kconfig
··· 1189 1189 Support for the TCSR clock controller on SM8650 devices. 1190 1190 Say Y if you want to use peripheral devices such as SD/UFS. 1191 1191 1192 + config SA_VIDEOCC_8775P 1193 + tristate "SA8775P Video Clock Controller" 1194 + depends on ARM64 || COMPILE_TEST 1195 + select SA_GCC_8775P 1196 + select QCOM_GDSC 1197 + help 1198 + Support for the video clock controller on Qualcomm Technologies, Inc. 1199 + SA8775P devices. 1200 + Say Y if you want to support video devices and functionality such as 1201 + video encode/decode. 1202 + 1192 1203 config SM_VIDEOCC_7150 1193 1204 tristate "SM7150 Video Clock Controller" 1194 1205 depends on ARM64 || COMPILE_TEST
+1
drivers/clk/qcom/Makefile
··· 82 82 obj-$(CONFIG_SC_DISPCC_8280XP) += dispcc-sc8280xp.o 83 83 obj-$(CONFIG_SA_GCC_8775P) += gcc-sa8775p.o 84 84 obj-$(CONFIG_SA_GPUCC_8775P) += gpucc-sa8775p.o 85 + obj-$(CONFIG_SA_VIDEOCC_8775P) += videocc-sa8775p.o 85 86 obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o 86 87 obj-$(CONFIG_SC_GCC_7280) += gcc-sc7280.o 87 88 obj-$(CONFIG_SC_GCC_8180X) += gcc-sc8180x.o
+576
drivers/clk/qcom/videocc-sa8775p.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/pm_runtime.h> 12 + #include <linux/regmap.h> 13 + 14 + #include <dt-bindings/clock/qcom,sa8775p-videocc.h> 15 + 16 + #include "clk-alpha-pll.h" 17 + #include "clk-branch.h" 18 + #include "clk-pll.h" 19 + #include "clk-rcg.h" 20 + #include "clk-regmap.h" 21 + #include "clk-regmap-divider.h" 22 + #include "clk-regmap-mux.h" 23 + #include "common.h" 24 + #include "gdsc.h" 25 + #include "reset.h" 26 + 27 + enum { 28 + DT_IFACE, 29 + DT_BI_TCXO, 30 + DT_BI_TCXO_AO, 31 + DT_SLEEP_CLK, 32 + }; 33 + 34 + enum { 35 + P_BI_TCXO, 36 + P_BI_TCXO_AO, 37 + P_SLEEP_CLK, 38 + P_VIDEO_PLL0_OUT_MAIN, 39 + P_VIDEO_PLL1_OUT_MAIN, 40 + }; 41 + 42 + static const struct pll_vco lucid_evo_vco[] = { 43 + { 249600000, 2020000000, 0 }, 44 + }; 45 + 46 + static const struct alpha_pll_config video_pll0_config = { 47 + .l = 0x39, 48 + .alpha = 0x3000, 49 + .config_ctl_val = 0x20485699, 50 + .config_ctl_hi_val = 0x00182261, 51 + .config_ctl_hi1_val = 0x32aa299c, 52 + .user_ctl_val = 0x00000000, 53 + .user_ctl_hi_val = 0x00400805, 54 + }; 55 + 56 + static struct clk_alpha_pll video_pll0 = { 57 + .offset = 0x0, 58 + .vco_table = lucid_evo_vco, 59 + .num_vco = ARRAY_SIZE(lucid_evo_vco), 60 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], 61 + .clkr = { 62 + .hw.init = &(const struct clk_init_data) { 63 + .name = "video_pll0", 64 + .parent_data = &(const struct clk_parent_data) { 65 + .index = DT_BI_TCXO, 66 + }, 67 + .num_parents = 1, 68 + .ops = &clk_alpha_pll_lucid_evo_ops, 69 + }, 70 + }, 71 + }; 72 + 73 + static const struct alpha_pll_config video_pll1_config = { 74 + .l = 0x39, 75 + .alpha = 0x3000, 76 + .config_ctl_val = 0x20485699, 77 + .config_ctl_hi_val = 0x00182261, 78 + .config_ctl_hi1_val = 0x32aa299c, 79 + .user_ctl_val = 0x00000000, 80 + .user_ctl_hi_val = 0x00400805, 81 + }; 82 + 83 + static struct clk_alpha_pll video_pll1 = { 84 + .offset = 0x1000, 85 + .vco_table = lucid_evo_vco, 86 + .num_vco = ARRAY_SIZE(lucid_evo_vco), 87 + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], 88 + .clkr = { 89 + .hw.init = &(const struct clk_init_data) { 90 + .name = "video_pll1", 91 + .parent_data = &(const struct clk_parent_data) { 92 + .index = DT_BI_TCXO, 93 + }, 94 + .num_parents = 1, 95 + .ops = &clk_alpha_pll_lucid_evo_ops, 96 + }, 97 + }, 98 + }; 99 + 100 + static const struct parent_map video_cc_parent_map_0_ao[] = { 101 + { P_BI_TCXO_AO, 0 }, 102 + }; 103 + 104 + static const struct clk_parent_data video_cc_parent_data_0_ao[] = { 105 + { .index = DT_BI_TCXO_AO }, 106 + }; 107 + 108 + static const struct parent_map video_cc_parent_map_1[] = { 109 + { P_BI_TCXO, 0 }, 110 + { P_VIDEO_PLL0_OUT_MAIN, 1 }, 111 + }; 112 + 113 + static const struct clk_parent_data video_cc_parent_data_1[] = { 114 + { .index = DT_BI_TCXO }, 115 + { .hw = &video_pll0.clkr.hw }, 116 + }; 117 + 118 + static const struct parent_map video_cc_parent_map_2[] = { 119 + { P_BI_TCXO, 0 }, 120 + { P_VIDEO_PLL1_OUT_MAIN, 1 }, 121 + }; 122 + 123 + static const struct clk_parent_data video_cc_parent_data_2[] = { 124 + { .index = DT_BI_TCXO }, 125 + { .hw = &video_pll1.clkr.hw }, 126 + }; 127 + 128 + static const struct parent_map video_cc_parent_map_3[] = { 129 + { P_SLEEP_CLK, 0 }, 130 + }; 131 + 132 + static const struct clk_parent_data video_cc_parent_data_3[] = { 133 + { .index = DT_SLEEP_CLK }, 134 + }; 135 + 136 + static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = { 137 + F(19200000, P_BI_TCXO_AO, 1, 0, 0), 138 + { } 139 + }; 140 + 141 + static struct clk_rcg2 video_cc_ahb_clk_src = { 142 + .cmd_rcgr = 0x8030, 143 + .mnd_width = 0, 144 + .hid_width = 5, 145 + .parent_map = video_cc_parent_map_0_ao, 146 + .freq_tbl = ftbl_video_cc_ahb_clk_src, 147 + .clkr.hw.init = &(const struct clk_init_data) { 148 + .name = "video_cc_ahb_clk_src", 149 + .parent_data = video_cc_parent_data_0_ao, 150 + .num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao), 151 + .flags = CLK_SET_RATE_PARENT, 152 + .ops = &clk_rcg2_shared_ops, 153 + }, 154 + }; 155 + 156 + static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { 157 + F(1098000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 158 + F(1332000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 159 + F(1599000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 160 + F(1680000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0), 161 + { } 162 + }; 163 + 164 + static struct clk_rcg2 video_cc_mvs0_clk_src = { 165 + .cmd_rcgr = 0x8000, 166 + .mnd_width = 0, 167 + .hid_width = 5, 168 + .parent_map = video_cc_parent_map_1, 169 + .freq_tbl = ftbl_video_cc_mvs0_clk_src, 170 + .clkr.hw.init = &(const struct clk_init_data) { 171 + .name = "video_cc_mvs0_clk_src", 172 + .parent_data = video_cc_parent_data_1, 173 + .num_parents = ARRAY_SIZE(video_cc_parent_data_1), 174 + .flags = CLK_SET_RATE_PARENT, 175 + .ops = &clk_rcg2_shared_ops, 176 + }, 177 + }; 178 + 179 + static const struct freq_tbl ftbl_video_cc_mvs1_clk_src[] = { 180 + F(1098000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 181 + F(1332000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 182 + F(1600000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 183 + F(1800000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0), 184 + { } 185 + }; 186 + 187 + static struct clk_rcg2 video_cc_mvs1_clk_src = { 188 + .cmd_rcgr = 0x8018, 189 + .mnd_width = 0, 190 + .hid_width = 5, 191 + .parent_map = video_cc_parent_map_2, 192 + .freq_tbl = ftbl_video_cc_mvs1_clk_src, 193 + .clkr.hw.init = &(const struct clk_init_data) { 194 + .name = "video_cc_mvs1_clk_src", 195 + .parent_data = video_cc_parent_data_2, 196 + .num_parents = ARRAY_SIZE(video_cc_parent_data_2), 197 + .flags = CLK_SET_RATE_PARENT, 198 + .ops = &clk_rcg2_shared_ops, 199 + }, 200 + }; 201 + 202 + static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = { 203 + F(32000, P_SLEEP_CLK, 1, 0, 0), 204 + { } 205 + }; 206 + 207 + static struct clk_rcg2 video_cc_sleep_clk_src = { 208 + .cmd_rcgr = 0x812c, 209 + .mnd_width = 0, 210 + .hid_width = 5, 211 + .parent_map = video_cc_parent_map_3, 212 + .freq_tbl = ftbl_video_cc_sleep_clk_src, 213 + .clkr.hw.init = &(const struct clk_init_data) { 214 + .name = "video_cc_sleep_clk_src", 215 + .parent_data = video_cc_parent_data_3, 216 + .num_parents = ARRAY_SIZE(video_cc_parent_data_3), 217 + .flags = CLK_SET_RATE_PARENT, 218 + .ops = &clk_rcg2_shared_ops, 219 + }, 220 + }; 221 + 222 + static struct clk_rcg2 video_cc_xo_clk_src = { 223 + .cmd_rcgr = 0x8110, 224 + .mnd_width = 0, 225 + .hid_width = 5, 226 + .parent_map = video_cc_parent_map_0_ao, 227 + .freq_tbl = ftbl_video_cc_ahb_clk_src, 228 + .clkr.hw.init = &(const struct clk_init_data) { 229 + .name = "video_cc_xo_clk_src", 230 + .parent_data = video_cc_parent_data_0_ao, 231 + .num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao), 232 + .flags = CLK_SET_RATE_PARENT, 233 + .ops = &clk_rcg2_shared_ops, 234 + }, 235 + }; 236 + 237 + static struct clk_regmap_div video_cc_mvs0_div_clk_src = { 238 + .reg = 0x80b8, 239 + .shift = 0, 240 + .width = 4, 241 + .clkr.hw.init = &(const struct clk_init_data) { 242 + .name = "video_cc_mvs0_div_clk_src", 243 + .parent_hws = (const struct clk_hw*[]) { 244 + &video_cc_mvs0_clk_src.clkr.hw, 245 + }, 246 + .num_parents = 1, 247 + .flags = CLK_SET_RATE_PARENT, 248 + .ops = &clk_regmap_div_ro_ops, 249 + }, 250 + }; 251 + 252 + static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = { 253 + .reg = 0x806c, 254 + .shift = 0, 255 + .width = 4, 256 + .clkr.hw.init = &(const struct clk_init_data) { 257 + .name = "video_cc_mvs0c_div2_div_clk_src", 258 + .parent_hws = (const struct clk_hw*[]) { 259 + &video_cc_mvs0_clk_src.clkr.hw, 260 + }, 261 + .num_parents = 1, 262 + .flags = CLK_SET_RATE_PARENT, 263 + .ops = &clk_regmap_div_ro_ops, 264 + }, 265 + }; 266 + 267 + static struct clk_regmap_div video_cc_mvs1_div_clk_src = { 268 + .reg = 0x80dc, 269 + .shift = 0, 270 + .width = 4, 271 + .clkr.hw.init = &(const struct clk_init_data) { 272 + .name = "video_cc_mvs1_div_clk_src", 273 + .parent_hws = (const struct clk_hw*[]) { 274 + &video_cc_mvs1_clk_src.clkr.hw, 275 + }, 276 + .num_parents = 1, 277 + .flags = CLK_SET_RATE_PARENT, 278 + .ops = &clk_regmap_div_ro_ops, 279 + }, 280 + }; 281 + 282 + static struct clk_regmap_div video_cc_mvs1c_div2_div_clk_src = { 283 + .reg = 0x8094, 284 + .shift = 0, 285 + .width = 4, 286 + .clkr.hw.init = &(const struct clk_init_data) { 287 + .name = "video_cc_mvs1c_div2_div_clk_src", 288 + .parent_hws = (const struct clk_hw*[]) { 289 + &video_cc_mvs1_clk_src.clkr.hw, 290 + }, 291 + .num_parents = 1, 292 + .flags = CLK_SET_RATE_PARENT, 293 + .ops = &clk_regmap_div_ro_ops, 294 + }, 295 + }; 296 + 297 + static struct clk_regmap_div video_cc_sm_div_clk_src = { 298 + .reg = 0x8108, 299 + .shift = 0, 300 + .width = 4, 301 + .clkr.hw.init = &(const struct clk_init_data) { 302 + .name = "video_cc_sm_div_clk_src", 303 + .ops = &clk_regmap_div_ro_ops, 304 + }, 305 + }; 306 + 307 + static struct clk_branch video_cc_mvs0_clk = { 308 + .halt_reg = 0x80b0, 309 + .halt_check = BRANCH_HALT_VOTED, 310 + .hwcg_reg = 0x80b0, 311 + .hwcg_bit = 1, 312 + .clkr = { 313 + .enable_reg = 0x80b0, 314 + .enable_mask = BIT(0), 315 + .hw.init = &(const struct clk_init_data) { 316 + .name = "video_cc_mvs0_clk", 317 + .parent_hws = (const struct clk_hw*[]) { 318 + &video_cc_mvs0_div_clk_src.clkr.hw, 319 + }, 320 + .num_parents = 1, 321 + .flags = CLK_SET_RATE_PARENT, 322 + .ops = &clk_branch2_ops, 323 + }, 324 + }, 325 + }; 326 + 327 + static struct clk_branch video_cc_mvs0c_clk = { 328 + .halt_reg = 0x8064, 329 + .halt_check = BRANCH_HALT, 330 + .clkr = { 331 + .enable_reg = 0x8064, 332 + .enable_mask = BIT(0), 333 + .hw.init = &(const struct clk_init_data) { 334 + .name = "video_cc_mvs0c_clk", 335 + .parent_hws = (const struct clk_hw*[]) { 336 + &video_cc_mvs0c_div2_div_clk_src.clkr.hw, 337 + }, 338 + .num_parents = 1, 339 + .flags = CLK_SET_RATE_PARENT, 340 + .ops = &clk_branch2_ops, 341 + }, 342 + }, 343 + }; 344 + 345 + static struct clk_branch video_cc_mvs1_clk = { 346 + .halt_reg = 0x80d4, 347 + .halt_check = BRANCH_HALT_VOTED, 348 + .hwcg_reg = 0x80d4, 349 + .hwcg_bit = 1, 350 + .clkr = { 351 + .enable_reg = 0x80d4, 352 + .enable_mask = BIT(0), 353 + .hw.init = &(const struct clk_init_data) { 354 + .name = "video_cc_mvs1_clk", 355 + .parent_hws = (const struct clk_hw*[]) { 356 + &video_cc_mvs1_div_clk_src.clkr.hw, 357 + }, 358 + .num_parents = 1, 359 + .flags = CLK_SET_RATE_PARENT, 360 + .ops = &clk_branch2_ops, 361 + }, 362 + }, 363 + }; 364 + 365 + static struct clk_branch video_cc_mvs1c_clk = { 366 + .halt_reg = 0x808c, 367 + .halt_check = BRANCH_HALT, 368 + .clkr = { 369 + .enable_reg = 0x808c, 370 + .enable_mask = BIT(0), 371 + .hw.init = &(const struct clk_init_data) { 372 + .name = "video_cc_mvs1c_clk", 373 + .parent_hws = (const struct clk_hw*[]) { 374 + &video_cc_mvs1c_div2_div_clk_src.clkr.hw, 375 + }, 376 + .num_parents = 1, 377 + .flags = CLK_SET_RATE_PARENT, 378 + .ops = &clk_branch2_ops, 379 + }, 380 + }, 381 + }; 382 + 383 + static struct clk_branch video_cc_pll_lock_monitor_clk = { 384 + .halt_reg = 0x9000, 385 + .halt_check = BRANCH_HALT, 386 + .clkr = { 387 + .enable_reg = 0x9000, 388 + .enable_mask = BIT(0), 389 + .hw.init = &(const struct clk_init_data) { 390 + .name = "video_cc_pll_lock_monitor_clk", 391 + .parent_hws = (const struct clk_hw*[]) { 392 + &video_cc_xo_clk_src.clkr.hw, 393 + }, 394 + .num_parents = 1, 395 + .flags = CLK_SET_RATE_PARENT, 396 + .ops = &clk_branch2_ops, 397 + }, 398 + }, 399 + }; 400 + 401 + static struct clk_branch video_cc_sm_obs_clk = { 402 + .halt_reg = 0x810c, 403 + .halt_check = BRANCH_HALT_SKIP, 404 + .clkr = { 405 + .enable_reg = 0x810c, 406 + .enable_mask = BIT(0), 407 + .hw.init = &(const struct clk_init_data) { 408 + .name = "video_cc_sm_obs_clk", 409 + .parent_hws = (const struct clk_hw*[]) { 410 + &video_cc_sm_div_clk_src.clkr.hw, 411 + }, 412 + .num_parents = 1, 413 + .flags = CLK_SET_RATE_PARENT, 414 + .ops = &clk_branch2_ops, 415 + }, 416 + }, 417 + }; 418 + 419 + static struct gdsc video_cc_mvs0c_gdsc = { 420 + .gdscr = 0x804c, 421 + .en_rest_wait_val = 0x2, 422 + .en_few_wait_val = 0x2, 423 + .clk_dis_wait_val = 0x6, 424 + .pd = { 425 + .name = "video_cc_mvs0c_gdsc", 426 + }, 427 + .pwrsts = PWRSTS_OFF_ON, 428 + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, 429 + }; 430 + 431 + static struct gdsc video_cc_mvs0_gdsc = { 432 + .gdscr = 0x809c, 433 + .en_rest_wait_val = 0x2, 434 + .en_few_wait_val = 0x2, 435 + .clk_dis_wait_val = 0x6, 436 + .pd = { 437 + .name = "video_cc_mvs0_gdsc", 438 + }, 439 + .pwrsts = PWRSTS_OFF_ON, 440 + .parent = &video_cc_mvs0c_gdsc.pd, 441 + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR | HW_CTRL_TRIGGER, 442 + }; 443 + 444 + static struct gdsc video_cc_mvs1c_gdsc = { 445 + .gdscr = 0x8074, 446 + .en_rest_wait_val = 0x2, 447 + .en_few_wait_val = 0x2, 448 + .clk_dis_wait_val = 0x6, 449 + .pd = { 450 + .name = "video_cc_mvs1c_gdsc", 451 + }, 452 + .pwrsts = PWRSTS_OFF_ON, 453 + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR, 454 + }; 455 + 456 + static struct gdsc video_cc_mvs1_gdsc = { 457 + .gdscr = 0x80c0, 458 + .en_rest_wait_val = 0x2, 459 + .en_few_wait_val = 0x2, 460 + .clk_dis_wait_val = 0x6, 461 + .pd = { 462 + .name = "video_cc_mvs1_gdsc", 463 + }, 464 + .pwrsts = PWRSTS_OFF_ON, 465 + .parent = &video_cc_mvs1c_gdsc.pd, 466 + .flags = RETAIN_FF_ENABLE | POLL_CFG_GDSCR | HW_CTRL_TRIGGER, 467 + }; 468 + 469 + static struct clk_regmap *video_cc_sa8775p_clocks[] = { 470 + [VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr, 471 + [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr, 472 + [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr, 473 + [VIDEO_CC_MVS0_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr, 474 + [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, 475 + [VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr, 476 + [VIDEO_CC_MVS1_CLK] = &video_cc_mvs1_clk.clkr, 477 + [VIDEO_CC_MVS1_CLK_SRC] = &video_cc_mvs1_clk_src.clkr, 478 + [VIDEO_CC_MVS1_DIV_CLK_SRC] = &video_cc_mvs1_div_clk_src.clkr, 479 + [VIDEO_CC_MVS1C_CLK] = &video_cc_mvs1c_clk.clkr, 480 + [VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC] = &video_cc_mvs1c_div2_div_clk_src.clkr, 481 + [VIDEO_CC_PLL_LOCK_MONITOR_CLK] = &video_cc_pll_lock_monitor_clk.clkr, 482 + [VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr, 483 + [VIDEO_CC_SM_DIV_CLK_SRC] = &video_cc_sm_div_clk_src.clkr, 484 + [VIDEO_CC_SM_OBS_CLK] = &video_cc_sm_obs_clk.clkr, 485 + [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, 486 + [VIDEO_PLL0] = &video_pll0.clkr, 487 + [VIDEO_PLL1] = &video_pll1.clkr, 488 + }; 489 + 490 + static struct gdsc *video_cc_sa8775p_gdscs[] = { 491 + [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc, 492 + [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc, 493 + [VIDEO_CC_MVS1_GDSC] = &video_cc_mvs1_gdsc, 494 + [VIDEO_CC_MVS1C_GDSC] = &video_cc_mvs1c_gdsc, 495 + }; 496 + 497 + static const struct qcom_reset_map video_cc_sa8775p_resets[] = { 498 + [VIDEO_CC_INTERFACE_BCR] = { 0x80e8 }, 499 + [VIDEO_CC_MVS0_BCR] = { 0x8098 }, 500 + [VIDEO_CC_MVS0C_CLK_ARES] = { 0x8064, 2 }, 501 + [VIDEO_CC_MVS0C_BCR] = { 0x8048 }, 502 + [VIDEO_CC_MVS1_BCR] = { 0x80bc }, 503 + [VIDEO_CC_MVS1C_CLK_ARES] = { 0x808c, 2 }, 504 + [VIDEO_CC_MVS1C_BCR] = { 0x8070 }, 505 + }; 506 + 507 + static const struct regmap_config video_cc_sa8775p_regmap_config = { 508 + .reg_bits = 32, 509 + .reg_stride = 4, 510 + .val_bits = 32, 511 + .max_register = 0xb000, 512 + .fast_io = true, 513 + }; 514 + 515 + static struct qcom_cc_desc video_cc_sa8775p_desc = { 516 + .config = &video_cc_sa8775p_regmap_config, 517 + .clks = video_cc_sa8775p_clocks, 518 + .num_clks = ARRAY_SIZE(video_cc_sa8775p_clocks), 519 + .resets = video_cc_sa8775p_resets, 520 + .num_resets = ARRAY_SIZE(video_cc_sa8775p_resets), 521 + .gdscs = video_cc_sa8775p_gdscs, 522 + .num_gdscs = ARRAY_SIZE(video_cc_sa8775p_gdscs), 523 + }; 524 + 525 + static const struct of_device_id video_cc_sa8775p_match_table[] = { 526 + { .compatible = "qcom,sa8775p-videocc" }, 527 + { } 528 + }; 529 + MODULE_DEVICE_TABLE(of, video_cc_sa8775p_match_table); 530 + 531 + static int video_cc_sa8775p_probe(struct platform_device *pdev) 532 + { 533 + struct regmap *regmap; 534 + int ret; 535 + 536 + ret = devm_pm_runtime_enable(&pdev->dev); 537 + if (ret) 538 + return ret; 539 + 540 + ret = pm_runtime_resume_and_get(&pdev->dev); 541 + if (ret) 542 + return ret; 543 + 544 + regmap = qcom_cc_map(pdev, &video_cc_sa8775p_desc); 545 + if (IS_ERR(regmap)) { 546 + pm_runtime_put(&pdev->dev); 547 + return PTR_ERR(regmap); 548 + } 549 + 550 + clk_lucid_evo_pll_configure(&video_pll0, regmap, &video_pll0_config); 551 + clk_lucid_evo_pll_configure(&video_pll1, regmap, &video_pll1_config); 552 + 553 + /* Keep some clocks always enabled */ 554 + qcom_branch_set_clk_en(regmap, 0x80ec); /* VIDEO_CC_AHB_CLK */ 555 + qcom_branch_set_clk_en(regmap, 0x8144); /* VIDEO_CC_SLEEP_CLK */ 556 + qcom_branch_set_clk_en(regmap, 0x8128); /* VIDEO_CC_XO_CLK */ 557 + 558 + ret = qcom_cc_really_probe(&pdev->dev, &video_cc_sa8775p_desc, regmap); 559 + 560 + pm_runtime_put(&pdev->dev); 561 + 562 + return ret; 563 + } 564 + 565 + static struct platform_driver video_cc_sa8775p_driver = { 566 + .probe = video_cc_sa8775p_probe, 567 + .driver = { 568 + .name = "videocc-sa8775p", 569 + .of_match_table = video_cc_sa8775p_match_table, 570 + }, 571 + }; 572 + 573 + module_platform_driver(video_cc_sa8775p_driver); 574 + 575 + MODULE_DESCRIPTION("QTI VIDEOCC SA8775P Driver"); 576 + MODULE_LICENSE("GPL");