From patchwork Tue Jan 16 13:47:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 861571 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3zLWrB1dQnz9s1h for ; Wed, 17 Jan 2018 00:52:42 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id CE8E1C21E3A; Tue, 16 Jan 2018 13:50:11 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id F20D6C21DFA; Tue, 16 Jan 2018 13:48:55 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id D967EC21E1E; Tue, 16 Jan 2018 13:47:56 +0000 (UTC) Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by lists.denx.de (Postfix) with ESMTPS id 95438C21E16 for ; Tue, 16 Jan 2018 13:47:42 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 5E6F4AD0F; Tue, 16 Jan 2018 13:47:42 +0000 (UTC) From: Alexander Graf To: u-boot@lists.denx.de Date: Tue, 16 Jan 2018 14:47:39 +0100 Message-Id: <20180116134741.4103-6-agraf@suse.de> X-Mailer: git-send-email 2.12.3 In-Reply-To: <20180116134741.4103-1-agraf@suse.de> References: <20180116134741.4103-1-agraf@suse.de> Subject: [U-Boot] [PATCH 5/7] rpi: Properly detect which serial device is active X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Now that we have all infrastructure in place to dynamically determine whether a serial device is actually usable (read: routed to user accessible pins), we can wire it up to the board. This patch adds support to determine whether the pl011 or mini-uart or no serial is routed to the UART RX/TX pins on the Raspberry Pi family of boards. Signed-off-by: Alexander Graf --- board/raspberrypi/rpi/rpi.c | 69 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index a96d5d8952..b0cdad70f7 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -24,9 +24,16 @@ #include #endif #include +#include DECLARE_GLOBAL_DATA_PTR; +/* + * This is the GPIO pin that the user facing UART RX line is attached to. + * We use this pin to determine which serial device is available. + */ +#define BCM2835_GPIO_RX 15 + /* From lowlevel_init.S */ extern unsigned long fw_dtb_pointer; @@ -419,6 +426,68 @@ static void get_board_rev(void) printf("RPI %s (0x%x)\n", model->name, revision); } +/* + * We may get called before the device model is initialized, so we can not + * rely on the GPIO driver. + */ +int get_func_id(unsigned gpio) +{ + u32 val; + u32 node; + u32 *gpfsel; + fdt_addr_t addr; + fdt_size_t size; + + node = fdt_node_offset_by_compatible(gd->fdt_blob, -1, "brcm,bcm2835-gpio"); + if (node < 0) + return -EINVAL; + + addr = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, node, "reg", + 0, &size, true); + gpfsel = (void*)addr; + + val = readl(&gpfsel[BCM2835_GPIO_FSEL_BANK(gpio)]); + + return (val >> BCM2835_GPIO_FSEL_SHIFT(gpio) & BCM2835_GPIO_FSEL_MASK); +} + + +/* + * The RPi has 2 serial ports: A PL011 based one and the mini-uart. + * Depending on firmware configuration, either can be configured to either + * nothing, the wifi adapter or serial output. + * + * We only want to use the serial port that is user facing to not + * end up with a potentially unresponsive serial port. Due to this + * we need to check whether the serial device is actually connected + * to the UART RX/TX pins on the RPi GPIO pin bar. + * + * We only allow U-Boot to instantiate the serial driver for the serial + * device that is muxed correctly. + */ +int board_check_serial(struct udevice *dev) +{ + int func; + + printf("Checking serial %s\n", dev->name); + + if (device_is_compatible(dev, "arm,pl011")) { + func = BCM2835_GPIO_ALT0; + } else if (device_is_compatible(dev, "brcm,bcm2835-aux-uart")) { + func = BCM2835_GPIO_ALT5; + } else { + return 0; + } + + if (get_func_id(BCM2835_GPIO_RX) != func) { + printf("Disabling serial %s\n", dev->name); + return -ENODEV; + } + + printf("Enabling serial %s\n", dev->name); + return 0; +} + int board_init(void) { #ifdef CONFIG_HW_WATCHDOG