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
16 enum {
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
82 volatile 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
92 volatile 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
122 enum irqNumbers {
123 irqInvalid = 255
124 };
125
isIRQPending(void)126 static 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
ackInterrupt(UNUSED irq_t irq)136 static inline void ackInterrupt(UNUSED irq_t irq)
137 {
138 /* No way to ACK an interrupt */
139 }
140
handleSpuriousIRQ(void)141 static inline void handleSpuriousIRQ(void)
142 {
143 /* Nothing to do here */
144 }
145
146
147