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
This commit is contained in:
parent
34412eda32
commit
e3e48b5c38
|
@ -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
|
||||
#------------------------------------------------
|
|
@ -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;
|
||||
}
|
|
@ -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 */
|
Loading…
Reference in New Issue