nicstarmac.c (5979B)
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 13typedef 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 39static 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 */ 61static 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 */ 84static 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 117u_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 157static 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 202static 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 233static void 234nicstar_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}