1 /* 2 * Copyright (c) 2014 MundoReader S.L. 3 * Author: Heiko Stuebner <heiko@sntech.de> 4 * 5 * Copyright (c) 2015 Rockchip Electronics Co. Ltd. 6 * Author: Xing Zheng <zhengxing@rock-chips.com> 7 * 8 * based on 9 * 10 * samsung/clk.h 11 * Copyright (c) 2013 Samsung Electronics Co., Ltd. 12 * Copyright (c) 2013 Linaro Ltd. 13 * Author: Thomas Abraham <thomas.ab@samsung.com> 14 * 15 * This program is free software; you can redistribute it and/or modify 16 * it under the terms of the GNU General Public License as published by 17 * the Free Software Foundation; either version 2 of the License, or 18 * (at your option) any later version. 19 * 20 * This program is distributed in the hope that it will be useful, 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 * GNU General Public License for more details. 24 */ 25 26 #ifndef CLK_ROCKCHIP_CLK_H 27 #define CLK_ROCKCHIP_CLK_H 28 29 #include <linux/io.h> 30 #include <linux/clk-provider.h> 31 32 struct clk; 33 34 #define HIWORD_UPDATE(val, mask, shift) \ 35 ((val) << (shift) | (mask) << ((shift) + 16)) 36 37 #define RK2928_PLL_CON(x) ((x) * 0x4) 38 #define RK2928_MODE_CON 0x40 39 #define RK2928_CLKSEL_CON(x) ((x) * 0x4 + 0x44) 40 #define RK2928_CLKGATE_CON(x) ((x) * 0x4 + 0xd0) 41 #define RK2928_GLB_SRST_FST 0x100 42 #define RK2928_GLB_SRST_SND 0x104 43 #define RK2928_SOFTRST_CON(x) ((x) * 0x4 + 0x110) 44 #define RK2928_MISC_CON 0x134 45 46 #define RK3036_SDMMC_CON0 0x144 47 #define RK3036_SDMMC_CON1 0x148 48 #define RK3036_SDIO_CON0 0x14c 49 #define RK3036_SDIO_CON1 0x150 50 #define RK3036_EMMC_CON0 0x154 51 #define RK3036_EMMC_CON1 0x158 52 53 #define RK3228_GLB_SRST_FST 0x1f0 54 #define RK3228_GLB_SRST_SND 0x1f4 55 #define RK3228_SDMMC_CON0 0x1c0 56 #define RK3228_SDMMC_CON1 0x1c4 57 #define RK3228_SDIO_CON0 0x1c8 58 #define RK3228_SDIO_CON1 0x1cc 59 #define RK3228_EMMC_CON0 0x1d8 60 #define RK3228_EMMC_CON1 0x1dc 61 62 #define RK3288_PLL_CON(x) RK2928_PLL_CON(x) 63 #define RK3288_MODE_CON 0x50 64 #define RK3288_CLKSEL_CON(x) ((x) * 0x4 + 0x60) 65 #define RK3288_CLKGATE_CON(x) ((x) * 0x4 + 0x160) 66 #define RK3288_GLB_SRST_FST 0x1b0 67 #define RK3288_GLB_SRST_SND 0x1b4 68 #define RK3288_SOFTRST_CON(x) ((x) * 0x4 + 0x1b8) 69 #define RK3288_MISC_CON 0x1e8 70 #define RK3288_SDMMC_CON0 0x200 71 #define RK3288_SDMMC_CON1 0x204 72 #define RK3288_SDIO0_CON0 0x208 73 #define RK3288_SDIO0_CON1 0x20c 74 #define RK3288_SDIO1_CON0 0x210 75 #define RK3288_SDIO1_CON1 0x214 76 #define RK3288_EMMC_CON0 0x218 77 #define RK3288_EMMC_CON1 0x21c 78 79 #define RK3368_PLL_CON(x) RK2928_PLL_CON(x) 80 #define RK3368_CLKSEL_CON(x) ((x) * 0x4 + 0x100) 81 #define RK3368_CLKGATE_CON(x) ((x) * 0x4 + 0x200) 82 #define RK3368_GLB_SRST_FST 0x280 83 #define RK3368_GLB_SRST_SND 0x284 84 #define RK3368_SOFTRST_CON(x) ((x) * 0x4 + 0x300) 85 #define RK3368_MISC_CON 0x380 86 #define RK3368_SDMMC_CON0 0x400 87 #define RK3368_SDMMC_CON1 0x404 88 #define RK3368_SDIO0_CON0 0x408 89 #define RK3368_SDIO0_CON1 0x40c 90 #define RK3368_SDIO1_CON0 0x410 91 #define RK3368_SDIO1_CON1 0x414 92 #define RK3368_EMMC_CON0 0x418 93 #define RK3368_EMMC_CON1 0x41c 94 95 #define RK3399_PLL_CON(x) RK2928_PLL_CON(x) 96 #define RK3399_CLKSEL_CON(x) ((x) * 0x4 + 0x100) 97 #define RK3399_CLKGATE_CON(x) ((x) * 0x4 + 0x300) 98 #define RK3399_SOFTRST_CON(x) ((x) * 0x4 + 0x400) 99 #define RK3399_GLB_SRST_FST 0x500 100 #define RK3399_GLB_SRST_SND 0x504 101 #define RK3399_GLB_CNT_TH 0x508 102 #define RK3399_MISC_CON 0x50c 103 #define RK3399_RST_CON 0x510 104 #define RK3399_RST_ST 0x514 105 #define RK3399_SDMMC_CON0 0x580 106 #define RK3399_SDMMC_CON1 0x584 107 #define RK3399_SDIO_CON0 0x588 108 #define RK3399_SDIO_CON1 0x58c 109 110 #define RK3399_PMU_PLL_CON(x) RK2928_PLL_CON(x) 111 #define RK3399_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x80) 112 #define RK3399_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x100) 113 #define RK3399_PMU_SOFTRST_CON(x) ((x) * 0x4 + 0x110) 114 115 enum rockchip_pll_type { 116 pll_rk3036, 117 pll_rk3066, 118 pll_rk3399, 119 }; 120 121 #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \ 122 _postdiv2, _dsmpd, _frac) \ 123 { \ 124 .rate = _rate##U, \ 125 .fbdiv = _fbdiv, \ 126 .postdiv1 = _postdiv1, \ 127 .refdiv = _refdiv, \ 128 .postdiv2 = _postdiv2, \ 129 .dsmpd = _dsmpd, \ 130 .frac = _frac, \ 131 } 132 133 #define RK3066_PLL_RATE(_rate, _nr, _nf, _no) \ 134 { \ 135 .rate = _rate##U, \ 136 .nr = _nr, \ 137 .nf = _nf, \ 138 .no = _no, \ 139 .nb = ((_nf) < 2) ? 1 : (_nf) >> 1, \ 140 } 141 142 #define RK3066_PLL_RATE_NB(_rate, _nr, _nf, _no, _nb) \ 143 { \ 144 .rate = _rate##U, \ 145 .nr = _nr, \ 146 .nf = _nf, \ 147 .no = _no, \ 148 .nb = _nb, \ 149 } 150 151 /** 152 * struct rockchip_clk_provider - information about clock provider 153 * @reg_base: virtual address for the register base. 154 * @clk_data: holds clock related data like clk* and number of clocks. 155 * @cru_node: device-node of the clock-provider 156 * @grf: regmap of the general-register-files syscon 157 * @lock: maintains exclusion between callbacks for a given clock-provider. 158 */ 159 struct rockchip_clk_provider { 160 void __iomem *reg_base; 161 struct clk_onecell_data clk_data; 162 struct device_node *cru_node; 163 struct regmap *grf; 164 spinlock_t lock; 165 }; 166 167 struct rockchip_pll_rate_table { 168 unsigned long rate; 169 unsigned int nr; 170 unsigned int nf; 171 unsigned int no; 172 unsigned int nb; 173 /* for RK3036/RK3399 */ 174 unsigned int fbdiv; 175 unsigned int postdiv1; 176 unsigned int refdiv; 177 unsigned int postdiv2; 178 unsigned int dsmpd; 179 unsigned int frac; 180 }; 181 182 /** 183 * struct rockchip_pll_clock - information about pll clock 184 * @id: platform specific id of the clock. 185 * @name: name of this pll clock. 186 * @parent_names: name of the parent clock. 187 * @num_parents: number of parents 188 * @flags: optional flags for basic clock. 189 * @con_offset: offset of the register for configuring the PLL. 190 * @mode_offset: offset of the register for configuring the PLL-mode. 191 * @mode_shift: offset inside the mode-register for the mode of this pll. 192 * @lock_shift: offset inside the lock register for the lock status. 193 * @type: Type of PLL to be registered. 194 * @pll_flags: hardware-specific flags 195 * @rate_table: Table of usable pll rates 196 * 197 * Flags: 198 * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the 199 * rate_table parameters and ajust them if necessary. 200 */ 201 struct rockchip_pll_clock { 202 unsigned int id; 203 const char *name; 204 const char *const *parent_names; 205 u8 num_parents; 206 unsigned long flags; 207 int con_offset; 208 int mode_offset; 209 int mode_shift; 210 int lock_shift; 211 enum rockchip_pll_type type; 212 u8 pll_flags; 213 struct rockchip_pll_rate_table *rate_table; 214 }; 215 216 #define ROCKCHIP_PLL_SYNC_RATE BIT(0) 217 218 #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \ 219 _lshift, _pflags, _rtable) \ 220 { \ 221 .id = _id, \ 222 .type = _type, \ 223 .name = _name, \ 224 .parent_names = _pnames, \ 225 .num_parents = ARRAY_SIZE(_pnames), \ 226 .flags = CLK_GET_RATE_NOCACHE | _flags, \ 227 .con_offset = _con, \ 228 .mode_offset = _mode, \ 229 .mode_shift = _mshift, \ 230 .lock_shift = _lshift, \ 231 .pll_flags = _pflags, \ 232 .rate_table = _rtable, \ 233 } 234 235 struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, 236 enum rockchip_pll_type pll_type, 237 const char *name, const char *const *parent_names, 238 u8 num_parents, int con_offset, int grf_lock_offset, 239 int lock_shift, int mode_offset, int mode_shift, 240 struct rockchip_pll_rate_table *rate_table, 241 unsigned long flags, u8 clk_pll_flags); 242 243 struct rockchip_cpuclk_clksel { 244 int reg; 245 u32 val; 246 }; 247 248 #define ROCKCHIP_CPUCLK_NUM_DIVIDERS 2 249 struct rockchip_cpuclk_rate_table { 250 unsigned long prate; 251 struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS]; 252 }; 253 254 /** 255 * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock 256 * @core_reg: register offset of the core settings register 257 * @div_core_shift: core divider offset used to divide the pll value 258 * @div_core_mask: core divider mask 259 * @mux_core_alt: mux value to select alternate parent 260 * @mux_core_main: mux value to select main parent of core 261 * @mux_core_shift: offset of the core multiplexer 262 * @mux_core_mask: core multiplexer mask 263 */ 264 struct rockchip_cpuclk_reg_data { 265 int core_reg; 266 u8 div_core_shift; 267 u32 div_core_mask; 268 u8 mux_core_alt; 269 u8 mux_core_main; 270 u8 mux_core_shift; 271 u32 mux_core_mask; 272 }; 273 274 struct clk *rockchip_clk_register_cpuclk(const char *name, 275 const char *const *parent_names, u8 num_parents, 276 const struct rockchip_cpuclk_reg_data *reg_data, 277 const struct rockchip_cpuclk_rate_table *rates, 278 int nrates, void __iomem *reg_base, spinlock_t *lock); 279 280 struct clk *rockchip_clk_register_mmc(const char *name, 281 const char *const *parent_names, u8 num_parents, 282 void __iomem *reg, int shift); 283 284 /* 285 * DDRCLK flags, including method of setting the rate 286 * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate. 287 */ 288 #define ROCKCHIP_DDRCLK_SIP BIT(0) 289 290 struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, 291 const char *const *parent_names, 292 u8 num_parents, int mux_offset, 293 int mux_shift, int mux_width, 294 int div_shift, int div_width, 295 int ddr_flags, void __iomem *reg_base, 296 spinlock_t *lock); 297 298 #define ROCKCHIP_INVERTER_HIWORD_MASK BIT(0) 299 300 struct clk *rockchip_clk_register_inverter(const char *name, 301 const char *const *parent_names, u8 num_parents, 302 void __iomem *reg, int shift, int flags, 303 spinlock_t *lock); 304 305 #define PNAME(x) static const char *const x[] __initconst 306 307 enum rockchip_clk_branch_type { 308 branch_composite, 309 branch_mux, 310 branch_divider, 311 branch_fraction_divider, 312 branch_gate, 313 branch_mmc, 314 branch_inverter, 315 branch_factor, 316 branch_ddrclk, 317 }; 318 319 struct rockchip_clk_branch { 320 unsigned int id; 321 enum rockchip_clk_branch_type branch_type; 322 const char *name; 323 const char *const *parent_names; 324 u8 num_parents; 325 unsigned long flags; 326 int muxdiv_offset; 327 u8 mux_shift; 328 u8 mux_width; 329 u8 mux_flags; 330 u8 div_shift; 331 u8 div_width; 332 u8 div_flags; 333 struct clk_div_table *div_table; 334 int gate_offset; 335 u8 gate_shift; 336 u8 gate_flags; 337 struct rockchip_clk_branch *child; 338 }; 339 340 #define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\ 341 df, go, gs, gf) \ 342 { \ 343 .id = _id, \ 344 .branch_type = branch_composite, \ 345 .name = cname, \ 346 .parent_names = pnames, \ 347 .num_parents = ARRAY_SIZE(pnames), \ 348 .flags = f, \ 349 .muxdiv_offset = mo, \ 350 .mux_shift = ms, \ 351 .mux_width = mw, \ 352 .mux_flags = mf, \ 353 .div_shift = ds, \ 354 .div_width = dw, \ 355 .div_flags = df, \ 356 .gate_offset = go, \ 357 .gate_shift = gs, \ 358 .gate_flags = gf, \ 359 } 360 361 #define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df, \ 362 go, gs, gf) \ 363 { \ 364 .id = _id, \ 365 .branch_type = branch_composite, \ 366 .name = cname, \ 367 .parent_names = (const char *[]){ pname }, \ 368 .num_parents = 1, \ 369 .flags = f, \ 370 .muxdiv_offset = mo, \ 371 .div_shift = ds, \ 372 .div_width = dw, \ 373 .div_flags = df, \ 374 .gate_offset = go, \ 375 .gate_shift = gs, \ 376 .gate_flags = gf, \ 377 } 378 379 #define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\ 380 df, dt, go, gs, gf) \ 381 { \ 382 .id = _id, \ 383 .branch_type = branch_composite, \ 384 .name = cname, \ 385 .parent_names = (const char *[]){ pname }, \ 386 .num_parents = 1, \ 387 .flags = f, \ 388 .muxdiv_offset = mo, \ 389 .div_shift = ds, \ 390 .div_width = dw, \ 391 .div_flags = df, \ 392 .div_table = dt, \ 393 .gate_offset = go, \ 394 .gate_shift = gs, \ 395 .gate_flags = gf, \ 396 } 397 398 #define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf, \ 399 go, gs, gf) \ 400 { \ 401 .id = _id, \ 402 .branch_type = branch_composite, \ 403 .name = cname, \ 404 .parent_names = pnames, \ 405 .num_parents = ARRAY_SIZE(pnames), \ 406 .flags = f, \ 407 .muxdiv_offset = mo, \ 408 .mux_shift = ms, \ 409 .mux_width = mw, \ 410 .mux_flags = mf, \ 411 .gate_offset = go, \ 412 .gate_shift = gs, \ 413 .gate_flags = gf, \ 414 } 415 416 #define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \ 417 ds, dw, df) \ 418 { \ 419 .id = _id, \ 420 .branch_type = branch_composite, \ 421 .name = cname, \ 422 .parent_names = pnames, \ 423 .num_parents = ARRAY_SIZE(pnames), \ 424 .flags = f, \ 425 .muxdiv_offset = mo, \ 426 .mux_shift = ms, \ 427 .mux_width = mw, \ 428 .mux_flags = mf, \ 429 .div_shift = ds, \ 430 .div_width = dw, \ 431 .div_flags = df, \ 432 .gate_offset = -1, \ 433 } 434 435 #define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms, \ 436 mw, mf, ds, dw, df, dt) \ 437 { \ 438 .id = _id, \ 439 .branch_type = branch_composite, \ 440 .name = cname, \ 441 .parent_names = pnames, \ 442 .num_parents = ARRAY_SIZE(pnames), \ 443 .flags = f, \ 444 .muxdiv_offset = mo, \ 445 .mux_shift = ms, \ 446 .mux_width = mw, \ 447 .mux_flags = mf, \ 448 .div_shift = ds, \ 449 .div_width = dw, \ 450 .div_flags = df, \ 451 .div_table = dt, \ 452 .gate_offset = -1, \ 453 } 454 455 #define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\ 456 { \ 457 .id = _id, \ 458 .branch_type = branch_fraction_divider, \ 459 .name = cname, \ 460 .parent_names = (const char *[]){ pname }, \ 461 .num_parents = 1, \ 462 .flags = f, \ 463 .muxdiv_offset = mo, \ 464 .div_shift = 16, \ 465 .div_width = 16, \ 466 .div_flags = df, \ 467 .gate_offset = go, \ 468 .gate_shift = gs, \ 469 .gate_flags = gf, \ 470 } 471 472 #define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \ 473 { \ 474 .id = _id, \ 475 .branch_type = branch_fraction_divider, \ 476 .name = cname, \ 477 .parent_names = (const char *[]){ pname }, \ 478 .num_parents = 1, \ 479 .flags = f, \ 480 .muxdiv_offset = mo, \ 481 .div_shift = 16, \ 482 .div_width = 16, \ 483 .div_flags = df, \ 484 .gate_offset = go, \ 485 .gate_shift = gs, \ 486 .gate_flags = gf, \ 487 .child = ch, \ 488 } 489 490 #define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \ 491 { \ 492 .id = _id, \ 493 .branch_type = branch_fraction_divider, \ 494 .name = cname, \ 495 .parent_names = (const char *[]){ pname }, \ 496 .num_parents = 1, \ 497 .flags = f, \ 498 .muxdiv_offset = mo, \ 499 .div_shift = 16, \ 500 .div_width = 16, \ 501 .div_flags = df, \ 502 .gate_offset = -1, \ 503 .child = ch, \ 504 } 505 506 #define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw, \ 507 ds, dw, df) \ 508 { \ 509 .id = _id, \ 510 .branch_type = branch_ddrclk, \ 511 .name = cname, \ 512 .parent_names = pnames, \ 513 .num_parents = ARRAY_SIZE(pnames), \ 514 .flags = f, \ 515 .muxdiv_offset = mo, \ 516 .mux_shift = ms, \ 517 .mux_width = mw, \ 518 .div_shift = ds, \ 519 .div_width = dw, \ 520 .div_flags = df, \ 521 .gate_offset = -1, \ 522 } 523 524 #define MUX(_id, cname, pnames, f, o, s, w, mf) \ 525 { \ 526 .id = _id, \ 527 .branch_type = branch_mux, \ 528 .name = cname, \ 529 .parent_names = pnames, \ 530 .num_parents = ARRAY_SIZE(pnames), \ 531 .flags = f, \ 532 .muxdiv_offset = o, \ 533 .mux_shift = s, \ 534 .mux_width = w, \ 535 .mux_flags = mf, \ 536 .gate_offset = -1, \ 537 } 538 539 #define DIV(_id, cname, pname, f, o, s, w, df) \ 540 { \ 541 .id = _id, \ 542 .branch_type = branch_divider, \ 543 .name = cname, \ 544 .parent_names = (const char *[]){ pname }, \ 545 .num_parents = 1, \ 546 .flags = f, \ 547 .muxdiv_offset = o, \ 548 .div_shift = s, \ 549 .div_width = w, \ 550 .div_flags = df, \ 551 .gate_offset = -1, \ 552 } 553 554 #define DIVTBL(_id, cname, pname, f, o, s, w, df, dt) \ 555 { \ 556 .id = _id, \ 557 .branch_type = branch_divider, \ 558 .name = cname, \ 559 .parent_names = (const char *[]){ pname }, \ 560 .num_parents = 1, \ 561 .flags = f, \ 562 .muxdiv_offset = o, \ 563 .div_shift = s, \ 564 .div_width = w, \ 565 .div_flags = df, \ 566 .div_table = dt, \ 567 } 568 569 #define GATE(_id, cname, pname, f, o, b, gf) \ 570 { \ 571 .id = _id, \ 572 .branch_type = branch_gate, \ 573 .name = cname, \ 574 .parent_names = (const char *[]){ pname }, \ 575 .num_parents = 1, \ 576 .flags = f, \ 577 .gate_offset = o, \ 578 .gate_shift = b, \ 579 .gate_flags = gf, \ 580 } 581 582 #define MMC(_id, cname, pname, offset, shift) \ 583 { \ 584 .id = _id, \ 585 .branch_type = branch_mmc, \ 586 .name = cname, \ 587 .parent_names = (const char *[]){ pname }, \ 588 .num_parents = 1, \ 589 .muxdiv_offset = offset, \ 590 .div_shift = shift, \ 591 } 592 593 #define INVERTER(_id, cname, pname, io, is, if) \ 594 { \ 595 .id = _id, \ 596 .branch_type = branch_inverter, \ 597 .name = cname, \ 598 .parent_names = (const char *[]){ pname }, \ 599 .num_parents = 1, \ 600 .muxdiv_offset = io, \ 601 .div_shift = is, \ 602 .div_flags = if, \ 603 } 604 605 #define FACTOR(_id, cname, pname, f, fm, fd) \ 606 { \ 607 .id = _id, \ 608 .branch_type = branch_factor, \ 609 .name = cname, \ 610 .parent_names = (const char *[]){ pname }, \ 611 .num_parents = 1, \ 612 .flags = f, \ 613 .div_shift = fm, \ 614 .div_width = fd, \ 615 } 616 617 #define FACTOR_GATE(_id, cname, pname, f, fm, fd, go, gb, gf) \ 618 { \ 619 .id = _id, \ 620 .branch_type = branch_factor, \ 621 .name = cname, \ 622 .parent_names = (const char *[]){ pname }, \ 623 .num_parents = 1, \ 624 .flags = f, \ 625 .div_shift = fm, \ 626 .div_width = fd, \ 627 .gate_offset = go, \ 628 .gate_shift = gb, \ 629 .gate_flags = gf, \ 630 } 631 632 struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, 633 void __iomem *base, unsigned long nr_clks); 634 void rockchip_clk_of_add_provider(struct device_node *np, 635 struct rockchip_clk_provider *ctx); 636 void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx, 637 struct clk *clk, unsigned int id); 638 void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, 639 struct rockchip_clk_branch *list, 640 unsigned int nr_clk); 641 void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, 642 struct rockchip_pll_clock *pll_list, 643 unsigned int nr_pll, int grf_lock_offset); 644 void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, 645 unsigned int lookup_id, const char *name, 646 const char *const *parent_names, u8 num_parents, 647 const struct rockchip_cpuclk_reg_data *reg_data, 648 const struct rockchip_cpuclk_rate_table *rates, 649 int nrates); 650 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks); 651 void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, 652 unsigned int reg, void (*cb)(void)); 653 654 #define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) 655 656 #ifdef CONFIG_RESET_CONTROLLER 657 void rockchip_register_softrst(struct device_node *np, 658 unsigned int num_regs, 659 void __iomem *base, u8 flags); 660 #else 661 static inline void rockchip_register_softrst(struct device_node *np, 662 unsigned int num_regs, 663 void __iomem *base, u8 flags) 664 { 665 } 666 #endif 667 668 #endif 669