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