18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci** atariints.h -- Atari Linux interrupt handling structs and prototypes
38c2ecf20Sopenharmony_ci**
48c2ecf20Sopenharmony_ci** Copyright 1994 by Björn Brauel
58c2ecf20Sopenharmony_ci**
68c2ecf20Sopenharmony_ci** 5/2/94 Roman Hodek:
78c2ecf20Sopenharmony_ci**   TT interrupt definitions added.
88c2ecf20Sopenharmony_ci**
98c2ecf20Sopenharmony_ci** 12/02/96: (Roman)
108c2ecf20Sopenharmony_ci**   Adapted to new int handling scheme (see ataints.c); revised numbering
118c2ecf20Sopenharmony_ci**
128c2ecf20Sopenharmony_ci** This file is subject to the terms and conditions of the GNU General Public
138c2ecf20Sopenharmony_ci** License.  See the file COPYING in the main directory of this archive
148c2ecf20Sopenharmony_ci** for more details.
158c2ecf20Sopenharmony_ci**
168c2ecf20Sopenharmony_ci*/
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#ifndef _LINUX_ATARIINTS_H_
198c2ecf20Sopenharmony_ci#define _LINUX_ATARIINTS_H_
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci#include <asm/irq.h>
228c2ecf20Sopenharmony_ci#include <asm/atarihw.h>
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci/*
258c2ecf20Sopenharmony_ci** Atari Interrupt sources.
268c2ecf20Sopenharmony_ci**
278c2ecf20Sopenharmony_ci*/
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#define STMFP_SOURCE_BASE  8
308c2ecf20Sopenharmony_ci#define TTMFP_SOURCE_BASE  24
318c2ecf20Sopenharmony_ci#define SCC_SOURCE_BASE    40
328c2ecf20Sopenharmony_ci#define VME_SOURCE_BASE    56
338c2ecf20Sopenharmony_ci#define VME_MAX_SOURCES    16
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci#define NUM_ATARI_SOURCES  141
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci/* convert vector number to int source number */
388c2ecf20Sopenharmony_ci#define IRQ_VECTOR_TO_SOURCE(v)	((v) - ((v) < 0x20 ? 0x18 : (0x40-8)))
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci/* convert irq_handler index to vector number */
418c2ecf20Sopenharmony_ci#define IRQ_SOURCE_TO_VECTOR(i)	((i) + ((i) < 8 ? 0x18 : (0x40-8)))
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci/* ST-MFP interrupts */
448c2ecf20Sopenharmony_ci#define IRQ_MFP_BUSY      (8)
458c2ecf20Sopenharmony_ci#define IRQ_MFP_DCD       (9)
468c2ecf20Sopenharmony_ci#define IRQ_MFP_CTS	  (10)
478c2ecf20Sopenharmony_ci#define IRQ_MFP_GPU	  (11)
488c2ecf20Sopenharmony_ci#define IRQ_MFP_TIMD      (12)
498c2ecf20Sopenharmony_ci#define IRQ_MFP_TIMC	  (13)
508c2ecf20Sopenharmony_ci#define IRQ_MFP_ACIA	  (14)
518c2ecf20Sopenharmony_ci#define IRQ_MFP_FDC       (15)
528c2ecf20Sopenharmony_ci#define IRQ_MFP_ACSI      IRQ_MFP_FDC
538c2ecf20Sopenharmony_ci#define IRQ_MFP_FSCSI     IRQ_MFP_FDC
548c2ecf20Sopenharmony_ci#define IRQ_MFP_IDE       IRQ_MFP_FDC
558c2ecf20Sopenharmony_ci#define IRQ_MFP_TIMB      (16)
568c2ecf20Sopenharmony_ci#define IRQ_MFP_SERERR    (17)
578c2ecf20Sopenharmony_ci#define IRQ_MFP_SEREMPT   (18)
588c2ecf20Sopenharmony_ci#define IRQ_MFP_RECERR    (19)
598c2ecf20Sopenharmony_ci#define IRQ_MFP_RECFULL   (20)
608c2ecf20Sopenharmony_ci#define IRQ_MFP_TIMA      (21)
618c2ecf20Sopenharmony_ci#define IRQ_MFP_RI        (22)
628c2ecf20Sopenharmony_ci#define IRQ_MFP_MMD       (23)
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci/* TT-MFP interrupts */
658c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_IO0       (24)
668c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_IO1       (25)
678c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_SCC	     (26)
688c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_RI	     (27)
698c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_TIMD      (28)
708c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_TIMC	     (29)
718c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_DRVRDY    (30)
728c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_SCSIDMA   (31)
738c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_TIMB      (32)
748c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_SERERR    (33)
758c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_SEREMPT   (34)
768c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_RECERR    (35)
778c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_RECFULL   (36)
788c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_TIMA      (37)
798c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_RTC       (38)
808c2ecf20Sopenharmony_ci#define IRQ_TT_MFP_SCSI      (39)
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci/* SCC interrupts */
838c2ecf20Sopenharmony_ci#define IRQ_SCCB_TX	     (40)
848c2ecf20Sopenharmony_ci#define IRQ_SCCB_STAT	     (42)
858c2ecf20Sopenharmony_ci#define IRQ_SCCB_RX	     (44)
868c2ecf20Sopenharmony_ci#define IRQ_SCCB_SPCOND	     (46)
878c2ecf20Sopenharmony_ci#define IRQ_SCCA_TX	     (48)
888c2ecf20Sopenharmony_ci#define IRQ_SCCA_STAT	     (50)
898c2ecf20Sopenharmony_ci#define IRQ_SCCA_RX	     (52)
908c2ecf20Sopenharmony_ci#define IRQ_SCCA_SPCOND	     (54)
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci/* shared MFP timer D interrupts - hires timer for EtherNEC et al. */
938c2ecf20Sopenharmony_ci#define IRQ_MFP_TIMER1       (64)
948c2ecf20Sopenharmony_ci#define IRQ_MFP_TIMER2       (65)
958c2ecf20Sopenharmony_ci#define IRQ_MFP_TIMER3       (66)
968c2ecf20Sopenharmony_ci#define IRQ_MFP_TIMER4       (67)
978c2ecf20Sopenharmony_ci#define IRQ_MFP_TIMER5       (68)
988c2ecf20Sopenharmony_ci#define IRQ_MFP_TIMER6       (69)
998c2ecf20Sopenharmony_ci#define IRQ_MFP_TIMER7       (70)
1008c2ecf20Sopenharmony_ci#define IRQ_MFP_TIMER8       (71)
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci#define INT_CLK   24576	    /* CLK while int_clk =2.456MHz and divide = 100 */
1038c2ecf20Sopenharmony_ci#define INT_TICKS 246	    /* to make sched_time = 99.902... HZ */
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci#define MFP_ENABLE	0
1078c2ecf20Sopenharmony_ci#define MFP_PENDING	1
1088c2ecf20Sopenharmony_ci#define MFP_SERVICE	2
1098c2ecf20Sopenharmony_ci#define MFP_MASK	3
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci/* Utility functions for setting/clearing bits in the interrupt registers of
1128c2ecf20Sopenharmony_ci * the MFP. 'type' should be constant, if 'irq' is constant, too, code size is
1138c2ecf20Sopenharmony_ci * reduced. set_mfp_bit() is nonsense for PENDING and SERVICE registers. */
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_cistatic inline int get_mfp_bit( unsigned irq, int type )
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci{	unsigned char	mask, *reg;
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	mask = 1 << (irq & 7);
1208c2ecf20Sopenharmony_ci	reg = (unsigned char *)&st_mfp.int_en_a + type*4 +
1218c2ecf20Sopenharmony_ci		  ((irq & 8) >> 2) + (((irq-8) & 16) << 3);
1228c2ecf20Sopenharmony_ci	return( *reg & mask );
1238c2ecf20Sopenharmony_ci}
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_cistatic inline void set_mfp_bit( unsigned irq, int type )
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci{	unsigned char	mask, *reg;
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci	mask = 1 << (irq & 7);
1308c2ecf20Sopenharmony_ci	reg = (unsigned char *)&st_mfp.int_en_a + type*4 +
1318c2ecf20Sopenharmony_ci		  ((irq & 8) >> 2) + (((irq-8) & 16) << 3);
1328c2ecf20Sopenharmony_ci	__asm__ __volatile__ ( "orb %0,%1"
1338c2ecf20Sopenharmony_ci			      : : "di" (mask), "m" (*reg) : "memory" );
1348c2ecf20Sopenharmony_ci}
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_cistatic inline void clear_mfp_bit( unsigned irq, int type )
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci{	unsigned char	mask, *reg;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	mask = ~(1 << (irq & 7));
1418c2ecf20Sopenharmony_ci	reg = (unsigned char *)&st_mfp.int_en_a + type*4 +
1428c2ecf20Sopenharmony_ci		  ((irq & 8) >> 2) + (((irq-8) & 16) << 3);
1438c2ecf20Sopenharmony_ci	if (type == MFP_PENDING || type == MFP_SERVICE)
1448c2ecf20Sopenharmony_ci		__asm__ __volatile__ ( "moveb %0,%1"
1458c2ecf20Sopenharmony_ci				      : : "di" (mask), "m" (*reg) : "memory" );
1468c2ecf20Sopenharmony_ci	else
1478c2ecf20Sopenharmony_ci		__asm__ __volatile__ ( "andb %0,%1"
1488c2ecf20Sopenharmony_ci				      : : "di" (mask), "m" (*reg) : "memory" );
1498c2ecf20Sopenharmony_ci}
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci/*
1528c2ecf20Sopenharmony_ci * {en,dis}able_irq have the usual semantics of temporary blocking the
1538c2ecf20Sopenharmony_ci * interrupt, but not losing requests that happen between disabling and
1548c2ecf20Sopenharmony_ci * enabling. This is done with the MFP mask registers.
1558c2ecf20Sopenharmony_ci */
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_cistatic inline void atari_enable_irq( unsigned irq )
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci{
1608c2ecf20Sopenharmony_ci	if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
1618c2ecf20Sopenharmony_ci	set_mfp_bit( irq, MFP_MASK );
1628c2ecf20Sopenharmony_ci}
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_cistatic inline void atari_disable_irq( unsigned irq )
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci{
1678c2ecf20Sopenharmony_ci	if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
1688c2ecf20Sopenharmony_ci	clear_mfp_bit( irq, MFP_MASK );
1698c2ecf20Sopenharmony_ci}
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci/*
1728c2ecf20Sopenharmony_ci * In opposite to {en,dis}able_irq, requests between turn{off,on}_irq are not
1738c2ecf20Sopenharmony_ci * "stored"
1748c2ecf20Sopenharmony_ci */
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_cistatic inline void atari_turnon_irq( unsigned irq )
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci{
1798c2ecf20Sopenharmony_ci	if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
1808c2ecf20Sopenharmony_ci	set_mfp_bit( irq, MFP_ENABLE );
1818c2ecf20Sopenharmony_ci}
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_cistatic inline void atari_turnoff_irq( unsigned irq )
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci{
1868c2ecf20Sopenharmony_ci	if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
1878c2ecf20Sopenharmony_ci	clear_mfp_bit( irq, MFP_ENABLE );
1888c2ecf20Sopenharmony_ci	clear_mfp_bit( irq, MFP_PENDING );
1898c2ecf20Sopenharmony_ci}
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_cistatic inline void atari_clear_pending_irq( unsigned irq )
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ci{
1948c2ecf20Sopenharmony_ci	if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return;
1958c2ecf20Sopenharmony_ci	clear_mfp_bit( irq, MFP_PENDING );
1968c2ecf20Sopenharmony_ci}
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_cistatic inline int atari_irq_pending( unsigned irq )
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci{
2018c2ecf20Sopenharmony_ci	if (irq < STMFP_SOURCE_BASE || irq >= SCC_SOURCE_BASE) return( 0 );
2028c2ecf20Sopenharmony_ci	return( get_mfp_bit( irq, MFP_PENDING ) );
2038c2ecf20Sopenharmony_ci}
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ciunsigned int atari_register_vme_int(void);
2068c2ecf20Sopenharmony_civoid atari_unregister_vme_int(unsigned int);
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci#endif /* linux/atariints.h */
209