uboot/drivers/i2c/i2c-cdns.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2015 Moritz Fischer <moritz.fischer@ettus.com>
   3 * IP from Cadence (ID T-CS-PE-0007-100, Version R1p10f2)
   4 *
   5 * This file is based on: drivers/i2c/zynq_i2c.c,
   6 * with added driver-model support and code cleanup.
   7 *
   8 * SPDX-License-Identifier:     GPL-2.0+
   9 */
  10
  11#include <common.h>
  12#include <dm.h>
  13#include <linux/types.h>
  14#include <linux/io.h>
  15#include <linux/errno.h>
  16#include <dm/root.h>
  17#include <i2c.h>
  18#include <fdtdec.h>
  19#include <mapmem.h>
  20#include <wait_bit.h>
  21
  22DECLARE_GLOBAL_DATA_PTR;
  23
  24/* i2c register set */
  25struct cdns_i2c_regs {
  26        u32 control;
  27        u32 status;
  28        u32 address;
  29        u32 data;
  30        u32 interrupt_status;
  31        u32 transfer_size;
  32        u32 slave_mon_pause;
  33        u32 time_out;
  34        u32 interrupt_mask;
  35        u32 interrupt_enable;
  36        u32 interrupt_disable;
  37};
  38
  39/* Control register fields */
  40#define CDNS_I2C_CONTROL_RW             0x00000001
  41#define CDNS_I2C_CONTROL_MS             0x00000002
  42#define CDNS_I2C_CONTROL_NEA            0x00000004
  43#define CDNS_I2C_CONTROL_ACKEN          0x00000008
  44#define CDNS_I2C_CONTROL_HOLD           0x00000010
  45#define CDNS_I2C_CONTROL_SLVMON         0x00000020
  46#define CDNS_I2C_CONTROL_CLR_FIFO       0x00000040
  47#define CDNS_I2C_CONTROL_DIV_B_SHIFT    8
  48#define CDNS_I2C_CONTROL_DIV_B_MASK     0x00003F00
  49#define CDNS_I2C_CONTROL_DIV_A_SHIFT    14
  50#define CDNS_I2C_CONTROL_DIV_A_MASK     0x0000C000
  51
  52/* Status register values */
  53#define CDNS_I2C_STATUS_RXDV    0x00000020
  54#define CDNS_I2C_STATUS_TXDV    0x00000040
  55#define CDNS_I2C_STATUS_RXOVF   0x00000080
  56#define CDNS_I2C_STATUS_BA      0x00000100
  57
  58/* Interrupt register fields */
  59#define CDNS_I2C_INTERRUPT_COMP         0x00000001
  60#define CDNS_I2C_INTERRUPT_DATA         0x00000002
  61#define CDNS_I2C_INTERRUPT_NACK         0x00000004
  62#define CDNS_I2C_INTERRUPT_TO           0x00000008
  63#define CDNS_I2C_INTERRUPT_SLVRDY       0x00000010
  64#define CDNS_I2C_INTERRUPT_RXOVF        0x00000020
  65#define CDNS_I2C_INTERRUPT_TXOVF        0x00000040
  66#define CDNS_I2C_INTERRUPT_RXUNF        0x00000080
  67#define CDNS_I2C_INTERRUPT_ARBLOST      0x00000200
  68
  69#define CDNS_I2C_FIFO_DEPTH             16
  70#define CDNS_I2C_TRANSFER_SIZE_MAX      255 /* Controller transfer limit */
  71#define CDNS_I2C_TRANSFER_SIZE          (CDNS_I2C_TRANSFER_SIZE_MAX - 3)
  72
  73#define CDNS_I2C_BROKEN_HOLD_BIT        BIT(0)
  74
  75#ifdef DEBUG
  76static void cdns_i2c_debug_status(struct cdns_i2c_regs *cdns_i2c)
  77{
  78        int int_status;
  79        int status;
  80        int_status = readl(&cdns_i2c->interrupt_status);
  81
  82        status = readl(&cdns_i2c->status);
  83        if (int_status || status) {
  84                debug("Status: ");
  85                if (int_status & CDNS_I2C_INTERRUPT_COMP)
  86                        debug("COMP ");
  87                if (int_status & CDNS_I2C_INTERRUPT_DATA)
  88                        debug("DATA ");
  89                if (int_status & CDNS_I2C_INTERRUPT_NACK)
  90                        debug("NACK ");
  91                if (int_status & CDNS_I2C_INTERRUPT_TO)
  92                        debug("TO ");
  93                if (int_status & CDNS_I2C_INTERRUPT_SLVRDY)
  94                        debug("SLVRDY ");
  95                if (int_status & CDNS_I2C_INTERRUPT_RXOVF)
  96                        debug("RXOVF ");
  97                if (int_status & CDNS_I2C_INTERRUPT_TXOVF)
  98                        debug("TXOVF ");
  99                if (int_status & CDNS_I2C_INTERRUPT_RXUNF)
 100                        debug("RXUNF ");
 101                if (int_status & CDNS_I2C_INTERRUPT_ARBLOST)
 102                        debug("ARBLOST ");
 103                if (status & CDNS_I2C_STATUS_RXDV)
 104                        debug("RXDV ");
 105                if (status & CDNS_I2C_STATUS_TXDV)
 106                        debug("TXDV ");
 107                if (status & CDNS_I2C_STATUS_RXOVF)
 108                        debug("RXOVF ");
 109                if (status & CDNS_I2C_STATUS_BA)
 110                        debug("BA ");
 111                debug("TS%d ", readl(&cdns_i2c->transfer_size));
 112                debug("\n");
 113        }
 114}
 115#endif
 116
 117struct i2c_cdns_bus {
 118        int id;
 119        unsigned int input_freq;
 120        struct cdns_i2c_regs __iomem *regs;     /* register base */
 121
 122        int hold_flag;
 123        u32 quirks;
 124};
 125
 126struct cdns_i2c_platform_data {
 127        u32 quirks;
 128};
 129
 130/* Wait for an interrupt */
 131static u32 cdns_i2c_wait(struct cdns_i2c_regs *cdns_i2c, u32 mask)
 132{
 133        int timeout, int_status;
 134
 135        for (timeout = 0; timeout < 100; timeout++) {
 136                int_status = readl(&cdns_i2c->interrupt_status);
 137                if (int_status & mask)
 138                        break;
 139                udelay(100);
 140        }
 141
 142        /* Clear interrupt status flags */
 143        writel(int_status & mask, &cdns_i2c->interrupt_status);
 144
 145        return int_status & mask;
 146}
 147
 148#define CDNS_I2C_DIVA_MAX       4
 149#define CDNS_I2C_DIVB_MAX       64
 150
 151static int cdns_i2c_calc_divs(unsigned long *f, unsigned long input_clk,
 152                unsigned int *a, unsigned int *b)
 153{
 154        unsigned long fscl = *f, best_fscl = *f, actual_fscl, temp;
 155        unsigned int div_a, div_b, calc_div_a = 0, calc_div_b = 0;
 156        unsigned int last_error, current_error;
 157
 158        /* calculate (divisor_a+1) x (divisor_b+1) */
 159        temp = input_clk / (22 * fscl);
 160
 161        /*
 162         * If the calculated value is negative or 0CDNS_I2C_DIVA_MAX,
 163         * the fscl input is out of range. Return error.
 164         */
 165        if (!temp || (temp > (CDNS_I2C_DIVA_MAX * CDNS_I2C_DIVB_MAX)))
 166                return -EINVAL;
 167
 168        last_error = -1;
 169        for (div_a = 0; div_a < CDNS_I2C_DIVA_MAX; div_a++) {
 170                div_b = DIV_ROUND_UP(input_clk, 22 * fscl * (div_a + 1));
 171
 172                if ((div_b < 1) || (div_b > CDNS_I2C_DIVB_MAX))
 173                        continue;
 174                div_b--;
 175
 176                actual_fscl = input_clk / (22 * (div_a + 1) * (div_b + 1));
 177
 178                if (actual_fscl > fscl)
 179                        continue;
 180
 181                current_error = ((actual_fscl > fscl) ? (actual_fscl - fscl) :
 182                                                        (fscl - actual_fscl));
 183
 184                if (last_error > current_error) {
 185                        calc_div_a = div_a;
 186                        calc_div_b = div_b;
 187                        best_fscl = actual_fscl;
 188                        last_error = current_error;
 189                }
 190        }
 191
 192        *a = calc_div_a;
 193        *b = calc_div_b;
 194        *f = best_fscl;
 195
 196        return 0;
 197}
 198
 199static int cdns_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
 200{
 201        struct i2c_cdns_bus *bus = dev_get_priv(dev);
 202        u32 div_a = 0, div_b = 0;
 203        unsigned long speed_p = speed;
 204        int ret = 0;
 205
 206        if (speed > 400000) {
 207                debug("%s, failed to set clock speed to %u\n", __func__,
 208                      speed);
 209                return -EINVAL;
 210        }
 211
 212        ret = cdns_i2c_calc_divs(&speed_p, bus->input_freq, &div_a, &div_b);
 213        if (ret)
 214                return ret;
 215
 216        debug("%s: div_a: %d, div_b: %d, input freq: %d, speed: %d/%ld\n",
 217              __func__, div_a, div_b, bus->input_freq, speed, speed_p);
 218
 219        writel((div_b << CDNS_I2C_CONTROL_DIV_B_SHIFT) |
 220               (div_a << CDNS_I2C_CONTROL_DIV_A_SHIFT), &bus->regs->control);
 221
 222        /* Enable master mode, ack, and 7-bit addressing */
 223        setbits_le32(&bus->regs->control, CDNS_I2C_CONTROL_MS |
 224                CDNS_I2C_CONTROL_ACKEN | CDNS_I2C_CONTROL_NEA);
 225
 226        return 0;
 227}
 228
 229static int cdns_i2c_write_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data,
 230                               u32 len)
 231{
 232        u8 *cur_data = data;
 233        struct cdns_i2c_regs *regs = i2c_bus->regs;
 234
 235        /* Set the controller in Master transmit mode and clear FIFO */
 236        setbits_le32(&regs->control, CDNS_I2C_CONTROL_CLR_FIFO);
 237        clrbits_le32(&regs->control, CDNS_I2C_CONTROL_RW);
 238
 239        /* Check message size against FIFO depth, and set hold bus bit
 240         * if it is greater than FIFO depth
 241         */
 242        if (len > CDNS_I2C_FIFO_DEPTH)
 243                setbits_le32(&regs->control, CDNS_I2C_CONTROL_HOLD);
 244
 245        /* Clear the interrupts in status register */
 246        writel(0xFF, &regs->interrupt_status);
 247
 248        writel(addr, &regs->address);
 249
 250        while (len--) {
 251                writel(*(cur_data++), &regs->data);
 252                if (readl(&regs->transfer_size) == CDNS_I2C_FIFO_DEPTH) {
 253                        if (!cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP)) {
 254                                /* Release the bus */
 255                                clrbits_le32(&regs->control,
 256                                             CDNS_I2C_CONTROL_HOLD);
 257                                return -ETIMEDOUT;
 258                        }
 259                }
 260        }
 261
 262        /* All done... release the bus */
 263        if (!i2c_bus->hold_flag)
 264                clrbits_le32(&regs->control, CDNS_I2C_CONTROL_HOLD);
 265
 266        /* Wait for the address and data to be sent */
 267        if (!cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP))
 268                return -ETIMEDOUT;
 269        return 0;
 270}
 271
 272static inline bool cdns_is_hold_quirk(int hold_quirk, int curr_recv_count)
 273{
 274        return hold_quirk && (curr_recv_count == CDNS_I2C_FIFO_DEPTH + 1);
 275}
 276
 277static int cdns_i2c_read_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data,
 278                              u32 recv_count)
 279{
 280        u8 *cur_data = data;
 281        struct cdns_i2c_regs *regs = i2c_bus->regs;
 282        int curr_recv_count;
 283        int updatetx, hold_quirk;
 284
 285        /* Check the hardware can handle the requested bytes */
 286        if ((recv_count < 0))
 287                return -EINVAL;
 288
 289        curr_recv_count = recv_count;
 290
 291        /* Check for the message size against the FIFO depth */
 292        if (recv_count > CDNS_I2C_FIFO_DEPTH)
 293                setbits_le32(&regs->control, CDNS_I2C_CONTROL_HOLD);
 294
 295        setbits_le32(&regs->control, CDNS_I2C_CONTROL_CLR_FIFO |
 296                CDNS_I2C_CONTROL_RW);
 297
 298        if (recv_count > CDNS_I2C_TRANSFER_SIZE) {
 299                curr_recv_count = CDNS_I2C_TRANSFER_SIZE;
 300                writel(curr_recv_count, &regs->transfer_size);
 301        } else {
 302                writel(recv_count, &regs->transfer_size);
 303        }
 304
 305        /* Start reading data */
 306        writel(addr, &regs->address);
 307
 308        updatetx = recv_count > curr_recv_count;
 309
 310        hold_quirk = (i2c_bus->quirks & CDNS_I2C_BROKEN_HOLD_BIT) && updatetx;
 311
 312        while (recv_count) {
 313                while (readl(&regs->status) & CDNS_I2C_STATUS_RXDV) {
 314                        if (recv_count < CDNS_I2C_FIFO_DEPTH &&
 315                            !i2c_bus->hold_flag) {
 316                                clrbits_le32(&regs->control,
 317                                             CDNS_I2C_CONTROL_HOLD);
 318                        }
 319                        *(cur_data)++ = readl(&regs->data);
 320                        recv_count--;
 321                        curr_recv_count--;
 322
 323                        if (cdns_is_hold_quirk(hold_quirk, curr_recv_count))
 324                                break;
 325                }
 326
 327                if (cdns_is_hold_quirk(hold_quirk, curr_recv_count)) {
 328                        /* wait while fifo is full */
 329                        while (readl(&regs->transfer_size) !=
 330                                     (curr_recv_count - CDNS_I2C_FIFO_DEPTH))
 331                                ;
 332                        /*
 333                         * Check number of bytes to be received against maximum
 334                         * transfer size and update register accordingly.
 335                         */
 336                        if ((recv_count - CDNS_I2C_FIFO_DEPTH) >
 337                            CDNS_I2C_TRANSFER_SIZE) {
 338                                writel(CDNS_I2C_TRANSFER_SIZE,
 339                                       &regs->transfer_size);
 340                                curr_recv_count = CDNS_I2C_TRANSFER_SIZE +
 341                                        CDNS_I2C_FIFO_DEPTH;
 342                        } else {
 343                                writel(recv_count - CDNS_I2C_FIFO_DEPTH,
 344                                       &regs->transfer_size);
 345                                curr_recv_count = recv_count;
 346                        }
 347                } else if (recv_count && !hold_quirk && !curr_recv_count) {
 348                        writel(addr, &regs->address);
 349                        if (recv_count > CDNS_I2C_TRANSFER_SIZE) {
 350                                writel(CDNS_I2C_TRANSFER_SIZE,
 351                                       &regs->transfer_size);
 352                                curr_recv_count = CDNS_I2C_TRANSFER_SIZE;
 353                        } else {
 354                                writel(recv_count, &regs->transfer_size);
 355                                curr_recv_count = recv_count;
 356                        }
 357                }
 358        }
 359
 360        /* Wait for the address and data to be sent */
 361        if (!cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP))
 362                return -ETIMEDOUT;
 363
 364        return 0;
 365}
 366
 367static int cdns_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
 368                         int nmsgs)
 369{
 370        struct i2c_cdns_bus *i2c_bus = dev_get_priv(dev);
 371        int ret, count;
 372        bool hold_quirk;
 373
 374        hold_quirk = !!(i2c_bus->quirks & CDNS_I2C_BROKEN_HOLD_BIT);
 375
 376        if (nmsgs > 1) {
 377                /*
 378                 * This controller does not give completion interrupt after a
 379                 * master receive message if HOLD bit is set (repeated start),
 380                 * resulting in SW timeout. Hence, if a receive message is
 381                 * followed by any other message, an error is returned
 382                 * indicating that this sequence is not supported.
 383                 */
 384                for (count = 0; (count < nmsgs - 1) && hold_quirk; count++) {
 385                        if (msg[count].flags & I2C_M_RD) {
 386                                printf("Can't do repeated start after a receive message\n");
 387                                return -EOPNOTSUPP;
 388                        }
 389                }
 390
 391                i2c_bus->hold_flag = 1;
 392                setbits_le32(&i2c_bus->regs->control, CDNS_I2C_CONTROL_HOLD);
 393        } else {
 394                i2c_bus->hold_flag = 0;
 395        }
 396
 397        debug("i2c_xfer: %d messages\n", nmsgs);
 398        for (; nmsgs > 0; nmsgs--, msg++) {
 399                debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
 400                if (msg->flags & I2C_M_RD) {
 401                        ret = cdns_i2c_read_data(i2c_bus, msg->addr, msg->buf,
 402                                                 msg->len);
 403                } else {
 404                        ret = cdns_i2c_write_data(i2c_bus, msg->addr, msg->buf,
 405                                                  msg->len);
 406                }
 407                if (ret) {
 408                        debug("i2c_write: error sending\n");
 409                        return -EREMOTEIO;
 410                }
 411        }
 412
 413        return 0;
 414}
 415
 416static int cdns_i2c_ofdata_to_platdata(struct udevice *dev)
 417{
 418        struct i2c_cdns_bus *i2c_bus = dev_get_priv(dev);
 419        struct cdns_i2c_platform_data *pdata =
 420                (struct cdns_i2c_platform_data *)dev_get_driver_data(dev);
 421
 422        i2c_bus->regs = (struct cdns_i2c_regs *)devfdt_get_addr(dev);
 423        if (!i2c_bus->regs)
 424                return -ENOMEM;
 425
 426        if (pdata)
 427                i2c_bus->quirks = pdata->quirks;
 428
 429        i2c_bus->input_freq = 100000000; /* TODO hardcode input freq for now */
 430
 431        return 0;
 432}
 433
 434static const struct dm_i2c_ops cdns_i2c_ops = {
 435        .xfer = cdns_i2c_xfer,
 436        .set_bus_speed = cdns_i2c_set_bus_speed,
 437};
 438
 439static const struct cdns_i2c_platform_data r1p10_i2c_def = {
 440        .quirks = CDNS_I2C_BROKEN_HOLD_BIT,
 441};
 442
 443static const struct udevice_id cdns_i2c_of_match[] = {
 444        { .compatible = "cdns,i2c-r1p10", .data = (ulong)&r1p10_i2c_def },
 445        { .compatible = "cdns,i2c-r1p14" },
 446        { /* end of table */ }
 447};
 448
 449U_BOOT_DRIVER(cdns_i2c) = {
 450        .name = "i2c-cdns",
 451        .id = UCLASS_I2C,
 452        .of_match = cdns_i2c_of_match,
 453        .ofdata_to_platdata = cdns_i2c_ofdata_to_platdata,
 454        .priv_auto_alloc_size = sizeof(struct i2c_cdns_bus),
 455        .ops = &cdns_i2c_ops,
 456};
 457