191a6c3ceSAndrew Jones /* 291a6c3ceSAndrew Jones * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com> 391a6c3ceSAndrew Jones * 491a6c3ceSAndrew Jones * This work is licensed under the terms of the GNU LGPL, version 2. 591a6c3ceSAndrew Jones */ 691a6c3ceSAndrew Jones #include <asm/gic.h> 791a6c3ceSAndrew Jones #include <asm/io.h> 891a6c3ceSAndrew Jones 991a6c3ceSAndrew Jones void gicv2_enable_defaults(void) 1091a6c3ceSAndrew Jones { 1191a6c3ceSAndrew Jones void *dist = gicv2_dist_base(); 1291a6c3ceSAndrew Jones void *cpu_base = gicv2_cpu_base(); 1391a6c3ceSAndrew Jones unsigned int i; 1491a6c3ceSAndrew Jones 1591a6c3ceSAndrew Jones gicv2_data.irq_nr = GICD_TYPER_IRQS(readl(dist + GICD_TYPER)); 1691a6c3ceSAndrew Jones if (gicv2_data.irq_nr > 1020) 1791a6c3ceSAndrew Jones gicv2_data.irq_nr = 1020; 1891a6c3ceSAndrew Jones 1991a6c3ceSAndrew Jones for (i = 0; i < gicv2_data.irq_nr; i += 4) 2091a6c3ceSAndrew Jones writel(GICD_INT_DEF_PRI_X4, dist + GICD_IPRIORITYR + i); 2191a6c3ceSAndrew Jones 2291a6c3ceSAndrew Jones writel(GICD_INT_EN_SET_SGI, dist + GICD_ISENABLER + 0); 2391a6c3ceSAndrew Jones writel(GICD_ENABLE, dist + GICD_CTLR); 2491a6c3ceSAndrew Jones 2591a6c3ceSAndrew Jones writel(GICC_INT_PRI_THRESHOLD, cpu_base + GICC_PMR); 2691a6c3ceSAndrew Jones writel(GICC_ENABLE, cpu_base + GICC_CTLR); 2791a6c3ceSAndrew Jones } 28*2e2d471dSAndrew Jones 29*2e2d471dSAndrew Jones u32 gicv2_read_iar(void) 30*2e2d471dSAndrew Jones { 31*2e2d471dSAndrew Jones return readl(gicv2_cpu_base() + GICC_IAR); 32*2e2d471dSAndrew Jones } 33*2e2d471dSAndrew Jones 34*2e2d471dSAndrew Jones u32 gicv2_iar_irqnr(u32 iar) 35*2e2d471dSAndrew Jones { 36*2e2d471dSAndrew Jones return iar & GICC_IAR_INT_ID_MASK; 37*2e2d471dSAndrew Jones } 38*2e2d471dSAndrew Jones 39*2e2d471dSAndrew Jones void gicv2_write_eoir(u32 irqstat) 40*2e2d471dSAndrew Jones { 41*2e2d471dSAndrew Jones writel(irqstat, gicv2_cpu_base() + GICC_EOIR); 42*2e2d471dSAndrew Jones } 43*2e2d471dSAndrew Jones 44*2e2d471dSAndrew Jones void gicv2_ipi_send_single(int irq, int cpu) 45*2e2d471dSAndrew Jones { 46*2e2d471dSAndrew Jones assert(cpu < 8); 47*2e2d471dSAndrew Jones assert(irq < 16); 48*2e2d471dSAndrew Jones writel(1 << (cpu + 16) | irq, gicv2_dist_base() + GICD_SGIR); 49*2e2d471dSAndrew Jones } 50*2e2d471dSAndrew Jones 51*2e2d471dSAndrew Jones void gicv2_ipi_send_mask(int irq, const cpumask_t *dest) 52*2e2d471dSAndrew Jones { 53*2e2d471dSAndrew Jones u8 tlist = (u8)cpumask_bits(dest)[0]; 54*2e2d471dSAndrew Jones 55*2e2d471dSAndrew Jones assert(irq < 16); 56*2e2d471dSAndrew Jones writel(tlist << 16 | irq, gicv2_dist_base() + GICD_SGIR); 57*2e2d471dSAndrew Jones } 58