nidas v1.2.3
isa_bus.h
Go to the documentation of this file.
1/* -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 8; tab-width: 8; -*- */
2/* vim: set shiftwidth=8 softtabstop=8 expandtab: */
3/*
4 ********************************************************************
5 ** NIDAS: NCAR In-situ Data Acquistion Software
6 **
7 ** 2007, Copyright University Corporation for Atmospheric Research
8 **
9 ** This program is free software; you can redistribute it and/or modify
10 ** it under the terms of the GNU General Public License as published by
11 ** the Free Software Foundation; either version 2 of the License, or
12 ** (at your option) any later version.
13 **
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ** GNU General Public License for more details.
18 **
19 ** The LICENSE.txt file accompanying this software contains
20 ** a copy of the GNU General Public License. If it is not found,
21 ** write to the Free Software Foundation, Inc.,
22 ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 **
24 ********************************************************************
25*/
26
27/*
28 Macros needed for ISA drivers to get the right ioport addresses
29 and IRQs on various processors.
30*/
31
32#ifndef NIDAS_LINUX_ISA_BUS_H
33#define NIDAS_LINUX_ISA_BUS_H
34
35#ifdef __KERNEL__
36
37#ifdef CONFIG_ARCH_VIPER /* Arcom Viper */
38
39#include <linux/version.h>
40
41#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
42#include <mach/irqs.h>
43#include <mach/viper.h>
44#else
45#include <asm/arch/viper.h>
46#endif
47
48#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,16,0)
49#define SYSTEM_ISA_IOPORT_BASE 0
50#elif defined(VIPER_PC104IO_BASE)
51#define SYSTEM_ISA_IOPORT_BASE ((unsigned long)VIPER_PC104IO_BASE)
52#endif
53
54#define SYSTEM_ISA_IOMEM_BASE 0x3c000000
55
56#define ISA_16BIT_ADDR_OFFSET 0
57/*
58 * Special versions of 16 bit I/O operations, that can an address
59 * offset as necessary on a given CPU. See VULCAN section below.
60 * Offset is not needed on VIPER.
61 */
62#define inw_16o(a) inw(a)
63#define insw_16o(a,p,n) insw(a,p,n)
64#define outw_16o(v,a) outw(v,a)
65
66#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
67/* In earlier kernels the viper maps ISA irqs
68 * 3,4,5,6,7,10,11,12,9,14,15 to system interrupts
69 * VIPER_IRQ(0)+0,+1, etc.
70 * Note that 9 is out of order, and 1,2,8 and 13 aren't available.
71 * ISA interrupts 9,14 and 15 are only supported on version 2 Vipers.
72 *
73 * VIPER_IRQ(0) is 104 for kernel 2.6.16, so the above irqs are
74 * mapped to interrupts 104-114.
75 * VIPER_IRQ(0) is 108 for kernel 2.6.21, so the above irqs are
76 * mapped to interrupts 108-118.
77 *
78 * VIPER_IRQ(0)+n are not actual hardware interrupt lines.
79 *
80 * All the ISA interrupts are multiplexed by CPLD code into actual
81 * GPIO interrupt GPIO1=VIPER_CPLD_IRQ. The handler for that interrupt
82 * then calls the interrupt handlers for the PC104 interrupts based on the
83 * bits set in the PC104 interrupt status register.
84 * See <linux_2.6_source>/arch/arm/mach-pxa/viper.c.
85 * Return -1 if interrupt is not available.
86 */
87#define GET_SYSTEM_ISA_IRQ(x) \
88({ \
89 const int irq_map[] = { -1, -1, -1, \
90 VIPER_IRQ(0)+0, \
91 VIPER_IRQ(0)+1, \
92 VIPER_IRQ(0)+2, \
93 VIPER_IRQ(0)+3, \
94 VIPER_IRQ(0)+4, \
95 -1, \
96 VIPER_IRQ(0)+8, \
97 VIPER_IRQ(0)+5, \
98 VIPER_IRQ(0)+6, \
99 VIPER_IRQ(0)+7, \
100 -1, \
101 VIPER_IRQ(0)+9, \
102 VIPER_IRQ(0)+10, \
103 }; \
104 int n = -1; \
105 if ((x) >= 0 && (x) < sizeof(irq_map)/sizeof(irq_map[0])) \
106 n = irq_map[(x)]; \
107 n; \
108})
109
110#else
111
112/* Starting in kernel 2.6.35 the viper maps ISA irq 3,4,5,...
113 * to system irqs 3,4,5,... How about that! Simple.
114 * PXA_ISA_IRQ(0) is 0.
115 * See linux-source_2.6.35.../arch/arm/mach-pxa/viper.c.
116 * Return -1 if interrupt is not available.
117 */
118#define GET_SYSTEM_ISA_IRQ(x) \
119({ \
120 const int irq_map[] = { -1, -1, -1, \
121 PXA_ISA_IRQ(0)+3, /* PC104 IRQ 3 */ \
122 PXA_ISA_IRQ(0)+4, /* PC104 IRQ 4 */ \
123 PXA_ISA_IRQ(0)+5, /* PC104 IRQ 5 */ \
124 PXA_ISA_IRQ(0)+6, /* PC104 IRQ 6 */ \
125 PXA_ISA_IRQ(0)+7, /* PC104 IRQ 7 */ \
126 -1, \
127 PXA_ISA_IRQ(0)+9, /* PC104 IRQ 9 */ \
128 PXA_ISA_IRQ(0)+10, /* PC104 IRQ 10 */ \
129 PXA_ISA_IRQ(0)+11, /* PC104 IRQ 11 */ \
130 PXA_ISA_IRQ(0)+12, /* PC104 IRQ 12 */ \
131 -1, \
132 PXA_ISA_IRQ(0)+14, /* PC104 IRQ 14 */ \
133 PXA_ISA_IRQ(0)+15, /* PC104 IRQ 15 */ \
134 }; \
135 int n = -1; \
136 if ((x) >= 0 && (x) < sizeof(irq_map)/sizeof(irq_map[0])) \
137 n = irq_map[(x)]; \
138 n; \
139})
140
141#endif
142
143#elif defined(CONFIG_MACH_ARCOM_MERCURY) || defined(CONFIG_MACH_ARCOM_VULCAN) /* Arcom Mercury (or Vulcan) */
144
145#include <asm/irq.h>
146#define SYSTEM_ISA_IOPORT_BASE 0x0
147#define SYSTEM_ISA_IOMEM_BASE 0x049000000 /* 8 bit memory space. 16 bit is at 0x4a000000 */
148
149/*
150 * On VULCANs I/O window 1 of the PCI1520 bridge chip is configured for 16 bit
151 * accesses, and starts at address 0x1000. 0x1000 is subtracted from addresses
152 * that are placed on the ISA bus, so that if an outw/inw is done to address 0x1XXX
153 * the address on the PC104 bus will be 0x0XXX.
154 */
155#define ISA_16BIT_ADDR_OFFSET 0x1000
156
157/*
158 * Add 0x1000 to addresses on VULCANs for 16 bit operations, so they
159 * happen in I/O window 1 on the PCI1520, which is configured
160 * for 16 bit accesses.
161 */
162#define inw_16o(a) inw((a) + ISA_16BIT_ADDR_OFFSET )
163#define insw_16o(a,p,n) insw((a) + ISA_16BIT_ADDR_OFFSET ,p,n)
164#define outw_16o(v,a) outw(v,(a) + ISA_16BIT_ADDR_OFFSET )
165
166/*
167 * On the Mercury/Vulcan, most of the ISA interrupts are routed to GPIO
168 * pins on the processor. Handle those mappings here.
169 * Return -1 if interrupt is not available.
170 */
171#define GET_SYSTEM_ISA_IRQ(x) \
172({ \
173 const int irq_map[] = { -1, -1, -1, IRQ_IXP4XX_GPIO5, IRQ_IXP4XX_GPIO6,\
174 IRQ_IXP4XX_GPIO7, IRQ_IXP4XX_GPIO8, \
175 IRQ_IXP4XX_GPIO9, -1, -1, IRQ_IXP4XX_GPIO10,\
176 IRQ_IXP4XX_GPIO11, IRQ_IXP4XX_GPIO12}; \
177 int n = -1; \
178 if ((x) >= 0 && (x) < sizeof(irq_map)/sizeof(irq_map[0])) \
179 n = irq_map[(x)]; \
180 n; \
181})
182
183#elif defined(CONFIG_MACH_ARCOM_TITAN) /* Arcom Titan */
184
185#include <linux/version.h>
186
187#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
188#include <mach/irqs.h>
189#include <mach/titan.h>
190#else
191#include <asm/arch/titan.h>
192#endif
193
194#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,16,0)
195#define SYSTEM_ISA_IOPORT_BASE 0
196#elif defined(TITAN_PC104IO_BASE)
197#define SYSTEM_ISA_IOPORT_BASE ((unsigned long)TITAN_PC104IO_BASE)
198#elif defined(TITAN_PC104IO_VIRT)
199#define SYSTEM_ISA_IOPORT_BASE ((unsigned long)TITAN_PC104IO_VIRT)
200#endif
201
202#define SYSTEM_ISA_IOMEM_BASE 0x3c000000
203
204#define ISA_16BIT_ADDR_OFFSET 0
205/*
206 * Special versions of 16 bit I/O operations, that add an address
207 * offset as necessary on a given CPU. See VULCAN section.
208 * Offset is not needed on a Titan
209 */
210#define inw_16o(a) inw(a)
211#define insw_16o(a,p,n) insw(a,p,n)
212#define outw_16o(v,a) outw(v,a)
213
214#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
215/* The titan maps ISA irqs 3,4,5,... to system irqs 3,4,5,...
216 * PXA_ISA_IRQ(0) is 0.
217 */
218#define GET_SYSTEM_ISA_IRQ(x) \
219({ \
220 const int irq_map[] = { -1, -1, -1, \
221 PXA_ISA_IRQ(0)+3, /* PC104 IRQ 3 */ \
222 PXA_ISA_IRQ(0)+4, /* PC104 IRQ 4 */ \
223 PXA_ISA_IRQ(0)+5, /* PC104 IRQ 5 */ \
224 PXA_ISA_IRQ(0)+6, /* PC104 IRQ 6 */ \
225 PXA_ISA_IRQ(0)+7, /* PC104 IRQ 7 */ \
226 -1, \
227 PXA_ISA_IRQ(0)+9, /* PC104 IRQ 9 */ \
228 PXA_ISA_IRQ(0)+10, /* PC104 IRQ 10 */ \
229 PXA_ISA_IRQ(0)+11, /* PC104 IRQ 11 */ \
230 PXA_ISA_IRQ(0)+12, /* PC104 IRQ 12 */ \
231 -1, \
232 PXA_ISA_IRQ(0)+14, /* PC104 IRQ 14 */ \
233 PXA_ISA_IRQ(0)+15, /* PC104 IRQ 15 */ \
234 }; \
235 int n = -1; \
236 if ((x) >= 0 && (x) < sizeof(irq_map)/sizeof(irq_map[0])) \
237 n = irq_map[(x)]; \
238 n; \
239})
240#else
241/* Different irq mapping in older kernels. TITAN_IRQ is 160.
242 * 3,4,5,6,7,10,11,12 are mapped to 160-167
243 */
244#define GET_SYSTEM_ISA_IRQ(x) \
245({ \
246 const int irq_map[] = { -1, -1, -1, \
247 TITAN_IRQ(0)+0, /* PC104 IRQ 3 */ \
248 TITAN_IRQ(0)+1, /* PC104 IRQ 4 */ \
249 TITAN_IRQ(0)+2, /* PC104 IRQ 5 */ \
250 TITAN_IRQ(0)+3, /* PC104 IRQ 6 */ \
251 TITAN_IRQ(0)+4, /* PC104 IRQ 7 */ \
252 -1, \
253 -1, /* PC104 IRQ 9 */ \
254 TITAN_IRQ(0)+5, /* PC104 IRQ 10 */ \
255 TITAN_IRQ(0)+6, /* PC104 IRQ 11 */ \
256 TITAN_IRQ(0)+7, /* PC104 IRQ 12 */ \
257 -1, \
258 -1, /* PC104 IRQ 14 */ \
259 -1, /* PC104 IRQ 15 */ \
260 }; \
261 int n = -1; \
262 if ((x) >= 0 && (x) < sizeof(irq_map)/sizeof(irq_map[0])) \
263 n = irq_map[(x)]; \
264 n; \
265})
266
267#endif
268
269#else /* nothing machine/architecture specific */
270
271#define SYSTEM_ISA_IOPORT_BASE 0x0
272#define SYSTEM_ISA_IOMEM_BASE 0x0
273#define GET_SYSTEM_ISA_IRQ(x) (x)
274
275#define ISA_16BIT_ADDR_OFFSET 0
276#define inw_16o(a) inw(a)
277#define insw_16o(a,p,n) insw(a,p,n)
278#define outw_16o(v,a) outw(v,a)
279
280#endif
281
282#endif
283
284#endif