1*16c13b4dSManish Tomar // SPDX-License-Identifier: BSD-2-Clause 2*16c13b4dSManish Tomar /* 3*16c13b4dSManish Tomar * Copyright 2021 NXP 4*16c13b4dSManish Tomar * 5*16c13b4dSManish Tomar * Driver for GPIO Controller 6*16c13b4dSManish Tomar * 7*16c13b4dSManish Tomar */ 8*16c13b4dSManish Tomar 9*16c13b4dSManish Tomar #include <assert.h> 10*16c13b4dSManish Tomar #include <drivers/ls_gpio.h> 11*16c13b4dSManish Tomar #include <io.h> 12*16c13b4dSManish Tomar #include <kernel/boot.h> 13*16c13b4dSManish Tomar #include <kernel/dt.h> 14*16c13b4dSManish Tomar #include <libfdt.h> 15*16c13b4dSManish Tomar #include <mm/core_memprot.h> 16*16c13b4dSManish Tomar 17*16c13b4dSManish Tomar static const char * const gpio_controller_map[] = { 18*16c13b4dSManish Tomar "/soc/gpio@2300000", 19*16c13b4dSManish Tomar "/soc/gpio@2310000", 20*16c13b4dSManish Tomar "/soc/gpio@2320000", 21*16c13b4dSManish Tomar "/soc/gpio@2330000" 22*16c13b4dSManish Tomar }; 23*16c13b4dSManish Tomar 24*16c13b4dSManish Tomar /* 25*16c13b4dSManish Tomar * Get value from GPIO controller 26*16c13b4dSManish Tomar * chip: pointer to GPIO controller chip instance 27*16c13b4dSManish Tomar * gpio_pin: pin from which value needs to be read 28*16c13b4dSManish Tomar */ 29*16c13b4dSManish Tomar static enum gpio_level gpio_get_value(struct gpio_chip *chip, 30*16c13b4dSManish Tomar unsigned int gpio_pin) 31*16c13b4dSManish Tomar { 32*16c13b4dSManish Tomar vaddr_t gpio_data_addr = 0; 33*16c13b4dSManish Tomar uint32_t data = 0; 34*16c13b4dSManish Tomar struct ls_gpio_chip_data *gc_data = container_of(chip, 35*16c13b4dSManish Tomar struct ls_gpio_chip_data, 36*16c13b4dSManish Tomar chip); 37*16c13b4dSManish Tomar 38*16c13b4dSManish Tomar assert(gpio_pin <= MAX_GPIO_PINS); 39*16c13b4dSManish Tomar 40*16c13b4dSManish Tomar gpio_data_addr = gc_data->gpio_base + GPIODAT; 41*16c13b4dSManish Tomar data = io_read32(gpio_data_addr); 42*16c13b4dSManish Tomar 43*16c13b4dSManish Tomar if (data & PIN_SHIFT(gpio_pin)) 44*16c13b4dSManish Tomar return GPIO_LEVEL_HIGH; 45*16c13b4dSManish Tomar else 46*16c13b4dSManish Tomar return GPIO_LEVEL_LOW; 47*16c13b4dSManish Tomar } 48*16c13b4dSManish Tomar 49*16c13b4dSManish Tomar /* 50*16c13b4dSManish Tomar * Set value for GPIO controller 51*16c13b4dSManish Tomar * chip: pointer to GPIO controller chip instance 52*16c13b4dSManish Tomar * gpio_pin: pin to which value needs to be write 53*16c13b4dSManish Tomar * value: value needs to be written to the pin 54*16c13b4dSManish Tomar */ 55*16c13b4dSManish Tomar static void gpio_set_value(struct gpio_chip *chip, unsigned int gpio_pin, 56*16c13b4dSManish Tomar enum gpio_level value) 57*16c13b4dSManish Tomar { 58*16c13b4dSManish Tomar vaddr_t gpio_data_addr = 0; 59*16c13b4dSManish Tomar struct ls_gpio_chip_data *gc_data = container_of(chip, 60*16c13b4dSManish Tomar struct ls_gpio_chip_data, 61*16c13b4dSManish Tomar chip); 62*16c13b4dSManish Tomar 63*16c13b4dSManish Tomar assert(gpio_pin <= MAX_GPIO_PINS); 64*16c13b4dSManish Tomar 65*16c13b4dSManish Tomar gpio_data_addr = gc_data->gpio_base + GPIODAT; 66*16c13b4dSManish Tomar 67*16c13b4dSManish Tomar if (value == GPIO_LEVEL_HIGH) 68*16c13b4dSManish Tomar /* if value is high then set pin value */ 69*16c13b4dSManish Tomar io_setbits32(gpio_data_addr, PIN_SHIFT(gpio_pin)); 70*16c13b4dSManish Tomar else 71*16c13b4dSManish Tomar /* if value is low then clear pin value */ 72*16c13b4dSManish Tomar io_clrbits32(gpio_data_addr, PIN_SHIFT(gpio_pin)); 73*16c13b4dSManish Tomar } 74*16c13b4dSManish Tomar 75*16c13b4dSManish Tomar /* 76*16c13b4dSManish Tomar * Get direction from GPIO controller 77*16c13b4dSManish Tomar * chip: pointer to GPIO controller chip instance 78*16c13b4dSManish Tomar * gpio_pin: pin from which direction needs to be read 79*16c13b4dSManish Tomar */ 80*16c13b4dSManish Tomar static enum gpio_dir gpio_get_direction(struct gpio_chip *chip, 81*16c13b4dSManish Tomar unsigned int gpio_pin) 82*16c13b4dSManish Tomar { 83*16c13b4dSManish Tomar vaddr_t gpio_dir_addr = 0; 84*16c13b4dSManish Tomar uint32_t data = 0; 85*16c13b4dSManish Tomar struct ls_gpio_chip_data *gc_data = container_of(chip, 86*16c13b4dSManish Tomar struct ls_gpio_chip_data, 87*16c13b4dSManish Tomar chip); 88*16c13b4dSManish Tomar 89*16c13b4dSManish Tomar assert(gpio_pin <= MAX_GPIO_PINS); 90*16c13b4dSManish Tomar 91*16c13b4dSManish Tomar gpio_dir_addr = gc_data->gpio_base + GPIODIR; 92*16c13b4dSManish Tomar data = io_read32(gpio_dir_addr); 93*16c13b4dSManish Tomar 94*16c13b4dSManish Tomar if (data & PIN_SHIFT(gpio_pin)) 95*16c13b4dSManish Tomar return GPIO_DIR_OUT; 96*16c13b4dSManish Tomar else 97*16c13b4dSManish Tomar return GPIO_DIR_IN; 98*16c13b4dSManish Tomar } 99*16c13b4dSManish Tomar 100*16c13b4dSManish Tomar /* 101*16c13b4dSManish Tomar * Set direction for GPIO controller 102*16c13b4dSManish Tomar * chip: pointer to GPIO controller chip instance 103*16c13b4dSManish Tomar * gpio_pin: pin on which direction needs to be set 104*16c13b4dSManish Tomar * direction: direction which needs to be set on pin 105*16c13b4dSManish Tomar */ 106*16c13b4dSManish Tomar static void gpio_set_direction(struct gpio_chip *chip, unsigned int gpio_pin, 107*16c13b4dSManish Tomar enum gpio_dir direction) 108*16c13b4dSManish Tomar { 109*16c13b4dSManish Tomar vaddr_t gpio_dir_addr = 0; 110*16c13b4dSManish Tomar struct ls_gpio_chip_data *gc_data = container_of(chip, 111*16c13b4dSManish Tomar struct ls_gpio_chip_data, 112*16c13b4dSManish Tomar chip); 113*16c13b4dSManish Tomar 114*16c13b4dSManish Tomar assert(gpio_pin <= MAX_GPIO_PINS); 115*16c13b4dSManish Tomar 116*16c13b4dSManish Tomar gpio_dir_addr = gc_data->gpio_base + GPIODIR; 117*16c13b4dSManish Tomar 118*16c13b4dSManish Tomar if (direction == GPIO_DIR_OUT) 119*16c13b4dSManish Tomar io_setbits32(gpio_dir_addr, PIN_SHIFT(gpio_pin)); 120*16c13b4dSManish Tomar else 121*16c13b4dSManish Tomar io_clrbits32(gpio_dir_addr, PIN_SHIFT(gpio_pin)); 122*16c13b4dSManish Tomar } 123*16c13b4dSManish Tomar 124*16c13b4dSManish Tomar /* 125*16c13b4dSManish Tomar * Get interrupt from GPIO controller 126*16c13b4dSManish Tomar * chip: pointer to GPIO controller chip instance 127*16c13b4dSManish Tomar * gpio_pin: pin from which interrupt value needs to be read 128*16c13b4dSManish Tomar */ 129*16c13b4dSManish Tomar static enum gpio_interrupt gpio_get_interrupt(struct gpio_chip *chip, 130*16c13b4dSManish Tomar unsigned int gpio_pin) 131*16c13b4dSManish Tomar { 132*16c13b4dSManish Tomar vaddr_t gpio_ier_addr = 0; 133*16c13b4dSManish Tomar uint32_t data = 0; 134*16c13b4dSManish Tomar struct ls_gpio_chip_data *gc_data = container_of(chip, 135*16c13b4dSManish Tomar struct ls_gpio_chip_data, 136*16c13b4dSManish Tomar chip); 137*16c13b4dSManish Tomar 138*16c13b4dSManish Tomar assert(gpio_pin <= MAX_GPIO_PINS); 139*16c13b4dSManish Tomar 140*16c13b4dSManish Tomar gpio_ier_addr = gc_data->gpio_base + GPIOIER; 141*16c13b4dSManish Tomar data = io_read32(gpio_ier_addr); 142*16c13b4dSManish Tomar 143*16c13b4dSManish Tomar if (data & PIN_SHIFT(gpio_pin)) 144*16c13b4dSManish Tomar return GPIO_INTERRUPT_ENABLE; 145*16c13b4dSManish Tomar else 146*16c13b4dSManish Tomar return GPIO_INTERRUPT_DISABLE; 147*16c13b4dSManish Tomar } 148*16c13b4dSManish Tomar 149*16c13b4dSManish Tomar /* 150*16c13b4dSManish Tomar * Set interrupt event for GPIO controller 151*16c13b4dSManish Tomar * chip: pointer to GPIO controller chip instance 152*16c13b4dSManish Tomar * gpio_pin: pin on which interrupt value needs to be set 153*16c13b4dSManish Tomar * interrupt: interrupt valie which needs to be set on pin 154*16c13b4dSManish Tomar */ 155*16c13b4dSManish Tomar static void gpio_set_interrupt(struct gpio_chip *chip, unsigned int gpio_pin, 156*16c13b4dSManish Tomar enum gpio_interrupt interrupt) 157*16c13b4dSManish Tomar { 158*16c13b4dSManish Tomar vaddr_t gpio_ier_addr = 0; 159*16c13b4dSManish Tomar struct ls_gpio_chip_data *gc_data = container_of(chip, 160*16c13b4dSManish Tomar struct ls_gpio_chip_data, 161*16c13b4dSManish Tomar chip); 162*16c13b4dSManish Tomar 163*16c13b4dSManish Tomar assert(gpio_pin <= MAX_GPIO_PINS); 164*16c13b4dSManish Tomar 165*16c13b4dSManish Tomar gpio_ier_addr = gc_data->gpio_base + GPIOIER; 166*16c13b4dSManish Tomar 167*16c13b4dSManish Tomar if (interrupt == GPIO_INTERRUPT_ENABLE) 168*16c13b4dSManish Tomar io_setbits32(gpio_ier_addr, PIN_SHIFT(gpio_pin)); 169*16c13b4dSManish Tomar else 170*16c13b4dSManish Tomar io_clrbits32(gpio_ier_addr, PIN_SHIFT(gpio_pin)); 171*16c13b4dSManish Tomar } 172*16c13b4dSManish Tomar 173*16c13b4dSManish Tomar /* 174*16c13b4dSManish Tomar * Extract information for GPIO Controller from the DTB 175*16c13b4dSManish Tomar * gpio_data: GPIO controller chip instance 176*16c13b4dSManish Tomar */ 177*16c13b4dSManish Tomar static TEE_Result get_info_from_device_tree(struct ls_gpio_chip_data *gpio_data) 178*16c13b4dSManish Tomar { 179*16c13b4dSManish Tomar size_t size = 0; 180*16c13b4dSManish Tomar int node = 0; 181*16c13b4dSManish Tomar vaddr_t ctrl_base = 0; 182*16c13b4dSManish Tomar void *fdt = NULL; 183*16c13b4dSManish Tomar 184*16c13b4dSManish Tomar /* 185*16c13b4dSManish Tomar * First get the GPIO Controller base address from the DTB 186*16c13b4dSManish Tomar * if DTB present and if the GPIO Controller defined in it. 187*16c13b4dSManish Tomar */ 188*16c13b4dSManish Tomar fdt = get_embedded_dt(); 189*16c13b4dSManish Tomar if (!fdt) { 190*16c13b4dSManish Tomar EMSG("Unable to get the Embedded DTB, GPIO init failed\n"); 191*16c13b4dSManish Tomar return TEE_ERROR_GENERIC; 192*16c13b4dSManish Tomar } 193*16c13b4dSManish Tomar 194*16c13b4dSManish Tomar node = fdt_path_offset(fdt, gpio_controller_map 195*16c13b4dSManish Tomar [gpio_data->gpio_controller]); 196*16c13b4dSManish Tomar if (node > 0) { 197*16c13b4dSManish Tomar if (dt_map_dev(fdt, node, &ctrl_base, &size) < 0) { 198*16c13b4dSManish Tomar EMSG("Unable to get virtual address"); 199*16c13b4dSManish Tomar return TEE_ERROR_GENERIC; 200*16c13b4dSManish Tomar } 201*16c13b4dSManish Tomar } else { 202*16c13b4dSManish Tomar EMSG("Unable to get gpio offset node"); 203*16c13b4dSManish Tomar return TEE_ERROR_ITEM_NOT_FOUND; 204*16c13b4dSManish Tomar } 205*16c13b4dSManish Tomar 206*16c13b4dSManish Tomar gpio_data->gpio_base = ctrl_base; 207*16c13b4dSManish Tomar 208*16c13b4dSManish Tomar return TEE_SUCCESS; 209*16c13b4dSManish Tomar } 210*16c13b4dSManish Tomar 211*16c13b4dSManish Tomar static const struct gpio_ops ls_gpio_ops = { 212*16c13b4dSManish Tomar .get_direction = gpio_get_direction, 213*16c13b4dSManish Tomar .set_direction = gpio_set_direction, 214*16c13b4dSManish Tomar .get_value = gpio_get_value, 215*16c13b4dSManish Tomar .set_value = gpio_set_value, 216*16c13b4dSManish Tomar .get_interrupt = gpio_get_interrupt, 217*16c13b4dSManish Tomar .set_interrupt = gpio_set_interrupt, 218*16c13b4dSManish Tomar }; 219*16c13b4dSManish Tomar DECLARE_KEEP_PAGER(ls_gpio_ops); 220*16c13b4dSManish Tomar 221*16c13b4dSManish Tomar TEE_Result ls_gpio_init(struct ls_gpio_chip_data *gpio_data) 222*16c13b4dSManish Tomar { 223*16c13b4dSManish Tomar TEE_Result status = TEE_ERROR_GENERIC; 224*16c13b4dSManish Tomar 225*16c13b4dSManish Tomar /* 226*16c13b4dSManish Tomar * First get the GPIO Controller base address from the DTB, 227*16c13b4dSManish Tomar * if DTB present and if the GPIO Controller defined in it. 228*16c13b4dSManish Tomar */ 229*16c13b4dSManish Tomar status = get_info_from_device_tree(gpio_data); 230*16c13b4dSManish Tomar if (status == TEE_SUCCESS) { 231*16c13b4dSManish Tomar /* set GPIO Input Buffer Enable register */ 232*16c13b4dSManish Tomar io_setbits32(gpio_data->gpio_base + GPIOIBE, UINT32_MAX); 233*16c13b4dSManish Tomar 234*16c13b4dSManish Tomar /* generic GPIO chip handle */ 235*16c13b4dSManish Tomar gpio_data->chip.ops = &ls_gpio_ops; 236*16c13b4dSManish Tomar } else { 237*16c13b4dSManish Tomar EMSG("Unable to get info from device tree"); 238*16c13b4dSManish Tomar } 239*16c13b4dSManish Tomar 240*16c13b4dSManish Tomar return status; 241*16c13b4dSManish Tomar } 242