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