LGTM. Seems reasonable. Reviewed-by: Andrei Warkentin ________________________________ From: devel@edk2.groups.io on behalf of Jeremy Linton via groups.io Sent: Monday, December 14, 2020 5:23 PM To: devel@edk2.groups.io Cc: ard.biesheuvel@arm.com ; leif@nuviainc.com ; pete@akeo.ie ; andrey.warkentin@gmail.com ; samer.el-haj-mahmoud@arm.com ; Jeremy Linton Subject: [edk2-devel] [PATCH 2/7] Platform/RaspberryPi: Add further mailbox helpers Lets add some further mailbox helpers and convert the existing RpiFirmwareSetLed into a generic SetGpio() function. Signed-off-by: Jeremy Linton --- .../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; } - #pragma pack() typedef struct { UINT32 ClockId; @@ -1152,6 +1151,17 @@ RpiFirmwareGetClockRate ( STATIC EFI_STATUS EFIAPI +RpiFirmwareGetCurrentClockState ( + IN UINT32 ClockId, + OUT UINT32 *ClockState + ) +{ + return RpiFirmwareGetClockRate (ClockId, RPI_MBOX_GET_CLOCK_STATE, ClockState); +} + +STATIC +EFI_STATUS +EFIAPI RpiFirmwareGetCurrentClockRate ( IN UINT32 ClockId, OUT UINT32 *ClockRate @@ -1181,6 +1191,63 @@ RpiFirmwareGetMinClockRate ( { return RpiFirmwareGetClockRate (ClockId, RPI_MBOX_GET_MIN_CLOCK_RATE, ClockRate); } + +#pragma pack() +typedef struct { + UINT32 ClockId; + UINT32 ClockState; +} RPI_FW_GET_CLOCK_STATE_TAG; + +typedef struct { + RPI_FW_BUFFER_HEAD BufferHead; + RPI_FW_TAG_HEAD TagHead; + RPI_FW_GET_CLOCK_STATE_TAG TagBody; + UINT32 EndTag; +} RPI_FW_SET_CLOCK_STATE_CMD; +#pragma pack() + +STATIC +EFI_STATUS +RpiFirmwareSetClockState ( + IN UINT32 ClockId, + IN UINT32 ClockState + ) +{ + RPI_FW_SET_CLOCK_STATE_CMD *Cmd; + EFI_STATUS Status; + UINT32 Result; + + if (!AcquireSpinLockOrFail (&mMailboxLock)) { + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + + Cmd = mDmaBuffer; + ZeroMem (Cmd, sizeof (*Cmd)); + + Cmd->BufferHead.BufferSize = sizeof (*Cmd); + Cmd->BufferHead.Response = 0; + Cmd->TagHead.TagId = RPI_MBOX_SET_CLOCK_STATE; + Cmd->TagHead.TagSize = sizeof (Cmd->TagBody); + Cmd->TagHead.TagValueSize = 0; + Cmd->TagBody.ClockId = ClockId; + Cmd->TagBody.ClockState = ClockState; + Cmd->EndTag = 0; + + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_MBOX_VC_CHANNEL, &Result); + + ReleaseSpinLock (&mMailboxLock); + + if (EFI_ERROR (Status) || + Cmd->BufferHead.Response != RPI_MBOX_RESP_SUCCESS) { + DEBUG ((DEBUG_ERROR, + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n", + __FUNCTION__, Status, Cmd->BufferHead.Response)); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} #pragma pack() typedef struct { @@ -1199,8 +1266,9 @@ typedef struct { STATIC VOID EFIAPI -RpiFirmwareSetLed ( - IN BOOLEAN On +RpiFirmwareSetGpio ( + IN UINT32 Gpio, + IN BOOLEAN State ) { RPI_FW_SET_GPIO_CMD *Cmd; @@ -1220,14 +1288,10 @@ RpiFirmwareSetLed ( Cmd->TagHead.TagId = RPI_MBOX_SET_GPIO; Cmd->TagHead.TagSize = sizeof (Cmd->TagBody); /* - * GPIO_PIN_2 = Activity LED - * GPIO_PIN_4 = HDMI Detect (Input / Active Low) - * GPIO_PIN_7 = Power LED (Input / Active Low) - * * There's also a 128 pin offset. */ - Cmd->TagBody.Pin = 128 + 2; - Cmd->TagBody.State = On; + Cmd->TagBody.Pin = 128 + Gpio; + Cmd->TagBody.State = State; Cmd->TagHead.TagValueSize = 0; Cmd->EndTag = 0; @@ -1242,6 +1306,16 @@ RpiFirmwareSetLed ( __FUNCTION__, Status, Cmd->BufferHead.Response)); } } + +STATIC +VOID +EFIAPI +RpiFirmwareSetLed ( + IN BOOLEAN On + ) +{ + RpiFirmwareSetGpio (RPI_EXP_GPIO_LED, On); +} #pragma pack() typedef struct { @@ -1299,6 +1373,149 @@ RpiFirmwareNotifyXhciReset ( return Status; } +#pragma pack() +typedef struct { + UINT32 Gpio; + UINT32 Direction; + UINT32 Polarity; + UINT32 TermEn; + UINT32 TermPullUp; +} RPI_FW_GPIO_GET_CFG_TAG; + +typedef struct { + RPI_FW_BUFFER_HEAD BufferHead; + RPI_FW_TAG_HEAD TagHead; + RPI_FW_GPIO_GET_CFG_TAG TagBody; + UINT32 EndTag; +} RPI_FW_NOTIFY_GPIO_GET_CFG_CMD; +#pragma pack() + + +STATIC +EFI_STATUS +EFIAPI +RpiFirmwareNotifyGpioGetCfg ( + IN UINTN Gpio, + IN UINT32 *Polarity + ) +{ + RPI_FW_NOTIFY_GPIO_GET_CFG_CMD *Cmd; + EFI_STATUS Status; + UINT32 Result; + + if (!AcquireSpinLockOrFail (&mMailboxLock)) { + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + + Cmd = mDmaBuffer; + ZeroMem (Cmd, sizeof (*Cmd)); + + Cmd->BufferHead.BufferSize = sizeof (*Cmd); + Cmd->BufferHead.Response = 0; + Cmd->TagHead.TagId = RPI_MBOX_GET_GPIO_CONFIG; + Cmd->TagHead.TagSize = sizeof (Cmd->TagBody); + Cmd->TagBody.Gpio = 128 + Gpio; + + Cmd->TagHead.TagValueSize = 0; + Cmd->EndTag = 0; + + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_MBOX_VC_CHANNEL, &Result); + + *Polarity = Cmd->TagBody.Polarity; + + ReleaseSpinLock (&mMailboxLock); + + if (EFI_ERROR (Status) || + Cmd->BufferHead.Response != RPI_MBOX_RESP_SUCCESS) { + DEBUG ((DEBUG_ERROR, + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n", + __FUNCTION__, Status, Cmd->BufferHead.Response)); + } + + return Status; +} + + +#pragma pack() +typedef struct { + UINT32 Gpio; + UINT32 Direction; + UINT32 Polarity; + UINT32 TermEn; + UINT32 TermPullUp; + UINT32 State; +} RPI_FW_GPIO_SET_CFG_TAG; + +typedef struct { + RPI_FW_BUFFER_HEAD BufferHead; + RPI_FW_TAG_HEAD TagHead; + RPI_FW_GPIO_SET_CFG_TAG TagBody; + UINT32 EndTag; +} RPI_FW_NOTIFY_GPIO_SET_CFG_CMD; +#pragma pack() + + +STATIC +EFI_STATUS +EFIAPI +RpiFirmwareNotifyGpioSetCfg ( + IN UINTN Gpio, + IN UINTN Direction, + IN UINTN State + ) +{ + RPI_FW_NOTIFY_GPIO_SET_CFG_CMD *Cmd; + EFI_STATUS Status; + UINT32 Result; + + Status = RpiFirmwareNotifyGpioGetCfg (Gpio, &Result); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Failed to get GPIO polarity\n", __FUNCTION__)); + Result = 0; //default polarity + } + + + if (!AcquireSpinLockOrFail (&mMailboxLock)) { + DEBUG ((DEBUG_ERROR, "%a: failed to acquire spinlock\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + + Cmd = mDmaBuffer; + ZeroMem (Cmd, sizeof (*Cmd)); + + Cmd->BufferHead.BufferSize = sizeof (*Cmd); + Cmd->BufferHead.Response = 0; + Cmd->TagHead.TagId = RPI_MBOX_SET_GPIO_CONFIG; + Cmd->TagHead.TagSize = sizeof (Cmd->TagBody); + + Cmd->TagBody.Gpio = 128 + Gpio; + Cmd->TagBody.Direction = Direction; + Cmd->TagBody.Polarity = Result; + Cmd->TagBody.TermEn = 0; + Cmd->TagBody.TermPullUp = 0; + Cmd->TagBody.State = State; + + Cmd->TagHead.TagValueSize = 0; + Cmd->EndTag = 0; + + Status = MailboxTransaction (Cmd->BufferHead.BufferSize, RPI_MBOX_VC_CHANNEL, &Result); + + ReleaseSpinLock (&mMailboxLock); + + if (EFI_ERROR (Status) || + Cmd->BufferHead.Response != RPI_MBOX_RESP_SUCCESS) { + DEBUG ((DEBUG_ERROR, + "%a: mailbox transaction error: Status == %r, Response == 0x%x\n", + __FUNCTION__, Status, Cmd->BufferHead.Response)); + } + + RpiFirmwareSetGpio (Gpio,!State); + + + return Status; +} + STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL mRpiFirmwareProtocol = { RpiFirmwareSetPowerState, RpiFirmwareGetMacAddress, @@ -1321,7 +1538,10 @@ STATIC RASPBERRY_PI_FIRMWARE_PROTOCOL mRpiFirmwareProtocol = { RpiFirmwareGetCpuName, RpiFirmwareGetArmMemory, RPiFirmwareGetModelInstalledMB, - RpiFirmwareNotifyXhciReset + RpiFirmwareNotifyXhciReset, + RpiFirmwareGetCurrentClockState, + RpiFirmwareSetClockState, + RpiFirmwareNotifyGpioSetCfg }; /** 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 typedef EFI_STATUS +(EFIAPI *GET_CLOCK_STATE) ( + IN UINT32 ClockId, + OUT UINT32 *ClockState + ); + +typedef +EFI_STATUS +(EFIAPI *SET_CLOCK_STATE) ( + IN UINT32 ClockId, + IN UINT32 ClockState + ); + +typedef +EFI_STATUS (EFIAPI *GET_CLOCK_RATE) ( IN UINT32 ClockId, OUT UINT32 *ClockRate @@ -149,6 +163,14 @@ EFI_STATUS UINTN FunctionNumber ); +typedef +EFI_STATUS +(EFIAPI *GPIO_SET_CFG) ( + UINTN Gpio, + UINTN Direction, + UINTN State + ); + typedef struct { SET_POWER_STATE SetPowerState; GET_MAC_ADDRESS GetMacAddress; @@ -172,6 +194,9 @@ typedef struct { GET_ARM_MEM GetArmMem; GET_MODEL_INSTALLED_MB GetModelInstalledMB; NOTIFY_XHCI_RESET NotifyXhciReset; + GET_CLOCK_STATE GetClockState; + SET_CLOCK_STATE SetClockState; + GPIO_SET_CFG SetGpioConfig; } RASPBERRY_PI_FIRMWARE_PROTOCOL; extern EFI_GUID gRaspberryPiFirmwareProtocolGuid; -- 2.13.7 -=-=-=-=-=-= Groups.io Links: You receive all messages sent to this group. View/Reply Online (#68814): https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Fmessage%2F68814&data=04%7C01%7Cawarkentin%40vmware.com%7Cd008b6c3109a4d90740b08d8a08755fc%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C637435850424785824%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=iJY0BHT2JMnlQXHGFAjB1b0LF5yqTAKpxSoHVThwXHI%3D&reserved=0 Mute This Topic: https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgroups.io%2Fmt%2F78964891%2F4387333&data=04%7C01%7Cawarkentin%40vmware.com%7Cd008b6c3109a4d90740b08d8a08755fc%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C637435850424785824%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=xC9ynLadafljUyR%2BOqCDFmgIxzCCiXtaJFo%2Brq%2BeGjE%3D&reserved=0 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fedk2.groups.io%2Fg%2Fdevel%2Funsub&data=04%7C01%7Cawarkentin%40vmware.com%7Cd008b6c3109a4d90740b08d8a08755fc%7Cb39138ca3cee4b4aa4d6cd83d9dd62f0%7C0%7C0%7C637435850424785824%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=YxVZVIiiwGR37p34ccfqVIbjrCaS%2FYNF64CBf99ebq0%3D&reserved=0 [awarkentin@vmware.com] -=-=-=-=-=-=