The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/mips/atheros/uart_dev_ar933x.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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.0/sys/mips/atheros/uart_dev_ar933x.c 249120 2013-04-05 00:26:06Z adrian $");
   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 
  329 static kobj_method_t ar933x_methods[] = {
  330         KOBJMETHOD(uart_attach,         ar933x_bus_attach),
  331         KOBJMETHOD(uart_detach,         ar933x_bus_detach),
  332         KOBJMETHOD(uart_flush,          ar933x_bus_flush),
  333         KOBJMETHOD(uart_getsig,         ar933x_bus_getsig),
  334         KOBJMETHOD(uart_ioctl,          ar933x_bus_ioctl),
  335         KOBJMETHOD(uart_ipend,          ar933x_bus_ipend),
  336         KOBJMETHOD(uart_param,          ar933x_bus_param),
  337         KOBJMETHOD(uart_probe,          ar933x_bus_probe),
  338         KOBJMETHOD(uart_receive,        ar933x_bus_receive),
  339         KOBJMETHOD(uart_setsig,         ar933x_bus_setsig),
  340         KOBJMETHOD(uart_transmit,       ar933x_bus_transmit),
  341         { 0, 0 }
  342 };
  343 
  344 struct uart_class uart_ar933x_class = {
  345         "ar933x",
  346         ar933x_methods,
  347         sizeof(struct ar933x_softc),
  348         .uc_ops = &uart_ar933x_ops,
  349         .uc_range = 8,
  350         .uc_rclk = DEFAULT_RCLK
  351 };
  352 
  353 #define SIGCHG(c, i, s, d)                              \
  354         if (c) {                                        \
  355                 i |= (i & s) ? s : s | d;               \
  356         } else {                                        \
  357                 i = (i & s) ? (i & ~s) | d : i;         \
  358         }
  359 
  360 static int
  361 ar933x_bus_attach(struct uart_softc *sc)
  362 {
  363         struct ar933x_softc *u = (struct ar933x_softc *)sc;
  364         struct uart_bas *bas = &sc->sc_bas;
  365         uint32_t reg;
  366 
  367         /* XXX TODO: flush transmitter */
  368 
  369         /*
  370          * Setup initial interrupt notifications.
  371          *
  372          * XXX for now, just RX FIFO valid.
  373          * Later on (when they're handled), also handle
  374          * RX errors/overflow.
  375          */
  376         u->u_ier = AR933X_UART_INT_RX_VALID;
  377 
  378         /* Enable RX interrupts to kick-start things */
  379         ar933x_setreg(bas, AR933X_UART_INT_EN_REG, u->u_ier);
  380 
  381         /* Enable the host interrupt now */
  382         reg = ar933x_getreg(bas, AR933X_UART_CS_REG);
  383         reg |= AR933X_UART_CS_HOST_INT_EN;
  384         ar933x_setreg(bas, AR933X_UART_CS_REG, reg);
  385 
  386         return (0);
  387 }
  388 
  389 static int
  390 ar933x_bus_detach(struct uart_softc *sc)
  391 {
  392         struct uart_bas *bas = &sc->sc_bas;
  393         uint32_t reg;
  394 
  395         /* Disable all interrupts */
  396         ar933x_setreg(bas, AR933X_UART_INT_EN_REG, 0x00000000);
  397 
  398         /* Disable the host interrupt */
  399         reg = ar933x_getreg(bas, AR933X_UART_CS_REG);
  400         reg &= ~AR933X_UART_CS_HOST_INT_EN;
  401         ar933x_setreg(bas, AR933X_UART_CS_REG, reg);
  402         uart_barrier(bas);
  403 
  404         return (0);
  405 }
  406 
  407 static int
  408 ar933x_bus_flush(struct uart_softc *sc, int what)
  409 {
  410         struct uart_bas *bas;
  411 
  412         bas = &sc->sc_bas;
  413         uart_lock(sc->sc_hwmtx);
  414         ar933x_drain(bas, what);
  415         uart_unlock(sc->sc_hwmtx);
  416 
  417         return (0);
  418 }
  419 
  420 static int
  421 ar933x_bus_getsig(struct uart_softc *sc)
  422 {
  423         uint32_t sig = sc->sc_hwsig;
  424 
  425         /*
  426          * For now, let's just return that DSR/DCD/CTS is asserted.
  427          *
  428          * XXX TODO: actually verify whether this is correct!
  429          */
  430         SIGCHG(1, sig, SER_DSR, SER_DDSR);
  431         SIGCHG(1, sig, SER_CTS, SER_DCTS);
  432         SIGCHG(1, sig, SER_DCD, SER_DDCD);
  433         SIGCHG(1, sig,  SER_RI,  SER_DRI);
  434 
  435         sc->sc_hwsig = sig & ~SER_MASK_DELTA;
  436 
  437         return (sig);
  438 }
  439 
  440 static int
  441 ar933x_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
  442 {
  443 #if 0
  444         struct uart_bas *bas;
  445         int baudrate, divisor, error;
  446         uint8_t efr, lcr;
  447 
  448         bas = &sc->sc_bas;
  449         error = 0;
  450         uart_lock(sc->sc_hwmtx);
  451         switch (request) {
  452         case UART_IOCTL_BREAK:
  453                 lcr = uart_getreg(bas, REG_LCR);
  454                 if (data)
  455                         lcr |= LCR_SBREAK;
  456                 else
  457                         lcr &= ~LCR_SBREAK;
  458                 uart_setreg(bas, REG_LCR, lcr);
  459                 uart_barrier(bas);
  460                 break;
  461         case UART_IOCTL_IFLOW:
  462                 lcr = uart_getreg(bas, REG_LCR);
  463                 uart_barrier(bas);
  464                 uart_setreg(bas, REG_LCR, 0xbf);
  465                 uart_barrier(bas);
  466                 efr = uart_getreg(bas, REG_EFR);
  467                 if (data)
  468                         efr |= EFR_RTS;
  469                 else
  470                         efr &= ~EFR_RTS;
  471                 uart_setreg(bas, REG_EFR, efr);
  472                 uart_barrier(bas);
  473                 uart_setreg(bas, REG_LCR, lcr);
  474                 uart_barrier(bas);
  475                 break;
  476         case UART_IOCTL_OFLOW:
  477                 lcr = uart_getreg(bas, REG_LCR);
  478                 uart_barrier(bas);
  479                 uart_setreg(bas, REG_LCR, 0xbf);
  480                 uart_barrier(bas);
  481                 efr = uart_getreg(bas, REG_EFR);
  482                 if (data)
  483                         efr |= EFR_CTS;
  484                 else
  485                         efr &= ~EFR_CTS;
  486                 uart_setreg(bas, REG_EFR, efr);
  487                 uart_barrier(bas);
  488                 uart_setreg(bas, REG_LCR, lcr);
  489                 uart_barrier(bas);
  490                 break;
  491         case UART_IOCTL_BAUD:
  492                 lcr = uart_getreg(bas, REG_LCR);
  493                 uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
  494                 uart_barrier(bas);
  495                 divisor = uart_getreg(bas, REG_DLL) |
  496                     (uart_getreg(bas, REG_DLH) << 8);
  497                 uart_barrier(bas);
  498                 uart_setreg(bas, REG_LCR, lcr);
  499                 uart_barrier(bas);
  500                 baudrate = (divisor > 0) ? bas->rclk / divisor / 16 : 0;
  501                 if (baudrate > 0)
  502                         *(int*)data = baudrate;
  503                 else
  504                         error = ENXIO;
  505                 break;
  506         default:
  507                 error = EINVAL;
  508                 break;
  509         }
  510         uart_unlock(sc->sc_hwmtx);
  511         return (error);
  512 #endif
  513         return (ENXIO);
  514 }
  515 
  516 /*
  517  * Bus interrupt handler.
  518  *
  519  * For now, system interrupts are disabled.
  520  * So this is just called from a callout in uart_core.c
  521  * to poll various state.
  522  */
  523 static int
  524 ar933x_bus_ipend(struct uart_softc *sc)
  525 {
  526         struct ar933x_softc *u = (struct ar933x_softc *)sc;
  527         struct uart_bas *bas = &sc->sc_bas;
  528         int ipend = 0;
  529         uint32_t isr;
  530 
  531         uart_lock(sc->sc_hwmtx);
  532 
  533         /*
  534          * Fetch/ACK the ISR status.
  535          */
  536         isr = ar933x_getreg(bas, AR933X_UART_INT_REG);
  537         ar933x_setreg(bas, AR933X_UART_INT_REG, isr);
  538         uart_barrier(bas);
  539 
  540         /*
  541          * RX ready - notify upper layer.
  542          */
  543         if (isr & AR933X_UART_INT_RX_VALID) {
  544                 ipend |= SER_INT_RXREADY;
  545         }
  546 
  547         /*
  548          * If we get this interrupt, we should disable
  549          * it from the interrupt mask and inform the uart
  550          * driver appropriately.
  551          *
  552          * We can't keep setting SER_INT_TXIDLE or SER_INT_SIGCHG
  553          * all the time or IO stops working.  So we will always
  554          * clear this interrupt if we get it, then we only signal
  555          * the upper layer if we were doing active TX in the
  556          * first place.
  557          *
  558          * Also, the name is misleading.  This actually means
  559          * "the FIFO is almost empty."  So if we just write some
  560          * more data to the FIFO without checking whether it can
  561          * take said data, we'll overflow the thing.
  562          *
  563          * Unfortunately the FreeBSD uart device has no concept of
  564          * partial UART writes - it expects that the whole buffer
  565          * is written to the hardware.  Thus for now, ar933x_bus_transmit()
  566          * will wait for the FIFO to finish draining before it pushes
  567          * more frames into it.
  568          */
  569         if (isr & AR933X_UART_INT_TX_EMPTY) {
  570                 /*
  571                  * Update u_ier to disable TX notifications; update hardware
  572                  */
  573                 u->u_ier &= ~AR933X_UART_INT_TX_EMPTY;
  574                 ar933x_setreg(bas, AR933X_UART_INT_EN_REG, u->u_ier);
  575                 uart_barrier(bas);
  576         }
  577 
  578         /*
  579          * Only signal TX idle if we're not busy transmitting.
  580          */
  581         if (sc->sc_txbusy) {
  582                 if (isr & AR933X_UART_INT_TX_EMPTY) {
  583                         ipend |= SER_INT_TXIDLE;
  584                 } else {
  585                         ipend |= SER_INT_SIGCHG;
  586                 }
  587         }
  588 
  589         uart_unlock(sc->sc_hwmtx);
  590         return (ipend);
  591 }
  592 
  593 static int
  594 ar933x_bus_param(struct uart_softc *sc, int baudrate, int databits,
  595     int stopbits, int parity)
  596 {
  597         struct uart_bas *bas;
  598         int error;
  599 
  600         bas = &sc->sc_bas;
  601         uart_lock(sc->sc_hwmtx);
  602         error = ar933x_param(bas, baudrate, databits, stopbits, parity);
  603         uart_unlock(sc->sc_hwmtx);
  604         return (error);
  605 }
  606 
  607 static int
  608 ar933x_bus_probe(struct uart_softc *sc)
  609 {
  610         struct uart_bas *bas;
  611         int error;
  612 
  613         bas = &sc->sc_bas;
  614 
  615         error = ar933x_probe(bas);
  616         if (error)
  617                 return (error);
  618 
  619         /* Reset FIFOs. */
  620         ar933x_drain(bas, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
  621 
  622         /* XXX TODO: actually find out what the FIFO depth is! */
  623         sc->sc_rxfifosz = 16;
  624         sc->sc_txfifosz = 16;
  625 
  626         return (0);
  627 }
  628 
  629 static int
  630 ar933x_bus_receive(struct uart_softc *sc)
  631 {
  632         struct uart_bas *bas = &sc->sc_bas;
  633         int xc;
  634 
  635         uart_lock(sc->sc_hwmtx);
  636 
  637         /* Loop over until we are full, or no data is available */
  638         while (ar933x_rxready(bas)) {
  639                 if (uart_rx_full(sc)) {
  640                         sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
  641                         break;
  642                 }
  643 
  644                 /* Read the top of the RX FIFO */
  645                 xc = ar933x_getreg(bas, AR933X_UART_DATA_REG) & 0xff;
  646 
  647                 /* Remove that entry from said RX FIFO */
  648                 ar933x_setreg(bas, AR933X_UART_DATA_REG,
  649                     AR933X_UART_DATA_RX_CSR);
  650                 uart_barrier(bas);
  651 
  652                 /* XXX frame, parity error */
  653                 uart_rx_put(sc, xc);
  654         }
  655 
  656         /*
  657          * XXX TODO: Discard everything left in the Rx FIFO?
  658          * XXX only if we've hit an overrun condition?
  659          */
  660 
  661         uart_unlock(sc->sc_hwmtx);
  662 
  663         return (0);
  664 }
  665 
  666 static int
  667 ar933x_bus_setsig(struct uart_softc *sc, int sig)
  668 {
  669 #if 0
  670         struct ar933x_softc *ns8250 = (struct ar933x_softc*)sc;
  671         struct uart_bas *bas;
  672         uint32_t new, old;
  673 
  674         bas = &sc->sc_bas;
  675         do {
  676                 old = sc->sc_hwsig;
  677                 new = old;
  678                 if (sig & SER_DDTR) {
  679                         SIGCHG(sig & SER_DTR, new, SER_DTR,
  680                             SER_DDTR);
  681                 }
  682                 if (sig & SER_DRTS) {
  683                         SIGCHG(sig & SER_RTS, new, SER_RTS,
  684                             SER_DRTS);
  685                 }
  686         } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
  687         uart_lock(sc->sc_hwmtx);
  688         ns8250->mcr &= ~(MCR_DTR|MCR_RTS);
  689         if (new & SER_DTR)
  690                 ns8250->mcr |= MCR_DTR;
  691         if (new & SER_RTS)
  692                 ns8250->mcr |= MCR_RTS;
  693         uart_setreg(bas, REG_MCR, ns8250->mcr);
  694         uart_barrier(bas);
  695         uart_unlock(sc->sc_hwmtx);
  696 #endif
  697         return (0);
  698 }
  699 
  700 /*
  701  * Write the current transmit buffer to the TX FIFO.
  702  *
  703  * Unfortunately the FreeBSD uart device has no concept of
  704  * partial UART writes - it expects that the whole buffer
  705  * is written to the hardware.  Thus for now, this will wait for
  706  * the FIFO to finish draining before it pushes more frames into it.
  707  *
  708  * If non-blocking operation is truely needed here, either
  709  * the FreeBSD uart device will need to handle partial writes
  710  * in xxx_bus_transmit(), or we'll need to do TX FIFO buffering
  711  * of our own here.
  712  */
  713 static int
  714 ar933x_bus_transmit(struct uart_softc *sc)
  715 {
  716         struct uart_bas *bas = &sc->sc_bas;
  717         struct ar933x_softc *u = (struct ar933x_softc *)sc;
  718         int i;
  719 
  720         uart_lock(sc->sc_hwmtx);
  721 
  722         /* Wait for the FIFO to be clear - see above */
  723         while (ar933x_getreg(bas, AR933X_UART_CS_REG) &
  724             AR933X_UART_CS_TX_BUSY)
  725                 ;
  726 
  727         /*
  728          * Write some data!
  729          */
  730         for (i = 0; i < sc->sc_txdatasz; i++) {
  731                 /* Write the TX data */
  732                 ar933x_setreg(bas, AR933X_UART_DATA_REG,
  733                     (sc->sc_txbuf[i] & 0xff) | AR933X_UART_DATA_TX_CSR);
  734                 uart_barrier(bas);
  735         }
  736 
  737         /*
  738          * Now that we're transmitting, get interrupt notification
  739          * when the FIFO is (almost) empty - see above.
  740          */
  741         u->u_ier |= AR933X_UART_INT_TX_EMPTY;
  742         ar933x_setreg(bas, AR933X_UART_INT_EN_REG, u->u_ier);
  743         uart_barrier(bas);
  744 
  745         /*
  746          * Inform the upper layer that we are presently transmitting
  747          * data to the hardware; this will be cleared when the
  748          * TXIDLE interrupt occurs.
  749          */
  750         sc->sc_txbusy = 1;
  751         uart_unlock(sc->sc_hwmtx);
  752 
  753         return (0);
  754 }

Cache object: e2e3bdaea77feede15631b9528aaabfe


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.