From patchwork Wed Jun 15 12:52:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evan Lloyd X-Patchwork-Id: 70109 Delivered-To: patch@linaro.org Received: by 10.140.106.246 with SMTP id e109csp2553859qgf; Wed, 15 Jun 2016 05:52:59 -0700 (PDT) X-Received: by 10.66.127.47 with SMTP id nd15mr3705477pab.74.1465995179031; Wed, 15 Jun 2016 05:52:59 -0700 (PDT) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id hf8si30725870pac.23.2016.06.15.05.52.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 15 Jun 2016 05:52:59 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 as permitted sender) client-ip=198.145.21.10; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of edk2-devel-bounces@lists.01.org designates 198.145.21.10 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 AF7371A1E48; Wed, 15 Jun 2016 05:53:17 -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 9E17C1A1E3F for ; Wed, 15 Jun 2016 05:53:15 -0700 (PDT) Received: from E107800.Emea.Arm.com (e107800.emea.arm.com [10.1.26.57]) by cam-smtp0.cambridge.arm.com (8.13.8/8.13.8) with ESMTP id u5FCqkuV020558; Wed, 15 Jun 2016 13:52:48 +0100 From: evan.lloyd@arm.com To: edk2-devel@ml01.01.org Date: Wed, 15 Jun 2016 13:52:43 +0100 Message-Id: <20160615125243.1376-7-evan.lloyd@arm.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20160615125243.1376-1-evan.lloyd@arm.com> References: <20160615125243.1376-1-evan.lloyd@arm.com> Subject: [edk2] [PATCH v3 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: , Cc: WoA-Tech , Laszlo Ersek , Leif Lindholm , Ard Biesheuvel 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 Tested-by: Ryan Harkin Reviewed-by: Ryan Harkin --- ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) -- Guid("CE165669-3EF3-493F-B85D-6190EE5B9759") _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel diff --git a/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c index 3c283fdf33e1d64509de262638d4ca82af581161..3748972acbfc80f1077b9b928756a72cc77b5c75 100644 --- a/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c +++ b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c @@ -32,6 +32,8 @@ 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. @@ -191,6 +193,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);