• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
read_eprom_byte(virt_addr_t base,u_int8_t offset)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 
nicstar_init_eprom(virt_addr_t base)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
nicstar_read_eprom(virt_addr_t base,u_int8_t prom_offset,u_int8_t * buffer,u_int32_t nbytes)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