Tegra: GIC: enable FIQ interrupt handling

Tegra chips support multiple FIQ interrupt sources. These interrupts
are enabled in the GICD/GICC interfaces by the tegra_gic driver. A
new FIQ handler would be added in a subsequent change which can be
registered by the platform code.

This patch adds the GIC programming as part of the tegra_gic_setup()
which now takes an array of all the FIQ interrupts to be enabled for
the platform. The Tegra132 and Tegra210 platforms right now do not
register for any FIQ interrupts themselves, but will definitely use
this support in the future.

Change-Id: I0ea164be901cd6681167028fea0567399f18d4b8
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
This commit is contained in:
Varun Wadekar 2015-12-28 14:55:41 -08:00
parent 3eac92d264
commit d336030169
9 changed files with 90 additions and 12 deletions

View File

@ -185,6 +185,9 @@ void bl31_platform_setup(void)
{
uint32_t tmp_reg;
/* Initialize the gic cpu and distributor interfaces */
plat_gic_setup();
/*
* Initialize delay timer
*/
@ -216,9 +219,6 @@ void bl31_platform_setup(void)
tmp_reg = SCR_RES1_BITS | SCR_RW_BIT;
write_scr(tmp_reg);
/* Initialize the gic cpu and distributor interfaces */
tegra_gic_setup();
INFO("BL3-1: Tegra platform setup complete\n");
}

View File

@ -47,7 +47,6 @@ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \
COMMON_DIR := plat/nvidia/tegra/common
BL31_SOURCES += drivers/arm/gic/gic_v2.c \
drivers/arm/gic/gic_v3.c \
drivers/console/aarch64/console.S \
drivers/delay_timer/delay_timer.c \
drivers/ti/uart/aarch64/16550_console.S \

View File

