arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / drivers / ata / pata_parport / bpck.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * (c) 1996-1998  Grant R. Guenther <grant@torque.net>
4  *
5  * bpck.c is a low-level protocol driver for the MicroSolutions
6  * "backpack" parallel port IDE adapter.
7  */
8
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/delay.h>
12 #include <linux/kernel.h>
13 #include <linux/types.h>
14 #include <linux/wait.h>
15 #include <asm/io.h>
16 #include "pata_parport.h"
17
18 #undef r2
19 #undef w2
20 #undef PC
21
22 #define PC                      pi->private
23 #define r2()                    (PC=(in_p(2) & 0xff))
24 #define w2(byte)                {out_p(2,byte); PC = byte;}
25 #define t2(pat)                 {PC ^= pat; out_p(2,PC);}
26 #define e2()                    {PC &= 0xfe; out_p(2,PC);}
27 #define o2()                    {PC |= 1; out_p(2,PC);}
28
29 #define j44(l,h)     (((l>>3)&0x7)|((l>>4)&0x8)|((h<<1)&0x70)|(h&0x80))
30
31 /*
32  * cont = 0 - access the IDE register file
33  * cont = 1 - access the IDE command set
34  * cont = 2 - use internal bpck register addressing
35  */
36 static int  cont_map[3] = { 0x40, 0x48, 0 };
37
38 static int bpck_read_regr(struct pi_adapter *pi, int cont, int regr)
39 {
40         int r, l, h;
41
42         r = regr + cont_map[cont];
43
44         switch (pi->mode) {
45         case 0:
46                 w0(r & 0xf); w0(r); t2(2); t2(4);
47                 l = r1();
48                 t2(4);
49                 h = r1();
50                 return j44(l, h);
51         case 1:
52                 w0(r & 0xf); w0(r); t2(2);
53                 e2(); t2(0x20);
54                 t2(4); h = r0();
55                 t2(1); t2(0x20);
56                 return h;
57         case 2:
58         case 3:
59         case 4:
60                 w0(r); w2(9); w2(0); w2(0x20);
61                 h = r4();
62                 w2(0);
63                 return h;
64
65         }
66         return -1;
67 }
68
69 static void bpck_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
70 {
71         int r;
72
73         r = regr + cont_map[cont];
74
75         switch (pi->mode) {
76         case 0:
77         case 1: w0(r);
78                 t2(2);
79                 w0(val);
80                 o2(); t2(4); t2(1);
81                 break;
82         case 2:
83         case 3:
84         case 4: w0(r); w2(9); w2(0);
85                 w0(val); w2(1); w2(3); w2(0);
86                 break;
87
88         }
89 }
90
91 /* These macros access the bpck registers in native addressing */
92
93 #define WR(r,v)         bpck_write_regr(pi,2,r,v)
94 #define RR(r)           (bpck_read_regr(pi,2,r))
95
96 static void bpck_write_block(struct pi_adapter *pi, char *buf, int count)
97 {
98         int i;
99
100         switch (pi->mode) {
101
102         case 0:
103                 WR(4, 0x40);
104                 w0(0x40); t2(2); t2(1);
105                 for (i = 0; i < count; i++) {
106                         w0(buf[i]);
107                         t2(4);
108                 }
109                 WR(4, 0);
110                 break;
111
112         case 1:
113                 WR(4, 0x50);
114                 w0(0x40); t2(2); t2(1);
115                 for (i = 0; i < count; i++) {
116                         w0(buf[i]);
117                         t2(4);
118                 }
119                 WR(4, 0x10);
120                 break;
121
122         case 2:
123                 WR(4, 0x48);
124                 w0(0x40); w2(9); w2(0); w2(1);
125                 for (i = 0; i < count; i++)
126                         w4(buf[i]);
127                 w2(0);
128                 WR(4, 8);
129                 break;
130
131         case 3:
132                 WR(4, 0x48);
133                 w0(0x40); w2(9); w2(0); w2(1);
134                 for (i = 0; i < count / 2; i++)
135                         w4w(((u16 *)buf)[i]);
136                 w2(0);
137                 WR(4, 8);
138                 break;
139
140         case 4:
141                 WR(4, 0x48);
142                 w0(0x40); w2(9); w2(0); w2(1);
143                 for (i = 0; i < count / 4; i++)
144                         w4l(((u32 *)buf)[i]);
145                 w2(0);
146                 WR(4, 8);
147                 break;
148         }
149 }
150
151 static void bpck_read_block(struct pi_adapter *pi, char *buf, int count)
152 {
153         int i, l, h;
154
155         switch (pi->mode) {
156
157         case 0:
158                 WR(4, 0x40);
159                 w0(0x40); t2(2);
160                 for (i = 0; i < count; i++) {
161                         t2(4); l = r1();
162                         t2(4); h = r1();
163                         buf[i] = j44(l, h);
164                 }
165                 WR(4, 0);
166                 break;
167
168         case 1:
169                 WR(4, 0x50);
170                 w0(0x40); t2(2); t2(0x20);
171                 for (i = 0; i < count; i++) {
172                         t2(4);
173                         buf[i] = r0();
174                 }
175                 t2(1); t2(0x20);
176                 WR(4, 0x10);
177                 break;
178
179         case 2:
180                 WR(4, 0x48);
181                 w0(0x40); w2(9); w2(0); w2(0x20);
182                 for (i = 0; i < count; i++)
183                         buf[i] = r4();
184                 w2(0);
185                 WR(4, 8);
186                 break;
187
188         case 3:
189                 WR(4, 0x48);
190                 w0(0x40); w2(9); w2(0); w2(0x20);
191                 for (i = 0; i < count / 2; i++)
192                         ((u16 *)buf)[i] = r4w();
193                 w2(0);
194                 WR(4, 8);
195                 break;
196
197         case 4:
198                 WR(4, 0x48);
199                 w0(0x40); w2(9); w2(0); w2(0x20);
200                 for (i = 0; i < count / 4; i++)
201                         ((u32 *)buf)[i] = r4l();
202                 w2(0);
203                 WR(4, 8);
204                 break;
205
206         }
207 }
208
209 static int bpck_probe_unit(struct pi_adapter *pi)
210 {
211         int o1, o0, f7, id;
212         int t, s;
213
214         id = pi->unit;
215         s = 0;
216         w2(4); w2(0xe); r2(); t2(2);
217         o1 = r1()&0xf8;
218         o0 = r0();
219         w0(255-id); w2(4); w0(id);
220         t2(8); t2(8); t2(8);
221         t2(2); t = r1()&0xf8;
222         f7 = ((id % 8) == 7);
223         if ((f7) || (t != o1)) {
224                 t2(2);
225                 s = r1() & 0xf8;
226         }
227         if ((t == o1) && ((!f7) || (s == o1)))  {
228                 w2(0x4c); w0(o0);
229                 return 0;
230         }
231         t2(8); w0(0); t2(2); w2(0x4c); w0(o0);
232         return 1;
233 }
234
235 static void bpck_connect(struct pi_adapter *pi)
236 {
237         pi->saved_r0 = r0();
238         w0(0xff-pi->unit); w2(4); w0(pi->unit);
239         t2(8); t2(8); t2(8);
240         t2(2); t2(2);
241
242         switch (pi->mode) {
243         case 0:
244                 t2(8); WR(4, 0);
245                 break;
246         case 1:
247                 t2(8); WR(4, 0x10);
248                 break;
249         case 2:
250         case 3:
251         case 4:
252                 w2(0); WR(4, 8);
253                 break;
254         }
255
256         WR(5,8);
257
258         /*
259          * Possibly wrong, purpose unknown (fiddle with ESS logic ???)
260          * if (pi->devtype == PI_PCD) {
261          */
262         WR(0x46, 0x10);
263         WR(0x4c, 0x38);
264         WR(0x4d, 0x88);
265         WR(0x46, 0xa0);
266         WR(0x41, 0);
267         WR(0x4e, 8);
268         /* } */
269 }
270
271 static void bpck_disconnect(struct pi_adapter *pi)
272 {
273         w0(0);
274         if (pi->mode >= 2) {
275                 w2(9); w2(0);
276         } else {
277                 t2(2);
278         }
279         w2(0x4c); w0(pi->saved_r0);
280 }
281
282 static void bpck_force_spp(struct pi_adapter *pi)
283 {
284         /* This fakes the EPP protocol to turn off EPP ... */
285         pi->saved_r0 = r0();
286         w0(0xff-pi->unit); w2(4); w0(pi->unit);
287         t2(8); t2(8); t2(8);
288         t2(2); t2(2);
289
290         w2(0);
291         w0(4); w2(9); w2(0);
292         w0(0); w2(1); w2(3); w2(0);
293         w0(0); w2(9); w2(0);
294         w2(0x4c); w0(pi->saved_r0);
295 }
296
297 #define TEST_LEN  16
298
299 static int bpck_test_proto(struct pi_adapter *pi)
300 {
301         int i, e, l, h, om;
302         char buf[TEST_LEN];
303
304         bpck_force_spp(pi);
305
306         switch (pi->mode) {
307
308         case 0:
309                 bpck_connect(pi);
310                 WR(0x13, 0x7f);
311                 w0(0x13); t2(2);
312                 for (i = 0; i < TEST_LEN; i++) {
313                         t2(4); l = r1();
314                         t2(4); h = r1();
315                         buf[i] = j44(l, h);
316                 }
317                 bpck_disconnect(pi);
318                 break;
319
320         case 1:
321                 bpck_connect(pi);
322                 WR(0x13, 0x7f);
323                 w0(0x13); t2(2); t2(0x20);
324                 for (i = 0; i < TEST_LEN; i++) {
325                         t2(4);
326                         buf[i] = r0();
327                 }
328                 t2(1); t2(0x20);
329                 bpck_disconnect(pi);
330                 break;
331
332         case 2:
333         case 3:
334         case 4:
335                 om = pi->mode;
336                 pi->mode = 0;
337                 bpck_connect(pi);
338                 WR(7, 3);
339                 WR(4, 8);
340                 bpck_disconnect(pi);
341
342                 pi->mode = om;
343                 bpck_connect(pi);
344                 w0(0x13); w2(9); w2(1); w0(0); w2(3); w2(0); w2(0xe0);
345
346                 switch (pi->mode) {
347                 case 2:
348                         for (i = 0; i < TEST_LEN; i++)
349                                 buf[i] = r4();
350                         break;
351                 case 3:
352                         for (i = 0; i < TEST_LEN / 2; i++)
353                                 ((u16 *)buf)[i] = r4w();
354                         break;
355                 case 4:
356                         for (i = 0; i < TEST_LEN / 4; i++)
357                                 ((u32 *)buf)[i] = r4l();
358                         break;
359                 }
360
361                 w2(0);
362                 WR(7, 0);
363                 bpck_disconnect(pi);
364                 break;
365
366         }
367
368         dev_dbg(&pi->dev, "bpck: 0x%x unit %d mode %d: ",
369                 pi->port, pi->unit, pi->mode);
370         print_hex_dump_debug("bpck: ", DUMP_PREFIX_NONE, TEST_LEN, 1, buf,
371                              TEST_LEN, false);
372
373         e = 0;
374         for (i = 0; i < TEST_LEN; i++) {
375                 if (buf[i] != i + 1)
376                         e++;
377         }
378
379         return e;
380 }
381
382 static void bpck_read_eeprom(struct pi_adapter *pi, char *buf)
383 {
384         int i, j, k, p, v, f, om, od;
385
386         bpck_force_spp(pi);
387
388         om = pi->mode;  od = pi->delay;
389         pi->mode = 0; pi->delay = 6;
390
391         bpck_connect(pi);
392
393         WR(4, 0);
394         for (i = 0; i < 64; i++) {
395                 WR(6, 8);
396                 WR(6, 0xc);
397                 p = 0x100;
398                 for (k = 0; k < 9; k++) {
399                         f = (((i + 0x180) & p) != 0) * 2;
400                         WR(6, f + 0xc);
401                         WR(6, f + 0xd);
402                         WR(6, f + 0xc);
403                         p = (p >> 1);
404                 }
405                 for (j = 0; j < 2; j++) {
406                         v = 0;
407                         for (k = 0; k < 8; k++) {
408                                 WR(6, 0xc);
409                                 WR(6, 0xd);
410                                 WR(6, 0xc);
411                                 f = RR(0);
412                                 v = 2 * v + (f == 0x84);
413                         }
414                         buf[2 * i + 1 - j] = v;
415                 }
416         }
417         WR(6, 8);
418         WR(6, 0);
419         WR(5, 8);
420
421         bpck_disconnect(pi);
422
423         if (om >= 2) {
424                 bpck_connect(pi);
425                 WR(7, 3);
426                 WR(4, 8);
427                 bpck_disconnect(pi);
428         }
429
430         pi->mode = om; pi->delay = od;
431 }
432
433 static int bpck_test_port(struct pi_adapter *pi)
434 {
435         int i, r, m;
436
437         /* Check for 8-bit port */
438         w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i);
439         m = -1;
440         if (r == i)
441                 m = 2;
442         if (r == (255-i))
443                 m = 0;
444
445         w2(0xc);
446         i = r0();
447         w0(255-i);
448         r = r0();
449         w0(i);
450         if (r != (255-i))
451                 m = -1;
452
453         if (m == 0) {
454                 w2(6);
455                 w2(0xc);
456                 r = r0();
457                 w0(0xaa);
458                 w0(r);
459                 w0(0xaa);
460         }
461         if (m == 2) {
462                 w2(0x26);
463                 w2(0xc);
464         }
465
466         if (m == -1)
467                 return 0;
468
469         return 5;
470 }
471
472 static void bpck_log_adapter(struct pi_adapter *pi)
473 {
474         char *mode_str[5] = { "4-bit", "8-bit", "EPP-8", "EPP-16", "EPP-32" };
475         char scratch[128];
476
477         bpck_read_eeprom(pi,scratch);
478         print_hex_dump_bytes("bpck EEPROM: ", DUMP_PREFIX_NONE, scratch, 128);
479         dev_info(&pi->dev,
480                  "backpack %8.8s unit %d at 0x%x, mode %d (%s), delay %d\n",
481                  &scratch[110], pi->unit, pi->port, pi->mode,
482                  mode_str[pi->mode], pi->delay);
483 }
484
485 static struct pi_protocol bpck = {
486         .owner          = THIS_MODULE,
487         .name           = "bpck",
488         .max_mode       = 5,
489         .epp_first      = 2,
490         .default_delay  = 4,
491         .max_units      = 255,
492         .write_regr     = bpck_write_regr,
493         .read_regr      = bpck_read_regr,
494         .write_block    = bpck_write_block,
495         .read_block     = bpck_read_block,
496         .connect        = bpck_connect,
497         .disconnect     = bpck_disconnect,
498         .test_port      = bpck_test_port,
499         .probe_unit     = bpck_probe_unit,
500         .test_proto     = bpck_test_proto,
501         .log_adapter    = bpck_log_adapter,
502 };
503
504 MODULE_LICENSE("GPL");
505 MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");
506 MODULE_DESCRIPTION("MicroSolutions BACKPACK parallel port IDE adapter protocol driver");
507 module_pata_parport_driver(bpck);