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 #define LOCAL_CONTROL 0x000 25 #define LOCAL_PRESCALER 0x008 26 27 /* 28 * The low 2 bits identify the CPU that the GPU IRQ goes to, and the 29 * next 2 bits identify the CPU that the GPU FIQ goes to. 30 */ 31 #define LOCAL_GPU_ROUTING 0x00c 32 /* When setting bits 0-3, enables PMU interrupts on that CPU. */ 33 #define LOCAL_PM_ROUTING_SET 0x010 34 /* When setting bits 0-3, disables PMU interrupts on that CPU. */ 35 #define LOCAL_PM_ROUTING_CLR 0x014 36 /* 37 * The low 4 bits of this are the CPU's timer IRQ enables, and the 38 * next 4 bits are the CPU's timer FIQ enables (which override the IRQ 39 * bits). 40 */ 41 #define LOCAL_TIMER_INT_CONTROL0 0x040 42 /* 43 * The low 4 bits of this are the CPU's per-mailbox IRQ enables, and 44 * the next 4 bits are the CPU's per-mailbox FIQ enables (which 45 * override the IRQ bits). 46 */ 47 #define LOCAL_MAILBOX_INT_CONTROL0 0x050 48 /* 49 * The CPU's interrupt status register. Bits are defined by the the 50 * LOCAL_IRQ_* bits below. 51 */ 52 #define LOCAL_IRQ_PENDING0 0x060 53 /* Same status bits as above, but for FIQ. */ 54 #define LOCAL_FIQ_PENDING0 0x070 55 /* 56 * Mailbox write-to-set bits. There are 16 mailboxes, 4 per CPU, and 57 * these bits are organized by mailbox number and then CPU number. We 58 * use mailbox 0 for IPIs. The mailbox's interrupt is raised while 59 * any bit is set. 60 */ 61 #define LOCAL_MAILBOX0_SET0 0x080 62 #define LOCAL_MAILBOX3_SET0 0x08c 63 /* Mailbox write-to-clear bits. */ 64 #define LOCAL_MAILBOX0_CLR0 0x0c0 65 #define LOCAL_MAILBOX3_CLR0 0x0cc 66 67 #define LOCAL_IRQ_CNTPSIRQ 0 68 #define LOCAL_IRQ_CNTPNSIRQ 1 69 #define LOCAL_IRQ_CNTHPIRQ 2 70 #define LOCAL_IRQ_CNTVIRQ 3 71 #define LOCAL_IRQ_MAILBOX0 4 72 #define LOCAL_IRQ_MAILBOX1 5 73 #define LOCAL_IRQ_MAILBOX2 6 74 #define LOCAL_IRQ_MAILBOX3 7 75 #define LOCAL_IRQ_GPU_FAST 8 76 #define LOCAL_IRQ_PMU_FAST 9 77 #define LAST_IRQ LOCAL_IRQ_PMU_FAST 78 79 struct bcm2836_arm_irqchip_intc { 80 struct irq_domain *domain; 81 void __iomem *base; 82 }; 83 84 static struct bcm2836_arm_irqchip_intc intc __read_mostly; 85 86 static void bcm2836_arm_irqchip_mask_per_cpu_irq(unsigned int reg_offset, 87 unsigned int bit, 88 int cpu) 89 { 90 void __iomem *reg = intc.base + reg_offset + 4 * cpu; 91 92 writel(readl(reg) & ~BIT(bit), reg); 93 } 94 95 static void bcm2836_arm_irqchip_unmask_per_cpu_irq(unsigned int reg_offset, 96 unsigned int bit, 97 int cpu) 98 { 99 void __iomem *reg = intc.base + reg_offset + 4 * cpu; 100 101 writel(readl(reg) | BIT(bit), reg); 102 } 103 104 static void bcm2836_arm_irqchip_mask_timer_irq(struct irq_data *d) 105 { 106 bcm2836_arm_irqchip_mask_per_cpu_irq(LOCAL_TIMER_INT_CONTROL0, 107 d->hwirq - LOCAL_IRQ_CNTPSIRQ, 108 smp_processor_id()); 109 } 110 111 static void bcm2836_arm_irqchip_unmask_timer_irq(struct irq_data *d) 112 { 113 bcm2836_arm_irqchip_unmask_per_cpu_irq(LOCAL_TIMER_INT_CONTROL0, 114 d->hwirq - LOCAL_IRQ_CNTPSIRQ, 115 smp_processor_id()); 116 } 117 118 static struct irq_chip bcm2836_arm_irqchip_timer = { 119 .name = "bcm2836-timer", 120 .irq_mask = bcm2836_arm_irqchip_mask_timer_irq, 121 .irq_unmask = bcm2836_arm_irqchip_unmask_timer_irq, 122 }; 123 124 static void bcm2836_arm_irqchip_mask_pmu_irq(struct irq_data *d) 125 { 126 writel(1 << smp_processor_id(), intc.base + LOCAL_PM_ROUTING_CLR); 127 } 128 129 static void bcm2836_arm_irqchip_unmask_pmu_irq(struct irq_data *d) 130 { 131 writel(1 << smp_processor_id(), intc.base + LOCAL_PM_ROUTING_SET); 132 } 133 134 static struct irq_chip bcm2836_arm_irqchip_pmu = { 135 .name = "bcm2836-pmu", 136 .irq_mask = bcm2836_arm_irqchip_mask_pmu_irq, 137 .irq_unmask = bcm2836_arm_irqchip_unmask_pmu_irq, 138 }; 139 140 static void bcm2836_arm_irqchip_mask_gpu_irq(struct irq_data *d) 141 { 142 } 143 144 static void bcm2836_arm_irqchip_unmask_gpu_irq(struct irq_data *d) 145 { 146 } 147 148 static struct irq_chip bcm2836_arm_irqchip_gpu = { 149 .name = "bcm2836-gpu", 150 .irq_mask = bcm2836_arm_irqchip_mask_gpu_irq, 151 .irq_unmask = bcm2836_arm_irqchip_unmask_gpu_irq, 152 }; 153 154 static void bcm2836_arm_irqchip_register_irq(int hwirq, struct irq_chip *chip) 155 { 156 int irq = irq_create_mapping(intc.domain, hwirq); 157 158 irq_set_percpu_devid(irq); 159 irq_set_chip_and_handler(irq, chip, handle_percpu_devid_irq); 160 irq_set_status_flags(irq, IRQ_NOAUTOEN); 161 } 162 163 static void 164 __exception_irq_entry bcm2836_arm_irqchip_handle_irq(struct pt_regs *regs) 165 { 166 int cpu = smp_processor_id(); 167 u32 stat; 168 169 stat = readl_relaxed(intc.base + LOCAL_IRQ_PENDING0 + 4 * cpu); 170 if (stat & BIT(LOCAL_IRQ_MAILBOX0)) { 171 #ifdef CONFIG_SMP 172 void __iomem *mailbox0 = (intc.base + 173 LOCAL_MAILBOX0_CLR0 + 16 * cpu); 174 u32 mbox_val = readl(mailbox0); 175 u32 ipi = ffs(mbox_val) - 1; 176 177 writel(1 << ipi, mailbox0); 178 handle_IPI(ipi, regs); 179 #endif 180 } else if (stat) { 181 u32 hwirq = ffs(stat) - 1; 182 183 handle_domain_irq(intc.domain, hwirq, regs); 184 } 185 } 186 187 #ifdef CONFIG_SMP 188 static void bcm2836_arm_irqchip_send_ipi(const struct cpumask *mask, 189 unsigned int ipi) 190 { 191 int cpu; 192 void __iomem *mailbox0_base = intc.base + LOCAL_MAILBOX0_SET0; 193 194 /* 195 * Ensure that stores to normal memory are visible to the 196 * other CPUs before issuing the IPI. 197 */ 198 smp_wmb(); 199 200 for_each_cpu(cpu, mask) { 201 writel(1 << ipi, mailbox0_base + 16 * cpu); 202 } 203 } 204 205 static int bcm2836_cpu_starting(unsigned int cpu) 206 { 207 bcm2836_arm_irqchip_unmask_per_cpu_irq(LOCAL_MAILBOX_INT_CONTROL0, 0, 208 cpu); 209 return 0; 210 } 211 212 static int bcm2836_cpu_dying(unsigned int cpu) 213 { 214 bcm2836_arm_irqchip_mask_per_cpu_irq(LOCAL_MAILBOX_INT_CONTROL0, 0, 215 cpu); 216 return 0; 217 } 218 219 #ifdef CONFIG_ARM 220 static int __init bcm2836_smp_boot_secondary(unsigned int cpu, 221 struct task_struct *idle) 222 { 223 unsigned long secondary_startup_phys = 224 (unsigned long)virt_to_phys((void *)secondary_startup); 225 226 writel(secondary_startup_phys, 227 intc.base + LOCAL_MAILBOX3_SET0 + 16 * cpu); 228 229 return 0; 230 } 231 232 static const struct smp_operations bcm2836_smp_ops __initconst = { 233 .smp_boot_secondary = bcm2836_smp_boot_secondary, 234 }; 235 #endif 236 #endif 237 238 static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = { 239 .xlate = irq_domain_xlate_onecell 240 }; 241 242 static void 243 bcm2836_arm_irqchip_smp_init(void) 244 { 245 #ifdef CONFIG_SMP 246 /* Unmask IPIs to the boot CPU. */ 247 cpuhp_setup_state(CPUHP_AP_IRQ_BCM2836_STARTING, 248 "AP_IRQ_BCM2836_STARTING", bcm2836_cpu_starting, 249 bcm2836_cpu_dying); 250 251 set_smp_cross_call(bcm2836_arm_irqchip_send_ipi); 252 253 #ifdef CONFIG_ARM 254 smp_set_ops(&bcm2836_smp_ops); 255 #endif 256 #endif 257 } 258 259 /* 260 * The LOCAL_IRQ_CNT* timer firings are based off of the external 261 * oscillator with some scaling. The firmware sets up CNTFRQ to 262 * report 19.2Mhz, but doesn't set up the scaling registers. 263 */ 264 static void bcm2835_init_local_timer_frequency(void) 265 { 266 /* 267 * Set the timer to source from the 19.2Mhz crystal clock (bit 268 * 8 unset), and only increment by 1 instead of 2 (bit 9 269 * unset). 270 */ 271 writel(0, intc.base + LOCAL_CONTROL); 272 273 /* 274 * Set the timer prescaler to 1:1 (timer freq = input freq * 275 * 2**31 / prescaler) 276 */ 277 writel(0x80000000, intc.base + LOCAL_PRESCALER); 278 } 279 280 static int __init bcm2836_arm_irqchip_l1_intc_of_init(struct device_node *node, 281 struct device_node *parent) 282 { 283 intc.base = of_iomap(node, 0); 284 if (!intc.base) { 285 panic("%s: unable to map local interrupt registers\n", 286 node->full_name); 287 } 288 289 bcm2835_init_local_timer_frequency(); 290 291 intc.domain = irq_domain_add_linear(node, LAST_IRQ + 1, 292 &bcm2836_arm_irqchip_intc_ops, 293 NULL); 294 if (!intc.domain) 295 panic("%s: unable to create IRQ domain\n", node->full_name); 296 297 bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTPSIRQ, 298 &bcm2836_arm_irqchip_timer); 299 bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTPNSIRQ, 300 &bcm2836_arm_irqchip_timer); 301 bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTHPIRQ, 302 &bcm2836_arm_irqchip_timer); 303 bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_CNTVIRQ, 304 &bcm2836_arm_irqchip_timer); 305 bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_GPU_FAST, 306 &bcm2836_arm_irqchip_gpu); 307 bcm2836_arm_irqchip_register_irq(LOCAL_IRQ_PMU_FAST, 308 &bcm2836_arm_irqchip_pmu); 309 310 bcm2836_arm_irqchip_smp_init(); 311 312 set_handle_irq(bcm2836_arm_irqchip_handle_irq); 313 return 0; 314 } 315 316 IRQCHIP_DECLARE(bcm2836_arm_irqchip_l1_intc, "brcm,bcm2836-l1-intc", 317 bcm2836_arm_irqchip_l1_intc_of_init); 318