]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/uart/uart_dev_imx.c
Ensure a minimum packet length before creating a mbuf in if_ure.
[FreeBSD/FreeBSD.git] / sys / dev / uart / uart_dev_imx.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2012 The FreeBSD Foundation
5  * All rights reserved.
6  *
7  * This software was developed by Oleksandr Rybalko under sponsorship
8  * from the FreeBSD Foundation.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1.   Redistributions of source code must retain the above copyright
14  *      notice, this list of conditions and the following disclaimer.
15  * 2.   Redistributions in binary form must reproduce the above copyright
16  *      notice, this list of conditions and the following disclaimer in the
17  *      documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34
35 #include "opt_ddb.h"
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/bus.h>
40 #include <sys/conf.h>
41 #include <sys/kdb.h>
42 #include <machine/bus.h>
43
44 #include <dev/uart/uart.h>
45 #include <dev/uart/uart_cpu.h>
46 #include <dev/uart/uart_cpu_fdt.h>
47 #include <dev/uart/uart_bus.h>
48 #include <dev/uart/uart_dev_imx.h>
49
50 #if defined(EXT_RESOURCES) && defined(__aarch64__)
51 #define IMX_ENABLE_CLOCKS
52 #endif
53
54 #ifdef IMX_ENABLE_CLOCKS
55 #include <dev/extres/clk/clk.h>
56 #endif
57
58 #include "uart_if.h"
59
60 #include <arm/freescale/imx/imx_ccmvar.h>
61
62 /*
63  * The hardare FIFOs are 32 bytes.  We want an interrupt when there are 24 bytes
64  * available to read or space for 24 more bytes to write.  While 8 bytes of
65  * slack before over/underrun might seem excessive, the hardware can run at
66  * 5mbps, which means 2uS per char, so at full speed 8 bytes provides only 16uS
67  * to get into the interrupt handler and service the fifo.
68  */
69 #define IMX_FIFOSZ              32
70 #define IMX_RXFIFO_LEVEL        24
71 #define IMX_TXFIFO_LEVEL        24
72
73 /*
74  * Low-level UART interface.
75  */
76 static int imx_uart_probe(struct uart_bas *bas);
77 static void imx_uart_init(struct uart_bas *bas, int, int, int, int);
78 static void imx_uart_term(struct uart_bas *bas);
79 static void imx_uart_putc(struct uart_bas *bas, int);
80 static int imx_uart_rxready(struct uart_bas *bas);
81 static int imx_uart_getc(struct uart_bas *bas, struct mtx *);
82
83 static struct uart_ops uart_imx_uart_ops = {
84         .probe = imx_uart_probe,
85         .init = imx_uart_init,
86         .term = imx_uart_term,
87         .putc = imx_uart_putc,
88         .rxready = imx_uart_rxready,
89         .getc = imx_uart_getc,
90 };
91
92 #if 0 /* Handy when debugging. */
93 static void
94 dumpregs(struct uart_bas *bas, const char * msg)
95 {
96
97         if (!bootverbose)
98                 return;
99         printf("%s bsh 0x%08lx UCR1 0x%08x UCR2 0x%08x "
100                 "UCR3 0x%08x UCR4 0x%08x USR1 0x%08x USR2 0x%08x\n",
101             msg, bas->bsh,
102             GETREG(bas, REG(UCR1)), GETREG(bas, REG(UCR2)), 
103             GETREG(bas, REG(UCR3)), GETREG(bas, REG(UCR4)),
104             GETREG(bas, REG(USR1)), GETREG(bas, REG(USR2)));
105 }
106 #endif
107
108 static int
109 imx_uart_probe(struct uart_bas *bas)
110 {
111
112         return (0);
113 }
114
115 static u_int
116 imx_uart_getbaud(struct uart_bas *bas)
117 {
118         uint32_t rate, ubir, ubmr;
119         u_int baud, blo, bhi, i;
120         static const u_int predivs[] = {6, 5, 4, 3, 2, 1, 7, 1};
121         static const u_int std_rates[] = {
122                 9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600
123         };
124
125         /*
126          * Get the baud rate the hardware is programmed for, then search the
127          * table of standard baud rates for a number that's within 3% of the
128          * actual rate the hardware is programmed for.  It's more comforting to
129          * see that your console is running at 115200 than 114942.  Note that
130          * here we cannot make a simplifying assumption that the predivider and
131          * numerator are 1 (like we do when setting the baud rate), because we
132          * don't know what u-boot might have set up.
133          */
134         i = (GETREG(bas, REG(UFCR)) & IMXUART_UFCR_RFDIV_MASK) >>
135             IMXUART_UFCR_RFDIV_SHIFT;
136         rate = bas->rclk / predivs[i];
137         ubir = GETREG(bas, REG(UBIR)) + 1;
138         ubmr = GETREG(bas, REG(UBMR)) + 1;
139         baud = ((rate / 16 ) * ubir) / ubmr;
140
141         blo = (baud * 100) / 103;
142         bhi = (baud * 100) / 97;
143         for (i = 0; i < nitems(std_rates); i++) {
144                 rate = std_rates[i];
145                 if (rate >= blo && rate <= bhi) {
146                         baud = rate;
147                         break;
148                 }
149         }
150
151         return (baud);
152 }
153
154 static void
155 imx_uart_init(struct uart_bas *bas, int baudrate, int databits, 
156     int stopbits, int parity)
157 {
158         uint32_t baseclk, reg;
159
160         /* Enable the device and the RX/TX channels. */
161         SET(bas, REG(UCR1), FLD(UCR1, UARTEN));
162         SET(bas, REG(UCR2), FLD(UCR2, RXEN) | FLD(UCR2, TXEN));
163
164         if (databits == 7)
165                 DIS(bas, UCR2, WS);
166         else
167                 ENA(bas, UCR2, WS);
168
169         if (stopbits == 2)
170                 ENA(bas, UCR2, STPB);
171         else
172                 DIS(bas, UCR2, STPB);
173
174         switch (parity) {
175         case UART_PARITY_ODD:
176                 DIS(bas, UCR2, PROE);
177                 ENA(bas, UCR2, PREN);
178                 break;
179         case UART_PARITY_EVEN:
180                 ENA(bas, UCR2, PROE);
181                 ENA(bas, UCR2, PREN);
182                 break;
183         case UART_PARITY_MARK:
184         case UART_PARITY_SPACE:
185                 /* FALLTHROUGH: Hardware doesn't support mark/space. */
186         case UART_PARITY_NONE:
187         default:
188                 DIS(bas, UCR2, PREN);
189                 break;
190         }
191
192         /*
193          * The hardware has an extremely flexible baud clock: it allows setting
194          * both the numerator and denominator of the divider, as well as a
195          * separate pre-divider.  We simplify the problem of coming up with a
196          * workable pair of numbers by assuming a pre-divider and numerator of
197          * one because our base clock is so fast we can reach virtually any
198          * reasonable speed with a simple divisor.  The numerator value actually
199          * includes the 16x over-sampling (so a value of 16 means divide by 1);
200          * the register value is the numerator-1, so we have a hard-coded 15.
201          * Note that a quirk of the hardware requires that both UBIR and UBMR be
202          * set back to back in order for the change to take effect.
203          */
204         if ((baudrate > 0) && (bas->rclk != 0)) {
205                 baseclk = bas->rclk;
206                 reg = GETREG(bas, REG(UFCR));
207                 reg = (reg & ~IMXUART_UFCR_RFDIV_MASK) | IMXUART_UFCR_RFDIV_DIV1;
208                 SETREG(bas, REG(UFCR), reg);
209                 SETREG(bas, REG(UBIR), 15);
210                 SETREG(bas, REG(UBMR), (baseclk / baudrate) - 1);
211         }
212
213         /*
214          * Program the tx lowater and rx hiwater levels at which fifo-service
215          * interrupts are signaled.  The tx value is interpetted as "when there
216          * are only this many bytes remaining" (not "this many free").
217          */
218         reg = GETREG(bas, REG(UFCR));
219         reg &= ~(IMXUART_UFCR_TXTL_MASK | IMXUART_UFCR_RXTL_MASK);
220         reg |= (IMX_FIFOSZ - IMX_TXFIFO_LEVEL) << IMXUART_UFCR_TXTL_SHIFT;
221         reg |= IMX_RXFIFO_LEVEL << IMXUART_UFCR_RXTL_SHIFT;
222         SETREG(bas, REG(UFCR), reg);
223 }
224
225 static void
226 imx_uart_term(struct uart_bas *bas)
227 {
228
229 }
230
231 static void
232 imx_uart_putc(struct uart_bas *bas, int c)
233 {
234
235         while (!(IS(bas, USR1, TRDY)))
236                 ;
237         SETREG(bas, REG(UTXD), c);
238 }
239
240 static int
241 imx_uart_rxready(struct uart_bas *bas)
242 {
243
244         return ((IS(bas, USR2, RDR)) ? 1 : 0);
245 }
246
247 static int
248 imx_uart_getc(struct uart_bas *bas, struct mtx *hwmtx)
249 {
250         int c;
251
252         uart_lock(hwmtx);
253         while (!(IS(bas, USR2, RDR)))
254                 ;
255
256         c = GETREG(bas, REG(URXD));
257         uart_unlock(hwmtx);
258 #if defined(KDB)
259         if (c & FLD(URXD, BRK)) {
260                 if (kdb_break())
261                         return (0);
262         }
263 #endif
264         return (c & 0xff);
265 }
266
267 /*
268  * High-level UART interface.
269  */
270 struct imx_uart_softc {
271         struct uart_softc base;
272 };
273
274 static int imx_uart_bus_attach(struct uart_softc *);
275 static int imx_uart_bus_detach(struct uart_softc *);
276 static int imx_uart_bus_flush(struct uart_softc *, int);
277 static int imx_uart_bus_getsig(struct uart_softc *);
278 static int imx_uart_bus_ioctl(struct uart_softc *, int, intptr_t);
279 static int imx_uart_bus_ipend(struct uart_softc *);
280 static int imx_uart_bus_param(struct uart_softc *, int, int, int, int);
281 static int imx_uart_bus_probe(struct uart_softc *);
282 static int imx_uart_bus_receive(struct uart_softc *);
283 static int imx_uart_bus_setsig(struct uart_softc *, int);
284 static int imx_uart_bus_transmit(struct uart_softc *);
285 static void imx_uart_bus_grab(struct uart_softc *);
286 static void imx_uart_bus_ungrab(struct uart_softc *);
287
288 static kobj_method_t imx_uart_methods[] = {
289         KOBJMETHOD(uart_attach,         imx_uart_bus_attach),
290         KOBJMETHOD(uart_detach,         imx_uart_bus_detach),
291         KOBJMETHOD(uart_flush,          imx_uart_bus_flush),
292         KOBJMETHOD(uart_getsig,         imx_uart_bus_getsig),
293         KOBJMETHOD(uart_ioctl,          imx_uart_bus_ioctl),
294         KOBJMETHOD(uart_ipend,          imx_uart_bus_ipend),
295         KOBJMETHOD(uart_param,          imx_uart_bus_param),
296         KOBJMETHOD(uart_probe,          imx_uart_bus_probe),
297         KOBJMETHOD(uart_receive,        imx_uart_bus_receive),
298         KOBJMETHOD(uart_setsig,         imx_uart_bus_setsig),
299         KOBJMETHOD(uart_transmit,       imx_uart_bus_transmit),
300         KOBJMETHOD(uart_grab,           imx_uart_bus_grab),
301         KOBJMETHOD(uart_ungrab,         imx_uart_bus_ungrab),
302         { 0, 0 }
303 };
304
305 static struct uart_class uart_imx_class = {
306         "imx",
307         imx_uart_methods,
308         sizeof(struct imx_uart_softc),
309         .uc_ops = &uart_imx_uart_ops,
310         .uc_range = 0x100,
311         .uc_rclk = 24000000, /* TODO: get value from CCM */
312         .uc_rshift = 0
313 };
314
315 static struct ofw_compat_data compat_data[] = {
316         {"fsl,imx6q-uart",      (uintptr_t)&uart_imx_class},
317         {"fsl,imx53-uart",      (uintptr_t)&uart_imx_class},
318         {"fsl,imx51-uart",      (uintptr_t)&uart_imx_class},
319         {"fsl,imx31-uart",      (uintptr_t)&uart_imx_class},
320         {"fsl,imx27-uart",      (uintptr_t)&uart_imx_class},
321         {"fsl,imx25-uart",      (uintptr_t)&uart_imx_class},
322         {"fsl,imx21-uart",      (uintptr_t)&uart_imx_class},
323         {NULL,                  (uintptr_t)NULL},
324 };
325 UART_FDT_CLASS_AND_DEVICE(compat_data);
326
327 #define SIGCHG(c, i, s, d)                              \
328         if (c) {                                        \
329                 i |= (i & s) ? s : s | d;               \
330         } else {                                        \
331                 i = (i & s) ? (i & ~s) | d : i;         \
332         }
333
334 #ifdef IMX_ENABLE_CLOCKS
335 static int
336 imx_uart_setup_clocks(struct uart_softc *sc)
337 {
338         struct uart_bas *bas;
339         clk_t ipgclk, perclk;
340         uint64_t freq;
341         int error;
342
343         bas = &sc->sc_bas;
344
345         if (clk_get_by_ofw_name(sc->sc_dev, 0, "ipg", &ipgclk) != 0)
346                 return (ENOENT);
347
348         if (clk_get_by_ofw_name(sc->sc_dev, 0, "per", &perclk) != 0) {
349                 return (ENOENT);
350         }
351
352         error = clk_enable(ipgclk);
353         if (error != 0) {
354                 device_printf(sc->sc_dev, "cannot enable ipg clock\n");
355                 return (error);
356         }
357
358         error = clk_get_freq(perclk, &freq);
359         if (error != 0) {
360                 device_printf(sc->sc_dev, "cannot get frequency\n");
361                 return (error);
362         }
363
364         bas->rclk = (uint32_t)freq;
365
366         return (0);
367 }
368 #endif
369
370 static int
371 imx_uart_bus_attach(struct uart_softc *sc)
372 {
373         struct uart_bas *bas;
374         struct uart_devinfo *di;
375
376         bas = &sc->sc_bas;
377
378 #ifdef IMX_ENABLE_CLOCKS
379         int error = imx_uart_setup_clocks(sc);
380         if (error)
381                 return (error);
382 #else
383         bas->rclk = imx_ccm_uart_hz();
384 #endif
385
386         if (sc->sc_sysdev != NULL) {
387                 di = sc->sc_sysdev;
388                 imx_uart_init(bas, di->baudrate, di->databits, di->stopbits,
389                     di->parity);
390         } else {
391                 imx_uart_init(bas, 115200, 8, 1, 0);
392         }
393
394         (void)imx_uart_bus_getsig(sc);
395
396         /* Clear all pending interrupts. */
397         SETREG(bas, REG(USR1), 0xffff);
398         SETREG(bas, REG(USR2), 0xffff);
399
400         DIS(bas, UCR4, DREN);
401         ENA(bas, UCR1, RRDYEN);
402         DIS(bas, UCR1, IDEN);
403         DIS(bas, UCR3, RXDSEN);
404         ENA(bas, UCR2, ATEN);
405         DIS(bas, UCR1, TXMPTYEN);
406         DIS(bas, UCR1, TRDYEN);
407         DIS(bas, UCR4, TCEN);
408         DIS(bas, UCR4, OREN);
409         ENA(bas, UCR4, BKEN);
410         DIS(bas, UCR4, WKEN);
411         DIS(bas, UCR1, ADEN);
412         DIS(bas, UCR3, ACIEN);
413         DIS(bas, UCR2, ESCI);
414         DIS(bas, UCR4, ENIRI);
415         DIS(bas, UCR3, AIRINTEN);
416         DIS(bas, UCR3, AWAKEN);
417         DIS(bas, UCR3, FRAERREN);
418         DIS(bas, UCR3, PARERREN);
419         DIS(bas, UCR1, RTSDEN);
420         DIS(bas, UCR2, RTSEN);
421         DIS(bas, UCR3, DTREN);
422         DIS(bas, UCR3, RI);
423         DIS(bas, UCR3, DCD);
424         DIS(bas, UCR3, DTRDEN);
425         ENA(bas, UCR2, IRTS);
426         ENA(bas, UCR3, RXDMUXSEL);
427
428         return (0);
429 }
430
431 static int
432 imx_uart_bus_detach(struct uart_softc *sc)
433 {
434
435         SETREG(&sc->sc_bas, REG(UCR4), 0);
436
437         return (0);
438 }
439
440 static int
441 imx_uart_bus_flush(struct uart_softc *sc, int what)
442 {
443
444         /* TODO */
445         return (0);
446 }
447
448 static int
449 imx_uart_bus_getsig(struct uart_softc *sc)
450 {
451         uint32_t new, old, sig;
452         uint8_t bes;
453
454         do {
455                 old = sc->sc_hwsig;
456                 sig = old;
457                 uart_lock(sc->sc_hwmtx);
458                 bes = GETREG(&sc->sc_bas, REG(USR2));
459                 uart_unlock(sc->sc_hwmtx);
460                 /* XXX: chip can show delta */
461                 SIGCHG(bes & FLD(USR2, DCDIN), sig, SER_DCD, SER_DDCD);
462                 new = sig & ~SER_MASK_DELTA;
463         } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
464
465         return (sig);
466 }
467
468 static int
469 imx_uart_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
470 {
471         struct uart_bas *bas;
472         int error;
473
474         bas = &sc->sc_bas;
475         error = 0;
476         uart_lock(sc->sc_hwmtx);
477         switch (request) {
478         case UART_IOCTL_BREAK:
479                 /* TODO */
480                 break;
481         case UART_IOCTL_BAUD:
482                 *(u_int*)data = imx_uart_getbaud(bas);
483                 break;
484         default:
485                 error = EINVAL;
486                 break;
487         }
488         uart_unlock(sc->sc_hwmtx);
489
490         return (error);
491 }
492
493 static int
494 imx_uart_bus_ipend(struct uart_softc *sc)
495 {
496         struct uart_bas *bas;
497         int ipend;
498         uint32_t usr1, usr2;
499         uint32_t ucr1, ucr2, ucr4;
500
501         bas = &sc->sc_bas;
502         ipend = 0;
503
504         uart_lock(sc->sc_hwmtx);
505
506         /* Read pending interrupts */
507         usr1 = GETREG(bas, REG(USR1));
508         usr2 = GETREG(bas, REG(USR2));
509         /* ACK interrupts */
510         SETREG(bas, REG(USR1), usr1);
511         SETREG(bas, REG(USR2), usr2);
512
513         ucr1 = GETREG(bas, REG(UCR1));
514         ucr2 = GETREG(bas, REG(UCR2));
515         ucr4 = GETREG(bas, REG(UCR4));
516
517         /* If we have reached tx low-water, we can tx some more now. */
518         if ((usr1 & FLD(USR1, TRDY)) && (ucr1 & FLD(UCR1, TRDYEN))) {
519                 DIS(bas, UCR1, TRDYEN);
520                 ipend |= SER_INT_TXIDLE;
521         }
522
523         /*
524          * If we have reached the rx high-water, or if there are bytes in the rx
525          * fifo and no new data has arrived for 8 character periods (aging
526          * timer), we have input data to process.
527          */
528         if (((usr1 & FLD(USR1, RRDY)) && (ucr1 & FLD(UCR1, RRDYEN))) || 
529             ((usr1 & FLD(USR1, AGTIM)) && (ucr2 & FLD(UCR2, ATEN)))) {
530                 DIS(bas, UCR1, RRDYEN);
531                 DIS(bas, UCR2, ATEN);
532                 ipend |= SER_INT_RXREADY;
533         }
534
535         /* A break can come in at any time, it never gets disabled. */
536         if ((usr2 & FLD(USR2, BRCD)) && (ucr4 & FLD(UCR4, BKEN)))
537                 ipend |= SER_INT_BREAK;
538
539         uart_unlock(sc->sc_hwmtx);
540
541         return (ipend);
542 }
543
544 static int
545 imx_uart_bus_param(struct uart_softc *sc, int baudrate, int databits,
546     int stopbits, int parity)
547 {
548
549         uart_lock(sc->sc_hwmtx);
550         imx_uart_init(&sc->sc_bas, baudrate, databits, stopbits, parity);
551         uart_unlock(sc->sc_hwmtx);
552         return (0);
553 }
554
555 static int
556 imx_uart_bus_probe(struct uart_softc *sc)
557 {
558         int error;
559
560         error = imx_uart_probe(&sc->sc_bas);
561         if (error)
562                 return (error);
563
564         /*
565          * On input we can read up to the full fifo size at once.  On output, we
566          * want to write only as much as the programmed tx low water level,
567          * because that's all we can be certain we have room for in the fifo
568          * when we get a tx-ready interrupt.
569          */
570         sc->sc_rxfifosz = IMX_FIFOSZ;
571         sc->sc_txfifosz = IMX_TXFIFO_LEVEL;
572
573         device_set_desc(sc->sc_dev, "Freescale i.MX UART");
574         return (0);
575 }
576
577 static int
578 imx_uart_bus_receive(struct uart_softc *sc)
579 {
580         struct uart_bas *bas;
581         int xc, out;
582
583         bas = &sc->sc_bas;
584         uart_lock(sc->sc_hwmtx);
585
586         /*
587          * Empty the rx fifo.  We get the RRDY interrupt when IMX_RXFIFO_LEVEL
588          * (the rx high-water level) is reached, but we set sc_rxfifosz to the
589          * full hardware fifo size, so we can safely process however much is
590          * there, not just the highwater size.
591          */
592         while (IS(bas, USR2, RDR)) {
593                 if (uart_rx_full(sc)) {
594                         /* No space left in input buffer */
595                         sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
596                         break;
597                 }
598                 xc = GETREG(bas, REG(URXD));
599                 out = xc & 0x000000ff;
600                 if (xc & FLD(URXD, FRMERR))
601                         out |= UART_STAT_FRAMERR;
602                 if (xc & FLD(URXD, PRERR))
603                         out |= UART_STAT_PARERR;
604                 if (xc & FLD(URXD, OVRRUN))
605                         out |= UART_STAT_OVERRUN;
606                 if (xc & FLD(URXD, BRK))
607                         out |= UART_STAT_BREAK;
608
609                 uart_rx_put(sc, out);
610         }
611         ENA(bas, UCR1, RRDYEN);
612         ENA(bas, UCR2, ATEN);
613
614         uart_unlock(sc->sc_hwmtx);
615         return (0);
616 }
617
618 static int
619 imx_uart_bus_setsig(struct uart_softc *sc, int sig)
620 {
621
622         return (0);
623 }
624
625 static int
626 imx_uart_bus_transmit(struct uart_softc *sc)
627 {
628         struct uart_bas *bas = &sc->sc_bas;
629         int i;
630
631         bas = &sc->sc_bas;
632         uart_lock(sc->sc_hwmtx);
633
634         /*
635          * Fill the tx fifo.  The uart core puts at most IMX_TXFIFO_LEVEL bytes
636          * into the txbuf (because that's what sc_txfifosz is set to), and
637          * because we got the TRDY (low-water reached) interrupt we know at
638          * least that much space is available in the fifo.
639          */
640         for (i = 0; i < sc->sc_txdatasz; i++) {
641                 SETREG(bas, REG(UTXD), sc->sc_txbuf[i] & 0xff);
642         }
643         sc->sc_txbusy = 1;
644         ENA(bas, UCR1, TRDYEN);
645
646         uart_unlock(sc->sc_hwmtx);
647
648         return (0);
649 }
650
651 static void
652 imx_uart_bus_grab(struct uart_softc *sc)
653 {
654         struct uart_bas *bas = &sc->sc_bas;
655
656         bas = &sc->sc_bas;
657         uart_lock(sc->sc_hwmtx);
658         DIS(bas, UCR1, RRDYEN);
659         DIS(bas, UCR2, ATEN);
660         uart_unlock(sc->sc_hwmtx);
661 }
662
663 static void
664 imx_uart_bus_ungrab(struct uart_softc *sc)
665 {
666         struct uart_bas *bas = &sc->sc_bas;
667
668         bas = &sc->sc_bas;
669         uart_lock(sc->sc_hwmtx);
670         ENA(bas, UCR1, RRDYEN);
671         ENA(bas, UCR2, ATEN);
672         uart_unlock(sc->sc_hwmtx);
673 }