Commit 1086bfa9f49127e40a92b1225af1ed5e41f8fa1c

Authored by Nobuhiro Iwamatsu
Committed by Heiko Schocher
1 parent e66587495d

i2c: Add support for Renesas rcar

This supports i2c controller for Renesas rcar.

Signed-off-by: Hisashi Nakamura <hisashi.nakamura.ak@renesas.com>
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>

Showing 3 changed files with 303 additions and 0 deletions Side-by-side Diff

... ... @@ -2014,6 +2014,20 @@
2014 2014 If thoses defines are not set, default value is 100000
2015 2015 for speed, and 0 for slave.
2016 2016  
  2017 + - drivers/i2c/rcar_i2c.c:
  2018 + - activate this driver with CONFIG_SYS_I2C_RCAR
  2019 + - This driver adds 4 i2c buses
  2020 +
  2021 + - CONFIG_SYS_RCAR_I2C0_BASE for setting the register channel 0
  2022 + - CONFIG_SYS_RCAR_I2C0_SPEED for for the speed channel 0
  2023 + - CONFIG_SYS_RCAR_I2C1_BASE for setting the register channel 1
  2024 + - CONFIG_SYS_RCAR_I2C1_SPEED for for the speed channel 1
  2025 + - CONFIG_SYS_RCAR_I2C2_BASE for setting the register channel 2
  2026 + - CONFIG_SYS_RCAR_I2C2_SPEED for for the speed channel 2
  2027 + - CONFIG_SYS_RCAR_I2C3_BASE for setting the register channel 3
  2028 + - CONFIG_SYS_RCAR_I2C3_SPEED for for the speed channel 3
  2029 + - CONFIF_SYS_RCAR_I2C_NUM_CONTROLLERS for number of i2c buses
  2030 +
2017 2031 additional defines:
2018 2032  
2019 2033 CONFIG_SYS_NUM_I2C_BUSES
drivers/i2c/Makefile
... ... @@ -29,6 +29,7 @@
29 29 COBJS-$(CONFIG_SYS_I2C_FTI2C010) += fti2c010.o
30 30 COBJS-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o
31 31 COBJS-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o
  32 +COBJS-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o
