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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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