diff options
author | Pankaj Gupta <pankaj.gupta@nxp.com> | 2020-12-09 14:02:39 +0530 |
---|---|---|
committer | Pankaj Gupta <pankaj.gupta@nxp.com> | 2021-03-24 09:49:31 +0530 |
commit | e3e48b5c3872609181f8e0a1f441c676a694b213 (patch) | |
tree | 7dedbcf45f57682a2998801463fc723917f92d99 /drivers/nxp | |
parent | 34412eda32c8678e0ea7479a5dac24e6d8959484 (diff) | |
download | arm-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.mk | 30 | ||||
-rw-r--r-- | drivers/nxp/gpio/nxp_gpio.c | 144 | ||||
-rw-r--r-- | drivers/nxp/gpio/nxp_gpio.h | 53 |
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 */ |