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 0x0000 22 #define GICD_CTLR_RWP (1U << 31) 23 #define GICD_CTLR_nASSGIreq (1U << 8) 24 #define GICD_CTLR_ARE_NS (1U << 4) 25 #define GICD_CTLR_ENABLE_G1A (1U << 1) 26 #define GICD_CTLR_ENABLE_G1 (1U << 0) 27 28 #define GICD_TYPER2_nASSGIcap (1U << 8) 29 30 /* Re-Distributor registers, offsets from RD_base */ 31 #define GICR_TYPER 0x0008 32 33 #define GICR_TYPER_LAST (1U << 4) 34 35 /* Re-Distributor registers, offsets from SGI_base */ 36 #define GICR_IGROUPR0 GICD_IGROUPR 37 #define GICR_ISENABLER0 GICD_ISENABLER 38 #define GICR_ICENABLER0 GICD_ICENABLER 39 #define GICR_ISPENDR0 GICD_ISPENDR 40 #define GICR_ICPENDR0 GICD_ICPENDR 41 #define GICR_ISACTIVER0 GICD_ISACTIVER 42 #define GICR_ICACTIVER0 GICD_ICACTIVER 43 #define GICR_IPRIORITYR0 GICD_IPRIORITYR 44 45 #define GICR_PROPBASER 0x0070 46 #define GICR_PENDBASER 0x0078 47 #define GICR_CTLR GICD_CTLR 48 #define GICR_CTLR_ENABLE_LPIS (1UL << 0) 49 50 #define ICC_SGI1R_AFFINITY_1_SHIFT 16 51 #define ICC_SGI1R_AFFINITY_2_SHIFT 32 52 #define ICC_SGI1R_AFFINITY_3_SHIFT 48 53 #define MPIDR_TO_SGI_AFFINITY(cluster_id, level) \ 54 (MPIDR_AFFINITY_LEVEL(cluster_id, level) << ICC_SGI1R_AFFINITY_## level ## _SHIFT) 55 56 #define GICR_PENDBASER_PTZ BIT_ULL(62) 57 58 #define LPI_PROP_GROUP1 (1 << 1) 59 #define LPI_PROP_ENABLED (1 << 0) 60 #define LPI_PROP_DEFAULT_PRIO 0xa0 61 #define LPI_PROP_DEFAULT (LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1 | LPI_PROP_ENABLED) 62 63 #define LPI_ID_BASE 8192 64 #define LPI(lpi) ((lpi) + LPI_ID_BASE) 65 #define LPI_OFFSET(intid) ((intid) - LPI_ID_BASE) 66 67 #include <asm/arch_gicv3.h> 68 69 #ifndef __ASSEMBLY__ 70 #include <cpumask.h> 71 #include <asm/setup.h> 72 #include <asm/processor.h> 73 #include <asm/delay.h> 74 #include <asm/smp.h> 75 #include <asm/io.h> 76 77 #define GICV3_NR_REDISTS 8 78 79 struct gicv3_data { 80 void *dist_base; 81 void *redist_bases[GICV3_NR_REDISTS]; 82 void *redist_base[NR_CPUS]; 83 u8 *lpi_prop; 84 void *lpi_pend[NR_CPUS]; 85 unsigned int irq_nr; 86 }; 87 extern struct gicv3_data gicv3_data; 88 89 #define gicv3_dist_base() (gicv3_data.dist_base) 90 #define gicv3_redist_base() (gicv3_data.redist_base[smp_processor_id()]) 91 #define gicv3_sgi_base() (gicv3_data.redist_base[smp_processor_id()] + SZ_64K) 92 93 extern int gicv3_init(void); 94 extern void gicv3_enable_defaults(void); 95 extern u32 gicv3_read_iar(void); 96 extern u32 gicv3_iar_irqnr(u32 iar); 97 extern void gicv3_write_eoir(u32 irqstat); 98 extern void gicv3_ipi_send_single(int irq, int cpu); 99 extern void gicv3_ipi_send_mask(int irq, const cpumask_t *dest); 100 extern void gicv3_set_redist_base(size_t stride); 101 extern void gicv3_lpi_set_clr_pending(int rdist, int n, bool set); 102 extern void gicv3_lpi_alloc_tables(void); 103 extern void gicv3_lpi_rdist_enable(int redist); 104 extern void gicv3_lpi_rdist_disable(int redist); 105 106 static inline void gicv3_do_wait_for_rwp(void *base) 107 { 108 int count = 100000; /* 1s */ 109 110 while (readl(base + GICD_CTLR) & GICD_CTLR_RWP) { 111 if (!--count) { 112 printf("GICv3: RWP timeout!\n"); 113 abort(); 114 } 115 cpu_relax(); 116 udelay(10); 117 }; 118 } 119 120 static inline void gicv3_dist_wait_for_rwp(void) 121 { 122 gicv3_do_wait_for_rwp(gicv3_dist_base()); 123 } 124 125 static inline void gicv3_redist_wait_for_uwp(void) 126 { 127 /* 128 * We can build on gic_do_wait_for_rwp, which uses GICD_ registers 129 * because GICD_CTLR == GICR_CTLR and GICD_CTLR_RWP == GICR_CTLR_UWP 130 */ 131 gicv3_do_wait_for_rwp(gicv3_redist_base()); 132 } 133 134 static inline u32 mpidr_compress(u64 mpidr) 135 { 136 u64 compressed = mpidr & MPIDR_HWID_BITMASK; 137 138 compressed = (((compressed >> 32) & 0xff) << 24) | compressed; 139 return compressed; 140 } 141 142 static inline u64 mpidr_uncompress(u32 compressed) 143 { 144 u64 mpidr = ((u64)compressed >> 24) << 32; 145 146 mpidr |= compressed & MPIDR_HWID_BITMASK; 147 return mpidr; 148 } 149 150 #define gicv3_lpi_set_config(intid, value) ({ \ 151 gicv3_data.lpi_prop[LPI_OFFSET(intid)] = value; \ 152 }) 153 154 #define gicv3_lpi_get_config(intid) (gicv3_data.lpi_prop[LPI_OFFSET(intid)]) 155 156 #endif /* !__ASSEMBLY__ */ 157 #endif /* _ASMARM_GIC_V3_H_ */ 158