summaryrefslogtreecommitdiff
path: root/drivers/nxp
diff options
context:
space:
mode:
authorPankaj Gupta <pankaj.gupta@nxp.com>2020-12-09 14:02:39 +0530
committerPankaj Gupta <pankaj.gupta@nxp.com>2021-03-24 09:49:31 +0530
commite3e48b5c3872609181f8e0a1f441c676a694b213 (patch)
tree7dedbcf45f57682a2998801463fc723917f92d99 /drivers/nxp
parent34412eda32c8678e0ea7479a5dac24e6d8959484 (diff)
downloadarm-trusted-firmware-e3e48b5c3872609181f8e0a1f441c676a694b213.tar.gz
nxp: gpio driver support
NXP General Purpose Input/Output driver support for NXP platforms. Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com> Change-Id: I9a3574f1d5d12e4a65ff60f640d4e77e2defd6d4
Diffstat (limited to 'drivers/nxp')
-rw-r--r--drivers/nxp/gpio/gpio.mk30
-rw-r--r--drivers/nxp/gpio/nxp_gpio.c144
-rw-r--r--drivers/nxp/gpio/nxp_gpio.h53
3 files changed, 227 insertions, 0 deletions
diff --git a/drivers/nxp/gpio/gpio.mk b/drivers/nxp/gpio/gpio.mk
new file mode 100644
index 000000000..157c60a16
--- /dev/null
+++ b/drivers/nxp/gpio/gpio.mk
@@ -0,0 +1,30 @@
+#
+# Copyright 2021 NXP
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-----------------------------------------------------------------------------
+
+ifeq (${GPIO_ADDED},)
+
+GPIO_ADDED := 1
+
+GPIO_DRIVERS_PATH := drivers/nxp/gpio
+
+PLAT_INCLUDES += -I$(GPIO_DRIVERS_PATH)
+
+GPIO_SOURCES := $(GPIO_DRIVERS_PATH)/nxp_gpio.c
+
+ifeq (${BL_COMM_GPIO_NEEDED},yes)
+BL_COMMON_SOURCES += ${GPIO_SOURCES}
+else
+ifeq (${BL2_GPIO_NEEDED},yes)
+BL2_SOURCES += ${GPIO_SOURCES}
+endif
+ifeq (${BL31_GPIO_NEEDED},yes)
+BL31_SOURCES += ${GPIO_SOURCES}
+endif
+endif
+
+endif
+#------------------------------------------------
diff --git a/drivers/nxp/gpio/nxp_gpio.c b/drivers/nxp/gpio/nxp_gpio.c
new file mode 100644
index 000000000..28c9db979
--- /dev/null
+++ b/drivers/nxp/gpio/nxp_gpio.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <common/debug.h>
+#include <lib/mmio.h>
+#include <nxp_gpio.h>
+
+static gpio_init_info_t *gpio_init_info;
+
+void gpio_init(gpio_init_info_t *gpio_init_data)
+{
+ gpio_init_info = gpio_init_data;
+}
+
+/* This function set GPIO pin for raising POVDD. */
+int set_gpio_bit(uint32_t *gpio_base_addr,
+ uint32_t bit_num)
+{
+ uint32_t val = 0U;
+ uint32_t *gpdir = NULL;
+ uint32_t *gpdat = NULL;
+
+ if (gpio_init_info == NULL) {
+ ERROR("GPIO is not initialized.\n");
+ return GPIO_FAILURE;
+ }
+
+ gpdir = gpio_base_addr + GPDIR_REG_OFFSET;
+ gpdat = gpio_base_addr + (GPDAT_REG_OFFSET >> 2);
+
+ /*
+ * Set the corresponding bit in direction register
+ * to configure the GPIO as output.
+ */
+ val = gpio_read32(gpdir);
+ val = val | bit_num;
+ gpio_write32(gpdir, val);
+
+ /* Set the corresponding bit in GPIO data register */
+ val = gpio_read32(gpdat);
+ val = val | bit_num;
+ gpio_write32(gpdat, val);
+
+ val = gpio_read32(gpdat);
+
+ if ((val & bit_num) == 0U) {
+ return GPIO_FAILURE;
+ }
+
+ return GPIO_SUCCESS;
+}
+
+/* This function reset GPIO pin set for raising POVDD. */
+int clr_gpio_bit(uint32_t *gpio_base_addr, uint32_t bit_num)
+{
+ uint32_t val = 0U;
+ uint32_t *gpdir = NULL;
+ uint32_t *gpdat = NULL;
+
+
+ if (gpio_init_info == NULL) {
+ ERROR("GPIO is not initialized.\n");
+ return GPIO_FAILURE;
+ }
+
+ gpdir = gpio_base_addr + GPDIR_REG_OFFSET;
+ gpdat = gpio_base_addr + GPDAT_REG_OFFSET;
+
+ /*
+ * Reset the corresponding bit in direction and data register
+ * to configure the GPIO as input.
+ */
+ val = gpio_read32(gpdat);
+ val = val & ~(bit_num);
+ gpio_write32(gpdat, val);
+
+ val = gpio_read32(gpdat);
+
+ val = gpio_read32(gpdir);
+ val = val & ~(bit_num);
+ gpio_write32(gpdir, val);
+
+ val = gpio_read32(gpdat);
+
+ if ((val & bit_num) != 0U) {
+ return GPIO_FAILURE;
+ }
+
+ return GPIO_SUCCESS;
+}
+
+uint32_t *select_gpio_n_bitnum(uint32_t povdd_gpio, uint32_t *bit_num)
+{
+ uint32_t *ret_gpio;
+ uint32_t povdd_gpio_val = 0U;
+ uint32_t gpio_num = 0U;
+
+ if (gpio_init_info == NULL) {
+ ERROR("GPIO is not initialized.\n");
+ }
+ /*
+ * Subtract 1 from fuse_hdr povdd_gpio value as
+ * for 0x1 value, bit 0 is to be set
+ * for 0x20 value i.e 32, bit 31 i.e. 0x1f is to be set.
+ * 0x1f - 0x00 : GPIO_1
+ * 0x3f - 0x20 : GPIO_2
+ * 0x5f - 0x40 : GPIO_3
+ * 0x7f - 0x60 : GPIO_4
+ */
+ povdd_gpio_val = (povdd_gpio - 1U) & GPIO_SEL_MASK;
+
+ /* Right shift by 5 to divide by 32 */
+ gpio_num = povdd_gpio_val >> GPIO_ID_BASE_ADDR_SHIFT;
+ *bit_num = 1U << (GPIO_BITS_PER_BASE_REG
+ - (povdd_gpio_val & GPIO_BIT_MASK)
+ - 1U);
+
+ switch (gpio_num) {
+ case GPIO_0:
+ ret_gpio = (uint32_t *) gpio_init_info->gpio1_base_addr;
+ break;
+ case GPIO_1:
+ ret_gpio = (uint32_t *) gpio_init_info->gpio2_base_addr;
+ break;
+ case GPIO_2:
+ ret_gpio = (uint32_t *) gpio_init_info->gpio3_base_addr;
+ break;
+ case GPIO_3:
+ ret_gpio = (uint32_t *) gpio_init_info->gpio4_base_addr;
+ break;
+ default:
+ ret_gpio = NULL;
+ }
+
+ if (ret_gpio == NULL) {
+ INFO("GPIO_NUM = %d doesn't exist.\n", gpio_num);
+ }
+
+ return ret_gpio;
+}
diff --git a/drivers/nxp/gpio/nxp_gpio.h b/drivers/nxp/gpio/nxp_gpio.h
new file mode 100644
index 000000000..df758404c
--- /dev/null
+++ b/drivers/nxp/gpio/nxp_gpio.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2021 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PLAT_GPIO_H
+#define PLAT_GPIO_H
+
+#include <endian.h>
+#include <lib/mmio.h>
+
+/* GPIO Register offset */
+#define GPIO_SEL_MASK 0x7F
+#define GPIO_BIT_MASK 0x1F
+#define GPDIR_REG_OFFSET 0x0
+#define GPDAT_REG_OFFSET 0x8
+
+#define GPIO_ID_BASE_ADDR_SHIFT 5U
+#define GPIO_BITS_PER_BASE_REG 32U
+
+#define GPIO_0 0
+#define GPIO_1 1
+#define GPIO_2 2
+#define GPIO_3 3
+
+#define GPIO_SUCCESS 0x0
+#define GPIO_FAILURE 0x1
+
+#ifdef NXP_GPIO_BE
+#define gpio_read32(a) bswap32(mmio_read_32((uintptr_t)(a)))
+#define gpio_write32(a, v) mmio_write_32((uintptr_t)(a), bswap32(v))
+#elif defined(NXP_GPIO_LE)
+#define gpio_read32(a) mmio_read_32((uintptr_t)(a))
+#define gpio_write32(a, v) mmio_write_32((uintptr_t)(a), (v))
+#else
+#error Please define GPIO register endianness
+#endif
+
+typedef struct {
+ uintptr_t gpio1_base_addr;
+ uintptr_t gpio2_base_addr;
+ uintptr_t gpio3_base_addr;
+ uintptr_t gpio4_base_addr;
+} gpio_init_info_t;
+
+void gpio_init(gpio_init_info_t *gpio_init_data);
+uint32_t *select_gpio_n_bitnum(uint32_t povdd_gpio, uint32_t *bit_num);
+int clr_gpio_bit(uint32_t *gpio_base_addr, uint32_t bit_num);
+int set_gpio_bit(uint32_t *gpio_base_addr, uint32_t bit_num);
+
+#endif /* PLAT_GPIO_H */