1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) 2002-2021 Xilinx, Inc. All rights reserved. 4 * Copyright (c) 2022 Foundries.io Ltd. (jorge@foundries.io) 5 * Copyright (c) 2024-2025, Advanced Micro Devices, Inc. All rights reserved. 6 * 7 */ 8 9 #include <assert.h> 10 #include <drivers/gpio.h> 11 #include <io.h> 12 #include <kernel/dt.h> 13 #include <kernel/panic.h> 14 #include <libfdt.h> 15 #include <malloc.h> 16 #include <mm/core_mmu.h> 17 #include <stdbool.h> 18 #include <stdint.h> 19 #include <trace.h> 20 #include <util.h> 21 22 #include "gpio_private.h" 23 24 static struct amd_gbank_data ps_bank = { 25 .label = "ps_gpio", 26 .ngpio = 58, 27 .max_bank = PS_BANK_MAX, 28 .bank_min[0] = 0, 29 .bank_max[0] = 25, 30 .bank_min[3] = 26, 31 .bank_max[3] = 57, 32 }; 33 34 /* Standard GPIO Operations */ 35 static enum gpio_level ps_gpio_get_value(struct gpio_chip *chip, 36 unsigned int gpio_pin) 37 { 38 uint32_t bank = 0; 39 uint32_t pin = 0; 40 struct amd_gpio_info *ps = container_of(chip, struct amd_gpio_info, 41 chip); 42 43 amd_gpio_get_bank_and_pin(ps->bdata, gpio_pin, &bank, &pin); 44 45 if (io_read32(ps->vbase + DATA_RO_OFFSET(bank)) & BIT(pin)) 46 return GPIO_LEVEL_HIGH; 47 48 return GPIO_LEVEL_LOW; 49 } 50 51 static void ps_gpio_set_value(struct gpio_chip *chip, 52 unsigned int gpio_pin, 53 enum gpio_level level) 54 { 55 uint32_t bank = 0; 56 uint32_t pin = 0; 57 uint32_t offset = 0; 58 uint32_t lvl = 0; 59 struct amd_gpio_info *ps = container_of(chip, struct amd_gpio_info, 60 chip); 61 62 amd_gpio_get_bank_and_pin(ps->bdata, gpio_pin, &bank, &pin); 63 64 if (pin < GPIO_NUM_MAX) { 65 offset = DATA_LSW_OFFSET(bank); 66 } else { 67 pin -= GPIO_NUM_MAX; 68 offset = DATA_MSW_OFFSET(bank); 69 } 70 71 /* Explicitly compare the enum value */ 72 if (level == GPIO_LEVEL_HIGH) 73 lvl = 1; 74 else 75 lvl = 0; 76 77 lvl = ~BIT32(pin + GPIO_NUM_MAX) & 78 (SHIFT_U32(lvl, pin) | GPIO_UPPER_MASK); 79 80 io_write32(ps->vbase + offset, lvl); 81 } 82 83 static enum gpio_dir ps_gpio_get_dir(struct gpio_chip *chip, 84 unsigned int gpio_pin) 85 { 86 uint32_t bank = 0; 87 uint32_t pin = 0; 88 struct amd_gpio_info *ps = container_of(chip, struct amd_gpio_info, 89 chip); 90 91 amd_gpio_get_bank_and_pin(ps->bdata, gpio_pin, &bank, &pin); 92 93 if (io_read32(ps->vbase + DIRM_OFFSET(bank)) & BIT(pin)) 94 return GPIO_DIR_OUT; 95 96 return GPIO_DIR_IN; 97 } 98 99 static void ps_gpio_set_dir(struct gpio_chip *chip, 100 unsigned int gpio_pin, 101 enum gpio_dir direction) 102 { 103 uint32_t bank = 0; 104 uint32_t pin = 0; 105 struct amd_gpio_info *ps = container_of(chip, struct amd_gpio_info, 106 chip); 107 108 amd_gpio_get_bank_and_pin(ps->bdata, gpio_pin, &bank, &pin); 109 110 if (direction == GPIO_DIR_OUT) { 111 /* set the GPIO pin as output */ 112 io_setbits32(ps->vbase + DIRM_OFFSET(bank), BIT(pin)); 113 114 /* configure the output enable reg for the pin */ 115 io_setbits32(ps->vbase + OUTEN_OFFSET(bank), BIT(pin)); 116 117 /* set the state of the pin */ 118 ps_gpio_set_value(chip, gpio_pin, GPIO_LEVEL_LOW); 119 } else { 120 /* Set the GPIO pin as input */ 121 io_clrbits32(ps->vbase + DIRM_OFFSET(bank), BIT(pin)); 122 } 123 } 124 125 static enum gpio_interrupt ps_gpio_get_intr(struct gpio_chip *chip, 126 unsigned int gpio_pin) 127 { 128 uint32_t bank = 0; 129 uint32_t pin = 0; 130 struct amd_gpio_info *ps = container_of(chip, struct amd_gpio_info, 131 chip); 132 133 amd_gpio_get_bank_and_pin(ps->bdata, gpio_pin, &bank, &pin); 134 135 if ((io_read32(ps->vbase + INTMASK_OFFSET(bank)) & BIT(pin))) 136 return GPIO_INTERRUPT_DISABLE; 137 138 return GPIO_INTERRUPT_ENABLE; 139 } 140 141 static void ps_gpio_set_intr(struct gpio_chip *chip, 142 unsigned int gpio_pin, 143 enum gpio_interrupt interrupt) 144 { 145 uint32_t bank = 0; 146 uint32_t pin = 0; 147 uint32_t offset = 0; 148 uint32_t mask = 0; 149 struct amd_gpio_info *ps = container_of(chip, struct amd_gpio_info, 150 chip); 151 152 amd_gpio_get_bank_and_pin(ps->bdata, gpio_pin, &bank, &pin); 153 154 mask = io_read32(ps->vbase + INTMASK_OFFSET(bank)) & BIT(pin); 155 156 /* 157 * mask = 1 --> Interrupt is masked/disabled. 158 * mask = 0 --> Interrupt is un-masked/enabled. 159 */ 160 if (mask && interrupt == GPIO_INTERRUPT_ENABLE) { 161 offset = INTEN_OFFSET(bank); 162 } else if (!mask && interrupt == GPIO_INTERRUPT_DISABLE) { 163 offset = INTDIS_OFFSET(bank); 164 } else { 165 DMSG("No change, interrupt already %s", 166 interrupt ? "Enabled" : "Disabled"); 167 return; 168 } 169 170 io_setbits32(ps->vbase + offset, BIT(pin)); 171 } 172 173 static const struct gpio_ops ps_gpio_ops = { 174 .get_direction = ps_gpio_get_dir, 175 .set_direction = ps_gpio_set_dir, 176 .get_value = ps_gpio_get_value, 177 .set_value = ps_gpio_set_value, 178 .get_interrupt = ps_gpio_get_intr, 179 .set_interrupt = ps_gpio_set_intr, 180 }; 181 182 static TEE_Result amd_ps_gpio_probe(const void *fdt, int node, 183 const void *compat_data __unused) 184 { 185 TEE_Result res = TEE_ERROR_GENERIC; 186 int status = DT_STATUS_DISABLED; 187 struct amd_gpio_info *ps_gpio = NULL; 188 paddr_t base = 0; 189 size_t len = 0; 190 191 /* Status Check */ 192 status = fdt_get_status(fdt, node); 193 194 /* PS GPIO Controller to be in Non Secure World */ 195 if (status & DT_STATUS_OK_NSEC) { 196 DMSG("PS GPIO controller configured for NS world"); 197 return TEE_SUCCESS; 198 } 199 200 /* PS GPIO Controller is disabled for Secure World as well */ 201 if (!(status & DT_STATUS_OK_SEC)) { 202 DMSG("PS GPIO Controller is disabled"); 203 return TEE_SUCCESS; 204 } 205 206 ps_gpio = calloc(1, sizeof(*ps_gpio)); 207 if (!ps_gpio) { 208 EMSG("Failed to allocate memory for ps_gpio"); 209 return TEE_ERROR_OUT_OF_MEMORY; 210 } 211 212 if (fdt_reg_info(fdt, node, &base, &len) != 0) { 213 EMSG("Failed to get Register Base and Size"); 214 free(ps_gpio); 215 return TEE_ERROR_GENERIC; 216 } 217 218 /* Populate GPIO ops */ 219 ps_gpio->chip.ops = &ps_gpio_ops; 220 /* Populate Bank information */ 221 ps_gpio->bdata = &ps_bank; 222 223 /* Validate node entries */ 224 assert(base); 225 assert(len); 226 227 ps_gpio->vbase = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, base, 228 len); 229 if (!ps_gpio->vbase) { 230 EMSG("AMD PS GPIO initialization Failed"); 231 free(ps_gpio); 232 return TEE_ERROR_GENERIC; 233 } 234 235 res = gpio_register_provider(fdt, node, amd_gpio_get_dt, ps_gpio); 236 if (res) { 237 EMSG("Failed to register PS GPIO Provider"); 238 /* Ignoring return value */ 239 core_mmu_remove_mapping(MEM_AREA_IO_SEC, 240 (void *)ps_gpio->vbase, len); 241 free(ps_gpio); 242 return res; 243 } 244 245 DMSG("AMD PS GPIO initialized"); 246 247 return TEE_SUCCESS; 248 } 249 250 GPIO_DT_DECLARE(amd_ps_gpio, "xlnx,versal-gpio-1.0", amd_ps_gpio_probe); 251