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