1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. 4 * Copyright (c) 2023, Linaro Limited 5 */ 6 7 #include <linux/clk-provider.h> 8 #include <linux/err.h> 9 #include <linux/kernel.h> 10 #include <linux/mod_devicetable.h> 11 #include <linux/module.h> 12 #include <linux/platform_device.h> 13 #include <linux/regmap.h> 14 15 #include <dt-bindings/clock/qcom,sa8775p-gpucc.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 "reset.h" 24 #include "gdsc.h" 25 26 /* Need to match the order of clocks in DT binding */ 27 enum { 28 DT_BI_TCXO, 29 DT_GCC_GPU_GPLL0_CLK_SRC, 30 DT_GCC_GPU_GPLL0_DIV_CLK_SRC, 31 }; 32 33 enum { 34 P_BI_TCXO, 35 P_GPLL0_OUT_MAIN, 36 P_GPLL0_OUT_MAIN_DIV, 37 P_GPU_CC_PLL0_OUT_MAIN, 38 P_GPU_CC_PLL1_OUT_MAIN, 39 }; 40 41 static const struct clk_parent_data parent_data_tcxo = { .index = DT_BI_TCXO }; 42 43 static const struct pll_vco lucid_evo_vco[] = { 44 { 249600000, 2020000000, 0 }, 45 }; 46 47 /* 810MHz configuration */ 48 static struct alpha_pll_config gpu_cc_pll0_config = { 49 .l = 0x2a, 50 .alpha = 0x3000, 51 .config_ctl_val = 0x20485699, 52 .config_ctl_hi_val = 0x00182261, 53 .config_ctl_hi1_val = 0x32aa299c, 54 .user_ctl_val = 0x00000001, 55 .user_ctl_hi_val = 0x00400805, 56 }; 57 58 static struct clk_alpha_pll gpu_cc_pll0 = { 59 .offset = 0x0, 60 .vco_table = lucid_evo_vco, 61 .num_vco = ARRAY_SIZE(lucid_evo_vco), 62 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], 63 .clkr = { 64 .hw.init = &(const struct clk_init_data){ 65 .name = "gpu_cc_pll0", 66 .parent_data = &parent_data_tcxo, 67 .num_parents = 1, 68 .ops = &clk_alpha_pll_lucid_evo_ops, 69 }, 70 }, 71 }; 72 73 /* 1000MHz configuration */ 74 static struct alpha_pll_config gpu_cc_pll1_config = { 75 .l = 0x34, 76 .alpha = 0x1555, 77 .config_ctl_val = 0x20485699, 78 .config_ctl_hi_val = 0x00182261, 79 .config_ctl_hi1_val = 0x32aa299c, 80 .user_ctl_val = 0x00000001, 81 .user_ctl_hi_val = 0x00400805, 82 }; 83 84 static struct clk_alpha_pll gpu_cc_pll1 = { 85 .offset = 0x1000, 86 .vco_table = lucid_evo_vco, 87 .num_vco = ARRAY_SIZE(lucid_evo_vco), 88 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_EVO], 89 .clkr = { 90 .hw.init = &(const struct clk_init_data){ 91 .name = "gpu_cc_pll1", 92 .parent_data = &parent_data_tcxo, 93 .num_parents = 1, 94 .ops = &clk_alpha_pll_lucid_evo_ops, 95 }, 96 }, 97 }; 98 99 static const struct parent_map gpu_cc_parent_map_0[] = { 100 { P_BI_TCXO, 0 }, 101 { P_GPLL0_OUT_MAIN, 5 }, 102 { P_GPLL0_OUT_MAIN_DIV, 6 }, 103 }; 104 105 static const struct clk_parent_data gpu_cc_parent_data_0[] = { 106 { .index = DT_BI_TCXO }, 107 { .index = DT_GCC_GPU_GPLL0_CLK_SRC }, 108 { .index = DT_GCC_GPU_GPLL0_DIV_CLK_SRC }, 109 }; 110 111 static const struct parent_map gpu_cc_parent_map_1[] = { 112 { P_BI_TCXO, 0 }, 113 { P_GPU_CC_PLL0_OUT_MAIN, 1 }, 114 { P_GPU_CC_PLL1_OUT_MAIN, 3 }, 115 { P_GPLL0_OUT_MAIN, 5 }, 116 { P_GPLL0_OUT_MAIN_DIV, 6 }, 117 }; 118 119 static const struct clk_parent_data gpu_cc_parent_data_1[] = { 120 { .index = DT_BI_TCXO }, 121 { .hw = &gpu_cc_pll0.clkr.hw }, 122 { .hw = &gpu_cc_pll1.clkr.hw }, 123 { .index = DT_GCC_GPU_GPLL0_CLK_SRC }, 124 { .index = DT_GCC_GPU_GPLL0_DIV_CLK_SRC }, 125 }; 126 127 static const struct parent_map gpu_cc_parent_map_2[] = { 128 { P_BI_TCXO, 0 }, 129 { P_GPU_CC_PLL1_OUT_MAIN, 3 }, 130 { P_GPLL0_OUT_MAIN, 5 }, 131 { P_GPLL0_OUT_MAIN_DIV, 6 }, 132 }; 133 134 static const struct clk_parent_data gpu_cc_parent_data_2[] = { 135 { .index = DT_BI_TCXO }, 136 { .hw = &gpu_cc_pll1.clkr.hw }, 137 { .index = DT_GCC_GPU_GPLL0_CLK_SRC }, 138 { .index = DT_GCC_GPU_GPLL0_DIV_CLK_SRC }, 139 }; 140 141 static const struct parent_map gpu_cc_parent_map_3[] = { 142 { P_BI_TCXO, 0 }, 143 }; 144 145 static const struct clk_parent_data gpu_cc_parent_data_3[] = { 146 { .index = DT_BI_TCXO }, 147 }; 148 149 static const struct freq_tbl ftbl_gpu_cc_ff_clk_src[] = { 150 F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), 151 { } 152 }; 153 154 static struct clk_rcg2 gpu_cc_ff_clk_src = { 155 .cmd_rcgr = 0x9474, 156 .mnd_width = 0, 157 .hid_width = 5, 158 .parent_map = gpu_cc_parent_map_0, 159 .freq_tbl = ftbl_gpu_cc_ff_clk_src, 160 .clkr.hw.init = &(const struct clk_init_data){ 161 .name = "gpu_cc_ff_clk_src", 162 .parent_data = gpu_cc_parent_data_0, 163 .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), 164 .ops = &clk_rcg2_ops, 165 }, 166 }; 167 168 static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { 169 F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 2, 0, 0), 170 { } 171 }; 172 173 static struct clk_rcg2 gpu_cc_gmu_clk_src = { 174 .cmd_rcgr = 0x9318, 175 .mnd_width = 0, 176 .hid_width = 5, 177 .parent_map = gpu_cc_parent_map_1, 178 .freq_tbl = ftbl_gpu_cc_gmu_clk_src, 179 .clkr.hw.init = &(const struct clk_init_data){ 180 .name = "gpu_cc_gmu_clk_src", 181 .parent_data = gpu_cc_parent_data_1, 182 .num_parents = ARRAY_SIZE(gpu_cc_parent_data_1), 183 .flags = CLK_SET_RATE_PARENT, 184 .ops = &clk_rcg2_ops, 185 }, 186 }; 187 188 static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = { 189 F(240000000, P_GPLL0_OUT_MAIN, 2.5, 0, 0), 190 { } 191 }; 192 193 static struct clk_rcg2 gpu_cc_hub_clk_src = { 194 .cmd_rcgr = 0x93ec, 195 .mnd_width = 0, 196 .hid_width = 5, 197 .parent_map = gpu_cc_parent_map_2, 198 .freq_tbl = ftbl_gpu_cc_hub_clk_src, 199 .clkr.hw.init = &(const struct clk_init_data){ 200 .name = "gpu_cc_hub_clk_src", 201 .parent_data = gpu_cc_parent_data_2, 202 .num_parents = ARRAY_SIZE(gpu_cc_parent_data_2), 203 .ops = &clk_rcg2_ops, 204 }, 205 }; 206 207 static const struct freq_tbl ftbl_gpu_cc_xo_clk_src[] = { 208 F(19200000, P_BI_TCXO, 1, 0, 0), 209 { } 210 }; 211 212 static struct clk_rcg2 gpu_cc_xo_clk_src = { 213 .cmd_rcgr = 0x9010, 214 .mnd_width = 0, 215 .hid_width = 5, 216 .parent_map = gpu_cc_parent_map_3, 217 .freq_tbl = ftbl_gpu_cc_xo_clk_src, 218 .clkr.hw.init = &(const struct clk_init_data){ 219 .name = "gpu_cc_xo_clk_src", 220 .parent_data = gpu_cc_parent_data_3, 221 .num_parents = ARRAY_SIZE(gpu_cc_parent_data_3), 222 .ops = &clk_rcg2_ops, 223 }, 224 }; 225 226 static struct clk_regmap_div gpu_cc_demet_div_clk_src = { 227 .reg = 0x9054, 228 .shift = 0, 229 .width = 4, 230 .clkr.hw.init = &(const struct clk_init_data) { 231 .name = "gpu_cc_demet_div_clk_src", 232 .parent_hws = (const struct clk_hw*[]){ 233 &gpu_cc_xo_clk_src.clkr.hw, 234 }, 235 .num_parents = 1, 236 .flags = CLK_SET_RATE_PARENT, 237 .ops = &clk_regmap_div_ro_ops, 238 }, 239 }; 240 241 static struct clk_regmap_div gpu_cc_hub_ahb_div_clk_src = { 242 .reg = 0x9430, 243 .shift = 0, 244 .width = 4, 245 .clkr.hw.init = &(const struct clk_init_data) { 246 .name = "gpu_cc_hub_ahb_div_clk_src", 247 .parent_hws = (const struct clk_hw*[]){ 248 &gpu_cc_hub_clk_src.clkr.hw, 249 }, 250 .num_parents = 1, 251 .flags = CLK_SET_RATE_PARENT, 252 .ops = &clk_regmap_div_ro_ops, 253 }, 254 }; 255 256 static struct clk_regmap_div gpu_cc_hub_cx_int_div_clk_src = { 257 .reg = 0x942c, 258 .shift = 0, 259 .width = 4, 260 .clkr.hw.init = &(const struct clk_init_data) { 261 .name = "gpu_cc_hub_cx_int_div_clk_src", 262 .parent_hws = (const struct clk_hw*[]){ 263 &gpu_cc_hub_clk_src.clkr.hw, 264 }, 265 .num_parents = 1, 266 .flags = CLK_SET_RATE_PARENT, 267 .ops = &clk_regmap_div_ro_ops, 268 }, 269 }; 270 271 static struct clk_branch gpu_cc_ahb_clk = { 272 .halt_reg = 0x911c, 273 .halt_check = BRANCH_HALT_DELAY, 274 .clkr = { 275 .enable_reg = 0x911c, 276 .enable_mask = BIT(0), 277 .hw.init = &(const struct clk_init_data){ 278 .name = "gpu_cc_ahb_clk", 279 .parent_hws = (const struct clk_hw*[]){ 280 &gpu_cc_hub_ahb_div_clk_src.clkr.hw, 281 }, 282 .num_parents = 1, 283 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 284 .ops = &clk_branch2_ops, 285 }, 286 }, 287 }; 288 289 static struct clk_branch gpu_cc_cb_clk = { 290 .halt_reg = 0x93a4, 291 .halt_check = BRANCH_HALT, 292 .clkr = { 293 .enable_reg = 0x93a4, 294 .enable_mask = BIT(0), 295 .hw.init = &(const struct clk_init_data){ 296 .name = "gpu_cc_cb_clk", 297 .flags = CLK_IS_CRITICAL, 298 .ops = &clk_branch2_ops, 299 }, 300 }, 301 }; 302 303 static struct clk_branch gpu_cc_crc_ahb_clk = { 304 .halt_reg = 0x9120, 305 .halt_check = BRANCH_HALT_VOTED, 306 .clkr = { 307 .enable_reg = 0x9120, 308 .enable_mask = BIT(0), 309 .hw.init = &(const struct clk_init_data){ 310 .name = "gpu_cc_crc_ahb_clk", 311 .parent_hws = (const struct clk_hw*[]){ 312 &gpu_cc_hub_ahb_div_clk_src.clkr.hw, 313 }, 314 .num_parents = 1, 315 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 316 .ops = &clk_branch2_ops, 317 }, 318 }, 319 }; 320 321 static struct clk_branch gpu_cc_cx_ff_clk = { 322 .halt_reg = 0x914c, 323 .halt_check = BRANCH_HALT, 324 .clkr = { 325 .enable_reg = 0x914c, 326 .enable_mask = BIT(0), 327 .hw.init = &(const struct clk_init_data){ 328 .name = "gpu_cc_cx_ff_clk", 329 .parent_hws = (const struct clk_hw*[]){ 330 &gpu_cc_ff_clk_src.clkr.hw, 331 }, 332 .num_parents = 1, 333 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 334 .ops = &clk_branch2_ops, 335 }, 336 }, 337 }; 338 339 static struct clk_branch gpu_cc_cx_gmu_clk = { 340 .halt_reg = 0x913c, 341 .halt_check = BRANCH_HALT, 342 .clkr = { 343 .enable_reg = 0x913c, 344 .enable_mask = BIT(0), 345 .hw.init = &(const struct clk_init_data){ 346 .name = "gpu_cc_cx_gmu_clk", 347 .parent_hws = (const struct clk_hw*[]){ 348 &gpu_cc_gmu_clk_src.clkr.hw, 349 }, 350 .num_parents = 1, 351 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 352 .ops = &clk_branch2_aon_ops, 353 }, 354 }, 355 }; 356 357 static struct clk_branch gpu_cc_cx_snoc_dvm_clk = { 358 .halt_reg = 0x9130, 359 .halt_check = BRANCH_HALT_VOTED, 360 .clkr = { 361 .enable_reg = 0x9130, 362 .enable_mask = BIT(0), 363 .hw.init = &(const struct clk_init_data){ 364 .name = "gpu_cc_cx_snoc_dvm_clk", 365 .flags = CLK_IS_CRITICAL, 366 .ops = &clk_branch2_ops, 367 }, 368 }, 369 }; 370 371 static struct clk_branch gpu_cc_cxo_aon_clk = { 372 .halt_reg = 0x9004, 373 .halt_check = BRANCH_HALT_VOTED, 374 .clkr = { 375 .enable_reg = 0x9004, 376 .enable_mask = BIT(0), 377 .hw.init = &(const struct clk_init_data){ 378 .name = "gpu_cc_cxo_aon_clk", 379 .parent_hws = (const struct clk_hw*[]){ 380 &gpu_cc_xo_clk_src.clkr.hw, 381 }, 382 .num_parents = 1, 383 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 384 .ops = &clk_branch2_ops, 385 }, 386 }, 387 }; 388 389 static struct clk_branch gpu_cc_cxo_clk = { 390 .halt_reg = 0x9144, 391 .halt_check = BRANCH_HALT, 392 .clkr = { 393 .enable_reg = 0x9144, 394 .enable_mask = BIT(0), 395 .hw.init = &(const struct clk_init_data){ 396 .name = "gpu_cc_cxo_clk", 397 .parent_hws = (const struct clk_hw*[]){ 398 &gpu_cc_xo_clk_src.clkr.hw, 399 }, 400 .num_parents = 1, 401 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 402 .ops = &clk_branch2_ops, 403 }, 404 }, 405 }; 406 407 static struct clk_branch gpu_cc_demet_clk = { 408 .halt_reg = 0x900c, 409 .halt_check = BRANCH_HALT, 410 .clkr = { 411 .enable_reg = 0x900c, 412 .enable_mask = BIT(0), 413 .hw.init = &(const struct clk_init_data){ 414 .name = "gpu_cc_demet_clk", 415 .parent_hws = (const struct clk_hw*[]){ 416 &gpu_cc_demet_div_clk_src.clkr.hw, 417 }, 418 .num_parents = 1, 419 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 420 .ops = &clk_branch2_aon_ops, 421 }, 422 }, 423 }; 424 425 static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { 426 .halt_reg = 0x7000, 427 .halt_check = BRANCH_HALT_VOTED, 428 .clkr = { 429 .enable_reg = 0x7000, 430 .enable_mask = BIT(0), 431 .hw.init = &(const struct clk_init_data){ 432 .name = "gpu_cc_hlos1_vote_gpu_smmu_clk", 433 .flags = CLK_IS_CRITICAL, 434 .ops = &clk_branch2_ops, 435 }, 436 }, 437 }; 438 439 static struct clk_branch gpu_cc_hub_aon_clk = { 440 .halt_reg = 0x93e8, 441 .halt_check = BRANCH_HALT, 442 .clkr = { 443 .enable_reg = 0x93e8, 444 .enable_mask = BIT(0), 445 .hw.init = &(const struct clk_init_data){ 446 .name = "gpu_cc_hub_aon_clk", 447 .parent_hws = (const struct clk_hw*[]){ 448 &gpu_cc_hub_clk_src.clkr.hw, 449 }, 450 .num_parents = 1, 451 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 452 .ops = &clk_branch2_aon_ops, 453 }, 454 }, 455 }; 456 457 static struct clk_branch gpu_cc_hub_cx_int_clk = { 458 .halt_reg = 0x9148, 459 .halt_check = BRANCH_HALT, 460 .clkr = { 461 .enable_reg = 0x9148, 462 .enable_mask = BIT(0), 463 .hw.init = &(const struct clk_init_data){ 464 .name = "gpu_cc_hub_cx_int_clk", 465 .parent_hws = (const struct clk_hw*[]){ 466 &gpu_cc_hub_cx_int_div_clk_src.clkr.hw, 467 }, 468 .num_parents = 1, 469 .flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, 470 .ops = &clk_branch2_aon_ops, 471 }, 472 }, 473 }; 474 475 static struct clk_branch gpu_cc_memnoc_gfx_clk = { 476 .halt_reg = 0x9150, 477 .halt_check = BRANCH_HALT, 478 .clkr = { 479 .enable_reg = 0x9150, 480 .enable_mask = BIT(0), 481 .hw.init = &(const struct clk_init_data){ 482 .name = "gpu_cc_memnoc_gfx_clk", 483 .flags = CLK_IS_CRITICAL, 484 .ops = &clk_branch2_ops, 485 }, 486 }, 487 }; 488 489 static struct clk_branch gpu_cc_sleep_clk = { 490 .halt_reg = 0x9134, 491 .halt_check = BRANCH_HALT_VOTED, 492 .clkr = { 493 .enable_reg = 0x9134, 494 .enable_mask = BIT(0), 495 .hw.init = &(const struct clk_init_data){ 496 .name = "gpu_cc_sleep_clk", 497 .flags = CLK_IS_CRITICAL, 498 .ops = &clk_branch2_ops, 499 }, 500 }, 501 }; 502 503 static struct clk_regmap *gpu_cc_sa8775p_clocks[] = { 504 [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, 505 [GPU_CC_CB_CLK] = &gpu_cc_cb_clk.clkr, 506 [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, 507 [GPU_CC_CX_FF_CLK] = &gpu_cc_cx_ff_clk.clkr, 508 [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, 509 [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr, 510 [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr, 511 [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, 512 [GPU_CC_DEMET_CLK] = &gpu_cc_demet_clk.clkr, 513 [GPU_CC_DEMET_DIV_CLK_SRC] = &gpu_cc_demet_div_clk_src.clkr, 514 [GPU_CC_FF_CLK_SRC] = &gpu_cc_ff_clk_src.clkr, 515 [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, 516 [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr, 517 [GPU_CC_HUB_AHB_DIV_CLK_SRC] = &gpu_cc_hub_ahb_div_clk_src.clkr, 518 [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr, 519 [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr, 520 [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr, 521 [GPU_CC_HUB_CX_INT_DIV_CLK_SRC] = &gpu_cc_hub_cx_int_div_clk_src.clkr, 522 [GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr, 523 [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, 524 [GPU_CC_PLL1] = &gpu_cc_pll1.clkr, 525 [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr, 526 [GPU_CC_XO_CLK_SRC] = &gpu_cc_xo_clk_src.clkr, 527 }; 528 529 static struct gdsc cx_gdsc = { 530 .gdscr = 0x9108, 531 .gds_hw_ctrl = 0x953c, 532 .pd = { 533 .name = "cx_gdsc", 534 }, 535 .pwrsts = PWRSTS_OFF_ON, 536 .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON, 537 }; 538 539 static struct gdsc gx_gdsc = { 540 .gdscr = 0x905c, 541 .pd = { 542 .name = "gx_gdsc", 543 .power_on = gdsc_gx_do_nothing_enable, 544 }, 545 .pwrsts = PWRSTS_OFF_ON, 546 .flags = AON_RESET | RETAIN_FF_ENABLE, 547 }; 548 549 static struct gdsc *gpu_cc_sa8775p_gdscs[] = { 550 [GPU_CC_CX_GDSC] = &cx_gdsc, 551 [GPU_CC_GX_GDSC] = &gx_gdsc, 552 }; 553 554 static const struct qcom_reset_map gpu_cc_sa8775p_resets[] = { 555 [GPUCC_GPU_CC_ACD_BCR] = { 0x9358 }, 556 [GPUCC_GPU_CC_CB_BCR] = { 0x93a0 }, 557 [GPUCC_GPU_CC_CX_BCR] = { 0x9104 }, 558 [GPUCC_GPU_CC_FAST_HUB_BCR] = { 0x93e4 }, 559 [GPUCC_GPU_CC_FF_BCR] = { 0x9470 }, 560 [GPUCC_GPU_CC_GFX3D_AON_BCR] = { 0x9198 }, 561 [GPUCC_GPU_CC_GMU_BCR] = { 0x9314 }, 562 [GPUCC_GPU_CC_GX_BCR] = { 0x9058 }, 563 [GPUCC_GPU_CC_XO_BCR] = { 0x9000 }, 564 }; 565 566 static const struct regmap_config gpu_cc_sa8775p_regmap_config = { 567 .reg_bits = 32, 568 .reg_stride = 4, 569 .val_bits = 32, 570 .max_register = 0x9988, 571 .fast_io = true, 572 }; 573 574 static const struct qcom_cc_desc gpu_cc_sa8775p_desc = { 575 .config = &gpu_cc_sa8775p_regmap_config, 576 .clks = gpu_cc_sa8775p_clocks, 577 .num_clks = ARRAY_SIZE(gpu_cc_sa8775p_clocks), 578 .resets = gpu_cc_sa8775p_resets, 579 .num_resets = ARRAY_SIZE(gpu_cc_sa8775p_resets), 580 .gdscs = gpu_cc_sa8775p_gdscs, 581 .num_gdscs = ARRAY_SIZE(gpu_cc_sa8775p_gdscs), 582 }; 583 584 static const struct of_device_id gpu_cc_sa8775p_match_table[] = { 585 { .compatible = "qcom,sa8775p-gpucc" }, 586 { } 587 }; 588 MODULE_DEVICE_TABLE(of, gpu_cc_sa8775p_match_table); 589 590 static int gpu_cc_sa8775p_probe(struct platform_device *pdev) 591 { 592 struct regmap *regmap; 593 594 regmap = qcom_cc_map(pdev, &gpu_cc_sa8775p_desc); 595 if (IS_ERR(regmap)) 596 return PTR_ERR(regmap); 597 598 clk_lucid_evo_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); 599 clk_lucid_evo_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); 600 601 return qcom_cc_really_probe(pdev, &gpu_cc_sa8775p_desc, regmap); 602 } 603 604 static struct platform_driver gpu_cc_sa8775p_driver = { 605 .probe = gpu_cc_sa8775p_probe, 606 .driver = { 607 .name = "gpu_cc-sa8775p", 608 .of_match_table = gpu_cc_sa8775p_match_table, 609 }, 610 }; 611 612 static int __init gpu_cc_sa8775p_init(void) 613 { 614 return platform_driver_register(&gpu_cc_sa8775p_driver); 615 } 616 subsys_initcall(gpu_cc_sa8775p_init); 617 618 static void __exit gpu_cc_sa8775p_exit(void) 619 { 620 platform_driver_unregister(&gpu_cc_sa8775p_driver); 621 } 622 module_exit(gpu_cc_sa8775p_exit); 623 624 MODULE_DESCRIPTION("SA8775P GPUCC driver"); 625 MODULE_LICENSE("GPL"); 626