uboot/drivers/i2c/imx_lpi2c.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright 2016 Freescale Semiconductors, Inc.
   4 */
   5
   6#include <common.h>
   7#include <errno.h>
   8#include <log.h>
   9#include <asm/io.h>
  10#include <asm/arch/clock.h>
  11#include <asm/arch/imx-regs.h>
  12#include <imx_lpi2c.h>
  13#include <asm/arch/sys_proto.h>
  14#include <dm.h>
  15#include <fdtdec.h>
  16#include <i2c.h>
  17#include <dm/device_compat.h>
  18
  19#define LPI2C_FIFO_SIZE 4
  20#define LPI2C_NACK_TOUT_MS 1
  21#define LPI2C_TIMEOUT_MS 100
  22
  23static int bus_i2c_init(struct udevice *bus, int speed);
  24
  25/* Weak linked function for overridden by some SoC power function */
  26int __weak init_i2c_power(unsigned i2c_num)
  27{
  28        return 0;
  29}
  30
  31static int imx_lpci2c_check_busy_bus(const struct imx_lpi2c_reg *regs)
  32{
  33        lpi2c_status_t result = LPI2C_SUCESS;
  34        u32 status;
  35
  36        status = readl(&regs->msr);
  37
  38        if ((status & LPI2C_MSR_BBF_MASK) && !(status & LPI2C_MSR_MBF_MASK))
  39                result = LPI2C_BUSY;
  40
  41        return result;
  42}
  43
  44static int imx_lpci2c_check_clear_error(struct imx_lpi2c_reg *regs)
  45{
  46        lpi2c_status_t result = LPI2C_SUCESS;
  47        u32 val, status;
  48
  49        status = readl(&regs->msr);
  50        /* errors to check for */
  51        status &= LPI2C_MSR_NDF_MASK | LPI2C_MSR_ALF_MASK |
  52                LPI2C_MSR_FEF_MASK | LPI2C_MSR_PLTF_MASK;
  53
  54        if (status) {
  55                if (status & LPI2C_MSR_PLTF_MASK)
  56                        result = LPI2C_PIN_LOW_TIMEOUT_ERR;
  57                else if (status & LPI2C_MSR_ALF_MASK)
  58                        result = LPI2C_ARB_LOST_ERR;
  59                else if (status & LPI2C_MSR_NDF_MASK)
  60                        result = LPI2C_NAK_ERR;
  61                else if (status & LPI2C_MSR_FEF_MASK)
  62                        result = LPI2C_FIFO_ERR;
  63
  64                /* clear status flags */
  65                writel(0x7f00, &regs->msr);
  66                /* reset fifos */
  67                val = readl(&regs->mcr);
  68                val |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK;
  69                writel(val, &regs->mcr);
  70        }
  71
  72        return result;
  73}
  74
  75static int bus_i2c_wait_for_tx_ready(struct imx_lpi2c_reg *regs)
  76{
  77        lpi2c_status_t result = LPI2C_SUCESS;
  78        u32 txcount = 0;
  79        ulong start_time = get_timer(0);
  80
  81        do {
  82                txcount = LPI2C_MFSR_TXCOUNT(readl(&regs->mfsr));
  83                txcount = LPI2C_FIFO_SIZE - txcount;
  84                result = imx_lpci2c_check_clear_error(regs);
  85                if (result) {
  86                        debug("i2c: wait for tx ready: result 0x%x\n", result);
  87                        return result;
  88                }
  89                if (get_timer(start_time) > LPI2C_TIMEOUT_MS) {
  90                        debug("i2c: wait for tx ready: timeout\n");
  91                        return -1;
  92                }
  93        } while (!txcount);
  94
  95        return result;
  96}
  97
  98static int bus_i2c_send(struct udevice *bus, u8 *txbuf, int len)
  99{
 100        struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus);
 101        struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base);
 102        lpi2c_status_t result = LPI2C_SUCESS;
 103
 104        /* empty tx */
 105        if (!len)
 106                return result;
 107
 108        while (len--) {
 109                result = bus_i2c_wait_for_tx_ready(regs);
 110                if (result) {
 111                        debug("i2c: send wait for tx ready: %d\n", result);
 112                        return result;
 113                }
 114                writel(*txbuf++, &regs->mtdr);
 115        }
 116
 117        return result;
 118}
 119
 120static int bus_i2c_receive(struct udevice *bus, u8 *rxbuf, int len)
 121{
 122        struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus);
 123        struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base);
 124        lpi2c_status_t result = LPI2C_SUCESS;
 125        u32 val;
 126        ulong start_time = get_timer(0);
 127
 128        /* empty read */
 129        if (!len)
 130                return result;
 131
 132        result = bus_i2c_wait_for_tx_ready(regs);
 133        if (result) {
 134                debug("i2c: receive wait fot tx ready: %d\n", result);
 135                return result;
 136        }
 137
 138        /* clear all status flags */
 139        writel(0x7f00, &regs->msr);
 140        /* send receive command */
 141        val = LPI2C_MTDR_CMD(0x1) | LPI2C_MTDR_DATA(len - 1);
 142        writel(val, &regs->mtdr);
 143
 144        while (len--) {
 145                do {
 146                        result = imx_lpci2c_check_clear_error(regs);
 147                        if (result) {
 148                                debug("i2c: receive check clear error: %d\n",
 149                                      result);
 150                                return result;
 151                        }
 152                        if (get_timer(start_time) > LPI2C_TIMEOUT_MS) {
 153                                debug("i2c: receive mrdr: timeout\n");
 154                                return -1;
 155                        }
 156                        val = readl(&regs->mrdr);
 157                } while (val & LPI2C_MRDR_RXEMPTY_MASK);
 158                *rxbuf++ = LPI2C_MRDR_DATA(val);
 159        }
 160
 161        return result;
 162}
 163
 164static int bus_i2c_start(struct udevice *bus, u8 addr, u8 dir)
 165{
 166        lpi2c_status_t result;
 167        struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus);
 168        struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base);
 169        u32 val;
 170
 171        result = imx_lpci2c_check_busy_bus(regs);
 172        if (result) {
 173                debug("i2c: start check busy bus: 0x%x\n", result);
 174
 175                /* Try to init the lpi2c then check the bus busy again */
 176                bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
 177                result = imx_lpci2c_check_busy_bus(regs);
 178                if (result) {
 179                        printf("i2c: Error check busy bus: 0x%x\n", result);
 180                        return result;
 181                }
 182        }
 183        /* clear all status flags */
 184        writel(0x7f00, &regs->msr);
 185        /* turn off auto-stop condition */
 186        val = readl(&regs->mcfgr1) & ~LPI2C_MCFGR1_AUTOSTOP_MASK;
 187        writel(val, &regs->mcfgr1);
 188        /* wait tx fifo ready */
 189        result = bus_i2c_wait_for_tx_ready(regs);
 190        if (result) {
 191                debug("i2c: start wait for tx ready: 0x%x\n", result);
 192                return result;
 193        }
 194        /* issue start command */
 195        val = LPI2C_MTDR_CMD(0x4) | (addr << 0x1) | dir;
 196        writel(val, &regs->mtdr);
 197
 198        return result;
 199}
 200
 201static int bus_i2c_stop(struct udevice *bus)
 202{
 203        lpi2c_status_t result;
 204        struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus);
 205        struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base);
 206        u32 status;
 207        ulong start_time;
 208
 209        result = bus_i2c_wait_for_tx_ready(regs);
 210        if (result) {
 211                debug("i2c: stop wait for tx ready: 0x%x\n", result);
 212                return result;
 213        }
 214
 215        /* send stop command */
 216        writel(LPI2C_MTDR_CMD(0x2), &regs->mtdr);
 217
 218        start_time = get_timer(0);
 219        while (1) {
 220                status = readl(&regs->msr);
 221                result = imx_lpci2c_check_clear_error(regs);
 222                /* stop detect flag */
 223                if (status & LPI2C_MSR_SDF_MASK) {
 224                        /* clear stop flag */
 225                        status &= LPI2C_MSR_SDF_MASK;
 226                        writel(status, &regs->msr);
 227                        break;
 228                }
 229
 230                if (get_timer(start_time) > LPI2C_NACK_TOUT_MS) {
 231                        debug("stop timeout\n");
 232                        return -ETIMEDOUT;
 233                }
 234        }
 235
 236        return result;
 237}
 238
 239static int bus_i2c_read(struct udevice *bus, u32 chip, u8 *buf, int len)
 240{
 241        lpi2c_status_t result;
 242
 243        result = bus_i2c_start(bus, chip, 1);
 244        if (result)
 245                return result;
 246        result = bus_i2c_receive(bus, buf, len);
 247        if (result)
 248                return result;
 249
 250        return result;
 251}
 252
 253static int bus_i2c_write(struct udevice *bus, u32 chip, u8 *buf, int len)
 254{
 255        lpi2c_status_t result;
 256
 257        result = bus_i2c_start(bus, chip, 0);
 258        if (result)
 259                return result;
 260        result = bus_i2c_send(bus, buf, len);
 261        if (result)
 262                return result;
 263
 264        return result;
 265}
 266
 267
 268u32 __weak imx_get_i2cclk(u32 i2c_num)
 269{
 270        return 0;
 271}
 272
 273static int bus_i2c_set_bus_speed(struct udevice *bus, int speed)
 274{
 275        struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus);
 276        struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base);
 277        u32 val;
 278        u32 preescale = 0, best_pre = 0, clkhi = 0;
 279        u32 best_clkhi = 0, abs_error = 0, rate;
 280        u32 error = 0xffffffff;
 281        u32 clock_rate;
 282        bool mode;
 283        int i;
 284
 285        if (IS_ENABLED(CONFIG_CLK)) {
 286                clock_rate = clk_get_rate(&i2c_bus->per_clk);
 287                if (clock_rate <= 0) {
 288                        dev_err(bus, "Failed to get i2c clk: %d\n", clock_rate);
 289                        return clock_rate;
 290                }
 291        } else {
 292                clock_rate = imx_get_i2cclk(dev_seq(bus));
 293                if (!clock_rate)
 294                        return -EPERM;
 295        }
 296
 297        mode = (readl(&regs->mcr) & LPI2C_MCR_MEN_MASK) >> LPI2C_MCR_MEN_SHIFT;
 298        /* disable master mode */
 299        val = readl(&regs->mcr) & ~LPI2C_MCR_MEN_MASK;
 300        writel(val | LPI2C_MCR_MEN(0), &regs->mcr);
 301
 302        for (preescale = 1; (preescale <= 128) &&
 303                (error != 0); preescale = 2 * preescale) {
 304                for (clkhi = 1; clkhi < 32; clkhi++) {
 305                        if (clkhi == 1)
 306                                rate = (clock_rate / preescale) / (1 + 3 + 2 + 2 / preescale);
 307                        else
 308                                rate = (clock_rate / preescale / (3 * clkhi + 2 + 2 / preescale));
 309
 310                        abs_error = speed > rate ? speed - rate : rate - speed;
 311
 312                        if (abs_error < error) {
 313                                best_pre = preescale;
 314                                best_clkhi = clkhi;
 315                                error = abs_error;
 316                                if (abs_error == 0)
 317                                        break;
 318                        }
 319                }
 320        }
 321
 322        /* Standard, fast, fast mode plus and ultra-fast transfers. */
 323        val = LPI2C_MCCR0_CLKHI(best_clkhi);
 324        if (best_clkhi < 2)
 325                val |= LPI2C_MCCR0_CLKLO(3) | LPI2C_MCCR0_SETHOLD(2) | LPI2C_MCCR0_DATAVD(1);
 326        else
 327                val |= LPI2C_MCCR0_CLKLO(2 * best_clkhi) | LPI2C_MCCR0_SETHOLD(best_clkhi) |
 328                        LPI2C_MCCR0_DATAVD(best_clkhi / 2);
 329        writel(val, &regs->mccr0);
 330
 331        for (i = 0; i < 8; i++) {
 332                if (best_pre == (1 << i)) {
 333                        best_pre = i;
 334                        break;
 335                }
 336        }
 337
 338        val = readl(&regs->mcfgr1) & ~LPI2C_MCFGR1_PRESCALE_MASK;
 339        writel(val | LPI2C_MCFGR1_PRESCALE(best_pre), &regs->mcfgr1);
 340
 341        if (mode) {
 342                val = readl(&regs->mcr) & ~LPI2C_MCR_MEN_MASK;
 343                writel(val | LPI2C_MCR_MEN(1), &regs->mcr);
 344        }
 345
 346        return 0;
 347}
 348
 349static int bus_i2c_init(struct udevice *bus, int speed)
 350{
 351        u32 val;
 352        int ret;
 353
 354        struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus);
 355        struct imx_lpi2c_reg *regs = (struct imx_lpi2c_reg *)(i2c_bus->base);
 356        /* reset peripheral */
 357        writel(LPI2C_MCR_RST_MASK, &regs->mcr);
 358        writel(0x0, &regs->mcr);
 359        /* Disable Dozen mode */
 360        writel(LPI2C_MCR_DBGEN(0) | LPI2C_MCR_DOZEN(1), &regs->mcr);
 361        /* host request disable, active high, external pin */
 362        val = readl(&regs->mcfgr0);
 363        val &= (~(LPI2C_MCFGR0_HREN_MASK | LPI2C_MCFGR0_HRPOL_MASK |
 364                                LPI2C_MCFGR0_HRSEL_MASK));
 365        val |= LPI2C_MCFGR0_HRPOL(0x1);
 366        writel(val, &regs->mcfgr0);
 367        /* pincfg and ignore ack */
 368        val = readl(&regs->mcfgr1);
 369        val &= ~(LPI2C_MCFGR1_PINCFG_MASK | LPI2C_MCFGR1_IGNACK_MASK);
 370        val |= LPI2C_MCFGR1_PINCFG(0x0); /* 2 pin open drain */
 371        val |= LPI2C_MCFGR1_IGNACK(0x0); /* ignore nack */
 372        writel(val, &regs->mcfgr1);
 373
 374        ret = bus_i2c_set_bus_speed(bus, speed);
 375
 376        /* enable lpi2c in master mode */
 377        val = readl(&regs->mcr) & ~LPI2C_MCR_MEN_MASK;
 378        writel(val | LPI2C_MCR_MEN(1), &regs->mcr);
 379
 380        debug("i2c : controller bus %d, speed %d:\n", dev_seq(bus), speed);
 381
 382        return ret;
 383}
 384
 385static int imx_lpi2c_probe_chip(struct udevice *bus, u32 chip,
 386                                u32 chip_flags)
 387{
 388        lpi2c_status_t result;
 389
 390        result = bus_i2c_start(bus, chip, 0);
 391        if (result) {
 392                bus_i2c_stop(bus);
 393                bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
 394                return result;
 395        }
 396
 397        result = bus_i2c_stop(bus);
 398        if (result)
 399                bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
 400
 401        return result;
 402}
 403
 404static int imx_lpi2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
 405{
 406        int ret = 0, ret_stop;
 407
 408        for (; nmsgs > 0; nmsgs--, msg++) {
 409                debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
 410                if (msg->flags & I2C_M_RD)
 411                        ret = bus_i2c_read(bus, msg->addr, msg->buf, msg->len);
 412                else {
 413                        ret = bus_i2c_write(bus, msg->addr, msg->buf,
 414                                            msg->len);
 415                        if (ret)
 416                                break;
 417                }
 418        }
 419
 420        if (ret)
 421                debug("i2c_write: error sending\n");
 422
 423        ret_stop = bus_i2c_stop(bus);
 424        if (ret_stop)
 425                debug("i2c_xfer: stop bus error\n");
 426
 427        ret |= ret_stop;
 428
 429        return ret;
 430}
 431
 432static int imx_lpi2c_set_bus_speed(struct udevice *bus, unsigned int speed)
 433{
 434        return bus_i2c_set_bus_speed(bus, speed);
 435}
 436
 437__weak int enable_i2c_clk(unsigned char enable, unsigned int i2c_num)
 438{
 439        return 0;
 440}
 441
 442static int imx_lpi2c_probe(struct udevice *bus)
 443{
 444        struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus);
 445        fdt_addr_t addr;
 446        int ret;
 447
 448        i2c_bus->driver_data = dev_get_driver_data(bus);
 449
 450        addr = dev_read_addr(bus);
 451        if (addr == FDT_ADDR_T_NONE)
 452                return -EINVAL;
 453
 454        i2c_bus->base = addr;
 455        i2c_bus->index = dev_seq(bus);
 456        i2c_bus->bus = bus;
 457
 458        /* power up i2c resource */
 459        ret = init_i2c_power(dev_seq(bus));
 460        if (ret) {
 461                debug("init_i2c_power err = %d\n", ret);
 462                return ret;
 463        }
 464
 465        if (IS_ENABLED(CONFIG_CLK)) {
 466                ret = clk_get_by_name(bus, "per", &i2c_bus->per_clk);
 467                if (ret) {
 468                        dev_err(bus, "Failed to get per clk\n");
 469                        return ret;
 470                }
 471                ret = clk_enable(&i2c_bus->per_clk);
 472                if (ret) {
 473                        dev_err(bus, "Failed to enable per clk\n");
 474                        return ret;
 475                }
 476
 477                ret = clk_get_by_name(bus, "ipg", &i2c_bus->ipg_clk);
 478                if (ret) {
 479                        dev_err(bus, "Failed to get ipg clk\n");
 480                        return ret;
 481                }
 482                ret = clk_enable(&i2c_bus->ipg_clk);
 483                if (ret) {
 484                        dev_err(bus, "Failed to enable ipg clk\n");
 485                        return ret;
 486                }
 487        } else {
 488                /* To i.MX7ULP, only i2c4-7 can be handled by A7 core */
 489                ret = enable_i2c_clk(1, dev_seq(bus));
 490                if (ret < 0)
 491                        return ret;
 492        }
 493
 494        ret = bus_i2c_init(bus, I2C_SPEED_STANDARD_RATE);
 495        if (ret < 0)
 496                return ret;
 497
 498        debug("i2c : controller bus %d at 0x%lx , speed %d: ",
 499              dev_seq(bus), i2c_bus->base,
 500              i2c_bus->speed);
 501
 502        return 0;
 503}
 504
 505static const struct dm_i2c_ops imx_lpi2c_ops = {
 506        .xfer           = imx_lpi2c_xfer,
 507        .probe_chip     = imx_lpi2c_probe_chip,
 508        .set_bus_speed  = imx_lpi2c_set_bus_speed,
 509};
 510
 511static const struct udevice_id imx_lpi2c_ids[] = {
 512        { .compatible = "fsl,imx7ulp-lpi2c", },
 513        { .compatible = "fsl,imx8qm-lpi2c", },
 514        {}
 515};
 516
 517U_BOOT_DRIVER(imx_lpi2c) = {
 518        .name = "imx_lpi2c",
 519        .id = UCLASS_I2C,
 520        .of_match = imx_lpi2c_ids,
 521        .probe = imx_lpi2c_probe,
 522        .priv_auto      = sizeof(struct imx_lpi2c_bus),
 523        .ops = &imx_lpi2c_ops,
 524};
 525