1 /* 2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 /* 8 * Driver for implementation defined features that are identical in ARM GICv3 9 * implementations (GIC-500 and GIC-600 for now). This driver only overrides 10 * APIs that are different to those generic ones in GICv3 driver. 11 */ 12 13 #include <arch_helpers.h> 14 #include <assert.h> 15 #include <gicv3.h> 16 17 #include "gicv3_private.h" 18 #include "arm_gicv3_common.h" 19 20 /* 21 * Flush the internal GIC cache of the LPIs pending tables to memory before 22 * saving the state of the Redistributor. This is required before powering off 23 * the GIC when the pending status must be preserved. 24 * `rdist_proc_num` is the processor number corresponding to the Redistributor of the 25 * current CPU. 26 */ 27 void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num) 28 { 29 uintptr_t gicr_base = 0; 30 31 assert(gicv3_driver_data); 32 assert(gicv3_driver_data->rdistif_base_addrs); 33 34 /* 35 * The GICR_WAKER.Sleep bit should be set only when both 36 * GICR_WAKER.ChildrenAsleep and GICR_WAKER.ProcessorSleep are set on 37 * all the Redistributors. 38 */ 39 for (unsigned int i = 0; i < gicv3_driver_data->rdistif_num; i++) { 40 gicr_base = gicv3_driver_data->rdistif_base_addrs[i]; 41 assert(gicr_base); 42 assert(gicr_read_waker(gicr_base) & WAKER_CA_BIT); 43 assert(gicr_read_waker(gicr_base) & WAKER_PS_BIT); 44 } 45 46 gicr_base = gicv3_driver_data->rdistif_base_addrs[rdist_proc_num]; 47 /* 48 * According to the TRM, there is only one instance of the 49 * GICR_WAKER.Sleep and GICR_WAKER.Quiescent bits that can be accessed 50 * through any of the Redistributor. 51 */ 52 53 /* 54 * Set GICR_WAKER.Sleep 55 * After this point, the system must be configured so that the 56 * wake_request signals for the right cores are asserted when a wakeup 57 * interrupt is detected. The GIC will not be able to do that anymore 58 * when the GICR_WAKER.Sleep bit is set to 1. 59 */ 60 gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_SL_BIT); 61 62 /* Wait until the GICR_WAKER.Quiescent bit is set */ 63 while (!(gicr_read_waker(gicr_base) & WAKER_QSC_BIT)) 64 ; 65 } 66 67 /* 68 * Allow the LPIs pending state to be read back from the tables in memory after 69 * having restored the state of the GIC Redistributor. 70 */ 71 void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num) 72 { 73 uintptr_t gicr_base; 74 75 assert(gicv3_driver_data); 76 assert(gicv3_driver_data->rdistif_base_addrs); 77 78 /* 79 * According to the TRM, there is only one instance of the 80 * GICR_WAKER.Sleep and GICR_WAKER.Quiescent bits that can be accessed 81 * through any of the Redistributor. 82 */ 83 gicr_base = gicv3_driver_data->rdistif_base_addrs[rdist_proc_num]; 84 assert(gicr_base); 85 86 /* 87 * Writes to GICR_WAKER.Sleep bit are ignored if GICR_WAKER.Quiescent 88 * bit is not set. We should be alright on power on path, therefore 89 * coming out of sleep and Quiescent should be set, but we assert in 90 * case. 91 */ 92 assert(gicr_read_waker(gicr_base) & WAKER_QSC_BIT); 93 94 /* Clear GICR_WAKER.Sleep */ 95 gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_SL_BIT); 96 97 /* 98 * We don't know if the effects of setting GICR_WAKER.Sleep bit is 99 * instantaneous, so we wait until the interface is not Quiescent 100 * anymore. 101 */ 102 while (gicr_read_waker(gicr_base) & WAKER_QSC_BIT) 103 ; 104 } 105 106