[U-Boot] [PATCH 1/4] i2c: UniPhier: add driver for UniPhier i2c controller
Simon Glass
sjg at chromium.org
Sat Dec 27 18:32:38 CET 2014
Hi Masahiro,
On 25 December 2014 at 00:15, Masahiro Yamada <yamada.m at jp.panasonic.com> wrote:
> Simon, Heiko,
>
>
> If you have no objection to this series,
> I will apply it to u-boot-uniphier.
>
> Is this OK?
>
>
> Some replies below to Simon's comment.
>
>
>
> On Tue, 23 Dec 2014 12:54:53 -0700
> Simon Glass <sjg at chromium.org> wrote:
>
>
>> > +
>> > +#define IOBUS_FREQ 100000000
>> > +
>> > +struct uniphier_i2c_dev {
>> > + void __iomem *base; /* register base */
>>
>> U-Boot normally uses a struct for register access.
>
>
> IMHO, we can play it by ear.
>
> I notice two disadvantages of struct strategy.
>
> [1] we have to intert dummy registers where no register exist.
>
> For example, there is no register at offset address 0x8
> of fi2c controller.
>
> struct uniphier_fi2c_regs {
> u32 cr;
> u32 dttx;
> u32 __dummy; <-- necessary
> u32 slad;
That seems like a minor problem to me. A better term might be 'reserved'.
> ...
>
> [2] It is difficult to describe alias register name for the same address.
>
> For example,
>
> #define I2C_DTTX 0x04 /* send FIFO */
> #define I2C_DTRX 0x04 /* receive FIFO */
>
> DTTX is write-only register.
> DTRX is read-only register.
>
> They are assigned to the same address.
You could use fifo or rx_tx or data. Of even a #define if you can't avoid it.
There has been quite a bit of discussion about this U-Boot design
decision. I think Albert is the main expert.
>
>
>
>
>
>
>> > + unsigned long input_clk; /* master clock (Hz) */
>> > + unsigned long wait_us; /* wait for every byte transfer (us) */
>> > +};
>> > +
>> > +static int uniphier_i2c_probe(struct udevice *dev)
>> > +{
>> > + fdt_addr_t addr;
>> > + fdt_size_t size;
>> > + struct uniphier_i2c_dev *priv = dev_get_priv(dev);
>> > +
>> > + addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size);
>> > +
>> > + priv->base = map_sysmem(addr, size);
>> > +
>> > + if (!priv->base)
>> > + return -ENOMEM;
>> > +
>> > + priv->input_clk = IOBUS_FREQ;
>> > +
>> > + /* deassert reset */
>> > + writel(0x3, priv->base + I2C_BRST);
>> > +
>> > + return 0;
>> > +}
>> > +
>> > +static int uniphier_i2c_remove(struct udevice *dev)
>> > +{
>> > + struct uniphier_i2c_dev *priv = dev_get_priv(dev);
>> > +
>> > + unmap_sysmem(priv->base);
>> > +
>> > + return 0;
>> > +}
>> > +
>> > +static int uniphier_i2c_child_pre_probe(struct udevice *dev)
>> > +{
>> > + struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev);
>> > +
>> > + if (dev->of_offset == -1)
>> > + return 0;
>> > + return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
>> > + i2c_chip);
>> > +}
>> > +
>> > +static int send_and_recv_byte(struct uniphier_i2c_dev *dev, u32 dtrm)
>> > +{
>> > + writel(dtrm, dev->base + I2C_DTRM);
>> > +
>> > + /*
>> > + * U-Boot does not have a good support of interrupt.
>> > + * Wait for a while.
>> > + */
>> > + udelay(dev->wait_us);
>>
>> It might be possible to check a 'ready' bit in the hardware, but I
>> suppose this works and is simple for what sounds like old hardware.
>
>
> Unfortunately, there is no 'ready' bit in this I2C controller.
> This hardware expects intrruption is checked.
>
> It is true that we can check the GIC register of ARM processor,
> but I think it is too much for this driver.
OK.
>
>
>> > +static int uniphier_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
>> > +{
>> > + struct uniphier_i2c_dev *priv = dev_get_priv(bus);
>> > +
>> > + /* max supported frequency is 400 kHz */
>> > + if (speed > 400000)
>> > + return -EINVAL;
>> > +
>> > + /* bus reset: make sure the bus is idle when change the freqency */
>> > + writel(0x1, priv->base + I2C_BRST);
>> > +
>> > + writel((priv->input_clk / speed / 2 << 16) | (priv->input_clk / speed),
>> > + priv->base + I2C_CLK);
>> > +
>> > + writel(0x3, priv->base + I2C_BRST);
>> > +
>> > + priv->wait_us = 20000000 / speed;
>>
>> How is that calculated? Perhaps have a comment?
>
> OK, I will add some comments.
> No precise theory for this line. Rough calculation.
OK.
Regards,
Simon
More information about the U-Boot
mailing list