From owner-svn-src-head@freebsd.org Sat Mar 11 22:34:03 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 88DCBD08CA8; Sat, 11 Mar 2017 22:34:03 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 60F45160B; Sat, 11 Mar 2017 22:34:03 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v2BMY2Ig095970; Sat, 11 Mar 2017 22:34:02 GMT (envelope-from ian@FreeBSD.org) Received: (from ian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v2BMY2Ou095969; Sat, 11 Mar 2017 22:34:02 GMT (envelope-from ian@FreeBSD.org) Message-Id: <201703112234.v2BMY2Ou095969@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ian set sender to ian@FreeBSD.org using -f From: Ian Lepore Date: Sat, 11 Mar 2017 22:34:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r315090 - head/sys/dev/uart X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 11 Mar 2017 22:34:03 -0000 Author: ian Date: Sat Mar 11 22:34:02 2017 New Revision: 315090 URL: https://svnweb.freebsd.org/changeset/base/315090 Log: Extend the pl011 small-fifos fix to other SoCs that indicate rev 5 hardware but lack the larger fifos rev 5 hardware should have. The linux world (where our FDT data comes from) solved this by adding a new property to pl011 nodes, "arm,primecell-periphid". When this property is present, its values override the values in the hardware periphid registers. For pl011 rev 5 hardware with small fifos, they override the id so that it appears to be rev 4 hardware. The driver now uses the new property when present. It also continues to check the device compat string, to handle older fdt data that may still be in use on existing systems (on RPi systems it is common to update system software without updating fdt data which is part of the boot firmware). Reviewed by: imp Modified: head/sys/dev/uart/uart_dev_pl011.c Modified: head/sys/dev/uart/uart_dev_pl011.c ============================================================================== --- head/sys/dev/uart/uart_dev_pl011.c Sat Mar 11 22:22:51 2017 (r315089) +++ head/sys/dev/uart/uart_dev_pl011.c Sat Mar 11 22:34:02 2017 (r315090) @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include #ifdef FDT #include +#include #endif #include #include "uart_if.h" @@ -449,25 +450,36 @@ static int uart_pl011_bus_probe(struct uart_softc *sc) { uint8_t hwrev; - bool is_bcm2835; - - device_set_desc(sc->sc_dev, "PrimeCell UART (PL011)"); +#ifdef FDT + pcell_t node; + uint32_t periphid; /* * The FIFO sizes vary depending on hardware; rev 2 and below have 16 - * byte FIFOs, rev 3 and up are 32 byte. We get a bit of drama, as - * always, with the bcm2835 (rpi), which claims to be rev 3, but has 16 - * byte FIFOs. We check for both the old freebsd-historic and the - * proper bindings-defined compatible strings for bcm2835. + * byte FIFOs, rev 3 and up are 32 byte. The hardware rev is in the + * primecell periphid register, but we get a bit of drama, as always, + * with the bcm2835 (rpi), which claims to be rev 3, but has 16 byte + * FIFOs. We check for both the old freebsd-historic and the proper + * bindings-defined compatible strings for bcm2835, and also check the + * workaround the linux drivers use for rpi3, which is to override the + * primecell periphid register value with a property. */ -#ifdef FDT - is_bcm2835 = ofw_bus_is_compatible(sc->sc_dev, "brcm,bcm2835-pl011") || - ofw_bus_is_compatible(sc->sc_dev, "broadcom,bcm2835-uart"); + if (ofw_bus_is_compatible(sc->sc_dev, "brcm,bcm2835-pl011") || + ofw_bus_is_compatible(sc->sc_dev, "broadcom,bcm2835-uart")) { + hwrev = 2; + } else { + node = ofw_bus_get_node(sc->sc_dev); + if (OF_getencprop(node, "arm,primecell-periphid", &periphid, + sizeof(periphid)) > 0) { + hwrev = (periphid >> 20) & 0x0f; + } else { + hwrev = __uart_getreg(&sc->sc_bas, UART_PIDREG_2) >> 4; + } + } #else - is_bcm2835 = false; -#endif hwrev = __uart_getreg(&sc->sc_bas, UART_PIDREG_2) >> 4; - if (hwrev <= 2 || is_bcm2835) { +#endif + if (hwrev <= 2) { sc->sc_rxfifosz = FIFO_RX_SIZE_R2; sc->sc_txfifosz = FIFO_TX_SIZE_R2; } else { @@ -475,6 +487,8 @@ uart_pl011_bus_probe(struct uart_softc * sc->sc_txfifosz = FIFO_TX_SIZE_R3; } + device_set_desc(sc->sc_dev, "PrimeCell UART (PL011)"); + return (0); }