forked from Minki/linux
irqchip/gic: Support RealView variant setup
The ARM RealView PB11MPCore reference design has some special bits in a system controller register to set up the GIC in one of three modes: legacy, new with DCC, new without DCC. The register is also used to enable FIQ. Since the platform will not boot unless this register is set up to "new with DCC" mode, we need a special quirk to be compiled-in for the RealView platforms. If we find the right compatible string on the GIC TestChip, we enable this quirk by looking up the system controller and enabling the special bits. We depend on the CONFIG_REALVIEW_DT Kconfig symbol as the old boardfile code has the same fix hardcoded, and this is only needed for the attempts to modernize the RealView code using device tree. After fixing this, the PB11MPCore boots with device tree only. Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Jason Cooper <jason@lakedaemon.net> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
This commit is contained in:
parent
126aebd055
commit
8673c1d7e8
@ -21,6 +21,7 @@ obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o
|
||||
obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o
|
||||
obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o
|
||||
obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o
|
||||
obj-$(CONFIG_REALVIEW_DT) += irq-gic-realview.o
|
||||
obj-$(CONFIG_ARM_GIC_V2M) += irq-gic-v2m.o
|
||||
obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o
|
||||
obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v3-its-pci-msi.o irq-gic-v3-its-platform-msi.o
|
||||
|
43
drivers/irqchip/irq-gic-realview.c
Normal file
43
drivers/irqchip/irq-gic-realview.c
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Special GIC quirks for the ARM RealView
|
||||
* Copyright (C) 2015 Linus Walleij
|
||||
*/
|
||||
#include <linux/of.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/irqchip/arm-gic.h>
|
||||
|
||||
#define REALVIEW_SYS_LOCK_OFFSET 0x20
|
||||
#define REALVIEW_PB11MP_SYS_PLD_CTRL1 0x74
|
||||
#define VERSATILE_LOCK_VAL 0xA05F
|
||||
#define PLD_INTMODE_MASK BIT(22)|BIT(23)|BIT(24)
|
||||
#define PLD_INTMODE_LEGACY 0x0
|
||||
#define PLD_INTMODE_NEW_DCC BIT(22)
|
||||
#define PLD_INTMODE_NEW_NO_DCC BIT(23)
|
||||
#define PLD_INTMODE_FIQ_ENABLE BIT(24)
|
||||
|
||||
static int __init
|
||||
realview_gic_of_init(struct device_node *node, struct device_node *parent)
|
||||
{
|
||||
static struct regmap *map;
|
||||
|
||||
/* The PB11MPCore GIC needs to be configured in the syscon */
|
||||
map = syscon_regmap_lookup_by_compatible("arm,realview-pb11mp-syscon");
|
||||
if (!IS_ERR(map)) {
|
||||
/* new irq mode with no DCC */
|
||||
regmap_write(map, REALVIEW_SYS_LOCK_OFFSET,
|
||||
VERSATILE_LOCK_VAL);
|
||||
regmap_update_bits(map, REALVIEW_PB11MP_SYS_PLD_CTRL1,
|
||||
PLD_INTMODE_NEW_NO_DCC,
|
||||
PLD_INTMODE_MASK);
|
||||
regmap_write(map, REALVIEW_SYS_LOCK_OFFSET, 0x0000);
|
||||
pr_info("TC11MP GIC: set up interrupt controller to NEW mode, no DCC\n");
|
||||
} else {
|
||||
pr_err("TC11MP GIC setup: could not find syscon\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
return gic_of_init(node, parent);
|
||||
}
|
||||
IRQCHIP_DECLARE(armtc11mp_gic, "arm,tc11mp-gic", realview_gic_of_init);
|
@ -1196,7 +1196,7 @@ static bool gic_check_eoimode(struct device_node *node, void __iomem **base)
|
||||
return true;
|
||||
}
|
||||
|
||||
static int __init
|
||||
int __init
|
||||
gic_of_init(struct device_node *node, struct device_node *parent)
|
||||
{
|
||||
void __iomem *cpu_base;
|
||||
|
@ -103,6 +103,16 @@ struct device_node;
|
||||
void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
|
||||
int gic_cpu_if_down(unsigned int gic_nr);
|
||||
|
||||
/*
|
||||
* Subdrivers that need some preparatory work can initialize their
|
||||
* chips and call this to register their GICs.
|
||||
*/
|
||||
int gic_of_init(struct device_node *node, struct device_node *parent);
|
||||
|
||||
/*
|
||||
* Legacy platforms not converted to DT yet must use this to init
|
||||
* their GIC
|
||||
*/
|
||||
void gic_init(unsigned int nr, int start,
|
||||
void __iomem *dist , void __iomem *cpu);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user