psci-mx7.c 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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. #define GPC_CPU_PGC_SW_PDN_REQ 0xfc
  13. #define GPC_CPU_PGC_SW_PUP_REQ 0xf0
  14. #define GPC_PGC_C1 0x840
  15. #define BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7 0x2
  16. /* below is for i.MX7D */
  17. #define SRC_GPR1_MX7D 0x074
  18. #define SRC_A7RCR0 0x004
  19. #define SRC_A7RCR1 0x008
  20. #define BP_SRC_A7RCR0_A7_CORE_RESET0 0
  21. #define BP_SRC_A7RCR1_A7_CORE1_ENABLE 1
  22. static inline void imx_gpcv2_set_m_core_pgc(bool enable, u32 offset)
  23. {
  24. writel(enable, GPC_IPS_BASE_ADDR + offset);
  25. }
  26. __secure void imx_gpcv2_set_core1_power(bool pdn)
  27. {
  28. u32 reg = pdn ? GPC_CPU_PGC_SW_PUP_REQ : GPC_CPU_PGC_SW_PDN_REQ;
  29. u32 val;
  30. imx_gpcv2_set_m_core_pgc(true, GPC_PGC_C1);
  31. val = readl(GPC_IPS_BASE_ADDR + reg);
  32. val |= BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7;
  33. writel(val, GPC_IPS_BASE_ADDR + reg);
  34. while ((readl(GPC_IPS_BASE_ADDR + reg) &
  35. BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7) != 0)
  36. ;
  37. imx_gpcv2_set_m_core_pgc(false, GPC_PGC_C1);
  38. }
  39. __secure void imx_enable_cpu_ca7(int cpu, bool enable)
  40. {
  41. u32 mask, val;
  42. mask = 1 << (BP_SRC_A7RCR1_A7_CORE1_ENABLE + cpu - 1);
  43. val = readl(SRC_BASE_ADDR + SRC_A7RCR1);
  44. val = enable ? val | mask : val & ~mask;
  45. writel(val, SRC_BASE_ADDR + SRC_A7RCR1);
  46. }
  47. __secure int imx_cpu_on(int fn, int cpu, int pc)
  48. {
  49. writel(pc, SRC_BASE_ADDR + cpu * 8 + SRC_GPR1_MX7D);
  50. imx_gpcv2_set_core1_power(true);
  51. imx_enable_cpu_ca7(cpu, true);
  52. return 0;
  53. }
  54. __secure int imx_cpu_off(int cpu)
  55. {
  56. imx_enable_cpu_ca7(cpu, false);
  57. imx_gpcv2_set_core1_power(false);
  58. writel(0, SRC_BASE_ADDR + cpu * 8 + SRC_GPR1_MX7D + 4);
  59. return 0;
  60. }