diff options
Diffstat (limited to 'include/asm-m68knommu/ide.h')
-rw-r--r-- | include/asm-m68knommu/ide.h | 444 |
1 files changed, 444 insertions, 0 deletions
diff --git a/include/asm-m68knommu/ide.h b/include/asm-m68knommu/ide.h new file mode 100644 index 000000000000..b1cbf8bb9232 --- /dev/null +++ b/include/asm-m68knommu/ide.h @@ -0,0 +1,444 @@ +/****************************************************************************/ +/* + * linux/include/asm-m68knommu/ide.h + * + * Copyright (C) 1994-1996 Linus Torvalds & authors + * Copyright (C) 2001 Lineo Inc., davidm@uclinux.org + */ +/****************************************************************************/ +#ifndef _M68KNOMMU_IDE_H +#define _M68KNOMMU_IDE_H + +#ifdef __KERNEL__ +/****************************************************************************/ + +#include <linux/config.h> +#include <linux/interrupt.h> + +#include <asm/setup.h> +#include <asm/io.h> +#include <asm/irq.h> + +/****************************************************************************/ +/* + * some coldfire specifics + */ + +#ifdef CONFIG_COLDFIRE +#include <asm/coldfire.h> +#include <asm/mcfsim.h> + +/* + * Save some space, only have 1 interface + */ +#define MAX_HWIFS 1 /* we only have one interface for now */ + +#ifdef CONFIG_SECUREEDGEMP3 +#define MCFSIM_LOCALCS MCFSIM_CSCR4 +#else +#define MCFSIM_LOCALCS MCFSIM_CSCR6 +#endif + +#endif /* CONFIG_COLDFIRE */ + +/****************************************************************************/ +/* + * Fix up things that may not have been provided + */ + +#ifndef MAX_HWIFS +#define MAX_HWIFS 4 /* same as the other archs */ +#endif + +#undef SUPPORT_SLOW_DATA_PORTS +#define SUPPORT_SLOW_DATA_PORTS 0 + +#undef SUPPORT_VLB_SYNC +#define SUPPORT_VLB_SYNC 0 + +/* this definition is used only on startup .. */ +#undef HD_DATA +#define HD_DATA NULL + +#define DBGIDE(fmt,a...) +// #define DBGIDE(fmt,a...) printk(fmt, ##a) +#define IDE_INLINE __inline__ +// #define IDE_INLINE + +/****************************************************************************/ + +typedef union { + unsigned all : 8; /* all of the bits together */ + struct { + unsigned bit7 : 1; /* always 1 */ + unsigned lba : 1; /* using LBA instead of CHS */ + unsigned bit5 : 1; /* always 1 */ + unsigned unit : 1; /* drive select number, 0 or 1 */ + unsigned head : 4; /* always zeros here */ + } b; +} select_t; + +/* + * our list of ports/irq's for different boards + */ + +static struct m68k_ide_defaults { + ide_ioreg_t base; + int irq; +} m68k_ide_defaults[MAX_HWIFS] = { +#if defined(CONFIG_SECUREEDGEMP3) + { ((ide_ioreg_t)0x30800000), 29 }, +#elif defined(CONFIG_eLIA) + { ((ide_ioreg_t)0x30c00000), 29 }, +#else + { ((ide_ioreg_t)0x0), 0 } +#endif +}; + +/****************************************************************************/ + +static IDE_INLINE int ide_default_irq(ide_ioreg_t base) +{ + int i; + + for (i = 0; i < MAX_HWIFS; i++) + if (m68k_ide_defaults[i].base == base) + return(m68k_ide_defaults[i].irq); + return 0; +} + +static IDE_INLINE ide_ioreg_t ide_default_io_base(int index) +{ + if (index >= 0 && index < MAX_HWIFS) + return(m68k_ide_defaults[index].base); + return 0; +} + + +/* + * Set up a hw structure for a specified data port, control port and IRQ. + * This should follow whatever the default interface uses. + */ +static IDE_INLINE void ide_init_hwif_ports( + hw_regs_t *hw, + ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, + int *irq) +{ + ide_ioreg_t reg = data_port; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = data_port + 0xe; + } +} + +#define ide_init_default_irq(base) ide_default_irq(base) + +static IDE_INLINE int +ide_request_irq( + unsigned int irq, + void (*handler)(int, void *, struct pt_regs *), + unsigned long flags, + const char *device, + void *dev_id) +{ +#ifdef CONFIG_COLDFIRE + mcf_autovector(irq); +#endif + return(request_irq(irq, handler, flags, device, dev_id)); +} + + +static IDE_INLINE void +ide_free_irq(unsigned int irq, void *dev_id) +{ + free_irq(irq, dev_id); +} + + +static IDE_INLINE int +ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return 0; +} + + +static IDE_INLINE void +ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name) +{ +} + + +static IDE_INLINE void +ide_release_region(ide_ioreg_t from, unsigned int extent) +{ +} + + +static IDE_INLINE void +ide_fix_driveid(struct hd_driveid *id) +{ +#ifdef CONFIG_COLDFIRE + int i, n; + unsigned short *wp = (unsigned short *) id; + int avoid[] = {49, 51, 52, 59, -1 }; /* do not swap these words */ + + /* Need to byte swap shorts, but not char fields */ + for (i = n = 0; i < sizeof(*id) / sizeof(*wp); i++, wp++) { + if (avoid[n] == i) { + n++; + continue; + } + *wp = ((*wp & 0xff) << 8) | ((*wp >> 8) & 0xff); + } + /* have to word swap the one 32 bit field */ + id->lba_capacity = ((id->lba_capacity & 0xffff) << 16) | + ((id->lba_capacity >> 16) & 0xffff); +#endif +} + + +static IDE_INLINE void +ide_release_lock (int *ide_lock) +{ +} + + +static IDE_INLINE void +ide_get_lock( + int *ide_lock, + void (*handler)(int, void *, struct pt_regs *), + void *data) +{ +} + + +#define ide_ack_intr(hwif) \ + ((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1) +#define ide__sti() __sti() + +/****************************************************************************/ +/* + * System specific IO requirements + */ + +#ifdef CONFIG_COLDFIRE + +#ifdef CONFIG_SECUREEDGEMP3 + +/* Replace standard IO functions for funky mapping of MP3 board */ +#undef outb +#undef outb_p +#undef inb +#undef inb_p + +#define outb(v, a) ide_outb(v, (unsigned long) (a)) +#define outb_p(v, a) ide_outb(v, (unsigned long) (a)) +#define inb(a) ide_inb((unsigned long) (a)) +#define inb_p(a) ide_inb((unsigned long) (a)) + +#define ADDR8_PTR(addr) (((addr) & 0x1) ? (0x8000 + (addr) - 1) : (addr)) +#define ADDR16_PTR(addr) (addr) +#define ADDR32_PTR(addr) (addr) +#define SWAP8(w) ((((w) & 0xffff) << 8) | (((w) & 0xffff) >> 8)) +#define SWAP16(w) (w) +#define SWAP32(w) (w) + + +static IDE_INLINE void +ide_outb(unsigned int val, unsigned int addr) +{ + volatile unsigned short *rp; + + DBGIDE("%s(val=%x,addr=%x)\n", __FUNCTION__, val, addr); + rp = (volatile unsigned short *) ADDR8_PTR(addr); + *rp = SWAP8(val); +} + + +static IDE_INLINE int +ide_inb(unsigned int addr) +{ + volatile unsigned short *rp, val; + + DBGIDE("%s(addr=%x)\n", __FUNCTION__, addr); + rp = (volatile unsigned short *) ADDR8_PTR(addr); + val = *rp; + return(SWAP8(val)); +} + + +static IDE_INLINE void +ide_outw(unsigned int val, unsigned int addr) +{ + volatile unsigned short *rp; + + DBGIDE("%s(val=%x,addr=%x)\n", __FUNCTION__, val, addr); + rp = (volatile unsigned short *) ADDR16_PTR(addr); + *rp = SWAP16(val); +} + +static IDE_INLINE void +ide_outsw(unsigned int addr, const void *vbuf, unsigned long len) +{ + volatile unsigned short *rp, val; + unsigned short *buf; + + DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len); + buf = (unsigned short *) vbuf; + rp = (volatile unsigned short *) ADDR16_PTR(addr); + for (; (len > 0); len--) { + val = *buf++; + *rp = SWAP16(val); + } +} + +static IDE_INLINE int +ide_inw(unsigned int addr) +{ + volatile unsigned short *rp, val; + + DBGIDE("%s(addr=%x)\n", __FUNCTION__, addr); + rp = (volatile unsigned short *) ADDR16_PTR(addr); + val = *rp; + return(SWAP16(val)); +} + +static IDE_INLINE void +ide_insw(unsigned int addr, void *vbuf, unsigned long len) +{ + volatile unsigned short *rp; + unsigned short w, *buf; + + DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len); + buf = (unsigned short *) vbuf; + rp = (volatile unsigned short *) ADDR16_PTR(addr); + for (; (len > 0); len--) { + w = *rp; + *buf++ = SWAP16(w); + } +} + +static IDE_INLINE void +ide_insl(unsigned int addr, void *vbuf, unsigned long len) +{ + volatile unsigned long *rp; + unsigned long w, *buf; + + DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len); + buf = (unsigned long *) vbuf; + rp = (volatile unsigned long *) ADDR32_PTR(addr); + for (; (len > 0); len--) { + w = *rp; + *buf++ = SWAP32(w); + } +} + +static IDE_INLINE void +ide_outsl(unsigned int addr, const void *vbuf, unsigned long len) +{ + volatile unsigned long *rp, val; + unsigned long *buf; + + DBGIDE("%s(addr=%x,vbuf=%p,len=%x)\n", __FUNCTION__, addr, vbuf, len); + buf = (unsigned long *) vbuf; + rp = (volatile unsigned long *) ADDR32_PTR(addr); + for (; (len > 0); len--) { + val = *buf++; + *rp = SWAP32(val); + } +} + +#elif CONFIG_eLIA + +/* 8/16 bit acesses are controlled by flicking bits in the CS register */ +#define ACCESS_MODE_16BIT() \ + *((volatile unsigned short *) (MCF_MBAR + MCFSIM_LOCALCS)) = 0x0080 +#define ACCESS_MODE_8BIT() \ + *((volatile unsigned short *) (MCF_MBAR + MCFSIM_LOCALCS)) = 0x0040 + + +static IDE_INLINE void +ide_outw(unsigned int val, unsigned int addr) +{ + ACCESS_MODE_16BIT(); + outw(val, addr); + ACCESS_MODE_8BIT(); +} + +static IDE_INLINE void +ide_outsw(unsigned int addr, const void *vbuf, unsigned long len) +{ + ACCESS_MODE_16BIT(); + outsw(addr, vbuf, len); + ACCESS_MODE_8BIT(); +} + +static IDE_INLINE int +ide_inw(unsigned int addr) +{ + int ret; + + ACCESS_MODE_16BIT(); + ret = inw(addr); + ACCESS_MODE_8BIT(); + return(ret); +} + +static IDE_INLINE void +ide_insw(unsigned int addr, void *vbuf, unsigned long len) +{ + ACCESS_MODE_16BIT(); + insw(addr, vbuf, len); + ACCESS_MODE_8BIT(); +} + +static IDE_INLINE void +ide_insl(unsigned int addr, void *vbuf, unsigned long len) +{ + ACCESS_MODE_16BIT(); + insl(addr, vbuf, len); + ACCESS_MODE_8BIT(); +} + +static IDE_INLINE void +ide_outsl(unsigned int addr, const void *vbuf, unsigned long len) +{ + ACCESS_MODE_16BIT(); + outsl(addr, vbuf, len); + ACCESS_MODE_8BIT(); +} + +#endif /* CONFIG_SECUREEDGEMP3 */ + +#undef outw +#undef outw_p +#undef outsw +#undef inw +#undef inw_p +#undef insw +#undef insl +#undef outsl + +#define outw(v, a) ide_outw(v, (unsigned long) (a)) +#define outw_p(v, a) ide_outw(v, (unsigned long) (a)) +#define outsw(a, b, n) ide_outsw((unsigned long) (a), b, n) +#define inw(a) ide_inw((unsigned long) (a)) +#define inw_p(a) ide_inw((unsigned long) (a)) +#define insw(a, b, n) ide_insw((unsigned long) (a), b, n) +#define insl(a, b, n) ide_insl((unsigned long) (a), b, n) +#define outsl(a, b, n) ide_outsl((unsigned long) (a), b, n) + +#endif CONFIG_COLDFIRE + +/****************************************************************************/ +#endif /* __KERNEL__ */ +#endif /* _M68KNOMMU_IDE_H */ +/****************************************************************************/ |