clk.h 24 KB

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