On 28 May 2016 at 14:54,  <[email protected]> wrote:
> From: Evan Lloyd <[email protected]>
>
> 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 <[email protected]>
> Signed-off-by: Evan Lloyd <[email protected]>

Tested on Juno R2 and FVP Foundation and AEMv8 models.

Tested-by: Ryan Harkin <[email protected]>
Reviewed-by: Ryan Harkin <[email protected]>


> ---
>  ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.c | 24 +++++++++++++++++++-
>  1 file changed, 23 insertions(+), 1 deletion(-)
>
> 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);
> --
> Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")
>
> _______________________________________________
> edk2-devel mailing list
> [email protected]
> https://lists.01.org/mailman/listinfo/edk2-devel
_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to