sunxi_pm.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /*
  2. * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <platform_def.h>
  8. #include <common/debug.h>
  9. #include <common/fdt_fixup.h>
  10. #include <lib/mmio.h>
  11. #include <lib/psci/psci.h>
  12. #include <sunxi_cpucfg.h>
  13. #include <sunxi_private.h>
  14. static bool psci_is_scpi;
  15. #if SUNXI_PSCI_USE_SCPI
  16. bool sunxi_psci_is_scpi(void)
  17. {
  18. return psci_is_scpi;
  19. }
  20. #endif
  21. #ifndef SUNXI_ALT_RVBAR_LO_REG
  22. #define SUNXI_ALT_RVBAR_LO_REG(n) 0
  23. #define SUNXI_ALT_RVBAR_HI_REG(n) 0
  24. #endif
  25. int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint)
  26. {
  27. /* The non-secure entry point must be in DRAM */
  28. if (ns_entrypoint < SUNXI_DRAM_BASE) {
  29. return PSCI_E_INVALID_ADDRESS;
  30. }
  31. return PSCI_E_SUCCESS;
  32. }
  33. int plat_setup_psci_ops(uintptr_t sec_entrypoint,
  34. const plat_psci_ops_t **psci_ops)
  35. {
  36. assert(psci_ops);
  37. /* Program all CPU entry points. */
  38. for (unsigned int cpu = 0; cpu < PLATFORM_CORE_COUNT; ++cpu) {
  39. if (sunxi_cpucfg_has_per_cluster_regs()) {
  40. mmio_write_32(SUNXI_CPUCFG_RVBAR_LO_REG(cpu),
  41. sec_entrypoint & 0xffffffff);
  42. mmio_write_32(SUNXI_CPUCFG_RVBAR_HI_REG(cpu),
  43. sec_entrypoint >> 32);
  44. } else {
  45. mmio_write_32(SUNXI_ALT_RVBAR_LO_REG(cpu),
  46. sec_entrypoint & 0xffffffff);
  47. mmio_write_32(SUNXI_ALT_RVBAR_HI_REG(cpu),
  48. sec_entrypoint >> 32);
  49. }
  50. }
  51. if (sunxi_set_scpi_psci_ops(psci_ops) == 0) {
  52. INFO("PSCI: Suspend is available via SCPI\n");
  53. psci_is_scpi = true;
  54. } else {
  55. INFO("PSCI: Suspend is unavailable\n");
  56. sunxi_set_native_psci_ops(psci_ops);
  57. }
  58. return 0;
  59. }