uboot/drivers/i2c/synquacer_i2c.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 */
   4
   5#include <dm/device_compat.h>
   6#include <linux/delay.h>
   7#include <linux/errno.h>
   8#include <linux/io.h>
   9#include <linux/sizes.h>
  10#include <linux/types.h>
  11#include <dm.h>
  12#include <fdtdec.h>
  13#include <i2c.h>
  14#include <clk.h>
  15
  16#define REG_BSR         0x0
  17#define REG_BCR         0x4
  18#define REG_CCR         0x8
  19#define REG_ADR         0xc
  20#define REG_DAR         0x10
  21#define REG_CSR         0x14
  22#define REG_FSR         0x18
  23#define REG_BC2R        0x1c
  24
  25/* I2C register bit definitions */
  26#define BSR_FBT         BIT(0)  // First Byte Transfer
  27#define BSR_GCA         BIT(1)  // General Call Address
  28#define BSR_AAS         BIT(2)  // Address as Slave
  29#define BSR_TRX         BIT(3)  // Transfer/Receive
  30#define BSR_LRB         BIT(4)  // Last Received Bit
  31#define BSR_AL          BIT(5)  // Arbitration Lost
  32#define BSR_RSC         BIT(6)  // Repeated Start Cond.
  33#define BSR_BB          BIT(7)  // Bus Busy
  34
  35#define BCR_INT         BIT(0)  // Interrupt
  36#define BCR_INTE                BIT(1)  // Interrupt Enable
  37#define BCR_GCAA                BIT(2)  // Gen. Call Access Ack.
  38#define BCR_ACK         BIT(3)  // Acknowledge
  39#define BCR_MSS         BIT(4)  // Master Slave Select
  40#define BCR_SCC         BIT(5)  // Start Condition Cont.
  41#define BCR_BEIE                BIT(6)  // Bus Error Int Enable
  42#define BCR_BER         BIT(7)  // Bus Error
  43
  44#define CCR_CS_MASK     (0x1f)  // CCR Clock Period Sel.
  45#define CCR_EN          BIT(5)  // Enable
  46#define CCR_FM          BIT(6)  // Speed Mode Select
  47
  48#define CSR_CS_MASK     (0x3f)  // CSR Clock Period Sel.
  49
  50#define BC2R_SCLL               BIT(0)  // SCL Low Drive
  51#define BC2R_SDAL               BIT(1)  // SDA Low Drive
  52#define BC2R_SCLS               BIT(4)  // SCL Status
  53#define BC2R_SDAS               BIT(5)  // SDA Status
  54
  55/* PCLK frequency */
  56#define BUS_CLK_FR(rate)        (((rate) / 20000000) + 1)
  57
  58#define I2C_CLK_DEF             62500000
  59
  60/* STANDARD MODE frequency */
  61#define CLK_MASTER_STD(rate)                    \
  62        DIV_ROUND_UP(DIV_ROUND_UP((rate), I2C_SPEED_STANDARD_RATE) - 2, 2)
  63/* FAST MODE frequency */
  64#define CLK_MASTER_FAST(rate)                   \
  65        DIV_ROUND_UP((DIV_ROUND_UP((rate), I2C_SPEED_FAST_RATE) - 2) * 2, 3)
  66
  67/* (clkrate <= 18000000) */
  68/* calculate the value of CS bits in CCR register on standard mode */
  69#define CCR_CS_STD_MAX_18M(rate)                        \
  70           ((CLK_MASTER_STD(rate) - 65)         \
  71                                        & CCR_CS_MASK)
  72
  73/* calculate the value of CS bits in CSR register on standard mode */
  74#define CSR_CS_STD_MAX_18M(rate)                0x00
  75
  76/* calculate the value of CS bits in CCR register on fast mode */
  77#define CCR_CS_FAST_MAX_18M(rate)                       \
  78           ((CLK_MASTER_FAST(rate) - 1)         \
  79                                        & CCR_CS_MASK)
  80
  81/* calculate the value of CS bits in CSR register on fast mode */
  82#define CSR_CS_FAST_MAX_18M(rate)               0x00
  83
  84/* (clkrate > 18000000) */
  85/* calculate the value of CS bits in CCR register on standard mode */
  86#define CCR_CS_STD_MIN_18M(rate)                        \
  87           ((CLK_MASTER_STD(rate) - 1)          \
  88                                        & CCR_CS_MASK)
  89
  90/* calculate the value of CS bits in CSR register on standard mode */
  91#define CSR_CS_STD_MIN_18M(rate)                        \
  92           (((CLK_MASTER_STD(rate) - 1) >> 5)   \
  93                                        & CSR_CS_MASK)
  94
  95/* calculate the value of CS bits in CCR register on fast mode */
  96#define CCR_CS_FAST_MIN_18M(rate)                       \
  97           ((CLK_MASTER_FAST(rate) - 1)         \
  98                                        & CCR_CS_MASK)
  99
 100/* calculate the value of CS bits in CSR register on fast mode */
 101#define CSR_CS_FAST_MIN_18M(rate)                       \
 102           (((CLK_MASTER_FAST(rate) - 1) >> 5)  \
 103                                        & CSR_CS_MASK)
 104
 105/* min I2C clock frequency 14M */
 106#define MIN_CLK_RATE    (14 * 1000000)
 107/* max I2C clock frequency 200M */
 108#define MAX_CLK_RATE    (200 * 1000000)
 109/* I2C clock frequency 18M */
 110#define CLK_RATE_18M    (18 * 1000000)
 111
 112#define SPEED_FM                400     // Fast Mode
 113#define SPEED_SM                100     // Standard Mode
 114
 115DECLARE_GLOBAL_DATA_PTR;
 116
 117struct synquacer_i2c {
 118        void __iomem *base;
 119        unsigned long pclkrate;
 120        unsigned long speed_khz;
 121};
 122
 123static int wait_irq(struct udevice *dev)
 124{
 125        struct synquacer_i2c *i2c = dev_get_priv(dev);
 126        int timeout = 500000;
 127
 128        do {
 129                if (readb(i2c->base + REG_BCR) & BCR_INT)
 130                        return 0;
 131        } while (timeout--);
 132
 133        pr_err("%s: timeout\n", __func__);
 134        return -1;
 135}
 136
 137static int synquacer_i2c_xfer_start(struct synquacer_i2c *i2c,
 138                                    int addr, int read)
 139{
 140        u8 bsr, bcr;
 141
 142        writeb((addr << 1) | (read ? 1 : 0), i2c->base + REG_DAR);
 143
 144        bsr = readb(i2c->base + REG_BSR);
 145        bcr = readb(i2c->base + REG_BCR);
 146
 147        if ((bsr & BSR_BB) && !(bcr & BCR_MSS))
 148                return -EBUSY;
 149
 150        if (bsr & BSR_BB) {
 151                writeb(bcr | BCR_SCC, i2c->base + REG_BCR);
 152        } else {
 153                if (bcr & BCR_MSS)
 154                        return -EAGAIN;
 155                /* Start Condition + Enable Interrupts */
 156                writeb(bcr | BCR_MSS | BCR_INTE | BCR_BEIE, i2c->base + REG_BCR);
 157        }
 158
 159        udelay(100);
 160        return 0;
 161}
 162
 163static int synquacer_i2c_xfer(struct udevice *bus,
 164                              struct i2c_msg *msg, int nmsgs)
 165{
 166        struct synquacer_i2c *i2c = dev_get_priv(bus);
 167        u8 bsr, bcr;
 168        int idx;
 169
 170        for (; nmsgs > 0; nmsgs--, msg++) {
 171                synquacer_i2c_xfer_start(i2c, msg->addr, msg->flags & I2C_M_RD);
 172                if (wait_irq(bus))
 173                        return -EREMOTEIO;
 174
 175                bsr = readb(i2c->base + REG_BSR);
 176                if (bsr & BSR_LRB) {
 177                        debug("%s: No ack received\n", __func__);
 178                        return -EREMOTEIO;
 179                }
 180
 181                idx = 0;
 182                do {
 183                        bsr = readb(i2c->base + REG_BSR);
 184                        bcr = readb(i2c->base + REG_BCR);
 185                        if (bcr & BCR_BER) {
 186                                debug("%s: Bus error detected\n", __func__);
 187                                return -EREMOTEIO;
 188                        }
 189                        if ((bsr & BSR_AL) || !(bcr & BCR_MSS)) {
 190                                debug("%s: Arbitration lost\n", __func__);
 191                                return -EREMOTEIO;
 192                        }
 193
 194                        if (msg->flags & I2C_M_RD) {
 195                                bcr = BCR_MSS | BCR_INTE | BCR_BEIE;
 196                                if (idx < msg->len - 1)
 197                                        bcr |= BCR_ACK;
 198                                writeb(bcr, i2c->base + REG_BCR);
 199                                if (wait_irq(bus))
 200                                        return -EREMOTEIO;
 201                                bsr = readb(i2c->base + REG_BSR);
 202                                if (!(bsr & BSR_FBT))
 203                                        msg->buf[idx++] = readb(i2c->base + REG_DAR);
 204                        } else {
 205                                writeb(msg->buf[idx++], i2c->base + REG_DAR);
 206                                bcr = BCR_MSS | BCR_INTE | BCR_BEIE;
 207                                writeb(bcr, i2c->base + REG_BCR);
 208                                if (wait_irq(bus))
 209                                        return -EREMOTEIO;
 210                                bsr = readb(i2c->base + REG_BSR);
 211                                if (bsr & BSR_LRB) {
 212                                        debug("%s: no ack\n", __func__);
 213                                        return -EREMOTEIO;
 214                                }
 215                        }
 216                } while (idx < msg->len);
 217        }
 218
 219        /* Force bus state to idle, terminating any ongoing transfer */
 220        writeb(0, i2c->base + REG_BCR);
 221        udelay(100);
 222
 223        return 0;
 224}
 225
 226static void synquacer_i2c_hw_reset(struct synquacer_i2c *i2c)
 227{
 228        /* Disable clock */
 229        writeb(0, i2c->base + REG_CCR);
 230        writeb(0, i2c->base + REG_CSR);
 231
 232        /* Set own Address */
 233        writeb(0, i2c->base + REG_ADR);
 234
 235        /* Set PCLK frequency */
 236        writeb(BUS_CLK_FR(i2c->pclkrate), i2c->base + REG_FSR);
 237
 238        /* clear IRQ (INT=0, BER=0), Interrupt Disable */
 239        writeb(0, i2c->base + REG_BCR);
 240        writeb(0, i2c->base + REG_BC2R);
 241}
 242
 243static int synquacer_i2c_get_bus_speed(struct udevice *bus)
 244{
 245        struct synquacer_i2c *i2c = dev_get_priv(bus);
 246
 247        return i2c->speed_khz * 1000;
 248}
 249
 250static int synquacer_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
 251{
 252        struct synquacer_i2c *i2c = dev_get_priv(bus);
 253        u32 rt = i2c->pclkrate;
 254        u8 ccr_cs, csr_cs;
 255
 256        /* Set PCLK frequency */
 257        writeb(BUS_CLK_FR(i2c->pclkrate), i2c->base + REG_FSR);
 258
 259        if (speed >= SPEED_FM * 1000) {
 260                i2c->speed_khz = SPEED_FM;
 261                if (i2c->pclkrate <= CLK_RATE_18M) {
 262                        ccr_cs = CCR_CS_FAST_MAX_18M(rt);
 263                        csr_cs = CSR_CS_FAST_MAX_18M(rt);
 264                } else {
 265                        ccr_cs = CCR_CS_FAST_MIN_18M(rt);
 266                        csr_cs = CSR_CS_FAST_MIN_18M(rt);
 267                }
 268
 269                /* Set Clock and enable, Set fast mode */
 270                writeb(ccr_cs | CCR_FM | CCR_EN, i2c->base + REG_CCR);
 271                writeb(csr_cs, i2c->base + REG_CSR);
 272        } else {
 273                i2c->speed_khz = SPEED_SM;
 274                if (i2c->pclkrate <= CLK_RATE_18M) {
 275                        ccr_cs = CCR_CS_STD_MAX_18M(rt);
 276                        csr_cs = CSR_CS_STD_MAX_18M(rt);
 277                } else {
 278                        ccr_cs = CCR_CS_STD_MIN_18M(rt);
 279                        csr_cs = CSR_CS_STD_MIN_18M(rt);
 280                }
 281
 282                /* Set Clock and enable, Set standard mode */
 283                writeb(ccr_cs | CCR_EN, i2c->base + REG_CCR);
 284                writeb(csr_cs, i2c->base + REG_CSR);
 285        }
 286
 287        return 0;
 288}
 289
 290static int synquacer_i2c_of_to_plat(struct udevice *bus)
 291{
 292        struct synquacer_i2c *priv = dev_get_priv(bus);
 293        struct clk ck;
 294        int ret;
 295
 296        ret = clk_get_by_index(bus, 0, &ck);
 297        if (ret < 0) {
 298                priv->pclkrate = I2C_CLK_DEF;
 299        } else {
 300                clk_enable(&ck);
 301                priv->pclkrate = clk_get_rate(&ck);
 302        }
 303
 304        return 0;
 305}
 306
 307static int synquacer_i2c_probe(struct udevice *bus)
 308{
 309        struct synquacer_i2c *i2c = dev_get_priv(bus);
 310
 311        i2c->base = dev_read_addr_ptr(bus);
 312        synquacer_i2c_hw_reset(i2c);
 313        synquacer_i2c_set_bus_speed(bus, 400000); /* set default speed */
 314        return 0;
 315}
 316
 317static const struct dm_i2c_ops synquacer_i2c_ops = {
 318        .xfer = synquacer_i2c_xfer,
 319        .set_bus_speed = synquacer_i2c_set_bus_speed,
 320        .get_bus_speed = synquacer_i2c_get_bus_speed,
 321};
 322
 323static const struct udevice_id synquacer_i2c_ids[] = {
 324        {
 325                .compatible = "socionext,synquacer-i2c",
 326        },
 327        { }
 328};
 329
 330U_BOOT_DRIVER(sni_synquacer_i2c) = {
 331        .name   = "sni_synquacer_i2c",
 332        .id     = UCLASS_I2C,
 333        .of_match = synquacer_i2c_ids,
 334        .of_to_plat = synquacer_i2c_of_to_plat,
 335        .probe  = synquacer_i2c_probe,
 336        .priv_auto      = sizeof(struct synquacer_i2c),
 337        .ops    = &synquacer_i2c_ops,
 338};
 339