arm_sleep.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * Copyright 2014 Freescale Semiconductor, Inc.
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. */
  6. #include <common.h>
  7. #include <asm/io.h>
  8. #if !defined(CONFIG_ARMV7_NONSEC) || !defined(CONFIG_ARMV7_VIRT)
  9. #error " Deep sleep needs non-secure mode support. "
  10. #else
  11. #include <asm/secure.h>
  12. #endif
  13. #include <asm/armv7.h>
  14. #include <asm/cache.h>
  15. #if defined(CONFIG_LS102XA)
  16. #include <asm/arch/immap_ls102xa.h>
  17. #endif
  18. #include "sleep.h"
  19. DECLARE_GLOBAL_DATA_PTR;
  20. void __weak board_mem_sleep_setup(void)
  21. {
  22. }
  23. void __weak board_sleep_prepare(void)
  24. {
  25. }
  26. bool is_warm_boot(void)
  27. {
  28. struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
  29. if (in_be32(&gur->crstsr) & DCFG_CCSR_CRSTSR_WDRFR)
  30. return 1;
  31. return 0;
  32. }
  33. void fsl_dp_disable_console(void)
  34. {
  35. gd->flags |= GD_FLG_SILENT | GD_FLG_DISABLE_CONSOLE;
  36. }
  37. /*
  38. * When wakeup from deep sleep, the first 128 bytes space
  39. * will be used to do DDR training which corrupts the data
  40. * in there. This function will restore them.
  41. */
  42. static void dp_ddr_restore(void)
  43. {
  44. u64 *src, *dst;
  45. int i;
  46. struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
  47. /* get the address of ddr date from SPARECR3 */
  48. src = (u64 *)in_le32(&scfg->sparecr[2]);
  49. dst = (u64 *)CONFIG_SYS_SDRAM_BASE;
  50. for (i = 0; i < DDR_BUFF_LEN / 8; i++)
  51. *dst++ = *src++;
  52. flush_dcache_all();
  53. }
  54. static void dp_resume_prepare(void)
  55. {
  56. dp_ddr_restore();
  57. board_sleep_prepare();
  58. armv7_init_nonsec();
  59. cleanup_before_linux();
  60. }
  61. int fsl_dp_resume(void)
  62. {
  63. u32 start_addr;
  64. void (*kernel_resume)(void);
  65. struct ccsr_scfg __iomem *scfg = (void *)CONFIG_SYS_FSL_SCFG_ADDR;
  66. if (!is_warm_boot())
  67. return 0;
  68. dp_resume_prepare();
  69. /* Get the entry address and jump to kernel */
  70. start_addr = in_le32(&scfg->sparecr[1]);
  71. debug("Entry address is 0x%08x\n", start_addr);
  72. kernel_resume = (void (*)(void))start_addr;
  73. secure_ram_addr(_do_nonsec_entry)(kernel_resume, 0, 0, 0);
  74. return 0;
  75. }