plat_imx8_gic.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <platform_def.h>
  7. #include <common/bl_common.h>
  8. #include <common/interrupt_props.h>
  9. #include <drivers/arm/gicv3.h>
  10. #include <drivers/arm/arm_gicv3_common.h>
  11. #include <lib/mmio.h>
  12. #include <lib/utils.h>
  13. #include <plat/common/platform.h>
  14. #include <plat_imx8.h>
  15. /* the GICv3 driver only needs to be initialized in EL3 */
  16. uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT];
  17. static const interrupt_prop_t g01s_interrupt_props[] = {
  18. INTR_PROP_DESC(8, GIC_HIGHEST_SEC_PRIORITY,
  19. INTR_GROUP0, GIC_INTR_CFG_LEVEL),
  20. #if SDEI_SUPPORT
  21. INTR_PROP_DESC(PLAT_SDEI_SGI_PRIVATE, PLAT_SDEI_NORMAL_PRI,
  22. INTR_GROUP0, GIC_INTR_CFG_LEVEL),
  23. #endif
  24. };
  25. static unsigned int plat_imx_mpidr_to_core_pos(unsigned long mpidr)
  26. {
  27. return (unsigned int)plat_core_pos_by_mpidr(mpidr);
  28. }
  29. const gicv3_driver_data_t arm_gic_data = {
  30. .gicd_base = PLAT_GICD_BASE,
  31. .gicr_base = PLAT_GICR_BASE,
  32. .interrupt_props = g01s_interrupt_props,
  33. .interrupt_props_num = ARRAY_SIZE(g01s_interrupt_props),
  34. .rdistif_num = PLATFORM_CORE_COUNT,
  35. .rdistif_base_addrs = rdistif_base_addrs,
  36. .mpidr_to_core_pos = plat_imx_mpidr_to_core_pos,
  37. };
  38. void plat_gic_driver_init(void)
  39. {
  40. /*
  41. * the GICv3 driver is initialized in EL3 and does not need
  42. * to be initialized again in S-EL1. This is because the S-EL1
  43. * can use GIC system registers to manage interrupts and does
  44. * not need GIC interface base addresses to be configured.
  45. */
  46. #if IMAGE_BL31
  47. gicv3_driver_init(&arm_gic_data);
  48. #endif
  49. }
  50. static __inline void plat_gicr_exit_sleep(void)
  51. {
  52. unsigned int val = mmio_read_32(PLAT_GICR_BASE + GICR_WAKER);
  53. /*
  54. * ProcessorSleep bit can ONLY be set to zero when
  55. * Quiescent bit and Sleep bit are both zero, so
  56. * need to make sure Quiescent bit and Sleep bit
  57. * are zero before clearing ProcessorSleep bit.
  58. */
  59. if (val & WAKER_QSC_BIT) {
  60. mmio_write_32(PLAT_GICR_BASE + GICR_WAKER, val & ~WAKER_SL_BIT);
  61. /* Wait till the WAKER_QSC_BIT changes to 0 */
  62. while ((mmio_read_32(PLAT_GICR_BASE + GICR_WAKER) & WAKER_QSC_BIT) != 0U)
  63. ;
  64. }
  65. }
  66. void plat_gic_init(void)
  67. {
  68. plat_gicr_exit_sleep();
  69. gicv3_distif_init();
  70. gicv3_rdistif_init(plat_my_core_pos());
  71. gicv3_cpuif_enable(plat_my_core_pos());
  72. }
  73. void plat_gic_cpuif_enable(void)
  74. {
  75. gicv3_cpuif_enable(plat_my_core_pos());
  76. }
  77. void plat_gic_cpuif_disable(void)
  78. {
  79. gicv3_cpuif_disable(plat_my_core_pos());
  80. }
  81. void plat_gic_pcpu_init(void)
  82. {
  83. gicv3_rdistif_init(plat_my_core_pos());
  84. }
  85. void plat_gic_save(unsigned int proc_num, struct plat_gic_ctx *ctx)
  86. {
  87. /* save the gic rdist/dist context */
  88. for (int i = 0; i < PLATFORM_CORE_COUNT; i++)
  89. gicv3_rdistif_save(i, &ctx->rdist_ctx[i]);
  90. gicv3_distif_save(&ctx->dist_ctx);
  91. }
  92. void plat_gic_restore(unsigned int proc_num, struct plat_gic_ctx *ctx)
  93. {
  94. /* restore the gic rdist/dist context */
  95. gicv3_distif_init_restore(&ctx->dist_ctx);
  96. for (int i = 0; i < PLATFORM_CORE_COUNT; i++)
  97. gicv3_rdistif_init_restore(i, &ctx->rdist_ctx[i]);
  98. }