1 /* 2 * Root interrupt controller for the BCM2836 (Raspberry Pi 2). 3 * 4 * Copyright 2015 Broadcom 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16 17 #include <linux/cpu.h> 18 #include <linux/of_address.h> 19 #include <linux/of_irq.h> 20 #include <linux/irqchip.h> 21 #include <linux/irqdomain.h> 22 #include <asm/exception.h> 23 24 /* 25 * The low 2 bits identify the CPU that the GPU IRQ goes to, and the 26 * next 2 bits identify the CPU that the GPU FIQ goes to. 27 */ 28 #define LOCAL_GPU_ROUTING 0x00c 29 /* When setting bits 0-3, enables PMU interrupts on that CPU. */ 30 #define LOCAL_PM_ROUTING_SET 0x010 31 /* When setting bits 0-3, disables PMU interrupts on that CPU. */ 32 #define LOCAL_PM_ROUTING_CLR 0x014 33 /* 34 * The low 4 bits of this are the CPU's timer IRQ enables, and the 35 * next 4 bits are the CPU's timer FIQ enables (which override the IRQ 36 * bits). 37 */ 38 #define LOCAL_TIMER_INT_CONTROL0 0x040 39 /* 40 * The low 4 bits of this are the CPU's per-mailbox IRQ enables, and 41 * the next 4 bits are the CPU's per-mailbox FIQ enables (which 42 * override the IRQ bits). 43 */ 44 #define LOCAL_MAILBOX_INT_CONTROL0 0x050 45 /* 46 * The CPU's interrupt status register. Bits are defined by the the 47 * LOCAL_IRQ_* bits below. 48 */ 49 #define LOCAL_IRQ_PENDING0 0x060 50 /* Same status bits as above, but for FIQ. */ 51 #define LOCAL_FIQ_PENDING0 0x070 52 /* 53 * Mailbox0 write-to-set bits. There are 16 mailboxes, 4 per CPU, and 54 * these bits are organized by mailbox number and then CPU number. We 55 * use mailbox 0 for IPIs. The mailbox's interrupt is raised while 56 * any bit is set. 57 */ 58 #define LOCAL_MAILBOX0_SET0 0x080 59 /* Mailbox0 write-to-clear bits. */ 60 #define LOCAL_MAILBOX0_CLR0 0x0c0 61 62 #define LOCAL_IRQ_CNTPSIRQ 0 63 #define LOCAL_IRQ_CNTPNSIRQ 1 64 #define LOCAL_IRQ_CNTHPIRQ 2 65 #define LOCAL_IRQ_CNTVIRQ 3 66 #define LOCAL_IRQ_MAILBOX0 4 67 #define LOCAL_IRQ_MAILBOX1 5 68 #define LOCAL_IRQ_MAILBOX2 6 69 #define LOCAL_IRQ_MAILBOX3 7 70 #define LOCAL_IRQ_GPU_FAST 8 71 #define LOCAL_IRQ_PMU_FAST 9 72 #define LAST_IRQ LOCAL_IRQ_PMU_FAST 73 74 struct bcm2836_arm_irqchip_intc { 75 struct irq_domain *domain; 76 void __iomem *base; 77 }; 78 79 static struct bcm2836_arm_irqchip_intc intc __read_mostly; 80 81 static void bcm2836_arm_irqchip_mask_per_cpu_irq(unsigned int reg_offset, 82 unsigned int bit, 83 int cpu) 84 { 85 void __iomem *reg = intc.base + reg_offset + 4 * cpu; 86 87 writel(readl(reg) & ~BIT(bit), reg); 88 } 89 90 static void bcm2836_arm_irqchip_unmask_per_cpu_irq(unsigned int reg_offset, 91 unsigned int bit, 92 int cpu) 93 { 94 void __iomem *reg = intc.base + reg_offset + 4 * cpu; 95 96 writel(readl(reg) | BIT(bit), reg); 97 } 98 99 static void bcm2836_arm_irqchip_mask_timer_irq(struct irq_data *d) 100 { 101 bcm2836_arm_irqchip_mask_per_cpu_irq(LOCAL_TIMER_INT_CONTROL0, 102 d->hwirq - LOCAL_IRQ_CNTPSIRQ, 103 smp_processor_id()); 104 } 105 106 static void bcm2836_arm_irqchip_unmask_timer_irq(struct irq_data *d) 107 { 108 bcm2836_arm_irqchip_unmask_per_cpu_irq(LOCAL_TIMER_INT_CONTROL0, 109 d->hwirq - LOCAL_IRQ_CNTPSIRQ, 110 smp_processor_id()); 111 } 112 113 static struct irq_chip bcm2836_arm_irqchip_timer = { 114 .name = "bcm2836-timer", 115 .irq_mask = bcm2836_arm_irqchip_mask_timer_irq, 116 .irq_unmask = bcm2836_arm_irqchip_unmask_timer_irq, 117 }; 118 119 static void bcm2836_arm_irqchip_mask_pmu_irq(struct irq_data *d) 120 { 121 writel(1 << smp_processor_id(), intc.base + LOCAL_PM_ROUTING_CLR); 122 } 123 124 static void bcm2836_arm_irqchip_unmask_pmu_irq(struct irq_data *d) 125 { 126 writel(1 << smp_processor_id(), intc.base + LOCAL_PM_ROUTING_SET); 127 } 128 129 static struct irq_chip bcm2836_arm_irqchip_pmu = { 130 .name = "bcm2836-pmu", 131 .irq_mask = bcm2836_arm_irqchip_mask_pmu_irq, 132 .irq_unmask = bcm2836_arm_irqchip_unmask_pmu_irq, 133 }; 134 135 static void bcm2836_arm_irqchip_mask_gpu_irq(struct irq_data *d) 136 { 137 } 138 139 static void bcm2836_arm_irqchip_unmask_gpu_irq(struct irq_data *d) 140 { 141 } 142 143 static struct irq_chip bcm2836_arm_irqchip_gpu = { 144 .name = "bcm2836-gpu", 145 .irq_mask = bcm2836_arm_irqchip_mask_gpu_irq, 146 .irq_unmask = bcm2836_arm_irqchip_unmask_gpu_irq, 147 }; 148 149 static void bcm2836_arm_irqchip_register_irq(int hwirq, struct irq_chip *chip) 150 { 151 int irq = irq_create_mapping(intc.domain, hwirq); 152 153 irq_set_percpu_devid(irq); 154 irq_set_chip_and_handler(irq, chip, handle_percpu_devid_irq); 155 irq_set_status_flags(irq, IRQ_NOAUTOEN); 156 } 157 158 static void 159 __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs) 160 { 161 int cpu = smp_processor_id(); 162 u32 stat; 163 164 stat = readl_relaxed(intc.base + LOCAL_IRQ_PENDING0 + 4 * cpu); 165 if (stat & 0x10) { 166 #ifdef CONFIG_SMP 167 void __iomem *mailbox0 = (intc.base + 168 LOCAL_MAILBOX0_CLR0 + 16 * cpu); 169 u32 mbox_val = readl(mailbox0); 170 u32 ipi = ffs(mbox_val) - 1; 171 172 writel(1 << ipi, mailbox0); 173 handle_IPI(ipi, regs); 174 #endif 175 } else { 176 u32 hwirq = ffs(stat) - 1; 177 178 handle_IRQ(irq_linear_revmap(intc.domain, hwirq), regs); 179 } 180 } 181 182 #ifdef CONFIG_SMP 183 static void bcm2836_arm_irqchip_send_ipi(const struct cpumask *mask, 184 unsigned int ipi) 185 { 186 int cpu; 187 void __iomem *mailbox0_base = intc.base + LOCAL_MAILBOX0_SET0; 188 189 /* 190 * Ensure that stores to normal memory are visible to the 191 * other CPUs before issuing the IPI. 192 */ 193 dsb(); 194 195 for_each_cpu(cpu, mask) { 196 writel(1 << ipi, mailbox0_base + 16 * cpu); 197 } 198 } 199 200 /* Unmasks the IPI on the CPU when it's online. */ 201 static int bcm2836_arm_irqchip_cpu_notify(struct notifier_block *nfb, 202 unsigned long action, void *hcpu) 203 { 204 unsigned int cpu = (unsigned long)hcpu; 205 unsigned int int_reg = LOCAL_MAILBOX_INT_CONTROL0; 206 unsigned int mailbox = 0; 207 208 if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) 209 bcm2836_arm_irqchip_unmask_per_cpu_irq(int_reg, mailbox, cpu); 210 else if (action == CPU_DYING) 211 bcm2836_arm_irqchip_mask_per_cpu_irq(int_reg, mailbox, cpu); 212 213 return NOTIFY_OK; 214 } 215 216 static struct notifier_block bcm2836_arm_irqchip_cpu_notifier = { 217 .notifier_call = bcm2836_arm_irqchip_cpu_notify, 218 .priority = 100, 219 }; 220 #endif 221 222 static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = { 223 .xlate = irq_domain_xlate_onecell 224 }; 225 226 static void 227 bcm2836_arm_irqchip_smp_init(void) 228 { 229 #ifdef CONFIG_SMP 230 /* Unmask IPIs to the boot CPU. */ 231 bcm2836_arm_irqchip_cpu_notify(&bcm2836_arm_irqchip_cpu_notifier, 232 CPU_STARTING, 233 (void *)smp_processor_id()); 234 register_cpu_notifier(&bcm2836_arm_irqchip_cpu_notifier); 235 236 set_smp_cross_call(bcm2836_arm_irqchip_send_ipi); 237 #endif 238 } 239 240 static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node, 241 struct device_node *parent) 242 { 243 intc.base = of_iomap(node, 0); 244 if (!intc.base) { 245 panic("%s: unable to map local interrupt registers\n", 246 node->full_name); 247 } 248 249 intc.domain = irq_domain_add_linear(node, LAST_IRQ + 1, 250 &bcm2836_arm_irqchip_intc_ops, 251 NULL); 252 if (!intc.domain) 253 panic("%s: unable to create IRQ domain\n", node->full_name); 254 255 bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTPSIRQ, 256 &bcm2836_arm_irqchip_timer); 257 bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTPNSIRQ, 258 &bcm2836_arm_irqchip_timer); 259 bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTHPIRQ, 260 &bcm2836_arm_irqchip_timer); 261 bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTVIRQ, 262 &bcm2836_arm_irqchip_timer); 263 bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_GPU_FAST, 264 &bcm2836_arm_irqchip_gpu); 265 bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_PMU_FAST, 266 &bcm2836_arm_irqchip_pmu); 267 268 bcm2836_arm_irqchip_smp_init(); 269 270 set_handle_irq(bcm2836_arm_irqchip_handle_irq); 271 return 0; 272 } 273 274 IRQCHIP_DECLARE(bcm2836_arm_irqchip_l1_intc, "brcm,bcm2836-l1-intc", 275 bcm2836_arm_irqchip_l1_intc_of_init); 276