32 33 COBJS-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o
33 34 COBJS-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
34 35 COBJS-$(CONFIG_ZYNQ_I2C) += zynq_i2c.o
drivers/i2c/rcar_i2c.c
  1 +/*
  2 + * drivers/i2c/rcar_i2c.c
  3 + *
  4 + * Copyright (C) 2013 Renesas Electronics Corporation
  5 + * Copyright (C) 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
  6 + *
  7 + * SPDX-License-Identifier: GPL-2.0
  8 + */
  9 +
  10 +#include <common.h>
  11 +#include <i2c.h>
  12 +#include <asm/io.h>
  13 +
  14 +DECLARE_GLOBAL_DATA_PTR;
  15 +
  16 +struct rcar_i2c {
  17 + u32 icscr;
  18 + u32 icmcr;
  19 + u32 icssr;
  20 + u32 icmsr;
  21 + u32 icsier;
  22 + u32 icmier;
  23 + u32 icccr;
  24 + u32 icsar;
  25 + u32 icmar;
  26 + u32 icrxdtxd;
  27 + u32 icccr2;
  28 + u32 icmpr;
  29 + u32 ichpr;
  30 + u32 iclpr;
  31 +};
  32 +
  33 +#define MCR_MDBS 0x80 /* non-fifo mode switch */
  34 +#define MCR_FSCL 0x40 /* override SCL pin */
  35 +#define MCR_FSDA 0x20 /* override SDA pin */
  36 +#define MCR_OBPC 0x10 /* override pins */
  37 +#define MCR_MIE 0x08 /* master if enable */
  38 +#define MCR_TSBE 0x04
  39 +#define MCR_FSB 0x02 /* force stop bit */
  40 +#define MCR_ESG 0x01 /* en startbit gen. */
  41 +
  42 +#define MSR_MASK 0x7f
  43 +#define MSR_MNR 0x40 /* nack received */
  44 +#define MSR_MAL 0x20 /* arbitration lost */
  45 +#define MSR_MST 0x10 /* sent a stop */
  46 +#define MSR_MDE 0x08
  47 +#define MSR_MDT 0x04
  48 +#define MSR_MDR 0x02
  49 +#define MSR_MAT 0x01 /* slave addr xfer done */
  50 +
  51 +static const struct rcar_i2c *i2c_dev[CONFIF_SYS_RCAR_I2C_NUM_CONTROLLERS] = {
  52 + (struct rcar_i2c *)CONFIG_SYS_RCAR_I2C0_BASE,
  53 + (struct rcar_i2c *)CONFIG_SYS_RCAR_I2C1_BASE,
  54 + (struct rcar_i2c *)CONFIG_SYS_RCAR_I2C2_BASE,
  55 + (struct rcar_i2c *)CONFIG_SYS_RCAR_I2C3_BASE,
  56 +};
  57 +
  58 +static void rcar_i2c_raw_rw_common(struct rcar_i2c *dev, u8 chip, uint addr)
  59 +{
  60 + /* set slave address */
  61 + writel(chip << 1, &dev->icmar);
  62 + /* set register address */
  63 + writel(addr, &dev->icrxdtxd);
  64 + /* clear status */
  65 + writel(0, &dev->icmsr);
  66 + /* start master send */
  67 + writel(MCR_MDBS | MCR_MIE | MCR_ESG, &dev->icmcr);
  68 +
  69 + while ((readl(&dev->icmsr) & (MSR_MAT | MSR_MDE))
  70 + != (MSR_MAT | MSR_MDE))
  71 + udelay(10);
  72 +
  73 + /* clear ESG */
  74 + writel(MCR_MDBS | MCR_MIE, &dev->icmcr);
  75 + /* start SCLclk */
  76 + writel(~(MSR_MAT | MSR_MDE), &dev->icmsr);
  77 +
  78 + while (!(readl(&dev->icmsr) & MSR_MDE))
  79 + udelay(10);
  80 +}
  81 +
  82 +static void rcar_i2c_raw_rw_finish(struct rcar_i2c *dev)
  83 +{
  84 + while (!(readl(&dev->icmsr) & MSR_MST))
  85 + udelay(10);
  86 +
  87 + writel(0, &dev->icmcr);
  88 +}
  89 +
  90 +static int
  91 +rcar_i2c_raw_write(struct rcar_i2c *dev, u8 chip, uint addr, u8 *val, int size)
  92 +{
  93 + rcar_i2c_raw_rw_common(dev, chip, addr);
  94 +
  95 + /* set send date */
  96 + writel(*val, &dev->icrxdtxd);
  97 + /* start SCLclk */
  98 + writel(~MSR_MDE, &dev->icmsr);
  99 +
  100 + while (!(readl(&dev->icmsr) & MSR_MDE))
  101 + udelay(10);
  102 +
  103 + /* set stop condition */
  104 + writel(MCR_MDBS | MCR_MIE | MCR_FSB, &dev->icmcr);
  105 + /* start SCLclk */
  106 + writel(~MSR_MDE, &dev->icmsr);
  107 +
  108 + rcar_i2c_raw_rw_finish(dev);
  109 +
  110 + return 0;
  111 +}
  112 +
  113 +static u8
  114 +rcar_i2c_raw_read(struct rcar_i2c *dev, u8 chip, uint addr)
  115 +{
  116 + u8 ret;
  117 +
  118 + rcar_i2c_raw_rw_common(dev, chip, addr);
  119 +
  120 + /* set slave address, receive */
  121 + writel((chip << 1) | 1, &dev->icmar);
  122 + /* start master receive */
  123 + writel(MCR_MDBS | MCR_MIE | MCR_ESG, &dev->icmcr);
  124 +
  125 + while ((readl(&dev->icmsr) & (MSR_MAT | MSR_MDE))
  126 + != (MSR_MAT | MSR_MDE))
  127 + udelay(10);
  128 +
  129 + /* clear ESG */
  130 + writel(MCR_MDBS | MCR_MIE, &dev->icmcr);
  131 + /* prepare stop condition */
  132 + writel(MCR_MDBS | MCR_MIE | MCR_FSB, &dev->icmcr);
  133 + /* start SCLclk */
  134 + writel(~(MSR_MAT | MSR_MDR), &dev->icmsr);
  135 +
  136 + while (!(readl(&dev->icmsr) & MSR_MDR))
  137 + udelay(10);
  138 +
  139 + /* get receive data */
  140 + ret = (u8)readl(&dev->icrxdtxd);
  141 + /* start SCLclk */
  142 + writel(~MSR_MDR, &dev->icmsr);
  143 +
  144 + rcar_i2c_raw_rw_finish(dev);
  145 +
  146 + return ret;
  147 +}
  148 +
  149 +/*
  150 + * SCL = iicck / (20 + SCGD * 8 + F[(ticf + tr + intd) * iicck])
  151 + * iicck : I2C internal clock < 20 MHz
  152 + * ticf : I2C SCL falling time: 35 ns
  153 + * tr : I2C SCL rising time: 200 ns
  154 + * intd : LSI internal delay: I2C0: 50 ns I2C1-3: 5
  155 + * F[n] : n rounded up to an integer
  156 + */
  157 +static u32 rcar_clock_gen(int i2c_no, u32 bus_speed)
  158 +{
  159 + u32 iicck, f, scl, scgd;
  160 + u32 intd = 5;
  161 +
  162 + int bit = 0, cdf_width = 3;
  163 + for (bit = 0; bit < (1 << cdf_width); bit++) {
  164 + iicck = CONFIG_HP_CLK_FREQ / (1 + bit);
  165 + if (iicck < 20000000)
  166 + break;
  167 + }
  168 +
  169 + if (bit > (1 << cdf_width)) {
  170 + puts("rcar-i2c: Can not get CDF\n");
  171 + return 0;
  172 + }
  173 +
  174 + if (i2c_no == 0)
  175 + intd = 50;
  176 +
  177 + f = (35 + 200 + intd) * (iicck / 1000000000);
  178 +
  179 + for (scgd = 0; scgd < 0x40; scgd++) {
  180 + scl = iicck / (20 + (scgd * 8) + f);
  181 + if (scl <= bus_speed)
  182 + break;
  183 + }
  184 +
  185 + if (scgd > 0x40) {
  186 + puts("rcar-i2c: Can not get SDGB\n");
  187 + return 0;
  188 + }
  189 +
  190 + debug("%s: scl: %d\n", __func__, scl);
  191 + debug("%s: bit %x\n", __func__, bit);
  192 + debug("%s: scgd %x\n", __func__, scgd);
  193 + debug("%s: iccr %x\n", __func__, (scgd << (cdf_width) | bit));
  194 +
  195 + return scgd << (cdf_width) | bit;
  196 +}
  197 +
  198 +static void
  199 +rcar_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
  200 +{
  201 + struct rcar_i2c *dev = (struct rcar_i2c *)i2c_dev[adap->hwadapnr];
  202 + u32 icccr = 0;
  203 +
  204 + /* No i2c support prior to relocation */
  205 + if (!(gd->flags & GD_FLG_RELOC))
  206 + return;
  207 +
  208 + /*
  209 + * reset slave mode.
  210 + * slave mode is not used on this driver
  211 + */
  212 + writel(0, &dev->icsier);
  213 + writel(0, &dev->icsar);
  214 + writel(0, &dev->icscr);
  215 + writel(0, &dev->icssr);
  216 +
  217 + /* reset master mode */
  218 + writel(0, &dev->icmier);
  219 + writel(0, &dev->icmcr);
  220 + writel(0, &dev->icmsr);
  221 + writel(0, &dev->icmar);
  222 +
  223 + icccr = rcar_clock_gen(adap->hwadapnr, adap->speed);
  224 + if (icccr == 0)
  225 + puts("I2C: Init failed\n");
  226 + else
  227 + writel(icccr, &dev->icccr);
  228 +}
  229 +
  230 +static int rcar_i2c_read(struct i2c_adapter *adap, uint8_t chip,
  231 + uint addr, int alen, u8 *data, int len)
  232 +{
  233 + struct rcar_i2c *dev = (struct rcar_i2c *)i2c_dev[adap->hwadapnr];
  234 + int i;
  235 +
  236 + for (i = 0; i < len; i++)
  237 + data[i] = rcar_i2c_raw_read(dev, chip, addr + i);
  238 +
  239 + return 0;
  240 +}
  241 +
  242 +static int rcar_i2c_write(struct i2c_adapter *adap, uint8_t chip, uint addr,
  243 + int alen, u8 *data, int len)
  244 +{
  245 + struct rcar_i2c *dev = (struct rcar_i2c *)i2c_dev[adap->hwadapnr];
  246 + return rcar_i2c_raw_write(dev, chip, addr, data, len);
  247 +}
  248 +
  249 +static int
  250 +rcar_i2c_probe(struct i2c_adapter *adap, u8 dev)
  251 +{
  252 + return rcar_i2c_read(adap, dev, 0, 0, NULL, 0);
  253 +}
  254 +
  255 +static unsigned int rcar_i2c_set_bus_speed(struct i2c_adapter *adap,
  256 + unsigned int speed)
  257 +{
  258 + struct rcar_i2c *dev = (struct rcar_i2c *)i2c_dev[adap->hwadapnr];
  259 + u32 icccr;
  260 + int ret = 0;
  261 +
  262 + rcar_i2c_raw_rw_finish(dev);
  263 +
  264 + icccr = rcar_clock_gen(adap->hwadapnr, speed);
  265 + if (icccr == 0) {
  266 + puts("I2C: Init failed\n");
  267 + ret = -1;
  268 + } else {
  269 + writel(icccr, &dev->icccr);
  270 + }
  271 + return ret;
  272 +}
  273 +
  274 +/*
  275 + * Register RCAR i2c adapters
  276 + */
  277 +U_BOOT_I2C_ADAP_COMPLETE(rcar_0, rcar_i2c_init, rcar_i2c_probe, rcar_i2c_read,
  278 + rcar_i2c_write, rcar_i2c_set_bus_speed,
  279 + CONFIG_SYS_RCAR_I2C0_SPEED, 0, 0)
  280 +U_BOOT_I2C_ADAP_COMPLETE(rcar_1, rcar_i2c_init, rcar_i2c_probe, rcar_i2c_read,
  281 + rcar_i2c_write, rcar_i2c_set_bus_speed,
  282 + CONFIG_SYS_RCAR_I2C1_SPEED, 0, 1)
  283 +U_BOOT_I2C_ADAP_COMPLETE(rcar_2, rcar_i2c_init, rcar_i2c_probe, rcar_i2c_read,
  284 + rcar_i2c_write, rcar_i2c_set_bus_speed,
  285 + CONFIG_SYS_RCAR_I2C2_SPEED, 0, 2)
  286 +U_BOOT_I2C_ADAP_COMPLETE(rcar_3, rcar_i2c_init, rcar_i2c_probe, rcar_i2c_read,
  287 + rcar_i2c_write, rcar_i2c_set_bus_speed,
  288 + CONFIG_SYS_RCAR_I2C3_SPEED, 0, 3)