soc_clock.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. /*
  2. * Copyright (c) 2019 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file peripheral clock interface for Actions SoC
  8. */
  9. #include <kernel.h>
  10. #include <device.h>
  11. #include <soc.h>
  12. extern void cmu_dev_clk_enable(uint32_t id);
  13. extern void cmu_dev_clk_disable(uint32_t id);
  14. static void acts_clock_peripheral_control(int clock_id, int enable)
  15. {
  16. unsigned int key;
  17. if (clock_id > CLOCK_ID_MAX_ID)
  18. return;
  19. key = irq_lock();
  20. if (enable) {
  21. if (clock_id < 32) {
  22. sys_set_bit(CMU_DEVCLKEN0, clock_id);
  23. } else {
  24. sys_set_bit(CMU_DEVCLKEN1, clock_id - 32);
  25. }
  26. } else {
  27. if (clock_id < 32) {
  28. sys_clear_bit(CMU_DEVCLKEN0, clock_id);
  29. } else {
  30. sys_clear_bit(CMU_DEVCLKEN1, clock_id - 32);
  31. }
  32. }
  33. irq_unlock(key);
  34. }
  35. void acts_clock_peripheral_enable(int clock_id)
  36. {
  37. acts_clock_peripheral_control(clock_id, 1);
  38. }
  39. void acts_clock_peripheral_disable(int clock_id)
  40. {
  41. acts_clock_peripheral_control(clock_id, 0);
  42. }
  43. uint32_t clk_rate_get_corepll(void)
  44. {
  45. return MHZ(((sys_read32(COREPLL_CTL)&0x3F)*8));
  46. }
  47. uint32_t soc_freq_calculate(uint8_t divisor, uint8_t clk_src)
  48. {
  49. uint32_t freq = 0;
  50. if (clk_src == 0) { /* RC4M */
  51. freq = 4000000UL;
  52. } else if (clk_src == 1) { /* HOSC */
  53. freq = 32000000UL;
  54. } else if (clk_src == 3) { /* RC64M */
  55. freq = 64000000UL;
  56. } else if (clk_src == 4) { /* RC96M */
  57. freq = 96000000UL;
  58. } else if (clk_src == 5) { /* RC128M */
  59. freq = 128000000UL;
  60. } else if (clk_src == 6) { /* RC32K */
  61. freq = 32000UL;
  62. } else if (clk_src == 2) { /* COREPLL */
  63. freq = clk_rate_get_corepll();
  64. }
  65. if (divisor == 14) {
  66. /* 1.5 divisor */
  67. freq = freq * 10 / 15;
  68. } else if (divisor == 15) {
  69. /* 2.5 divisor */
  70. freq = freq * 10 / 25;
  71. } else {
  72. freq = freq / (divisor + 1);
  73. }
  74. return freq;
  75. }
  76. uint8_t soc_freq_divisor_calculate(uint32_t freq_mhz, uint32_t max_mhz)
  77. {
  78. uint8_t divisor;
  79. if (max_mhz > freq_mhz && max_mhz <= (freq_mhz * 3 / 2)) {
  80. /* /1.5 */
  81. divisor = 14;
  82. } else if ((max_mhz > 2 * freq_mhz) && max_mhz <= (freq_mhz * 5 / 2)) {
  83. /* /2.5 */
  84. divisor = 15;
  85. } else {
  86. /* /n */
  87. divisor = (max_mhz + freq_mhz - 1) / freq_mhz - 1;
  88. if (divisor > 13) {
  89. divisor = 13;
  90. }
  91. }
  92. return divisor;
  93. }
  94. uint32_t soc_freq_get_dsp_freq(void)
  95. {
  96. uint8_t dspclk_div = (sys_read32(CMU_DSPCLK) & (0xF << 4)) >> 4;
  97. uint8_t dspclk_src = sys_read32(CMU_DSPCLK) & 0x7;
  98. return soc_freq_calculate(dspclk_div, dspclk_src);
  99. }
  100. uint32_t soc_freq_get_cpu_freq(void)
  101. {
  102. uint8_t cpuclk_div = (sys_read32(CMU_SYSCLK) & (0xF << 4)) >> 4;
  103. uint8_t cpuclk_src = sys_read32(CMU_SYSCLK) & 0x7;
  104. return soc_freq_calculate(cpuclk_div, cpuclk_src);
  105. }
  106. void soc_freq_set_gpu_clk(uint32_t gpu_mhz, uint32_t de_mhz, uint32_t jpeg_mhz)
  107. {
  108. uint32_t val, flags, divisor;
  109. uint32_t corepll_mhz;
  110. flags = irq_lock();
  111. corepll_mhz = clk_rate_get_corepll() / 1000000UL;
  112. if ((gpu_mhz > corepll_mhz)
  113. || (de_mhz > corepll_mhz)
  114. || (jpeg_mhz > corepll_mhz)) {
  115. irq_unlock(flags);
  116. return ;
  117. }
  118. /* set gpu clk */
  119. if (gpu_mhz) {
  120. divisor = soc_freq_divisor_calculate(gpu_mhz, corepll_mhz);
  121. val = sys_read32(CMU_GPUCLK);
  122. val &= ~((0xf << 0) | (0x3 << 8));
  123. val |= (0x1 << 8); /* select gpu clock source from corepll */
  124. val |= (divisor << 0);
  125. sys_write32(val, CMU_GPUCLK);
  126. }
  127. /* set de clk */
  128. if (de_mhz) {
  129. divisor = soc_freq_divisor_calculate(de_mhz, corepll_mhz);
  130. val = sys_read32(CMU_DECLK);
  131. val &= ~((0xf << 0) | (0x3 << 8));
  132. val |= (0x1 << 8); /* select de clock source from corepll */
  133. val |= (divisor << 0);
  134. sys_write32(val, CMU_DECLK);
  135. }
  136. /* set jpeg clk */
  137. if (jpeg_mhz) {
  138. divisor = soc_freq_divisor_calculate(jpeg_mhz, corepll_mhz);
  139. val = sys_read32(CMU_JPEGCLK);
  140. val &= ~((0xf << 0) | (0x3 << 8));
  141. val |= (0x1 << 8); /* select jpeg clock source from corepll */
  142. val |= (divisor << 0);
  143. sys_write32(val, CMU_JPEGCLK);
  144. }
  145. irq_unlock(flags);
  146. }
  147. void soc_freq_set_cpu_clk(uint32_t dsp_mhz, uint32_t cpu_mhz)
  148. {
  149. uint32_t val, flags, divisor;
  150. uint32_t corepll_mhz;
  151. flags = irq_lock();
  152. corepll_mhz = clk_rate_get_corepll() / 1000000UL;
  153. if ((cpu_mhz > corepll_mhz) || (!cpu_mhz))
  154. return;
  155. if ((dsp_mhz > corepll_mhz) || (!dsp_mhz))
  156. return;
  157. divisor = soc_freq_divisor_calculate(cpu_mhz, corepll_mhz);
  158. /* set cpu clock */
  159. val = sys_read32(CMU_SYSCLK);
  160. val &= ~((0xf << 4) | (0x7 << 0) | (3<<8));
  161. val |= (0x2 << 0); /* select cpu clock source from corepll */
  162. val |= divisor << 4;
  163. if (soc_dvfs_opt())
  164. val |= (0x1 << 8); /* ahb /4 */
  165. else
  166. val |= (0x2 << 8); /* ahb /1 */
  167. sys_write32(val, CMU_SYSCLK);
  168. divisor = soc_freq_divisor_calculate(dsp_mhz, corepll_mhz);
  169. /* set dsp clock */
  170. val = sys_read32(CMU_DSPCLK);
  171. val &= ~((0x3f << 4) | (0x7 << 0));
  172. val |= (0x2 << 0); /* select dsp clock source from corepll */
  173. val |= divisor << 4;
  174. val |= (0x2 << 8); /* apb / 2 */
  175. sys_write32(val, CMU_DSPCLK);
  176. irq_unlock(flags);
  177. }
  178. #ifdef CONFIG_MMC_ACTS
  179. static void acts_clk_set_rate_sd(int sd, unsigned int rate_hz)
  180. {
  181. unsigned int core_pll, hosc_hz, val, real_rate, div;
  182. core_pll = clk_rate_get_corepll();
  183. hosc_hz = CONFIG_HOSC_CLK_MHZ*1000000;
  184. /*
  185. * Set the RDELAY and WDELAY based on the sd clk.
  186. */
  187. if (rate_hz < hosc_hz/16) {
  188. /* clock source: HOSC, 1/128, real freq: 188KHz */
  189. div = (hosc_hz+(128*rate_hz)-1)/(128*rate_hz);
  190. val = 0x40 + div-1 ;
  191. real_rate = hosc_hz/(128*div);
  192. } else if (rate_hz <= hosc_hz) {
  193. /* clock source: HOSC, real freq: 1.5M~24M */
  194. div = (hosc_hz+rate_hz-1)/rate_hz;
  195. val = div - 1;
  196. real_rate = hosc_hz/div;
  197. } else {
  198. /* clock source: core_pll, real freq: 200MHz */
  199. div = (core_pll+rate_hz-1)/rate_hz;
  200. real_rate = core_pll/div;
  201. val = (div-1)|(1<<8);
  202. }
  203. sys_write32(val, CMU_SD0CLK+sd*4);
  204. printk("mmc%d: set rate %d Hz, real rate %d Hz, core pll=%d HZ\n",
  205. sd, rate_hz, real_rate, core_pll);
  206. }
  207. #else
  208. static void acts_clk_set_rate_sd(int sd, unsigned int rate_hz)
  209. {
  210. }
  211. #endif
  212. #ifdef CONFIG_SOC_SPI0_USE_CK64M
  213. static unsigned int calc_spi_clk_div(unsigned int max_freq, unsigned int spi_freq)
  214. {
  215. unsigned int div;
  216. if (max_freq > spi_freq && max_freq <= (spi_freq * 3 / 2)) {
  217. /* /1.5 */
  218. div = 14;
  219. } else if ((max_freq > 2 * spi_freq) && max_freq <= (spi_freq * 5 / 2)) {
  220. /* /2.5 */
  221. div = 15;
  222. } else {
  223. /* /n */
  224. div = (max_freq + spi_freq - 1) / spi_freq - 1;
  225. if (div > 13) {
  226. div = 13;
  227. }
  228. }
  229. return div;
  230. }
  231. static void __acts_clk_set_rate_spi_ck64m(int clock_id, unsigned int rate_hz)
  232. {
  233. unsigned int div, reg_val, real_rate;
  234. div = calc_spi_clk_div(MHZ(64), rate_hz) & 0xf;
  235. /* check CK64M has been enabled or not */
  236. if (!(sys_read32(CMU_S1CLKCTL) & (1 << 2))) {
  237. /* enable S1 CK64M */
  238. sys_write32(sys_read32(CMU_S1CLKCTL) | (1 << 2), CMU_S1CLKCTL);
  239. /* enable S1BT CK64M */
  240. sys_write32(sys_read32(CMU_S1BTCLKCTL) | (1 << 2), CMU_S1BTCLKCTL);
  241. k_busy_wait(10);
  242. /* calibrate CK64M clock */
  243. sys_write32(0xe, CK64M_CTL);
  244. /* wait calibration done */
  245. while(!(sys_read32(CK64M_CTL) & (1 << 8))) {
  246. ;
  247. }
  248. }
  249. /* set SPIx clock source and divison */
  250. reg_val = sys_read32(CMU_SPI0CLK + ((clock_id - CLOCK_ID_SPI0) * 4));
  251. reg_val &= ~0x30f;
  252. reg_val |= (0x3 << 8) | (div << 0);
  253. if (div == 14)
  254. real_rate = MHZ(64) * 2 / 3;
  255. else if (div == 15)
  256. real_rate = MHZ(64) * 2 / 5;
  257. else
  258. real_rate = MHZ(64) / (div + 1);
  259. sys_write32(reg_val, CMU_SPI0CLK + ((clock_id - CLOCK_ID_SPI0) * 4));
  260. printk("SPI%d: set rate %d Hz real rate %d Hz\n",
  261. clock_id - CLOCK_ID_SPI0, rate_hz, real_rate);
  262. }
  263. #endif
  264. static void acts_clk_set_rate_spi(int clock_id, unsigned int rate_hz)
  265. {
  266. unsigned int core_pll, val, real_rate, div;
  267. #ifdef CONFIG_SOC_SPI0_USE_CK64M
  268. if (CLOCK_ID_SPI0 == clock_id)
  269. return __acts_clk_set_rate_spi_ck64m(CLOCK_ID_SPI0, rate_hz);
  270. #endif
  271. if(rate_hz < CONFIG_HOSC_CLK_MHZ*1000000/2){
  272. div = (CONFIG_HOSC_CLK_MHZ*1000000+rate_hz-1)/rate_hz;
  273. real_rate = CONFIG_HOSC_CLK_MHZ*1000000/div;
  274. val = (div-1);
  275. }else{
  276. core_pll = clk_rate_get_corepll();
  277. if((rate_hz >= 186000000) && (rate_hz < core_pll)){ //div =1.5
  278. real_rate = core_pll*2/3;
  279. val = (0xe)|(1<<8);
  280. }else{
  281. div = (core_pll+rate_hz-1)/rate_hz;
  282. real_rate = core_pll/div;
  283. val = (div-1)|(1<<8);
  284. }
  285. }
  286. sys_write32(val, CMU_SPI0CLK + (clock_id - CLOCK_ID_SPI0)*4);
  287. printk("SPI%d: set rate %d Hz, real rate %d Hz,CMU_SPICLK=0x%x\n",
  288. clock_id - CLOCK_ID_SPI0, rate_hz, real_rate, val);
  289. }
  290. #ifdef CONFIG_SPIMT_ACTS
  291. static void acts_clk_set_rate_spimt(int clock_id, unsigned int rate_hz)
  292. {
  293. unsigned int val, div, real_rate;
  294. if (rate_hz > 4000000) {
  295. rate_hz = 4000000;
  296. }
  297. div = 4000000 / rate_hz;
  298. real_rate = 4000000 / div;
  299. val = (0 << 8) | (div - 1);
  300. sys_write32(val, CMU_SPIMT0CLK + (clock_id - CLOCK_ID_SPIMT0)*4);
  301. printk("SPIMT%d: set rate %d Hz, real rate %d Hz\n",
  302. clock_id - CLOCK_ID_SPIMT0, rate_hz, real_rate);
  303. }
  304. #else
  305. static void acts_clk_set_rate_spimt(int clock_id, unsigned int rate_hz)
  306. {
  307. }
  308. #endif
  309. #ifdef CONFIG_DISPLAY_LCDC
  310. static void acts_clk_set_rate_lcd(unsigned int rate_hz)
  311. {
  312. uint32_t real_rate, div, pre_div;
  313. uint32_t src_sel, parent_clk;
  314. parent_clk = clk_rate_get_corepll();
  315. if (rate_hz < parent_clk / 72) {
  316. parent_clk = CONFIG_HOSC_CLK_MHZ * 1000000u;
  317. src_sel = 0;
  318. } else {
  319. src_sel = 1 << 8;
  320. }
  321. pre_div = (rate_hz < parent_clk / 12) ? 6 : 1;
  322. div = (parent_clk + rate_hz * pre_div - 1) / (rate_hz * pre_div);
  323. if (div < 1) div = 1;
  324. else if (div > 12) div = 12;
  325. real_rate = parent_clk / (div * pre_div);
  326. sys_write32(src_sel | (div - 1) | ((pre_div > 1) ? (1 << 4) : 0), CMU_LCDCLK);
  327. printk("LCD: set rate %d Hz, real rate %d Hz\n", rate_hz, real_rate);
  328. }
  329. #endif /* CONFIG_DISPLAY_LCDC */
  330. #ifdef CONFIG_DISPLAY_ENGINE
  331. static void acts_clk_set_rate_de(unsigned int rate_hz)
  332. {
  333. uint32_t core_pll, real_rate, div2, div;
  334. core_pll = clk_rate_get_corepll();
  335. div2 = (core_pll * 2 + rate_hz - 1) / rate_hz;
  336. switch (div2) {
  337. case 3:
  338. div = 15; /* +1 */
  339. break;
  340. case 5:
  341. div = 16; /* +1 */
  342. break;
  343. default:
  344. div = div2 / 2;
  345. if (div < 1) div = 1;
  346. else if (div > 14) div = 14;
  347. div2 = div * 2;
  348. break;
  349. }
  350. real_rate = core_pll * 2 / div2;
  351. sys_write32((1 << 8) | (div - 1), CMU_DECLK);
  352. printk("DE: set rate %d Hz, real rate %d Hz\n", rate_hz, real_rate);
  353. }
  354. #endif /* CONFIG_DISPLAY_ENGINE */
  355. #ifdef CONFIG_VG_LITE
  356. static void acts_clk_set_rate_gpu(unsigned int rate_hz)
  357. {
  358. uint32_t core_pll, real_rate, div2, div;
  359. core_pll = clk_rate_get_corepll();
  360. div2 = (core_pll * 2 + rate_hz - 1) / rate_hz;
  361. switch (div2) {
  362. case 3:
  363. div = 15; /* +1 */
  364. break;
  365. case 5:
  366. div = 16; /* +1 */
  367. break;
  368. default:
  369. div = div2 / 2;
  370. if (div < 1) div = 1;
  371. else if (div > 14) div = 14;
  372. div2 = div * 2;
  373. break;
  374. }
  375. real_rate = core_pll * 2 / div2;
  376. sys_write32((1 << 12) | (1 << 8) | (div - 1), CMU_GPUCLK);
  377. printk("GPU: set rate %d Hz, real rate %d Hz\n", rate_hz, real_rate);
  378. }
  379. #endif /* CONFIG_VG_LITE */
  380. #ifdef CONFIG_JPEG_HW
  381. static void acts_clk_set_rate_jpeg(unsigned int rate_hz)
  382. {
  383. uint32_t core_pll, real_rate, div2, div;
  384. core_pll = clk_rate_get_corepll();
  385. div2 = (core_pll * 2 + rate_hz - 1) / rate_hz;
  386. switch (div2) {
  387. case 3:
  388. div = 15; /* +1 */
  389. break;
  390. case 5:
  391. div = 16; /* +1 */
  392. break;
  393. default:
  394. div = div2 / 2;
  395. if (div < 1) div = 1;
  396. else if (div > 14) div = 14;
  397. div2 = div * 2;
  398. break;
  399. }
  400. real_rate = core_pll * 2 / div2;
  401. sys_write32((1 << 8) | (div - 1), CMU_JPEGCLK);
  402. //printk("jpeg : set rate %d Hz, real rate %d Hz\n", rate_hz, real_rate);
  403. }
  404. #endif /* CONFIG_JPEG_HW */
  405. int clk_set_rate(int clock_id, uint32_t rate_hz)
  406. {
  407. int ret = 0;
  408. switch(clock_id) {
  409. case CLOCK_ID_SD0:
  410. case CLOCK_ID_SD1:
  411. acts_clk_set_rate_sd(clock_id-CLOCK_ID_SD0, rate_hz);
  412. break;
  413. case CLOCK_ID_DMA:
  414. break;
  415. case CLOCK_ID_SPI0:
  416. case CLOCK_ID_SPI1:
  417. case CLOCK_ID_SPI2:
  418. case CLOCK_ID_SPI3:
  419. acts_clk_set_rate_spi(clock_id, rate_hz);
  420. break;
  421. case CLOCK_ID_SPIMT0:
  422. case CLOCK_ID_SPIMT1:
  423. acts_clk_set_rate_spimt(clock_id, rate_hz);
  424. break;
  425. #ifdef CONFIG_DISPLAY_LCDC
  426. case CLOCK_ID_LCD:
  427. acts_clk_set_rate_lcd(rate_hz);
  428. break;
  429. #endif
  430. #ifdef CONFIG_DISPLAY_ENGINE
  431. case CLOCK_ID_DE:
  432. acts_clk_set_rate_de(rate_hz);
  433. break;
  434. #endif
  435. #ifdef CONFIG_VG_LITE
  436. case CLOCK_ID_GPU:
  437. acts_clk_set_rate_gpu(rate_hz);
  438. break;
  439. #endif
  440. #ifdef CONFIG_JPEG_HW
  441. case CLOCK_ID_JPEG:
  442. acts_clk_set_rate_jpeg(rate_hz);
  443. break;
  444. #endif
  445. case CLOCK_ID_I2CMT0:
  446. case CLOCK_ID_I2CMT1:
  447. case CLOCK_ID_SPI0CACHE:
  448. case CLOCK_ID_SPI1CACHE:
  449. case CLOCK_ID_USB:
  450. case CLOCK_ID_USB2:
  451. case CLOCK_ID_SE:
  452. case CLOCK_ID_LRADC:
  453. case CLOCK_ID_UART0:
  454. case CLOCK_ID_UART1:
  455. case CLOCK_ID_UART2:
  456. case CLOCK_ID_I2C0:
  457. case CLOCK_ID_I2C1:
  458. case CLOCK_ID_DSP:
  459. case CLOCK_ID_ASRC:
  460. case CLOCK_ID_DAC:
  461. case CLOCK_ID_ADC:
  462. case CLOCK_ID_I2STX:
  463. case CLOCK_ID_I2SRX:
  464. printk("clkid=%d not support clk set\n",clock_id);
  465. ret = -1;
  466. break;
  467. }
  468. return 0;
  469. }
  470. uint32_t clk_get_rate(int clock_id)
  471. {
  472. uint32_t rate = 0;
  473. switch(clock_id) {
  474. case CLOCK_ID_SD0:
  475. case CLOCK_ID_SD1:
  476. case CLOCK_ID_DMA:
  477. case CLOCK_ID_SPI0:
  478. case CLOCK_ID_SPI1:
  479. case CLOCK_ID_SPI2:
  480. case CLOCK_ID_SPI3:
  481. case CLOCK_ID_SPI0CACHE:
  482. case CLOCK_ID_SPI1CACHE:
  483. case CLOCK_ID_USB:
  484. case CLOCK_ID_USB2:
  485. case CLOCK_ID_DE:
  486. case CLOCK_ID_LCD:
  487. case CLOCK_ID_SE:
  488. case CLOCK_ID_LRADC:
  489. case CLOCK_ID_UART0:
  490. case CLOCK_ID_UART1:
  491. case CLOCK_ID_UART2:
  492. case CLOCK_ID_I2C0:
  493. case CLOCK_ID_I2C1:
  494. case CLOCK_ID_DSP:
  495. case CLOCK_ID_ASRC:
  496. case CLOCK_ID_DAC:
  497. case CLOCK_ID_ADC:
  498. case CLOCK_ID_I2STX:
  499. case CLOCK_ID_I2SRX:
  500. printk("clkid=%d not support clk get\n",clock_id);
  501. break;
  502. }
  503. return rate;
  504. }
  505. /*set cpu clk, return old clk*/
  506. #if 0
  507. uint32_t clk_cpu_set(uint32_t mhz)
  508. {
  509. unsigned int core_pll, div, tmp, real_rate;
  510. core_pll = (sys_read32(COREPLL_CTL)&0x3F)*80;
  511. tmp = core_pll/mhz;
  512. if(tmp > 13){// div 1.5
  513. real_rate = core_pll/15;
  514. div = 14;
  515. } else if ( (tmp < 28) && (tmp > 22) ) { // div 2.5
  516. real_rate = core_pll/25;
  517. div = 15;
  518. }else if( tmp > 140){
  519. real_rate = core_pll/14;
  520. div = 13;
  521. }else{
  522. div = (tmp/10)-1;
  523. real_rate = core_pll/10;
  524. }
  525. tmp = sys_read32(CMU_SYSCLK);
  526. sys_write32((old & (~(0x3<<8))) | val , CMU_SYSCLK);
  527. printk("cpu: set rate %d MHz, real rate %d MHz, core pll=%d MHZ\n", mhz, real_rate, core_pll);
  528. }
  529. #endif
  530. /*set ahb div, return old div*/
  531. uint32_t clk_ahb_set(uint32_t div)
  532. {
  533. uint32_t val, old;
  534. old = sys_read32(CMU_SYSCLK);
  535. if(div == 1)
  536. val = 1<<8;
  537. else if (div == 4)
  538. val = 3<<8;
  539. else
  540. val = 0;
  541. div = (old >>8) & 0x03;
  542. sys_write32((old & (~(0x3<<8))) | val , CMU_SYSCLK);
  543. return div;
  544. }