Skip site navigation (1)Skip section navigation (2)
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

--=-ftk80ddYYMvK4QgupW9h
Content-Type: text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding: 8bit

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

--=-ftk80ddYYMvK4QgupW9h
Content-Disposition: inline; filename="uart_pl011_fifosizes.diff"
Content-Type: text/x-patch; name="uart_pl011_fifosizes.diff"; charset="us-ascii"
Content-Transfer-Encoding: 7bit

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);
 }

--=-ftk80ddYYMvK4QgupW9h--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1488936952.18764.63.camel>