clk-pll.c 37 KB

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