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