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