arm_sleep.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright 2014 Freescale Semiconductor, Inc.
  4. */
  5. #include <common.h>
  6. #include <asm/io.h>
  7. #ifndef CONFIG_ARMV7_NONSEC
  8. #error " Deep sleep needs non-secure mode support. "
  9. #else
  10. #include <asm/secure.h>
  11. #endif
  12. #include <asm/armv7.h>
  13. #if defined(CONFIG_ARCH_LS1021A)
  14. #include <asm/arch/immap_ls102xa.h>
  15. #endif
  16. #include "sleep.h"
  17. #ifdef CONFIG_U_QE
  18. #include <fsl_qe.h>
  19. #endif
  20. DECLARE_GLOBAL_DATA_PTR;
  21. void __weak board_mem_sleep_setup(void)
  22. {
  23. }
  24. void __weak board_sleep_prepare(void)
  25. {
  26. }
  27. bool is_warm_boot(void)
  28. {
  29. struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
  30. if (in_be32(&gur->crstsr) & DCFG_CCSR_CRSTSR_WDRFR)
  31. return 1;
  32. return 0;
  33. }
  34. void fsl_dp_disable_console(void)
  35. {
  36. gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE;
  37. }
  38. /*
  39. * When wakeup from deep sleep, the first 128 bytes space
  40. * will be used to do DDR training which corrupts the data
  41. * in there. This function will restore them.
  42. */
  43. static void dp_ddr_restore(void)
  44. {
  45. u64 *src, *dst;
  46. int i;
  47. struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
  48. /* get the address of ddr date from SPARECR3 */
  49. src = (u64 *)in_le32(&scfg->sparecr[2]);
  50. dst = (u64 *)CONFIG_SYS_SDRAM_BASE;
  51. for (i = 0; i < DDR_BUFF_LEN / 8; i++)
  52. *dst++ = *src++;
  53. }
  54. #if defined(CONFIG_ARMV7_PSCI) && defined(CONFIG_ARCH_LS1021A)
  55. void ls1_psci_resume_fixup(void)
  56. {
  57. u32 tmp;
  58. struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
  59. #ifdef QIXIS_BASE
  60. void *qixis_base = (void *)QIXIS_BASE;
  61. /* Pull on PCIe RST# */
  62. out_8(qixis_base + QIXIS_RST_FORCE_3, 0);
  63. /* disable deep sleep signals in FPGA */
  64. tmp = in_8(qixis_base + QIXIS_PWR_CTL2);
  65. tmp &= ~QIXIS_PWR_CTL2_PCTL;
  66. out_8(qixis_base + QIXIS_PWR_CTL2, tmp);
  67. #endif
  68. /* Disable wakeup interrupt during deep sleep */
  69. out_be32(&scfg->pmcintecr, 0);
  70. /* Clear PMC interrupt status */
  71. out_be32(&scfg->pmcintsr, 0xffffffff);
  72. /* Disable Warm Device Reset */
  73. tmp = in_be32(&scfg->dpslpcr);
  74. tmp &= ~SCFG_DPSLPCR_WDRR_EN;
  75. out_be32(&scfg->dpslpcr, tmp);
  76. }
  77. #endif
  78. static void dp_resume_prepare(void)
  79. {
  80. dp_ddr_restore();
  81. board_sleep_prepare();
  82. armv7_init_nonsec();
  83. #ifdef CONFIG_U_QE
  84. u_qe_resume();
  85. #endif
  86. #if defined(CONFIG_ARMV7_PSCI) && defined(CONFIG_ARCH_LS1021A)
  87. ls1_psci_resume_fixup();
  88. #endif
  89. }
  90. int fsl_dp_resume(void)
  91. {
  92. u32 start_addr;
  93. void (*kernel_resume)(void);
  94. struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
  95. if (!is_warm_boot())
  96. return 0;
  97. dp_resume_prepare();
  98. /* Get the entry address and jump to kernel */
  99. start_addr = in_le32(&scfg->sparecr[3]);
  100. debug("Entry address is 0x%08x\n", start_addr);
  101. kernel_resume = (void (*)(void))start_addr;
  102. secure_ram_addr(_do_nonsec_entry)(kernel_resume, 0, 0, 0);
  103. return 0;
  104. }