clock.c 39 KB

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