From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: None (no SPF record) identity=mailfrom; client-ip=2a00:1450:4864:20::141; helo=mail-lf1-x141.google.com; envelope-from=mw@semihalf.com; receiver=edk2-devel@lists.01.org Received: from mail-lf1-x141.google.com (mail-lf1-x141.google.com [IPv6:2a00:1450:4864:20::141]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id F02EE2117B56E for ; Fri, 19 Oct 2018 18:58:15 -0700 (PDT) Received: by mail-lf1-x141.google.com with SMTP id n26-v6so7869649lfl.1 for ; Fri, 19 Oct 2018 18:58:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CwMQmTRm5BIqy2Wh8ytxY9wZ9X261GoMifyN31Jg3uw=; b=Sa7sGsS3vByMopeaB2kcYk75IObguevnQqr/Q4Dy5UWlg+vhzOmQXX9moZAPXorVT2 ++3hJlMEIhuS+Uz3klTraVQWOvBGYzzkOP4jhLRlcSCieGpXV+ArqgBsQtsE5eLk6ZAU sJcI1vssscB046qtUblhPKTCveiltVDDeN+0fDyseIRubcZv1PF67s5UdYbfZhlzWaFY NBf6l2mOOe2g6KcOdBviuJeGaAvelQSiu789E0RzVXYLiWt+7Q8rfHFx3Heny7wh60xK AV/1pg6iFHOZGFIj2q2yJcgHZNWMRANDC81IK9YbunUt4Kbe0uzUd70pOk1takIJJ3c+ eGdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CwMQmTRm5BIqy2Wh8ytxY9wZ9X261GoMifyN31Jg3uw=; b=DiyZotuzBmQdCkArEz6QfdJ57NhF6rb80flrKrPUwYu5/fWKlUoS26TcmqvoUAn4Tv oWodpC7fCFPmdOb+q/sBiA8RZS5/HnilA7M8/ZwehvM6cCFtI9QM0NgTIdJYET0e73Gh z+Wa9uPtqNlIW1O4bmeHu1EZc96VOJTgFF8/aSeOE5M1K+xIRKGiyZoQDhB+nksl5x3s z2GUREQ9YhIbdRRK94YSTXRTsW/vboOX/2reecw+FDGyAiMjuNouL3TLiRIfD34hVMeh Eb75DtJNG3NuEMuRQEZpIf/9hCQ3CRO6xmyoaX8K/CzyWfAe1k+5raRNyI5X0Czl35OL qzlw== X-Gm-Message-State: ABuFfohfD/SLs4vluDB09Ur6KnrgOrQyqlxh+/+e41qgmngD8gkJmYE9 NQJa6yzgJCWSFg1ulxEo9jrr5kkUqOg= X-Google-Smtp-Source: ACcGV60Yg1IV4U7T5w0PFsdOKRuNVRMZn7VnX80X/bK2I7YQrE56dw8aW5z3UhMhAjMf/XdyjKRRkg== X-Received: by 2002:a19:990c:: with SMTP id b12-v6mr4230288lfe.18.1540000693652; Fri, 19 Oct 2018 18:58:13 -0700 (PDT) Received: from gilgamesh.semihalf.com (31-172-191-173.noc.fibertech.net.pl. [31.172.191.173]) by smtp.gmail.com with ESMTPSA id p63-v6sm5562777lfg.46.2018.10.19.18.58.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 19 Oct 2018 18:58:12 -0700 (PDT) From: Marcin Wojtas To: edk2-devel@lists.01.org Cc: leif.lindholm@linaro.org, ard.biesheuvel@linaro.org, nadavh@marvell.com, mw@semihalf.com, jsd@semihalf.com, jaz@semihalf.com, kostap@marvell.com, jinghua Date: Sat, 20 Oct 2018 03:57:37 +0200 Message-Id: <1540000661-1956-9-git-send-email-mw@semihalf.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1540000661-1956-1-git-send-email-mw@semihalf.com> References: <1540000661-1956-1-git-send-email-mw@semihalf.com> Subject: [platforms: PATCH 08/12] Marvell/Drivers: MvGpioDxe: Introduce platform GPIO driver X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Oct 2018 01:58:16 -0000 From: jinghua Marvell Armada 7k/8k SoCs comprise integrated GPIO controllers, one in AP and two in each possible CP hardware blocks. This patch introduces support for them, which is a producer of MARVELL_GPIO_PROTOCOL, which add necessary routines. Hardware description of the controllers is placed in MvHwDescLib.c, same as other devices. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Marcin Wojtas --- Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf | 43 +++ Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h | 52 ++++ Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c | 298 ++++++++++++++++++++ 3 files changed, 393 insertions(+) create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h create mode 100644 Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c diff --git a/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf new file mode 100644 index 0000000..2d56433 --- /dev/null +++ b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.inf @@ -0,0 +1,43 @@ +## @file +# +# Copyright (c) 2017, Marvell International Ltd. 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. +# + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = MvGpioDxe + FILE_GUID = 706eb761-b3b5-4f41-8558-5fd9217c0079 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = MvGpioEntryPoint + +[Sources] + MvGpioDxe.c + MvGpioDxe.h + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + Silicon/Marvell/Marvell.dec + +[LibraryClasses] + ArmadaSoCDescLib + DebugLib + MemoryAllocationLib + UefiDriverEntryPoint + UefiLib + +[Protocols] + gMarvellBoardDescProtocolGuid + gMarvellGpioProtocolGuid + +[Depex] + TRUE diff --git a/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h new file mode 100644 index 0000000..48744dc --- /dev/null +++ b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.h @@ -0,0 +1,52 @@ +/** +* +* Copyright (c) 2018, Marvell International Ltd. 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. +* +**/ +#ifndef __MV_GPIO_H__ +#define __MV_GPIO_H__ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#define GPIO_SIGNATURE SIGNATURE_32 ('G', 'P', 'I', 'O') + +#ifndef BIT +#define BIT(nr) (1 << (nr)) +#endif + +// Marvell GPIO Controller Registers +#define GPIO_DATA_OUT_REG (0x0) +#define GPIO_OUT_EN_REG (0x4) +#define GPIO_BLINK_EN_REG (0x8) +#define GPIO_DATA_IN_POL_REG (0xc) +#define GPIO_DATA_IN_REG (0x10) + +typedef struct { + MARVELL_GPIO_PROTOCOL GpioProtocol; + MV_BOARD_GPIO_DESC *Desc; + UINTN Signature; + EFI_HANDLE Handle; +} MV_GPIO; + +#endif // __MV_GPIO_H__ diff --git a/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c new file mode 100644 index 0000000..fc2d416 --- /dev/null +++ b/Silicon/Marvell/Drivers/Gpio/MvGpioDxe/MvGpioDxe.c @@ -0,0 +1,298 @@ +/** +* +* Copyright (c) 2018, Marvell International Ltd. 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 "MvGpioDxe.h" + +STATIC MV_GPIO *mGpioInstance; + +STATIC MV_GPIO_DEVICE_PATH mGpioDevicePathTemplate = { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (VENDOR_DEVICE_PATH) + + sizeof (MARVELL_GPIO_DRIVER_TYPE)), + (UINT8) ((sizeof (VENDOR_DEVICE_PATH) + + sizeof (MARVELL_GPIO_DRIVER_TYPE)) >> 8), + }, + }, + EFI_CALLER_ID_GUID + }, + GPIO_DRIVER_TYPE_SOC_CONTROLLER, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + sizeof(EFI_DEVICE_PATH_PROTOCOL), + 0 + } + } +}; + +STATIC +EFI_STATUS +MvGpioValidate ( + IN UINTN ControllerIndex, + IN UINTN GpioPin + ) +{ + if (ControllerIndex >= mGpioInstance->Desc->GpioDevCount) { + DEBUG ((DEBUG_ERROR, + "%a: Invalid GPIO ControllerIndex: %d\n", + __FUNCTION__, + ControllerIndex)); + return EFI_INVALID_PARAMETER; + } + + if (GpioPin >= mGpioInstance->Desc->SoC[ControllerIndex].GpioPinCount) { + DEBUG ((DEBUG_ERROR, + "%a: GPIO pin #%d not available in Controller#%d\n", + __FUNCTION__, + GpioPin, + ControllerIndex)); + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MvGpioDirectionOutput ( + IN MARVELL_GPIO_PROTOCOL *This, + IN UINTN ControllerIndex, + IN UINTN GpioPin, + IN BOOLEAN Value + ) +{ + UINTN BaseAddress; + EFI_STATUS Status; + + Status = MvGpioValidate (ControllerIndex, GpioPin); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "%a: Fail to set output for pin #%d\n", + __FUNCTION__, + GpioPin)); + return Status; + } + + BaseAddress = mGpioInstance->Desc->SoC[ControllerIndex].GpioBaseAddress; + + MmioAndThenOr32 (BaseAddress + GPIO_DATA_OUT_REG, + ~BIT (GpioPin), + (Value) << GpioPin); + + MmioAnd32 (BaseAddress + GPIO_OUT_EN_REG, ~BIT (GpioPin)); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MvGpioDirectionInput ( + IN MARVELL_GPIO_PROTOCOL *This, + IN UINTN ControllerIndex, + IN UINTN GpioPin + ) +{ + UINTN BaseAddress; + EFI_STATUS Status; + + Status = MvGpioValidate (ControllerIndex, GpioPin); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "%a: Fail to set input for pin #%d\n", + __FUNCTION__, + GpioPin)); + return Status; + } + + BaseAddress = mGpioInstance->Desc->SoC[ControllerIndex].GpioBaseAddress; + + MmioOr32 (BaseAddress + GPIO_OUT_EN_REG, BIT (GpioPin)); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MvGpioGetFunction ( + IN MARVELL_GPIO_PROTOCOL *This, + IN UINTN ControllerIndex, + IN UINTN GpioPin, + OUT MARVELL_GPIO_MODE *Mode + ) +{ + UINT32 RegVal; + UINTN BaseAddress; + EFI_STATUS Status; + + Status = MvGpioValidate (ControllerIndex, GpioPin); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "%a: Fail to get function of pin #%d\n", + __FUNCTION__, + GpioPin)); + return Status; + } + + BaseAddress = mGpioInstance->Desc->SoC[ControllerIndex].GpioBaseAddress; + + RegVal = MmioRead32 (BaseAddress + GPIO_OUT_EN_REG); + *Mode = ((RegVal & BIT (GpioPin)) ? GPIO_MODE_INPUT : GPIO_MODE_OUTPUT); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MvGpioGetValue ( + IN MARVELL_GPIO_PROTOCOL *This, + IN UINTN ControllerIndex, + IN UINTN GpioPin, + IN OUT BOOLEAN *Value + ) +{ + UINTN BaseAddress; + EFI_STATUS Status; + + Status = MvGpioValidate (ControllerIndex, GpioPin); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "%a: Fail to get value of pin #%d\n", + __FUNCTION__, + GpioPin)); + return Status; + } + + BaseAddress = mGpioInstance->Desc->SoC[ControllerIndex].GpioBaseAddress; + + *Value = !!(MmioRead32 (BaseAddress + GPIO_DATA_IN_REG) & BIT (GpioPin)); + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MvGpioSetValue ( + IN MARVELL_GPIO_PROTOCOL *This, + IN UINTN ControllerIndex, + IN UINTN GpioPin, + IN BOOLEAN Value + ) +{ + UINTN BaseAddress; + EFI_STATUS Status; + + Status = MvGpioValidate (ControllerIndex, GpioPin); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "%a: Fail to get value of pin #%d\n", + __FUNCTION__, + GpioPin)); + return Status; + } + + BaseAddress = mGpioInstance->Desc->SoC[ControllerIndex].GpioBaseAddress; + + MmioAndThenOr32 (BaseAddress + GPIO_DATA_OUT_REG, + ~BIT (GpioPin), + Value << GpioPin); + + return EFI_SUCCESS; +} + +STATIC +VOID +MvGpioInitProtocol ( + IN MARVELL_GPIO_PROTOCOL *GpioProtocol + ) +{ + GpioProtocol->DirectionInput = MvGpioDirectionInput; + GpioProtocol->DirectionOutput = MvGpioDirectionOutput; + GpioProtocol->GetFunction = MvGpioGetFunction; + GpioProtocol->GetValue = MvGpioGetValue; + GpioProtocol->SetValue = MvGpioSetValue; +} + +EFI_STATUS +EFIAPI +MvGpioEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + MARVELL_BOARD_DESC_PROTOCOL *BoardDescProtocol; + MV_GPIO_DEVICE_PATH *GpioDevicePath; + MV_BOARD_GPIO_DESC *Desc; + EFI_STATUS Status; + + GpioDevicePath = AllocateCopyPool (sizeof (MV_GPIO_DEVICE_PATH), + &mGpioDevicePathTemplate); + if (GpioDevicePath == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + mGpioInstance = AllocateZeroPool (sizeof (MV_GPIO)); + if (mGpioInstance == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ErrGpioInstanceAlloc; + } + + /* Obtain list of available controllers */ + Status = gBS->LocateProtocol (&gMarvellBoardDescProtocolGuid, + NULL, + (VOID **)&BoardDescProtocol); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "%a: Cannot locate BoardDesc protocol\n", + __FUNCTION__)); + goto ErrLocateBoardDesc; + } + + Status = BoardDescProtocol->BoardDescGpioGet (BoardDescProtocol, &Desc); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, + "%a: Cannot get GPIO board desc from BoardDesc protocol\n", + __FUNCTION__)); + goto ErrLocateBoardDesc; + } + + mGpioInstance->Signature = GPIO_SIGNATURE; + mGpioInstance->Desc = Desc; + + MvGpioInitProtocol (&mGpioInstance->GpioProtocol); + + Status = gBS->InstallMultipleProtocolInterfaces (&(mGpioInstance->Handle), + &gMarvellGpioProtocolGuid, + &(mGpioInstance->GpioProtocol), + &gEfiDevicePathProtocolGuid, + (EFI_DEVICE_PATH_PROTOCOL *)GpioDevicePath, + NULL); + if (EFI_ERROR (Status)) { + goto ErrLocateBoardDesc; + } + + return EFI_SUCCESS; + +ErrLocateBoardDesc: + gBS->FreePool (mGpioInstance); + +ErrGpioInstanceAlloc: + gBS->FreePool (GpioDevicePath); + + return Status; +} -- 2.7.4