1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (c) 2013 - 2018 Xilinx, Michal Simek 4 */ 5 6 #include <common.h> 7 #include <errno.h> 8 #include <malloc.h> 9 #include <linux/list.h> 10 #include <asm/io.h> 11 #include <asm/gpio.h> 12 #include <dm.h> 13 #include <dt-bindings/gpio/gpio.h> 14 15 #define XILINX_GPIO_MAX_BANK 2 16 17 /* Gpio simple map */ 18 struct gpio_regs { 19 u32 gpiodata; 20 u32 gpiodir; 21 }; 22 23 struct xilinx_gpio_platdata { 24 struct gpio_regs *regs; 25 int bank_max[XILINX_GPIO_MAX_BANK]; 26 int bank_input[XILINX_GPIO_MAX_BANK]; 27 int bank_output[XILINX_GPIO_MAX_BANK]; 28 u32 dout_default[XILINX_GPIO_MAX_BANK]; 29 }; 30 31 struct xilinx_gpio_privdata { 32 u32 output_val[XILINX_GPIO_MAX_BANK]; 33 }; 34 35 static int xilinx_gpio_get_bank_pin(unsigned offset, u32 *bank_num, 36 u32 *bank_pin_num, struct udevice *dev) 37 { 38 struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); 39 u32 bank, max_pins; 40 /* the first gpio is 0 not 1 */ 41 u32 pin_num = offset; 42 43 for (bank = 0; bank < XILINX_GPIO_MAX_BANK; bank++) { 44 max_pins = platdata->bank_max[bank]; 45 if (pin_num < max_pins) { 46 debug("%s: found at bank 0x%x pin 0x%x\n", __func__, 47 bank, pin_num); 48 *bank_num = bank; 49 *bank_pin_num = pin_num; 50 return 0; 51 } 52 pin_num -= max_pins; 53 } 54 55 return -EINVAL; 56 } 57 58 static int xilinx_gpio_set_value(struct udevice *dev, unsigned offset, 59 int value) 60 { 61 struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); 62 struct xilinx_gpio_privdata *priv = dev_get_priv(dev); 63 int val, ret; 64 u32 bank, pin; 65 66 ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev); 67 if (ret) 68 return ret; 69 70 val = priv->output_val[bank]; 71 72 debug("%s: regs: %lx, value: %x, gpio: %x, bank %x, pin %x, out %x\n", 73 __func__, (ulong)platdata->regs, value, offset, bank, pin, val); 74 75 if (value) 76 val = val | (1 << pin); 77 else 78 val = val & ~(1 << pin); 79 80 writel(val, &platdata->regs->gpiodata + bank * 2); 81 82 priv->output_val[bank] = val; 83 84 return 0; 85 }; 86 87 static int xilinx_gpio_get_value(struct udevice *dev, unsigned offset) 88 { 89 struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); 90 struct xilinx_gpio_privdata *priv = dev_get_priv(dev); 91 int val, ret; 92 u32 bank, pin; 93 94 ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev); 95 if (ret) 96 return ret; 97 98 debug("%s: regs: %lx, gpio: %x, bank %x, pin %x\n", __func__, 99 (ulong)platdata->regs, offset, bank, pin); 100 101 if (platdata->bank_output[bank]) { 102 debug("%s: Read saved output value\n", __func__); 103 val = priv->output_val[bank]; 104 } else { 105 debug("%s: Read input value from reg\n", __func__); 106 val = readl(&platdata->regs->gpiodata + bank * 2); 107 } 108 109 val = !!(val & (1 << pin)); 110 111 return val; 112 }; 113 114 static int xilinx_gpio_get_function(struct udevice *dev, unsigned offset) 115 { 116 struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); 117 int val, ret; 118 u32 bank, pin; 119 120 ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev); 121 if (ret) 122 return ret; 123 124 /* Check if all pins are inputs */ 125 if (platdata->bank_input[bank]) 126 return GPIOF_INPUT; 127 128 /* Check if all pins are outputs */ 129 if (platdata->bank_output[bank]) 130 return GPIOF_OUTPUT; 131 132 /* FIXME test on dual */ 133 val = readl(&platdata->regs->gpiodir + bank * 2); 134 val = !(val & (1 << pin)); 135 136 /* input is 1 in reg but GPIOF_INPUT is 0 */ 137 /* output is 0 in reg but GPIOF_OUTPUT is 1 */ 138 139 return val; 140 } 141 142 static int xilinx_gpio_direction_output(struct udevice *dev, unsigned offset, 143 int value) 144 { 145 struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); 146 int val, ret; 147 u32 bank, pin; 148 149 ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev); 150 if (ret) 151 return ret; 152 153 /* can't change it if all is input by default */ 154 if (platdata->bank_input[bank]) 155 return -EINVAL; 156 157 xilinx_gpio_set_value(dev, offset, value); 158 159 if (!platdata->bank_output[bank]) { 160 val = readl(&platdata->regs->gpiodir + bank * 2); 161 val = val & ~(1 << pin); 162 writel(val, &platdata->regs->gpiodir + bank * 2); 163 } 164 165 return 0; 166 } 167 168 static int xilinx_gpio_direction_input(struct udevice *dev, unsigned offset) 169 { 170 struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); 171 int val, ret; 172 u32 bank, pin; 173 174 ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev); 175 if (ret) 176 return ret; 177 178 /* Already input */ 179 if (platdata->bank_input[bank]) 180 return 0; 181 182 /* can't change it if all is output by default */ 183 if (platdata->bank_output[bank]) 184 return -EINVAL; 185 186 val = readl(&platdata->regs->gpiodir + bank * 2); 187 val = val | (1 << pin); 188 writel(val, &platdata->regs->gpiodir + bank * 2); 189 190 return 0; 191 } 192 193 static int xilinx_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, 194 struct ofnode_phandle_args *args) 195 { 196 struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); 197 198 desc->offset = args->args[0]; 199 200 debug("%s: argc: %x, [0]: %x, [1]: %x, [2]: %x\n", __func__, 201 args->args_count, args->args[0], args->args[1], args->args[2]); 202 203 /* 204 * The second cell is channel offset: 205 * 0 is first channel, 8 is second channel 206 * 207 * U-Boot driver just combine channels together that's why simply 208 * add amount of pins in second channel if present. 209 */ 210 if (args->args[1]) { 211 if (!platdata->bank_max[1]) { 212 printf("%s: %s has no second channel\n", 213 __func__, dev->name); 214 return -EINVAL; 215 } 216 217 desc->offset += platdata->bank_max[0]; 218 } 219 220 /* The third cell is optional */ 221 if (args->args_count > 2) 222 desc->flags = (args->args[2] & 223 GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0); 224 225 debug("%s: offset %x, flags %lx\n", 226 __func__, desc->offset, desc->flags); 227 return 0; 228 } 229 230 static const struct dm_gpio_ops xilinx_gpio_ops = { 231 .direction_input = xilinx_gpio_direction_input, 232 .direction_output = xilinx_gpio_direction_output, 233 .get_value = xilinx_gpio_get_value, 234 .set_value = xilinx_gpio_set_value, 235 .get_function = xilinx_gpio_get_function, 236 .xlate = xilinx_gpio_xlate, 237 }; 238 239 static int xilinx_gpio_probe(struct udevice *dev) 240 { 241 struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); 242 struct xilinx_gpio_privdata *priv = dev_get_priv(dev); 243 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 244 const void *label_ptr; 245 246 label_ptr = dev_read_prop(dev, "label", NULL); 247 if (label_ptr) { 248 uc_priv->bank_name = strdup(label_ptr); 249 if (!uc_priv->bank_name) 250 return -ENOMEM; 251 } else { 252 uc_priv->bank_name = dev->name; 253 } 254 255 uc_priv->gpio_count = platdata->bank_max[0] + platdata->bank_max[1]; 256 257 priv->output_val[0] = platdata->dout_default[0]; 258 259 if (platdata->bank_max[1]) 260 priv->output_val[1] = platdata->dout_default[1]; 261 262 return 0; 263 } 264 265 static int xilinx_gpio_ofdata_to_platdata(struct udevice *dev) 266 { 267 struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); 268 int is_dual; 269 270 platdata->regs = (struct gpio_regs *)dev_read_addr(dev); 271 272 platdata->bank_max[0] = dev_read_u32_default(dev, 273 "xlnx,gpio-width", 0); 274 platdata->bank_input[0] = dev_read_u32_default(dev, 275 "xlnx,all-inputs", 0); 276 platdata->bank_output[0] = dev_read_u32_default(dev, 277 "xlnx,all-outputs", 0); 278 platdata->dout_default[0] = dev_read_u32_default(dev, 279 "xlnx,dout-default", 280 0); 281 282 is_dual = dev_read_u32_default(dev, "xlnx,is-dual", 0); 283 if (is_dual) { 284 platdata->bank_max[1] = dev_read_u32_default(dev, 285 "xlnx,gpio2-width", 0); 286 platdata->bank_input[1] = dev_read_u32_default(dev, 287 "xlnx,all-inputs-2", 0); 288 platdata->bank_output[1] = dev_read_u32_default(dev, 289 "xlnx,all-outputs-2", 0); 290 platdata->dout_default[1] = dev_read_u32_default(dev, 291 "xlnx,dout-default-2", 0); 292 } 293 294 return 0; 295 } 296 297 static const struct udevice_id xilinx_gpio_ids[] = { 298 { .compatible = "xlnx,xps-gpio-1.00.a",}, 299 { } 300 }; 301 302 U_BOOT_DRIVER(xilinx_gpio) = { 303 .name = "xlnx_gpio", 304 .id = UCLASS_GPIO, 305 .ops = &xilinx_gpio_ops, 306 .of_match = xilinx_gpio_ids, 307 .ofdata_to_platdata = xilinx_gpio_ofdata_to_platdata, 308 .probe = xilinx_gpio_probe, 309 .platdata_auto_alloc_size = sizeof(struct xilinx_gpio_platdata), 310 .priv_auto_alloc_size = sizeof(struct xilinx_gpio_privdata), 311 }; 312