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 int div_offset; 411 u8 div_shift; 412 u8 div_width; 413 u8 div_flags; 414 struct clk_div_table *div_table; 415 int gate_offset; 416 u8 gate_shift; 417 u8 gate_flags; 418 struct rockchip_clk_branch *child; 419 }; 420 421 #define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\ 422 df, go, gs, gf) \ 423 { \ 424 .id = _id, \ 425 .branch_type = branch_composite, \ 426 .name = cname, \ 427 .parent_names = pnames, \ 428 .num_parents = ARRAY_SIZE(pnames), \ 429 .flags = f, \ 430 .muxdiv_offset = mo, \ 431 .mux_shift = ms, \ 432 .mux_width = mw, \ 433 .mux_flags = mf, \ 434 .div_shift = ds, \ 435 .div_width = dw, \ 436 .div_flags = df, \ 437 .gate_offset = go, \ 438 .gate_shift = gs, \ 439 .gate_flags = gf, \ 440 } 441 442 #define COMPOSITE_DIV_OFFSET(_id, cname, pnames, f, mo, ms, mw, \ 443 mf, do, ds, dw, df, go, gs, gf) \ 444 { \ 445 .id = _id, \ 446 .branch_type = branch_composite, \ 447 .name = cname, \ 448 .parent_names = pnames, \ 449 .num_parents = ARRAY_SIZE(pnames), \ 450 .flags = f, \ 451 .muxdiv_offset = mo, \ 452 .mux_shift = ms, \ 453 .mux_width = mw, \ 454 .mux_flags = mf, \ 455 .div_offset = do, \ 456 .div_shift = ds, \ 457 .div_width = dw, \ 458 .div_flags = df, \ 459 .gate_offset = go, \ 460 .gate_shift = gs, \ 461 .gate_flags = gf, \ 462 } 463 464 #define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df, \ 465 go, gs, gf) \ 466 { \ 467 .id = _id, \ 468 .branch_type = branch_composite, \ 469 .name = cname, \ 470 .parent_names = (const char *[]){ pname }, \ 471 .num_parents = 1, \ 472 .flags = f, \ 473 .muxdiv_offset = mo, \ 474 .div_shift = ds, \ 475 .div_width = dw, \ 476 .div_flags = df, \ 477 .gate_offset = go, \ 478 .gate_shift = gs, \ 479 .gate_flags = gf, \ 480 } 481 482 #define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\ 483 df, dt, go, gs, gf) \ 484 { \ 485 .id = _id, \ 486 .branch_type = branch_composite, \ 487 .name = cname, \ 488 .parent_names = (const char *[]){ pname }, \ 489 .num_parents = 1, \ 490 .flags = f, \ 491 .muxdiv_offset = mo, \ 492 .div_shift = ds, \ 493 .div_width = dw, \ 494 .div_flags = df, \ 495 .div_table = dt, \ 496 .gate_offset = go, \ 497 .gate_shift = gs, \ 498 .gate_flags = gf, \ 499 } 500 501 #define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf, \ 502 go, gs, gf) \ 503 { \ 504 .id = _id, \ 505 .branch_type = branch_composite, \ 506 .name = cname, \ 507 .parent_names = pnames, \ 508 .num_parents = ARRAY_SIZE(pnames), \ 509 .flags = f, \ 510 .muxdiv_offset = mo, \ 511 .mux_shift = ms, \ 512 .mux_width = mw, \ 513 .mux_flags = mf, \ 514 .gate_offset = go, \ 515 .gate_shift = gs, \ 516 .gate_flags = gf, \ 517 } 518 519 #define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \ 520 ds, dw, df) \ 521 { \ 522 .id = _id, \ 523 .branch_type = branch_composite, \ 524 .name = cname, \ 525 .parent_names = pnames, \ 526 .num_parents = ARRAY_SIZE(pnames), \ 527 .flags = f, \ 528 .muxdiv_offset = mo, \ 529 .mux_shift = ms, \ 530 .mux_width = mw, \ 531 .mux_flags = mf, \ 532 .div_shift = ds, \ 533 .div_width = dw, \ 534 .div_flags = df, \ 535 .gate_offset = -1, \ 536 } 537 538 #define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms, \ 539 mw, mf, ds, dw, df, dt) \ 540 { \ 541 .id = _id, \ 542 .branch_type = branch_composite, \ 543 .name = cname, \ 544 .parent_names = pnames, \ 545 .num_parents = ARRAY_SIZE(pnames), \ 546 .flags = f, \ 547 .muxdiv_offset = mo, \ 548 .mux_shift = ms, \ 549 .mux_width = mw, \ 550 .mux_flags = mf, \ 551 .div_shift = ds, \ 552 .div_width = dw, \ 553 .div_flags = df, \ 554 .div_table = dt, \ 555 .gate_offset = -1, \ 556 } 557 558 #define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\ 559 { \ 560 .id = _id, \ 561 .branch_type = branch_fraction_divider, \ 562 .name = cname, \ 563 .parent_names = (const char *[]){ pname }, \ 564 .num_parents = 1, \ 565 .flags = f, \ 566 .muxdiv_offset = mo, \ 567 .div_shift = 16, \ 568 .div_width = 16, \ 569 .div_flags = df, \ 570 .gate_offset = go, \ 571 .gate_shift = gs, \ 572 .gate_flags = gf, \ 573 } 574 575 #define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \ 576 { \ 577 .id = _id, \ 578 .branch_type = branch_fraction_divider, \ 579 .name = cname, \ 580 .parent_names = (const char *[]){ pname }, \ 581 .num_parents = 1, \ 582 .flags = f, \ 583 .muxdiv_offset = mo, \ 584 .div_shift = 16, \ 585 .div_width = 16, \ 586 .div_flags = df, \ 587 .gate_offset = go, \ 588 .gate_shift = gs, \ 589 .gate_flags = gf, \ 590 .child = ch, \ 591 } 592 593 #define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \ 594 { \ 595 .id = _id, \ 596 .branch_type = branch_fraction_divider, \ 597 .name = cname, \ 598 .parent_names = (const char *[]){ pname }, \ 599 .num_parents = 1, \ 600 .flags = f, \ 601 .muxdiv_offset = mo, \ 602 .div_shift = 16, \ 603 .div_width = 16, \ 604 .div_flags = df, \ 605 .gate_offset = -1, \ 606 .child = ch, \ 607 } 608 609 #define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw, \ 610 ds, dw, df) \ 611 { \ 612 .id = _id, \ 613 .branch_type = branch_ddrclk, \ 614 .name = cname, \ 615 .parent_names = pnames, \ 616 .num_parents = ARRAY_SIZE(pnames), \ 617 .flags = f, \ 618 .muxdiv_offset = mo, \ 619 .mux_shift = ms, \ 620 .mux_width = mw, \ 621 .div_shift = ds, \ 622 .div_width = dw, \ 623 .div_flags = df, \ 624 .gate_offset = -1, \ 625 } 626 627 #define MUX(_id, cname, pnames, f, o, s, w, mf) \ 628 { \ 629 .id = _id, \ 630 .branch_type = branch_mux, \ 631 .name = cname, \ 632 .parent_names = pnames, \ 633 .num_parents = ARRAY_SIZE(pnames), \ 634 .flags = f, \ 635 .muxdiv_offset = o, \ 636 .mux_shift = s, \ 637 .mux_width = w, \ 638 .mux_flags = mf, \ 639 .gate_offset = -1, \ 640 } 641 642 #define MUXGRF(_id, cname, pnames, f, o, s, w, mf) \ 643 { \ 644 .id = _id, \ 645 .branch_type = branch_muxgrf, \ 646 .name = cname, \ 647 .parent_names = pnames, \ 648 .num_parents = ARRAY_SIZE(pnames), \ 649 .flags = f, \ 650 .muxdiv_offset = o, \ 651 .mux_shift = s, \ 652 .mux_width = w, \ 653 .mux_flags = mf, \ 654 .gate_offset = -1, \ 655 } 656 657 #define DIV(_id, cname, pname, f, o, s, w, df) \ 658 { \ 659 .id = _id, \ 660 .branch_type = branch_divider, \ 661 .name = cname, \ 662 .parent_names = (const char *[]){ pname }, \ 663 .num_parents = 1, \ 664 .flags = f, \ 665 .muxdiv_offset = o, \ 666 .div_shift = s, \ 667 .div_width = w, \ 668 .div_flags = df, \ 669 .gate_offset = -1, \ 670 } 671 672 #define DIVTBL(_id, cname, pname, f, o, s, w, df, dt) \ 673 { \ 674 .id = _id, \ 675 .branch_type = branch_divider, \ 676 .name = cname, \ 677 .parent_names = (const char *[]){ pname }, \ 678 .num_parents = 1, \ 679 .flags = f, \ 680 .muxdiv_offset = o, \ 681 .div_shift = s, \ 682 .div_width = w, \ 683 .div_flags = df, \ 684 .div_table = dt, \ 685 } 686 687 #define GATE(_id, cname, pname, f, o, b, gf) \ 688 { \ 689 .id = _id, \ 690 .branch_type = branch_gate, \ 691 .name = cname, \ 692 .parent_names = (const char *[]){ pname }, \ 693 .num_parents = 1, \ 694 .flags = f, \ 695 .gate_offset = o, \ 696 .gate_shift = b, \ 697 .gate_flags = gf, \ 698 } 699 700 #define MMC(_id, cname, pname, offset, shift) \ 701 { \ 702 .id = _id, \ 703 .branch_type = branch_mmc, \ 704 .name = cname, \ 705 .parent_names = (const char *[]){ pname }, \ 706 .num_parents = 1, \ 707 .muxdiv_offset = offset, \ 708 .div_shift = shift, \ 709 } 710 711 #define INVERTER(_id, cname, pname, io, is, if) \ 712 { \ 713 .id = _id, \ 714 .branch_type = branch_inverter, \ 715 .name = cname, \ 716 .parent_names = (const char *[]){ pname }, \ 717 .num_parents = 1, \ 718 .muxdiv_offset = io, \ 719 .div_shift = is, \ 720 .div_flags = if, \ 721 } 722 723 #define FACTOR(_id, cname, pname, f, fm, fd) \ 724 { \ 725 .id = _id, \ 726 .branch_type = branch_factor, \ 727 .name = cname, \ 728 .parent_names = (const char *[]){ pname }, \ 729 .num_parents = 1, \ 730 .flags = f, \ 731 .div_shift = fm, \ 732 .div_width = fd, \ 733 } 734 735 #define FACTOR_GATE(_id, cname, pname, f, fm, fd, go, gb, gf) \ 736 { \ 737 .id = _id, \ 738 .branch_type = branch_factor, \ 739 .name = cname, \ 740 .parent_names = (const char *[]){ pname }, \ 741 .num_parents = 1, \ 742 .flags = f, \ 743 .div_shift = fm, \ 744 .div_width = fd, \ 745 .gate_offset = go, \ 746 .gate_shift = gb, \ 747 .gate_flags = gf, \ 748 } 749 750 #define COMPOSITE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\ 751 df, go, gs, gf) \ 752 { \ 753 .id = _id, \ 754 .branch_type = branch_half_divider, \ 755 .name = cname, \ 756 .parent_names = pnames, \ 757 .num_parents = ARRAY_SIZE(pnames), \ 758 .flags = f, \ 759 .muxdiv_offset = mo, \ 760 .mux_shift = ms, \ 761 .mux_width = mw, \ 762 .mux_flags = mf, \ 763 .div_shift = ds, \ 764 .div_width = dw, \ 765 .div_flags = df, \ 766 .gate_offset = go, \ 767 .gate_shift = gs, \ 768 .gate_flags = gf, \ 769 } 770 771 #define COMPOSITE_NOGATE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, \ 772 ds, dw, df) \ 773 { \ 774 .id = _id, \ 775 .branch_type = branch_half_divider, \ 776 .name = cname, \ 777 .parent_names = pnames, \ 778 .num_parents = ARRAY_SIZE(pnames), \ 779 .flags = f, \ 780 .muxdiv_offset = mo, \ 781 .mux_shift = ms, \ 782 .mux_width = mw, \ 783 .mux_flags = mf, \ 784 .div_shift = ds, \ 785 .div_width = dw, \ 786 .div_flags = df, \ 787 .gate_offset = -1, \ 788 } 789 790 #define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df, \ 791 go, gs, gf) \ 792 { \ 793 .id = _id, \ 794 .branch_type = branch_half_divider, \ 795 .name = cname, \ 796 .parent_names = (const char *[]){ pname }, \ 797 .num_parents = 1, \ 798 .flags = f, \ 799 .muxdiv_offset = mo, \ 800 .div_shift = ds, \ 801 .div_width = dw, \ 802 .div_flags = df, \ 803 .gate_offset = go, \ 804 .gate_shift = gs, \ 805 .gate_flags = gf, \ 806 } 807 808 #define DIV_HALF(_id, cname, pname, f, o, s, w, df) \ 809 { \ 810 .id = _id, \ 811 .branch_type = branch_half_divider, \ 812 .name = cname, \ 813 .parent_names = (const char *[]){ pname }, \ 814 .num_parents = 1, \ 815 .flags = f, \ 816 .muxdiv_offset = o, \ 817 .div_shift = s, \ 818 .div_width = w, \ 819 .div_flags = df, \ 820 .gate_offset = -1, \ 821 } 822 823 struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, 824 void __iomem *base, unsigned long nr_clks); 825 void rockchip_clk_of_add_provider(struct device_node *np, 826 struct rockchip_clk_provider *ctx); 827 void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx, 828 struct clk *clk, unsigned int id); 829 void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, 830 struct rockchip_clk_branch *list, 831 unsigned int nr_clk); 832 void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, 833 struct rockchip_pll_clock *pll_list, 834 unsigned int nr_pll, int grf_lock_offset); 835 void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, 836 unsigned int lookup_id, const char *name, 837 const char *const *parent_names, u8 num_parents, 838 const struct rockchip_cpuclk_reg_data *reg_data, 839 const struct rockchip_cpuclk_rate_table *rates, 840 int nrates); 841 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks); 842 void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, 843 unsigned int reg, void (*cb)(void)); 844 845 #define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) 846 847 struct clk *rockchip_clk_register_halfdiv(const char *name, 848 const char *const *parent_names, 849 u8 num_parents, void __iomem *base, 850 int muxdiv_offset, u8 mux_shift, 851 u8 mux_width, u8 mux_flags, 852 u8 div_shift, u8 div_width, 853 u8 div_flags, int gate_offset, 854 u8 gate_shift, u8 gate_flags, 855 unsigned long flags, 856 spinlock_t *lock); 857 858 #ifdef CONFIG_RESET_CONTROLLER 859 void rockchip_register_softrst(struct device_node *np, 860 unsigned int num_regs, 861 void __iomem *base, u8 flags); 862 #else 863 static inline void rockchip_register_softrst(struct device_node *np, 864 unsigned int num_regs, 865 void __iomem *base, u8 flags) 866 { 867 } 868 #endif 869 870 #endif 871