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