/****************************************************************************/
/*
* mcfsmc.h -- SMC ethernet support for ColdFire environments.
*
* (C) Copyright 1999-2002, Greg Ungerer (gerg@snapgear.com)
* (C) Copyright 2000, Lineo Inc. (www.lineo.com)
*/
/****************************************************************************/
#ifndef mcfsmc_h
#define mcfsmc_h
/****************************************************************************/
/*
* None of the current ColdFire targets that use the SMC91x111
* allow 8 bit accesses. So this code is 16bit access only.
*/
#undef outb
#undef inb
#undef outw
#undef outwd
#undef inw
#undef outl
#undef inl
#undef outsb
#undef outsw
#undef outsl
#undef insb
#undef insw
#undef insl
/*
* Re-defines for ColdFire environment... The SMC part is
* mapped into memory space, so remap the PC-style in/out
* routines to handle that.
*/
#define outb smc_outb
#define inb smc_inb
#define outw smc_outw
#define outwd smc_outwd
#define inw smc_inw
#define outl smc_outl
#define inl smc_inl
#define outsb smc_outsb
#define outsw smc_outsw
#define outsl smc_outsl
#define insb smc_insb
#define insw smc_insw
#define insl smc_insl
static inline int smc_inb(unsigned int addr)
{
register unsigned short w;
w = *((volatile unsigned short *) (addr & ~0x1));
return(((addr & 0x1) ? w : (w >> 8)) & 0xff);
}
static inline void smc_outw(unsigned int val, unsigned int addr)
{
*((volatile unsigned short *) addr) = (val << 8) | (val >> 8);
}
static inline int smc_inw(unsigned int addr)
{
register unsigned short w;
w = *((volatile unsigned short *) addr);
return(((w << 8) | (w >> 8)) & 0xffff);
}
static inline void smc_outl(unsigned long val, unsigned int addr)
{
*((volatile unsigned long *) addr) =
((val << 8) & 0xff000000) | ((val >> 8) & 0x00ff0000) |
((val << 8) & 0x0000ff00) | ((val >> 8) & 0x000000ff);
}
static inline void smc_outwd(unsigned int val, unsigned int addr)
{
*((volatile unsigned short *) addr) = val;
}
/*
* The rep* functions are used to feed the data port with
* raw data. So we do not byte swap them when copying.
*/
static inline void smc_insb(unsigned int addr, void *vbuf, int unsigned long len)
{
volatile unsigned short *rp;
unsigned short *buf, *ebuf;
buf = (unsigned short *) vbuf;
rp = (volatile unsigned short *) addr;
/* Copy as words for as long as possible */
for (ebuf = buf + (len >> 1); (buf < ebuf); )
*buf++ = *rp;
/* Lastly, handle left over byte */
if (len & 0x1)
*((unsigned char *) buf) = (*rp >> 8) & 0xff;
}
static inline void smc_insw(unsigned int addr, void *vbuf, unsigned long len)
{
volatile unsigned short *rp;
unsigned short *buf, *ebuf;
buf = (unsigned short *) vbuf;
rp = (volatile unsigned short *) addr;
for (ebuf = buf + len; (buf < ebuf); )
*buf++ = *rp;
}
static inline void smc_insl(unsigned int addr, void *vbuf, unsigned long len)
{
volatile unsigned long *rp;
unsigned long *buf, *ebuf;
buf = (unsigned long *) vbuf;
rp = (volatile unsigned long *) addr;
for (ebuf = buf + len; (buf < ebuf); )
*buf++ = *rp;
}
static inline void smc_outsw(unsigned int addr, const void *vbuf, unsigned long len)
{
volatile unsigned short *rp;
unsigned short *buf, *ebuf;
buf = (unsigned short *) vbuf;
rp = (volatile unsigned short *) addr;
for (ebuf = buf + len; (buf < ebuf); )
*rp = *buf++;
}
static inline void smc_outsl(unsigned int addr, void *vbuf, unsigned long len)
{
volatile unsigned long *rp;
unsigned long *buf, *ebuf;
buf = (unsigned long *) vbuf;
rp = (volatile unsigned long *) addr;
for (ebuf = buf + len; (buf < ebuf); )
*rp = *buf++;
}
#ifdef CONFIG_NETtel
/*
* Re-map the address space of at least one of the SMC ethernet
* parts. Both parts power up decoding the same address, so we
* need to move one of them first, before doing enything else.
*
* We also increase the number of wait states for this part by one.
*/
void smc_remap(unsigned int ioaddr)
{
static int once = 0;
extern unsigned short ppdata;
if (once++ == 0) {
*((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADDR)) = 0x00ec;
ppdata |= 0x0080;
*((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata;
outw(0x0001, ioaddr + BANK_SELECT);
outw(0x0001, ioaddr + BANK_SELECT);
outw(0x0067, ioaddr + BASE);
ppdata &= ~0x0080;
*((volatile unsigned short *)(MCF_MBAR+MCFSIM_PADAT)) = ppdata;
}
*((volatile unsigned short *)(MCF_MBAR+MCFSIM_CSCR3)) = 0x1180;
}
#endif
/****************************************************************************/
#endif /* mcfsmc_h */