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