xref: /aosp_15_r20/external/arm-trusted-firmware/drivers/nxp/gpio/nxp_gpio.c (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park  * Copyright 2021 NXP
3*54fd6939SJiyong Park  *
4*54fd6939SJiyong Park  * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park  *
6*54fd6939SJiyong Park  */
7*54fd6939SJiyong Park 
8*54fd6939SJiyong Park #include <common/debug.h>
9*54fd6939SJiyong Park #include <lib/mmio.h>
10*54fd6939SJiyong Park #include <nxp_gpio.h>
11*54fd6939SJiyong Park 
12*54fd6939SJiyong Park static gpio_init_info_t *gpio_init_info;
13*54fd6939SJiyong Park 
gpio_init(gpio_init_info_t * gpio_init_data)14*54fd6939SJiyong Park void gpio_init(gpio_init_info_t *gpio_init_data)
15*54fd6939SJiyong Park {
16*54fd6939SJiyong Park 	gpio_init_info = gpio_init_data;
17*54fd6939SJiyong Park }
18*54fd6939SJiyong Park 
19*54fd6939SJiyong Park /* This function set GPIO pin for raising POVDD. */
set_gpio_bit(uint32_t * gpio_base_addr,uint32_t bit_num)20*54fd6939SJiyong Park int set_gpio_bit(uint32_t *gpio_base_addr,
21*54fd6939SJiyong Park 		 uint32_t bit_num)
22*54fd6939SJiyong Park {
23*54fd6939SJiyong Park 	uint32_t val = 0U;
24*54fd6939SJiyong Park 	uint32_t *gpdir = NULL;
25*54fd6939SJiyong Park 	uint32_t *gpdat = NULL;
26*54fd6939SJiyong Park 
27*54fd6939SJiyong Park 	if (gpio_init_info == NULL) {
28*54fd6939SJiyong Park 		ERROR("GPIO is not initialized.\n");
29*54fd6939SJiyong Park 		return GPIO_FAILURE;
30*54fd6939SJiyong Park 	}
31*54fd6939SJiyong Park 
32*54fd6939SJiyong Park 	gpdir = gpio_base_addr + GPDIR_REG_OFFSET;
33*54fd6939SJiyong Park 	gpdat = gpio_base_addr + (GPDAT_REG_OFFSET >> 2);
34*54fd6939SJiyong Park 
35*54fd6939SJiyong Park 	/*
36*54fd6939SJiyong Park 	 * Set the corresponding bit in direction register
37*54fd6939SJiyong Park 	 * to configure the GPIO as output.
38*54fd6939SJiyong Park 	 */
39*54fd6939SJiyong Park 	val = gpio_read32(gpdir);
40*54fd6939SJiyong Park 	val = val | bit_num;
41*54fd6939SJiyong Park 	gpio_write32(gpdir, val);
42*54fd6939SJiyong Park 
43*54fd6939SJiyong Park 	/* Set the corresponding bit in GPIO data register */
44*54fd6939SJiyong Park 	val = gpio_read32(gpdat);
45*54fd6939SJiyong Park 	val = val | bit_num;
46*54fd6939SJiyong Park 	gpio_write32(gpdat, val);
47*54fd6939SJiyong Park 
48*54fd6939SJiyong Park 	val = gpio_read32(gpdat);
49*54fd6939SJiyong Park 
50*54fd6939SJiyong Park 	if ((val & bit_num) == 0U) {
51*54fd6939SJiyong Park 		return GPIO_FAILURE;
52*54fd6939SJiyong Park 	}
53*54fd6939SJiyong Park 
54*54fd6939SJiyong Park 	return GPIO_SUCCESS;
55*54fd6939SJiyong Park }
56*54fd6939SJiyong Park 
57*54fd6939SJiyong Park /* This function reset GPIO pin set for raising POVDD. */
clr_gpio_bit(uint32_t * gpio_base_addr,uint32_t bit_num)58*54fd6939SJiyong Park int clr_gpio_bit(uint32_t *gpio_base_addr, uint32_t bit_num)
59*54fd6939SJiyong Park {
60*54fd6939SJiyong Park 	uint32_t val = 0U;
61*54fd6939SJiyong Park 	uint32_t *gpdir = NULL;
62*54fd6939SJiyong Park 	uint32_t *gpdat = NULL;
63*54fd6939SJiyong Park 
64*54fd6939SJiyong Park 
65*54fd6939SJiyong Park 	if (gpio_init_info == NULL) {
66*54fd6939SJiyong Park 		ERROR("GPIO is not initialized.\n");
67*54fd6939SJiyong Park 		return GPIO_FAILURE;
68*54fd6939SJiyong Park 	}
69*54fd6939SJiyong Park 
70*54fd6939SJiyong Park 	gpdir = gpio_base_addr + GPDIR_REG_OFFSET;
71*54fd6939SJiyong Park 	gpdat = gpio_base_addr + GPDAT_REG_OFFSET;
72*54fd6939SJiyong Park 
73*54fd6939SJiyong Park 	/*
74*54fd6939SJiyong Park 	 * Reset the corresponding bit in direction and data register
75*54fd6939SJiyong Park 	 * to configure the GPIO as input.
76*54fd6939SJiyong Park 	 */
77*54fd6939SJiyong Park 	val = gpio_read32(gpdat);
78*54fd6939SJiyong Park 	val = val & ~(bit_num);
79*54fd6939SJiyong Park 	gpio_write32(gpdat, val);
80*54fd6939SJiyong Park 
81*54fd6939SJiyong Park 	val = gpio_read32(gpdat);
82*54fd6939SJiyong Park 
83*54fd6939SJiyong Park 	val = gpio_read32(gpdir);
84*54fd6939SJiyong Park 	val = val & ~(bit_num);
85*54fd6939SJiyong Park 	gpio_write32(gpdir, val);
86*54fd6939SJiyong Park 
87*54fd6939SJiyong Park 	val = gpio_read32(gpdat);
88*54fd6939SJiyong Park 
89*54fd6939SJiyong Park 	if ((val & bit_num) != 0U) {
90*54fd6939SJiyong Park 		return GPIO_FAILURE;
91*54fd6939SJiyong Park 	}
92*54fd6939SJiyong Park 
93*54fd6939SJiyong Park 	return GPIO_SUCCESS;
94*54fd6939SJiyong Park }
95*54fd6939SJiyong Park 
select_gpio_n_bitnum(uint32_t povdd_gpio,uint32_t * bit_num)96*54fd6939SJiyong Park uint32_t *select_gpio_n_bitnum(uint32_t povdd_gpio, uint32_t *bit_num)
97*54fd6939SJiyong Park {
98*54fd6939SJiyong Park 	uint32_t *ret_gpio;
99*54fd6939SJiyong Park 	uint32_t povdd_gpio_val = 0U;
100*54fd6939SJiyong Park 	uint32_t gpio_num = 0U;
101*54fd6939SJiyong Park 
102*54fd6939SJiyong Park 	if (gpio_init_info == NULL) {
103*54fd6939SJiyong Park 		ERROR("GPIO is not initialized.\n");
104*54fd6939SJiyong Park 	}
105*54fd6939SJiyong Park 	/*
106*54fd6939SJiyong Park 	 * Subtract 1 from fuse_hdr povdd_gpio value as
107*54fd6939SJiyong Park 	 * for 0x1 value, bit 0 is to be set
108*54fd6939SJiyong Park 	 * for 0x20 value i.e 32, bit 31 i.e. 0x1f is to be set.
109*54fd6939SJiyong Park 	 * 0x1f - 0x00 : GPIO_1
110*54fd6939SJiyong Park 	 * 0x3f - 0x20 : GPIO_2
111*54fd6939SJiyong Park 	 * 0x5f - 0x40 : GPIO_3
112*54fd6939SJiyong Park 	 * 0x7f - 0x60 : GPIO_4
113*54fd6939SJiyong Park 	 */
114*54fd6939SJiyong Park 	povdd_gpio_val = (povdd_gpio - 1U) & GPIO_SEL_MASK;
115*54fd6939SJiyong Park 
116*54fd6939SJiyong Park 	/* Right shift by 5 to divide by 32 */
117*54fd6939SJiyong Park 	gpio_num = povdd_gpio_val >> GPIO_ID_BASE_ADDR_SHIFT;
118*54fd6939SJiyong Park 	*bit_num = 1U << (GPIO_BITS_PER_BASE_REG
119*54fd6939SJiyong Park 			  - (povdd_gpio_val & GPIO_BIT_MASK)
120*54fd6939SJiyong Park 			  - 1U);
121*54fd6939SJiyong Park 
122*54fd6939SJiyong Park 	switch (gpio_num) {
123*54fd6939SJiyong Park 	case GPIO_0:
124*54fd6939SJiyong Park 		ret_gpio = (uint32_t *) gpio_init_info->gpio1_base_addr;
125*54fd6939SJiyong Park 		break;
126*54fd6939SJiyong Park 	case GPIO_1:
127*54fd6939SJiyong Park 		ret_gpio = (uint32_t *) gpio_init_info->gpio2_base_addr;
128*54fd6939SJiyong Park 		break;
129*54fd6939SJiyong Park 	case GPIO_2:
130*54fd6939SJiyong Park 		ret_gpio = (uint32_t *) gpio_init_info->gpio3_base_addr;
131*54fd6939SJiyong Park 		break;
132*54fd6939SJiyong Park 	case GPIO_3:
133*54fd6939SJiyong Park 		ret_gpio = (uint32_t *) gpio_init_info->gpio4_base_addr;
134*54fd6939SJiyong Park 		break;
135*54fd6939SJiyong Park 	default:
136*54fd6939SJiyong Park 		ret_gpio = NULL;
137*54fd6939SJiyong Park 	}
138*54fd6939SJiyong Park 
139*54fd6939SJiyong Park 	if (ret_gpio == NULL) {
140*54fd6939SJiyong Park 		INFO("GPIO_NUM = %d doesn't exist.\n", gpio_num);
141*54fd6939SJiyong Park 	}
142*54fd6939SJiyong Park 
143*54fd6939SJiyong Park 	return ret_gpio;
144*54fd6939SJiyong Park }
145