s3c2443-clock.c 15 KB

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