versal_net_gicv3.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
  3. * Copyright (c) 2018-2022, Xilinx, Inc. All rights reserved.
  4. * Copyright (C) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
  5. *
  6. * SPDX-License-Identifier: BSD-3-Clause
  7. */
  8. #include <common/debug.h>
  9. #include <common/interrupt_props.h>
  10. #include <drivers/arm/gicv3.h>
  11. #include <lib/utils.h>
  12. #include <plat/common/platform.h>
  13. #include <plat_private.h>
  14. #include <platform_def.h>
  15. /******************************************************************************
  16. * The following functions are defined as weak to allow a platform to override
  17. * the way the GICv3 driver is initialised and used.
  18. *****************************************************************************/
  19. #pragma weak plat_versal_net_gic_driver_init
  20. #pragma weak plat_versal_net_gic_init
  21. #pragma weak plat_versal_net_gic_cpuif_enable
  22. #pragma weak plat_versal_net_gic_cpuif_disable
  23. #pragma weak plat_versal_net_gic_pcpu_init
  24. #pragma weak plat_versal_net_gic_redistif_on
  25. #pragma weak plat_versal_net_gic_redistif_off
  26. /* The GICv3 driver only needs to be initialized in EL3 */
  27. static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
  28. static const interrupt_prop_t versal_net_interrupt_props[] = {
  29. PLAT_VERSAL_NET_G1S_IRQ_PROPS(INTR_GROUP1S),
  30. PLAT_VERSAL_NET_G0_IRQ_PROPS(INTR_GROUP0)
  31. };
  32. /*
  33. * We save and restore the GICv3 context on system suspend. Allocate the
  34. * data in the designated EL3 Secure carve-out memory.
  35. */
  36. static gicv3_redist_ctx_t rdist_ctx __section(".versal_net_el3_tzc_dram");
  37. static gicv3_dist_ctx_t dist_ctx __section(".versal_net_el3_tzc_dram");
  38. /*
  39. * MPIDR hashing function for translating MPIDRs read from GICR_TYPER register
  40. * to core position.
  41. *
  42. * Calculating core position is dependent on MPIDR_EL1.MT bit. However, affinity
  43. * values read from GICR_TYPER don't have an MT field. To reuse the same
  44. * translation used for CPUs, we insert MT bit read from the PE's MPIDR into
  45. * that read from GICR_TYPER.
  46. *
  47. * Assumptions:
  48. *
  49. * - All CPUs implemented in the system have MPIDR_EL1.MT bit set;
  50. * - No CPUs implemented in the system use affinity level 3.
  51. */
  52. static uint32_t versal_net_gicv3_mpidr_hash(u_register_t mpidr)
  53. {
  54. mpidr |= (read_mpidr_el1() & MPIDR_MT_MASK);
  55. return plat_core_pos_by_mpidr(mpidr);
  56. }
  57. static const gicv3_driver_data_t versal_net_gic_data __unused = {
  58. .gicd_base = PLAT_VERSAL_NET_GICD_BASE,
  59. .gicr_base = PLAT_VERSAL_NET_GICR_BASE,
  60. .interrupt_props = versal_net_interrupt_props,
  61. .interrupt_props_num = ARRAY_SIZE(versal_net_interrupt_props),
  62. .rdistif_num = PLATFORM_CORE_COUNT,
  63. .rdistif_base_addrs = rdistif_base_addrs,
  64. .mpidr_to_core_pos = versal_net_gicv3_mpidr_hash
  65. };
  66. void __init plat_versal_net_gic_driver_init(void)
  67. {
  68. /*
  69. * The GICv3 driver is initialized in EL3 and does not need
  70. * to be initialized again in SEL1. This is because the S-EL1
  71. * can use GIC system registers to manage interrupts and does
  72. * not need GIC interface base addresses to be configured.
  73. */
  74. #if IMAGE_BL31
  75. gicv3_driver_init(&versal_net_gic_data);
  76. #endif
  77. }
  78. /******************************************************************************
  79. * Versal NET common helper to initialize the GIC. Only invoked by BL31
  80. *****************************************************************************/
  81. void __init plat_versal_net_gic_init(void)
  82. {
  83. gicv3_distif_init();
  84. gicv3_rdistif_init(plat_my_core_pos());
  85. gicv3_cpuif_enable(plat_my_core_pos());
  86. }
  87. /******************************************************************************
  88. * Versal NET common helper to enable the GIC CPU interface
  89. *****************************************************************************/
  90. void plat_versal_net_gic_cpuif_enable(void)
  91. {
  92. gicv3_cpuif_enable(plat_my_core_pos());
  93. }
  94. /******************************************************************************
  95. * Versal NET common helper to disable the GIC CPU interface
  96. *****************************************************************************/
  97. void plat_versal_net_gic_cpuif_disable(void)
  98. {
  99. gicv3_cpuif_disable(plat_my_core_pos());
  100. }
  101. /******************************************************************************
  102. * Versal NET common helper to initialize the per-cpu redistributor interface in
  103. * GICv3
  104. *****************************************************************************/
  105. void plat_versal_net_gic_pcpu_init(void)
  106. {
  107. gicv3_rdistif_init(plat_my_core_pos());
  108. }
  109. /******************************************************************************
  110. * Versal NET common helpers to power GIC redistributor interface
  111. *****************************************************************************/
  112. void plat_versal_net_gic_redistif_on(void)
  113. {
  114. gicv3_rdistif_on(plat_my_core_pos());
  115. }
  116. void plat_versal_net_gic_redistif_off(void)
  117. {
  118. gicv3_rdistif_off(plat_my_core_pos());
  119. }
  120. /******************************************************************************
  121. * Versal NET common helper to save & restore the GICv3 on resume from system
  122. * suspend
  123. *****************************************************************************/
  124. void plat_versal_net_gic_save(void)
  125. {
  126. /*
  127. * If an ITS is available, save its context before
  128. * the Redistributor using:
  129. * gicv3_its_save_disable(gits_base, &its_ctx[i])
  130. * Additionnaly, an implementation-defined sequence may
  131. * be required to save the whole ITS state.
  132. */
  133. /*
  134. * Save the GIC Redistributors and ITS contexts before the
  135. * Distributor context. As we only handle SYSTEM SUSPEND API,
  136. * we only need to save the context of the CPU that is issuing
  137. * the SYSTEM SUSPEND call, i.e. the current CPU.
  138. */
  139. gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx);
  140. /* Save the GIC Distributor context */
  141. gicv3_distif_save(&dist_ctx);
  142. /*
  143. * From here, all the components of the GIC can be safely powered down
  144. * as long as there is an alternate way to handle wakeup interrupt
  145. * sources.
  146. */
  147. }
  148. void plat_versal_net_gic_resume(void)
  149. {
  150. /* Restore the GIC Distributor context */
  151. gicv3_distif_init_restore(&dist_ctx);
  152. /*
  153. * Restore the GIC Redistributor and ITS contexts after the
  154. * Distributor context. As we only handle SYSTEM SUSPEND API,
  155. * we only need to restore the context of the CPU that issued
  156. * the SYSTEM SUSPEND call.
  157. */
  158. gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx);
  159. /*
  160. * If an ITS is available, restore its context after
  161. * the Redistributor using:
  162. * gicv3_its_restore(gits_base, &its_ctx[i])
  163. * An implementation-defined sequence may be required to
  164. * restore the whole ITS state. The ITS must also be
  165. * re-enabled after this sequence has been executed.
  166. */
  167. }