1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2010-2016, NVIDIA CORPORATION. 4 * (based on tegra_gpio.c) 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <malloc.h> 10 #include <errno.h> 11 #include <fdtdec.h> 12 #include <asm/io.h> 13 #include <asm/bitops.h> 14 #include <asm/gpio.h> 15 #include <dm/device-internal.h> 16 #include <dt-bindings/gpio/gpio.h> 17 #include "tegra186_gpio_priv.h" 18 19 struct tegra186_gpio_port_data { 20 const char *name; 21 uint32_t offset; 22 }; 23 24 struct tegra186_gpio_ctlr_data { 25 const struct tegra186_gpio_port_data *ports; 26 uint32_t port_count; 27 }; 28 29 struct tegra186_gpio_platdata { 30 const char *name; 31 uint32_t *regs; 32 }; 33 34 static uint32_t *tegra186_gpio_reg(struct udevice *dev, uint32_t reg, 35 uint32_t gpio) 36 { 37 struct tegra186_gpio_platdata *plat = dev->platdata; 38 uint32_t index = (reg + (gpio * TEGRA186_GPIO_PER_GPIO_STRIDE)) / 4; 39 40 return &(plat->regs[index]); 41 } 42 43 static int tegra186_gpio_set_out(struct udevice *dev, unsigned offset, 44 bool output) 45 { 46 uint32_t *reg; 47 uint32_t rval; 48 49 reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_OUTPUT_CONTROL, offset); 50 rval = readl(reg); 51 if (output) 52 rval &= ~TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED; 53 else 54 rval |= TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED; 55 writel(rval, reg); 56 57 reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_ENABLE_CONFIG, offset); 58 rval = readl(reg); 59 if (output) 60 rval |= TEGRA186_GPIO_ENABLE_CONFIG_OUT; 61 else 62 rval &= ~TEGRA186_GPIO_ENABLE_CONFIG_OUT; 63 rval |= TEGRA186_GPIO_ENABLE_CONFIG_ENABLE; 64 writel(rval, reg); 65 66 return 0; 67 } 68 69 static int tegra186_gpio_set_val(struct udevice *dev, unsigned offset, bool val) 70 { 71 uint32_t *reg; 72 uint32_t rval; 73 74 reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_OUTPUT_VALUE, offset); 75 rval = readl(reg); 76 if (val) 77 rval |= TEGRA186_GPIO_OUTPUT_VALUE_HIGH; 78 else 79 rval &= ~TEGRA186_GPIO_OUTPUT_VALUE_HIGH; 80 writel(rval, reg); 81 82 return 0; 83 } 84 85 static int tegra186_gpio_direction_input(struct udevice *dev, unsigned offset) 86 { 87 return tegra186_gpio_set_out(dev, offset, false); 88 } 89 90 static int tegra186_gpio_direction_output(struct udevice *dev, unsigned offset, 91 int value) 92 { 93 int ret; 94 95 ret = tegra186_gpio_set_val(dev, offset, value != 0); 96 if (ret) 97 return ret; 98 return tegra186_gpio_set_out(dev, offset, true); 99 } 100 101 static int tegra186_gpio_get_value(struct udevice *dev, unsigned offset) 102 { 103 uint32_t *reg; 104 uint32_t rval; 105 106 reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_ENABLE_CONFIG, offset); 107 rval = readl(reg); 108 109 if (rval & TEGRA186_GPIO_ENABLE_CONFIG_OUT) 110 reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_OUTPUT_VALUE, 111 offset); 112 else 113 reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_INPUT, offset); 114 115 rval = readl(reg); 116 return !!rval; 117 } 118 119 static int tegra186_gpio_set_value(struct udevice *dev, unsigned offset, 120 int value) 121 { 122 return tegra186_gpio_set_val(dev, offset, value != 0); 123 } 124 125 static int tegra186_gpio_get_function(struct udevice *dev, unsigned offset) 126 { 127 uint32_t *reg; 128 uint32_t rval; 129 130 reg = tegra186_gpio_reg(dev, TEGRA186_GPIO_ENABLE_CONFIG, offset); 131 rval = readl(reg); 132 if (rval & TEGRA186_GPIO_ENABLE_CONFIG_OUT) 133 return GPIOF_OUTPUT; 134 else 135 return GPIOF_INPUT; 136 } 137 138 static int tegra186_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, 139 struct ofnode_phandle_args *args) 140 { 141 int gpio, port, ret; 142 143 gpio = args->args[0]; 144 port = gpio / TEGRA186_GPIO_PER_GPIO_COUNT; 145 ret = device_get_child(dev, port, &desc->dev); 146 if (ret) 147 return ret; 148 desc->offset = gpio % TEGRA186_GPIO_PER_GPIO_COUNT; 149 desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0; 150 151 return 0; 152 } 153 154 static const struct dm_gpio_ops tegra186_gpio_ops = { 155 .direction_input = tegra186_gpio_direction_input, 156 .direction_output = tegra186_gpio_direction_output, 157 .get_value = tegra186_gpio_get_value, 158 .set_value = tegra186_gpio_set_value, 159 .get_function = tegra186_gpio_get_function, 160 .xlate = tegra186_gpio_xlate, 161 }; 162 163 /** 164 * We have a top-level GPIO device with no actual GPIOs. It has a child device 165 * for each port within the controller. 166 */ 167 static int tegra186_gpio_bind(struct udevice *parent) 168 { 169 struct tegra186_gpio_platdata *parent_plat = parent->platdata; 170 struct tegra186_gpio_ctlr_data *ctlr_data = 171 (struct tegra186_gpio_ctlr_data *)dev_get_driver_data(parent); 172 uint32_t *regs; 173 int port, ret; 174 175 /* If this is a child device, there is nothing to do here */ 176 if (parent_plat) 177 return 0; 178 179 regs = (uint32_t *)devfdt_get_addr_name(parent, "gpio"); 180 if (regs == (uint32_t *)FDT_ADDR_T_NONE) 181 return -EINVAL; 182 183 for (port = 0; port < ctlr_data->port_count; port++) { 184 struct tegra186_gpio_platdata *plat; 185 struct udevice *dev; 186 187 plat = calloc(1, sizeof(*plat)); 188 if (!plat) 189 return -ENOMEM; 190 plat->name = ctlr_data->ports[port].name; 191 plat->regs = &(regs[ctlr_data->ports[port].offset / 4]); 192 193 ret = device_bind(parent, parent->driver, plat->name, plat, 194 -1, &dev); 195 if (ret) 196 return ret; 197 dev_set_of_offset(dev, dev_of_offset(parent)); 198 } 199 200 return 0; 201 } 202 203 static int tegra186_gpio_probe(struct udevice *dev) 204 { 205 struct tegra186_gpio_platdata *plat = dev->platdata; 206 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 207 208 /* Only child devices have ports */ 209 if (!plat) 210 return 0; 211 212 uc_priv->gpio_count = TEGRA186_GPIO_PER_GPIO_COUNT; 213 uc_priv->bank_name = plat->name; 214 215 return 0; 216 } 217 218 static const struct tegra186_gpio_port_data tegra186_gpio_main_ports[] = { 219 {"A", 0x2000}, 220 {"B", 0x3000}, 221 {"C", 0x3200}, 222 {"D", 0x3400}, 223 {"E", 0x2200}, 224 {"F", 0x2400}, 225 {"G", 0x4200}, 226 {"H", 0x1000}, 227 {"I", 0x0800}, 228 {"J", 0x5000}, 229 {"K", 0x5200}, 230 {"L", 0x1200}, 231 {"M", 0x5600}, 232 {"N", 0x0000}, 233 {"O", 0x0200}, 234 {"P", 0x4000}, 235 {"Q", 0x0400}, 236 {"R", 0x0a00}, 237 {"T", 0x0600}, 238 {"X", 0x1400}, 239 {"Y", 0x1600}, 240 {"BB", 0x2600}, 241 {"CC", 0x5400}, 242 }; 243 244 static const struct tegra186_gpio_ctlr_data tegra186_gpio_main_data = { 245 .ports = tegra186_gpio_main_ports, 246 .port_count = ARRAY_SIZE(tegra186_gpio_main_ports), 247 }; 248 249 static const struct tegra186_gpio_port_data tegra186_gpio_aon_ports[] = { 250 {"S", 0x0200}, 251 {"U", 0x0400}, 252 {"V", 0x0800}, 253 {"W", 0x0a00}, 254 {"Z", 0x0e00}, 255 {"AA", 0x0c00}, 256 {"EE", 0x0600}, 257 {"FF", 0x0000}, 258 }; 259 260 static const struct tegra186_gpio_ctlr_data tegra186_gpio_aon_data = { 261 .ports = tegra186_gpio_aon_ports, 262 .port_count = ARRAY_SIZE(tegra186_gpio_aon_ports), 263 }; 264 265 static const struct udevice_id tegra186_gpio_ids[] = { 266 { 267 .compatible = "nvidia,tegra186-gpio", 268 .data = (ulong)&tegra186_gpio_main_data, 269 }, 270 { 271 .compatible = "nvidia,tegra186-gpio-aon", 272 .data = (ulong)&tegra186_gpio_aon_data, 273 }, 274 { } 275 }; 276 277 U_BOOT_DRIVER(tegra186_gpio) = { 278 .name = "tegra186_gpio", 279 .id = UCLASS_GPIO, 280 .of_match = tegra186_gpio_ids, 281 .bind = tegra186_gpio_bind, 282 .probe = tegra186_gpio_probe, 283 .ops = &tegra186_gpio_ops, 284 }; 285