clock.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791
  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 <log.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_exynos542x())
  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_exynos542x())
  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. static int exynos5420_set_i2s_clk_source(void)
  1166. {
  1167. struct exynos5420_clock *clk =
  1168. (struct exynos5420_clock *)samsung_get_base_clock();
  1169. setbits_le32(&clk->src_top6, EXYNOS5420_CLK_SRC_MOUT_EPLL);
  1170. clrsetbits_le32(&clk->src_mau, EXYNOS5420_AUDIO0_SEL_MASK,
  1171. (EXYNOS5420_CLK_SRC_SCLK_EPLL));
  1172. setbits_le32(EXYNOS5_AUDIOSS_BASE, 1 << 0);
  1173. return 0;
  1174. }
  1175. int exynos5_set_i2s_clk_source(unsigned int i2s_id)
  1176. {
  1177. struct exynos5_clock *clk =
  1178. (struct exynos5_clock *)samsung_get_base_clock();
  1179. unsigned int *audio_ass = (unsigned int *)samsung_get_base_audio_ass();
  1180. if (i2s_id == 0) {
  1181. setbits_le32(&clk->src_top2, CLK_SRC_MOUT_EPLL);
  1182. clrsetbits_le32(&clk->src_mau, AUDIO0_SEL_MASK,
  1183. (CLK_SRC_SCLK_EPLL));
  1184. setbits_le32(audio_ass, AUDIO_CLKMUX_ASS);
  1185. } else if (i2s_id == 1) {
  1186. clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK,
  1187. (CLK_SRC_SCLK_EPLL));
  1188. } else {
  1189. return -1;
  1190. }
  1191. return 0;
  1192. }
  1193. int exynos5_set_i2s_clk_prescaler(unsigned int src_frq,
  1194. unsigned int dst_frq,
  1195. unsigned int i2s_id)
  1196. {
  1197. struct exynos5_clock *clk =
  1198. (struct exynos5_clock *)samsung_get_base_clock();
  1199. unsigned int div;
  1200. if ((dst_frq == 0) || (src_frq == 0)) {
  1201. debug("%s: Invalid requency input for prescaler\n", __func__);
  1202. debug("src frq = %d des frq = %d ", src_frq, dst_frq);
  1203. return -1;
  1204. }
  1205. div = (src_frq / dst_frq);
  1206. if (i2s_id == 0) {
  1207. if (div > AUDIO_0_RATIO_MASK) {
  1208. debug("%s: Frequency ratio is out of range\n",
  1209. __func__);
  1210. debug("src frq = %d des frq = %d ", src_frq, dst_frq);
  1211. return -1;
  1212. }
  1213. clrsetbits_le32(&clk->div_mau, AUDIO_0_RATIO_MASK,
  1214. (div & AUDIO_0_RATIO_MASK));
  1215. } else if (i2s_id == 1) {
  1216. if (div > AUDIO_1_RATIO_MASK) {
  1217. debug("%s: Frequency ratio is out of range\n",
  1218. __func__);
  1219. debug("src frq = %d des frq = %d ", src_frq, dst_frq);
  1220. return -1;
  1221. }
  1222. clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK,
  1223. (div & AUDIO_1_RATIO_MASK));
  1224. } else {
  1225. return -1;
  1226. }
  1227. return 0;
  1228. }
  1229. /**
  1230. * Linearly searches for the most accurate main and fine stage clock scalars
  1231. * (divisors) for a specified target frequency and scalar bit sizes by checking
  1232. * all multiples of main_scalar_bits values. Will always return scalars up to or
  1233. * slower than target.
  1234. *
  1235. * @param main_scalar_bits Number of main scalar bits, must be > 0 and < 32
  1236. * @param fine_scalar_bits Number of fine scalar bits, must be > 0 and < 32
  1237. * @param input_freq Clock frequency to be scaled in Hz
  1238. * @param target_freq Desired clock frequency in Hz
  1239. * @param best_fine_scalar Pointer to store the fine stage divisor
  1240. *
  1241. * @return best_main_scalar Main scalar for desired frequency or -1 if none
  1242. * found
  1243. */
  1244. static int clock_calc_best_scalar(unsigned int main_scaler_bits,
  1245. unsigned int fine_scalar_bits, unsigned int input_rate,
  1246. unsigned int target_rate, unsigned int *best_fine_scalar)
  1247. {
  1248. int i;
  1249. int best_main_scalar = -1;
  1250. unsigned int best_error = target_rate;
  1251. const unsigned int cap = (1 << fine_scalar_bits) - 1;
  1252. const unsigned int loops = 1 << main_scaler_bits;
  1253. debug("Input Rate is %u, Target is %u, Cap is %u\n", input_rate,
  1254. target_rate, cap);
  1255. assert(best_fine_scalar != NULL);
  1256. assert(main_scaler_bits <= fine_scalar_bits);
  1257. *best_fine_scalar = 1;
  1258. if (input_rate == 0 || target_rate == 0)
  1259. return -1;
  1260. if (target_rate >= input_rate)
  1261. return 1;
  1262. for (i = 1; i <= loops; i++) {
  1263. const unsigned int effective_div =
  1264. max(min(input_rate / i / target_rate, cap), 1U);
  1265. const unsigned int effective_rate = input_rate / i /
  1266. effective_div;
  1267. const int error = target_rate - effective_rate;
  1268. debug("%d|effdiv:%u, effrate:%u, error:%d\n", i, effective_div,
  1269. effective_rate, error);
  1270. if (error >= 0 && error <= best_error) {
  1271. best_error = error;
  1272. best_main_scalar = i;
  1273. *best_fine_scalar = effective_div;
  1274. }
  1275. }
  1276. return best_main_scalar;
  1277. }
  1278. static int exynos5_set_spi_clk(enum periph_id periph_id,
  1279. unsigned int rate)
  1280. {
  1281. struct exynos5_clock *clk =
  1282. (struct exynos5_clock *)samsung_get_base_clock();
  1283. int main;
  1284. unsigned int fine;
  1285. unsigned shift, pre_shift;
  1286. unsigned mask = 0xff;
  1287. u32 *reg;
  1288. main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
  1289. if (main < 0) {
  1290. debug("%s: Cannot set clock rate for periph %d",
  1291. __func__, periph_id);
  1292. return -1;
  1293. }
  1294. main = main - 1;
  1295. fine = fine - 1;
  1296. switch (periph_id) {
  1297. case PERIPH_ID_SPI0:
  1298. reg = &clk->div_peric1;
  1299. shift = 0;
  1300. pre_shift = 8;
  1301. break;
  1302. case PERIPH_ID_SPI1:
  1303. reg = &clk->div_peric1;
  1304. shift = 16;
  1305. pre_shift = 24;
  1306. break;
  1307. case PERIPH_ID_SPI2:
  1308. reg = &clk->div_peric2;
  1309. shift = 0;
  1310. pre_shift = 8;
  1311. break;
  1312. case PERIPH_ID_SPI3:
  1313. reg = &clk->sclk_div_isp;
  1314. shift = 0;
  1315. pre_shift = 4;
  1316. break;
  1317. case PERIPH_ID_SPI4:
  1318. reg = &clk->sclk_div_isp;
  1319. shift = 12;
  1320. pre_shift = 16;
  1321. break;
  1322. default:
  1323. debug("%s: Unsupported peripheral ID %d\n", __func__,
  1324. periph_id);
  1325. return -1;
  1326. }
  1327. clrsetbits_le32(reg, mask << shift, (main & mask) << shift);
  1328. clrsetbits_le32(reg, mask << pre_shift, (fine & mask) << pre_shift);
  1329. return 0;
  1330. }
  1331. static int exynos5420_set_spi_clk(enum periph_id periph_id,
  1332. unsigned int rate)
  1333. {
  1334. struct exynos5420_clock *clk =
  1335. (struct exynos5420_clock *)samsung_get_base_clock();
  1336. int main;
  1337. unsigned int fine;
  1338. unsigned shift, pre_shift;
  1339. unsigned div_mask = 0xf, pre_div_mask = 0xff;
  1340. u32 *reg;
  1341. u32 *pre_reg;
  1342. main = clock_calc_best_scalar(4, 8, 400000000, rate, &fine);
  1343. if (main < 0) {
  1344. debug("%s: Cannot set clock rate for periph %d",
  1345. __func__, periph_id);
  1346. return -1;
  1347. }
  1348. main = main - 1;
  1349. fine = fine - 1;
  1350. switch (periph_id) {
  1351. case PERIPH_ID_SPI0:
  1352. reg = &clk->div_peric1;
  1353. shift = 20;
  1354. pre_reg = &clk->div_peric4;
  1355. pre_shift = 8;
  1356. break;
  1357. case PERIPH_ID_SPI1:
  1358. reg = &clk->div_peric1;
  1359. shift = 24;
  1360. pre_reg = &clk->div_peric4;
  1361. pre_shift = 16;
  1362. break;
  1363. case PERIPH_ID_SPI2:
  1364. reg = &clk->div_peric1;
  1365. shift = 28;
  1366. pre_reg = &clk->div_peric4;
  1367. pre_shift = 24;
  1368. break;
  1369. case PERIPH_ID_SPI3:
  1370. reg = &clk->div_isp1;
  1371. shift = 16;
  1372. pre_reg = &clk->div_isp1;
  1373. pre_shift = 0;
  1374. break;
  1375. case PERIPH_ID_SPI4:
  1376. reg = &clk->div_isp1;
  1377. shift = 20;
  1378. pre_reg = &clk->div_isp1;
  1379. pre_shift = 8;
  1380. break;
  1381. default:
  1382. debug("%s: Unsupported peripheral ID %d\n", __func__,
  1383. periph_id);
  1384. return -1;
  1385. }
  1386. clrsetbits_le32(reg, div_mask << shift, (main & div_mask) << shift);
  1387. clrsetbits_le32(pre_reg, pre_div_mask << pre_shift,
  1388. (fine & pre_div_mask) << pre_shift);
  1389. return 0;
  1390. }
  1391. static unsigned long exynos4_get_i2c_clk(void)
  1392. {
  1393. struct exynos4_clock *clk =
  1394. (struct exynos4_clock *)samsung_get_base_clock();
  1395. unsigned long sclk, aclk_100;
  1396. unsigned int ratio;
  1397. sclk = get_pll_clk(APLL);
  1398. ratio = (readl(&clk->div_top)) >> 4;
  1399. ratio &= 0xf;
  1400. aclk_100 = sclk / (ratio + 1);
  1401. return aclk_100;
  1402. }
  1403. unsigned long get_pll_clk(int pllreg)
  1404. {
  1405. if (cpu_is_exynos5()) {
  1406. if (proid_is_exynos542x())
  1407. return exynos542x_get_pll_clk(pllreg);
  1408. return exynos5_get_pll_clk(pllreg);
  1409. } else if (cpu_is_exynos4()) {
  1410. if (proid_is_exynos4412())
  1411. return exynos4x12_get_pll_clk(pllreg);
  1412. return exynos4_get_pll_clk(pllreg);
  1413. }
  1414. return 0;
  1415. }
  1416. unsigned long get_arm_clk(void)
  1417. {
  1418. if (cpu_is_exynos5()) {
  1419. return exynos5_get_arm_clk();
  1420. } else if (cpu_is_exynos4()) {
  1421. if (proid_is_exynos4412())
  1422. return exynos4x12_get_arm_clk();
  1423. return exynos4_get_arm_clk();
  1424. }
  1425. return 0;
  1426. }
  1427. unsigned long get_i2c_clk(void)
  1428. {
  1429. if (cpu_is_exynos5())
  1430. return clock_get_periph_rate(PERIPH_ID_I2C0);
  1431. else if (cpu_is_exynos4())
  1432. return exynos4_get_i2c_clk();
  1433. return 0;
  1434. }
  1435. unsigned long get_pwm_clk(void)
  1436. {
  1437. if (cpu_is_exynos5()) {
  1438. return clock_get_periph_rate(PERIPH_ID_PWM0);
  1439. } else if (cpu_is_exynos4()) {
  1440. if (proid_is_exynos4412())
  1441. return exynos4x12_get_pwm_clk();
  1442. return exynos4_get_pwm_clk();
  1443. }
  1444. return 0;
  1445. }
  1446. unsigned long get_uart_clk(int dev_index)
  1447. {
  1448. enum periph_id id;
  1449. switch (dev_index) {
  1450. case 0:
  1451. id = PERIPH_ID_UART0;
  1452. break;
  1453. case 1:
  1454. id = PERIPH_ID_UART1;
  1455. break;
  1456. case 2:
  1457. id = PERIPH_ID_UART2;
  1458. break;
  1459. case 3:
  1460. id = PERIPH_ID_UART3;
  1461. break;
  1462. default:
  1463. debug("%s: invalid UART index %d", __func__, dev_index);
  1464. return -1;
  1465. }
  1466. if (cpu_is_exynos5()) {
  1467. return clock_get_periph_rate(id);
  1468. } else if (cpu_is_exynos4()) {
  1469. if (proid_is_exynos4412())
  1470. return exynos4x12_get_uart_clk(dev_index);
  1471. return exynos4_get_uart_clk(dev_index);
  1472. }
  1473. return 0;
  1474. }
  1475. unsigned long get_mmc_clk(int dev_index)
  1476. {
  1477. enum periph_id id;
  1478. if (cpu_is_exynos4())
  1479. return exynos4_get_mmc_clk(dev_index);
  1480. switch (dev_index) {
  1481. case 0:
  1482. id = PERIPH_ID_SDMMC0;
  1483. break;
  1484. case 1:
  1485. id = PERIPH_ID_SDMMC1;
  1486. break;
  1487. case 2:
  1488. id = PERIPH_ID_SDMMC2;
  1489. break;
  1490. case 3:
  1491. id = PERIPH_ID_SDMMC3;
  1492. break;
  1493. default:
  1494. debug("%s: invalid MMC index %d", __func__, dev_index);
  1495. return -1;
  1496. }
  1497. return clock_get_periph_rate(id);
  1498. }
  1499. void set_mmc_clk(int dev_index, unsigned int div)
  1500. {
  1501. /* If want to set correct value, it needs to substract one from div.*/
  1502. if (div > 0)
  1503. div -= 1;
  1504. if (cpu_is_exynos5()) {
  1505. if (proid_is_exynos542x())
  1506. exynos5420_set_mmc_clk(dev_index, div);
  1507. else
  1508. exynos5_set_mmc_clk(dev_index, div);
  1509. } else if (cpu_is_exynos4()) {
  1510. exynos4_set_mmc_clk(dev_index, div);
  1511. }
  1512. }
  1513. unsigned long get_lcd_clk(void)
  1514. {
  1515. if (cpu_is_exynos4()) {
  1516. return exynos4_get_lcd_clk();
  1517. } else if (cpu_is_exynos5()) {
  1518. if (proid_is_exynos5420())
  1519. return exynos5420_get_lcd_clk();
  1520. else if (proid_is_exynos5422())
  1521. return exynos5800_get_lcd_clk();
  1522. else
  1523. return exynos5_get_lcd_clk();
  1524. }
  1525. return 0;
  1526. }
  1527. void set_lcd_clk(void)
  1528. {
  1529. if (cpu_is_exynos4()) {
  1530. exynos4_set_lcd_clk();
  1531. } else if (cpu_is_exynos5()) {
  1532. if (proid_is_exynos5250())
  1533. exynos5_set_lcd_clk();
  1534. else if (proid_is_exynos5420())
  1535. exynos5420_set_lcd_clk();
  1536. else
  1537. exynos5800_set_lcd_clk();
  1538. }
  1539. }
  1540. void set_mipi_clk(void)
  1541. {
  1542. if (cpu_is_exynos4())
  1543. exynos4_set_mipi_clk();
  1544. }
  1545. int set_spi_clk(int periph_id, unsigned int rate)
  1546. {
  1547. if (cpu_is_exynos5()) {
  1548. if (proid_is_exynos542x())
  1549. return exynos5420_set_spi_clk(periph_id, rate);
  1550. return exynos5_set_spi_clk(periph_id, rate);
  1551. }
  1552. return 0;
  1553. }
  1554. int set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq,
  1555. unsigned int i2s_id)
  1556. {
  1557. if (cpu_is_exynos5())
  1558. return exynos5_set_i2s_clk_prescaler(src_frq, dst_frq, i2s_id);
  1559. return 0;
  1560. }
  1561. int set_i2s_clk_source(unsigned int i2s_id)
  1562. {
  1563. if (cpu_is_exynos5()) {
  1564. if (proid_is_exynos542x())
  1565. return exynos5420_set_i2s_clk_source();
  1566. else
  1567. return exynos5_set_i2s_clk_source(i2s_id);
  1568. }
  1569. return 0;
  1570. }
  1571. int set_epll_clk(unsigned long rate)
  1572. {
  1573. if (cpu_is_exynos5())
  1574. return exynos5_set_epll_clk(rate);
  1575. return 0;
  1576. }