a5ds_pm.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * Copyright (c) 2019, Arm Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <drivers/arm/gicv2.h>
  8. #include <lib/psci/psci.h>
  9. #include <plat/arm/common/plat_arm.h>
  10. #include <plat/common/platform.h>
  11. /*******************************************************************************
  12. * Platform handler called when a power domain is about to be turned on. The
  13. * mpidr determines the CPU to be turned on.
  14. ******************************************************************************/
  15. static int a5ds_pwr_domain_on(u_register_t mpidr)
  16. {
  17. unsigned int pos = plat_core_pos_by_mpidr(mpidr);
  18. uint64_t *hold_base = (uint64_t *)A5DS_HOLD_BASE;
  19. hold_base[pos] = A5DS_HOLD_STATE_GO;
  20. dsbish();
  21. sev();
  22. return PSCI_E_SUCCESS;
  23. }
  24. /*******************************************************************************
  25. * Platform handler called when a power domain has just been powered on after
  26. * being turned off earlier. The target_state encodes the low power state that
  27. * each level has woken up from.
  28. ******************************************************************************/
  29. void a5ds_pwr_domain_on_finish(const psci_power_state_t *target_state)
  30. {
  31. /* TODO: This setup is needed only after a cold boot*/
  32. gicv2_pcpu_distif_init();
  33. /* Enable the gic cpu interface */
  34. gicv2_cpuif_enable();
  35. }
  36. /*******************************************************************************
  37. * Platform handler called when a power domain is about to be turned off. The
  38. * target_state encodes the power state that each level should transition to.
  39. * a5ds only has always-on power domain and there is no power control present.
  40. ******************************************************************************/
  41. void a5ds_pwr_domain_off(const psci_power_state_t *target_state)
  42. {
  43. ERROR("CPU_OFF not supported on this platform\n");
  44. assert(false);
  45. panic();
  46. }
  47. /*******************************************************************************
  48. * Export the platform handlers via a5ds_psci_pm_ops. The ARM Standard
  49. * platform layer will take care of registering the handlers with PSCI.
  50. ******************************************************************************/
  51. plat_psci_ops_t a5ds_psci_pm_ops = {
  52. /* dummy struct */
  53. .validate_ns_entrypoint = NULL,
  54. .pwr_domain_on = a5ds_pwr_domain_on,
  55. .pwr_domain_on_finish = a5ds_pwr_domain_on_finish,
  56. .pwr_domain_off = a5ds_pwr_domain_off
  57. };
  58. int __init plat_setup_psci_ops(uintptr_t sec_entrypoint,
  59. const plat_psci_ops_t **psci_ops)
  60. {
  61. uintptr_t *mailbox = (void *)A5DS_TRUSTED_MAILBOX_BASE;
  62. *mailbox = sec_entrypoint;
  63. *psci_ops = &a5ds_psci_pm_ops;
  64. return 0;
  65. }