nu_sys.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. /**************************************************************************//**
  2. * @file sys.c
  3. * @brief N9H30 SYS driver source file
  4. *
  5. * @note
  6. * SPDX-License-Identifier: Apache-2.0
  7. * Copyright (C) 2018 Nuvoton Technology Corp. All rights reserved.
  8. *****************************************************************************/
  9. #include "N9H30.h"
  10. #include "nu_sys.h"
  11. /// @cond HIDDEN_SYMBOLS
  12. #define SYS_MIN_INT_SOURCE 1
  13. #define SYS_MAX_INT_SOURCE 62
  14. #define SYS_NUM_OF_AICREG 16
  15. /* Global variables */
  16. BOOL volatile _sys_bIsAICInitial = FALSE;
  17. /* declaration the function prototype */
  18. extern void SYS_Interrupt_Shell(void);
  19. /* Interrupt Handler Table */
  20. //typedef void (*sys_pvFunPtr)(); /* function pointer */
  21. sys_pvFunPtr sysIrqHandlerTable[] = { 0, /* 0 */
  22. SYS_Interrupt_Shell, /* 1 */
  23. SYS_Interrupt_Shell, /* 2 */
  24. SYS_Interrupt_Shell, /* 3 */
  25. SYS_Interrupt_Shell, /* 4 */
  26. SYS_Interrupt_Shell, /* 5 */
  27. SYS_Interrupt_Shell, /* 6 */
  28. SYS_Interrupt_Shell, /* 7 */
  29. SYS_Interrupt_Shell, /* 8 */
  30. SYS_Interrupt_Shell, /* 9 */
  31. SYS_Interrupt_Shell, /* 10 */
  32. SYS_Interrupt_Shell, /* 11 */
  33. SYS_Interrupt_Shell, /* 12 */
  34. SYS_Interrupt_Shell, /* 13 */
  35. SYS_Interrupt_Shell, /* 14 */
  36. SYS_Interrupt_Shell, /* 15 */
  37. SYS_Interrupt_Shell, /* 16 */
  38. SYS_Interrupt_Shell, /* 17 */
  39. SYS_Interrupt_Shell, /* 18 */
  40. SYS_Interrupt_Shell, /* 19 */
  41. SYS_Interrupt_Shell, /* 20 */
  42. SYS_Interrupt_Shell, /* 21 */
  43. SYS_Interrupt_Shell, /* 22 */
  44. SYS_Interrupt_Shell, /* 23 */
  45. SYS_Interrupt_Shell, /* 24 */
  46. SYS_Interrupt_Shell, /* 25 */
  47. SYS_Interrupt_Shell, /* 26 */
  48. SYS_Interrupt_Shell, /* 27 */
  49. SYS_Interrupt_Shell, /* 28 */
  50. SYS_Interrupt_Shell, /* 29 */
  51. SYS_Interrupt_Shell, /* 30 */
  52. SYS_Interrupt_Shell, /* 31 */
  53. SYS_Interrupt_Shell, /* 32 */
  54. SYS_Interrupt_Shell, /* 33 */
  55. SYS_Interrupt_Shell, /* 34 */
  56. SYS_Interrupt_Shell, /* 35 */
  57. SYS_Interrupt_Shell, /* 36 */
  58. SYS_Interrupt_Shell, /* 37 */
  59. SYS_Interrupt_Shell, /* 38 */
  60. SYS_Interrupt_Shell, /* 39 */
  61. SYS_Interrupt_Shell, /* 40 */
  62. SYS_Interrupt_Shell, /* 41 */
  63. SYS_Interrupt_Shell, /* 42 */
  64. SYS_Interrupt_Shell, /* 43 */
  65. SYS_Interrupt_Shell, /* 44 */
  66. SYS_Interrupt_Shell, /* 45 */
  67. SYS_Interrupt_Shell, /* 46 */
  68. SYS_Interrupt_Shell, /* 47 */
  69. SYS_Interrupt_Shell, /* 48 */
  70. SYS_Interrupt_Shell, /* 49 */
  71. SYS_Interrupt_Shell, /* 50 */
  72. SYS_Interrupt_Shell, /* 51 */
  73. SYS_Interrupt_Shell, /* 52 */
  74. SYS_Interrupt_Shell, /* 53 */
  75. SYS_Interrupt_Shell, /* 54 */
  76. SYS_Interrupt_Shell, /* 55 */
  77. SYS_Interrupt_Shell, /* 56 */
  78. SYS_Interrupt_Shell, /* 57 */
  79. SYS_Interrupt_Shell, /* 58 */
  80. SYS_Interrupt_Shell, /* 59 */
  81. SYS_Interrupt_Shell, /* 60 */
  82. SYS_Interrupt_Shell /* 61 */
  83. };
  84. sys_pvFunPtr sysFiqHandlerTable[] = { 0,
  85. SYS_Interrupt_Shell, /* 1 */
  86. SYS_Interrupt_Shell, /* 2 */
  87. SYS_Interrupt_Shell, /* 3 */
  88. SYS_Interrupt_Shell, /* 4 */
  89. SYS_Interrupt_Shell, /* 5 */
  90. SYS_Interrupt_Shell, /* 6 */
  91. SYS_Interrupt_Shell, /* 7 */
  92. SYS_Interrupt_Shell, /* 8 */
  93. SYS_Interrupt_Shell, /* 9 */
  94. SYS_Interrupt_Shell, /* 10 */
  95. SYS_Interrupt_Shell, /* 11 */
  96. SYS_Interrupt_Shell, /* 12 */
  97. SYS_Interrupt_Shell, /* 13 */
  98. SYS_Interrupt_Shell, /* 14 */
  99. SYS_Interrupt_Shell, /* 15 */
  100. SYS_Interrupt_Shell, /* 16 */
  101. SYS_Interrupt_Shell, /* 17 */
  102. SYS_Interrupt_Shell, /* 18 */
  103. SYS_Interrupt_Shell, /* 19 */
  104. SYS_Interrupt_Shell, /* 20 */
  105. SYS_Interrupt_Shell, /* 21 */
  106. SYS_Interrupt_Shell, /* 22 */
  107. SYS_Interrupt_Shell, /* 23 */
  108. SYS_Interrupt_Shell, /* 24 */
  109. SYS_Interrupt_Shell, /* 25 */
  110. SYS_Interrupt_Shell, /* 26 */
  111. SYS_Interrupt_Shell, /* 27 */
  112. SYS_Interrupt_Shell, /* 28 */
  113. SYS_Interrupt_Shell, /* 29 */
  114. SYS_Interrupt_Shell, /* 30 */
  115. SYS_Interrupt_Shell, /* 31 */
  116. SYS_Interrupt_Shell, /* 32 */
  117. SYS_Interrupt_Shell, /* 33 */
  118. SYS_Interrupt_Shell, /* 34 */
  119. SYS_Interrupt_Shell, /* 35 */
  120. SYS_Interrupt_Shell, /* 36 */
  121. SYS_Interrupt_Shell, /* 37 */
  122. SYS_Interrupt_Shell, /* 38 */
  123. SYS_Interrupt_Shell, /* 39 */
  124. SYS_Interrupt_Shell, /* 40 */
  125. SYS_Interrupt_Shell, /* 41 */
  126. SYS_Interrupt_Shell, /* 42 */
  127. SYS_Interrupt_Shell, /* 43 */
  128. SYS_Interrupt_Shell, /* 44 */
  129. SYS_Interrupt_Shell, /* 45 */
  130. SYS_Interrupt_Shell, /* 46 */
  131. SYS_Interrupt_Shell, /* 47 */
  132. SYS_Interrupt_Shell, /* 48 */
  133. SYS_Interrupt_Shell, /* 49 */
  134. SYS_Interrupt_Shell, /* 50 */
  135. SYS_Interrupt_Shell, /* 51 */
  136. SYS_Interrupt_Shell, /* 52 */
  137. SYS_Interrupt_Shell, /* 53 */
  138. SYS_Interrupt_Shell, /* 54 */
  139. SYS_Interrupt_Shell, /* 55 */
  140. SYS_Interrupt_Shell, /* 56 */
  141. SYS_Interrupt_Shell, /* 57 */
  142. SYS_Interrupt_Shell, /* 58 */
  143. SYS_Interrupt_Shell, /* 59 */
  144. SYS_Interrupt_Shell, /* 60 */
  145. SYS_Interrupt_Shell /* 61 */
  146. };
  147. /* Interrupt Handler */
  148. #if defined ( __GNUC__ ) && !(__CC_ARM)
  149. static void __attribute__((interrupt("IRQ"))) sysIrqHandler(void)
  150. #else
  151. __irq void sysIrqHandler()
  152. #endif
  153. {
  154. UINT32 volatile _mIPER, _mISNR;
  155. _mIPER = (inpw(REG_AIC_IPER) >> 2) & 0x3f;
  156. _mISNR = inpw(REG_AIC_ISNR);
  157. if (_mIPER != 0)
  158. {
  159. if (_mISNR != 0)
  160. (*sysIrqHandlerTable[_mIPER])();
  161. outpw(REG_AIC_EOSCR, 1);
  162. }
  163. }
  164. #if defined ( __GNUC__ ) && !(__CC_ARM)
  165. static void __attribute__((interrupt("FIQ"))) sysFiqHandler(void)
  166. #else
  167. __irq void sysFiqHandler()
  168. #endif
  169. {
  170. UINT32 volatile _mIPER, _mISNR;
  171. _mIPER = (inpw(REG_AIC_IPER) >> 2) & 0x3f;
  172. _mISNR = inpw(REG_AIC_ISNR);
  173. if (_mIPER != 0)
  174. {
  175. if (_mISNR != 0)
  176. (*sysFiqHandlerTable[_mIPER])();
  177. outpw(REG_AIC_EOSCR, 1);
  178. }
  179. }
  180. void SYS_Interrupt_Shell()
  181. {
  182. //sysprintf("ISR not found! ISNR=%d\n", inpw(REG_AIC_ISNR));
  183. }
  184. void sysInitializeAIC()
  185. {
  186. *(unsigned int volatile *)0x38 = (unsigned int)sysIrqHandler;
  187. *(unsigned int volatile *)0x3C = (unsigned int)sysFiqHandler;
  188. }
  189. /// @endcond HIDDEN_SYMBOLS
  190. /* Interrupt library functions */
  191. /**
  192. * @brief system AIC - disable interrupt
  193. *
  194. * @param[in] eIntNo Select interrupt source. \ref IRQn_Type
  195. *
  196. * @return 0
  197. */
  198. INT32 sysDisableInterrupt(IRQn_Type eIntNo)
  199. {
  200. if ((eIntNo > SYS_MAX_INT_SOURCE) || (eIntNo < SYS_MIN_INT_SOURCE))
  201. return 1;
  202. if (eIntNo < 32)
  203. outpw(REG_AIC_MDCR, (1 << eIntNo));
  204. else
  205. outpw(REG_AIC_MDCRH, (1 << (eIntNo - 32)));
  206. return 0;
  207. }
  208. /**
  209. * @brief system AIC - enable interrupt
  210. *
  211. * @param[in] eIntNo Select interrupt source. \ref IRQn_Type
  212. *
  213. * @return 0
  214. */
  215. INT32 sysEnableInterrupt(IRQn_Type eIntNo)
  216. {
  217. if ((eIntNo > SYS_MAX_INT_SOURCE) || (eIntNo < SYS_MIN_INT_SOURCE))
  218. return 1;
  219. if (eIntNo < 32)
  220. outpw(REG_AIC_MECR, (1 << eIntNo));
  221. else
  222. outpw(REG_AIC_MECRH, (1 << (eIntNo - 32)));
  223. return 0;
  224. }
  225. /**
  226. * @brief system AIC - install exception handler
  227. *
  228. * @param[in] nExceptType exception type. ( \ref SYS_SWI / \ref SYS_D_ABORT / \ref SYS_I_ABORT / \ref SYS_UNDEFINE)
  229. * @param[in] pvNewHandler own exception handler
  230. *
  231. * @return old handler
  232. */
  233. PVOID sysInstallExceptionHandler(INT32 nExceptType, PVOID pvNewHandler)
  234. {
  235. PVOID _mOldVect = NULL;
  236. switch (nExceptType)
  237. {
  238. case SYS_SWI:
  239. _mOldVect = *(PVOID volatile *)0x28;
  240. *(PVOID volatile *)0x28 = pvNewHandler;
  241. break;
  242. case SYS_D_ABORT:
  243. _mOldVect = *(PVOID volatile *)0x30;
  244. *(PVOID volatile *)0x30 = pvNewHandler;
  245. break;
  246. case SYS_I_ABORT:
  247. _mOldVect = *(PVOID volatile *)0x2C;
  248. *(PVOID volatile *)0x2C = pvNewHandler;
  249. break;
  250. case SYS_UNDEFINE:
  251. _mOldVect = *(PVOID volatile *)0x24;
  252. *(PVOID volatile *)0x24 = pvNewHandler;
  253. break;
  254. default:
  255. ;
  256. }
  257. return _mOldVect;
  258. }
  259. /**
  260. * @brief system AIC - install FIQ handler
  261. *
  262. * @param[in] pvNewISR own fiq handler
  263. *
  264. * @return old handler
  265. */
  266. PVOID sysInstallFiqHandler(PVOID pvNewISR)
  267. {
  268. PVOID _mOldVect;
  269. _mOldVect = *(PVOID volatile *)0x3C;
  270. *(PVOID volatile *)0x3C = pvNewISR;
  271. return _mOldVect;
  272. }
  273. /**
  274. * @brief system AIC - install IRQ handler
  275. *
  276. * @param[in] pvNewISR own irq handler
  277. *
  278. * @return old handler
  279. */
  280. PVOID sysInstallIrqHandler(PVOID pvNewISR)
  281. {
  282. PVOID _mOldVect;
  283. _mOldVect = *(PVOID volatile *)0x38;
  284. *(PVOID volatile *)0x38 = pvNewISR;
  285. return _mOldVect;
  286. }
  287. /**
  288. * @brief system AIC - install Own IRQ service routine
  289. *
  290. * @param[in] nIntTypeLevel Interrupt Level. ( \ref FIQ_LEVEL_0 / \ref IRQ_LEVEL_1 / \ref IRQ_LEVEL_2 / \ref IRQ_LEVEL_3 /
  291. * \ref IRQ_LEVEL_4 / \ref IRQ_LEVEL_5 / \ref IRQ_LEVEL_6 / \ref IRQ_LEVEL_7 )
  292. * @param[in] eIntNo Interrupt number. \ref IRQn_Type
  293. * @param[in] pvNewISR own irq handler
  294. *
  295. * @return old handler
  296. */
  297. PVOID sysInstallISR(INT32 nIntTypeLevel, IRQn_Type eIntNo, PVOID pvNewISR)
  298. {
  299. PVOID _mOldVect;
  300. UINT32 _mRegAddr/*, _mRegValue*/;
  301. INT shift;
  302. if (!_sys_bIsAICInitial)
  303. {
  304. sysInitializeAIC();
  305. _sys_bIsAICInitial = TRUE;
  306. }
  307. _mRegAddr = REG_AIC_SCR1 + ((eIntNo / 4) * 4);
  308. shift = (eIntNo % 4) * 8;
  309. nIntTypeLevel &= 0xff;
  310. outpw(_mRegAddr, (inpw(_mRegAddr) & ~(0x07 << shift)) | (nIntTypeLevel << shift));
  311. if ((nIntTypeLevel & 0x7) == FIQ_LEVEL_0)
  312. {
  313. _mOldVect = (PVOID) sysFiqHandlerTable[eIntNo];
  314. sysFiqHandlerTable[eIntNo] = (sys_pvFunPtr)pvNewISR;
  315. }
  316. else
  317. {
  318. _mOldVect = (PVOID) sysIrqHandlerTable[eIntNo];
  319. sysIrqHandlerTable[eIntNo] = (sys_pvFunPtr)pvNewISR;
  320. }
  321. return _mOldVect;
  322. }
  323. INT32 sysSetGlobalInterrupt(INT32 nIntState)
  324. {
  325. switch (nIntState)
  326. {
  327. case ENABLE_ALL_INTERRUPTS:
  328. outpw(REG_AIC_MECR, 0xFFFFFFFF);
  329. outpw(REG_AIC_MECRH, 0xFFFFFFFF);
  330. break;
  331. case DISABLE_ALL_INTERRUPTS:
  332. outpw(REG_AIC_MDCR, 0xFFFFFFFF);
  333. outpw(REG_AIC_MDCRH, 0xFFFFFFFF);
  334. break;
  335. default:
  336. ;
  337. }
  338. return 0;
  339. }
  340. /**
  341. * @brief system AIC - Change interrupt level
  342. *
  343. * @param[in] eIntNo Interrupt number. \ref IRQn_Type
  344. * @param[in] uIntLevel Interrupt Level. ( \ref FIQ_LEVEL_0 / \ref IRQ_LEVEL_1 / \ref IRQ_LEVEL_2 / \ref IRQ_LEVEL_3 /
  345. * \ref IRQ_LEVEL_4 / \ref IRQ_LEVEL_5 / \ref IRQ_LEVEL_6 / \ref IRQ_LEVEL_7 )
  346. *
  347. * @return 0
  348. */
  349. INT32 sysSetInterruptPriorityLevel(IRQn_Type eIntNo, UINT32 uIntLevel)
  350. {
  351. UINT32 _mRegAddr;
  352. INT shift;
  353. if ((eIntNo > SYS_MAX_INT_SOURCE) || (eIntNo < SYS_MIN_INT_SOURCE))
  354. return 1;
  355. _mRegAddr = REG_AIC_SCR1 + ((eIntNo / 4) * 4);
  356. shift = (eIntNo % 4) * 8;
  357. uIntLevel &= 0x7;
  358. outpw(_mRegAddr, (inpw(_mRegAddr) & ~(0x07 << shift)) | (uIntLevel << shift));
  359. return 0;
  360. }
  361. INT32 sysSetInterruptType(IRQn_Type eIntNo, UINT32 uIntSourceType)
  362. {
  363. UINT32 _mRegAddr;
  364. INT shift;
  365. if ((eIntNo > SYS_MAX_INT_SOURCE) || (eIntNo < SYS_MIN_INT_SOURCE))
  366. return 1;
  367. _mRegAddr = REG_AIC_SCR1 + ((eIntNo / 4) * 4);
  368. shift = (eIntNo % 4) * 8;
  369. uIntSourceType &= 0xC0;
  370. outpw(_mRegAddr, (inpw(_mRegAddr) & ~(0xC0 << shift)) | (uIntSourceType << shift));
  371. return 0;
  372. }
  373. /**
  374. * @brief system AIC - Set CP15 Interrupt Type
  375. *
  376. * @param[in] nIntState Interrupt state. ( \ref ENABLE_IRQ / \ref ENABLE_FIQ / \ref ENABLE_FIQ_IRQ /
  377. * \ref DISABLE_IRQ / \ref DISABLE_FIQ / \ref DISABLE_FIQ_IRQ)
  378. *
  379. * @return 0
  380. */
  381. INT32 sysSetLocalInterrupt(INT32 nIntState)
  382. {
  383. #if defined ( __GNUC__ ) && !(__CC_ARM)
  384. # else
  385. INT32 temp;
  386. #endif
  387. switch (nIntState)
  388. {
  389. case ENABLE_IRQ:
  390. case ENABLE_FIQ:
  391. case ENABLE_FIQ_IRQ:
  392. #if defined ( __GNUC__ ) && !(__CC_ARM)
  393. asm
  394. (
  395. "mrs r0, CPSR \n"
  396. "bic r0, r0, #0x80 \n"
  397. "msr CPSR_c, r0 \n"
  398. );
  399. #else
  400. __asm
  401. {
  402. MRS temp, CPSR
  403. AND temp, temp, nIntState
  404. MSR CPSR_c, temp
  405. }
  406. #endif
  407. break;
  408. case DISABLE_IRQ:
  409. case DISABLE_FIQ:
  410. case DISABLE_FIQ_IRQ:
  411. #if defined ( __GNUC__ ) && !(__CC_ARM)
  412. asm
  413. (
  414. "MRS r0, CPSR \n"
  415. "ORR r0, r0, #0x80 \n"
  416. "MSR CPSR_c, r0 \n"
  417. );
  418. #else
  419. __asm
  420. {
  421. MRS temp, CPSR
  422. ORR temp, temp, nIntState
  423. MSR CPSR_c, temp
  424. }
  425. #endif
  426. break;
  427. default:
  428. ;
  429. }
  430. return 0;
  431. }
  432. UINT32 sysGetInterruptEnableStatus(void)
  433. {
  434. return (inpw(REG_AIC_IMR));
  435. }
  436. UINT32 sysGetInterruptEnableStatusH(void)
  437. {
  438. return (inpw(REG_AIC_IMRH));
  439. }
  440. /// @cond HIDDEN_SYMBOLS
  441. BOOL sysGetIBitState()
  442. {
  443. INT32 temp;
  444. #if defined ( __GNUC__ ) && !(__CC_ARM)
  445. asm
  446. (
  447. "MRS %0, CPSR \n"
  448. :"=r"(temp) : :
  449. );
  450. #else
  451. __asm
  452. {
  453. MRS temp, CPSR
  454. }
  455. #endif
  456. if (temp & 0x80)
  457. return FALSE;
  458. else
  459. return TRUE;
  460. }
  461. INT32 sysGetPLL(UINT32 reg)
  462. {
  463. UINT32 N, M, P;
  464. N = ((inpw(reg) & 0x007F) >> 0) + 1;
  465. M = ((inpw(reg) & 0x1F80) >> 7) + 1;
  466. P = ((inpw(reg) & 0xE000) >> 13) + 1;
  467. return (12 * N / (M * P)); /* 12MHz HXT */
  468. }
  469. /// @endcond HIDDEN_SYMBOLS
  470. /**
  471. * @brief system Timer - install WDT interrupt handler
  472. *
  473. * @param[in] clk clock source. \ref CLK_Type
  474. *
  475. * @return MHz
  476. */
  477. UINT32 sysGetClock(CLK_Type clk)
  478. {
  479. UINT32 src, divS, divN, reg, div;
  480. switch (clk)
  481. {
  482. case SYS_UPLL:
  483. return sysGetPLL(REG_CLK_UPLLCON);
  484. case SYS_APLL:
  485. return sysGetPLL(REG_CLK_APLLCON);
  486. case SYS_SYSTEM:
  487. {
  488. reg = inpw(REG_CLK_DIVCTL0);
  489. switch (reg & 0x18)
  490. {
  491. case 0x0:
  492. src = 12; /* HXT */
  493. break;
  494. case 0x10:
  495. src = sysGetPLL(REG_CLK_APLLCON);
  496. break;
  497. case 0x18:
  498. src = sysGetPLL(REG_CLK_UPLLCON);
  499. break;
  500. default:
  501. return 0;
  502. }
  503. divS = (reg & 0x7) + 1;
  504. divN = ((reg & 0xf00) >> 8) + 1;
  505. return (src / divS / divN);
  506. }
  507. case SYS_HCLK1:
  508. {
  509. reg = inpw(REG_CLK_DIVCTL0);
  510. switch (reg & 0x18)
  511. {
  512. case 0x0:
  513. src = 12; /* HXT */
  514. break;
  515. case 0x10:
  516. src = sysGetPLL(REG_CLK_APLLCON);
  517. break;
  518. case 0x18:
  519. src = sysGetPLL(REG_CLK_UPLLCON);
  520. break;
  521. default:
  522. return 0;
  523. }
  524. divS = (reg & 0x7) + 1;
  525. divN = ((reg & 0xf00) >> 8) + 1;
  526. return (src / divS / divN / 2);
  527. }
  528. case SYS_HCLK234:
  529. {
  530. reg = inpw(REG_CLK_DIVCTL0);
  531. switch (reg & 0x18)
  532. {
  533. case 0x0:
  534. src = 12; /* HXT */
  535. break;
  536. case 0x10:
  537. src = sysGetPLL(REG_CLK_APLLCON);
  538. break;
  539. case 0x18:
  540. src = sysGetPLL(REG_CLK_UPLLCON);
  541. break;
  542. default:
  543. return 0;
  544. }
  545. divS = (reg & 0x7) + 1;
  546. divN = ((reg & 0xf00) >> 8) + 1;
  547. div = ((reg & 0xf00000) >> 20) + 1;
  548. return (src / divS / divN / 2 / div);
  549. }
  550. case SYS_PCLK:
  551. {
  552. reg = inpw(REG_CLK_DIVCTL0);
  553. switch (reg & 0x18)
  554. {
  555. case 0x0:
  556. src = 12; /* HXT */
  557. break;
  558. case 0x10:
  559. src = sysGetPLL(REG_CLK_APLLCON);
  560. break;
  561. case 0x18:
  562. src = sysGetPLL(REG_CLK_UPLLCON);
  563. break;
  564. default:
  565. return 0;
  566. }
  567. divS = (reg & 0x7) + 1;
  568. divN = ((reg & 0xf00) >> 8) + 1;
  569. div = ((reg & 0xf000000) >> 24) + 1;
  570. return (src / divS / divN / 2 / div);
  571. }
  572. case SYS_CPU:
  573. {
  574. reg = inpw(REG_CLK_DIVCTL0);
  575. switch (reg & 0x18)
  576. {
  577. case 0x0:
  578. src = 12; /* HXT */
  579. break;
  580. case 0x10:
  581. src = sysGetPLL(REG_CLK_APLLCON);
  582. break;
  583. case 0x18:
  584. src = sysGetPLL(REG_CLK_UPLLCON);
  585. break;
  586. default:
  587. return 0;
  588. }
  589. divS = (reg & 0x7) + 1;
  590. divN = ((reg & 0xf00) >> 8) + 1;
  591. div = ((reg & 0xf0000) >> 16) + 1;
  592. return (src / divS / divN / div);
  593. }
  594. default:
  595. ;
  596. }
  597. return 0;
  598. }
  599. /*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/