On 19 August 2015 at 08:56, Haojian Zhuang <[email protected]> wrote:
> Support multiple PL061 controllers. If platform gpio driver couldn't be found,
> PL061 gpio driver will continue to load PcdPL061GpioBase as the register base.
> It could be compatible with the use case of current PL061 gpio driver.
>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Haojian Zhuang <[email protected]>
> ---
>  ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c    | 137 
> +++++++++++++++------
>  .../Drivers/PL061GpioDxe/PL061GpioDxe.inf          |   1 +
>  ArmPlatformPkg/Include/Drivers/PL061Gpio.h         |  47 ++++---
>  3 files changed, 125 insertions(+), 60 deletions(-)
>
> diff --git a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c 
> b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c
> index 042fc76..02da8e1 100644
> --- a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c
> +++ b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c
> @@ -19,6 +19,7 @@
>  #include <Library/BaseMemoryLib.h>
>  #include <Library/DebugLib.h>
>  #include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
>  #include <Library/PcdLib.h>
>  #include <Library/UefiBootServicesTableLib.h>
>  #include <Library/UefiLib.h>
> @@ -28,6 +29,7 @@
>  #include <Drivers/PL061Gpio.h>
>
>  BOOLEAN     mPL061Initialized = FALSE;
> +PLATFORM_GPIO_CONTROLLER *mPL061PlatformGpio;
>
>  /**
>    Function implementations
> @@ -38,20 +40,36 @@ PL061Identify (
>    VOID
>    )
>  {
> -  // Check if this is a PrimeCell Peripheral
> -  if (    (MmioRead8 (PL061_GPIO_PCELL_ID0) != 0x0D)
> -      ||  (MmioRead8 (PL061_GPIO_PCELL_ID1) != 0xF0)
> -      ||  (MmioRead8 (PL061_GPIO_PCELL_ID2) != 0x05)
> -      ||  (MmioRead8 (PL061_GPIO_PCELL_ID3) != 0xB1)) {
> -    return EFI_NOT_FOUND;
> +  UINTN    Index;
> +  UINTN    RegisterBase;
> +
> +  if (   (mPL061PlatformGpio->GpioCount == 0)
> +      || (mPL061PlatformGpio->GpioControllerCount == 0)) {
> +     return EFI_NOT_FOUND;
>    }
>
> -  // Check if this PrimeCell Peripheral is the PL061 GPIO
> -  if (    (MmioRead8 (PL061_GPIO_PERIPH_ID0) != 0x61)
> -      ||  (MmioRead8 (PL061_GPIO_PERIPH_ID1) != 0x10)
> -      ||  ((MmioRead8 (PL061_GPIO_PERIPH_ID2) & 0xF) != 0x04)
> -      ||  (MmioRead8 (PL061_GPIO_PERIPH_ID3) != 0x00)) {
> -    return EFI_NOT_FOUND;
> +  for (Index = 0; Index < mPL061PlatformGpio->GpioControllerCount; Index++) {
> +    if (mPL061PlatformGpio->GpioController[Index].InternalGpioCount != 
> PL061_GPIO_PINS) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    RegisterBase = mPL061PlatformGpio->GpioController[Index].RegisterBase;
> +
> +    // Check if this is a PrimeCell Peripheral
> +    if (    (MmioRead8 (RegisterBase + PL061_GPIO_PCELL_ID0) != 0x0D)
> +        ||  (MmioRead8 (RegisterBase + PL061_GPIO_PCELL_ID1) != 0xF0)
> +        ||  (MmioRead8 (RegisterBase + PL061_GPIO_PCELL_ID2) != 0x05)
> +        ||  (MmioRead8 (RegisterBase + PL061_GPIO_PCELL_ID3) != 0xB1)) {
> +      return EFI_NOT_FOUND;
> +    }
> +
> +    // Check if this PrimeCell Peripheral is the PL061 GPIO
> +    if (    (MmioRead8 (RegisterBase + PL061_GPIO_PERIPH_ID0) != 0x61)
> +        ||  (MmioRead8 (RegisterBase + PL061_GPIO_PERIPH_ID1) != 0x10)
> +        ||  ((MmioRead8 (RegisterBase + PL061_GPIO_PERIPH_ID2) & 0xF) != 
> 0x04)
> +        ||  (MmioRead8 (RegisterBase + PL061_GPIO_PERIPH_ID3) != 0x00)) {
> +      return EFI_NOT_FOUND;
> +    }
>    }
>
>    return EFI_SUCCESS;
> @@ -84,6 +102,31 @@ PL061Initialize (
>    return Status;
>  }
>
> +EFI_STATUS
> +EFIAPI
> +PL061Locate (
> +  IN  EMBEDDED_GPIO_PIN Gpio,
> +  OUT UINTN             *ControllerIndex,
> +  OUT UINTN             *ControllerOffset,
> +  OUT UINTN             *RegisterBase
> +  )
> +{
> +  UINT32    Index;
> +
> +  for (Index = 0; Index < mPL061PlatformGpio->GpioControllerCount; Index++) {
> +    if (    (Gpio >= mPL061PlatformGpio->GpioController[Index].GpioIndex)
> +        &&  (Gpio < mPL061PlatformGpio->GpioController[Index].GpioIndex
> +             + mPL061PlatformGpio->GpioController[Index].InternalGpioCount)) 
> {
> +      *ControllerIndex = Index;
> +      *ControllerOffset = Gpio % 
> mPL061PlatformGpio->GpioController[Index].InternalGpioCount;
> +      *RegisterBase = mPL061PlatformGpio->GpioController[Index].RegisterBase;
> +      return EFI_SUCCESS;
> +    }
> +  }
> +  DEBUG ((EFI_D_ERROR, "%a, failed to locate gpio %d\n", __func__, Gpio));
> +  return EFI_INVALID_PARAMETER;
> +}
> +
>  /**
>
>  Routine Description:
> @@ -110,11 +153,15 @@ Get (
>    )
>  {
>    EFI_STATUS    Status = EFI_SUCCESS;
> +  UINTN         Index, Offset, RegisterBase;
>
> -  if (    (Value == NULL)
> -      ||  (Gpio > LAST_GPIO_PIN))
> -  {
> -    return EFI_INVALID_PARAMETER;
> +  Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase);
> +  if (EFI_ERROR (Status))
> +    goto EXIT;
> +
> +  if (Value == NULL) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto EXIT;
>    }
>
>    // Initialize the hardware if not already done
> @@ -125,7 +172,7 @@ Get (
>      }
>    }
>
> -  if (MmioRead8 (PL061_GPIO_DATA_REG + (GPIO_PIN_MASK(Gpio) << 2))) {
> +  if (MmioRead8 (RegisterBase + PL061_GPIO_DATA_REG + (GPIO_PIN_MASK(Offset) 
> << 2))) {

As per my comment on [PATCH 1/3], I think this should be a "|" for the
mask, not a "+".  So I think exra brackets would make sense here too:

+  if (MmioRead8 ((RegisterBase + PL061_GPIO_DATA_REG) |
(GPIO_PIN_MASK(Offset) << 2))) {

I appreciate that the original code was using a "+", but I don't think
it should have.

There are a few more later in this patch that should be changed too.


>      *Value = 1;
>    } else {
>      *Value = 0;
> @@ -162,12 +209,11 @@ Set (
>    )
>  {
>    EFI_STATUS    Status = EFI_SUCCESS;
> +  UINTN         Index, Offset, RegisterBase;
>
> -  // Check for errors
> -  if (Gpio > LAST_GPIO_PIN) {
> -    Status = EFI_INVALID_PARAMETER;
> +  Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase);
> +  if (EFI_ERROR (Status))
>      goto EXIT;
> -  }
>
>    // Initialize the hardware if not already done
>    if (!mPL061Initialized) {
> @@ -181,21 +227,21 @@ Set (
>    {
>      case GPIO_MODE_INPUT:
>        // Set the corresponding direction bit to LOW for input
> -      MmioAnd8 (PL061_GPIO_DIR_REG, ~GPIO_PIN_MASK(Gpio));
> +      MmioAnd8 (RegisterBase + PL061_GPIO_DIR_REG, ~GPIO_PIN_MASK(Gpio));
>        break;
>
>      case GPIO_MODE_OUTPUT_0:
>        // Set the corresponding data bit to LOW for 0
> -      MmioWrite8 (PL061_GPIO_DATA_REG + (GPIO_PIN_MASK(Gpio) << 2), 0);
> +      MmioWrite8 (RegisterBase + PL061_GPIO_DATA_REG + 
> (GPIO_PIN_MASK(Offset) << 2), 0);
>        // Set the corresponding direction bit to HIGH for output
> -      MmioOr8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK(Gpio));
> +      MmioOr8 (RegisterBase + PL061_GPIO_DIR_REG, GPIO_PIN_MASK(Offset));
>        break;
>
>      case GPIO_MODE_OUTPUT_1:
>        // Set the corresponding data bit to HIGH for 1
> -      MmioWrite8 (PL061_GPIO_DATA_REG + (GPIO_PIN_MASK(Gpio) << 2), 0xff);
> +      MmioWrite8 (RegisterBase + PL061_GPIO_DATA_REG + 
> (GPIO_PIN_MASK(Offset) << 2), 0xff);
>        // Set the corresponding direction bit to HIGH for output
> -      MmioOr8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK(Gpio));
> +      MmioOr8 (RegisterBase + PL061_GPIO_DIR_REG, GPIO_PIN_MASK(Offset));
>        break;
>
>      default:
> @@ -233,13 +279,12 @@ GetMode (
>    OUT EMBEDDED_GPIO_MODE  *Mode
>    )
>  {
> -  EFI_STATUS Status;
> +  EFI_STATUS    Status;
> +  UINTN         Index, Offset, RegisterBase;
>
> -  // Check for errors
> -  if (    (Mode == NULL)
> -      ||  (Gpio > LAST_GPIO_PIN)) {
> -    return EFI_INVALID_PARAMETER;
> -  }
> +  Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase);
> +  if (EFI_ERROR (Status))
> +    return Status;
>
>    // Initialize the hardware if not already done
>    if (!mPL061Initialized) {
> @@ -250,9 +295,9 @@ GetMode (
>    }
>
>    // Check if it is input or output
> -  if (MmioRead8 (PL061_GPIO_DIR_REG) & GPIO_PIN_MASK(Gpio)) {
> +  if (MmioRead8 (RegisterBase + PL061_GPIO_DIR_REG) & GPIO_PIN_MASK(Offset)) 
> {
>      // Pin set to output
> -    if (MmioRead8 (PL061_GPIO_DATA_REG + (GPIO_PIN_MASK(Gpio) << 2))) {
> +    if (MmioRead8 (RegisterBase + PL061_GPIO_DATA_REG + 
> (GPIO_PIN_MASK(Offset) << 2))) {
>        *Mode = GPIO_MODE_OUTPUT_1;
>      } else {
>        *Mode = GPIO_MODE_OUTPUT_0;
> @@ -321,14 +366,34 @@ PL061InstallProtocol (
>    IN EFI_SYSTEM_TABLE   *SystemTable
>    )
>  {
> -  EFI_STATUS  Status;
> -  EFI_HANDLE  Handle;
> +  EFI_STATUS            Status;
> +  EFI_HANDLE            Handle;
> +  GPIO_CONTROLLER       *GpioController;
>
>    //
>    // Make sure the Gpio protocol has not been installed in the system yet.
>    //
>    ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEmbeddedGpioProtocolGuid);
>
> +  Status = gBS->LocateProtocol (&gPlatformGpioProtocolGuid, NULL, (VOID 
> **)&mPL061PlatformGpio);
> +  if (EFI_ERROR (Status) && (Status == EFI_NOT_FOUND)) {
> +    // Create the mPL061PlatformGpio
> +    mPL061PlatformGpio = (PLATFORM_GPIO_CONTROLLER *)AllocateZeroPool 
> (sizeof (PLATFORM_GPIO_CONTROLLER) + sizeof (GPIO_CONTROLLER));
> +    if (mPL061PlatformGpio == NULL) {
> +      DEBUG ((EFI_D_ERROR, "%a: failed to allocate 
> PLATFORM_GPIO_CONTROLLER\n", __func__));
> +      return EFI_BAD_BUFFER_SIZE;
> +    }
> +
> +    mPL061PlatformGpio->GpioCount = PL061_GPIO_PINS;
> +    mPL061PlatformGpio->GpioControllerCount = 1;
> +    mPL061PlatformGpio->GpioController = (GPIO_CONTROLLER *)((UINTN) 
> mPL061PlatformGpio + sizeof (PLATFORM_GPIO_CONTROLLER));
> +
> +    GpioController = mPL061PlatformGpio->GpioController;
> +    GpioController->RegisterBase = (UINTN) PcdGet32 (PcdPL061GpioBase);
> +    GpioController->GpioIndex = 0;
> +    GpioController->InternalGpioCount = PL061_GPIO_PINS;
> +  }
> +
>    // Install the Embedded GPIO Protocol onto a new handle
>    Handle = NULL;
>    Status = gBS->InstallMultipleProtocolInterfaces(
> diff --git a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf 
> b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
> index 9d9e4cd..405a3a9 100644
> --- a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
> +++ b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf
> @@ -45,6 +45,7 @@
>
>  [Protocols]
>    gEmbeddedGpioProtocolGuid
> +  gPlatformGpioProtocolGuid
>
>  [Depex]
>    TRUE
> diff --git a/ArmPlatformPkg/Include/Drivers/PL061Gpio.h 
> b/ArmPlatformPkg/Include/Drivers/PL061Gpio.h
> index d436fd4..356428a 100644
> --- a/ArmPlatformPkg/Include/Drivers/PL061Gpio.h
> +++ b/ArmPlatformPkg/Include/Drivers/PL061Gpio.h
> @@ -19,30 +19,29 @@
>  #include <Protocol/EmbeddedGpio.h>
>
>  // PL061 GPIO Registers
> -#define PL061_GPIO_DATA_REG             ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0x000)
> -#define PL061_GPIO_DIR_REG              ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0x400)
> -#define PL061_GPIO_IS_REG               ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0x404)
> -#define PL061_GPIO_IBE_REG              ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0x408)
> -#define PL061_GPIO_IEV_REG              ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0x40C)
> -#define PL061_GPIO_IE_REG               ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0x410)
> -#define PL061_GPIO_RIS_REG              ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0x414)
> -#define PL061_GPIO_MIS_REG              ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0x410)
> -#define PL061_GPIO_IC_REG               ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0x41C)
> -#define PL061_GPIO_AFSEL_REG            ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0x420)
> -
> -#define PL061_GPIO_PERIPH_ID0           ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0xFE0)
> -#define PL061_GPIO_PERIPH_ID1           ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0xFE4)
> -#define PL061_GPIO_PERIPH_ID2           ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0xFE8)
> -#define PL061_GPIO_PERIPH_ID3           ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0xFEC)
> -
> -#define PL061_GPIO_PCELL_ID0            ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0xFF0)
> -#define PL061_GPIO_PCELL_ID1            ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0xFF4)
> -#define PL061_GPIO_PCELL_ID2            ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0xFF8)
> -#define PL061_GPIO_PCELL_ID3            ((UINT32)PcdGet32 (PcdPL061GpioBase) 
> + 0xFFC)
> -
> -
> -// GPIO pins are numbered 0..7
> -#define LAST_GPIO_PIN                   7
> +#define PL061_GPIO_DATA_REG             0x000
> +#define PL061_GPIO_DIR_REG              0x400
> +#define PL061_GPIO_IS_REG               0x404
> +#define PL061_GPIO_IBE_REG              0x408
> +#define PL061_GPIO_IEV_REG              0x40C
> +#define PL061_GPIO_IE_REG               0x410
> +#define PL061_GPIO_RIS_REG              0x414
> +#define PL061_GPIO_MIS_REG              0x410
> +#define PL061_GPIO_IC_REG               0x41C
> +#define PL061_GPIO_AFSEL_REG            0x420
> +
> +#define PL061_GPIO_PERIPH_ID0           0xFE0
> +#define PL061_GPIO_PERIPH_ID1           0xFE4
> +#define PL061_GPIO_PERIPH_ID2           0xFE8
> +#define PL061_GPIO_PERIPH_ID3           0xFEC
> +
> +#define PL061_GPIO_PCELL_ID0            0xFF0
> +#define PL061_GPIO_PCELL_ID1            0xFF4
> +#define PL061_GPIO_PCELL_ID2            0xFF8
> +#define PL061_GPIO_PCELL_ID3            0xFFC
> +
> +
> +#define PL061_GPIO_PINS                 8
>
>  // All bits low except one bit high, native bit length
>  #define GPIO_PIN_MASK(Pin)              (1UL << ((UINTN)(Pin)))
> --
> 2.1.4
>
> _______________________________________________
> 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