Date: Tue, 30 Sep 2014 23:01:12 +0000 (UTC) From: Ian Lepore <ian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r272334 - head/sys/dev/uart Message-ID: <201409302301.s8UN1CIu075264@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409302301.s8UN1CIu075264>