uboot/drivers/i2c/i2c-uniphier-f.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <common.h>
   8#include <linux/types.h>
   9#include <linux/io.h>
  10#include <asm/errno.h>
  11#include <dm/device.h>
  12#include <dm/root.h>
  13#include <i2c.h>
  14#include <fdtdec.h>
  15#include <mapmem.h>
  16
  17DECLARE_GLOBAL_DATA_PTR;
  18
  19struct uniphier_fi2c_regs {
  20        u32 cr;                         /* control register */
  21#define I2C_CR_MST      (1 << 3)        /* master mode */
  22#define I2C_CR_STA      (1 << 2)        /* start condition */
  23#define I2C_CR_STO      (1 << 1)        /* stop condition */
  24#define I2C_CR_NACK     (1 << 0)        /* not ACK */
  25        u32 dttx;                       /* send FIFO (write-only) */
  26#define dtrx            dttx            /* receive FIFO (read-only) */
  27#define I2C_DTTX_CMD    (1 << 8)        /* send command (slave addr) */
  28#define I2C_DTTX_RD     (1 << 0)        /* read */
  29        u32 __reserved;                 /* no register at offset 0x08 */
  30        u32 slad;                       /* slave address */
  31        u32 cyc;                        /* clock cycle control */
  32        u32 lctl;                       /* clock low period control */
  33        u32 ssut;                       /* restart/stop setup time control */
  34        u32 dsut;                       /* data setup time control */
  35        u32 intr;                       /* interrupt status */
  36        u32 ie;                         /* interrupt enable */
  37        u32 ic;                         /* interrupt clear */
  38#define I2C_INT_TE      (1 << 9)        /* TX FIFO empty */
  39#define I2C_INT_RB      (1 << 4)        /* received specified bytes */
  40#define I2C_INT_NA      (1 << 2)        /* no answer */
  41#define I2C_INT_AL      (1 << 1)        /* arbitration lost */
  42        u32 sr;                         /* status register */
  43#define I2C_SR_DB       (1 << 12)       /* device busy */
  44#define I2C_SR_BB       (1 << 8)        /* bus busy */
  45#define I2C_SR_RFF      (1 << 3)        /* Rx FIFO full */
  46#define I2C_SR_RNE      (1 << 2)        /* Rx FIFO not empty */
  47#define I2C_SR_TNF      (1 << 1)        /* Tx FIFO not full */
  48#define I2C_SR_TFE      (1 << 0)        /* Tx FIFO empty */
  49        u32 __reserved2;                /* no register at offset 0x30 */
  50        u32 rst;                        /* reset control */
  51#define I2C_RST_TBRST   (1 << 2)        /* clear Tx FIFO */
  52#define I2C_RST_RBRST   (1 << 1)        /* clear Rx FIFO */
  53#define I2C_RST_RST     (1 << 0)        /* forcible bus reset */
  54        u32 bm;                         /* bus monitor */
  55        u32 noise;                      /* noise filter control */
  56        u32 tbc;                        /* Tx byte count setting */
  57        u32 rbc;                        /* Rx byte count setting */
  58        u32 tbcm;                       /* Tx byte count monitor */
  59        u32 rbcm;                       /* Rx byte count monitor */
  60        u32 brst;                       /* bus reset */
  61#define I2C_BRST_FOEN   (1 << 1)        /* normal operation */
  62#define I2C_BRST_RSCLO  (1 << 0)        /* release SCL low fixing */
  63};
  64
  65#define FIOCLK  50000000
  66
  67struct uniphier_fi2c_dev {
  68        struct uniphier_fi2c_regs __iomem *regs;        /* register base */
  69        unsigned long fioclk;                   /* internal operation clock */
  70        unsigned long timeout;                  /* time out (us) */
  71};
  72
  73static int poll_status(u32 __iomem *reg, u32 flag)
  74{
  75        int wait = 1000000; /* 1 sec is long enough */
  76
  77        while (readl(reg) & flag) {
  78                if (wait-- < 0)
  79                        return -EREMOTEIO;
  80                udelay(1);
  81        }
  82
  83        return 0;
  84}
  85
  86static int reset_bus(struct uniphier_fi2c_regs __iomem *regs)
  87{
  88        int ret;
  89
  90        /* bus forcible reset */
  91        writel(I2C_RST_RST, &regs->rst);
  92        ret = poll_status(&regs->rst, I2C_RST_RST);
  93        if (ret < 0)
  94                debug("error: fail to reset I2C controller\n");
  95
  96        return ret;
  97}
  98
  99static int check_device_busy(struct uniphier_fi2c_regs __iomem *regs)
 100{
 101        int ret;
 102
 103        ret = poll_status(&regs->sr, I2C_SR_DB);
 104        if (ret < 0) {
 105                debug("error: device busy too long. reset...\n");
 106                ret = reset_bus(regs);
 107        }
 108
 109        return ret;
 110}
 111
 112static int uniphier_fi2c_probe(struct udevice *dev)
 113{
 114        fdt_addr_t addr;
 115        fdt_size_t size;
 116        struct uniphier_fi2c_dev *priv = dev_get_priv(dev);
 117        int ret;
 118
 119        addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg",
 120                                    &size);
 121
 122        priv->regs = map_sysmem(addr, size);
 123
 124        if (!priv->regs)
 125                return -ENOMEM;
 126
 127        priv->fioclk = FIOCLK;
 128
 129        /* bus forcible reset */
 130        ret = reset_bus(priv->regs);
 131        if (ret < 0)
 132                return ret;
 133
 134        writel(I2C_BRST_FOEN | I2C_BRST_RSCLO, &priv->regs->brst);
 135
 136        return 0;
 137}
 138
 139static int uniphier_fi2c_remove(struct udevice *dev)
 140{
 141        struct uniphier_fi2c_dev *priv = dev_get_priv(dev);
 142
 143        unmap_sysmem(priv->regs);
 144
 145        return 0;
 146}
 147
 148static int wait_for_irq(struct uniphier_fi2c_dev *dev, u32 flags,
 149                        bool *stop)
 150{
 151        u32 irq;
 152        unsigned long wait = dev->timeout;
 153        int ret = -EREMOTEIO;
 154
 155        do {
 156                udelay(1);
 157                irq = readl(&dev->regs->intr);
 158        } while (!(irq & flags) && wait--);
 159
 160        if (wait < 0) {
 161                debug("error: time out\n");
 162                return ret;
 163        }
 164
 165        if (irq & I2C_INT_AL) {
 166                debug("error: arbitration lost\n");
 167                *stop = false;
 168                return ret;
 169        }
 170
 171        if (irq & I2C_INT_NA) {
 172                debug("error: no answer\n");
 173                return ret;
 174        }
 175
 176        return 0;
 177}
 178
 179static int issue_stop(struct uniphier_fi2c_dev *dev, int old_ret)
 180{
 181        int ret;
 182
 183        debug("stop condition\n");
 184        writel(I2C_CR_MST | I2C_CR_STO, &dev->regs->cr);
 185
 186        ret = poll_status(&dev->regs->sr, I2C_SR_DB);
 187        if (ret < 0)
 188                debug("error: device busy after operation\n");
 189
 190        return old_ret ? old_ret : ret;
 191}
 192
 193static int uniphier_fi2c_transmit(struct uniphier_fi2c_dev *dev, uint addr,
 194                                  uint len, const u8 *buf, bool *stop)
 195{
 196        int ret;
 197        const u32 irq_flags = I2C_INT_TE | I2C_INT_NA | I2C_INT_AL;
 198        struct uniphier_fi2c_regs __iomem *regs = dev->regs;
 199
 200        debug("%s: addr = %x, len = %d\n", __func__, addr, len);
 201
 202        writel(I2C_DTTX_CMD | addr << 1, &regs->dttx);
 203
 204        writel(irq_flags, &regs->ie);
 205        writel(irq_flags, &regs->ic);
 206
 207        debug("start condition\n");
 208        writel(I2C_CR_MST | I2C_CR_STA, &regs->cr);
 209
 210        ret = wait_for_irq(dev, irq_flags, stop);
 211        if (ret < 0)
 212                goto error;
 213
 214        while (len--) {
 215                debug("sending %x\n", *buf);
 216                writel(*buf++, &regs->dttx);
 217
 218                writel(irq_flags, &regs->ic);
 219
 220                ret = wait_for_irq(dev, irq_flags, stop);
 221                if (ret < 0)
 222                        goto error;
 223        }
 224
 225error:
 226        writel(irq_flags, &regs->ic);
 227
 228        if (*stop)
 229                ret = issue_stop(dev, ret);
 230
 231        return ret;
 232}
 233
 234static int uniphier_fi2c_receive(struct uniphier_fi2c_dev *dev, uint addr,
 235                                 uint len, u8 *buf, bool *stop)
 236{
 237        int ret = 0;
 238        const u32 irq_flags = I2C_INT_RB | I2C_INT_NA | I2C_INT_AL;
 239        struct uniphier_fi2c_regs __iomem *regs = dev->regs;
 240
 241        debug("%s: addr = %x, len = %d\n", __func__, addr, len);
 242
 243        /*
 244         * In case 'len == 0', only the slave address should be sent
 245         * for probing, which is covered by the transmit function.
 246         */
 247        if (len == 0)
 248                return uniphier_fi2c_transmit(dev, addr, len, buf, stop);
 249
 250        writel(I2C_DTTX_CMD | I2C_DTTX_RD | addr << 1, &regs->dttx);
 251
 252        writel(0, &regs->rbc);
 253        writel(irq_flags, &regs->ie);
 254        writel(irq_flags, &regs->ic);
 255
 256        debug("start condition\n");
 257        writel(I2C_CR_MST | I2C_CR_STA | (len == 1 ? I2C_CR_NACK : 0),
 258               &regs->cr);
 259
 260        while (len--) {
 261                ret = wait_for_irq(dev, irq_flags, stop);
 262                if (ret < 0)
 263                        goto error;
 264
 265                *buf++ = readl(&regs->dtrx);
 266                debug("received %x\n", *(buf - 1));
 267
 268                if (len == 1)
 269                        writel(I2C_CR_MST | I2C_CR_NACK, &regs->cr);
 270
 271                writel(irq_flags, &regs->ic);
 272        }
 273
 274error:
 275        writel(irq_flags, &regs->ic);
 276
 277        if (*stop)
 278                ret = issue_stop(dev, ret);
 279
 280        return ret;
 281}
 282
 283static int uniphier_fi2c_xfer(struct udevice *bus, struct i2c_msg *msg,
 284                             int nmsgs)
 285{
 286        int ret;
 287        struct uniphier_fi2c_dev *dev = dev_get_priv(bus);
 288        bool stop;
 289
 290        ret = check_device_busy(dev->regs);
 291        if (ret < 0)
 292                return ret;
 293
 294        for (; nmsgs > 0; nmsgs--, msg++) {
 295                /* If next message is read, skip the stop condition */
 296                stop = nmsgs > 1 && msg[1].flags & I2C_M_RD ? false : true;
 297
 298                if (msg->flags & I2C_M_RD)
 299                        ret = uniphier_fi2c_receive(dev, msg->addr, msg->len,
 300                                                    msg->buf, &stop);
 301                else
 302                        ret = uniphier_fi2c_transmit(dev, msg->addr, msg->len,
 303                                                     msg->buf, &stop);
 304
 305                if (ret < 0)
 306                        break;
 307        }
 308
 309        return ret;
 310}
 311
 312static int uniphier_fi2c_set_bus_speed(struct udevice *bus, unsigned int speed)
 313{
 314        int ret;
 315        unsigned int clk_count;
 316        struct uniphier_fi2c_dev *dev = dev_get_priv(bus);
 317        struct uniphier_fi2c_regs __iomem *regs = dev->regs;
 318
 319        /* max supported frequency is 400 kHz */
 320        if (speed > 400000)
 321                return -EINVAL;
 322
 323        ret = check_device_busy(dev->regs);
 324        if (ret < 0)
 325                return ret;
 326
 327        /* make sure the bus is idle when changing the frequency */
 328        writel(I2C_BRST_RSCLO, &regs->brst);
 329
 330        clk_count = dev->fioclk / speed;
 331
 332        writel(clk_count, &regs->cyc);
 333        writel(clk_count / 2, &regs->lctl);
 334        writel(clk_count / 2, &regs->ssut);
 335        writel(clk_count / 16, &regs->dsut);
 336
 337        writel(I2C_BRST_FOEN | I2C_BRST_RSCLO, &regs->brst);
 338
 339        /*
 340         * Theoretically, each byte can be transferred in
 341         * 1000000 * 9 / speed usec.
 342         * This time out value is long enough.
 343         */
 344        dev->timeout = 100000000L / speed;
 345
 346        return 0;
 347}
 348
 349static const struct dm_i2c_ops uniphier_fi2c_ops = {
 350        .xfer = uniphier_fi2c_xfer,
 351        .set_bus_speed = uniphier_fi2c_set_bus_speed,
 352};
 353
 354static const struct udevice_id uniphier_fi2c_of_match[] = {
 355        { .compatible = "socionext,uniphier-fi2c" },
 356        { /* sentinel */ }
 357};
 358
 359U_BOOT_DRIVER(uniphier_fi2c) = {
 360        .name = "uniphier-fi2c",
 361        .id = UCLASS_I2C,
 362        .of_match = uniphier_fi2c_of_match,
 363        .probe = uniphier_fi2c_probe,
 364        .remove = uniphier_fi2c_remove,
 365        .priv_auto_alloc_size = sizeof(struct uniphier_fi2c_dev),
 366        .ops = &uniphier_fi2c_ops,
 367};
 368