psci-mx7.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /*
  2. * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
  3. * Copyright 2017 NXP
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <asm/io.h>
  8. #include <asm/psci.h>
  9. #include <asm/secure.h>
  10. #include <asm/arch/imx-regs.h>
  11. #include <common.h>
  12. #include <fsl_wdog.h>
  13. #define GPC_CPU_PGC_SW_PDN_REQ 0xfc
  14. #define GPC_CPU_PGC_SW_PUP_REQ 0xf0
  15. #define GPC_PGC_C1 0x840
  16. #define BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7 0x2
  17. /* below is for i.MX7D */
  18. #define SRC_GPR1_MX7D 0x074
  19. #define SRC_A7RCR0 0x004
  20. #define SRC_A7RCR1 0x008
  21. #define BP_SRC_A7RCR0_A7_CORE_RESET0 0
  22. #define BP_SRC_A7RCR1_A7_CORE1_ENABLE 1
  23. #define CCM_ROOT_WDOG 0xbb80
  24. #define CCM_CCGR_WDOG1 0x49c0
  25. static inline void imx_gpcv2_set_m_core_pgc(bool enable, u32 offset)
  26. {
  27. writel(enable, GPC_IPS_BASE_ADDR + offset);
  28. }
  29. __secure void imx_gpcv2_set_core1_power(bool pdn)
  30. {
  31. u32 reg = pdn ? GPC_CPU_PGC_SW_PUP_REQ : GPC_CPU_PGC_SW_PDN_REQ;
  32. u32 val;
  33. imx_gpcv2_set_m_core_pgc(true, GPC_PGC_C1);
  34. val = readl(GPC_IPS_BASE_ADDR + reg);
  35. val |= BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7;
  36. writel(val, GPC_IPS_BASE_ADDR + reg);
  37. while ((readl(GPC_IPS_BASE_ADDR + reg) &
  38. BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7) != 0)
  39. ;
  40. imx_gpcv2_set_m_core_pgc(false, GPC_PGC_C1);
  41. }
  42. __secure void imx_enable_cpu_ca7(int cpu, bool enable)
  43. {
  44. u32 mask, val;
  45. mask = 1 << (BP_SRC_A7RCR1_A7_CORE1_ENABLE + cpu - 1);
  46. val = readl(SRC_BASE_ADDR + SRC_A7RCR1);
  47. val = enable ? val | mask : val & ~mask;
  48. writel(val, SRC_BASE_ADDR + SRC_A7RCR1);
  49. }
  50. __secure int imx_cpu_on(int fn, int cpu, int pc)
  51. {
  52. writel(pc, SRC_BASE_ADDR + cpu * 8 + SRC_GPR1_MX7D);
  53. imx_gpcv2_set_core1_power(true);
  54. imx_enable_cpu_ca7(cpu, true);
  55. return 0;
  56. }
  57. __secure int imx_cpu_off(int cpu)
  58. {
  59. imx_enable_cpu_ca7(cpu, false);
  60. imx_gpcv2_set_core1_power(false);
  61. writel(0, SRC_BASE_ADDR + cpu * 8 + SRC_GPR1_MX7D + 4);
  62. return 0;
  63. }
  64. __secure void imx_system_reset(void)
  65. {
  66. struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
  67. /* make sure WDOG1 clock is enabled */
  68. writel(0x1 << 28, CCM_BASE_ADDR + CCM_ROOT_WDOG);
  69. writel(0x3, CCM_BASE_ADDR + CCM_CCGR_WDOG1);
  70. writew(WCR_WDE, &wdog->wcr);
  71. }