clk-rcg.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  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;
  43. regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
  44. ns = ns_to_src(&rcg->s, ns);
  45. for (i = 0; i < num_parents; i++)
  46. if (ns == rcg->s.parent_map[i])
  47. return i;
  48. return -EINVAL;
  49. }
  50. static int reg_to_bank(struct clk_dyn_rcg *rcg, u32 bank)
  51. {
  52. bank &= BIT(rcg->mux_sel_bit);
  53. return !!bank;
  54. }
  55. static u8 clk_dyn_rcg_get_parent(struct clk_hw *hw)
  56. {
  57. struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
  58. int num_parents = __clk_get_num_parents(hw->clk);
  59. u32 ns, reg;
  60. int bank;
  61. int i;
  62. struct src_sel *s;
  63. regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
  64. bank = reg_to_bank(rcg, reg);
  65. s = &rcg->s[bank];
  66. regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
  67. ns = ns_to_src(s, ns);
  68. for (i = 0; i < num_parents; i++)
  69. if (ns == s->parent_map[i])
  70. return i;
  71. return -EINVAL;
  72. }
  73. static int clk_rcg_set_parent(struct clk_hw *hw, u8 index)
  74. {
  75. struct clk_rcg *rcg = to_clk_rcg(hw);
  76. u32 ns;
  77. regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
  78. ns = src_to_ns(&rcg->s, rcg->s.parent_map[index], ns);
  79. regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
  80. return 0;
  81. }
  82. static u32 md_to_m(struct mn *mn, u32 md)
  83. {
  84. md >>= mn->m_val_shift;
  85. md &= BIT(mn->width) - 1;
  86. return md;
  87. }
  88. static u32 ns_to_pre_div(struct pre_div *p, u32 ns)
  89. {
  90. ns >>= p->pre_div_shift;
  91. ns &= BIT(p->pre_div_width) - 1;
  92. return ns;
  93. }
  94. static u32 pre_div_to_ns(struct pre_div *p, u8 pre_div, u32 ns)
  95. {
  96. u32 mask;
  97. mask = BIT(p->pre_div_width) - 1;
  98. mask <<= p->pre_div_shift;
  99. ns &= ~mask;
  100. ns |= pre_div << p->pre_div_shift;
  101. return ns;
  102. }
  103. static u32 mn_to_md(struct mn *mn, u32 m, u32 n, u32 md)
  104. {
  105. u32 mask, mask_w;
  106. mask_w = BIT(mn->width) - 1;
  107. mask = (mask_w << mn->m_val_shift) | mask_w;
  108. md &= ~mask;
  109. if (n) {
  110. m <<= mn->m_val_shift;
  111. md |= m;
  112. md |= ~n & mask_w;
  113. }
  114. return md;
  115. }
  116. static u32 ns_m_to_n(struct mn *mn, u32 ns, u32 m)
  117. {
  118. ns = ~ns >> mn->n_val_shift;
  119. ns &= BIT(mn->width) - 1;
  120. return ns + m;
  121. }
  122. static u32 reg_to_mnctr_mode(struct mn *mn, u32 val)
  123. {
  124. val >>= mn->mnctr_mode_shift;
  125. val &= MNCTR_MODE_MASK;
  126. return val;
  127. }
  128. static u32 mn_to_ns(struct mn *mn, u32 m, u32 n, u32 ns)
  129. {
  130. u32 mask;
  131. mask = BIT(mn->width) - 1;
  132. mask <<= mn->n_val_shift;
  133. ns &= ~mask;
  134. if (n) {
  135. n = n - m;
  136. n = ~n;
  137. n &= BIT(mn->width) - 1;
  138. n <<= mn->n_val_shift;
  139. ns |= n;
  140. }
  141. return ns;
  142. }
  143. static u32 mn_to_reg(struct mn *mn, u32 m, u32 n, u32 val)
  144. {
  145. u32 mask;
  146. mask = MNCTR_MODE_MASK << mn->mnctr_mode_shift;
  147. mask |= BIT(mn->mnctr_en_bit);
  148. val &= ~mask;
  149. if (n) {
  150. val |= BIT(mn->mnctr_en_bit);
  151. val |= MNCTR_MODE_DUAL << mn->mnctr_mode_shift;
  152. }
  153. return val;
  154. }
  155. static void configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f)
  156. {
  157. u32 ns, md, reg;
  158. int bank, new_bank;
  159. struct mn *mn;
  160. struct pre_div *p;
  161. struct src_sel *s;
  162. bool enabled;
  163. u32 md_reg, ns_reg;
  164. bool banked_mn = !!rcg->mn[1].width;
  165. bool banked_p = !!rcg->p[1].pre_div_width;
  166. struct clk_hw *hw = &rcg->clkr.hw;
  167. enabled = __clk_is_enabled(hw->clk);
  168. regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
  169. bank = reg_to_bank(rcg, reg);
  170. new_bank = enabled ? !bank : bank;
  171. ns_reg = rcg->ns_reg[new_bank];
  172. regmap_read(rcg->clkr.regmap, ns_reg, &ns);
  173. if (banked_mn) {
  174. mn = &rcg->mn[new_bank];
  175. md_reg = rcg->md_reg[new_bank];
  176. ns |= BIT(mn->mnctr_reset_bit);
  177. regmap_write(rcg->clkr.regmap, ns_reg, ns);
  178. regmap_read(rcg->clkr.regmap, md_reg, &md);
  179. md = mn_to_md(mn, f->m, f->n, md);
  180. regmap_write(rcg->clkr.regmap, md_reg, md);
  181. ns = mn_to_ns(mn, f->m, f->n, ns);
  182. regmap_write(rcg->clkr.regmap, ns_reg, ns);
  183. /* Two NS registers means mode control is in NS register */
  184. if (rcg->ns_reg[0] != rcg->ns_reg[1]) {
  185. ns = mn_to_reg(mn, f->m, f->n, ns);
  186. regmap_write(rcg->clkr.regmap, ns_reg, ns);
  187. } else {
  188. reg = mn_to_reg(mn, f->m, f->n, reg);
  189. regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg);
  190. }
  191. ns &= ~BIT(mn->mnctr_reset_bit);
  192. regmap_write(rcg->clkr.regmap, ns_reg, ns);
  193. }
  194. if (banked_p) {
  195. p = &rcg->p[new_bank];
  196. ns = pre_div_to_ns(p, f->pre_div - 1, ns);
  197. }
  198. s = &rcg->s[new_bank];
  199. ns = src_to_ns(s, s->parent_map[f->src], ns);
  200. regmap_write(rcg->clkr.regmap, ns_reg, ns);
  201. if (enabled) {
  202. regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
  203. reg ^= BIT(rcg->mux_sel_bit);
  204. regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg);
  205. }
  206. }
  207. static int clk_dyn_rcg_set_parent(struct clk_hw *hw, u8 index)
  208. {
  209. struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
  210. u32 ns, md, reg;
  211. int bank;
  212. struct freq_tbl f = { 0 };
  213. bool banked_mn = !!rcg->mn[1].width;
  214. bool banked_p = !!rcg->p[1].pre_div_width;
  215. regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
  216. bank = reg_to_bank(rcg, reg);
  217. regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
  218. if (banked_mn) {
  219. regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md);
  220. f.m = md_to_m(&rcg->mn[bank], md);
  221. f.n = ns_m_to_n(&rcg->mn[bank], ns, f.m);
  222. }
  223. if (banked_p)
  224. f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1;
  225. f.src = index;
  226. configure_bank(rcg, &f);
  227. return 0;
  228. }
  229. /*
  230. * Calculate m/n:d rate
  231. *
  232. * parent_rate m
  233. * rate = ----------- x ---
  234. * pre_div n
  235. */
  236. static unsigned long
  237. calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 pre_div)
  238. {
  239. if (pre_div)
  240. rate /= pre_div + 1;
  241. if (mode) {
  242. u64 tmp = rate;
  243. tmp *= m;
  244. do_div(tmp, n);
  245. rate = tmp;
  246. }
  247. return rate;
  248. }
  249. static unsigned long
  250. clk_rcg_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
  251. {
  252. struct clk_rcg *rcg = to_clk_rcg(hw);
  253. u32 pre_div, m = 0, n = 0, ns, md, mode = 0;
  254. struct mn *mn = &rcg->mn;
  255. regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
  256. pre_div = ns_to_pre_div(&rcg->p, ns);
  257. if (rcg->mn.width) {
  258. regmap_read(rcg->clkr.regmap, rcg->md_reg, &md);
  259. m = md_to_m(mn, md);
  260. n = ns_m_to_n(mn, ns, m);
  261. /* MN counter mode is in hw.enable_reg sometimes */
  262. if (rcg->clkr.enable_reg != rcg->ns_reg)
  263. regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &mode);
  264. else
  265. mode = ns;
  266. mode = reg_to_mnctr_mode(mn, mode);
  267. }
  268. return calc_rate(parent_rate, m, n, mode, pre_div);
  269. }
  270. static unsigned long
  271. clk_dyn_rcg_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
  272. {
  273. struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
  274. u32 m, n, pre_div, ns, md, mode, reg;
  275. int bank;
  276. struct mn *mn;
  277. bool banked_p = !!rcg->p[1].pre_div_width;
  278. bool banked_mn = !!rcg->mn[1].width;
  279. regmap_read(rcg->clkr.regmap, rcg->bank_reg, &reg);
  280. bank = reg_to_bank(rcg, reg);
  281. regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
  282. m = n = pre_div = mode = 0;
  283. if (banked_mn) {
  284. mn = &rcg->mn[bank];
  285. regmap_read(rcg->clkr.regmap, rcg->md_reg[bank], &md);
  286. m = md_to_m(mn, md);
  287. n = ns_m_to_n(mn, ns, m);
  288. /* Two NS registers means mode control is in NS register */
  289. if (rcg->ns_reg[0] != rcg->ns_reg[1])
  290. reg = ns;
  291. mode = reg_to_mnctr_mode(mn, reg);
  292. }
  293. if (banked_p)
  294. pre_div = ns_to_pre_div(&rcg->p[bank], ns);
  295. return calc_rate(parent_rate, m, n, mode, pre_div);
  296. }
  297. static long _freq_tbl_determine_rate(struct clk_hw *hw,
  298. const struct freq_tbl *f, unsigned long rate,
  299. unsigned long *p_rate, struct clk_hw **p_hw)
  300. {
  301. unsigned long clk_flags;
  302. struct clk *p;
  303. f = qcom_find_freq(f, rate);
  304. if (!f)
  305. return -EINVAL;
  306. clk_flags = __clk_get_flags(hw->clk);
  307. p = clk_get_parent_by_index(hw->clk, f->src);
  308. if (clk_flags & CLK_SET_RATE_PARENT) {
  309. rate = rate * f->pre_div;
  310. if (f->n) {
  311. u64 tmp = rate;
  312. tmp = tmp * f->n;
  313. do_div(tmp, f->m);
  314. rate = tmp;
  315. }
  316. } else {
  317. rate = __clk_get_rate(p);
  318. }
  319. *p_hw = __clk_get_hw(p);
  320. *p_rate = rate;
  321. return f->freq;
  322. }
  323. static long clk_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
  324. unsigned long *p_rate, struct clk_hw **p)
  325. {
  326. struct clk_rcg *rcg = to_clk_rcg(hw);
  327. return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p);
  328. }
  329. static long clk_dyn_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
  330. unsigned long *p_rate, struct clk_hw **p)
  331. {
  332. struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
  333. return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, p_rate, p);
  334. }
  335. static long clk_rcg_bypass_determine_rate(struct clk_hw *hw, unsigned long rate,
  336. unsigned long *p_rate, struct clk_hw **p_hw)
  337. {
  338. struct clk_rcg *rcg = to_clk_rcg(hw);
  339. const struct freq_tbl *f = rcg->freq_tbl;
  340. struct clk *p;
  341. p = clk_get_parent_by_index(hw->clk, f->src);
  342. *p_hw = __clk_get_hw(p);
  343. *p_rate = __clk_round_rate(p, rate);
  344. return *p_rate;
  345. }
  346. static int __clk_rcg_set_rate(struct clk_rcg *rcg, const struct freq_tbl *f)
  347. {
  348. u32 ns, md, ctl;
  349. struct mn *mn = &rcg->mn;
  350. u32 mask = 0;
  351. unsigned int reset_reg;
  352. if (rcg->mn.reset_in_cc)
  353. reset_reg = rcg->clkr.enable_reg;
  354. else
  355. reset_reg = rcg->ns_reg;
  356. if (rcg->mn.width) {
  357. mask = BIT(mn->mnctr_reset_bit);
  358. regmap_update_bits(rcg->clkr.regmap, reset_reg, mask, mask);
  359. regmap_read(rcg->clkr.regmap, rcg->md_reg, &md);
  360. md = mn_to_md(mn, f->m, f->n, md);
  361. regmap_write(rcg->clkr.regmap, rcg->md_reg, md);
  362. regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
  363. /* MN counter mode is in hw.enable_reg sometimes */
  364. if (rcg->clkr.enable_reg != rcg->ns_reg) {
  365. regmap_read(rcg->clkr.regmap, rcg->clkr.enable_reg, &ctl);
  366. ctl = mn_to_reg(mn, f->m, f->n, ctl);
  367. regmap_write(rcg->clkr.regmap, rcg->clkr.enable_reg, ctl);
  368. } else {
  369. ns = mn_to_reg(mn, f->m, f->n, ns);
  370. }
  371. ns = mn_to_ns(mn, f->m, f->n, ns);
  372. } else {
  373. regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
  374. }
  375. ns = pre_div_to_ns(&rcg->p, f->pre_div - 1, ns);
  376. regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
  377. regmap_update_bits(rcg->clkr.regmap, reset_reg, mask, 0);
  378. return 0;
  379. }
  380. static int clk_rcg_set_rate(struct clk_hw *hw, unsigned long rate,
  381. unsigned long parent_rate)
  382. {
  383. struct clk_rcg *rcg = to_clk_rcg(hw);
  384. const struct freq_tbl *f;
  385. f = qcom_find_freq(rcg->freq_tbl, rate);
  386. if (!f)
  387. return -EINVAL;
  388. return __clk_rcg_set_rate(rcg, f);
  389. }
  390. static int clk_rcg_bypass_set_rate(struct clk_hw *hw, unsigned long rate,
  391. unsigned long parent_rate)
  392. {
  393. struct clk_rcg *rcg = to_clk_rcg(hw);
  394. return __clk_rcg_set_rate(rcg, rcg->freq_tbl);
  395. }
  396. static int __clk_dyn_rcg_set_rate(struct clk_hw *hw, unsigned long rate)
  397. {
  398. struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
  399. const struct freq_tbl *f;
  400. f = qcom_find_freq(rcg->freq_tbl, rate);
  401. if (!f)
  402. return -EINVAL;
  403. configure_bank(rcg, f);
  404. return 0;
  405. }
  406. static int clk_dyn_rcg_set_rate(struct clk_hw *hw, unsigned long rate,
  407. unsigned long parent_rate)
  408. {
  409. return __clk_dyn_rcg_set_rate(hw, rate);
  410. }
  411. static int clk_dyn_rcg_set_rate_and_parent(struct clk_hw *hw,
  412. unsigned long rate, unsigned long parent_rate, u8 index)
  413. {
  414. return __clk_dyn_rcg_set_rate(hw, rate);
  415. }
  416. const struct clk_ops clk_rcg_ops = {
  417. .enable = clk_enable_regmap,
  418. .disable = clk_disable_regmap,
  419. .get_parent = clk_rcg_get_parent,
  420. .set_parent = clk_rcg_set_parent,
  421. .recalc_rate = clk_rcg_recalc_rate,
  422. .determine_rate = clk_rcg_determine_rate,
  423. .set_rate = clk_rcg_set_rate,
  424. };
  425. EXPORT_SYMBOL_GPL(clk_rcg_ops);
  426. const struct clk_ops clk_rcg_bypass_ops = {
  427. .enable = clk_enable_regmap,
  428. .disable = clk_disable_regmap,
  429. .get_parent = clk_rcg_get_parent,
  430. .set_parent = clk_rcg_set_parent,
  431. .recalc_rate = clk_rcg_recalc_rate,
  432. .determine_rate = clk_rcg_bypass_determine_rate,
  433. .set_rate = clk_rcg_bypass_set_rate,
  434. };
  435. EXPORT_SYMBOL_GPL(clk_rcg_bypass_ops);
  436. const struct clk_ops clk_dyn_rcg_ops = {
  437. .enable = clk_enable_regmap,
  438. .is_enabled = clk_is_enabled_regmap,
  439. .disable = clk_disable_regmap,
  440. .get_parent = clk_dyn_rcg_get_parent,
  441. .set_parent = clk_dyn_rcg_set_parent,
  442. .recalc_rate = clk_dyn_rcg_recalc_rate,
  443. .determine_rate = clk_dyn_rcg_determine_rate,
  444. .set_rate = clk_dyn_rcg_set_rate,
  445. .set_rate_and_parent = clk_dyn_rcg_set_rate_and_parent,
  446. };
  447. EXPORT_SYMBOL_GPL(clk_dyn_rcg_ops);