uboot/drivers/gpio/da8xx_gpio.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * GPIO driver for TI DaVinci DA8xx SOCs.
   4 *
   5 * (C) Copyright 2011 Guralp Systems Ltd.
   6 * Laurence Withers <lwithers@guralp.com>
   7 */
   8
   9#include <common.h>
  10#include <dm.h>
  11#include <fdtdec.h>
  12#include <malloc.h>
  13#include <asm/io.h>
  14#include <asm/global_data.h>
  15#include <asm/gpio.h>
  16#include <dt-bindings/gpio/gpio.h>
  17
  18#include "da8xx_gpio.h"
  19
  20#if !CONFIG_IS_ENABLED(DM_GPIO)
  21#include <asm/arch/hardware.h>
  22#include <asm/arch/davinci_misc.h>
  23
  24static struct gpio_registry {
  25        int is_registered;
  26        char name[GPIO_NAME_SIZE];
  27} gpio_registry[MAX_NUM_GPIOS];
  28
  29#if defined(CONFIG_SOC_DA8XX)
  30#define pinmux(x)       (&davinci_syscfg_regs->pinmux[x])
  31
  32#if defined(CONFIG_SOC_DA8XX) && !defined(CONFIG_SOC_DA850)
  33static const struct pinmux_config gpio_pinmux[] = {
  34        { pinmux(13), 8, 6 },   /* GP0[0] */
  35        { pinmux(13), 8, 7 },
  36        { pinmux(14), 8, 0 },
  37        { pinmux(14), 8, 1 },
  38        { pinmux(14), 8, 2 },
  39        { pinmux(14), 8, 3 },
  40        { pinmux(14), 8, 4 },
  41        { pinmux(14), 8, 5 },
  42        { pinmux(14), 8, 6 },
  43        { pinmux(14), 8, 7 },
  44        { pinmux(15), 8, 0 },
  45        { pinmux(15), 8, 1 },
  46        { pinmux(15), 8, 2 },
  47        { pinmux(15), 8, 3 },
  48        { pinmux(15), 8, 4 },
  49        { pinmux(15), 8, 5 },
  50        { pinmux(15), 8, 6 },   /* GP1[0] */
  51        { pinmux(15), 8, 7 },
  52        { pinmux(16), 8, 0 },
  53        { pinmux(16), 8, 1 },
  54        { pinmux(16), 8, 2 },
  55        { pinmux(16), 8, 3 },
  56        { pinmux(16), 8, 4 },
  57        { pinmux(16), 8, 5 },
  58        { pinmux(16), 8, 6 },
  59        { pinmux(16), 8, 7 },
  60        { pinmux(17), 8, 0 },
  61        { pinmux(17), 8, 1 },
  62        { pinmux(17), 8, 2 },
  63        { pinmux(17), 8, 3 },
  64        { pinmux(17), 8, 4 },
  65        { pinmux(17), 8, 5 },
  66        { pinmux(17), 8, 6 },   /* GP2[0] */
  67        { pinmux(17), 8, 7 },
  68        { pinmux(18), 8, 0 },
  69        { pinmux(18), 8, 1 },
  70        { pinmux(18), 8, 2 },
  71        { pinmux(18), 8, 3 },
  72        { pinmux(18), 8, 4 },
  73        { pinmux(18), 8, 5 },
  74        { pinmux(18), 8, 6 },
  75        { pinmux(18), 8, 7 },
  76        { pinmux(19), 8, 0 },
  77        { pinmux(9), 8, 2 },
  78        { pinmux(9), 8, 3 },
  79        { pinmux(9), 8, 4 },
  80        { pinmux(9), 8, 5 },
  81        { pinmux(9), 8, 6 },
  82        { pinmux(10), 8, 1 },   /* GP3[0] */
  83        { pinmux(10), 8, 2 },
  84        { pinmux(10), 8, 3 },
  85        { pinmux(10), 8, 4 },
  86        { pinmux(10), 8, 5 },
  87        { pinmux(10), 8, 6 },
  88        { pinmux(10), 8, 7 },
  89        { pinmux(11), 8, 0 },
  90        { pinmux(11), 8, 1 },
  91        { pinmux(11), 8, 2 },
  92        { pinmux(11), 8, 3 },
  93        { pinmux(11), 8, 4 },
  94        { pinmux(9), 8, 7 },
  95        { pinmux(2), 8, 6 },
  96        { pinmux(11), 8, 5 },
  97        { pinmux(11), 8, 6 },
  98        { pinmux(12), 8, 4 },   /* GP4[0] */
  99        { pinmux(12), 8, 5 },
 100        { pinmux(12), 8, 6 },
 101        { pinmux(12), 8, 7 },
 102        { pinmux(13), 8, 0 },
 103        { pinmux(13), 8, 1 },
 104        { pinmux(13), 8, 2 },
 105        { pinmux(13), 8, 3 },
 106        { pinmux(13), 8, 4 },
 107        { pinmux(13), 8, 5 },
 108        { pinmux(11), 8, 7 },
 109        { pinmux(12), 8, 0 },
 110        { pinmux(12), 8, 1 },
 111        { pinmux(12), 8, 2 },
 112        { pinmux(12), 8, 3 },
 113        { pinmux(9), 8, 1 },
 114        { pinmux(7), 8, 3 },    /* GP5[0] */
 115        { pinmux(7), 8, 4 },
 116        { pinmux(7), 8, 5 },
 117        { pinmux(7), 8, 6 },
 118        { pinmux(7), 8, 7 },
 119        { pinmux(8), 8, 0 },
 120        { pinmux(8), 8, 1 },
 121        { pinmux(8), 8, 2 },
 122        { pinmux(8), 8, 3 },
 123        { pinmux(8), 8, 4 },
 124        { pinmux(8), 8, 5 },
 125        { pinmux(8), 8, 6 },
 126        { pinmux(8), 8, 7 },
 127        { pinmux(9), 8, 0 },
 128        { pinmux(7), 8, 1 },
 129        { pinmux(7), 8, 2 },
 130        { pinmux(5), 8, 1 },    /* GP6[0] */
 131        { pinmux(5), 8, 2 },
 132        { pinmux(5), 8, 3 },
 133        { pinmux(5), 8, 4 },
 134        { pinmux(5), 8, 5 },
 135        { pinmux(5), 8, 6 },
 136        { pinmux(5), 8, 7 },
 137        { pinmux(6), 8, 0 },
 138        { pinmux(6), 8, 1 },
 139        { pinmux(6), 8, 2 },
 140        { pinmux(6), 8, 3 },
 141        { pinmux(6), 8, 4 },
 142        { pinmux(6), 8, 5 },
 143        { pinmux(6), 8, 6 },
 144        { pinmux(6), 8, 7 },
 145        { pinmux(7), 8, 0 },
 146        { pinmux(1), 8, 0 },    /* GP7[0] */
 147        { pinmux(1), 8, 1 },
 148        { pinmux(1), 8, 2 },
 149        { pinmux(1), 8, 3 },
 150        { pinmux(1), 8, 4 },
 151        { pinmux(1), 8, 5 },
 152        { pinmux(1), 8, 6 },
 153        { pinmux(1), 8, 7 },
 154        { pinmux(2), 8, 0 },
 155        { pinmux(2), 8, 1 },
 156        { pinmux(2), 8, 2 },
 157        { pinmux(2), 8, 3 },
 158        { pinmux(2), 8, 4 },
 159        { pinmux(2), 8, 5 },
 160        { pinmux(0), 1, 0 },
 161        { pinmux(0), 1, 1 },
 162};
 163#else /* CONFIG_SOC_DA8XX && CONFIG_SOC_DA850 */
 164static const struct pinmux_config gpio_pinmux[] = {
 165        { pinmux(1), 8, 7 },    /* GP0[0] */
 166        { pinmux(1), 8, 6 },
 167        { pinmux(1), 8, 5 },
 168        { pinmux(1), 8, 4 },
 169        { pinmux(1), 8, 3 },
 170        { pinmux(1), 8, 2 },
 171        { pinmux(1), 8, 1 },
 172        { pinmux(1), 8, 0 },
 173        { pinmux(0), 8, 7 },
 174        { pinmux(0), 8, 6 },
 175        { pinmux(0), 8, 5 },
 176        { pinmux(0), 8, 4 },
 177        { pinmux(0), 8, 3 },
 178        { pinmux(0), 8, 2 },
 179        { pinmux(0), 8, 1 },
 180        { pinmux(0), 8, 0 },
 181        { pinmux(4), 8, 7 },    /* GP1[0] */
 182        { pinmux(4), 8, 6 },
 183        { pinmux(4), 8, 5 },
 184        { pinmux(4), 8, 4 },
 185        { pinmux(4), 8, 3 },
 186        { pinmux(4), 8, 2 },
 187        { pinmux(4), 4, 1 },
 188        { pinmux(4), 4, 0 },
 189        { pinmux(3), 4, 0 },
 190        { pinmux(2), 4, 6 },
 191        { pinmux(2), 4, 5 },
 192        { pinmux(2), 4, 4 },
 193        { pinmux(2), 4, 3 },
 194        { pinmux(2), 4, 2 },
 195        { pinmux(2), 4, 1 },
 196        { pinmux(2), 8, 0 },
 197        { pinmux(6), 8, 7 },    /* GP2[0] */
 198        { pinmux(6), 8, 6 },
 199        { pinmux(6), 8, 5 },
 200        { pinmux(6), 8, 4 },
 201        { pinmux(6), 8, 3 },
 202        { pinmux(6), 8, 2 },
 203        { pinmux(6), 8, 1 },
 204        { pinmux(6), 8, 0 },
 205        { pinmux(5), 8, 7 },
 206        { pinmux(5), 8, 6 },
 207        { pinmux(5), 8, 5 },
 208        { pinmux(5), 8, 4 },
 209        { pinmux(5), 8, 3 },
 210        { pinmux(5), 8, 2 },
 211        { pinmux(5), 8, 1 },
 212        { pinmux(5), 8, 0 },
 213        { pinmux(8), 8, 7 },    /* GP3[0] */
 214        { pinmux(8), 8, 6 },
 215        { pinmux(8), 8, 5 },
 216        { pinmux(8), 8, 4 },
 217        { pinmux(8), 8, 3 },
 218        { pinmux(8), 8, 2 },
 219        { pinmux(8), 8, 1 },
 220        { pinmux(8), 8, 0 },
 221        { pinmux(7), 8, 7 },
 222        { pinmux(7), 8, 6 },
 223        { pinmux(7), 8, 5 },
 224        { pinmux(7), 8, 4 },
 225        { pinmux(7), 8, 3 },
 226        { pinmux(7), 8, 2 },
 227        { pinmux(7), 8, 1 },
 228        { pinmux(7), 8, 0 },
 229        { pinmux(10), 8, 7 },   /* GP4[0] */
 230        { pinmux(10), 8, 6 },
 231        { pinmux(10), 8, 5 },
 232        { pinmux(10), 8, 4 },
 233        { pinmux(10), 8, 3 },
 234        { pinmux(10), 8, 2 },
 235        { pinmux(10), 8, 1 },
 236        { pinmux(10), 8, 0 },
 237        { pinmux(9), 8, 7 },
 238        { pinmux(9), 8, 6 },
 239        { pinmux(9), 8, 5 },
 240        { pinmux(9), 8, 4 },
 241        { pinmux(9), 8, 3 },
 242        { pinmux(9), 8, 2 },
 243        { pinmux(9), 8, 1 },
 244        { pinmux(9), 8, 0 },
 245        { pinmux(12), 8, 7 },   /* GP5[0] */
 246        { pinmux(12), 8, 6 },
 247        { pinmux(12), 8, 5 },
 248        { pinmux(12), 8, 4 },
 249        { pinmux(12), 8, 3 },
 250        { pinmux(12), 8, 2 },
 251        { pinmux(12), 8, 1 },
 252        { pinmux(12), 8, 0 },
 253        { pinmux(11), 8, 7 },
 254        { pinmux(11), 8, 6 },
 255        { pinmux(11), 8, 5 },
 256        { pinmux(11), 8, 4 },
 257        { pinmux(11), 8, 3 },
 258        { pinmux(11), 8, 2 },
 259        { pinmux(11), 8, 1 },
 260        { pinmux(11), 8, 0 },
 261        { pinmux(19), 8, 6 },   /* GP6[0] */
 262        { pinmux(19), 8, 5 },
 263        { pinmux(19), 8, 4 },
 264        { pinmux(19), 8, 3 },
 265        { pinmux(19), 8, 2 },
 266        { pinmux(16), 8, 1 },
 267        { pinmux(14), 8, 1 },
 268        { pinmux(14), 8, 0 },
 269        { pinmux(13), 8, 7 },
 270        { pinmux(13), 8, 6 },
 271        { pinmux(13), 8, 5 },
 272        { pinmux(13), 8, 4 },
 273        { pinmux(13), 8, 3 },
 274        { pinmux(13), 8, 2 },
 275        { pinmux(13), 8, 1 },
 276        { pinmux(13), 8, 0 },
 277        { pinmux(18), 8, 1 },   /* GP7[0] */
 278        { pinmux(18), 8, 0 },
 279        { pinmux(17), 8, 7 },
 280        { pinmux(17), 8, 6 },
 281        { pinmux(17), 8, 5 },
 282        { pinmux(17), 8, 4 },
 283        { pinmux(17), 8, 3 },
 284        { pinmux(17), 8, 2 },
 285        { pinmux(17), 8, 1 },
 286        { pinmux(17), 8, 0 },
 287        { pinmux(16), 8, 7 },
 288        { pinmux(16), 8, 6 },
 289        { pinmux(16), 8, 5 },
 290        { pinmux(16), 8, 4 },
 291        { pinmux(16), 8, 3 },
 292        { pinmux(16), 8, 2 },
 293        { pinmux(19), 8, 0 },   /* GP8[0] */
 294        { pinmux(3), 4, 7 },
 295        { pinmux(3), 4, 6 },
 296        { pinmux(3), 4, 5 },
 297        { pinmux(3), 4, 4 },
 298        { pinmux(3), 4, 3 },
 299        { pinmux(3), 4, 2 },
 300        { pinmux(2), 4, 7 },
 301        { pinmux(19), 8, 1 },
 302        { pinmux(19), 8, 0 },
 303        { pinmux(18), 8, 7 },
 304        { pinmux(18), 8, 6 },
 305        { pinmux(18), 8, 5 },
 306        { pinmux(18), 8, 4 },
 307        { pinmux(18), 8, 3 },
 308        { pinmux(18), 8, 2 },
 309};
 310#endif /* CONFIG_SOC_DA8XX && !CONFIG_SOC_DA850 */
 311#else /* !CONFIG_SOC_DA8XX */
 312#define davinci_configure_pin_mux(a, b)
 313#endif /* CONFIG_SOC_DA8XX */
 314
 315int gpio_request(unsigned int gpio, const char *label)
 316{
 317        if (gpio >= MAX_NUM_GPIOS)
 318                return -1;
 319
 320        if (gpio_registry[gpio].is_registered)
 321                return -1;
 322
 323        gpio_registry[gpio].is_registered = 1;
 324        strncpy(gpio_registry[gpio].name, label, GPIO_NAME_SIZE);
 325        gpio_registry[gpio].name[GPIO_NAME_SIZE - 1] = 0;
 326
 327        davinci_configure_pin_mux(&gpio_pinmux[gpio], 1);
 328
 329        return 0;
 330}
 331
 332int gpio_free(unsigned int gpio)
 333{
 334        if (gpio >= MAX_NUM_GPIOS)
 335                return -1;
 336
 337        if (!gpio_registry[gpio].is_registered)
 338                return -1;
 339
 340        gpio_registry[gpio].is_registered = 0;
 341        gpio_registry[gpio].name[0] = '\0';
 342        /* Do not configure as input or change pin mux here */
 343        return 0;
 344}
 345#endif
 346
 347static int _gpio_direction_input(struct davinci_gpio *bank, unsigned int gpio)
 348{
 349        setbits_le32(&bank->dir, 1U << GPIO_BIT(gpio));
 350        return 0;
 351}
 352
 353static int _gpio_get_value(struct davinci_gpio *bank, unsigned int gpio)
 354{
 355        unsigned int ip;
 356        ip = in_le32(&bank->in_data) & (1U << GPIO_BIT(gpio));
 357        return ip ? 1 : 0;
 358}
 359
 360static int _gpio_set_value(struct davinci_gpio *bank, unsigned int gpio, int value)
 361{
 362        if (value)
 363                bank->set_data = 1U << GPIO_BIT(gpio);
 364        else
 365                bank->clr_data = 1U << GPIO_BIT(gpio);
 366
 367        return 0;
 368}
 369
 370static int _gpio_get_dir(struct davinci_gpio *bank, unsigned int gpio)
 371{
 372        return in_le32(&bank->dir) & (1U << GPIO_BIT(gpio));
 373}
 374
 375static int _gpio_direction_output(struct davinci_gpio *bank, unsigned int gpio,
 376                                  int value)
 377{
 378        clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio));
 379        _gpio_set_value(bank, gpio, value);
 380        return 0;
 381}
 382
 383#if !CONFIG_IS_ENABLED(DM_GPIO)
 384
 385void gpio_info(void)
 386{
 387        unsigned int gpio, dir, val;
 388        struct davinci_gpio *bank;
 389
 390        for (gpio = 0; gpio < MAX_NUM_GPIOS; ++gpio) {
 391                bank = GPIO_BANK(gpio);
 392                dir = _gpio_get_dir(bank, gpio);
 393                val = gpio_get_value(gpio);
 394
 395                printf("% 4d: %s: %d [%c] %s\n",
 396                        gpio, dir ? " in" : "out", val,
 397                        gpio_registry[gpio].is_registered ? 'x' : ' ',
 398                        gpio_registry[gpio].name);
 399        }
 400}
 401
 402int gpio_direction_input(unsigned int gpio)
 403{
 404        struct davinci_gpio *bank;
 405
 406        bank = GPIO_BANK(gpio);
 407        return _gpio_direction_input(bank, gpio);
 408}
 409
 410int gpio_direction_output(unsigned int gpio, int value)
 411{
 412        struct davinci_gpio *bank;
 413
 414        bank = GPIO_BANK(gpio);
 415        return _gpio_direction_output(bank, gpio, value);
 416}
 417
 418int gpio_get_value(unsigned int gpio)
 419{
 420        struct davinci_gpio *bank;
 421
 422        bank = GPIO_BANK(gpio);
 423        return _gpio_get_value(bank, gpio);
 424}
 425
 426int gpio_set_value(unsigned int gpio, int value)
 427{
 428        struct davinci_gpio *bank;
 429
 430        bank = GPIO_BANK(gpio);
 431        return _gpio_set_value(bank, gpio, value);
 432}
 433
 434#else /* DM_GPIO */
 435
 436static struct davinci_gpio *davinci_get_gpio_bank(struct udevice *dev, unsigned int offset)
 437{
 438        struct davinci_gpio_bank *bank = dev_get_priv(dev);
 439        unsigned long addr;
 440
 441        /*
 442         * The device tree is not broken into banks but the infrastructure is
 443         * expecting it this way, so we'll first include the 0x10 offset, then
 444         * calculate the bank manually based on the offset.
 445         * Casting 'addr' as Unsigned long is needed to make the math work.
 446         */
 447        addr = ((unsigned long)(struct davinci_gpio *)bank->base) +
 448                        0x10 + (0x28 * (offset >> 5));
 449        return (struct davinci_gpio *)addr;
 450}
 451
 452static int davinci_gpio_direction_input(struct udevice *dev, unsigned int offset)
 453{
 454        struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
 455
 456        /*
 457         * Fetch the address based on GPIO, but only pass the masked low 32-bits
 458         */
 459        _gpio_direction_input(base, (offset & 0x1f));
 460        return 0;
 461}
 462
 463static int davinci_gpio_direction_output(struct udevice *dev, unsigned int offset,
 464                                         int value)
 465{
 466        struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
 467
 468        _gpio_direction_output(base, (offset & 0x1f), value);
 469        return 0;
 470}
 471
 472static int davinci_gpio_get_value(struct udevice *dev, unsigned int offset)
 473{
 474        struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
 475
 476        return _gpio_get_value(base, (offset & 0x1f));
 477}
 478
 479static int davinci_gpio_set_value(struct udevice *dev, unsigned int offset,
 480                                  int value)
 481{
 482        struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
 483
 484        _gpio_set_value(base, (offset & 0x1f), value);
 485
 486        return 0;
 487}
 488
 489static int davinci_gpio_get_function(struct udevice *dev, unsigned int offset)
 490{
 491        unsigned int dir;
 492        struct davinci_gpio *base = davinci_get_gpio_bank(dev, offset);
 493
 494        dir = _gpio_get_dir(base, offset);
 495
 496        if (dir)
 497                return GPIOF_INPUT;
 498
 499        return GPIOF_OUTPUT;
 500}
 501
 502static int davinci_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
 503                              struct ofnode_phandle_args *args)
 504{
 505        desc->offset = args->args[0];
 506
 507        if (args->args[1] & GPIO_ACTIVE_LOW)
 508                desc->flags = GPIOD_ACTIVE_LOW;
 509        else
 510                desc->flags = 0;
 511        return 0;
 512}
 513
 514static const struct dm_gpio_ops gpio_davinci_ops = {
 515        .direction_input        = davinci_gpio_direction_input,
 516        .direction_output       = davinci_gpio_direction_output,
 517        .get_value              = davinci_gpio_get_value,
 518        .set_value              = davinci_gpio_set_value,
 519        .get_function           = davinci_gpio_get_function,
 520        .xlate                  = davinci_gpio_xlate,
 521};
 522
 523static int davinci_gpio_probe(struct udevice *dev)
 524{
 525        struct davinci_gpio_bank *bank = dev_get_priv(dev);
 526        struct davinci_gpio_plat *plat = dev_get_plat(dev);
 527        struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 528        const void *fdt = gd->fdt_blob;
 529        int node = dev_of_offset(dev);
 530
 531        uc_priv->bank_name = plat->port_name;
 532        uc_priv->gpio_count = fdtdec_get_int(fdt, node, "ti,ngpio", -1);
 533        bank->base = (struct davinci_gpio *)plat->base;
 534        return 0;
 535}
 536
 537static const struct udevice_id davinci_gpio_ids[] = {
 538        { .compatible = "ti,dm6441-gpio" },
 539        { .compatible = "ti,k2g-gpio" },
 540        { .compatible = "ti,keystone-gpio" },
 541        { }
 542};
 543
 544static int davinci_gpio_of_to_plat(struct udevice *dev)
 545{
 546        struct davinci_gpio_plat *plat = dev_get_plat(dev);
 547        fdt_addr_t addr;
 548        char name[18], *str;
 549
 550        addr = dev_read_addr(dev);
 551        if (addr == FDT_ADDR_T_NONE)
 552                return -EINVAL;
 553
 554        plat->base = addr;
 555
 556        sprintf(name, "gpio@%4x_", (unsigned int)plat->base);
 557        str = strdup(name);
 558        if (!str)
 559                return -ENOMEM;
 560        plat->port_name = str;
 561
 562        return 0;
 563}
 564
 565U_BOOT_DRIVER(ti_dm6441_gpio) = {
 566        .name   = "ti_dm6441_gpio",
 567        .id     = UCLASS_GPIO,
 568        .ops    = &gpio_davinci_ops,
 569        .of_to_plat = of_match_ptr(davinci_gpio_of_to_plat),
 570        .of_match = davinci_gpio_ids,
 571        .bind   = dm_scan_fdt_dev,
 572        .plat_auto      = sizeof(struct davinci_gpio_plat),
 573        .probe  = davinci_gpio_probe,
 574        .priv_auto      = sizeof(struct davinci_gpio_bank),
 575};
 576
 577#endif
 578