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