summaryrefslogtreecommitdiffstats
path: root/ArmPlatformPkg
diff options
context:
space:
mode:
authorEvan Lloyd <evan.lloyd@arm.com>2016-06-15 13:52:41 +0100
committerArd Biesheuvel <ard.biesheuvel@linaro.org>2016-06-15 16:15:50 +0200
commitf63005282cc59f76b050c0be0813345cf7d54171 (patch)
tree1586901911d4f742016afa76ee405fe01bbf7c69 /ArmPlatformPkg
parentca0aad698212bed2b65b4569cfeabcf7f0a7e88a (diff)
downloadedk2-f63005282cc59f76b050c0be0813345cf7d54171.tar.gz
edk2-f63005282cc59f76b050c0be0813345cf7d54171.tar.bz2
edk2-f63005282cc59f76b050c0be0813345cf7d54171.zip
ArmPlatformPkg: Add support to configure PL011 UART clock
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 <sami.mujawar@arm.com> Signed-off-by: Evan Lloyd <evan.lloyd@arm.com> Tested-by: Ryan Harkin <ryan.harkin@linaro.org>
Diffstat (limited to 'ArmPlatformPkg')
-rw-r--r--ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c25
-rw-r--r--ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf1
-rw-r--r--ArmPlatformPkg/Include/Drivers/PL011Uart.h17
-rw-r--r--ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c30
-rw-r--r--ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf1
5 files changed, 46 insertions, 28 deletions
diff --git a/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c
index db15a8b322..3c283fdf33 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,27 @@ 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;
+ }
+ }
+ if (0 == UartClkInHz) {
+ 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/Drivers/PL011Uart/PL011Uart.inf b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
index 5afce36d39..0154f3bd2e 100644
--- a/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
+++ b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
@@ -37,6 +37,5 @@
[FixedPcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate
- gArmPlatformTokenSpaceGuid.PL011UartClkInHz
gArmPlatformTokenSpaceGuid.PL011UartInteger
gArmPlatformTokenSpaceGuid.PL011UartFractional
diff --git a/ArmPlatformPkg/Include/Drivers/PL011Uart.h b/ArmPlatformPkg/Include/Drivers/PL011Uart.h
index a4a6b4c0c0..36ea9d6269 100644
--- a/ArmPlatformPkg/Include/Drivers/PL011Uart.h
+++ b/ArmPlatformPkg/Include/Drivers/PL011Uart.h
@@ -89,26 +89,28 @@
#define PL011_UARTPID2_VER(X) (((X) >> 4) & 0xF)
#define PL011_VER_R1P4 0x2
-/*
+/**
Initialise the serial port to the specified settings.
All unspecified settings will be set to the default values.
- @param UartBase The base address of the serial device.
- @param BaudRate The baud rate of the serial device. If the
+ @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
+ @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 Parity If applicable, this is the EFI_PARITY_TYPE
+ @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 DataBits The number of data bits in each character.
- @param StopBits If applicable, the EFI_STOP_BITS_TYPE number
+ @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.
@@ -123,6 +125,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,
diff --git a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c
index 015f6fbb71..5092a0a202 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
+ );
}
/**
@@ -158,13 +159,14 @@ SerialPortSetAttributes (
)
{
return PL011UartInitializePort (
- (UINTN)FixedPcdGet64 (PcdSerialRegisterBase),
- BaudRate,
- ReceiveFifoDepth,
- Parity,
- DataBits,
- StopBits
- );
+ (UINTN)FixedPcdGet64 (PcdSerialRegisterBase),
+ FixedPcdGet32 (PL011UartClkInHz),
+ BaudRate,
+ ReceiveFifoDepth,
+ Parity,
+ DataBits,
+ StopBits
+ );
}
/**
diff --git a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
index 653c0b2dfc..3683e06d27 100644
--- a/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
+++ b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
@@ -41,3 +41,4 @@
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
+ gArmPlatformTokenSpaceGuid.PL011UartClkInHz