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