1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2021 NXP
4  *
5  * Driver for GPIO Controller
6  *
7  */
8 
9 #include <assert.h>
10 #include <drivers/ls_gpio.h>
11 #include <io.h>
12 #include <kernel/boot.h>
13 #include <kernel/dt.h>
14 #include <libfdt.h>
15 #include <mm/core_memprot.h>
16 
17 static const char * const gpio_controller_map[] = {
18 	 "/soc/gpio@2300000",
19 	 "/soc/gpio@2310000",
20 	 "/soc/gpio@2320000",
21 	 "/soc/gpio@2330000"
22 };
23 
24 /*
25  * Get value from GPIO controller
26  * chip:        pointer to GPIO controller chip instance
27  * gpio_pin:    pin from which value needs to be read
28  */
gpio_get_value(struct gpio_chip * chip,unsigned int gpio_pin)29 static enum gpio_level gpio_get_value(struct gpio_chip *chip,
30 				      unsigned int gpio_pin)
31 {
32 	vaddr_t gpio_data_addr = 0;
33 	uint32_t data = 0;
34 	struct ls_gpio_chip_data *gc_data = container_of(chip,
35 						      struct ls_gpio_chip_data,
36 						      chip);
37 
38 	assert(gpio_pin <= MAX_GPIO_PINS);
39 
40 	gpio_data_addr = gc_data->gpio_base + GPIODAT;
41 	data = io_read32(gpio_data_addr);
42 
43 	if (data & PIN_SHIFT(gpio_pin))
44 		return GPIO_LEVEL_HIGH;
45 	else
46 		return GPIO_LEVEL_LOW;
47 }
48 
49 /*
50  * Set value for GPIO controller
51  * chip:        pointer to GPIO controller chip instance
52  * gpio_pin:    pin to which value needs to be write
53  * value:       value needs to be written to the pin
54  */
gpio_set_value(struct gpio_chip * chip,unsigned int gpio_pin,enum gpio_level value)55 static void gpio_set_value(struct gpio_chip *chip, unsigned int gpio_pin,
56 			   enum gpio_level value)
57 {
58 	vaddr_t gpio_data_addr = 0;
59 	struct ls_gpio_chip_data *gc_data = container_of(chip,
60 						      struct ls_gpio_chip_data,
61 						      chip);
62 
63 	assert(gpio_pin <= MAX_GPIO_PINS);
64 
65 	gpio_data_addr = gc_data->gpio_base + GPIODAT;
66 
67 	if (value == GPIO_LEVEL_HIGH)
68 		/* if value is high then set pin value */
69 		io_setbits32(gpio_data_addr, PIN_SHIFT(gpio_pin));
70 	else
71 		/* if value is low then clear pin value */
72 		io_clrbits32(gpio_data_addr, PIN_SHIFT(gpio_pin));
73 }
74 
75 /*
76  * Get direction from GPIO controller
77  * chip:        pointer to GPIO controller chip instance
78  * gpio_pin:    pin from which direction needs to be read
79  */
gpio_get_direction(struct gpio_chip * chip,unsigned int gpio_pin)80 static enum gpio_dir gpio_get_direction(struct gpio_chip *chip,
81 					unsigned int gpio_pin)
82 {
83 	vaddr_t gpio_dir_addr = 0;
84 	uint32_t data = 0;
85 	struct ls_gpio_chip_data *gc_data = container_of(chip,
86 						      struct ls_gpio_chip_data,
87 						      chip);
88 
89 	assert(gpio_pin <= MAX_GPIO_PINS);
90 
91 	gpio_dir_addr = gc_data->gpio_base + GPIODIR;
92 	data = io_read32(gpio_dir_addr);
93 
94 	if (data & PIN_SHIFT(gpio_pin))
95 		return GPIO_DIR_OUT;
96 	else
97 		return GPIO_DIR_IN;
98 }
99 
100 /*
101  * Set direction for GPIO controller
102  * chip:        pointer to GPIO controller chip instance
103  * gpio_pin:    pin on which direction needs to be set
104  * direction:   direction which needs to be set on pin
105  */
gpio_set_direction(struct gpio_chip * chip,unsigned int gpio_pin,enum gpio_dir direction)106 static void gpio_set_direction(struct gpio_chip *chip, unsigned int gpio_pin,
107 			       enum gpio_dir direction)
108 {
109 	vaddr_t gpio_dir_addr = 0;
110 	struct ls_gpio_chip_data *gc_data = container_of(chip,
111 						      struct ls_gpio_chip_data,
112 						      chip);
113 
114 	assert(gpio_pin <= MAX_GPIO_PINS);
115 
116 	gpio_dir_addr = gc_data->gpio_base + GPIODIR;
117 
118 	if (direction == GPIO_DIR_OUT)
119 		io_setbits32(gpio_dir_addr, PIN_SHIFT(gpio_pin));
120 	else
121 		io_clrbits32(gpio_dir_addr, PIN_SHIFT(gpio_pin));
122 }
123 
124 /*
125  * Get interrupt from GPIO controller
126  * chip:        pointer to GPIO controller chip instance
127  * gpio_pin:    pin from which interrupt value needs to be read
128  */
gpio_get_interrupt(struct gpio_chip * chip,unsigned int gpio_pin)129 static enum gpio_interrupt gpio_get_interrupt(struct gpio_chip *chip,
130 					      unsigned int gpio_pin)
131 {
132 	vaddr_t gpio_ier_addr = 0;
133 	uint32_t data = 0;
134 	struct ls_gpio_chip_data *gc_data = container_of(chip,
135 						      struct ls_gpio_chip_data,
136 						      chip);
137 
138 	assert(gpio_pin <= MAX_GPIO_PINS);
139 
140 	gpio_ier_addr = gc_data->gpio_base + GPIOIER;
141 	data = io_read32(gpio_ier_addr);
142 
143 	if (data & PIN_SHIFT(gpio_pin))
144 		return GPIO_INTERRUPT_ENABLE;
145 	else
146 		return GPIO_INTERRUPT_DISABLE;
147 }
148 
149 /*
150  * Set interrupt event for GPIO controller
151  * chip:        pointer to GPIO controller chip instance
152  * gpio_pin:    pin on which interrupt value needs to be set
153  * interrupt:   interrupt valie which needs to be set on pin
154  */
gpio_set_interrupt(struct gpio_chip * chip,unsigned int gpio_pin,enum gpio_interrupt interrupt)155 static void gpio_set_interrupt(struct gpio_chip *chip, unsigned int gpio_pin,
156 			       enum gpio_interrupt interrupt)
157 {
158 	vaddr_t gpio_ier_addr = 0;
159 	struct ls_gpio_chip_data *gc_data = container_of(chip,
160 						      struct ls_gpio_chip_data,
161 						      chip);
162 
163 	assert(gpio_pin <= MAX_GPIO_PINS);
164 
165 	gpio_ier_addr = gc_data->gpio_base + GPIOIER;
166 
167 	if (interrupt == GPIO_INTERRUPT_ENABLE)
168 		io_setbits32(gpio_ier_addr, PIN_SHIFT(gpio_pin));
169 	else
170 		io_clrbits32(gpio_ier_addr, PIN_SHIFT(gpio_pin));
171 }
172 
173 /*
174  * Extract information for GPIO Controller from the DTB
175  * gpio_data:	GPIO controller chip instance
176  */
get_info_from_device_tree(struct ls_gpio_chip_data * gpio_data)177 static TEE_Result get_info_from_device_tree(struct ls_gpio_chip_data *gpio_data)
178 {
179 	size_t size = 0;
180 	int node = 0;
181 	vaddr_t ctrl_base = 0;
182 	void *fdt = NULL;
183 
184 	/*
185 	 * First get the GPIO Controller base address from the DTB
186 	 * if DTB present and if the GPIO Controller defined in it.
187 	 */
188 	fdt = get_embedded_dt();
189 	if (!fdt) {
190 		EMSG("Unable to get the Embedded DTB, GPIO init failed\n");
191 		return TEE_ERROR_GENERIC;
192 	}
193 
194 	node = fdt_path_offset(fdt, gpio_controller_map
195 			       [gpio_data->gpio_controller]);
196 	if (node > 0) {
197 		if (dt_map_dev(fdt, node, &ctrl_base, &size,
198 			       DT_MAP_AUTO) < 0) {
199 			EMSG("Unable to get virtual address");
200 			return TEE_ERROR_GENERIC;
201 		}
202 	} else {
203 		EMSG("Unable to get gpio offset node");
204 		return TEE_ERROR_ITEM_NOT_FOUND;
205 	}
206 
207 	gpio_data->gpio_base = ctrl_base;
208 
209 	return TEE_SUCCESS;
210 }
211 
212 static const struct gpio_ops ls_gpio_ops = {
213 	.get_direction = gpio_get_direction,
214 	.set_direction = gpio_set_direction,
215 	.get_value = gpio_get_value,
216 	.set_value = gpio_set_value,
217 	.get_interrupt = gpio_get_interrupt,
218 	.set_interrupt = gpio_set_interrupt,
219 };
220 DECLARE_KEEP_PAGER(ls_gpio_ops);
221 
ls_gpio_init(struct ls_gpio_chip_data * gpio_data)222 TEE_Result ls_gpio_init(struct ls_gpio_chip_data *gpio_data)
223 {
224 	TEE_Result status = TEE_ERROR_GENERIC;
225 
226 	/*
227 	 * First get the GPIO Controller base address from the DTB,
228 	 * if DTB present and if the GPIO Controller defined in it.
229 	 */
230 	status = get_info_from_device_tree(gpio_data);
231 	if (status == TEE_SUCCESS) {
232 		/* set GPIO Input Buffer Enable register */
233 		io_setbits32(gpio_data->gpio_base + GPIOIBE, UINT32_MAX);
234 
235 		/* generic GPIO chip handle */
236 		gpio_data->chip.ops = &ls_gpio_ops;
237 	} else {
238 		EMSG("Unable to get info from device tree");
239 	}
240 
241 	return status;
242 }
243