[PATCH v4 2/7] Platform/RaspberryPi: Add further mailbox helpers


Jeremy Linton
 

Lets add some further mailbox helpers and convert the existing
RpiFirmwareSetLed into a generic SetGpio() function.

Signed-off-by: Jeremy Linton <jeremy.linton@arm.com>
Reviewed-by: Andrei Warkentin <awarkentin@vmware.com>
---
.../Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c | 240 +++++++++++++++++=
+++-
.../RaspberryPi/Include/Protocol/RpiFirmware.h | 25 +++
2 files changed, 255 insertions(+), 10 deletions(-)

diff --git a/Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c b=
/Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
index ade91c9f34..bf74148bbb 100644
--- a/Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
+++ b/Platform/RaspberryPi/Drivers/RpiFirmwareDxe/RpiFirmwareDxe.c
@@ -1090,7 +1090,6 @@ RpiFirmwareSetClockRate (
return EFI_SUCCESS;=0D
}=0D
=0D
-=0D
#pragma pack()=0D
typedef struct {=0D
UINT32 ClockId;=0D
@@ -1152,6 +1151,17 @@ RpiFirmwareGetClockRate (
STATIC=0D
EFI_STATUS=0D
EFIAPI=0D
+RpiFirmwareGetCurrentClockState (=0D
+ IN UINT32 ClockId,=0D
+ OUT UINT32 *ClockState=0D
+ )=0D
+{=0D
+ return RpiFirmwareGetClockRate (ClockId, RPI_MBOX_GET_CLOCK_STATE, Clock=
State);=0D
+}=0D
+=0D
+STATIC=0D
+EFI_STATUS=0D
+EFIAPI=0D
RpiFirmwareGetCurrentClockRate (=0D
IN UINT32 ClockId,=0D
OUT UINT32 *ClockRate=0D
@@ -1181,6 +1191,63 @@ RpiFirmwareGetMinClockRate (
{=0D
return RpiFirmwareGetClockRate (ClockId, RPI_MBOX_GET_MIN_CLOCK_RATE, Cl=
ockRate);=0D
}=0D
+
+#pragma pack()=0D
+typedef struct {=0D
+ UINT32 ClockId;=0D
+ UINT32 ClockState;=0D
+} RPI_FW_GET_CLOCK_STATE_TAG;=0D
+=0D
+typedef struct {=0D
+ RPI_FW_BUFFER_HEAD BufferHead;=0D
+ RPI_FW_TAG_HEAD TagHead;=0D
+ RPI_FW_GET_CLOCK_STATE_TAG TagBody;=0D
+ UINT32 EndTag;=0D
+} RPI_FW_SET_CLOCK_STATE_CMD;=0D
+#pragma pack()=0D
+=0D
+STATIC=0D
+EFI_STATUS=0D
+RpiFirmwareSetClockState (=0D
+ IN UINT32 ClockId,=0D
+ IN UINT32 ClockState=0D
+ )=0D
+{=0D
+ RPI_FW_SET_CLOCK_STATE_CMD *Cmd;=0D
+ EFI_STATUS Status;=0D
+ UINT32 Result;=0D
+=0D
+ if (!AcquireSpinLockOrFail (&mMailboxLock)) {=0D
+ DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__)=
);=0D
+ return EFI_DEVICE_ERROR;=0D
+ }=0D
+=0D
+ Cmd =3D mDmaBuffer;=0D
+ ZeroMem (Cmd, sizeof (*Cmd));=0D
+=0D
+ Cmd->BufferHead.BufferSize =3D sizeof (*Cmd);=0D
+ Cmd->BufferHead.Response =3D 0;=0D
+ Cmd->TagHead.TagId =3D RPI_MBOX_SET_CLOCK_STATE;=0D
+ Cmd->TagHead.TagSize =3D sizeof (Cmd->TagBody);=0D
+ Cmd->TagHead.TagValueSize =3D 0;=0D
+ Cmd->TagBody.ClockId =3D ClockId;=0D
+ Cmd->TagBody.ClockState =3D ClockState;=0D
+ Cmd->EndTag =3D 0;=0D
+=0D
+ Status =3D MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_MBOX_VC_C=
HANNEL, &Result);=0D
+=0D
+ ReleaseSpinLock (&mMailboxLock);=0D
+=0D
+ if (EFI_ERROR (Status) ||=0D
+ Cmd->BufferHead.Response !=3D RPI_MBOX_RESP_SUCCESS) {=0D
+ DEBUG ((DEBUG_ERROR,=0D
+ "%a: mailbox transaction error: Status =3D=3D %r, Response =3D=3D 0x=
%x\n",=0D
+ __FUNCTION__, Status, Cmd->BufferHead.Response));=0D
+ return EFI_DEVICE_ERROR;=0D
+ }=0D
+=0D
+ return EFI_SUCCESS;=0D
+}=0D
=0D
#pragma pack()=0D
typedef struct {=0D
@@ -1199,8 +1266,9 @@ typedef struct {
STATIC=0D
VOID=0D
EFIAPI=0D
-RpiFirmwareSetLed (=0D
- IN BOOLEAN On=0D
+RpiFirmwareSetGpio (=0D
+ IN UINT32 Gpio,=0D
+ IN BOOLEAN State=0D
)=0D
{=0D
RPI_FW_SET_GPIO_CMD *Cmd;=0D
@@ -1220,14 +1288,10 @@ RpiFirmwareSetLed (
Cmd->TagHead.TagId =3D RPI_MBOX_SET_GPIO;=0D
Cmd->TagHead.TagSize =3D sizeof (Cmd->TagBody);=0D
/*=0D
- * GPIO_PIN_2 =3D Activity LED=0D
- * GPIO_PIN_4 =3D HDMI Detect (Input / Active Low)=0D
- * GPIO_PIN_7 =3D Power LED (Input / Active Low)=0D
- *=0D
* There's also a 128 pin offset.=0D
*/=0D
- Cmd->TagBody.Pin =3D 128 + 2;=0D
- Cmd->TagBody.State =3D On;=0D
+ Cmd->TagBody.Pin =3D 128 + Gpio;=0D
+ Cmd->TagBody.State =3D State;=0D
Cmd->TagHead.TagValueSize =3D 0;=0D
Cmd->EndTag =3D 0;=0D
=0D
@@ -1242,6 +1306,16 @@ RpiFirmwareSetLed (
__FUNCTION__, Status, Cmd->BufferHead.Response));=0D
}=0D
}=0D
+
+STATIC=0D
+VOID=0D
+EFIAPI=0D
+RpiFirmwareSetLed (=0D
+ IN BOOLEAN On=0D
+ )=0D
+{=0D
+ RpiFirmwareSetGpio (RPI_EXP_GPIO_LED, On);=0D
+}=0D
=0D
#pragma pack()=0D
typedef struct {=0D
@@ -1299,6 +1373,149 @@ RpiFirmwareNotifyXhciReset (
return Status;=0D
}=0D
=0D
+#pragma pack()=0D
+typedef struct {=0D
+ UINT32 Gpio;=0D
+ UINT32 Direction;=0D
+ UINT32 Polarity;=0D
+ UINT32 TermEn;=0D
+ UINT32 TermPullUp;=0D
+} RPI_FW_GPIO_GET_CFG_TAG;=0D
+=0D
+typedef struct {=0D
+ RPI_FW_BUFFER_HEAD BufferHead;=0D
+ RPI_FW_TAG_HEAD TagHead;=0D
+ RPI_FW_GPIO_GET_CFG_TAG TagBody;=0D
+ UINT32 EndTag;=0D
+} RPI_FW_NOTIFY_GPIO_GET_CFG_CMD;=0D
+#pragma pack()=0D
+=0D
+=0D
+STATIC=0D
+EFI_STATUS=0D
+EFIAPI=0D
+RpiFirmwareNotifyGpioGetCfg (=0D
+ IN UINTN Gpio,=0D
+ IN UINT32 *Polarity=0D
+ )=0D
+{=0D
+ RPI_FW_NOTIFY_GPIO_GET_CFG_CMD *Cmd;=0D
+ EFI_STATUS Status;=0D
+ UINT32 Result;=0D
+=0D
+ if (!AcquireSpinLockOrFail (&mMailboxLock)) {=0D
+ DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__)=
);=0D
+ return EFI_DEVICE_ERROR;=0D
+ }=0D
+=0D
+ Cmd =3D mDmaBuffer;=0D
+ ZeroMem (Cmd, sizeof (*Cmd));=0D
+=0D
+ Cmd->BufferHead.BufferSize =3D sizeof (*Cmd);=0D
+ Cmd->BufferHead.Response =3D 0;=0D
+ Cmd->TagHead.TagId =3D RPI_MBOX_GET_GPIO_CONFIG;=0D
+ Cmd->TagHead.TagSize =3D sizeof (Cmd->TagBody);=0D
+ Cmd->TagBody.Gpio =3D 128 + Gpio;=0D
+=0D
+ Cmd->TagHead.TagValueSize =3D 0;=0D
+ Cmd->EndTag =3D 0;=0D
+=0D
+ Status =3D MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_MBOX_VC_C=
HANNEL, &Result);=0D
+=0D
+ *Polarity =3D Cmd->TagBody.Polarity;=0D
+=0D
+ ReleaseSpinLock (&mMailboxLock);=0D
+=0D
+ if (EFI_ERROR (Status) ||=0D
+ Cmd->BufferHead.Response !=3D RPI_MBOX_RESP_SUCCESS) {=0D
+ DEBUG ((DEBUG_ERROR,=0D
+ "%a: mailbox transaction error: Status =3D=3D %r, Response =3D=3D 0=
x%x\n",=0D
+ __FUNCTION__, Status, Cmd->BufferHead.Response));=0D
+ }=0D
+=0D
+ return Status;=0D
+}=0D
+=0D
+=0D
+#pragma pack()=0D
+typedef struct {=0D
+ UINT32 Gpio;=0D
+ UINT32 Direction;=0D
+ UINT32 Polarity;=0D
+ UINT32 TermEn;=0D
+ UINT32 TermPullUp;=0D
+ UINT32 State;=0D
+} RPI_FW_GPIO_SET_CFG_TAG;=0D
+=0D
+typedef struct {=0D
+ RPI_FW_BUFFER_HEAD BufferHead;=0D
+ RPI_FW_TAG_HEAD TagHead;=0D
+ RPI_FW_GPIO_SET_CFG_TAG TagBody;=0D
+ UINT32 EndTag;=0D
+} RPI_FW_NOTIFY_GPIO_SET_CFG_CMD;=0D
+#pragma pack()=0D
+=0D
+=0D
+STATIC=0D
+EFI_STATUS=0D
+EFIAPI=0D
+RpiFirmwareNotifyGpioSetCfg (=0D
+ IN UINTN Gpio,=0D
+ IN UINTN Direction,=0D
+ IN UINTN State=0D
+ )=0D
+{=0D
+ RPI_FW_NOTIFY_GPIO_SET_CFG_CMD *Cmd;=0D
+ EFI_STATUS Status;=0D
+ UINT32 Result;=0D
+=0D
+ Status =3D RpiFirmwareNotifyGpioGetCfg (Gpio, &Result);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "%a: Failed to get GPIO polarity\n", __FUNCTION__)=
);=0D
+ Result =3D 0; //default polarity=0D
+ }=0D
+=0D
+=0D
+ if (!AcquireSpinLockOrFail (&mMailboxLock)) {=0D
+ DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__)=
);=0D
+ return EFI_DEVICE_ERROR;=0D
+ }=0D
+=0D
+ Cmd =3D mDmaBuffer;=0D
+ ZeroMem (Cmd, sizeof (*Cmd));=0D
+=0D
+ Cmd->BufferHead.BufferSize =3D sizeof (*Cmd);=0D
+ Cmd->BufferHead.Response =3D 0;=0D
+ Cmd->TagHead.TagId =3D RPI_MBOX_SET_GPIO_CONFIG;=0D
+ Cmd->TagHead.TagSize =3D sizeof (Cmd->TagBody);=0D
+
+ Cmd->TagBody.Gpio =3D 128 + Gpio;=0D
+ Cmd->TagBody.Direction =3D Direction;=0D
+ Cmd->TagBody.Polarity =3D Result;=0D
+ Cmd->TagBody.TermEn =3D 0;=0D
+ Cmd->TagBody.TermPullUp =3D 0;=0D
+ Cmd->TagBody.State =3D State;=0D
+=0D
+ Cmd->TagHead.TagValueSize =3D 0;=0D
+ Cmd->EndTag =3D 0;=0D
+=0D
+ Status =3D MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_MBOX_VC_C=
HANNEL, &Result);=0D
+=0D
+ ReleaseSpinLock (&mMailboxLock);=0D
+=0D
+ if (EFI_ERROR (Status) ||=0D
+ Cmd->BufferHead.Response !=3D RPI_MBOX_RESP_SUCCESS) {=0D
+ DEBUG ((DEBUG_ERROR,=0D
+ "%a: mailbox transaction error: Status =3D=3D %r, Response =3D=3D 0=
x%x\n",=0D
+ __FUNCTION__, Status, Cmd->BufferHead.Response));=0D
+ }=0D
+
+ RpiFirmwareSetGpio (Gpio,!State);
+
+=0D
+ return Status;=0D
+}=0D
+=0D
STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL mRpiFirmwareProtocol =3D {=0D
RpiFirmwareSetPowerState,=0D
RpiFirmwareGetMacAddress,=0D
@@ -1321,7 +1538,10 @@ STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL mRpiFirmwarePr=
otocol =3D {
RpiFirmwareGetCpuName,=0D
RpiFirmwareGetArmMemory,=0D
RPiFirmwareGetModelInstalledMB,=0D
- RpiFirmwareNotifyXhciReset=0D
+ RpiFirmwareNotifyXhciReset,=0D
+ RpiFirmwareGetCurrentClockState,=0D
+ RpiFirmwareSetClockState,
+ RpiFirmwareNotifyGpioSetCfg=0D
};=0D
=0D
/**=0D
diff --git a/Platform/RaspberryPi/Include/Protocol/RpiFirmware.h b/Platform=
/RaspberryPi/Include/Protocol/RpiFirmware.h
index 56a8d15a38..d841608e57 100644
--- a/Platform/RaspberryPi/Include/Protocol/RpiFirmware.h
+++ b/Platform/RaspberryPi/Include/Protocol/RpiFirmware.h
@@ -37,6 +37,20 @@ EFI_STATUS
=0D
typedef=0D
EFI_STATUS=0D
+(EFIAPI *GET_CLOCK_STATE) (=0D
+ IN UINT32 ClockId,=0D
+ OUT UINT32 *ClockState=0D
+ );=0D
+=0D
+typedef=0D
+EFI_STATUS=0D
+(EFIAPI *SET_CLOCK_STATE) (=0D
+ IN UINT32 ClockId,=0D
+ IN UINT32 ClockState=0D
+ );=0D
+=0D
+typedef=0D
+EFI_STATUS=0D
(EFIAPI *GET_CLOCK_RATE) (=0D
IN UINT32 ClockId,=0D
OUT UINT32 *ClockRate=0D
@@ -149,6 +163,14 @@ EFI_STATUS
UINTN FunctionNumber=0D
);=0D
=0D
+typedef =0D
+EFI_STATUS=0D
+(EFIAPI *GPIO_SET_CFG) (=0D
+ UINTN Gpio,=0D
+ UINTN Direction,=0D
+ UINTN State=0D
+ );=0D
+=0D
typedef struct {=0D
SET_POWER_STATE SetPowerState;=0D
GET_MAC_ADDRESS GetMacAddress;=0D
@@ -172,6 +194,9 @@ typedef struct {
GET_ARM_MEM GetArmMem;=0D
GET_MODEL_INSTALLED_MB GetModelInstalledMB;=0D
NOTIFY_XHCI_RESET NotifyXhciReset;=0D
+ GET_CLOCK_STATE GetClockState;=0D
+ SET_CLOCK_STATE SetClockState;=0D
+ GPIO_SET_CFG SetGpioConfig;=0D
} RASPBERRY_PI_FIRMWARE_PROTOCOL;=0D
=0D
extern EFI_GUID gRaspberryPiFirmwareProtocolGuid;=0D
--=20
2.13.7

Join devel@edk2.groups.io to automatically receive all group messages.