xref: /optee_os/core/drivers/versal_gpio.c (revision 748d43be1495f384cc9f3213403327ca44499ff0)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright (C) 2002 - 2021 Xilinx, Inc.  All rights reserved.
4  * Copyright (c) 2022 Foundries.io Ltd. (jorge@foundries.io)
5  */
6 #include <arm.h>
7 #include <assert.h>
8 #include <crypto/crypto.h>
9 #include <initcall.h>
10 #include <io.h>
11 #include <kernel/panic.h>
12 #include <mm/core_mmu.h>
13 #include <platform_config.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <tee/tee_cryp_utl.h>
17 
18 #include "drivers/versal_gpio.h"
19 
20 #define VERSAL_GPIO_LEN  0x10000
21 
22 #define DATA_LSW_OFFSET(__bank)	(0x000 + 0x08 * (__bank))
23 #define DATA_MSW_OFFSET(__bank)	(0x004 + 0x08 * (__bank))
24 #define DATA_RO_OFFSET(__bank)	(0x060 + 0x04 * (__bank))
25 #define DIRM_OFFSET(__bank)	(0x204 + 0x40 * (__bank))
26 #define OUTEN_OFFSET(__bank)	(0x208 + 0x40 * (__bank))
27 
28 #define VERSAL_GPIO_MID_PIN		16
29 #define VERSAL_GPIO_UPPER_MASK		0xFFFF0000
30 
31 /* Max pins in the PMC_GPIO devices
32  * 00  - 025,  Bank 0
33  * 26 -  051,  Bank 1
34  * 52 -  083,  Bank 3
35  * 84 -  115,  Bank 4
36  */
37 #define VERSAL_GPIO_PMC_BASE		0xf1020000
38 #define VERSAL_GPIO_PMC_NR_GPIOS	116
39 #define VERSAL_GPIO_PMC_MAX_BANK	5
40 
41 static const struct versal_gpio_platform_data versal_gpio_pmc_def = {
42 	.max_bank = VERSAL_GPIO_PMC_MAX_BANK,
43 	.ngpio = VERSAL_GPIO_PMC_NR_GPIOS,
44 	.label = "versal_pmc_gpio",
45 	.bank_min[0] = 0,
46 	.bank_max[0] = 25,
47 	.bank_min[1] = 26,
48 	.bank_max[1] = 51,
49 	.bank_min[3] = 52,
50 	.bank_max[3] = 83,
51 	.bank_min[4] = 84,
52 	.bank_max[4] = 115,
53 };
54 
55 /* Max pins in the PS_GPIO devices
56  *  00 - 25, Bank 0
57  *  26 - 57, Bank 3
58  */
59 #if defined(PLATFORM_FLAVOR_net)
60 #define VERSAL_GPIO_PS_BASE		0xf19d0000
61 #else
62 #define VERSAL_GPIO_PS_BASE		0xff0b0000
63 #endif
64 #define VERSAL_GPIO_PS_NR_GPIOS		58
65 #define VERSAL_GPIO_PS_MAX_BANK		4
66 
67 static const struct versal_gpio_platform_data versal_gpio_ps_def = {
68 	.max_bank = VERSAL_GPIO_PS_MAX_BANK,
69 	.ngpio = VERSAL_GPIO_PS_NR_GPIOS,
70 	.label = "versal_ps_gpio",
71 	.bank_min[0] = 0,
72 	.bank_max[0] = 25,
73 	.bank_min[3] = 26,
74 	.bank_max[3] = 57,
75 };
76 
versal_gpio_get_pin(struct versal_gpio_chip * chip,uint32_t gpio,uint32_t * bank,uint32_t * pin)77 static void versal_gpio_get_pin(struct versal_gpio_chip *chip, uint32_t gpio,
78 				uint32_t *bank, uint32_t *pin)
79 {
80 	struct versal_gpio_platdata *platdata = &chip->plat;
81 	uint32_t bnk = 0;
82 
83 	assert(gpio < platdata->p_data->ngpio);
84 
85 	for (bnk = 0; bnk < platdata->p_data->max_bank; bnk++) {
86 		if (gpio < platdata->p_data->bank_min[bnk])
87 			continue;
88 
89 		if (gpio > platdata->p_data->bank_max[bnk])
90 			continue;
91 
92 		*bank = bnk;
93 		*pin = gpio - platdata->p_data->bank_min[bnk];
94 
95 		return;
96 	}
97 
98 	EMSG("GPIO_%d not found", gpio);
99 	panic();
100 }
101 
versal_gpio_get_value(struct versal_gpio_chip * chip,uint32_t gpio)102 static enum gpio_level versal_gpio_get_value(struct versal_gpio_chip *chip,
103 					     uint32_t gpio)
104 {
105 	uint32_t bank = 0;
106 	uint32_t pin = 0;
107 
108 	versal_gpio_get_pin(chip, gpio, &bank, &pin);
109 
110 	return (io_read32(chip->base + DATA_RO_OFFSET(bank)) >> pin) & 1;
111 }
112 
versal_gpio_set_value(struct versal_gpio_chip * chip,uint32_t gpio,enum gpio_level val)113 static void versal_gpio_set_value(struct versal_gpio_chip *chip, uint32_t gpio,
114 				  enum gpio_level val)
115 {
116 	uint32_t bank = 0;
117 	uint32_t off = 0;
118 	uint32_t pin = 0;
119 
120 	versal_gpio_get_pin(chip, gpio, &bank, &pin);
121 
122 	if (bank >= VERSAL_GPIO_MID_PIN) {
123 		bank -= VERSAL_GPIO_MID_PIN;
124 		off = DATA_MSW_OFFSET(bank);
125 	} else {
126 		off = DATA_LSW_OFFSET(bank);
127 	}
128 
129 	/*
130 	 * get the 32 bit value to be written to the mask/data register where
131 	 * the upper 16 bits is the mask and lower 16 bits is the data
132 	 */
133 	val = !!val;
134 	val = ~BIT32(pin + VERSAL_GPIO_MID_PIN) &
135 	      (SHIFT_U32(val, pin) | VERSAL_GPIO_UPPER_MASK);
136 
137 	io_write32(chip->base + off, val);
138 }
139 
versal_gpio_set_direction(struct versal_gpio_chip * chip,uint32_t gpio,enum gpio_dir direction)140 static void versal_gpio_set_direction(struct versal_gpio_chip *chip,
141 				      uint32_t gpio, enum gpio_dir direction)
142 {
143 	uint32_t bank = 0;
144 	uint32_t reg = 0;
145 	uint32_t pin = 0;
146 
147 	versal_gpio_get_pin(chip, gpio, &bank, &pin);
148 
149 	if (direction == GPIO_DIR_OUT) {
150 		/* set the GPIO pin as output */
151 		reg = io_read32(chip->base + DIRM_OFFSET(bank));
152 		reg |= BIT(pin);
153 		io_write32(chip->base + DIRM_OFFSET(bank), reg);
154 
155 		/* configure the output enable reg for the pin */
156 		reg = io_read32(chip->base + OUTEN_OFFSET(bank));
157 
158 		reg |= BIT(pin);
159 		io_write32(chip->base + OUTEN_OFFSET(bank), reg);
160 
161 		/* set the state of the pin */
162 		versal_gpio_set_value(chip, gpio, GPIO_LEVEL_LOW);
163 	} else {
164 		/* bnk 0 pins 7 and 8 cannot be used as inputs */
165 		assert(!(bank == 0 && (pin == 7 || pin == 8)));
166 
167 		reg = io_read32(chip->base + DIRM_OFFSET(bank));
168 		reg &= ~BIT(pin);
169 		io_write32(chip->base + DIRM_OFFSET(bank), reg);
170 	}
171 }
172 
versal_gpio_get_direction(struct versal_gpio_chip * chip,uint32_t gpio)173 static enum gpio_dir versal_gpio_get_direction(struct versal_gpio_chip *chip,
174 					       uint32_t gpio)
175 {
176 	uint32_t pin = 0;
177 	uint32_t bank = 0;
178 
179 	versal_gpio_get_pin(chip, gpio, &bank, &pin);
180 
181 	if (io_read32(chip->base + DIRM_OFFSET(bank)) & BIT(pin))
182 		return GPIO_DIR_OUT;
183 
184 	return GPIO_DIR_IN;
185 }
186 
do_get_value(struct gpio_chip * chip,uint32_t gpio)187 static enum gpio_level do_get_value(struct gpio_chip *chip, uint32_t gpio)
188 {
189 	struct versal_gpio_chip *p = container_of(chip,
190 						struct versal_gpio_chip, chip);
191 	return versal_gpio_get_value(p, gpio);
192 }
193 
do_set_value(struct gpio_chip * chip,uint32_t gpio,enum gpio_level val)194 static void do_set_value(struct gpio_chip *chip, uint32_t gpio,
195 			 enum gpio_level val)
196 {
197 	struct versal_gpio_chip *p = container_of(chip,
198 						struct versal_gpio_chip, chip);
199 	return versal_gpio_set_value(p, gpio, val);
200 }
201 
do_set_dir(struct gpio_chip * chip,uint32_t gpio,enum gpio_dir direction)202 static void do_set_dir(struct gpio_chip *chip, uint32_t gpio,
203 		       enum gpio_dir direction)
204 {
205 	struct versal_gpio_chip *p = container_of(chip,
206 						struct versal_gpio_chip, chip);
207 	return versal_gpio_set_direction(p, gpio, direction);
208 }
209 
do_get_dir(struct gpio_chip * chip,uint32_t gpio)210 static enum gpio_dir do_get_dir(struct gpio_chip *chip, uint32_t gpio)
211 {
212 	struct versal_gpio_chip *p = container_of(chip,
213 						struct versal_gpio_chip, chip);
214 	return versal_gpio_get_direction(p, gpio);
215 }
216 
217 static const struct gpio_ops versal_gpio_ops = {
218 	.get_direction = do_get_dir,
219 	.set_direction = do_set_dir,
220 	.get_value = do_get_value,
221 	.set_value = do_set_value,
222 	.get_interrupt = NULL,
223 	.set_interrupt = NULL,
224 };
225 
versal_gpio_pmc_init(struct versal_gpio_chip * chip)226 TEE_Result versal_gpio_pmc_init(struct versal_gpio_chip *chip)
227 {
228 	if (chip->base)
229 		return TEE_SUCCESS;
230 
231 	chip->plat.p_data = &versal_gpio_pmc_def;
232 	chip->plat.base = VERSAL_GPIO_PMC_BASE;
233 	chip->chip.ops = &versal_gpio_ops;
234 
235 	chip->base = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC,
236 						   VERSAL_GPIO_PMC_BASE,
237 						   VERSAL_GPIO_LEN);
238 	if (!chip->base) {
239 		EMSG("Failed to map gpio");
240 		chip->chip.ops = NULL;
241 		return TEE_ERROR_GENERIC;
242 	}
243 
244 	return TEE_SUCCESS;
245 }
246 
versal_gpio_ps_init(struct versal_gpio_chip * chip)247 TEE_Result versal_gpio_ps_init(struct versal_gpio_chip *chip)
248 {
249 	if (chip->base)
250 		return TEE_SUCCESS;
251 
252 	chip->plat.p_data = &versal_gpio_ps_def;
253 	chip->plat.base = VERSAL_GPIO_PS_BASE;
254 	chip->chip.ops = &versal_gpio_ops;
255 
256 	chip->base = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC,
257 						   VERSAL_GPIO_PS_BASE,
258 						   VERSAL_GPIO_LEN);
259 	if (!chip->base) {
260 		EMSG("Failed to map gpio");
261 		chip->chip.ops = NULL;
262 		return TEE_ERROR_GENERIC;
263 	}
264 
265 	return TEE_SUCCESS;
266 }
267