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 #define VERSAL_GPIO_PS_BASE 0xff0b0000 60 #define VERSAL_GPIO_PS_NR_GPIOS 58 61 #define VERSAL_GPIO_PS_MAX_BANK 4 62 63 static const struct versal_gpio_platform_data versal_gpio_ps_def = { 64 .max_bank = VERSAL_GPIO_PS_MAX_BANK, 65 .ngpio = VERSAL_GPIO_PS_NR_GPIOS, 66 .label = "versal_ps_gpio", 67 .bank_min[0] = 0, 68 .bank_max[0] = 25, 69 .bank_min[3] = 26, 70 .bank_max[3] = 57, 71 }; 72 73 static void versal_gpio_get_pin(struct versal_gpio_chip *chip, uint32_t gpio, 74 uint32_t *bank, uint32_t *pin) 75 { 76 struct versal_gpio_platdata *platdata = &chip->plat; 77 uint32_t bnk = 0; 78 79 assert(gpio < platdata->p_data->ngpio); 80 81 for (bnk = 0; bnk < platdata->p_data->max_bank; bnk++) { 82 if (gpio < platdata->p_data->bank_min[bnk]) 83 continue; 84 85 if (gpio > platdata->p_data->bank_max[bnk]) 86 continue; 87 88 *bank = bnk; 89 *pin = gpio - platdata->p_data->bank_min[bnk]; 90 91 return; 92 } 93 94 EMSG("GPIO_%d not found", gpio); 95 panic(); 96 } 97 98 static enum gpio_level versal_gpio_get_value(struct versal_gpio_chip *chip, 99 uint32_t gpio) 100 { 101 uint32_t bank = 0; 102 uint32_t pin = 0; 103 104 versal_gpio_get_pin(chip, gpio, &bank, &pin); 105 106 return (io_read32(chip->base + DATA_RO_OFFSET(bank)) >> pin) & 1; 107 } 108 109 static void versal_gpio_set_value(struct versal_gpio_chip *chip, uint32_t gpio, 110 enum gpio_level val) 111 { 112 uint32_t bank = 0; 113 uint32_t off = 0; 114 uint32_t pin = 0; 115 116 versal_gpio_get_pin(chip, gpio, &bank, &pin); 117 118 if (bank >= VERSAL_GPIO_MID_PIN) { 119 bank -= VERSAL_GPIO_MID_PIN; 120 off = DATA_MSW_OFFSET(bank); 121 } else { 122 off = DATA_LSW_OFFSET(bank); 123 } 124 125 /* 126 * get the 32 bit value to be written to the mask/data register where 127 * the upper 16 bits is the mask and lower 16 bits is the data 128 */ 129 val = !!val; 130 val = ~BIT32(pin + VERSAL_GPIO_MID_PIN) & 131 (SHIFT_U32(val, pin) | VERSAL_GPIO_UPPER_MASK); 132 133 io_write32(chip->base + off, val); 134 } 135 136 static void versal_gpio_set_direction(struct versal_gpio_chip *chip, 137 uint32_t gpio, enum gpio_dir direction) 138 { 139 uint32_t bank = 0; 140 uint32_t reg = 0; 141 uint32_t pin = 0; 142 143 versal_gpio_get_pin(chip, gpio, &bank, &pin); 144 145 if (direction == GPIO_DIR_OUT) { 146 /* set the GPIO pin as output */ 147 reg = io_read32(chip->base + DIRM_OFFSET(bank)); 148 reg |= BIT(pin); 149 io_write32(chip->base + DIRM_OFFSET(bank), reg); 150 151 /* configure the output enable reg for the pin */ 152 reg = io_read32(chip->base + OUTEN_OFFSET(bank)); 153 154 reg |= BIT(pin); 155 io_write32(chip->base + OUTEN_OFFSET(bank), reg); 156 157 /* set the state of the pin */ 158 versal_gpio_set_value(chip, gpio, GPIO_LEVEL_LOW); 159 } else { 160 /* bnk 0 pins 7 and 8 cannot be used as inputs */ 161 assert(!(bank == 0 && (pin == 7 || pin == 8))); 162 163 reg = io_read32(chip->base + DIRM_OFFSET(bank)); 164 reg &= ~BIT(pin); 165 io_write32(chip->base + DIRM_OFFSET(bank), reg); 166 } 167 } 168 169 static enum gpio_dir versal_gpio_get_direction(struct versal_gpio_chip *chip, 170 uint32_t gpio) 171 { 172 uint32_t pin = 0; 173 uint32_t bank = 0; 174 175 versal_gpio_get_pin(chip, gpio, &bank, &pin); 176 177 if (io_read32(chip->base + DIRM_OFFSET(bank)) & BIT(pin)) 178 return GPIO_DIR_OUT; 179 180 return GPIO_DIR_IN; 181 } 182 183 static enum gpio_level do_get_value(struct gpio_chip *chip, uint32_t gpio) 184 { 185 struct versal_gpio_chip *p = container_of(chip, 186 struct versal_gpio_chip, chip); 187 return versal_gpio_get_value(p, gpio); 188 } 189 190 static void do_set_value(struct gpio_chip *chip, uint32_t gpio, 191 enum gpio_level val) 192 { 193 struct versal_gpio_chip *p = container_of(chip, 194 struct versal_gpio_chip, chip); 195 return versal_gpio_set_value(p, gpio, val); 196 } 197 198 static void do_set_dir(struct gpio_chip *chip, uint32_t gpio, 199 enum gpio_dir direction) 200 { 201 struct versal_gpio_chip *p = container_of(chip, 202 struct versal_gpio_chip, chip); 203 return versal_gpio_set_direction(p, gpio, direction); 204 } 205 206 static enum gpio_dir do_get_dir(struct gpio_chip *chip, uint32_t gpio) 207 { 208 struct versal_gpio_chip *p = container_of(chip, 209 struct versal_gpio_chip, chip); 210 return versal_gpio_get_direction(p, gpio); 211 } 212 213 static const struct gpio_ops versal_gpio_ops = { 214 .get_direction = do_get_dir, 215 .set_direction = do_set_dir, 216 .get_value = do_get_value, 217 .set_value = do_set_value, 218 .get_interrupt = NULL, 219 .set_interrupt = NULL, 220 }; 221 222 TEE_Result versal_gpio_pmc_init(struct versal_gpio_chip *chip) 223 { 224 if (chip->base) 225 return TEE_SUCCESS; 226 227 chip->plat.p_data = &versal_gpio_pmc_def; 228 chip->plat.base = VERSAL_GPIO_PMC_BASE; 229 chip->chip.ops = &versal_gpio_ops; 230 231 chip->base = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, 232 VERSAL_GPIO_PMC_BASE, 233 VERSAL_GPIO_LEN); 234 if (!chip->base) { 235 EMSG("Failed to map gpio"); 236 chip->chip.ops = NULL; 237 return TEE_ERROR_GENERIC; 238 } 239 240 return TEE_SUCCESS; 241 } 242 243 TEE_Result versal_gpio_ps_init(struct versal_gpio_chip *chip) 244 { 245 if (chip->base) 246 return TEE_SUCCESS; 247 248 chip->plat.p_data = &versal_gpio_ps_def; 249 chip->plat.base = VERSAL_GPIO_PS_BASE; 250 chip->chip.ops = &versal_gpio_ops; 251 252 chip->base = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, 253 VERSAL_GPIO_PS_BASE, 254 VERSAL_GPIO_LEN); 255 if (!chip->base) { 256 EMSG("Failed to map gpio"); 257 chip->chip.ops = NULL; 258 return TEE_ERROR_GENERIC; 259 } 260 261 return TEE_SUCCESS; 262 } 263