clk.h 27 KB

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