1*91a6c3ceSAndrew Jones /* 2*91a6c3ceSAndrew Jones * All GIC* defines are lifted from include/linux/irqchip/arm-gic-v3.h 3*91a6c3ceSAndrew Jones * 4*91a6c3ceSAndrew Jones * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com> 5*91a6c3ceSAndrew Jones * 6*91a6c3ceSAndrew Jones * This work is licensed under the terms of the GNU LGPL, version 2. 7*91a6c3ceSAndrew Jones */ 8*91a6c3ceSAndrew Jones #ifndef _ASMARM_GIC_V3_H_ 9*91a6c3ceSAndrew Jones #define _ASMARM_GIC_V3_H_ 10*91a6c3ceSAndrew Jones 11*91a6c3ceSAndrew Jones #ifndef _ASMARM_GIC_H_ 12*91a6c3ceSAndrew Jones #error Do not directly include <asm/gic-v3.h>. Include <asm/gic.h> 13*91a6c3ceSAndrew Jones #endif 14*91a6c3ceSAndrew Jones 15*91a6c3ceSAndrew Jones /* 16*91a6c3ceSAndrew Jones * Distributor registers 17*91a6c3ceSAndrew Jones * 18*91a6c3ceSAndrew Jones * We expect to be run in Non-secure mode, thus we define the 19*91a6c3ceSAndrew Jones * group1 enable bits with respect to that view. 20*91a6c3ceSAndrew Jones */ 21*91a6c3ceSAndrew Jones #define GICD_CTLR_RWP (1U << 31) 22*91a6c3ceSAndrew Jones #define GICD_CTLR_ARE_NS (1U << 4) 23*91a6c3ceSAndrew Jones #define GICD_CTLR_ENABLE_G1A (1U << 1) 24*91a6c3ceSAndrew Jones #define GICD_CTLR_ENABLE_G1 (1U << 0) 25*91a6c3ceSAndrew Jones 26*91a6c3ceSAndrew Jones /* Re-Distributor registers, offsets from RD_base */ 27*91a6c3ceSAndrew Jones #define GICR_TYPER 0x0008 28*91a6c3ceSAndrew Jones 29*91a6c3ceSAndrew Jones #define GICR_TYPER_LAST (1U << 4) 30*91a6c3ceSAndrew Jones 31*91a6c3ceSAndrew Jones /* Re-Distributor registers, offsets from SGI_base */ 32*91a6c3ceSAndrew Jones #define GICR_IGROUPR0 GICD_IGROUPR 33*91a6c3ceSAndrew Jones #define GICR_ISENABLER0 GICD_ISENABLER 34*91a6c3ceSAndrew Jones #define GICR_IPRIORITYR0 GICD_IPRIORITYR 35*91a6c3ceSAndrew Jones 36*91a6c3ceSAndrew Jones #include <asm/arch_gicv3.h> 37*91a6c3ceSAndrew Jones 38*91a6c3ceSAndrew Jones #ifndef __ASSEMBLY__ 39*91a6c3ceSAndrew Jones #include <asm/setup.h> 40*91a6c3ceSAndrew Jones #include <asm/processor.h> 41*91a6c3ceSAndrew Jones #include <asm/delay.h> 42*91a6c3ceSAndrew Jones #include <asm/smp.h> 43*91a6c3ceSAndrew Jones #include <asm/io.h> 44*91a6c3ceSAndrew Jones 45*91a6c3ceSAndrew Jones struct gicv3_data { 46*91a6c3ceSAndrew Jones void *dist_base; 47*91a6c3ceSAndrew Jones void *redist_base[NR_CPUS]; 48*91a6c3ceSAndrew Jones unsigned int irq_nr; 49*91a6c3ceSAndrew Jones }; 50*91a6c3ceSAndrew Jones extern struct gicv3_data gicv3_data; 51*91a6c3ceSAndrew Jones 52*91a6c3ceSAndrew Jones #define gicv3_dist_base() (gicv3_data.dist_base) 53*91a6c3ceSAndrew Jones #define gicv3_redist_base() (gicv3_data.redist_base[smp_processor_id()]) 54*91a6c3ceSAndrew Jones #define gicv3_sgi_base() (gicv3_data.redist_base[smp_processor_id()] + SZ_64K) 55*91a6c3ceSAndrew Jones 56*91a6c3ceSAndrew Jones extern int gicv3_init(void); 57*91a6c3ceSAndrew Jones extern void gicv3_enable_defaults(void); 58*91a6c3ceSAndrew Jones extern void gicv3_set_redist_base(size_t stride); 59*91a6c3ceSAndrew Jones 60*91a6c3ceSAndrew Jones static inline void gicv3_do_wait_for_rwp(void *base) 61*91a6c3ceSAndrew Jones { 62*91a6c3ceSAndrew Jones int count = 100000; /* 1s */ 63*91a6c3ceSAndrew Jones 64*91a6c3ceSAndrew Jones while (readl(base + GICD_CTLR) & GICD_CTLR_RWP) { 65*91a6c3ceSAndrew Jones if (!--count) { 66*91a6c3ceSAndrew Jones printf("GICv3: RWP timeout!\n"); 67*91a6c3ceSAndrew Jones abort(); 68*91a6c3ceSAndrew Jones } 69*91a6c3ceSAndrew Jones cpu_relax(); 70*91a6c3ceSAndrew Jones udelay(10); 71*91a6c3ceSAndrew Jones }; 72*91a6c3ceSAndrew Jones } 73*91a6c3ceSAndrew Jones 74*91a6c3ceSAndrew Jones static inline void gicv3_dist_wait_for_rwp(void) 75*91a6c3ceSAndrew Jones { 76*91a6c3ceSAndrew Jones gicv3_do_wait_for_rwp(gicv3_dist_base()); 77*91a6c3ceSAndrew Jones } 78*91a6c3ceSAndrew Jones 79*91a6c3ceSAndrew Jones static inline void gicv3_redist_wait_for_uwp(void) 80*91a6c3ceSAndrew Jones { 81*91a6c3ceSAndrew Jones /* 82*91a6c3ceSAndrew Jones * We can build on gic_do_wait_for_rwp, which uses GICD_ registers 83*91a6c3ceSAndrew Jones * because GICD_CTLR == GICR_CTLR and GICD_CTLR_RWP == GICR_CTLR_UWP 84*91a6c3ceSAndrew Jones */ 85*91a6c3ceSAndrew Jones gicv3_do_wait_for_rwp(gicv3_redist_base()); 86*91a6c3ceSAndrew Jones } 87*91a6c3ceSAndrew Jones 88*91a6c3ceSAndrew Jones static inline u32 mpidr_compress(u64 mpidr) 89*91a6c3ceSAndrew Jones { 90*91a6c3ceSAndrew Jones u64 compressed = mpidr & MPIDR_HWID_BITMASK; 91*91a6c3ceSAndrew Jones 92*91a6c3ceSAndrew Jones compressed = (((compressed >> 32) & 0xff) << 24) | compressed; 93*91a6c3ceSAndrew Jones return compressed; 94*91a6c3ceSAndrew Jones } 95*91a6c3ceSAndrew Jones 96*91a6c3ceSAndrew Jones static inline u64 mpidr_uncompress(u32 compressed) 97*91a6c3ceSAndrew Jones { 98*91a6c3ceSAndrew Jones u64 mpidr = ((u64)compressed >> 24) << 32; 99*91a6c3ceSAndrew Jones 100*91a6c3ceSAndrew Jones mpidr |= compressed & MPIDR_HWID_BITMASK; 101*91a6c3ceSAndrew Jones return mpidr; 102*91a6c3ceSAndrew Jones } 103*91a6c3ceSAndrew Jones 104*91a6c3ceSAndrew Jones #endif /* !__ASSEMBLY__ */ 105*91a6c3ceSAndrew Jones #endif /* _ASMARM_GIC_V3_H_ */ 106