1 /*-
2 * Copyright (c) 2013 Adrian Chadd <adrian@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD: releng/10.1/sys/mips/atheros/uart_dev_ar933x.c 262649 2014-03-01 04:16:54Z imp $");
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/bus.h>
33 #include <sys/conf.h>
34 #include <machine/bus.h>
35
36 #include <dev/uart/uart.h>
37 #include <dev/uart/uart_cpu.h>
38 #include <dev/uart/uart_bus.h>
39
40 #include <mips/atheros/ar933x_uart.h>
41
42 #include "uart_if.h"
43
44 /*
45 * Default system clock is 25MHz; see ar933x_chip.c for how
46 * the startup process determines whether it's 25MHz or 40MHz.
47 */
48 #define DEFAULT_RCLK (25 * 1000 * 1000)
49
50 #define ar933x_getreg(bas, reg) \
51 bus_space_read_4((bas)->bst, (bas)->bsh, reg)
52 #define ar933x_setreg(bas, reg, value) \
53 bus_space_write_4((bas)->bst, (bas)->bsh, reg, value)
54
55
56
57 static int
58 ar933x_drain(struct uart_bas *bas, int what)
59 {
60 int limit;
61
62 if (what & UART_DRAIN_TRANSMITTER) {
63 limit = 10*1024;
64
65 /* Loop over until the TX FIFO shows entirely clear */
66 while (--limit) {
67 if ((ar933x_getreg(bas, AR933X_UART_CS_REG)
68 & AR933X_UART_CS_TX_BUSY) == 0)
69 break;
70 }
71 if (limit == 0) {
72 return (EIO);
73 }
74 }
75
76 if (what & UART_DRAIN_RECEIVER) {
77 limit=10*4096;
78 while (--limit) {
79
80 /* XXX duplicated from ar933x_getc() */
81 /* XXX TODO: refactor! */
82
83 /* If there's nothing to read, stop! */
84 if ((ar933x_getreg(bas, AR933X_UART_DATA_REG) &
85 AR933X_UART_DATA_RX_CSR) == 0) {
86 break;
87 }
88
89 /* Read the top of the RX FIFO */
90 (void) ar933x_getreg(bas, AR933X_UART_DATA_REG);
91
92 /* Remove that entry from said RX FIFO */
93 ar933x_setreg(bas, AR933X_UART_DATA_REG,
94 AR933X_UART_DATA_RX_CSR);
95
96 uart_barrier(bas);
97 DELAY(2);
98 }
99 if (limit == 0) {
100 return (EIO);
101 }
102 }
103 return (0);
104 }
105
106 /*
107 * Calculate the baud from the given chip configuration parameters.
108 */
109 static unsigned long
110 ar933x_uart_get_baud(unsigned int clk, unsigned int scale,
111 unsigned int step)
112 {
113 uint64_t t;
114 uint32_t div;
115
116 div = (2 << 16) * (scale + 1);
117 t = clk;
118 t *= step;
119 t += (div / 2);
120 t = t / div;
121
122 return (t);
123 }
124
125 /*
126 * Calculate the scale/step with the lowest possible deviation from
127 * the target baudrate.
128 */
129 static void
130 ar933x_uart_get_scale_step(struct uart_bas *bas, unsigned int baud,
131 unsigned int *scale, unsigned int *step)
132 {
133 unsigned int tscale;
134 uint32_t clk;
135 long min_diff;
136
137 clk = bas->rclk;
138 *scale = 0;
139 *step = 0;
140
141 min_diff = baud;
142 for (tscale = 0; tscale < AR933X_UART_MAX_SCALE; tscale++) {
143 uint64_t tstep;
144 int diff;
145
146 tstep = baud * (tscale + 1);
147 tstep *= (2 << 16);
148 tstep = tstep / clk;
149
150 if (tstep > AR933X_UART_MAX_STEP)
151 break;
152
153 diff = abs(ar933x_uart_get_baud(clk, tscale, tstep) - baud);
154 if (diff < min_diff) {
155 min_diff = diff;
156 *scale = tscale;
157 *step = tstep;
158 }
159 }
160 }
161
162 static int
163 ar933x_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
164 int parity)
165 {
166 /* UART always 8 bits */
167
168 /* UART always 1 stop bit */
169
170 /* UART parity is controllable by bits 0:1, ignore for now */
171
172 /* Set baudrate if required. */
173 if (baudrate > 0) {
174 uint32_t clock_scale, clock_step;
175
176 /* Find the best fit for the given baud rate */
177 ar933x_uart_get_scale_step(bas, baudrate, &clock_scale,
178 &clock_step);
179
180 /*
181 * Program the clock register in its entirety - no need
182 * for Read-Modify-Write.
183 */
184 ar933x_setreg(bas, AR933X_UART_CLOCK_REG,
185 ((clock_scale & AR933X_UART_CLOCK_SCALE_M)
186 << AR933X_UART_CLOCK_SCALE_S) |
187 (clock_step & AR933X_UART_CLOCK_STEP_M));
188 }
189
190 uart_barrier(bas);
191 return (0);
192 }
193
194
195 /*
196 * Low-level UART interface.
197 */
198 static int ar933x_probe(struct uart_bas *bas);
199 static void ar933x_init(struct uart_bas *bas, int, int, int, int);
200 static void ar933x_term(struct uart_bas *bas);
201 static void ar933x_putc(struct uart_bas *bas, int);
202 static int ar933x_rxready(struct uart_bas *bas);
203 static int ar933x_getc(struct uart_bas *bas, struct mtx *);
204
205 static struct uart_ops uart_ar933x_ops = {
206 .probe = ar933x_probe,
207 .init = ar933x_init,
208 .term = ar933x_term,
209 .putc = ar933x_putc,
210 .rxready = ar933x_rxready,
211 .getc = ar933x_getc,
212 };
213
214 static int
215 ar933x_probe(struct uart_bas *bas)
216 {
217
218 /* We always know this will be here */
219 return (0);
220 }
221
222 static void
223 ar933x_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
224 int parity)
225 {
226 uint32_t reg;
227
228 /* Setup default parameters */
229 ar933x_param(bas, baudrate, databits, stopbits, parity);
230
231 /* XXX Force enable UART in case it was disabled */
232
233 /* Disable all interrupts */
234 ar933x_setreg(bas, AR933X_UART_INT_EN_REG, 0x00000000);
235
236 /* Disable the host interrupt */
237 reg = ar933x_getreg(bas, AR933X_UART_CS_REG);
238 reg &= ~AR933X_UART_CS_HOST_INT_EN;
239 ar933x_setreg(bas, AR933X_UART_CS_REG, reg);
240
241 uart_barrier(bas);
242
243 /* XXX Set RTS/DTR? */
244 }
245
246 /*
247 * Detach from console.
248 */
249 static void
250 ar933x_term(struct uart_bas *bas)
251 {
252
253 /* XXX TODO */
254 }
255
256 static void
257 ar933x_putc(struct uart_bas *bas, int c)
258 {
259 int limit;
260
261 limit = 250000;
262
263 /* Wait for space in the TX FIFO */
264 while ( ((ar933x_getreg(bas, AR933X_UART_DATA_REG) &
265 AR933X_UART_DATA_TX_CSR) == 0) && --limit)
266 DELAY(4);
267
268 /* Write the actual byte */
269 ar933x_setreg(bas, AR933X_UART_DATA_REG,
270 (c & 0xff) | AR933X_UART_DATA_TX_CSR);
271 }
272
273 static int
274 ar933x_rxready(struct uart_bas *bas)
275 {
276
277 /* Wait for a character to come ready */
278 return (!!(ar933x_getreg(bas, AR933X_UART_DATA_REG)
279 & AR933X_UART_DATA_RX_CSR));
280 }
281
282 static int
283 ar933x_getc(struct uart_bas *bas, struct mtx *hwmtx)
284 {
285 int c;
286
287 uart_lock(hwmtx);
288
289 /* Wait for a character to come ready */
290 while ((ar933x_getreg(bas, AR933X_UART_DATA_REG) &
291 AR933X_UART_DATA_RX_CSR) == 0) {
292 uart_unlock(hwmtx);
293 DELAY(4);
294 uart_lock(hwmtx);
295 }
296
297 /* Read the top of the RX FIFO */
298 c = ar933x_getreg(bas, AR933X_UART_DATA_REG) & 0xff;
299
300 /* Remove that entry from said RX FIFO */
301 ar933x_setreg(bas, AR933X_UART_DATA_REG, AR933X_UART_DATA_RX_CSR);
302
303 uart_unlock(hwmtx);
304
305 return (c);
306 }
307
308 /*
309 * High-level UART interface.
310 */
311 struct ar933x_softc {
312 struct uart_softc base;
313
314 uint32_t u_ier;
315 };
316
317 static int ar933x_bus_attach(struct uart_softc *);
318 static int ar933x_bus_detach(struct uart_softc *);
319 static int ar933x_bus_flush(struct uart_softc *, int);
320 static int ar933x_bus_getsig(struct uart_softc *);
321 static int ar933x_bus_ioctl(struct uart_softc *, int, intptr_t);
322 static int ar933x_bus_ipend(struct uart_softc *);
323 static int ar933x_bus_param(struct uart_softc *, int, int, int, int);
324 static int ar933x_bus_probe(struct uart_softc *);
325 static int ar933x_bus_receive(struct uart_softc *);
326 static int ar933x_bus_setsig(struct uart_softc *, int);
327 static int ar933x_bus_transmit(struct uart_softc *);
328 static void ar933x_bus_grab(struct uart_softc *);
329 static void ar933x_bus_ungrab(struct uart_softc *);
330
331 static kobj_method_t ar933x_methods[] = {
332 KOBJMETHOD(uart_attach, ar933x_bus_attach),
333 KOBJMETHOD(uart_detach, ar933x_bus_detach),
334 KOBJMETHOD(uart_flush, ar933x_bus_flush),
335 KOBJMETHOD(uart_getsig, ar933x_bus_getsig),
336 KOBJMETHOD(uart_ioctl, ar933x_bus_ioctl),
337 KOBJMETHOD(uart_ipend, ar933x_bus_ipend),
338 KOBJMETHOD(uart_param, ar933x_bus_param),
339 KOBJMETHOD(uart_probe, ar933x_bus_probe),
340 KOBJMETHOD(uart_receive, ar933x_bus_receive),
341 KOBJMETHOD(uart_setsig, ar933x_bus_setsig),
342 KOBJMETHOD(uart_transmit, ar933x_bus_transmit),
343 KOBJMETHOD(uart_grab, ar933x_bus_grab),
344 KOBJMETHOD(uart_ungrab, ar933x_bus_ungrab),
345 { 0, 0 }
346 };
347
348 struct uart_class uart_ar933x_class = {
349 "ar933x",
350 ar933x_methods,
351 sizeof(struct ar933x_softc),
352 .uc_ops = &uart_ar933x_ops,
353 .uc_range = 8,
354 .uc_rclk = DEFAULT_RCLK
355 };
356
357 #define SIGCHG(c, i, s, d) \
358 if (c) { \
359 i |= (i & s) ? s : s | d; \
360 } else { \
361 i = (i & s) ? (i & ~s) | d : i; \
362 }
363
364 static int
365 ar933x_bus_attach(struct uart_softc *sc)
366 {
367 struct ar933x_softc *u = (struct ar933x_softc *)sc;
368 struct uart_bas *bas = &sc->sc_bas;
369 uint32_t reg;
370
371 /* XXX TODO: flush transmitter */
372
373 /*
374 * Setup initial interrupt notifications.
375 *
376 * XXX for now, just RX FIFO valid.
377 * Later on (when they're handled), also handle
378 * RX errors/overflow.
379 */
380 u->u_ier = AR933X_UART_INT_RX_VALID;
381
382 /* Enable RX interrupts to kick-start things */
383 ar933x_setreg(bas, AR933X_UART_INT_EN_REG, u->u_ier);
384
385 /* Enable the host interrupt now */
386 reg = ar933x_getreg(bas, AR933X_UART_CS_REG);
387 reg |= AR933X_UART_CS_HOST_INT_EN;
388 ar933x_setreg(bas, AR933X_UART_CS_REG, reg);
389
390 return (0);
391 }
392
393 static int
394 ar933x_bus_detach(struct uart_softc *sc)
395 {
396 struct uart_bas *bas = &sc->sc_bas;
397 uint32_t reg;
398
399 /* Disable all interrupts */
400 ar933x_setreg(bas, AR933X_UART_INT_EN_REG, 0x00000000);
401
402 /* Disable the host interrupt */
403 reg = ar933x_getreg(bas, AR933X_UART_CS_REG);
404 reg &= ~AR933X_UART_CS_HOST_INT_EN;
405 ar933x_setreg(bas, AR933X_UART_CS_REG, reg);
406 uart_barrier(bas);
407
408 return (0);
409 }
410
411 static int
412 ar933x_bus_flush(struct uart_softc *sc, int what)
413 {
414 struct uart_bas *bas;
415
416 bas = &sc->sc_bas;
417 uart_lock(sc->sc_hwmtx);
418 ar933x_drain(bas, what);
419 uart_unlock(sc->sc_hwmtx);
420
421 return (0);
422 }
423
424 static int
425 ar933x_bus_getsig(struct uart_softc *sc)
426 {
427 uint32_t sig = sc->sc_hwsig;
428
429 /*
430 * For now, let's just return that DSR/DCD/CTS is asserted.
431 *
432 * XXX TODO: actually verify whether this is correct!
433 */
434 SIGCHG(1, sig, SER_DSR, SER_DDSR);
435 SIGCHG(1, sig, SER_CTS, SER_DCTS);
436 SIGCHG(1, sig, SER_DCD, SER_DDCD);
437 SIGCHG(1, sig, SER_RI, SER_DRI);
438
439 sc->sc_hwsig = sig & ~SER_MASK_DELTA;
440
441 return (sig);
442 }
443
444 static int
445 ar933x_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
446 {
447 #if 0
448 struct uart_bas *bas;
449 int baudrate, divisor, error;
450 uint8_t efr, lcr;
451
452 bas = &sc->sc_bas;
453 error = 0;
454 uart_lock(sc->sc_hwmtx);
455 switch (request) {
456 case UART_IOCTL_BREAK:
457 lcr = uart_getreg(bas, REG_LCR);
458 if (data)
459 lcr |= LCR_SBREAK;
460 else
461 lcr &= ~LCR_SBREAK;
462 uart_setreg(bas, REG_LCR, lcr);
463 uart_barrier(bas);
464 break;
465 case UART_IOCTL_IFLOW:
466 lcr = uart_getreg(bas, REG_LCR);
467 uart_barrier(bas);
468 uart_setreg(bas, REG_LCR, 0xbf);
469 uart_barrier(bas);
470 efr = uart_getreg(bas, REG_EFR);
471 if (data)
472 efr |= EFR_RTS;
473 else
474 efr &= ~EFR_RTS;
475 uart_setreg(bas, REG_EFR, efr);
476 uart_barrier(bas);
477 uart_setreg(bas, REG_LCR, lcr);
478 uart_barrier(bas);
479 break;
480 case UART_IOCTL_OFLOW:
481 lcr = uart_getreg(bas, REG_LCR);
482 uart_barrier(bas);
483 uart_setreg(bas, REG_LCR, 0xbf);
484 uart_barrier(bas);
485 efr = uart_getreg(bas, REG_EFR);
486 if (data)
487 efr |= EFR_CTS;
488 else
489 efr &= ~EFR_CTS;
490 uart_setreg(bas, REG_EFR, efr);
491 uart_barrier(bas);
492 uart_setreg(bas, REG_LCR, lcr);
493 uart_barrier(bas);
494 break;
495 case UART_IOCTL_BAUD:
496 lcr = uart_getreg(bas, REG_LCR);
497 uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
498 uart_barrier(bas);
499 divisor = uart_getreg(bas, REG_DLL) |
500 (uart_getreg(bas, REG_DLH) << 8);
501 uart_barrier(bas);
502 uart_setreg(bas, REG_LCR, lcr);
503 uart_barrier(bas);
504 baudrate = (divisor > 0) ? bas->rclk / divisor / 16 : 0;
505 if (baudrate > 0)
506 *(int*)data = baudrate;
507 else
508 error = ENXIO;
509 break;
510 default:
511 error = EINVAL;
512 break;
513 }
514 uart_unlock(sc->sc_hwmtx);
515 return (error);
516 #endif
517 return (ENXIO);
518 }
519
520 /*
521 * Bus interrupt handler.
522 *
523 * For now, system interrupts are disabled.
524 * So this is just called from a callout in uart_core.c
525 * to poll various state.
526 */
527 static int
528 ar933x_bus_ipend(struct uart_softc *sc)
529 {
530 struct ar933x_softc *u = (struct ar933x_softc *)sc;
531 struct uart_bas *bas = &sc->sc_bas;
532 int ipend = 0;
533 uint32_t isr;
534
535 uart_lock(sc->sc_hwmtx);
536
537 /*
538 * Fetch/ACK the ISR status.
539 */
540 isr = ar933x_getreg(bas, AR933X_UART_INT_REG);
541 ar933x_setreg(bas, AR933X_UART_INT_REG, isr);
542 uart_barrier(bas);
543
544 /*
545 * RX ready - notify upper layer.
546 */
547 if (isr & AR933X_UART_INT_RX_VALID) {
548 ipend |= SER_INT_RXREADY;
549 }
550
551 /*
552 * If we get this interrupt, we should disable
553 * it from the interrupt mask and inform the uart
554 * driver appropriately.
555 *
556 * We can't keep setting SER_INT_TXIDLE or SER_INT_SIGCHG
557 * all the time or IO stops working. So we will always
558 * clear this interrupt if we get it, then we only signal
559 * the upper layer if we were doing active TX in the
560 * first place.
561 *
562 * Also, the name is misleading. This actually means
563 * "the FIFO is almost empty." So if we just write some
564 * more data to the FIFO without checking whether it can
565 * take said data, we'll overflow the thing.
566 *
567 * Unfortunately the FreeBSD uart device has no concept of
568 * partial UART writes - it expects that the whole buffer
569 * is written to the hardware. Thus for now, ar933x_bus_transmit()
570 * will wait for the FIFO to finish draining before it pushes
571 * more frames into it.
572 */
573 if (isr & AR933X_UART_INT_TX_EMPTY) {
574 /*
575 * Update u_ier to disable TX notifications; update hardware
576 */
577 u->u_ier &= ~AR933X_UART_INT_TX_EMPTY;
578 ar933x_setreg(bas, AR933X_UART_INT_EN_REG, u->u_ier);
579 uart_barrier(bas);
580 }
581
582 /*
583 * Only signal TX idle if we're not busy transmitting.
584 */
585 if (sc->sc_txbusy) {
586 if (isr & AR933X_UART_INT_TX_EMPTY) {
587 ipend |= SER_INT_TXIDLE;
588 } else {
589 ipend |= SER_INT_SIGCHG;
590 }
591 }
592
593 uart_unlock(sc->sc_hwmtx);
594 return (ipend);
595 }
596
597 static int
598 ar933x_bus_param(struct uart_softc *sc, int baudrate, int databits,
599 int stopbits, int parity)
600 {
601 struct uart_bas *bas;
602 int error;
603
604 bas = &sc->sc_bas;
605 uart_lock(sc->sc_hwmtx);
606 error = ar933x_param(bas, baudrate, databits, stopbits, parity);
607 uart_unlock(sc->sc_hwmtx);
608 return (error);
609 }
610
611 static int
612 ar933x_bus_probe(struct uart_softc *sc)
613 {
614 struct uart_bas *bas;
615 int error;
616
617 bas = &sc->sc_bas;
618
619 error = ar933x_probe(bas);
620 if (error)
621 return (error);
622
623 /* Reset FIFOs. */
624 ar933x_drain(bas, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
625
626 /* XXX TODO: actually find out what the FIFO depth is! */
627 sc->sc_rxfifosz = 16;
628 sc->sc_txfifosz = 16;
629
630 return (0);
631 }
632
633 static int
634 ar933x_bus_receive(struct uart_softc *sc)
635 {
636 struct uart_bas *bas = &sc->sc_bas;
637 int xc;
638
639 uart_lock(sc->sc_hwmtx);
640
641 /* Loop over until we are full, or no data is available */
642 while (ar933x_rxready(bas)) {
643 if (uart_rx_full(sc)) {
644 sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
645 break;
646 }
647
648 /* Read the top of the RX FIFO */
649 xc = ar933x_getreg(bas, AR933X_UART_DATA_REG) & 0xff;
650
651 /* Remove that entry from said RX FIFO */
652 ar933x_setreg(bas, AR933X_UART_DATA_REG,
653 AR933X_UART_DATA_RX_CSR);
654 uart_barrier(bas);
655
656 /* XXX frame, parity error */
657 uart_rx_put(sc, xc);
658 }
659
660 /*
661 * XXX TODO: Discard everything left in the Rx FIFO?
662 * XXX only if we've hit an overrun condition?
663 */
664
665 uart_unlock(sc->sc_hwmtx);
666
667 return (0);
668 }
669
670 static int
671 ar933x_bus_setsig(struct uart_softc *sc, int sig)
672 {
673 #if 0
674 struct ar933x_softc *ns8250 = (struct ar933x_softc*)sc;
675 struct uart_bas *bas;
676 uint32_t new, old;
677
678 bas = &sc->sc_bas;
679 do {
680 old = sc->sc_hwsig;
681 new = old;
682 if (sig & SER_DDTR) {
683 SIGCHG(sig & SER_DTR, new, SER_DTR,
684 SER_DDTR);
685 }
686 if (sig & SER_DRTS) {
687 SIGCHG(sig & SER_RTS, new, SER_RTS,
688 SER_DRTS);
689 }
690 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
691 uart_lock(sc->sc_hwmtx);
692 ns8250->mcr &= ~(MCR_DTR|MCR_RTS);
693 if (new & SER_DTR)
694 ns8250->mcr |= MCR_DTR;
695 if (new & SER_RTS)
696 ns8250->mcr |= MCR_RTS;
697 uart_setreg(bas, REG_MCR, ns8250->mcr);
698 uart_barrier(bas);
699 uart_unlock(sc->sc_hwmtx);
700 #endif
701 return (0);
702 }
703
704 /*
705 * Write the current transmit buffer to the TX FIFO.
706 *
707 * Unfortunately the FreeBSD uart device has no concept of
708 * partial UART writes - it expects that the whole buffer
709 * is written to the hardware. Thus for now, this will wait for
710 * the FIFO to finish draining before it pushes more frames into it.
711 *
712 * If non-blocking operation is truely needed here, either
713 * the FreeBSD uart device will need to handle partial writes
714 * in xxx_bus_transmit(), or we'll need to do TX FIFO buffering
715 * of our own here.
716 */
717 static int
718 ar933x_bus_transmit(struct uart_softc *sc)
719 {
720 struct uart_bas *bas = &sc->sc_bas;
721 struct ar933x_softc *u = (struct ar933x_softc *)sc;
722 int i;
723
724 uart_lock(sc->sc_hwmtx);
725
726 /* Wait for the FIFO to be clear - see above */
727 while (ar933x_getreg(bas, AR933X_UART_CS_REG) &
728 AR933X_UART_CS_TX_BUSY)
729 ;
730
731 /*
732 * Write some data!
733 */
734 for (i = 0; i < sc->sc_txdatasz; i++) {
735 /* Write the TX data */
736 ar933x_setreg(bas, AR933X_UART_DATA_REG,
737 (sc->sc_txbuf[i] & 0xff) | AR933X_UART_DATA_TX_CSR);
738 uart_barrier(bas);
739 }
740
741 /*
742 * Now that we're transmitting, get interrupt notification
743 * when the FIFO is (almost) empty - see above.
744 */
745 u->u_ier |= AR933X_UART_INT_TX_EMPTY;
746 ar933x_setreg(bas, AR933X_UART_INT_EN_REG, u->u_ier);
747 uart_barrier(bas);
748
749 /*
750 * Inform the upper layer that we are presently transmitting
751 * data to the hardware; this will be cleared when the
752 * TXIDLE interrupt occurs.
753 */
754 sc->sc_txbusy = 1;
755 uart_unlock(sc->sc_hwmtx);
756
757 return (0);
758 }
759
760 static void
761 ar933x_bus_grab(struct uart_softc *sc)
762 {
763 struct uart_bas *bas = &sc->sc_bas;
764 uint32_t reg;
765
766 /* Disable the host interrupt now */
767 uart_lock(sc->sc_hwmtx);
768 reg = ar933x_getreg(bas, AR933X_UART_CS_REG);
769 reg &= ~AR933X_UART_CS_HOST_INT_EN;
770 ar933x_setreg(bas, AR933X_UART_CS_REG, reg);
771 uart_unlock(sc->sc_hwmtx);
772 }
773
774 static void
775 ar933x_bus_ungrab(struct uart_softc *sc)
776 {
777 struct uart_bas *bas = &sc->sc_bas;
778 uint32_t reg;
779
780 /* Enable the host interrupt now */
781 uart_lock(sc->sc_hwmtx);
782 reg = ar933x_getreg(bas, AR933X_UART_CS_REG);
783 reg |= AR933X_UART_CS_HOST_INT_EN;
784 ar933x_setreg(bas, AR933X_UART_CS_REG, reg);
785 uart_unlock(sc->sc_hwmtx);
786 }
Cache object: 69d6d7e8dfa996953295ee3700017cd3
|