uboot/drivers/i2c/ast_i2c.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2012-2020  ASPEED Technology Inc.
   4 * Copyright 2016 IBM Corporation
   5 * Copyright 2017 Google, Inc.
   6 */
   7
   8#include <common.h>
   9#include <clk.h>
  10#include <dm.h>
  11#include <errno.h>
  12#include <fdtdec.h>
  13#include <i2c.h>
  14#include <log.h>
  15#include <asm/io.h>
  16#include <asm/arch/scu_ast2500.h>
  17#include <linux/delay.h>
  18#include <linux/err.h>
  19#include <reset.h>
  20
  21#include "ast_i2c.h"
  22
  23#define I2C_TIMEOUT_US 100000
  24#define I2C_SLEEP_STEP_US 20
  25
  26#define HIGHSPEED_TTIMEOUT              3
  27
  28/*
  29 * Device private data
  30 */
  31struct ast_i2c_priv {
  32        /* This device's clock */
  33        struct clk clk;
  34        /* Device registers */
  35        struct ast_i2c_regs *regs;
  36        /* I2C speed in Hz */
  37        int speed;
  38};
  39
  40/*
  41 * Given desired divider ratio, return the value that needs to be set
  42 * in Clock and AC Timing Control register
  43 */
  44static u32 get_clk_reg_val(ulong divider_ratio)
  45{
  46        ulong inc = 0, div;
  47        ulong scl_low, scl_high, data;
  48
  49        for (div = 0; divider_ratio >= 16; div++) {
  50                inc |= (divider_ratio & 1);
  51                divider_ratio >>= 1;
  52        }
  53        divider_ratio += inc;
  54        scl_low = (divider_ratio >> 1) - 1;
  55        scl_high = divider_ratio - scl_low - 2;
  56        data = I2CD_CACTC_BASE
  57                        | (scl_high << I2CD_TCKHIGH_SHIFT)
  58                        | (scl_low << I2CD_TCKLOW_SHIFT)
  59                        | (div << I2CD_BASE_DIV_SHIFT);
  60
  61        return data;
  62}
  63
  64static void ast_i2c_clear_interrupts(struct udevice *dev)
  65{
  66        struct ast_i2c_priv *priv = dev_get_priv(dev);
  67
  68        writel(~0, &priv->regs->isr);
  69}
  70
  71static void ast_i2c_init_bus(struct udevice *dev)
  72{
  73        struct ast_i2c_priv *priv = dev_get_priv(dev);
  74
  75        /* Reset device */
  76        writel(0, &priv->regs->fcr);
  77        /* Enable Master Mode. Assuming single-master */
  78        writel(I2CD_MASTER_EN
  79               | I2CD_M_SDA_LOCK_EN
  80               | I2CD_MULTI_MASTER_DIS,
  81               &priv->regs->fcr);
  82        /* Enable Interrupts */
  83        writel(I2CD_INTR_TX_ACK
  84               | I2CD_INTR_TX_NAK
  85               | I2CD_INTR_RX_DONE
  86               | I2CD_INTR_BUS_RECOVER_DONE
  87               | I2CD_INTR_NORMAL_STOP
  88               | I2CD_INTR_ABNORMAL, &priv->regs->icr);
  89}
  90
  91static int ast_i2c_of_to_plat(struct udevice *dev)
  92{
  93        struct ast_i2c_priv *priv = dev_get_priv(dev);
  94        int ret;
  95
  96        priv->regs = dev_read_addr_ptr(dev);
  97        if (!priv->regs)
  98                return -EINVAL;
  99
 100        ret = clk_get_by_index(dev, 0, &priv->clk);
 101        if (ret < 0) {
 102                debug("%s: Can't get clock for %s: %d\n", __func__, dev->name,
 103                      ret);
 104                return ret;
 105        }
 106
 107        return 0;
 108}
 109
 110static int ast_i2c_probe(struct udevice *dev)
 111{
 112        struct reset_ctl reset_ctl;
 113        int rc;
 114
 115        debug("Enabling I2C%u\n", dev_seq(dev));
 116
 117        /*
 118         * Get all I2C devices out of Reset.
 119         *
 120         * Only needs to be done once so test before performing reset.
 121         */
 122        rc = reset_get_by_index(dev, 0, &reset_ctl);
 123        if (rc) {
 124                printf("%s: Failed to get reset signal\n", __func__);
 125                return rc;
 126        }
 127
 128        if (reset_status(&reset_ctl) > 0) {
 129                reset_assert(&reset_ctl);
 130                reset_deassert(&reset_ctl);
 131        }
 132
 133        ast_i2c_init_bus(dev);
 134
 135        return 0;
 136}
 137
 138static int ast_i2c_wait_isr(struct udevice *dev, u32 flag)
 139{
 140        struct ast_i2c_priv *priv = dev_get_priv(dev);
 141        int timeout = I2C_TIMEOUT_US;
 142
 143        while (!(readl(&priv->regs->isr) & flag) && timeout > 0) {
 144                udelay(I2C_SLEEP_STEP_US);
 145                timeout -= I2C_SLEEP_STEP_US;
 146        }
 147
 148        ast_i2c_clear_interrupts(dev);
 149        if (timeout <= 0)
 150                return -ETIMEDOUT;
 151
 152        return 0;
 153}
 154
 155static int ast_i2c_send_stop(struct udevice *dev)
 156{
 157        struct ast_i2c_priv *priv = dev_get_priv(dev);
 158
 159        writel(I2CD_M_STOP_CMD, &priv->regs->csr);
 160
 161        return ast_i2c_wait_isr(dev, I2CD_INTR_NORMAL_STOP);
 162}
 163
 164static int ast_i2c_wait_tx(struct udevice *dev)
 165{
 166        struct ast_i2c_priv *priv = dev_get_priv(dev);
 167        int timeout = I2C_TIMEOUT_US;
 168        u32 flag = I2CD_INTR_TX_ACK | I2CD_INTR_TX_NAK;
 169        u32 status = readl(&priv->regs->isr) & flag;
 170        int ret = 0;
 171
 172        while (!status && timeout > 0) {
 173                status = readl(&priv->regs->isr) & flag;
 174                udelay(I2C_SLEEP_STEP_US);
 175                timeout -= I2C_SLEEP_STEP_US;
 176        }
 177
 178        if (status == I2CD_INTR_TX_NAK)
 179                ret = -EREMOTEIO;
 180
 181        if (timeout <= 0)
 182                ret = -ETIMEDOUT;
 183
 184        ast_i2c_clear_interrupts(dev);
 185
 186        return ret;
 187}
 188
 189static int ast_i2c_start_txn(struct udevice *dev, uint devaddr)
 190{
 191        struct ast_i2c_priv *priv = dev_get_priv(dev);
 192
 193        /* Start and Send Device Address */
 194        writel(devaddr, &priv->regs->trbbr);
 195        writel(I2CD_M_START_CMD | I2CD_M_TX_CMD, &priv->regs->csr);
 196
 197        return ast_i2c_wait_tx(dev);
 198}
 199
 200static int ast_i2c_read_data(struct udevice *dev, u8 chip_addr, u8 *buffer,
 201                             size_t len, bool send_stop)
 202{
 203        struct ast_i2c_priv *priv = dev_get_priv(dev);
 204        u32 i2c_cmd = I2CD_M_RX_CMD;
 205        int ret;
 206
 207        ret = ast_i2c_start_txn(dev, (chip_addr << 1) | I2C_M_RD);
 208        if (ret < 0)
 209                return ret;
 210
 211        for (; len > 0; len--, buffer++) {
 212                if (len == 1)
 213                        i2c_cmd |= I2CD_M_S_RX_CMD_LAST;
 214                writel(i2c_cmd, &priv->regs->csr);
 215                ret = ast_i2c_wait_isr(dev, I2CD_INTR_RX_DONE);
 216                if (ret < 0)
 217                        return ret;
 218                *buffer = (readl(&priv->regs->trbbr) & I2CD_RX_DATA_MASK)
 219                                >> I2CD_RX_DATA_SHIFT;
 220        }
 221        ast_i2c_clear_interrupts(dev);
 222
 223        if (send_stop)
 224                return ast_i2c_send_stop(dev);
 225
 226        return 0;
 227}
 228
 229static int ast_i2c_write_data(struct udevice *dev, u8 chip_addr, u8
 230                              *buffer, size_t len, bool send_stop)
 231{
 232        struct ast_i2c_priv *priv = dev_get_priv(dev);
 233        int ret;
 234
 235        ret = ast_i2c_start_txn(dev, (chip_addr << 1));
 236        if (ret < 0)
 237                return ret;
 238
 239        for (; len > 0; len--, buffer++) {
 240                writel(*buffer, &priv->regs->trbbr);
 241                writel(I2CD_M_TX_CMD, &priv->regs->csr);
 242                ret = ast_i2c_wait_tx(dev);
 243                if (ret < 0)
 244                        return ret;
 245        }
 246
 247        if (send_stop)
 248                return ast_i2c_send_stop(dev);
 249
 250        return 0;
 251}
 252
 253static int ast_i2c_deblock(struct udevice *dev)
 254{
 255        struct ast_i2c_priv *priv = dev_get_priv(dev);
 256        struct ast_i2c_regs *regs = priv->regs;
 257        u32 csr = readl(&regs->csr);
 258        bool sda_high = csr & I2CD_SDA_LINE_STS;
 259        bool scl_high = csr & I2CD_SCL_LINE_STS;
 260        int ret = 0;
 261
 262        if (sda_high && scl_high) {
 263                /* Bus is idle, no deblocking needed. */
 264                return 0;
 265        } else if (sda_high) {
 266                /* Send stop command */
 267                debug("Unterminated TXN in (%x), sending stop\n", csr);
 268                ret = ast_i2c_send_stop(dev);
 269        } else if (scl_high) {
 270                /* Possibly stuck slave */
 271                debug("Bus stuck (%x), attempting recovery\n", csr);
 272                writel(I2CD_BUS_RECOVER_CMD, &regs->csr);
 273                ret = ast_i2c_wait_isr(dev, I2CD_INTR_BUS_RECOVER_DONE);
 274        } else {
 275                /* Just try to reinit the device. */
 276                ast_i2c_init_bus(dev);
 277        }
 278
 279        return ret;
 280}
 281
 282static int ast_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
 283{
 284        int ret;
 285
 286        ret = ast_i2c_deblock(dev);
 287        if (ret < 0)
 288                return ret;
 289
 290        debug("i2c_xfer: %d messages\n", nmsgs);
 291        for (; nmsgs > 0; nmsgs--, msg++) {
 292                if (msg->flags & I2C_M_RD) {
 293                        debug("i2c_read: chip=0x%x, len=0x%x, flags=0x%x\n",
 294                              msg->addr, msg->len, msg->flags);
 295                        ret = ast_i2c_read_data(dev, msg->addr, msg->buf,
 296                                                msg->len, (nmsgs == 1));
 297                } else {
 298                        debug("i2c_write: chip=0x%x, len=0x%x, flags=0x%x\n",
 299                              msg->addr, msg->len, msg->flags);
 300                        ret = ast_i2c_write_data(dev, msg->addr, msg->buf,
 301                                                 msg->len, (nmsgs == 1));
 302                }
 303                if (ret) {
 304                        debug("%s: error (%d)\n", __func__, ret);
 305                        return -EREMOTEIO;
 306                }
 307        }
 308
 309        return 0;
 310}
 311
 312static int ast_i2c_set_speed(struct udevice *dev, unsigned int speed)
 313{
 314        struct ast_i2c_priv *priv = dev_get_priv(dev);
 315        struct ast_i2c_regs *regs = priv->regs;
 316        ulong i2c_rate, divider;
 317
 318        debug("Setting speed for I2C%d to <%u>\n", dev_seq(dev), speed);
 319        if (!speed) {
 320                debug("No valid speed specified\n");
 321                return -EINVAL;
 322        }
 323
 324        i2c_rate = clk_get_rate(&priv->clk);
 325        divider = i2c_rate / speed;
 326
 327        priv->speed = speed;
 328        if (speed > I2C_SPEED_FAST_RATE) {
 329                debug("Enable High Speed\n");
 330                setbits_le32(&regs->fcr, I2CD_M_HIGH_SPEED_EN
 331                             | I2CD_M_SDA_DRIVE_1T_EN
 332                             | I2CD_SDA_DRIVE_1T_EN);
 333                writel(HIGHSPEED_TTIMEOUT, &regs->cactcr2);
 334        } else {
 335                debug("Enabling Normal Speed\n");
 336                writel(I2CD_NO_TIMEOUT_CTRL, &regs->cactcr2);
 337        }
 338
 339        writel(get_clk_reg_val(divider), &regs->cactcr1);
 340        ast_i2c_clear_interrupts(dev);
 341
 342        return 0;
 343}
 344
 345static const struct dm_i2c_ops ast_i2c_ops = {
 346        .xfer = ast_i2c_xfer,
 347        .set_bus_speed = ast_i2c_set_speed,
 348        .deblock = ast_i2c_deblock,
 349};
 350
 351static const struct udevice_id ast_i2c_ids[] = {
 352        { .compatible = "aspeed,ast2400-i2c-bus" },
 353        { .compatible = "aspeed,ast2500-i2c-bus" },
 354        { .compatible = "aspeed,ast2600-i2c-bus" },
 355        { },
 356};
 357
 358U_BOOT_DRIVER(ast_i2c) = {
 359        .name = "ast_i2c",
 360        .id = UCLASS_I2C,
 361        .of_match = ast_i2c_ids,
 362        .probe = ast_i2c_probe,
 363        .of_to_plat = ast_i2c_of_to_plat,
 364        .priv_auto      = sizeof(struct ast_i2c_priv),
 365        .ops = &ast_i2c_ops,
 366};
 367