From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ed1-f66.google.com (mail-ed1-f66.google.com [209.85.208.66]) by mx.groups.io with SMTP id smtpd.web10.2322.1593455981233667508 for ; Mon, 29 Jun 2020 11:39:41 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@akeo-ie.20150623.gappssmtp.com header.s=20150623 header.b=QMV++Rxw; spf=none, err=permanent DNS error (domain: akeo.ie, ip: 209.85.208.66, mailfrom: pete@akeo.ie) Received: by mail-ed1-f66.google.com with SMTP id z17so13778277edr.9 for ; Mon, 29 Jun 2020 11:39:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=akeo-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=fj41mMyPgdTphaXxLQ8eq73Lqt1lByb+ISWbT5iZcZ4=; b=QMV++Rxw7EfQNFCLv9TNrnn9PTIU3ZCTkWpOhVk9QxdO76a0ZSLDxrPV5ZDSq2TU83 Zyhmu4EzvxIND4tgqwpFEfFa38NxZICSfDfoH/HejfzznrzWCgBgSm1ny7xopgSUYqSY +QhzBwNj3robuw9D6O42oDJxxrc4BDcy0iS996cIQdmANc2PrDa5CgowXeVhrkR6eHp5 xaWuBLZl+vHOHEVJV/E6MeLsgxnPFgqdX0hJ9M2i5/PGzQ8VTIDKnGQ2uLiBSy0rWkd/ sZiBdAG0dqPoCVS6EZhLWfj5pP9bgvKeZQmPkAUEqicJUNqDUjEWm9eTeISYsb2Yi92m 8hyg== 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:mime-version :content-transfer-encoding; bh=fj41mMyPgdTphaXxLQ8eq73Lqt1lByb+ISWbT5iZcZ4=; b=gAQo0F/xrF710dJB069ZulnAf6IrWE8FtNAnJwYsgMB8DjW8yTyy5vh2iSAleT3EF8 6fys+sb5TCbV4NRzFdxcfmb6Qti6iBWsCkJ2UMWdYBq+rhkW0gjJ7fCXwSzCGh8kvnbF Dkn9tVb14arbzC9NzjOcLpy0YEJz1t6CIfYwQ7AvafEHxmgknkVke8t+wXVDC2GNn0Et sYfe0FHHjIU0qk7RPbw1YglcM+oXoQXSOqtY0wTbGHzdzwxpyPf8bQvlbuO1lOdnGcgF pIA5eOYJXYNIvTK7w48b06s69anIH4nTah0gT55I8LjPr0O5MKn+WLpA3JlTPPpYUN/q aQZw== X-Gm-Message-State: AOAM531Q9UA3JqZ7XcZDFl0h6pNbJ428ChL6BjGgafDvZ0uGhSSQ3Uzr EOIkyZf2KNeYq6BLlt75K404Ivl01Tqo8g== X-Google-Smtp-Source: ABdhPJxoVCR/ptqD++eZlX1vtTYaMvw+E7KKkBzQLQRiHZ5EyyifegnIdlMBIzlRs6gs1k7+cfDmcQ== X-Received: by 2002:a05:6402:1c8f:: with SMTP id cy15mr19075190edb.308.1593455979403; Mon, 29 Jun 2020 11:39:39 -0700 (PDT) Return-Path: Received: from localhost.localdomain ([84.203.82.173]) by smtp.gmail.com with ESMTPSA id i33sm492583edi.21.2020.06.29.11.39.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 29 Jun 2020 11:39:38 -0700 (PDT) From: "Pete Batard" To: devel@edk2.groups.io Cc: ard.biesheuvel@arm.com, leif@nuviainc.com, awarkentin@vmware.com Subject: [edk2-platforms][PATCH 1/1] Silicon/Broadcom/Bcm283x: GpioLib enhancements Date: Mon, 29 Jun 2020 19:39:26 +0100 Message-Id: <20200629183926.12332-1-pete@akeo.ie> X-Mailer: git-send-email 2.21.0.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit * Add GpioPinSet () function to set a GPIO pin value * Add GpioPinGet () function to read a GPIO pin value * Add GpioSetPull () function to set pullup/down state of a GPIO pin GpioSetPull () supports both the legacy method used on Bcm283[5-7] as well as the new method used on Bcm2711. Each of these calls was tested on Raspberry Pi 3 B+ as well as on a Raspberry Pi 4 B. Signed-off-by: Pete Batard --- Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Gpio.h | 44 ++++++++- Silicon/Broadcom/Bcm283x/Include/Library/GpioLib.h | 17 ++++ Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.c | 93 ++++++++++++++++++++ Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.inf | 1 + 4 files changed, 152 insertions(+), 3 deletions(-) diff --git a/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Gpio.h b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Gpio.h index e65cc5c3bbb4..8ad81776b43a 100644 --- a/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Gpio.h +++ b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Gpio.h @@ -1,5 +1,6 @@ /** @file * + * Copyright (c) 2020, Pete Batard * Copyright (c) 2018, Andrei Warkentin * Copyright (c) Microsoft Corporation. All rights reserved. * @@ -23,12 +24,45 @@ #define GPIO_GPFSEL4 (GPIO_BASE_ADDRESS + 0x10) #define GPIO_GPFSEL5 (GPIO_BASE_ADDRESS + 0x14) -#define GPIO_GPCLR0 (GPIO_BASE_ADDRESS + 0x28) -#define GPIO_GPCLR1 (GPIO_BASE_ADDRESS + 0x2C) - #define GPIO_GPSET0 (GPIO_BASE_ADDRESS + 0x1C) #define GPIO_GPSET1 (GPIO_BASE_ADDRESS + 0x20) +#define GPIO_GPCLR0 (GPIO_BASE_ADDRESS + 0x28) +#define GPIO_GPCLR1 (GPIO_BASE_ADDRESS + 0x2C) + +#define GPIO_GPLEV0 (GPIO_BASE_ADDRESS + 0x34) +#define GPIO_GPLEV1 (GPIO_BASE_ADDRESS + 0x38) + +#define GPIO_GPEDS0 (GPIO_BASE_ADDRESS + 0x40) +#define GPIO_GPEDS1 (GPIO_BASE_ADDRESS + 0x44) + +#define GPIO_GPREN0 (GPIO_BASE_ADDRESS + 0x4C) +#define GPIO_GPREN1 (GPIO_BASE_ADDRESS + 0x50) + +#define GPIO_GPFEN0 (GPIO_BASE_ADDRESS + 0x58) +#define GPIO_GPFEN1 (GPIO_BASE_ADDRESS + 0x5C) + +#define GPIO_GPHEN0 (GPIO_BASE_ADDRESS + 0x64) +#define GPIO_GPHEN1 (GPIO_BASE_ADDRESS + 0x68) + +#define GPIO_GPLEN0 (GPIO_BASE_ADDRESS + 0x70) +#define GPIO_GPLEN1 (GPIO_BASE_ADDRESS + 0x74) + +#define GPIO_GPAREN0 (GPIO_BASE_ADDRESS + 0x7C) +#define GPIO_GPAREN1 (GPIO_BASE_ADDRESS + 0x80) + +#define GPIO_GPAFEN0 (GPIO_BASE_ADDRESS + 0x88) +#define GPIO_GPAFEN1 (GPIO_BASE_ADDRESS + 0x8C) + +#define GPIO_GPPUD (GPIO_BASE_ADDRESS + 0x94) +#define GPIO_GPPUDCLK0 (GPIO_BASE_ADDRESS + 0x98) +#define GPIO_GPPUDCLK1 (GPIO_BASE_ADDRESS + 0x9C) + +#define GPIO_GPPUPPDN0 (GPIO_BASE_ADDRESS + 0xE4) +#define GPIO_GPPUPPDN1 (GPIO_BASE_ADDRESS + 0xE8) +#define GPIO_GPPUPPDN2 (GPIO_BASE_ADDRESS + 0xEC) +#define GPIO_GPPUPPDN3 (GPIO_BASE_ADDRESS + 0xF0) + #define GPIO_FSEL_INPUT 0x0 #define GPIO_FSEL_OUTPUT 0x1 #define GPIO_FSEL_ALT0 0x4 @@ -44,4 +78,8 @@ #define GPIO_PINS 54 +#define GPIO_PULL_NONE 0x00 +#define GPIO_PULL_DOWN 0x01 +#define GPIO_PULL_UP 0x02 + #endif /* __BCM2836_GPIO_H__ */ diff --git a/Silicon/Broadcom/Bcm283x/Include/Library/GpioLib.h b/Silicon/Broadcom/Bcm283x/Include/Library/GpioLib.h index 014c6b07a29f..75c2c8be51aa 100644 --- a/Silicon/Broadcom/Bcm283x/Include/Library/GpioLib.h +++ b/Silicon/Broadcom/Bcm283x/Include/Library/GpioLib.h @@ -24,4 +24,21 @@ GpioPinFuncGet ( IN UINTN Pin ); +VOID +GpioPinSet ( + IN UINTN Pin, + IN UINTN Val + ); + +UINTN +GpioPinGet ( + IN UINTN Pin + ); + +VOID +GpioSetPull ( + IN UINTN Pin, + IN UINTN Pud +); + #endif /* __GPIO_LIB__ */ diff --git a/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.c b/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.c index 542b6e8f6b2f..a4b4af59ebb1 100644 --- a/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.c +++ b/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.c @@ -2,6 +2,7 @@ * * GPIO manipulation. * + * Copyright (c) 2020, Pete Batard * Copyright (c) 2018, Andrei Warkentin * * SPDX-License-Identifier: BSD-2-Clause-Patent @@ -13,6 +14,7 @@ #include #include #include +#include #include #include @@ -81,3 +83,94 @@ GpioPinFuncGet ( Val &= GPIO_FSEL_MASK; return Val; } + +VOID +GpioPinSet ( + IN UINTN Pin, + IN UINTN Val + ) +{ + EFI_PHYSICAL_ADDRESS Reg; + UINTN RegIndex; + UINTN SelIndex; + + ASSERT (Pin < GPIO_PINS); + + RegIndex = Pin / 32; + SelIndex = Pin % 32; + + // + // Different base addresses are used for clear and set + // + Reg = (Val == 0) ? GPIO_GPCLR0 : GPIO_GPSET0; + Reg += RegIndex * sizeof (UINT32); + MmioWrite32 (Reg, 1 << SelIndex); +} + +UINTN +GpioPinGet ( + IN UINTN Pin + ) +{ + EFI_PHYSICAL_ADDRESS Reg; + UINTN RegIndex; + UINTN SelIndex; + UINT32 Val; + + ASSERT (Pin < GPIO_PINS); + + RegIndex = Pin / 32; + SelIndex = Pin % 32; + + Reg = RegIndex * sizeof (UINT32) + GPIO_GPLEV0; + Val = MmioRead32 (Reg) >> SelIndex; + return Val & 1; +} + +VOID +GpioSetPull ( + IN UINTN Pin, + IN UINTN Pud +) +{ + EFI_PHYSICAL_ADDRESS Reg; + UINTN RegIndex; + UINTN SelIndex; + UINT32 Val; + + ASSERT (Pin < GPIO_PINS); + ASSERT (Pud <= GPIO_PULL_UP); + + // + // Check if we should use the legacy or newer method of + // enabling pullup/pulldown by querying GPPUPPDN3, which + // is unused on Bcm2835/2836/2837 and returns 'gpio'. + // + if (MmioRead32 (GPIO_GPPUPPDN3) == 0x6770696f) { + RegIndex = Pin / 32; + SelIndex = Pin % 32; + + MmioWrite32 (GPIO_GPPUD, Pud); + MicroSecondDelay (5); + + Reg = RegIndex * sizeof (UINT32) + GPIO_GPPUDCLK0; + MmioWrite32 (Reg, 1 << SelIndex); + MicroSecondDelay (5); + + MmioWrite32 (GPIO_GPPUD, 0); + MmioWrite32 (Reg, 0); + } else { + // + // The newer method uses inverted values for up/down. + // + if (Pud != 0) + Pud ^= 0x3; + RegIndex = Pin / 16; + SelIndex = (Pin % 16) * 2; + Reg = RegIndex * sizeof (UINT32) + GPIO_GPPUPPDN0; + Val = MmioRead32 (Reg); + Val &= ~(0x3 << SelIndex); + Val |= Pud << SelIndex; + MmioWrite32 (Reg, Val); + } +} diff --git a/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.inf b/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.inf index ff1b5af6db6e..a0356306d83c 100644 --- a/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.inf +++ b/Silicon/Broadcom/Bcm283x/Library/GpioLib/GpioLib.inf @@ -30,6 +30,7 @@ [LibraryClasses] BaseLib DebugLib IoLib + TimerLib [FixedPcd] gBcm283xTokenSpaceGuid.PcdBcm283xRegistersAddress -- 2.21.0.windows.1