X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=ArmPlatformPkg%2FDrivers%2FPL061GpioDxe%2FPL061Gpio.c;h=c8125fd0e08f261af88e9642f735690bb33ac29d;hp=0e263c03a779f392ab721ad24fadad08c8d78a5c;hb=2a77a37ea43d8269a4320301e2f77b45f59a3ac1;hpb=5a62a8b7f19019e7aa8d26d30ed7b7a22fc2a6d0 diff --git a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c index 0e263c03a7..c8125fd0e0 100644 --- a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c +++ b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c @@ -1,347 +1,318 @@ -/** @file -* -* Copyright (c) 2011, ARM Limited. All rights reserved. -* -* This program and the accompanying materials -* are licensed and made available under the terms and conditions of the BSD License -* which accompanies this distribution. The full text of the license may be found at -* http://opensource.org/licenses/bsd-license.php -* -* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -* -**/ - - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define LOW_4_BITS 0x0000000F - -BOOLEAN mPL061Initialized = FALSE; - -/** - Function implementations -**/ - -EFI_STATUS -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; - } - - // 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 ) & LOW_4_BITS ) != 0x04 ) - || ( MmioRead8( PL061_GPIO_PERIPH_ID3 ) != 0x00 ) ) { - return EFI_NOT_FOUND; - } - - return EFI_SUCCESS; -} - -EFI_STATUS -PL061Initialize ( -VOID - ) -{ - EFI_STATUS Status; - - // Check if the PL061 GPIO module exists on board - Status = PL061Identify(); - if (EFI_ERROR( Status )) { - Status = EFI_DEVICE_ERROR; - goto EXIT; - } - - // Do other hardware initialisation things here as required - - // Disable Interrupts - //if( MmioRead8( PL061_GPIO_IE_REG ) != 0 ) { - // // Ensure interrupts are disabled - //} - - mPL061Initialized = TRUE; - - EXIT: - return Status; -} - -/** - -Routine Description: - - Gets the state of a GPIO pin - -Arguments: - - This - pointer to protocol - Gpio - which pin to read - Value - state of the pin - -Returns: - - EFI_SUCCESS - GPIO state returned in Value - EFI_INVALID_PARAMETER - Value is NULL pointer or Gpio pin is out of range -**/ -EFI_STATUS -EFIAPI -Get ( - IN EMBEDDED_GPIO *This, - IN EMBEDDED_GPIO_PIN Gpio, - OUT UINTN *Value - ) -{ - EFI_STATUS Status = EFI_SUCCESS; - - if( ( Value == NULL ) - || ( Gpio > LAST_GPIO_PIN ) ) - { - return EFI_INVALID_PARAMETER; - } - - // Initialize the hardware if not already done - if( !mPL061Initialized ) { - Status = PL061Initialize(); - if( EFI_ERROR(Status) ) { - goto EXIT; - } - } - - if( MmioRead8( PL061_GPIO_DATA_REG ) & GPIO_PIN_MASK_HIGH_8BIT(Gpio) ) { - *Value = 1; - } else { - *Value = 0; - } - - EXIT: - return Status; -} - -/** - -Routine Description: - - Sets the state of a GPIO pin - -Arguments: - - This - pointer to protocol - Gpio - which pin to modify - Mode - mode to set - -Returns: - - EFI_SUCCESS - GPIO set as requested - EFI_UNSUPPORTED - Mode is not supported - EFI_INVALID_PARAMETER - Gpio pin is out of range -**/ -EFI_STATUS -EFIAPI -Set ( - IN EMBEDDED_GPIO *This, - IN EMBEDDED_GPIO_PIN Gpio, - IN EMBEDDED_GPIO_MODE Mode - ) -{ - EFI_STATUS Status = EFI_SUCCESS; - - // Check for errors - if( Gpio > LAST_GPIO_PIN ) { - Status = EFI_INVALID_PARAMETER; - goto EXIT; - } - - // Initialize the hardware if not already done - if( !mPL061Initialized ) { - Status = PL061Initialize(); - if( EFI_ERROR(Status) ) { - goto EXIT; - } - } - - switch (Mode) - { - case GPIO_MODE_INPUT: - // Set the corresponding direction bit to LOW for input - MmioAnd8( PL061_GPIO_DIR_REG, GPIO_PIN_MASK_LOW_8BIT(Gpio) ); - break; - - case GPIO_MODE_OUTPUT_0: - // Set the corresponding data bit to LOW for 0 - MmioAnd8( PL061_GPIO_DATA_REG, GPIO_PIN_MASK_LOW_8BIT(Gpio) ); - // Set the corresponding direction bit to HIGH for output - MmioOr8( PL061_GPIO_DIR_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio) ); - break; - - case GPIO_MODE_OUTPUT_1: - // Set the corresponding data bit to HIGH for 1 - MmioOr8( PL061_GPIO_DATA_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio) ); - // Set the corresponding direction bit to HIGH for output - MmioOr8( PL061_GPIO_DIR_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio) ); - break; - - default: - // Other modes are not supported - return EFI_UNSUPPORTED; - } - -EXIT: - return Status; -} - -/** - -Routine Description: - - Gets the mode (function) of a GPIO pin - -Arguments: - - This - pointer to protocol - Gpio - which pin - Mode - pointer to output mode value - -Returns: - - EFI_SUCCESS - mode value retrieved - EFI_INVALID_PARAMETER - Mode is a null pointer or Gpio pin is out of range - -**/ -EFI_STATUS -EFIAPI -GetMode ( - IN EMBEDDED_GPIO *This, - IN EMBEDDED_GPIO_PIN Gpio, - OUT EMBEDDED_GPIO_MODE *Mode - ) -{ - EFI_STATUS Status; - - // Check for errors - if( ( Mode == NULL ) - || ( Gpio > LAST_GPIO_PIN ) ) { - return EFI_INVALID_PARAMETER; - } - - // Initialize the hardware if not already done - if( !mPL061Initialized ) { - Status = PL061Initialize(); - if( EFI_ERROR(Status) ) { - return Status; - } - } - - // Check if it is input or output - if( MmioRead8( PL061_GPIO_DIR_REG ) & GPIO_PIN_MASK_HIGH_8BIT(Gpio) ) { - // Pin set to output - if( MmioRead8( PL061_GPIO_DATA_REG ) & GPIO_PIN_MASK_HIGH_8BIT(Gpio) ) { - *Mode = GPIO_MODE_OUTPUT_1; - } else { - *Mode = GPIO_MODE_OUTPUT_0; - } - } else { - // Pin set to input - *Mode = GPIO_MODE_INPUT; - } - - return EFI_SUCCESS; -} - -/** - -Routine Description: - - Sets the pull-up / pull-down resistor of a GPIO pin - -Arguments: - - This - pointer to protocol - Gpio - which pin - Direction - pull-up, pull-down, or none - -Returns: - - EFI_UNSUPPORTED - Can not perform the requested operation - -**/ -EFI_STATUS -EFIAPI -SetPull ( - IN EMBEDDED_GPIO *This, - IN EMBEDDED_GPIO_PIN Gpio, - IN EMBEDDED_GPIO_PULL Direction - ) -{ - return EFI_UNSUPPORTED; -} - -/** - Protocol variable definition - **/ -EMBEDDED_GPIO gGpio = { - Get, - Set, - GetMode, - SetPull -}; - -/** - Initialize the state information for the Embedded Gpio protocol. - - @param ImageHandle of the loaded driver - @param SystemTable Pointer to the System Table - - @retval EFI_SUCCESS Protocol registered - @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure - @retval EFI_DEVICE_ERROR Hardware problems - -**/ -EFI_STATUS -EFIAPI -PL061InstallProtocol ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - EFI_HANDLE Handle; - - // - // Make sure the Gpio protocol has not been installed in the system yet. - // - ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEmbeddedGpioProtocolGuid); - - // Install the Embedded GPIO Protocol onto a new handle - Handle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces( - &Handle, - &gEmbeddedGpioProtocolGuid, &gGpio, - NULL - ); - if (EFI_ERROR(Status)) { - Status = EFI_OUT_OF_RESOURCES; - } - - return Status; -} +/** @file +* +* Copyright (c) 2011, ARM Limited. All rights reserved. +* Copyright (c) 2016, Linaro Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD +* License which accompanies this distribution. The full text of the license +* may be found at http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +/** + Function implementations +**/ + +EFI_STATUS +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; + } + + // 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; + } + + return EFI_SUCCESS; +} + +EFI_STATUS +PL061Initialize ( + VOID + ) +{ + EFI_STATUS Status; + + // Check if the PL061 GPIO module exists on board + Status = PL061Identify(); + if (EFI_ERROR (Status)) { + Status = EFI_DEVICE_ERROR; + goto EXIT; + } + + // Do other hardware initialisation things here as required + + // Disable Interrupts + //if (MmioRead8 (PL061_GPIO_IE_REG) != 0) { + // // Ensure interrupts are disabled + //} + + EXIT: + return Status; +} + +/** + +Routine Description: + + Gets the state of a GPIO pin + +Arguments: + + This - pointer to protocol + Gpio - which pin to read + Value - state of the pin + +Returns: + + EFI_SUCCESS - GPIO state returned in Value + EFI_INVALID_PARAMETER - Value is NULL pointer or Gpio pin is out of range +**/ +EFI_STATUS +EFIAPI +Get ( + IN EMBEDDED_GPIO *This, + IN EMBEDDED_GPIO_PIN Gpio, + OUT UINTN *Value + ) +{ + if ( (Value == NULL) + || (Gpio > LAST_GPIO_PIN)) + { + return EFI_INVALID_PARAMETER; + } + + if (MmioRead8 (PL061_GPIO_DATA_REG) & GPIO_PIN_MASK_HIGH_8BIT(Gpio)) { + *Value = 1; + } else { + *Value = 0; + } + + return EFI_SUCCESS; +} + +/** + +Routine Description: + + Sets the state of a GPIO pin + +Arguments: + + This - pointer to protocol + Gpio - which pin to modify + Mode - mode to set + +Returns: + + EFI_SUCCESS - GPIO set as requested + EFI_UNSUPPORTED - Mode is not supported + EFI_INVALID_PARAMETER - Gpio pin is out of range +**/ +EFI_STATUS +EFIAPI +Set ( + IN EMBEDDED_GPIO *This, + IN EMBEDDED_GPIO_PIN Gpio, + IN EMBEDDED_GPIO_MODE Mode + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + + // Check for errors + if (Gpio > LAST_GPIO_PIN) { + Status = EFI_INVALID_PARAMETER; + goto EXIT; + } + + switch (Mode) + { + case GPIO_MODE_INPUT: + // Set the corresponding direction bit to LOW for input + MmioAnd8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK_LOW_8BIT(Gpio)); + break; + + case GPIO_MODE_OUTPUT_0: + // Set the corresponding data bit to LOW for 0 + MmioAnd8 (PL061_GPIO_DATA_REG, GPIO_PIN_MASK_LOW_8BIT(Gpio)); + // Set the corresponding direction bit to HIGH for output + MmioOr8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio)); + break; + + case GPIO_MODE_OUTPUT_1: + // Set the corresponding data bit to HIGH for 1 + MmioOr8 (PL061_GPIO_DATA_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio)); + // Set the corresponding direction bit to HIGH for output + MmioOr8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK_HIGH_8BIT(Gpio)); + break; + + default: + // Other modes are not supported + return EFI_UNSUPPORTED; + } + +EXIT: + return Status; +} + +/** + +Routine Description: + + Gets the mode (function) of a GPIO pin + +Arguments: + + This - pointer to protocol + Gpio - which pin + Mode - pointer to output mode value + +Returns: + + EFI_SUCCESS - mode value retrieved + EFI_INVALID_PARAMETER - Mode is a null pointer or Gpio pin is out of range + +**/ +EFI_STATUS +EFIAPI +GetMode ( + IN EMBEDDED_GPIO *This, + IN EMBEDDED_GPIO_PIN Gpio, + OUT EMBEDDED_GPIO_MODE *Mode + ) +{ + // Check for errors + if ( (Mode == NULL) + || (Gpio > LAST_GPIO_PIN)) { + return EFI_INVALID_PARAMETER; + } + + // Check if it is input or output + if (MmioRead8 (PL061_GPIO_DIR_REG) & GPIO_PIN_MASK_HIGH_8BIT(Gpio)) { + // Pin set to output + if (MmioRead8 (PL061_GPIO_DATA_REG) & GPIO_PIN_MASK_HIGH_8BIT(Gpio)) { + *Mode = GPIO_MODE_OUTPUT_1; + } else { + *Mode = GPIO_MODE_OUTPUT_0; + } + } else { + // Pin set to input + *Mode = GPIO_MODE_INPUT; + } + + return EFI_SUCCESS; +} + +/** + +Routine Description: + + Sets the pull-up / pull-down resistor of a GPIO pin + +Arguments: + + This - pointer to protocol + Gpio - which pin + Direction - pull-up, pull-down, or none + +Returns: + + EFI_UNSUPPORTED - Can not perform the requested operation + +**/ +EFI_STATUS +EFIAPI +SetPull ( + IN EMBEDDED_GPIO *This, + IN EMBEDDED_GPIO_PIN Gpio, + IN EMBEDDED_GPIO_PULL Direction + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Protocol variable definition + **/ +EMBEDDED_GPIO gGpio = { + Get, + Set, + GetMode, + SetPull +}; + +/** + Initialize the state information for the Embedded Gpio protocol. + + @param ImageHandle of the loaded driver + @param SystemTable Pointer to the System Table + + @retval EFI_SUCCESS Protocol registered + @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure + @retval EFI_DEVICE_ERROR Hardware problems + +**/ +EFI_STATUS +EFIAPI +PL061InstallProtocol ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + // + // Make sure the Gpio protocol has not been installed in the system yet. + // + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEmbeddedGpioProtocolGuid); + + Status = PL061Initialize(); + if (EFI_ERROR(Status)) { + return EFI_DEVICE_ERROR; + } + + // Install the Embedded GPIO Protocol onto a new handle + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces( + &Handle, + &gEmbeddedGpioProtocolGuid, &gGpio, + NULL + ); + if (EFI_ERROR(Status)) { + Status = EFI_OUT_OF_RESOURCES; + } + + return Status; +}