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