uboot/drivers/pinctrl/pinctrl_pic32.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Pinctrl driver for Microchip PIC32 SoCs
   4 * Copyright (c) 2015 Microchip Technology Inc.
   5 * Written by Purna Chandra Mandal <purna.mandal@microchip.com>
   6 */
   7#include <common.h>
   8#include <dm.h>
   9#include <errno.h>
  10#include <asm/io.h>
  11#include <dm/pinctrl.h>
  12#include <mach/pic32.h>
  13
  14DECLARE_GLOBAL_DATA_PTR;
  15
  16/* PIC32 has 10 peripheral ports with 16 pins each.
  17 * Ports are marked PORTA-PORTK or PORT0-PORT9.
  18 */
  19enum {
  20        PIC32_PORT_A = 0,
  21        PIC32_PORT_B = 1,
  22        PIC32_PORT_C = 2,
  23        PIC32_PORT_D = 3,
  24        PIC32_PORT_E = 4,
  25        PIC32_PORT_F = 5,
  26        PIC32_PORT_G = 6,
  27        PIC32_PORT_H = 7,
  28        PIC32_PORT_J = 8, /* no PORT_I */
  29        PIC32_PORT_K = 9,
  30        PIC32_PINS_PER_PORT = 16,
  31};
  32
  33#define PIN_CONFIG_PIC32_DIGITAL        (PIN_CONFIG_END + 1)
  34#define PIN_CONFIG_PIC32_ANALOG         (PIN_CONFIG_END + 2)
  35
  36/* pin configuration descriptor */
  37struct pic32_pin_config {
  38        u16 port;       /* port number */
  39        u16 pin;        /* pin number in the port */
  40        u32 config;     /* one of PIN_CONFIG_* */
  41};
  42#define PIN_CONFIG(_prt, _pin, _cfg) \
  43        {.port = (_prt), .pin = (_pin), .config = (_cfg), }
  44
  45/* In PIC32 muxing is performed at pin-level through two
  46 * different set of registers - one set for input functions,
  47 * and other for output functions.
  48 * Pin configuration is handled through port register.
  49 */
  50/* Port control registers */
  51struct pic32_reg_port {
  52        struct pic32_reg_atomic ansel;
  53        struct pic32_reg_atomic tris;
  54        struct pic32_reg_atomic port;
  55        struct pic32_reg_atomic lat;
  56        struct pic32_reg_atomic odc;
  57        struct pic32_reg_atomic cnpu;
  58        struct pic32_reg_atomic cnpd;
  59        struct pic32_reg_atomic cncon;
  60        struct pic32_reg_atomic unused[8];
  61};
  62
  63/* Input function mux registers */
  64struct pic32_reg_in_mux {
  65        u32 unused0;
  66        u32 int1[4];
  67        u32 unused1;
  68        u32 t2ck[8];
  69        u32 ic1[9];
  70        u32 unused2;
  71        u32 ocfar;
  72        u32 unused3;
  73        u32 u1rx;
  74        u32 u1cts;
  75        u32 u2rx;
  76        u32 u2cts;
  77        u32 u3rx;
  78        u32 u3cts;
  79        u32 u4rx;
  80        u32 u4cts;
  81        u32 u5rx;
  82        u32 u5cts;
  83        u32 u6rx;
  84        u32 u6cts;
  85        u32 unused4;
  86        u32 sdi1;
  87        u32 ss1;
  88        u32 unused5;
  89        u32 sdi2;
  90        u32 ss2;
  91        u32 unused6;
  92        u32 sdi3;
  93        u32 ss3;
  94        u32 unused7;
  95        u32 sdi4;
  96        u32 ss4;
  97        u32 unused8;
  98        u32 sdi5;
  99        u32 ss5;
 100        u32 unused9;
 101        u32 sdi6;
 102        u32 ss6;
 103        u32 c1rx;
 104        u32 c2rx;
 105        u32 refclki1;
 106        u32 refclki2;
 107        u32 refclki3;
 108        u32 refclki4;
 109};
 110
 111/* output mux register offset */
 112#define PPS_OUT(__port, __pin) \
 113        (((__port) * PIC32_PINS_PER_PORT + (__pin)) << 2)
 114
 115
 116struct pic32_pinctrl_priv {
 117        struct pic32_reg_in_mux *mux_in; /* mux input function */
 118        struct pic32_reg_port *pinconf; /* pin configuration*/
 119        void __iomem *mux_out;  /* mux output function */
 120};
 121
 122enum {
 123        PERIPH_ID_UART1,
 124        PERIPH_ID_UART2,
 125        PERIPH_ID_ETH,
 126        PERIPH_ID_USB,
 127        PERIPH_ID_SDHCI,
 128        PERIPH_ID_I2C1,
 129        PERIPH_ID_I2C2,
 130        PERIPH_ID_SPI1,
 131        PERIPH_ID_SPI2,
 132        PERIPH_ID_SQI,
 133};
 134
 135static int pic32_pinconfig_one(struct pic32_pinctrl_priv *priv,
 136                               u32 port_nr, u32 pin, u32 param)
 137{
 138        struct pic32_reg_port *port;
 139
 140        port = &priv->pinconf[port_nr];
 141        switch (param) {
 142        case PIN_CONFIG_PIC32_DIGITAL:
 143                writel(BIT(pin), &port->ansel.clr);
 144                break;
 145        case PIN_CONFIG_PIC32_ANALOG:
 146                writel(BIT(pin), &port->ansel.set);
 147                break;
 148        case PIN_CONFIG_INPUT_ENABLE:
 149                writel(BIT(pin), &port->tris.set);
 150                break;
 151        case PIN_CONFIG_OUTPUT:
 152                writel(BIT(pin), &port->tris.clr);
 153                break;
 154        case PIN_CONFIG_BIAS_PULL_UP:
 155                writel(BIT(pin), &port->cnpu.set);
 156                break;
 157        case PIN_CONFIG_BIAS_PULL_DOWN:
 158                writel(BIT(pin), &port->cnpd.set);
 159                break;
 160        case PIN_CONFIG_DRIVE_OPEN_DRAIN:
 161                writel(BIT(pin), &port->odc.set);
 162                break;
 163        default:
 164                break;
 165        }
 166
 167        return 0;
 168}
 169
 170static int pic32_pinconfig_set(struct pic32_pinctrl_priv *priv,
 171                               const struct pic32_pin_config *list, int count)
 172{
 173        int i;
 174
 175        for (i = 0 ; i < count; i++)
 176                pic32_pinconfig_one(priv, list[i].port,
 177                                    list[i].pin, list[i].config);
 178
 179        return 0;
 180}
 181
 182static void pic32_eth_pin_config(struct udevice *dev)
 183{
 184        struct pic32_pinctrl_priv *priv = dev_get_priv(dev);
 185        const struct pic32_pin_config configs[] = {
 186                /* EMDC - D11 */
 187                PIN_CONFIG(PIC32_PORT_D, 11, PIN_CONFIG_PIC32_DIGITAL),
 188                PIN_CONFIG(PIC32_PORT_D, 11, PIN_CONFIG_OUTPUT),
 189                /* ETXEN */
 190                PIN_CONFIG(PIC32_PORT_D, 6, PIN_CONFIG_PIC32_DIGITAL),
 191                PIN_CONFIG(PIC32_PORT_D, 6, PIN_CONFIG_OUTPUT),
 192                /* ECRSDV */
 193                PIN_CONFIG(PIC32_PORT_H, 13, PIN_CONFIG_PIC32_DIGITAL),
 194                PIN_CONFIG(PIC32_PORT_H, 13, PIN_CONFIG_INPUT_ENABLE),
 195                /* ERXD0 */
 196                PIN_CONFIG(PIC32_PORT_H, 8, PIN_CONFIG_PIC32_DIGITAL),
 197                PIN_CONFIG(PIC32_PORT_H, 8, PIN_CONFIG_INPUT_ENABLE),
 198                PIN_CONFIG(PIC32_PORT_H, 8, PIN_CONFIG_BIAS_PULL_DOWN),
 199                /* ERXD1 */
 200                PIN_CONFIG(PIC32_PORT_H, 5, PIN_CONFIG_PIC32_DIGITAL),
 201                PIN_CONFIG(PIC32_PORT_H, 5, PIN_CONFIG_INPUT_ENABLE),
 202                PIN_CONFIG(PIC32_PORT_H, 5, PIN_CONFIG_BIAS_PULL_DOWN),
 203                /* EREFCLK */
 204                PIN_CONFIG(PIC32_PORT_J, 11, PIN_CONFIG_PIC32_DIGITAL),
 205                PIN_CONFIG(PIC32_PORT_J, 11, PIN_CONFIG_INPUT_ENABLE),
 206                /* ETXD1 */
 207                PIN_CONFIG(PIC32_PORT_J, 9, PIN_CONFIG_PIC32_DIGITAL),
 208                PIN_CONFIG(PIC32_PORT_J, 9, PIN_CONFIG_OUTPUT),
 209                /* ETXD0 */
 210                PIN_CONFIG(PIC32_PORT_J, 8, PIN_CONFIG_PIC32_DIGITAL),
 211                PIN_CONFIG(PIC32_PORT_J, 8, PIN_CONFIG_OUTPUT),
 212                /* EMDIO */
 213                PIN_CONFIG(PIC32_PORT_J, 1, PIN_CONFIG_PIC32_DIGITAL),
 214                PIN_CONFIG(PIC32_PORT_J, 1, PIN_CONFIG_INPUT_ENABLE),
 215                /* ERXERR */
 216                PIN_CONFIG(PIC32_PORT_F, 3, PIN_CONFIG_PIC32_DIGITAL),
 217                PIN_CONFIG(PIC32_PORT_F, 3, PIN_CONFIG_INPUT_ENABLE),
 218        };
 219
 220        pic32_pinconfig_set(priv, configs, ARRAY_SIZE(configs));
 221}
 222
 223static int pic32_pinctrl_request(struct udevice *dev, int func, int flags)
 224{
 225        struct pic32_pinctrl_priv *priv = dev_get_priv(dev);
 226
 227        switch (func) {
 228        case PERIPH_ID_UART2:
 229                /* PPS for U2 RX/TX */
 230                writel(0x02, priv->mux_out + PPS_OUT(PIC32_PORT_G, 9));
 231                writel(0x05, &priv->mux_in->u2rx); /* B0 */
 232                /* set digital mode */
 233                pic32_pinconfig_one(priv, PIC32_PORT_G, 9,
 234                                    PIN_CONFIG_PIC32_DIGITAL);
 235                pic32_pinconfig_one(priv, PIC32_PORT_B, 0,
 236                                    PIN_CONFIG_PIC32_DIGITAL);
 237                break;
 238        case PERIPH_ID_ETH:
 239                pic32_eth_pin_config(dev);
 240                break;
 241        default:
 242                debug("%s: unknown-unhandled case\n", __func__);
 243                break;
 244        }
 245
 246        return 0;
 247}
 248
 249static int pic32_pinctrl_get_periph_id(struct udevice *dev,
 250                                       struct udevice *periph)
 251{
 252        int ret;
 253        u32 cell[2];
 254
 255        ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
 256                                   "interrupts", cell, ARRAY_SIZE(cell));
 257        if (ret < 0)
 258                return -EINVAL;
 259
 260        /* interrupt number */
 261        switch (cell[0]) {
 262        case 112 ... 114:
 263                return PERIPH_ID_UART1;
 264        case 145 ... 147:
 265                return PERIPH_ID_UART2;
 266        case 109 ... 111:
 267                return PERIPH_ID_SPI1;
 268        case 142 ... 144:
 269                return PERIPH_ID_SPI2;
 270        case 115 ... 117:
 271                return PERIPH_ID_I2C1;
 272        case 148 ... 150:
 273                return PERIPH_ID_I2C2;
 274        case 132 ... 133:
 275                return PERIPH_ID_USB;
 276        case 169:
 277                return PERIPH_ID_SQI;
 278        case 191:
 279                return PERIPH_ID_SDHCI;
 280        case 153:
 281                return PERIPH_ID_ETH;
 282        default:
 283                break;
 284        }
 285
 286        return -ENOENT;
 287}
 288
 289static int pic32_pinctrl_set_state_simple(struct udevice *dev,
 290                                          struct udevice *periph)
 291{
 292        int func;
 293
 294        debug("%s: periph %s\n", __func__, periph->name);
 295        func = pic32_pinctrl_get_periph_id(dev, periph);
 296        if (func < 0)
 297                return func;
 298        return pic32_pinctrl_request(dev, func, 0);
 299}
 300
 301static struct pinctrl_ops pic32_pinctrl_ops = {
 302        .set_state_simple       = pic32_pinctrl_set_state_simple,
 303        .request                = pic32_pinctrl_request,
 304        .get_periph_id          = pic32_pinctrl_get_periph_id,
 305};
 306
 307static int pic32_pinctrl_probe(struct udevice *dev)
 308{
 309        struct pic32_pinctrl_priv *priv = dev_get_priv(dev);
 310        struct fdt_resource res;
 311        void *fdt = (void *)gd->fdt_blob;
 312        int node = dev_of_offset(dev);
 313        int ret;
 314
 315        ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
 316                                     "ppsin", &res);
 317        if (ret < 0) {
 318                printf("pinctrl: resource \"ppsin\" not found\n");
 319                return ret;
 320        }
 321        priv->mux_in = ioremap(res.start, fdt_resource_size(&res));
 322
 323        ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
 324                                     "ppsout", &res);
 325        if (ret < 0) {
 326                printf("pinctrl: resource \"ppsout\" not found\n");
 327                return ret;
 328        }
 329        priv->mux_out = ioremap(res.start, fdt_resource_size(&res));
 330
 331        ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
 332                                     "port", &res);
 333        if (ret < 0) {
 334                printf("pinctrl: resource \"port\" not found\n");
 335                return ret;
 336        }
 337        priv->pinconf = ioremap(res.start, fdt_resource_size(&res));
 338
 339        return 0;
 340}
 341
 342static const struct udevice_id pic32_pinctrl_ids[] = {
 343        { .compatible = "microchip,pic32mzda-pinctrl" },
 344        { }
 345};
 346
 347U_BOOT_DRIVER(pinctrl_pic32) = {
 348        .name           = "pinctrl_pic32",
 349        .id             = UCLASS_PINCTRL,
 350        .of_match       = pic32_pinctrl_ids,
 351        .ops            = &pic32_pinctrl_ops,
 352        .probe          = pic32_pinctrl_probe,
 353        .bind           = dm_scan_fdt_dev,
 354        .priv_auto_alloc_size = sizeof(struct pic32_pinctrl_priv),
 355};
 356