common-s3c2443.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. /*
  2. * Common code for SoCs starting with the S3C2443
  3. *
  4. * Copyright (c) 2007, 2010 Simtec Electronics
  5. * Ben Dooks <ben@simtec.co.uk>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. */
  17. #include <linux/init.h>
  18. #include <linux/clk.h>
  19. #include <linux/io.h>
  20. #include <mach/regs-s3c2443-clock.h>
  21. #include <plat/clock.h>
  22. #include <plat/clock-clksrc.h>
  23. #include <plat/cpu.h>
  24. #include <plat/cpu-freq.h>
  25. static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
  26. {
  27. u32 ctrlbit = clk->ctrlbit;
  28. u32 con = __raw_readl(reg);
  29. if (enable)
  30. con |= ctrlbit;
  31. else
  32. con &= ~ctrlbit;
  33. __raw_writel(con, reg);
  34. return 0;
  35. }
  36. int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
  37. {
  38. return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
  39. }
  40. int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
  41. {
  42. return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
  43. }
  44. int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
  45. {
  46. return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
  47. }
  48. /* mpllref is a direct descendant of clk_xtal by default, but it is not
  49. * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
  50. * such directly equating the two source clocks is impossible.
  51. */
  52. static struct clk clk_mpllref = {
  53. .name = "mpllref",
  54. .parent = &clk_xtal,
  55. };
  56. static struct clk *clk_epllref_sources[] = {
  57. [0] = &clk_mpllref,
  58. [1] = &clk_mpllref,
  59. [2] = &clk_xtal,
  60. [3] = &clk_ext,
  61. };
  62. struct clksrc_clk clk_epllref = {
  63. .clk = {
  64. .name = "epllref",
  65. },
  66. .sources = &(struct clksrc_sources) {
  67. .sources = clk_epllref_sources,
  68. .nr_sources = ARRAY_SIZE(clk_epllref_sources),
  69. },
  70. .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
  71. };
  72. /* esysclk
  73. *
  74. * this is sourced from either the EPLL or the EPLLref clock
  75. */
  76. static struct clk *clk_sysclk_sources[] = {
  77. [0] = &clk_epllref.clk,
  78. [1] = &clk_epll,
  79. };
  80. struct clksrc_clk clk_esysclk = {
  81. .clk = {
  82. .name = "esysclk",
  83. .parent = &clk_epll,
  84. },
  85. .sources = &(struct clksrc_sources) {
  86. .sources = clk_sysclk_sources,
  87. .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
  88. },
  89. .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
  90. };
  91. static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
  92. {
  93. unsigned long parent_rate = clk_get_rate(clk->parent);
  94. unsigned long div = __raw_readl(S3C2443_CLKDIV0);
  95. div &= S3C2443_CLKDIV0_EXTDIV_MASK;
  96. div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */
  97. return parent_rate / (div + 1);
  98. }
  99. static struct clk clk_mdivclk = {
  100. .name = "mdivclk",
  101. .parent = &clk_mpllref,
  102. .ops = &(struct clk_ops) {
  103. .get_rate = s3c2443_getrate_mdivclk,
  104. },
  105. };
  106. static struct clk *clk_msysclk_sources[] = {
  107. [0] = &clk_mpllref,
  108. [1] = &clk_mpll,
  109. [2] = &clk_mdivclk,
  110. [3] = &clk_mpllref,
  111. };
  112. struct clksrc_clk clk_msysclk = {
  113. .clk = {
  114. .name = "msysclk",
  115. .parent = &clk_xtal,
  116. },
  117. .sources = &(struct clksrc_sources) {
  118. .sources = clk_msysclk_sources,
  119. .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
  120. },
  121. .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
  122. };
  123. /* prediv
  124. *
  125. * this divides the msysclk down to pass to h/p/etc.
  126. */
  127. static unsigned long s3c2443_prediv_getrate(struct clk *clk)
  128. {
  129. unsigned long rate = clk_get_rate(clk->parent);
  130. unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
  131. clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
  132. clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
  133. return rate / (clkdiv0 + 1);
  134. }
  135. static struct clk clk_prediv = {
  136. .name = "prediv",
  137. .parent = &clk_msysclk.clk,
  138. .ops = &(struct clk_ops) {
  139. .get_rate = s3c2443_prediv_getrate,
  140. },
  141. };
  142. /* hclk divider
  143. *
  144. * divides the prediv and provides the hclk.
  145. */
  146. static unsigned long s3c2443_hclkdiv_getrate(struct clk *clk)
  147. {
  148. unsigned long rate = clk_get_rate(clk->parent);
  149. unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
  150. clkdiv0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
  151. return rate / (clkdiv0 + 1);
  152. }
  153. static struct clk_ops clk_h_ops = {
  154. .get_rate = s3c2443_hclkdiv_getrate,
  155. };
  156. /* pclk divider
  157. *
  158. * divides the hclk and provides the pclk.
  159. */
  160. static unsigned long s3c2443_pclkdiv_getrate(struct clk *clk)
  161. {
  162. unsigned long rate = clk_get_rate(clk->parent);
  163. unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
  164. clkdiv0 = ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 1 : 0);
  165. return rate / (clkdiv0 + 1);
  166. }
  167. static struct clk_ops clk_p_ops = {
  168. .get_rate = s3c2443_pclkdiv_getrate,
  169. };
  170. /* armdiv
  171. *
  172. * this clock is sourced from msysclk and can have a number of
  173. * divider values applied to it to then be fed into armclk.
  174. */
  175. static unsigned int *armdiv;
  176. static int nr_armdiv;
  177. static int armdivmask;
  178. static unsigned long s3c2443_armclk_roundrate(struct clk *clk,
  179. unsigned long rate)
  180. {
  181. unsigned long parent = clk_get_rate(clk->parent);
  182. unsigned long calc;
  183. unsigned best = 256; /* bigger than any value */
  184. unsigned div;
  185. int ptr;
  186. if (!nr_armdiv)
  187. return -EINVAL;
  188. for (ptr = 0; ptr < nr_armdiv; ptr++) {
  189. div = armdiv[ptr];
  190. if (div) {
  191. /* cpufreq provides 266mhz as 266666000 not 266666666 */
  192. calc = (parent / div / 1000) * 1000;
  193. if (calc <= rate && div < best)
  194. best = div;
  195. }
  196. }
  197. return parent / best;
  198. }
  199. static unsigned long s3c2443_armclk_getrate(struct clk *clk)
  200. {
  201. unsigned long rate = clk_get_rate(clk->parent);
  202. unsigned long clkcon0;
  203. int val;
  204. if (!nr_armdiv || !armdivmask)
  205. return -EINVAL;
  206. clkcon0 = __raw_readl(S3C2443_CLKDIV0);
  207. clkcon0 &= armdivmask;
  208. val = clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT;
  209. return rate / armdiv[val];
  210. }
  211. static int s3c2443_armclk_setrate(struct clk *clk, unsigned long rate)
  212. {
  213. unsigned long parent = clk_get_rate(clk->parent);
  214. unsigned long calc;
  215. unsigned div;
  216. unsigned best = 256; /* bigger than any value */
  217. int ptr;
  218. int val = -1;
  219. if (!nr_armdiv || !armdivmask)
  220. return -EINVAL;
  221. for (ptr = 0; ptr < nr_armdiv; ptr++) {
  222. div = armdiv[ptr];
  223. if (div) {
  224. /* cpufreq provides 266mhz as 266666000 not 266666666 */
  225. calc = (parent / div / 1000) * 1000;
  226. if (calc <= rate && div < best) {
  227. best = div;
  228. val = ptr;
  229. }
  230. }
  231. }
  232. if (val >= 0) {
  233. unsigned long clkcon0;
  234. clkcon0 = __raw_readl(S3C2443_CLKDIV0);
  235. clkcon0 &= ~armdivmask;
  236. clkcon0 |= val << S3C2443_CLKDIV0_ARMDIV_SHIFT;
  237. __raw_writel(clkcon0, S3C2443_CLKDIV0);
  238. }
  239. return (val == -1) ? -EINVAL : 0;
  240. }
  241. static struct clk clk_armdiv = {
  242. .name = "armdiv",
  243. .parent = &clk_msysclk.clk,
  244. .ops = &(struct clk_ops) {
  245. .round_rate = s3c2443_armclk_roundrate,
  246. .get_rate = s3c2443_armclk_getrate,
  247. .set_rate = s3c2443_armclk_setrate,
  248. },
  249. };
  250. /* armclk
  251. *
  252. * this is the clock fed into the ARM core itself, from armdiv or from hclk.
  253. */
  254. static struct clk *clk_arm_sources[] = {
  255. [0] = &clk_armdiv,
  256. [1] = &clk_h,
  257. };
  258. static struct clksrc_clk clk_arm = {
  259. .clk = {
  260. .name = "armclk",
  261. },
  262. .sources = &(struct clksrc_sources) {
  263. .sources = clk_arm_sources,
  264. .nr_sources = ARRAY_SIZE(clk_arm_sources),
  265. },
  266. .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
  267. };
  268. /* usbhost
  269. *
  270. * usb host bus-clock, usually 48MHz to provide USB bus clock timing
  271. */
  272. static struct clksrc_clk clk_usb_bus_host = {
  273. .clk = {
  274. .name = "usb-bus-host-parent",
  275. .parent = &clk_esysclk.clk,
  276. .ctrlbit = S3C2443_SCLKCON_USBHOST,
  277. .enable = s3c2443_clkcon_enable_s,
  278. },
  279. .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
  280. };
  281. /* common clksrc clocks */
  282. static struct clksrc_clk clksrc_clks[] = {
  283. {
  284. /* camera interface bus-clock, divided down from esysclk */
  285. .clk = {
  286. .name = "camif-upll", /* same as 2440 name */
  287. .parent = &clk_esysclk.clk,
  288. .ctrlbit = S3C2443_SCLKCON_CAMCLK,
  289. .enable = s3c2443_clkcon_enable_s,
  290. },
  291. .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
  292. }, {
  293. .clk = {
  294. .name = "display-if",
  295. .parent = &clk_esysclk.clk,
  296. .ctrlbit = S3C2443_SCLKCON_DISPCLK,
  297. .enable = s3c2443_clkcon_enable_s,
  298. },
  299. .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
  300. },
  301. };
  302. static struct clksrc_clk clk_esys_uart = {
  303. /* ART baud-rate clock sourced from esysclk via a divisor */
  304. .clk = {
  305. .name = "uartclk",
  306. .parent = &clk_esysclk.clk,
  307. },
  308. .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
  309. };
  310. static struct clk clk_i2s_ext = {
  311. .name = "i2s-ext",
  312. };
  313. /* i2s_eplldiv
  314. *
  315. * This clock is the output from the I2S divisor of ESYSCLK, and is separate
  316. * from the mux that comes after it (cannot merge into one single clock)
  317. */
  318. static struct clksrc_clk clk_i2s_eplldiv = {
  319. .clk = {
  320. .name = "i2s-eplldiv",
  321. .parent = &clk_esysclk.clk,
  322. },
  323. .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
  324. };
  325. /* i2s-ref
  326. *
  327. * i2s bus reference clock, selectable from external, esysclk or epllref
  328. *
  329. * Note, this used to be two clocks, but was compressed into one.
  330. */
  331. static struct clk *clk_i2s_srclist[] = {
  332. [0] = &clk_i2s_eplldiv.clk,
  333. [1] = &clk_i2s_ext,
  334. [2] = &clk_epllref.clk,
  335. [3] = &clk_epllref.clk,
  336. };
  337. static struct clksrc_clk clk_i2s = {
  338. .clk = {
  339. .name = "i2s-if",
  340. .ctrlbit = S3C2443_SCLKCON_I2SCLK,
  341. .enable = s3c2443_clkcon_enable_s,
  342. },
  343. .sources = &(struct clksrc_sources) {
  344. .sources = clk_i2s_srclist,
  345. .nr_sources = ARRAY_SIZE(clk_i2s_srclist),
  346. },
  347. .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
  348. };
  349. static struct clk init_clocks_off[] = {
  350. {
  351. .name = "iis",
  352. .parent = &clk_p,
  353. .enable = s3c2443_clkcon_enable_p,
  354. .ctrlbit = S3C2443_PCLKCON_IIS,
  355. }, {
  356. .name = "hsspi",
  357. .parent = &clk_p,
  358. .enable = s3c2443_clkcon_enable_p,
  359. .ctrlbit = S3C2443_PCLKCON_HSSPI,
  360. }, {
  361. .name = "adc",
  362. .parent = &clk_p,
  363. .enable = s3c2443_clkcon_enable_p,
  364. .ctrlbit = S3C2443_PCLKCON_ADC,
  365. }, {
  366. .name = "i2c",
  367. .parent = &clk_p,
  368. .enable = s3c2443_clkcon_enable_p,
  369. .ctrlbit = S3C2443_PCLKCON_IIC,
  370. }
  371. };
  372. static struct clk init_clocks[] = {
  373. {
  374. .name = "dma",
  375. .parent = &clk_h,
  376. .enable = s3c2443_clkcon_enable_h,
  377. .ctrlbit = S3C2443_HCLKCON_DMA0,
  378. }, {
  379. .name = "dma",
  380. .parent = &clk_h,
  381. .enable = s3c2443_clkcon_enable_h,
  382. .ctrlbit = S3C2443_HCLKCON_DMA1,
  383. }, {
  384. .name = "dma",
  385. .parent = &clk_h,
  386. .enable = s3c2443_clkcon_enable_h,
  387. .ctrlbit = S3C2443_HCLKCON_DMA2,
  388. }, {
  389. .name = "dma",
  390. .parent = &clk_h,
  391. .enable = s3c2443_clkcon_enable_h,
  392. .ctrlbit = S3C2443_HCLKCON_DMA3,
  393. }, {
  394. .name = "dma",
  395. .parent = &clk_h,
  396. .enable = s3c2443_clkcon_enable_h,
  397. .ctrlbit = S3C2443_HCLKCON_DMA4,
  398. }, {
  399. .name = "dma",
  400. .parent = &clk_h,
  401. .enable = s3c2443_clkcon_enable_h,
  402. .ctrlbit = S3C2443_HCLKCON_DMA5,
  403. }, {
  404. .name = "gpio",
  405. .parent = &clk_p,
  406. .enable = s3c2443_clkcon_enable_p,
  407. .ctrlbit = S3C2443_PCLKCON_GPIO,
  408. }, {
  409. .name = "usb-host",
  410. .parent = &clk_h,
  411. .enable = s3c2443_clkcon_enable_h,
  412. .ctrlbit = S3C2443_HCLKCON_USBH,
  413. }, {
  414. .name = "usb-device",
  415. .parent = &clk_h,
  416. .enable = s3c2443_clkcon_enable_h,
  417. .ctrlbit = S3C2443_HCLKCON_USBD,
  418. }, {
  419. .name = "lcd",
  420. .parent = &clk_h,
  421. .enable = s3c2443_clkcon_enable_h,
  422. .ctrlbit = S3C2443_HCLKCON_LCDC,
  423. }, {
  424. .name = "timers",
  425. .parent = &clk_p,
  426. .enable = s3c2443_clkcon_enable_p,
  427. .ctrlbit = S3C2443_PCLKCON_PWMT,
  428. }, {
  429. .name = "cfc",
  430. .parent = &clk_h,
  431. .enable = s3c2443_clkcon_enable_h,
  432. .ctrlbit = S3C2443_HCLKCON_CFC,
  433. }, {
  434. .name = "ssmc",
  435. .parent = &clk_h,
  436. .enable = s3c2443_clkcon_enable_h,
  437. .ctrlbit = S3C2443_HCLKCON_SSMC,
  438. }, {
  439. .name = "uart",
  440. .devname = "s3c2440-uart.0",
  441. .parent = &clk_p,
  442. .enable = s3c2443_clkcon_enable_p,
  443. .ctrlbit = S3C2443_PCLKCON_UART0,
  444. }, {
  445. .name = "uart",
  446. .devname = "s3c2440-uart.1",
  447. .parent = &clk_p,
  448. .enable = s3c2443_clkcon_enable_p,
  449. .ctrlbit = S3C2443_PCLKCON_UART1,
  450. }, {
  451. .name = "uart",
  452. .devname = "s3c2440-uart.2",
  453. .parent = &clk_p,
  454. .enable = s3c2443_clkcon_enable_p,
  455. .ctrlbit = S3C2443_PCLKCON_UART2,
  456. }, {
  457. .name = "uart",
  458. .devname = "s3c2440-uart.3",
  459. .parent = &clk_p,
  460. .enable = s3c2443_clkcon_enable_p,
  461. .ctrlbit = S3C2443_PCLKCON_UART3,
  462. }, {
  463. .name = "rtc",
  464. .parent = &clk_p,
  465. .enable = s3c2443_clkcon_enable_p,
  466. .ctrlbit = S3C2443_PCLKCON_RTC,
  467. }, {
  468. .name = "watchdog",
  469. .parent = &clk_p,
  470. .ctrlbit = S3C2443_PCLKCON_WDT,
  471. }, {
  472. .name = "ac97",
  473. .parent = &clk_p,
  474. .ctrlbit = S3C2443_PCLKCON_AC97,
  475. }, {
  476. .name = "nand",
  477. .parent = &clk_h,
  478. }, {
  479. .name = "usb-bus-host",
  480. .parent = &clk_usb_bus_host.clk,
  481. }
  482. };
  483. static struct clk hsmmc1_clk = {
  484. .name = "hsmmc",
  485. .devname = "s3c-sdhci.1",
  486. .parent = &clk_h,
  487. .enable = s3c2443_clkcon_enable_h,
  488. .ctrlbit = S3C2443_HCLKCON_HSMMC,
  489. };
  490. /* EPLLCON compatible enough to get on/off information */
  491. void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll)
  492. {
  493. unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
  494. unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
  495. struct clk *xtal_clk;
  496. unsigned long xtal;
  497. unsigned long pll;
  498. int ptr;
  499. xtal_clk = clk_get(NULL, "xtal");
  500. xtal = clk_get_rate(xtal_clk);
  501. clk_put(xtal_clk);
  502. pll = get_mpll(mpllcon, xtal);
  503. clk_msysclk.clk.rate = pll;
  504. clk_mpll.rate = pll;
  505. printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
  506. (mpllcon & S3C2443_PLLCON_OFF) ? "off" : "on",
  507. print_mhz(pll), print_mhz(clk_get_rate(&clk_armdiv)),
  508. print_mhz(clk_get_rate(&clk_h)),
  509. print_mhz(clk_get_rate(&clk_p)));
  510. for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
  511. s3c_set_clksrc(&clksrc_clks[ptr], true);
  512. /* ensure usb bus clock is within correct rate of 48MHz */
  513. if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
  514. printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
  515. clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
  516. }
  517. printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
  518. (epllcon & S3C2443_PLLCON_OFF) ? "off" : "on",
  519. print_mhz(clk_get_rate(&clk_epll)),
  520. print_mhz(clk_get_rate(&clk_usb_bus)));
  521. }
  522. static struct clk *clks[] __initdata = {
  523. &clk_prediv,
  524. &clk_mpllref,
  525. &clk_mdivclk,
  526. &clk_ext,
  527. &clk_epll,
  528. &clk_usb_bus,
  529. &clk_armdiv,
  530. &hsmmc1_clk,
  531. };
  532. static struct clksrc_clk *clksrcs[] __initdata = {
  533. &clk_i2s_eplldiv,
  534. &clk_i2s,
  535. &clk_usb_bus_host,
  536. &clk_epllref,
  537. &clk_esysclk,
  538. &clk_msysclk,
  539. &clk_arm,
  540. };
  541. static struct clk_lookup s3c2443_clk_lookup[] = {
  542. CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
  543. CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
  544. CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk),
  545. CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &hsmmc1_clk),
  546. };
  547. void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
  548. unsigned int *divs, int nr_divs,
  549. int divmask)
  550. {
  551. int ptr;
  552. armdiv = divs;
  553. nr_armdiv = nr_divs;
  554. armdivmask = divmask;
  555. /* s3c2443 parents h clock from prediv */
  556. clk_h.parent = &clk_prediv;
  557. clk_h.ops = &clk_h_ops;
  558. /* and p clock from h clock */
  559. clk_p.parent = &clk_h;
  560. clk_p.ops = &clk_p_ops;
  561. clk_usb_bus.parent = &clk_usb_bus_host.clk;
  562. clk_epll.parent = &clk_epllref.clk;
  563. s3c24xx_register_baseclocks(xtal);
  564. s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
  565. for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
  566. s3c_register_clksrc(clksrcs[ptr], 1);
  567. s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
  568. s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
  569. /* See s3c2443/etc notes on disabling clocks at init time */
  570. s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
  571. s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
  572. clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
  573. s3c2443_common_setup_clocks(get_mpll);
  574. }