From patchwork Sat May 28 13:54:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evan Lloyd X-Patchwork-Id: 68796 Delivered-To: patch@linaro.org Received: by 10.140.92.199 with SMTP id b65csp593922qge; Sat, 28 May 2016 06:54:33 -0700 (PDT) X-Received: by 10.98.77.6 with SMTP id a6mr30904944pfb.133.1464443673546; Sat, 28 May 2016 06:54:33 -0700 (PDT) Return-Path: Received: from ml01.01.org (ml01.01.org. [2001:19d0:306:5::1]) by mx.google.com with ESMTPS id p11si36124434pag.115.2016.05.28.06.54.33 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 28 May 2016 06:54:33 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) client-ip=2001:19d0:306:5::1; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 2001:19d0:306:5::1 as permitted sender) smtp.mailfrom=edk2-devel-bounces@lists.01.org Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 8E9ED1A1FC3; Sat, 28 May 2016 06:54:35 -0700 (PDT) X-Original-To: edk2-devel@ml01.01.org Delivered-To: edk2-devel@ml01.01.org Received: from cam-smtp0.cambridge.arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 3717E1A1FB1 for ; Sat, 28 May 2016 06:54:33 -0700 (PDT) Received: from E107800.Emea.Arm.com (e107800.emea.arm.com [10.1.32.78]) by cam-smtp0.cambridge.arm.com (8.13.8/8.13.8) with ESMTP id u4SDsG6W001418 for ; Sat, 28 May 2016 14:54:19 +0100 From: evan.lloyd@arm.com To: edk2-devel@ml01.01.org Date: Sat, 28 May 2016 14:54:16 +0100 Message-Id: <1464443656-12108-7-git-send-email-evan.lloyd@arm.com> X-Mailer: git-send-email 2.8.0 In-Reply-To: <1464443656-12108-1-git-send-email-evan.lloyd@arm.com> References: <1464443656-12108-1-git-send-email-evan.lloyd@arm.com> Subject: [edk2] [PATCH 6/6] ArmPlatformPkg: Fix PL011 Glitches. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" From: Evan Lloyd This change corrects 3 problems in the PL011 driver. 1. The TRM states "The UARTLCR_H, UARTIBRD, and UARTFBRD registers must not be changed:...when the UART is enabled" 2. The TRM (3.3.8) describes logic requiring the UART to be disabled and flushed before adjusting UARTCR. 3. Several redundant calls get made to PL011UartInitializePort, where the characteristics do not change, but updating the registers can cause glitches in the output stream. The parameters are compared to the current state and no action taken if no change of state is required. Where an update is required, the specified logic is followed, and the register updates only made when the UART is disabled. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Sami Mujawar Signed-off-by: Evan Lloyd --- ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c | 24 +++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) -- Guid("CE165669-3EF3-493F-B85D-6190EE5B9759") _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel Tested-by: Ryan Harkin Reviewed-by: Ryan Harkin diff --git a/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c index 61b122a67ab7354714adb429e401126973ab6c8d..ec1abdd10c4ab2fdf59576af6eb3c92b8728d81a 100644 --- a/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c +++ b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c @@ -29,9 +29,11 @@ // STATIC CONST UINT32 mInvalidControlBits = EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE; -/* +/** Initialise the serial port to the specified settings. + The serial port is re-configured only if the specified settings + are different from the current settings. All unspecified settings will be set to the default values. @param UartBase The base address of the serial device. @@ -188,6 +190,26 @@ PL011UartInitializePort ( Integer = Divisor >> FRACTION_PART_SIZE_IN_BITS; Fractional = Divisor & FRACTION_PART_MASK; } + + // + // If PL011 is already initialized, check the current settings + // and re-initialize only if the settings are different. + // + if (((MmioRead32 (UartBase + UARTCR) & PL011_UARTCR_UARTEN) != 0) && + (MmioRead32 (UartBase + UARTLCR_H) == LineControl) && + (MmioRead32 (UartBase + UARTIBRD) == Integer) && + (MmioRead32 (UartBase + UARTFBRD) == Fractional)) { + // Nothing to do - already initialized with correct attributes + return RETURN_SUCCESS; + } + + // Wait for the end of transmission + while ((MmioRead32 (UartBase + UARTFR) & PL011_UARTFR_TXFE) == 0); + + // Disable UART: "The UARTLCR_H, UARTIBRD, and UARTFBRD registers must not be changed + // when the UART is enabled" + MmioWrite32 (UartBase + UARTCR, 0); + // Set Baud Rate Registers MmioWrite32 (UartBase + UARTIBRD, Integer); MmioWrite32 (UartBase + UARTFBRD, Fractional);