From c3f57f02e3a275d8b5c6dc692adb21525ccb392c Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Tue, 14 Jul 2015 10:26:09 +0100 Subject: IRQCHIP: irq-mips-gic: Extend GIC accessors for 64-bit CMs Previously, the GIC accessors were only accessing u32 registers but newer CMs may actually be 64-bit on MIPS64 cores. As a result of which, extended these accessors to support 64-bit reads and writes. Signed-off-by: Markos Chandras Cc: Thomas Gleixner Cc: Jason Cooper Cc: Andrew Bresticker Cc: Paul Burton Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/10709/ Signed-off-by: Ralf Baechle --- include/linux/irqchip/mips-gic.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'include/linux/irqchip') diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h index 9b1ad3734911..10e4a9073019 100644 --- a/include/linux/irqchip/mips-gic.h +++ b/include/linux/irqchip/mips-gic.h @@ -45,8 +45,14 @@ #define GIC_SH_REVISIONID_OFS 0x0020 /* Convert an interrupt number to a byte offset/bit for multi-word registers */ -#define GIC_INTR_OFS(intr) (((intr) / 32) * 4) -#define GIC_INTR_BIT(intr) ((intr) % 32) +#define GIC_INTR_OFS(intr) ({ \ + unsigned bits = mips_cm_is64 ? 64 : 32; \ + unsigned reg_idx = (intr) / bits; \ + unsigned reg_width = bits / 8; \ + \ + reg_idx * reg_width; \ +}) +#define GIC_INTR_BIT(intr) ((intr) % (mips_cm_is64 ? 64 : 32)) /* Polarity : Reset Value is always 0 */ #define GIC_SH_SET_POLARITY_OFS 0x0100 -- cgit v1.2.3 From 6f50c83529ac1fa3444ff4be5f5b0bf3d76db678 Mon Sep 17 00:00:00 2001 From: Markos Chandras Date: Thu, 9 Jul 2015 10:40:49 +0100 Subject: IRQCHIP: irq-mips-gic: Add support for CM3 64-bit timer irqs CM3 uses a 64-bit counter and compare registers so add support for them in the GIC counter interrupt. Signed-off-by: Markos Chandras Cc: Thomas Gleixner Cc: Jason Cooper Cc: Andrew Bresticker Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/10648/ Signed-off-by: Ralf Baechle --- drivers/irqchip/irq-mips-gic.c | 33 ++++++++++++++++++++++++--------- include/linux/irqchip/mips-gic.h | 4 ++++ 2 files changed, 28 insertions(+), 9 deletions(-) (limited to 'include/linux/irqchip') diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c index d8db854afded..7d4616963b5a 100644 --- a/drivers/irqchip/irq-mips-gic.c +++ b/drivers/irqchip/irq-mips-gic.c @@ -140,6 +140,9 @@ cycle_t gic_read_count(void) { unsigned int hi, hi2, lo; + if (mips_cm_is64) + return (cycle_t)gic_read(GIC_REG(SHARED, GIC_SH_COUNTER)); + do { hi = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_63_32)); lo = gic_read32(GIC_REG(SHARED, GIC_SH_COUNTER_31_00)); @@ -162,10 +165,14 @@ unsigned int gic_get_count_width(void) void gic_write_compare(cycle_t cnt) { - gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), - (int)(cnt >> 32)); - gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), - (int)(cnt & 0xffffffff)); + if (mips_cm_is64) { + gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE), cnt); + } else { + gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI), + (int)(cnt >> 32)); + gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO), + (int)(cnt & 0xffffffff)); + } } void gic_write_cpu_compare(cycle_t cnt, int cpu) @@ -174,11 +181,16 @@ void gic_write_cpu_compare(cycle_t cnt, int cpu) local_irq_save(flags); - gic_write32(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu); - gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI), - (int)(cnt >> 32)); - gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO), - (int)(cnt & 0xffffffff)); + gic_write(GIC_REG(VPE_LOCAL, GIC_VPE_OTHER_ADDR), cpu); + + if (mips_cm_is64) { + gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE), cnt); + } else { + gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_HI), + (int)(cnt >> 32)); + gic_write32(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_LO), + (int)(cnt & 0xffffffff)); + } local_irq_restore(flags); } @@ -187,6 +199,9 @@ cycle_t gic_read_compare(void) { unsigned int hi, lo; + if (mips_cm_is64) + return (cycle_t)gic_read(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE)); + hi = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_HI)); lo = gic_read32(GIC_REG(VPE_LOCAL, GIC_VPE_COMPARE_LO)); diff --git a/include/linux/irqchip/mips-gic.h b/include/linux/irqchip/mips-gic.h index 10e4a9073019..4e6861605050 100644 --- a/include/linux/irqchip/mips-gic.h +++ b/include/linux/irqchip/mips-gic.h @@ -41,6 +41,8 @@ /* Shared Global Counter */ #define GIC_SH_COUNTER_31_00_OFS 0x0010 +/* 64-bit counter register for CM3 */ +#define GIC_SH_COUNTER_OFS GIC_SH_COUNTER_31_00_OFS #define GIC_SH_COUNTER_63_32_OFS 0x0014 #define GIC_SH_REVISIONID_OFS 0x0020 @@ -104,6 +106,8 @@ #define GIC_VPE_WD_COUNT0_OFS 0x0094 #define GIC_VPE_WD_INITIAL0_OFS 0x0098 #define GIC_VPE_COMPARE_LO_OFS 0x00a0 +/* 64-bit Compare register on CM3 */ +#define GIC_VPE_COMPARE_OFS GIC_VPE_COMPARE_LO_OFS #define GIC_VPE_COMPARE_HI_OFS 0x00a4 #define GIC_VPE_EIC_SHADOW_SET_BASE_OFS 0x0100 -- cgit v1.2.3