On Fri, Nov 10, 2017 at 02:21:21PM +0000, Ard Biesheuvel wrote: > In order to be able to sample the state of the DIP switches at early > boot on the Developer Box platform, implement the GPIO PPI based on > the GPIO block that is implemented in the SynQuacer SoC. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ard Biesheuvel <[email protected]>
Reviewed-by: Leif Lindholm <[email protected]> > --- > Silicon/Socionext/SynQuacer/Drivers/SynQuacerGpioPei/SynQuacerGpioPei.c | > 203 ++++++++++++++++++++ > Silicon/Socionext/SynQuacer/Drivers/SynQuacerGpioPei/SynQuacerGpioPei.inf | > 47 +++++ > 2 files changed, 250 insertions(+) > > diff --git > a/Silicon/Socionext/SynQuacer/Drivers/SynQuacerGpioPei/SynQuacerGpioPei.c > b/Silicon/Socionext/SynQuacer/Drivers/SynQuacerGpioPei/SynQuacerGpioPei.c > new file mode 100644 > index 000000000000..24d08b4e5899 > --- /dev/null > +++ b/Silicon/Socionext/SynQuacer/Drivers/SynQuacerGpioPei/SynQuacerGpioPei.c > @@ -0,0 +1,203 @@ > +/** @file > + > + Copyright (c) 2017, Linaro, Ltd. All rights reserved.<BR> > + > + 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 <PiPei.h> > +#include <Library/IoLib.h> > +#include <Library/PeiServicesLib.h> > +#include <Platform/MemoryMap.h> > +#include <Ppi/EmbeddedGpio.h> > + > +#define PDR(x) (SYNQUACER_GPIO_BASE + 4 * (GPIO_PIN (x) >> 3)) > +#define DDR(x) (SYNQUACER_GPIO_BASE + 0x10 + 4 * (GPIO_PIN (x) >> > 3)) > +#define PFR(x) (SYNQUACER_GPIO_BASE + 0x20 + 4 * (GPIO_PIN (x) >> > 3)) > + > +#define GPIO_BIT(x) (1U << (GPIO_PIN (x) % 8)) > + > +STATIC CONST UINTN mGpioPinCount = 32; > + > +/** > + > + Gets the state of a GPIO pin > + > + @param This Pointer to protocol > + @param Gpio Which pin to read > + @param Value State of the pin > + > + @retval EFI_SUCCESS GPIO state returned in Value > + @retval EFI_INVALID_PARAMETER Value is NULL > + @retval EFI_NOT_FOUND Pin does not exit > + > +**/ > +STATIC > +EFI_STATUS > +EFIAPI > +GpioGet ( > + IN EMBEDDED_GPIO_PPI *This, > + IN EMBEDDED_GPIO_PIN Gpio, > + OUT UINTN *Value > + ) > +{ > + if (Value == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + if (GPIO_PORT (Gpio) > 0 || GPIO_PIN (Gpio) >= mGpioPinCount) { > + return EFI_NOT_FOUND; > + } > + > + *Value = ((MmioRead32 (PDR (GPIO_PIN (Gpio))) & GPIO_BIT (Gpio)) != 0); > + > + return EFI_SUCCESS; > +} > + > +/** > + > + Sets the state of a GPIO pin > + > + @param This Pointer to protocol > + @param Gpio Which pin to modify > + @param Mode Mode to set > + > + @retval EFI_SUCCESS GPIO set as requested > + @retval EFI_INVALID_PARAMETER Invalid mode > + @retval EFI_NOT_FOUND Pin does not exit > + > +**/ > +STATIC > +EFI_STATUS > +EFIAPI > +GpioSet ( > + IN EMBEDDED_GPIO_PPI *This, > + IN EMBEDDED_GPIO_PIN Gpio, > + IN EMBEDDED_GPIO_MODE Mode > + ) > +{ > + if (GPIO_PORT (Gpio) > 0 || GPIO_PIN (Gpio) >= mGpioPinCount) { > + return EFI_NOT_FOUND; > + } > + > + switch (Mode) { > + case GPIO_MODE_INPUT: > + MmioAnd32 (DDR (GPIO_PIN (Gpio)), ~GPIO_BIT (Gpio)); > + break; > + > + case GPIO_MODE_OUTPUT_0: > + MmioOr32 (DDR (GPIO_PIN (Gpio)), GPIO_BIT (Gpio)); > + MmioAnd32 (PDR (GPIO_PIN (Gpio)), ~GPIO_BIT (Gpio)); > + break; > + > + case GPIO_MODE_OUTPUT_1: > + MmioOr32 (DDR (GPIO_PIN (Gpio)), GPIO_BIT (Gpio)); > + MmioOr32 (PDR (GPIO_PIN (Gpio)), GPIO_BIT (Gpio)); > + break; > + > + default: > + return EFI_INVALID_PARAMETER; > + } > + return EFI_SUCCESS; > +} > + > + > +/** > + > + Gets the mode (function) of a GPIO pin > + > + @param This Pointer to protocol > + @param Gpio Which pin > + @param Mode Pointer to output mode value > + > + @retval EFI_SUCCESS Mode value retrieved > + @retval EFI_INVALID_PARAMETER Mode is NULL > + @retval EFI_NOT_FOUND Pin does not exit > + > +**/ > +STATIC > +EFI_STATUS > +EFIAPI > +GpioGetMode ( > + IN EMBEDDED_GPIO_PPI *This, > + IN EMBEDDED_GPIO_PIN Gpio, > + OUT EMBEDDED_GPIO_MODE *Mode > + ) > +{ > + if (Mode == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + if (GPIO_PORT (Gpio) > 0 || GPIO_PIN (Gpio) >= mGpioPinCount) { > + return EFI_NOT_FOUND; > + } > + > + if (!(MmioRead32 (DDR (GPIO_PIN (Gpio))) & GPIO_BIT (Gpio))) { > + *Mode = GPIO_MODE_INPUT; > + } else if (!(MmioRead32 (PDR (GPIO_PIN (Gpio))) & GPIO_BIT (Gpio))) { > + *Mode = GPIO_MODE_OUTPUT_0; > + } else { > + *Mode = GPIO_MODE_OUTPUT_1; > + } > + return EFI_SUCCESS; > +} > + > + > +/** > + > + Sets the pull-up / pull-down resistor of a GPIO pin > + > + @param This Pointer to PPI > + @param Gpio Port/pin index > + @param Pull The pullup/pulldown mode to set > + > + @retval EFI_SUCCESS Mode was set > + @retval EFI_NOT_FOUND Pin does not exist > + @retval EFI_UNSUPPORTED Action not supported > + > +**/ > +STATIC > +EFI_STATUS > +EFIAPI > +GpioSetPull ( > + IN EMBEDDED_GPIO_PPI *This, > + IN EMBEDDED_GPIO_PIN Gpio, > + IN EMBEDDED_GPIO_PULL Pull > + ) > +{ > + if (Pull != GPIO_PULL_NONE) { > + return EFI_UNSUPPORTED; > + } > + if (GPIO_PORT (Gpio) > 0 || GPIO_PIN (Gpio) >= mGpioPinCount) { > + return EFI_NOT_FOUND; > + } > + return EFI_SUCCESS; > +} > + > +STATIC EMBEDDED_GPIO_PPI mGpioPpi = { > + GpioGet, > + GpioSet, > + GpioGetMode, > + GpioSetPull, > +}; > + > +STATIC CONST EFI_PEI_PPI_DESCRIPTOR mEmbeddedGpioPpiDescriptor = { > + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, > + &gEdkiiEmbeddedGpioPpiGuid, > + &mGpioPpi > +}; > + > +EFI_STATUS > +EFIAPI > +SynQuacerGpioPeiEntryPoint ( > + IN EFI_PEI_FILE_HANDLE FfsHeader, > + IN CONST EFI_PEI_SERVICES **PeiServices > + ) > +{ > + return PeiServicesInstallPpi (&mEmbeddedGpioPpiDescriptor); > +} > diff --git > a/Silicon/Socionext/SynQuacer/Drivers/SynQuacerGpioPei/SynQuacerGpioPei.inf > b/Silicon/Socionext/SynQuacer/Drivers/SynQuacerGpioPei/SynQuacerGpioPei.inf > new file mode 100644 > index 000000000000..dbb5e9d4c53a > --- /dev/null > +++ > b/Silicon/Socionext/SynQuacer/Drivers/SynQuacerGpioPei/SynQuacerGpioPei.inf > @@ -0,0 +1,47 @@ > +#/* @file > +# > +# Copyright (c) 2017, Linaro, Ltd. All rights reserved.<BR> > +# > +# 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. > +# > +#*/ > + > +[Defines] > + INF_VERSION = 0x0001001A > + BASE_NAME = SynQuacerGpioPei > + FILE_GUID = 55a981a5-f371-4ba3-93a5-37fa0ca95089 > + MODULE_TYPE = PEIM > + VERSION_STRING = 1.0 > + ENTRY_POINT = SynQuacerGpioPeiEntryPoint > + > +# > +# The following information is for reference only and not required by the > build tools. > +# > +# VALID_ARCHITECTURES = AARCH64 > +# > +# > + > +[Sources] > + SynQuacerGpioPei.c > + > +[Packages] > + EmbeddedPkg/EmbeddedPkg.dec > + MdePkg/MdePkg.dec > + Silicon/Socionext/SynQuacer/SynQuacer.dec > + > +[LibraryClasses] > + IoLib > + PeimEntryPoint > + PeiServicesLib > + > +[Ppis] > + gEdkiiEmbeddedGpioPpiGuid ## PRODUCES > + > +[Depex] > + TRUE > -- > 2.11.0 > _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

