[edk2,edk2-platforms,v4,28/34] Silicon/SynQuacer: implement PEIM that exposes GPIO PPI

Message ID 20171110142127.12018-29-ard.biesheuvel@linaro.org
State New
Headers show
Series
  • add support for Socionext SynQuacer
Related show

Commit Message

Ard Biesheuvel Nov. 10, 2017, 2:21 p.m.
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 <ard.biesheuvel@linaro.org>

---
 Silicon/Socionext/SynQuacer/Drivers/SynQuacerGpioPei/SynQuacerGpioPei.c   | 203 ++++++++++++++++++++
 Silicon/Socionext/SynQuacer/Drivers/SynQuacerGpioPei/SynQuacerGpioPei.inf |  47 +++++
 2 files changed, 250 insertions(+)

-- 
2.11.0

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Comments

Leif Lindholm Nov. 17, 2017, 3:46 p.m. | #1
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 <ard.biesheuvel@linaro.org>


Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>


> ---

>  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
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Patch

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