Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | /****************************************************************************/ /* * 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 */ |