Author: ian
Date: Tue Sep 30 23:01:11 2014
New Revision: 272334
URL: http://svnweb.freebsd.org/changeset/base/272334

Log:
  Return the actual baud rate programmed in the hardware rather than 115200.
  This allows the "3wire" entry in /etc/ttys (with no speed specified) to work.

Modified:
  head/sys/dev/uart/uart_dev_imx.c

Modified: head/sys/dev/uart/uart_dev_imx.c
==============================================================================
--- head/sys/dev/uart/uart_dev_imx.c    Tue Sep 30 21:28:05 2014        
(r272333)
+++ head/sys/dev/uart/uart_dev_imx.c    Tue Sep 30 23:01:11 2014        
(r272334)
@@ -90,6 +90,45 @@ imx_uart_probe(struct uart_bas *bas)
        return (0);
 }
 
+static u_int
+imx_uart_getbaud(struct uart_bas *bas)
+{
+       uint32_t rate, ubir, ubmr;
+       u_int baud, blo, bhi, i;
+       static const u_int predivs[] = {6, 5, 4, 3, 2, 1, 7, 1};
+       static const u_int std_rates[] = {
+               9600, 14400, 19200, 38400, 57600, 115200, 230400, 460800, 921600
+       };
+
+       /*
+        * Get the baud rate the hardware is programmed for, then search the
+        * table of standard baud rates for a number that's within 3% of the
+        * actual rate the hardware is programmed for.  It's more comforting to
+        * see that your console is running at 115200 than 114942.  Note that
+        * here we cannot make a simplifying assumption that the predivider and
+        * numerator are 1 (like we do when setting the baud rate), because we
+        * don't know what u-boot might have set up.
+        */
+       i = (GETREG(bas, REG(UFCR)) & IMXUART_UFCR_RFDIV_MASK) >>
+           IMXUART_UFCR_RFDIV_SHIFT;
+       rate = imx_ccm_uart_hz() / predivs[i];
+       ubir = GETREG(bas, REG(UBIR)) + 1;
+       ubmr = GETREG(bas, REG(UBMR)) + 1;
+       baud = ((rate / 16 ) * ubir) / ubmr;
+
+       blo = (baud * 100) / 103;
+       bhi = (baud * 100) / 97;
+       for (i = 0; i < nitems(std_rates); i++) {
+               rate = std_rates[i];
+               if (rate >= blo && rate <= bhi) {
+                       baud = rate;
+                       break;
+               }
+       }
+
+       return (baud);
+}
+
 static void
 imx_uart_init(struct uart_bas *bas, int baudrate, int databits, 
     int stopbits, int parity)
@@ -348,8 +387,7 @@ imx_uart_bus_ioctl(struct uart_softc *sc
                /* TODO */
                break;
        case UART_IOCTL_BAUD:
-               /* TODO */
-               *(int*)data = 115200;
+               *(u_int*)data = imx_uart_getbaud(bas);
                break;
        default:
                error = EINVAL;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to