gcc-ipq4019.c (43419B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (c) 2015 The Linux Foundation. All rights reserved. 4 */ 5 6#include <linux/kernel.h> 7#include <linux/err.h> 8#include <linux/platform_device.h> 9#include <linux/module.h> 10#include <linux/of.h> 11#include <linux/of_device.h> 12#include <linux/clk-provider.h> 13#include <linux/regmap.h> 14#include <linux/reset-controller.h> 15#include <linux/math64.h> 16#include <linux/delay.h> 17#include <linux/clk.h> 18 19#include <dt-bindings/clock/qcom,gcc-ipq4019.h> 20 21#include "common.h" 22#include "clk-regmap.h" 23#include "clk-rcg.h" 24#include "clk-branch.h" 25#include "reset.h" 26#include "clk-regmap-divider.h" 27 28#define to_clk_regmap_div(_hw) container_of(to_clk_regmap(_hw),\ 29 struct clk_regmap_div, clkr) 30 31#define to_clk_fepll(_hw) container_of(to_clk_regmap_div(_hw),\ 32 struct clk_fepll, cdiv) 33 34enum { 35 P_XO, 36 P_FEPLL200, 37 P_FEPLL500, 38 P_DDRPLL, 39 P_FEPLLWCSS2G, 40 P_FEPLLWCSS5G, 41 P_FEPLL125DLY, 42 P_DDRPLLAPSS, 43}; 44 45/* 46 * struct clk_fepll_vco - vco feedback divider corresponds for FEPLL clocks 47 * @fdbkdiv_shift: lowest bit for FDBKDIV 48 * @fdbkdiv_width: number of bits in FDBKDIV 49 * @refclkdiv_shift: lowest bit for REFCLKDIV 50 * @refclkdiv_width: number of bits in REFCLKDIV 51 * @reg: PLL_DIV register address 52 */ 53struct clk_fepll_vco { 54 u32 fdbkdiv_shift; 55 u32 fdbkdiv_width; 56 u32 refclkdiv_shift; 57 u32 refclkdiv_width; 58 u32 reg; 59}; 60 61/* 62 * struct clk_fepll - clk divider corresponds to FEPLL clocks 63 * @fixed_div: fixed divider value if divider is fixed 64 * @parent_map: map from software's parent index to hardware's src_sel field 65 * @cdiv: divider values for PLL_DIV 66 * @pll_vco: vco feedback divider 67 * @div_table: mapping for actual divider value to register divider value 68 * in case of non fixed divider 69 * @freq_tbl: frequency table 70 */ 71struct clk_fepll { 72 u32 fixed_div; 73 const u8 *parent_map; 74 struct clk_regmap_div cdiv; 75 const struct clk_fepll_vco *pll_vco; 76 const struct clk_div_table *div_table; 77 const struct freq_tbl *freq_tbl; 78}; 79 80static struct parent_map gcc_xo_200_500_map[] = { 81 { P_XO, 0 }, 82 { P_FEPLL200, 1 }, 83 { P_FEPLL500, 2 }, 84}; 85 86static const char * const gcc_xo_200_500[] = { 87 "xo", 88 "fepll200", 89 "fepll500", 90}; 91 92static struct parent_map gcc_xo_200_map[] = { 93 { P_XO, 0 }, 94 { P_FEPLL200, 1 }, 95}; 96 97static const char * const gcc_xo_200[] = { 98 "xo", 99 "fepll200", 100}; 101 102static struct parent_map gcc_xo_200_spi_map[] = { 103 { P_XO, 0 }, 104 { P_FEPLL200, 2 }, 105}; 106 107static const char * const gcc_xo_200_spi[] = { 108 "xo", 109 "fepll200", 110}; 111 112static struct parent_map gcc_xo_sdcc1_500_map[] = { 113 { P_XO, 0 }, 114 { P_DDRPLL, 1 }, 115 { P_FEPLL500, 2 }, 116}; 117 118static const char * const gcc_xo_sdcc1_500[] = { 119 "xo", 120 "ddrpllsdcc", 121 "fepll500", 122}; 123 124static struct parent_map gcc_xo_wcss2g_map[] = { 125 { P_XO, 0 }, 126 { P_FEPLLWCSS2G, 1 }, 127}; 128 129static const char * const gcc_xo_wcss2g[] = { 130 "xo", 131 "fepllwcss2g", 132}; 133 134static struct parent_map gcc_xo_wcss5g_map[] = { 135 { P_XO, 0 }, 136 { P_FEPLLWCSS5G, 1 }, 137}; 138 139static const char * const gcc_xo_wcss5g[] = { 140 "xo", 141 "fepllwcss5g", 142}; 143 144static struct parent_map gcc_xo_125_dly_map[] = { 145 { P_XO, 0 }, 146 { P_FEPLL125DLY, 1 }, 147}; 148 149static const char * const gcc_xo_125_dly[] = { 150 "xo", 151 "fepll125dly", 152}; 153 154static struct parent_map gcc_xo_ddr_500_200_map[] = { 155 { P_XO, 0 }, 156 { P_FEPLL200, 3 }, 157 { P_FEPLL500, 2 }, 158 { P_DDRPLLAPSS, 1 }, 159}; 160 161/* 162 * Contains index for safe clock during APSS freq change. 163 * fepll500 is being used as safe clock so initialize it 164 * with its index in parents list gcc_xo_ddr_500_200. 165 */ 166static const int gcc_ipq4019_cpu_safe_parent = 2; 167static const char * const gcc_xo_ddr_500_200[] = { 168 "xo", 169 "fepll200", 170 "fepll500", 171 "ddrpllapss", 172}; 173 174static const struct freq_tbl ftbl_gcc_audio_pwm_clk[] = { 175 F(48000000, P_XO, 1, 0, 0), 176 F(200000000, P_FEPLL200, 1, 0, 0), 177 { } 178}; 179 180static struct clk_rcg2 audio_clk_src = { 181 .cmd_rcgr = 0x1b000, 182 .hid_width = 5, 183 .parent_map = gcc_xo_200_map, 184 .freq_tbl = ftbl_gcc_audio_pwm_clk, 185 .clkr.hw.init = &(struct clk_init_data){ 186 .name = "audio_clk_src", 187 .parent_names = gcc_xo_200, 188 .num_parents = 2, 189 .ops = &clk_rcg2_ops, 190 191 }, 192}; 193 194static struct clk_branch gcc_audio_ahb_clk = { 195 .halt_reg = 0x1b010, 196 .clkr = { 197 .enable_reg = 0x1b010, 198 .enable_mask = BIT(0), 199 .hw.init = &(struct clk_init_data){ 200 .name = "gcc_audio_ahb_clk", 201 .parent_names = (const char *[]){ 202 "pcnoc_clk_src", 203 }, 204 .flags = CLK_SET_RATE_PARENT, 205 .num_parents = 1, 206 .ops = &clk_branch2_ops, 207 }, 208 }, 209}; 210 211static struct clk_branch gcc_audio_pwm_clk = { 212 .halt_reg = 0x1b00C, 213 .clkr = { 214 .enable_reg = 0x1b00C, 215 .enable_mask = BIT(0), 216 .hw.init = &(struct clk_init_data){ 217 .name = "gcc_audio_pwm_clk", 218 .parent_names = (const char *[]){ 219 "audio_clk_src", 220 }, 221 .flags = CLK_SET_RATE_PARENT, 222 .num_parents = 1, 223 .ops = &clk_branch2_ops, 224 }, 225 }, 226}; 227 228static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_i2c_apps_clk[] = { 229 F(19050000, P_FEPLL200, 10.5, 1, 1), 230 { } 231}; 232 233static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = { 234 .cmd_rcgr = 0x200c, 235 .hid_width = 5, 236 .parent_map = gcc_xo_200_map, 237 .freq_tbl = ftbl_gcc_blsp1_qup1_2_i2c_apps_clk, 238 .clkr.hw.init = &(struct clk_init_data){ 239 .name = "blsp1_qup1_i2c_apps_clk_src", 240 .parent_names = gcc_xo_200, 241 .num_parents = 2, 242 .ops = &clk_rcg2_ops, 243 }, 244}; 245 246static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = { 247 .halt_reg = 0x2008, 248 .clkr = { 249 .enable_reg = 0x2008, 250 .enable_mask = BIT(0), 251 .hw.init = &(struct clk_init_data){ 252 .name = "gcc_blsp1_qup1_i2c_apps_clk", 253 .parent_names = (const char *[]){ 254 "blsp1_qup1_i2c_apps_clk_src", 255 }, 256 .num_parents = 1, 257 .ops = &clk_branch2_ops, 258 .flags = CLK_SET_RATE_PARENT, 259 }, 260 }, 261}; 262 263static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = { 264 .cmd_rcgr = 0x3000, 265 .hid_width = 5, 266 .parent_map = gcc_xo_200_map, 267 .freq_tbl = ftbl_gcc_blsp1_qup1_2_i2c_apps_clk, 268 .clkr.hw.init = &(struct clk_init_data){ 269 .name = "blsp1_qup2_i2c_apps_clk_src", 270 .parent_names = gcc_xo_200, 271 .num_parents = 2, 272 .ops = &clk_rcg2_ops, 273 }, 274}; 275 276static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = { 277 .halt_reg = 0x3010, 278 .clkr = { 279 .enable_reg = 0x3010, 280 .enable_mask = BIT(0), 281 .hw.init = &(struct clk_init_data){ 282 .name = "gcc_blsp1_qup2_i2c_apps_clk", 283 .parent_names = (const char *[]){ 284 "blsp1_qup2_i2c_apps_clk_src", 285 }, 286 .num_parents = 1, 287 .ops = &clk_branch2_ops, 288 .flags = CLK_SET_RATE_PARENT, 289 }, 290 }, 291}; 292 293static const struct freq_tbl ftbl_gcc_blsp1_qup1_2_spi_apps_clk[] = { 294 F(960000, P_XO, 12, 1, 4), 295 F(4800000, P_XO, 1, 1, 10), 296 F(9600000, P_XO, 1, 1, 5), 297 F(15000000, P_XO, 1, 1, 3), 298 F(19200000, P_XO, 1, 2, 5), 299 F(24000000, P_XO, 1, 1, 2), 300 F(48000000, P_XO, 1, 0, 0), 301 { } 302}; 303 304static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = { 305 .cmd_rcgr = 0x2024, 306 .mnd_width = 8, 307 .hid_width = 5, 308 .parent_map = gcc_xo_200_spi_map, 309 .freq_tbl = ftbl_gcc_blsp1_qup1_2_spi_apps_clk, 310 .clkr.hw.init = &(struct clk_init_data){ 311 .name = "blsp1_qup1_spi_apps_clk_src", 312 .parent_names = gcc_xo_200_spi, 313 .num_parents = 2, 314 .ops = &clk_rcg2_ops, 315 }, 316}; 317 318static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = { 319 .halt_reg = 0x2004, 320 .clkr = { 321 .enable_reg = 0x2004, 322 .enable_mask = BIT(0), 323 .hw.init = &(struct clk_init_data){ 324 .name = "gcc_blsp1_qup1_spi_apps_clk", 325 .parent_names = (const char *[]){ 326 "blsp1_qup1_spi_apps_clk_src", 327 }, 328 .num_parents = 1, 329 .ops = &clk_branch2_ops, 330 .flags = CLK_SET_RATE_PARENT, 331 }, 332 }, 333}; 334 335static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = { 336 .cmd_rcgr = 0x3014, 337 .mnd_width = 8, 338 .hid_width = 5, 339 .freq_tbl = ftbl_gcc_blsp1_qup1_2_spi_apps_clk, 340 .parent_map = gcc_xo_200_spi_map, 341 .clkr.hw.init = &(struct clk_init_data){ 342 .name = "blsp1_qup2_spi_apps_clk_src", 343 .parent_names = gcc_xo_200_spi, 344 .num_parents = 2, 345 .ops = &clk_rcg2_ops, 346 }, 347}; 348 349static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = { 350 .halt_reg = 0x300c, 351 .clkr = { 352 .enable_reg = 0x300c, 353 .enable_mask = BIT(0), 354 .hw.init = &(struct clk_init_data){ 355 .name = "gcc_blsp1_qup2_spi_apps_clk", 356 .parent_names = (const char *[]){ 357 "blsp1_qup2_spi_apps_clk_src", 358 }, 359 .num_parents = 1, 360 .ops = &clk_branch2_ops, 361 .flags = CLK_SET_RATE_PARENT, 362 }, 363 }, 364}; 365 366static const struct freq_tbl ftbl_gcc_blsp1_uart1_2_apps_clk[] = { 367 F(1843200, P_FEPLL200, 1, 144, 15625), 368 F(3686400, P_FEPLL200, 1, 288, 15625), 369 F(7372800, P_FEPLL200, 1, 576, 15625), 370 F(14745600, P_FEPLL200, 1, 1152, 15625), 371 F(16000000, P_FEPLL200, 1, 2, 25), 372 F(24000000, P_XO, 1, 1, 2), 373 F(32000000, P_FEPLL200, 1, 4, 25), 374 F(40000000, P_FEPLL200, 1, 1, 5), 375 F(46400000, P_FEPLL200, 1, 29, 125), 376 F(48000000, P_XO, 1, 0, 0), 377 { } 378}; 379 380static struct clk_rcg2 blsp1_uart1_apps_clk_src = { 381 .cmd_rcgr = 0x2044, 382 .mnd_width = 16, 383 .hid_width = 5, 384 .freq_tbl = ftbl_gcc_blsp1_uart1_2_apps_clk, 385 .parent_map = gcc_xo_200_spi_map, 386 .clkr.hw.init = &(struct clk_init_data){ 387 .name = "blsp1_uart1_apps_clk_src", 388 .parent_names = gcc_xo_200_spi, 389 .num_parents = 2, 390 .ops = &clk_rcg2_ops, 391 }, 392}; 393 394static struct clk_branch gcc_blsp1_uart1_apps_clk = { 395 .halt_reg = 0x203c, 396 .clkr = { 397 .enable_reg = 0x203c, 398 .enable_mask = BIT(0), 399 .hw.init = &(struct clk_init_data){ 400 .name = "gcc_blsp1_uart1_apps_clk", 401 .parent_names = (const char *[]){ 402 "blsp1_uart1_apps_clk_src", 403 }, 404 .flags = CLK_SET_RATE_PARENT, 405 .num_parents = 1, 406 .ops = &clk_branch2_ops, 407 }, 408 }, 409}; 410 411static struct clk_rcg2 blsp1_uart2_apps_clk_src = { 412 .cmd_rcgr = 0x3034, 413 .mnd_width = 16, 414 .hid_width = 5, 415 .freq_tbl = ftbl_gcc_blsp1_uart1_2_apps_clk, 416 .parent_map = gcc_xo_200_spi_map, 417 .clkr.hw.init = &(struct clk_init_data){ 418 .name = "blsp1_uart2_apps_clk_src", 419 .parent_names = gcc_xo_200_spi, 420 .num_parents = 2, 421 .ops = &clk_rcg2_ops, 422 }, 423}; 424 425static struct clk_branch gcc_blsp1_uart2_apps_clk = { 426 .halt_reg = 0x302c, 427 .clkr = { 428 .enable_reg = 0x302c, 429 .enable_mask = BIT(0), 430 .hw.init = &(struct clk_init_data){ 431 .name = "gcc_blsp1_uart2_apps_clk", 432 .parent_names = (const char *[]){ 433 "blsp1_uart2_apps_clk_src", 434 }, 435 .num_parents = 1, 436 .ops = &clk_branch2_ops, 437 .flags = CLK_SET_RATE_PARENT, 438 }, 439 }, 440}; 441 442static const struct freq_tbl ftbl_gcc_gp_clk[] = { 443 F(1250000, P_FEPLL200, 1, 16, 0), 444 F(2500000, P_FEPLL200, 1, 8, 0), 445 F(5000000, P_FEPLL200, 1, 4, 0), 446 { } 447}; 448 449static struct clk_rcg2 gp1_clk_src = { 450 .cmd_rcgr = 0x8004, 451 .mnd_width = 8, 452 .hid_width = 5, 453 .freq_tbl = ftbl_gcc_gp_clk, 454 .parent_map = gcc_xo_200_map, 455 .clkr.hw.init = &(struct clk_init_data){ 456 .name = "gp1_clk_src", 457 .parent_names = gcc_xo_200, 458 .num_parents = 2, 459 .ops = &clk_rcg2_ops, 460 }, 461}; 462 463static struct clk_branch gcc_gp1_clk = { 464 .halt_reg = 0x8000, 465 .clkr = { 466 .enable_reg = 0x8000, 467 .enable_mask = BIT(0), 468 .hw.init = &(struct clk_init_data){ 469 .name = "gcc_gp1_clk", 470 .parent_names = (const char *[]){ 471 "gp1_clk_src", 472 }, 473 .num_parents = 1, 474 .ops = &clk_branch2_ops, 475 .flags = CLK_SET_RATE_PARENT, 476 }, 477 }, 478}; 479 480static struct clk_rcg2 gp2_clk_src = { 481 .cmd_rcgr = 0x9004, 482 .mnd_width = 8, 483 .hid_width = 5, 484 .freq_tbl = ftbl_gcc_gp_clk, 485 .parent_map = gcc_xo_200_map, 486 .clkr.hw.init = &(struct clk_init_data){ 487 .name = "gp2_clk_src", 488 .parent_names = gcc_xo_200, 489 .num_parents = 2, 490 .ops = &clk_rcg2_ops, 491 }, 492}; 493 494static struct clk_branch gcc_gp2_clk = { 495 .halt_reg = 0x9000, 496 .clkr = { 497 .enable_reg = 0x9000, 498 .enable_mask = BIT(0), 499 .hw.init = &(struct clk_init_data){ 500 .name = "gcc_gp2_clk", 501 .parent_names = (const char *[]){ 502 "gp2_clk_src", 503 }, 504 .num_parents = 1, 505 .ops = &clk_branch2_ops, 506 .flags = CLK_SET_RATE_PARENT, 507 }, 508 }, 509}; 510 511static struct clk_rcg2 gp3_clk_src = { 512 .cmd_rcgr = 0xa004, 513 .mnd_width = 8, 514 .hid_width = 5, 515 .freq_tbl = ftbl_gcc_gp_clk, 516 .parent_map = gcc_xo_200_map, 517 .clkr.hw.init = &(struct clk_init_data){ 518 .name = "gp3_clk_src", 519 .parent_names = gcc_xo_200, 520 .num_parents = 2, 521 .ops = &clk_rcg2_ops, 522 }, 523}; 524 525static struct clk_branch gcc_gp3_clk = { 526 .halt_reg = 0xa000, 527 .clkr = { 528 .enable_reg = 0xa000, 529 .enable_mask = BIT(0), 530 .hw.init = &(struct clk_init_data){ 531 .name = "gcc_gp3_clk", 532 .parent_names = (const char *[]){ 533 "gp3_clk_src", 534 }, 535 .num_parents = 1, 536 .ops = &clk_branch2_ops, 537 .flags = CLK_SET_RATE_PARENT, 538 }, 539 }, 540}; 541 542static const struct freq_tbl ftbl_gcc_sdcc1_apps_clk[] = { 543 F(144000, P_XO, 1, 3, 240), 544 F(400000, P_XO, 1, 1, 0), 545 F(20000000, P_FEPLL500, 1, 1, 25), 546 F(25000000, P_FEPLL500, 1, 1, 20), 547 F(50000000, P_FEPLL500, 1, 1, 10), 548 F(100000000, P_FEPLL500, 1, 1, 5), 549 F(192000000, P_DDRPLL, 1, 0, 0), 550 { } 551}; 552 553static struct clk_rcg2 sdcc1_apps_clk_src = { 554 .cmd_rcgr = 0x18004, 555 .hid_width = 5, 556 .freq_tbl = ftbl_gcc_sdcc1_apps_clk, 557 .parent_map = gcc_xo_sdcc1_500_map, 558 .clkr.hw.init = &(struct clk_init_data){ 559 .name = "sdcc1_apps_clk_src", 560 .parent_names = gcc_xo_sdcc1_500, 561 .num_parents = 3, 562 .ops = &clk_rcg2_ops, 563 .flags = CLK_SET_RATE_PARENT, 564 }, 565}; 566 567static const struct freq_tbl ftbl_gcc_apps_clk[] = { 568 F(48000000, P_XO, 1, 0, 0), 569 F(200000000, P_FEPLL200, 1, 0, 0), 570 F(384000000, P_DDRPLLAPSS, 1, 0, 0), 571 F(413000000, P_DDRPLLAPSS, 1, 0, 0), 572 F(448000000, P_DDRPLLAPSS, 1, 0, 0), 573 F(488000000, P_DDRPLLAPSS, 1, 0, 0), 574 F(500000000, P_FEPLL500, 1, 0, 0), 575 F(512000000, P_DDRPLLAPSS, 1, 0, 0), 576 F(537000000, P_DDRPLLAPSS, 1, 0, 0), 577 F(565000000, P_DDRPLLAPSS, 1, 0, 0), 578 F(597000000, P_DDRPLLAPSS, 1, 0, 0), 579 F(632000000, P_DDRPLLAPSS, 1, 0, 0), 580 F(672000000, P_DDRPLLAPSS, 1, 0, 0), 581 F(716000000, P_DDRPLLAPSS, 1, 0, 0), 582 { } 583}; 584 585static struct clk_rcg2 apps_clk_src = { 586 .cmd_rcgr = 0x1900c, 587 .hid_width = 5, 588 .freq_tbl = ftbl_gcc_apps_clk, 589 .parent_map = gcc_xo_ddr_500_200_map, 590 .clkr.hw.init = &(struct clk_init_data){ 591 .name = "apps_clk_src", 592 .parent_names = gcc_xo_ddr_500_200, 593 .num_parents = 4, 594 .ops = &clk_rcg2_ops, 595 .flags = CLK_SET_RATE_PARENT, 596 }, 597}; 598 599static const struct freq_tbl ftbl_gcc_apps_ahb_clk[] = { 600 F(48000000, P_XO, 1, 0, 0), 601 F(100000000, P_FEPLL200, 2, 0, 0), 602 { } 603}; 604 605static struct clk_rcg2 apps_ahb_clk_src = { 606 .cmd_rcgr = 0x19014, 607 .hid_width = 5, 608 .parent_map = gcc_xo_200_500_map, 609 .freq_tbl = ftbl_gcc_apps_ahb_clk, 610 .clkr.hw.init = &(struct clk_init_data){ 611 .name = "apps_ahb_clk_src", 612 .parent_names = gcc_xo_200_500, 613 .num_parents = 3, 614 .ops = &clk_rcg2_ops, 615 }, 616}; 617 618static struct clk_branch gcc_apss_ahb_clk = { 619 .halt_reg = 0x19004, 620 .halt_check = BRANCH_HALT_VOTED, 621 .clkr = { 622 .enable_reg = 0x6000, 623 .enable_mask = BIT(14), 624 .hw.init = &(struct clk_init_data){ 625 .name = "gcc_apss_ahb_clk", 626 .parent_names = (const char *[]){ 627 "apps_ahb_clk_src", 628 }, 629 .num_parents = 1, 630 .ops = &clk_branch2_ops, 631 .flags = CLK_SET_RATE_PARENT, 632 }, 633 }, 634}; 635 636static struct clk_branch gcc_blsp1_ahb_clk = { 637 .halt_reg = 0x1008, 638 .halt_check = BRANCH_HALT_VOTED, 639 .clkr = { 640 .enable_reg = 0x6000, 641 .enable_mask = BIT(10), 642 .hw.init = &(struct clk_init_data){ 643 .name = "gcc_blsp1_ahb_clk", 644 .parent_names = (const char *[]){ 645 "pcnoc_clk_src", 646 }, 647 .num_parents = 1, 648 .ops = &clk_branch2_ops, 649 }, 650 }, 651}; 652 653static struct clk_branch gcc_dcd_xo_clk = { 654 .halt_reg = 0x2103c, 655 .clkr = { 656 .enable_reg = 0x2103c, 657 .enable_mask = BIT(0), 658 .hw.init = &(struct clk_init_data){ 659 .name = "gcc_dcd_xo_clk", 660 .parent_names = (const char *[]){ 661 "xo", 662 }, 663 .num_parents = 1, 664 .ops = &clk_branch2_ops, 665 }, 666 }, 667}; 668 669static struct clk_branch gcc_boot_rom_ahb_clk = { 670 .halt_reg = 0x1300c, 671 .clkr = { 672 .enable_reg = 0x1300c, 673 .enable_mask = BIT(0), 674 .hw.init = &(struct clk_init_data){ 675 .name = "gcc_boot_rom_ahb_clk", 676 .parent_names = (const char *[]){ 677 "pcnoc_clk_src", 678 }, 679 .num_parents = 1, 680 .ops = &clk_branch2_ops, 681 .flags = CLK_SET_RATE_PARENT, 682 }, 683 }, 684}; 685 686static struct clk_branch gcc_crypto_ahb_clk = { 687 .halt_reg = 0x16024, 688 .halt_check = BRANCH_HALT_VOTED, 689 .clkr = { 690 .enable_reg = 0x6000, 691 .enable_mask = BIT(0), 692 .hw.init = &(struct clk_init_data){ 693 .name = "gcc_crypto_ahb_clk", 694 .parent_names = (const char *[]){ 695 "pcnoc_clk_src", 696 }, 697 .num_parents = 1, 698 .ops = &clk_branch2_ops, 699 }, 700 }, 701}; 702 703static struct clk_branch gcc_crypto_axi_clk = { 704 .halt_reg = 0x16020, 705 .halt_check = BRANCH_HALT_VOTED, 706 .clkr = { 707 .enable_reg = 0x6000, 708 .enable_mask = BIT(1), 709 .hw.init = &(struct clk_init_data){ 710 .name = "gcc_crypto_axi_clk", 711 .parent_names = (const char *[]){ 712 "fepll125", 713 }, 714 .num_parents = 1, 715 .ops = &clk_branch2_ops, 716 }, 717 }, 718}; 719 720static struct clk_branch gcc_crypto_clk = { 721 .halt_reg = 0x1601c, 722 .halt_check = BRANCH_HALT_VOTED, 723 .clkr = { 724 .enable_reg = 0x6000, 725 .enable_mask = BIT(2), 726 .hw.init = &(struct clk_init_data){ 727 .name = "gcc_crypto_clk", 728 .parent_names = (const char *[]){ 729 "fepll125", 730 }, 731 .num_parents = 1, 732 .ops = &clk_branch2_ops, 733 }, 734 }, 735}; 736 737static struct clk_branch gcc_ess_clk = { 738 .halt_reg = 0x12010, 739 .clkr = { 740 .enable_reg = 0x12010, 741 .enable_mask = BIT(0), 742 .hw.init = &(struct clk_init_data){ 743 .name = "gcc_ess_clk", 744 .parent_names = (const char *[]){ 745 "fephy_125m_dly_clk_src", 746 }, 747 .num_parents = 1, 748 .ops = &clk_branch2_ops, 749 .flags = CLK_SET_RATE_PARENT, 750 }, 751 }, 752}; 753 754static struct clk_branch gcc_imem_axi_clk = { 755 .halt_reg = 0xe004, 756 .halt_check = BRANCH_HALT_VOTED, 757 .clkr = { 758 .enable_reg = 0x6000, 759 .enable_mask = BIT(17), 760 .hw.init = &(struct clk_init_data){ 761 .name = "gcc_imem_axi_clk", 762 .parent_names = (const char *[]){ 763 "fepll200", 764 }, 765 .num_parents = 1, 766 .ops = &clk_branch2_ops, 767 }, 768 }, 769}; 770 771static struct clk_branch gcc_imem_cfg_ahb_clk = { 772 .halt_reg = 0xe008, 773 .clkr = { 774 .enable_reg = 0xe008, 775 .enable_mask = BIT(0), 776 .hw.init = &(struct clk_init_data){ 777 .name = "gcc_imem_cfg_ahb_clk", 778 .parent_names = (const char *[]){ 779 "pcnoc_clk_src", 780 }, 781 .num_parents = 1, 782 .ops = &clk_branch2_ops, 783 }, 784 }, 785}; 786 787static struct clk_branch gcc_pcie_ahb_clk = { 788 .halt_reg = 0x1d00c, 789 .clkr = { 790 .enable_reg = 0x1d00c, 791 .enable_mask = BIT(0), 792 .hw.init = &(struct clk_init_data){ 793 .name = "gcc_pcie_ahb_clk", 794 .parent_names = (const char *[]){ 795 "pcnoc_clk_src", 796 }, 797 .num_parents = 1, 798 .ops = &clk_branch2_ops, 799 }, 800 }, 801}; 802 803static struct clk_branch gcc_pcie_axi_m_clk = { 804 .halt_reg = 0x1d004, 805 .clkr = { 806 .enable_reg = 0x1d004, 807 .enable_mask = BIT(0), 808 .hw.init = &(struct clk_init_data){ 809 .name = "gcc_pcie_axi_m_clk", 810 .parent_names = (const char *[]){ 811 "fepll200", 812 }, 813 .num_parents = 1, 814 .ops = &clk_branch2_ops, 815 }, 816 }, 817}; 818 819static struct clk_branch gcc_pcie_axi_s_clk = { 820 .halt_reg = 0x1d008, 821 .clkr = { 822 .enable_reg = 0x1d008, 823 .enable_mask = BIT(0), 824 .hw.init = &(struct clk_init_data){ 825 .name = "gcc_pcie_axi_s_clk", 826 .parent_names = (const char *[]){ 827 "fepll200", 828 }, 829 .num_parents = 1, 830 .ops = &clk_branch2_ops, 831 }, 832 }, 833}; 834 835static struct clk_branch gcc_prng_ahb_clk = { 836 .halt_reg = 0x13004, 837 .halt_check = BRANCH_HALT_VOTED, 838 .clkr = { 839 .enable_reg = 0x6000, 840 .enable_mask = BIT(8), 841 .hw.init = &(struct clk_init_data){ 842 .name = "gcc_prng_ahb_clk", 843 .parent_names = (const char *[]){ 844 "pcnoc_clk_src", 845 }, 846 .num_parents = 1, 847 .ops = &clk_branch2_ops, 848 }, 849 }, 850}; 851 852static struct clk_branch gcc_qpic_ahb_clk = { 853 .halt_reg = 0x1c008, 854 .clkr = { 855 .enable_reg = 0x1c008, 856 .enable_mask = BIT(0), 857 .hw.init = &(struct clk_init_data){ 858 .name = "gcc_qpic_ahb_clk", 859 .parent_names = (const char *[]){ 860 "pcnoc_clk_src", 861 }, 862 .num_parents = 1, 863 .ops = &clk_branch2_ops, 864 }, 865 }, 866}; 867 868static struct clk_branch gcc_qpic_clk = { 869 .halt_reg = 0x1c004, 870 .clkr = { 871 .enable_reg = 0x1c004, 872 .enable_mask = BIT(0), 873 .hw.init = &(struct clk_init_data){ 874 .name = "gcc_qpic_clk", 875 .parent_names = (const char *[]){ 876 "pcnoc_clk_src", 877 }, 878 .num_parents = 1, 879 .ops = &clk_branch2_ops, 880 }, 881 }, 882}; 883 884static struct clk_branch gcc_sdcc1_ahb_clk = { 885 .halt_reg = 0x18010, 886 .clkr = { 887 .enable_reg = 0x18010, 888 .enable_mask = BIT(0), 889 .hw.init = &(struct clk_init_data){ 890 .name = "gcc_sdcc1_ahb_clk", 891 .parent_names = (const char *[]){ 892 "pcnoc_clk_src", 893 }, 894 .num_parents = 1, 895 .ops = &clk_branch2_ops, 896 }, 897 }, 898}; 899 900static struct clk_branch gcc_sdcc1_apps_clk = { 901 .halt_reg = 0x1800c, 902 .clkr = { 903 .enable_reg = 0x1800c, 904 .enable_mask = BIT(0), 905 .hw.init = &(struct clk_init_data){ 906 .name = "gcc_sdcc1_apps_clk", 907 .parent_names = (const char *[]){ 908 "sdcc1_apps_clk_src", 909 }, 910 .num_parents = 1, 911 .ops = &clk_branch2_ops, 912 .flags = CLK_SET_RATE_PARENT, 913 }, 914 }, 915}; 916 917static struct clk_branch gcc_tlmm_ahb_clk = { 918 .halt_reg = 0x5004, 919 .halt_check = BRANCH_HALT_VOTED, 920 .clkr = { 921 .enable_reg = 0x6000, 922 .enable_mask = BIT(5), 923 .hw.init = &(struct clk_init_data){ 924 .name = "gcc_tlmm_ahb_clk", 925 .parent_names = (const char *[]){ 926 "pcnoc_clk_src", 927 }, 928 .num_parents = 1, 929 .ops = &clk_branch2_ops, 930 }, 931 }, 932}; 933 934static struct clk_branch gcc_usb2_master_clk = { 935 .halt_reg = 0x1e00c, 936 .clkr = { 937 .enable_reg = 0x1e00c, 938 .enable_mask = BIT(0), 939 .hw.init = &(struct clk_init_data){ 940 .name = "gcc_usb2_master_clk", 941 .parent_names = (const char *[]){ 942 "pcnoc_clk_src", 943 }, 944 .num_parents = 1, 945 .ops = &clk_branch2_ops, 946 }, 947 }, 948}; 949 950static struct clk_branch gcc_usb2_sleep_clk = { 951 .halt_reg = 0x1e010, 952 .clkr = { 953 .enable_reg = 0x1e010, 954 .enable_mask = BIT(0), 955 .hw.init = &(struct clk_init_data){ 956 .name = "gcc_usb2_sleep_clk", 957 .parent_names = (const char *[]){ 958 "gcc_sleep_clk_src", 959 }, 960 .num_parents = 1, 961 .ops = &clk_branch2_ops, 962 }, 963 }, 964}; 965 966static struct clk_branch gcc_usb2_mock_utmi_clk = { 967 .halt_reg = 0x1e014, 968 .clkr = { 969 .enable_reg = 0x1e014, 970 .enable_mask = BIT(0), 971 .hw.init = &(struct clk_init_data){ 972 .name = "gcc_usb2_mock_utmi_clk", 973 .parent_names = (const char *[]){ 974 "usb30_mock_utmi_clk_src", 975 }, 976 .num_parents = 1, 977 .ops = &clk_branch2_ops, 978 .flags = CLK_SET_RATE_PARENT, 979 }, 980 }, 981}; 982 983static const struct freq_tbl ftbl_gcc_usb30_mock_utmi_clk[] = { 984 F(2000000, P_FEPLL200, 10, 0, 0), 985 { } 986}; 987 988static struct clk_rcg2 usb30_mock_utmi_clk_src = { 989 .cmd_rcgr = 0x1e000, 990 .hid_width = 5, 991 .parent_map = gcc_xo_200_map, 992 .freq_tbl = ftbl_gcc_usb30_mock_utmi_clk, 993 .clkr.hw.init = &(struct clk_init_data){ 994 .name = "usb30_mock_utmi_clk_src", 995 .parent_names = gcc_xo_200, 996 .num_parents = 2, 997 .ops = &clk_rcg2_ops, 998 }, 999}; 1000 1001static struct clk_branch gcc_usb3_master_clk = { 1002 .halt_reg = 0x1e028, 1003 .clkr = { 1004 .enable_reg = 0x1e028, 1005 .enable_mask = BIT(0), 1006 .hw.init = &(struct clk_init_data){ 1007 .name = "gcc_usb3_master_clk", 1008 .parent_names = (const char *[]){ 1009 "fepll125", 1010 }, 1011 .num_parents = 1, 1012 .ops = &clk_branch2_ops, 1013 }, 1014 }, 1015}; 1016 1017static struct clk_branch gcc_usb3_sleep_clk = { 1018 .halt_reg = 0x1e02C, 1019 .clkr = { 1020 .enable_reg = 0x1e02C, 1021 .enable_mask = BIT(0), 1022 .hw.init = &(struct clk_init_data){ 1023 .name = "gcc_usb3_sleep_clk", 1024 .parent_names = (const char *[]){ 1025 "gcc_sleep_clk_src", 1026 }, 1027 .num_parents = 1, 1028 .ops = &clk_branch2_ops, 1029 }, 1030 }, 1031}; 1032 1033static struct clk_branch gcc_usb3_mock_utmi_clk = { 1034 .halt_reg = 0x1e030, 1035 .clkr = { 1036 .enable_reg = 0x1e030, 1037 .enable_mask = BIT(0), 1038 .hw.init = &(struct clk_init_data){ 1039 .name = "gcc_usb3_mock_utmi_clk", 1040 .parent_names = (const char *[]){ 1041 "usb30_mock_utmi_clk_src", 1042 }, 1043 .num_parents = 1, 1044 .ops = &clk_branch2_ops, 1045 .flags = CLK_SET_RATE_PARENT, 1046 }, 1047 }, 1048}; 1049 1050static const struct freq_tbl ftbl_gcc_fephy_dly_clk[] = { 1051 F(125000000, P_FEPLL125DLY, 1, 0, 0), 1052 { } 1053}; 1054 1055static struct clk_rcg2 fephy_125m_dly_clk_src = { 1056 .cmd_rcgr = 0x12000, 1057 .hid_width = 5, 1058 .parent_map = gcc_xo_125_dly_map, 1059 .freq_tbl = ftbl_gcc_fephy_dly_clk, 1060 .clkr.hw.init = &(struct clk_init_data){ 1061 .name = "fephy_125m_dly_clk_src", 1062 .parent_names = gcc_xo_125_dly, 1063 .num_parents = 2, 1064 .ops = &clk_rcg2_ops, 1065 }, 1066}; 1067 1068 1069static const struct freq_tbl ftbl_gcc_wcss2g_clk[] = { 1070 F(48000000, P_XO, 1, 0, 0), 1071 F(250000000, P_FEPLLWCSS2G, 1, 0, 0), 1072 { } 1073}; 1074 1075static struct clk_rcg2 wcss2g_clk_src = { 1076 .cmd_rcgr = 0x1f000, 1077 .hid_width = 5, 1078 .freq_tbl = ftbl_gcc_wcss2g_clk, 1079 .parent_map = gcc_xo_wcss2g_map, 1080 .clkr.hw.init = &(struct clk_init_data){ 1081 .name = "wcss2g_clk_src", 1082 .parent_names = gcc_xo_wcss2g, 1083 .num_parents = 2, 1084 .ops = &clk_rcg2_ops, 1085 .flags = CLK_SET_RATE_PARENT, 1086 }, 1087}; 1088 1089static struct clk_branch gcc_wcss2g_clk = { 1090 .halt_reg = 0x1f00C, 1091 .clkr = { 1092 .enable_reg = 0x1f00C, 1093 .enable_mask = BIT(0), 1094 .hw.init = &(struct clk_init_data){ 1095 .name = "gcc_wcss2g_clk", 1096 .parent_names = (const char *[]){ 1097 "wcss2g_clk_src", 1098 }, 1099 .num_parents = 1, 1100 .ops = &clk_branch2_ops, 1101 .flags = CLK_SET_RATE_PARENT, 1102 }, 1103 }, 1104}; 1105 1106static struct clk_branch gcc_wcss2g_ref_clk = { 1107 .halt_reg = 0x1f00C, 1108 .clkr = { 1109 .enable_reg = 0x1f00C, 1110 .enable_mask = BIT(0), 1111 .hw.init = &(struct clk_init_data){ 1112 .name = "gcc_wcss2g_ref_clk", 1113 .parent_names = (const char *[]){ 1114 "xo", 1115 }, 1116 .num_parents = 1, 1117 .ops = &clk_branch2_ops, 1118 .flags = CLK_SET_RATE_PARENT, 1119 }, 1120 }, 1121}; 1122 1123static struct clk_branch gcc_wcss2g_rtc_clk = { 1124 .halt_reg = 0x1f010, 1125 .clkr = { 1126 .enable_reg = 0x1f010, 1127 .enable_mask = BIT(0), 1128 .hw.init = &(struct clk_init_data){ 1129 .name = "gcc_wcss2g_rtc_clk", 1130 .parent_names = (const char *[]){ 1131 "gcc_sleep_clk_src", 1132 }, 1133 .num_parents = 1, 1134 .ops = &clk_branch2_ops, 1135 }, 1136 }, 1137}; 1138 1139static const struct freq_tbl ftbl_gcc_wcss5g_clk[] = { 1140 F(48000000, P_XO, 1, 0, 0), 1141 F(250000000, P_FEPLLWCSS5G, 1, 0, 0), 1142 { } 1143}; 1144 1145static struct clk_rcg2 wcss5g_clk_src = { 1146 .cmd_rcgr = 0x20000, 1147 .hid_width = 5, 1148 .parent_map = gcc_xo_wcss5g_map, 1149 .freq_tbl = ftbl_gcc_wcss5g_clk, 1150 .clkr.hw.init = &(struct clk_init_data){ 1151 .name = "wcss5g_clk_src", 1152 .parent_names = gcc_xo_wcss5g, 1153 .num_parents = 2, 1154 .ops = &clk_rcg2_ops, 1155 }, 1156}; 1157 1158static struct clk_branch gcc_wcss5g_clk = { 1159 .halt_reg = 0x2000c, 1160 .clkr = { 1161 .enable_reg = 0x2000c, 1162 .enable_mask = BIT(0), 1163 .hw.init = &(struct clk_init_data){ 1164 .name = "gcc_wcss5g_clk", 1165 .parent_names = (const char *[]){ 1166 "wcss5g_clk_src", 1167 }, 1168 .num_parents = 1, 1169 .ops = &clk_branch2_ops, 1170 .flags = CLK_SET_RATE_PARENT, 1171 }, 1172 }, 1173}; 1174 1175static struct clk_branch gcc_wcss5g_ref_clk = { 1176 .halt_reg = 0x2000c, 1177 .clkr = { 1178 .enable_reg = 0x2000c, 1179 .enable_mask = BIT(0), 1180 .hw.init = &(struct clk_init_data){ 1181 .name = "gcc_wcss5g_ref_clk", 1182 .parent_names = (const char *[]){ 1183 "xo", 1184 }, 1185 .num_parents = 1, 1186 .ops = &clk_branch2_ops, 1187 .flags = CLK_SET_RATE_PARENT, 1188 }, 1189 }, 1190}; 1191 1192static struct clk_branch gcc_wcss5g_rtc_clk = { 1193 .halt_reg = 0x20010, 1194 .clkr = { 1195 .enable_reg = 0x20010, 1196 .enable_mask = BIT(0), 1197 .hw.init = &(struct clk_init_data){ 1198 .name = "gcc_wcss5g_rtc_clk", 1199 .parent_names = (const char *[]){ 1200 "gcc_sleep_clk_src", 1201 }, 1202 .num_parents = 1, 1203 .ops = &clk_branch2_ops, 1204 .flags = CLK_SET_RATE_PARENT, 1205 }, 1206 }, 1207}; 1208 1209/* Calculates the VCO rate for FEPLL. */ 1210static u64 clk_fepll_vco_calc_rate(struct clk_fepll *pll_div, 1211 unsigned long parent_rate) 1212{ 1213 const struct clk_fepll_vco *pll_vco = pll_div->pll_vco; 1214 u32 fdbkdiv, refclkdiv, cdiv; 1215 u64 vco; 1216 1217 regmap_read(pll_div->cdiv.clkr.regmap, pll_vco->reg, &cdiv); 1218 refclkdiv = (cdiv >> pll_vco->refclkdiv_shift) & 1219 (BIT(pll_vco->refclkdiv_width) - 1); 1220 fdbkdiv = (cdiv >> pll_vco->fdbkdiv_shift) & 1221 (BIT(pll_vco->fdbkdiv_width) - 1); 1222 1223 vco = parent_rate / refclkdiv; 1224 vco *= 2; 1225 vco *= fdbkdiv; 1226 1227 return vco; 1228} 1229 1230static const struct clk_fepll_vco gcc_apss_ddrpll_vco = { 1231 .fdbkdiv_shift = 16, 1232 .fdbkdiv_width = 8, 1233 .refclkdiv_shift = 24, 1234 .refclkdiv_width = 5, 1235 .reg = 0x2e020, 1236}; 1237 1238static const struct clk_fepll_vco gcc_fepll_vco = { 1239 .fdbkdiv_shift = 16, 1240 .fdbkdiv_width = 8, 1241 .refclkdiv_shift = 24, 1242 .refclkdiv_width = 5, 1243 .reg = 0x2f020, 1244}; 1245 1246/* 1247 * Round rate function for APSS CPU PLL Clock divider. 1248 * It looks up the frequency table and returns the next higher frequency 1249 * supported in hardware. 1250 */ 1251static long clk_cpu_div_round_rate(struct clk_hw *hw, unsigned long rate, 1252 unsigned long *p_rate) 1253{ 1254 struct clk_fepll *pll = to_clk_fepll(hw); 1255 struct clk_hw *p_hw; 1256 const struct freq_tbl *f; 1257 1258 f = qcom_find_freq(pll->freq_tbl, rate); 1259 if (!f) 1260 return -EINVAL; 1261 1262 p_hw = clk_hw_get_parent_by_index(hw, f->src); 1263 *p_rate = clk_hw_get_rate(p_hw); 1264 1265 return f->freq; 1266}; 1267 1268/* 1269 * Clock set rate function for APSS CPU PLL Clock divider. 1270 * It looks up the frequency table and updates the PLL divider to corresponding 1271 * divider value. 1272 */ 1273static int clk_cpu_div_set_rate(struct clk_hw *hw, unsigned long rate, 1274 unsigned long parent_rate) 1275{ 1276 struct clk_fepll *pll = to_clk_fepll(hw); 1277 const struct freq_tbl *f; 1278 u32 mask; 1279 1280 f = qcom_find_freq(pll->freq_tbl, rate); 1281 if (!f) 1282 return -EINVAL; 1283 1284 mask = (BIT(pll->cdiv.width) - 1) << pll->cdiv.shift; 1285 regmap_update_bits(pll->cdiv.clkr.regmap, 1286 pll->cdiv.reg, mask, 1287 f->pre_div << pll->cdiv.shift); 1288 /* 1289 * There is no status bit which can be checked for successful CPU 1290 * divider update operation so using delay for the same. 1291 */ 1292 udelay(1); 1293 1294 return 0; 1295}; 1296 1297/* 1298 * Clock frequency calculation function for APSS CPU PLL Clock divider. 1299 * This clock divider is nonlinear so this function calculates the actual 1300 * divider and returns the output frequency by dividing VCO Frequency 1301 * with this actual divider value. 1302 */ 1303static unsigned long 1304clk_cpu_div_recalc_rate(struct clk_hw *hw, 1305 unsigned long parent_rate) 1306{ 1307 struct clk_fepll *pll = to_clk_fepll(hw); 1308 u32 cdiv, pre_div; 1309 u64 rate; 1310 1311 regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv); 1312 cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1); 1313 1314 /* 1315 * Some dividers have value in 0.5 fraction so multiply both VCO 1316 * frequency(parent_rate) and pre_div with 2 to make integer 1317 * calculation. 1318 */ 1319 if (cdiv > 10) 1320 pre_div = (cdiv + 1) * 2; 1321 else 1322 pre_div = cdiv + 12; 1323 1324 rate = clk_fepll_vco_calc_rate(pll, parent_rate) * 2; 1325 do_div(rate, pre_div); 1326 1327 return rate; 1328}; 1329 1330static const struct clk_ops clk_regmap_cpu_div_ops = { 1331 .round_rate = clk_cpu_div_round_rate, 1332 .set_rate = clk_cpu_div_set_rate, 1333 .recalc_rate = clk_cpu_div_recalc_rate, 1334}; 1335 1336static const struct freq_tbl ftbl_apss_ddr_pll[] = { 1337 { 384000000, P_XO, 0xd, 0, 0 }, 1338 { 413000000, P_XO, 0xc, 0, 0 }, 1339 { 448000000, P_XO, 0xb, 0, 0 }, 1340 { 488000000, P_XO, 0xa, 0, 0 }, 1341 { 512000000, P_XO, 0x9, 0, 0 }, 1342 { 537000000, P_XO, 0x8, 0, 0 }, 1343 { 565000000, P_XO, 0x7, 0, 0 }, 1344 { 597000000, P_XO, 0x6, 0, 0 }, 1345 { 632000000, P_XO, 0x5, 0, 0 }, 1346 { 672000000, P_XO, 0x4, 0, 0 }, 1347 { 716000000, P_XO, 0x3, 0, 0 }, 1348 { 768000000, P_XO, 0x2, 0, 0 }, 1349 { 823000000, P_XO, 0x1, 0, 0 }, 1350 { 896000000, P_XO, 0x0, 0, 0 }, 1351 { } 1352}; 1353 1354static struct clk_fepll gcc_apss_cpu_plldiv_clk = { 1355 .cdiv.reg = 0x2e020, 1356 .cdiv.shift = 4, 1357 .cdiv.width = 4, 1358 .cdiv.clkr = { 1359 .enable_reg = 0x2e000, 1360 .enable_mask = BIT(0), 1361 .hw.init = &(struct clk_init_data){ 1362 .name = "ddrpllapss", 1363 .parent_names = (const char *[]){ 1364 "xo", 1365 }, 1366 .num_parents = 1, 1367 .ops = &clk_regmap_cpu_div_ops, 1368 }, 1369 }, 1370 .freq_tbl = ftbl_apss_ddr_pll, 1371 .pll_vco = &gcc_apss_ddrpll_vco, 1372}; 1373 1374/* Calculates the rate for PLL divider. 1375 * If the divider value is not fixed then it gets the actual divider value 1376 * from divider table. Then, it calculate the clock rate by dividing the 1377 * parent rate with actual divider value. 1378 */ 1379static unsigned long 1380clk_regmap_clk_div_recalc_rate(struct clk_hw *hw, 1381 unsigned long parent_rate) 1382{ 1383 struct clk_fepll *pll = to_clk_fepll(hw); 1384 u32 cdiv, pre_div = 1; 1385 u64 rate; 1386 const struct clk_div_table *clkt; 1387 1388 if (pll->fixed_div) { 1389 pre_div = pll->fixed_div; 1390 } else { 1391 regmap_read(pll->cdiv.clkr.regmap, pll->cdiv.reg, &cdiv); 1392 cdiv = (cdiv >> pll->cdiv.shift) & (BIT(pll->cdiv.width) - 1); 1393 1394 for (clkt = pll->div_table; clkt->div; clkt++) { 1395 if (clkt->val == cdiv) 1396 pre_div = clkt->div; 1397 } 1398 } 1399 1400 rate = clk_fepll_vco_calc_rate(pll, parent_rate); 1401 do_div(rate, pre_div); 1402 1403 return rate; 1404}; 1405 1406static const struct clk_ops clk_fepll_div_ops = { 1407 .recalc_rate = clk_regmap_clk_div_recalc_rate, 1408}; 1409 1410static struct clk_fepll gcc_apss_sdcc_clk = { 1411 .fixed_div = 28, 1412 .cdiv.clkr = { 1413 .hw.init = &(struct clk_init_data){ 1414 .name = "ddrpllsdcc", 1415 .parent_names = (const char *[]){ 1416 "xo", 1417 }, 1418 .num_parents = 1, 1419 .ops = &clk_fepll_div_ops, 1420 }, 1421 }, 1422 .pll_vco = &gcc_apss_ddrpll_vco, 1423}; 1424 1425static struct clk_fepll gcc_fepll125_clk = { 1426 .fixed_div = 32, 1427 .cdiv.clkr = { 1428 .hw.init = &(struct clk_init_data){ 1429 .name = "fepll125", 1430 .parent_names = (const char *[]){ 1431 "xo", 1432 }, 1433 .num_parents = 1, 1434 .ops = &clk_fepll_div_ops, 1435 }, 1436 }, 1437 .pll_vco = &gcc_fepll_vco, 1438}; 1439 1440static struct clk_fepll gcc_fepll125dly_clk = { 1441 .fixed_div = 32, 1442 .cdiv.clkr = { 1443 .hw.init = &(struct clk_init_data){ 1444 .name = "fepll125dly", 1445 .parent_names = (const char *[]){ 1446 "xo", 1447 }, 1448 .num_parents = 1, 1449 .ops = &clk_fepll_div_ops, 1450 }, 1451 }, 1452 .pll_vco = &gcc_fepll_vco, 1453}; 1454 1455static struct clk_fepll gcc_fepll200_clk = { 1456 .fixed_div = 20, 1457 .cdiv.clkr = { 1458 .hw.init = &(struct clk_init_data){ 1459 .name = "fepll200", 1460 .parent_names = (const char *[]){ 1461 "xo", 1462 }, 1463 .num_parents = 1, 1464 .ops = &clk_fepll_div_ops, 1465 }, 1466 }, 1467 .pll_vco = &gcc_fepll_vco, 1468}; 1469 1470static struct clk_fepll gcc_fepll500_clk = { 1471 .fixed_div = 8, 1472 .cdiv.clkr = { 1473 .hw.init = &(struct clk_init_data){ 1474 .name = "fepll500", 1475 .parent_names = (const char *[]){ 1476 "xo", 1477 }, 1478 .num_parents = 1, 1479 .ops = &clk_fepll_div_ops, 1480 }, 1481 }, 1482 .pll_vco = &gcc_fepll_vco, 1483}; 1484 1485static const struct clk_div_table fepllwcss_clk_div_table[] = { 1486 { 0, 15 }, 1487 { 1, 16 }, 1488 { 2, 18 }, 1489 { 3, 20 }, 1490 { }, 1491}; 1492 1493static struct clk_fepll gcc_fepllwcss2g_clk = { 1494 .cdiv.reg = 0x2f020, 1495 .cdiv.shift = 8, 1496 .cdiv.width = 2, 1497 .cdiv.clkr = { 1498 .hw.init = &(struct clk_init_data){ 1499 .name = "fepllwcss2g", 1500 .parent_names = (const char *[]){ 1501 "xo", 1502 }, 1503 .num_parents = 1, 1504 .ops = &clk_fepll_div_ops, 1505 }, 1506 }, 1507 .div_table = fepllwcss_clk_div_table, 1508 .pll_vco = &gcc_fepll_vco, 1509}; 1510 1511static struct clk_fepll gcc_fepllwcss5g_clk = { 1512 .cdiv.reg = 0x2f020, 1513 .cdiv.shift = 12, 1514 .cdiv.width = 2, 1515 .cdiv.clkr = { 1516 .hw.init = &(struct clk_init_data){ 1517 .name = "fepllwcss5g", 1518 .parent_names = (const char *[]){ 1519 "xo", 1520 }, 1521 .num_parents = 1, 1522 .ops = &clk_fepll_div_ops, 1523 }, 1524 }, 1525 .div_table = fepllwcss_clk_div_table, 1526 .pll_vco = &gcc_fepll_vco, 1527}; 1528 1529static const struct freq_tbl ftbl_gcc_pcnoc_ahb_clk[] = { 1530 F(48000000, P_XO, 1, 0, 0), 1531 F(100000000, P_FEPLL200, 2, 0, 0), 1532 { } 1533}; 1534 1535static struct clk_rcg2 gcc_pcnoc_ahb_clk_src = { 1536 .cmd_rcgr = 0x21024, 1537 .hid_width = 5, 1538 .parent_map = gcc_xo_200_500_map, 1539 .freq_tbl = ftbl_gcc_pcnoc_ahb_clk, 1540 .clkr.hw.init = &(struct clk_init_data){ 1541 .name = "gcc_pcnoc_ahb_clk_src", 1542 .parent_names = gcc_xo_200_500, 1543 .num_parents = 3, 1544 .ops = &clk_rcg2_ops, 1545 }, 1546}; 1547 1548static struct clk_branch pcnoc_clk_src = { 1549 .halt_reg = 0x21030, 1550 .clkr = { 1551 .enable_reg = 0x21030, 1552 .enable_mask = BIT(0), 1553 .hw.init = &(struct clk_init_data){ 1554 .name = "pcnoc_clk_src", 1555 .parent_names = (const char *[]){ 1556 "gcc_pcnoc_ahb_clk_src", 1557 }, 1558 .num_parents = 1, 1559 .ops = &clk_branch2_ops, 1560 .flags = CLK_SET_RATE_PARENT | 1561 CLK_IS_CRITICAL, 1562 }, 1563 }, 1564}; 1565 1566static struct clk_regmap *gcc_ipq4019_clocks[] = { 1567 [AUDIO_CLK_SRC] = &audio_clk_src.clkr, 1568 [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, 1569 [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, 1570 [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, 1571 [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, 1572 [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, 1573 [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, 1574 [GCC_USB3_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr, 1575 [GCC_APPS_CLK_SRC] = &apps_clk_src.clkr, 1576 [GCC_APPS_AHB_CLK_SRC] = &apps_ahb_clk_src.clkr, 1577 [GP1_CLK_SRC] = &gp1_clk_src.clkr, 1578 [GP2_CLK_SRC] = &gp2_clk_src.clkr, 1579 [GP3_CLK_SRC] = &gp3_clk_src.clkr, 1580 [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, 1581 [FEPHY_125M_DLY_CLK_SRC] = &fephy_125m_dly_clk_src.clkr, 1582 [WCSS2G_CLK_SRC] = &wcss2g_clk_src.clkr, 1583 [WCSS5G_CLK_SRC] = &wcss5g_clk_src.clkr, 1584 [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr, 1585 [GCC_AUDIO_AHB_CLK] = &gcc_audio_ahb_clk.clkr, 1586 [GCC_AUDIO_PWM_CLK] = &gcc_audio_pwm_clk.clkr, 1587 [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, 1588 [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, 1589 [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, 1590 [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, 1591 [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, 1592 [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, 1593 [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, 1594 [GCC_DCD_XO_CLK] = &gcc_dcd_xo_clk.clkr, 1595 [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, 1596 [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, 1597 [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, 1598 [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, 1599 [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr, 1600 [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr, 1601 [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr, 1602 [GCC_ESS_CLK] = &gcc_ess_clk.clkr, 1603 [GCC_IMEM_AXI_CLK] = &gcc_imem_axi_clk.clkr, 1604 [GCC_IMEM_CFG_AHB_CLK] = &gcc_imem_cfg_ahb_clk.clkr, 1605 [GCC_PCIE_AHB_CLK] = &gcc_pcie_ahb_clk.clkr, 1606 [GCC_PCIE_AXI_M_CLK] = &gcc_pcie_axi_m_clk.clkr, 1607 [GCC_PCIE_AXI_S_CLK] = &gcc_pcie_axi_s_clk.clkr, 1608 [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, 1609 [GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr, 1610 [GCC_QPIC_CLK] = &gcc_qpic_clk.clkr, 1611 [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, 1612 [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, 1613 [GCC_TLMM_AHB_CLK] = &gcc_tlmm_ahb_clk.clkr, 1614 [GCC_USB2_MASTER_CLK] = &gcc_usb2_master_clk.clkr, 1615 [GCC_USB2_SLEEP_CLK] = &gcc_usb2_sleep_clk.clkr, 1616 [GCC_USB2_MOCK_UTMI_CLK] = &gcc_usb2_mock_utmi_clk.clkr, 1617 [GCC_USB3_MASTER_CLK] = &gcc_usb3_master_clk.clkr, 1618 [GCC_USB3_SLEEP_CLK] = &gcc_usb3_sleep_clk.clkr, 1619 [GCC_USB3_MOCK_UTMI_CLK] = &gcc_usb3_mock_utmi_clk.clkr, 1620 [GCC_WCSS2G_CLK] = &gcc_wcss2g_clk.clkr, 1621 [GCC_WCSS2G_REF_CLK] = &gcc_wcss2g_ref_clk.clkr, 1622 [GCC_WCSS2G_RTC_CLK] = &gcc_wcss2g_rtc_clk.clkr, 1623 [GCC_WCSS5G_CLK] = &gcc_wcss5g_clk.clkr, 1624 [GCC_WCSS5G_REF_CLK] = &gcc_wcss5g_ref_clk.clkr, 1625 [GCC_WCSS5G_RTC_CLK] = &gcc_wcss5g_rtc_clk.clkr, 1626 [GCC_SDCC_PLLDIV_CLK] = &gcc_apss_sdcc_clk.cdiv.clkr, 1627 [GCC_FEPLL125_CLK] = &gcc_fepll125_clk.cdiv.clkr, 1628 [GCC_FEPLL125DLY_CLK] = &gcc_fepll125dly_clk.cdiv.clkr, 1629 [GCC_FEPLL200_CLK] = &gcc_fepll200_clk.cdiv.clkr, 1630 [GCC_FEPLL500_CLK] = &gcc_fepll500_clk.cdiv.clkr, 1631 [GCC_FEPLL_WCSS2G_CLK] = &gcc_fepllwcss2g_clk.cdiv.clkr, 1632 [GCC_FEPLL_WCSS5G_CLK] = &gcc_fepllwcss5g_clk.cdiv.clkr, 1633 [GCC_APSS_CPU_PLLDIV_CLK] = &gcc_apss_cpu_plldiv_clk.cdiv.clkr, 1634 [GCC_PCNOC_AHB_CLK_SRC] = &gcc_pcnoc_ahb_clk_src.clkr, 1635 [GCC_PCNOC_AHB_CLK] = &pcnoc_clk_src.clkr, 1636}; 1637 1638static const struct qcom_reset_map gcc_ipq4019_resets[] = { 1639 [WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 }, 1640 [WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 }, 1641 [WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 }, 1642 [WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 }, 1643 [WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 }, 1644 [WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 }, 1645 [WIFI1_CPU_INIT_RESET] = { 0x20008, 5 }, 1646 [WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 }, 1647 [WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 }, 1648 [WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 }, 1649 [WIFI1_CORE_WARM_RESET] = { 0x20008, 1 }, 1650 [WIFI1_CORE_COLD_RESET] = { 0x20008, 0 }, 1651 [USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 }, 1652 [USB3_HSPHY_POR_ARES] = { 0x1e038, 4 }, 1653 [USB3_HSPHY_S_ARES] = { 0x1e038, 2 }, 1654 [USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 }, 1655 [USB2_HSPHY_S_ARES] = { 0x1e01c, 2 }, 1656 [PCIE_PHY_AHB_ARES] = { 0x1d010, 11 }, 1657 [PCIE_AHB_ARES] = { 0x1d010, 10 }, 1658 [PCIE_PWR_ARES] = { 0x1d010, 9 }, 1659 [PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 }, 1660 [PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 }, 1661 [PCIE_PHY_ARES] = { 0x1d010, 6 }, 1662 [PCIE_PARF_XPU_ARES] = { 0x1d010, 5 }, 1663 [PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 }, 1664 [PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 }, 1665 [PCIE_PIPE_ARES] = { 0x1d010, 2 }, 1666 [PCIE_AXI_S_ARES] = { 0x1d010, 1 }, 1667 [PCIE_AXI_M_ARES] = { 0x1d010, 0 }, 1668 [ESS_RESET] = { 0x12008, 0}, 1669 [GCC_BLSP1_BCR] = {0x01000, 0}, 1670 [GCC_BLSP1_QUP1_BCR] = {0x02000, 0}, 1671 [GCC_BLSP1_UART1_BCR] = {0x02038, 0}, 1672 [GCC_BLSP1_QUP2_BCR] = {0x03008, 0}, 1673 [GCC_BLSP1_UART2_BCR] = {0x03028, 0}, 1674 [GCC_BIMC_BCR] = {0x04000, 0}, 1675 [GCC_TLMM_BCR] = {0x05000, 0}, 1676 [GCC_IMEM_BCR] = {0x0E000, 0}, 1677 [GCC_ESS_BCR] = {0x12008, 0}, 1678 [GCC_PRNG_BCR] = {0x13000, 0}, 1679 [GCC_BOOT_ROM_BCR] = {0x13008, 0}, 1680 [GCC_CRYPTO_BCR] = {0x16000, 0}, 1681 [GCC_SDCC1_BCR] = {0x18000, 0}, 1682 [GCC_SEC_CTRL_BCR] = {0x1A000, 0}, 1683 [GCC_AUDIO_BCR] = {0x1B008, 0}, 1684 [GCC_QPIC_BCR] = {0x1C000, 0}, 1685 [GCC_PCIE_BCR] = {0x1D000, 0}, 1686 [GCC_USB2_BCR] = {0x1E008, 0}, 1687 [GCC_USB2_PHY_BCR] = {0x1E018, 0}, 1688 [GCC_USB3_BCR] = {0x1E024, 0}, 1689 [GCC_USB3_PHY_BCR] = {0x1E034, 0}, 1690 [GCC_SYSTEM_NOC_BCR] = {0x21000, 0}, 1691 [GCC_PCNOC_BCR] = {0x2102C, 0}, 1692 [GCC_DCD_BCR] = {0x21038, 0}, 1693 [GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0}, 1694 [GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0}, 1695 [GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0}, 1696 [GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0}, 1697 [GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0}, 1698 [GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0}, 1699 [GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0}, 1700 [GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0}, 1701 [GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0}, 1702 [GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0}, 1703 [GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0}, 1704 [GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0}, 1705 [GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0}, 1706 [GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0}, 1707 [GCC_TCSR_BCR] = {0x22000, 0}, 1708 [GCC_MPM_BCR] = {0x24000, 0}, 1709 [GCC_SPDM_BCR] = {0x25000, 0}, 1710}; 1711 1712static const struct regmap_config gcc_ipq4019_regmap_config = { 1713 .reg_bits = 32, 1714 .reg_stride = 4, 1715 .val_bits = 32, 1716 .max_register = 0x2ffff, 1717 .fast_io = true, 1718}; 1719 1720static const struct qcom_cc_desc gcc_ipq4019_desc = { 1721 .config = &gcc_ipq4019_regmap_config, 1722 .clks = gcc_ipq4019_clocks, 1723 .num_clks = ARRAY_SIZE(gcc_ipq4019_clocks), 1724 .resets = gcc_ipq4019_resets, 1725 .num_resets = ARRAY_SIZE(gcc_ipq4019_resets), 1726}; 1727 1728static const struct of_device_id gcc_ipq4019_match_table[] = { 1729 { .compatible = "qcom,gcc-ipq4019" }, 1730 { } 1731}; 1732MODULE_DEVICE_TABLE(of, gcc_ipq4019_match_table); 1733 1734static int 1735gcc_ipq4019_cpu_clk_notifier_fn(struct notifier_block *nb, 1736 unsigned long action, void *data) 1737{ 1738 int err = 0; 1739 1740 if (action == PRE_RATE_CHANGE) 1741 err = clk_rcg2_ops.set_parent(&apps_clk_src.clkr.hw, 1742 gcc_ipq4019_cpu_safe_parent); 1743 1744 return notifier_from_errno(err); 1745} 1746 1747static struct notifier_block gcc_ipq4019_cpu_clk_notifier = { 1748 .notifier_call = gcc_ipq4019_cpu_clk_notifier_fn, 1749}; 1750 1751static int gcc_ipq4019_probe(struct platform_device *pdev) 1752{ 1753 int err; 1754 1755 err = qcom_cc_probe(pdev, &gcc_ipq4019_desc); 1756 if (err) 1757 return err; 1758 1759 return clk_notifier_register(apps_clk_src.clkr.hw.clk, 1760 &gcc_ipq4019_cpu_clk_notifier); 1761} 1762 1763static int gcc_ipq4019_remove(struct platform_device *pdev) 1764{ 1765 return clk_notifier_unregister(apps_clk_src.clkr.hw.clk, 1766 &gcc_ipq4019_cpu_clk_notifier); 1767} 1768 1769static struct platform_driver gcc_ipq4019_driver = { 1770 .probe = gcc_ipq4019_probe, 1771 .remove = gcc_ipq4019_remove, 1772 .driver = { 1773 .name = "qcom,gcc-ipq4019", 1774 .of_match_table = gcc_ipq4019_match_table, 1775 }, 1776}; 1777 1778static int __init gcc_ipq4019_init(void) 1779{ 1780 return platform_driver_register(&gcc_ipq4019_driver); 1781} 1782core_initcall(gcc_ipq4019_init); 1783 1784static void __exit gcc_ipq4019_exit(void) 1785{ 1786 platform_driver_unregister(&gcc_ipq4019_driver); 1787} 1788module_exit(gcc_ipq4019_exit); 1789 1790MODULE_ALIAS("platform:gcc-ipq4019"); 1791MODULE_LICENSE("GPL v2"); 1792MODULE_DESCRIPTION("QCOM GCC IPQ4019 driver");