Date: Tue, 07 Mar 2017 18:35:52 -0700 From: Ian Lepore <ian@freebsd.org> To: "Jayachandran C." <jchandra@freebsd.org> Cc: Michael Tuexen <tuexen@fh-muenster.de>, freebsd-arm@freebsd.org, Oleksandr Tymoshenko <gonzo@id.bluezbox.com> Subject: Re: Odd-looking serial console prompt on RPI2 Message-ID: <1488936952.18764.63.camel@freebsd.org> In-Reply-To: <CA%2B7sy7ANOxzJXfx62M8c7sq4SsLL3gDxyhSj74QDmupjKsT7mQ@mail.gmail.com> References: <20170227195647.GA91329@www.zefox.net> <20170301200112.ymwkfd64tzz5f3b2@mutt-hbsd> <4194F030-4E5C-4EB6-82D7-FD725E3B7CEF@fh-muenster.de> <20170302000334.GA99403@www.zefox.net> <1488419304.60166.26.camel@freebsd.org> <20170302020116.GA98466@bluezbox.com> <1488420309.60166.32.camel@freebsd.org> <CA%2B7sy7Bv=-2mx2MJP18ZnbNp2yO2hKukw=KALn711txaxsk=rg@mail.gmail.com> <1488664965.69705.24.camel@freebsd.org> <CA%2B7sy7D0ctonL26mchbpyDL-CrcyW%2B5F9CYsQ9UwagR4UcoK7g@mail.gmail.com> <1488817492.18764.14.camel@freebsd.org> <CA%2B7sy7ANOxzJXfx62M8c7sq4SsLL3gDxyhSj74QDmupjKsT7mQ@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
On Wed, 2017-03-08 at 03:18 +0530, Jayachandran C. wrote:
> On Mon, Mar 6, 2017 at 9:54 PM, Ian Lepore <ian@freebsd.org> wrote:
> > [...]
>
> I was thinking that IFLS behaved differently on ThunderX and that is
> why my original code worked there. But after going thru the spec
> again,
> it looks like the FIFO in newer pl011 implementations is 32 entry
> deep,
> and that may be real reason why ThunderX did not have any issues.
>
> JC.
Could you (and anybody else who has a board that uses pl011 uarts)
please test the attached patch? I tested already on an rpi-b and it
works fine there, but I'd like to hear whether it works on something
that actually has 32-byte fifos. It should probably be tested on an
rpi2 as well (which I don't have).
-- Ian
[-- Attachment #2 --]
Index: sys/dev/uart/uart_dev_pl011.c
===================================================================
--- sys/dev/uart/uart_dev_pl011.c (revision 314682)
+++ sys/dev/uart/uart_dev_pl011.c (working copy)
@@ -111,16 +111,24 @@ __FBSDID("$FreeBSD$");
#define UART_MIS 0x10 /* Masked interrupt status register */
#define UART_ICR 0x11 /* Interrupt clear register */
+#define UART_PIDREG_0 0x3f8 /* Peripheral ID register 0 */
+#define UART_PIDREG_1 0x3f9 /* Peripheral ID register 1 */
+#define UART_PIDREG_2 0x3fa /* Peripheral ID register 2 */
+#define UART_PIDREG_3 0x3fb /* Peripheral ID register 3 */
+
/*
- * The hardware FIFOs are 16 bytes each. We configure them to interrupt when
- * 3/4 full/empty. For RX we set the size to the full hardware capacity so that
- * the uart core allocates enough buffer space to hold a complete fifo full of
- * incoming data. For TX, we need to limit the size to the capacity we know
- * will be available when the interrupt occurs; uart_core will feed exactly that
- * many bytes to uart_pl011_bus_transmit() which must consume them all.
+ * The hardware FIFOs are 16 bytes each on rev 2 and earlier hardware, 32 bytes
+ * on rev 3 and later. We configure them to interrupt when 3/4 full/empty. For
+ * RX we set the size to the full hardware capacity so that the uart core
+ * allocates enough buffer space to hold a complete fifo full of incoming data.
+ * For TX, we need to limit the size to the capacity we know will be available
+ * when the interrupt occurs; uart_core will feed exactly that many bytes to
+ * uart_pl011_bus_transmit() which must consume them all.
*/
-#define FIFO_RX_SIZE 16
-#define FIFO_TX_SIZE 12
+#define FIFO_RX_SIZE_R2 16
+#define FIFO_TX_SIZE_R2 12
+#define FIFO_RX_SIZE_R3 32
+#define FIFO_TX_SIZE_R3 24
#define FIFO_IFLS_BITS ((IFLS_LVL_6_8th << IFLS_RX_SHIFT) | (IFLS_LVL_2_8th))
/*
@@ -440,11 +448,32 @@ uart_pl011_bus_param(struct uart_softc *sc, int ba
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)");
- sc->sc_rxfifosz = FIFO_RX_SIZE;
- sc->sc_txfifosz = FIFO_TX_SIZE;
+ /*
+ * 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.
+ */
+#ifdef FDT
+ is_bcm2835 = ofw_bus_is_compatible(sc->sc_dev, "brcm,bcm2835-pl011") ||
+ ofw_bus_is_compatible(sc->sc_dev, "broadcom,bcm2835-uart");
+#else
+ is_bcm2835 = false;
+#endif
+ hwrev = __uart_getreg(&sc->sc_bas, UART_PIDREG_2) >> 4;
+ if (hwrev <= 2 || is_bcm2835) {
+ sc->sc_rxfifosz = FIFO_RX_SIZE_R2;
+ sc->sc_txfifosz = FIFO_TX_SIZE_R2;
+ } else {
+ sc->sc_rxfifosz = FIFO_RX_SIZE_R3;
+ sc->sc_txfifosz = FIFO_TX_SIZE_R3;
+ }
return (0);
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1488936952.18764.63.camel>
