1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 4 */ 5 6 #include <linux/clk-provider.h> 7 #include <linux/mod_devicetable.h> 8 #include <linux/module.h> 9 #include <linux/platform_device.h> 10 #include <linux/regmap.h> 11 12 #include <dt-bindings/clock/qcom,nord-nwgcc.h> 13 14 #include "clk-alpha-pll.h" 15 #include "clk-branch.h" 16 #include "clk-pll.h" 17 #include "clk-rcg.h" 18 #include "clk-regmap.h" 19 #include "clk-regmap-divider.h" 20 #include "clk-regmap-mux.h" 21 #include "common.h" 22 #include "reset.h" 23 24 enum { 25 DT_BI_TCXO, 26 DT_SLEEP_CLK, 27 }; 28 29 enum { 30 P_BI_TCXO, 31 P_NW_GCC_GPLL0_OUT_EVEN, 32 P_NW_GCC_GPLL0_OUT_MAIN, 33 P_SLEEP_CLK, 34 }; 35 36 static struct clk_alpha_pll nw_gcc_gpll0 = { 37 .offset = 0x0, 38 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], 39 .clkr = { 40 .enable_reg = 0x0, 41 .enable_mask = BIT(0), 42 .hw.init = &(const struct clk_init_data) { 43 .name = "nw_gcc_gpll0", 44 .parent_data = &(const struct clk_parent_data) { 45 .index = DT_BI_TCXO, 46 }, 47 .num_parents = 1, 48 .ops = &clk_alpha_pll_fixed_lucid_ole_ops, 49 }, 50 }, 51 }; 52 53 static const struct clk_div_table post_div_table_nw_gcc_gpll0_out_even[] = { 54 { 0x1, 2 }, 55 { } 56 }; 57 58 static struct clk_alpha_pll_postdiv nw_gcc_gpll0_out_even = { 59 .offset = 0x0, 60 .post_div_shift = 10, 61 .post_div_table = post_div_table_nw_gcc_gpll0_out_even, 62 .num_post_div = ARRAY_SIZE(post_div_table_nw_gcc_gpll0_out_even), 63 .width = 4, 64 .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID_OLE], 65 .clkr.hw.init = &(const struct clk_init_data) { 66 .name = "nw_gcc_gpll0_out_even", 67 .parent_hws = (const struct clk_hw*[]) { 68 &nw_gcc_gpll0.clkr.hw, 69 }, 70 .num_parents = 1, 71 .ops = &clk_alpha_pll_postdiv_lucid_ole_ops, 72 }, 73 }; 74 75 static const struct parent_map nw_gcc_parent_map_0[] = { 76 { P_BI_TCXO, 0 }, 77 { P_NW_GCC_GPLL0_OUT_MAIN, 1 }, 78 { P_SLEEP_CLK, 5 }, 79 { P_NW_GCC_GPLL0_OUT_EVEN, 6 }, 80 }; 81 82 static const struct clk_parent_data nw_gcc_parent_data_0[] = { 83 { .index = DT_BI_TCXO }, 84 { .hw = &nw_gcc_gpll0.clkr.hw }, 85 { .index = DT_SLEEP_CLK }, 86 { .hw = &nw_gcc_gpll0_out_even.clkr.hw }, 87 }; 88 89 static const struct freq_tbl ftbl_nw_gcc_gp1_clk_src[] = { 90 F(60000000, P_NW_GCC_GPLL0_OUT_MAIN, 10, 0, 0), 91 F(100000000, P_NW_GCC_GPLL0_OUT_MAIN, 6, 0, 0), 92 F(200000000, P_NW_GCC_GPLL0_OUT_MAIN, 3, 0, 0), 93 { } 94 }; 95 96 static struct clk_rcg2 nw_gcc_gp1_clk_src = { 97 .cmd_rcgr = 0x20004, 98 .mnd_width = 16, 99 .hid_width = 5, 100 .parent_map = nw_gcc_parent_map_0, 101 .freq_tbl = ftbl_nw_gcc_gp1_clk_src, 102 .hw_clk_ctrl = true, 103 .clkr.hw.init = &(const struct clk_init_data) { 104 .name = "nw_gcc_gp1_clk_src", 105 .parent_data = nw_gcc_parent_data_0, 106 .num_parents = ARRAY_SIZE(nw_gcc_parent_data_0), 107 .flags = CLK_SET_RATE_PARENT, 108 .ops = &clk_rcg2_shared_ops, 109 }, 110 }; 111 112 static struct clk_rcg2 nw_gcc_gp2_clk_src = { 113 .cmd_rcgr = 0x21004, 114 .mnd_width = 16, 115 .hid_width = 5, 116 .parent_map = nw_gcc_parent_map_0, 117 .freq_tbl = ftbl_nw_gcc_gp1_clk_src, 118 .hw_clk_ctrl = true, 119 .clkr.hw.init = &(const struct clk_init_data) { 120 .name = "nw_gcc_gp2_clk_src", 121 .parent_data = nw_gcc_parent_data_0, 122 .num_parents = ARRAY_SIZE(nw_gcc_parent_data_0), 123 .flags = CLK_SET_RATE_PARENT, 124 .ops = &clk_rcg2_shared_ops, 125 }, 126 }; 127 128 static struct clk_branch nw_gcc_acmu_mux_clk = { 129 .halt_reg = 0x1f01c, 130 .halt_check = BRANCH_HALT, 131 .clkr = { 132 .enable_reg = 0x1f01c, 133 .enable_mask = BIT(0), 134 .hw.init = &(const struct clk_init_data) { 135 .name = "nw_gcc_acmu_mux_clk", 136 .ops = &clk_branch2_ops, 137 }, 138 }, 139 }; 140 141 static struct clk_branch nw_gcc_camera_hf_axi_clk = { 142 .halt_reg = 0x16008, 143 .halt_check = BRANCH_HALT_SKIP, 144 .hwcg_reg = 0x16008, 145 .hwcg_bit = 1, 146 .clkr = { 147 .enable_reg = 0x16008, 148 .enable_mask = BIT(0), 149 .hw.init = &(const struct clk_init_data) { 150 .name = "nw_gcc_camera_hf_axi_clk", 151 .ops = &clk_branch2_ops, 152 }, 153 }, 154 }; 155 156 static struct clk_branch nw_gcc_camera_sf_axi_clk = { 157 .halt_reg = 0x1601c, 158 .halt_check = BRANCH_HALT_SKIP, 159 .hwcg_reg = 0x1601c, 160 .hwcg_bit = 1, 161 .clkr = { 162 .enable_reg = 0x1601c, 163 .enable_mask = BIT(0), 164 .hw.init = &(const struct clk_init_data) { 165 .name = "nw_gcc_camera_sf_axi_clk", 166 .ops = &clk_branch2_ops, 167 }, 168 }, 169 }; 170 171 static struct clk_branch nw_gcc_camera_trig_clk = { 172 .halt_reg = 0x16034, 173 .halt_check = BRANCH_HALT_VOTED, 174 .hwcg_reg = 0x16034, 175 .hwcg_bit = 1, 176 .clkr = { 177 .enable_reg = 0x16034, 178 .enable_mask = BIT(0), 179 .hw.init = &(const struct clk_init_data) { 180 .name = "nw_gcc_camera_trig_clk", 181 .ops = &clk_branch2_ops, 182 }, 183 }, 184 }; 185 186 static struct clk_branch nw_gcc_disp_0_hf_axi_clk = { 187 .halt_reg = 0x18008, 188 .halt_check = BRANCH_HALT_SKIP, 189 .hwcg_reg = 0x18008, 190 .hwcg_bit = 1, 191 .clkr = { 192 .enable_reg = 0x18008, 193 .enable_mask = BIT(0), 194 .hw.init = &(const struct clk_init_data) { 195 .name = "nw_gcc_disp_0_hf_axi_clk", 196 .ops = &clk_branch2_ops, 197 }, 198 }, 199 }; 200 201 static struct clk_branch nw_gcc_disp_0_trig_clk = { 202 .halt_reg = 0x1801c, 203 .halt_check = BRANCH_HALT_VOTED, 204 .hwcg_reg = 0x1801c, 205 .hwcg_bit = 1, 206 .clkr = { 207 .enable_reg = 0x1801c, 208 .enable_mask = BIT(0), 209 .hw.init = &(const struct clk_init_data) { 210 .name = "nw_gcc_disp_0_trig_clk", 211 .ops = &clk_branch2_ops, 212 }, 213 }, 214 }; 215 216 static struct clk_branch nw_gcc_disp_1_hf_axi_clk = { 217 .halt_reg = 0x19008, 218 .halt_check = BRANCH_HALT_SKIP, 219 .hwcg_reg = 0x19008, 220 .hwcg_bit = 1, 221 .clkr = { 222 .enable_reg = 0x19008, 223 .enable_mask = BIT(0), 224 .hw.init = &(const struct clk_init_data) { 225 .name = "nw_gcc_disp_1_hf_axi_clk", 226 .ops = &clk_branch2_ops, 227 }, 228 }, 229 }; 230 231 static struct clk_branch nw_gcc_disp_1_trig_clk = { 232 .halt_reg = 0x1901c, 233 .halt_check = BRANCH_HALT_VOTED, 234 .hwcg_reg = 0x1901c, 235 .hwcg_bit = 1, 236 .clkr = { 237 .enable_reg = 0x1901c, 238 .enable_mask = BIT(0), 239 .hw.init = &(const struct clk_init_data) { 240 .name = "nw_gcc_disp_1_trig_clk", 241 .ops = &clk_branch2_ops, 242 }, 243 }, 244 }; 245 246 static struct clk_branch nw_gcc_dprx0_axi_hf_clk = { 247 .halt_reg = 0x29004, 248 .halt_check = BRANCH_HALT_SKIP, 249 .hwcg_reg = 0x29004, 250 .hwcg_bit = 1, 251 .clkr = { 252 .enable_reg = 0x29004, 253 .enable_mask = BIT(0), 254 .hw.init = &(const struct clk_init_data) { 255 .name = "nw_gcc_dprx0_axi_hf_clk", 256 .ops = &clk_branch2_ops, 257 }, 258 }, 259 }; 260 261 static struct clk_branch nw_gcc_dprx1_axi_hf_clk = { 262 .halt_reg = 0x2a004, 263 .halt_check = BRANCH_HALT_SKIP, 264 .hwcg_reg = 0x2a004, 265 .hwcg_bit = 1, 266 .clkr = { 267 .enable_reg = 0x2a004, 268 .enable_mask = BIT(0), 269 .hw.init = &(const struct clk_init_data) { 270 .name = "nw_gcc_dprx1_axi_hf_clk", 271 .ops = &clk_branch2_ops, 272 }, 273 }, 274 }; 275 276 static struct clk_branch nw_gcc_eva_axi0_clk = { 277 .halt_reg = 0x1b008, 278 .halt_check = BRANCH_HALT_SKIP, 279 .hwcg_reg = 0x1b008, 280 .hwcg_bit = 1, 281 .clkr = { 282 .enable_reg = 0x1b008, 283 .enable_mask = BIT(0), 284 .hw.init = &(const struct clk_init_data) { 285 .name = "nw_gcc_eva_axi0_clk", 286 .ops = &clk_branch2_ops, 287 }, 288 }, 289 }; 290 291 static struct clk_branch nw_gcc_eva_axi0c_clk = { 292 .halt_reg = 0x1b01c, 293 .halt_check = BRANCH_HALT_SKIP, 294 .hwcg_reg = 0x1b01c, 295 .hwcg_bit = 1, 296 .clkr = { 297 .enable_reg = 0x1b01c, 298 .enable_mask = BIT(0), 299 .hw.init = &(const struct clk_init_data) { 300 .name = "nw_gcc_eva_axi0c_clk", 301 .ops = &clk_branch2_ops, 302 }, 303 }, 304 }; 305 306 static struct clk_branch nw_gcc_eva_trig_clk = { 307 .halt_reg = 0x1b028, 308 .halt_check = BRANCH_HALT_VOTED, 309 .hwcg_reg = 0x1b028, 310 .hwcg_bit = 1, 311 .clkr = { 312 .enable_reg = 0x1b028, 313 .enable_mask = BIT(0), 314 .hw.init = &(const struct clk_init_data) { 315 .name = "nw_gcc_eva_trig_clk", 316 .ops = &clk_branch2_ops, 317 }, 318 }, 319 }; 320 321 static struct clk_branch nw_gcc_frq_measure_ref_clk = { 322 .halt_reg = 0x1f008, 323 .halt_check = BRANCH_HALT, 324 .clkr = { 325 .enable_reg = 0x1f008, 326 .enable_mask = BIT(0), 327 .hw.init = &(const struct clk_init_data) { 328 .name = "nw_gcc_frq_measure_ref_clk", 329 .ops = &clk_branch2_ops, 330 }, 331 }, 332 }; 333 334 static struct clk_branch nw_gcc_gp1_clk = { 335 .halt_reg = 0x20000, 336 .halt_check = BRANCH_HALT, 337 .clkr = { 338 .enable_reg = 0x20000, 339 .enable_mask = BIT(0), 340 .hw.init = &(const struct clk_init_data) { 341 .name = "nw_gcc_gp1_clk", 342 .parent_hws = (const struct clk_hw*[]) { 343 &nw_gcc_gp1_clk_src.clkr.hw, 344 }, 345 .num_parents = 1, 346 .flags = CLK_SET_RATE_PARENT, 347 .ops = &clk_branch2_ops, 348 }, 349 }, 350 }; 351 352 static struct clk_branch nw_gcc_gp2_clk = { 353 .halt_reg = 0x21000, 354 .halt_check = BRANCH_HALT, 355 .clkr = { 356 .enable_reg = 0x21000, 357 .enable_mask = BIT(0), 358 .hw.init = &(const struct clk_init_data) { 359 .name = "nw_gcc_gp2_clk", 360 .parent_hws = (const struct clk_hw*[]) { 361 &nw_gcc_gp2_clk_src.clkr.hw, 362 }, 363 .num_parents = 1, 364 .flags = CLK_SET_RATE_PARENT, 365 .ops = &clk_branch2_ops, 366 }, 367 }, 368 }; 369 370 static struct clk_branch nw_gcc_gpu_2_gpll0_clk_src = { 371 .halt_reg = 0x24150, 372 .halt_check = BRANCH_HALT_VOTED, 373 .hwcg_reg = 0x24150, 374 .hwcg_bit = 1, 375 .clkr = { 376 .enable_reg = 0x76000, 377 .enable_mask = BIT(6), 378 .hw.init = &(const struct clk_init_data) { 379 .name = "nw_gcc_gpu_2_gpll0_clk_src", 380 .parent_hws = (const struct clk_hw*[]) { 381 &nw_gcc_gpll0.clkr.hw, 382 }, 383 .num_parents = 1, 384 .flags = CLK_SET_RATE_PARENT, 385 .ops = &clk_branch2_ops, 386 }, 387 }, 388 }; 389 390 static struct clk_branch nw_gcc_gpu_2_gpll0_div_clk_src = { 391 .halt_reg = 0x24158, 392 .halt_check = BRANCH_HALT_VOTED, 393 .hwcg_reg = 0x24158, 394 .hwcg_bit = 1, 395 .clkr = { 396 .enable_reg = 0x76000, 397 .enable_mask = BIT(7), 398 .hw.init = &(const struct clk_init_data) { 399 .name = "nw_gcc_gpu_2_gpll0_div_clk_src", 400 .parent_hws = (const struct clk_hw*[]) { 401 &nw_gcc_gpll0_out_even.clkr.hw, 402 }, 403 .num_parents = 1, 404 .flags = CLK_SET_RATE_PARENT, 405 .ops = &clk_branch2_ops, 406 }, 407 }, 408 }; 409 410 static struct clk_branch nw_gcc_gpu_2_hscnoc_gfx_clk = { 411 .halt_reg = 0x2400c, 412 .halt_check = BRANCH_HALT_VOTED, 413 .hwcg_reg = 0x2400c, 414 .hwcg_bit = 1, 415 .clkr = { 416 .enable_reg = 0x2400c, 417 .enable_mask = BIT(0), 418 .hw.init = &(const struct clk_init_data) { 419 .name = "nw_gcc_gpu_2_hscnoc_gfx_clk", 420 .ops = &clk_branch2_ops, 421 }, 422 }, 423 }; 424 425 static struct clk_branch nw_gcc_gpu_gpll0_clk_src = { 426 .halt_reg = 0x23150, 427 .halt_check = BRANCH_HALT_VOTED, 428 .hwcg_reg = 0x23150, 429 .hwcg_bit = 1, 430 .clkr = { 431 .enable_reg = 0x76000, 432 .enable_mask = BIT(4), 433 .hw.init = &(const struct clk_init_data) { 434 .name = "nw_gcc_gpu_gpll0_clk_src", 435 .parent_hws = (const struct clk_hw*[]) { 436 &nw_gcc_gpll0.clkr.hw, 437 }, 438 .num_parents = 1, 439 .flags = CLK_SET_RATE_PARENT, 440 .ops = &clk_branch2_ops, 441 }, 442 }, 443 }; 444 445 static struct clk_branch nw_gcc_gpu_gpll0_div_clk_src = { 446 .halt_reg = 0x23158, 447 .halt_check = BRANCH_HALT_VOTED, 448 .hwcg_reg = 0x23158, 449 .hwcg_bit = 1, 450 .clkr = { 451 .enable_reg = 0x76000, 452 .enable_mask = BIT(5), 453 .hw.init = &(const struct clk_init_data) { 454 .name = "nw_gcc_gpu_gpll0_div_clk_src", 455 .parent_hws = (const struct clk_hw*[]) { 456 &nw_gcc_gpll0_out_even.clkr.hw, 457 }, 458 .num_parents = 1, 459 .flags = CLK_SET_RATE_PARENT, 460 .ops = &clk_branch2_ops, 461 }, 462 }, 463 }; 464 465 static struct clk_branch nw_gcc_gpu_hscnoc_gfx_clk = { 466 .halt_reg = 0x2300c, 467 .halt_check = BRANCH_HALT_SKIP, 468 .hwcg_reg = 0x2300c, 469 .hwcg_bit = 1, 470 .clkr = { 471 .enable_reg = 0x2300c, 472 .enable_mask = BIT(0), 473 .hw.init = &(const struct clk_init_data) { 474 .name = "nw_gcc_gpu_hscnoc_gfx_clk", 475 .ops = &clk_branch2_ops, 476 }, 477 }, 478 }; 479 480 static struct clk_branch nw_gcc_gpu_smmu_vote_clk = { 481 .halt_reg = 0x86038, 482 .halt_check = BRANCH_HALT_VOTED, 483 .clkr = { 484 .enable_reg = 0x86038, 485 .enable_mask = BIT(0), 486 .hw.init = &(const struct clk_init_data) { 487 .name = "nw_gcc_gpu_smmu_vote_clk", 488 .ops = &clk_branch2_ops, 489 }, 490 }, 491 }; 492 493 static struct clk_branch nw_gcc_hscnoc_gpu_2_axi_clk = { 494 .halt_reg = 0x24160, 495 .halt_check = BRANCH_HALT_SKIP, 496 .hwcg_reg = 0x24160, 497 .hwcg_bit = 1, 498 .clkr = { 499 .enable_reg = 0x24160, 500 .enable_mask = BIT(0), 501 .hw.init = &(const struct clk_init_data) { 502 .name = "nw_gcc_hscnoc_gpu_2_axi_clk", 503 .ops = &clk_branch2_ops, 504 }, 505 }, 506 }; 507 508 static struct clk_branch nw_gcc_hscnoc_gpu_axi_clk = { 509 .halt_reg = 0x23160, 510 .halt_check = BRANCH_HALT_SKIP, 511 .hwcg_reg = 0x23160, 512 .hwcg_bit = 1, 513 .clkr = { 514 .enable_reg = 0x23160, 515 .enable_mask = BIT(0), 516 .hw.init = &(const struct clk_init_data) { 517 .name = "nw_gcc_hscnoc_gpu_axi_clk", 518 .ops = &clk_branch2_ops, 519 }, 520 }, 521 }; 522 523 static struct clk_branch nw_gcc_mmu_1_tcu_vote_clk = { 524 .halt_reg = 0x86040, 525 .halt_check = BRANCH_HALT_VOTED, 526 .clkr = { 527 .enable_reg = 0x86040, 528 .enable_mask = BIT(0), 529 .hw.init = &(const struct clk_init_data) { 530 .name = "nw_gcc_mmu_1_tcu_vote_clk", 531 .ops = &clk_branch2_ops, 532 }, 533 }, 534 }; 535 536 static struct clk_branch nw_gcc_video_axi0_clk = { 537 .halt_reg = 0x1a008, 538 .halt_check = BRANCH_HALT_SKIP, 539 .hwcg_reg = 0x1a008, 540 .hwcg_bit = 1, 541 .clkr = { 542 .enable_reg = 0x1a008, 543 .enable_mask = BIT(0), 544 .hw.init = &(const struct clk_init_data) { 545 .name = "nw_gcc_video_axi0_clk", 546 .ops = &clk_branch2_ops, 547 }, 548 }, 549 }; 550 551 static struct clk_branch nw_gcc_video_axi0c_clk = { 552 .halt_reg = 0x1a01c, 553 .halt_check = BRANCH_HALT_SKIP, 554 .hwcg_reg = 0x1a01c, 555 .hwcg_bit = 1, 556 .clkr = { 557 .enable_reg = 0x1a01c, 558 .enable_mask = BIT(0), 559 .hw.init = &(const struct clk_init_data) { 560 .name = "nw_gcc_video_axi0c_clk", 561 .ops = &clk_branch2_ops, 562 }, 563 }, 564 }; 565 566 static struct clk_branch nw_gcc_video_axi1_clk = { 567 .halt_reg = 0x1a030, 568 .halt_check = BRANCH_HALT_SKIP, 569 .hwcg_reg = 0x1a030, 570 .hwcg_bit = 1, 571 .clkr = { 572 .enable_reg = 0x1a030, 573 .enable_mask = BIT(0), 574 .hw.init = &(const struct clk_init_data) { 575 .name = "nw_gcc_video_axi1_clk", 576 .ops = &clk_branch2_ops, 577 }, 578 }, 579 }; 580 581 static struct clk_regmap *nw_gcc_nord_clocks[] = { 582 [NW_GCC_ACMU_MUX_CLK] = &nw_gcc_acmu_mux_clk.clkr, 583 [NW_GCC_CAMERA_HF_AXI_CLK] = &nw_gcc_camera_hf_axi_clk.clkr, 584 [NW_GCC_CAMERA_SF_AXI_CLK] = &nw_gcc_camera_sf_axi_clk.clkr, 585 [NW_GCC_CAMERA_TRIG_CLK] = &nw_gcc_camera_trig_clk.clkr, 586 [NW_GCC_DISP_0_HF_AXI_CLK] = &nw_gcc_disp_0_hf_axi_clk.clkr, 587 [NW_GCC_DISP_0_TRIG_CLK] = &nw_gcc_disp_0_trig_clk.clkr, 588 [NW_GCC_DISP_1_HF_AXI_CLK] = &nw_gcc_disp_1_hf_axi_clk.clkr, 589 [NW_GCC_DISP_1_TRIG_CLK] = &nw_gcc_disp_1_trig_clk.clkr, 590 [NW_GCC_DPRX0_AXI_HF_CLK] = &nw_gcc_dprx0_axi_hf_clk.clkr, 591 [NW_GCC_DPRX1_AXI_HF_CLK] = &nw_gcc_dprx1_axi_hf_clk.clkr, 592 [NW_GCC_EVA_AXI0_CLK] = &nw_gcc_eva_axi0_clk.clkr, 593 [NW_GCC_EVA_AXI0C_CLK] = &nw_gcc_eva_axi0c_clk.clkr, 594 [NW_GCC_EVA_TRIG_CLK] = &nw_gcc_eva_trig_clk.clkr, 595 [NW_GCC_FRQ_MEASURE_REF_CLK] = &nw_gcc_frq_measure_ref_clk.clkr, 596 [NW_GCC_GP1_CLK] = &nw_gcc_gp1_clk.clkr, 597 [NW_GCC_GP1_CLK_SRC] = &nw_gcc_gp1_clk_src.clkr, 598 [NW_GCC_GP2_CLK] = &nw_gcc_gp2_clk.clkr, 599 [NW_GCC_GP2_CLK_SRC] = &nw_gcc_gp2_clk_src.clkr, 600 [NW_GCC_GPLL0] = &nw_gcc_gpll0.clkr, 601 [NW_GCC_GPLL0_OUT_EVEN] = &nw_gcc_gpll0_out_even.clkr, 602 [NW_GCC_GPU_2_GPLL0_CLK_SRC] = &nw_gcc_gpu_2_gpll0_clk_src.clkr, 603 [NW_GCC_GPU_2_GPLL0_DIV_CLK_SRC] = &nw_gcc_gpu_2_gpll0_div_clk_src.clkr, 604 [NW_GCC_GPU_2_HSCNOC_GFX_CLK] = &nw_gcc_gpu_2_hscnoc_gfx_clk.clkr, 605 [NW_GCC_GPU_GPLL0_CLK_SRC] = &nw_gcc_gpu_gpll0_clk_src.clkr, 606 [NW_GCC_GPU_GPLL0_DIV_CLK_SRC] = &nw_gcc_gpu_gpll0_div_clk_src.clkr, 607 [NW_GCC_GPU_HSCNOC_GFX_CLK] = &nw_gcc_gpu_hscnoc_gfx_clk.clkr, 608 [NW_GCC_GPU_SMMU_VOTE_CLK] = &nw_gcc_gpu_smmu_vote_clk.clkr, 609 [NW_GCC_HSCNOC_GPU_2_AXI_CLK] = &nw_gcc_hscnoc_gpu_2_axi_clk.clkr, 610 [NW_GCC_HSCNOC_GPU_AXI_CLK] = &nw_gcc_hscnoc_gpu_axi_clk.clkr, 611 [NW_GCC_MMU_1_TCU_VOTE_CLK] = &nw_gcc_mmu_1_tcu_vote_clk.clkr, 612 [NW_GCC_VIDEO_AXI0_CLK] = &nw_gcc_video_axi0_clk.clkr, 613 [NW_GCC_VIDEO_AXI0C_CLK] = &nw_gcc_video_axi0c_clk.clkr, 614 [NW_GCC_VIDEO_AXI1_CLK] = &nw_gcc_video_axi1_clk.clkr, 615 }; 616 617 static const struct qcom_reset_map nw_gcc_nord_resets[] = { 618 [NW_GCC_CAMERA_BCR] = { 0x16000 }, 619 [NW_GCC_DISPLAY_0_BCR] = { 0x18000 }, 620 [NW_GCC_DISPLAY_1_BCR] = { 0x19000 }, 621 [NW_GCC_DPRX0_BCR] = { 0x29000 }, 622 [NW_GCC_DPRX1_BCR] = { 0x2a000 }, 623 [NW_GCC_EVA_BCR] = { 0x1b000 }, 624 [NW_GCC_GPU_2_BCR] = { 0x24000 }, 625 [NW_GCC_GPU_BCR] = { 0x23000 }, 626 [NW_GCC_VIDEO_BCR] = { 0x1a000 }, 627 }; 628 629 static u32 nw_gcc_nord_critical_cbcrs[] = { 630 0x16004, /* NW_GCC_CAMERA_AHB_CLK */ 631 0x16030, /* NW_GCC_CAMERA_XO_CLK */ 632 0x18004, /* NW_GCC_DISP_0_AHB_CLK */ 633 0x19004, /* NW_GCC_DISP_1_AHB_CLK */ 634 0x29018, /* NW_GCC_DPRX0_CFG_AHB_CLK */ 635 0x2a018, /* NW_GCC_DPRX1_CFG_AHB_CLK */ 636 0x1b004, /* NW_GCC_EVA_AHB_CLK */ 637 0x1b024, /* NW_GCC_EVA_XO_CLK */ 638 0x23004, /* NW_GCC_GPU_CFG_AHB_CLK */ 639 0x24004, /* NW_GCC_GPU_2_CFG_AHB_CLK */ 640 0x1a004, /* NW_GCC_VIDEO_AHB_CLK */ 641 0x1a044, /* NW_GCC_VIDEO_XO_CLK */ 642 }; 643 644 static struct qcom_cc_driver_data nw_gcc_nord_driver_data = { 645 .clk_cbcrs = nw_gcc_nord_critical_cbcrs, 646 .num_clk_cbcrs = ARRAY_SIZE(nw_gcc_nord_critical_cbcrs), 647 }; 648 649 static const struct regmap_config nw_gcc_nord_regmap_config = { 650 .reg_bits = 32, 651 .reg_stride = 4, 652 .val_bits = 32, 653 .max_register = 0xf41f0, 654 .fast_io = true, 655 }; 656 657 static const struct qcom_cc_desc nw_gcc_nord_desc = { 658 .config = &nw_gcc_nord_regmap_config, 659 .clks = nw_gcc_nord_clocks, 660 .num_clks = ARRAY_SIZE(nw_gcc_nord_clocks), 661 .resets = nw_gcc_nord_resets, 662 .num_resets = ARRAY_SIZE(nw_gcc_nord_resets), 663 .driver_data = &nw_gcc_nord_driver_data, 664 }; 665 666 static const struct of_device_id nw_gcc_nord_match_table[] = { 667 { .compatible = "qcom,nord-nwgcc" }, 668 { } 669 }; 670 MODULE_DEVICE_TABLE(of, nw_gcc_nord_match_table); 671 672 static int nw_gcc_nord_probe(struct platform_device *pdev) 673 { 674 return qcom_cc_probe(pdev, &nw_gcc_nord_desc); 675 } 676 677 static struct platform_driver nw_gcc_nord_driver = { 678 .probe = nw_gcc_nord_probe, 679 .driver = { 680 .name = "nwgcc-nord", 681 .of_match_table = nw_gcc_nord_match_table, 682 }, 683 }; 684 685 module_platform_driver(nw_gcc_nord_driver); 686 687 MODULE_DESCRIPTION("QTI NWGCC NORD Driver"); 688 MODULE_LICENSE("GPL"); 689