From patchwork Tue Aug 18 09:04:52 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haojian Zhuang X-Patchwork-Id: 52491 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f72.google.com (mail-la0-f72.google.com [209.85.215.72]) by patches.linaro.org (Postfix) with ESMTPS id 75F7822DB1 for ; Tue, 18 Aug 2015 09:05:14 +0000 (UTC) Received: by labia3 with SMTP id ia3sf55204317lab.1 for ; Tue, 18 Aug 2015 02:05:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:subject:precedence:list-id:list-unsubscribe:list-archive :list-post:list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:errors-to:x-original-sender :x-original-authentication-results:mailing-list; bh=JXsAcqVObcCTSNxl7ahhl3Quy5DikqQsTWhh9Xg00RU=; b=gOUw70qCMNnk6EP5ePd04UIp8niJKzaNCFPM11aNXTpp4a6KIiHEkMTtdqos3YcG9g ck56Qe/vRyVDNhJq8L5sR6ZNN8NqKK5tGcmZCi6+oEeTGROw7oa5+0sTzzJ3Zt4HSVKe q179BUemDjogSsUM3DfJ4ASuwZM7ndUxYCZdrtrBUQ+EVgAmXJBa6035QEINvwe+yAtg 3rK+tR1SbKsWpzm/H3sVmRAtkHQkzUI/ySSigAMMHvl9gkdnTJ6i6EUtwIiTm51mJyOT dr9Va/awc/di/PXBGe7oMn2g9QbYu+H/U38lne+YRAFNFa0td2zwOVjwvYTYME1Wt7t9 1/jw== X-Gm-Message-State: ALoCoQlkDTQTLtj8TuY/e/G5LVNZZD7r4rEJmbYgK63QpLKC9vPiWLTzXRV0uY5Xtg+eH1NokefA X-Received: by 10.112.99.37 with SMTP id en5mr1537594lbb.7.1439888713458; Tue, 18 Aug 2015 02:05:13 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.6.196 with SMTP id d4ls839983laa.91.gmail; Tue, 18 Aug 2015 02:05:13 -0700 (PDT) X-Received: by 10.112.170.103 with SMTP id al7mr5413740lbc.66.1439888713307; Tue, 18 Aug 2015 02:05:13 -0700 (PDT) Received: from mail-lb0-f181.google.com (mail-lb0-f181.google.com. [209.85.217.181]) by mx.google.com with ESMTPS id l9si13654841laf.101.2015.08.18.02.05.13 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 18 Aug 2015 02:05:13 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.181 as permitted sender) client-ip=209.85.217.181; Received: by lbbtg9 with SMTP id tg9so99279687lbb.1 for ; Tue, 18 Aug 2015 02:05:13 -0700 (PDT) X-Received: by 10.112.235.130 with SMTP id um2mr1464893lbc.72.1439888713199; Tue, 18 Aug 2015 02:05:13 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.162.200 with SMTP id yc8csp347944lbb; Tue, 18 Aug 2015 02:05:12 -0700 (PDT) X-Received: by 10.107.15.81 with SMTP id x78mr2691041ioi.168.1439888711282; Tue, 18 Aug 2015 02:05:11 -0700 (PDT) Received: from lists.sourceforge.net (lists.sourceforge.net. [216.34.181.88]) by mx.google.com with ESMTPS id k196si11756737ioe.130.2015.08.18.02.05.10 (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 18 Aug 2015 02:05:11 -0700 (PDT) Received-SPF: pass (google.com: domain of edk2-devel-bounces@lists.sourceforge.net designates 216.34.181.88 as permitted sender) client-ip=216.34.181.88; Received: from localhost ([127.0.0.1] helo=sfs-ml-1.v29.ch3.sourceforge.com) by sfs-ml-1.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1ZRcpF-000462-AB; Tue, 18 Aug 2015 09:04:57 +0000 Received: from sog-mx-4.v43.ch3.sourceforge.com ([172.29.43.194] helo=mx.sourceforge.net) by sfs-ml-1.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from ) id 1ZRcpC-00045r-Ak for edk2-devel@lists.sourceforge.net; Tue, 18 Aug 2015 09:04:54 +0000 Received-SPF: pass (sog-mx-4.v43.ch3.sourceforge.com: domain of linaro.org designates 209.85.220.52 as permitted sender) client-ip=209.85.220.52; envelope-from=haojian.zhuang@linaro.org; helo=mail-pa0-f52.google.com; Received: from mail-pa0-f52.google.com ([209.85.220.52]) by sog-mx-4.v43.ch3.sourceforge.com with esmtps (TLSv1:RC4-SHA:128) (Exim 4.76) id 1ZRcpA-00041e-W7 for edk2-devel@lists.sourceforge.net; Tue, 18 Aug 2015 09:04:54 +0000 Received: by pawq9 with SMTP id q9so31135960paw.3 for ; Tue, 18 Aug 2015 02:04:47 -0700 (PDT) X-Received: by 10.66.160.40 with SMTP id xh8mr11367215pab.10.1439888687329; Tue, 18 Aug 2015 02:04:47 -0700 (PDT) Received: from debian.mars ([199.101.119.141]) by smtp.gmail.com with ESMTPSA id jr12sm17266725pbb.91.2015.08.18.02.04.44 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 18 Aug 2015 02:04:46 -0700 (PDT) From: Haojian Zhuang To: ard.biesheuvel@linaro.org, edk2-devel@lists.sourceforge.net, ryan.harkin@linaro.org, leif.lindholm@linaro.org, edk2-devel@lists.01.org Date: Tue, 18 Aug 2015 17:04:52 +0800 Message-Id: <1439888692-2304-2-git-send-email-haojian.zhuang@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1439888692-2304-1-git-send-email-haojian.zhuang@linaro.org> References: <1439888692-2304-1-git-send-email-haojian.zhuang@linaro.org> X-Spam-Score: 1.0 (+) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain -0.0 SPF_PASS SPF: sender matches SPF record 2.5 SUSPICIOUS_RECIPS Similar addresses in recipient list X-Headers-End: 1ZRcpA-00041e-W7 Subject: [edk2] [PATCH 3/3] ArmPlatformPkg: PL061: support multiple controller X-BeenThere: edk2-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Errors-To: edk2-devel-bounces@lists.sourceforge.net X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: haojian.zhuang@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.181 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 Support multiple PL061 controllers. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Haojian Zhuang --- ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c | 107 ++++++++++++++------- .../Drivers/PL061GpioDxe/PL061GpioDxe.inf | 3 +- ArmPlatformPkg/Include/Drivers/PL061Gpio.h | 40 ++++---- 3 files changed, 96 insertions(+), 54 deletions(-) diff --git a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c index e8a2094..3027656 100644 --- a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c +++ b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061Gpio.c @@ -28,6 +28,7 @@ #include BOOLEAN mPL061Initialized = FALSE; +PLATFORM_GPIO_CONTROLLER *mPL061PlatformGpio; /** Function implementations @@ -38,20 +39,31 @@ PL061Identify ( VOID ) { - // Check if this is a PrimeCell Peripheral - if ( (MmioRead8 (PL061_GPIO_PCELL_ID0) != 0x0D) - || (MmioRead8 (PL061_GPIO_PCELL_ID1) != 0xF0) - || (MmioRead8 (PL061_GPIO_PCELL_ID2) != 0x05) - || (MmioRead8 (PL061_GPIO_PCELL_ID3) != 0xB1)) { - return EFI_NOT_FOUND; + UINTN Index; + UINT32 RegisterBase; + + if ( (mPL061PlatformGpio->GpioCount == 0) + || (mPL061PlatformGpio->GpioControllerCount == 0)) { + return EFI_NOT_FOUND; } - // Check if this PrimeCell Peripheral is the PL061 GPIO - if ( (MmioRead8 (PL061_GPIO_PERIPH_ID0) != 0x61) - || (MmioRead8 (PL061_GPIO_PERIPH_ID1) != 0x10) - || ((MmioRead8 (PL061_GPIO_PERIPH_ID2) & 0xF) != 0x04) - || (MmioRead8 (PL061_GPIO_PERIPH_ID3) != 0x00)) { - return EFI_NOT_FOUND; + for (Index = 0; Index < mPL061PlatformGpio->GpioControllerCount; Index++) { + RegisterBase = (UINT32) mPL061PlatformGpio->GpioController[Index].RegisterBase; + // Check if this is a PrimeCell Peripheral + if ( (MmioRead8 (RegisterBase + PL061_GPIO_PCELL_ID0) != 0x0D) + || (MmioRead8 (RegisterBase + PL061_GPIO_PCELL_ID1) != 0xF0) + || (MmioRead8 (RegisterBase + PL061_GPIO_PCELL_ID2) != 0x05) + || (MmioRead8 (RegisterBase + PL061_GPIO_PCELL_ID3) != 0xB1)) { + return EFI_NOT_FOUND; + } + + // Check if this PrimeCell Peripheral is the PL061 GPIO + if ( (MmioRead8 (RegisterBase + PL061_GPIO_PERIPH_ID0) != 0x61) + || (MmioRead8 (RegisterBase + PL061_GPIO_PERIPH_ID1) != 0x10) + || ((MmioRead8 (RegisterBase + PL061_GPIO_PERIPH_ID2) & 0xF) != 0x04) + || (MmioRead8 (RegisterBase + PL061_GPIO_PERIPH_ID3) != 0x00)) { + return EFI_NOT_FOUND; + } } return EFI_SUCCESS; @@ -84,6 +96,30 @@ PL061Initialize ( return Status; } +EFI_STATUS +EFIAPI +PL061Locate ( + IN EMBEDDED_GPIO_PIN Gpio, + OUT UINT32 *ControllerIndex, + OUT UINT32 *ControllerOffset, + OUT UINT32 *RegisterBase + ) +{ + UINT32 Index; + + for (Index = 0; Index < mPL061PlatformGpio->GpioControllerCount; Index++) { + if ( (Gpio >= mPL061PlatformGpio->GpioController[Index].GpioIndex) + && (Gpio < mPL061PlatformGpio->GpioController[Index].GpioIndex + + mPL061PlatformGpio->GpioController[Index].InternalGpioCount)) { + *ControllerIndex = Index; + *ControllerOffset = Gpio % mPL061PlatformGpio->GpioController[Index].InternalGpioCount; + *RegisterBase = mPL061PlatformGpio->GpioController[Index].RegisterBase; + return EFI_SUCCESS; + } + } + return EFI_INVALID_PARAMETER; +} + /** Routine Description: @@ -110,11 +146,15 @@ Get ( ) { EFI_STATUS Status = EFI_SUCCESS; + UINT32 Index, Offset, RegisterBase; - if ( (Value == NULL) - || (Gpio > LAST_GPIO_PIN)) - { - return EFI_INVALID_PARAMETER; + Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase); + if (EFI_ERROR (Status)) + goto EXIT; + + if (Value == NULL) { + Status = EFI_INVALID_PARAMETER; + goto EXIT; } // Initialize the hardware if not already done @@ -125,7 +165,7 @@ Get ( } } - if (MmioRead8 (PL061_GPIO_DATA_REG + (GPIO_PIN_MASK(Gpio) << 2))) { + if (MmioRead8 (RegisterBase + PL061_GPIO_DATA_REG + (GPIO_PIN_MASK(Offset) << 2))) { *Value = 1; } else { *Value = 0; @@ -162,12 +202,11 @@ Set ( ) { EFI_STATUS Status = EFI_SUCCESS; + UINT32 Index, Offset, RegisterBase; - // Check for errors - if (Gpio > LAST_GPIO_PIN) { - Status = EFI_INVALID_PARAMETER; + Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase); + if (EFI_ERROR (Status)) goto EXIT; - } // Initialize the hardware if not already done if (!mPL061Initialized) { @@ -181,21 +220,21 @@ Set ( { case GPIO_MODE_INPUT: // Set the corresponding direction bit to LOW for input - MmioAnd8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK(Gpio)); + MmioAnd8 (RegisterBase + PL061_GPIO_DIR_REG, GPIO_PIN_MASK(Offset)); break; case GPIO_MODE_OUTPUT_0: // Set the corresponding data bit to LOW for 0 - MmioWrite8 (PL061_GPIO_DATA_REG + (GPIO_PIN_MASK(Gpio) << 2), GPIO_PIN_MASK(Gpio)); + MmioWrite8 (RegisterBase + PL061_GPIO_DATA_REG + (GPIO_PIN_MASK(Offset) << 2), 0); // Set the corresponding direction bit to HIGH for output - MmioOr8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK(Gpio)); + MmioOr8 (RegisterBase + PL061_GPIO_DIR_REG, GPIO_PIN_MASK(Offset)); break; case GPIO_MODE_OUTPUT_1: // Set the corresponding data bit to HIGH for 1 - MmioWrite8 (PL061_GPIO_DATA_REG + (GPIO_PIN_MASK(Gpio) << 2), GPIO_PIN_MASK(Gpio)); + MmioWrite8 (RegisterBase + PL061_GPIO_DATA_REG + (GPIO_PIN_MASK(Offset) << 2), 0xff); // Set the corresponding direction bit to HIGH for output - MmioOr8 (PL061_GPIO_DIR_REG, GPIO_PIN_MASK(Gpio)); + MmioOr8 (RegisterBase + PL061_GPIO_DIR_REG, GPIO_PIN_MASK(Offset)); break; default: @@ -234,12 +273,11 @@ GetMode ( ) { EFI_STATUS Status; + UINT32 Index, Offset, RegisterBase; - // Check for errors - if ( (Mode == NULL) - || (Gpio > LAST_GPIO_PIN)) { - return EFI_INVALID_PARAMETER; - } + Status = PL061Locate (Gpio, &Index, &Offset, &RegisterBase); + if (EFI_ERROR (Status)) + return Status; // Initialize the hardware if not already done if (!mPL061Initialized) { @@ -250,9 +288,9 @@ GetMode ( } // Check if it is input or output - if (MmioRead8 (PL061_GPIO_DIR_REG + (GPIO_PIN_MASK(Gpio) << 2))) { + if (MmioRead8 (RegisterBase + PL061_GPIO_DIR_REG) & GPIO_PIN_MASK(Offset)) { // Pin set to output - if (MmioRead8 (PL061_GPIO_DATA_REG) & GPIO_PIN_MASK(Gpio)) { + if (MmioRead8 (RegisterBase + PL061_GPIO_DATA_REG) & GPIO_PIN_MASK(Offset)) { *Mode = GPIO_MODE_OUTPUT_1; } else { *Mode = GPIO_MODE_OUTPUT_0; @@ -329,6 +367,9 @@ PL061InstallProtocol ( // ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEmbeddedGpioProtocolGuid); + Status = gBS->LocateProtocol (&gPlatformGpioProtocolGuid, NULL, (VOID **)&mPL061PlatformGpio); + ASSERT_EFI_ERROR (Status); + // Install the Embedded GPIO Protocol onto a new handle Handle = NULL; Status = gBS->InstallMultipleProtocolInterfaces( diff --git a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf index 9d9e4cd..971452c 100644 --- a/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf +++ b/ArmPlatformPkg/Drivers/PL061GpioDxe/PL061GpioDxe.inf @@ -45,6 +45,7 @@ [Protocols] gEmbeddedGpioProtocolGuid + gPlatformGpioProtocolGuid [Depex] - TRUE + gPlatformGpioProtocolGuid diff --git a/ArmPlatformPkg/Include/Drivers/PL061Gpio.h b/ArmPlatformPkg/Include/Drivers/PL061Gpio.h index d436fd4..98d7bc2 100644 --- a/ArmPlatformPkg/Include/Drivers/PL061Gpio.h +++ b/ArmPlatformPkg/Include/Drivers/PL061Gpio.h @@ -19,26 +19,26 @@ #include // PL061 GPIO Registers -#define PL061_GPIO_DATA_REG ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0x000) -#define PL061_GPIO_DIR_REG ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0x400) -#define PL061_GPIO_IS_REG ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0x404) -#define PL061_GPIO_IBE_REG ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0x408) -#define PL061_GPIO_IEV_REG ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0x40C) -#define PL061_GPIO_IE_REG ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0x410) -#define PL061_GPIO_RIS_REG ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0x414) -#define PL061_GPIO_MIS_REG ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0x410) -#define PL061_GPIO_IC_REG ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0x41C) -#define PL061_GPIO_AFSEL_REG ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0x420) - -#define PL061_GPIO_PERIPH_ID0 ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0xFE0) -#define PL061_GPIO_PERIPH_ID1 ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0xFE4) -#define PL061_GPIO_PERIPH_ID2 ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0xFE8) -#define PL061_GPIO_PERIPH_ID3 ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0xFEC) - -#define PL061_GPIO_PCELL_ID0 ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0xFF0) -#define PL061_GPIO_PCELL_ID1 ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0xFF4) -#define PL061_GPIO_PCELL_ID2 ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0xFF8) -#define PL061_GPIO_PCELL_ID3 ((UINT32)PcdGet32 (PcdPL061GpioBase) + 0xFFC) +#define PL061_GPIO_DATA_REG 0x000 +#define PL061_GPIO_DIR_REG 0x400 +#define PL061_GPIO_IS_REG 0x404 +#define PL061_GPIO_IBE_REG 0x408 +#define PL061_GPIO_IEV_REG 0x40C +#define PL061_GPIO_IE_REG 0x410 +#define PL061_GPIO_RIS_REG 0x414 +#define PL061_GPIO_MIS_REG 0x410 +#define PL061_GPIO_IC_REG 0x41C +#define PL061_GPIO_AFSEL_REG 0x420 + +#define PL061_GPIO_PERIPH_ID0 0xFE0 +#define PL061_GPIO_PERIPH_ID1 0xFE4 +#define PL061_GPIO_PERIPH_ID2 0xFE8 +#define PL061_GPIO_PERIPH_ID3 0xFEC + +#define PL061_GPIO_PCELL_ID0 0xFF0 +#define PL061_GPIO_PCELL_ID1 0xFF4 +#define PL061_GPIO_PCELL_ID2 0xFF8 +#define PL061_GPIO_PCELL_ID3 0xFFC // GPIO pins are numbered 0..7