Linux-2.6.12-rc2
[GitHub/exynos8895/android_kernel_samsung_universal8895.git] / 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 int
167 ide_check_region(ide_ioreg_t from, unsigned int extent)
168 {
169 return 0;
170 }
171
172
173 static IDE_INLINE void
174 ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
175 {
176 }
177
178
179 static IDE_INLINE void
180 ide_release_region(ide_ioreg_t from, unsigned int extent)
181 {
182 }
183
184
185 static IDE_INLINE void
186 ide_fix_driveid(struct hd_driveid *id)
187 {
188 #ifdef CONFIG_COLDFIRE
189 int i, n;
190 unsigned short *wp = (unsigned short *) id;
191 int avoid[] = {49, 51, 52, 59, -1 }; /* do not swap these words */
192
193 /* Need to byte swap shorts, but not char fields */
194 for (i = n = 0; i < sizeof(*id) / sizeof(*wp); i++, wp++) {
195 if (avoid[n] == i) {
196 n++;
197 continue;
198 }
199 *wp = ((*wp & 0xff) << 8) | ((*wp >> 8) & 0xff);
200 }
201 /* have to word swap the one 32 bit field */
202 id->lba_capacity = ((id->lba_capacity & 0xffff) << 16) |
203 ((id->lba_capacity >> 16) & 0xffff);
204 #endif
205 }
206
207
208 static IDE_INLINE void
209 ide_release_lock (int *ide_lock)
210 {
211 }
212
213
214 static IDE_INLINE void
215 ide_get_lock(
216 int *ide_lock,
217 void (*handler)(int, void *, struct pt_regs *),
218 void *data)
219 {
220 }
221
222
223 #define ide_ack_intr(hwif) \
224 ((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1)
225 #define ide__sti() __sti()
226
227 /****************************************************************************/
228 /*
229 * System specific IO requirements
230 */
231
232 #ifdef CONFIG_COLDFIRE
233
234 #ifdef CONFIG_SECUREEDGEMP3
235
236 /* Replace standard IO functions for funky mapping of MP3 board */
237 #undef outb
238 #undef outb_p
239 #undef inb
240 #undef inb_p
241
242 #define outb(v, a) ide_outb(v, (unsigned long) (a))
243 #define outb_p(v, a) ide_outb(v, (unsigned long) (a))
244 #define inb(a) ide_inb((unsigned long) (a))
245 #define inb_p(a) ide_inb((unsigned long) (a))
246
247 #define ADDR8_PTR(addr) (((addr) & 0x1) ? (0x8000 + (addr) - 1) : (addr))
248 #define ADDR16_PTR(addr) (addr)
249 #define ADDR32_PTR(addr) (addr)
250 #define SWAP8(w) ((((w) & 0xffff) << 8) | (((w) & 0xffff) >> 8))
251 #define SWAP16(w) (w)
252 #define SWAP32(w) (w)
253
254
255 static IDE_INLINE void
256 ide_outb(unsigned int val, unsigned int addr)
257 {
258 volatile unsigned short *rp;
259
260 DBGIDE("%s(val=%x,addr=%x)\n", __FUNCTION__, val, addr);
261 rp = (volatile unsigned short *) ADDR8_PTR(addr);
262 *rp = SWAP8(val);
263 }
264
265
266 static IDE_INLINE int
267 ide_inb(unsigned int addr)
268 {
269 volatile unsigned short *rp, val;
270
271 DBGIDE("%s(addr=%x)\n", __FUNCTION__, addr);
272 rp = (volatile unsigned short *) ADDR8_PTR(addr);
273 val = *rp;
274 return(SWAP8(val));
275 }
276
277
278 static IDE_INLINE void
279 ide_outw(unsigned int val, unsigned int addr)
280 {
281 volatile unsigned short *rp;
282
283 DBGIDE("%s(val=%x,addr=%x)\n", __FUNCTION__, val, addr);
284 rp = (volatile unsigned short *) ADDR16_PTR(addr);
285 *rp = SWAP16(val);
286 }
287
288 static IDE_INLINE void
289 ide_outsw(unsigned int addr, const void *vbuf, unsigned long len)
290 {
291 volatile unsigned short *rp, val;
292 unsigned short *buf;
293
294 DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
295 buf = (unsigned short *) vbuf;
296 rp = (volatile unsigned short *) ADDR16_PTR(addr);
297 for (; (len > 0); len--) {
298 val = *buf++;
299 *rp = SWAP16(val);
300 }
301 }
302
303 static IDE_INLINE int
304 ide_inw(unsigned int addr)
305 {
306 volatile unsigned short *rp, val;
307
308 DBGIDE("%s(addr=%x)\n", __FUNCTION__, addr);
309 rp = (volatile unsigned short *) ADDR16_PTR(addr);
310 val = *rp;
311 return(SWAP16(val));
312 }
313
314 static IDE_INLINE void
315 ide_insw(unsigned int addr, void *vbuf, unsigned long len)
316 {
317 volatile unsigned short *rp;
318 unsigned short w, *buf;
319
320 DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
321 buf = (unsigned short *) vbuf;
322 rp = (volatile unsigned short *) ADDR16_PTR(addr);
323 for (; (len > 0); len--) {
324 w = *rp;
325 *buf++ = SWAP16(w);
326 }
327 }
328
329 static IDE_INLINE void
330 ide_insl(unsigned int addr, void *vbuf, unsigned long len)
331 {
332 volatile unsigned long *rp;
333 unsigned long w, *buf;
334
335 DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
336 buf = (unsigned long *) vbuf;
337 rp = (volatile unsigned long *) ADDR32_PTR(addr);
338 for (; (len > 0); len--) {
339 w = *rp;
340 *buf++ = SWAP32(w);
341 }
342 }
343
344 static IDE_INLINE void
345 ide_outsl(unsigned int addr, const void *vbuf, unsigned long len)
346 {
347 volatile unsigned long *rp, val;
348 unsigned long *buf;
349
350 DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len);
351 buf = (unsigned long *) vbuf;
352 rp = (volatile unsigned long *) ADDR32_PTR(addr);
353 for (; (len > 0); len--) {
354 val = *buf++;
355 *rp = SWAP32(val);
356 }
357 }
358
359 #elif CONFIG_eLIA
360
361 /* 8/16 bit acesses are controlled by flicking bits in the CS register */
362 #define ACCESS_MODE_16BIT() \
363 *((volatile unsigned short *) (MCF_MBAR + MCFSIM_LOCALCS)) = 0x0080
364 #define ACCESS_MODE_8BIT() \
365 *((volatile unsigned short *) (MCF_MBAR + MCFSIM_LOCALCS)) = 0x0040
366
367
368 static IDE_INLINE void
369 ide_outw(unsigned int val, unsigned int addr)
370 {
371 ACCESS_MODE_16BIT();
372 outw(val, addr);
373 ACCESS_MODE_8BIT();
374 }
375
376 static IDE_INLINE void
377 ide_outsw(unsigned int addr, const void *vbuf, unsigned long len)
378 {
379 ACCESS_MODE_16BIT();
380 outsw(addr, vbuf, len);
381 ACCESS_MODE_8BIT();
382 }
383
384 static IDE_INLINE int
385 ide_inw(unsigned int addr)
386 {
387 int ret;
388
389 ACCESS_MODE_16BIT();
390 ret = inw(addr);
391 ACCESS_MODE_8BIT();
392 return(ret);
393 }
394
395 static IDE_INLINE void
396 ide_insw(unsigned int addr, void *vbuf, unsigned long len)
397 {
398 ACCESS_MODE_16BIT();
399 insw(addr, vbuf, len);
400 ACCESS_MODE_8BIT();
401 }
402
403 static IDE_INLINE void
404 ide_insl(unsigned int addr, void *vbuf, unsigned long len)
405 {
406 ACCESS_MODE_16BIT();
407 insl(addr, vbuf, len);
408 ACCESS_MODE_8BIT();
409 }
410
411 static IDE_INLINE void
412 ide_outsl(unsigned int addr, const void *vbuf, unsigned long len)
413 {
414 ACCESS_MODE_16BIT();
415 outsl(addr, vbuf, len);
416 ACCESS_MODE_8BIT();
417 }
418
419 #endif /* CONFIG_SECUREEDGEMP3 */
420
421 #undef outw
422 #undef outw_p
423 #undef outsw
424 #undef inw
425 #undef inw_p
426 #undef insw
427 #undef insl
428 #undef outsl
429
430 #define outw(v, a) ide_outw(v, (unsigned long) (a))
431 #define outw_p(v, a) ide_outw(v, (unsigned long) (a))
432 #define outsw(a, b, n) ide_outsw((unsigned long) (a), b, n)
433 #define inw(a) ide_inw((unsigned long) (a))
434 #define inw_p(a) ide_inw((unsigned long) (a))
435 #define insw(a, b, n) ide_insw((unsigned long) (a), b, n)
436 #define insl(a, b, n) ide_insl((unsigned long) (a), b, n)
437 #define outsl(a, b, n) ide_outsl((unsigned long) (a), b, n)
438
439 #endif CONFIG_COLDFIRE
440
441 /****************************************************************************/
442 #endif /* __KERNEL__ */
443 #endif /* _M68KNOMMU_IDE_H */
444 /****************************************************************************/