From patchwork Sat May 28 13:54:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Evan Lloyd X-Patchwork-Id: 68794 Delivered-To: patch@linaro.org Received: by 10.140.92.199 with SMTP id b65csp593898qge; Sat, 28 May 2016 06:54:29 -0700 (PDT) X-Received: by 10.66.132.37 with SMTP id or5mr31074043pab.144.1464443669327; Sat, 28 May 2016 06:54:29 -0700 (PDT) Return-Path: Received: from ml01.01.org (ml01.01.org. [198.145.21.10]) by mx.google.com with ESMTPS id r4si36097356paa.218.2016.05.28.06.54.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 28 May 2016 06:54:29 -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 04DBD1A1FBC; 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 A1C5A1A1FAE for ; Sat, 28 May 2016 06:54:32 -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 u4SDsG6U001418 for ; Sat, 28 May 2016 14:54:18 +0100 From: evan.lloyd@arm.com To: edk2-devel@ml01.01.org Date: Sat, 28 May 2016 14:54:14 +0100 Message-Id: <1464443656-12108-5-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 4/6] ArmPlatformPkg: Add support to configure PL011 UART clock 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 On some platforms the UART clock is not the same for all the serial ports. The PL011 driver must be capable of handling serial ports with different clock rates, so must not rely on a PCD for the clock rate. This patch allows the UART clock rate to be passed as a parameter to PL011UartInitializePort(), which is called from the serial port library. This patch also contains the corresponding changes in the serial port library. The PCD in Drivers/PL011Uart is replaced by an extra parameter for PL011UartInitializePort. The PCD is moved to Library/PL011SerialPortLib to supply the value to pass. A corresponding patch to ArmVirtPkg is included in the same bundle to align that with these changes. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Sami Mujawar Signed-off-by: Evan Lloyd --- ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf | 1 - ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf | 1 + ArmPlatformPkg/Include/Drivers/PL011Uart.h | 43 ++++++++++++-------- ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c | 22 +++++++--- ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c | 30 +++++++------- 5 files changed, 60 insertions(+), 37 deletions(-) -- 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 diff --git a/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf index 5afce36d3935e7fd79c25c46360d72328b2a571f..0154f3bd2e3a3ab930227bde8e45d5e13eaf92ae 100644 --- a/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf +++ b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf @@ -37,6 +37,5 @@ [Packages] [FixedPcd] gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate - gArmPlatformTokenSpaceGuid.PL011UartClkInHz gArmPlatformTokenSpaceGuid.PL011UartInteger gArmPlatformTokenSpaceGuid.PL011UartFractional diff --git a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf index 653c0b2dfc147f1d82155e4150812f0cb4c59e12..3683e06d27e1a084ba493b0bdf1bec4c0e8f117a 100644 --- a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf +++ b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf @@ -41,3 +41,4 @@ [FixedPcd] gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits + gArmPlatformTokenSpaceGuid.PL011UartClkInHz diff --git a/ArmPlatformPkg/Include/Drivers/PL011Uart.h b/ArmPlatformPkg/Include/Drivers/PL011Uart.h index 8c2616ede4131b7504088d656160ce184dadf914..6a97174c82fa8d3153af1327060a98e3b66a8a45 100644 --- a/ArmPlatformPkg/Include/Drivers/PL011Uart.h +++ b/ArmPlatformPkg/Include/Drivers/PL011Uart.h @@ -89,32 +89,43 @@ #define PL011_UARTPID2_VER(X) (((X) >> 4) & 0xF) #define PL011_VER_R1P4 0x2 -/* +/** Initialise the serial port to the specified settings. - Programmed hardware of Serial port. - @param UartBase The base address of the serial device. - @param BaudRate The baud rate of the serial device. If the baud rate is not supported, - the speed will be reduced down to the nearest supported one and the + All unspecified settings will be set to the default values. + + @param[in] UartBase The base address of the serial device. + @param[in] UartClkInHz The clock in Hz for the serial device. + Ignored if the PCD PL011UartInteger is not 0 + @param[in out] BaudRate The baud rate of the serial device. If the + baud rate is not supported, the speed will be + reduced to the nearest supported one and the variable's value will be updated accordingly. - @param ReceiveFifoDepth The number of characters the device will buffer on input. - ReceiveFifoDepth value of 0 will use the device's default FIFO depth. - @param Parity If applicable, this is the EFI_PARITY_TYPE that is computed or checked - as each character is transmitted or received. If the device does not - support parity, the value is the default parity value. - @param DataBits The number of data bits in each character - @param StopBits If applicable, the EFI_STOP_BITS_TYPE number of stop bits per character. - If the device does not support stop bits, the value is the default stop - bit value. + @param[in out] ReceiveFifoDepth The number of characters the device will + buffer on input. Value of 0 will use the + device's default FIFO depth. + @param[in out] Parity If applicable, this is the EFI_PARITY_TYPE + that is computed or checked as each character + is transmitted or received. If the device does + not support parity, the value is the default + parity value. + @param[in out] DataBits The number of data bits in each character. + @param[in out] StopBits If applicable, the EFI_STOP_BITS_TYPE number + of stop bits per character. + If the device does not support stop bits, the + value is the default stop bit value. - @retval RETURN_SUCCESS All attributes were set correctly on the serial device. - @retval RETURN_INVALID_PARAMETER One or more of the attributes has an unsupported value. + @retval RETURN_SUCCESS All attributes were set correctly on the + serial device. + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an + unsupported value. **/ RETURN_STATUS EFIAPI PL011UartInitializePort ( IN UINTN UartBase, + IN UINT32 UartClkInHz, IN OUT UINT64 *BaudRate, IN OUT UINT32 *ReceiveFifoDepth, IN OUT EFI_PARITY_TYPE *Parity, diff --git a/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c index dd5f88d3d629d345a50af468ed394a269b35f52a..61b122a67ab7354714adb429e401126973ab6c8d 100644 --- a/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c +++ b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c @@ -35,6 +35,8 @@ STATIC CONST UINT32 mInvalidControlBits = EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE; All unspecified settings will be set to the default values. @param UartBase The base address of the serial device. + @param UartClkInHz The clock in Hz for the serial device. + Ignored if the PCD PL011UartInteger is not 0 @param BaudRate The baud rate of the serial device. If the baud rate is not supported, the speed will be reduced to the nearest supported one and the @@ -63,6 +65,7 @@ RETURN_STATUS EFIAPI PL011UartInitializePort ( IN UINTN UartBase, + IN UINT32 UartClkInHz, IN OUT UINT64 *BaudRate, IN OUT UINT32 *ReceiveFifoDepth, IN OUT EFI_PARITY_TYPE *Parity, @@ -72,6 +75,8 @@ PL011UartInitializePort ( { UINT32 LineControl; UINT32 Divisor; + UINT32 Integer; + UINT32 Fractional; // The PL011 supports a buffer of 1, 16 or 32 chars. Therefore we can accept // 1 char buffer as the minimum FIFO size. Because everything can be rounded @@ -168,19 +173,24 @@ PL011UartInitializePort ( // If PL011 Integer value has been defined then always ignore the BAUD rate if (FixedPcdGet32 (PL011UartInteger) != 0) { - MmioWrite32 (UartBase + UARTIBRD, FixedPcdGet32 (PL011UartInteger)); - MmioWrite32 (UartBase + UARTFBRD, FixedPcdGet32 (PL011UartFractional)); + Integer = FixedPcdGet32 (PL011UartInteger); + Fractional = FixedPcdGet32 (PL011UartFractional); } else { // If BAUD rate is zero then replace it with the system default value if (*BaudRate == 0) { *BaudRate = FixedPcdGet32 (PcdSerialBaudRate); - ASSERT (*BaudRate != 0); + if (*BaudRate == 0) { + return RETURN_INVALID_PARAMETER; + } } - Divisor = (FixedPcdGet32 (PL011UartClkInHz) * 4) / *BaudRate; - MmioWrite32 (UartBase + UARTIBRD, Divisor >> FRACTION_PART_SIZE_IN_BITS); - MmioWrite32 (UartBase + UARTFBRD, Divisor & FRACTION_PART_MASK); + Divisor = (UartClkInHz * 4) / *BaudRate; + Integer = Divisor >> FRACTION_PART_SIZE_IN_BITS; + Fractional = Divisor & FRACTION_PART_MASK; } + // Set Baud Rate Registers + MmioWrite32 (UartBase + UARTIBRD, Integer); + MmioWrite32 (UartBase + UARTFBRD, Fractional); // No parity, 1 stop, no fifo, 8 data bits MmioWrite32 (UartBase + UARTLCR_H, LineControl); diff --git a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c index 9c998a63cfe4e1506e6c1f0aa25ab6566f6dbf65..b3dea6b3aca91b3bc7a296c28a02aaa6593e4cf2 100644 --- a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c +++ b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c @@ -50,13 +50,14 @@ SerialPortInitialize ( StopBits = (EFI_STOP_BITS_TYPE) FixedPcdGet8 (PcdUartDefaultStopBits); return PL011UartInitializePort ( - (UINTN)FixedPcdGet64 (PcdSerialRegisterBase), - &BaudRate, - &ReceiveFifoDepth, - &Parity, - &DataBits, - &StopBits - ); + (UINTN)FixedPcdGet64 (PcdSerialRegisterBase), + FixedPcdGet32 (PL011UartClkInHz), + &BaudRate, + &ReceiveFifoDepth, + &Parity, + &DataBits, + &StopBits + ); } /** @@ -150,13 +151,14 @@ SerialPortSetAttributes ( ) { return PL011UartInitializePort ( - (UINTN)FixedPcdGet64 (PcdSerialRegisterBase), - BaudRate, - ReceiveFifoDepth, - Parity, - DataBits, - StopBits - ); + (UINTN)FixedPcdGet64 (PcdSerialRegisterBase), + FixedPcdGet32 (PL011UartClkInHz), + BaudRate, + ReceiveFifoDepth, + Parity, + DataBits, + StopBits + ); } /**