svn commit: r272334 - head/sys/dev/uart

Ian Lepore ian at FreeBSD.org
Tue Sep 30 23:01:12 UTC 2014


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;


More information about the svn-src-all mailing list