1 /* 2 * this file included by nicstar.c 3 */ 4 5 /* 6 * nicstarmac.c 7 * Read this ForeRunner's MAC address from eprom/eeprom 8 */ 9 10 #include <linux/kernel.h> 11 12 typedef void __iomem *virt_addr_t; 13 14 #define CYCLE_DELAY 5 15 16 /* This was the original definition 17 #define osp_MicroDelay(microsec) \ 18 do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0) 19 */ 20 #define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \ 21 udelay((useconds));} 22 23 24 /* The following tables represent the timing diagrams found in 25 * the Data Sheet for the Xicor X25020 EEProm. The #defines below 26 * represent the bits in the NICStAR's General Purpose register 27 * that must be toggled for the corresponding actions on the EEProm 28 * to occur. 29 */ 30 31 /* Write Data To EEProm from SI line on rising edge of CLK */ 32 /* Read Data From EEProm on falling edge of CLK */ 33 34 #define CS_HIGH 0x0002 /* Chip select high */ 35 #define CS_LOW 0x0000 /* Chip select low (active low)*/ 36 #define CLK_HIGH 0x0004 /* Clock high */ 37 #define CLK_LOW 0x0000 /* Clock low */ 38 #define SI_HIGH 0x0001 /* Serial input data high */ 39 #define SI_LOW 0x0000 /* Serial input data low */ 40 41 /* Read Status Register = 0000 0101b */ 42 #if 0 43 static u_int32_t rdsrtab[] = 44 { 45 CS_HIGH | CLK_HIGH, 46 CS_LOW | CLK_LOW, 47 CLK_HIGH, /* 0 */ 48 CLK_LOW, 49 CLK_HIGH, /* 0 */ 50 CLK_LOW, 51 CLK_HIGH, /* 0 */ 52 CLK_LOW, 53 CLK_HIGH, /* 0 */ 54 CLK_LOW, 55 CLK_HIGH, /* 0 */ 56 CLK_LOW | SI_HIGH, 57 CLK_HIGH | SI_HIGH, /* 1 */ 58 CLK_LOW | SI_LOW, 59 CLK_HIGH, /* 0 */ 60 CLK_LOW | SI_HIGH, 61 CLK_HIGH | SI_HIGH /* 1 */ 62 }; 63 #endif /* 0 */ 64 65 66 /* Read from EEPROM = 0000 0011b */ 67 static u_int32_t readtab[] = 68 { 69 /* 70 CS_HIGH | CLK_HIGH, 71 */ 72 CS_LOW | CLK_LOW, 73 CLK_HIGH, /* 0 */ 74 CLK_LOW, 75 CLK_HIGH, /* 0 */ 76 CLK_LOW, 77 CLK_HIGH, /* 0 */ 78 CLK_LOW, 79 CLK_HIGH, /* 0 */ 80 CLK_LOW, 81 CLK_HIGH, /* 0 */ 82 CLK_LOW, 83 CLK_HIGH, /* 0 */ 84 CLK_LOW | SI_HIGH, 85 CLK_HIGH | SI_HIGH, /* 1 */ 86 CLK_LOW | SI_HIGH, 87 CLK_HIGH | SI_HIGH /* 1 */ 88 }; 89 90 91 /* Clock to read from/write to the eeprom */ 92 static u_int32_t clocktab[] = 93 { 94 CLK_LOW, 95 CLK_HIGH, 96 CLK_LOW, 97 CLK_HIGH, 98 CLK_LOW, 99 CLK_HIGH, 100 CLK_LOW, 101 CLK_HIGH, 102 CLK_LOW, 103 CLK_HIGH, 104 CLK_LOW, 105 CLK_HIGH, 106 CLK_LOW, 107 CLK_HIGH, 108 CLK_LOW, 109 CLK_HIGH, 110 CLK_LOW 111 }; 112 113 114 #define NICSTAR_REG_WRITE(bs, reg, val) \ 115 while ( readl(bs + STAT) & 0x0200 ) ; \ 116 writel((val),(base)+(reg)) 117 #define NICSTAR_REG_READ(bs, reg) \ 118 readl((base)+(reg)) 119 #define NICSTAR_REG_GENERAL_PURPOSE GP 120 121 /* 122 * This routine will clock the Read_Status_reg function into the X2520 123 * eeprom, then pull the result from bit 16 of the NicSTaR's General Purpose 124 * register. 125 */ 126 #if 0 127 u_int32_t 128 nicstar_read_eprom_status( virt_addr_t base ) 129 { 130 u_int32_t val; 131 u_int32_t rbyte; 132 int32_t i, j; 133 134 /* Send read instruction */ 135 val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0; 136 137 for (i=0; i<ARRAY_SIZE(rdsrtab); i++) 138 { 139 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 140 (val | rdsrtab[i]) ); 141 osp_MicroDelay( CYCLE_DELAY ); 142 } 143 144 /* Done sending instruction - now pull data off of bit 16, MSB first */ 145 /* Data clocked out of eeprom on falling edge of clock */ 146 147 rbyte = 0; 148 for (i=7, j=0; i>=0; i--) 149 { 150 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 151 (val | clocktab[j++]) ); 152 rbyte |= (((NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE) 153 & 0x00010000) >> 16) << i); 154 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 155 (val | clocktab[j++]) ); 156 osp_MicroDelay( CYCLE_DELAY ); 157 } 158 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 2 ); 159 osp_MicroDelay( CYCLE_DELAY ); 160 return rbyte; 161 } 162 #endif /* 0 */ 163 164 165 /* 166 * This routine will clock the Read_data function into the X2520 167 * eeprom, followed by the address to read from, through the NicSTaR's General 168 * Purpose register. 169 */ 170 171 static u_int8_t 172 read_eprom_byte(virt_addr_t base, u_int8_t offset) 173 { 174 u_int32_t val = 0; 175 int i,j=0; 176 u_int8_t tempread = 0; 177 178 val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0; 179 180 /* Send READ instruction */ 181 for (i=0; i<ARRAY_SIZE(readtab); i++) 182 { 183 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 184 (val | readtab[i]) ); 185 osp_MicroDelay( CYCLE_DELAY ); 186 } 187 188 /* Next, we need to send the byte address to read from */ 189 for (i=7; i>=0; i--) 190 { 191 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 192 (val | clocktab[j++] | ((offset >> i) & 1) ) ); 193 osp_MicroDelay(CYCLE_DELAY); 194 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 195 (val | clocktab[j++] | ((offset >> i) & 1) ) ); 196 osp_MicroDelay( CYCLE_DELAY ); 197 } 198 199 j = 0; 200 201 /* Now, we can read data from the eeprom by clocking it in */ 202 for (i=7; i>=0; i--) 203 { 204 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 205 (val | clocktab[j++]) ); 206 osp_MicroDelay( CYCLE_DELAY ); 207 tempread |= (((NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) 208 & 0x00010000) >> 16) << i); 209 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 210 (val | clocktab[j++]) ); 211 osp_MicroDelay( CYCLE_DELAY ); 212 } 213 214 NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE, 2 ); 215 osp_MicroDelay( CYCLE_DELAY ); 216 return tempread; 217 } 218 219 220 static void 221 nicstar_init_eprom( virt_addr_t base ) 222 { 223 u_int32_t val; 224 225 /* 226 * turn chip select off 227 */ 228 val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0; 229 230 NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 231 (val | CS_HIGH | CLK_HIGH)); 232 osp_MicroDelay( CYCLE_DELAY ); 233 234 NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 235 (val | CS_HIGH | CLK_LOW)); 236 osp_MicroDelay( CYCLE_DELAY ); 237 238 NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 239 (val | CS_HIGH | CLK_HIGH)); 240 osp_MicroDelay( CYCLE_DELAY ); 241 242 NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 243 (val | CS_HIGH | CLK_LOW)); 244 osp_MicroDelay( CYCLE_DELAY ); 245 } 246 247 248 /* 249 * This routine will be the interface to the ReadPromByte function 250 * above. 251 */ 252 253 static void 254 nicstar_read_eprom( 255 virt_addr_t base, 256 u_int8_t prom_offset, 257 u_int8_t *buffer, 258 u_int32_t nbytes ) 259 { 260 u_int i; 261 262 for (i=0; i<nbytes; i++) 263 { 264 buffer[i] = read_eprom_byte( base, prom_offset ); 265 ++prom_offset; 266 osp_MicroDelay( CYCLE_DELAY ); 267 } 268 } 269 270 271 /* 272 void osp_MicroDelay(int x) { 273 274 } 275 */ 276 277