From 589e63ee7c302a96ef7f9349838936dccdb19f52 Mon Sep 17 00:00:00 2001 From: Joseph Lo Date: Wed, 29 Apr 2015 17:14:03 +0800 Subject: drivers/gic: reprogram the GIC CPU interface to bypass IRQ GICv2 provides a wake IRQ/FIQ (for wake-event purpose), which are not disabled by GIC CPU interface. This is done by adding a bypass override capability when the interrupts are disabled at the CPU interface. To support this, there are four bits about IRQ/FIQ BypassDisable in CPU interface Control Register. So the CPU can exit from WFI when an asserted IRQ is coming. This is critical for power gating a CPU. BRANCH=none BUG=chrome-os-partner:39620 TEST=testing with CPU idle with power down state support and CPU can wake up normally Change-Id: I71ac642e28024a562db898665b74a5791fce325a Signed-off-by: Patrick Georgi Original-Commit-Id: 3a3f098cbf3fbfdab8150ebd4fd688fdb472b529 Original-Change-Id: I20569a18f34a4b11b8c8c67ea255b3d0f021839f Original-Signed-off-by: Joseph Lo Original-Reviewed-on: https://chromium-review.googlesource.com/269116 Original-Reviewed-by: Aaron Durbin Reviewed-on: http://review.coreboot.org/10172 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Stefan Reinauer --- src/drivers/gic/gic.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/drivers/gic') diff --git a/src/drivers/gic/gic.c b/src/drivers/gic/gic.c index 71073a580a..b7bce2a371 100644 --- a/src/drivers/gic/gic.c +++ b/src/drivers/gic/gic.c @@ -26,6 +26,10 @@ enum { ENABLE_GRP0 = 0x1 << 0, ENABLE_GRP1 = 0x1 << 1, + FIQ_BYP_DIS_GRP0 = 0x1 << 5, + IRQ_BYP_DIS_GRP0 = 0x1 << 6, + FIQ_BYP_DIS_GRP1 = 0x1 << 7, + IRQ_BYP_DIS_GRP1 = 0x1 << 8, }; struct gic { @@ -135,6 +139,13 @@ void gic_disable(void) /* Disable secure, non-secure interrupts. */ uint32_t val = gic_read(&gicc->ctlr); val &= ~(ENABLE_GRP0 | ENABLE_GRP1); + /* + * Enable the IRQ/FIQ BypassDisable bits to bypass the IRQs. + * So the CPU can wake up from power gating state when the GIC + * was disabled. + */ + val |= FIQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP0 | + FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1; gic_write(&gicc->ctlr, val); } -- cgit v1.2.3