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