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