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 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 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 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 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 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 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 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 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 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 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 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