clock.c 39 KB

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