s3c2443-clock.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  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. /* ART baud-rate clock sourced from esysclk via a divisor */
  249. .clk = {
  250. .name = "uartclk",
  251. .parent = &clk_esysclk.clk,
  252. },
  253. .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
  254. }, {
  255. /* camera interface bus-clock, divided down from esysclk */
  256. .clk = {
  257. .name = "camif-upll", /* same as 2440 name */
  258. .parent = &clk_esysclk.clk,
  259. .ctrlbit = S3C2443_SCLKCON_CAMCLK,
  260. .enable = s3c2443_clkcon_enable_s,
  261. },
  262. .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
  263. }, {
  264. .clk = {
  265. .name = "display-if",
  266. .parent = &clk_esysclk.clk,
  267. .ctrlbit = S3C2443_SCLKCON_DISPCLK,
  268. .enable = s3c2443_clkcon_enable_s,
  269. },
  270. .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
  271. },
  272. };
  273. static struct clk clk_i2s_ext = {
  274. .name = "i2s-ext",
  275. };
  276. /* i2s_eplldiv
  277. *
  278. * This clock is the output from the I2S divisor of ESYSCLK, and is separate
  279. * from the mux that comes after it (cannot merge into one single clock)
  280. */
  281. static struct clksrc_clk clk_i2s_eplldiv = {
  282. .clk = {
  283. .name = "i2s-eplldiv",
  284. .parent = &clk_esysclk.clk,
  285. },
  286. .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
  287. };
  288. /* i2s-ref
  289. *
  290. * i2s bus reference clock, selectable from external, esysclk or epllref
  291. *
  292. * Note, this used to be two clocks, but was compressed into one.
  293. */
  294. static struct clk *clk_i2s_srclist[] = {
  295. [0] = &clk_i2s_eplldiv.clk,
  296. [1] = &clk_i2s_ext,
  297. [2] = &clk_epllref.clk,
  298. [3] = &clk_epllref.clk,
  299. };
  300. static struct clksrc_clk clk_i2s = {
  301. .clk = {
  302. .name = "i2s-if",
  303. .ctrlbit = S3C2443_SCLKCON_I2SCLK,
  304. .enable = s3c2443_clkcon_enable_s,
  305. },
  306. .sources = &(struct clksrc_sources) {
  307. .sources = clk_i2s_srclist,
  308. .nr_sources = ARRAY_SIZE(clk_i2s_srclist),
  309. },
  310. .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
  311. };
  312. static struct clk init_clocks_off[] = {
  313. {
  314. .name = "iis",
  315. .parent = &clk_p,
  316. .enable = s3c2443_clkcon_enable_p,
  317. .ctrlbit = S3C2443_PCLKCON_IIS,
  318. }, {
  319. .name = "hsspi",
  320. .parent = &clk_p,
  321. .enable = s3c2443_clkcon_enable_p,
  322. .ctrlbit = S3C2443_PCLKCON_HSSPI,
  323. }, {
  324. .name = "adc",
  325. .parent = &clk_p,
  326. .enable = s3c2443_clkcon_enable_p,
  327. .ctrlbit = S3C2443_PCLKCON_ADC,
  328. }, {
  329. .name = "i2c",
  330. .parent = &clk_p,
  331. .enable = s3c2443_clkcon_enable_p,
  332. .ctrlbit = S3C2443_PCLKCON_IIC,
  333. }
  334. };
  335. static struct clk init_clocks[] = {
  336. {
  337. .name = "dma",
  338. .parent = &clk_h,
  339. .enable = s3c2443_clkcon_enable_h,
  340. .ctrlbit = S3C2443_HCLKCON_DMA0,
  341. }, {
  342. .name = "dma",
  343. .parent = &clk_h,
  344. .enable = s3c2443_clkcon_enable_h,
  345. .ctrlbit = S3C2443_HCLKCON_DMA1,
  346. }, {
  347. .name = "dma",
  348. .parent = &clk_h,
  349. .enable = s3c2443_clkcon_enable_h,
  350. .ctrlbit = S3C2443_HCLKCON_DMA2,
  351. }, {
  352. .name = "dma",
  353. .parent = &clk_h,
  354. .enable = s3c2443_clkcon_enable_h,
  355. .ctrlbit = S3C2443_HCLKCON_DMA3,
  356. }, {
  357. .name = "dma",
  358. .parent = &clk_h,
  359. .enable = s3c2443_clkcon_enable_h,
  360. .ctrlbit = S3C2443_HCLKCON_DMA4,
  361. }, {
  362. .name = "dma",
  363. .parent = &clk_h,
  364. .enable = s3c2443_clkcon_enable_h,
  365. .ctrlbit = S3C2443_HCLKCON_DMA5,
  366. }, {
  367. .name = "hsmmc",
  368. .devname = "s3c-sdhci.1",
  369. .parent = &clk_h,
  370. .enable = s3c2443_clkcon_enable_h,
  371. .ctrlbit = S3C2443_HCLKCON_HSMMC,
  372. }, {
  373. .name = "gpio",
  374. .parent = &clk_p,
  375. .enable = s3c2443_clkcon_enable_p,
  376. .ctrlbit = S3C2443_PCLKCON_GPIO,
  377. }, {
  378. .name = "usb-host",
  379. .parent = &clk_h,
  380. .enable = s3c2443_clkcon_enable_h,
  381. .ctrlbit = S3C2443_HCLKCON_USBH,
  382. }, {
  383. .name = "usb-device",
  384. .parent = &clk_h,
  385. .enable = s3c2443_clkcon_enable_h,
  386. .ctrlbit = S3C2443_HCLKCON_USBD,
  387. }, {
  388. .name = "lcd",
  389. .parent = &clk_h,
  390. .enable = s3c2443_clkcon_enable_h,
  391. .ctrlbit = S3C2443_HCLKCON_LCDC,
  392. }, {
  393. .name = "timers",
  394. .parent = &clk_p,
  395. .enable = s3c2443_clkcon_enable_p,
  396. .ctrlbit = S3C2443_PCLKCON_PWMT,
  397. }, {
  398. .name = "cfc",
  399. .parent = &clk_h,
  400. .enable = s3c2443_clkcon_enable_h,
  401. .ctrlbit = S3C2443_HCLKCON_CFC,
  402. }, {
  403. .name = "ssmc",
  404. .parent = &clk_h,
  405. .enable = s3c2443_clkcon_enable_h,
  406. .ctrlbit = S3C2443_HCLKCON_SSMC,
  407. }, {
  408. .name = "uart",
  409. .devname = "s3c2440-uart.0",
  410. .parent = &clk_p,
  411. .enable = s3c2443_clkcon_enable_p,
  412. .ctrlbit = S3C2443_PCLKCON_UART0,
  413. }, {
  414. .name = "uart",
  415. .devname = "s3c2440-uart.1",
  416. .parent = &clk_p,
  417. .enable = s3c2443_clkcon_enable_p,
  418. .ctrlbit = S3C2443_PCLKCON_UART1,
  419. }, {
  420. .name = "uart",
  421. .devname = "s3c2440-uart.2",
  422. .parent = &clk_p,
  423. .enable = s3c2443_clkcon_enable_p,
  424. .ctrlbit = S3C2443_PCLKCON_UART2,
  425. }, {
  426. .name = "uart",
  427. .devname = "s3c2440-uart.3",
  428. .parent = &clk_p,
  429. .enable = s3c2443_clkcon_enable_p,
  430. .ctrlbit = S3C2443_PCLKCON_UART3,
  431. }, {
  432. .name = "rtc",
  433. .parent = &clk_p,
  434. .enable = s3c2443_clkcon_enable_p,
  435. .ctrlbit = S3C2443_PCLKCON_RTC,
  436. }, {
  437. .name = "watchdog",
  438. .parent = &clk_p,
  439. .ctrlbit = S3C2443_PCLKCON_WDT,
  440. }, {
  441. .name = "ac97",
  442. .parent = &clk_p,
  443. .ctrlbit = S3C2443_PCLKCON_AC97,
  444. }, {
  445. .name = "nand",
  446. .parent = &clk_h,
  447. }, {
  448. .name = "usb-bus-host",
  449. .parent = &clk_usb_bus_host.clk,
  450. }
  451. };
  452. static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
  453. {
  454. clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
  455. return clkcon0 + 1;
  456. }
  457. /* EPLLCON compatible enough to get on/off information */
  458. void __init_or_cpufreq s3c2443_common_setup_clocks(pll_fn get_mpll)
  459. {
  460. unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
  461. unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
  462. unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
  463. struct clk *xtal_clk;
  464. unsigned long xtal;
  465. unsigned long pll;
  466. unsigned long fclk;
  467. unsigned long hclk;
  468. unsigned long pclk;
  469. int ptr;
  470. xtal_clk = clk_get(NULL, "xtal");
  471. xtal = clk_get_rate(xtal_clk);
  472. clk_put(xtal_clk);
  473. pll = get_mpll(mpllcon, xtal);
  474. clk_msysclk.clk.rate = pll;
  475. fclk = clk_get_rate(&clk_armdiv);
  476. hclk = s3c2443_prediv_getrate(&clk_prediv);
  477. hclk /= s3c2443_get_hdiv(clkdiv0);
  478. pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
  479. s3c24xx_setup_clocks(fclk, hclk, pclk);
  480. printk("CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
  481. (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
  482. print_mhz(pll), print_mhz(fclk),
  483. print_mhz(hclk), print_mhz(pclk));
  484. for (ptr = 0; ptr < ARRAY_SIZE(clksrc_clks); ptr++)
  485. s3c_set_clksrc(&clksrc_clks[ptr], true);
  486. /* ensure usb bus clock is within correct rate of 48MHz */
  487. if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
  488. printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
  489. clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
  490. }
  491. printk("CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
  492. (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
  493. print_mhz(clk_get_rate(&clk_epll)),
  494. print_mhz(clk_get_rate(&clk_usb_bus)));
  495. }
  496. static struct clk *clks[] __initdata = {
  497. &clk_prediv,
  498. &clk_mpllref,
  499. &clk_mdivclk,
  500. &clk_ext,
  501. &clk_epll,
  502. &clk_usb_bus,
  503. &clk_armdiv,
  504. };
  505. static struct clksrc_clk *clksrcs[] __initdata = {
  506. &clk_i2s_eplldiv,
  507. &clk_i2s,
  508. &clk_usb_bus_host,
  509. &clk_epllref,
  510. &clk_esysclk,
  511. &clk_msysclk,
  512. &clk_arm,
  513. };
  514. void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
  515. unsigned int *divs, int nr_divs,
  516. int divmask)
  517. {
  518. int ptr;
  519. armdiv = divs;
  520. nr_armdiv = nr_divs;
  521. armdivmask = divmask;
  522. /* s3c2443 parents h and p clocks from prediv */
  523. clk_h.parent = &clk_prediv;
  524. clk_p.parent = &clk_prediv;
  525. clk_usb_bus.parent = &clk_usb_bus_host.clk;
  526. clk_epll.parent = &clk_epllref.clk;
  527. s3c24xx_register_baseclocks(xtal);
  528. s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
  529. for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
  530. s3c_register_clksrc(clksrcs[ptr], 1);
  531. s3c_register_clksrc(clksrc_clks, ARRAY_SIZE(clksrc_clks));
  532. s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
  533. /* See s3c2443/etc notes on disabling clocks at init time */
  534. s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
  535. s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
  536. s3c2443_common_setup_clocks(get_mpll);
  537. }