1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2021-2022, 2024, 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_shared_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_shared_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_shared_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, 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 .ops = &clk_branch2_aon_ops, 298 }, 299 }, 300 }; 301 302 static struct clk_branch gpu_cc_crc_ahb_clk = { 303 .halt_reg = 0x9120, 304 .halt_check = BRANCH_HALT_VOTED, 305 .clkr = { 306 .enable_reg = 0x9120, 307 .enable_mask = BIT(0), 308 .hw.init = &(const struct clk_init_data){ 309 .name = "gpu_cc_crc_ahb_clk", 310 .parent_hws = (const struct clk_hw*[]){ 311 &gpu_cc_hub_ahb_div_clk_src.clkr.hw, 312 }, 313 .num_parents = 1, 314 .flags = CLK_SET_RATE_PARENT, 315 .ops = &clk_branch2_ops, 316 }, 317 }, 318 }; 319 320 static struct clk_branch gpu_cc_cx_ff_clk = { 321 .halt_reg = 0x914c, 322 .halt_check = BRANCH_HALT, 323 .clkr = { 324 .enable_reg = 0x914c, 325 .enable_mask = BIT(0), 326 .hw.init = &(const struct clk_init_data){ 327 .name = "gpu_cc_cx_ff_clk", 328 .parent_hws = (const struct clk_hw*[]){ 329 &gpu_cc_ff_clk_src.clkr.hw, 330 }, 331 .num_parents = 1, 332 .flags = CLK_SET_RATE_PARENT, 333 .ops = &clk_branch2_ops, 334 }, 335 }, 336 }; 337 338 static struct clk_branch gpu_cc_cx_gmu_clk = { 339 .halt_reg = 0x913c, 340 .halt_check = BRANCH_HALT, 341 .clkr = { 342 .enable_reg = 0x913c, 343 .enable_mask = BIT(0), 344 .hw.init = &(const struct clk_init_data){ 345 .name = "gpu_cc_cx_gmu_clk", 346 .parent_hws = (const struct clk_hw*[]){ 347 &gpu_cc_gmu_clk_src.clkr.hw, 348 }, 349 .num_parents = 1, 350 .flags = CLK_SET_RATE_PARENT, 351 .ops = &clk_branch2_aon_ops, 352 }, 353 }, 354 }; 355 356 static struct clk_branch gpu_cc_cx_snoc_dvm_clk = { 357 .halt_reg = 0x9130, 358 .halt_check = BRANCH_HALT_VOTED, 359 .clkr = { 360 .enable_reg = 0x9130, 361 .enable_mask = BIT(0), 362 .hw.init = &(const struct clk_init_data){ 363 .name = "gpu_cc_cx_snoc_dvm_clk", 364 .ops = &clk_branch2_ops, 365 }, 366 }, 367 }; 368 369 static struct clk_branch gpu_cc_cxo_aon_clk = { 370 .halt_reg = 0x9004, 371 .halt_check = BRANCH_HALT_VOTED, 372 .clkr = { 373 .enable_reg = 0x9004, 374 .enable_mask = BIT(0), 375 .hw.init = &(const struct clk_init_data){ 376 .name = "gpu_cc_cxo_aon_clk", 377 .parent_hws = (const struct clk_hw*[]){ 378 &gpu_cc_xo_clk_src.clkr.hw, 379 }, 380 .num_parents = 1, 381 .flags = CLK_SET_RATE_PARENT, 382 .ops = &clk_branch2_ops, 383 }, 384 }, 385 }; 386 387 static struct clk_branch gpu_cc_cxo_clk = { 388 .halt_reg = 0x9144, 389 .halt_check = BRANCH_HALT, 390 .clkr = { 391 .enable_reg = 0x9144, 392 .enable_mask = BIT(0), 393 .hw.init = &(const struct clk_init_data){ 394 .name = "gpu_cc_cxo_clk", 395 .parent_hws = (const struct clk_hw*[]){ 396 &gpu_cc_xo_clk_src.clkr.hw, 397 }, 398 .num_parents = 1, 399 .flags = CLK_SET_RATE_PARENT, 400 .ops = &clk_branch2_ops, 401 }, 402 }, 403 }; 404 405 static struct clk_branch gpu_cc_demet_clk = { 406 .halt_reg = 0x900c, 407 .halt_check = BRANCH_HALT, 408 .clkr = { 409 .enable_reg = 0x900c, 410 .enable_mask = BIT(0), 411 .hw.init = &(const struct clk_init_data){ 412 .name = "gpu_cc_demet_clk", 413 .parent_hws = (const struct clk_hw*[]){ 414 &gpu_cc_demet_div_clk_src.clkr.hw, 415 }, 416 .num_parents = 1, 417 .flags = CLK_SET_RATE_PARENT, 418 .ops = &clk_branch2_aon_ops, 419 }, 420 }, 421 }; 422 423 static struct clk_branch gpu_cc_hlos1_vote_gpu_smmu_clk = { 424 .halt_reg = 0x7000, 425 .halt_check = BRANCH_HALT_VOTED, 426 .clkr = { 427 .enable_reg = 0x7000, 428 .enable_mask = BIT(0), 429 .hw.init = &(const struct clk_init_data){ 430 .name = "gpu_cc_hlos1_vote_gpu_smmu_clk", 431 .ops = &clk_branch2_ops, 432 }, 433 }, 434 }; 435 436 static struct clk_branch gpu_cc_hub_aon_clk = { 437 .halt_reg = 0x93e8, 438 .halt_check = BRANCH_HALT, 439 .clkr = { 440 .enable_reg = 0x93e8, 441 .enable_mask = BIT(0), 442 .hw.init = &(const struct clk_init_data){ 443 .name = "gpu_cc_hub_aon_clk", 444 .parent_hws = (const struct clk_hw*[]){ 445 &gpu_cc_hub_clk_src.clkr.hw, 446 }, 447 .num_parents = 1, 448 .flags = CLK_SET_RATE_PARENT, 449 .ops = &clk_branch2_aon_ops, 450 }, 451 }, 452 }; 453 454 static struct clk_branch gpu_cc_hub_cx_int_clk = { 455 .halt_reg = 0x9148, 456 .halt_check = BRANCH_HALT, 457 .clkr = { 458 .enable_reg = 0x9148, 459 .enable_mask = BIT(0), 460 .hw.init = &(const struct clk_init_data){ 461 .name = "gpu_cc_hub_cx_int_clk", 462 .parent_hws = (const struct clk_hw*[]){ 463 &gpu_cc_hub_cx_int_div_clk_src.clkr.hw, 464 }, 465 .num_parents = 1, 466 .flags = CLK_SET_RATE_PARENT, 467 .ops = &clk_branch2_aon_ops, 468 }, 469 }, 470 }; 471 472 static struct clk_branch gpu_cc_memnoc_gfx_clk = { 473 .halt_reg = 0x9150, 474 .halt_check = BRANCH_HALT, 475 .clkr = { 476 .enable_reg = 0x9150, 477 .enable_mask = BIT(0), 478 .hw.init = &(const struct clk_init_data){ 479 .name = "gpu_cc_memnoc_gfx_clk", 480 .ops = &clk_branch2_ops, 481 }, 482 }, 483 }; 484 485 static struct clk_branch gpu_cc_sleep_clk = { 486 .halt_reg = 0x9134, 487 .halt_check = BRANCH_HALT_VOTED, 488 .clkr = { 489 .enable_reg = 0x9134, 490 .enable_mask = BIT(0), 491 .hw.init = &(const struct clk_init_data){ 492 .name = "gpu_cc_sleep_clk", 493 .ops = &clk_branch2_ops, 494 }, 495 }, 496 }; 497 498 static struct clk_regmap *gpu_cc_sa8775p_clocks[] = { 499 [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, 500 [GPU_CC_CB_CLK] = &gpu_cc_cb_clk.clkr, 501 [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr, 502 [GPU_CC_CX_FF_CLK] = &gpu_cc_cx_ff_clk.clkr, 503 [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, 504 [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr, 505 [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr, 506 [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, 507 [GPU_CC_DEMET_CLK] = &gpu_cc_demet_clk.clkr, 508 [GPU_CC_DEMET_DIV_CLK_SRC] = &gpu_cc_demet_div_clk_src.clkr, 509 [GPU_CC_FF_CLK_SRC] = &gpu_cc_ff_clk_src.clkr, 510 [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, 511 [GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK] = &gpu_cc_hlos1_vote_gpu_smmu_clk.clkr, 512 [GPU_CC_HUB_AHB_DIV_CLK_SRC] = &gpu_cc_hub_ahb_div_clk_src.clkr, 513 [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr, 514 [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr, 515 [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr, 516 [GPU_CC_HUB_CX_INT_DIV_CLK_SRC] = &gpu_cc_hub_cx_int_div_clk_src.clkr, 517 [GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr, 518 [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, 519 [GPU_CC_PLL1] = &gpu_cc_pll1.clkr, 520 [GPU_CC_SLEEP_CLK] = &gpu_cc_sleep_clk.clkr, 521 [GPU_CC_XO_CLK_SRC] = &gpu_cc_xo_clk_src.clkr, 522 }; 523 524 static struct gdsc cx_gdsc = { 525 .gdscr = 0x9108, 526 .en_rest_wait_val = 0x2, 527 .en_few_wait_val = 0x2, 528 .clk_dis_wait_val = 0xf, 529 .gds_hw_ctrl = 0x953c, 530 .pd = { 531 .name = "cx_gdsc", 532 }, 533 .pwrsts = PWRSTS_OFF_ON, 534 .flags = VOTABLE | RETAIN_FF_ENABLE, 535 }; 536 537 static struct gdsc gx_gdsc = { 538 .gdscr = 0x905c, 539 .en_rest_wait_val = 0x2, 540 .en_few_wait_val = 0x2, 541 .clk_dis_wait_val = 0xf, 542 .pd = { 543 .name = "gx_gdsc", 544 .power_on = gdsc_gx_do_nothing_enable, 545 }, 546 .pwrsts = PWRSTS_OFF_ON, 547 .flags = AON_RESET | RETAIN_FF_ENABLE, 548 }; 549 550 static struct gdsc *gpu_cc_sa8775p_gdscs[] = { 551 [GPU_CC_CX_GDSC] = &cx_gdsc, 552 [GPU_CC_GX_GDSC] = &gx_gdsc, 553 }; 554 555 static const struct qcom_reset_map gpu_cc_sa8775p_resets[] = { 556 [GPUCC_GPU_CC_ACD_BCR] = { 0x9358 }, 557 [GPUCC_GPU_CC_CB_BCR] = { 0x93a0 }, 558 [GPUCC_GPU_CC_CX_BCR] = { 0x9104 }, 559 [GPUCC_GPU_CC_FAST_HUB_BCR] = { 0x93e4 }, 560 [GPUCC_GPU_CC_FF_BCR] = { 0x9470 }, 561 [GPUCC_GPU_CC_GFX3D_AON_BCR] = { 0x9198 }, 562 [GPUCC_GPU_CC_GMU_BCR] = { 0x9314 }, 563 [GPUCC_GPU_CC_GX_BCR] = { 0x9058 }, 564 [GPUCC_GPU_CC_XO_BCR] = { 0x9000 }, 565 }; 566 567 static const struct regmap_config gpu_cc_sa8775p_regmap_config = { 568 .reg_bits = 32, 569 .reg_stride = 4, 570 .val_bits = 32, 571 .max_register = 0x9988, 572 .fast_io = true, 573 }; 574 575 static const struct qcom_cc_desc gpu_cc_sa8775p_desc = { 576 .config = &gpu_cc_sa8775p_regmap_config, 577 .clks = gpu_cc_sa8775p_clocks, 578 .num_clks = ARRAY_SIZE(gpu_cc_sa8775p_clocks), 579 .resets = gpu_cc_sa8775p_resets, 580 .num_resets = ARRAY_SIZE(gpu_cc_sa8775p_resets), 581 .gdscs = gpu_cc_sa8775p_gdscs, 582 .num_gdscs = ARRAY_SIZE(gpu_cc_sa8775p_gdscs), 583 }; 584 585 static const struct of_device_id gpu_cc_sa8775p_match_table[] = { 586 { .compatible = "qcom,sa8775p-gpucc" }, 587 { } 588 }; 589 MODULE_DEVICE_TABLE(of, gpu_cc_sa8775p_match_table); 590 591 static int gpu_cc_sa8775p_probe(struct platform_device *pdev) 592 { 593 struct regmap *regmap; 594 595 regmap = qcom_cc_map(pdev, &gpu_cc_sa8775p_desc); 596 if (IS_ERR(regmap)) 597 return PTR_ERR(regmap); 598 599 clk_lucid_evo_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config); 600 clk_lucid_evo_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config); 601 602 return qcom_cc_really_probe(pdev, &gpu_cc_sa8775p_desc, regmap); 603 } 604 605 static struct platform_driver gpu_cc_sa8775p_driver = { 606 .probe = gpu_cc_sa8775p_probe, 607 .driver = { 608 .name = "gpu_cc-sa8775p", 609 .of_match_table = gpu_cc_sa8775p_match_table, 610 }, 611 }; 612 613 static int __init gpu_cc_sa8775p_init(void) 614 { 615 return platform_driver_register(&gpu_cc_sa8775p_driver); 616 } 617 subsys_initcall(gpu_cc_sa8775p_init); 618 619 static void __exit gpu_cc_sa8775p_exit(void) 620 { 621 platform_driver_unregister(&gpu_cc_sa8775p_driver); 622 } 623 module_exit(gpu_cc_sa8775p_exit); 624 625 MODULE_DESCRIPTION("SA8775P GPUCC driver"); 626 MODULE_LICENSE("GPL"); 627