@ -47,6 +47,9 @@
(GIC_HIGHEST_NS_PRIORITY << 16) | \
(GIC_HIGHEST_NS_PRIORITY << 24))
static const unsigned int *g_irq_sec_ptr;
static unsigned int g_num_irqs;
/*******************************************************************************
* Place the cpu interface in a state where it can never make a cpu exit wfi as
* as result of an asserted interrupt. This is critical for powering down a cpu
@ -110,7 +113,9 @@ static void tegra_gic_pcpu_distif_setup(unsigned int gicd_base)
******************************************************************************/
static void tegra_gic_distif_setup(unsigned int gicd_base)
{
unsigned int index, num_ints;
unsigned int index, num_ints, irq_num;
uint8_t target_cpus;
uint32_t val;
/*
* Mark out non-secure interrupts. Calculate number of
@ -128,6 +133,41 @@ static void tegra_gic_distif_setup(unsigned int gicd_base)
GICD_IPRIORITYR_DEF_VAL);
}
/* Configure SPI secure interrupts now */
if (g_irq_sec_ptr) {
/* Read the target CPU mask */
target_cpus = TEGRA_SEC_IRQ_TARGET_MASK & GIC_TARGET_CPU_MASK;
for (index = 0; index < g_num_irqs; index++) {
irq_num = g_irq_sec_ptr[index];
if (irq_num >= MIN_SPI_ID) {
/* Configure as a secure interrupt */
gicd_clr_igroupr(gicd_base, irq_num);
/* Configure SPI priority */
mmio_write_8(gicd_base + GICD_IPRIORITYR +
irq_num,
GIC_HIGHEST_SEC_PRIORITY &
GIC_PRI_MASK);
/* Configure as level triggered */
val = gicd_read_icfgr(gicd_base, irq_num);
val |= (3 << ((irq_num & 0xF) << 1));
gicd_write_icfgr(gicd_base, irq_num, val);
/* Route SPI to the target CPUs */
gicd_set_itargetsr(gicd_base, irq_num,
target_cpus);
/* Enable this interrupt */
gicd_set_isenabler(gicd_base, irq_num);
}
}
}
/*
* Configure the SGI and PPI. This is done in a separated function
* because each CPU is responsible for initializing its own private
@ -139,8 +179,11 @@ static void tegra_gic_distif_setup(unsigned int gicd_base)
gicd_write_ctlr(gicd_base, ENABLE_GRP0 | ENABLE_GRP1);
}
void tegra_gic_setup(void)
void tegra_gic_setup(const unsigned int *irq_sec_ptr, unsigned int num_irqs)
{
g_irq_sec_ptr = irq_sec_ptr;
g_num_irqs = num_irqs;
tegra_gic_cpuif_setup(TEGRA_GICC_BASE);
tegra_gic_distif_setup(TEGRA_GICD_BASE);
}

View File

@ -183,7 +183,7 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
/*
* Initialize the GIC cpu and distributor interfaces
*/
tegra_gic_setup();
plat_gic_setup();
/*
* Check if we are exiting from deep sleep.

View File

@ -48,6 +48,11 @@
#define PLAT_MAX_RET_STATE 1
#define PLAT_MAX_OFF_STATE (PSTATE_ID_SOC_POWERDN + 1)
/*******************************************************************************
* Secure IRQ definitions
******************************************************************************/
#define TEGRA_SEC_IRQ_TARGET_MASK 0x3 /* 2 Denver's */
/*******************************************************************************
* GIC memory map
******************************************************************************/

View File

@ -56,6 +56,11 @@
#define PLAT_MAX_RET_STATE 1
#define PLAT_MAX_OFF_STATE (PSTATE_ID_SOC_POWERDN + 1)
/*******************************************************************************
* Secure IRQ definitions
******************************************************************************/
#define TEGRA_SEC_IRQ_TARGET_MASK 0xF /* 4 A57's or 4 A53's */
/*******************************************************************************
* GIC memory map
******************************************************************************/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@ -42,6 +42,9 @@
#define TEGRA_DRAM_BASE 0x80000000
#define TEGRA_DRAM_END 0x27FFFFFFF
/*******************************************************************************
* Struct for parameters received from BL2
******************************************************************************/
typedef struct plat_params_from_bl2 {
/* TZ memory size */
uint64_t tzdram_size;
@ -58,13 +61,14 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state,
/* Declarations for plat_setup.c */
const mmap_region_t *plat_get_mmio_map(void);
uint32_t plat_get_console_from_id(int id);
void plat_gic_setup(void);
/* Declarations for plat_secondary.c */
void plat_secondary_setup(void);
int plat_lock_cpu_vectors(void);
/* Declarations for tegra_gic.c */
void tegra_gic_setup(void);
void tegra_gic_setup(const unsigned int *irq_sec_ptr, unsigned int num_irqs);
void tegra_gic_cpuif_deactivate(void);
/* Declarations for tegra_security.c */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@ -28,8 +28,11 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <xlat_tables.h>
#include <arch_helpers.h>
#include <bl_common.h>
#include <tegra_def.h>
#include <tegra_private.h>
#include <xlat_tables.h>
/*******************************************************************************
* The Tegra power domain tree has a single system level power domain i.e. a
@ -106,3 +109,11 @@ uint32_t plat_get_console_from_id(int id)
return tegra132_uart_addresses[id];
}
/*******************************************************************************
* Initialize the GIC and SGIs
******************************************************************************/
void plat_gic_setup(void)
{
tegra_gic_setup(NULL, 0);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@ -28,8 +28,11 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <arch_helpers.h>
#include <bl_common.h>
#include <console.h>
#include <tegra_def.h>
#include <tegra_private.h>
#include <xlat_tables.h>
/*******************************************************************************
@ -112,3 +115,11 @@ uint32_t plat_get_console_from_id(int id)
return tegra210_uart_addresses[id];
}
/*******************************************************************************
* Initialize the GIC and SGIs
******************************************************************************/
void plat_gic_setup(void)
{
tegra_gic_setup(NULL, 0);
}