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