apd_context.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. /*
  2. * Copyright 2021-2024 NXP
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <stdbool.h>
  8. #include <drivers/delay_timer.h>
  9. #include <lib/mmio.h>
  10. #include <plat_imx8.h>
  11. #include <xrdc.h>
  12. #define PCC_PR BIT(31)
  13. #define PFD_VALID_MASK U(0x40404040)
  14. #define S400_MU_BASE U(0x27020000)
  15. #define S400_MU_RSR (S400_MU_BASE + 0x12c)
  16. #define S400_MU_TRx(i) (S400_MU_BASE + 0x200 + (i) * 4)
  17. #define S400_MU_RRx(i) (S400_MU_BASE + 0x280 + (i) * 4)
  18. /*
  19. * need to re-init the PLL, CGC1, PCC, CMC, XRDC, SIM, GPIO etc.
  20. * init the PLL &PFD first, then switch the CA35 clock to PLL for
  21. * performance consideration, restore other bus fabric clock.
  22. */
  23. extern void imx8ulp_caam_init(void);
  24. extern void upower_wait_resp(void);
  25. extern void dram_enter_retention(void);
  26. extern void dram_exit_retention(void);
  27. struct plat_gic_ctx imx_gicv3_ctx;
  28. static uint32_t cmc1_pmprot;
  29. static uint32_t cmc1_srie;
  30. /* TPM5: global timer */
  31. static uint32_t tpm5[3];
  32. static uint32_t wdog3[2];
  33. /* CGC1 PLL2 */
  34. uint32_t pll2[][2] = {
  35. {0x292c0510, 0x0}, {0x292c0518, 0x0}, {0x292c051c, 0x0},
  36. {0x292c0520, 0x0}, {0x292c0500, 0x0},
  37. };
  38. /* CGC1 PLL3 */
  39. uint32_t pll3[][2] = {
  40. {0x292c0604, 0x0}, {0x292c0608, 0x0}, {0x292c060c, 0x0},
  41. {0x292c0610, 0x0}, {0x292c0618, 0x0}, {0x292c061c, 0x0},
  42. {0x292c0620, 0x0}, {0x292c0624, 0x0}, {0x292c0600, 0x0},
  43. {0x292c0614, 0x0},
  44. };
  45. /* CGC1 others */
  46. uint32_t cgc1[][2] = {
  47. {0x292c0014, 0x0}, {0x292c0034, 0x0}, {0x292c0038, 0x0},
  48. {0x292c0108, 0x0}, {0x292c0208, 0x0}, {0x292c0700, 0x0},
  49. {0x292c0810, 0x0}, {0x292c0900, 0x0}, {0x292c0904, 0x0},
  50. {0x292c0908, 0x0}, {0x292c090c, 0x0}, {0x292c0a00, 0x0},
  51. };
  52. static uint32_t pcc3[61];
  53. static uint32_t pcc4[32];
  54. static uint32_t pcc5_0[33];
  55. static uint32_t pcc5_1[][2] = {
  56. {0x2da70084, 0x0}, {0x2da70088, 0x0}, {0x2da7008c, 0x0},
  57. {0x2da700a0, 0x0}, {0x2da700a4, 0x0}, {0x2da700a8, 0x0},
  58. {0x2da700ac, 0x0}, {0x2da700b0, 0x0}, {0x2da700b4, 0x0},
  59. {0x2da700bc, 0x0}, {0x2da700c0, 0x0}, {0x2da700c8, 0x0},
  60. {0x2da700cc, 0x0}, {0x2da700d0, 0x0}, {0x2da700f0, 0x0},
  61. {0x2da700f4, 0x0}, {0x2da700f8, 0x0}, {0x2da70108, 0x0},
  62. {0x2da7010c, 0x0}, {0x2da70110, 0x0}, {0x2da70114, 0x0},
  63. };
  64. static uint32_t cgc2[][2] = {
  65. {0x2da60014, 0x0}, {0x2da60020, 0x0}, {0x2da6003c, 0x0},
  66. {0x2da60040, 0x0}, {0x2da60108, 0x0}, {0x2da60208, 0x0},
  67. {0x2da60900, 0x0}, {0x2da60904, 0x0}, {0x2da60908, 0x0},
  68. {0x2da60910, 0x0}, {0x2da60a00, 0x0},
  69. };
  70. static uint32_t pll4[][2] = {
  71. {0x2da60604, 0x0}, {0x2da60608, 0x0}, {0x2da6060c, 0x0},
  72. {0x2da60610, 0x0}, {0x2da60618, 0x0}, {0x2da6061c, 0x0},
  73. {0x2da60620, 0x0}, {0x2da60624, 0x0}, {0x2da60600, 0x0},
  74. {0x2da60614, 0x0},
  75. };
  76. static uint32_t lpav_sim[][2] = {
  77. {0x2da50000, 0x0}, {0x2da50004, 0x0}, {0x2da50008, 0x0},
  78. {0x2da5001c, 0x0}, {0x2da50020, 0x0}, {0x2da50024, 0x0},
  79. {0x2da50034, 0x0},
  80. };
  81. #define APD_GPIO_CTRL_NUM 2
  82. #define LPAV_GPIO_CTRL_NUM 1
  83. #define GPIO_CTRL_REG_NUM 8
  84. #define GPIO_PIN_MAX_NUM 32
  85. #define GPIO_CTX(addr, num) \
  86. {.base = (addr), .pin_num = (num), }
  87. struct gpio_ctx {
  88. /* gpio base */
  89. uintptr_t base;
  90. /* port control */
  91. uint32_t port_ctrl[GPIO_CTRL_REG_NUM];
  92. /* GPIO ICR, Max 32 */
  93. uint32_t pin_num;
  94. uint32_t gpio_icr[GPIO_PIN_MAX_NUM];
  95. };
  96. static uint32_t gpio_ctrl_offset[GPIO_CTRL_REG_NUM] = {
  97. 0xc, 0x10, 0x14, 0x18, 0x1c, 0x40, 0x54, 0x58
  98. };
  99. static struct gpio_ctx apd_gpio_ctx[APD_GPIO_CTRL_NUM] = {
  100. GPIO_CTX(IMX_GPIOE_BASE, 24),
  101. GPIO_CTX(IMX_GPIOF_BASE, 32),
  102. };
  103. static struct gpio_ctx lpav_gpio_ctx = GPIO_CTX(IMX_GPIOD_BASE, 24);
  104. /* iomuxc setting */
  105. #define IOMUXC_SECTION_NUM 8
  106. struct iomuxc_section {
  107. uint32_t offset;
  108. uint32_t reg_num;
  109. };
  110. struct iomuxc_section iomuxc_sections[IOMUXC_SECTION_NUM] = {
  111. {.offset = IOMUXC_PTD_PCR_BASE, .reg_num = 24},
  112. {.offset = IOMUXC_PTE_PCR_BASE, .reg_num = 24},
  113. {.offset = IOMUXC_PTF_PCR_BASE, .reg_num = 32},
  114. {.offset = IOMUXC_PSMI_BASE0, .reg_num = 10},
  115. {.offset = IOMUXC_PSMI_BASE1, .reg_num = 61},
  116. {.offset = IOMUXC_PSMI_BASE2, .reg_num = 12},
  117. {.offset = IOMUXC_PSMI_BASE3, .reg_num = 20},
  118. {.offset = IOMUXC_PSMI_BASE4, .reg_num = 75},
  119. };
  120. static uint32_t iomuxc_ctx[258];
  121. #define PORTS_NUM 3U
  122. void apd_io_pad_off(void)
  123. {
  124. unsigned int i, j;
  125. /* off the PTD/E/F, need to be customized based on actual user case */
  126. for (i = 0; i < PORTS_NUM; i++) {
  127. for (j = 0; j < iomuxc_sections[i].reg_num; j++) {
  128. mmio_write_32(iomuxc_sections[i].offset + j * 4, 0);
  129. }
  130. }
  131. /* disable the PTD compensation */
  132. mmio_write_32(IMX_SIM1_BASE + 0x48, 0x800);
  133. }
  134. void iomuxc_save(void)
  135. {
  136. unsigned int i, j;
  137. unsigned int index = 0U;
  138. for (i = 0U; i < IOMUXC_SECTION_NUM; i++) {
  139. for (j = 0U; j < iomuxc_sections[i].reg_num; j++) {
  140. iomuxc_ctx[index++] = mmio_read_32(iomuxc_sections[i].offset + j * 4);
  141. }
  142. }
  143. apd_io_pad_off();
  144. }
  145. void iomuxc_restore(void)
  146. {
  147. unsigned int i, j;
  148. unsigned int index = 0U;
  149. for (i = 0U; i < IOMUXC_SECTION_NUM; i++) {
  150. for (j = 0U; j < iomuxc_sections[i].reg_num; j++) {
  151. mmio_write_32(iomuxc_sections[i].offset + j * 4, iomuxc_ctx[index++]);
  152. }
  153. }
  154. }
  155. void gpio_save(struct gpio_ctx *ctx, int port_num)
  156. {
  157. unsigned int i, j;
  158. for (i = 0U; i < port_num; i++) {
  159. /* save the port control setting */
  160. for (j = 0U; j < GPIO_CTRL_REG_NUM; j++) {
  161. if (j < 4U) {
  162. ctx->port_ctrl[j] = mmio_read_32(ctx->base + gpio_ctrl_offset[j]);
  163. /*
  164. * clear the permission setting to read the GPIO
  165. * non-secure world setting.
  166. */
  167. mmio_write_32(ctx->base + gpio_ctrl_offset[j], 0x0);
  168. } else {
  169. ctx->port_ctrl[j] = mmio_read_32(ctx->base + gpio_ctrl_offset[j]);
  170. }
  171. }
  172. /* save the gpio icr setting */
  173. for (j = 0U; j < ctx->pin_num; j++) {
  174. ctx->gpio_icr[j] = mmio_read_32(ctx->base + 0x80 + j * 4);
  175. }
  176. ctx++;
  177. }
  178. }
  179. void gpio_restore(struct gpio_ctx *ctx, int port_num)
  180. {
  181. unsigned int i, j;
  182. for (i = 0U; i < port_num; i++) {
  183. for (j = 0U; j < ctx->pin_num; j++)
  184. mmio_write_32(ctx->base + 0x80 + j * 4, ctx->gpio_icr[j]);
  185. for (j = 4U; j < GPIO_CTRL_REG_NUM; j++) {
  186. mmio_write_32(ctx->base + gpio_ctrl_offset[j], ctx->port_ctrl[j]);
  187. }
  188. /* permission config retore last */
  189. for (j = 0U; j < 4; j++) {
  190. mmio_write_32(ctx->base + gpio_ctrl_offset[j], ctx->port_ctrl[j]);
  191. }
  192. ctx++;
  193. }
  194. }
  195. void cgc1_save(void)
  196. {
  197. unsigned int i;
  198. /* PLL2 */
  199. for (i = 0U; i < ARRAY_SIZE(pll2); i++) {
  200. pll2[i][1] = mmio_read_32(pll2[i][0]);
  201. }
  202. /* PLL3 */
  203. for (i = 0U; i < ARRAY_SIZE(pll3); i++) {
  204. pll3[i][1] = mmio_read_32(pll3[i][0]);
  205. }
  206. /* CGC1 others */
  207. for (i = 0U; i < ARRAY_SIZE(cgc1); i++) {
  208. cgc1[i][1] = mmio_read_32(cgc1[i][0]);
  209. }
  210. }
  211. void cgc1_restore(void)
  212. {
  213. unsigned int i;
  214. /* PLL2 */
  215. for (i = 0U; i < ARRAY_SIZE(pll2); i++) {
  216. mmio_write_32(pll2[i][0], pll2[i][1]);
  217. }
  218. /* wait for PLL2 lock */
  219. while (!(mmio_read_32(pll2[4][0]) & BIT(24))) {
  220. ;
  221. }
  222. /* PLL3 */
  223. for (i = 0U; i < 9U; i++) {
  224. mmio_write_32(pll3[i][0], pll3[i][1]);
  225. }
  226. /* wait for PLL3 lock */
  227. while (!(mmio_read_32(pll3[4][0]) & BIT(24))) {
  228. ;
  229. }
  230. /* restore the PFDs */
  231. mmio_write_32(pll3[9][0], pll3[9][1] & ~(BIT(31) | BIT(23) | BIT(15) | BIT(7)));
  232. mmio_write_32(pll3[9][0], pll3[9][1]);
  233. /* wait for the PFD is stable, only need to check the enabled PFDs */
  234. while (!(mmio_read_32(pll3[9][0]) & PFD_VALID_MASK)) {
  235. ;
  236. }
  237. /* CGC1 others */
  238. for (i = 0U; i < ARRAY_SIZE(cgc1); i++) {
  239. mmio_write_32(cgc1[i][0], cgc1[i][1]);
  240. }
  241. }
  242. void tpm5_save(void)
  243. {
  244. tpm5[0] = mmio_read_32(IMX_TPM5_BASE + 0x10);
  245. tpm5[1] = mmio_read_32(IMX_TPM5_BASE + 0x18);
  246. tpm5[2] = mmio_read_32(IMX_TPM5_BASE + 0x20);
  247. }
  248. void tpm5_restore(void)
  249. {
  250. mmio_write_32(IMX_TPM5_BASE + 0x10, tpm5[0]);
  251. mmio_write_32(IMX_TPM5_BASE + 0x18, tpm5[1]);
  252. mmio_write_32(IMX_TPM5_BASE + 0x20, tpm5[2]);
  253. }
  254. void wdog3_save(void)
  255. {
  256. /* enable wdog3 clock */
  257. mmio_write_32(IMX_PCC3_BASE + 0xa8, 0xd2800000);
  258. /* save the CS & TOVAL regiter */
  259. wdog3[0] = mmio_read_32(IMX_WDOG3_BASE);
  260. wdog3[1] = mmio_read_32(IMX_WDOG3_BASE + 0x8);
  261. }
  262. void wdog3_restore(void)
  263. {
  264. /* enable wdog3 clock */
  265. mmio_write_32(IMX_PCC3_BASE + 0xa8, 0xd2800000);
  266. /* reconfig the CS */
  267. mmio_write_32(IMX_WDOG3_BASE, wdog3[0]);
  268. /* set the tiemout value */
  269. mmio_write_32(IMX_WDOG3_BASE + 0x8, wdog3[1]);
  270. /* wait for the lock status */
  271. while ((mmio_read_32(IMX_WDOG3_BASE) & BIT(11))) {
  272. ;
  273. }
  274. /* wait for the config done */
  275. while (!(mmio_read_32(IMX_WDOG3_BASE) & BIT(10))) {
  276. ;
  277. }
  278. }
  279. static uint32_t lpuart_regs[4];
  280. #define LPUART_BAUD 0x10
  281. #define LPUART_CTRL 0x18
  282. #define LPUART_FIFO 0x28
  283. #define LPUART_WATER 0x2c
  284. void lpuart_save(void)
  285. {
  286. lpuart_regs[0] = mmio_read_32(IMX_LPUART5_BASE + LPUART_BAUD);
  287. lpuart_regs[1] = mmio_read_32(IMX_LPUART5_BASE + LPUART_FIFO);
  288. lpuart_regs[2] = mmio_read_32(IMX_LPUART5_BASE + LPUART_WATER);
  289. lpuart_regs[3] = mmio_read_32(IMX_LPUART5_BASE + LPUART_CTRL);
  290. }
  291. void lpuart_restore(void)
  292. {
  293. mmio_write_32(IMX_LPUART5_BASE + LPUART_BAUD, lpuart_regs[0]);
  294. mmio_write_32(IMX_LPUART5_BASE + LPUART_FIFO, lpuart_regs[1]);
  295. mmio_write_32(IMX_LPUART5_BASE + LPUART_WATER, lpuart_regs[2]);
  296. mmio_write_32(IMX_LPUART5_BASE + LPUART_CTRL, lpuart_regs[3]);
  297. }
  298. bool is_lpav_owned_by_apd(void)
  299. {
  300. return (mmio_read_32(0x2802b044) & BIT(7)) ? true : false;
  301. }
  302. void lpav_ctx_save(void)
  303. {
  304. unsigned int i;
  305. uint32_t val;
  306. /* CGC2 save */
  307. for (i = 0U; i < ARRAY_SIZE(cgc2); i++) {
  308. cgc2[i][1] = mmio_read_32(cgc2[i][0]);
  309. }
  310. /* PLL4 */
  311. for (i = 0U; i < ARRAY_SIZE(pll4); i++) {
  312. pll4[i][1] = mmio_read_32(pll4[i][0]);
  313. }
  314. /* PCC5 save */
  315. for (i = 0U; i < ARRAY_SIZE(pcc5_0); i++) {
  316. val = mmio_read_32(IMX_PCC5_BASE + i * 4);
  317. if (val & PCC_PR) {
  318. pcc5_0[i] = val;
  319. }
  320. }
  321. for (i = 0U; i < ARRAY_SIZE(pcc5_1); i++) {
  322. val = mmio_read_32(pcc5_1[i][0]);
  323. if (val & PCC_PR) {
  324. pcc5_1[i][1] = val;
  325. }
  326. }
  327. /* LPAV SIM save */
  328. for (i = 0U; i < ARRAY_SIZE(lpav_sim); i++) {
  329. lpav_sim[i][1] = mmio_read_32(lpav_sim[i][0]);
  330. }
  331. /* Save GPIO port D */
  332. gpio_save(&lpav_gpio_ctx, LPAV_GPIO_CTRL_NUM);
  333. /* put DDR into retention */
  334. dram_enter_retention();
  335. }
  336. void lpav_ctx_restore(void)
  337. {
  338. unsigned int i;
  339. /* PLL4 */
  340. for (i = 0U; i < 9U; i++) {
  341. mmio_write_32(pll4[i][0], pll4[i][1]);
  342. }
  343. /* wait for PLL4 lock */
  344. while (!(mmio_read_32(pll4[8][0]) & BIT(24))) {
  345. ;
  346. }
  347. /* restore the PLL4 PFDs */
  348. mmio_write_32(pll4[9][0], pll4[9][1] & ~(BIT(31) | BIT(23) | BIT(15) | BIT(7)));
  349. mmio_write_32(pll4[9][0], pll4[9][1]);
  350. /* wait for the PFD is stable */
  351. while (!(mmio_read_32(pll4[9][0]) & PFD_VALID_MASK)) {
  352. ;
  353. }
  354. /* CGC2 restore */
  355. for (i = 0U; i < ARRAY_SIZE(cgc2); i++) {
  356. mmio_write_32(cgc2[i][0], cgc2[i][1]);
  357. }
  358. /* PCC5 restore */
  359. for (i = 0U; i < ARRAY_SIZE(pcc5_0); i++) {
  360. if (pcc5_0[i] & PCC_PR) {
  361. mmio_write_32(IMX_PCC5_BASE + i * 4, pcc5_0[i]);
  362. }
  363. }
  364. for (i = 0U; i < ARRAY_SIZE(pcc5_1); i++) {
  365. if (pcc5_1[i][1] & PCC_PR) {
  366. mmio_write_32(pcc5_1[i][0], pcc5_1[i][1]);
  367. }
  368. }
  369. /* LPAV_SIM */
  370. for (i = 0U; i < ARRAY_SIZE(lpav_sim); i++) {
  371. mmio_write_32(lpav_sim[i][0], lpav_sim[i][1]);
  372. }
  373. gpio_restore(&lpav_gpio_ctx, LPAV_GPIO_CTRL_NUM);
  374. /* DDR retention exit */
  375. dram_exit_retention();
  376. }
  377. void imx_apd_ctx_save(unsigned int proc_num)
  378. {
  379. unsigned int i;
  380. uint32_t val;
  381. /* enable LPUART5's clock by default */
  382. mmio_setbits_32(IMX_PCC3_BASE + 0xe8, BIT(30));
  383. /* save the gic config */
  384. plat_gic_save(proc_num, &imx_gicv3_ctx);
  385. cmc1_pmprot = mmio_read_32(IMX_CMC1_BASE + 0x18);
  386. cmc1_srie = mmio_read_32(IMX_CMC1_BASE + 0x8c);
  387. /* save the PCC3 */
  388. for (i = 0U; i < ARRAY_SIZE(pcc3); i++) {
  389. /* save the pcc if it is exist */
  390. val = mmio_read_32(IMX_PCC3_BASE + i * 4);
  391. if (val & PCC_PR) {
  392. pcc3[i] = val;
  393. }
  394. }
  395. /* save the PCC4 */
  396. for (i = 0U; i < ARRAY_SIZE(pcc4); i++) {
  397. /* save the pcc if it is exist */
  398. val = mmio_read_32(IMX_PCC4_BASE + i * 4);
  399. if (val & PCC_PR) {
  400. pcc4[i] = val;
  401. }
  402. }
  403. /* save the CGC1 */
  404. cgc1_save();
  405. wdog3_save();
  406. gpio_save(apd_gpio_ctx, APD_GPIO_CTRL_NUM);
  407. iomuxc_save();
  408. tpm5_save();
  409. lpuart_save();
  410. /*
  411. * save the lpav ctx & put the ddr into retention
  412. * if lpav master is assigned to APD domain.
  413. */
  414. if (is_lpav_owned_by_apd()) {
  415. lpav_ctx_save();
  416. }
  417. }
  418. void xrdc_reinit(void)
  419. {
  420. xrdc_apply_apd_config();
  421. xrdc_apply_lpav_config();
  422. xrdc_enable();
  423. }
  424. void s400_release_caam(void)
  425. {
  426. uint32_t msg, resp;
  427. mmio_write_32(S400_MU_TRx(0), 0x17d70206);
  428. mmio_write_32(S400_MU_TRx(1), 0x7);
  429. do {
  430. resp = mmio_read_32(S400_MU_RSR);
  431. } while ((resp & 0x3) != 0x3);
  432. msg = mmio_read_32(S400_MU_RRx(0));
  433. resp = mmio_read_32(S400_MU_RRx(1));
  434. VERBOSE("resp %x; %x", msg, resp);
  435. }
  436. void imx_apd_ctx_restore(unsigned int proc_num)
  437. {
  438. unsigned int i;
  439. /* restore the CCG1 */
  440. cgc1_restore();
  441. for (i = 0U; i < ARRAY_SIZE(pcc3); i++) {
  442. /* save the pcc if it is exist */
  443. if (pcc3[i] & PCC_PR) {
  444. mmio_write_32(IMX_PCC3_BASE + i * 4, pcc3[i]);
  445. }
  446. }
  447. for (i = 0U; i < ARRAY_SIZE(pcc4); i++) {
  448. if (pcc4[i] & PCC_PR) {
  449. mmio_write_32(IMX_PCC4_BASE + i * 4, pcc4[i]);
  450. }
  451. }
  452. wdog3_restore();
  453. iomuxc_restore();
  454. tpm5_restore();
  455. xrdc_reinit();
  456. /* Restore GPIO after xrdc_reinit, otherwise MSCs are invalid */
  457. gpio_restore(apd_gpio_ctx, APD_GPIO_CTRL_NUM);
  458. /* restore the gic config */
  459. plat_gic_restore(proc_num, &imx_gicv3_ctx);
  460. mmio_write_32(IMX_CMC1_BASE + 0x18, cmc1_pmprot);
  461. mmio_write_32(IMX_CMC1_BASE + 0x8c, cmc1_srie);
  462. /* enable LPUART5's clock by default */
  463. mmio_setbits_32(IMX_PCC3_BASE + 0xe8, BIT(30));
  464. /* restore the console lpuart */
  465. lpuart_restore();
  466. /* FIXME: make uart work for ATF */
  467. mmio_write_32(IMX_LPUART_BASE + 0x18, 0xc0000);
  468. /* Allow M core to reset A core */
  469. mmio_clrbits_32(IMX_MU0B_BASE + 0x10, BIT(2));
  470. /*
  471. * Ask S400 to release caam to APD as it is owned by s400
  472. */
  473. s400_release_caam();
  474. /* re-init the caam */
  475. imx8ulp_caam_init();
  476. /*
  477. * ack the upower, seems a necessary steps, otherwise the upower can
  478. * not response to the new API service call. put this just before the
  479. * ddr retention exit because that the dram retention exit flow need to
  480. * communicate with upower.
  481. */
  482. upower_wait_resp();
  483. /*
  484. * restore the lpav ctx & make ddr out of retention
  485. * if lpav master is assigned to APD domain.
  486. */
  487. if (is_lpav_owned_by_apd()) {
  488. lpav_ctx_restore();
  489. }
  490. }
  491. #define DGO_CTRL1 U(0xc)
  492. #define USB_WAKEUP U(0x44)
  493. #define USB1_PHY_DPD_WAKEUP_EN BIT_32(5)
  494. #define USB0_PHY_DPD_WAKEUP_EN BIT_32(4)
  495. #define USB1_PHY_WAKEUP_ISO_DISABLE BIT_32(1)
  496. #define USB0_PHY_WAKEUP_ISO_DISABLE BIT_32(0)
  497. void usb_wakeup_enable(bool enable)
  498. {
  499. if (enable) {
  500. mmio_setbits_32(IMX_SIM1_BASE + USB_WAKEUP,
  501. USB1_PHY_WAKEUP_ISO_DISABLE | USB0_PHY_WAKEUP_ISO_DISABLE);
  502. mmio_setbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
  503. while (!(mmio_read_32(IMX_SIM1_BASE + DGO_CTRL1) & BIT(1))) {
  504. ;
  505. }
  506. mmio_clrbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
  507. mmio_write_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(1));
  508. /* Need to delay for a while to make sure the wakeup logic can work */
  509. udelay(500);
  510. mmio_setbits_32(IMX_SIM1_BASE + USB_WAKEUP,
  511. USB1_PHY_DPD_WAKEUP_EN | USB0_PHY_DPD_WAKEUP_EN);
  512. mmio_setbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
  513. while (!(mmio_read_32(IMX_SIM1_BASE + DGO_CTRL1) & BIT(1))) {
  514. ;
  515. }
  516. mmio_clrbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
  517. mmio_write_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(1));
  518. } else {
  519. /*
  520. * USBx_PHY_DPD_WAKEUP_EN should be cleared before USB0_PHY_WAKEUP_ISO_DISABLE
  521. * to provide the correct the wake-up functionality.
  522. */
  523. mmio_write_32(IMX_SIM1_BASE + USB_WAKEUP, USB1_PHY_WAKEUP_ISO_DISABLE |
  524. USB0_PHY_WAKEUP_ISO_DISABLE);
  525. mmio_write_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
  526. while (!(mmio_read_32(IMX_SIM1_BASE + DGO_CTRL1) & BIT(1))) {
  527. ;
  528. }
  529. mmio_clrbits_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(0));
  530. mmio_write_32(IMX_SIM1_BASE + DGO_CTRL1, BIT(1));
  531. }
  532. }