linux/drivers/irqchip/irq-bcm2836.c
<<
>>
Prefs
   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
  79struct bcm2836_arm_irqchip_intc {
  80        struct irq_domain *domain;
  81        void __iomem *base;
  82};
  83
  84static struct bcm2836_arm_irqchip_intc intc  __read_mostly;
  85
  86static 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
  95static 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
 104static 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
 111static 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
 118static 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
 124static 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
 129static 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
 134static 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
 140static void bcm2836_arm_irqchip_mask_gpu_irq(struct irq_data *d)
 141{
 142}
 143
 144static void bcm2836_arm_irqchip_unmask_gpu_irq(struct irq_data *d)
 145{
 146}
 147
 148static 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
 154static 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
 163static 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
 188static 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
 205static 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
 212static 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
 220static 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
 232static const struct smp_operations bcm2836_smp_ops __initconst = {
 233        .smp_boot_secondary     = bcm2836_smp_boot_secondary,
 234};
 235#endif
 236#endif
 237
 238static const struct irq_domain_ops bcm2836_arm_irqchip_intc_ops = {
 239        .xlate = irq_domain_xlate_onecell
 240};
 241
 242static void
 243bcm2836_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                          "irqchip/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 */
 264static 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
 280static 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
 316IRQCHIP_DECLARE(bcm2836_arm_irqchip_l1_intc, "brcm,bcm2836-l1-intc",
 317                bcm2836_arm_irqchip_l1_intc_of_init);
 318