836f0721ecf9738f46a41d9be4f88d82ac1fde11
[safe/jmp/linux-2.6] / include / asm-m68knommu / ide.h
1 /****************************************************************************/
2 /*
3  *  linux/include/asm-m68knommu/ide.h
4  *
5  *  Copyright (C) 1994-1996  Linus Torvalds & authors
6  *      Copyright (C) 2001       Lineo Inc., davidm@uclinux.org
7  */
8 /****************************************************************************/
9 #ifndef _M68KNOMMU_IDE_H
10 #define _M68KNOMMU_IDE_H
11
12 #ifdef __KERNEL__
13 /****************************************************************************/
14
15 #include <linux/config.h>
16 #include <linux/interrupt.h>
17
18 #include <asm/setup.h>
19 #include <asm/io.h>
20 #include <asm/irq.h>
21
22 /****************************************************************************/
23 /*
24  *      some coldfire specifics
25  */
26
27 #ifdef CONFIG_COLDFIRE
28 #include <asm/coldfire.h>
29 #include <asm/mcfsim.h>
30
31 /*
32  *      Save some space,  only have 1 interface
33  */
34 #define MAX_HWIFS                 1     /* we only have one interface for now */
35
36 #ifdef CONFIG_SECUREEDGEMP3
37 #define MCFSIM_LOCALCS    MCFSIM_CSCR4
38 #else
39 #define MCFSIM_LOCALCS    MCFSIM_CSCR6
40 #endif
41
42 #endif /* CONFIG_COLDFIRE */
43
44 /****************************************************************************/
45 /*
46  *      Fix up things that may not have been provided
47  */
48
49 #ifndef MAX_HWIFS
50 #define MAX_HWIFS       4       /* same as the other archs */
51 #endif
52
53 #undef SUPPORT_SLOW_DATA_PORTS
54 #define SUPPORT_SLOW_DATA_PORTS 0
55
56 #undef SUPPORT_VLB_SYNC
57 #define SUPPORT_VLB_SYNC 0
58
59 /* this definition is used only on startup .. */
60 #undef HD_DATA
61 #define HD_DATA NULL
62
63 #define DBGIDE(fmt,a...)
64 // #define      DBGIDE(fmt,a...) printk(fmt, ##a)
65 #define IDE_INLINE __inline__
66 // #define IDE_INLINE
67
68 /****************************************************************************/
69
70 typedef union {
71         unsigned all                    : 8;    /* all of the bits together */
72         struct {
73                 unsigned bit7           : 1;    /* always 1 */
74                 unsigned lba            : 1;    /* using LBA instead of CHS */
75                 unsigned bit5           : 1;    /* always 1 */
76                 unsigned unit           : 1;    /* drive select number, 0 or 1 */
77                 unsigned head           : 4;    /* always zeros here */
78         } b;
79 } select_t;
80
81 /*
82  *      our list of ports/irq's for different boards
83  */
84
85 static struct m68k_ide_defaults {
86         ide_ioreg_t     base;
87         int                     irq;
88 } m68k_ide_defaults[MAX_HWIFS] = {
89 #if defined(CONFIG_SECUREEDGEMP3)
90         { ((ide_ioreg_t)0x30800000), 29 },
91 #elif defined(CONFIG_eLIA)
92         { ((ide_ioreg_t)0x30c00000), 29 },
93 #else
94         { ((ide_ioreg_t)0x0), 0 }
95 #endif
96 };
97
98 /****************************************************************************/
99
100 static IDE_INLINE int ide_default_irq(ide_ioreg_t base)
101 {
102         int i;
103
104         for (i = 0; i < MAX_HWIFS; i++)
105                 if (m68k_ide_defaults[i].base == base)
106                         return(m68k_ide_defaults[i].irq);
107         return 0;
108 }
109
110 static IDE_INLINE ide_ioreg_t ide_default_io_base(int index)
111 {
112         if (index >= 0 && index < MAX_HWIFS)
113                 return(m68k_ide_defaults[index].base);
114         return 0;
115 }
116
117
118 /*
119  * Set up a hw structure for a specified data port, control port and IRQ.
120  * This should follow whatever the default interface uses.
121  */
122 static IDE_INLINE void ide_init_hwif_ports(
123         hw_regs_t *hw,
124         ide_ioreg_t data_port,
125         ide_ioreg_t ctrl_port,
126         int *irq)
127 {
128         ide_ioreg_t reg = data_port;
129         int i;
130
131         for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
132                 hw->io_ports[i] = reg;
133                 reg += 1;
134         }
135         if (ctrl_port) {
136                 hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
137         } else {
138                 hw->io_ports[IDE_CONTROL_OFFSET] = data_port + 0xe;
139         }
140 }
141
142 #define ide_init_default_irq(base)      ide_default_irq(base)
143
144 static IDE_INLINE int
145 ide_request_irq(
146         unsigned int irq,
147         void (*handler)(int, void *, struct pt_regs *),
148         unsigned long flags,
149         const char *device,
150         void *dev_id)
151 {
152 #ifdef CONFIG_COLDFIRE
153         mcf_autovector(irq);
154 #endif
155         return(request_irq(irq, handler, flags, device, dev_id));
156 }
157
158
159 static IDE_INLINE void
160 ide_free_irq(unsigned int irq, void *dev_id)
161 {
162         free_irq(irq, dev_id);
163 }
164
165
166 static IDE_INLINE void
167 ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
168 {
169 }
170
171
172 static IDE_INLINE void
173 ide_release_region(ide_ioreg_t from, unsigned int extent)
174 {
175 }
176
177
178 static IDE_INLINE void
179 ide_fix_driveid(struct hd_driveid *id)
180 {
181 #ifdef CONFIG_COLDFIRE
182         int i, n;
183         unsigned short *wp = (unsigned short *) id;
184         int avoid[] = {49, 51, 52, 59, -1 }; /* do not swap these words */
185
186         /* Need to byte swap shorts,  but not char fields */
187         for (i = n = 0; i < sizeof(*id) / sizeof(*wp); i++, wp++) {
188                 if (avoid[n] == i) {
189                         n++;
190                         continue;
191                 }
192                 *wp = ((*wp & 0xff) << 8) | ((*wp >> 8) & 0xff);
193         }
194         /* have to word swap the one 32 bit field */
195         id->lba_capacity = ((id->lba_capacity & 0xffff) << 16) |
196                                 ((id->lba_capacity >> 16) & 0xffff);
197 #endif
198 }
199
200
201 static IDE_INLINE void
202 ide_release_lock (int *ide_lock)
203 {
204 }
205
206
207 static IDE_INLINE void
208 ide_get_lock(
209         int *ide_lock,
210         void (*handler)(int, void *, struct pt_regs *),
211         void *data)
212 {
213 }
214
215
216 #define ide_ack_intr(hwif) \
217         ((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1)
218 #define ide__sti()      __sti()
219
220 /****************************************************************************/
221 /*
222  *      System specific IO requirements
223  */
224
225 #ifdef CONFIG_COLDFIRE
226
227 #ifdef CONFIG_SECUREEDGEMP3
228
229 /* Replace standard IO functions for funky mapping of MP3 board */
230 #undef outb
231 #undef outb_p
232 #undef inb
233 #undef inb_p
234
235 #define outb(v, a)          ide_outb(v, (unsigned long) (a))
236 #define outb_p(v, a)        ide_outb(v, (unsigned long) (a))
237 #define inb(a)              ide_inb((unsigned long) (a))
238 #define inb_p(a)            ide_inb((unsigned long) (a))
239
240 #define ADDR8_PTR(addr)         (((addr) & 0x1) ? (0x8000 + (addr) - 1) : (addr))
241 #define ADDR16_PTR(addr)        (addr)
242 #define ADDR32_PTR(addr)        (addr)
243 #define SWAP8(w)                        ((((w) & 0xffff) << 8) | (((w) & 0xffff) >> 8))
244 #define SWAP16(w)                       (w)
245 #define SWAP32(w)                       (w)
246
247
248 static IDE_INLINE void
249 ide_outb(unsigned int val, unsigned int addr)
250 {
251         volatile unsigned short *rp;
252
253         DBGIDE("%s(val=%x,addr=%x)\n", __FUNCTION__, val, addr);
254         rp = (volatile unsigned short *) ADDR8_PTR(addr);
255         *rp = SWAP8(val);
256 }
257
258
259 static IDE_INLINE int
260 ide_inb(unsigned int addr)
261 {
262         volatile unsigned short *rp, val;
263
264         DBGIDE("%s(addr=%x)\n", __FUNCTION__, addr);
265         rp = (volatile unsigned short *) ADDR8_PTR(addr);
266         val = *rp;
267         return(SWAP8(val));
268 }
269
270
271 static IDE_INLINE void
272 ide_outw(unsigned int val, unsigned int addr)
273 {
274         volatile unsigned short *rp;
275
276         DBGIDE("%s(val=%x,addr=%x)\n", __FUNCTION__, val, addr);
277         rp = (volatile unsigned short *) ADDR16_PTR(addr);
278         *rp = SWAP16(val);
279 }
280
281 static IDE_INLINE void
282 ide_outsw(unsigned int addr, const void *vbuf, unsigned long len)
283 {
284         volatile unsigned short *rp, val;
285         unsigned short          *buf;
286
287         DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
288         buf = (unsigned short *) vbuf;
289         rp = (volatile unsigned short *) ADDR16_PTR(addr);
290         for (; (len > 0); len--) {
291                 val = *buf++;
292                 *rp = SWAP16(val);
293         }
294 }
295
296 static IDE_INLINE int
297 ide_inw(unsigned int addr)
298 {
299         volatile unsigned short *rp, val;
300
301         DBGIDE("%s(addr=%x)\n", __FUNCTION__, addr);
302         rp = (volatile unsigned short *) ADDR16_PTR(addr);
303         val = *rp;
304         return(SWAP16(val));
305 }
306
307 static IDE_INLINE void
308 ide_insw(unsigned int addr, void *vbuf, unsigned long len)
309 {
310         volatile unsigned short *rp;
311         unsigned short          w, *buf;
312
313         DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
314         buf = (unsigned short *) vbuf;
315         rp = (volatile unsigned short *) ADDR16_PTR(addr);
316         for (; (len > 0); len--) {
317                 w = *rp;
318                 *buf++ = SWAP16(w);
319         }
320 }
321
322 static IDE_INLINE void
323 ide_insl(unsigned int addr, void *vbuf, unsigned long len)
324 {
325         volatile unsigned long *rp;
326         unsigned long          w, *buf;
327
328         DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
329         buf = (unsigned long *) vbuf;
330         rp = (volatile unsigned long *) ADDR32_PTR(addr);
331         for (; (len > 0); len--) {
332                 w = *rp;
333                 *buf++ = SWAP32(w);
334         }
335 }
336
337 static IDE_INLINE void
338 ide_outsl(unsigned int addr, const void *vbuf, unsigned long len)
339 {
340         volatile unsigned long  *rp, val;
341         unsigned long           *buf;
342
343         DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
344         buf = (unsigned long *) vbuf;
345         rp = (volatile unsigned long *) ADDR32_PTR(addr);
346         for (; (len > 0); len--) {
347                 val = *buf++;
348                 *rp = SWAP32(val);
349         }
350 }
351
352 #elif CONFIG_eLIA
353
354 /* 8/16 bit acesses are controlled by flicking bits in the CS register */
355 #define ACCESS_MODE_16BIT()     \
356         *((volatile unsigned short *) (MCF_MBAR + MCFSIM_LOCALCS)) = 0x0080
357 #define ACCESS_MODE_8BIT()      \
358         *((volatile unsigned short *) (MCF_MBAR + MCFSIM_LOCALCS)) = 0x0040
359
360
361 static IDE_INLINE void
362 ide_outw(unsigned int val, unsigned int addr)
363 {
364         ACCESS_MODE_16BIT();
365         outw(val, addr);
366         ACCESS_MODE_8BIT();
367 }
368
369 static IDE_INLINE void
370 ide_outsw(unsigned int addr, const void *vbuf, unsigned long len)
371 {
372         ACCESS_MODE_16BIT();
373         outsw(addr, vbuf, len);
374         ACCESS_MODE_8BIT();
375 }
376
377 static IDE_INLINE int
378 ide_inw(unsigned int addr)
379 {
380         int ret;
381
382         ACCESS_MODE_16BIT();
383         ret = inw(addr);
384         ACCESS_MODE_8BIT();
385         return(ret);
386 }
387
388 static IDE_INLINE void
389 ide_insw(unsigned int addr, void *vbuf, unsigned long len)
390 {
391         ACCESS_MODE_16BIT();
392         insw(addr, vbuf, len);
393         ACCESS_MODE_8BIT();
394 }
395
396 static IDE_INLINE void
397 ide_insl(unsigned int addr, void *vbuf, unsigned long len)
398 {
399         ACCESS_MODE_16BIT();
400         insl(addr, vbuf, len);
401         ACCESS_MODE_8BIT();
402 }
403
404 static IDE_INLINE void
405 ide_outsl(unsigned int addr, const void *vbuf, unsigned long len)
406 {
407         ACCESS_MODE_16BIT();
408         outsl(addr, vbuf, len);
409         ACCESS_MODE_8BIT();
410 }
411
412 #endif /* CONFIG_SECUREEDGEMP3 */
413
414 #undef outw
415 #undef outw_p
416 #undef outsw
417 #undef inw
418 #undef inw_p
419 #undef insw
420 #undef insl
421 #undef outsl
422
423 #define outw(v, a)           ide_outw(v, (unsigned long) (a))
424 #define outw_p(v, a)     ide_outw(v, (unsigned long) (a))
425 #define outsw(a, b, n)   ide_outsw((unsigned long) (a), b, n)
426 #define inw(a)           ide_inw((unsigned long) (a))
427 #define inw_p(a)             ide_inw((unsigned long) (a))
428 #define insw(a, b, n)    ide_insw((unsigned long) (a), b, n)
429 #define insl(a, b, n)    ide_insl((unsigned long) (a), b, n)
430 #define outsl(a, b, n)   ide_outsl((unsigned long) (a), b, n)
431
432 #endif CONFIG_COLDFIRE
433
434 /****************************************************************************/
435 #endif /* __KERNEL__ */
436 #endif /* _M68KNOMMU_IDE_H */
437 /****************************************************************************/