sysctl.c 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858
  1. /* Copyright 2018 Canaan Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #include <math.h>
  16. #include <stdint.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include "bsp.h"
  20. #include "encoding.h"
  21. #include "string.h"
  22. #include "sysctl.h"
  23. #include "uart.h"
  24. #define SYSCTRL_CLOCK_FREQ_IN0 (26000000UL)
  25. const uint8_t get_select_pll2[] =
  26. {
  27. [SYSCTL_SOURCE_IN0] = 0,
  28. [SYSCTL_SOURCE_PLL0] = 1,
  29. [SYSCTL_SOURCE_PLL1] = 2,
  30. };
  31. const uint8_t get_source_pll2[] =
  32. {
  33. [0] = SYSCTL_SOURCE_IN0,
  34. [1] = SYSCTL_SOURCE_PLL0,
  35. [2] = SYSCTL_SOURCE_PLL1,
  36. };
  37. const uint8_t get_select_aclk[] =
  38. {
  39. [SYSCTL_SOURCE_IN0] = 0,
  40. [SYSCTL_SOURCE_PLL0] = 1,
  41. };
  42. const uint8_t get_source_aclk[] =
  43. {
  44. [0] = SYSCTL_SOURCE_IN0,
  45. [1] = SYSCTL_SOURCE_PLL0,
  46. };
  47. volatile sysctl_t *const sysctl = (volatile sysctl_t *)SYSCTL_BASE_ADDR;
  48. uint32_t sysctl_get_git_id(void)
  49. {
  50. return sysctl->git_id.git_id;
  51. }
  52. uint32_t sysctl_get_freq(void)
  53. {
  54. return sysctl->clk_freq.clk_freq;
  55. }
  56. static void sysctl_reset_ctl(sysctl_reset_t reset, uint8_t rst_value)
  57. {
  58. switch(reset)
  59. {
  60. case SYSCTL_RESET_SOC:
  61. sysctl->soft_reset.soft_reset = rst_value;
  62. break;
  63. case SYSCTL_RESET_ROM:
  64. sysctl->peri_reset.rom_reset = rst_value;
  65. break;
  66. case SYSCTL_RESET_DMA:
  67. sysctl->peri_reset.dma_reset = rst_value;
  68. break;
  69. case SYSCTL_RESET_AI:
  70. sysctl->peri_reset.ai_reset = rst_value;
  71. break;
  72. case SYSCTL_RESET_DVP:
  73. sysctl->peri_reset.dvp_reset = rst_value;
  74. break;
  75. case SYSCTL_RESET_FFT:
  76. sysctl->peri_reset.fft_reset = rst_value;
  77. break;
  78. case SYSCTL_RESET_GPIO:
  79. sysctl->peri_reset.gpio_reset = rst_value;
  80. break;
  81. case SYSCTL_RESET_SPI0:
  82. sysctl->peri_reset.spi0_reset = rst_value;
  83. break;
  84. case SYSCTL_RESET_SPI1:
  85. sysctl->peri_reset.spi1_reset = rst_value;
  86. break;
  87. case SYSCTL_RESET_SPI2:
  88. sysctl->peri_reset.spi2_reset = rst_value;
  89. break;
  90. case SYSCTL_RESET_SPI3:
  91. sysctl->peri_reset.spi3_reset = rst_value;
  92. break;
  93. case SYSCTL_RESET_I2S0:
  94. sysctl->peri_reset.i2s0_reset = rst_value;
  95. break;
  96. case SYSCTL_RESET_I2S1:
  97. sysctl->peri_reset.i2s1_reset = rst_value;
  98. break;
  99. case SYSCTL_RESET_I2S2:
  100. sysctl->peri_reset.i2s2_reset = rst_value;
  101. break;
  102. case SYSCTL_RESET_I2C0:
  103. sysctl->peri_reset.i2c0_reset = rst_value;
  104. break;
  105. case SYSCTL_RESET_I2C1:
  106. sysctl->peri_reset.i2c1_reset = rst_value;
  107. break;
  108. case SYSCTL_RESET_I2C2:
  109. sysctl->peri_reset.i2c2_reset = rst_value;
  110. break;
  111. case SYSCTL_RESET_UART1:
  112. sysctl->peri_reset.uart1_reset = rst_value;
  113. break;
  114. case SYSCTL_RESET_UART2:
  115. sysctl->peri_reset.uart2_reset = rst_value;
  116. break;
  117. case SYSCTL_RESET_UART3:
  118. sysctl->peri_reset.uart3_reset = rst_value;
  119. break;
  120. case SYSCTL_RESET_AES:
  121. sysctl->peri_reset.aes_reset = rst_value;
  122. break;
  123. case SYSCTL_RESET_FPIOA:
  124. sysctl->peri_reset.fpioa_reset = rst_value;
  125. break;
  126. case SYSCTL_RESET_TIMER0:
  127. sysctl->peri_reset.timer0_reset = rst_value;
  128. break;
  129. case SYSCTL_RESET_TIMER1:
  130. sysctl->peri_reset.timer1_reset = rst_value;
  131. break;
  132. case SYSCTL_RESET_TIMER2:
  133. sysctl->peri_reset.timer2_reset = rst_value;
  134. break;
  135. case SYSCTL_RESET_WDT0:
  136. sysctl->peri_reset.wdt0_reset = rst_value;
  137. break;
  138. case SYSCTL_RESET_WDT1:
  139. sysctl->peri_reset.wdt1_reset = rst_value;
  140. break;
  141. case SYSCTL_RESET_SHA:
  142. sysctl->peri_reset.sha_reset = rst_value;
  143. break;
  144. case SYSCTL_RESET_RTC:
  145. sysctl->peri_reset.rtc_reset = rst_value;
  146. break;
  147. default:
  148. break;
  149. }
  150. }
  151. void sysctl_reset(sysctl_reset_t reset)
  152. {
  153. sysctl_reset_ctl(reset, 1);
  154. usleep(10);
  155. sysctl_reset_ctl(reset, 0);
  156. }
  157. static int sysctl_clock_bus_en(sysctl_clock_t clock, uint8_t en)
  158. {
  159. /*
  160. * The timer is under APB0, to prevent apb0_clk_en1 and apb0_clk_en0
  161. * on same register, we split it to peripheral and central two
  162. * registers, to protect CPU close apb0 clock accidentally.
  163. *
  164. * The apb0_clk_en0 and apb0_clk_en1 have same function,
  165. * one of them set, the APB0 clock enable.
  166. */
  167. /* The APB clock should carefully disable */
  168. if(en)
  169. {
  170. switch(clock)
  171. {
  172. /*
  173. * These peripheral devices are under APB0
  174. * GPIO, UART1, UART2, UART3, SPI_SLAVE, I2S0, I2S1,
  175. * I2S2, I2C0, I2C1, I2C2, FPIOA, SHA256, TIMER0,
  176. * TIMER1, TIMER2
  177. */
  178. case SYSCTL_CLOCK_GPIO:
  179. case SYSCTL_CLOCK_SPI2:
  180. case SYSCTL_CLOCK_I2S0:
  181. case SYSCTL_CLOCK_I2S1:
  182. case SYSCTL_CLOCK_I2S2:
  183. case SYSCTL_CLOCK_I2C0:
  184. case SYSCTL_CLOCK_I2C1:
  185. case SYSCTL_CLOCK_I2C2:
  186. case SYSCTL_CLOCK_UART1:
  187. case SYSCTL_CLOCK_UART2:
  188. case SYSCTL_CLOCK_UART3:
  189. case SYSCTL_CLOCK_FPIOA:
  190. case SYSCTL_CLOCK_TIMER0:
  191. case SYSCTL_CLOCK_TIMER1:
  192. case SYSCTL_CLOCK_TIMER2:
  193. case SYSCTL_CLOCK_SHA:
  194. sysctl->clk_en_cent.apb0_clk_en = en;
  195. break;
  196. /*
  197. * These peripheral devices are under APB1
  198. * WDT, AES, OTP, DVP, SYSCTL
  199. */
  200. case SYSCTL_CLOCK_AES:
  201. case SYSCTL_CLOCK_WDT0:
  202. case SYSCTL_CLOCK_WDT1:
  203. case SYSCTL_CLOCK_OTP:
  204. case SYSCTL_CLOCK_RTC:
  205. sysctl->clk_en_cent.apb1_clk_en = en;
  206. break;
  207. /*
  208. * These peripheral devices are under APB2
  209. * SPI0, SPI1
  210. */
  211. case SYSCTL_CLOCK_SPI0:
  212. case SYSCTL_CLOCK_SPI1:
  213. sysctl->clk_en_cent.apb2_clk_en = en;
  214. break;
  215. default:
  216. break;
  217. }
  218. }
  219. return 0;
  220. }
  221. static int sysctl_clock_device_en(sysctl_clock_t clock, uint8_t en)
  222. {
  223. switch(clock)
  224. {
  225. /*
  226. * These devices are PLL
  227. */
  228. case SYSCTL_CLOCK_PLL0:
  229. sysctl->pll0.pll_out_en0 = en;
  230. break;
  231. case SYSCTL_CLOCK_PLL1:
  232. sysctl->pll1.pll_out_en1 = en;
  233. break;
  234. case SYSCTL_CLOCK_PLL2:
  235. sysctl->pll2.pll_out_en2 = en;
  236. break;
  237. /*
  238. * These devices are CPU, SRAM, APB bus, ROM, DMA, AI
  239. */
  240. case SYSCTL_CLOCK_CPU:
  241. sysctl->clk_en_cent.cpu_clk_en = en;
  242. break;
  243. case SYSCTL_CLOCK_SRAM0:
  244. sysctl->clk_en_cent.sram0_clk_en = en;
  245. break;
  246. case SYSCTL_CLOCK_SRAM1:
  247. sysctl->clk_en_cent.sram1_clk_en = en;
  248. break;
  249. case SYSCTL_CLOCK_APB0:
  250. sysctl->clk_en_cent.apb0_clk_en = en;
  251. break;
  252. case SYSCTL_CLOCK_APB1:
  253. sysctl->clk_en_cent.apb1_clk_en = en;
  254. break;
  255. case SYSCTL_CLOCK_APB2:
  256. sysctl->clk_en_cent.apb2_clk_en = en;
  257. break;
  258. case SYSCTL_CLOCK_ROM:
  259. sysctl->clk_en_peri.rom_clk_en = en;
  260. break;
  261. case SYSCTL_CLOCK_DMA:
  262. sysctl->clk_en_peri.dma_clk_en = en;
  263. break;
  264. case SYSCTL_CLOCK_AI:
  265. sysctl->clk_en_peri.ai_clk_en = en;
  266. break;
  267. case SYSCTL_CLOCK_DVP:
  268. sysctl->clk_en_peri.dvp_clk_en = en;
  269. break;
  270. case SYSCTL_CLOCK_FFT:
  271. sysctl->clk_en_peri.fft_clk_en = en;
  272. break;
  273. case SYSCTL_CLOCK_SPI3:
  274. sysctl->clk_en_peri.spi3_clk_en = en;
  275. break;
  276. /*
  277. * These peripheral devices are under APB0
  278. * GPIO, UART1, UART2, UART3, SPI_SLAVE, I2S0, I2S1,
  279. * I2S2, I2C0, I2C1, I2C2, FPIOA, SHA256, TIMER0,
  280. * TIMER1, TIMER2
  281. */
  282. case SYSCTL_CLOCK_GPIO:
  283. sysctl->clk_en_peri.gpio_clk_en = en;
  284. break;
  285. case SYSCTL_CLOCK_SPI2:
  286. sysctl->clk_en_peri.spi2_clk_en = en;
  287. break;
  288. case SYSCTL_CLOCK_I2S0:
  289. sysctl->clk_en_peri.i2s0_clk_en = en;
  290. break;
  291. case SYSCTL_CLOCK_I2S1:
  292. sysctl->clk_en_peri.i2s1_clk_en = en;
  293. break;
  294. case SYSCTL_CLOCK_I2S2:
  295. sysctl->clk_en_peri.i2s2_clk_en = en;
  296. break;
  297. case SYSCTL_CLOCK_I2C0:
  298. sysctl->clk_en_peri.i2c0_clk_en = en;
  299. break;
  300. case SYSCTL_CLOCK_I2C1:
  301. sysctl->clk_en_peri.i2c1_clk_en = en;
  302. break;
  303. case SYSCTL_CLOCK_I2C2:
  304. sysctl->clk_en_peri.i2c2_clk_en = en;
  305. break;
  306. case SYSCTL_CLOCK_UART1:
  307. sysctl->clk_en_peri.uart1_clk_en = en;
  308. break;
  309. case SYSCTL_CLOCK_UART2:
  310. sysctl->clk_en_peri.uart2_clk_en = en;
  311. break;
  312. case SYSCTL_CLOCK_UART3:
  313. sysctl->clk_en_peri.uart3_clk_en = en;
  314. break;
  315. case SYSCTL_CLOCK_FPIOA:
  316. sysctl->clk_en_peri.fpioa_clk_en = en;
  317. break;
  318. case SYSCTL_CLOCK_TIMER0:
  319. sysctl->clk_en_peri.timer0_clk_en = en;
  320. break;
  321. case SYSCTL_CLOCK_TIMER1:
  322. sysctl->clk_en_peri.timer1_clk_en = en;
  323. break;
  324. case SYSCTL_CLOCK_TIMER2:
  325. sysctl->clk_en_peri.timer2_clk_en = en;
  326. break;
  327. case SYSCTL_CLOCK_SHA:
  328. sysctl->clk_en_peri.sha_clk_en = en;
  329. break;
  330. /*
  331. * These peripheral devices are under APB1
  332. * WDT, AES, OTP, DVP, SYSCTL
  333. */
  334. case SYSCTL_CLOCK_AES:
  335. sysctl->clk_en_peri.aes_clk_en = en;
  336. break;
  337. case SYSCTL_CLOCK_WDT0:
  338. sysctl->clk_en_peri.wdt0_clk_en = en;
  339. break;
  340. case SYSCTL_CLOCK_WDT1:
  341. sysctl->clk_en_peri.wdt1_clk_en = en;
  342. break;
  343. case SYSCTL_CLOCK_OTP:
  344. sysctl->clk_en_peri.otp_clk_en = en;
  345. break;
  346. case SYSCTL_CLOCK_RTC:
  347. sysctl->clk_en_peri.rtc_clk_en = en;
  348. break;
  349. /*
  350. * These peripheral devices are under APB2
  351. * SPI0, SPI1
  352. */
  353. case SYSCTL_CLOCK_SPI0:
  354. sysctl->clk_en_peri.spi0_clk_en = en;
  355. break;
  356. case SYSCTL_CLOCK_SPI1:
  357. sysctl->clk_en_peri.spi1_clk_en = en;
  358. break;
  359. default:
  360. break;
  361. }
  362. return 0;
  363. }
  364. int sysctl_clock_enable(sysctl_clock_t clock)
  365. {
  366. if(clock >= SYSCTL_CLOCK_MAX)
  367. return -1;
  368. sysctl_clock_bus_en(clock, 1);
  369. sysctl_clock_device_en(clock, 1);
  370. return 0;
  371. }
  372. int sysctl_clock_disable(sysctl_clock_t clock)
  373. {
  374. if(clock >= SYSCTL_CLOCK_MAX)
  375. return -1;
  376. sysctl_clock_device_en(clock, 0);
  377. return 0;
  378. }
  379. int sysctl_clock_set_threshold(sysctl_threshold_t which, int threshold)
  380. {
  381. int result = 0;
  382. switch(which)
  383. {
  384. /*
  385. * These threshold is 2 bit width
  386. */
  387. case SYSCTL_THRESHOLD_ACLK:
  388. sysctl->clk_sel0.aclk_divider_sel = (uint8_t)threshold & 0x03;
  389. break;
  390. /*
  391. * These threshold is 3 bit width
  392. */
  393. case SYSCTL_THRESHOLD_APB0:
  394. sysctl->clk_sel0.apb0_clk_sel = (uint8_t)threshold & 0x07;
  395. break;
  396. case SYSCTL_THRESHOLD_APB1:
  397. sysctl->clk_sel0.apb1_clk_sel = (uint8_t)threshold & 0x07;
  398. break;
  399. case SYSCTL_THRESHOLD_APB2:
  400. sysctl->clk_sel0.apb2_clk_sel = (uint8_t)threshold & 0x07;
  401. break;
  402. /*
  403. * These threshold is 4 bit width
  404. */
  405. case SYSCTL_THRESHOLD_SRAM0:
  406. sysctl->clk_th0.sram0_gclk_threshold = (uint8_t)threshold & 0x0F;
  407. break;
  408. case SYSCTL_THRESHOLD_SRAM1:
  409. sysctl->clk_th0.sram1_gclk_threshold = (uint8_t)threshold & 0x0F;
  410. break;
  411. case SYSCTL_THRESHOLD_AI:
  412. sysctl->clk_th0.ai_gclk_threshold = (uint8_t)threshold & 0x0F;
  413. break;
  414. case SYSCTL_THRESHOLD_DVP:
  415. sysctl->clk_th0.dvp_gclk_threshold = (uint8_t)threshold & 0x0F;
  416. break;
  417. case SYSCTL_THRESHOLD_ROM:
  418. sysctl->clk_th0.rom_gclk_threshold = (uint8_t)threshold & 0x0F;
  419. break;
  420. /*
  421. * These threshold is 8 bit width
  422. */
  423. case SYSCTL_THRESHOLD_SPI0:
  424. sysctl->clk_th1.spi0_clk_threshold = (uint8_t)threshold;
  425. break;
  426. case SYSCTL_THRESHOLD_SPI1:
  427. sysctl->clk_th1.spi1_clk_threshold = (uint8_t)threshold;
  428. break;
  429. case SYSCTL_THRESHOLD_SPI2:
  430. sysctl->clk_th1.spi2_clk_threshold = (uint8_t)threshold;
  431. break;
  432. case SYSCTL_THRESHOLD_SPI3:
  433. sysctl->clk_th1.spi3_clk_threshold = (uint8_t)threshold;
  434. break;
  435. case SYSCTL_THRESHOLD_TIMER0:
  436. sysctl->clk_th2.timer0_clk_threshold = (uint8_t)threshold;
  437. break;
  438. case SYSCTL_THRESHOLD_TIMER1:
  439. sysctl->clk_th2.timer1_clk_threshold = (uint8_t)threshold;
  440. break;
  441. case SYSCTL_THRESHOLD_TIMER2:
  442. sysctl->clk_th2.timer2_clk_threshold = (uint8_t)threshold;
  443. break;
  444. case SYSCTL_THRESHOLD_I2S0_M:
  445. sysctl->clk_th4.i2s0_mclk_threshold = (uint8_t)threshold;
  446. break;
  447. case SYSCTL_THRESHOLD_I2S1_M:
  448. sysctl->clk_th4.i2s1_mclk_threshold = (uint8_t)threshold;
  449. break;
  450. case SYSCTL_THRESHOLD_I2S2_M:
  451. sysctl->clk_th5.i2s2_mclk_threshold = (uint8_t)threshold;
  452. break;
  453. case SYSCTL_THRESHOLD_I2C0:
  454. sysctl->clk_th5.i2c0_clk_threshold = (uint8_t)threshold;
  455. break;
  456. case SYSCTL_THRESHOLD_I2C1:
  457. sysctl->clk_th5.i2c1_clk_threshold = (uint8_t)threshold;
  458. break;
  459. case SYSCTL_THRESHOLD_I2C2:
  460. sysctl->clk_th5.i2c2_clk_threshold = (uint8_t)threshold;
  461. break;
  462. case SYSCTL_THRESHOLD_WDT0:
  463. sysctl->clk_th6.wdt0_clk_threshold = (uint8_t)threshold;
  464. break;
  465. case SYSCTL_THRESHOLD_WDT1:
  466. sysctl->clk_th6.wdt1_clk_threshold = (uint8_t)threshold;
  467. break;
  468. /*
  469. * These threshold is 16 bit width
  470. */
  471. case SYSCTL_THRESHOLD_I2S0:
  472. sysctl->clk_th3.i2s0_clk_threshold = (uint16_t)threshold;
  473. break;
  474. case SYSCTL_THRESHOLD_I2S1:
  475. sysctl->clk_th3.i2s1_clk_threshold = (uint16_t)threshold;
  476. break;
  477. case SYSCTL_THRESHOLD_I2S2:
  478. sysctl->clk_th4.i2s2_clk_threshold = (uint16_t)threshold;
  479. break;
  480. default:
  481. result = -1;
  482. break;
  483. }
  484. return result;
  485. }
  486. int sysctl_clock_get_threshold(sysctl_threshold_t which)
  487. {
  488. int threshold = 0;
  489. switch(which)
  490. {
  491. /*
  492. * Select and get threshold value
  493. */
  494. case SYSCTL_THRESHOLD_ACLK:
  495. threshold = (int)sysctl->clk_sel0.aclk_divider_sel;
  496. break;
  497. case SYSCTL_THRESHOLD_APB0:
  498. threshold = (int)sysctl->clk_sel0.apb0_clk_sel;
  499. break;
  500. case SYSCTL_THRESHOLD_APB1:
  501. threshold = (int)sysctl->clk_sel0.apb1_clk_sel;
  502. break;
  503. case SYSCTL_THRESHOLD_APB2:
  504. threshold = (int)sysctl->clk_sel0.apb2_clk_sel;
  505. break;
  506. case SYSCTL_THRESHOLD_SRAM0:
  507. threshold = (int)sysctl->clk_th0.sram0_gclk_threshold;
  508. break;
  509. case SYSCTL_THRESHOLD_SRAM1:
  510. threshold = (int)sysctl->clk_th0.sram1_gclk_threshold;
  511. break;
  512. case SYSCTL_THRESHOLD_AI:
  513. threshold = (int)sysctl->clk_th0.ai_gclk_threshold;
  514. break;
  515. case SYSCTL_THRESHOLD_DVP:
  516. threshold = (int)sysctl->clk_th0.dvp_gclk_threshold;
  517. break;
  518. case SYSCTL_THRESHOLD_ROM:
  519. threshold = (int)sysctl->clk_th0.rom_gclk_threshold;
  520. break;
  521. case SYSCTL_THRESHOLD_SPI0:
  522. threshold = (int)sysctl->clk_th1.spi0_clk_threshold;
  523. break;
  524. case SYSCTL_THRESHOLD_SPI1:
  525. threshold = (int)sysctl->clk_th1.spi1_clk_threshold;
  526. break;
  527. case SYSCTL_THRESHOLD_SPI2:
  528. threshold = (int)sysctl->clk_th1.spi2_clk_threshold;
  529. break;
  530. case SYSCTL_THRESHOLD_SPI3:
  531. threshold = (int)sysctl->clk_th1.spi3_clk_threshold;
  532. break;
  533. case SYSCTL_THRESHOLD_TIMER0:
  534. threshold = (int)sysctl->clk_th2.timer0_clk_threshold;
  535. break;
  536. case SYSCTL_THRESHOLD_TIMER1:
  537. threshold = (int)sysctl->clk_th2.timer1_clk_threshold;
  538. break;
  539. case SYSCTL_THRESHOLD_TIMER2:
  540. threshold = (int)sysctl->clk_th2.timer2_clk_threshold;
  541. break;
  542. case SYSCTL_THRESHOLD_I2S0:
  543. threshold = (int)sysctl->clk_th3.i2s0_clk_threshold;
  544. break;
  545. case SYSCTL_THRESHOLD_I2S1:
  546. threshold = (int)sysctl->clk_th3.i2s1_clk_threshold;
  547. break;
  548. case SYSCTL_THRESHOLD_I2S2:
  549. threshold = (int)sysctl->clk_th4.i2s2_clk_threshold;
  550. break;
  551. case SYSCTL_THRESHOLD_I2S0_M:
  552. threshold = (int)sysctl->clk_th4.i2s0_mclk_threshold;
  553. break;
  554. case SYSCTL_THRESHOLD_I2S1_M:
  555. threshold = (int)sysctl->clk_th4.i2s1_mclk_threshold;
  556. break;
  557. case SYSCTL_THRESHOLD_I2S2_M:
  558. threshold = (int)sysctl->clk_th5.i2s2_mclk_threshold;
  559. break;
  560. case SYSCTL_THRESHOLD_I2C0:
  561. threshold = (int)sysctl->clk_th5.i2c0_clk_threshold;
  562. break;
  563. case SYSCTL_THRESHOLD_I2C1:
  564. threshold = (int)sysctl->clk_th5.i2c1_clk_threshold;
  565. break;
  566. case SYSCTL_THRESHOLD_I2C2:
  567. threshold = (int)sysctl->clk_th5.i2c2_clk_threshold;
  568. break;
  569. case SYSCTL_THRESHOLD_WDT0:
  570. threshold = (int)sysctl->clk_th6.wdt0_clk_threshold;
  571. break;
  572. case SYSCTL_THRESHOLD_WDT1:
  573. threshold = (int)sysctl->clk_th6.wdt1_clk_threshold;
  574. break;
  575. default:
  576. break;
  577. }
  578. return threshold;
  579. }
  580. int sysctl_clock_set_clock_select(sysctl_clock_select_t which, int select)
  581. {
  582. int result = 0;
  583. switch(which)
  584. {
  585. /*
  586. * These clock select is 1 bit width
  587. */
  588. case SYSCTL_CLOCK_SELECT_PLL0_BYPASS:
  589. sysctl->pll0.pll_bypass0 = select & 0x01;
  590. break;
  591. case SYSCTL_CLOCK_SELECT_PLL1_BYPASS:
  592. sysctl->pll1.pll_bypass1 = select & 0x01;
  593. break;
  594. case SYSCTL_CLOCK_SELECT_PLL2_BYPASS:
  595. sysctl->pll2.pll_bypass2 = select & 0x01;
  596. break;
  597. case SYSCTL_CLOCK_SELECT_ACLK:
  598. sysctl->clk_sel0.aclk_sel = select & 0x01;
  599. break;
  600. case SYSCTL_CLOCK_SELECT_SPI3:
  601. sysctl->clk_sel0.spi3_clk_sel = select & 0x01;
  602. break;
  603. case SYSCTL_CLOCK_SELECT_TIMER0:
  604. sysctl->clk_sel0.timer0_clk_sel = select & 0x01;
  605. break;
  606. case SYSCTL_CLOCK_SELECT_TIMER1:
  607. sysctl->clk_sel0.timer1_clk_sel = select & 0x01;
  608. break;
  609. case SYSCTL_CLOCK_SELECT_TIMER2:
  610. sysctl->clk_sel0.timer2_clk_sel = select & 0x01;
  611. break;
  612. case SYSCTL_CLOCK_SELECT_SPI3_SAMPLE:
  613. sysctl->clk_sel1.spi3_sample_clk_sel = select & 0x01;
  614. break;
  615. /*
  616. * These clock select is 2 bit width
  617. */
  618. case SYSCTL_CLOCK_SELECT_PLL2:
  619. sysctl->pll2.pll_ckin_sel2 = select & 0x03;
  620. break;
  621. default:
  622. result = -1;
  623. break;
  624. }
  625. return result;
  626. }
  627. int sysctl_clock_get_clock_select(sysctl_clock_select_t which)
  628. {
  629. int clock_select = 0;
  630. switch(which)
  631. {
  632. /*
  633. * Select and get clock select value
  634. */
  635. case SYSCTL_CLOCK_SELECT_PLL0_BYPASS:
  636. clock_select = (int)sysctl->pll0.pll_bypass0;
  637. break;
  638. case SYSCTL_CLOCK_SELECT_PLL1_BYPASS:
  639. clock_select = (int)sysctl->pll1.pll_bypass1;
  640. break;
  641. case SYSCTL_CLOCK_SELECT_PLL2_BYPASS:
  642. clock_select = (int)sysctl->pll2.pll_bypass2;
  643. break;
  644. case SYSCTL_CLOCK_SELECT_PLL2:
  645. clock_select = (int)sysctl->pll2.pll_ckin_sel2;
  646. break;
  647. case SYSCTL_CLOCK_SELECT_ACLK:
  648. clock_select = (int)sysctl->clk_sel0.aclk_sel;
  649. break;
  650. case SYSCTL_CLOCK_SELECT_SPI3:
  651. clock_select = (int)sysctl->clk_sel0.spi3_clk_sel;
  652. break;
  653. case SYSCTL_CLOCK_SELECT_TIMER0:
  654. clock_select = (int)sysctl->clk_sel0.timer0_clk_sel;
  655. break;
  656. case SYSCTL_CLOCK_SELECT_TIMER1:
  657. clock_select = (int)sysctl->clk_sel0.timer1_clk_sel;
  658. break;
  659. case SYSCTL_CLOCK_SELECT_TIMER2:
  660. clock_select = (int)sysctl->clk_sel0.timer2_clk_sel;
  661. break;
  662. case SYSCTL_CLOCK_SELECT_SPI3_SAMPLE:
  663. clock_select = (int)sysctl->clk_sel1.spi3_sample_clk_sel;
  664. break;
  665. default:
  666. break;
  667. }
  668. return clock_select;
  669. }
  670. uint32_t sysctl_clock_source_get_freq(sysctl_clock_source_t input)
  671. {
  672. uint32_t result;
  673. switch(input)
  674. {
  675. case SYSCTL_SOURCE_IN0:
  676. result = SYSCTRL_CLOCK_FREQ_IN0;
  677. break;
  678. case SYSCTL_SOURCE_PLL0:
  679. result = sysctl_pll_get_freq(SYSCTL_PLL0);
  680. break;
  681. case SYSCTL_SOURCE_PLL1:
  682. result = sysctl_pll_get_freq(SYSCTL_PLL1);
  683. break;
  684. case SYSCTL_SOURCE_PLL2:
  685. result = sysctl_pll_get_freq(SYSCTL_PLL2);
  686. break;
  687. case SYSCTL_SOURCE_ACLK:
  688. result = sysctl_clock_get_freq(SYSCTL_CLOCK_ACLK);
  689. break;
  690. default:
  691. result = 0;
  692. break;
  693. }
  694. return result;
  695. }
  696. static int sysctl_pll_is_lock(sysctl_pll_t pll)
  697. {
  698. /*
  699. * All bit enable means PLL lock
  700. *
  701. * struct pll_lock_t
  702. * {
  703. * uint8_t overflow : 1;
  704. * uint8_t rfslip : 1;
  705. * uint8_t fbslip : 1;
  706. * };
  707. *
  708. */
  709. if(pll >= SYSCTL_PLL_MAX)
  710. return 0;
  711. switch(pll)
  712. {
  713. case SYSCTL_PLL0:
  714. return sysctl->pll_lock.pll_lock0 == 3;
  715. case SYSCTL_PLL1:
  716. return sysctl->pll_lock.pll_lock1 & 1;
  717. case SYSCTL_PLL2:
  718. return sysctl->pll_lock.pll_lock2 & 1;
  719. default:
  720. break;
  721. }
  722. return 0;
  723. }
  724. static int sysctl_pll_clear_slip(sysctl_pll_t pll)
  725. {
  726. if(pll >= SYSCTL_PLL_MAX)
  727. return -1;
  728. switch(pll)
  729. {
  730. case SYSCTL_PLL0:
  731. sysctl->pll_lock.pll_slip_clear0 = 1;
  732. break;
  733. case SYSCTL_PLL1:
  734. sysctl->pll_lock.pll_slip_clear1 = 1;
  735. break;
  736. case SYSCTL_PLL2:
  737. sysctl->pll_lock.pll_slip_clear2 = 1;
  738. break;
  739. default:
  740. break;
  741. }
  742. return sysctl_pll_is_lock(pll) ? 0 : -1;
  743. }
  744. int sysctl_pll_enable(sysctl_pll_t pll)
  745. {
  746. /*
  747. * ---+
  748. * PWRDN |
  749. * +-------------------------------------------------------------
  750. * ^
  751. * |
  752. * |
  753. * t1
  754. * +------------------+
  755. * RESET | |
  756. * ----------+ +-----------------------------------
  757. * ^ ^ ^
  758. * |<----- t_rst ---->|<---------- t_lock ---------->|
  759. * | | |
  760. * t2 t3 t4
  761. */
  762. if(pll >= SYSCTL_PLL_MAX)
  763. return -1;
  764. switch(pll)
  765. {
  766. case SYSCTL_PLL0:
  767. /* Do not bypass PLL */
  768. sysctl->pll0.pll_bypass0 = 0;
  769. /*
  770. * Power on the PLL, negtive from PWRDN
  771. * 0 is power off
  772. * 1 is power on
  773. */
  774. sysctl->pll0.pll_pwrd0 = 1;
  775. /*
  776. * Reset trigger of the PLL, connected RESET
  777. * 0 is free
  778. * 1 is reset
  779. */
  780. sysctl->pll0.pll_reset0 = 0;
  781. sysctl->pll0.pll_reset0 = 1;
  782. asm volatile("nop");
  783. asm volatile("nop");
  784. sysctl->pll0.pll_reset0 = 0;
  785. break;
  786. case SYSCTL_PLL1:
  787. /* Do not bypass PLL */
  788. sysctl->pll1.pll_bypass1 = 0;
  789. /*
  790. * Power on the PLL, negtive from PWRDN
  791. * 0 is power off
  792. * 1 is power on
  793. */
  794. sysctl->pll1.pll_pwrd1 = 1;
  795. /*
  796. * Reset trigger of the PLL, connected RESET
  797. * 0 is free
  798. * 1 is reset
  799. */
  800. sysctl->pll1.pll_reset1 = 0;
  801. sysctl->pll1.pll_reset1 = 1;
  802. asm volatile("nop");
  803. asm volatile("nop");
  804. sysctl->pll1.pll_reset1 = 0;
  805. break;
  806. case SYSCTL_PLL2:
  807. /* Do not bypass PLL */
  808. sysctl->pll2.pll_bypass2 = 0;
  809. /*
  810. * Power on the PLL, negtive from PWRDN
  811. * 0 is power off
  812. * 1 is power on
  813. */
  814. sysctl->pll2.pll_pwrd2 = 1;
  815. /*
  816. * Reset trigger of the PLL, connected RESET
  817. * 0 is free
  818. * 1 is reset
  819. */
  820. sysctl->pll2.pll_reset2 = 0;
  821. sysctl->pll2.pll_reset2 = 1;
  822. asm volatile("nop");
  823. asm volatile("nop");
  824. sysctl->pll2.pll_reset2 = 0;
  825. break;
  826. default:
  827. break;
  828. }
  829. return 0;
  830. }
  831. int sysctl_pll_disable(sysctl_pll_t pll)
  832. {
  833. if(pll >= SYSCTL_PLL_MAX)
  834. return -1;
  835. switch(pll)
  836. {
  837. case SYSCTL_PLL0:
  838. /* Bypass PLL */
  839. sysctl->pll0.pll_bypass0 = 1;
  840. /*
  841. * Power on the PLL, negtive from PWRDN
  842. * 0 is power off
  843. * 1 is power on
  844. */
  845. sysctl->pll0.pll_pwrd0 = 0;
  846. break;
  847. case SYSCTL_PLL1:
  848. /* Bypass PLL */
  849. sysctl->pll1.pll_bypass1 = 1;
  850. /*
  851. * Power on the PLL, negtive from PWRDN
  852. * 0 is power off
  853. * 1 is power on
  854. */
  855. sysctl->pll1.pll_pwrd1 = 0;
  856. break;
  857. case SYSCTL_PLL2:
  858. /* Bypass PLL */
  859. sysctl->pll2.pll_bypass2 = 1;
  860. /*
  861. * Power on the PLL, negtive from PWRDN
  862. * 0 is power off
  863. * 1 is power on
  864. */
  865. sysctl->pll2.pll_pwrd2 = 0;
  866. break;
  867. default:
  868. break;
  869. }
  870. return 0;
  871. }
  872. uint32_t sysctl_pll_get_freq(sysctl_pll_t pll)
  873. {
  874. uint32_t freq_in = 0, freq_out = 0;
  875. uint32_t nr = 0, nf = 0, od = 0;
  876. uint8_t select = 0;
  877. if(pll >= SYSCTL_PLL_MAX)
  878. return 0;
  879. switch(pll)
  880. {
  881. case SYSCTL_PLL0:
  882. freq_in = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  883. nr = sysctl->pll0.clkr0 + 1;
  884. nf = sysctl->pll0.clkf0 + 1;
  885. od = sysctl->pll0.clkod0 + 1;
  886. break;
  887. case SYSCTL_PLL1:
  888. freq_in = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  889. nr = sysctl->pll1.clkr1 + 1;
  890. nf = sysctl->pll1.clkf1 + 1;
  891. od = sysctl->pll1.clkod1 + 1;
  892. break;
  893. case SYSCTL_PLL2:
  894. /*
  895. * Get input freq accroding select register
  896. */
  897. select = sysctl->pll2.pll_ckin_sel2;
  898. if(select < sizeof(get_source_pll2))
  899. freq_in = sysctl_clock_source_get_freq(get_source_pll2[select]);
  900. else
  901. return 0;
  902. nr = sysctl->pll2.clkr2 + 1;
  903. nf = sysctl->pll2.clkf2 + 1;
  904. od = sysctl->pll2.clkod2 + 1;
  905. break;
  906. default:
  907. break;
  908. }
  909. /*
  910. * Get final PLL output freq
  911. * FOUT = FIN / NR * NF / OD
  912. */
  913. freq_out = (double)freq_in / (double)nr * (double)nf / (double)od;
  914. return freq_out;
  915. }
  916. static uint32_t sysctl_pll_source_set_freq(sysctl_pll_t pll, sysctl_clock_source_t source, uint32_t freq)
  917. {
  918. uint32_t freq_in = 0;
  919. if(pll >= SYSCTL_PLL_MAX)
  920. return 0;
  921. if(source >= SYSCTL_SOURCE_MAX)
  922. return 0;
  923. switch(pll)
  924. {
  925. case SYSCTL_PLL0:
  926. case SYSCTL_PLL1:
  927. /*
  928. * Check input clock source
  929. */
  930. if(source != SYSCTL_SOURCE_IN0)
  931. return 0;
  932. freq_in = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  933. /*
  934. * Check input clock freq
  935. */
  936. if(freq_in == 0)
  937. return 0;
  938. break;
  939. case SYSCTL_PLL2:
  940. /*
  941. * Check input clock source
  942. */
  943. if(source < sizeof(get_select_pll2))
  944. freq_in = sysctl_clock_source_get_freq(source);
  945. /*
  946. * Check input clock freq
  947. */
  948. if(freq_in == 0)
  949. return 0;
  950. break;
  951. default:
  952. return 0;
  953. }
  954. /*
  955. * Begin calculate PLL registers' value
  956. */
  957. /* constants */
  958. const double vco_min = 3.5e+08;
  959. const double vco_max = 1.75e+09;
  960. const double ref_min = 1.36719e+07;
  961. const double ref_max = 1.75e+09;
  962. const int nr_min = 1;
  963. const int nr_max = 16;
  964. const int nf_min = 1;
  965. const int nf_max = 64;
  966. const int no_min = 1;
  967. const int no_max = 16;
  968. const int nb_min = 1;
  969. const int nb_max = 64;
  970. const int max_vco = 1;
  971. const int ref_rng = 1;
  972. /* variables */
  973. int nr = 0;
  974. int nrx = 0;
  975. int nf = 0;
  976. int nfi = 0;
  977. int no = 0;
  978. int noe = 0;
  979. int not = 0;
  980. int nor = 0;
  981. int nore = 0;
  982. int nb = 0;
  983. int first = 0;
  984. int firstx = 0;
  985. int found = 0;
  986. long long nfx = 0;
  987. double fin = 0, fout = 0, fvco = 0;
  988. double val = 0, nval = 0, err = 0, merr = 0, terr = 0;
  989. int x_nrx = 0, x_no = 0, x_nb = 0;
  990. long long x_nfx = 0;
  991. double x_fvco = 0, x_err = 0;
  992. fin = freq_in;
  993. fout = freq;
  994. val = fout / fin;
  995. terr = 0.5 / ((double)(nf_max / 2));
  996. first = firstx = 1;
  997. if(terr != -2)
  998. {
  999. first = 0;
  1000. if(terr == 0)
  1001. terr = 1e-16;
  1002. merr = fabs(terr);
  1003. }
  1004. found = 0;
  1005. for(nfi = val; nfi < nf_max; ++nfi)
  1006. {
  1007. nr = rint(((double)nfi) / val);
  1008. if(nr == 0)
  1009. continue;
  1010. if((ref_rng) && (nr < nr_min))
  1011. continue;
  1012. if(fin / ((double)nr) > ref_max)
  1013. continue;
  1014. nrx = nr;
  1015. nf = nfx = nfi;
  1016. nval = ((double)nfx) / ((double)nr);
  1017. if(nf == 0)
  1018. nf = 1;
  1019. err = 1 - nval / val;
  1020. if((first) || (fabs(err) < merr * (1 + 1e-6)) || (fabs(err) < 1e-16))
  1021. {
  1022. not = floor(vco_max / fout);
  1023. for(no = (not > no_max) ? no_max : not; no > no_min; --no)
  1024. {
  1025. if((ref_rng) && ((nr / no) < nr_min))
  1026. continue;
  1027. if((nr % no) == 0)
  1028. break;
  1029. }
  1030. if((nr % no) != 0)
  1031. continue;
  1032. nor = ((not > no_max) ? no_max : not) / no;
  1033. nore = nf_max / nf;
  1034. if(nor > nore)
  1035. nor = nore;
  1036. noe = ceil(vco_min / fout);
  1037. if(!max_vco)
  1038. {
  1039. nore = (noe - 1) / no + 1;
  1040. nor = nore;
  1041. not = 0; /* force next if to fail */
  1042. }
  1043. if((((no * nor) < (not >> 1)) || ((no * nor) < noe)) && ((no * nor) < (nf_max / nf)))
  1044. {
  1045. no = nf_max / nf;
  1046. if(no > no_max)
  1047. no = no_max;
  1048. if(no > not)
  1049. no = not;
  1050. nfx *= no;
  1051. nf *= no;
  1052. if((no > 1) && (!firstx))
  1053. continue;
  1054. /* wait for larger nf in later iterations */
  1055. } else
  1056. {
  1057. nrx /= no;
  1058. nfx *= nor;
  1059. nf *= nor;
  1060. no *= nor;
  1061. if(no > no_max)
  1062. continue;
  1063. if((nor > 1) && (!firstx))
  1064. continue;
  1065. /* wait for larger nf in later iterations */
  1066. }
  1067. nb = nfx;
  1068. if(nb < nb_min)
  1069. nb = nb_min;
  1070. if(nb > nb_max)
  1071. continue;
  1072. fvco = fin / ((double)nrx) * ((double)nfx);
  1073. if(fvco < vco_min)
  1074. continue;
  1075. if(fvco > vco_max)
  1076. continue;
  1077. if(nf < nf_min)
  1078. continue;
  1079. if((ref_rng) && (fin / ((double)nrx) < ref_min))
  1080. continue;
  1081. if((ref_rng) && (nrx > nr_max))
  1082. continue;
  1083. if(!(((firstx) && (terr < 0)) || (fabs(err) < merr * (1 - 1e-6)) || ((max_vco) && (no > x_no))))
  1084. continue;
  1085. if((!firstx) && (terr >= 0) && (nrx > x_nrx))
  1086. continue;
  1087. found = 1;
  1088. x_no = no;
  1089. x_nrx = nrx;
  1090. x_nfx = nfx;
  1091. x_nb = nb;
  1092. x_fvco = fvco;
  1093. x_err = err;
  1094. first = firstx = 0;
  1095. merr = fabs(err);
  1096. if(terr != -1)
  1097. continue;
  1098. }
  1099. }
  1100. if(!found)
  1101. {
  1102. return 0;
  1103. }
  1104. nrx = x_nrx;
  1105. nfx = x_nfx;
  1106. no = x_no;
  1107. nb = x_nb;
  1108. fvco = x_fvco;
  1109. err = x_err;
  1110. if((terr != -2) && (fabs(err) >= terr * (1 - 1e-6)))
  1111. {
  1112. return 0;
  1113. }
  1114. /*
  1115. * Begin write PLL registers' value,
  1116. * Using atomic write method.
  1117. */
  1118. sysctl_pll0_t pll0;
  1119. sysctl_pll1_t pll1;
  1120. sysctl_pll2_t pll2;
  1121. switch(pll)
  1122. {
  1123. case SYSCTL_PLL0:
  1124. /* Read register from bus */
  1125. pll0 = sysctl->pll0;
  1126. /* Set register temporary value */
  1127. pll0.clkr0 = nrx - 1;
  1128. pll0.clkf0 = nfx - 1;
  1129. pll0.clkod0 = no - 1;
  1130. pll0.bwadj0 = nb - 1;
  1131. /* Write register back to bus */
  1132. sysctl->pll0 = pll0;
  1133. break;
  1134. case SYSCTL_PLL1:
  1135. /* Read register from bus */
  1136. pll1 = sysctl->pll1;
  1137. /* Set register temporary value */
  1138. pll1.clkr1 = nrx - 1;
  1139. pll1.clkf1 = nfx - 1;
  1140. pll1.clkod1 = no - 1;
  1141. pll1.bwadj1 = nb - 1;
  1142. /* Write register back to bus */
  1143. sysctl->pll1 = pll1;
  1144. break;
  1145. case SYSCTL_PLL2:
  1146. /* Read register from bus */
  1147. pll2 = sysctl->pll2;
  1148. /* Set register temporary value */
  1149. if(source < sizeof(get_select_pll2))
  1150. pll2.pll_ckin_sel2 = get_select_pll2[source];
  1151. pll2.clkr2 = nrx - 1;
  1152. pll2.clkf2 = nfx - 1;
  1153. pll2.clkod2 = no - 1;
  1154. pll2.bwadj2 = nb - 1;
  1155. /* Write register back to bus */
  1156. sysctl->pll2 = pll2;
  1157. break;
  1158. default:
  1159. return 0;
  1160. }
  1161. return sysctl_pll_get_freq(pll);
  1162. }
  1163. uint32_t sysctl_clock_get_freq(sysctl_clock_t clock)
  1164. {
  1165. uint32_t source = 0;
  1166. uint32_t result = 0;
  1167. switch(clock)
  1168. {
  1169. /*
  1170. * The clock IN0
  1171. */
  1172. case SYSCTL_CLOCK_IN0:
  1173. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  1174. result = source;
  1175. break;
  1176. /*
  1177. * These clock directly under PLL clock domain
  1178. * They are using gated divider.
  1179. */
  1180. case SYSCTL_CLOCK_PLL0:
  1181. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
  1182. result = source;
  1183. break;
  1184. case SYSCTL_CLOCK_PLL1:
  1185. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL1);
  1186. result = source;
  1187. break;
  1188. case SYSCTL_CLOCK_PLL2:
  1189. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL2);
  1190. result = source;
  1191. break;
  1192. /*
  1193. * These clock directly under ACLK clock domain
  1194. */
  1195. case SYSCTL_CLOCK_CPU:
  1196. switch(sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK))
  1197. {
  1198. case 0:
  1199. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  1200. break;
  1201. case 1:
  1202. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) /
  1203. (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK));
  1204. break;
  1205. default:
  1206. break;
  1207. }
  1208. result = source;
  1209. break;
  1210. case SYSCTL_CLOCK_DMA:
  1211. switch(sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK))
  1212. {
  1213. case 0:
  1214. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  1215. break;
  1216. case 1:
  1217. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) /
  1218. (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK));
  1219. break;
  1220. default:
  1221. break;
  1222. }
  1223. result = source;
  1224. break;
  1225. case SYSCTL_CLOCK_FFT:
  1226. switch(sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK))
  1227. {
  1228. case 0:
  1229. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  1230. break;
  1231. case 1:
  1232. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) /
  1233. (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK));
  1234. break;
  1235. default:
  1236. break;
  1237. }
  1238. result = source;
  1239. break;
  1240. case SYSCTL_CLOCK_ACLK:
  1241. switch(sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK))
  1242. {
  1243. case 0:
  1244. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  1245. break;
  1246. case 1:
  1247. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) /
  1248. (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK));
  1249. break;
  1250. default:
  1251. break;
  1252. }
  1253. result = source;
  1254. break;
  1255. case SYSCTL_CLOCK_HCLK:
  1256. switch(sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK))
  1257. {
  1258. case 0:
  1259. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  1260. break;
  1261. case 1:
  1262. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) /
  1263. (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK));
  1264. break;
  1265. default:
  1266. break;
  1267. }
  1268. result = source;
  1269. break;
  1270. /*
  1271. * These clock under ACLK clock domain.
  1272. * They are using gated divider.
  1273. */
  1274. case SYSCTL_CLOCK_SRAM0:
  1275. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK);
  1276. result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SRAM0) + 1);
  1277. break;
  1278. case SYSCTL_CLOCK_SRAM1:
  1279. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK);
  1280. result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SRAM1) + 1);
  1281. break;
  1282. case SYSCTL_CLOCK_ROM:
  1283. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK);
  1284. result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ROM) + 1);
  1285. break;
  1286. case SYSCTL_CLOCK_DVP:
  1287. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK);
  1288. result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_DVP) + 1);
  1289. break;
  1290. /*
  1291. * These clock under ACLK clock domain.
  1292. * They are using even divider.
  1293. */
  1294. case SYSCTL_CLOCK_APB0:
  1295. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK);
  1296. result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_APB0) + 1);
  1297. break;
  1298. case SYSCTL_CLOCK_APB1:
  1299. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK);
  1300. result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_APB1) + 1);
  1301. break;
  1302. case SYSCTL_CLOCK_APB2:
  1303. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK);
  1304. result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_APB2) + 1);
  1305. break;
  1306. /*
  1307. * These clock under AI clock domain.
  1308. * They are using gated divider.
  1309. */
  1310. case SYSCTL_CLOCK_AI:
  1311. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL1);
  1312. result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_AI) + 1);
  1313. break;
  1314. /*
  1315. * These clock under I2S clock domain.
  1316. * They are using even divider.
  1317. */
  1318. case SYSCTL_CLOCK_I2S0:
  1319. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL2);
  1320. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2S0) + 1) * 2);
  1321. break;
  1322. case SYSCTL_CLOCK_I2S1:
  1323. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL2);
  1324. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2S1) + 1) * 2);
  1325. break;
  1326. case SYSCTL_CLOCK_I2S2:
  1327. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL2);
  1328. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2S2) + 1) * 2);
  1329. break;
  1330. /*
  1331. * These clock under WDT clock domain.
  1332. * They are using even divider.
  1333. */
  1334. case SYSCTL_CLOCK_WDT0:
  1335. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  1336. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_WDT0) + 1) * 2);
  1337. break;
  1338. case SYSCTL_CLOCK_WDT1:
  1339. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  1340. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_WDT1) + 1) * 2);
  1341. break;
  1342. /*
  1343. * These clock under PLL0 clock domain.
  1344. * They are using even divider.
  1345. */
  1346. case SYSCTL_CLOCK_SPI0:
  1347. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
  1348. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SPI0) + 1) * 2);
  1349. break;
  1350. case SYSCTL_CLOCK_SPI1:
  1351. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
  1352. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SPI1) + 1) * 2);
  1353. break;
  1354. case SYSCTL_CLOCK_SPI2:
  1355. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
  1356. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SPI2) + 1) * 2);
  1357. break;
  1358. case SYSCTL_CLOCK_I2C0:
  1359. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
  1360. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2C0) + 1) * 2);
  1361. break;
  1362. case SYSCTL_CLOCK_I2C1:
  1363. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
  1364. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2C1) + 1) * 2);
  1365. break;
  1366. case SYSCTL_CLOCK_I2C2:
  1367. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
  1368. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2C2) + 1) * 2);
  1369. break;
  1370. /*
  1371. * These clock under PLL0_SEL clock domain.
  1372. * They are using even divider.
  1373. */
  1374. case SYSCTL_CLOCK_SPI3:
  1375. switch(sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_SPI3))
  1376. {
  1377. case 0:
  1378. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  1379. break;
  1380. case 1:
  1381. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
  1382. break;
  1383. default:
  1384. break;
  1385. }
  1386. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SPI3) + 1) * 2);
  1387. break;
  1388. case SYSCTL_CLOCK_TIMER0:
  1389. switch(sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_TIMER0))
  1390. {
  1391. case 0:
  1392. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  1393. break;
  1394. case 1:
  1395. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
  1396. break;
  1397. default:
  1398. break;
  1399. }
  1400. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_TIMER0) + 1) * 2);
  1401. break;
  1402. case SYSCTL_CLOCK_TIMER1:
  1403. switch(sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_TIMER1))
  1404. {
  1405. case 0:
  1406. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  1407. break;
  1408. case 1:
  1409. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
  1410. break;
  1411. default:
  1412. break;
  1413. }
  1414. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_TIMER1) + 1) * 2);
  1415. break;
  1416. case SYSCTL_CLOCK_TIMER2:
  1417. switch(sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_TIMER2))
  1418. {
  1419. case 0:
  1420. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  1421. break;
  1422. case 1:
  1423. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0);
  1424. break;
  1425. default:
  1426. break;
  1427. }
  1428. result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_TIMER2) + 1) * 2);
  1429. break;
  1430. /*
  1431. * These clock under MISC clock domain.
  1432. * They are using even divider.
  1433. */
  1434. /*
  1435. * These clock under APB0 clock domain.
  1436. * They are using even divider.
  1437. */
  1438. case SYSCTL_CLOCK_GPIO:
  1439. source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
  1440. result = source;
  1441. break;
  1442. case SYSCTL_CLOCK_UART1:
  1443. source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
  1444. result = source;
  1445. break;
  1446. case SYSCTL_CLOCK_UART2:
  1447. source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
  1448. result = source;
  1449. break;
  1450. case SYSCTL_CLOCK_UART3:
  1451. source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
  1452. result = source;
  1453. break;
  1454. case SYSCTL_CLOCK_FPIOA:
  1455. source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
  1456. result = source;
  1457. break;
  1458. case SYSCTL_CLOCK_SHA:
  1459. source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
  1460. result = source;
  1461. break;
  1462. /*
  1463. * These clock under APB1 clock domain.
  1464. * They are using even divider.
  1465. */
  1466. case SYSCTL_CLOCK_AES:
  1467. source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB1);
  1468. result = source;
  1469. break;
  1470. case SYSCTL_CLOCK_OTP:
  1471. source = sysctl_clock_get_freq(SYSCTL_CLOCK_APB1);
  1472. result = source;
  1473. break;
  1474. case SYSCTL_CLOCK_RTC:
  1475. source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0);
  1476. result = source;
  1477. break;
  1478. /*
  1479. * These clock under APB2 clock domain.
  1480. * They are using even divider.
  1481. */
  1482. /*
  1483. * Do nothing.
  1484. */
  1485. default:
  1486. break;
  1487. }
  1488. return result;
  1489. }
  1490. int sysctl_dma_select(sysctl_dma_channel_t channel, sysctl_dma_select_t select)
  1491. {
  1492. sysctl_dma_sel0_t dma_sel0;
  1493. sysctl_dma_sel1_t dma_sel1;
  1494. /* Read register from bus */
  1495. dma_sel0 = sysctl->dma_sel0;
  1496. dma_sel1 = sysctl->dma_sel1;
  1497. switch(channel)
  1498. {
  1499. case SYSCTL_DMA_CHANNEL_0:
  1500. dma_sel0.dma_sel0 = select;
  1501. break;
  1502. case SYSCTL_DMA_CHANNEL_1:
  1503. dma_sel0.dma_sel1 = select;
  1504. break;
  1505. case SYSCTL_DMA_CHANNEL_2:
  1506. dma_sel0.dma_sel2 = select;
  1507. break;
  1508. case SYSCTL_DMA_CHANNEL_3:
  1509. dma_sel0.dma_sel3 = select;
  1510. break;
  1511. case SYSCTL_DMA_CHANNEL_4:
  1512. dma_sel0.dma_sel4 = select;
  1513. break;
  1514. case SYSCTL_DMA_CHANNEL_5:
  1515. dma_sel1.dma_sel5 = select;
  1516. break;
  1517. default:
  1518. return -1;
  1519. }
  1520. /* Write register back to bus */
  1521. sysctl->dma_sel0 = dma_sel0;
  1522. sysctl->dma_sel1 = dma_sel1;
  1523. return 0;
  1524. }
  1525. uint32_t sysctl_pll_fast_enable_pll(void)
  1526. {
  1527. /*
  1528. * Begin write PLL registers' value,
  1529. * Using atomic write method.
  1530. */
  1531. sysctl_pll0_t pll0;
  1532. sysctl_pll1_t pll1;
  1533. sysctl_pll2_t pll2;
  1534. /* Read register from bus */
  1535. pll0 = sysctl->pll0;
  1536. pll1 = sysctl->pll1;
  1537. pll2 = sysctl->pll2;
  1538. /* PLL VCO MAX freq: 1.8GHz */
  1539. /* PLL0: 26M reference clk get 793M output clock */
  1540. pll0.clkr0 = 0;
  1541. pll0.clkf0 = 60;
  1542. pll0.clkod0 = 1;
  1543. pll0.bwadj0 = 60;
  1544. /* PLL1: 26M reference clk get 390M output clock */
  1545. pll1.clkr1 = 0;
  1546. pll1.clkf1 = 59;
  1547. pll1.clkod1 = 3;
  1548. pll1.bwadj1 = 59;
  1549. /* PLL2: 26M reference clk get 390M output clock */
  1550. pll2.clkr2 = 0;
  1551. pll2.clkf2 = 59;
  1552. pll2.clkod2 = 3;
  1553. pll2.bwadj2 = 59;
  1554. /* Write register to bus */
  1555. sysctl->pll0 = pll0;
  1556. sysctl->pll1 = pll1;
  1557. sysctl->pll2 = pll2;
  1558. sysctl_pll_enable(SYSCTL_PLL0);
  1559. sysctl_pll_enable(SYSCTL_PLL1);
  1560. sysctl_pll_enable(SYSCTL_PLL2);
  1561. while(sysctl_pll_is_lock(SYSCTL_PLL0) == 0)
  1562. sysctl_pll_clear_slip(SYSCTL_PLL0);
  1563. while(sysctl_pll_is_lock(SYSCTL_PLL1) == 0)
  1564. sysctl_pll_clear_slip(SYSCTL_PLL1);
  1565. while(sysctl_pll_is_lock(SYSCTL_PLL2) == 0)
  1566. sysctl_pll_clear_slip(SYSCTL_PLL2);
  1567. sysctl_clock_enable(SYSCTL_CLOCK_PLL0);
  1568. sysctl_clock_enable(SYSCTL_CLOCK_PLL1);
  1569. sysctl_clock_enable(SYSCTL_CLOCK_PLL2);
  1570. /* Set ACLK to PLL0 */
  1571. sysctl_clock_set_clock_select(SYSCTL_CLOCK_SELECT_ACLK, SYSCTL_SOURCE_PLL0);
  1572. return 0;
  1573. }
  1574. uint32_t sysctl_set_spi0_dvp_data(uint8_t en)
  1575. {
  1576. sysctl->misc.spi_dvp_data_enable = en;
  1577. return 0;
  1578. }
  1579. void sysctl_set_power_mode(sysctl_power_bank_t power_bank, sysctl_io_power_mode_t io_power_mode)
  1580. {
  1581. if(io_power_mode)
  1582. *((uint32_t *)(&sysctl->power_sel)) |= (1 << power_bank);
  1583. else
  1584. *((uint32_t *)(&sysctl->power_sel)) &= ~(1 << power_bank);
  1585. }
  1586. uint32_t sysctl_pll_set_freq(sysctl_pll_t pll, uint32_t pll_freq)
  1587. {
  1588. if(pll_freq == 0)
  1589. return 0;
  1590. volatile sysctl_general_pll_t *v_pll_t;
  1591. switch(pll)
  1592. {
  1593. case SYSCTL_PLL0:
  1594. v_pll_t = (sysctl_general_pll_t *)(&sysctl->pll0);
  1595. break;
  1596. case SYSCTL_PLL1:
  1597. v_pll_t = (sysctl_general_pll_t *)(&sysctl->pll1);
  1598. break;
  1599. case SYSCTL_PLL2:
  1600. v_pll_t = (sysctl_general_pll_t *)(&sysctl->pll2);
  1601. break;
  1602. default:
  1603. return 0;
  1604. break;
  1605. }
  1606. /* 1. Change CPU CLK to XTAL */
  1607. if(pll == SYSCTL_PLL0)
  1608. sysctl_clock_set_clock_select(SYSCTL_CLOCK_SELECT_ACLK, SYSCTL_SOURCE_IN0);
  1609. /* 2. Disable PLL output */
  1610. v_pll_t->pll_out_en = 0;
  1611. /* 3. Turn off PLL */
  1612. v_pll_t->pll_pwrd = 0;
  1613. /* 4. Set PLL new value */
  1614. uint32_t result;
  1615. if(pll == SYSCTL_PLL2)
  1616. result = sysctl_pll_source_set_freq(pll, v_pll_t->pll_ckin_sel, pll_freq);
  1617. else
  1618. result = sysctl_pll_source_set_freq(pll, SYSCTL_SOURCE_IN0, pll_freq);
  1619. /* 5. Power on PLL */
  1620. v_pll_t->pll_pwrd = 1;
  1621. /* wait >100ns */
  1622. usleep(1);
  1623. /* 6. Reset PLL then Release Reset*/
  1624. v_pll_t->pll_reset = 0;
  1625. v_pll_t->pll_reset = 1;
  1626. /* wait >100ns */
  1627. usleep(1);
  1628. v_pll_t->pll_reset = 0;
  1629. /* 7. Get lock status, wait PLL stable */
  1630. while(sysctl_pll_is_lock(pll) == 0)
  1631. sysctl_pll_clear_slip(pll);
  1632. /* 8. Enable PLL output */
  1633. v_pll_t->pll_out_en = 1;
  1634. /* 9. Change CPU CLK to PLL */
  1635. if(pll == SYSCTL_PLL0)
  1636. {
  1637. sysctl_clock_set_clock_select(SYSCTL_CLOCK_SELECT_ACLK, SYSCTL_SOURCE_PLL0);
  1638. uart_debug_init(-1);
  1639. }
  1640. return result;
  1641. }
  1642. static uint32_t cpu_freq = 390000000;
  1643. uint32_t sysctl_cpu_get_freq(void)
  1644. {
  1645. return cpu_freq;
  1646. }
  1647. uint32_t sysctl_cpu_set_freq(uint32_t freq)
  1648. {
  1649. if(freq == 0)
  1650. return 0;
  1651. cpu_freq = sysctl_pll_set_freq(SYSCTL_PLL0, (sysctl->clk_sel0.aclk_divider_sel + 1) * 2 * freq);
  1652. return cpu_freq;
  1653. }
  1654. void sysctl_enable_irq(void)
  1655. {
  1656. set_csr(mie, MIP_MEIP);
  1657. set_csr(mstatus, MSTATUS_MIE);
  1658. }
  1659. void sysctl_disable_irq(void)
  1660. {
  1661. clear_csr(mie, MIP_MEIP);
  1662. clear_csr(mstatus, MSTATUS_MIE);
  1663. }
  1664. uint64_t sysctl_get_time_us(void)
  1665. {
  1666. uint64_t v_cycle = read_cycle();
  1667. return v_cycle * 1000000 / sysctl_clock_get_freq(SYSCTL_CLOCK_CPU);
  1668. }
  1669. sysctl_reset_enum_status_t sysctl_get_reset_status(void)
  1670. {
  1671. static sysctl_reset_enum_status_t s_reset_status = 0;
  1672. if(s_reset_status != 0)
  1673. {
  1674. return s_reset_status;
  1675. }
  1676. if(sysctl->reset_status.wdt0_reset_sts)
  1677. {
  1678. s_reset_status = SYSCTL_RESET_STATUS_WDT0;
  1679. } else if(sysctl->reset_status.wdt1_reset_sts)
  1680. {
  1681. s_reset_status = SYSCTL_RESET_STATUS_WDT1;
  1682. } else if(sysctl->reset_status.soft_reset_sts)
  1683. {
  1684. s_reset_status = SYSCTL_RESET_STATUS_SOFT;
  1685. } else
  1686. {
  1687. s_reset_status = SYSCTL_RESET_STATUS_HARD;
  1688. }
  1689. sysctl->reset_status.reset_sts_clr = 1;
  1690. return s_reset_status;
  1691. }