summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2014-08-27 16:58:42 -0500
committerPatrick Georgi <pgeorgi@google.com>2015-03-27 08:04:11 +0100
commit97b78cba5afd1636a306cc6533f8abd0a886483a (patch)
tree61c075174b739137b89c68060a509c4d330a54a9
parentcc175767c98b60a7a9be4651a5187d79b40164c1 (diff)
downloadcoreboot-97b78cba5afd1636a306cc6533f8abd0a886483a.tar.xz
tegra132: support GIC secondary cpu support
For the secondary CPUs the set of banked registers needs to be initialized. In the boot CPU path all both the CPU's banked registers and the global register set is initialized. BUG=chrome-os-partner:31545 BRANCH=None TEST=Built and brought up 2nd cpu in kernel. Change-Id: I3a7bc708f726c4435afca817a251790f536844d9 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Original-Commit-Id: 813b0a8b3faacf2342164d385e5837ebede29b18 Original-Change-Id: Ie5db56ca052eebac4ed1a34eaeeb6bbd8a26ca30 Original-Signed-off-by: Aaron Durbin <adurbin@chromium.org> Original-Reviewed-on: https://chromium-review.googlesource.com/214774 Original-Reviewed-by: Furquan Shaikh <furquan@chromium.org> Reviewed-on: http://review.coreboot.org/9018 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
-rw-r--r--src/soc/nvidia/tegra132/gic.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/src/soc/nvidia/tegra132/gic.c b/src/soc/nvidia/tegra132/gic.c
index 95b592f799..6b1b657495 100644
--- a/src/soc/nvidia/tegra132/gic.c
+++ b/src/soc/nvidia/tegra132/gic.c
@@ -17,6 +17,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <arch/cpu.h>
#include <arch/io.h>
#include <stdint.h>
#include <console/console.h>
@@ -80,6 +81,13 @@ static void gicd_write_regs(struct gicd *gicd, size_t offset,
interrupts_per_reg, val);
}
+static void gicd_write_banked_regs(struct gicd *gicd, size_t offset,
+ size_t interrupts_per_reg, uint32_t val)
+{
+ /* 1st 32 interrupts are banked per CPU. */
+ gic_write_regs(gicd->base, offset, 32, interrupts_per_reg, val);
+}
+
static void gicd_init(struct gicd *gicd, uintptr_t base)
{
uint32_t typer;
@@ -98,6 +106,7 @@ void gic_init(void)
{
struct gicd gicd;
uint32_t * const gicc = (void *)(uintptr_t)TEGRA_GICC_BASE;
+ uint32_t cpu_mask;
gicd_init(&gicd, TEGRA_GICD_BASE);
@@ -108,8 +117,22 @@ void gic_init(void)
gic_write(gicc, GICC_CTLR, ENABLE_GRP0 | ENABLE_GRP1);
gic_write(gicc, GICC_PMR, 1 << 7);
- /* All interrupts route go to CPU 0. */
- gicd_write_regs(&gicd, GICD_ITARGETSR, 4, 0x01010101);
+ cpu_mask = 1 << smp_processor_id();
+ cpu_mask |= cpu_mask << 8;
+ cpu_mask |= cpu_mask << 16;
+
+ /* Only write banked registers for secondary CPUs. */
+ if (smp_processor_id()) {
+ gicd_write_banked_regs(&gicd, GICD_ITARGETSR, 4, cpu_mask);
+ /* Put interrupts into Group 1. */
+ gicd_write_banked_regs(&gicd, GICD_IGROUPR, 32, 0xffffffff);
+ /* Allow Non-secure access to everything. */
+ gicd_write_banked_regs(&gicd, GICD_NSACR, 16, 0xffffffff);
+ return;
+ }
+
+ /* All interrupts routed to processors that execute this function. */
+ gicd_write_regs(&gicd, GICD_ITARGETSR, 4, cpu_mask);
/* Put all interrupts into Gropup 1. */
gicd_write_regs(&gicd, GICD_IGROUPR, 32, 0xffffffff);
/* Allow Non-secure access to everything. */