2 #include "../port/lib.h"
8 #include "../port/error.h"
9 #include "../ppc/uartsmc.h"
12 * PowerPC 8260 SMC UART
16 /* SMC Mode Registers */
17 Clen = 0x7800, /* Character length */
18 Sl = 0x0400, /* Stop length, 0: one stop bit, 1: two */
19 Pen = 0x0200, /* Parity enable */
20 Pm = 0x0100, /* Parity mode, 0 is odd */
21 Sm = 0x0030, /* SMC mode, two bits */
22 SMUart = 0x0020, /* SMC mode, 0b10 is uart */
23 Dm = 0x000c, /* Diagnostic mode, 00 is normal */
24 Ten = 0x0002, /* Transmit enable, 1 is enabled */
25 Ren = 0x0001, /* Receive enable, 1 is enabled */
27 /* SMC Event/Mask Registers */
28 ce_Brke = 0x0040, /* Break end */
29 ce_Br = 0x0020, /* Break character received */
30 ce_Bsy = 0x0004, /* Busy condition */
31 ce_Txb = 0x0002, /* Tx buffer */
32 ce_Rxb = 0x0001, /* Rx buffer */
34 /* Receive/Transmit Buffer Descriptor Control bits */
43 /* Tx and Rx buffer sizes (32 bytes) */
48 extern PhysUart smcphysuart;
50 Uart smcuart[Nuart] = {
60 /* Only configure SMC1 for now
75 static void smcinterrupt(Ureg*, void*);
76 static void smcputc(Uart *uart, int c);
83 d = ((m->brghz+(baud>>1))/baud)>>4;
94 for (i = 0; i < nelem(smcuart) - 1; i++)
95 smcuart[i].next = smcuart + i + 1;
113 smcsetup(uart); /* Steps 1 through 4, PPC-dependent */
117 /* step 5: set up buffer descriptors */
118 /* setup my uart structure */
120 ud->rxb = bdalloc(1);
122 ud->txb = bdalloc(1);
124 p->rbase = ((ulong)ud->rxb) - (ulong)IMMR;
125 p->tbase = ((ulong)ud->txb) - (ulong)IMMR;
127 /* step 8: receive buffer size */
140 /* step 12: setup receive buffer */
141 ud->rxb->status = BDEmpty|BDWrap|BDInt;
143 ud->rxbuf = xspanalloc(Rxsize, 0, CACHELINESZ);
144 ud->rxb->addr = PADDR(ud->rxbuf);
146 /* step 13: step transmit buffer */
147 ud->txb->status = BDWrap|BDInt;
149 ud->txbuf = xspanalloc(Txsize, 0, CACHELINESZ);
150 ud->txb->addr = PADDR(ud->txbuf);
152 /* step 14: clear events */
153 smc->smce = ce_Brke | ce_Br | ce_Bsy | ce_Txb | ce_Rxb;
156 * step 15: enable interrupts (done later)
157 * smc->smcm = ce_Brke | ce_Br | ce_Bsy | ce_Txb | ce_Rxb;
160 /* step 17: set parity, no of bits, UART mode, ... */
162 bits = uart->bits + 1;
164 switch(uart->parity){
183 /* Set new value and reenable if device was previously enabled */
184 smc->smcmr = lcr | bits <<11 | 0x3;
190 smcenable(Uart *uart, int intenb)
197 if (nr < 0 || nr > Nuart)
198 panic("No SMC %d", nr);
202 if (ud->initialized == 0)
204 if (ud->enabled || intenb == 0)
208 smc->smce = ce_Brke | ce_Br | ce_Bsy | ce_Txb | ce_Rxb;
209 /* enable interrupts */
210 smc->smcm = ce_Brke | ce_Br | ce_Bsy | ce_Txb | ce_Rxb;
211 intrenable(VecSMC1 + ud->smcno, smcinterrupt, uart, uart->name);
216 smcstatus(Uart* uart, void* buf, long n, long offset)
221 sp = ((UartData*)uart->regs)->smc;
222 snprint(p, sizeof p, "b%d c%d e%d l%d m0 p%c s%d i1\n"
223 "dev(%d) type(%d) framing(%d) overruns(%d)\n",
228 ((sp->smcmr & Clen) >>11) - ((sp->smcmr&Pen) ? 1 : 0) - ((sp->smcmr&Sl) ? 2 : 1),
229 (sp->smcmr & Pen) ? ((sp->smcmr & Pm) ? 'e': 'o'): 'n',
230 (sp->smcmr & Sl) ? 2: 1,
237 n = readstr(offset, buf, n, p);
248 * if none, do nothing;
249 * reset the Rx and Tx FIFOs;
250 * empty the Rx buffer and clear any interrupt conditions;
251 * if enabling, try to turn them on.
267 smcmodemctl(Uart*, int)
272 smcparity(Uart* uart, int parity)
277 sp = ((UartData*)uart->regs)->smc;
279 lcr = sp->smcmr & ~(Pen|Pm);
281 /* Disable transmitter/receiver. */
282 sp->smcmr &= ~(Ren | Ten);
295 /* Set new value and reenable if device was previously enabled */
298 uart->parity = parity;
304 smcstop(Uart* uart, int stop)
309 sp = ((UartData*)uart->regs)->smc;
310 lcr = sp->smcmr & ~(Sl | Clen);
312 /* Disable transmitter/receiver. */
313 sp->smcmr &= ~(Ren | Ten);
325 bits = uart->bits + ((lcr & Pen) ? 1 : 0) + ((lcr & Sl) ? 2 : 1);
328 /* Set new value and reenable if device was previously enabled */
337 smcbits(Uart* uart, int bits)
342 if (bits < 5 || bits > 14)
345 sp = ((UartData*)uart->regs)->smc;
346 lcr = sp->smcmr & ~Clen;
348 b = bits + ((sp->smcmr & Pen) ? 1 : 0) + ((sp->smcmr & Sl) ? 2 : 1);
353 /* Disable transmitter/receiver */
354 sp->smcmr &= ~(Ren | Ten);
356 /* Set new value and reenable if device was previously enabled */
357 sp->smcmr = lcr | b<<11;
365 smcbaud(Uart* uart, int baud)
371 sp = ((UartData*)uart->regs)->smc;
373 if(uart->freq == 0 || baud <= 0)
377 imm->brgc[i] = (((m->brghz >> 4) / baud) << 1) | 0x00010000;
402 if (txb->status & BDReady)
403 return; /* Still busy */
405 for(i = 0; i < Txsize; i++){
406 if(uart->op >= uart->oe && uartstageoutput(uart) == 0)
408 ud->txbuf[i] = *(uart->op++);
412 dcflush(ud->txbuf, Txsize);
415 txb->status |= BDReady|BDInt;
419 smcinterrupt(Ureg*, void* u)
430 panic("uart is nil");
435 events = ud->smc->smce;
436 ud->smc->smce = events; /* Clear events */
439 iprint("smc%d: break\n", ud->smcno);
443 /* Receive characters
447 dczap(buf, Rxsize); /* invalidate data cache before copying */
448 if ((rxb->status & BDEmpty) == 0){
451 uartrecv(uart, *buf++);
453 rxb->status |= BDEmpty;
455 iprint("uartsmc: unexpected receive event\n");
459 if ((ud->txb->status & BDReady) == 0)
465 smcdisable(Uart* uart)
469 sp = ((UartData*)uart->regs)->smc;
470 sp->smcmr &= ~(Ren | Ten);
474 getchars(Uart *uart, uchar *cbuf)
484 /* Wait for character to show up.
487 while (rxb->status & BDEmpty)
493 rxb->status |= BDEmpty;
501 static uchar buf[128], *p;
506 cnt = getchars(uart, buf);
516 smcputc(Uart *uart, int c)
527 /* Wait for last character to go.
529 while (txb->status & BDReady)
533 dcflush(ud->txbuf, 1);
536 txb->status |= BDReady;
538 while (txb->status & BDReady)
542 PhysUart smcphysuart = {
546 .disable = smcdisable,
553 .modemctl = smcmodemctl,
569 if((p = getconf("console")) == nil)
571 n = strtoul(p, &cmd, 0);
574 if(n < 0 || n >= nelem(smcuart))
578 /* uartctl(uart, "b115200 l8 pn s1"); */
581 (*uart->phys->enable)(uart, 0);