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 RK3308_PLL_CON(x) RK2928_PLL_CON(x) 125 #define RK3308_CLKSEL_CON(x) ((x) * 0x4 + 0x100) 126 #define RK3308_CLKGATE_CON(x) ((x) * 0x4 + 0x300) 127 #define RK3308_GLB_SRST_FST 0xb8 128 #define RK3308_SOFTRST_CON(x) ((x) * 0x4 + 0x400) 129 #define RK3308_MODE_CON 0xa0 130 #define RK3308_SDMMC_CON0 0x480 131 #define RK3308_SDMMC_CON1 0x484 132 #define RK3308_SDIO_CON0 0x488 133 #define RK3308_SDIO_CON1 0x48c 134 #define RK3308_EMMC_CON0 0x490 135 #define RK3308_EMMC_CON1 0x494 136 137 #define RK3328_PLL_CON(x) RK2928_PLL_CON(x) 138 #define RK3328_CLKSEL_CON(x) ((x) * 0x4 + 0x100) 139 #define RK3328_CLKGATE_CON(x) ((x) * 0x4 + 0x200) 140 #define RK3328_GRFCLKSEL_CON(x) ((x) * 0x4 + 0x100) 141 #define RK3328_GLB_SRST_FST 0x9c 142 #define RK3328_GLB_SRST_SND 0x98 143 #define RK3328_SOFTRST_CON(x) ((x) * 0x4 + 0x300) 144 #define RK3328_MODE_CON 0x80 145 #define RK3328_MISC_CON 0x84 146 #define RK3328_SDMMC_CON0 0x380 147 #define RK3328_SDMMC_CON1 0x384 148 #define RK3328_SDIO_CON0 0x388 149 #define RK3328_SDIO_CON1 0x38c 150 #define RK3328_EMMC_CON0 0x390 151 #define RK3328_EMMC_CON1 0x394 152 #define RK3328_SDMMC_EXT_CON0 0x398 153 #define RK3328_SDMMC_EXT_CON1 0x39C 154 155 #define RK3368_PLL_CON(x) RK2928_PLL_CON(x) 156 #define RK3368_CLKSEL_CON(x) ((x) * 0x4 + 0x100) 157 #define RK3368_CLKGATE_CON(x) ((x) * 0x4 + 0x200) 158 #define RK3368_GLB_SRST_FST 0x280 159 #define RK3368_GLB_SRST_SND 0x284 160 #define RK3368_SOFTRST_CON(x) ((x) * 0x4 + 0x300) 161 #define RK3368_MISC_CON 0x380 162 #define RK3368_SDMMC_CON0 0x400 163 #define RK3368_SDMMC_CON1 0x404 164 #define RK3368_SDIO0_CON0 0x408 165 #define RK3368_SDIO0_CON1 0x40c 166 #define RK3368_SDIO1_CON0 0x410 167 #define RK3368_SDIO1_CON1 0x414 168 #define RK3368_EMMC_CON0 0x418 169 #define RK3368_EMMC_CON1 0x41c 170 171 #define RK3399_PLL_CON(x) RK2928_PLL_CON(x) 172 #define RK3399_CLKSEL_CON(x) ((x) * 0x4 + 0x100) 173 #define RK3399_CLKGATE_CON(x) ((x) * 0x4 + 0x300) 174 #define RK3399_SOFTRST_CON(x) ((x) * 0x4 + 0x400) 175 #define RK3399_GLB_SRST_FST 0x500 176 #define RK3399_GLB_SRST_SND 0x504 177 #define RK3399_GLB_CNT_TH 0x508 178 #define RK3399_MISC_CON 0x50c 179 #define RK3399_RST_CON 0x510 180 #define RK3399_RST_ST 0x514 181 #define RK3399_SDMMC_CON0 0x580 182 #define RK3399_SDMMC_CON1 0x584 183 #define RK3399_SDIO_CON0 0x588 184 #define RK3399_SDIO_CON1 0x58c 185 186 #define RK3399_PMU_PLL_CON(x) RK2928_PLL_CON(x) 187 #define RK3399_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x80) 188 #define RK3399_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x100) 189 #define RK3399_PMU_SOFTRST_CON(x) ((x) * 0x4 + 0x110) 190 191 enum rockchip_pll_type { 192 pll_rk3036, 193 pll_rk3066, 194 pll_rk3328, 195 pll_rk3399, 196 }; 197 198 #define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \ 199 _postdiv2, _dsmpd, _frac) \ 200 { \ 201 .rate = _rate##U, \ 202 .fbdiv = _fbdiv, \ 203 .postdiv1 = _postdiv1, \ 204 .refdiv = _refdiv, \ 205 .postdiv2 = _postdiv2, \ 206 .dsmpd = _dsmpd, \ 207 .frac = _frac, \ 208 } 209 210 #define RK3066_PLL_RATE(_rate, _nr, _nf, _no) \ 211 { \ 212 .rate = _rate##U, \ 213 .nr = _nr, \ 214 .nf = _nf, \ 215 .no = _no, \ 216 .nb = ((_nf) < 2) ? 1 : (_nf) >> 1, \ 217 } 218 219 #define RK3066_PLL_RATE_NB(_rate, _nr, _nf, _no, _nb) \ 220 { \ 221 .rate = _rate##U, \ 222 .nr = _nr, \ 223 .nf = _nf, \ 224 .no = _no, \ 225 .nb = _nb, \ 226 } 227 228 /** 229 * struct rockchip_clk_provider - information about clock provider 230 * @reg_base: virtual address for the register base. 231 * @clk_data: holds clock related data like clk* and number of clocks. 232 * @cru_node: device-node of the clock-provider 233 * @grf: regmap of the general-register-files syscon 234 * @lock: maintains exclusion between callbacks for a given clock-provider. 235 */ 236 struct rockchip_clk_provider { 237 void __iomem *reg_base; 238 struct clk_onecell_data clk_data; 239 struct device_node *cru_node; 240 struct regmap *grf; 241 spinlock_t lock; 242 }; 243 244 struct rockchip_pll_rate_table { 245 unsigned long rate; 246 unsigned int nr; 247 unsigned int nf; 248 unsigned int no; 249 unsigned int nb; 250 /* for RK3036/RK3399 */ 251 unsigned int fbdiv; 252 unsigned int postdiv1; 253 unsigned int refdiv; 254 unsigned int postdiv2; 255 unsigned int dsmpd; 256 unsigned int frac; 257 }; 258 259 /** 260 * struct rockchip_pll_clock - information about pll clock 261 * @id: platform specific id of the clock. 262 * @name: name of this pll clock. 263 * @parent_names: name of the parent clock. 264 * @num_parents: number of parents 265 * @flags: optional flags for basic clock. 266 * @con_offset: offset of the register for configuring the PLL. 267 * @mode_offset: offset of the register for configuring the PLL-mode. 268 * @mode_shift: offset inside the mode-register for the mode of this pll. 269 * @lock_shift: offset inside the lock register for the lock status. 270 * @type: Type of PLL to be registered. 271 * @pll_flags: hardware-specific flags 272 * @rate_table: Table of usable pll rates 273 * 274 * Flags: 275 * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the 276 * rate_table parameters and ajust them if necessary. 277 */ 278 struct rockchip_pll_clock { 279 unsigned int id; 280 const char *name; 281 const char *const *parent_names; 282 u8 num_parents; 283 unsigned long flags; 284 int con_offset; 285 int mode_offset; 286 int mode_shift; 287 int lock_shift; 288 enum rockchip_pll_type type; 289 u8 pll_flags; 290 struct rockchip_pll_rate_table *rate_table; 291 }; 292 293 #define ROCKCHIP_PLL_SYNC_RATE BIT(0) 294 295 #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \ 296 _lshift, _pflags, _rtable) \ 297 { \ 298 .id = _id, \ 299 .type = _type, \ 300 .name = _name, \ 301 .parent_names = _pnames, \ 302 .num_parents = ARRAY_SIZE(_pnames), \ 303 .flags = CLK_GET_RATE_NOCACHE | _flags, \ 304 .con_offset = _con, \ 305 .mode_offset = _mode, \ 306 .mode_shift = _mshift, \ 307 .lock_shift = _lshift, \ 308 .pll_flags = _pflags, \ 309 .rate_table = _rtable, \ 310 } 311 312 struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, 313 enum rockchip_pll_type pll_type, 314 const char *name, const char *const *parent_names, 315 u8 num_parents, int con_offset, int grf_lock_offset, 316 int lock_shift, int mode_offset, int mode_shift, 317 struct rockchip_pll_rate_table *rate_table, 318 unsigned long flags, u8 clk_pll_flags); 319 320 struct rockchip_cpuclk_clksel { 321 int reg; 322 u32 val; 323 }; 324 325 #define ROCKCHIP_CPUCLK_NUM_DIVIDERS 2 326 struct rockchip_cpuclk_rate_table { 327 unsigned long prate; 328 struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS]; 329 }; 330 331 /** 332 * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock 333 * @core_reg: register offset of the core settings register 334 * @div_core_shift: core divider offset used to divide the pll value 335 * @div_core_mask: core divider mask 336 * @mux_core_alt: mux value to select alternate parent 337 * @mux_core_main: mux value to select main parent of core 338 * @mux_core_shift: offset of the core multiplexer 339 * @mux_core_mask: core multiplexer mask 340 */ 341 struct rockchip_cpuclk_reg_data { 342 int core_reg; 343 u8 div_core_shift; 344 u32 div_core_mask; 345 u8 mux_core_alt; 346 u8 mux_core_main; 347 u8 mux_core_shift; 348 u32 mux_core_mask; 349 }; 350 351 struct clk *rockchip_clk_register_cpuclk(const char *name, 352 const char *const *parent_names, u8 num_parents, 353 const struct rockchip_cpuclk_reg_data *reg_data, 354 const struct rockchip_cpuclk_rate_table *rates, 355 int nrates, void __iomem *reg_base, spinlock_t *lock); 356 357 struct clk *rockchip_clk_register_mmc(const char *name, 358 const char *const *parent_names, u8 num_parents, 359 void __iomem *reg, int shift); 360 361 /* 362 * DDRCLK flags, including method of setting the rate 363 * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate. 364 */ 365 #define ROCKCHIP_DDRCLK_SIP BIT(0) 366 367 struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, 368 const char *const *parent_names, 369 u8 num_parents, int mux_offset, 370 int mux_shift, int mux_width, 371 int div_shift, int div_width, 372 int ddr_flags, void __iomem *reg_base, 373 spinlock_t *lock); 374 375 #define ROCKCHIP_INVERTER_HIWORD_MASK BIT(0) 376 377 struct clk *rockchip_clk_register_inverter(const char *name, 378 const char *const *parent_names, u8 num_parents, 379 void __iomem *reg, int shift, int flags, 380 spinlock_t *lock); 381 382 struct clk *rockchip_clk_register_muxgrf(const char *name, 383 const char *const *parent_names, u8 num_parents, 384 int flags, struct regmap *grf, int reg, 385 int shift, int width, int mux_flags); 386 387 #define PNAME(x) static const char *const x[] __initconst 388 389 enum rockchip_clk_branch_type { 390 branch_composite, 391 branch_mux, 392 branch_muxgrf, 393 branch_divider, 394 branch_fraction_divider, 395 branch_gate, 396 branch_mmc, 397 branch_inverter, 398 branch_factor, 399 branch_ddrclk, 400 branch_half_divider, 401 }; 402 403 struct rockchip_clk_branch { 404 unsigned int id; 405 enum rockchip_clk_branch_type branch_type; 406 const char *name; 407 const char *const *parent_names; 408 u8 num_parents; 409 unsigned long flags; 410 int muxdiv_offset; 411 u8 mux_shift; 412 u8 mux_width; 413 u8 mux_flags; 414 int div_offset; 415 u8 div_shift; 416 u8 div_width; 417 u8 div_flags; 418 struct clk_div_table *div_table; 419 int gate_offset; 420 u8 gate_shift; 421 u8 gate_flags; 422 struct rockchip_clk_branch *child; 423 }; 424 425 #define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\ 426 df, go, gs, gf) \ 427 { \ 428 .id = _id, \ 429 .branch_type = branch_composite, \ 430 .name = cname, \ 431 .parent_names = pnames, \ 432 .num_parents = ARRAY_SIZE(pnames), \ 433 .flags = f, \ 434 .muxdiv_offset = mo, \ 435 .mux_shift = ms, \ 436 .mux_width = mw, \ 437 .mux_flags = mf, \ 438 .div_shift = ds, \ 439 .div_width = dw, \ 440 .div_flags = df, \ 441 .gate_offset = go, \ 442 .gate_shift = gs, \ 443 .gate_flags = gf, \ 444 } 445 446 #define COMPOSITE_DIV_OFFSET(_id, cname, pnames, f, mo, ms, mw, \ 447 mf, do, ds, dw, df, go, gs, gf) \ 448 { \ 449 .id = _id, \ 450 .branch_type = branch_composite, \ 451 .name = cname, \ 452 .parent_names = pnames, \ 453 .num_parents = ARRAY_SIZE(pnames), \ 454 .flags = f, \ 455 .muxdiv_offset = mo, \ 456 .mux_shift = ms, \ 457 .mux_width = mw, \ 458 .mux_flags = mf, \ 459 .div_offset = do, \ 460 .div_shift = ds, \ 461 .div_width = dw, \ 462 .div_flags = df, \ 463 .gate_offset = go, \ 464 .gate_shift = gs, \ 465 .gate_flags = gf, \ 466 } 467 468 #define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df, \ 469 go, gs, gf) \ 470 { \ 471 .id = _id, \ 472 .branch_type = branch_composite, \ 473 .name = cname, \ 474 .parent_names = (const char *[]){ pname }, \ 475 .num_parents = 1, \ 476 .flags = f, \ 477 .muxdiv_offset = mo, \ 478 .div_shift = ds, \ 479 .div_width = dw, \ 480 .div_flags = df, \ 481 .gate_offset = go, \ 482 .gate_shift = gs, \ 483 .gate_flags = gf, \ 484 } 485 486 #define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\ 487 df, dt, go, gs, gf) \ 488 { \ 489 .id = _id, \ 490 .branch_type = branch_composite, \ 491 .name = cname, \ 492 .parent_names = (const char *[]){ pname }, \ 493 .num_parents = 1, \ 494 .flags = f, \ 495 .muxdiv_offset = mo, \ 496 .div_shift = ds, \ 497 .div_width = dw, \ 498 .div_flags = df, \ 499 .div_table = dt, \ 500 .gate_offset = go, \ 501 .gate_shift = gs, \ 502 .gate_flags = gf, \ 503 } 504 505 #define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf, \ 506 go, gs, gf) \ 507 { \ 508 .id = _id, \ 509 .branch_type = branch_composite, \ 510 .name = cname, \ 511 .parent_names = pnames, \ 512 .num_parents = ARRAY_SIZE(pnames), \ 513 .flags = f, \ 514 .muxdiv_offset = mo, \ 515 .mux_shift = ms, \ 516 .mux_width = mw, \ 517 .mux_flags = mf, \ 518 .gate_offset = go, \ 519 .gate_shift = gs, \ 520 .gate_flags = gf, \ 521 } 522 523 #define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \ 524 ds, dw, df) \ 525 { \ 526 .id = _id, \ 527 .branch_type = branch_composite, \ 528 .name = cname, \ 529 .parent_names = pnames, \ 530 .num_parents = ARRAY_SIZE(pnames), \ 531 .flags = f, \ 532 .muxdiv_offset = mo, \ 533 .mux_shift = ms, \ 534 .mux_width = mw, \ 535 .mux_flags = mf, \ 536 .div_shift = ds, \ 537 .div_width = dw, \ 538 .div_flags = df, \ 539 .gate_offset = -1, \ 540 } 541 542 #define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms, \ 543 mw, mf, ds, dw, df, dt) \ 544 { \ 545 .id = _id, \ 546 .branch_type = branch_composite, \ 547 .name = cname, \ 548 .parent_names = pnames, \ 549 .num_parents = ARRAY_SIZE(pnames), \ 550 .flags = f, \ 551 .muxdiv_offset = mo, \ 552 .mux_shift = ms, \ 553 .mux_width = mw, \ 554 .mux_flags = mf, \ 555 .div_shift = ds, \ 556 .div_width = dw, \ 557 .div_flags = df, \ 558 .div_table = dt, \ 559 .gate_offset = -1, \ 560 } 561 562 #define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\ 563 { \ 564 .id = _id, \ 565 .branch_type = branch_fraction_divider, \ 566 .name = cname, \ 567 .parent_names = (const char *[]){ pname }, \ 568 .num_parents = 1, \ 569 .flags = f, \ 570 .muxdiv_offset = mo, \ 571 .div_shift = 16, \ 572 .div_width = 16, \ 573 .div_flags = df, \ 574 .gate_offset = go, \ 575 .gate_shift = gs, \ 576 .gate_flags = gf, \ 577 } 578 579 #define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \ 580 { \ 581 .id = _id, \ 582 .branch_type = branch_fraction_divider, \ 583 .name = cname, \ 584 .parent_names = (const char *[]){ pname }, \ 585 .num_parents = 1, \ 586 .flags = f, \ 587 .muxdiv_offset = mo, \ 588 .div_shift = 16, \ 589 .div_width = 16, \ 590 .div_flags = df, \ 591 .gate_offset = go, \ 592 .gate_shift = gs, \ 593 .gate_flags = gf, \ 594 .child = ch, \ 595 } 596 597 #define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \ 598 { \ 599 .id = _id, \ 600 .branch_type = branch_fraction_divider, \ 601 .name = cname, \ 602 .parent_names = (const char *[]){ pname }, \ 603 .num_parents = 1, \ 604 .flags = f, \ 605 .muxdiv_offset = mo, \ 606 .div_shift = 16, \ 607 .div_width = 16, \ 608 .div_flags = df, \ 609 .gate_offset = -1, \ 610 .child = ch, \ 611 } 612 613 #define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw, \ 614 ds, dw, df) \ 615 { \ 616 .id = _id, \ 617 .branch_type = branch_ddrclk, \ 618 .name = cname, \ 619 .parent_names = pnames, \ 620 .num_parents = ARRAY_SIZE(pnames), \ 621 .flags = f, \ 622 .muxdiv_offset = mo, \ 623 .mux_shift = ms, \ 624 .mux_width = mw, \ 625 .div_shift = ds, \ 626 .div_width = dw, \ 627 .div_flags = df, \ 628 .gate_offset = -1, \ 629 } 630 631 #define MUX(_id, cname, pnames, f, o, s, w, mf) \ 632 { \ 633 .id = _id, \ 634 .branch_type = branch_mux, \ 635 .name = cname, \ 636 .parent_names = pnames, \ 637 .num_parents = ARRAY_SIZE(pnames), \ 638 .flags = f, \ 639 .muxdiv_offset = o, \ 640 .mux_shift = s, \ 641 .mux_width = w, \ 642 .mux_flags = mf, \ 643 .gate_offset = -1, \ 644 } 645 646 #define MUXGRF(_id, cname, pnames, f, o, s, w, mf) \ 647 { \ 648 .id = _id, \ 649 .branch_type = branch_muxgrf, \ 650 .name = cname, \ 651 .parent_names = pnames, \ 652 .num_parents = ARRAY_SIZE(pnames), \ 653 .flags = f, \ 654 .muxdiv_offset = o, \ 655 .mux_shift = s, \ 656 .mux_width = w, \ 657 .mux_flags = mf, \ 658 .gate_offset = -1, \ 659 } 660 661 #define DIV(_id, cname, pname, f, o, s, w, df) \ 662 { \ 663 .id = _id, \ 664 .branch_type = branch_divider, \ 665 .name = cname, \ 666 .parent_names = (const char *[]){ pname }, \ 667 .num_parents = 1, \ 668 .flags = f, \ 669 .muxdiv_offset = o, \ 670 .div_shift = s, \ 671 .div_width = w, \ 672 .div_flags = df, \ 673 .gate_offset = -1, \ 674 } 675 676 #define DIVTBL(_id, cname, pname, f, o, s, w, df, dt) \ 677 { \ 678 .id = _id, \ 679 .branch_type = branch_divider, \ 680 .name = cname, \ 681 .parent_names = (const char *[]){ pname }, \ 682 .num_parents = 1, \ 683 .flags = f, \ 684 .muxdiv_offset = o, \ 685 .div_shift = s, \ 686 .div_width = w, \ 687 .div_flags = df, \ 688 .div_table = dt, \ 689 } 690 691 #define GATE(_id, cname, pname, f, o, b, gf) \ 692 { \ 693 .id = _id, \ 694 .branch_type = branch_gate, \ 695 .name = cname, \ 696 .parent_names = (const char *[]){ pname }, \ 697 .num_parents = 1, \ 698 .flags = f, \ 699 .gate_offset = o, \ 700 .gate_shift = b, \ 701 .gate_flags = gf, \ 702 } 703 704 #define MMC(_id, cname, pname, offset, shift) \ 705 { \ 706 .id = _id, \ 707 .branch_type = branch_mmc, \ 708 .name = cname, \ 709 .parent_names = (const char *[]){ pname }, \ 710 .num_parents = 1, \ 711 .muxdiv_offset = offset, \ 712 .div_shift = shift, \ 713 } 714 715 #define INVERTER(_id, cname, pname, io, is, if) \ 716 { \ 717 .id = _id, \ 718 .branch_type = branch_inverter, \ 719 .name = cname, \ 720 .parent_names = (const char *[]){ pname }, \ 721 .num_parents = 1, \ 722 .muxdiv_offset = io, \ 723 .div_shift = is, \ 724 .div_flags = if, \ 725 } 726 727 #define FACTOR(_id, cname, pname, f, fm, fd) \ 728 { \ 729 .id = _id, \ 730 .branch_type = branch_factor, \ 731 .name = cname, \ 732 .parent_names = (const char *[]){ pname }, \ 733 .num_parents = 1, \ 734 .flags = f, \ 735 .div_shift = fm, \ 736 .div_width = fd, \ 737 } 738 739 #define FACTOR_GATE(_id, cname, pname, f, fm, fd, go, gb, gf) \ 740 { \ 741 .id = _id, \ 742 .branch_type = branch_factor, \ 743 .name = cname, \ 744 .parent_names = (const char *[]){ pname }, \ 745 .num_parents = 1, \ 746 .flags = f, \ 747 .div_shift = fm, \ 748 .div_width = fd, \ 749 .gate_offset = go, \ 750 .gate_shift = gb, \ 751 .gate_flags = gf, \ 752 } 753 754 #define COMPOSITE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\ 755 df, go, gs, gf) \ 756 { \ 757 .id = _id, \ 758 .branch_type = branch_half_divider, \ 759 .name = cname, \ 760 .parent_names = pnames, \ 761 .num_parents = ARRAY_SIZE(pnames), \ 762 .flags = f, \ 763 .muxdiv_offset = mo, \ 764 .mux_shift = ms, \ 765 .mux_width = mw, \ 766 .mux_flags = mf, \ 767 .div_shift = ds, \ 768 .div_width = dw, \ 769 .div_flags = df, \ 770 .gate_offset = go, \ 771 .gate_shift = gs, \ 772 .gate_flags = gf, \ 773 } 774 775 #define COMPOSITE_NOGATE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, \ 776 ds, dw, df) \ 777 { \ 778 .id = _id, \ 779 .branch_type = branch_half_divider, \ 780 .name = cname, \ 781 .parent_names = pnames, \ 782 .num_parents = ARRAY_SIZE(pnames), \ 783 .flags = f, \ 784 .muxdiv_offset = mo, \ 785 .mux_shift = ms, \ 786 .mux_width = mw, \ 787 .mux_flags = mf, \ 788 .div_shift = ds, \ 789 .div_width = dw, \ 790 .div_flags = df, \ 791 .gate_offset = -1, \ 792 } 793 794 #define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df, \ 795 go, gs, gf) \ 796 { \ 797 .id = _id, \ 798 .branch_type = branch_half_divider, \ 799 .name = cname, \ 800 .parent_names = (const char *[]){ pname }, \ 801 .num_parents = 1, \ 802 .flags = f, \ 803 .muxdiv_offset = mo, \ 804 .div_shift = ds, \ 805 .div_width = dw, \ 806 .div_flags = df, \ 807 .gate_offset = go, \ 808 .gate_shift = gs, \ 809 .gate_flags = gf, \ 810 } 811 812 #define DIV_HALF(_id, cname, pname, f, o, s, w, df) \ 813 { \ 814 .id = _id, \ 815 .branch_type = branch_half_divider, \ 816 .name = cname, \ 817 .parent_names = (const char *[]){ pname }, \ 818 .num_parents = 1, \ 819 .flags = f, \ 820 .muxdiv_offset = o, \ 821 .div_shift = s, \ 822 .div_width = w, \ 823 .div_flags = df, \ 824 .gate_offset = -1, \ 825 } 826 827 /* SGRF clocks are only accessible from secure mode, so not controllable */ 828 #define SGRF_GATE(_id, cname, pname) \ 829 FACTOR(_id, cname, pname, 0, 1, 1) 830 831 struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, 832 void __iomem *base, unsigned long nr_clks); 833 void rockchip_clk_of_add_provider(struct device_node *np, 834 struct rockchip_clk_provider *ctx); 835 void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx, 836 struct clk *clk, unsigned int id); 837 void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, 838 struct rockchip_clk_branch *list, 839 unsigned int nr_clk); 840 void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, 841 struct rockchip_pll_clock *pll_list, 842 unsigned int nr_pll, int grf_lock_offset); 843 void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, 844 unsigned int lookup_id, const char *name, 845 const char *const *parent_names, u8 num_parents, 846 const struct rockchip_cpuclk_reg_data *reg_data, 847 const struct rockchip_cpuclk_rate_table *rates, 848 int nrates); 849 void rockchip_clk_protect_critical(const char *const clocks[], int nclocks); 850 void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, 851 unsigned int reg, void (*cb)(void)); 852 853 #define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) 854 855 struct clk *rockchip_clk_register_halfdiv(const char *name, 856 const char *const *parent_names, 857 u8 num_parents, void __iomem *base, 858 int muxdiv_offset, u8 mux_shift, 859 u8 mux_width, u8 mux_flags, 860 u8 div_shift, u8 div_width, 861 u8 div_flags, int gate_offset, 862 u8 gate_shift, u8 gate_flags, 863 unsigned long flags, 864 spinlock_t *lock); 865 866 #ifdef CONFIG_RESET_CONTROLLER 867 void rockchip_register_softrst(struct device_node *np, 868 unsigned int num_regs, 869 void __iomem *base, u8 flags); 870 #else 871 static inline void rockchip_register_softrst(struct device_node *np, 872 unsigned int num_regs, 873 void __iomem *base, u8 flags) 874 { 875 } 876 #endif 877 878 #endif 879