On Mon, Mar 14, 2016 at 01:30:37PM +0800, Haojian Zhuang 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.
The content looks fine. There are two whitespace errors, which are picked up by BaseTools/Scripts/PatchCheck.py. Now, given that I've already been a pain over this set, I don't mind fixing it up on commit, but it's worth integrating this step into your workflow. Reviewed-by: Leif Lindholm <[email protected]> (Already pushed.) > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Haojian Zhuang <[email protected]> > --- > ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c | 141 > ++++++++++++++++----- > .../Drivers/PL061GpioDxe/PL061GpioDxe.inf | 1 + > ArmPlatformPkg/Include/Drivers/PL061Gpio.h | 46 ++++--- > 3 files changed, 129 insertions(+), 59 deletions(-) > > diff --git a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c > b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c > index 38341a3..59d615d 100644 > --- a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c > +++ b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c > @@ -20,6 +20,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,33 @@ > #include <Protocol/EmbeddedGpio.h> > #include <Drivers/PL061Gpio.h> > > +PLATFORM_GPIO_CONTROLLER *mPL061PlatformGpio; > + > +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; > +} > + > // > // The PL061 is a strange beast. The 8-bit data register is aliased across a > // region 0x400 bytes in size, with bits [9:2] of the address operating as a > @@ -88,20 +116,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; > @@ -132,13 +176,17 @@ Get ( > OUT UINTN *Value > ) > { > - if ( (Value == NULL) > - || (Gpio > LAST_GPIO_PIN)) > - { > + EFI_STATUS Status = EFI_SUCCESS; > + UINTN Index, Offset, RegisterBase; > + > + Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase); > + ASSERT_EFI_ERROR (Status); > + > + if (Value == NULL) { > return EFI_INVALID_PARAMETER; > } > > - if (PL061GetPins (PL061_GPIO_DATA_REG, Gpio)) { > + if (PL061GetPins (RegisterBase + PL061_GPIO_DATA_REG, Offset)) { > *Value = 1; > } else { > *Value = 0; > @@ -174,41 +222,39 @@ Set ( > ) > { > EFI_STATUS Status = EFI_SUCCESS; > + UINTN Index, Offset, RegisterBase; > > - // Check for errors > - if (Gpio > LAST_GPIO_PIN) { > - Status = EFI_INVALID_PARAMETER; > - goto EXIT; > - } > + Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase); > + ASSERT_EFI_ERROR (Status); > > switch (Mode) > { > case GPIO_MODE_INPUT: > // Set the corresponding direction bit to LOW for input > - MmioAnd8 (PL061_GPIO_DIR_REG, ~GPIO_PIN_MASK(Gpio) & 0xFF); > + MmioAnd8 (RegisterBase + PL061_GPIO_DIR_REG, > + ~GPIO_PIN_MASK(Offset) & 0xFF); > break; > > case GPIO_MODE_OUTPUT_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)); > // Set the corresponding data bit to LOW for 0 > - PL061SetPins (PL061_GPIO_DATA_REG, GPIO_PIN_MASK(Gpio), 0); > + PL061SetPins (RegisterBase + PL061_GPIO_DATA_REG, > GPIO_PIN_MASK(Offset), 0); > break; > > case GPIO_MODE_OUTPUT_1: > // 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)); > // Set the corresponding data bit to HIGH for 1 > - PL061SetPins (PL061_GPIO_DATA_REG, GPIO_PIN_MASK(Gpio), 0xff); > - break; > + PL061SetPins (RegisterBase + PL061_GPIO_DATA_REG, > GPIO_PIN_MASK(Offset), 0xff); > + break; > > default: > // Other modes are not supported > return EFI_UNSUPPORTED; > } > > -EXIT: > - return Status; > + return EFI_SUCCESS; > } > > /** > @@ -237,16 +283,21 @@ GetMode ( > OUT EMBEDDED_GPIO_MODE *Mode > ) > { > + EFI_STATUS Status = EFI_SUCCESS; > + UINTN Index, Offset, RegisterBase; > + > + Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase); > + ASSERT_EFI_ERROR (Status); > + > // Check for errors > - if ( (Mode == NULL) > - || (Gpio > LAST_GPIO_PIN)) { > + if (Mode == NULL) { > return EFI_INVALID_PARAMETER; > } > > // 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 (PL061GetPins (PL061_GPIO_DATA_REG, GPIO_PIN_MASK(Gpio))) { > + if (PL061GetPins (RegisterBase + PL061_GPIO_DATA_REG, > GPIO_PIN_MASK(Offset))) { > *Mode = GPIO_MODE_OUTPUT_1; > } else { > *Mode = GPIO_MODE_OUTPUT_0; > @@ -315,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; > + } > + > Status = PL061Identify(); > if (EFI_ERROR(Status)) { > return EFI_DEVICE_ERROR; > 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 8fde2bb..308f69f 100644 > --- a/ArmPlatformPkg/Include/Drivers/PL061Gpio.h > +++ b/ArmPlatformPkg/Include/Drivers/PL061Gpio.h > @@ -20,30 +20,28 @@ > > // PL061 GPIO Registers > #define PL061_GPIO_DATA_REG_OFFSET ((UINTN) 0x000) > -#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))) > -- > 1.9.1 > _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

