clk-pll.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298
  1. /*
  2. * Copyright (c) 2013 Samsung Electronics Co., Ltd.
  3. * Copyright (c) 2013 Linaro Ltd.
  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 file contains the utility functions to register the pll clocks.
  10. */
  11. #include <linux/errno.h>
  12. #include <linux/hrtimer.h>
  13. #include <linux/delay.h>
  14. #include "clk.h"
  15. #include "clk-pll.h"
  16. #define PLL_TIMEOUT_MS 10
  17. struct samsung_clk_pll {
  18. struct clk_hw hw;
  19. void __iomem *lock_reg;
  20. void __iomem *con_reg;
  21. enum samsung_pll_type type;
  22. unsigned int rate_count;
  23. const struct samsung_pll_rate_table *rate_table;
  24. };
  25. #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
  26. static const struct samsung_pll_rate_table *samsung_get_pll_settings(
  27. struct samsung_clk_pll *pll, unsigned long rate)
  28. {
  29. const struct samsung_pll_rate_table *rate_table = pll->rate_table;
  30. int i;
  31. for (i = 0; i < pll->rate_count; i++) {
  32. if (rate == rate_table[i].rate)
  33. return &rate_table[i];
  34. }
  35. return NULL;
  36. }
  37. static long samsung_pll_round_rate(struct clk_hw *hw,
  38. unsigned long drate, unsigned long *prate)
  39. {
  40. struct samsung_clk_pll *pll = to_clk_pll(hw);
  41. const struct samsung_pll_rate_table *rate_table = pll->rate_table;
  42. int i;
  43. /* Assumming rate_table is in descending order */
  44. for (i = 0; i < pll->rate_count; i++) {
  45. if (drate >= rate_table[i].rate)
  46. return rate_table[i].rate;
  47. }
  48. /* return minimum supported value */
  49. return rate_table[i - 1].rate;
  50. }
  51. /*
  52. * PLL2126 Clock Type
  53. */
  54. #define PLL2126_MDIV_MASK (0xff)
  55. #define PLL2126_PDIV_MASK (0x3f)
  56. #define PLL2126_SDIV_MASK (0x3)
  57. #define PLL2126_MDIV_SHIFT (16)
  58. #define PLL2126_PDIV_SHIFT (8)
  59. #define PLL2126_SDIV_SHIFT (0)
  60. static unsigned long samsung_pll2126_recalc_rate(struct clk_hw *hw,
  61. unsigned long parent_rate)
  62. {
  63. struct samsung_clk_pll *pll = to_clk_pll(hw);
  64. u32 pll_con, mdiv, pdiv, sdiv;
  65. u64 fvco = parent_rate;
  66. pll_con = __raw_readl(pll->con_reg);
  67. mdiv = (pll_con >> PLL2126_MDIV_SHIFT) & PLL2126_MDIV_MASK;
  68. pdiv = (pll_con >> PLL2126_PDIV_SHIFT) & PLL2126_PDIV_MASK;
  69. sdiv = (pll_con >> PLL2126_SDIV_SHIFT) & PLL2126_SDIV_MASK;
  70. fvco *= (mdiv + 8);
  71. do_div(fvco, (pdiv + 2) << sdiv);
  72. return (unsigned long)fvco;
  73. }
  74. static const struct clk_ops samsung_pll2126_clk_ops = {
  75. .recalc_rate = samsung_pll2126_recalc_rate,
  76. };
  77. /*
  78. * PLL3000 Clock Type
  79. */
  80. #define PLL3000_MDIV_MASK (0xff)
  81. #define PLL3000_PDIV_MASK (0x3)
  82. #define PLL3000_SDIV_MASK (0x3)
  83. #define PLL3000_MDIV_SHIFT (16)
  84. #define PLL3000_PDIV_SHIFT (8)
  85. #define PLL3000_SDIV_SHIFT (0)
  86. static unsigned long samsung_pll3000_recalc_rate(struct clk_hw *hw,
  87. unsigned long parent_rate)
  88. {
  89. struct samsung_clk_pll *pll = to_clk_pll(hw);
  90. u32 pll_con, mdiv, pdiv, sdiv;
  91. u64 fvco = parent_rate;
  92. pll_con = __raw_readl(pll->con_reg);
  93. mdiv = (pll_con >> PLL3000_MDIV_SHIFT) & PLL3000_MDIV_MASK;
  94. pdiv = (pll_con >> PLL3000_PDIV_SHIFT) & PLL3000_PDIV_MASK;
  95. sdiv = (pll_con >> PLL3000_SDIV_SHIFT) & PLL3000_SDIV_MASK;
  96. fvco *= (2 * (mdiv + 8));
  97. do_div(fvco, pdiv << sdiv);
  98. return (unsigned long)fvco;
  99. }
  100. static const struct clk_ops samsung_pll3000_clk_ops = {
  101. .recalc_rate = samsung_pll3000_recalc_rate,
  102. };
  103. /*
  104. * PLL35xx Clock Type
  105. */
  106. /* Maximum lock time can be 270 * PDIV cycles */
  107. #define PLL35XX_LOCK_FACTOR (270)
  108. #define PLL35XX_MDIV_MASK (0x3FF)
  109. #define PLL35XX_PDIV_MASK (0x3F)
  110. #define PLL35XX_SDIV_MASK (0x7)
  111. #define PLL35XX_LOCK_STAT_MASK (0x1)
  112. #define PLL35XX_MDIV_SHIFT (16)
  113. #define PLL35XX_PDIV_SHIFT (8)
  114. #define PLL35XX_SDIV_SHIFT (0)
  115. #define PLL35XX_LOCK_STAT_SHIFT (29)
  116. static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
  117. unsigned long parent_rate)
  118. {
  119. struct samsung_clk_pll *pll = to_clk_pll(hw);
  120. u32 mdiv, pdiv, sdiv, pll_con;
  121. u64 fvco = parent_rate;
  122. pll_con = __raw_readl(pll->con_reg);
  123. mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
  124. pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
  125. sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK;
  126. fvco *= mdiv;
  127. do_div(fvco, (pdiv << sdiv));
  128. return (unsigned long)fvco;
  129. }
  130. static inline bool samsung_pll35xx_mp_change(
  131. const struct samsung_pll_rate_table *rate, u32 pll_con)
  132. {
  133. u32 old_mdiv, old_pdiv;
  134. old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
  135. old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
  136. return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
  137. }
  138. static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
  139. unsigned long prate)
  140. {
  141. struct samsung_clk_pll *pll = to_clk_pll(hw);
  142. const struct samsung_pll_rate_table *rate;
  143. u32 tmp;
  144. /* Get required rate settings from table */
  145. rate = samsung_get_pll_settings(pll, drate);
  146. if (!rate) {
  147. pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
  148. drate, __clk_get_name(hw->clk));
  149. return -EINVAL;
  150. }
  151. tmp = __raw_readl(pll->con_reg);
  152. if (!(samsung_pll35xx_mp_change(rate, tmp))) {
  153. /* If only s change, change just s value only*/
  154. tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
  155. tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
  156. __raw_writel(tmp, pll->con_reg);
  157. return 0;
  158. }
  159. /* Set PLL lock time. */
  160. __raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
  161. pll->lock_reg);
  162. /* Change PLL PMS values */
  163. tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
  164. (PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
  165. (PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
  166. tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
  167. (rate->pdiv << PLL35XX_PDIV_SHIFT) |
  168. (rate->sdiv << PLL35XX_SDIV_SHIFT);
  169. __raw_writel(tmp, pll->con_reg);
  170. /* wait_lock_time */
  171. do {
  172. cpu_relax();
  173. tmp = __raw_readl(pll->con_reg);
  174. } while (!(tmp & (PLL35XX_LOCK_STAT_MASK
  175. << PLL35XX_LOCK_STAT_SHIFT)));
  176. return 0;
  177. }
  178. static const struct clk_ops samsung_pll35xx_clk_ops = {
  179. .recalc_rate = samsung_pll35xx_recalc_rate,
  180. .round_rate = samsung_pll_round_rate,
  181. .set_rate = samsung_pll35xx_set_rate,
  182. };
  183. static const struct clk_ops samsung_pll35xx_clk_min_ops = {
  184. .recalc_rate = samsung_pll35xx_recalc_rate,
  185. };
  186. /*
  187. * PLL36xx Clock Type
  188. */
  189. /* Maximum lock time can be 3000 * PDIV cycles */
  190. #define PLL36XX_LOCK_FACTOR (3000)
  191. #define PLL36XX_KDIV_MASK (0xFFFF)
  192. #define PLL36XX_MDIV_MASK (0x1FF)
  193. #define PLL36XX_PDIV_MASK (0x3F)
  194. #define PLL36XX_SDIV_MASK (0x7)
  195. #define PLL36XX_MDIV_SHIFT (16)
  196. #define PLL36XX_PDIV_SHIFT (8)
  197. #define PLL36XX_SDIV_SHIFT (0)
  198. #define PLL36XX_KDIV_SHIFT (0)
  199. #define PLL36XX_LOCK_STAT_SHIFT (29)
  200. static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
  201. unsigned long parent_rate)
  202. {
  203. struct samsung_clk_pll *pll = to_clk_pll(hw);
  204. u32 mdiv, pdiv, sdiv, pll_con0, pll_con1;
  205. s16 kdiv;
  206. u64 fvco = parent_rate;
  207. pll_con0 = __raw_readl(pll->con_reg);
  208. pll_con1 = __raw_readl(pll->con_reg + 4);
  209. mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
  210. pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
  211. sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK;
  212. kdiv = (s16)(pll_con1 & PLL36XX_KDIV_MASK);
  213. fvco *= (mdiv << 16) + kdiv;
  214. do_div(fvco, (pdiv << sdiv));
  215. fvco >>= 16;
  216. return (unsigned long)fvco;
  217. }
  218. static inline bool samsung_pll36xx_mpk_change(
  219. const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
  220. {
  221. u32 old_mdiv, old_pdiv, old_kdiv;
  222. old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
  223. old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
  224. old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
  225. return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
  226. rate->kdiv != old_kdiv);
  227. }
  228. static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
  229. unsigned long parent_rate)
  230. {
  231. struct samsung_clk_pll *pll = to_clk_pll(hw);
  232. u32 tmp, pll_con0, pll_con1;
  233. const struct samsung_pll_rate_table *rate;
  234. rate = samsung_get_pll_settings(pll, drate);
  235. if (!rate) {
  236. pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
  237. drate, __clk_get_name(hw->clk));
  238. return -EINVAL;
  239. }
  240. pll_con0 = __raw_readl(pll->con_reg);
  241. pll_con1 = __raw_readl(pll->con_reg + 4);
  242. if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
  243. /* If only s change, change just s value only*/
  244. pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
  245. pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
  246. __raw_writel(pll_con0, pll->con_reg);
  247. return 0;
  248. }
  249. /* Set PLL lock time. */
  250. __raw_writel(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
  251. /* Change PLL PMS values */
  252. pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
  253. (PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
  254. (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
  255. pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
  256. (rate->pdiv << PLL36XX_PDIV_SHIFT) |
  257. (rate->sdiv << PLL36XX_SDIV_SHIFT);
  258. __raw_writel(pll_con0, pll->con_reg);
  259. pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
  260. pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
  261. __raw_writel(pll_con1, pll->con_reg + 4);
  262. /* wait_lock_time */
  263. do {
  264. cpu_relax();
  265. tmp = __raw_readl(pll->con_reg);
  266. } while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
  267. return 0;
  268. }
  269. static const struct clk_ops samsung_pll36xx_clk_ops = {
  270. .recalc_rate = samsung_pll36xx_recalc_rate,
  271. .set_rate = samsung_pll36xx_set_rate,
  272. .round_rate = samsung_pll_round_rate,
  273. };
  274. static const struct clk_ops samsung_pll36xx_clk_min_ops = {
  275. .recalc_rate = samsung_pll36xx_recalc_rate,
  276. };
  277. /*
  278. * PLL45xx Clock Type
  279. */
  280. #define PLL4502_LOCK_FACTOR 400
  281. #define PLL4508_LOCK_FACTOR 240
  282. #define PLL45XX_MDIV_MASK (0x3FF)
  283. #define PLL45XX_PDIV_MASK (0x3F)
  284. #define PLL45XX_SDIV_MASK (0x7)
  285. #define PLL45XX_AFC_MASK (0x1F)
  286. #define PLL45XX_MDIV_SHIFT (16)
  287. #define PLL45XX_PDIV_SHIFT (8)
  288. #define PLL45XX_SDIV_SHIFT (0)
  289. #define PLL45XX_AFC_SHIFT (0)
  290. #define PLL45XX_ENABLE BIT(31)
  291. #define PLL45XX_LOCKED BIT(29)
  292. static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
  293. unsigned long parent_rate)
  294. {
  295. struct samsung_clk_pll *pll = to_clk_pll(hw);
  296. u32 mdiv, pdiv, sdiv, pll_con;
  297. u64 fvco = parent_rate;
  298. pll_con = __raw_readl(pll->con_reg);
  299. mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
  300. pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
  301. sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
  302. if (pll->type == pll_4508)
  303. sdiv = sdiv - 1;
  304. fvco *= mdiv;
  305. do_div(fvco, (pdiv << sdiv));
  306. return (unsigned long)fvco;
  307. }
  308. static bool samsung_pll45xx_mp_change(u32 pll_con0, u32 pll_con1,
  309. const struct samsung_pll_rate_table *rate)
  310. {
  311. u32 old_mdiv, old_pdiv, old_afc;
  312. old_mdiv = (pll_con0 >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
  313. old_pdiv = (pll_con0 >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
  314. old_afc = (pll_con1 >> PLL45XX_AFC_SHIFT) & PLL45XX_AFC_MASK;
  315. return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
  316. || old_afc != rate->afc);
  317. }
  318. static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
  319. unsigned long prate)
  320. {
  321. struct samsung_clk_pll *pll = to_clk_pll(hw);
  322. const struct samsung_pll_rate_table *rate;
  323. u32 con0, con1;
  324. ktime_t start;
  325. /* Get required rate settings from table */
  326. rate = samsung_get_pll_settings(pll, drate);
  327. if (!rate) {
  328. pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
  329. drate, __clk_get_name(hw->clk));
  330. return -EINVAL;
  331. }
  332. con0 = __raw_readl(pll->con_reg);
  333. con1 = __raw_readl(pll->con_reg + 0x4);
  334. if (!(samsung_pll45xx_mp_change(con0, con1, rate))) {
  335. /* If only s change, change just s value only*/
  336. con0 &= ~(PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT);
  337. con0 |= rate->sdiv << PLL45XX_SDIV_SHIFT;
  338. __raw_writel(con0, pll->con_reg);
  339. return 0;
  340. }
  341. /* Set PLL PMS values. */
  342. con0 &= ~((PLL45XX_MDIV_MASK << PLL45XX_MDIV_SHIFT) |
  343. (PLL45XX_PDIV_MASK << PLL45XX_PDIV_SHIFT) |
  344. (PLL45XX_SDIV_MASK << PLL45XX_SDIV_SHIFT));
  345. con0 |= (rate->mdiv << PLL45XX_MDIV_SHIFT) |
  346. (rate->pdiv << PLL45XX_PDIV_SHIFT) |
  347. (rate->sdiv << PLL45XX_SDIV_SHIFT);
  348. /* Set PLL AFC value. */
  349. con1 = __raw_readl(pll->con_reg + 0x4);
  350. con1 &= ~(PLL45XX_AFC_MASK << PLL45XX_AFC_SHIFT);
  351. con1 |= (rate->afc << PLL45XX_AFC_SHIFT);
  352. /* Set PLL lock time. */
  353. switch (pll->type) {
  354. case pll_4502:
  355. __raw_writel(rate->pdiv * PLL4502_LOCK_FACTOR, pll->lock_reg);
  356. break;
  357. case pll_4508:
  358. __raw_writel(rate->pdiv * PLL4508_LOCK_FACTOR, pll->lock_reg);
  359. break;
  360. default:
  361. break;
  362. }
  363. /* Set new configuration. */
  364. __raw_writel(con1, pll->con_reg + 0x4);
  365. __raw_writel(con0, pll->con_reg);
  366. /* Wait for locking. */
  367. start = ktime_get();
  368. while (!(__raw_readl(pll->con_reg) & PLL45XX_LOCKED)) {
  369. ktime_t delta = ktime_sub(ktime_get(), start);
  370. if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
  371. pr_err("%s: could not lock PLL %s\n",
  372. __func__, __clk_get_name(hw->clk));
  373. return -EFAULT;
  374. }
  375. cpu_relax();
  376. }
  377. return 0;
  378. }
  379. static const struct clk_ops samsung_pll45xx_clk_ops = {
  380. .recalc_rate = samsung_pll45xx_recalc_rate,
  381. .round_rate = samsung_pll_round_rate,
  382. .set_rate = samsung_pll45xx_set_rate,
  383. };
  384. static const struct clk_ops samsung_pll45xx_clk_min_ops = {
  385. .recalc_rate = samsung_pll45xx_recalc_rate,
  386. };
  387. /*
  388. * PLL46xx Clock Type
  389. */
  390. #define PLL46XX_LOCK_FACTOR 3000
  391. #define PLL46XX_VSEL_MASK (1)
  392. #define PLL46XX_MDIV_MASK (0x1FF)
  393. #define PLL46XX_PDIV_MASK (0x3F)
  394. #define PLL46XX_SDIV_MASK (0x7)
  395. #define PLL46XX_VSEL_SHIFT (27)
  396. #define PLL46XX_MDIV_SHIFT (16)
  397. #define PLL46XX_PDIV_SHIFT (8)
  398. #define PLL46XX_SDIV_SHIFT (0)
  399. #define PLL46XX_KDIV_MASK (0xFFFF)
  400. #define PLL4650C_KDIV_MASK (0xFFF)
  401. #define PLL46XX_KDIV_SHIFT (0)
  402. #define PLL46XX_MFR_MASK (0x3F)
  403. #define PLL46XX_MRR_MASK (0x1F)
  404. #define PLL46XX_KDIV_SHIFT (0)
  405. #define PLL46XX_MFR_SHIFT (16)
  406. #define PLL46XX_MRR_SHIFT (24)
  407. #define PLL46XX_ENABLE BIT(31)
  408. #define PLL46XX_LOCKED BIT(29)
  409. #define PLL46XX_VSEL BIT(27)
  410. static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
  411. unsigned long parent_rate)
  412. {
  413. struct samsung_clk_pll *pll = to_clk_pll(hw);
  414. u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift;
  415. u64 fvco = parent_rate;
  416. pll_con0 = __raw_readl(pll->con_reg);
  417. pll_con1 = __raw_readl(pll->con_reg + 4);
  418. mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
  419. pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
  420. sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
  421. kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
  422. pll_con1 & PLL46XX_KDIV_MASK;
  423. shift = pll->type == pll_4600 ? 16 : 10;
  424. fvco *= (mdiv << shift) + kdiv;
  425. do_div(fvco, (pdiv << sdiv));
  426. fvco >>= shift;
  427. return (unsigned long)fvco;
  428. }
  429. static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1,
  430. const struct samsung_pll_rate_table *rate)
  431. {
  432. u32 old_mdiv, old_pdiv, old_kdiv;
  433. old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
  434. old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
  435. old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK;
  436. return (old_mdiv != rate->mdiv || old_pdiv != rate->pdiv
  437. || old_kdiv != rate->kdiv);
  438. }
  439. static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
  440. unsigned long prate)
  441. {
  442. struct samsung_clk_pll *pll = to_clk_pll(hw);
  443. const struct samsung_pll_rate_table *rate;
  444. u32 con0, con1, lock;
  445. ktime_t start;
  446. /* Get required rate settings from table */
  447. rate = samsung_get_pll_settings(pll, drate);
  448. if (!rate) {
  449. pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
  450. drate, __clk_get_name(hw->clk));
  451. return -EINVAL;
  452. }
  453. con0 = __raw_readl(pll->con_reg);
  454. con1 = __raw_readl(pll->con_reg + 0x4);
  455. if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) {
  456. /* If only s change, change just s value only*/
  457. con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
  458. con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT;
  459. __raw_writel(con0, pll->con_reg);
  460. return 0;
  461. }
  462. /* Set PLL lock time. */
  463. lock = rate->pdiv * PLL46XX_LOCK_FACTOR;
  464. if (lock > 0xffff)
  465. /* Maximum lock time bitfield is 16-bit. */
  466. lock = 0xffff;
  467. /* Set PLL PMS and VSEL values. */
  468. con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
  469. (PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
  470. (PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) |
  471. (PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT));
  472. con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
  473. (rate->pdiv << PLL46XX_PDIV_SHIFT) |
  474. (rate->sdiv << PLL46XX_SDIV_SHIFT) |
  475. (rate->vsel << PLL46XX_VSEL_SHIFT);
  476. /* Set PLL K, MFR and MRR values. */
  477. con1 = __raw_readl(pll->con_reg + 0x4);
  478. con1 &= ~((PLL46XX_KDIV_MASK << PLL46XX_KDIV_SHIFT) |
  479. (PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT) |
  480. (PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT));
  481. con1 |= (rate->kdiv << PLL46XX_KDIV_SHIFT) |
  482. (rate->mfr << PLL46XX_MFR_SHIFT) |
  483. (rate->mrr << PLL46XX_MRR_SHIFT);
  484. /* Write configuration to PLL */
  485. __raw_writel(lock, pll->lock_reg);
  486. __raw_writel(con0, pll->con_reg);
  487. __raw_writel(con1, pll->con_reg + 0x4);
  488. /* Wait for locking. */
  489. start = ktime_get();
  490. while (!(__raw_readl(pll->con_reg) & PLL46XX_LOCKED)) {
  491. ktime_t delta = ktime_sub(ktime_get(), start);
  492. if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
  493. pr_err("%s: could not lock PLL %s\n",
  494. __func__, __clk_get_name(hw->clk));
  495. return -EFAULT;
  496. }
  497. cpu_relax();
  498. }
  499. return 0;
  500. }
  501. static const struct clk_ops samsung_pll46xx_clk_ops = {
  502. .recalc_rate = samsung_pll46xx_recalc_rate,
  503. .round_rate = samsung_pll_round_rate,
  504. .set_rate = samsung_pll46xx_set_rate,
  505. };
  506. static const struct clk_ops samsung_pll46xx_clk_min_ops = {
  507. .recalc_rate = samsung_pll46xx_recalc_rate,
  508. };
  509. /*
  510. * PLL6552 Clock Type
  511. */
  512. #define PLL6552_MDIV_MASK 0x3ff
  513. #define PLL6552_PDIV_MASK 0x3f
  514. #define PLL6552_SDIV_MASK 0x7
  515. #define PLL6552_MDIV_SHIFT 16
  516. #define PLL6552_MDIV_SHIFT_2416 14
  517. #define PLL6552_PDIV_SHIFT 8
  518. #define PLL6552_PDIV_SHIFT_2416 5
  519. #define PLL6552_SDIV_SHIFT 0
  520. static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
  521. unsigned long parent_rate)
  522. {
  523. struct samsung_clk_pll *pll = to_clk_pll(hw);
  524. u32 mdiv, pdiv, sdiv, pll_con;
  525. u64 fvco = parent_rate;
  526. pll_con = __raw_readl(pll->con_reg);
  527. if (pll->type == pll_6552_s3c2416) {
  528. mdiv = (pll_con >> PLL6552_MDIV_SHIFT_2416) & PLL6552_MDIV_MASK;
  529. pdiv = (pll_con >> PLL6552_PDIV_SHIFT_2416) & PLL6552_PDIV_MASK;
  530. } else {
  531. mdiv = (pll_con >> PLL6552_MDIV_SHIFT) & PLL6552_MDIV_MASK;
  532. pdiv = (pll_con >> PLL6552_PDIV_SHIFT) & PLL6552_PDIV_MASK;
  533. }
  534. sdiv = (pll_con >> PLL6552_SDIV_SHIFT) & PLL6552_SDIV_MASK;
  535. fvco *= mdiv;
  536. do_div(fvco, (pdiv << sdiv));
  537. return (unsigned long)fvco;
  538. }
  539. static const struct clk_ops samsung_pll6552_clk_ops = {
  540. .recalc_rate = samsung_pll6552_recalc_rate,
  541. };
  542. /*
  543. * PLL6553 Clock Type
  544. */
  545. #define PLL6553_MDIV_MASK 0xff
  546. #define PLL6553_PDIV_MASK 0x3f
  547. #define PLL6553_SDIV_MASK 0x7
  548. #define PLL6553_KDIV_MASK 0xffff
  549. #define PLL6553_MDIV_SHIFT 16
  550. #define PLL6553_PDIV_SHIFT 8
  551. #define PLL6553_SDIV_SHIFT 0
  552. #define PLL6553_KDIV_SHIFT 0
  553. static unsigned long samsung_pll6553_recalc_rate(struct clk_hw *hw,
  554. unsigned long parent_rate)
  555. {
  556. struct samsung_clk_pll *pll = to_clk_pll(hw);
  557. u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
  558. u64 fvco = parent_rate;
  559. pll_con0 = __raw_readl(pll->con_reg);
  560. pll_con1 = __raw_readl(pll->con_reg + 0x4);
  561. mdiv = (pll_con0 >> PLL6553_MDIV_SHIFT) & PLL6553_MDIV_MASK;
  562. pdiv = (pll_con0 >> PLL6553_PDIV_SHIFT) & PLL6553_PDIV_MASK;
  563. sdiv = (pll_con0 >> PLL6553_SDIV_SHIFT) & PLL6553_SDIV_MASK;
  564. kdiv = (pll_con1 >> PLL6553_KDIV_SHIFT) & PLL6553_KDIV_MASK;
  565. fvco *= (mdiv << 16) + kdiv;
  566. do_div(fvco, (pdiv << sdiv));
  567. fvco >>= 16;
  568. return (unsigned long)fvco;
  569. }
  570. static const struct clk_ops samsung_pll6553_clk_ops = {
  571. .recalc_rate = samsung_pll6553_recalc_rate,
  572. };
  573. /*
  574. * PLL Clock Type of S3C24XX before S3C2443
  575. */
  576. #define PLLS3C2410_MDIV_MASK (0xff)
  577. #define PLLS3C2410_PDIV_MASK (0x1f)
  578. #define PLLS3C2410_SDIV_MASK (0x3)
  579. #define PLLS3C2410_MDIV_SHIFT (12)
  580. #define PLLS3C2410_PDIV_SHIFT (4)
  581. #define PLLS3C2410_SDIV_SHIFT (0)
  582. #define PLLS3C2410_ENABLE_REG_OFFSET 0x10
  583. static unsigned long samsung_s3c2410_pll_recalc_rate(struct clk_hw *hw,
  584. unsigned long parent_rate)
  585. {
  586. struct samsung_clk_pll *pll = to_clk_pll(hw);
  587. u32 pll_con, mdiv, pdiv, sdiv;
  588. u64 fvco = parent_rate;
  589. pll_con = __raw_readl(pll->con_reg);
  590. mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
  591. pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
  592. sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
  593. fvco *= (mdiv + 8);
  594. do_div(fvco, (pdiv + 2) << sdiv);
  595. return (unsigned int)fvco;
  596. }
  597. static unsigned long samsung_s3c2440_mpll_recalc_rate(struct clk_hw *hw,
  598. unsigned long parent_rate)
  599. {
  600. struct samsung_clk_pll *pll = to_clk_pll(hw);
  601. u32 pll_con, mdiv, pdiv, sdiv;
  602. u64 fvco = parent_rate;
  603. pll_con = __raw_readl(pll->con_reg);
  604. mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
  605. pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
  606. sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
  607. fvco *= (2 * (mdiv + 8));
  608. do_div(fvco, (pdiv + 2) << sdiv);
  609. return (unsigned int)fvco;
  610. }
  611. static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate,
  612. unsigned long prate)
  613. {
  614. struct samsung_clk_pll *pll = to_clk_pll(hw);
  615. const struct samsung_pll_rate_table *rate;
  616. u32 tmp;
  617. /* Get required rate settings from table */
  618. rate = samsung_get_pll_settings(pll, drate);
  619. if (!rate) {
  620. pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
  621. drate, __clk_get_name(hw->clk));
  622. return -EINVAL;
  623. }
  624. tmp = __raw_readl(pll->con_reg);
  625. /* Change PLL PMS values */
  626. tmp &= ~((PLLS3C2410_MDIV_MASK << PLLS3C2410_MDIV_SHIFT) |
  627. (PLLS3C2410_PDIV_MASK << PLLS3C2410_PDIV_SHIFT) |
  628. (PLLS3C2410_SDIV_MASK << PLLS3C2410_SDIV_SHIFT));
  629. tmp |= (rate->mdiv << PLLS3C2410_MDIV_SHIFT) |
  630. (rate->pdiv << PLLS3C2410_PDIV_SHIFT) |
  631. (rate->sdiv << PLLS3C2410_SDIV_SHIFT);
  632. __raw_writel(tmp, pll->con_reg);
  633. /* Time to settle according to the manual */
  634. udelay(300);
  635. return 0;
  636. }
  637. static int samsung_s3c2410_pll_enable(struct clk_hw *hw, int bit, bool enable)
  638. {
  639. struct samsung_clk_pll *pll = to_clk_pll(hw);
  640. u32 pll_en = __raw_readl(pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
  641. u32 pll_en_orig = pll_en;
  642. if (enable)
  643. pll_en &= ~BIT(bit);
  644. else
  645. pll_en |= BIT(bit);
  646. __raw_writel(pll_en, pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
  647. /* if we started the UPLL, then allow to settle */
  648. if (enable && (pll_en_orig & BIT(bit)))
  649. udelay(300);
  650. return 0;
  651. }
  652. static int samsung_s3c2410_mpll_enable(struct clk_hw *hw)
  653. {
  654. return samsung_s3c2410_pll_enable(hw, 5, true);
  655. }
  656. static void samsung_s3c2410_mpll_disable(struct clk_hw *hw)
  657. {
  658. samsung_s3c2410_pll_enable(hw, 5, false);
  659. }
  660. static int samsung_s3c2410_upll_enable(struct clk_hw *hw)
  661. {
  662. return samsung_s3c2410_pll_enable(hw, 7, true);
  663. }
  664. static void samsung_s3c2410_upll_disable(struct clk_hw *hw)
  665. {
  666. samsung_s3c2410_pll_enable(hw, 7, false);
  667. }
  668. static const struct clk_ops samsung_s3c2410_mpll_clk_min_ops = {
  669. .recalc_rate = samsung_s3c2410_pll_recalc_rate,
  670. .enable = samsung_s3c2410_mpll_enable,
  671. .disable = samsung_s3c2410_mpll_disable,
  672. };
  673. static const struct clk_ops samsung_s3c2410_upll_clk_min_ops = {
  674. .recalc_rate = samsung_s3c2410_pll_recalc_rate,
  675. .enable = samsung_s3c2410_upll_enable,
  676. .disable = samsung_s3c2410_upll_disable,
  677. };
  678. static const struct clk_ops samsung_s3c2440_mpll_clk_min_ops = {
  679. .recalc_rate = samsung_s3c2440_mpll_recalc_rate,
  680. .enable = samsung_s3c2410_mpll_enable,
  681. .disable = samsung_s3c2410_mpll_disable,
  682. };
  683. static const struct clk_ops samsung_s3c2410_mpll_clk_ops = {
  684. .recalc_rate = samsung_s3c2410_pll_recalc_rate,
  685. .enable = samsung_s3c2410_mpll_enable,
  686. .disable = samsung_s3c2410_mpll_disable,
  687. .round_rate = samsung_pll_round_rate,
  688. .set_rate = samsung_s3c2410_pll_set_rate,
  689. };
  690. static const struct clk_ops samsung_s3c2410_upll_clk_ops = {
  691. .recalc_rate = samsung_s3c2410_pll_recalc_rate,
  692. .enable = samsung_s3c2410_upll_enable,
  693. .disable = samsung_s3c2410_upll_disable,
  694. .round_rate = samsung_pll_round_rate,
  695. .set_rate = samsung_s3c2410_pll_set_rate,
  696. };
  697. static const struct clk_ops samsung_s3c2440_mpll_clk_ops = {
  698. .recalc_rate = samsung_s3c2440_mpll_recalc_rate,
  699. .enable = samsung_s3c2410_mpll_enable,
  700. .disable = samsung_s3c2410_mpll_disable,
  701. .round_rate = samsung_pll_round_rate,
  702. .set_rate = samsung_s3c2410_pll_set_rate,
  703. };
  704. /*
  705. * PLL2550x Clock Type
  706. */
  707. #define PLL2550X_R_MASK (0x1)
  708. #define PLL2550X_P_MASK (0x3F)
  709. #define PLL2550X_M_MASK (0x3FF)
  710. #define PLL2550X_S_MASK (0x7)
  711. #define PLL2550X_R_SHIFT (20)
  712. #define PLL2550X_P_SHIFT (14)
  713. #define PLL2550X_M_SHIFT (4)
  714. #define PLL2550X_S_SHIFT (0)
  715. struct samsung_clk_pll2550x {
  716. struct clk_hw hw;
  717. const void __iomem *reg_base;
  718. unsigned long offset;
  719. };
  720. #define to_clk_pll2550x(_hw) container_of(_hw, struct samsung_clk_pll2550x, hw)
  721. static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw,
  722. unsigned long parent_rate)
  723. {
  724. struct samsung_clk_pll2550x *pll = to_clk_pll2550x(hw);
  725. u32 r, p, m, s, pll_stat;
  726. u64 fvco = parent_rate;
  727. pll_stat = __raw_readl(pll->reg_base + pll->offset * 3);
  728. r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK;
  729. if (!r)
  730. return 0;
  731. p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK;
  732. m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK;
  733. s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK;
  734. fvco *= m;
  735. do_div(fvco, (p << s));
  736. return (unsigned long)fvco;
  737. }
  738. static const struct clk_ops samsung_pll2550x_clk_ops = {
  739. .recalc_rate = samsung_pll2550x_recalc_rate,
  740. };
  741. struct clk * __init samsung_clk_register_pll2550x(const char *name,
  742. const char *pname, const void __iomem *reg_base,
  743. const unsigned long offset)
  744. {
  745. struct samsung_clk_pll2550x *pll;
  746. struct clk *clk;
  747. struct clk_init_data init;
  748. pll = kzalloc(sizeof(*pll), GFP_KERNEL);
  749. if (!pll) {
  750. pr_err("%s: could not allocate pll clk %s\n", __func__, name);
  751. return NULL;
  752. }
  753. init.name = name;
  754. init.ops = &samsung_pll2550x_clk_ops;
  755. init.flags = CLK_GET_RATE_NOCACHE;
  756. init.parent_names = &pname;
  757. init.num_parents = 1;
  758. pll->hw.init = &init;
  759. pll->reg_base = reg_base;
  760. pll->offset = offset;
  761. clk = clk_register(NULL, &pll->hw);
  762. if (IS_ERR(clk)) {
  763. pr_err("%s: failed to register pll clock %s\n", __func__,
  764. name);
  765. kfree(pll);
  766. }
  767. if (clk_register_clkdev(clk, name, NULL))
  768. pr_err("%s: failed to register lookup for %s", __func__, name);
  769. return clk;
  770. }
  771. /*
  772. * PLL2550xx Clock Type
  773. */
  774. /* Maximum lock time can be 270 * PDIV cycles */
  775. #define PLL2550XX_LOCK_FACTOR 270
  776. #define PLL2550XX_M_MASK 0x3FF
  777. #define PLL2550XX_P_MASK 0x3F
  778. #define PLL2550XX_S_MASK 0x7
  779. #define PLL2550XX_LOCK_STAT_MASK 0x1
  780. #define PLL2550XX_M_SHIFT 9
  781. #define PLL2550XX_P_SHIFT 3
  782. #define PLL2550XX_S_SHIFT 0
  783. #define PLL2550XX_LOCK_STAT_SHIFT 21
  784. static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw *hw,
  785. unsigned long parent_rate)
  786. {
  787. struct samsung_clk_pll *pll = to_clk_pll(hw);
  788. u32 mdiv, pdiv, sdiv, pll_con;
  789. u64 fvco = parent_rate;
  790. pll_con = __raw_readl(pll->con_reg);
  791. mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
  792. pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
  793. sdiv = (pll_con >> PLL2550XX_S_SHIFT) & PLL2550XX_S_MASK;
  794. fvco *= mdiv;
  795. do_div(fvco, (pdiv << sdiv));
  796. return (unsigned long)fvco;
  797. }
  798. static inline bool samsung_pll2550xx_mp_change(u32 mdiv, u32 pdiv, u32 pll_con)
  799. {
  800. u32 old_mdiv, old_pdiv;
  801. old_mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK;
  802. old_pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK;
  803. return mdiv != old_mdiv || pdiv != old_pdiv;
  804. }
  805. static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate,
  806. unsigned long prate)
  807. {
  808. struct samsung_clk_pll *pll = to_clk_pll(hw);
  809. const struct samsung_pll_rate_table *rate;
  810. u32 tmp;
  811. /* Get required rate settings from table */
  812. rate = samsung_get_pll_settings(pll, drate);
  813. if (!rate) {
  814. pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
  815. drate, __clk_get_name(hw->clk));
  816. return -EINVAL;
  817. }
  818. tmp = __raw_readl(pll->con_reg);
  819. if (!(samsung_pll2550xx_mp_change(rate->mdiv, rate->pdiv, tmp))) {
  820. /* If only s change, change just s value only*/
  821. tmp &= ~(PLL2550XX_S_MASK << PLL2550XX_S_SHIFT);
  822. tmp |= rate->sdiv << PLL2550XX_S_SHIFT;
  823. __raw_writel(tmp, pll->con_reg);
  824. return 0;
  825. }
  826. /* Set PLL lock time. */
  827. __raw_writel(rate->pdiv * PLL2550XX_LOCK_FACTOR, pll->lock_reg);
  828. /* Change PLL PMS values */
  829. tmp &= ~((PLL2550XX_M_MASK << PLL2550XX_M_SHIFT) |
  830. (PLL2550XX_P_MASK << PLL2550XX_P_SHIFT) |
  831. (PLL2550XX_S_MASK << PLL2550XX_S_SHIFT));
  832. tmp |= (rate->mdiv << PLL2550XX_M_SHIFT) |
  833. (rate->pdiv << PLL2550XX_P_SHIFT) |
  834. (rate->sdiv << PLL2550XX_S_SHIFT);
  835. __raw_writel(tmp, pll->con_reg);
  836. /* wait_lock_time */
  837. do {
  838. cpu_relax();
  839. tmp = __raw_readl(pll->con_reg);
  840. } while (!(tmp & (PLL2550XX_LOCK_STAT_MASK
  841. << PLL2550XX_LOCK_STAT_SHIFT)));
  842. return 0;
  843. }
  844. static const struct clk_ops samsung_pll2550xx_clk_ops = {
  845. .recalc_rate = samsung_pll2550xx_recalc_rate,
  846. .round_rate = samsung_pll_round_rate,
  847. .set_rate = samsung_pll2550xx_set_rate,
  848. };
  849. static const struct clk_ops samsung_pll2550xx_clk_min_ops = {
  850. .recalc_rate = samsung_pll2550xx_recalc_rate,
  851. };
  852. /*
  853. * PLL2650XX Clock Type
  854. */
  855. /* Maximum lock time can be 3000 * PDIV cycles */
  856. #define PLL2650XX_LOCK_FACTOR 3000
  857. #define PLL2650XX_MDIV_SHIFT 9
  858. #define PLL2650XX_PDIV_SHIFT 3
  859. #define PLL2650XX_SDIV_SHIFT 0
  860. #define PLL2650XX_KDIV_SHIFT 0
  861. #define PLL2650XX_MDIV_MASK 0x1ff
  862. #define PLL2650XX_PDIV_MASK 0x3f
  863. #define PLL2650XX_SDIV_MASK 0x7
  864. #define PLL2650XX_KDIV_MASK 0xffff
  865. #define PLL2650XX_PLL_ENABLE_SHIFT 23
  866. #define PLL2650XX_PLL_LOCKTIME_SHIFT 21
  867. #define PLL2650XX_PLL_FOUTMASK_SHIFT 31
  868. static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw *hw,
  869. unsigned long parent_rate)
  870. {
  871. struct samsung_clk_pll *pll = to_clk_pll(hw);
  872. u32 mdiv, pdiv, sdiv, pll_con0, pll_con2;
  873. s16 kdiv;
  874. u64 fvco = parent_rate;
  875. pll_con0 = __raw_readl(pll->con_reg);
  876. pll_con2 = __raw_readl(pll->con_reg + 8);
  877. mdiv = (pll_con0 >> PLL2650XX_MDIV_SHIFT) & PLL2650XX_MDIV_MASK;
  878. pdiv = (pll_con0 >> PLL2650XX_PDIV_SHIFT) & PLL2650XX_PDIV_MASK;
  879. sdiv = (pll_con0 >> PLL2650XX_SDIV_SHIFT) & PLL2650XX_SDIV_MASK;
  880. kdiv = (s16)(pll_con2 & PLL2650XX_KDIV_MASK);
  881. fvco *= (mdiv << 16) + kdiv;
  882. do_div(fvco, (pdiv << sdiv));
  883. fvco >>= 16;
  884. return (unsigned long)fvco;
  885. }
  886. static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate,
  887. unsigned long parent_rate)
  888. {
  889. struct samsung_clk_pll *pll = to_clk_pll(hw);
  890. u32 tmp, pll_con0, pll_con2;
  891. const struct samsung_pll_rate_table *rate;
  892. rate = samsung_get_pll_settings(pll, drate);
  893. if (!rate) {
  894. pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
  895. drate, __clk_get_name(hw->clk));
  896. return -EINVAL;
  897. }
  898. pll_con0 = __raw_readl(pll->con_reg);
  899. pll_con2 = __raw_readl(pll->con_reg + 8);
  900. /* Change PLL PMS values */
  901. pll_con0 &= ~(PLL2650XX_MDIV_MASK << PLL2650XX_MDIV_SHIFT |
  902. PLL2650XX_PDIV_MASK << PLL2650XX_PDIV_SHIFT |
  903. PLL2650XX_SDIV_MASK << PLL2650XX_SDIV_SHIFT);
  904. pll_con0 |= rate->mdiv << PLL2650XX_MDIV_SHIFT;
  905. pll_con0 |= rate->pdiv << PLL2650XX_PDIV_SHIFT;
  906. pll_con0 |= rate->sdiv << PLL2650XX_SDIV_SHIFT;
  907. pll_con0 |= 1 << PLL2650XX_PLL_ENABLE_SHIFT;
  908. pll_con0 |= 1 << PLL2650XX_PLL_FOUTMASK_SHIFT;
  909. pll_con2 &= ~(PLL2650XX_KDIV_MASK << PLL2650XX_KDIV_SHIFT);
  910. pll_con2 |= ((~(rate->kdiv) + 1) & PLL2650XX_KDIV_MASK)
  911. << PLL2650XX_KDIV_SHIFT;
  912. /* Set PLL lock time. */
  913. __raw_writel(PLL2650XX_LOCK_FACTOR * rate->pdiv, pll->lock_reg);
  914. __raw_writel(pll_con0, pll->con_reg);
  915. __raw_writel(pll_con2, pll->con_reg + 8);
  916. do {
  917. tmp = __raw_readl(pll->con_reg);
  918. } while (!(tmp & (0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT)));
  919. return 0;
  920. }
  921. static const struct clk_ops samsung_pll2650xx_clk_ops = {
  922. .recalc_rate = samsung_pll2650xx_recalc_rate,
  923. .set_rate = samsung_pll2650xx_set_rate,
  924. .round_rate = samsung_pll_round_rate,
  925. };
  926. static const struct clk_ops samsung_pll2650xx_clk_min_ops = {
  927. .recalc_rate = samsung_pll2650xx_recalc_rate,
  928. };
  929. static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
  930. struct samsung_pll_clock *pll_clk,
  931. void __iomem *base)
  932. {
  933. struct samsung_clk_pll *pll;
  934. struct clk *clk;
  935. struct clk_init_data init;
  936. int ret, len;
  937. pll = kzalloc(sizeof(*pll), GFP_KERNEL);
  938. if (!pll) {
  939. pr_err("%s: could not allocate pll clk %s\n",
  940. __func__, pll_clk->name);
  941. return;
  942. }
  943. init.name = pll_clk->name;
  944. init.flags = pll_clk->flags;
  945. init.parent_names = &pll_clk->parent_name;
  946. init.num_parents = 1;
  947. if (pll_clk->rate_table) {
  948. /* find count of rates in rate_table */
  949. for (len = 0; pll_clk->rate_table[len].rate != 0; )
  950. len++;
  951. pll->rate_count = len;
  952. pll->rate_table = kmemdup(pll_clk->rate_table,
  953. pll->rate_count *
  954. sizeof(struct samsung_pll_rate_table),
  955. GFP_KERNEL);
  956. WARN(!pll->rate_table,
  957. "%s: could not allocate rate table for %s\n",
  958. __func__, pll_clk->name);
  959. }
  960. switch (pll_clk->type) {
  961. case pll_2126:
  962. init.ops = &samsung_pll2126_clk_ops;
  963. break;
  964. case pll_3000:
  965. init.ops = &samsung_pll3000_clk_ops;
  966. break;
  967. /* clk_ops for 35xx and 2550 are similar */
  968. case pll_35xx:
  969. case pll_2550:
  970. if (!pll->rate_table)
  971. init.ops = &samsung_pll35xx_clk_min_ops;
  972. else
  973. init.ops = &samsung_pll35xx_clk_ops;
  974. break;
  975. case pll_4500:
  976. init.ops = &samsung_pll45xx_clk_min_ops;
  977. break;
  978. case pll_4502:
  979. case pll_4508:
  980. if (!pll->rate_table)
  981. init.ops = &samsung_pll45xx_clk_min_ops;
  982. else
  983. init.ops = &samsung_pll45xx_clk_ops;
  984. break;
  985. /* clk_ops for 36xx and 2650 are similar */
  986. case pll_36xx:
  987. case pll_2650:
  988. if (!pll->rate_table)
  989. init.ops = &samsung_pll36xx_clk_min_ops;
  990. else
  991. init.ops = &samsung_pll36xx_clk_ops;
  992. break;
  993. case pll_6552:
  994. case pll_6552_s3c2416:
  995. init.ops = &samsung_pll6552_clk_ops;
  996. break;
  997. case pll_6553:
  998. init.ops = &samsung_pll6553_clk_ops;
  999. break;
  1000. case pll_4600:
  1001. case pll_4650:
  1002. case pll_4650c:
  1003. if (!pll->rate_table)
  1004. init.ops = &samsung_pll46xx_clk_min_ops;
  1005. else
  1006. init.ops = &samsung_pll46xx_clk_ops;
  1007. break;
  1008. case pll_s3c2410_mpll:
  1009. if (!pll->rate_table)
  1010. init.ops = &samsung_s3c2410_mpll_clk_min_ops;
  1011. else
  1012. init.ops = &samsung_s3c2410_mpll_clk_ops;
  1013. break;
  1014. case pll_s3c2410_upll:
  1015. if (!pll->rate_table)
  1016. init.ops = &samsung_s3c2410_upll_clk_min_ops;
  1017. else
  1018. init.ops = &samsung_s3c2410_upll_clk_ops;
  1019. break;
  1020. case pll_s3c2440_mpll:
  1021. if (!pll->rate_table)
  1022. init.ops = &samsung_s3c2440_mpll_clk_min_ops;
  1023. else
  1024. init.ops = &samsung_s3c2440_mpll_clk_ops;
  1025. break;
  1026. case pll_2550xx:
  1027. if (!pll->rate_table)
  1028. init.ops = &samsung_pll2550xx_clk_min_ops;
  1029. else
  1030. init.ops = &samsung_pll2550xx_clk_ops;
  1031. break;
  1032. case pll_2650xx:
  1033. if (!pll->rate_table)
  1034. init.ops = &samsung_pll2650xx_clk_min_ops;
  1035. else
  1036. init.ops = &samsung_pll2650xx_clk_ops;
  1037. break;
  1038. default:
  1039. pr_warn("%s: Unknown pll type for pll clk %s\n",
  1040. __func__, pll_clk->name);
  1041. }
  1042. pll->hw.init = &init;
  1043. pll->type = pll_clk->type;
  1044. pll->lock_reg = base + pll_clk->lock_offset;
  1045. pll->con_reg = base + pll_clk->con_offset;
  1046. clk = clk_register(NULL, &pll->hw);
  1047. if (IS_ERR(clk)) {
  1048. pr_err("%s: failed to register pll clock %s : %ld\n",
  1049. __func__, pll_clk->name, PTR_ERR(clk));
  1050. kfree(pll);
  1051. return;
  1052. }
  1053. samsung_clk_add_lookup(ctx, clk, pll_clk->id);
  1054. if (!pll_clk->alias)
  1055. return;
  1056. ret = clk_register_clkdev(clk, pll_clk->alias, pll_clk->dev_name);
  1057. if (ret)
  1058. pr_err("%s: failed to register lookup for %s : %d",
  1059. __func__, pll_clk->name, ret);
  1060. }
  1061. void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
  1062. struct samsung_pll_clock *pll_list,
  1063. unsigned int nr_pll, void __iomem *base)
  1064. {
  1065. int cnt;
  1066. for (cnt = 0; cnt < nr_pll; cnt++)
  1067. _samsung_clk_register_pll(ctx, &pll_list[cnt], base);
  1068. }