uboot/drivers/i2c/i2c-microchip.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Microchip I2C controller driver
   4 *
   5 * Copyright (C) 2021-2022 Microchip Technology Inc.
   6 * Padmarao Begari <padmarao.begari@microchip.com>
   7 * Conor Dooley <conor.dooley@microchip.com>
   8 */
   9#include <common.h>
  10#include <clk.h>
  11#include <dm.h>
  12#include <i2c.h>
  13#include <asm/io.h>
  14#include <dm/device_compat.h>
  15#include <linux/bitops.h>
  16#include <linux/delay.h>
  17#include <linux/err.h>
  18
  19#define MICROCHIP_I2C_TIMEOUT   (1000 * 60)
  20
  21#define MPFS_I2C_CTRL   (0x00)
  22#define CTRL_CR0                (0x00)
  23#define CTRL_CR1                (0x01)
  24#define CTRL_AA                 BIT(2)
  25#define CTRL_SI                 BIT(3)
  26#define CTRL_STO                BIT(4)
  27#define CTRL_STA                BIT(5)
  28#define CTRL_ENS1               BIT(6)
  29#define CTRL_CR2                (0x07)
  30#define MPFS_I2C_STATUS                                                 (0x04)
  31#define STATUS_BUS_ERROR                                                (0x00)
  32#define STATUS_M_START_SENT                                             (0x08)
  33#define STATUS_M_REPEATED_START_SENT                    (0x10)
  34#define STATUS_M_SLAW_ACK                                               (0x18)
  35#define STATUS_M_SLAW_NACK                                              (0x20)
  36#define STATUS_M_TX_DATA_ACK                                    (0x28)
  37#define STATUS_M_TX_DATA_NACK                                   (0x30)
  38#define STATUS_M_ARB_LOST                                               (0x38)
  39#define STATUS_M_SLAR_ACK                                               (0x40)
  40#define STATUS_M_SLAR_NACK                                              (0x48)
  41#define STATUS_M_RX_DATA_ACKED                                  (0x50)
  42#define STATUS_M_RX_DATA_NACKED                                 (0x58)
  43#define STATUS_S_SLAW_ACKED                                             (0x60)
  44#define STATUS_S_ARB_LOST_SLAW_ACKED                    (0x68)
  45#define STATUS_S_GENERAL_CALL_ACKED                             (0x70)
  46#define STATUS_S_ARB_LOST_GENERAL_CALL_ACKED    (0x78)
  47#define STATUS_S_RX_DATA_ACKED                                  (0x80)
  48#define STATUS_S_RX_DATA_NACKED                                 (0x88)
  49#define STATUS_S_GENERAL_CALL_RX_DATA_ACKED             (0x90)
  50#define STATUS_S_GENERAL_CALL_RX_DATA_NACKED    (0x98)
  51#define STATUS_S_RX_STOP                                                (0xA0)
  52#define STATUS_S_SLAR_ACKED                                             (0xA8)
  53#define STATUS_S_ARB_LOST_SLAR_ACKED                    (0xB0)
  54#define STATUS_S_TX_DATA_ACK                                    (0xb8)
  55#define STATUS_S_TX_DATA_NACK                                   (0xC0)
  56#define STATUS_LAST_DATA_ACK                                    (0xC8)
  57#define STATUS_M_SMB_MASTER_RESET                               (0xD0)
  58#define STATUS_S_SCL_LOW_TIMEOUT                                (0xD8)
  59#define STATUS_NO_STATE_INFO                                    (0xF8)
  60#define MPFS_I2C_DATA                   (0x08)
  61#define MPFS_I2C_SLAVE0_ADDR    (0x0c)
  62#define MPFS_I2C_SMBUS                  (0x10)
  63#define MPFS_I2C_FREQ                   (0x14)
  64#define MPFS_I2C_GLITCHREG              (0x18)
  65#define MPFS_I2C_SLAVE1_ADDR    (0x1c)
  66
  67#define PCLK_DIV_256    ((0 << CTRL_CR0) | (0 << CTRL_CR1) | (0 << CTRL_CR2))
  68#define PCLK_DIV_224    ((1 << CTRL_CR0) | (0 << CTRL_CR1) | (0 << CTRL_CR2))
  69#define PCLK_DIV_192    ((0 << CTRL_CR0) | (1 << CTRL_CR1) | (0 << CTRL_CR2))
  70#define PCLK_DIV_160    ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (0 << CTRL_CR2))
  71#define PCLK_DIV_960    ((0 << CTRL_CR0) | (0 << CTRL_CR1) | (1 << CTRL_CR2))
  72#define PCLK_DIV_120    ((1 << CTRL_CR0) | (0 << CTRL_CR1) | (1 << CTRL_CR2))
  73#define PCLK_DIV_60             ((0 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
  74#define BCLK_DIV_8              ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
  75#define CLK_MASK                ((1 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2))
  76
  77/*
  78 * mpfs_i2c_bus - I2C bus context
  79 * @base: pointer to register struct
  80 * @msg_len: number of bytes transferred in msg
  81 * @msg_err: error code for completed message
  82 * @i2c_clk: clock reference for i2c input clock
  83 * @clk_rate: current i2c bus clock rate
  84 * @buf: ptr to msg buffer for easier use.
  85 * @addr: i2c address.
  86 * @isr_status: cached copy of local ISR status.
  87 */
  88struct mpfs_i2c_bus {
  89        void __iomem *base;
  90        size_t msg_len;
  91        int msg_err;
  92        struct clk i2c_clk;
  93        u32 clk_rate;
  94        u8 *buf;
  95        u8 addr;
  96        u32 isr_status;
  97};
  98
  99static inline u8 i2c_8bit_addr_from_msg(const struct i2c_msg *msg)
 100{
 101        return (msg->addr << 1) | (msg->flags & I2C_M_RD ? 1 : 0);
 102}
 103
 104static void mpfs_i2c_int_clear(struct mpfs_i2c_bus *bus)
 105{
 106        u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
 107
 108        ctrl &= ~CTRL_SI;
 109        writel(ctrl, bus->base + MPFS_I2C_CTRL);
 110}
 111
 112static void mpfs_i2c_core_disable(struct mpfs_i2c_bus *bus)
 113{
 114        u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
 115
 116        ctrl &= ~CTRL_ENS1;
 117        writel(ctrl, bus->base + MPFS_I2C_CTRL);
 118}
 119
 120static void mpfs_i2c_core_enable(struct mpfs_i2c_bus *bus)
 121{
 122        u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
 123
 124        ctrl |= CTRL_ENS1;
 125        writel(ctrl, bus->base + MPFS_I2C_CTRL);
 126}
 127
 128static void mpfs_i2c_reset(struct mpfs_i2c_bus *bus)
 129{
 130        mpfs_i2c_core_disable(bus);
 131        mpfs_i2c_core_enable(bus);
 132}
 133
 134static inline void mpfs_i2c_stop(struct mpfs_i2c_bus *bus)
 135{
 136        u8 ctrl = readl(bus->base + MPFS_I2C_CTRL);
 137
 138        ctrl |= CTRL_STO;
 139        writel(ctrl, bus->base + MPFS_I2C_CTRL);
 140}
 141
 142static inline int mpfs_generate_divisor(u32 rate, u8 *code)
 143{
 144        int ret = 0;
 145
 146        if (rate >= 960)
 147                *code = PCLK_DIV_960;
 148        else if (rate >= 256)
 149                *code = PCLK_DIV_256;
 150        else if (rate >= 224)
 151                *code = PCLK_DIV_224;
 152        else if (rate >= 192)
 153                *code = PCLK_DIV_192;
 154        else if (rate >= 160)
 155                *code = PCLK_DIV_160;
 156        else if (rate >= 120)
 157                *code = PCLK_DIV_120;
 158        else if (rate >= 60)
 159                *code = PCLK_DIV_60;
 160        else if (rate >= 8)
 161                *code = BCLK_DIV_8;
 162        else
 163                ret = -EINVAL;
 164
 165        return ret;
 166}
 167
 168static int mpfs_i2c_init(struct mpfs_i2c_bus *bus, struct udevice *dev)
 169{
 170        u32 clk_rate, divisor;
 171        u8 clkval, ctrl;
 172        int ret;
 173
 174        ret = clk_get_by_index(dev, 0, &bus->i2c_clk);
 175        if (ret)
 176                return -EINVAL;
 177
 178        ret = clk_enable(&bus->i2c_clk);
 179        if (ret)
 180                return ret;
 181
 182        clk_rate = clk_get_rate(&bus->i2c_clk);
 183        if (!clk_rate)
 184                return -EINVAL;
 185
 186        clk_free(&bus->i2c_clk);
 187
 188        divisor = clk_rate / bus->clk_rate;
 189
 190        ctrl = readl(bus->base + MPFS_I2C_CTRL);
 191
 192        ctrl &= ~CLK_MASK;
 193
 194        ret = mpfs_generate_divisor(divisor, &clkval);
 195        if (ret)
 196                return -EINVAL;
 197
 198        ctrl |= clkval;
 199
 200        writel(ctrl, bus->base + MPFS_I2C_CTRL);
 201
 202        ctrl = readl(bus->base + MPFS_I2C_CTRL);
 203
 204        /* Reset I2C core */
 205        mpfs_i2c_reset(bus);
 206
 207        return 0;
 208}
 209
 210static void mpfs_i2c_transfer(struct mpfs_i2c_bus *bus, u32 data)
 211{
 212        if (bus->msg_len > 0)
 213                writel(data, bus->base + MPFS_I2C_DATA);
 214}
 215
 216static void mpfs_i2c_empty_rx(struct mpfs_i2c_bus *bus)
 217{
 218        u8 ctrl;
 219        u8 data_read;
 220
 221        if (bus->msg_len > 0) {
 222                data_read = readl(bus->base + MPFS_I2C_DATA);
 223                *bus->buf++ = data_read;
 224                bus->msg_len--;
 225        }
 226
 227        if (bus->msg_len <= 1) {
 228                ctrl = readl(bus->base + MPFS_I2C_CTRL);
 229                ctrl &= ~CTRL_AA;
 230                writel(ctrl, bus->base + MPFS_I2C_CTRL);
 231        }
 232}
 233
 234static int mpfs_i2c_fill_tx(struct mpfs_i2c_bus *bus)
 235{
 236        mpfs_i2c_transfer(bus, *bus->buf++);
 237        bus->msg_len--;
 238
 239        return 0;
 240}
 241
 242static int mpfs_i2c_service_handler(struct mpfs_i2c_bus *bus)
 243{
 244        bool finish = false;
 245        u32 status;
 246        u8 ctrl;
 247
 248        status = bus->isr_status;
 249
 250        switch (status) {
 251        case STATUS_M_START_SENT:
 252        case STATUS_M_REPEATED_START_SENT:
 253                ctrl = readl(bus->base + MPFS_I2C_CTRL);
 254                ctrl &= ~CTRL_STA;
 255                writel(bus->addr, bus->base + MPFS_I2C_DATA);
 256                writel(ctrl, bus->base + MPFS_I2C_CTRL);
 257                break;
 258        case STATUS_M_SLAW_ACK:
 259        case STATUS_M_TX_DATA_ACK:
 260                if (bus->msg_len > 0) {
 261                        mpfs_i2c_fill_tx(bus);
 262                } else {
 263                        /* On the last byte to be transmitted, send STOP */
 264                        mpfs_i2c_stop(bus);
 265                        finish = true;
 266                }
 267                break;
 268        case STATUS_M_SLAR_ACK:
 269                if (bus->msg_len > 1u) {
 270                        ctrl = readl(bus->base + MPFS_I2C_CTRL);
 271                        ctrl |= CTRL_AA;
 272                        writel(ctrl, bus->base + MPFS_I2C_CTRL);
 273                } else if (bus->msg_len == 1u) {
 274                        ctrl = readl(bus->base + MPFS_I2C_CTRL);
 275                        ctrl &= ~CTRL_AA;
 276                        writel(ctrl, bus->base + MPFS_I2C_CTRL);
 277                } else {
 278                        ctrl = readl(bus->base + MPFS_I2C_CTRL);
 279                        ctrl |= CTRL_AA;
 280                        writel(ctrl, bus->base + MPFS_I2C_CTRL);
 281                        /* On the last byte to be transmitted, send STOP */
 282                        mpfs_i2c_stop(bus);
 283                        finish = true;
 284                }
 285                break;
 286        case STATUS_M_RX_DATA_ACKED:
 287                mpfs_i2c_empty_rx(bus);
 288                break;
 289        case STATUS_M_RX_DATA_NACKED:
 290                mpfs_i2c_empty_rx(bus);
 291                if (bus->msg_len == 0) {
 292                        /* On the last byte to be transmitted, send STOP */
 293                        mpfs_i2c_stop(bus);
 294                        finish = true;
 295                }
 296                break;
 297        case STATUS_M_TX_DATA_NACK:
 298        case STATUS_M_SLAR_NACK:
 299        case STATUS_M_SLAW_NACK:
 300                bus->msg_err = -ENXIO;
 301                mpfs_i2c_stop(bus);
 302                finish = true;
 303                break;
 304
 305        case STATUS_M_ARB_LOST:
 306                /* Handle Lost Arbitration */
 307                bus->msg_err = -EAGAIN;
 308                finish = true;
 309                break;
 310        default:
 311                break;
 312        }
 313
 314        if (finish) {
 315                ctrl = readl(bus->base + MPFS_I2C_CTRL);
 316                ctrl &= ~CTRL_AA;
 317                writel(ctrl, bus->base + MPFS_I2C_CTRL);
 318                return 0;
 319        }
 320
 321        return 1;
 322}
 323
 324static int mpfs_i2c_service(struct mpfs_i2c_bus *bus)
 325{
 326        int ret = 0;
 327        int si_bit;
 328
 329        si_bit = readl(bus->base + MPFS_I2C_CTRL);
 330        if (si_bit & CTRL_SI) {
 331                bus->isr_status = readl(bus->base + MPFS_I2C_STATUS);
 332                ret = mpfs_i2c_service_handler(bus);
 333        }
 334        /* Clear the si flag */
 335        mpfs_i2c_int_clear(bus);
 336        si_bit = readl(bus->base + MPFS_I2C_CTRL);
 337
 338        return ret;
 339}
 340
 341static int mpfs_i2c_check_service_change(struct mpfs_i2c_bus *bus)
 342{
 343        u8 ctrl;
 344        u32 count = 0;
 345
 346        while (1) {
 347                ctrl = readl(bus->base + MPFS_I2C_CTRL);
 348                if (ctrl & CTRL_SI)
 349                        break;
 350                udelay(1);
 351                count += 1;
 352                if (count == MICROCHIP_I2C_TIMEOUT)
 353                        return -ETIMEDOUT;
 354        }
 355        return 0;
 356}
 357
 358static int mpfs_i2c_poll_device(struct mpfs_i2c_bus *bus)
 359{
 360        int ret;
 361
 362        while (1) {
 363                ret = mpfs_i2c_check_service_change(bus);
 364                if (ret)
 365                        return ret;
 366
 367                ret = mpfs_i2c_service(bus);
 368                if (!ret)
 369                        /* all messages have been transferred */
 370                        return ret;
 371        }
 372}
 373
 374static int mpfs_i2c_xfer_msg(struct mpfs_i2c_bus *bus, struct i2c_msg *msg)
 375{
 376        u8 ctrl;
 377        int ret;
 378
 379        if (!msg->len || !msg->buf)
 380                return -EINVAL;
 381
 382        bus->addr = i2c_8bit_addr_from_msg(msg);
 383        bus->msg_len = msg->len;
 384        bus->buf = msg->buf;
 385        bus->msg_err = 0;
 386
 387        mpfs_i2c_core_enable(bus);
 388
 389        ctrl = readl(bus->base + MPFS_I2C_CTRL);
 390
 391        ctrl |= CTRL_STA;
 392
 393        writel(ctrl, bus->base + MPFS_I2C_CTRL);
 394
 395        ret = mpfs_i2c_poll_device(bus);
 396        if (ret)
 397                return ret;
 398
 399        return bus->msg_err;
 400}
 401
 402static int mpfs_i2c_xfer(struct udevice *dev, struct i2c_msg *msgs, int num_msgs)
 403{
 404        struct mpfs_i2c_bus *bus = dev_get_priv(dev);
 405        int idx, ret;
 406
 407        if (!msgs || !num_msgs)
 408                return -EINVAL;
 409
 410        for (idx = 0; idx < num_msgs; idx++) {
 411                ret = mpfs_i2c_xfer_msg(bus, msgs++);
 412                if (ret)
 413                        return ret;
 414        }
 415
 416        return ret;
 417}
 418
 419static int mpfs_i2c_probe_chip(struct udevice *dev, uint addr, uint flags)
 420{
 421        struct mpfs_i2c_bus *bus = dev_get_priv(dev);
 422        int ret;
 423        u8 ctrl, reg = 0;
 424
 425        /*
 426         * Send the chip address and verify that the
 427         * address was <ACK>ed.
 428         */
 429        bus->addr = addr << 1 | I2C_M_RD;
 430        bus->buf = &reg;
 431        bus->msg_len = 0;
 432        bus->msg_err = 0;
 433
 434        mpfs_i2c_core_enable(bus);
 435
 436        ctrl = readl(bus->base + MPFS_I2C_CTRL);
 437
 438        ctrl |= CTRL_STA;
 439
 440        writel(ctrl, bus->base + MPFS_I2C_CTRL);
 441
 442        ret = mpfs_i2c_poll_device(bus);
 443        if (ret)
 444                return ret;
 445
 446        return bus->msg_err;
 447}
 448
 449static int mpfs_i2c_probe(struct udevice *dev)
 450{
 451        int ret;
 452        u32 val;
 453        struct mpfs_i2c_bus *bus = dev_get_priv(dev);
 454
 455        bus->base = dev_read_addr_ptr(dev);
 456        if (!bus->base)
 457                return -EINVAL;
 458
 459        val = dev_read_u32(dev, "clock-frequency", &bus->clk_rate);
 460        if (val) {
 461                printf("Default to 100kHz\n");
 462                /* default clock rate */
 463                bus->clk_rate = 100000;
 464        }
 465
 466        if (bus->clk_rate > 400000 || bus->clk_rate <= 0) {
 467                printf("Invalid clock-frequency %d\n", bus->clk_rate);
 468                return -EINVAL;
 469        }
 470
 471        ret = mpfs_i2c_init(bus, dev);
 472
 473        return ret;
 474}
 475
 476static const struct dm_i2c_ops mpfs_i2c_ops = {
 477        .xfer = mpfs_i2c_xfer,
 478        .probe_chip = mpfs_i2c_probe_chip,
 479};
 480
 481static const struct udevice_id mpfs_i2c_ids[] = {
 482        {.compatible = "microchip,mpfs-i2c"},
 483        {}
 484};
 485
 486U_BOOT_DRIVER(mpfs_i2c) = {
 487        .name = "mpfs_i2c",
 488        .id = UCLASS_I2C,
 489        .of_match = mpfs_i2c_ids,
 490        .ops = &mpfs_i2c_ops,
 491        .probe = mpfs_i2c_probe,
 492        .priv_auto = sizeof(struct mpfs_i2c_bus),
 493};
 494