soc_sleep.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. /*
  2. * Copyright (c) 2019 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file soc_sleep.c sleep for Actions SoC
  8. */
  9. #include <zephyr.h>
  10. #include <soc.h>
  11. #include <arch/arm/aarch32/cortex_m/cmsis.h>
  12. #include <string.h>
  13. #include <drivers/timer/system_timer.h>
  14. #include <linker/linker-defs.h>
  15. #if 0
  16. #define MEM_S2_ITEM_MAX 10
  17. struct mem_backup {
  18. void *buf;
  19. uint32_t len;
  20. };
  21. /* COREPLL RW fields range from 0 t0 7 */
  22. //static uint32_t ram_power_backup;
  23. /* Save and restore the registers */
  24. static const uint32_t backup_regs_addr[] = {
  25. CMU_SPI0CLK,
  26. PMUADC_CTL,
  27. CMU_MEMCLKEN0,
  28. CMU_MEMCLKEN1,
  29. NVIC_ISER0,
  30. NVIC_ISER1,
  31. PWRGATE_DIG,
  32. };
  33. #define GPION_CTL(n) (GPIO_REG_BASE+4+(n)*4)
  34. /*gpio36-48, GPIO0-3 ,6,7 handle in sleep fun*/
  35. /*gpio not use int sleep*/
  36. static const uint32_t backup_regs_gpio[] = {
  37. /*misc */
  38. //GPION_CTL(4), /*not use defaut highz*/
  39. //GPION_CTL(22), /*not use defaut highz*/
  40. //GPION_CTL(23), /*not use defaut highz*/
  41. /*spinand */
  42. GPION_CTL(8),
  43. GPION_CTL(9),
  44. GPION_CTL(10),
  45. GPION_CTL(11),
  46. GPION_CTL(12),
  47. GPION_CTL(13),
  48. //GPION_CTL(64), /*power enable, use in sleep*/
  49. /*LCD */
  50. //GPION_CTL(5), /*lcd backlight enable*/
  51. GPION_CTL(14),
  52. GPION_CTL(15),
  53. GPION_CTL(16),
  54. GPION_CTL(17),
  55. GPION_CTL(30),
  56. GPION_CTL(34),
  57. GPION_CTL(35),
  58. /*sensor*/
  59. //GPION_CTL(18), /*not use defaut highz*/
  60. //GPION_CTL(19), /*EN_NTC. user in sleep*/
  61. //GPION_CTL(20), /*not use defaut highz*/
  62. //GPION_CTL(21), /*sensor irq ,use in sleep*/
  63. //GPION_CTL(24), /* HR_PWR_EN ,use in sleep*/
  64. //GPION_CTL(25) /*VDD1.8 eanble ,use in sleep*/
  65. /*TP*/
  66. //GPION_CTL(26), /*not use defaut highz*/
  67. //GPION_CTL(27), /*not use,defaut highz*/
  68. /*debug uart0 */
  69. //GPION_CTL(28), /*use in sleep*/
  70. //GPION_CTL(29), /*use in sleep*/
  71. };
  72. #define SP_IN_SLEEP (CONFIG_SRAM_BASE_ADDRESS+CONFIG_SRAM_SIZE*1024 - 4)
  73. #define SRAM_SAVE_BASE_ADDR ((uint32_t)(&__kernel_ram_start))
  74. #define SRAM_SAVE_END_ADDR ((uint32_t)(&__kernel_ram_save_end))
  75. #define SRAM_SAVE_LEN (SRAM_SAVE_END_ADDR - SRAM_SAVE_BASE_ADDR)
  76. #define SENSOR_CODE_MAX_LEN (SP_IN_SLEEP - SRAM_SAVE_BASE_ADDR-1024) /*1024 is for sp*/
  77. #define PSRAM_SAVE_MAXLEN 0x10000
  78. static uint32_t psram_bak_sram[PSRAM_SAVE_MAXLEN/4];
  79. static uint32_t psram_check_sum;
  80. static void *sensor_code_addr;
  81. static uint32_t sensor_code_len;
  82. int sleep_sensor_code_set(void *code_addr, uint32_t code_len)
  83. {
  84. printk("sensor code:base=0x%x, maxlen=0x%x, code_len=0x%x\n",
  85. SRAM_SAVE_BASE_ADDR, SENSOR_CODE_MAX_LEN, code_len);
  86. if((code_addr == NULL) || (code_len > SENSOR_CODE_MAX_LEN)){
  87. printk("sensor code invalid\n");
  88. return -1;
  89. }
  90. sensor_code_addr = code_addr;
  91. sensor_code_len = code_len;
  92. return 0;
  93. }
  94. static uint32_t check_sum(uint32_t *buf, int len)
  95. {
  96. int i;
  97. uint32_t chk = 0;
  98. for(i = 0; i < (len/4); i++)
  99. chk += buf[i];
  100. return chk;
  101. }
  102. static void suspend_check(void)
  103. {
  104. uint32_t chk;
  105. chk = check_sum((uint32_t *)psram_bak_sram, PSRAM_SAVE_MAXLEN);
  106. printk("psram suspend chk=0x%x\n", chk);
  107. psram_check_sum = chk;
  108. }
  109. static void wakeup_check(void)
  110. {
  111. uint32_t chk;
  112. chk = check_sum((uint32_t *)psram_bak_sram, PSRAM_SAVE_MAXLEN);
  113. printk("psram wakeup chk=0x%x, save=0x%x\n", chk, psram_check_sum);
  114. if(psram_check_sum != chk)
  115. printk("-------error psram check-----------\n");
  116. }
  117. static void mem_sram_save_to_psram(void)
  118. {
  119. memcpy(psram_bak_sram, (void*)SRAM_SAVE_BASE_ADDR, SRAM_SAVE_LEN);
  120. printk("save addr=0x%x len=0x%x\n", SRAM_SAVE_BASE_ADDR, SRAM_SAVE_LEN);
  121. suspend_check();
  122. if((sensor_code_addr != NULL) && sensor_code_len){
  123. printk("copy sensor code 0x%x to sram\n", sensor_code_len);
  124. memcpy((void*)SRAM_SAVE_BASE_ADDR, sensor_code_addr, sensor_code_len);
  125. }else{
  126. printk("set sram base=0x%x, L=0x%x\n", SRAM_SAVE_BASE_ADDR, SENSOR_CODE_MAX_LEN);
  127. memset((void*)SRAM_SAVE_BASE_ADDR, 0, SENSOR_CODE_MAX_LEN);
  128. }
  129. }
  130. static void mem_psram_recovery_tosram(void)
  131. {
  132. memcpy((void*)SRAM_SAVE_BASE_ADDR, psram_bak_sram, SRAM_SAVE_LEN);
  133. wakeup_check();
  134. }
  135. struct sleep_wk_data {
  136. uint16_t wksrc;
  137. uint16_t wk_en_bit;
  138. const char *wksrc_msg;
  139. };
  140. struct sleep_wk_cb {
  141. sleep_wk_callback_t wk_cb;
  142. enum S_WK_SRC_TYPE src;
  143. };
  144. const struct sleep_wk_data wk_msg[] = {
  145. {SLEEP_WK_SRC_BT, IRQ_ID_BT, "BT" },
  146. {SLEEP_WK_SRC_GPIO, IRQ_ID_GPIO, "GPIO" },
  147. {SLEEP_WK_SRC_PMU, IRQ_ID_PMU, "PMU" },
  148. {SLEEP_WK_SRC_T0, IRQ_ID_TIMER0, "T0" },
  149. {SLEEP_WK_SRC_T1, IRQ_ID_TIMER1, "T1" },
  150. {SLEEP_WK_SRC_T2, IRQ_ID_TIMER2, "T2" },
  151. {SLEEP_WK_SRC_T3, IRQ_ID_TIMER3, "T3" },
  152. {SLEEP_WK_SRC_TWS, IRQ_ID_TWS, "TWS" },
  153. {SLEEP_WK_SRC_SPI0MT, IRQ_ID_SPI0MT, "SPI0MT" },
  154. {SLEEP_WK_SRC_SPI1MT, IRQ_ID_SPI1MT, "SPI1MT" },
  155. {SLEEP_WK_SRC_IIC0MT, IRQ_ID_IIC0MT, "IIC0MT" },
  156. {SLEEP_WK_SRC_IIC1MT, IRQ_ID_IIC1MT, "IIC1MT" },
  157. };
  158. #define SLEEP_WKSRC_NUM ARRAY_SIZE(wk_msg)
  159. static struct sleep_wk_fun_data __act_s2_sleep_data *g_wk_fun[SLEEP_WKSRC_NUM] ;
  160. static volatile uint16_t __act_s2_sleep_data g_sleep_wksrc_en;
  161. static volatile uint32_t __act_s2_sleep_data g_sleep_cycle, g_wk_cnt;
  162. static enum S_WK_SRC_TYPE g_sleep_wksrc_src;
  163. int sleep_register_wk_callback(enum S_WK_SRC_TYPE wk_src, struct sleep_wk_fun_data *fn_data)
  164. {
  165. if(fn_data == NULL)
  166. return -1;
  167. fn_data->next = g_wk_fun[wk_src];
  168. g_wk_fun[wk_src] = fn_data;
  169. return 0;
  170. }
  171. void sys_s3_wksrc_set(enum S_WK_SRC_TYPE src)
  172. {
  173. g_sleep_wksrc_en |= (1 << src);
  174. }
  175. enum S_WK_SRC_TYPE sys_s3_wksrc_get(void)
  176. {
  177. return g_sleep_wksrc_src;
  178. }
  179. static enum S_WK_SRC_TYPE sys_sleep_check_wksrc(void)
  180. {
  181. int i;
  182. uint32_t wk_pd0, wk_pd1,wkbit;
  183. g_sleep_wksrc_src = 0;
  184. wk_pd0 = sys_read32(NVIC_ISPR0);
  185. wk_pd1 = sys_read32(NVIC_ISPR1);
  186. //printk("WK NVIC_ISPR0=0x%x\n", wk_pd0);
  187. //printk("WK NVIC_ISPR1=0x%x\n", wk_pd1);
  188. for(i = 0; i < SLEEP_WKSRC_NUM; i++){
  189. if((1<<wk_msg[i].wksrc) & g_sleep_wksrc_en){
  190. wkbit = wk_msg[i].wk_en_bit;
  191. if(wkbit >= 32){
  192. wkbit -= 32;
  193. if(wk_pd1 & (1<<wkbit))
  194. break;
  195. }else{
  196. if(wk_pd0 & (1<<wkbit))
  197. break;
  198. }
  199. }
  200. }
  201. if(i != SLEEP_WKSRC_NUM){
  202. g_sleep_wksrc_src = wk_msg[i].wksrc;
  203. printk("wksrc=%s\n", wk_msg[i].wksrc_msg);
  204. }else{
  205. printk("no wksrc\n");
  206. g_sleep_wksrc_src = 0;
  207. }
  208. return g_sleep_wksrc_src;
  209. }
  210. static void sys_set_wksrc_before_sleep(void)
  211. {
  212. int i;
  213. uint32_t wk_en0, wk_en1;
  214. //printk("NVIC_ISPR0-1=0x%x,0x%x\n", sys_read32(NVIC_ISPR0), sys_read32(NVIC_ISPR1));
  215. //printk("NVIC_ISER0-1=0x%x,0x%x\n", sys_read32(NVIC_ISER0), sys_read32(NVIC_ISER1));
  216. //printk("NVIC_IABR0-1=0x%x,0x%x\n", sys_read32(NVIC_IABR0), sys_read32(NVIC_IABR1));
  217. //printk("g_sleep_wksrc_en =0x%x\n", g_sleep_wksrc_en);
  218. sys_write32(sys_read32(NVIC_ISER0), NVIC_ICER0);
  219. sys_write32(sys_read32(NVIC_ISER1), NVIC_ICER1);
  220. sys_write32(0xffffffff, NVIC_ICPR0);
  221. sys_write32(0xffffffff, NVIC_ICPR1);
  222. if(g_sleep_wksrc_en){
  223. wk_en0 = wk_en1 = 0;
  224. for(i = 0; i < SLEEP_WKSRC_NUM; i++){
  225. if((1 << wk_msg[i].wksrc) & g_sleep_wksrc_en){
  226. printk("%d wksrc=%s \n",i, wk_msg[i].wksrc_msg);
  227. if(wk_msg[i].wk_en_bit >= 32){
  228. wk_en1 |= 1 << (wk_msg[i].wk_en_bit-32);
  229. }else{
  230. wk_en0 |= 1 << (wk_msg[i].wk_en_bit);
  231. }
  232. }
  233. }
  234. if(wk_en0)
  235. sys_write32(wk_en0, NVIC_ISER0);
  236. if(wk_en1)
  237. sys_write32(wk_en1, NVIC_ISER1);
  238. }
  239. //printk("NVIC_ISPR0-1=0x%x,0x%x\n", sys_read32(NVIC_ISPR0), sys_read32(NVIC_ISPR1));
  240. //printk("NVIC_ISER0-1=0x%x,0x%x\n", sys_read32(NVIC_ISER0), sys_read32(NVIC_ISER1));
  241. //printk("NVIC_IABR0-1=0x%x,0x%x\n", sys_read32(NVIC_IABR0), sys_read32(NVIC_IABR1));
  242. }
  243. static uint32_t s2_reg_backups[ARRAY_SIZE(backup_regs_addr)];
  244. static uint32_t s2_gpio_reg_backups[ARRAY_SIZE(backup_regs_gpio)];
  245. static void sys_pm_backup_registers(void)
  246. {
  247. int i;
  248. for (i = 0; i < ARRAY_SIZE(backup_regs_gpio); i++){ // set gpio highz
  249. s2_gpio_reg_backups[i] = sys_read32(backup_regs_gpio[i]);
  250. sys_write32(0x1000, backup_regs_gpio[i]);
  251. }
  252. for (i = 0; i < ARRAY_SIZE(backup_regs_addr); i++)
  253. s2_reg_backups[i] = sys_read32(backup_regs_addr[i]);
  254. }
  255. static void sys_pm_restore_registers(void)
  256. {
  257. int i;
  258. for (i = ARRAY_SIZE(backup_regs_gpio) - 1; i >= 0; i--)
  259. sys_write32(s2_gpio_reg_backups[i], backup_regs_gpio[i]);
  260. for (i = ARRAY_SIZE(backup_regs_addr) - 1; i >= 0; i--)
  261. sys_write32(s2_reg_backups[i], backup_regs_addr[i]);
  262. }
  263. void dump_reg(const char *promt)
  264. {
  265. #if 0
  266. int i;
  267. for (i = 0; i < 77 ; i++)// nor pin
  268. printk("gpio%d=0x%x\n", i, sys_read32(GPION_CTL(i)));
  269. printk("RMU_MRCR0=0x%x\n", sys_read32(RMU_MRCR0));
  270. printk("RMU_MRCR1=0x%x\n", sys_read32(RMU_MRCR1));
  271. printk("CMU_DEVCLKEN0=0x%x\n", sys_read32(CMU_DEVCLKEN0));
  272. printk("CMU_DEVCLKEN1=0x%x\n", sys_read32(CMU_DEVCLKEN1));
  273. printk("PMU_DET=0x%x\n", sys_read32(PMU_DET));
  274. printk("NVIC_ISPR0=0x%x\n", sys_read32(NVIC_ISPR0));
  275. printk("NVIC_ISPR1=0x%x\n", sys_read32(NVIC_ISPR1));
  276. printk("CMU_MEMCLKEN0=0x%x\n", sys_read32(CMU_MEMCLKEN0));
  277. printk("CMU_MEMCLKEN1=0x%x\n", sys_read32(CMU_MEMCLKEN1));
  278. printk("CMU_MEMCLKSRC0=0x%x\n", sys_read32(CMU_MEMCLKSRC0));
  279. printk("CMU_MEMCLKSRC1=0x%x\n", sys_read32(CMU_MEMCLKSRC1));
  280. printk("PWRGATE_DIG=0x%x\n", sys_read32(PWRGATE_DIG));
  281. printk("VOUT_CTL1_S2=0x%x\n", sys_read32(VOUT_CTL1_S2));
  282. printk("VOUT_CTL1_S3=0x%x\n", sys_read32(VOUT_CTL1_S3));
  283. printk("PWRGATE_RAM=0x%x\n", sys_read32(PWRGATE_RAM));
  284. printk("WIO0_CTL=0x%x\n", sys_read32(WIO0_CTL));
  285. printk("WIO1_CTL=0x%x\n", sys_read32(WIO1_CTL));
  286. printk("WIO2_CTL=0x%x\n", sys_read32(WIO2_CTL));
  287. printk("WIO3_CTL=0x%x\n", sys_read32(WIO3_CTL));
  288. #endif
  289. }
  290. void powergate_prepare_sleep(int isdeep)
  291. {
  292. /*
  293. RMU_MRCR0=0x1b0d5fb1
  294. RMU_MRCR1=0xc10c000c
  295. CMU_DEVCLKEN0=0x5b0413b1
  296. CMU_DEVCLKEN1=0x1f0c000c bit24-28 is bt
  297. */
  298. sys_write32(0x0, PMUADC_CTL);
  299. //PWRGATE_DIG bit20-aduio bit21-de/se/usb bit25-adncdsp bit26-audiodsp bit27-bt-f bit28-btp
  300. if(isdeep){
  301. sys_write32(0x90000000, PWRGATE_DIG); // m4f/bt on else off
  302. }else{
  303. sys_write32(0x88000000, PWRGATE_DIG); //m4f on, bt off else off
  304. }
  305. }
  306. void powergate_prepare_wakeup(void)
  307. {
  308. }
  309. static void soc_cmu_sleep_prepare(int isdeep)
  310. {
  311. sys_pm_backup_registers();
  312. powergate_prepare_sleep(isdeep);
  313. SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk ; // deepsleep
  314. /*spi0 clk switch to hosc*/
  315. sys_write32(0x0, CMU_SPI0CLK);
  316. sys_write32(0x0, CMU_GPIOCLKCTL); //select gpio clk RC32K
  317. sys_set_wksrc_before_sleep();
  318. }
  319. #if defined(CONFIG_BOARD_NANDBOOT) || !defined(CONFIG_SPI_FLASH_ACTS)
  320. void sys_norflash_power_ctrl(uint32_t is_powerdown)
  321. {
  322. }
  323. #else
  324. extern void sys_norflash_power_ctrl(uint32_t is_powerdown);
  325. #endif
  326. #ifdef CONFIG_DISABLE_IRQ_STAT
  327. static inline unsigned int n_irq_lock(void)
  328. {
  329. unsigned int key;
  330. unsigned int tmp;
  331. __asm__ volatile(
  332. "mov %1, %2;"
  333. "mrs %0, BASEPRI;"
  334. "msr BASEPRI, %1;"
  335. "isb;"
  336. : "=r"(key), "=r"(tmp)
  337. : "i"(_EXC_IRQ_DEFAULT_PRIO)
  338. : "memory");
  339. return key;
  340. }
  341. static inline void n_irq_unlock(unsigned int key)
  342. {
  343. __asm__ volatile(
  344. "msr BASEPRI, %0;"
  345. "isb;"
  346. : : "r"(key) : "memory");
  347. }
  348. #endif
  349. __sleepfunc uint32_t sleep_get_cycle(void)
  350. {
  351. return sys_read32(T2_CNT)+g_sleep_cycle;
  352. }
  353. __sleepfunc static void __cpu_enter_sleep(int isdeep)
  354. {
  355. #if 1
  356. volatile int loop;
  357. uint32_t corepll_backup, st, end, sysclk_bak;
  358. uint32_t gpio_nor[6];/*gpio0-3, gpio6-7*/
  359. //jtag_enable();
  360. /*bak nor gpio */
  361. for(st = 0; st < 4; st++) {
  362. gpio_nor[st] = sys_read32(GPION_CTL(st));
  363. sys_write32(0x1000, GPION_CTL(st));
  364. }
  365. gpio_nor[st++] = sys_read32(GPION_CTL(6));
  366. gpio_nor[st++] = sys_read32(GPION_CTL(7));
  367. sys_write32(0x1000, GPION_CTL(6));
  368. sys_write32(0x1000, GPION_CTL(7));
  369. sys_write32(0x4, CMU_TIMER2CLK); //select rc32k before enter S3
  370. st = sys_read32(T2_CNT);
  371. sysclk_bak = sys_read32(CMU_SYSCLK);
  372. corepll_backup = sys_read32(COREPLL_CTL);
  373. sys_write32(0x0, CMU_SYSCLK); /*cpu clk select rc4M*/
  374. sys_write32(sys_read32(COREPLL_CTL) & ~(1 << 7), COREPLL_CTL);
  375. sys_write32(0, COREPLL_CTL);
  376. /*spi0 cache disable*/
  377. sys_clear_bit(SPICACHE_CTL, 0); //bit0 disable spi 0 cache
  378. sys_clear_bit(AVDDLDO_CTL, 0); /*disable avdd, corepll use must enable*/
  379. loop=100;
  380. while(loop)loop--;
  381. /*enter sleep*/
  382. __asm__ volatile("cpsid i");
  383. #ifdef CONFIG_DISABLE_IRQ_STAT
  384. n_irq_unlock(0);
  385. #else
  386. irq_unlock(0);
  387. #endif
  388. __asm__ volatile("dsb");
  389. __asm__ volatile("wfi");
  390. #ifdef CONFIG_DISABLE_IRQ_STAT
  391. n_irq_lock();
  392. #else
  393. irq_lock();
  394. #endif
  395. __asm__ volatile("cpsie i");
  396. sys_set_bit(AVDDLDO_CTL, 0); /*enable avdd, for pll*/
  397. loop=300;
  398. while(loop)loop--; /*for avdd*/
  399. /*spi0 cache enable*/
  400. sys_set_bit(SPICACHE_CTL, 0); //enable spi 0 cache
  401. sys_write32(corepll_backup, COREPLL_CTL);
  402. sys_write32(0x0, CMU_SPI0CLK);// hosc
  403. end = sys_read32(T2_CNT);
  404. st = end-st-1;
  405. sys_write32(0x0, CMU_TIMER2CLK); //select hosc for k_cycle_get
  406. g_sleep_cycle += st*(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC/32768);
  407. sys_write32(sysclk_bak, CMU_SYSCLK);
  408. /*recovery nor gpio */
  409. for(st = 0; st < 4; st++) {
  410. sys_write32(gpio_nor[st], GPION_CTL(st));
  411. }
  412. sys_write32(gpio_nor[st++], GPION_CTL(6));
  413. sys_write32(gpio_nor[st++] , GPION_CTL(7));
  414. #else
  415. k_busy_wait(2000000); //wati 2s
  416. #endif
  417. }
  418. static inline void set_PSP(unsigned int p_sp)
  419. {
  420. __asm__ volatile(
  421. "msr psp, %0;"
  422. : : "r"(p_sp) : "memory");
  423. }
  424. __sleepfunc static enum WK_CB_RC check_wk_run_sram_nor(uint16_t *wk_en_bit,
  425. struct sleep_wk_cb *cb, int *cb_num)
  426. {
  427. int i;
  428. enum WK_CB_RC rc = WK_CB_SLEEP_AGAIN;
  429. enum WK_RUN_TYPE runt;
  430. uint32_t wk_pd0, wk_pd1,wkbit;
  431. bool b_nor_wk = false;
  432. struct sleep_wk_fun_data *p;
  433. wk_pd0 = sys_read32(NVIC_ISPR0);
  434. wk_pd1 = sys_read32(NVIC_ISPR1);
  435. *cb_num = 0;
  436. for(i = 0; i < SLEEP_WKSRC_NUM; i++){
  437. if(!((1 << i) & g_sleep_wksrc_en))
  438. continue;
  439. wkbit = wk_en_bit[i];
  440. if(wkbit >= 32){
  441. wkbit -= 32;
  442. if(!(wk_pd1 & (1<<wkbit)))
  443. continue;
  444. }else{
  445. if(!(wk_pd0 & (1<<wkbit)))
  446. continue;
  447. }
  448. if(g_wk_fun[i]){
  449. p = g_wk_fun[i];
  450. do{
  451. if(p->wk_prep){
  452. runt = p->wk_prep(i);//
  453. if(runt == WK_RUN_IN_SRAM){
  454. if(WK_CB_RUN_SYSTEM == p->wk_cb(i)) //要求唤醒到系统继续运行
  455. rc = WK_CB_RUN_SYSTEM;
  456. }else if (runt == WK_RUN_IN_NOR) {// 唤醒nor 跑
  457. if(!b_nor_wk){//nor 退出idle
  458. b_nor_wk = true;
  459. sys_norflash_power_ctrl(0);
  460. }
  461. if(WK_CB_RUN_SYSTEM == p->wk_cb(i)) //要求唤醒到系统继续运行
  462. rc = WK_CB_RUN_SYSTEM;
  463. }else{
  464. rc = WK_CB_RUN_SYSTEM; /*系统跑*/
  465. if(*cb_num < SLEEP_WKSRC_NUM){
  466. cb[*cb_num].wk_cb = p->wk_cb;
  467. cb[*cb_num].src = i;
  468. (*cb_num)++;
  469. }
  470. }
  471. }else{
  472. rc = WK_CB_RUN_SYSTEM; /*系统跑*/
  473. if(*cb_num < SLEEP_WKSRC_NUM){
  474. cb[*cb_num].wk_cb = p->wk_cb;
  475. cb[*cb_num].src = i;
  476. (*cb_num)++;
  477. }
  478. }
  479. p = p->next;
  480. }while(p);
  481. }else{
  482. rc = WK_CB_RUN_SYSTEM; /*not wake up callback , sytem handle*/
  483. }
  484. }
  485. if(rc == WK_CB_SLEEP_AGAIN){
  486. sys_write32(0xffffffff, NVIC_ICPR0);
  487. sys_write32(0xffffffff, NVIC_ICPR1);
  488. if(b_nor_wk){ // 如果继续休眠,但是nor已经退出idle,重新进idle
  489. sys_norflash_power_ctrl(1);
  490. }
  491. }else{
  492. if(!b_nor_wk){// 如果系统跑,还没有退出idle,退出idle
  493. sys_norflash_power_ctrl(0);
  494. }
  495. }
  496. return rc;
  497. }
  498. static struct sleep_wk_cb g_syste_cb[SLEEP_WKSRC_NUM];
  499. static int g_num_cb;
  500. __sleepfunc static void cpu_enter_sleep_tmp(int isdeep)
  501. {
  502. unsigned int i, num_cb;
  503. uint16_t wk_en_bit[SLEEP_WKSRC_NUM];
  504. struct sleep_wk_cb cb[SLEEP_WKSRC_NUM];
  505. uint32_t bk_clksrc0;
  506. uint32_t gpio_psram[13];/*gpio36-48*/
  507. mem_sram_save_to_psram();
  508. for(i = 0; i < SLEEP_WKSRC_NUM; i++) // copy nor to sram, nor is not use for wake first
  509. wk_en_bit[i] = wk_msg[i].wk_en_bit;
  510. sys_norflash_power_ctrl(1);/*nor enter deep power down */
  511. g_wk_cnt = 0;
  512. while(1) {
  513. //RAM4 shareRAM select RC4MHZ in s2)
  514. bk_clksrc0 = sys_read32(CMU_MEMCLKSRC0);
  515. sys_write32((bk_clksrc0 & (~0x3ff)) | (0x0<<5), CMU_MEMCLKSRC0);
  516. for(i = 0; i < 13; i++){ //bak psram pin and set highz
  517. gpio_psram[i] = sys_read32(GPION_CTL(i+36));
  518. sys_write32(0x1000, GPION_CTL(i+36));
  519. }
  520. sys_clear_bit(SPI1_CACHE_CTL, 0); //bit0 disable spi 1 cache
  521. __cpu_enter_sleep(isdeep);
  522. for(i = 0; i < 13; i++){ // recovery psram pin
  523. sys_write32(gpio_psram[i], GPION_CTL(i+36));
  524. }
  525. sys_set_bit(SPI1_CACHE_CTL, 0); //bit0 enable spi 1 cache
  526. sys_write32(bk_clksrc0, CMU_MEMCLKSRC0); // recovery
  527. g_wk_cnt++;
  528. if(WK_CB_RUN_SYSTEM == check_wk_run_sram_nor(wk_en_bit, cb, &num_cb))
  529. break;
  530. }
  531. g_num_cb = num_cb;
  532. memcpy(g_syste_cb, cb, num_cb*sizeof(struct sleep_wk_cb));
  533. mem_psram_recovery_tosram();
  534. }
  535. static void cpu_enter_sleep(int isdeep)
  536. {
  537. static unsigned int sp;
  538. sp = __get_PSP();
  539. set_PSP(SP_IN_SLEEP); //change sp to sram top
  540. cpu_enter_sleep_tmp(isdeep);
  541. set_PSP(sp); // recovery sp
  542. }
  543. static void wakeup_system_callback(void)
  544. {
  545. int i;
  546. for(i = 0; i < g_num_cb; i++){
  547. g_syste_cb[i].wk_cb(g_syste_cb[i].src);
  548. }
  549. g_num_cb = 0;
  550. }
  551. static void soc_cmu_sleep_exit(void)
  552. {
  553. SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk ;
  554. powergate_prepare_wakeup();
  555. sys_pm_restore_registers();
  556. sys_write32(0x1, CMU_GPIOCLKCTL); //select gpio clk RC4M
  557. }
  558. static void soc_pmu_onoff_wk_set(void)
  559. {
  560. //sys_write32(0x301, WIO0_CTL); // onoff
  561. sys_write32(0x3, WIO0_CTL);
  562. sys_write32(sys_read32(PMU_INTMASK) | (1<<1), PMU_INTMASK); //ONOFF SHORT WAKEUP
  563. k_busy_wait(300);
  564. printk("PMUINTMASK=0X%X\n", sys_read32(PMU_INTMASK));
  565. sys_s3_wksrc_set(SLEEP_WK_SRC_PMU);
  566. }
  567. static int check_exit_deep_sleep(void)
  568. {
  569. uint32_t wksrc;
  570. wksrc = sys_sleep_check_wksrc();
  571. //if(wksrc == 0){
  572. //return check_exit_by_wio();
  573. //}
  574. return 1;
  575. }
  576. #ifdef CONFIG_BOARD_LARK_DVB_EARPHONE
  577. #define soc_enter_sleep_switch_uart(x) NULL
  578. #else
  579. static const struct acts_pin_config bt_pin_cfg_uart[] = {
  580. {28, 23 | GPIO_CTL_PADDRV_LEVEL(1) | GPIO_CTL_PULLUP},
  581. {29, 23 | GPIO_CTL_PADDRV_LEVEL(1) | GPIO_CTL_PULLUP},
  582. };
  583. static const struct acts_pin_config lark_pin_cfg_uart[] = {
  584. {28, 5 | GPIO_CTL_PADDRV_LEVEL(1) | GPIO_CTL_PULLUP},
  585. {29, 5 | GPIO_CTL_PADDRV_LEVEL(1) | GPIO_CTL_PULLUP},
  586. };
  587. static void soc_enter_sleep_switch_uart(bool bt_uart)
  588. {
  589. if (bt_uart) {
  590. acts_pinmux_setup_pins(bt_pin_cfg_uart, ARRAY_SIZE(bt_pin_cfg_uart));
  591. } else {
  592. acts_pinmux_setup_pins(lark_pin_cfg_uart, ARRAY_SIZE(lark_pin_cfg_uart));
  593. }
  594. }
  595. #endif
  596. void soc_enter_deep_sleep(void)
  597. {
  598. unsigned int cyc ,end;
  599. sys_clock_set_timeout(CONFIG_SYS_CLOCK_TICKS_PER_SEC, false);
  600. sys_s3_wksrc_set(SLEEP_WK_SRC_BT);
  601. dump_reg("before");
  602. soc_pmu_onoff_wk_set();
  603. soc_cmu_sleep_prepare(1);
  604. cyc = sleep_get_cycle();
  605. soc_enter_sleep_switch_uart(true);
  606. cpu_enter_sleep(1);//wfi,enter to sleep
  607. soc_enter_sleep_switch_uart(false);
  608. end = sleep_get_cycle();
  609. printk("\n\n---sleep %d ms--cnt=%d--\n", k_cyc_to_ms_ceil32(end-cyc), g_wk_cnt);
  610. soc_cmu_sleep_exit();
  611. check_exit_deep_sleep();
  612. dump_reg("BT after");
  613. wakeup_system_callback();
  614. }
  615. void soc_enter_light_sleep(void)
  616. {
  617. sys_clock_set_timeout(CONFIG_SYS_CLOCK_TICKS_PER_SEC*5, false);
  618. dump_reg("before");
  619. soc_cmu_sleep_prepare(0);
  620. cpu_enter_sleep(0);//wfi,enter to sleep
  621. soc_cmu_sleep_exit();
  622. dump_reg("after");
  623. }
  624. static int soc_sleep_init(const struct device *arg)
  625. {
  626. int i;
  627. g_sleep_cycle = 0;
  628. g_sleep_wksrc_en = 0;
  629. printk("g_sleep_wksrc_en =0x%x\n", g_sleep_wksrc_en);
  630. for(i = 0; i < SLEEP_WKSRC_NUM; i++)
  631. g_wk_fun[i] = NULL;
  632. return 0;
  633. }
  634. SYS_INIT(soc_sleep_init, PRE_KERNEL_1, 20);
  635. #else
  636. void soc_enter_deep_sleep(void)
  637. {
  638. }
  639. #endif