diff mbox

[edk2,v3,4/6] ArmPlatformPkg: Add support to configure PL011 UART clock

Message ID 20160615125243.1376-5-evan.lloyd@arm.com
State New
Headers show

Commit Message

Evan Lloyd June 15, 2016, 12:52 p.m. UTC
From: Evan Lloyd <evan.lloyd@arm.com>


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>

---

Notes:
    pl011_v3:
    - Added check on UartClkInHz parameter value [Ryan Harkin]

 ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf                   |  1 -
 ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf |  1 +
 ArmPlatformPkg/Include/Drivers/PL011Uart.h                       | 17 ++++++-----
 ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c                     | 25 ++++++++++++----
 ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c   | 30 +++++++++++---------
 5 files changed, 46 insertions(+), 28 deletions(-)

-- 
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
diff mbox

Patch

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 a4a6b4c0c0349eddaab2afab838bcd43b091aa16..36ea9d62696162460567d91f9c1ba245d830db71 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/Drivers/PL011Uart/PL011Uart.c b/ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c
index db15a8b322fe35aa3a21cd8f5cc123804c6d2fcd..3c283fdf33e1d64509de262638d4ca82af581161 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/Library/PL011SerialPortLib/PL011SerialPortLib.c b/ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.c
index 015f6fbb712c4ca6fbf20448d795dda41ad24e9c..5092a0a202fac18f8c1b7bdc6d4e904db0c0d585 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
+           );
 }
 
 /**