c8097329517cfb03bdfc77cad9ea46e96ab0346b
2 * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
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.
13 #include <arch_helpers.h>
17 #include "gicv3_private.h"
18 #include "arm_gicv3_common.h"
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
27 void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num
)
29 uintptr_t gicr_base
= 0;
31 assert(gicv3_driver_data
);
32 assert(gicv3_driver_data
->rdistif_base_addrs
);
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.
39 for (unsigned int i
= 0; i
< gicv3_driver_data
->rdistif_num
; i
++) {
40 gicr_base
= gicv3_driver_data
->rdistif_base_addrs
[i
];
42 assert(gicr_read_waker(gicr_base
) & WAKER_CA_BIT
);
43 assert(gicr_read_waker(gicr_base
) & WAKER_PS_BIT
);
46 gicr_base
= gicv3_driver_data
->rdistif_base_addrs
[rdist_proc_num
];
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.
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.
60 gicr_write_waker(gicr_base
, gicr_read_waker(gicr_base
) | WAKER_SL_BIT
);
62 /* Wait until the GICR_WAKER.Quiescent bit is set */
63 while (!(gicr_read_waker(gicr_base
) & WAKER_QSC_BIT
))
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.
71 void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num
)
75 assert(gicv3_driver_data
);
76 assert(gicv3_driver_data
->rdistif_base_addrs
);
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.
83 gicr_base
= gicv3_driver_data
->rdistif_base_addrs
[rdist_proc_num
];
87 * If the GIC had power removed, the GICR_WAKER state will be reset.
88 * Since the GICR_WAKER.Sleep and GICR_WAKER.Quiescent bits are cleared,
89 * we can exit early. This also prevents the following assert from
90 * erroneously triggering.
92 if (!(gicr_read_waker(gicr_base
) & WAKER_SL_BIT
))
96 * Writes to GICR_WAKER.Sleep bit are ignored if GICR_WAKER.Quiescent
97 * bit is not set. We should be alright on power on path, therefore
98 * coming out of sleep and Quiescent should be set, but we assert in
101 assert(gicr_read_waker(gicr_base
) & WAKER_QSC_BIT
);
103 /* Clear GICR_WAKER.Sleep */
104 gicr_write_waker(gicr_base
, gicr_read_waker(gicr_base
) & ~WAKER_SL_BIT
);
107 * We don't know if the effects of setting GICR_WAKER.Sleep bit is
108 * instantaneous, so we wait until the interface is not Quiescent
111 while (gicr_read_waker(gicr_base
) & WAKER_QSC_BIT
)