1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun ** atariints.h -- Atari Linux interrupt handling structs and prototypes
3*4882a593Smuzhiyun **
4*4882a593Smuzhiyun ** Copyright 1994 by Björn Brauel
5*4882a593Smuzhiyun **
6*4882a593Smuzhiyun ** 5/2/94 Roman Hodek:
7*4882a593Smuzhiyun ** TT interrupt definitions added.
8*4882a593Smuzhiyun **
9*4882a593Smuzhiyun ** 12/02/96: (Roman)
10*4882a593Smuzhiyun ** Adapted to new int handling scheme (see ataints.c); revised numbering
11*4882a593Smuzhiyun **
12*4882a593Smuzhiyun ** This file is subject to the terms and conditions of the GNU General Public
13*4882a593Smuzhiyun ** License. See the file COPYING in the main directory of this archive
14*4882a593Smuzhiyun ** for more details.
15*4882a593Smuzhiyun **
16*4882a593Smuzhiyun */
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #ifndef _LINUX_ATARIINTS_H_
19*4882a593Smuzhiyun #define _LINUX_ATARIINTS_H_
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun #include <asm/irq.h>
22*4882a593Smuzhiyun #include <asm/atarihw.h>
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun /*
25*4882a593Smuzhiyun ** Atari Interrupt sources.
26*4882a593Smuzhiyun **
27*4882a593Smuzhiyun */
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #define STMFP_SOURCE_BASE 8
30*4882a593Smuzhiyun #define TTMFP_SOURCE_BASE 24
31*4882a593Smuzhiyun #define SCC_SOURCE_BASE 40
32*4882a593Smuzhiyun #define VME_SOURCE_BASE 56
33*4882a593Smuzhiyun #define VME_MAX_SOURCES 16
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun #define NUM_ATARI_SOURCES 141
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun /* convert vector number to int source number */
38*4882a593Smuzhiyun #define IRQ_VECTOR_TO_SOURCE(v) ((v) - ((v) < 0x20 ? 0x18 : (0x40-8)))
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun /* convert irq_handler index to vector number */
41*4882a593Smuzhiyun #define IRQ_SOURCE_TO_VECTOR(i) ((i) + ((i) < 8 ? 0x18 : (0x40-8)))
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun /* ST-MFP interrupts */
44*4882a593Smuzhiyun #define IRQ_MFP_BUSY (8)
45*4882a593Smuzhiyun #define IRQ_MFP_DCD (9)
46*4882a593Smuzhiyun #define IRQ_MFP_CTS (10)
47*4882a593Smuzhiyun #define IRQ_MFP_GPU (11)
48*4882a593Smuzhiyun #define IRQ_MFP_TIMD (12)
49*4882a593Smuzhiyun #define IRQ_MFP_TIMC (13)
50*4882a593Smuzhiyun #define IRQ_MFP_ACIA (14)
51*4882a593Smuzhiyun #define IRQ_MFP_FDC (15)
52*4882a593Smuzhiyun #define IRQ_MFP_ACSI IRQ_MFP_FDC
53*4882a593Smuzhiyun #define IRQ_MFP_FSCSI IRQ_MFP_FDC
54*4882a593Smuzhiyun #define IRQ_MFP_IDE IRQ_MFP_FDC
55*4882a593Smuzhiyun #define IRQ_MFP_TIMB (16)
56*4882a593Smuzhiyun #define IRQ_MFP_SERERR (17)
57*4882a593Smuzhiyun #define IRQ_MFP_SEREMPT (18)
58*4882a593Smuzhiyun #define IRQ_MFP_RECERR (19)
59*4882a593Smuzhiyun #define IRQ_MFP_RECFULL (20)
60*4882a593Smuzhiyun #define IRQ_MFP_TIMA (21)
61*4882a593Smuzhiyun #define IRQ_MFP_RI (22)
62*4882a593Smuzhiyun #define IRQ_MFP_MMD (23)
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun /* TT-MFP interrupts */
65*4882a593Smuzhiyun #define IRQ_TT_MFP_IO0 (24)
66*4882a593Smuzhiyun #define IRQ_TT_MFP_IO1 (25)
67*4882a593Smuzhiyun #define IRQ_TT_MFP_SCC (26)
68*4882a593Smuzhiyun #define IRQ_TT_MFP_RI (27)
69*4882a593Smuzhiyun #define IRQ_TT_MFP_TIMD (28)
70*4882a593Smuzhiyun #define IRQ_TT_MFP_TIMC (29)
71*4882a593Smuzhiyun #define IRQ_TT_MFP_DRVRDY (30)
72*4882a593Smuzhiyun #define IRQ_TT_MFP_SCSIDMA (31)
73*4882a593Smuzhiyun #define IRQ_TT_MFP_TIMB (32)
74*4882a593Smuzhiyun #define IRQ_TT_MFP_SERERR (33)
75*4882a593Smuzhiyun #define IRQ_TT_MFP_SEREMPT (34)
76*4882a593Smuzhiyun #define IRQ_TT_MFP_RECERR (35)
77*4882a593Smuzhiyun #define IRQ_TT_MFP_RECFULL (36)
78*4882a593Smuzhiyun #define IRQ_TT_MFP_TIMA (37)
79*4882a593Smuzhiyun #define IRQ_TT_MFP_RTC (38)
80*4882a593Smuzhiyun #define IRQ_TT_MFP_SCSI (39)
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun /* SCC interrupts */
83*4882a593Smuzhiyun #define IRQ_SCCB_TX (40)
84*4882a593Smuzhiyun #define IRQ_SCCB_STAT (42)
85*4882a593Smuzhiyun #define IRQ_SCCB_RX (44)
86*4882a593Smuzhiyun #define IRQ_SCCB_SPCOND (46)
87*4882a593Smuzhiyun #define IRQ_SCCA_TX (48)
88*4882a593Smuzhiyun #define IRQ_SCCA_STAT (50)
89*4882a593Smuzhiyun #define IRQ_SCCA_RX (52)
90*4882a593Smuzhiyun #define IRQ_SCCA_SPCOND (54)
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun /* shared MFP timer D interrupts - hires timer for EtherNEC et al. */
93*4882a593Smuzhiyun #define IRQ_MFP_TIMER1 (64)
94*4882a593Smuzhiyun #define IRQ_MFP_TIMER2 (65)
95*4882a593Smuzhiyun #define IRQ_MFP_TIMER3 (66)
96*4882a593Smuzhiyun #define IRQ_MFP_TIMER4 (67)
97*4882a593Smuzhiyun #define IRQ_MFP_TIMER5 (68)
98*4882a593Smuzhiyun #define IRQ_MFP_TIMER6 (69)
99*4882a593Smuzhiyun #define IRQ_MFP_TIMER7 (70)
100*4882a593Smuzhiyun #define IRQ_MFP_TIMER8 (71)
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun #define INT_CLK 24576 /* CLK while int_clk =2.456MHz and divide = 100 */
103*4882a593Smuzhiyun #define INT_TICKS 246 /* to make sched_time = 99.902... HZ */
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun #define MFP_ENABLE 0
107*4882a593Smuzhiyun #define MFP_PENDING 1
108*4882a593Smuzhiyun #define MFP_SERVICE 2
109*4882a593Smuzhiyun #define MFP_MASK 3
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun /* Utility functions for setting/clearing bits in the interrupt registers of
112*4882a593Smuzhiyun * the MFP. 'type' should be constant, if 'irq' is constant, too, code size is
113*4882a593Smuzhiyun * reduced. set_mfp_bit() is nonsense for PENDING and SERVICE registers. */
114*4882a593Smuzhiyun
get_mfp_bit(unsigned irq,int type)115*4882a593Smuzhiyun static inline int get_mfp_bit( unsigned irq, int type )
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun { unsigned char mask, *reg;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun mask = 1 << (irq & 7);
120*4882a593Smuzhiyun reg = (unsigned char *)&st_mfp.int_en_a + type*4 +
121*4882a593Smuzhiyun ((irq & 8) >> 2) + (((irq-8) & 16) << 3);
122*4882a593Smuzhiyun return( *reg & mask );
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun
set_mfp_bit(unsigned irq,int type)125*4882a593Smuzhiyun static inline void set_mfp_bit( unsigned irq, int type )
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun { unsigned char mask, *reg;
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun mask = 1 << (irq & 7);
130*4882a593Smuzhiyun reg = (unsigned char *)&st_mfp.int_en_a + type*4 +
131*4882a593Smuzhiyun ((irq & 8) >> 2) + (((irq-8) & 16) << 3);
132*4882a593Smuzhiyun __asm__ __volatile__ ( "orb %0,%1"
133*4882a593Smuzhiyun : : "di" (mask), "m" (*reg) : "memory" );
134*4882a593Smuzhiyun }
135*4882a593Smuzhiyun
clear_mfp_bit(unsigned irq,int type)136*4882a593Smuzhiyun static inline void clear_mfp_bit( unsigned irq, int type )
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun { unsigned char mask, *reg;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun mask = ~(1 << (irq & 7));
141*4882a593Smuzhiyun reg = (unsigned char *)&st_mfp.int_en_a + type*4 +
142*4882a593Smuzhiyun ((irq & 8) >> 2) + (((irq-8) & 16) << 3);
143*4882a593Smuzhiyun if (type == MFP_PENDING || type == MFP_SERVICE)
144*4882a593Smuzhiyun __asm__ __volatile__ ( "moveb %0,%1"
145*4882a593Smuzhiyun : : "di" (mask), "m" (*reg) : "memory" );
146*4882a593Smuzhiyun else
147*4882a593Smuzhiyun __asm__ __volatile__ ( "andb %0,%1"
148*4882a593Smuzhiyun : : "di" (mask), "m" (*reg) : "memory" );
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun /*
152*4882a593Smuzhiyun * {en,dis}able_irq have the usual semantics of temporary blocking the
153*4882a593Smuzhiyun * interrupt, but not losing requests that happen between disabling and
154*4882a593Smuzhiyun * enabling. This is done with the MFP mask registers.
155*4882a593Smuzhiyun */
156*4882a593Smuzhiyun
atari_enable_irq(unsigned irq)157*4882a593Smuzhiyun static inline void atari_enable_irq( unsigned irq )
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
161*4882a593Smuzhiyun set_mfp_bit( irq, MFP_MASK );
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun
atari_disable_irq(unsigned irq)164*4882a593Smuzhiyun static inline void atari_disable_irq( unsigned irq )
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
168*4882a593Smuzhiyun clear_mfp_bit( irq, MFP_MASK );
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun /*
172*4882a593Smuzhiyun * In opposite to {en,dis}able_irq, requests between turn{off,on}_irq are not
173*4882a593Smuzhiyun * "stored"
174*4882a593Smuzhiyun */
175*4882a593Smuzhiyun
atari_turnon_irq(unsigned irq)176*4882a593Smuzhiyun static inline void atari_turnon_irq( unsigned irq )
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
180*4882a593Smuzhiyun set_mfp_bit( irq, MFP_ENABLE );
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun
atari_turnoff_irq(unsigned irq)183*4882a593Smuzhiyun static inline void atari_turnoff_irq( unsigned irq )
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
187*4882a593Smuzhiyun clear_mfp_bit( irq, MFP_ENABLE );
188*4882a593Smuzhiyun clear_mfp_bit( irq, MFP_PENDING );
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun
atari_clear_pending_irq(unsigned irq)191*4882a593Smuzhiyun static inline void atari_clear_pending_irq( unsigned irq )
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun {
194*4882a593Smuzhiyun if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
195*4882a593Smuzhiyun clear_mfp_bit( irq, MFP_PENDING );
196*4882a593Smuzhiyun }
197*4882a593Smuzhiyun
atari_irq_pending(unsigned irq)198*4882a593Smuzhiyun static inline int atari_irq_pending( unsigned irq )
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return( 0 );
202*4882a593Smuzhiyun return( get_mfp_bit( irq, MFP_PENDING ) );
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun unsigned int atari_register_vme_int(void);
206*4882a593Smuzhiyun void atari_unregister_vme_int(unsigned int);
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun #endif /* linux/atariints.h */
209