clk-mt6735-pll.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984
  1. /*
  2. * Copyright (c) 2014 MediaTek Inc.
  3. * Author: James Liao <jamesjj.liao@mediatek.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include <linux/io.h>
  15. #include <linux/slab.h>
  16. #include <linux/delay.h>
  17. #include <linux/clkdev.h>
  18. #include "clk-mtk-v1.h"
  19. #include "clk-pll-v1.h"
  20. #include "clk-mt6735-pll.h"
  21. #if !defined(MT_CCF_DEBUG) || !defined(MT_CCF_BRINGUP)
  22. #define MT_CCF_DEBUG 0
  23. #define MT_CCF_BRINGUP 0
  24. #endif
  25. #ifndef GENMASK
  26. #define GENMASK(h, l) (((U32_C(1) << ((h) - (l) + 1)) - 1) << (l))
  27. #endif
  28. /*
  29. * clk_pll
  30. */
  31. #define PLL_BASE_EN BIT(0)
  32. #define PLL_PWR_ON BIT(0)
  33. #define PLL_ISO_EN BIT(1)
  34. #define PLL_PCW_CHG BIT(31)
  35. #define RST_BAR_MASK BIT(24)
  36. #define AUDPLL_TUNER_EN BIT(31)
  37. static const u32 pll_posdiv_map[8] = { 1, 2, 4, 8, 16, 16, 16, 16 };
  38. static u32 calc_pll_vco_freq(
  39. u32 fin,
  40. u32 pcw,
  41. u32 vcodivsel,
  42. u32 prediv,
  43. u32 pcwfbits)
  44. {
  45. /* vco = (fin * pcw * vcodivsel / prediv) >> pcwfbits; */
  46. u64 vco = fin;
  47. u8 c = 0;
  48. vco = vco * pcw * vcodivsel;
  49. do_div(vco, prediv);
  50. if (vco & GENMASK(pcwfbits - 1, 0))
  51. c = 1;
  52. vco >>= pcwfbits;
  53. if (c)
  54. ++vco;
  55. return (u32)vco;
  56. }
  57. static u32 freq_limit(u32 freq)
  58. {
  59. static const u64 freq_max = 3000UL * 1000 * 1000; /* 3000 MHz */
  60. static const u32 freq_min = 1000 * 1000 * 1000 / 16; /* 62.5 MHz */
  61. if (freq <= freq_min)
  62. freq = freq_min + 16;
  63. else if (freq > freq_max)
  64. freq = freq_max;
  65. return freq;
  66. }
  67. static int calc_pll_freq_cfg(
  68. u32 *pcw,
  69. u32 *postdiv_idx,
  70. u32 freq,
  71. u32 fin,
  72. int pcwfbits)
  73. {
  74. static const u64 freq_max = 3000UL * 1000 * 1000; /* 3000 MHz */
  75. static const u64 freq_min = 1000 * 1000 * 1000; /* 1000 MHz */
  76. static const u64 postdiv[] = { 1, 2, 4, 8, 16 };
  77. u64 n_info;
  78. u32 idx;
  79. #if MT_CCF_DEBUG
  80. pr_debug("freq: %u\n", freq);
  81. #endif
  82. /* search suitable postdiv */
  83. for (idx = *postdiv_idx;
  84. idx < ARRAY_SIZE(postdiv) && postdiv[idx] * freq <= freq_min;
  85. idx++)
  86. ;
  87. if (idx >= ARRAY_SIZE(postdiv))
  88. return -EINVAL; /* freq is out of range (too low) */
  89. else if (postdiv[idx] * freq > freq_max)
  90. return -EINVAL; /* freq is out of range (too high) */
  91. /* n_info = freq * postdiv / 26MHz * 2^pcwfbits */
  92. n_info = (postdiv[idx] * freq) << pcwfbits;
  93. do_div(n_info, fin);
  94. *postdiv_idx = idx;
  95. *pcw = (u32)n_info;
  96. return 0;
  97. }
  98. static int clk_pll_is_enabled(struct clk_hw *hw)
  99. {
  100. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  101. int r;
  102. #if MT_CCF_BRINGUP
  103. pr_debug("[CCF] %s: %s: S\n", __func__, __clk_get_name(hw->clk));
  104. return 1;
  105. #endif /* MT_CCF_BRINGUP */
  106. r = (readl_relaxed(pll->base_addr) & PLL_BASE_EN) != 0;
  107. #if MT_CCF_DEBUG
  108. pr_debug("[CCF] %s:%d: %s\n", __func__, r, __clk_get_name(hw->clk));
  109. #endif /* MT_CCF_DEBUG */
  110. return r;
  111. }
  112. static int clk_pll_enable(struct clk_hw *hw)
  113. {
  114. unsigned long flags = 0;
  115. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  116. u32 r;
  117. #if MT_CCF_DEBUG
  118. pr_debug("[CCF] %s: %s: S\n", __func__, __clk_get_name(hw->clk));
  119. #endif /* MT_CCF_DEBUG */
  120. #if MT_CCF_BRINGUP
  121. return 0;
  122. #endif /* MT_CCF_BRINGUP */
  123. mtk_clk_lock(flags);
  124. r = readl_relaxed(pll->pwr_addr) | PLL_PWR_ON;
  125. writel_relaxed(r, pll->pwr_addr);
  126. wmb(); /* sync write before delay */
  127. udelay(1);
  128. r = readl_relaxed(pll->pwr_addr) & ~PLL_ISO_EN;
  129. writel_relaxed(r , pll->pwr_addr);
  130. wmb(); /* sync write before delay */
  131. udelay(1);
  132. r = readl_relaxed(pll->base_addr) | pll->en_mask;
  133. writel_relaxed(r, pll->base_addr);
  134. wmb(); /* sync write before delay */
  135. udelay(20);
  136. if (pll->flags & HAVE_RST_BAR) {
  137. r = readl_relaxed(pll->base_addr) | RST_BAR_MASK;
  138. writel_relaxed(r, pll->base_addr);
  139. }
  140. mtk_clk_unlock(flags);
  141. return 0;
  142. }
  143. static void clk_pll_disable(struct clk_hw *hw)
  144. {
  145. unsigned long flags = 0;
  146. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  147. u32 r;
  148. #if MT_CCF_DEBUG
  149. pr_debug("[CCF] %s: %s: flags=%u, PLL_AO: %d\n", __func__,
  150. __clk_get_name(hw->clk), pll->flags, !!(pll->flags & PLL_AO));
  151. #endif /* MT_CCF_DEBUG */
  152. #if MT_CCF_BRINGUP
  153. return;
  154. #endif /* MT_CCF_BRINGUP */
  155. if (pll->flags & PLL_AO)
  156. return;
  157. mtk_clk_lock(flags);
  158. if (pll->flags & HAVE_RST_BAR) {
  159. r = readl_relaxed(pll->base_addr) & ~RST_BAR_MASK;
  160. writel_relaxed(r, pll->base_addr);
  161. }
  162. r = readl_relaxed(pll->base_addr) & ~PLL_BASE_EN;
  163. writel_relaxed(r, pll->base_addr);
  164. r = readl_relaxed(pll->pwr_addr) | PLL_ISO_EN;
  165. writel_relaxed(r, pll->pwr_addr);
  166. r = readl_relaxed(pll->pwr_addr) & ~PLL_PWR_ON;
  167. writel_relaxed(r, pll->pwr_addr);
  168. mtk_clk_unlock(flags);
  169. }
  170. static long clk_pll_round_rate(
  171. struct clk_hw *hw,
  172. unsigned long rate,
  173. unsigned long *prate)
  174. {
  175. u32 pcwfbits = 14;
  176. u32 pcw = 0;
  177. u32 postdiv = 0;
  178. u32 r;
  179. #if MT_CCF_DEBUG
  180. pr_debug("[CCF] %s: %s: rate=%lu\n", __func__, __clk_get_name(hw->clk),
  181. rate);
  182. #endif
  183. #if MT_CCF_BRINGUP
  184. return 0;
  185. #endif /* MT_CCF_BRINGUP */
  186. *prate = *prate ? *prate : 26000000;
  187. rate = freq_limit(rate);
  188. calc_pll_freq_cfg(&pcw, &postdiv, rate, *prate, pcwfbits);
  189. r = calc_pll_vco_freq(*prate, pcw, 1, 1, pcwfbits);
  190. r = (r + pll_posdiv_map[postdiv] - 1) / pll_posdiv_map[postdiv];
  191. return r;
  192. }
  193. #define SDM_PLL_POSTDIV_H 6
  194. #define SDM_PLL_POSTDIV_L 4
  195. #define SDM_PLL_POSTDIV_MASK GENMASK(SDM_PLL_POSTDIV_H, SDM_PLL_POSTDIV_L)
  196. #define SDM_PLL_PCW_H 20
  197. #define SDM_PLL_PCW_L 0
  198. #define SDM_PLL_PCW_MASK GENMASK(SDM_PLL_PCW_H, SDM_PLL_PCW_L)
  199. static unsigned long clk_sdm_pll_recalc_rate(
  200. struct clk_hw *hw,
  201. unsigned long parent_rate)
  202. {
  203. #if MT_CCF_BRINGUP
  204. pr_debug("[CCF] %s: %s: parent_rate=%lu\n", __func__,
  205. __clk_get_name(hw->clk), parent_rate);
  206. return 0;
  207. #endif /* MT_CCF_BRINGUP */
  208. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  209. u32 con0 = readl_relaxed(pll->base_addr);
  210. u32 con1 = readl_relaxed(pll->base_addr + 4);
  211. u32 posdiv = (con0 & SDM_PLL_POSTDIV_MASK) >> SDM_PLL_POSTDIV_L;
  212. u32 pcw = (con1 & SDM_PLL_PCW_MASK) >> SDM_PLL_PCW_L;
  213. u32 pcwfbits = 14;
  214. u32 vco_freq;
  215. unsigned long r;
  216. parent_rate = parent_rate ? parent_rate : 26000000;
  217. vco_freq = calc_pll_vco_freq(parent_rate, pcw, 1, 1, pcwfbits);
  218. r = (vco_freq + pll_posdiv_map[posdiv] - 1) / pll_posdiv_map[posdiv];
  219. #if MT_CCF_DEBUG
  220. pr_debug("[CCF] %s: %lu: %s\n", __func__, r, __clk_get_name(hw->clk));
  221. #endif
  222. return r;
  223. }
  224. static void clk_sdm_pll_set_rate_regs(
  225. struct clk_hw *hw,
  226. u32 pcw,
  227. u32 postdiv_idx)
  228. {
  229. unsigned long flags = 0;
  230. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  231. void __iomem *con0_addr = pll->base_addr;
  232. void __iomem *con1_addr = pll->base_addr + 4;
  233. u32 con0;
  234. u32 con1;
  235. u32 pll_en;
  236. mtk_clk_lock(flags);
  237. con0 = readl_relaxed(con0_addr);
  238. con1 = readl_relaxed(con1_addr);
  239. pll_en = con0 & PLL_BASE_EN;
  240. /* set postdiv */
  241. con0 &= ~SDM_PLL_POSTDIV_MASK;
  242. con0 |= postdiv_idx << SDM_PLL_POSTDIV_L;
  243. writel_relaxed(con0, con0_addr);
  244. /* set pcw */
  245. con1 &= ~SDM_PLL_PCW_MASK;
  246. con1 |= pcw << SDM_PLL_PCW_L;
  247. if (pll_en)
  248. con1 |= PLL_PCW_CHG;
  249. writel_relaxed(con1, con1_addr);
  250. if (pll_en) {
  251. wmb(); /* sync write before delay */
  252. udelay(20);
  253. }
  254. mtk_clk_unlock(flags);
  255. }
  256. static int clk_sdm_pll_set_rate(
  257. struct clk_hw *hw,
  258. unsigned long rate,
  259. unsigned long parent_rate)
  260. {
  261. u32 pcwfbits = 14;
  262. u32 pcw = 0;
  263. u32 postdiv_idx = 0;
  264. int r;
  265. #if MT_CCF_BRINGUP
  266. pr_debug("[CCF] %s: %s: S\n", __func__, __clk_get_name(hw->clk));
  267. return 0;
  268. #endif /* MT_CCF_BRINGUP */
  269. parent_rate = parent_rate ? parent_rate : 26000000;
  270. r = calc_pll_freq_cfg(&pcw, &postdiv_idx, rate, parent_rate, pcwfbits);
  271. #if MT_CCF_DEBUG
  272. pr_debug("[CCF] %s: %s, rate: %lu, pcw: %u, postdiv_idx: %u\n",
  273. __func__, __clk_get_name(hw->clk), rate, pcw, postdiv_idx);
  274. #endif
  275. if (r == 0)
  276. clk_sdm_pll_set_rate_regs(hw, pcw, postdiv_idx);
  277. return r;
  278. }
  279. const struct clk_ops mt_clk_sdm_pll_ops = {
  280. .is_enabled = clk_pll_is_enabled,
  281. .enable = clk_pll_enable,
  282. .disable = clk_pll_disable,
  283. .recalc_rate = clk_sdm_pll_recalc_rate,
  284. .round_rate = clk_pll_round_rate,
  285. .set_rate = clk_sdm_pll_set_rate,
  286. };
  287. #define ARM_PLL_POSTDIV_H 26
  288. #define ARM_PLL_POSTDIV_L 24
  289. #define ARM_PLL_POSTDIV_MASK GENMASK(ARM_PLL_POSTDIV_H, ARM_PLL_POSTDIV_L)
  290. #define ARM_PLL_PCW_H 20
  291. #define ARM_PLL_PCW_L 0
  292. #define ARM_PLL_PCW_MASK GENMASK(ARM_PLL_PCW_H, ARM_PLL_PCW_L)
  293. static unsigned long clk_arm_pll_recalc_rate(
  294. struct clk_hw *hw,
  295. unsigned long parent_rate)
  296. {
  297. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  298. u32 con1 = readl_relaxed(pll->base_addr + 4);
  299. u32 posdiv = (con1 & ARM_PLL_POSTDIV_MASK) >> ARM_PLL_POSTDIV_L;
  300. u32 pcw = (con1 & ARM_PLL_PCW_MASK) >> ARM_PLL_PCW_L;
  301. u32 pcwfbits = 14;
  302. u32 vco_freq;
  303. unsigned long r;
  304. #if MT_CCF_BRINGUP
  305. pr_debug("[CCF] %s: %s: S\n", __func__, __clk_get_name(hw->clk));
  306. return 0;
  307. #endif /* MT_CCF_BRINGUP */
  308. parent_rate = parent_rate ? parent_rate : 26000000;
  309. vco_freq = calc_pll_vco_freq(parent_rate, pcw, 1, 1, pcwfbits);
  310. r = (vco_freq + pll_posdiv_map[posdiv] - 1) / pll_posdiv_map[posdiv];
  311. #if MT_CCF_DEBUG
  312. pr_debug("[CCF] %s: %lu: %s\n", __func__, r, __clk_get_name(hw->clk));
  313. #endif
  314. return r;
  315. }
  316. static void clk_arm_pll_set_rate_regs(
  317. struct clk_hw *hw,
  318. u32 pcw,
  319. u32 postdiv_idx)
  320. {
  321. unsigned long flags = 0;
  322. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  323. void __iomem *con0_addr = pll->base_addr;
  324. void __iomem *con1_addr = pll->base_addr + 4;
  325. u32 con0;
  326. u32 con1;
  327. u32 pll_en;
  328. mtk_clk_lock(flags);
  329. con0 = readl_relaxed(con0_addr);
  330. con1 = readl_relaxed(con1_addr);
  331. pll_en = con0 & PLL_BASE_EN;
  332. /* postdiv */
  333. con1 &= ~ARM_PLL_POSTDIV_MASK;
  334. con1 |= postdiv_idx << ARM_PLL_POSTDIV_L;
  335. /* pcw */
  336. con1 &= ~ARM_PLL_PCW_MASK;
  337. con1 |= pcw << ARM_PLL_PCW_L;
  338. if (pll_en)
  339. con1 |= PLL_PCW_CHG;
  340. writel_relaxed(con1, con1_addr);
  341. if (pll_en) {
  342. wmb(); /* sync write before delay */
  343. udelay(20);
  344. }
  345. mtk_clk_unlock(flags);
  346. }
  347. static int clk_arm_pll_set_rate(
  348. struct clk_hw *hw,
  349. unsigned long rate,
  350. unsigned long parent_rate)
  351. {
  352. u32 pcwfbits = 14;
  353. u32 pcw = 0;
  354. u32 postdiv_idx = 0;
  355. int r;
  356. #if MT_CCF_BRINGUP
  357. pr_debug("[CCF] %s: %s: S\n", __func__, __clk_get_name(hw->clk));
  358. return 0;
  359. #endif /* MT_CCF_BRINGUP */
  360. parent_rate = parent_rate ? parent_rate : 26000000;
  361. r = calc_pll_freq_cfg(&pcw, &postdiv_idx, rate, parent_rate, pcwfbits);
  362. #if MT_CCF_DEBUG
  363. pr_debug("[CCF] %s: %s, rate: %lu, pcw: %u, postdiv_idx: %u\n",
  364. __func__, __clk_get_name(hw->clk), rate, pcw, postdiv_idx);
  365. #endif
  366. if (r == 0)
  367. clk_arm_pll_set_rate_regs(hw, pcw, postdiv_idx);
  368. return r;
  369. }
  370. const struct clk_ops mt_clk_arm_pll_ops = {
  371. .is_enabled = clk_pll_is_enabled,
  372. .enable = clk_pll_enable,
  373. .disable = clk_pll_disable,
  374. .recalc_rate = clk_arm_pll_recalc_rate,
  375. .round_rate = clk_pll_round_rate,
  376. .set_rate = clk_arm_pll_set_rate,
  377. };
  378. static long clk_mm_pll_round_rate(
  379. struct clk_hw *hw,
  380. unsigned long rate,
  381. unsigned long *prate)
  382. {
  383. u32 pcwfbits = 14;
  384. u32 pcw = 0;
  385. u32 postdiv = 0;
  386. u32 r;
  387. #if MT_CCF_DEBUG
  388. pr_debug("[CCF] %s: %s: rate: %lu\n", __func__,
  389. __clk_get_name(hw->clk), rate);
  390. #endif
  391. #if MT_CCF_BRINGUP
  392. return 0;
  393. #endif /* MT_CCF_BRINGUP */
  394. if (rate <= 702000000)
  395. postdiv = 2;
  396. *prate = *prate ? *prate : 26000000;
  397. rate = freq_limit(rate);
  398. calc_pll_freq_cfg(&pcw, &postdiv, rate, *prate, pcwfbits);
  399. r = calc_pll_vco_freq(*prate, pcw, 1, 1, pcwfbits);
  400. r = (r + pll_posdiv_map[postdiv] - 1) / pll_posdiv_map[postdiv];
  401. return r;
  402. }
  403. static int clk_mm_pll_set_rate(
  404. struct clk_hw *hw,
  405. unsigned long rate,
  406. unsigned long parent_rate)
  407. {
  408. u32 pcwfbits = 14;
  409. u32 pcw = 0;
  410. u32 postdiv_idx = 0;
  411. int r;
  412. #if MT_CCF_BRINGUP
  413. pr_debug("[CCF] %s: %s: S\n", __func__, __clk_get_name(hw->clk));
  414. return 0;
  415. #endif /* MT_CCF_BRINGUP */
  416. if (rate <= 702000000)
  417. postdiv_idx = 2;
  418. parent_rate = parent_rate ? parent_rate : 26000000;
  419. r = calc_pll_freq_cfg(&pcw, &postdiv_idx, rate, parent_rate, pcwfbits);
  420. #if MT_CCF_DEBUG
  421. pr_debug("%s, rate: %lu, pcw: %u, postdiv_idx: %u\n",
  422. __clk_get_name(hw->clk), rate, pcw, postdiv_idx);
  423. #endif
  424. if (r == 0)
  425. clk_arm_pll_set_rate_regs(hw, pcw, postdiv_idx);
  426. return r;
  427. }
  428. const struct clk_ops mt_clk_mm_pll_ops = {
  429. .is_enabled = clk_pll_is_enabled,
  430. .enable = clk_pll_enable,
  431. .disable = clk_pll_disable,
  432. .recalc_rate = clk_arm_pll_recalc_rate,
  433. .round_rate = clk_mm_pll_round_rate,
  434. .set_rate = clk_mm_pll_set_rate,
  435. };
  436. static int clk_univ_pll_enable(struct clk_hw *hw)
  437. {
  438. unsigned long flags = 0;
  439. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  440. u32 r;
  441. #if MT_CCF_DEBUG
  442. pr_debug("[CCF] %s: %s: S\n", __func__, __clk_get_name(hw->clk));
  443. #endif
  444. #if MT_CCF_BRINGUP
  445. return 0;
  446. #endif /* MT_CCF_BRINGUP */
  447. mtk_clk_lock(flags);
  448. r = readl_relaxed(pll->base_addr) | pll->en_mask;
  449. writel_relaxed(r, pll->base_addr);
  450. wmb(); /* sync write before delay */
  451. udelay(20);
  452. if (pll->flags & HAVE_RST_BAR) {
  453. r = readl_relaxed(pll->base_addr) | RST_BAR_MASK;
  454. writel_relaxed(r, pll->base_addr);
  455. }
  456. mtk_clk_unlock(flags);
  457. return 0;
  458. }
  459. static void clk_univ_pll_disable(struct clk_hw *hw)
  460. {
  461. unsigned long flags = 0;
  462. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  463. u32 r;
  464. #if MT_CCF_BRINGUP
  465. pr_debug("[CCF] %s: %s: S\n", __func__, __clk_get_name(hw->clk));
  466. return;
  467. #endif /* MT_CCF_BRINGUP */
  468. #if MT_CCF_DEBUG
  469. pr_debug("%s: PLL_AO: %d\n",
  470. __clk_get_name(hw->clk), !!(pll->flags & PLL_AO));
  471. #endif
  472. if (pll->flags & PLL_AO)
  473. return;
  474. mtk_clk_lock(flags);
  475. if (pll->flags & HAVE_RST_BAR) {
  476. r = readl_relaxed(pll->base_addr) & ~RST_BAR_MASK;
  477. writel_relaxed(r, pll->base_addr);
  478. }
  479. r = readl_relaxed(pll->base_addr) & ~PLL_BASE_EN;
  480. writel_relaxed(r, pll->base_addr);
  481. mtk_clk_unlock(flags);
  482. }
  483. #define UNIV_PLL_POSTDIV_H 6
  484. #define UNIV_PLL_POSTDIV_L 4
  485. #define UNIV_PLL_POSTDIV_MASK GENMASK(UNIV_PLL_POSTDIV_H, UNIV_PLL_POSTDIV_L)
  486. #define UNIV_PLL_FBKDIV_H 20
  487. #define UNIV_PLL_FBKDIV_L 14
  488. #define UNIV_PLL_FBKDIV_MASK GENMASK(UNIV_PLL_FBKDIV_H, UNIV_PLL_FBKDIV_L)
  489. static unsigned long clk_univ_pll_recalc_rate(
  490. struct clk_hw *hw,
  491. unsigned long parent_rate)
  492. {
  493. #if MT_CCF_BRINGUP
  494. pr_debug("[CCF] %s: %s: S\n", __func__, __clk_get_name(hw->clk));
  495. return 0;
  496. #endif /* MT_CCF_BRINGUP */
  497. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  498. u32 con0 = readl_relaxed(pll->base_addr);
  499. u32 con1 = readl_relaxed(pll->base_addr + 4);
  500. u32 fbkdiv = (con1 & UNIV_PLL_FBKDIV_MASK) >> UNIV_PLL_FBKDIV_L;
  501. u32 posdiv = (con0 & UNIV_PLL_POSTDIV_MASK) >> UNIV_PLL_POSTDIV_L;
  502. u32 vco_freq;
  503. unsigned long r;
  504. parent_rate = parent_rate ? parent_rate : 26000000;
  505. vco_freq = parent_rate * fbkdiv;
  506. r = (vco_freq + pll_posdiv_map[posdiv] - 1) / pll_posdiv_map[posdiv];
  507. #if MT_CCF_DEBUG
  508. pr_debug("%lu: %s\n", r, __clk_get_name(hw->clk));
  509. #endif
  510. return r;
  511. }
  512. static void clk_univ_pll_set_rate_regs(
  513. struct clk_hw *hw,
  514. u32 pcw,
  515. u32 postdiv_idx)
  516. {
  517. unsigned long flags = 0;
  518. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  519. void __iomem *con0_addr = pll->base_addr;
  520. void __iomem *con1_addr = pll->base_addr + 4;
  521. u32 con0;
  522. u32 con1;
  523. u32 pll_en;
  524. mtk_clk_lock(flags);
  525. con0 = readl_relaxed(con0_addr);
  526. con1 = readl_relaxed(con1_addr);
  527. pll_en = con0 & PLL_BASE_EN;
  528. /* postdiv */
  529. con0 &= ~UNIV_PLL_POSTDIV_MASK;
  530. con0 |= postdiv_idx << UNIV_PLL_POSTDIV_L;
  531. /* fkbdiv */
  532. con1 &= ~UNIV_PLL_FBKDIV_MASK;
  533. con1 |= pcw << UNIV_PLL_FBKDIV_L;
  534. writel_relaxed(con0, con0_addr);
  535. writel_relaxed(con1, con1_addr);
  536. if (pll_en) {
  537. wmb(); /* sync write before delay */
  538. udelay(20);
  539. }
  540. mtk_clk_unlock(flags);
  541. }
  542. static long clk_univ_pll_round_rate(
  543. struct clk_hw *hw,
  544. unsigned long rate,
  545. unsigned long *prate)
  546. {
  547. u32 pcwfbits = 0;
  548. u32 pcw = 0;
  549. u32 postdiv = 0;
  550. u32 r;
  551. #if MT_CCF_DEBUG
  552. pr_debug("[CCF] %s: %s: rate: %lu\n", __func__,
  553. __clk_get_name(hw->clk), rate);
  554. #endif
  555. #if MT_CCF_BRINGUP
  556. return 0;
  557. #endif /* MT_CCF_BRINGUP */
  558. *prate = *prate ? *prate : 26000000;
  559. rate = freq_limit(rate);
  560. calc_pll_freq_cfg(&pcw, &postdiv, rate, *prate, pcwfbits);
  561. r = *prate * pcw;
  562. r = (r + pll_posdiv_map[postdiv] - 1) / pll_posdiv_map[postdiv];
  563. return r;
  564. }
  565. static int clk_univ_pll_set_rate(
  566. struct clk_hw *hw,
  567. unsigned long rate,
  568. unsigned long parent_rate)
  569. {
  570. u32 pcwfbits = 0;
  571. u32 pcw = 0;
  572. u32 postdiv_idx = 0;
  573. int r;
  574. #if MT_CCF_BRINGUP
  575. pr_debug("[CCF] %s: %s: S\n", __func__, __clk_get_name(hw->clk));
  576. return 0;
  577. #endif /* MT_CCF_BRINGUP */
  578. parent_rate = parent_rate ? parent_rate : 26000000;
  579. r = calc_pll_freq_cfg(&pcw, &postdiv_idx, rate, parent_rate, pcwfbits);
  580. #if MT_CCF_DEBUG
  581. pr_debug("%s, rate: %lu, pcw: %u, postdiv_idx: %u\n",
  582. __clk_get_name(hw->clk), rate, pcw, postdiv_idx);
  583. #endif
  584. if (r == 0)
  585. clk_univ_pll_set_rate_regs(hw, pcw, postdiv_idx);
  586. return r;
  587. }
  588. const struct clk_ops mt_clk_univ_pll_ops = {
  589. .is_enabled = clk_pll_is_enabled,
  590. .enable = clk_univ_pll_enable,
  591. .disable = clk_univ_pll_disable,
  592. .recalc_rate = clk_univ_pll_recalc_rate,
  593. .round_rate = clk_univ_pll_round_rate,
  594. .set_rate = clk_univ_pll_set_rate,
  595. };
  596. static int clk_aud_pll_enable(struct clk_hw *hw)
  597. {
  598. unsigned long flags = 0;
  599. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  600. u32 r;
  601. #if MT_CCF_DEBUG
  602. pr_debug("[CCF] %s: %s: S\n", __func__, __clk_get_name(hw->clk));
  603. #endif
  604. #if MT_CCF_BRINGUP
  605. return 0;
  606. #endif /* MT_CCF_BRINGUP */
  607. mtk_clk_lock(flags);
  608. r = readl_relaxed(pll->pwr_addr) | PLL_PWR_ON;
  609. writel_relaxed(r, pll->pwr_addr);
  610. wmb(); /* sync write before delay */
  611. udelay(1);
  612. r = readl_relaxed(pll->pwr_addr) & ~PLL_ISO_EN;
  613. writel_relaxed(r, pll->pwr_addr);
  614. wmb(); /* sync write before delay */
  615. udelay(1);
  616. r = readl_relaxed(pll->base_addr) | pll->en_mask;
  617. writel_relaxed(r, pll->base_addr);
  618. r = readl_relaxed(pll->base_addr + 16) | AUDPLL_TUNER_EN;
  619. writel_relaxed(r, pll->base_addr + 16);
  620. wmb(); /* sync write before delay */
  621. udelay(20);
  622. if (pll->flags & HAVE_RST_BAR) {
  623. r = readl_relaxed(pll->base_addr) | RST_BAR_MASK;
  624. writel_relaxed(r, pll->base_addr);
  625. }
  626. mtk_clk_unlock(flags);
  627. return 0;
  628. }
  629. static void clk_aud_pll_disable(struct clk_hw *hw)
  630. {
  631. unsigned long flags = 0;
  632. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  633. u32 r;
  634. #if MT_CCF_BRINGUP
  635. pr_debug("[CCF] %s: %s: S\n", __func__, __clk_get_name(hw->clk));
  636. return;
  637. #endif /* MT_CCF_BRINGUP */
  638. #if MT_CCF_DEBUG
  639. pr_debug("%s: PLL_AO: %d\n",
  640. __clk_get_name(hw->clk), !!(pll->flags & PLL_AO));
  641. #endif
  642. if (pll->flags & PLL_AO)
  643. return;
  644. mtk_clk_lock(flags);
  645. if (pll->flags & HAVE_RST_BAR) {
  646. r = readl_relaxed(pll->base_addr) & ~RST_BAR_MASK;
  647. writel_relaxed(r, pll->base_addr);
  648. }
  649. r = readl_relaxed(pll->base_addr + 8) & ~AUDPLL_TUNER_EN;
  650. writel_relaxed(r, pll->base_addr + 8);
  651. r = readl_relaxed(pll->base_addr) & ~PLL_BASE_EN;
  652. writel_relaxed(r, pll->base_addr);
  653. r = readl_relaxed(pll->pwr_addr) | PLL_ISO_EN;
  654. writel_relaxed(r, pll->pwr_addr);
  655. r = readl_relaxed(pll->pwr_addr) & ~PLL_PWR_ON;
  656. writel_relaxed(r, pll->pwr_addr);
  657. mtk_clk_unlock(flags);
  658. }
  659. #define AUD_PLL_POSTDIV_H 6
  660. #define AUD_PLL_POSTDIV_L 4
  661. #define AUD_PLL_POSTDIV_MASK GENMASK(AUD_PLL_POSTDIV_H, AUD_PLL_POSTDIV_L)
  662. #define AUD_PLL_PCW_H 30
  663. #define AUD_PLL_PCW_L 0
  664. #define AUD_PLL_PCW_MASK GENMASK(AUD_PLL_PCW_H, AUD_PLL_PCW_L)
  665. static unsigned long clk_aud_pll_recalc_rate(
  666. struct clk_hw *hw,
  667. unsigned long parent_rate)
  668. {
  669. #if MT_CCF_BRINGUP
  670. pr_debug("[CCF] %s: %s: S\n", __func__, __clk_get_name(hw->clk));
  671. return 0;
  672. #endif /* MT_CCF_BRINGUP */
  673. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  674. u32 con0 = readl_relaxed(pll->base_addr);
  675. u32 con1 = readl_relaxed(pll->base_addr + 4);
  676. u32 posdiv = (con0 & AUD_PLL_POSTDIV_MASK) >> AUD_PLL_POSTDIV_L;
  677. u32 pcw = (con1 & AUD_PLL_PCW_MASK) >> AUD_PLL_PCW_L;
  678. u32 pcwfbits = 24;
  679. u32 vco_freq;
  680. unsigned long r;
  681. parent_rate = parent_rate ? parent_rate : 26000000;
  682. vco_freq = calc_pll_vco_freq(parent_rate, pcw, 1, 1, pcwfbits);
  683. r = (vco_freq + pll_posdiv_map[posdiv] - 1) / pll_posdiv_map[posdiv];
  684. #if MT_CCF_DEBUG
  685. pr_debug("%lu: %s\n", r, __clk_get_name(hw->clk));
  686. #endif
  687. return r;
  688. }
  689. static void clk_aud_pll_set_rate_regs(
  690. struct clk_hw *hw,
  691. u32 pcw,
  692. u32 postdiv_idx)
  693. {
  694. unsigned long flags = 0;
  695. struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
  696. void __iomem *con0_addr = pll->base_addr;
  697. void __iomem *con1_addr = pll->base_addr + 4;
  698. void __iomem *con2_addr = pll->base_addr + 8;
  699. u32 con0;
  700. u32 con1;
  701. u32 pll_en;
  702. mtk_clk_lock(flags);
  703. con0 = readl_relaxed(con0_addr);
  704. con1 = readl_relaxed(con1_addr);
  705. pll_en = con0 & PLL_BASE_EN;
  706. /* set postdiv */
  707. con0 &= ~AUD_PLL_POSTDIV_MASK;
  708. con0 |= postdiv_idx << AUD_PLL_POSTDIV_L;
  709. writel_relaxed(con0, con0_addr);
  710. /* set pcw */
  711. con1 &= ~AUD_PLL_PCW_MASK;
  712. con1 |= pcw << AUD_PLL_PCW_L;
  713. if (pll_en)
  714. con1 |= PLL_PCW_CHG;
  715. writel_relaxed(con1, con1_addr);
  716. writel_relaxed(con1 + 1, con2_addr);
  717. if (pll_en) {
  718. wmb(); /* sync write before delay */
  719. udelay(20);
  720. }
  721. mtk_clk_unlock(flags);
  722. }
  723. static long clk_aud_pll_round_rate(
  724. struct clk_hw *hw,
  725. unsigned long rate,
  726. unsigned long *prate)
  727. {
  728. u32 pcwfbits = 24;
  729. u32 pcw = 0;
  730. u32 postdiv = 0;
  731. u32 r;
  732. #if MT_CCF_DEBUG
  733. pr_debug("[CCF] %s: %s: rate: %lu\n", __func__,
  734. __clk_get_name(hw->clk), rate);
  735. #endif
  736. #if MT_CCF_BRINGUP
  737. return 0;
  738. #endif /* MT_CCF_BRINGUP */
  739. *prate = *prate ? *prate : 26000000;
  740. rate = freq_limit(rate);
  741. calc_pll_freq_cfg(&pcw, &postdiv, rate, *prate, pcwfbits);
  742. r = calc_pll_vco_freq(*prate, pcw, 1, 1, pcwfbits);
  743. r = (r + pll_posdiv_map[postdiv] - 1) / pll_posdiv_map[postdiv];
  744. return r;
  745. }
  746. static int clk_aud_pll_set_rate(
  747. struct clk_hw *hw,
  748. unsigned long rate,
  749. unsigned long parent_rate)
  750. {
  751. u32 pcwfbits = 24;
  752. u32 pcw = 0;
  753. u32 postdiv_idx = 0;
  754. int r;
  755. #if MT_CCF_BRINGUP
  756. pr_debug("[CCF] %s: %s: rate=%lu, parent_rate=%lu\n", __func__,
  757. __clk_get_name(hw->clk), rate, parent_rate);
  758. return 0;
  759. #endif /* MT_CCF_BRINGUP */
  760. parent_rate = parent_rate ? parent_rate : 26000000;
  761. r = calc_pll_freq_cfg(&pcw, &postdiv_idx, rate, parent_rate, pcwfbits);
  762. #if MT_CCF_DEBUG
  763. pr_debug("%s, rate: %lu, pcw: %u, postdiv_idx: %u\n",
  764. __clk_get_name(hw->clk), rate, pcw, postdiv_idx);
  765. #endif
  766. if (r == 0)
  767. clk_aud_pll_set_rate_regs(hw, pcw, postdiv_idx);
  768. return r;
  769. }
  770. const struct clk_ops mt_clk_aud_pll_ops = {
  771. .is_enabled = clk_pll_is_enabled,
  772. .enable = clk_aud_pll_enable,
  773. .disable = clk_aud_pll_disable,
  774. .recalc_rate = clk_aud_pll_recalc_rate,
  775. .round_rate = clk_aud_pll_round_rate,
  776. .set_rate = clk_aud_pll_set_rate,
  777. };