clk.h (26105B)
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 23struct 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#define RK3568_PLL_CON(x) RK2928_PLL_CON(x) 192#define RK3568_MODE_CON0 0xc0 193#define RK3568_MISC_CON0 0xc4 194#define RK3568_MISC_CON1 0xc8 195#define RK3568_MISC_CON2 0xcc 196#define RK3568_GLB_CNT_TH 0xd0 197#define RK3568_GLB_SRST_FST 0xd4 198#define RK3568_GLB_SRST_SND 0xd8 199#define RK3568_GLB_RST_CON 0xdc 200#define RK3568_GLB_RST_ST 0xe0 201#define RK3568_CLKSEL_CON(x) ((x) * 0x4 + 0x100) 202#define RK3568_CLKGATE_CON(x) ((x) * 0x4 + 0x300) 203#define RK3568_SOFTRST_CON(x) ((x) * 0x4 + 0x400) 204#define RK3568_SDMMC0_CON0 0x580 205#define RK3568_SDMMC0_CON1 0x584 206#define RK3568_SDMMC1_CON0 0x588 207#define RK3568_SDMMC1_CON1 0x58c 208#define RK3568_SDMMC2_CON0 0x590 209#define RK3568_SDMMC2_CON1 0x594 210#define RK3568_EMMC_CON0 0x598 211#define RK3568_EMMC_CON1 0x59c 212 213#define RK3568_PMU_PLL_CON(x) RK2928_PLL_CON(x) 214#define RK3568_PMU_MODE_CON0 0x80 215#define RK3568_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x100) 216#define RK3568_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x180) 217#define RK3568_PMU_SOFTRST_CON(x) ((x) * 0x4 + 0x200) 218 219enum rockchip_pll_type { 220 pll_rk3036, 221 pll_rk3066, 222 pll_rk3328, 223 pll_rk3399, 224}; 225 226#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, \ 227 _postdiv2, _dsmpd, _frac) \ 228{ \ 229 .rate = _rate##U, \ 230 .fbdiv = _fbdiv, \ 231 .postdiv1 = _postdiv1, \ 232 .refdiv = _refdiv, \ 233 .postdiv2 = _postdiv2, \ 234 .dsmpd = _dsmpd, \ 235 .frac = _frac, \ 236} 237 238#define RK3066_PLL_RATE(_rate, _nr, _nf, _no) \ 239{ \ 240 .rate = _rate##U, \ 241 .nr = _nr, \ 242 .nf = _nf, \ 243 .no = _no, \ 244 .nb = ((_nf) < 2) ? 1 : (_nf) >> 1, \ 245} 246 247#define RK3066_PLL_RATE_NB(_rate, _nr, _nf, _no, _nb) \ 248{ \ 249 .rate = _rate##U, \ 250 .nr = _nr, \ 251 .nf = _nf, \ 252 .no = _no, \ 253 .nb = _nb, \ 254} 255 256/** 257 * struct rockchip_clk_provider - information about clock provider 258 * @reg_base: virtual address for the register base. 259 * @clk_data: holds clock related data like clk* and number of clocks. 260 * @cru_node: device-node of the clock-provider 261 * @grf: regmap of the general-register-files syscon 262 * @lock: maintains exclusion between callbacks for a given clock-provider. 263 */ 264struct rockchip_clk_provider { 265 void __iomem *reg_base; 266 struct clk_onecell_data clk_data; 267 struct device_node *cru_node; 268 struct regmap *grf; 269 spinlock_t lock; 270}; 271 272struct rockchip_pll_rate_table { 273 unsigned long rate; 274 union { 275 struct { 276 /* for RK3066 */ 277 unsigned int nr; 278 unsigned int nf; 279 unsigned int no; 280 unsigned int nb; 281 }; 282 struct { 283 /* for RK3036/RK3399 */ 284 unsigned int fbdiv; 285 unsigned int postdiv1; 286 unsigned int refdiv; 287 unsigned int postdiv2; 288 unsigned int dsmpd; 289 unsigned int frac; 290 }; 291 }; 292}; 293 294/** 295 * struct rockchip_pll_clock - information about pll clock 296 * @id: platform specific id of the clock. 297 * @name: name of this pll clock. 298 * @parent_names: name of the parent clock. 299 * @num_parents: number of parents 300 * @flags: optional flags for basic clock. 301 * @con_offset: offset of the register for configuring the PLL. 302 * @mode_offset: offset of the register for configuring the PLL-mode. 303 * @mode_shift: offset inside the mode-register for the mode of this pll. 304 * @lock_shift: offset inside the lock register for the lock status. 305 * @type: Type of PLL to be registered. 306 * @pll_flags: hardware-specific flags 307 * @rate_table: Table of usable pll rates 308 * 309 * Flags: 310 * ROCKCHIP_PLL_SYNC_RATE - check rate parameters to match against the 311 * rate_table parameters and ajust them if necessary. 312 */ 313struct rockchip_pll_clock { 314 unsigned int id; 315 const char *name; 316 const char *const *parent_names; 317 u8 num_parents; 318 unsigned long flags; 319 int con_offset; 320 int mode_offset; 321 int mode_shift; 322 int lock_shift; 323 enum rockchip_pll_type type; 324 u8 pll_flags; 325 struct rockchip_pll_rate_table *rate_table; 326}; 327 328#define ROCKCHIP_PLL_SYNC_RATE BIT(0) 329 330#define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \ 331 _lshift, _pflags, _rtable) \ 332 { \ 333 .id = _id, \ 334 .type = _type, \ 335 .name = _name, \ 336 .parent_names = _pnames, \ 337 .num_parents = ARRAY_SIZE(_pnames), \ 338 .flags = CLK_GET_RATE_NOCACHE | _flags, \ 339 .con_offset = _con, \ 340 .mode_offset = _mode, \ 341 .mode_shift = _mshift, \ 342 .lock_shift = _lshift, \ 343 .pll_flags = _pflags, \ 344 .rate_table = _rtable, \ 345 } 346 347struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, 348 enum rockchip_pll_type pll_type, 349 const char *name, const char *const *parent_names, 350 u8 num_parents, int con_offset, int grf_lock_offset, 351 int lock_shift, int mode_offset, int mode_shift, 352 struct rockchip_pll_rate_table *rate_table, 353 unsigned long flags, u8 clk_pll_flags); 354 355struct rockchip_cpuclk_clksel { 356 int reg; 357 u32 val; 358}; 359 360#define ROCKCHIP_CPUCLK_NUM_DIVIDERS 5 361#define ROCKCHIP_CPUCLK_MAX_CORES 4 362struct rockchip_cpuclk_rate_table { 363 unsigned long prate; 364 struct rockchip_cpuclk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS]; 365}; 366 367/** 368 * struct rockchip_cpuclk_reg_data - register offsets and masks of the cpuclock 369 * @core_reg[]: register offset of the cores setting register 370 * @div_core_shift[]: cores divider offset used to divide the pll value 371 * @div_core_mask[]: cores divider mask 372 * @num_cores: number of cpu cores 373 * @mux_core_main: mux value to select main parent of core 374 * @mux_core_shift: offset of the core multiplexer 375 * @mux_core_mask: core multiplexer mask 376 */ 377struct rockchip_cpuclk_reg_data { 378 int core_reg[ROCKCHIP_CPUCLK_MAX_CORES]; 379 u8 div_core_shift[ROCKCHIP_CPUCLK_MAX_CORES]; 380 u32 div_core_mask[ROCKCHIP_CPUCLK_MAX_CORES]; 381 int num_cores; 382 u8 mux_core_alt; 383 u8 mux_core_main; 384 u8 mux_core_shift; 385 u32 mux_core_mask; 386}; 387 388struct clk *rockchip_clk_register_cpuclk(const char *name, 389 const char *const *parent_names, u8 num_parents, 390 const struct rockchip_cpuclk_reg_data *reg_data, 391 const struct rockchip_cpuclk_rate_table *rates, 392 int nrates, void __iomem *reg_base, spinlock_t *lock); 393 394struct clk *rockchip_clk_register_mmc(const char *name, 395 const char *const *parent_names, u8 num_parents, 396 void __iomem *reg, int shift); 397 398/* 399 * DDRCLK flags, including method of setting the rate 400 * ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate. 401 */ 402#define ROCKCHIP_DDRCLK_SIP BIT(0) 403 404struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, 405 const char *const *parent_names, 406 u8 num_parents, int mux_offset, 407 int mux_shift, int mux_width, 408 int div_shift, int div_width, 409 int ddr_flags, void __iomem *reg_base, 410 spinlock_t *lock); 411 412#define ROCKCHIP_INVERTER_HIWORD_MASK BIT(0) 413 414struct clk *rockchip_clk_register_inverter(const char *name, 415 const char *const *parent_names, u8 num_parents, 416 void __iomem *reg, int shift, int flags, 417 spinlock_t *lock); 418 419struct clk *rockchip_clk_register_muxgrf(const char *name, 420 const char *const *parent_names, u8 num_parents, 421 int flags, struct regmap *grf, int reg, 422 int shift, int width, int mux_flags); 423 424#define PNAME(x) static const char *const x[] __initconst 425 426enum rockchip_clk_branch_type { 427 branch_composite, 428 branch_mux, 429 branch_muxgrf, 430 branch_divider, 431 branch_fraction_divider, 432 branch_gate, 433 branch_mmc, 434 branch_inverter, 435 branch_factor, 436 branch_ddrclk, 437 branch_half_divider, 438}; 439 440struct rockchip_clk_branch { 441 unsigned int id; 442 enum rockchip_clk_branch_type branch_type; 443 const char *name; 444 const char *const *parent_names; 445 u8 num_parents; 446 unsigned long flags; 447 int muxdiv_offset; 448 u8 mux_shift; 449 u8 mux_width; 450 u8 mux_flags; 451 int div_offset; 452 u8 div_shift; 453 u8 div_width; 454 u8 div_flags; 455 struct clk_div_table *div_table; 456 int gate_offset; 457 u8 gate_shift; 458 u8 gate_flags; 459 struct rockchip_clk_branch *child; 460}; 461 462#define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\ 463 df, go, gs, gf) \ 464 { \ 465 .id = _id, \ 466 .branch_type = branch_composite, \ 467 .name = cname, \ 468 .parent_names = pnames, \ 469 .num_parents = ARRAY_SIZE(pnames), \ 470 .flags = f, \ 471 .muxdiv_offset = mo, \ 472 .mux_shift = ms, \ 473 .mux_width = mw, \ 474 .mux_flags = mf, \ 475 .div_shift = ds, \ 476 .div_width = dw, \ 477 .div_flags = df, \ 478 .gate_offset = go, \ 479 .gate_shift = gs, \ 480 .gate_flags = gf, \ 481 } 482 483#define COMPOSITE_DIV_OFFSET(_id, cname, pnames, f, mo, ms, mw, \ 484 mf, do, ds, dw, df, go, gs, gf) \ 485 { \ 486 .id = _id, \ 487 .branch_type = branch_composite, \ 488 .name = cname, \ 489 .parent_names = pnames, \ 490 .num_parents = ARRAY_SIZE(pnames), \ 491 .flags = f, \ 492 .muxdiv_offset = mo, \ 493 .mux_shift = ms, \ 494 .mux_width = mw, \ 495 .mux_flags = mf, \ 496 .div_offset = do, \ 497 .div_shift = ds, \ 498 .div_width = dw, \ 499 .div_flags = df, \ 500 .gate_offset = go, \ 501 .gate_shift = gs, \ 502 .gate_flags = gf, \ 503 } 504 505#define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df, \ 506 go, gs, gf) \ 507 { \ 508 .id = _id, \ 509 .branch_type = branch_composite, \ 510 .name = cname, \ 511 .parent_names = (const char *[]){ pname }, \ 512 .num_parents = 1, \ 513 .flags = f, \ 514 .muxdiv_offset = mo, \ 515 .div_shift = ds, \ 516 .div_width = dw, \ 517 .div_flags = df, \ 518 .gate_offset = go, \ 519 .gate_shift = gs, \ 520 .gate_flags = gf, \ 521 } 522 523#define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\ 524 df, dt, go, gs, gf) \ 525 { \ 526 .id = _id, \ 527 .branch_type = branch_composite, \ 528 .name = cname, \ 529 .parent_names = (const char *[]){ pname }, \ 530 .num_parents = 1, \ 531 .flags = f, \ 532 .muxdiv_offset = mo, \ 533 .div_shift = ds, \ 534 .div_width = dw, \ 535 .div_flags = df, \ 536 .div_table = dt, \ 537 .gate_offset = go, \ 538 .gate_shift = gs, \ 539 .gate_flags = gf, \ 540 } 541 542#define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf, \ 543 go, gs, gf) \ 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 .gate_offset = go, \ 556 .gate_shift = gs, \ 557 .gate_flags = gf, \ 558 } 559 560#define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \ 561 ds, dw, df) \ 562 { \ 563 .id = _id, \ 564 .branch_type = branch_composite, \ 565 .name = cname, \ 566 .parent_names = pnames, \ 567 .num_parents = ARRAY_SIZE(pnames), \ 568 .flags = f, \ 569 .muxdiv_offset = mo, \ 570 .mux_shift = ms, \ 571 .mux_width = mw, \ 572 .mux_flags = mf, \ 573 .div_shift = ds, \ 574 .div_width = dw, \ 575 .div_flags = df, \ 576 .gate_offset = -1, \ 577 } 578 579#define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms, \ 580 mw, mf, ds, dw, df, dt) \ 581 { \ 582 .id = _id, \ 583 .branch_type = branch_composite, \ 584 .name = cname, \ 585 .parent_names = pnames, \ 586 .num_parents = ARRAY_SIZE(pnames), \ 587 .flags = f, \ 588 .muxdiv_offset = mo, \ 589 .mux_shift = ms, \ 590 .mux_width = mw, \ 591 .mux_flags = mf, \ 592 .div_shift = ds, \ 593 .div_width = dw, \ 594 .div_flags = df, \ 595 .div_table = dt, \ 596 .gate_offset = -1, \ 597 } 598 599#define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\ 600 { \ 601 .id = _id, \ 602 .branch_type = branch_fraction_divider, \ 603 .name = cname, \ 604 .parent_names = (const char *[]){ pname }, \ 605 .num_parents = 1, \ 606 .flags = f, \ 607 .muxdiv_offset = mo, \ 608 .div_shift = 16, \ 609 .div_width = 16, \ 610 .div_flags = df, \ 611 .gate_offset = go, \ 612 .gate_shift = gs, \ 613 .gate_flags = gf, \ 614 } 615 616#define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \ 617 { \ 618 .id = _id, \ 619 .branch_type = branch_fraction_divider, \ 620 .name = cname, \ 621 .parent_names = (const char *[]){ pname }, \ 622 .num_parents = 1, \ 623 .flags = f, \ 624 .muxdiv_offset = mo, \ 625 .div_shift = 16, \ 626 .div_width = 16, \ 627 .div_flags = df, \ 628 .gate_offset = go, \ 629 .gate_shift = gs, \ 630 .gate_flags = gf, \ 631 .child = ch, \ 632 } 633 634#define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \ 635 { \ 636 .id = _id, \ 637 .branch_type = branch_fraction_divider, \ 638 .name = cname, \ 639 .parent_names = (const char *[]){ pname }, \ 640 .num_parents = 1, \ 641 .flags = f, \ 642 .muxdiv_offset = mo, \ 643 .div_shift = 16, \ 644 .div_width = 16, \ 645 .div_flags = df, \ 646 .gate_offset = -1, \ 647 .child = ch, \ 648 } 649 650#define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw, \ 651 ds, dw, df) \ 652 { \ 653 .id = _id, \ 654 .branch_type = branch_ddrclk, \ 655 .name = cname, \ 656 .parent_names = pnames, \ 657 .num_parents = ARRAY_SIZE(pnames), \ 658 .flags = f, \ 659 .muxdiv_offset = mo, \ 660 .mux_shift = ms, \ 661 .mux_width = mw, \ 662 .div_shift = ds, \ 663 .div_width = dw, \ 664 .div_flags = df, \ 665 .gate_offset = -1, \ 666 } 667 668#define MUX(_id, cname, pnames, f, o, s, w, mf) \ 669 { \ 670 .id = _id, \ 671 .branch_type = branch_mux, \ 672 .name = cname, \ 673 .parent_names = pnames, \ 674 .num_parents = ARRAY_SIZE(pnames), \ 675 .flags = f, \ 676 .muxdiv_offset = o, \ 677 .mux_shift = s, \ 678 .mux_width = w, \ 679 .mux_flags = mf, \ 680 .gate_offset = -1, \ 681 } 682 683#define MUXGRF(_id, cname, pnames, f, o, s, w, mf) \ 684 { \ 685 .id = _id, \ 686 .branch_type = branch_muxgrf, \ 687 .name = cname, \ 688 .parent_names = pnames, \ 689 .num_parents = ARRAY_SIZE(pnames), \ 690 .flags = f, \ 691 .muxdiv_offset = o, \ 692 .mux_shift = s, \ 693 .mux_width = w, \ 694 .mux_flags = mf, \ 695 .gate_offset = -1, \ 696 } 697 698#define DIV(_id, cname, pname, f, o, s, w, df) \ 699 { \ 700 .id = _id, \ 701 .branch_type = branch_divider, \ 702 .name = cname, \ 703 .parent_names = (const char *[]){ pname }, \ 704 .num_parents = 1, \ 705 .flags = f, \ 706 .muxdiv_offset = o, \ 707 .div_shift = s, \ 708 .div_width = w, \ 709 .div_flags = df, \ 710 .gate_offset = -1, \ 711 } 712 713#define DIVTBL(_id, cname, pname, f, o, s, w, df, dt) \ 714 { \ 715 .id = _id, \ 716 .branch_type = branch_divider, \ 717 .name = cname, \ 718 .parent_names = (const char *[]){ pname }, \ 719 .num_parents = 1, \ 720 .flags = f, \ 721 .muxdiv_offset = o, \ 722 .div_shift = s, \ 723 .div_width = w, \ 724 .div_flags = df, \ 725 .div_table = dt, \ 726 } 727 728#define GATE(_id, cname, pname, f, o, b, gf) \ 729 { \ 730 .id = _id, \ 731 .branch_type = branch_gate, \ 732 .name = cname, \ 733 .parent_names = (const char *[]){ pname }, \ 734 .num_parents = 1, \ 735 .flags = f, \ 736 .gate_offset = o, \ 737 .gate_shift = b, \ 738 .gate_flags = gf, \ 739 } 740 741#define MMC(_id, cname, pname, offset, shift) \ 742 { \ 743 .id = _id, \ 744 .branch_type = branch_mmc, \ 745 .name = cname, \ 746 .parent_names = (const char *[]){ pname }, \ 747 .num_parents = 1, \ 748 .muxdiv_offset = offset, \ 749 .div_shift = shift, \ 750 } 751 752#define INVERTER(_id, cname, pname, io, is, if) \ 753 { \ 754 .id = _id, \ 755 .branch_type = branch_inverter, \ 756 .name = cname, \ 757 .parent_names = (const char *[]){ pname }, \ 758 .num_parents = 1, \ 759 .muxdiv_offset = io, \ 760 .div_shift = is, \ 761 .div_flags = if, \ 762 } 763 764#define FACTOR(_id, cname, pname, f, fm, fd) \ 765 { \ 766 .id = _id, \ 767 .branch_type = branch_factor, \ 768 .name = cname, \ 769 .parent_names = (const char *[]){ pname }, \ 770 .num_parents = 1, \ 771 .flags = f, \ 772 .div_shift = fm, \ 773 .div_width = fd, \ 774 } 775 776#define FACTOR_GATE(_id, cname, pname, f, fm, fd, go, gb, gf) \ 777 { \ 778 .id = _id, \ 779 .branch_type = branch_factor, \ 780 .name = cname, \ 781 .parent_names = (const char *[]){ pname }, \ 782 .num_parents = 1, \ 783 .flags = f, \ 784 .div_shift = fm, \ 785 .div_width = fd, \ 786 .gate_offset = go, \ 787 .gate_shift = gb, \ 788 .gate_flags = gf, \ 789 } 790 791#define COMPOSITE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\ 792 df, go, gs, gf) \ 793 { \ 794 .id = _id, \ 795 .branch_type = branch_half_divider, \ 796 .name = cname, \ 797 .parent_names = pnames, \ 798 .num_parents = ARRAY_SIZE(pnames), \ 799 .flags = f, \ 800 .muxdiv_offset = mo, \ 801 .mux_shift = ms, \ 802 .mux_width = mw, \ 803 .mux_flags = mf, \ 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 COMPOSITE_NOGATE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, \ 813 ds, dw, df) \ 814 { \ 815 .id = _id, \ 816 .branch_type = branch_half_divider, \ 817 .name = cname, \ 818 .parent_names = pnames, \ 819 .num_parents = ARRAY_SIZE(pnames), \ 820 .flags = f, \ 821 .muxdiv_offset = mo, \ 822 .mux_shift = ms, \ 823 .mux_width = mw, \ 824 .mux_flags = mf, \ 825 .div_shift = ds, \ 826 .div_width = dw, \ 827 .div_flags = df, \ 828 .gate_offset = -1, \ 829 } 830 831#define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df, \ 832 go, gs, gf) \ 833 { \ 834 .id = _id, \ 835 .branch_type = branch_half_divider, \ 836 .name = cname, \ 837 .parent_names = (const char *[]){ pname }, \ 838 .num_parents = 1, \ 839 .flags = f, \ 840 .muxdiv_offset = mo, \ 841 .div_shift = ds, \ 842 .div_width = dw, \ 843 .div_flags = df, \ 844 .gate_offset = go, \ 845 .gate_shift = gs, \ 846 .gate_flags = gf, \ 847 } 848 849#define DIV_HALF(_id, cname, pname, f, o, s, w, df) \ 850 { \ 851 .id = _id, \ 852 .branch_type = branch_half_divider, \ 853 .name = cname, \ 854 .parent_names = (const char *[]){ pname }, \ 855 .num_parents = 1, \ 856 .flags = f, \ 857 .muxdiv_offset = o, \ 858 .div_shift = s, \ 859 .div_width = w, \ 860 .div_flags = df, \ 861 .gate_offset = -1, \ 862 } 863 864/* SGRF clocks are only accessible from secure mode, so not controllable */ 865#define SGRF_GATE(_id, cname, pname) \ 866 FACTOR(_id, cname, pname, 0, 1, 1) 867 868struct rockchip_clk_provider *rockchip_clk_init(struct device_node *np, 869 void __iomem *base, unsigned long nr_clks); 870void rockchip_clk_of_add_provider(struct device_node *np, 871 struct rockchip_clk_provider *ctx); 872void rockchip_clk_add_lookup(struct rockchip_clk_provider *ctx, 873 struct clk *clk, unsigned int id); 874void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx, 875 struct rockchip_clk_branch *list, 876 unsigned int nr_clk); 877void rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, 878 struct rockchip_pll_clock *pll_list, 879 unsigned int nr_pll, int grf_lock_offset); 880void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx, 881 unsigned int lookup_id, const char *name, 882 const char *const *parent_names, u8 num_parents, 883 const struct rockchip_cpuclk_reg_data *reg_data, 884 const struct rockchip_cpuclk_rate_table *rates, 885 int nrates); 886void rockchip_clk_protect_critical(const char *const clocks[], int nclocks); 887void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx, 888 unsigned int reg, void (*cb)(void)); 889 890#define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0) 891 892struct clk *rockchip_clk_register_halfdiv(const char *name, 893 const char *const *parent_names, 894 u8 num_parents, void __iomem *base, 895 int muxdiv_offset, u8 mux_shift, 896 u8 mux_width, u8 mux_flags, 897 u8 div_shift, u8 div_width, 898 u8 div_flags, int gate_offset, 899 u8 gate_shift, u8 gate_flags, 900 unsigned long flags, 901 spinlock_t *lock); 902 903#ifdef CONFIG_RESET_CONTROLLER 904void rockchip_register_softrst(struct device_node *np, 905 unsigned int num_regs, 906 void __iomem *base, u8 flags); 907#else 908static inline void rockchip_register_softrst(struct device_node *np, 909 unsigned int num_regs, 910 void __iomem *base, u8 flags) 911{ 912} 913#endif 914 915#endif