clock.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2010 Samsung Electronics
  4. * Minkyu Kang <mk7.kang@samsung.com>
  5. */
  6. #include <common.h>
  7. #include <clock_legacy.h>
  8. #include <log.h>
  9. #include <asm/io.h>
  10. #include <asm/arch/clock.h>
  11. #include <asm/arch/clk.h>
  12. #include <asm/arch/periph.h>
  13. #define PLL_DIV_1024 1024
  14. #define PLL_DIV_65535 65535
  15. #define PLL_DIV_65536 65536
  16. /* *
  17. * This structure is to store the src bit, div bit and prediv bit
  18. * positions of the peripheral clocks of the src and div registers
  19. */
  20. struct clk_bit_info {
  21. enum periph_id id;
  22. int32_t src_mask;
  23. int32_t div_mask;
  24. int32_t prediv_mask;
  25. int8_t src_bit;
  26. int8_t div_bit;
  27. int8_t prediv_bit;
  28. };
  29. static struct clk_bit_info exynos5_bit_info[] = {
  30. /* periph id s_mask d_mask p_mask s_bit d_bit p_bit */
  31. {PERIPH_ID_UART0, 0xf, 0xf, -1, 0, 0, -1},
  32. {PERIPH_ID_UART1, 0xf, 0xf, -1, 4, 4, -1},
  33. {PERIPH_ID_UART2, 0xf, 0xf, -1, 8, 8, -1},
  34. {PERIPH_ID_UART3, 0xf, 0xf, -1, 12, 12, -1},
  35. {PERIPH_ID_I2C0, -1, 0x7, 0x7, -1, 24, 0},
  36. {PERIPH_ID_I2C1, -1, 0x7, 0x7, -1, 24, 0},
  37. {PERIPH_ID_I2C2, -1, 0x7, 0x7, -1, 24, 0},
  38. {PERIPH_ID_I2C3, -1, 0x7, 0x7, -1, 24, 0},
  39. {PERIPH_ID_I2C4, -1, 0x7, 0x7, -1, 24, 0},
  40. {PERIPH_ID_I2C5, -1, 0x7, 0x7, -1, 24, 0},
  41. {PERIPH_ID_I2C6, -1, 0x7, 0x7, -1, 24, 0},
  42. {PERIPH_ID_I2C7, -1, 0x7, 0x7, -1, 24, 0},
  43. {PERIPH_ID_SPI0, 0xf, 0xf, 0xff, 16, 0, 8},
  44. {PERIPH_ID_SPI1, 0xf, 0xf, 0xff, 20, 16, 24},
  45. {PERIPH_ID_SPI2, 0xf, 0xf, 0xff, 24, 0, 8},
  46. {PERIPH_ID_SDMMC0, 0xf, 0xf, 0xff, 0, 0, 8},
  47. {PERIPH_ID_SDMMC1, 0xf, 0xf, 0xff, 4, 16, 24},
  48. {PERIPH_ID_SDMMC2, 0xf, 0xf, 0xff, 8, 0, 8},
  49. {PERIPH_ID_SDMMC3, 0xf, 0xf, 0xff, 12, 16, 24},
  50. {PERIPH_ID_I2S0, 0xf, 0xf, 0xff, 0, 0, 4},
  51. {PERIPH_ID_I2S1, 0xf, 0xf, 0xff, 4, 12, 16},
  52. {PERIPH_ID_SPI3, 0xf, 0xf, 0xff, 0, 0, 4},
  53. {PERIPH_ID_SPI4, 0xf, 0xf, 0xff, 4, 12, 16},
  54. {PERIPH_ID_SDMMC4, 0xf, 0xf, 0xff, 16, 0, 8},
  55. {PERIPH_ID_PWM0, 0xf, 0xf, -1, 24, 0, -1},
  56. {PERIPH_ID_PWM1, 0xf, 0xf, -1, 24, 0, -1},
  57. {PERIPH_ID_PWM2, 0xf, 0xf, -1, 24, 0, -1},
  58. {PERIPH_ID_PWM3, 0xf, 0xf, -1, 24, 0, -1},
  59. {PERIPH_ID_PWM4, 0xf, 0xf, -1, 24, 0, -1},
  60. {PERIPH_ID_NONE, -1, -1, -1, -1, -1, -1},
  61. };
  62. static struct clk_bit_info exynos542x_bit_info[] = {
  63. /* periph id s_mask d_mask p_mask s_bit d_bit p_bit */
  64. {PERIPH_ID_UART0, 0xf, 0xf, -1, 4, 8, -1},
  65. {PERIPH_ID_UART1, 0xf, 0xf, -1, 8, 12, -1},
  66. {PERIPH_ID_UART2, 0xf, 0xf, -1, 12, 16, -1},
  67. {PERIPH_ID_UART3, 0xf, 0xf, -1, 16, 20, -1},
  68. {PERIPH_ID_I2C0, -1, 0x3f, -1, -1, 8, -1},
  69. {PERIPH_ID_I2C1, -1, 0x3f, -1, -1, 8, -1},
  70. {PERIPH_ID_I2C2, -1, 0x3f, -1, -1, 8, -1},
  71. {PERIPH_ID_I2C3, -1, 0x3f, -1, -1, 8, -1},
  72. {PERIPH_ID_I2C4, -1, 0x3f, -1, -1, 8, -1},
  73. {PERIPH_ID_I2C5, -1, 0x3f, -1, -1, 8, -1},
  74. {PERIPH_ID_I2C6, -1, 0x3f, -1, -1, 8, -1},
  75. {PERIPH_ID_I2C7, -1, 0x3f, -1, -1, 8, -1},
  76. {PERIPH_ID_SPI0, 0xf, 0xf, 0xff, 20, 20, 8},
  77. {PERIPH_ID_SPI1, 0xf, 0xf, 0xff, 24, 24, 16},
  78. {PERIPH_ID_SPI2, 0xf, 0xf, 0xff, 28, 28, 24},
  79. {PERIPH_ID_SDMMC0, 0x7, 0x3ff, -1, 8, 0, -1},
  80. {PERIPH_ID_SDMMC1, 0x7, 0x3ff, -1, 12, 10, -1},
  81. {PERIPH_ID_SDMMC2, 0x7, 0x3ff, -1, 16, 20, -1},
  82. {PERIPH_ID_I2C8, -1, 0x3f, -1, -1, 8, -1},
  83. {PERIPH_ID_I2C9, -1, 0x3f, -1, -1, 8, -1},
  84. {PERIPH_ID_I2S0, 0xf, 0xf, 0xff, 0, 0, 4},
  85. {PERIPH_ID_I2S1, 0xf, 0xf, 0xff, 4, 12, 16},
  86. {PERIPH_ID_SPI3, 0xf, 0xf, 0xff, 12, 16, 0},
  87. {PERIPH_ID_SPI4, 0xf, 0xf, 0xff, 16, 20, 8},
  88. {PERIPH_ID_PWM0, 0xf, 0xf, -1, 24, 28, -1},
  89. {PERIPH_ID_PWM1, 0xf, 0xf, -1, 24, 28, -1},
  90. {PERIPH_ID_PWM2, 0xf, 0xf, -1, 24, 28, -1},
  91. {PERIPH_ID_PWM3, 0xf, 0xf, -1, 24, 28, -1},
  92. {PERIPH_ID_PWM4, 0xf, 0xf, -1, 24, 28, -1},
  93. {PERIPH_ID_I2C10, -1, 0x3f, -1, -1, 8, -1},
  94. {PERIPH_ID_NONE, -1, -1, -1, -1, -1, -1},
  95. };
  96. /* Epll Clock division values to achive different frequency output */
  97. static struct set_epll_con_val exynos5_epll_div[] = {
  98. { 192000000, 0, 48, 3, 1, 0 },
  99. { 180000000, 0, 45, 3, 1, 0 },
  100. { 73728000, 1, 73, 3, 3, 47710 },
  101. { 67737600, 1, 90, 4, 3, 20762 },
  102. { 49152000, 0, 49, 3, 3, 9961 },
  103. { 45158400, 0, 45, 3, 3, 10381 },
  104. { 180633600, 0, 45, 3, 1, 10381 }
  105. };
  106. /* exynos: return pll clock frequency */
  107. static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
  108. {
  109. unsigned long m, p, s = 0, mask, fout;
  110. unsigned int div;
  111. unsigned int freq;
  112. /*
  113. * APLL_CON: MIDV [25:16]
  114. * MPLL_CON: MIDV [25:16]
  115. * EPLL_CON: MIDV [24:16]
  116. * VPLL_CON: MIDV [24:16]
  117. * BPLL_CON: MIDV [25:16]: Exynos5
  118. */
  119. if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL ||
  120. pllreg == SPLL)
  121. mask = 0x3ff;
  122. else
  123. mask = 0x1ff;
  124. m = (r >> 16) & mask;
  125. /* PDIV [13:8] */
  126. p = (r >> 8) & 0x3f;
  127. /* SDIV [2:0] */
  128. s = r & 0x7;
  129. freq = get_board_sys_clk();
  130. if (pllreg == EPLL || pllreg == RPLL) {
  131. k = k & 0xffff;
  132. /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
  133. fout = (m + k / PLL_DIV_65536) * (freq / (p * (1 << s)));
  134. } else if (pllreg == VPLL) {
  135. k = k & 0xfff;
  136. /*
  137. * Exynos4210
  138. * FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV)
  139. *
  140. * Exynos4412
  141. * FOUT = (MDIV + K / 65535) * FIN / (PDIV * 2^SDIV)
  142. *
  143. * Exynos5250
  144. * FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV)
  145. */
  146. if (proid_is_exynos4210())
  147. div = PLL_DIV_1024;
  148. else if (proid_is_exynos4412())
  149. div = PLL_DIV_65535;
  150. else if (proid_is_exynos5250() || proid_is_exynos5420() ||
  151. proid_is_exynos5422())
  152. div = PLL_DIV_65536;
  153. else
  154. return 0;
  155. fout = (m + k / div) * (freq / (p * (1 << s)));
  156. } else {
  157. /*
  158. * Exynos4412 / Exynos5250
  159. * FOUT = MDIV * FIN / (PDIV * 2^SDIV)
  160. *
  161. * Exynos4210
  162. * FOUT = MDIV * FIN / (PDIV * 2^(SDIV-1))
  163. */
  164. if (proid_is_exynos4210())
  165. fout = m * (freq / (p * (1 << (s - 1))));
  166. else
  167. fout = m * (freq / (p * (1 << s)));
  168. }
  169. return fout;
  170. }
  171. /* exynos4: return pll clock frequency */
  172. static unsigned long exynos4_get_pll_clk(int pllreg)
  173. {
  174. struct exynos4_clock *clk =
  175. (struct exynos4_clock *)samsung_get_base_clock();
  176. unsigned long r, k = 0;
  177. switch (pllreg) {
  178. case APLL:
  179. r = readl(&clk->apll_con0);
  180. break;
  181. case MPLL:
  182. r = readl(&clk->mpll_con0);
  183. break;
  184. case EPLL:
  185. r = readl(&clk->epll_con0);
  186. k = readl(&clk->epll_con1);
  187. break;
  188. case VPLL:
  189. r = readl(&clk->vpll_con0);
  190. k = readl(&clk->vpll_con1);
  191. break;
  192. default:
  193. printf("Unsupported PLL (%d)\n", pllreg);
  194. return 0;
  195. }
  196. return exynos_get_pll_clk(pllreg, r, k);
  197. }
  198. /* exynos4x12: return pll clock frequency */
  199. static unsigned long exynos4x12_get_pll_clk(int pllreg)
  200. {
  201. struct exynos4x12_clock *clk =
  202. (struct exynos4x12_clock *)samsung_get_base_clock();
  203. unsigned long r, k = 0;
  204. switch (pllreg) {
  205. case APLL:
  206. r = readl(&clk->apll_con0);
  207. break;
  208. case MPLL:
  209. r = readl(&clk->mpll_con0);
  210. break;
  211. case EPLL:
  212. r = readl(&clk->epll_con0);
  213. k = readl(&clk->epll_con1);
  214. break;
  215. case VPLL:
  216. r = readl(&clk->vpll_con0);
  217. k = readl(&clk->vpll_con1);
  218. break;
  219. default:
  220. printf("Unsupported PLL (%d)\n", pllreg);
  221. return 0;
  222. }
  223. return exynos_get_pll_clk(pllreg, r, k);
  224. }
  225. /* exynos5: return pll clock frequency */
  226. static unsigned long exynos5_get_pll_clk(int pllreg)
  227. {
  228. struct exynos5_clock *clk =
  229. (struct exynos5_clock *)samsung_get_base_clock();
  230. unsigned long r, k = 0, fout;
  231. unsigned int pll_div2_sel, fout_sel;
  232. switch (pllreg) {
  233. case APLL:
  234. r = readl(&clk->apll_con0);
  235. break;
  236. case MPLL:
  237. r = readl(&clk->mpll_con0);
  238. break;
  239. case EPLL:
  240. r = readl(&clk->epll_con0);
  241. k = readl(&clk->epll_con1);
  242. break;
  243. case VPLL:
  244. r = readl(&clk->vpll_con0);
  245. k = readl(&clk->vpll_con1);
  246. break;
  247. case BPLL:
  248. r = readl(&clk->bpll_con0);
  249. break;
  250. default:
  251. printf("Unsupported PLL (%d)\n", pllreg);
  252. return 0;
  253. }
  254. fout = exynos_get_pll_clk(pllreg, r, k);
  255. /* According to the user manual, in EVT1 MPLL and BPLL always gives
  256. * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
  257. if (pllreg == MPLL || pllreg == BPLL) {
  258. pll_div2_sel = readl(&clk->pll_div2_sel);
  259. switch (pllreg) {
  260. case MPLL:
  261. fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
  262. & MPLL_FOUT_SEL_MASK;
  263. break;
  264. case BPLL:
  265. fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT)
  266. & BPLL_FOUT_SEL_MASK;
  267. break;
  268. default:
  269. fout_sel = -1;
  270. break;
  271. }
  272. if (fout_sel == 0)
  273. fout /= 2;
  274. }
  275. return fout;
  276. }
  277. /* exynos542x: return pll clock frequency */
  278. static unsigned long exynos542x_get_pll_clk(int pllreg)
  279. {
  280. struct exynos5420_clock *clk =
  281. (struct exynos5420_clock *)samsung_get_base_clock();
  282. unsigned long r, k = 0;
  283. switch (pllreg) {
  284. case APLL:
  285. r = readl(&clk->apll_con0);
  286. break;
  287. case MPLL:
  288. r = readl(&clk->mpll_con0);
  289. break;
  290. case EPLL:
  291. r = readl(&clk->epll_con0);
  292. k = readl(&clk->epll_con1);
  293. break;
  294. case VPLL:
  295. r = readl(&clk->vpll_con0);
  296. k = readl(&clk->vpll_con1);
  297. break;
  298. case BPLL:
  299. r = readl(&clk->bpll_con0);
  300. break;
  301. case RPLL:
  302. r = readl(&clk->rpll_con0);
  303. k = readl(&clk->rpll_con1);
  304. break;
  305. case SPLL:
  306. r = readl(&clk->spll_con0);
  307. break;
  308. default:
  309. printf("Unsupported PLL (%d)\n", pllreg);
  310. return 0;
  311. }
  312. return exynos_get_pll_clk(pllreg, r, k);
  313. }
  314. static struct clk_bit_info *get_clk_bit_info(int peripheral)
  315. {
  316. int i;
  317. struct clk_bit_info *info;
  318. if (proid_is_exynos542x())
  319. info = exynos542x_bit_info;
  320. else
  321. info = exynos5_bit_info;
  322. for (i = 0; info[i].id != PERIPH_ID_NONE; i++) {
  323. if (info[i].id == peripheral)
  324. break;
  325. }
  326. if (info[i].id == PERIPH_ID_NONE)
  327. debug("ERROR: Peripheral ID %d not found\n", peripheral);
  328. return &info[i];
  329. }
  330. static unsigned long exynos5_get_periph_rate(int peripheral)
  331. {
  332. struct clk_bit_info *bit_info = get_clk_bit_info(peripheral);
  333. unsigned long sclk = 0;
  334. unsigned int src = 0, div = 0, sub_div = 0;
  335. struct exynos5_clock *clk =
  336. (struct exynos5_clock *)samsung_get_base_clock();
  337. switch (peripheral) {
  338. case PERIPH_ID_UART0:
  339. case PERIPH_ID_UART1:
  340. case PERIPH_ID_UART2:
  341. case PERIPH_ID_UART3:
  342. src = readl(&clk->src_peric0);
  343. div = readl(&clk->div_peric0);
  344. break;
  345. case PERIPH_ID_PWM0:
  346. case PERIPH_ID_PWM1:
  347. case PERIPH_ID_PWM2:
  348. case PERIPH_ID_PWM3:
  349. case PERIPH_ID_PWM4:
  350. src = readl(&clk->src_peric0);
  351. div = readl(&clk->div_peric3);
  352. break;
  353. case PERIPH_ID_I2S0:
  354. src = readl(&clk->src_mau);
  355. div = sub_div = readl(&clk->div_mau);
  356. case PERIPH_ID_SPI0:
  357. case PERIPH_ID_SPI1:
  358. src = readl(&clk->src_peric1);
  359. div = sub_div = readl(&clk->div_peric1);
  360. break;
  361. case PERIPH_ID_SPI2:
  362. src = readl(&clk->src_peric1);
  363. div = sub_div = readl(&clk->div_peric2);
  364. break;
  365. case PERIPH_ID_SPI3:
  366. case PERIPH_ID_SPI4:
  367. src = readl(&clk->sclk_src_isp);
  368. div = sub_div = readl(&clk->sclk_div_isp);
  369. break;
  370. case PERIPH_ID_SDMMC0:
  371. case PERIPH_ID_SDMMC1:
  372. src = readl(&clk->src_fsys);
  373. div = sub_div = readl(&clk->div_fsys1);
  374. break;
  375. case PERIPH_ID_SDMMC2:
  376. case PERIPH_ID_SDMMC3:
  377. src = readl(&clk->src_fsys);
  378. div = sub_div = readl(&clk->div_fsys2);
  379. break;
  380. case PERIPH_ID_I2C0:
  381. case PERIPH_ID_I2C1:
  382. case PERIPH_ID_I2C2:
  383. case PERIPH_ID_I2C3:
  384. case PERIPH_ID_I2C4:
  385. case PERIPH_ID_I2C5:
  386. case PERIPH_ID_I2C6:
  387. case PERIPH_ID_I2C7:
  388. src = EXYNOS_SRC_MPLL;
  389. div = readl(&clk->div_top1);
  390. sub_div = readl(&clk->div_top0);
  391. break;
  392. default:
  393. debug("%s: invalid peripheral %d", __func__, peripheral);
  394. return -1;
  395. };
  396. if (bit_info->src_bit >= 0)
  397. src = (src >> bit_info->src_bit) & bit_info->src_mask;
  398. switch (src) {
  399. case EXYNOS_SRC_MPLL:
  400. sclk = exynos5_get_pll_clk(MPLL);
  401. break;
  402. case EXYNOS_SRC_EPLL:
  403. sclk = exynos5_get_pll_clk(EPLL);
  404. break;
  405. case EXYNOS_SRC_VPLL:
  406. sclk = exynos5_get_pll_clk(VPLL);
  407. break;
  408. default:
  409. debug("%s: EXYNOS_SRC %d not supported\n", __func__, src);
  410. return 0;
  411. }
  412. /* Clock divider ratio for this peripheral */
  413. if (bit_info->div_bit >= 0)
  414. div = (div >> bit_info->div_bit) & bit_info->div_mask;
  415. /* Clock pre-divider ratio for this peripheral */
  416. if (bit_info->prediv_bit >= 0)
  417. sub_div = (sub_div >> bit_info->prediv_bit)
  418. & bit_info->prediv_mask;
  419. /* Calculate and return required clock rate */
  420. return (sclk / (div + 1)) / (sub_div + 1);
  421. }
  422. static unsigned long exynos542x_get_periph_rate(int peripheral)
  423. {
  424. struct clk_bit_info *bit_info = get_clk_bit_info(peripheral);
  425. unsigned long sclk = 0;
  426. unsigned int src = 0, div = 0, sub_div = 0;
  427. struct exynos5420_clock *clk =
  428. (struct exynos5420_clock *)samsung_get_base_clock();
  429. switch (peripheral) {
  430. case PERIPH_ID_UART0:
  431. case PERIPH_ID_UART1:
  432. case PERIPH_ID_UART2:
  433. case PERIPH_ID_UART3:
  434. case PERIPH_ID_PWM0:
  435. case PERIPH_ID_PWM1:
  436. case PERIPH_ID_PWM2:
  437. case PERIPH_ID_PWM3:
  438. case PERIPH_ID_PWM4:
  439. src = readl(&clk->src_peric0);
  440. div = readl(&clk->div_peric0);
  441. break;
  442. case PERIPH_ID_SPI0:
  443. case PERIPH_ID_SPI1:
  444. case PERIPH_ID_SPI2:
  445. src = readl(&clk->src_peric1);
  446. div = readl(&clk->div_peric1);
  447. sub_div = readl(&clk->div_peric4);
  448. break;
  449. case PERIPH_ID_SPI3:
  450. case PERIPH_ID_SPI4:
  451. src = readl(&clk->src_isp);
  452. div = readl(&clk->div_isp1);
  453. sub_div = readl(&clk->div_isp1);
  454. break;
  455. case PERIPH_ID_SDMMC0:
  456. case PERIPH_ID_SDMMC1:
  457. case PERIPH_ID_SDMMC2:
  458. case PERIPH_ID_SDMMC3:
  459. src = readl(&clk->src_fsys);
  460. div = readl(&clk->div_fsys1);
  461. break;
  462. case PERIPH_ID_I2C0:
  463. case PERIPH_ID_I2C1:
  464. case PERIPH_ID_I2C2:
  465. case PERIPH_ID_I2C3:
  466. case PERIPH_ID_I2C4:
  467. case PERIPH_ID_I2C5:
  468. case PERIPH_ID_I2C6:
  469. case PERIPH_ID_I2C7:
  470. case PERIPH_ID_I2C8:
  471. case PERIPH_ID_I2C9:
  472. case PERIPH_ID_I2C10:
  473. src = EXYNOS542X_SRC_MPLL;
  474. div = readl(&clk->div_top1);
  475. break;
  476. default:
  477. debug("%s: invalid peripheral %d", __func__, peripheral);
  478. return -1;
  479. };
  480. if (bit_info->src_bit >= 0)
  481. src = (src >> bit_info->src_bit) & bit_info->src_mask;
  482. switch (src) {
  483. case EXYNOS542X_SRC_MPLL:
  484. sclk = exynos542x_get_pll_clk(MPLL);
  485. break;
  486. case EXYNOS542X_SRC_SPLL:
  487. sclk = exynos542x_get_pll_clk(SPLL);
  488. break;
  489. case EXYNOS542X_SRC_EPLL:
  490. sclk = exynos542x_get_pll_clk(EPLL);
  491. break;
  492. case EXYNOS542X_SRC_RPLL:
  493. sclk = exynos542x_get_pll_clk(RPLL);
  494. break;
  495. default:
  496. debug("%s: EXYNOS542X_SRC %d not supported", __func__, src);
  497. return 0;
  498. }
  499. /* Clock divider ratio for this peripheral */
  500. if (bit_info->div_bit >= 0)
  501. div = (div >> bit_info->div_bit) & bit_info->div_mask;
  502. /* Clock pre-divider ratio for this peripheral */
  503. if (bit_info->prediv_bit >= 0)
  504. sub_div = (sub_div >> bit_info->prediv_bit)
  505. & bit_info->prediv_mask;
  506. /* Calculate and return required clock rate */
  507. return (sclk / (div + 1)) / (sub_div + 1);
  508. }
  509. unsigned long clock_get_periph_rate(int peripheral)
  510. {
  511. if (cpu_is_exynos5()) {
  512. if (proid_is_exynos542x())
  513. return exynos542x_get_periph_rate(peripheral);
  514. return exynos5_get_periph_rate(peripheral);
  515. } else {
  516. return 0;
  517. }
  518. }
  519. /* exynos4: return ARM clock frequency */
  520. static unsigned long exynos4_get_arm_clk(void)
  521. {
  522. struct exynos4_clock *clk =
  523. (struct exynos4_clock *)samsung_get_base_clock();
  524. unsigned long div;
  525. unsigned long armclk;
  526. unsigned int core_ratio;
  527. unsigned int core2_ratio;
  528. div = readl(&clk->div_cpu0);
  529. /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
  530. core_ratio = (div >> 0) & 0x7;
  531. core2_ratio = (div >> 28) & 0x7;
  532. armclk = get_pll_clk(APLL) / (core_ratio + 1);
  533. armclk /= (core2_ratio + 1);
  534. return armclk;
  535. }
  536. /* exynos4x12: return ARM clock frequency */
  537. static unsigned long exynos4x12_get_arm_clk(void)
  538. {
  539. struct exynos4x12_clock *clk =
  540. (struct exynos4x12_clock *)samsung_get_base_clock();
  541. unsigned long div;
  542. unsigned long armclk;
  543. unsigned int core_ratio;
  544. unsigned int core2_ratio;
  545. div = readl(&clk->div_cpu0);
  546. /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
  547. core_ratio = (div >> 0) & 0x7;
  548. core2_ratio = (div >> 28) & 0x7;
  549. armclk = get_pll_clk(APLL) / (core_ratio + 1);
  550. armclk /= (core2_ratio + 1);
  551. return armclk;
  552. }
  553. /* exynos5: return ARM clock frequency */
  554. static unsigned long exynos5_get_arm_clk(void)
  555. {
  556. struct exynos5_clock *clk =
  557. (struct exynos5_clock *)samsung_get_base_clock();
  558. unsigned long div;
  559. unsigned long armclk;
  560. unsigned int arm_ratio;
  561. unsigned int arm2_ratio;
  562. div = readl(&clk->div_cpu0);
  563. /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
  564. arm_ratio = (div >> 0) & 0x7;
  565. arm2_ratio = (div >> 28) & 0x7;
  566. armclk = get_pll_clk(APLL) / (arm_ratio + 1);
  567. armclk /= (arm2_ratio + 1);
  568. return armclk;
  569. }
  570. /* exynos4: return pwm clock frequency */
  571. static unsigned long exynos4_get_pwm_clk(void)
  572. {
  573. struct exynos4_clock *clk =
  574. (struct exynos4_clock *)samsung_get_base_clock();
  575. unsigned long pclk, sclk;
  576. unsigned int sel;
  577. unsigned int ratio;
  578. if (s5p_get_cpu_rev() == 0) {
  579. /*
  580. * CLK_SRC_PERIL0
  581. * PWM_SEL [27:24]
  582. */
  583. sel = readl(&clk->src_peril0);
  584. sel = (sel >> 24) & 0xf;
  585. if (sel == 0x6)
  586. sclk = get_pll_clk(MPLL);
  587. else if (sel == 0x7)
  588. sclk = get_pll_clk(EPLL);
  589. else if (sel == 0x8)
  590. sclk = get_pll_clk(VPLL);
  591. else
  592. return 0;
  593. /*
  594. * CLK_DIV_PERIL3
  595. * PWM_RATIO [3:0]
  596. */
  597. ratio = readl(&clk->div_peril3);
  598. ratio = ratio & 0xf;
  599. } else if (s5p_get_cpu_rev() == 1) {
  600. sclk = get_pll_clk(MPLL);
  601. ratio = 8;
  602. } else
  603. return 0;
  604. pclk = sclk / (ratio + 1);
  605. return pclk;
  606. }
  607. /* exynos4x12: return pwm clock frequency */
  608. static unsigned long exynos4x12_get_pwm_clk(void)
  609. {
  610. unsigned long pclk, sclk;
  611. unsigned int ratio;
  612. sclk = get_pll_clk(MPLL);
  613. ratio = 8;
  614. pclk = sclk / (ratio + 1);
  615. return pclk;
  616. }
  617. /* exynos4: return uart clock frequency */
  618. static unsigned long exynos4_get_uart_clk(int dev_index)
  619. {
  620. struct exynos4_clock *clk =
  621. (struct exynos4_clock *)samsung_get_base_clock();
  622. unsigned long uclk, sclk;
  623. unsigned int sel;
  624. unsigned int ratio;
  625. /*
  626. * CLK_SRC_PERIL0
  627. * UART0_SEL [3:0]
  628. * UART1_SEL [7:4]
  629. * UART2_SEL [8:11]
  630. * UART3_SEL [12:15]
  631. * UART4_SEL [16:19]
  632. * UART5_SEL [23:20]
  633. */
  634. sel = readl(&clk->src_peril0);
  635. sel = (sel >> (dev_index << 2)) & 0xf;
  636. if (sel == 0x6)
  637. sclk = get_pll_clk(MPLL);
  638. else if (sel == 0x7)
  639. sclk = get_pll_clk(EPLL);
  640. else if (sel == 0x8)
  641. sclk = get_pll_clk(VPLL);
  642. else
  643. return 0;
  644. /*
  645. * CLK_DIV_PERIL0
  646. * UART0_RATIO [3:0]
  647. * UART1_RATIO [7:4]
  648. * UART2_RATIO [8:11]
  649. * UART3_RATIO [12:15]
  650. * UART4_RATIO [16:19]
  651. * UART5_RATIO [23:20]
  652. */
  653. ratio = readl(&clk->div_peril0);
  654. ratio = (ratio >> (dev_index << 2)) & 0xf;
  655. uclk = sclk / (ratio + 1);
  656. return uclk;
  657. }
  658. /* exynos4x12: return uart clock frequency */
  659. static unsigned long exynos4x12_get_uart_clk(int dev_index)
  660. {
  661. struct exynos4x12_clock *clk =
  662. (struct exynos4x12_clock *)samsung_get_base_clock();
  663. unsigned long uclk, sclk;
  664. unsigned int sel;
  665. unsigned int ratio;
  666. /*
  667. * CLK_SRC_PERIL0
  668. * UART0_SEL [3:0]
  669. * UART1_SEL [7:4]
  670. * UART2_SEL [8:11]
  671. * UART3_SEL [12:15]
  672. * UART4_SEL [16:19]
  673. */
  674. sel = readl(&clk->src_peril0);
  675. sel = (sel >> (dev_index << 2)) & 0xf;
  676. if (sel == 0x6)
  677. sclk = get_pll_clk(MPLL);
  678. else if (sel == 0x7)
  679. sclk = get_pll_clk(EPLL);
  680. else if (sel == 0x8)
  681. sclk = get_pll_clk(VPLL);
  682. else
  683. return 0;
  684. /*
  685. * CLK_DIV_PERIL0
  686. * UART0_RATIO [3:0]
  687. * UART1_RATIO [7:4]
  688. * UART2_RATIO [8:11]
  689. * UART3_RATIO [12:15]
  690. * UART4_RATIO [16:19]
  691. */
  692. ratio = readl(&clk->div_peril0);
  693. ratio = (ratio >> (dev_index << 2)) & 0xf;
  694. uclk = sclk / (ratio + 1);
  695. return uclk;
  696. }
  697. static unsigned long exynos4_get_mmc_clk(int dev_index)
  698. {
  699. struct exynos4_clock *clk =
  700. (struct exynos4_clock *)samsung_get_base_clock();
  701. unsigned long uclk, sclk;
  702. unsigned int sel, ratio, pre_ratio;
  703. int shift = 0;
  704. sel = readl(&clk->src_fsys);
  705. sel = (sel >> (dev_index << 2)) & 0xf;
  706. if (sel == 0x6)
  707. sclk = get_pll_clk(MPLL);
  708. else if (sel == 0x7)
  709. sclk = get_pll_clk(EPLL);
  710. else if (sel == 0x8)
  711. sclk = get_pll_clk(VPLL);
  712. else
  713. return 0;
  714. switch (dev_index) {
  715. case 0:
  716. case 1:
  717. ratio = readl(&clk->div_fsys1);
  718. pre_ratio = readl(&clk->div_fsys1);
  719. break;
  720. case 2:
  721. case 3:
  722. ratio = readl(&clk->div_fsys2);
  723. pre_ratio = readl(&clk->div_fsys2);
  724. break;
  725. case 4:
  726. ratio = readl(&clk->div_fsys3);
  727. pre_ratio = readl(&clk->div_fsys3);
  728. break;
  729. default:
  730. return 0;
  731. }
  732. if (dev_index == 1 || dev_index == 3)
  733. shift = 16;
  734. ratio = (ratio >> shift) & 0xf;
  735. pre_ratio = (pre_ratio >> (shift + 8)) & 0xff;
  736. uclk = (sclk / (ratio + 1)) / (pre_ratio + 1);
  737. return uclk;
  738. }
  739. /* exynos4: set the mmc clock */
  740. static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
  741. {
  742. struct exynos4_clock *clk =
  743. (struct exynos4_clock *)samsung_get_base_clock();
  744. unsigned int addr, clear_bit, set_bit;
  745. /*
  746. * CLK_DIV_FSYS1
  747. * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
  748. * CLK_DIV_FSYS2
  749. * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
  750. * CLK_DIV_FSYS3
  751. * MMC4_RATIO [3:0]
  752. */
  753. if (dev_index < 2) {
  754. addr = (unsigned int)&clk->div_fsys1;
  755. clear_bit = MASK_PRE_RATIO(dev_index);
  756. set_bit = SET_PRE_RATIO(dev_index, div);
  757. } else if (dev_index == 4) {
  758. addr = (unsigned int)&clk->div_fsys3;
  759. dev_index -= 4;
  760. /* MMC4 is controlled with the MMC4_RATIO value */
  761. clear_bit = MASK_RATIO(dev_index);
  762. set_bit = SET_RATIO(dev_index, div);
  763. } else {
  764. addr = (unsigned int)&clk->div_fsys2;
  765. dev_index -= 2;
  766. clear_bit = MASK_PRE_RATIO(dev_index);
  767. set_bit = SET_PRE_RATIO(dev_index, div);
  768. }
  769. clrsetbits_le32(addr, clear_bit, set_bit);
  770. }
  771. /* exynos5: set the mmc clock */
  772. static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
  773. {
  774. struct exynos5_clock *clk =
  775. (struct exynos5_clock *)samsung_get_base_clock();
  776. unsigned int addr;
  777. /*
  778. * CLK_DIV_FSYS1
  779. * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
  780. * CLK_DIV_FSYS2
  781. * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
  782. */
  783. if (dev_index < 2) {
  784. addr = (unsigned int)&clk->div_fsys1;
  785. } else {
  786. addr = (unsigned int)&clk->div_fsys2;
  787. dev_index -= 2;
  788. }
  789. clrsetbits_le32(addr, 0xff << ((dev_index << 4) + 8),
  790. (div & 0xff) << ((dev_index << 4) + 8));
  791. }
  792. /* exynos5: set the mmc clock */
  793. static void exynos5420_set_mmc_clk(int dev_index, unsigned int div)
  794. {
  795. struct exynos5420_clock *clk =
  796. (struct exynos5420_clock *)samsung_get_base_clock();
  797. unsigned int addr;
  798. unsigned int shift;
  799. /*
  800. * CLK_DIV_FSYS1
  801. * MMC0_RATIO [9:0]
  802. * MMC1_RATIO [19:10]
  803. * MMC2_RATIO [29:20]
  804. */
  805. addr = (unsigned int)&clk->div_fsys1;
  806. shift = dev_index * 10;
  807. clrsetbits_le32(addr, 0x3ff << shift, (div & 0x3ff) << shift);
  808. }
  809. /* get_lcd_clk: return lcd clock frequency */
  810. static unsigned long exynos4_get_lcd_clk(void)
  811. {
  812. struct exynos4_clock *clk =
  813. (struct exynos4_clock *)samsung_get_base_clock();
  814. unsigned long pclk, sclk;
  815. unsigned int sel;
  816. unsigned int ratio;
  817. /*
  818. * CLK_SRC_LCD0
  819. * FIMD0_SEL [3:0]
  820. */
  821. sel = readl(&clk->src_lcd0);
  822. sel = sel & 0xf;
  823. /*
  824. * 0x6: SCLK_MPLL
  825. * 0x7: SCLK_EPLL
  826. * 0x8: SCLK_VPLL
  827. */
  828. if (sel == 0x6)
  829. sclk = get_pll_clk(MPLL);
  830. else if (sel == 0x7)
  831. sclk = get_pll_clk(EPLL);
  832. else if (sel == 0x8)
  833. sclk = get_pll_clk(VPLL);
  834. else
  835. return 0;
  836. /*
  837. * CLK_DIV_LCD0
  838. * FIMD0_RATIO [3:0]
  839. */
  840. ratio = readl(&clk->div_lcd0);
  841. ratio = ratio & 0xf;
  842. pclk = sclk / (ratio + 1);
  843. return pclk;
  844. }
  845. /* get_lcd_clk: return lcd clock frequency */
  846. static unsigned long exynos5_get_lcd_clk(void)
  847. {
  848. struct exynos5_clock *clk =
  849. (struct exynos5_clock *)samsung_get_base_clock();
  850. unsigned long pclk, sclk;
  851. unsigned int sel;
  852. unsigned int ratio;
  853. /*
  854. * CLK_SRC_LCD0
  855. * FIMD0_SEL [3:0]
  856. */
  857. sel = readl(&clk->src_disp1_0);
  858. sel = sel & 0xf;
  859. /*
  860. * 0x6: SCLK_MPLL
  861. * 0x7: SCLK_EPLL
  862. * 0x8: SCLK_VPLL
  863. */
  864. if (sel == 0x6)
  865. sclk = get_pll_clk(MPLL);
  866. else if (sel == 0x7)
  867. sclk = get_pll_clk(EPLL);
  868. else if (sel == 0x8)
  869. sclk = get_pll_clk(VPLL);
  870. else
  871. return 0;
  872. /*
  873. * CLK_DIV_LCD0
  874. * FIMD0_RATIO [3:0]
  875. */
  876. ratio = readl(&clk->div_disp1_0);
  877. ratio = ratio & 0xf;
  878. pclk = sclk / (ratio + 1);
  879. return pclk;
  880. }
  881. static unsigned long exynos5420_get_lcd_clk(void)
  882. {
  883. struct exynos5420_clock *clk =
  884. (struct exynos5420_clock *)samsung_get_base_clock();
  885. unsigned long pclk, sclk;
  886. unsigned int sel;
  887. unsigned int ratio;
  888. /*
  889. * CLK_SRC_DISP10
  890. * FIMD1_SEL [4]
  891. * 0: SCLK_RPLL
  892. * 1: SCLK_SPLL
  893. */
  894. sel = readl(&clk->src_disp10);
  895. sel &= (1 << 4);
  896. if (sel)
  897. sclk = get_pll_clk(SPLL);
  898. else
  899. sclk = get_pll_clk(RPLL);
  900. /*
  901. * CLK_DIV_DISP10
  902. * FIMD1_RATIO [3:0]
  903. */
  904. ratio = readl(&clk->div_disp10);
  905. ratio = ratio & 0xf;
  906. pclk = sclk / (ratio + 1);
  907. return pclk;
  908. }
  909. static unsigned long exynos5800_get_lcd_clk(void)
  910. {
  911. struct exynos5420_clock *clk =
  912. (struct exynos5420_clock *)samsung_get_base_clock();
  913. unsigned long sclk;
  914. unsigned int sel;
  915. unsigned int ratio;
  916. /*
  917. * CLK_SRC_DISP10
  918. * CLKMUX_FIMD1 [6:4]
  919. */
  920. sel = (readl(&clk->src_disp10) >> 4) & 0x7;
  921. if (sel) {
  922. /*
  923. * Mapping of CLK_SRC_DISP10 CLKMUX_FIMD1 [6:4] values into
  924. * PLLs. The first element is a placeholder to bypass the
  925. * default settig.
  926. */
  927. const int reg_map[] = {0, CPLL, DPLL, MPLL, SPLL, IPLL, EPLL,
  928. RPLL};
  929. sclk = get_pll_clk(reg_map[sel]);
  930. } else
  931. sclk = get_board_sys_clk();
  932. /*
  933. * CLK_DIV_DISP10
  934. * FIMD1_RATIO [3:0]
  935. */
  936. ratio = readl(&clk->div_disp10) & 0xf;
  937. return sclk / (ratio + 1);
  938. }
  939. void exynos4_set_lcd_clk(void)
  940. {
  941. struct exynos4_clock *clk =
  942. (struct exynos4_clock *)samsung_get_base_clock();
  943. /*
  944. * CLK_GATE_BLOCK
  945. * CLK_CAM [0]
  946. * CLK_TV [1]
  947. * CLK_MFC [2]
  948. * CLK_G3D [3]
  949. * CLK_LCD0 [4]
  950. * CLK_LCD1 [5]
  951. * CLK_GPS [7]
  952. */
  953. setbits_le32(&clk->gate_block, 1 << 4);
  954. /*
  955. * CLK_SRC_LCD0
  956. * FIMD0_SEL [3:0]
  957. * MDNIE0_SEL [7:4]
  958. * MDNIE_PWM0_SEL [8:11]
  959. * MIPI0_SEL [12:15]
  960. * set lcd0 src clock 0x6: SCLK_MPLL
  961. */
  962. clrsetbits_le32(&clk->src_lcd0, 0xf, 0x6);
  963. /*
  964. * CLK_GATE_IP_LCD0
  965. * CLK_FIMD0 [0]
  966. * CLK_MIE0 [1]
  967. * CLK_MDNIE0 [2]
  968. * CLK_DSIM0 [3]
  969. * CLK_SMMUFIMD0 [4]
  970. * CLK_PPMULCD0 [5]
  971. * Gating all clocks for FIMD0
  972. */
  973. setbits_le32(&clk->gate_ip_lcd0, 1 << 0);
  974. /*
  975. * CLK_DIV_LCD0
  976. * FIMD0_RATIO [3:0]
  977. * MDNIE0_RATIO [7:4]
  978. * MDNIE_PWM0_RATIO [11:8]
  979. * MDNIE_PWM_PRE_RATIO [15:12]
  980. * MIPI0_RATIO [19:16]
  981. * MIPI0_PRE_RATIO [23:20]
  982. * set fimd ratio
  983. */
  984. clrsetbits_le32(&clk->div_lcd0, 0xf, 0x1);
  985. }
  986. void exynos5_set_lcd_clk(void)
  987. {
  988. struct exynos5_clock *clk =
  989. (struct exynos5_clock *)samsung_get_base_clock();
  990. /*
  991. * CLK_GATE_BLOCK
  992. * CLK_CAM [0]
  993. * CLK_TV [1]
  994. * CLK_MFC [2]
  995. * CLK_G3D [3]
  996. * CLK_LCD0 [4]
  997. * CLK_LCD1 [5]
  998. * CLK_GPS [7]
  999. */
  1000. setbits_le32(&clk->gate_block, 1 << 4);
  1001. /*
  1002. * CLK_SRC_LCD0
  1003. * FIMD0_SEL [3:0]
  1004. * MDNIE0_SEL [7:4]
  1005. * MDNIE_PWM0_SEL [8:11]
  1006. * MIPI0_SEL [12:15]
  1007. * set lcd0 src clock 0x6: SCLK_MPLL
  1008. */
  1009. clrsetbits_le32(&clk->src_disp1_0, 0xf, 0x6);
  1010. /*
  1011. * CLK_GATE_IP_LCD0
  1012. * CLK_FIMD0 [0]
  1013. * CLK_MIE0 [1]
  1014. * CLK_MDNIE0 [2]
  1015. * CLK_DSIM0 [3]
  1016. * CLK_SMMUFIMD0 [4]
  1017. * CLK_PPMULCD0 [5]
  1018. * Gating all clocks for FIMD0
  1019. */
  1020. setbits_le32(&clk->gate_ip_disp1, 1 << 0);
  1021. /*
  1022. * CLK_DIV_LCD0
  1023. * FIMD0_RATIO [3:0]
  1024. * MDNIE0_RATIO [7:4]
  1025. * MDNIE_PWM0_RATIO [11:8]
  1026. * MDNIE_PWM_PRE_RATIO [15:12]
  1027. * MIPI0_RATIO [19:16]
  1028. * MIPI0_PRE_RATIO [23:20]
  1029. * set fimd ratio
  1030. */
  1031. clrsetbits_le32(&clk->div_disp1_0, 0xf, 0x0);
  1032. }
  1033. void exynos5420_set_lcd_clk(void)
  1034. {
  1035. struct exynos5420_clock *clk =
  1036. (struct exynos5420_clock *)samsung_get_base_clock();
  1037. unsigned int cfg;
  1038. /*
  1039. * CLK_SRC_DISP10
  1040. * FIMD1_SEL [4]
  1041. * 0: SCLK_RPLL
  1042. * 1: SCLK_SPLL
  1043. */
  1044. cfg = readl(&clk->src_disp10);
  1045. cfg &= ~(0x1 << 4);
  1046. cfg |= (0 << 4);
  1047. writel(cfg, &clk->src_disp10);
  1048. /*
  1049. * CLK_DIV_DISP10
  1050. * FIMD1_RATIO [3:0]
  1051. */
  1052. cfg = readl(&clk->div_disp10);
  1053. cfg &= ~(0xf << 0);
  1054. cfg |= (0 << 0);
  1055. writel(cfg, &clk->div_disp10);
  1056. }
  1057. void exynos5800_set_lcd_clk(void)
  1058. {
  1059. struct exynos5420_clock *clk =
  1060. (struct exynos5420_clock *)samsung_get_base_clock();
  1061. unsigned int cfg;
  1062. /*
  1063. * Use RPLL for pixel clock
  1064. * CLK_SRC_DISP10 CLKMUX_FIMD1 [6:4]
  1065. * ==================
  1066. * 111: SCLK_RPLL
  1067. */
  1068. cfg = readl(&clk->src_disp10) | (0x7 << 4);
  1069. writel(cfg, &clk->src_disp10);
  1070. /*
  1071. * CLK_DIV_DISP10
  1072. * FIMD1_RATIO [3:0]
  1073. */
  1074. clrsetbits_le32(&clk->div_disp10, 0xf << 0, 0x0 << 0);
  1075. }
  1076. void exynos4_set_mipi_clk(void)
  1077. {
  1078. struct exynos4_clock *clk =
  1079. (struct exynos4_clock *)samsung_get_base_clock();
  1080. /*
  1081. * CLK_SRC_LCD0
  1082. * FIMD0_SEL [3:0]
  1083. * MDNIE0_SEL [7:4]
  1084. * MDNIE_PWM0_SEL [8:11]
  1085. * MIPI0_SEL [12:15]
  1086. * set mipi0 src clock 0x6: SCLK_MPLL
  1087. */
  1088. clrsetbits_le32(&clk->src_lcd0, 0xf << 12, 0x6 << 12);
  1089. /*
  1090. * CLK_SRC_MASK_LCD0
  1091. * FIMD0_MASK [0]
  1092. * MDNIE0_MASK [4]
  1093. * MDNIE_PWM0_MASK [8]
  1094. * MIPI0_MASK [12]
  1095. * set src mask mipi0 0x1: Unmask
  1096. */
  1097. setbits_le32(&clk->src_mask_lcd0, 0x1 << 12);
  1098. /*
  1099. * CLK_GATE_IP_LCD0
  1100. * CLK_FIMD0 [0]
  1101. * CLK_MIE0 [1]
  1102. * CLK_MDNIE0 [2]
  1103. * CLK_DSIM0 [3]
  1104. * CLK_SMMUFIMD0 [4]
  1105. * CLK_PPMULCD0 [5]
  1106. * Gating all clocks for MIPI0
  1107. */
  1108. setbits_le32(&clk->gate_ip_lcd0, 1 << 3);
  1109. /*
  1110. * CLK_DIV_LCD0
  1111. * FIMD0_RATIO [3:0]
  1112. * MDNIE0_RATIO [7:4]
  1113. * MDNIE_PWM0_RATIO [11:8]
  1114. * MDNIE_PWM_PRE_RATIO [15:12]
  1115. * MIPI0_RATIO [19:16]
  1116. * MIPI0_PRE_RATIO [23:20]
  1117. * set mipi ratio
  1118. */
  1119. clrsetbits_le32(&clk->div_lcd0, 0xf << 16, 0x1 << 16);
  1120. }
  1121. int exynos5_set_epll_clk(unsigned long rate)
  1122. {
  1123. unsigned int epll_con, epll_con_k;
  1124. unsigned int i;
  1125. unsigned int lockcnt;
  1126. unsigned int start;
  1127. struct exynos5_clock *clk =
  1128. (struct exynos5_clock *)samsung_get_base_clock();
  1129. epll_con = readl(&clk->epll_con0);
  1130. epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK <<
  1131. EPLL_CON0_LOCK_DET_EN_SHIFT) |
  1132. EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT |
  1133. EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT |
  1134. EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT);
  1135. for (i = 0; i < ARRAY_SIZE(exynos5_epll_div); i++) {
  1136. if (exynos5_epll_div[i].freq_out == rate)
  1137. break;
  1138. }
  1139. if (i == ARRAY_SIZE(exynos5_epll_div))
  1140. return -1;
  1141. epll_con_k = exynos5_epll_div[i].k_dsm << 0;
  1142. epll_con |= exynos5_epll_div[i].en_lock_det <<
  1143. EPLL_CON0_LOCK_DET_EN_SHIFT;
  1144. epll_con |= exynos5_epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT;
  1145. epll_con |= exynos5_epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT;
  1146. epll_con |= exynos5_epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT;
  1147. /*
  1148. * Required period ( in cycles) to genarate a stable clock output.
  1149. * The maximum clock time can be up to 3000 * PDIV cycles of PLLs
  1150. * frequency input (as per spec)
  1151. */
  1152. lockcnt = 3000 * exynos5_epll_div[i].p_div;
  1153. writel(lockcnt, &clk->epll_lock);
  1154. writel(epll_con, &clk->epll_con0);
  1155. writel(epll_con_k, &clk->epll_con1);
  1156. start = get_timer(0);
  1157. while (!(readl(&clk->epll_con0) &
  1158. (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) {
  1159. if (get_timer(start) > TIMEOUT_EPLL_LOCK) {
  1160. debug("%s: Timeout waiting for EPLL lock\n", __func__);
  1161. return -1;
  1162. }
  1163. }
  1164. return 0;
  1165. }
  1166. static int exynos5420_set_i2s_clk_source(void)
  1167. {
  1168. struct exynos5420_clock *clk =
  1169. (struct exynos5420_clock *)samsung_get_base_clock();
  1170. setbits_le32(&clk->src_top6, EXYNOS5420_CLK_SRC_MOUT_EPLL);
  1171. clrsetbits_le32(&clk->src_mau, EXYNOS5420_AUDIO0_SEL_MASK,
  1172. (EXYNOS5420_CLK_SRC_SCLK_EPLL));
  1173. setbits_le32(EXYNOS5_AUDIOSS_BASE, 1 << 0);
  1174. return 0;
  1175. }
  1176. int exynos5_set_i2s_clk_source(unsigned int i2s_id)
  1177. {
  1178. struct exynos5_clock *clk =
  1179. (struct exynos5_clock *)samsung_get_base_clock();
  1180. unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass();
  1181. if (i2s_id == 0) {
  1182. setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL);
  1183. clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK,
  1184. (CLK_SRC_SCLK_EPLL));
  1185. setbits_le32(audio_ass, AUDIO_CLKMUX_ASS);
  1186. } else if (i2s_id == 1) {
  1187. clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
  1188. (CLK_SRC_SCLK_EPLL));
  1189. } else {
  1190. return -1;
  1191. }
  1192. return 0;
  1193. }
  1194. int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
  1195. unsigned int dst_frq,
  1196. unsigned int i2s_id)
  1197. {
  1198. struct exynos5_clock *clk =
  1199. (struct exynos5_clock *)samsung_get_base_clock();
  1200. unsigned int div;
  1201. if ((dst_frq == 0) || (src_frq == 0)) {
  1202. debug("%s: Invalid requency input for prescaler\n", __func__);
  1203. debug("src frq = %d des frq = %d ", src_frq, dst_frq);
  1204. return -1;
  1205. }
  1206. div = (src_frq / dst_frq);
  1207. if (i2s_id == 0) {
  1208. if (div > AUDIO_0_RATIO_MASK) {
  1209. debug("%s: Frequency ratio is out of range\n",
  1210. __func__);
  1211. debug("src frq = %d des frq = %d ", src_frq, dst_frq);
  1212. return -1;
  1213. }
  1214. clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK,
  1215. (div & AUDIO_0_RATIO_MASK));
  1216. } else if (i2s_id == 1) {
  1217. if (div > AUDIO_1_RATIO_MASK) {
  1218. debug("%s: Frequency ratio is out of range\n",
  1219. __func__);
  1220. debug("src frq = %d des frq = %d ", src_frq, dst_frq);
  1221. return -1;
  1222. }
  1223. clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
  1224. (div & AUDIO_1_RATIO_MASK));
  1225. } else {
  1226. return -1;
  1227. }
  1228. return 0;
  1229. }
  1230. /**
  1231. * Linearly searches for the most accurate main and fine stage clock scalars
  1232. * (divisors) for a specified target frequency and scalar bit sizes by checking
  1233. * all multiples of main_scalar_bits values. Will always return scalars up to or
  1234. * slower than target.
  1235. *
  1236. * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32
  1237. * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32
  1238. * @param input_freq Clock frequency to be scaled in Hz
  1239. * @param target_freq Desired clock frequency in Hz
  1240. * @param best_fine_scalar Pointer to store the fine stage divisor
  1241. *
  1242. * Return: best_main_scalar Main scalar for desired frequency or -1 if none
  1243. * found
  1244. */
  1245. static int clock_calc_best_scalar(unsigned int main_scaler_bits,
  1246. unsigned int fine_scalar_bits, unsigned int input_rate,
  1247. unsigned int target_rate, unsigned int *best_fine_scalar)
  1248. {
  1249. int i;
  1250. int best_main_scalar = -1;
  1251. unsigned int best_error = target_rate;
  1252. const unsigned int cap = (1 << fine_scalar_bits) - 1;
  1253. const unsigned int loops = 1 << main_scaler_bits;
  1254. debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
  1255. target_rate, cap);
  1256. assert(best_fine_scalar != NULL);
  1257. assert(main_scaler_bits <= fine_scalar_bits);
  1258. *best_fine_scalar = 1;
  1259. if (input_rate == 0 || target_rate == 0)
  1260. return -1;
  1261. if (target_rate >= input_rate)
  1262. return 1;
  1263. for (i = 1; i <= loops; i++) {
  1264. const unsigned int effective_div =
  1265. max(min(input_rate / i / target_rate, cap), 1U);
  1266. const unsigned int effective_rate = input_rate / i /
  1267. effective_div;
  1268. const int error = target_rate - effective_rate;
  1269. debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
  1270. effective_rate, error);
  1271. if (error >= 0 && error <= best_error) {
  1272. best_error = error;
  1273. best_main_scalar = i;
  1274. *best_fine_scalar = effective_div;
  1275. }
  1276. }
  1277. return best_main_scalar;
  1278. }
  1279. static int exynos5_set_spi_clk(enum periph_id periph_id,
  1280. unsigned int rate)
  1281. {
  1282. struct exynos5_clock *clk =
  1283. (struct exynos5_clock *)samsung_get_base_clock();
  1284. int main;
  1285. unsigned int fine;
  1286. unsigned shift, pre_shift;
  1287. unsigned mask = 0xff;
  1288. u32 *reg;
  1289. main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
  1290. if (main < 0) {
  1291. debug("%s: Cannot set clock rate for periph %d",
  1292. __func__, periph_id);
  1293. return -1;
  1294. }
  1295. main = main - 1;
  1296. fine = fine - 1;
  1297. switch (periph_id) {
  1298. case PERIPH_ID_SPI0:
  1299. reg = &clk->div_peric1;
  1300. shift = 0;
  1301. pre_shift = 8;
  1302. break;
  1303. case PERIPH_ID_SPI1:
  1304. reg = &clk->div_peric1;
  1305. shift = 16;
  1306. pre_shift = 24;
  1307. break;
  1308. case PERIPH_ID_SPI2:
  1309. reg = &clk->div_peric2;
  1310. shift = 0;
  1311. pre_shift = 8;
  1312. break;
  1313. case PERIPH_ID_SPI3:
  1314. reg = &clk->sclk_div_isp;
  1315. shift = 0;
  1316. pre_shift = 4;
  1317. break;
  1318. case PERIPH_ID_SPI4:
  1319. reg = &clk->sclk_div_isp;
  1320. shift = 12;
  1321. pre_shift = 16;
  1322. break;
  1323. default:
  1324. debug("%s: Unsupported peripheral ID %d\n", __func__,
  1325. periph_id);
  1326. return -1;
  1327. }
  1328. clrsetbits_le32(reg, mask << shift, (main & mask) << shift);
  1329. clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift);
  1330. return 0;
  1331. }
  1332. static int exynos5420_set_spi_clk(enum periph_id periph_id,
  1333. unsigned int rate)
  1334. {
  1335. struct exynos5420_clock *clk =
  1336. (struct exynos5420_clock *)samsung_get_base_clock();
  1337. int main;
  1338. unsigned int fine;
  1339. unsigned shift, pre_shift;
  1340. unsigned div_mask = 0xf, pre_div_mask = 0xff;
  1341. u32 *reg;
  1342. u32 *pre_reg;
  1343. main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
  1344. if (main < 0) {
  1345. debug("%s: Cannot set clock rate for periph %d",
  1346. __func__, periph_id);
  1347. return -1;
  1348. }
  1349. main = main - 1;
  1350. fine = fine - 1;
  1351. switch (periph_id) {
  1352. case PERIPH_ID_SPI0:
  1353. reg = &clk->div_peric1;
  1354. shift = 20;
  1355. pre_reg = &clk->div_peric4;
  1356. pre_shift = 8;
  1357. break;
  1358. case PERIPH_ID_SPI1:
  1359. reg = &clk->div_peric1;
  1360. shift = 24;
  1361. pre_reg = &clk->div_peric4;
  1362. pre_shift = 16;
  1363. break;
  1364. case PERIPH_ID_SPI2:
  1365. reg = &clk->div_peric1;
  1366. shift = 28;
  1367. pre_reg = &clk->div_peric4;
  1368. pre_shift = 24;
  1369. break;
  1370. case PERIPH_ID_SPI3:
  1371. reg = &clk->div_isp1;
  1372. shift = 16;
  1373. pre_reg = &clk->div_isp1;
  1374. pre_shift = 0;
  1375. break;
  1376. case PERIPH_ID_SPI4:
  1377. reg = &clk->div_isp1;
  1378. shift = 20;
  1379. pre_reg = &clk->div_isp1;
  1380. pre_shift = 8;
  1381. break;
  1382. default:
  1383. debug("%s: Unsupported peripheral ID %d\n", __func__,
  1384. periph_id);
  1385. return -1;
  1386. }
  1387. clrsetbits_le32(reg, div_mask << shift, (main & div_mask) << shift);
  1388. clrsetbits_le32(pre_reg, pre_div_mask << pre_shift,
  1389. (fine & pre_div_mask) << pre_shift);
  1390. return 0;
  1391. }
  1392. static unsigned long exynos4_get_i2c_clk(void)
  1393. {
  1394. struct exynos4_clock *clk =
  1395. (struct exynos4_clock *)samsung_get_base_clock();
  1396. unsigned long sclk, aclk_100;
  1397. unsigned int ratio;
  1398. sclk = get_pll_clk(APLL);
  1399. ratio = (readl(&clk->div_top)) >> 4;
  1400. ratio &= 0xf;
  1401. aclk_100 = sclk / (ratio + 1);
  1402. return aclk_100;
  1403. }
  1404. unsigned long get_pll_clk(int pllreg)
  1405. {
  1406. if (cpu_is_exynos5()) {
  1407. if (proid_is_exynos542x())
  1408. return exynos542x_get_pll_clk(pllreg);
  1409. return exynos5_get_pll_clk(pllreg);
  1410. } else if (cpu_is_exynos4()) {
  1411. if (proid_is_exynos4412())
  1412. return exynos4x12_get_pll_clk(pllreg);
  1413. return exynos4_get_pll_clk(pllreg);
  1414. }
  1415. return 0;
  1416. }
  1417. unsigned long get_arm_clk(void)
  1418. {
  1419. if (cpu_is_exynos5()) {
  1420. return exynos5_get_arm_clk();
  1421. } else if (cpu_is_exynos4()) {
  1422. if (proid_is_exynos4412())
  1423. return exynos4x12_get_arm_clk();
  1424. return exynos4_get_arm_clk();
  1425. }
  1426. return 0;
  1427. }
  1428. unsigned long get_i2c_clk(void)
  1429. {
  1430. if (cpu_is_exynos5())
  1431. return clock_get_periph_rate(PERIPH_ID_I2C0);
  1432. else if (cpu_is_exynos4())
  1433. return exynos4_get_i2c_clk();
  1434. return 0;
  1435. }
  1436. unsigned long get_pwm_clk(void)
  1437. {
  1438. if (cpu_is_exynos5()) {
  1439. return clock_get_periph_rate(PERIPH_ID_PWM0);
  1440. } else if (cpu_is_exynos4()) {
  1441. if (proid_is_exynos4412())
  1442. return exynos4x12_get_pwm_clk();
  1443. return exynos4_get_pwm_clk();
  1444. }
  1445. return 0;
  1446. }
  1447. unsigned long get_uart_clk(int dev_index)
  1448. {
  1449. enum periph_id id;
  1450. switch (dev_index) {
  1451. case 0:
  1452. id = PERIPH_ID_UART0;
  1453. break;
  1454. case 1:
  1455. id = PERIPH_ID_UART1;
  1456. break;
  1457. case 2:
  1458. id = PERIPH_ID_UART2;
  1459. break;
  1460. case 3:
  1461. id = PERIPH_ID_UART3;
  1462. break;
  1463. default:
  1464. debug("%s: invalid UART index %d", __func__, dev_index);
  1465. return -1;
  1466. }
  1467. if (cpu_is_exynos5()) {
  1468. return clock_get_periph_rate(id);
  1469. } else if (cpu_is_exynos4()) {
  1470. if (proid_is_exynos4412())
  1471. return exynos4x12_get_uart_clk(dev_index);
  1472. return exynos4_get_uart_clk(dev_index);
  1473. }
  1474. return 0;
  1475. }
  1476. unsigned long get_mmc_clk(int dev_index)
  1477. {
  1478. enum periph_id id;
  1479. if (cpu_is_exynos4())
  1480. return exynos4_get_mmc_clk(dev_index);
  1481. switch (dev_index) {
  1482. case 0:
  1483. id = PERIPH_ID_SDMMC0;
  1484. break;
  1485. case 1:
  1486. id = PERIPH_ID_SDMMC1;
  1487. break;
  1488. case 2:
  1489. id = PERIPH_ID_SDMMC2;
  1490. break;
  1491. case 3:
  1492. id = PERIPH_ID_SDMMC3;
  1493. break;
  1494. default:
  1495. debug("%s: invalid MMC index %d", __func__, dev_index);
  1496. return -1;
  1497. }
  1498. return clock_get_periph_rate(id);
  1499. }
  1500. void set_mmc_clk(int dev_index, unsigned int div)
  1501. {
  1502. /* If want to set correct value, it needs to substract one from div.*/
  1503. if (div > 0)
  1504. div -= 1;
  1505. if (cpu_is_exynos5()) {
  1506. if (proid_is_exynos542x())
  1507. exynos5420_set_mmc_clk(dev_index, div);
  1508. else
  1509. exynos5_set_mmc_clk(dev_index, div);
  1510. } else if (cpu_is_exynos4()) {
  1511. exynos4_set_mmc_clk(dev_index, div);
  1512. }
  1513. }
  1514. unsigned long get_lcd_clk(void)
  1515. {
  1516. if (cpu_is_exynos4()) {
  1517. return exynos4_get_lcd_clk();
  1518. } else if (cpu_is_exynos5()) {
  1519. if (proid_is_exynos5420())
  1520. return exynos5420_get_lcd_clk();
  1521. else if (proid_is_exynos5422())
  1522. return exynos5800_get_lcd_clk();
  1523. else
  1524. return exynos5_get_lcd_clk();
  1525. }
  1526. return 0;
  1527. }
  1528. void set_lcd_clk(void)
  1529. {
  1530. if (cpu_is_exynos4()) {
  1531. exynos4_set_lcd_clk();
  1532. } else if (cpu_is_exynos5()) {
  1533. if (proid_is_exynos5250())
  1534. exynos5_set_lcd_clk();
  1535. else if (proid_is_exynos5420())
  1536. exynos5420_set_lcd_clk();
  1537. else
  1538. exynos5800_set_lcd_clk();
  1539. }
  1540. }
  1541. void set_mipi_clk(void)
  1542. {
  1543. if (cpu_is_exynos4())
  1544. exynos4_set_mipi_clk();
  1545. }
  1546. int set_spi_clk(int periph_id, unsigned int rate)
  1547. {
  1548. if (cpu_is_exynos5()) {
  1549. if (proid_is_exynos542x())
  1550. return exynos5420_set_spi_clk(periph_id, rate);
  1551. return exynos5_set_spi_clk(periph_id, rate);
  1552. }
  1553. return 0;
  1554. }
  1555. int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
  1556. unsigned int i2s_id)
  1557. {
  1558. if (cpu_is_exynos5())
  1559. return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id);
  1560. return 0;
  1561. }
  1562. int set_i2s_clk_source(unsigned int i2s_id)
  1563. {
  1564. if (cpu_is_exynos5()) {
  1565. if (proid_is_exynos542x())
  1566. return exynos5420_set_i2s_clk_source();
  1567. else
  1568. return exynos5_set_i2s_clk_source(i2s_id);
  1569. }
  1570. return 0;
  1571. }
  1572. int set_epll_clk(unsigned long rate)
  1573. {
  1574. if (cpu_is_exynos5())
  1575. return exynos5_set_epll_clk(rate);
  1576. return 0;
  1577. }