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