1 /*
2 * Oxford Semiconductor OXPCIe95x UART driver
3 */
4 #include "u.h"
5 #include "../port/lib.h"
6 #include "mem.h"
7 #include "dat.h"
8 #include "fns.h"
9 #include "io.h"
10 #include "../port/error.h"
11
12 extern PhysUart oxphysuart;
13
14 enum {
15 Ccr = 0x0000/4, /* Class Code and Revision ID */
16 Nuart = 0x0004/4, /* Decimal Number of UARTs */
17 Gis = 0x0008/4, /* Global UART IRQ Status */
18 Gie = 0x000C/4, /* Global UART IRQ Enable */
19 Gid = 0x0010/4, /* Global UART IRQ Disable */
20 Gwe = 0x0014/4, /* Global UART Wake Enable */
21 Gwd = 0x0018/4, /* Global UART Wake Disable */
22 };
23
24 enum {
25 Thr = 0x00, /* Transmitter Holding */
26 Rhr = 0x00, /* Receiver Holding */
27 Ier = 0x01, /* Interrupt Enable */
28 Fcr = 0x02, /* FIFO Control */
29 Isr = 0x02, /* Interrupt Status */
30 Lcr = 0x03, /* Line Control */
31 Mcr = 0x04, /* Modem Control */
32 Lsr = 0x05, /* Line Status */
33 Msr = 0x06, /* Modem Status */
34 Spr = 0x07, /* Scratch Pad */
35 Dll = 0x00, /* Divisor Latch LSB */
36 Dlm = 0x01, /* Divisor Latch MSB */
37 Efr = 0x02, /* Enhanced Feature */
38 };
39
40 typedef struct Port Port;
41 typedef struct Ctlr Ctlr;
42
43 struct Port {
44 Uart;
45 Ctlr *ctlr;
46 u8int *mem;
47
48 int level;
49 int dtr, rts;
50 int ri;
51 };
52
53 struct Ctlr {
54 Lock;
55 char *name;
56 Pcidev *pcidev;
57 u32int *mem;
58
59 u32int im;
60
61 Port port[0x10];
62 int nport;
63 };
64
65 static Uart *
oxpnp(void)66 oxpnp(void)
67 {
68 Pcidev *p;
69 Ctlr *ctlr;
70 Port *port;
71 int i;
72 char *model;
73 char name[12+1];
74 Uart *head, *tail;
75 static int ctlrno;
76
77 p = nil;
78 head = tail = nil;
79 while(p = pcimatch(p, 0x1415, 0)){
80 switch(p->did){
81 case 0xc101:
82 case 0xc105:
83 case 0xc11b:
84 case 0xc11f:
85 case 0xc120:
86 case 0xc124:
87 case 0xc138:
88 case 0xc13d:
89 case 0xc140:
90 case 0xc141:
91 case 0xc144:
92 case 0xc145:
93 case 0xc158:
94 case 0xc15d:
95 model = "OXPCIe952";
96 break;
97 case 0xc208:
98 case 0xc20d:
99 model = "OXPCIe954";
100 break;
101 case 0xc308:
102 case 0xc30d:
103 model = "OXPCIe958";
104 break;
105 default:
106 continue;
107 }
108 ctlr = malloc(sizeof *ctlr);
109 if(ctlr == nil){
110 print("oxpnp: out of memory\n");
111 continue;
112 }
113 ctlr->pcidev = p;
114 ctlr->mem = vmap(p->mem[0].bar & ~0xf, p->mem[0].size);
115 if(ctlr->mem == nil){
116 print("oxpnp: vmap failed\n");
117 free(ctlr);
118 continue;
119 }
120 snprint(name, sizeof name, "uartox%d", ctlrno);
121 kstrdup(&ctlr->name, name);
122 ctlr->nport = ctlr->mem[Nuart] & 0x1f;
123 for(i = 0; i < ctlr->nport; ++i){
124 port = &ctlr->port[i];
125 port->ctlr = ctlr;
126 port->mem = (u8int *)ctlr->mem + 0x1000 + 0x200*i;
127 port->regs = port;
128 snprint(name, sizeof name, "%s.%d", ctlr->name, i);
129 kstrdup(&port->name, name);
130 port->phys = &oxphysuart;
131 if(head == nil)
132 head = port;
133 else
134 tail->next = port;
135 tail = port;
136 }
137 print("%s: %s: %d ports irq %d\n",
138 ctlr->name, model, ctlr->nport, p->intl);
139 ctlrno++;
140 }
141 return head;
142 }
143
144 static void
oxinterrupt(Ureg *,void * arg)145 oxinterrupt(Ureg *, void *arg)
146 {
147 Ctlr *ctlr;
148 Port *port;
149 Uart *uart;
150 int i, old;
151 u8int val;
152 char ch;
153
154 ctlr = arg;
155
156 ilock(ctlr);
157 if(!(ctlr->im & ctlr->mem[Gis])){
158 iunlock(ctlr);
159 return;
160 }
161 for(i = 0; i < ctlr->nport; ++i){
162 if(!(ctlr->im & 1<<i))
163 continue;
164 port = &ctlr->port[i];
165 uart = port; /* "Come Clarity" */
166 switch(port->mem[Isr] & 0x3f){
167 case 0x06: /* Receiver status error */
168 case 0x04: /* Receiver data available */
169 case 0x0c: /* Receiver time-out */
170 for(;;){
171 val = port->mem[Lsr];
172 if(!(val & 1<<0)) /* RxRDY */
173 break;
174 if(val & 1<<1) /* Overrun Error */
175 uart->oerr++;
176 if(val & 1<<2) /* Parity Error */
177 uart->perr++;
178 if(val & 1<<3) /* Framing Error */
179 uart->ferr++;
180 ch = port->mem[Rhr];
181 if(!(val & 1<<7)) /* Data Error */
182 uartrecv(uart, ch);
183 }
184 break;
185 case 0x02: /* Transmitter THR empty */
186 uartkick(uart);
187 break;
188 case 0x00: /* Modem status change */
189 val = port->mem[Msr];
190 if(val & 1<<0){ /* Delta nCTS */
191 ilock(&uart->tlock);
192 old = uart->cts;
193 uart->cts = val & 1<<4; /* CTS */
194 if(!old && uart->cts)
195 uart->ctsbackoff = 2;
196 iunlock(&uart->tlock);
197 }
198 if(val & 1<<1){ /* Delta nDSR */
199 old = val & 1<<5; /* DSR */
200 if(!old && uart->dsr && uart->hup_dsr)
201 uart->dohup = 1;
202 uart->dsr = old;
203 }
204 port->ri = val & 1<<6; /* RI */
205 if(val & 1<<3){ /* Delta nDCD */
206 old = val & 1<<7; /* DCD */
207 if(!old && uart->dcd && uart->hup_dcd)
208 uart->dohup = 1;
209 uart->dcd = old;
210 }
211 break;
212 }
213 }
214 iunlock(ctlr);
215 }
216
217 #define MASK(p) (1UL<<((p)-(p)->ctlr->port))
218
219 static void
oxenable(Uart * uart,int)220 oxenable(Uart *uart, int)
221 {
222 Ctlr *ctlr;
223 Port *port;
224
225 port = uart->regs;
226 ctlr = port->ctlr;
227
228 ilock(ctlr);
229 if(ctlr->im == 0)
230 intrenable(ctlr->pcidev->intl, oxinterrupt, ctlr,
231 ctlr->pcidev->tbdf, ctlr->name);
232 ctlr->im |= MASK(port);
233 iunlock(ctlr);
234
235 /* Enable 950 Mode */
236 port->mem[Lcr] |= 1<<7; /* Divisor latch access */
237 port->mem[Efr] = 1<<4; /* Enhanced mode */
238 port->mem[Lcr] &= ~(1<<7);
239
240 port->mem[Ier] = 1<<2|1<<1|1<<0; /* Rx Stat, THRE, RxRDY */
241
242 (*uart->phys->dtr)(uart, 1);
243 (*uart->phys->rts)(uart, 1);
244
245 /* Enable FIFO */
246 (*uart->phys->fifo)(uart, ~0);
247 }
248
249 static void
oxdisable(Uart * uart)250 oxdisable(Uart *uart)
251 {
252 Ctlr *ctlr;
253 Port *port;
254
255 port = uart->regs;
256 ctlr = port->ctlr;
257
258 (*uart->phys->dtr)(uart, 0);
259 (*uart->phys->rts)(uart, 0);
260 (*uart->phys->fifo)(uart, 0);
261
262 port->mem[Ier] = 0;
263
264 ilock(ctlr);
265 ctlr->im &= ~MASK(port);
266 if(ctlr->im == 0)
267 intrdisable(ctlr->pcidev->intl, oxinterrupt, ctlr,
268 ctlr->pcidev->tbdf, ctlr->name);
269 iunlock(ctlr);
270 }
271
272 static void
oxkick(Uart * uart)273 oxkick(Uart *uart)
274 {
275 Port *port;
276
277 if(uart->cts == 0 || uart->blocked)
278 return;
279
280 port = uart->regs;
281
282 for(;;){
283 if(!(port->mem[Lsr] & 1<<5)) /* THR Empty */
284 break;
285 if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
286 break;
287 port->mem[Thr] = *(uart->op++);
288 }
289 }
290
291 static void
oxdobreak(Uart * uart,int ms)292 oxdobreak(Uart *uart, int ms)
293 {
294 Port *port;
295
296 if(ms <= 0)
297 ms = 200;
298
299 port = uart->regs;
300
301 port->mem[Lcr] |= 1<<6; /* Transmission break */
302 if(!waserror()){
303 tsleep(&up->sleep, return0, nil, ms);
304 poperror();
305 }
306 port->mem[Lcr] &= ~(1<<6);
307 }
308
309 static int
oxbaud(Uart * uart,int baud)310 oxbaud(Uart *uart, int baud)
311 {
312 Port *port;
313 u16int val;
314
315 if(baud <= 0)
316 return -1;
317
318 port = uart->regs;
319
320 /*
321 * We aren't terribly interested in non-standard baud rates.
322 * Rather than mess about with generator constants, we instead
323 * program DLM and DLL according to Table 37 in the datasheet.
324 */
325 switch(baud){
326 case 1200:
327 val = 0x0cb6;
328 break;
329 case 2400:
330 val = 0x065b;
331 break;
332 case 4800:
333 val = 0x032d;
334 break;
335 case 9600:
336 val = 0x0196;
337 break;
338 case 19200:
339 val = 0x00cb;
340 break;
341 case 38400:
342 val = 0x0066;
343 break;
344 case 57600:
345 val = 0x0044;
346 break;
347 case 115200:
348 val = 0x0022;
349 break;
350 default:
351 return -1;
352 }
353 port->mem[Lcr] |= 1<<7; /* Divisor latch access */
354 port->mem[Dlm] = val>>8;
355 port->mem[Dll] = val;
356 port->mem[Lcr] &= ~(1<<7);
357 uart->baud = baud;
358 return 0;
359 }
360
361 static int
oxbits(Uart * uart,int bits)362 oxbits(Uart *uart, int bits)
363 {
364 Port *port;
365 u8int val;
366
367 port = uart->regs;
368
369 val = port->mem[Lcr] & 0x7c;
370 switch(bits){
371 case 8:
372 val |= 0x3; /* Data length */
373 break;
374 case 7:
375 val |= 0x2;
376 break;
377 case 6:
378 val |= 0x1;
379 break;
380 case 5:
381 break;
382 default:
383 return -1;
384 }
385 port->mem[Lcr] = val;
386 uart->bits = bits;
387 return 0;
388 }
389
390 static int
oxstop(Uart * uart,int stop)391 oxstop(Uart *uart, int stop)
392 {
393 Port *port;
394 u8int val;
395
396 port = uart->regs;
397
398 val = port->mem[Lcr] & 0x7b;
399 switch(stop){
400 case 2:
401 val |= 1<<2; /* Number of Stop Bits */
402 break;
403 case 1:
404 break;
405 default:
406 return -1;
407 }
408 port->mem[Lcr] = val;
409 uart->stop = stop;
410 return 0;
411 }
412
413 static int
oxparity(Uart * uart,int parity)414 oxparity(Uart *uart, int parity)
415 {
416 Port *port;
417 u8int val;
418
419 port = uart->regs;
420
421 val = port->mem[Lcr] & 0x67;
422 switch(parity){
423 case 'e':
424 val |= 1<<4; /* Even/Odd Parity */
425 case 'o':
426 val |= 1<<3; /* Parity Enable */
427 break;
428 case 'n':
429 break;
430 default:
431 return -1;
432 }
433 port->mem[Lcr] = val;
434 uart->parity = parity;
435 return 0;
436 }
437
438 static void
oxmodemctl(Uart * uart,int on)439 oxmodemctl(Uart *uart, int on)
440 {
441 Ctlr *ctlr;
442 Port *port;
443
444 port = uart->regs;
445 ctlr = port->ctlr;
446
447 ilock(ctlr);
448 ilock(&uart->tlock);
449 if(on){
450 port->mem[Ier] |= 1<<3; /* Modem */
451 uart->cts = port->mem[Msr] & 1<<4; /* CTS */
452 }else{
453 port->mem[Ier] &= ~(1<<3);
454 uart->cts = 1;
455 }
456 uart->modem = on;
457 iunlock(&uart->tlock);
458 iunlock(ctlr);
459 }
460
461 static void
oxrts(Uart * uart,int on)462 oxrts(Uart *uart, int on)
463 {
464 Port *port;
465
466 port = uart->regs;
467
468 if(on)
469 port->mem[Mcr] |= 1<<1; /* RTS */
470 else
471 port->mem[Mcr] &= ~(1<<1);
472 port->rts = on;
473 }
474
475 static void
oxdtr(Uart * uart,int on)476 oxdtr(Uart *uart, int on)
477 {
478 Port *port;
479
480 port = uart->regs;
481
482 if(on)
483 port->mem[Mcr] |= 1<<0; /* DTR */
484 else
485 port->mem[Mcr] &= ~(1<<0);
486 port->dtr = on;
487 }
488
489 static long
oxstatus(Uart * uart,void * buf,long n,long offset)490 oxstatus(Uart *uart, void *buf, long n, long offset)
491 {
492 Port *port;
493
494 if(offset > 0)
495 return 0;
496
497 port = uart->regs;
498
499 return snprint(buf, n,
500 "b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n"
501 "dev(%d) type(%d) framing(%d) overruns(%d) "
502 "berr(%d) serr(%d)%s%s%s%s\n",
503
504 uart->baud,
505 uart->hup_dcd,
506 port->dtr,
507 uart->hup_dsr,
508 uart->bits,
509 uart->modem,
510 uart->parity,
511 port->rts,
512 uart->stop,
513 port->level,
514
515 uart->dev,
516 uart->type,
517 uart->ferr,
518 uart->oerr,
519 uart->berr,
520 uart->serr,
521 uart->cts ? " cts": "",
522 uart->dsr ? " dsr": "",
523 port->ri ? " ring": "",
524 uart->dcd ? " dcd": ""
525 );
526 }
527
528 static void
oxfifo(Uart * uart,int level)529 oxfifo(Uart *uart, int level)
530 {
531 Ctlr *ctlr;
532 Port *port;
533
534 port = uart->regs;
535 ctlr = port->ctlr;
536
537 /*
538 * 950 Mode FIFOs have a depth of 128 bytes; devuart only
539 * cares about setting RHR trigger levels. THR trigger
540 * levels are not supported.
541 */
542 ilock(ctlr);
543 if(level == 0)
544 port->mem[Fcr] = 0; /* Disable FIFO */
545 else{
546 port->mem[Fcr] = 1<<0; /* Enable FIFO */
547 switch(level){
548 default:
549 level = 112;
550 case 112:
551 port->mem[Fcr] = 0x03<<6|1<<0; /* RHR Trigger Level */
552 break;
553 case 64:
554 port->mem[Fcr] = 0x02<<6|1<<0;
555 break;
556 case 32:
557 port->mem[Fcr] = 0x01<<6|1<<0;
558 break;
559 case 16:
560 break;
561 }
562 }
563 port->level = level;
564 iunlock(ctlr);
565 }
566
567 PhysUart oxphysuart = {
568 .name = "OXPCIe95x",
569 .pnp = oxpnp,
570 .enable = oxenable,
571 .disable = oxdisable,
572 .kick = oxkick,
573 .dobreak = oxdobreak,
574 .baud = oxbaud,
575 .bits = oxbits,
576 .stop = oxstop,
577 .parity = oxparity,
578 .modemctl = oxmodemctl,
579 .rts = oxrts,
580 .dtr = oxdtr,
581 .status = oxstatus,
582 .fifo = oxfifo,
583 };
584