1 /* 2 * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com> 3 * 4 * This work is licensed under the terms of the GNU LGPL, version 2. 5 */ 6 #include <asm/gic.h> 7 #include <asm/io.h> 8 9 void gicv2_enable_defaults(void) 10 { 11 void *dist = gicv2_dist_base(); 12 void *cpu_base = gicv2_cpu_base(); 13 unsigned int i; 14 15 gicv2_data.irq_nr = GICD_TYPER_IRQS(readl(dist + GICD_TYPER)); 16 if (gicv2_data.irq_nr > 1020) 17 gicv2_data.irq_nr = 1020; 18 19 for (i = 0; i < gicv2_data.irq_nr; i += 4) 20 writel(GICD_INT_DEF_PRI_X4, dist + GICD_IPRIORITYR + i); 21 22 writel(GICD_INT_EN_SET_SGI, dist + GICD_ISENABLER + 0); 23 writel(GICD_ENABLE, dist + GICD_CTLR); 24 25 writel(GICC_INT_PRI_THRESHOLD, cpu_base + GICC_PMR); 26 writel(GICC_ENABLE, cpu_base + GICC_CTLR); 27 } 28 29 u32 gicv2_read_iar(void) 30 { 31 return readl(gicv2_cpu_base() + GICC_IAR); 32 } 33 34 u32 gicv2_iar_irqnr(u32 iar) 35 { 36 return iar & GICC_IAR_INT_ID_MASK; 37 } 38 39 void gicv2_write_eoir(u32 irqstat) 40 { 41 writel(irqstat, gicv2_cpu_base() + GICC_EOIR); 42 } 43 44 void gicv2_ipi_send_single(int irq, int cpu) 45 { 46 assert(cpu < 8); 47 assert(irq < 16); 48 /* 49 * The wmb() in writel and rmb() in readl() from gicv2_read_iar() are 50 * sufficient for ensuring that stores that happen in program order 51 * before the IPI will be visible after the interrupt is acknowledged. 52 */ 53 writel(1 << (cpu + 16) | irq, gicv2_dist_base() + GICD_SGIR); 54 } 55 56 void gicv2_ipi_send_mask(int irq, const cpumask_t *dest) 57 { 58 u8 tlist = (u8)cpumask_bits(dest)[0]; 59 60 assert(irq < 16); 61 /* No barriers needed, same situation as gicv2_ipi_send_single() */ 62 writel(tlist << 16 | irq, gicv2_dist_base() + GICD_SGIR); 63 } 64