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