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