clock.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779
  1. /*
  2. * Copyright (C) 2010 Samsung Electronics
  3. * Minkyu Kang <mk7.kang@samsung.com>
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. #include <common.h>
  24. #include <asm/io.h>
  25. #include <asm/arch/clock.h>
  26. #include <asm/arch/clk.h>
  27. /* exynos: return pll clock frequency */
  28. static int exynos_get_pll_clk(int pllreg, unsigned int r, unsigned int k)
  29. {
  30. unsigned long m, p, s = 0, mask, fout;
  31. unsigned int freq;
  32. /*
  33. * APLL_CON: MIDV [25:16]
  34. * MPLL_CON: MIDV [25:16]
  35. * EPLL_CON: MIDV [24:16]
  36. * VPLL_CON: MIDV [24:16]
  37. * BPLL_CON: MIDV [25:16]: Exynos5
  38. */
  39. if (pllreg == APLL || pllreg == MPLL || pllreg == BPLL)
  40. mask = 0x3ff;
  41. else
  42. mask = 0x1ff;
  43. m = (r >> 16) & mask;
  44. /* PDIV [13:8] */
  45. p = (r >> 8) & 0x3f;
  46. /* SDIV [2:0] */
  47. s = r & 0x7;
  48. freq = CONFIG_SYS_CLK_FREQ;
  49. if (pllreg == EPLL) {
  50. k = k & 0xffff;
  51. /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */
  52. fout = (m + k / 65536) * (freq / (p * (1 << s)));
  53. } else if (pllreg == VPLL) {
  54. k = k & 0xfff;
  55. /* FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) */
  56. fout = (m + k / 1024) * (freq / (p * (1 << s)));
  57. } else {
  58. if (s < 1)
  59. s = 1;
  60. /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */
  61. fout = m * (freq / (p * (1 << (s - 1))));
  62. }
  63. return fout;
  64. }
  65. /* exynos4: return pll clock frequency */
  66. static unsigned long exynos4_get_pll_clk(int pllreg)
  67. {
  68. struct exynos4_clock *clk =
  69. (struct exynos4_clock *)samsung_get_base_clock();
  70. unsigned long r, k = 0;
  71. switch (pllreg) {
  72. case APLL:
  73. r = readl(&clk->apll_con0);
  74. break;
  75. case MPLL:
  76. r = readl(&clk->mpll_con0);
  77. break;
  78. case EPLL:
  79. r = readl(&clk->epll_con0);
  80. k = readl(&clk->epll_con1);
  81. break;
  82. case VPLL:
  83. r = readl(&clk->vpll_con0);
  84. k = readl(&clk->vpll_con1);
  85. break;
  86. default:
  87. printf("Unsupported PLL (%d)\n", pllreg);
  88. return 0;
  89. }
  90. return exynos_get_pll_clk(pllreg, r, k);
  91. }
  92. /* exynos5: return pll clock frequency */
  93. static unsigned long exynos5_get_pll_clk(int pllreg)
  94. {
  95. struct exynos5_clock *clk =
  96. (struct exynos5_clock *)samsung_get_base_clock();
  97. unsigned long r, k = 0, fout;
  98. unsigned int pll_div2_sel, fout_sel;
  99. switch (pllreg) {
  100. case APLL:
  101. r = readl(&clk->apll_con0);
  102. break;
  103. case MPLL:
  104. r = readl(&clk->mpll_con0);
  105. break;
  106. case EPLL:
  107. r = readl(&clk->epll_con0);
  108. k = readl(&clk->epll_con1);
  109. break;
  110. case VPLL:
  111. r = readl(&clk->vpll_con0);
  112. k = readl(&clk->vpll_con1);
  113. break;
  114. case BPLL:
  115. r = readl(&clk->bpll_con0);
  116. break;
  117. default:
  118. printf("Unsupported PLL (%d)\n", pllreg);
  119. return 0;
  120. }
  121. fout = exynos_get_pll_clk(pllreg, r, k);
  122. /* According to the user manual, in EVT1 MPLL and BPLL always gives
  123. * 1.6GHz clock, so divide by 2 to get 800MHz MPLL clock.*/
  124. if (pllreg == MPLL || pllreg == BPLL) {
  125. pll_div2_sel = readl(&clk->pll_div2_sel);
  126. switch (pllreg) {
  127. case MPLL:
  128. fout_sel = (pll_div2_sel >> MPLL_FOUT_SEL_SHIFT)
  129. & MPLL_FOUT_SEL_MASK;
  130. break;
  131. case BPLL:
  132. fout_sel = (pll_div2_sel >> BPLL_FOUT_SEL_SHIFT)
  133. & BPLL_FOUT_SEL_MASK;
  134. break;
  135. default:
  136. fout_sel = -1;
  137. break;
  138. }
  139. if (fout_sel == 0)
  140. fout /= 2;
  141. }
  142. return fout;
  143. }
  144. /* exynos4: return ARM clock frequency */
  145. static unsigned long exynos4_get_arm_clk(void)
  146. {
  147. struct exynos4_clock *clk =
  148. (struct exynos4_clock *)samsung_get_base_clock();
  149. unsigned long div;
  150. unsigned long armclk;
  151. unsigned int core_ratio;
  152. unsigned int core2_ratio;
  153. div = readl(&clk->div_cpu0);
  154. /* CORE_RATIO: [2:0], CORE2_RATIO: [30:28] */
  155. core_ratio = (div >> 0) & 0x7;
  156. core2_ratio = (div >> 28) & 0x7;
  157. armclk = get_pll_clk(APLL) / (core_ratio + 1);
  158. armclk /= (core2_ratio + 1);
  159. return armclk;
  160. }
  161. /* exynos5: return ARM clock frequency */
  162. static unsigned long exynos5_get_arm_clk(void)
  163. {
  164. struct exynos5_clock *clk =
  165. (struct exynos5_clock *)samsung_get_base_clock();
  166. unsigned long div;
  167. unsigned long armclk;
  168. unsigned int arm_ratio;
  169. unsigned int arm2_ratio;
  170. div = readl(&clk->div_cpu0);
  171. /* ARM_RATIO: [2:0], ARM2_RATIO: [30:28] */
  172. arm_ratio = (div >> 0) & 0x7;
  173. arm2_ratio = (div >> 28) & 0x7;
  174. armclk = get_pll_clk(APLL) / (arm_ratio + 1);
  175. armclk /= (arm2_ratio + 1);
  176. return armclk;
  177. }
  178. /* exynos4: return pwm clock frequency */
  179. static unsigned long exynos4_get_pwm_clk(void)
  180. {
  181. struct exynos4_clock *clk =
  182. (struct exynos4_clock *)samsung_get_base_clock();
  183. unsigned long pclk, sclk;
  184. unsigned int sel;
  185. unsigned int ratio;
  186. if (s5p_get_cpu_rev() == 0) {
  187. /*
  188. * CLK_SRC_PERIL0
  189. * PWM_SEL [27:24]
  190. */
  191. sel = readl(&clk->src_peril0);
  192. sel = (sel >> 24) & 0xf;
  193. if (sel == 0x6)
  194. sclk = get_pll_clk(MPLL);
  195. else if (sel == 0x7)
  196. sclk = get_pll_clk(EPLL);
  197. else if (sel == 0x8)
  198. sclk = get_pll_clk(VPLL);
  199. else
  200. return 0;
  201. /*
  202. * CLK_DIV_PERIL3
  203. * PWM_RATIO [3:0]
  204. */
  205. ratio = readl(&clk->div_peril3);
  206. ratio = ratio & 0xf;
  207. } else if (s5p_get_cpu_rev() == 1) {
  208. sclk = get_pll_clk(MPLL);
  209. ratio = 8;
  210. } else
  211. return 0;
  212. pclk = sclk / (ratio + 1);
  213. return pclk;
  214. }
  215. /* exynos5: return pwm clock frequency */
  216. static unsigned long exynos5_get_pwm_clk(void)
  217. {
  218. struct exynos5_clock *clk =
  219. (struct exynos5_clock *)samsung_get_base_clock();
  220. unsigned long pclk, sclk;
  221. unsigned int ratio;
  222. /*
  223. * CLK_DIV_PERIC3
  224. * PWM_RATIO [3:0]
  225. */
  226. ratio = readl(&clk->div_peric3);
  227. ratio = ratio & 0xf;
  228. sclk = get_pll_clk(MPLL);
  229. pclk = sclk / (ratio + 1);
  230. return pclk;
  231. }
  232. /* exynos4: return uart clock frequency */
  233. static unsigned long exynos4_get_uart_clk(int dev_index)
  234. {
  235. struct exynos4_clock *clk =
  236. (struct exynos4_clock *)samsung_get_base_clock();
  237. unsigned long uclk, sclk;
  238. unsigned int sel;
  239. unsigned int ratio;
  240. /*
  241. * CLK_SRC_PERIL0
  242. * UART0_SEL [3:0]
  243. * UART1_SEL [7:4]
  244. * UART2_SEL [8:11]
  245. * UART3_SEL [12:15]
  246. * UART4_SEL [16:19]
  247. * UART5_SEL [23:20]
  248. */
  249. sel = readl(&clk->src_peril0);
  250. sel = (sel >> (dev_index << 2)) & 0xf;
  251. if (sel == 0x6)
  252. sclk = get_pll_clk(MPLL);
  253. else if (sel == 0x7)
  254. sclk = get_pll_clk(EPLL);
  255. else if (sel == 0x8)
  256. sclk = get_pll_clk(VPLL);
  257. else
  258. return 0;
  259. /*
  260. * CLK_DIV_PERIL0
  261. * UART0_RATIO [3:0]
  262. * UART1_RATIO [7:4]
  263. * UART2_RATIO [8:11]
  264. * UART3_RATIO [12:15]
  265. * UART4_RATIO [16:19]
  266. * UART5_RATIO [23:20]
  267. */
  268. ratio = readl(&clk->div_peril0);
  269. ratio = (ratio >> (dev_index << 2)) & 0xf;
  270. uclk = sclk / (ratio + 1);
  271. return uclk;
  272. }
  273. /* exynos5: return uart clock frequency */
  274. static unsigned long exynos5_get_uart_clk(int dev_index)
  275. {
  276. struct exynos5_clock *clk =
  277. (struct exynos5_clock *)samsung_get_base_clock();
  278. unsigned long uclk, sclk;
  279. unsigned int sel;
  280. unsigned int ratio;
  281. /*
  282. * CLK_SRC_PERIC0
  283. * UART0_SEL [3:0]
  284. * UART1_SEL [7:4]
  285. * UART2_SEL [8:11]
  286. * UART3_SEL [12:15]
  287. * UART4_SEL [16:19]
  288. * UART5_SEL [23:20]
  289. */
  290. sel = readl(&clk->src_peric0);
  291. sel = (sel >> (dev_index << 2)) & 0xf;
  292. if (sel == 0x6)
  293. sclk = get_pll_clk(MPLL);
  294. else if (sel == 0x7)
  295. sclk = get_pll_clk(EPLL);
  296. else if (sel == 0x8)
  297. sclk = get_pll_clk(VPLL);
  298. else
  299. return 0;
  300. /*
  301. * CLK_DIV_PERIC0
  302. * UART0_RATIO [3:0]
  303. * UART1_RATIO [7:4]
  304. * UART2_RATIO [8:11]
  305. * UART3_RATIO [12:15]
  306. * UART4_RATIO [16:19]
  307. * UART5_RATIO [23:20]
  308. */
  309. ratio = readl(&clk->div_peric0);
  310. ratio = (ratio >> (dev_index << 2)) & 0xf;
  311. uclk = sclk / (ratio + 1);
  312. return uclk;
  313. }
  314. /* exynos4: set the mmc clock */
  315. static void exynos4_set_mmc_clk(int dev_index, unsigned int div)
  316. {
  317. struct exynos4_clock *clk =
  318. (struct exynos4_clock *)samsung_get_base_clock();
  319. unsigned int addr;
  320. unsigned int val;
  321. /*
  322. * CLK_DIV_FSYS1
  323. * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
  324. * CLK_DIV_FSYS2
  325. * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
  326. */
  327. if (dev_index < 2) {
  328. addr = (unsigned int)&clk->div_fsys1;
  329. } else {
  330. addr = (unsigned int)&clk->div_fsys2;
  331. dev_index -= 2;
  332. }
  333. val = readl(addr);
  334. val &= ~(0xff << ((dev_index << 4) + 8));
  335. val |= (div & 0xff) << ((dev_index << 4) + 8);
  336. writel(val, addr);
  337. }
  338. /* exynos5: set the mmc clock */
  339. static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
  340. {
  341. struct exynos5_clock *clk =
  342. (struct exynos5_clock *)samsung_get_base_clock();
  343. unsigned int addr;
  344. unsigned int val;
  345. /*
  346. * CLK_DIV_FSYS1
  347. * MMC0_PRE_RATIO [15:8], MMC1_PRE_RATIO [31:24]
  348. * CLK_DIV_FSYS2
  349. * MMC2_PRE_RATIO [15:8], MMC3_PRE_RATIO [31:24]
  350. */
  351. if (dev_index < 2) {
  352. addr = (unsigned int)&clk->div_fsys1;
  353. } else {
  354. addr = (unsigned int)&clk->div_fsys2;
  355. dev_index -= 2;
  356. }
  357. val = readl(addr);
  358. val &= ~(0xff << ((dev_index << 4) + 8));
  359. val |= (div & 0xff) << ((dev_index << 4) + 8);
  360. writel(val, addr);
  361. }
  362. /* get_lcd_clk: return lcd clock frequency */
  363. static unsigned long exynos4_get_lcd_clk(void)
  364. {
  365. struct exynos4_clock *clk =
  366. (struct exynos4_clock *)samsung_get_base_clock();
  367. unsigned long pclk, sclk;
  368. unsigned int sel;
  369. unsigned int ratio;
  370. /*
  371. * CLK_SRC_LCD0
  372. * FIMD0_SEL [3:0]
  373. */
  374. sel = readl(&clk->src_lcd0);
  375. sel = sel & 0xf;
  376. /*
  377. * 0x6: SCLK_MPLL
  378. * 0x7: SCLK_EPLL
  379. * 0x8: SCLK_VPLL
  380. */
  381. if (sel == 0x6)
  382. sclk = get_pll_clk(MPLL);
  383. else if (sel == 0x7)
  384. sclk = get_pll_clk(EPLL);
  385. else if (sel == 0x8)
  386. sclk = get_pll_clk(VPLL);
  387. else
  388. return 0;
  389. /*
  390. * CLK_DIV_LCD0
  391. * FIMD0_RATIO [3:0]
  392. */
  393. ratio = readl(&clk->div_lcd0);
  394. ratio = ratio & 0xf;
  395. pclk = sclk / (ratio + 1);
  396. return pclk;
  397. }
  398. /* get_lcd_clk: return lcd clock frequency */
  399. static unsigned long exynos5_get_lcd_clk(void)
  400. {
  401. struct exynos5_clock *clk =
  402. (struct exynos5_clock *)samsung_get_base_clock();
  403. unsigned long pclk, sclk;
  404. unsigned int sel;
  405. unsigned int ratio;
  406. /*
  407. * CLK_SRC_LCD0
  408. * FIMD0_SEL [3:0]
  409. */
  410. sel = readl(&clk->src_disp1_0);
  411. sel = sel & 0xf;
  412. /*
  413. * 0x6: SCLK_MPLL
  414. * 0x7: SCLK_EPLL
  415. * 0x8: SCLK_VPLL
  416. */
  417. if (sel == 0x6)
  418. sclk = get_pll_clk(MPLL);
  419. else if (sel == 0x7)
  420. sclk = get_pll_clk(EPLL);
  421. else if (sel == 0x8)
  422. sclk = get_pll_clk(VPLL);
  423. else
  424. return 0;
  425. /*
  426. * CLK_DIV_LCD0
  427. * FIMD0_RATIO [3:0]
  428. */
  429. ratio = readl(&clk->div_disp1_0);
  430. ratio = ratio & 0xf;
  431. pclk = sclk / (ratio + 1);
  432. return pclk;
  433. }
  434. void exynos4_set_lcd_clk(void)
  435. {
  436. struct exynos4_clock *clk =
  437. (struct exynos4_clock *)samsung_get_base_clock();
  438. unsigned int cfg = 0;
  439. /*
  440. * CLK_GATE_BLOCK
  441. * CLK_CAM [0]
  442. * CLK_TV [1]
  443. * CLK_MFC [2]
  444. * CLK_G3D [3]
  445. * CLK_LCD0 [4]
  446. * CLK_LCD1 [5]
  447. * CLK_GPS [7]
  448. */
  449. cfg = readl(&clk->gate_block);
  450. cfg |= 1 << 4;
  451. writel(cfg, &clk->gate_block);
  452. /*
  453. * CLK_SRC_LCD0
  454. * FIMD0_SEL [3:0]
  455. * MDNIE0_SEL [7:4]
  456. * MDNIE_PWM0_SEL [8:11]
  457. * MIPI0_SEL [12:15]
  458. * set lcd0 src clock 0x6: SCLK_MPLL
  459. */
  460. cfg = readl(&clk->src_lcd0);
  461. cfg &= ~(0xf);
  462. cfg |= 0x6;
  463. writel(cfg, &clk->src_lcd0);
  464. /*
  465. * CLK_GATE_IP_LCD0
  466. * CLK_FIMD0 [0]
  467. * CLK_MIE0 [1]
  468. * CLK_MDNIE0 [2]
  469. * CLK_DSIM0 [3]
  470. * CLK_SMMUFIMD0 [4]
  471. * CLK_PPMULCD0 [5]
  472. * Gating all clocks for FIMD0
  473. */
  474. cfg = readl(&clk->gate_ip_lcd0);
  475. cfg |= 1 << 0;
  476. writel(cfg, &clk->gate_ip_lcd0);
  477. /*
  478. * CLK_DIV_LCD0
  479. * FIMD0_RATIO [3:0]
  480. * MDNIE0_RATIO [7:4]
  481. * MDNIE_PWM0_RATIO [11:8]
  482. * MDNIE_PWM_PRE_RATIO [15:12]
  483. * MIPI0_RATIO [19:16]
  484. * MIPI0_PRE_RATIO [23:20]
  485. * set fimd ratio
  486. */
  487. cfg &= ~(0xf);
  488. cfg |= 0x1;
  489. writel(cfg, &clk->div_lcd0);
  490. }
  491. void exynos5_set_lcd_clk(void)
  492. {
  493. struct exynos5_clock *clk =
  494. (struct exynos5_clock *)samsung_get_base_clock();
  495. unsigned int cfg = 0;
  496. /*
  497. * CLK_GATE_BLOCK
  498. * CLK_CAM [0]
  499. * CLK_TV [1]
  500. * CLK_MFC [2]
  501. * CLK_G3D [3]
  502. * CLK_LCD0 [4]
  503. * CLK_LCD1 [5]
  504. * CLK_GPS [7]
  505. */
  506. cfg = readl(&clk->gate_block);
  507. cfg |= 1 << 4;
  508. writel(cfg, &clk->gate_block);
  509. /*
  510. * CLK_SRC_LCD0
  511. * FIMD0_SEL [3:0]
  512. * MDNIE0_SEL [7:4]
  513. * MDNIE_PWM0_SEL [8:11]
  514. * MIPI0_SEL [12:15]
  515. * set lcd0 src clock 0x6: SCLK_MPLL
  516. */
  517. cfg = readl(&clk->src_disp1_0);
  518. cfg &= ~(0xf);
  519. cfg |= 0x8;
  520. writel(cfg, &clk->src_disp1_0);
  521. /*
  522. * CLK_GATE_IP_LCD0
  523. * CLK_FIMD0 [0]
  524. * CLK_MIE0 [1]
  525. * CLK_MDNIE0 [2]
  526. * CLK_DSIM0 [3]
  527. * CLK_SMMUFIMD0 [4]
  528. * CLK_PPMULCD0 [5]
  529. * Gating all clocks for FIMD0
  530. */
  531. cfg = readl(&clk->gate_ip_disp1);
  532. cfg |= 1 << 0;
  533. writel(cfg, &clk->gate_ip_disp1);
  534. /*
  535. * CLK_DIV_LCD0
  536. * FIMD0_RATIO [3:0]
  537. * MDNIE0_RATIO [7:4]
  538. * MDNIE_PWM0_RATIO [11:8]
  539. * MDNIE_PWM_PRE_RATIO [15:12]
  540. * MIPI0_RATIO [19:16]
  541. * MIPI0_PRE_RATIO [23:20]
  542. * set fimd ratio
  543. */
  544. cfg &= ~(0xf);
  545. cfg |= 0x0;
  546. writel(cfg, &clk->div_disp1_0);
  547. }
  548. void exynos4_set_mipi_clk(void)
  549. {
  550. struct exynos4_clock *clk =
  551. (struct exynos4_clock *)samsung_get_base_clock();
  552. unsigned int cfg = 0;
  553. /*
  554. * CLK_SRC_LCD0
  555. * FIMD0_SEL [3:0]
  556. * MDNIE0_SEL [7:4]
  557. * MDNIE_PWM0_SEL [8:11]
  558. * MIPI0_SEL [12:15]
  559. * set mipi0 src clock 0x6: SCLK_MPLL
  560. */
  561. cfg = readl(&clk->src_lcd0);
  562. cfg &= ~(0xf << 12);
  563. cfg |= (0x6 << 12);
  564. writel(cfg, &clk->src_lcd0);
  565. /*
  566. * CLK_SRC_MASK_LCD0
  567. * FIMD0_MASK [0]
  568. * MDNIE0_MASK [4]
  569. * MDNIE_PWM0_MASK [8]
  570. * MIPI0_MASK [12]
  571. * set src mask mipi0 0x1: Unmask
  572. */
  573. cfg = readl(&clk->src_mask_lcd0);
  574. cfg |= (0x1 << 12);
  575. writel(cfg, &clk->src_mask_lcd0);
  576. /*
  577. * CLK_GATE_IP_LCD0
  578. * CLK_FIMD0 [0]
  579. * CLK_MIE0 [1]
  580. * CLK_MDNIE0 [2]
  581. * CLK_DSIM0 [3]
  582. * CLK_SMMUFIMD0 [4]
  583. * CLK_PPMULCD0 [5]
  584. * Gating all clocks for MIPI0
  585. */
  586. cfg = readl(&clk->gate_ip_lcd0);
  587. cfg |= 1 << 3;
  588. writel(cfg, &clk->gate_ip_lcd0);
  589. /*
  590. * CLK_DIV_LCD0
  591. * FIMD0_RATIO [3:0]
  592. * MDNIE0_RATIO [7:4]
  593. * MDNIE_PWM0_RATIO [11:8]
  594. * MDNIE_PWM_PRE_RATIO [15:12]
  595. * MIPI0_RATIO [19:16]
  596. * MIPI0_PRE_RATIO [23:20]
  597. * set mipi ratio
  598. */
  599. cfg &= ~(0xf << 16);
  600. cfg |= (0x1 << 16);
  601. writel(cfg, &clk->div_lcd0);
  602. }
  603. /*
  604. * I2C
  605. *
  606. * exynos5: obtaining the I2C clock
  607. */
  608. static unsigned long exynos5_get_i2c_clk(void)
  609. {
  610. struct exynos5_clock *clk =
  611. (struct exynos5_clock *)samsung_get_base_clock();
  612. unsigned long aclk_66, aclk_66_pre, sclk;
  613. unsigned int ratio;
  614. sclk = get_pll_clk(MPLL);
  615. ratio = (readl(&clk->div_top1)) >> 24;
  616. ratio &= 0x7;
  617. aclk_66_pre = sclk / (ratio + 1);
  618. ratio = readl(&clk->div_top0);
  619. ratio &= 0x7;
  620. aclk_66 = aclk_66_pre / (ratio + 1);
  621. return aclk_66;
  622. }
  623. unsigned long get_pll_clk(int pllreg)
  624. {
  625. if (cpu_is_exynos5())
  626. return exynos5_get_pll_clk(pllreg);
  627. else
  628. return exynos4_get_pll_clk(pllreg);
  629. }
  630. unsigned long get_arm_clk(void)
  631. {
  632. if (cpu_is_exynos5())
  633. return exynos5_get_arm_clk();
  634. else
  635. return exynos4_get_arm_clk();
  636. }
  637. unsigned long get_i2c_clk(void)
  638. {
  639. if (cpu_is_exynos5()) {
  640. return exynos5_get_i2c_clk();
  641. } else {
  642. debug("I2C clock is not set for this CPU\n");
  643. return 0;
  644. }
  645. }
  646. unsigned long get_pwm_clk(void)
  647. {
  648. if (cpu_is_exynos5())
  649. return exynos5_get_pwm_clk();
  650. else
  651. return exynos4_get_pwm_clk();
  652. }
  653. unsigned long get_uart_clk(int dev_index)
  654. {
  655. if (cpu_is_exynos5())
  656. return exynos5_get_uart_clk(dev_index);
  657. else
  658. return exynos4_get_uart_clk(dev_index);
  659. }
  660. void set_mmc_clk(int dev_index, unsigned int div)
  661. {
  662. if (cpu_is_exynos5())
  663. exynos5_set_mmc_clk(dev_index, div);
  664. else
  665. exynos4_set_mmc_clk(dev_index, div);
  666. }
  667. unsigned long get_lcd_clk(void)
  668. {
  669. if (cpu_is_exynos4())
  670. return exynos4_get_lcd_clk();
  671. else
  672. return exynos5_get_lcd_clk();
  673. }
  674. void set_lcd_clk(void)
  675. {
  676. if (cpu_is_exynos4())
  677. exynos4_set_lcd_clk();
  678. else
  679. exynos5_set_lcd_clk();
  680. }
  681. void set_mipi_clk(void)
  682. {
  683. if (cpu_is_exynos4())
  684. exynos4_set_mipi_clk();
  685. }