Merge tag 'arm-apple-m1-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / drivers / atm / nicstarmac.c
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 }