1/* 2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7#pragma once 8 9#include <plat/machine/devices_gen.h> 10#include <machine/io.h> 11#include <machine/interrupt.h> 12 13#define BASIC_IRQ_OFFSET 32 14#define NORMAL_IRQ_OFFSET (BASIC_IRQ_OFFSET + 32) 15 16enum { 17 INTERRUPT_CORE_CNTPSIRQ = 0, 18 INTERRUPT_CORE_CNTPNSIRQ = 1, 19 INTERRUPT_CORE_CNTHPIRQ = 2, 20 INTERRUPT_CORE_CNTVIRQ = 3, 21 INTERRUPT_CORE_MAILBOX_0 = 4, 22 INTERRUPT_CORE_MAILBOX_1 = 5, 23 INTERRUPT_CORE_MAILBOX_2 = 6, 24 INTERRUPT_CORE_MAILBOX_3 = 7, 25 INTERRUPT_CORE_GPU = 8, 26 INTERRUPT_CORE_PMU = 9, 27 INTERRUPT_CORE_AXI = 10, 28 INTERRUPT_CORE_LOCAL_TIMER = 11, 29 //17:12 Peripheral 1..15 interrupt (Currently not used) 30 //31:28 <Reserved> 31 32 INTERRUPT_BASIC_IRQ_ARM_TIMER = (BASIC_IRQ_OFFSET + 0), 33 INTERRUPT_BASIC_IRQ_ARM_MAILBOX = (BASIC_IRQ_OFFSET + 1), 34 INTERRUPT_BASIC_IRQ_ARM_DOORBELL0 = (BASIC_IRQ_OFFSET + 2), 35 INTERRUPT_BASIC_IRQ_ARM_DOORBELL1 = (BASIC_IRQ_OFFSET + 3), 36 INTERRUPT_BASIC_IRQ_GPU0_HALTED = (BASIC_IRQ_OFFSET + 4), 37 INTERRUPT_BASIC_IRQ_GPU1_HALTED = (BASIC_IRQ_OFFSET + 5), 38 INTERRUPT_BASIC_IRQ_ILLEGAL_ACCESS_TYPE1 = (BASIC_IRQ_OFFSET + 6), 39 INTERRUPT_BASIC_IRQ_ILLEGAL_ACCESS_TYPE0 = (BASIC_IRQ_OFFSET + 7), 40 INTERRUPT_BASIC_IRQ_PENDING_REGISTER1 = (BASIC_IRQ_OFFSET + 8), 41 INTERRUPT_BASIC_IRQ_PENDING_REGISTER2 = (BASIC_IRQ_OFFSET + 9), 42 INTERRUPT_BASIC_IRQ_GPU_IRQ_7 = (BASIC_IRQ_OFFSET + 10), 43 INTERRUPT_BASIC_IRQ_GPU_IRQ_9 = (BASIC_IRQ_OFFSET + 11), 44 INTERRUPT_BASIC_IRQ_GPU_IRQ_10 = (BASIC_IRQ_OFFSET + 12), 45 INTERRUPT_BASIC_IRQ_GPU_IRQ_18 = (BASIC_IRQ_OFFSET + 13), 46 INTERRUPT_BASIC_IRQ_GPU_IRQ_19 = (BASIC_IRQ_OFFSET + 14), 47 INTERRUPT_BASIC_IRQ_GPU_IRQ_53 = (BASIC_IRQ_OFFSET + 15), 48 INTERRUPT_BASIC_IRQ_GPU_IRQ_54 = (BASIC_IRQ_OFFSET + 16), 49 INTERRUPT_BASIC_IRQ_GPU_IRQ_55 = (BASIC_IRQ_OFFSET + 17), 50 INTERRUPT_BASIC_IRQ_GPU_IRQ_56 = (BASIC_IRQ_OFFSET + 18), 51 INTERRUPT_BASIC_IRQ_GPU_IRQ_57 = (BASIC_IRQ_OFFSET + 19), 52 INTERRUPT_BASIC_IRQ_GPU_IRQ_62 = (BASIC_IRQ_OFFSET + 20), 53 // 31:21 <unused> 54 55 INTERRUPT_IRQ_AUX = (NORMAL_IRQ_OFFSET + 29), 56 INTERRUPT_IRQ_I2C_SPI_SLV = (NORMAL_IRQ_OFFSET + 43), 57 INTERRUPT_IRQ_PWA0 = (NORMAL_IRQ_OFFSET + 45), 58 INTERRUPT_IRQ_PWA1 = (NORMAL_IRQ_OFFSET + 46), 59 INTERRUPT_IRQ_SMI = (NORMAL_IRQ_OFFSET + 48), 60 INTERRUPT_IRQ_GPIO0 = (NORMAL_IRQ_OFFSET + 49), 61 INTERRUPT_IRQ_GPIO1 = (NORMAL_IRQ_OFFSET + 50), 62 INTERRUPT_IRQ_GPIO2 = (NORMAL_IRQ_OFFSET + 51), 63 INTERRUPT_IRQ_GPIO3 = (NORMAL_IRQ_OFFSET + 52), 64 INTERRUPT_IRQ_I2C = (NORMAL_IRQ_OFFSET + 53), 65 INTERRUPT_IRQ_SPI = (NORMAL_IRQ_OFFSET + 54), 66 INTERRUPT_IRQ_PCM = (NORMAL_IRQ_OFFSET + 55), 67 INTERRUPT_IRQ_UART = (NORMAL_IRQ_OFFSET + 57), 68}; 69 70#define FIQCTRL_FIQ_ENABLE BIT(7) 71#define FIQCTRL_FIQ_SRC_GPU_IRQ(x) (x) 72#define FIQCTRL_FIQ_SRC_ARM_TIMER 64 73#define FIQCTRL_FIQ_SRC_ARM_MAILBOX 65 74#define FIQCTRL_FIQ_SRC_ARM_DOORBELL0 66 75#define FIQCTRL_FIQ_SRC_ARM_DOORBELL1 67 76#define FIQCTRL_FIQ_SRC_GPU0_HALTED 68 77#define FIQCTRL_FIQ_SRC_GPU1_HALTED 69 78#define FIQCTRL_FIQ_SRC_ILLEGAL_ACCESS_TYPE1 70 79#define FIQCTRL_FIQ_SRC_ILLEGAL_ACCESS_TYPE0 71 80#define FIQCTRL_FIQ_SRC(src) (FIQCTRL_FIQ_SRC_##src) 81 82volatile struct intc_regs { 83 uint32_t bfIRQBasicPending; /* 0x200 R */ 84 uint32_t bfGPUIRQPending[2]; /* 0x204 R */ 85 uint32_t FIQ_control; /* 0x20C R/W */ 86 uint32_t bfEnableIRQs[2]; /* 0x210 R/Wbs */ 87 uint32_t bfEnableBasicIRQs; /* 0x218 R/Wbs */ 88 uint32_t bfDisableIRQs[2]; /* 0x21C R/Wbc */ 89 uint32_t bfDisableBasicIRQs; /* 0x224 R/Wbc */ 90} *intc_regs = (volatile struct intc_regs *)INTC_PPTR; 91 92volatile struct core_regs { 93 uint32_t controlRegister; /* 0x00 */ 94 uint32_t unused0; /* 0x04 */ 95 uint32_t coreTimerPrescaler; /* 0x08 */ 96 uint32_t gpuInterruptsRouting; /* 0x0C */ 97 uint32_t pmirSet; /* 0x10 */ 98 uint32_t pmirClear; /* 0x14 */ 99 uint32_t unused1; /* 0x18 */ 100 uint32_t coreTimerAccessLS; /* 0x1C */ 101 uint32_t coreTimerAccessMS; /* 0x20 */ 102 uint32_t localInterrupt0Routing; /* 0x24 */ 103 uint32_t unused2; /* 0x28 */ 104 uint32_t axiOutstandingCounters; /* 0x2C */ 105 uint32_t axiOutstandingIRQ; /* 0x30 */ 106 uint32_t localTimerCtl; /* 0x34 */ 107 uint32_t localTimerFlags; /* 0x38 */ 108 uint32_t unused3; /* 0x3C */ 109 uint32_t coreTimersIrqCtrl[4]; /* 0x40 Timers interrupt control registers */ 110 uint32_t coreMailboxesIrqCtrl[4]; /* 0x50 Mailbox interrupt control */ 111 uint32_t coreIRQSource[4]; /* 0x60 IRQ source registers */ 112 uint32_t coreFIQSource[4]; /* 0x70 FIQ source registers */ 113 uint32_t coreMailboxWriteset[4][4]; /* 0x80 Mailbox write-set registers (Write only) */ 114 uint32_t coreMailboxRW[4][4]; /* 0xC0 Mailbox write-clear registers (Read & Write) */ 115} *core_regs = (volatile struct core_regs *) ARM_LOCAL_PPTR; 116 117#define LOCAL_TIMER_IRQ_STATUS 31 118#define LOCAL_TIMER_CTRL_IRQ_BIT 29 119#define LOCAL_TIMER_CTRL_EN_BIT 28 120#define LOCAL_TIMER_CTRL_RL_MASK MASK(28) 121 122enum irqNumbers { 123 irqInvalid = 255 124}; 125 126static inline bool_t isIRQPending(void) 127{ 128 uint32_t pending; 129 pending = core_regs->coreIRQSource[0]; 130 131 /* Mask out invalid bits */ 132 pending &= MASK(12); 133 return pending != 0; 134} 135 136static inline void ackInterrupt(UNUSED irq_t irq) 137{ 138 /* No way to ACK an interrupt */ 139} 140 141static inline void handleSpuriousIRQ(void) 142{ 143 /* Nothing to do here */ 144} 145 146 147