2 * omap35 8250-like UART
4 * we ignore the first 2 uarts on the omap35 (see below) and use the
5 * third one but call it 0.
9 #include "../port/lib.h"
14 enum { /* registers */
15 Rbr = 0, /* Receiver Buffer (RO) */
16 Thr = 0, /* Transmitter Holding (WO) */
17 Ier = 1, /* Interrupt Enable */
18 Iir = 2, /* Interrupt Identification (RO) */
19 Fcr = 2, /* FIFO Control (WO) */
20 Lcr = 3, /* Line Control */
21 Mcr = 4, /* Modem Control */
22 Lsr = 5, /* Line Status */
23 Msr = 6, /* Modem Status */
24 Scr = 7, /* Scratch Pad */
25 Mdr = 8, /* Mode Def'n (omap rw) */
26 // Usr = 31, /* Uart Status Register; missing in omap? */
27 Dll = 0, /* Divisor Latch LSB */
28 Dlm = 1, /* Divisor Latch MSB */
36 Erda = 0x01, /* Enable Received Data Available */
37 Ethre = 0x02, /* Enable Thr Empty */
38 Erls = 0x04, /* Enable Receiver Line Status */
39 Ems = 0x08, /* Enable Modem Status */
43 Ims = 0x00, /* Ms interrupt */
44 Ip = 0x01, /* Interrupt Pending (not) */
45 Ithre = 0x02, /* Thr Empty */
46 Irda = 0x04, /* Received Data Available */
47 Irls = 0x06, /* Receiver Line Status */
48 Ictoi = 0x0C, /* Character Time-out Indication */
50 Ifena = 0xC0, /* FIFOs enabled */
54 FIFOena = 0x01, /* FIFO enable */
55 FIFOrclr = 0x02, /* clear Rx FIFO */
56 FIFOtclr = 0x04, /* clear Tx FIFO */
58 FIFO1 = 0x00, /* Rx FIFO trigger level 1 byte */
59 FIFO4 = 0x40, /* 4 bytes */
60 FIFO8 = 0x80, /* 8 bytes */
61 FIFO14 = 0xC0, /* 14 bytes */
65 Wls5 = 0x00, /* Word Length Select 5 bits/byte */
66 Wls6 = 0x01, /* 6 bits/byte */
67 Wls7 = 0x02, /* 7 bits/byte */
68 Wls8 = 0x03, /* 8 bits/byte */
70 Stb = 0x04, /* 2 stop bits */
71 Pen = 0x08, /* Parity Enable */
72 Eps = 0x10, /* Even Parity Select */
73 Stp = 0x20, /* Stick Parity */
74 Brk = 0x40, /* Break */
75 Dlab = 0x80, /* Divisor Latch Access Bit */
79 Dtr = 0x01, /* Data Terminal Ready */
80 Rts = 0x02, /* Ready To Send */
81 Out1 = 0x04, /* no longer in use */
82 // Ie = 0x08, /* IRQ Enable (cd_sts_ch on omap) */
83 Dm = 0x10, /* Diagnostic Mode loopback */
87 Dr = 0x01, /* Data Ready */
88 Oe = 0x02, /* Overrun Error */
89 Pe = 0x04, /* Parity Error */
90 Fe = 0x08, /* Framing Error */
91 Bi = 0x10, /* Break Interrupt */
92 Thre = 0x20, /* Thr Empty */
93 Temt = 0x40, /* Transmitter Empty */
94 FIFOerr = 0x80, /* error in receiver FIFO */
98 Dcts = 0x01, /* Delta Cts */
99 Ddsr = 0x02, /* Delta Dsr */
100 Teri = 0x04, /* Trailing Edge of Ri */
101 Ddcd = 0x08, /* Delta Dcd */
102 Cts = 0x10, /* Clear To Send */
103 Dsr = 0x20, /* Data Set Ready */
104 Ri = 0x40, /* Ring Indicator */
105 Dcd = 0x80, /* Carrier Detect */
114 typedef struct Ctlr {
129 extern PhysUart i8250physuart;
131 static Ctlr i8250ctlr[] = {
132 { .io = (u32int*)PHYSCONS, /* UART3 in TI terminology */
137 /* these exist, but I don't think they're connected to anything external */
138 //{ .io = (u32int*)PHYSUART0,
143 //{ .io = (u32int*)PHYSUART1,
149 static Uart i8250uart[] = {
150 { .regs = &i8250ctlr[0], /* not [2] */
152 .freq = 3686000, /* Not used, we use the global i8250freq */
153 .phys = &i8250physuart,
157 /* these exist, but I don't think they're connected to anything external */
158 //{ .regs = &i8250ctlr[0],
160 // .freq = 3686000, /* Not used, we use the global i8250freq */
161 // .phys = &i8250physuart,
163 // .next = &i8250uart[1], },
165 //{ .regs = &i8250ctlr[1],
167 // .freq = 3686000, /* Not used, we use the global i8250freq */
168 // .phys = &i8250physuart,
170 // .next = &i8250uart[2], },
173 #define csr8r(c, r) ((c)->io[r])
174 #define csr8w(c, r, v) ((c)->io[r] = (c)->sticky[r] | (v), coherence())
175 #define csr8o(c, r, v) ((c)->io[r] = (v), coherence())
178 i8250status(Uart* uart, void* buf, long n, long offset)
182 uchar ier, lcr, mcr, msr;
186 mcr = ctlr->sticky[Mcr];
187 msr = csr8r(ctlr, Msr);
188 ier = ctlr->sticky[Ier];
189 lcr = ctlr->sticky[Lcr];
191 "b%d c%d d%d e%d l%d m%d p%c r%d s%d i%d\n"
192 "dev(%d) type(%d) framing(%d) overruns(%d) "
193 "berr(%d) serr(%d)%s%s%s%s\n",
201 (lcr & Pen) ? ((lcr & Eps) ? 'e': 'o'): 'n',
212 (msr & Cts) ? " cts": "",
213 (msr & Dsr) ? " dsr": "",
214 (msr & Dcd) ? " dcd": "",
215 (msr & Ri) ? " ring": ""
217 n = readstr(offset, buf, n, p);
224 i8250fifo(Uart* uart, int level)
229 if(ctlr->hasfifo == 0)
233 * Changing the FIFOena bit in Fcr flushes data
234 * from both receive and transmit FIFOs; there's
235 * no easy way to guarantee not losing data on
236 * the receive side, but it's possible to wait until
237 * the transmitter is really empty.
240 while(!(csr8r(ctlr, Lsr) & Temt))
244 * Set the trigger level, default is the max.
246 * Some UARTs require FIFOena to be set before
247 * other bits can take effect, so set it twice.
254 level = FIFO1|FIFOena;
257 level = FIFO4|FIFOena;
260 level = FIFO8|FIFOena;
263 level = FIFO14|FIFOena;
266 csr8w(ctlr, Fcr, level);
267 csr8w(ctlr, Fcr, level);
272 i8250dtr(Uart* uart, int on)
281 ctlr->sticky[Mcr] |= Dtr;
283 ctlr->sticky[Mcr] &= ~Dtr;
288 i8250rts(Uart* uart, int on)
297 ctlr->sticky[Mcr] |= Rts;
299 ctlr->sticky[Mcr] &= ~Rts;
304 i8250modemctl(Uart* uart, int on)
311 ctlr->sticky[Ier] |= Ems;
314 uart->cts = csr8r(ctlr, Msr) & Cts;
317 ctlr->sticky[Ier] &= ~Ems;
322 iunlock(&uart->tlock);
324 /* modem needs fifo */
325 (*uart->phys->fifo)(uart, on);
329 i8250parity(Uart* uart, int parity)
335 lcr = ctlr->sticky[Lcr] & ~(Eps|Pen);
349 ctlr->sticky[Lcr] = lcr;
352 uart->parity = parity;
358 i8250stop(Uart* uart, int stop)
364 lcr = ctlr->sticky[Lcr] & ~Stb;
375 ctlr->sticky[Lcr] = lcr;
384 i8250bits(Uart* uart, int bits)
390 lcr = ctlr->sticky[Lcr] & ~WlsMASK;
408 ctlr->sticky[Lcr] = lcr;
417 i8250baud(Uart* uart, int baud)
419 #ifdef notdef /* don't change the speed */
422 extern int i8250freq; /* In the config file */
425 * Set the Baud rate by calculating and setting the Baud rate
426 * Generator Constant. This will work with fairly non-standard
429 if(i8250freq == 0 || baud <= 0)
431 bgc = (i8250freq+8*baud-1)/(16*baud);
434 while(csr8r(ctlr, Usr) & Busy)
436 csr8w(ctlr, Lcr, Dlab); /* begin kludge */
437 csr8o(ctlr, Dlm, bgc>>8);
438 csr8o(ctlr, Dll, bgc);
446 i8250break(Uart* uart, int ms)
451 panic("i8250break: nil up");
459 csr8w(ctlr, Lcr, Brk);
460 tsleep(&up->sleep, return0, 0, ms);
465 emptyoutstage(Uart *uart, int n)
467 _uartputs((char *)uart->op, n);
468 uart->op = uart->oe = uart->ostage;
472 i8250kick(Uart* uart)
477 if(/* uart->cts == 0 || */ uart->blocked)
480 if(!normalprint) { /* early */
481 if (uart->op < uart->oe)
482 emptyoutstage(uart, uart->oe - uart->op);
483 while ((i = uartstageoutput(uart)) > 0)
484 emptyoutstage(uart, i);
488 /* nothing more to send? then disable xmit intr */
490 if (uart->op >= uart->oe && qlen(uart->oq) == 0 &&
491 csr8r(ctlr, Lsr) & Temt) {
492 ctlr->sticky[Ier] &= ~Ethre;
498 * 128 here is an arbitrary limit to make sure
499 * we don't stay in this loop too long. If the
500 * chip's output queue is longer than 128, too
503 for(i = 0; i < 128; i++){
504 if(!(csr8r(ctlr, Lsr) & Thre))
506 if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
508 csr8o(ctlr, Thr, *uart->op++); /* start tx */
509 ctlr->sticky[Ier] |= Ethre;
510 csr8w(ctlr, Ier, 0); /* intr when done */
517 uartkick(&i8250uart[CONSOLE]);
521 i8250interrupt(Ureg*, void* arg)
525 int iir, lsr, old, r;
529 for(iir = csr8r(ctlr, Iir); !(iir & Ip); iir = csr8r(ctlr, Iir)){
530 switch(iir & IirMASK){
531 case Ims: /* Ms interrupt */
532 r = csr8r(ctlr, Msr);
537 if(old == 0 && uart->cts)
538 uart->ctsbackoff = 2;
539 iunlock(&uart->tlock);
543 if(uart->hup_dsr && uart->dsr && !old)
549 if(uart->hup_dcd && uart->dcd && !old)
554 case Ithre: /* Thr Empty */
557 case Irda: /* Received Data Available */
558 case Irls: /* Receiver Line Status */
559 case Ictoi: /* Character Time-out Indication */
561 * Consume any received data.
562 * If the received byte came in with a break,
563 * parity or framing error, throw it away;
564 * overrun is an indication that something has
565 * already been tossed.
567 while((lsr = csr8r(ctlr, Lsr)) & Dr){
568 if(lsr & (FIFOerr|Oe))
574 r = csr8r(ctlr, Rbr);
575 if(!(lsr & (Bi|Fe|Pe)))
581 iprint("weird uart interrupt type %#2.2uX\n", iir);
588 i8250disable(Uart* uart)
593 * Turn off DTR and RTS, disable interrupts and fifos.
595 (*uart->phys->dtr)(uart, 0);
596 (*uart->phys->rts)(uart, 0);
597 (*uart->phys->fifo)(uart, 0);
600 ctlr->sticky[Ier] = 0;
604 if(irqdisable(ctlr->irq, i8250interrupt, uart, uart->name) == 0)
610 i8250enable(Uart* uart, int ie)
616 return; /* too soon */
620 /* omap only: set uart/irda/cir mode to uart */
621 mode = csr8r(ctlr, Mdr);
622 csr8o(ctlr, Mdr, (mode & ~Modemask) | Modeuart);
624 ctlr->sticky[Lcr] = Wls8; /* no parity */
628 * Check if there is a FIFO.
629 * Changing the FIFOena bit in Fcr flushes data
630 * from both receive and transmit FIFOs; there's
631 * no easy way to guarantee not losing data on
632 * the receive side, but it's possible to wait until
633 * the transmitter is really empty.
634 * Also, reading the Iir outwith i8250interrupt()
635 * can be dangerous, but this should only happen
636 * once, before interrupts are enabled.
639 if(!ctlr->checkfifo){
641 * Wait until the transmitter is really empty.
643 while(!(csr8r(ctlr, Lsr) & Temt))
645 csr8w(ctlr, Fcr, FIFOena);
646 if(csr8r(ctlr, Iir) & Ifena)
654 * Enable interrupts and turn on DTR and RTS.
655 * Be careful if this is called to set up a polled serial line
656 * early on not to try to enable interrupts as interrupt-
657 * -enabling mechanisms might not be set up yet.
660 if(ctlr->iena == 0 && !ctlr->poll){
661 irqenable(ctlr->irq, i8250interrupt, uart, uart->name);
664 ctlr->sticky[Ier] = Erda;
665 // ctlr->sticky[Mcr] |= Ie; /* not on omap */
666 ctlr->sticky[Mcr] = 0;
669 ctlr->sticky[Ier] = 0;
670 ctlr->sticky[Mcr] = 0;
675 (*uart->phys->dtr)(uart, 1);
676 (*uart->phys->rts)(uart, 1);
679 * During startup, the i8259 interrupt controller is reset.
680 * This may result in a lost interrupt from the i8250 uart.
681 * The i8250 thinks the interrupt is still outstanding and does not
682 * generate any further interrupts. The workaround is to call the
683 * interrupt handler to clear any pending interrupt events.
684 * Note: this must be done after setting Ier.
687 i8250interrupt(nil, uart);
697 i8250getc(Uart* uart)
702 while(!(csr8r(ctlr, Lsr) & Dr))
704 return csr8r(ctlr, Rbr);
708 i8250putc(Uart* uart, int c)
713 if (!normalprint) { /* too early; use brute force */
716 while (!(((ulong *)PHYSCONS)[Lsr] & Thre))
718 ((ulong *)PHYSCONS)[Thr] = c;
725 for(i = 0; !(csr8r(ctlr, Lsr) & Thre) && i < 128; i++)
727 csr8o(ctlr, Thr, (uchar)c);
728 for(i = 0; !(csr8r(ctlr, Lsr) & Thre) && i < 128; i++)
735 i8250putc(&i8250uart[CONSOLE], c);
739 serialputs(char* s, int n)
746 i8250poll(Uart* uart)
751 * If PhysUart has a non-nil .poll member, this
752 * routine will be called from the uartclock timer.
753 * If the Ctlr .poll member is non-zero, when the
754 * Uart is enabled interrupts will not be enabled
755 * and the result is polled input and output.
756 * Not very useful here, but ports to new hardware
757 * or simulators can use this to get serial I/O
758 * without setting up the interrupt mechanism.
761 if(ctlr->iena || !ctlr->poll)
763 i8250interrupt(nil, uart);
767 PhysUart i8250physuart = {
770 .enable = i8250enable,
771 .disable = i8250disable,
773 .dobreak = i8250break,
777 .parity = i8250parity,
778 .modemctl = i8250modemctl,
781 .status = i8250status,
785 // .poll = i8250poll, /* only in 9k, not 9 */
789 i8250dumpregs(Ctlr* ctlr)
792 int _uartprint(char*, ...);
794 csr8w(ctlr, Lcr, Dlab);
795 dlm = csr8r(ctlr, Dlm);
796 dll = csr8r(ctlr, Dll);
799 _uartprint("dlm %#ux dll %#ux\n", dlm, dll);
802 Uart* uartenable(Uart *p);
804 /* must call this from a process's context */
808 Uart *uart = &i8250uart[CONSOLE];
811 return -1; /* too early */
813 if(uartenable(uart) != nil /* && uart->console */){
814 // iprint("i8250console: enabling console uart\n");
819 uartctl(uart, "b115200 l8 pn r1 s1 i1");
824 _uartputs(char* s, int n)
828 for(e = s+n; s < e; s++){
830 i8250putc(&i8250uart[CONSOLE], '\r');
831 i8250putc(&i8250uart[CONSOLE], *s);
836 _uartprint(char* fmt, ...)
843 n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;