1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2009 Samsung Electronics 4 * Minkyu Kang <mk7.kang@samsung.com> 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <errno.h> 10 #include <fdtdec.h> 11 #include <malloc.h> 12 #include <asm/io.h> 13 #include <asm/gpio.h> 14 #include <dm/device-internal.h> 15 16 DECLARE_GLOBAL_DATA_PTR; 17 18 #define S5P_GPIO_GET_PIN(x) (x % GPIO_PER_BANK) 19 20 #define CON_MASK(val) (0xf << ((val) << 2)) 21 #define CON_SFR(gpio, cfg) ((cfg) << ((gpio) << 2)) 22 #define CON_SFR_UNSHIFT(val, gpio) ((val) >> ((gpio) << 2)) 23 24 #define DAT_MASK(gpio) (0x1 << (gpio)) 25 #define DAT_SET(gpio) (0x1 << (gpio)) 26 27 #define PULL_MASK(gpio) (0x3 << ((gpio) << 1)) 28 #define PULL_MODE(gpio, pull) ((pull) << ((gpio) << 1)) 29 30 #define DRV_MASK(gpio) (0x3 << ((gpio) << 1)) 31 #define DRV_SET(gpio, mode) ((mode) << ((gpio) << 1)) 32 #define RATE_MASK(gpio) (0x1 << (gpio + 16)) 33 #define RATE_SET(gpio) (0x1 << (gpio + 16)) 34 35 /* Platform data for each bank */ 36 struct exynos_gpio_platdata { 37 struct s5p_gpio_bank *bank; 38 const char *bank_name; /* Name of port, e.g. 'gpa0" */ 39 }; 40 41 /* Information about each bank at run-time */ 42 struct exynos_bank_info { 43 struct s5p_gpio_bank *bank; 44 }; 45 46 static struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned int gpio) 47 { 48 const struct gpio_info *data; 49 unsigned int upto; 50 int i, count; 51 52 data = get_gpio_data(); 53 count = get_bank_num(); 54 upto = 0; 55 56 for (i = 0; i < count; i++) { 57 debug("i=%d, upto=%d\n", i, upto); 58 if (gpio < data->max_gpio) { 59 struct s5p_gpio_bank *bank; 60 bank = (struct s5p_gpio_bank *)data->reg_addr; 61 bank += (gpio - upto) / GPIO_PER_BANK; 62 debug("gpio=%d, bank=%p\n", gpio, bank); 63 return bank; 64 } 65 66 upto = data->max_gpio; 67 data++; 68 } 69 70 return NULL; 71 } 72 73 static void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg) 74 { 75 unsigned int value; 76 77 value = readl(&bank->con); 78 value &= ~CON_MASK(gpio); 79 value |= CON_SFR(gpio, cfg); 80 writel(value, &bank->con); 81 } 82 83 static void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en) 84 { 85 unsigned int value; 86 87 value = readl(&bank->dat); 88 value &= ~DAT_MASK(gpio); 89 if (en) 90 value |= DAT_SET(gpio); 91 writel(value, &bank->dat); 92 } 93 94 #ifdef CONFIG_SPL_BUILD 95 /* Common GPIO API - SPL does not support driver model yet */ 96 int gpio_set_value(unsigned gpio, int value) 97 { 98 s5p_gpio_set_value(s5p_gpio_get_bank(gpio), 99 s5p_gpio_get_pin(gpio), value); 100 101 return 0; 102 } 103 #else 104 static int s5p_gpio_get_cfg_pin(struct s5p_gpio_bank *bank, int gpio) 105 { 106 unsigned int value; 107 108 value = readl(&bank->con); 109 value &= CON_MASK(gpio); 110 return CON_SFR_UNSHIFT(value, gpio); 111 } 112 113 static unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, int gpio) 114 { 115 unsigned int value; 116 117 value = readl(&bank->dat); 118 return !!(value & DAT_MASK(gpio)); 119 } 120 #endif /* CONFIG_SPL_BUILD */ 121 122 static void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode) 123 { 124 unsigned int value; 125 126 value = readl(&bank->pull); 127 value &= ~PULL_MASK(gpio); 128 129 switch (mode) { 130 case S5P_GPIO_PULL_DOWN: 131 case S5P_GPIO_PULL_UP: 132 value |= PULL_MODE(gpio, mode); 133 break; 134 default: 135 break; 136 } 137 138 writel(value, &bank->pull); 139 } 140 141 static void s5p_gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode) 142 { 143 unsigned int value; 144 145 value = readl(&bank->drv); 146 value &= ~DRV_MASK(gpio); 147 148 switch (mode) { 149 case S5P_GPIO_DRV_1X: 150 case S5P_GPIO_DRV_2X: 151 case S5P_GPIO_DRV_3X: 152 case S5P_GPIO_DRV_4X: 153 value |= DRV_SET(gpio, mode); 154 break; 155 default: 156 return; 157 } 158 159 writel(value, &bank->drv); 160 } 161 162 static void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode) 163 { 164 unsigned int value; 165 166 value = readl(&bank->drv); 167 value &= ~RATE_MASK(gpio); 168 169 switch (mode) { 170 case S5P_GPIO_DRV_FAST: 171 case S5P_GPIO_DRV_SLOW: 172 value |= RATE_SET(gpio); 173 break; 174 default: 175 return; 176 } 177 178 writel(value, &bank->drv); 179 } 180 181 int s5p_gpio_get_pin(unsigned gpio) 182 { 183 return S5P_GPIO_GET_PIN(gpio); 184 } 185 186 /* Driver model interface */ 187 #ifndef CONFIG_SPL_BUILD 188 /* set GPIO pin 'gpio' as an input */ 189 static int exynos_gpio_direction_input(struct udevice *dev, unsigned offset) 190 { 191 struct exynos_bank_info *state = dev_get_priv(dev); 192 193 /* Configure GPIO direction as input. */ 194 s5p_gpio_cfg_pin(state->bank, offset, S5P_GPIO_INPUT); 195 196 return 0; 197 } 198 199 /* set GPIO pin 'gpio' as an output, with polarity 'value' */ 200 static int exynos_gpio_direction_output(struct udevice *dev, unsigned offset, 201 int value) 202 { 203 struct exynos_bank_info *state = dev_get_priv(dev); 204 205 /* Configure GPIO output value. */ 206 s5p_gpio_set_value(state->bank, offset, value); 207 208 /* Configure GPIO direction as output. */ 209 s5p_gpio_cfg_pin(state->bank, offset, S5P_GPIO_OUTPUT); 210 211 return 0; 212 } 213 214 /* read GPIO IN value of pin 'gpio' */ 215 static int exynos_gpio_get_value(struct udevice *dev, unsigned offset) 216 { 217 struct exynos_bank_info *state = dev_get_priv(dev); 218 219 return s5p_gpio_get_value(state->bank, offset); 220 } 221 222 /* write GPIO OUT value to pin 'gpio' */ 223 static int exynos_gpio_set_value(struct udevice *dev, unsigned offset, 224 int value) 225 { 226 struct exynos_bank_info *state = dev_get_priv(dev); 227 228 s5p_gpio_set_value(state->bank, offset, value); 229 230 return 0; 231 } 232 #endif /* nCONFIG_SPL_BUILD */ 233 234 /* 235 * There is no common GPIO API for pull, drv, pin, rate (yet). These 236 * functions are kept here to preserve function ordering for review. 237 */ 238 void gpio_set_pull(int gpio, int mode) 239 { 240 s5p_gpio_set_pull(s5p_gpio_get_bank(gpio), 241 s5p_gpio_get_pin(gpio), mode); 242 } 243 244 void gpio_set_drv(int gpio, int mode) 245 { 246 s5p_gpio_set_drv(s5p_gpio_get_bank(gpio), 247 s5p_gpio_get_pin(gpio), mode); 248 } 249 250 void gpio_cfg_pin(int gpio, int cfg) 251 { 252 s5p_gpio_cfg_pin(s5p_gpio_get_bank(gpio), 253 s5p_gpio_get_pin(gpio), cfg); 254 } 255 256 void gpio_set_rate(int gpio, int mode) 257 { 258 s5p_gpio_set_rate(s5p_gpio_get_bank(gpio), 259 s5p_gpio_get_pin(gpio), mode); 260 } 261 262 #ifndef CONFIG_SPL_BUILD 263 static int exynos_gpio_get_function(struct udevice *dev, unsigned offset) 264 { 265 struct exynos_bank_info *state = dev_get_priv(dev); 266 int cfg; 267 268 cfg = s5p_gpio_get_cfg_pin(state->bank, offset); 269 if (cfg == S5P_GPIO_OUTPUT) 270 return GPIOF_OUTPUT; 271 else if (cfg == S5P_GPIO_INPUT) 272 return GPIOF_INPUT; 273 else 274 return GPIOF_FUNC; 275 } 276 277 static const struct dm_gpio_ops gpio_exynos_ops = { 278 .direction_input = exynos_gpio_direction_input, 279 .direction_output = exynos_gpio_direction_output, 280 .get_value = exynos_gpio_get_value, 281 .set_value = exynos_gpio_set_value, 282 .get_function = exynos_gpio_get_function, 283 }; 284 285 static int gpio_exynos_probe(struct udevice *dev) 286 { 287 struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); 288 struct exynos_bank_info *priv = dev->priv; 289 struct exynos_gpio_platdata *plat = dev->platdata; 290 291 /* Only child devices have ports */ 292 if (!plat) 293 return 0; 294 295 priv->bank = plat->bank; 296 297 uc_priv->gpio_count = GPIO_PER_BANK; 298 uc_priv->bank_name = plat->bank_name; 299 300 return 0; 301 } 302 303 /** 304 * We have a top-level GPIO device with no actual GPIOs. It has a child 305 * device for each Exynos GPIO bank. 306 */ 307 static int gpio_exynos_bind(struct udevice *parent) 308 { 309 struct exynos_gpio_platdata *plat = parent->platdata; 310 struct s5p_gpio_bank *bank, *base; 311 const void *blob = gd->fdt_blob; 312 int node; 313 314 /* If this is a child device, there is nothing to do here */ 315 if (plat) 316 return 0; 317 318 base = (struct s5p_gpio_bank *)devfdt_get_addr(parent); 319 for (node = fdt_first_subnode(blob, dev_of_offset(parent)), bank = base; 320 node > 0; 321 node = fdt_next_subnode(blob, node), bank++) { 322 struct exynos_gpio_platdata *plat; 323 struct udevice *dev; 324 fdt_addr_t reg; 325 int ret; 326 327 if (!fdtdec_get_bool(blob, node, "gpio-controller")) 328 continue; 329 plat = calloc(1, sizeof(*plat)); 330 if (!plat) 331 return -ENOMEM; 332 333 plat->bank_name = fdt_get_name(blob, node, NULL); 334 ret = device_bind(parent, parent->driver, 335 plat->bank_name, plat, -1, &dev); 336 if (ret) 337 return ret; 338 339 dev_set_of_offset(dev, node); 340 341 reg = devfdt_get_addr(dev); 342 if (reg != FDT_ADDR_T_NONE) 343 bank = (struct s5p_gpio_bank *)((ulong)base + reg); 344 345 plat->bank = bank; 346 347 debug("dev at %p: %s\n", bank, plat->bank_name); 348 } 349 350 return 0; 351 } 352 353 static const struct udevice_id exynos_gpio_ids[] = { 354 { .compatible = "samsung,s5pc100-pinctrl" }, 355 { .compatible = "samsung,s5pc110-pinctrl" }, 356 { .compatible = "samsung,exynos4210-pinctrl" }, 357 { .compatible = "samsung,exynos4x12-pinctrl" }, 358 { .compatible = "samsung,exynos5250-pinctrl" }, 359 { .compatible = "samsung,exynos5420-pinctrl" }, 360 { } 361 }; 362 363 U_BOOT_DRIVER(gpio_exynos) = { 364 .name = "gpio_exynos", 365 .id = UCLASS_GPIO, 366 .of_match = exynos_gpio_ids, 367 .bind = gpio_exynos_bind, 368 .probe = gpio_exynos_probe, 369 .priv_auto_alloc_size = sizeof(struct exynos_bank_info), 370 .ops = &gpio_exynos_ops, 371 }; 372 #endif 373