clk-rcg.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. /*
  2. * Copyright (c) 2013, The Linux Foundation. All rights reserved.
  3. *
  4. * This software is licensed under the terms of the GNU General Public
  5. * License version 2, as published by the Free Software Foundation, and
  6. * may be copied, distributed, and modified under those terms.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/kernel.h>
  14. #include <linux/bitops.h>
  15. #include <linux/err.h>
  16. #include <linux/export.h>
  17. #include <linux/clk-provider.h>
  18. #include <linux/regmap.h>
  19. #include <asm/div64.h>
  20. #include "clk-rcg.h"
  21. #include "common.h"
  22. static u32 ns_to_src(struct src_sel *s, u32 ns)
  23. {
  24. ns >>= s->src_sel_shift;
  25. ns &= SRC_SEL_MASK;
  26. return ns;
  27. }
  28. static u32 src_to_ns(struct src_sel *s, u8 src, u32 ns)
  29. {
  30. u32 mask;
  31. mask = SRC_SEL_MASK;
  32. mask <<= s->src_sel_shift;
  33. ns &= ~mask;
  34. ns |= src << s->src_sel_shift;
  35. return ns;
  36. }
  37. static u8 clk_rcg_get_parent(struct clk_hw *hw)
  38. {
  39. struct clk_rcg *rcg = to_clk_rcg(hw);
  40. int num_parents = __clk_get_num_parents(hw->clk);
  41. u32 ns;
  42. int i, ret;
  43. ret = regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
  44. if (ret)
  45. goto err;
  46. ns = ns_to_src(&rcg->s, ns);
  47. for (i = 0; i < num_parents; i++)
  48. if (ns == rcg->s.parent_map[i].cfg)
  49. return i;
  50. err:
  51. pr_debug("%s: Clock %s has invalid parent, using default.\n",
  52. __func__, __clk_get_name(hw->clk));
  53. return 0;
  54. }
  55. static int reg_to_bank(struct clk_dyn_rcg *rcg, u32 bank)
  56. {
  57. bank &= BIT(rcg->mux_sel_bit);
  58. return !!bank;
  59. }
  60. static u8 clk_dyn_rcg_get_parent(struct clk_hw *hw)
  61. {
  62. struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
  63. int num_parents = __clk_get_num_parents(hw->clk);
  64. u32 ns, reg;
  65. int bank;
  66. int i, ret;
  67. struct src_sel *s;
  68. ret = regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
  69. if (ret)
  70. goto err;
  71. bank = reg_to_bank(rcg, reg);
  72. s = &rcg->s[bank];
  73. ret = regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
  74. if (ret)
  75. goto err;
  76. ns = ns_to_src(s, ns);
  77. for (i = 0; i < num_parents; i++)
  78. if (ns == s->parent_map[i].cfg)
  79. return i;
  80. err:
  81. pr_debug("%s: Clock %s has invalid parent, using default.\n",
  82. __func__, __clk_get_name(hw->clk));
  83. return 0;
  84. }
  85. static int clk_rcg_set_parent(struct clk_hw *hw, u8 index)
  86. {
  87. struct clk_rcg *rcg = to_clk_rcg(hw);
  88. u32 ns;
  89. regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
  90. ns = src_to_ns(&rcg->s, rcg->s.parent_map[index].cfg, ns);
  91. regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
  92. return 0;
  93. }
  94. static u32 md_to_m(struct mn *mn, u32 md)
  95. {
  96. md >>= mn->m_val_shift;
  97. md &= BIT(mn->width) - 1;
  98. return md;
  99. }
  100. static u32 ns_to_pre_div(struct pre_div *p, u32 ns)
  101. {
  102. ns >>= p->pre_div_shift;
  103. ns &= BIT(p->pre_div_width) - 1;
  104. return ns;
  105. }
  106. static u32 pre_div_to_ns(struct pre_div *p, u8 pre_div, u32 ns)
  107. {
  108. u32 mask;
  109. mask = BIT(p->pre_div_width) - 1;
  110. mask <<= p->pre_div_shift;
  111. ns &= ~mask;
  112. ns |= pre_div << p->pre_div_shift;
  113. return ns;
  114. }
  115. static u32 mn_to_md(struct mn *mn, u32 m, u32 n, u32 md)
  116. {
  117. u32 mask, mask_w;
  118. mask_w = BIT(mn->width) - 1;
  119. mask = (mask_w << mn->m_val_shift) | mask_w;
  120. md &= ~mask;
  121. if (n) {
  122. m <<= mn->m_val_shift;
  123. md |= m;
  124. md |= ~n & mask_w;
  125. }
  126. return md;
  127. }
  128. static u32 ns_m_to_n(struct mn *mn, u32 ns, u32 m)
  129. {
  130. ns = ~ns >> mn->n_val_shift;
  131. ns &= BIT(mn->width) - 1;
  132. return ns + m;
  133. }
  134. static u32 reg_to_mnctr_mode(struct mn *mn, u32 val)
  135. {
  136. val >>= mn->mnctr_mode_shift;
  137. val &= MNCTR_MODE_MASK;
  138. return val;
  139. }
  140. static u32 mn_to_ns(struct mn *mn, u32 m, u32 n, u32 ns)
  141. {
  142. u32 mask;
  143. mask = BIT(mn->width) - 1;
  144. mask <<= mn->n_val_shift;
  145. ns &= ~mask;
  146. if (n) {
  147. n = n - m;
  148. n = ~n;
  149. n &= BIT(mn->width) - 1;
  150. n <<= mn->n_val_shift;
  151. ns |= n;
  152. }
  153. return ns;
  154. }
  155. static u32 mn_to_reg(struct mn *mn, u32 m, u32 n, u32 val)
  156. {
  157. u32 mask;
  158. mask = MNCTR_MODE_MASK << mn->mnctr_mode_shift;
  159. mask |= BIT(mn->mnctr_en_bit);
  160. val &= ~mask;
  161. if (n) {
  162. val |= BIT(mn->mnctr_en_bit);
  163. val |= MNCTR_MODE_DUAL << mn->mnctr_mode_shift;
  164. }
  165. return val;
  166. }
  167. static int configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f)
  168. {
  169. u32 ns, md, reg;
  170. int bank, new_bank, ret, index;
  171. struct mn *mn;
  172. struct pre_div *p;
  173. struct src_sel *s;
  174. bool enabled;
  175. u32 md_reg, ns_reg;
  176. bool banked_mn = !!rcg->mn[1].width;
  177. bool banked_p = !!rcg->p[1].pre_div_width;
  178. struct clk_hw *hw = &rcg->clkr.hw;
  179. enabled = __clk_is_enabled(hw->clk);
  180. ret = regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
  181. if (ret)
  182. return ret;
  183. bank = reg_to_bank(rcg, reg);
  184. new_bank = enabled ? !bank : bank;
  185. ns_reg = rcg->ns_reg[new_bank];
  186. ret = regmap_read(rcg->clkr.regmap, ns_reg, &ns);
  187. if (ret)
  188. return ret;
  189. if (banked_mn) {
  190. mn = &rcg->mn[new_bank];
  191. md_reg = rcg->md_reg[new_bank];
  192. ns |= BIT(mn->mnctr_reset_bit);
  193. ret = regmap_write(rcg->clkr.regmap, ns_reg, ns);
  194. if (ret)
  195. return ret;
  196. ret = regmap_read(rcg->clkr.regmap, md_reg, &md);
  197. if (ret)
  198. return ret;
  199. md = mn_to_md(mn, f->m, f->n, md);
  200. ret = regmap_write(rcg->clkr.regmap, md_reg, md);
  201. if (ret)
  202. return ret;
  203. ns = mn_to_ns(mn, f->m, f->n, ns);
  204. ret = regmap_write(rcg->clkr.regmap, ns_reg, ns);
  205. if (ret)
  206. return ret;
  207. /* Two NS registers means mode control is in NS register */
  208. if (rcg->ns_reg[0] != rcg->ns_reg[1]) {
  209. ns = mn_to_reg(mn, f->m, f->n, ns);
  210. ret = regmap_write(rcg->clkr.regmap, ns_reg, ns);
  211. if (ret)
  212. return ret;
  213. } else {
  214. reg = mn_to_reg(mn, f->m, f->n, reg);
  215. ret = regmap_write(rcg->clkr.regmap, rcg->bank_reg,
  216. reg);
  217. if (ret)
  218. return ret;
  219. }
  220. ns &= ~BIT(mn->mnctr_reset_bit);
  221. ret = regmap_write(rcg->clkr.regmap, ns_reg, ns);
  222. if (ret)
  223. return ret;
  224. }
  225. if (banked_p) {
  226. p = &rcg->p[new_bank];
  227. ns = pre_div_to_ns(p, f->pre_div - 1, ns);
  228. }
  229. s = &rcg->s[new_bank];
  230. index = qcom_find_src_index(hw, s->parent_map, f->src);
  231. if (index < 0)
  232. return index;
  233. ns = src_to_ns(s, s->parent_map[index].cfg, ns);
  234. ret = regmap_write(rcg->clkr.regmap, ns_reg, ns);
  235. if (ret)
  236. return ret;
  237. if (enabled) {
  238. ret = regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
  239. if (ret)
  240. return ret;
  241. reg ^= BIT(rcg->mux_sel_bit);
  242. ret = regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg);
  243. if (ret)
  244. return ret;
  245. }
  246. return 0;
  247. }
  248. static int clk_dyn_rcg_set_parent(struct clk_hw *hw, u8 index)
  249. {
  250. struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
  251. u32 ns, md, reg;
  252. int bank;
  253. struct freq_tbl f = { 0 };
  254. bool banked_mn = !!rcg->mn[1].width;
  255. bool banked_p = !!rcg->p[1].pre_div_width;
  256. regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
  257. bank = reg_to_bank(rcg, reg);
  258. regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
  259. if (banked_mn) {
  260. regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md);
  261. f.m = md_to_m(&rcg->mn[bank], md);
  262. f.n = ns_m_to_n(&rcg->mn[bank], ns, f.m);
  263. }
  264. if (banked_p)
  265. f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1;
  266. f.src = qcom_find_src_index(hw, rcg->s[bank].parent_map, index);
  267. return configure_bank(rcg, &f);
  268. }
  269. /*
  270. * Calculate m/n:d rate
  271. *
  272. * parent_rate m
  273. * rate = ----------- x ---
  274. * pre_div n
  275. */
  276. static unsigned long
  277. calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 pre_div)
  278. {
  279. if (pre_div)
  280. rate /= pre_div + 1;
  281. if (mode) {
  282. u64 tmp = rate;
  283. tmp *= m;
  284. do_div(tmp, n);
  285. rate = tmp;
  286. }
  287. return rate;
  288. }
  289. static unsigned long
  290. clk_rcg_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
  291. {
  292. struct clk_rcg *rcg = to_clk_rcg(hw);
  293. u32 pre_div, m = 0, n = 0, ns, md, mode = 0;
  294. struct mn *mn = &rcg->mn;
  295. regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
  296. pre_div = ns_to_pre_div(&rcg->p, ns);
  297. if (rcg->mn.width) {
  298. regmap_read(rcg->clkr.regmap, rcg->md_reg, &md);
  299. m = md_to_m(mn, md);
  300. n = ns_m_to_n(mn, ns, m);
  301. /* MN counter mode is in hw.enable_reg sometimes */
  302. if (rcg->clkr.enable_reg != rcg->ns_reg)
  303. regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &mode);
  304. else
  305. mode = ns;
  306. mode = reg_to_mnctr_mode(mn, mode);
  307. }
  308. return calc_rate(parent_rate, m, n, mode, pre_div);
  309. }
  310. static unsigned long
  311. clk_dyn_rcg_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
  312. {
  313. struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
  314. u32 m, n, pre_div, ns, md, mode, reg;
  315. int bank;
  316. struct mn *mn;
  317. bool banked_p = !!rcg->p[1].pre_div_width;
  318. bool banked_mn = !!rcg->mn[1].width;
  319. regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
  320. bank = reg_to_bank(rcg, reg);
  321. regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
  322. m = n = pre_div = mode = 0;
  323. if (banked_mn) {
  324. mn = &rcg->mn[bank];
  325. regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md);
  326. m = md_to_m(mn, md);
  327. n = ns_m_to_n(mn, ns, m);
  328. /* Two NS registers means mode control is in NS register */
  329. if (rcg->ns_reg[0] != rcg->ns_reg[1])
  330. reg = ns;
  331. mode = reg_to_mnctr_mode(mn, reg);
  332. }
  333. if (banked_p)
  334. pre_div = ns_to_pre_div(&rcg->p[bank], ns);
  335. return calc_rate(parent_rate, m, n, mode, pre_div);
  336. }
  337. static long _freq_tbl_determine_rate(struct clk_hw *hw,
  338. const struct freq_tbl *f, unsigned long rate,
  339. unsigned long min_rate, unsigned long max_rate,
  340. unsigned long *p_rate, struct clk_hw **p_hw,
  341. const struct parent_map *parent_map)
  342. {
  343. unsigned long clk_flags;
  344. struct clk *p;
  345. int index;
  346. f = qcom_find_freq(f, rate);
  347. if (!f)
  348. return -EINVAL;
  349. index = qcom_find_src_index(hw, parent_map, f->src);
  350. if (index < 0)
  351. return index;
  352. clk_flags = __clk_get_flags(hw->clk);
  353. p = clk_get_parent_by_index(hw->clk, index);
  354. if (clk_flags & CLK_SET_RATE_PARENT) {
  355. rate = rate * f->pre_div;
  356. if (f->n) {
  357. u64 tmp = rate;
  358. tmp = tmp * f->n;
  359. do_div(tmp, f->m);
  360. rate = tmp;
  361. }
  362. } else {
  363. rate = __clk_get_rate(p);
  364. }
  365. *p_hw = __clk_get_hw(p);
  366. *p_rate = rate;
  367. return f->freq;
  368. }
  369. static long clk_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
  370. unsigned long min_rate, unsigned long max_rate,
  371. unsigned long *p_rate, struct clk_hw **p)
  372. {
  373. struct clk_rcg *rcg = to_clk_rcg(hw);
  374. return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, min_rate,
  375. max_rate, p_rate, p, rcg->s.parent_map);
  376. }
  377. static long clk_dyn_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
  378. unsigned long min_rate, unsigned long max_rate,
  379. unsigned long *p_rate, struct clk_hw **p)
  380. {
  381. struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
  382. u32 reg;
  383. int bank;
  384. struct src_sel *s;
  385. regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
  386. bank = reg_to_bank(rcg, reg);
  387. s = &rcg->s[bank];
  388. return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, min_rate,
  389. max_rate, p_rate, p, s->parent_map);
  390. }
  391. static long clk_rcg_bypass_determine_rate(struct clk_hw *hw, unsigned long rate,
  392. unsigned long min_rate, unsigned long max_rate,
  393. unsigned long *p_rate, struct clk_hw **p_hw)
  394. {
  395. struct clk_rcg *rcg = to_clk_rcg(hw);
  396. const struct freq_tbl *f = rcg->freq_tbl;
  397. struct clk *p;
  398. int index = qcom_find_src_index(hw, rcg->s.parent_map, f->src);
  399. p = clk_get_parent_by_index(hw->clk, index);
  400. *p_hw = __clk_get_hw(p);
  401. *p_rate = __clk_round_rate(p, rate);
  402. return *p_rate;
  403. }
  404. static int __clk_rcg_set_rate(struct clk_rcg *rcg, const struct freq_tbl *f)
  405. {
  406. u32 ns, md, ctl;
  407. struct mn *mn = &rcg->mn;
  408. u32 mask = 0;
  409. unsigned int reset_reg;
  410. if (rcg->mn.reset_in_cc)
  411. reset_reg = rcg->clkr.enable_reg;
  412. else
  413. reset_reg = rcg->ns_reg;
  414. if (rcg->mn.width) {
  415. mask = BIT(mn->mnctr_reset_bit);
  416. regmap_update_bits(rcg->clkr.regmap, reset_reg, mask, mask);
  417. regmap_read(rcg->clkr.regmap, rcg->md_reg, &md);
  418. md = mn_to_md(mn, f->m, f->n, md);
  419. regmap_write(rcg->clkr.regmap, rcg->md_reg, md);
  420. regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
  421. /* MN counter mode is in hw.enable_reg sometimes */
  422. if (rcg->clkr.enable_reg != rcg->ns_reg) {
  423. regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
  424. ctl = mn_to_reg(mn, f->m, f->n, ctl);
  425. regmap_write(rcg->clkr.regmap, rcg->clkr.enable_reg, ctl);
  426. } else {
  427. ns = mn_to_reg(mn, f->m, f->n, ns);
  428. }
  429. ns = mn_to_ns(mn, f->m, f->n, ns);
  430. } else {
  431. regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
  432. }
  433. ns = pre_div_to_ns(&rcg->p, f->pre_div - 1, ns);
  434. regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
  435. regmap_update_bits(rcg->clkr.regmap, reset_reg, mask, 0);
  436. return 0;
  437. }
  438. static int clk_rcg_set_rate(struct clk_hw *hw, unsigned long rate,
  439. unsigned long parent_rate)
  440. {
  441. struct clk_rcg *rcg = to_clk_rcg(hw);
  442. const struct freq_tbl *f;
  443. f = qcom_find_freq(rcg->freq_tbl, rate);
  444. if (!f)
  445. return -EINVAL;
  446. return __clk_rcg_set_rate(rcg, f);
  447. }
  448. static int clk_rcg_bypass_set_rate(struct clk_hw *hw, unsigned long rate,
  449. unsigned long parent_rate)
  450. {
  451. struct clk_rcg *rcg = to_clk_rcg(hw);
  452. return __clk_rcg_set_rate(rcg, rcg->freq_tbl);
  453. }
  454. /*
  455. * This type of clock has a glitch-free mux that switches between the output of
  456. * the M/N counter and an always on clock source (XO). When clk_set_rate() is
  457. * called we need to make sure that we don't switch to the M/N counter if it
  458. * isn't clocking because the mux will get stuck and the clock will stop
  459. * outputting a clock. This can happen if the framework isn't aware that this
  460. * clock is on and so clk_set_rate() doesn't turn on the new parent. To fix
  461. * this we switch the mux in the enable/disable ops and reprogram the M/N
  462. * counter in the set_rate op. We also make sure to switch away from the M/N
  463. * counter in set_rate if software thinks the clock is off.
  464. */
  465. static int clk_rcg_lcc_set_rate(struct clk_hw *hw, unsigned long rate,
  466. unsigned long parent_rate)
  467. {
  468. struct clk_rcg *rcg = to_clk_rcg(hw);
  469. const struct freq_tbl *f;
  470. int ret;
  471. u32 gfm = BIT(10);
  472. f = qcom_find_freq(rcg->freq_tbl, rate);
  473. if (!f)
  474. return -EINVAL;
  475. /* Switch to XO to avoid glitches */
  476. regmap_update_bits(rcg->clkr.regmap, rcg->ns_reg, gfm, 0);
  477. ret = __clk_rcg_set_rate(rcg, f);
  478. /* Switch back to M/N if it's clocking */
  479. if (__clk_is_enabled(hw->clk))
  480. regmap_update_bits(rcg->clkr.regmap, rcg->ns_reg, gfm, gfm);
  481. return ret;
  482. }
  483. static int clk_rcg_lcc_enable(struct clk_hw *hw)
  484. {
  485. struct clk_rcg *rcg = to_clk_rcg(hw);
  486. u32 gfm = BIT(10);
  487. /* Use M/N */
  488. return regmap_update_bits(rcg->clkr.regmap, rcg->ns_reg, gfm, gfm);
  489. }
  490. static void clk_rcg_lcc_disable(struct clk_hw *hw)
  491. {
  492. struct clk_rcg *rcg = to_clk_rcg(hw);
  493. u32 gfm = BIT(10);
  494. /* Use XO */
  495. regmap_update_bits(rcg->clkr.regmap, rcg->ns_reg, gfm, 0);
  496. }
  497. static int __clk_dyn_rcg_set_rate(struct clk_hw *hw, unsigned long rate)
  498. {
  499. struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
  500. const struct freq_tbl *f;
  501. f = qcom_find_freq(rcg->freq_tbl, rate);
  502. if (!f)
  503. return -EINVAL;
  504. return configure_bank(rcg, f);
  505. }
  506. static int clk_dyn_rcg_set_rate(struct clk_hw *hw, unsigned long rate,
  507. unsigned long parent_rate)
  508. {
  509. return __clk_dyn_rcg_set_rate(hw, rate);
  510. }
  511. static int clk_dyn_rcg_set_rate_and_parent(struct clk_hw *hw,
  512. unsigned long rate, unsigned long parent_rate, u8 index)
  513. {
  514. return __clk_dyn_rcg_set_rate(hw, rate);
  515. }
  516. const struct clk_ops clk_rcg_ops = {
  517. .enable = clk_enable_regmap,
  518. .disable = clk_disable_regmap,
  519. .get_parent = clk_rcg_get_parent,
  520. .set_parent = clk_rcg_set_parent,
  521. .recalc_rate = clk_rcg_recalc_rate,
  522. .determine_rate = clk_rcg_determine_rate,
  523. .set_rate = clk_rcg_set_rate,
  524. };
  525. EXPORT_SYMBOL_GPL(clk_rcg_ops);
  526. const struct clk_ops clk_rcg_bypass_ops = {
  527. .enable = clk_enable_regmap,
  528. .disable = clk_disable_regmap,
  529. .get_parent = clk_rcg_get_parent,
  530. .set_parent = clk_rcg_set_parent,
  531. .recalc_rate = clk_rcg_recalc_rate,
  532. .determine_rate = clk_rcg_bypass_determine_rate,
  533. .set_rate = clk_rcg_bypass_set_rate,
  534. };
  535. EXPORT_SYMBOL_GPL(clk_rcg_bypass_ops);
  536. const struct clk_ops clk_rcg_lcc_ops = {
  537. .enable = clk_rcg_lcc_enable,
  538. .disable = clk_rcg_lcc_disable,
  539. .get_parent = clk_rcg_get_parent,
  540. .set_parent = clk_rcg_set_parent,
  541. .recalc_rate = clk_rcg_recalc_rate,
  542. .determine_rate = clk_rcg_determine_rate,
  543. .set_rate = clk_rcg_lcc_set_rate,
  544. };
  545. EXPORT_SYMBOL_GPL(clk_rcg_lcc_ops);
  546. const struct clk_ops clk_dyn_rcg_ops = {
  547. .enable = clk_enable_regmap,
  548. .is_enabled = clk_is_enabled_regmap,
  549. .disable = clk_disable_regmap,
  550. .get_parent = clk_dyn_rcg_get_parent,
  551. .set_parent = clk_dyn_rcg_set_parent,
  552. .recalc_rate = clk_dyn_rcg_recalc_rate,
  553. .determine_rate = clk_dyn_rcg_determine_rate,
  554. .set_rate = clk_dyn_rcg_set_rate,
  555. .set_rate_and_parent = clk_dyn_rcg_set_rate_and_parent,
  556. };
  557. EXPORT_SYMBOL_GPL(clk_dyn_rcg_ops);