* [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c
@ 2015-12-28 17:47 Moritz Fischer
2015-12-28 17:47 ` [U-Boot] [RFC 1/2] i2c: Describe Cadence I2C devicetree bindings Moritz Fischer
` (3 more replies)
0 siblings, 4 replies; 15+ messages in thread
From: Moritz Fischer @ 2015-12-28 17:47 UTC (permalink / raw)
To: u-boot
Hi all,
I spent some time moving over the zynq-i2c.c to support dm.
While doing that I realized that renaming it to cdns-i2c might
make sense since it now could be used with other SoCs that also use the
the Cadence IP.
This is a first shot, but I'd like to get some early feedback ;-)
Cheers,
Moritz
PS: I skipped touching the Zynq board files for now, since I wanted to make sure
I get the driver right first ;-)
Moritz Fischer (2):
i2c: Describe Cadence I2C devicetree bindings
dm: i2c: Add driver for Cadence I2C IP
doc/device-tree-bindings/i2c/i2c-cdns.txt | 20 ++
drivers/i2c/Kconfig | 7 +
drivers/i2c/Makefile | 1 +
drivers/i2c/i2c-cdns.c | 339 ++++++++++++++++++++++++++++++
4 files changed, 367 insertions(+)
create mode 100644 doc/device-tree-bindings/i2c/i2c-cdns.txt
create mode 100644 drivers/i2c/i2c-cdns.c
--
2.4.3
^ permalink raw reply [flat|nested] 15+ messages in thread
* [U-Boot] [RFC 1/2] i2c: Describe Cadence I2C devicetree bindings
2015-12-28 17:47 [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c Moritz Fischer
@ 2015-12-28 17:47 ` Moritz Fischer
2016-01-04 7:09 ` Heiko Schocher
2015-12-28 17:47 ` [U-Boot] [RFC 2/2] dm: i2c: Add driver for Cadence I2C IP Moritz Fischer
` (2 subsequent siblings)
3 siblings, 1 reply; 15+ messages in thread
From: Moritz Fischer @ 2015-12-28 17:47 UTC (permalink / raw)
To: u-boot
Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
---
doc/device-tree-bindings/i2c/i2c-cdns.txt | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
create mode 100644 doc/device-tree-bindings/i2c/i2c-cdns.txt
diff --git a/doc/device-tree-bindings/i2c/i2c-cdns.txt b/doc/device-tree-bindings/i2c/i2c-cdns.txt
new file mode 100644
index 0000000..202e0b7
--- /dev/null
+++ b/doc/device-tree-bindings/i2c/i2c-cdns.txt
@@ -0,0 +1,20 @@
+Cadence I2C controller Device Tree Bindings
+-------------------------------------------
+
+Required properties:
+- compatible : Should be "cdns,i2c-r1p10" or "xlnx,zynq-spi-r1p10".
+- reg : Physical base address and size of I2C registers map.
+- interrupts : Property with a value describing the interrupt
+ number.
+- interrupt-parent : Must be core interrupt controller
+- clocks : Clock phandles (see clock bindings for details).
+
+Example:
+ i2c0: i2c at e0004000 {
+ compatible = "cdns,i2c-r1p10";
+ reg = <0xe0004000 0x1000>;
+ clocks = <&clkc 38>;
+ interrupts = <0 25 4>;
+ interrupt-parent = <&intc>;
+ status = "disabled";
+ };
--
2.4.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [U-Boot] [RFC 2/2] dm: i2c: Add driver for Cadence I2C IP
2015-12-28 17:47 [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c Moritz Fischer
2015-12-28 17:47 ` [U-Boot] [RFC 1/2] i2c: Describe Cadence I2C devicetree bindings Moritz Fischer
@ 2015-12-28 17:47 ` Moritz Fischer
2016-01-04 7:15 ` Heiko Schocher
2015-12-28 18:35 ` [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c Michal Simek
2016-01-05 15:44 ` Michal Simek
3 siblings, 1 reply; 15+ messages in thread
From: Moritz Fischer @ 2015-12-28 17:47 UTC (permalink / raw)
To: u-boot
This is a possible drop in replacement for drivers/i2c/zynq-i2c.c
Since this is cadence IP it has been renamed to cdns-i2c,
to make sense with the compatible string.
Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
---
drivers/i2c/Kconfig | 7 +
drivers/i2c/Makefile | 1 +
drivers/i2c/i2c-cdns.c | 339 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 347 insertions(+)
create mode 100644 drivers/i2c/i2c-cdns.c
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 14adda2..c058dc5 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -58,6 +58,13 @@ config DM_I2C_GPIO
bindings are supported.
Binding info: doc/device-tree-bindings/i2c/i2c-gpio.txt
+config SYS_I2C_CADENCE
+ tristate "Cadence I2C Controller"
+ depends on DM_I2C && (ARCH_ZYNQ || ARM64)
+ help
+ Say yes here to select Cadence I2C Host Controller. This controller is
+ e.g. used by Xilinx Zynq.
+
config SYS_I2C_ROCKCHIP
bool "Rockchip I2C driver"
depends on DM_I2C
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 811ad9b..35ad0d3 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o
obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o
obj-$(CONFIG_SYS_I2C) += i2c_core.o
+obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o
obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o
obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o
obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o
diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c
new file mode 100644
index 0000000..fab9609
--- /dev/null
+++ b/drivers/i2c/i2c-cdns.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2015 Moritz Fischer <moritz.fischer@ettus.com>
+ * IP from Cadence (ID T-CS-PE-0007-100, Version R1p10f2)
+ *
+ * This file is based on: drivers/i2c/zynq_i2c.c,
+ * with added driver-model support and code cleanup.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/types.h>
+#include <linux/io.h>
+#include <asm/errno.h>
+#include <dm/device.h>
+#include <dm/root.h>
+#include <i2c.h>
+#include <fdtdec.h>
+#include <mapmem.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* i2c register set */
+struct cdns_i2c_regs {
+ u32 control;
+ u32 status;
+ u32 address;
+ u32 data;
+ u32 interrupt_status;
+ u32 transfer_size;
+ u32 slave_mon_pause;
+ u32 time_out;
+ u32 interrupt_mask;
+ u32 interrupt_enable;
+ u32 interrupt_disable;
+};
+
+/* Control register fields */
+#define CDNS_I2C_CONTROL_RW 0x00000001
+#define CDNS_I2C_CONTROL_MS 0x00000002
+#define CDNS_I2C_CONTROL_NEA 0x00000004
+#define CDNS_I2C_CONTROL_ACKEN 0x00000008
+#define CDNS_I2C_CONTROL_HOLD 0x00000010
+#define CDNS_I2C_CONTROL_SLVMON 0x00000020
+#define CDNS_I2C_CONTROL_CLR_FIFO 0x00000040
+#define CDNS_I2C_CONTROL_DIV_B_SHIFT 8
+#define CDNS_I2C_CONTROL_DIV_B_MASK 0x00003F00
+#define CDNS_I2C_CONTROL_DIV_A_SHIFT 14
+#define CDNS_I2C_CONTROL_DIV_A_MASK 0x0000C000
+
+/* Status register values */
+#define CDNS_I2C_STATUS_RXDV 0x00000020
+#define CDNS_I2C_STATUS_TXDV 0x00000040
+#define CDNS_I2C_STATUS_RXOVF 0x00000080
+#define CDNS_I2C_STATUS_BA 0x00000100
+
+/* Interrupt register fields */
+#define CDNS_I2C_INTERRUPT_COMP 0x00000001
+#define CDNS_I2C_INTERRUPT_DATA 0x00000002
+#define CDNS_I2C_INTERRUPT_NACK 0x00000004
+#define CDNS_I2C_INTERRUPT_TO 0x00000008
+#define CDNS_I2C_INTERRUPT_SLVRDY 0x00000010
+#define CDNS_I2C_INTERRUPT_RXOVF 0x00000020
+#define CDNS_I2C_INTERRUPT_TXOVF 0x00000040
+#define CDNS_I2C_INTERRUPT_RXUNF 0x00000080
+#define CDNS_I2C_INTERRUPT_ARBLOST 0x00000200
+
+#define CDNS_I2C_FIFO_DEPTH 16
+#define CDNS_I2C_TRANSFER_SIZE_MAX 255 /* Controller transfer limit */
+
+#ifdef DEBUG
+static void cdns_i2c_debug_status(struct cdns_i2c_regs *cdns_i2c)
+{
+ int int_status;
+ int status;
+ int_status = readl(&cdns_i2c->interrupt_status);
+
+ status = readl(&cdns_i2c->status);
+ if (int_status || status) {
+ debug("Status: ");
+ if (int_status & CDNS_I2C_INTERRUPT_COMP)
+ debug("COMP ");
+ if (int_status & CDNS_I2C_INTERRUPT_DATA)
+ debug("DATA ");
+ if (int_status & CDNS_I2C_INTERRUPT_NACK)
+ debug("NACK ");
+ if (int_status & CDNS_I2C_INTERRUPT_TO)
+ debug("TO ");
+ if (int_status & CDNS_I2C_INTERRUPT_SLVRDY)
+ debug("SLVRDY ");
+ if (int_status & CDNS_I2C_INTERRUPT_RXOVF)
+ debug("RXOVF ");
+ if (int_status & CDNS_I2C_INTERRUPT_TXOVF)
+ debug("TXOVF ");
+ if (int_status & CDNS_I2C_INTERRUPT_RXUNF)
+ debug("RXUNF ");
+ if (int_status & CDNS_I2C_INTERRUPT_ARBLOST)
+ debug("ARBLOST ");
+ if (status & CDNS_I2C_STATUS_RXDV)
+ debug("RXDV ");
+ if (status & CDNS_I2C_STATUS_TXDV)
+ debug("TXDV ");
+ if (status & CDNS_I2C_STATUS_RXOVF)
+ debug("RXOVF ");
+ if (status & CDNS_I2C_STATUS_BA)
+ debug("BA ");
+ debug("TS%d ", readl(&cdns_i2c->transfer_size));
+ debug("\n");
+ }
+}
+#endif
+
+struct i2c_cdns_bus {
+ int id;
+ struct cdns_i2c_regs __iomem *regs; /* register base */
+};
+
+
+/** cdns_i2c_probe() - Probe method
+ * @dev: udevice pointer
+ *
+ * DM callback called when device is probed
+ */
+static int cdns_i2c_probe(struct udevice *dev)
+{
+ struct i2c_cdns_bus *bus = dev_get_priv(dev);
+ fdt_addr_t addr;
+ fdt_size_t size;
+
+ addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size);
+ bus->regs = map_sysmem(addr, size);
+
+ if (!bus->regs)
+ return -ENOMEM;
+
+ /* TODO: Calculate dividers based on CPU_CLK_1X */
+ /* 111MHz / ( (3 * 17) * 22 ) = ~100KHz */
+ writel((16 << CDNS_I2C_CONTROL_DIV_B_SHIFT) |
+ (2 << CDNS_I2C_CONTROL_DIV_A_SHIFT), &bus->regs->control);
+
+ /* Enable master mode, ack, and 7-bit addressing */
+ setbits_le32(&bus->regs->control, CDNS_I2C_CONTROL_MS |
+ CDNS_I2C_CONTROL_ACKEN | CDNS_I2C_CONTROL_NEA);
+
+ debug("%s bus %d at %p\n", __func__, dev->seq, bus->regs);
+
+ return 0;
+}
+
+static int cdns_i2c_remove(struct udevice *dev)
+{
+ struct i2c_cdns_bus *bus = dev_get_priv(dev);
+
+ debug("%s bus %d at %p\n", __func__, dev->seq, bus->regs);
+
+ unmap_sysmem(bus->regs);
+
+ return 0;
+}
+
+/* Wait for an interrupt */
+static u32 cdns_i2c_wait(struct cdns_i2c_regs *cdns_i2c, u32 mask)
+{
+ int timeout, int_status;
+
+ for (timeout = 0; timeout < 100; timeout++) {
+ udelay(100);
+ int_status = readl(&cdns_i2c->interrupt_status);
+ if (int_status & mask)
+ break;
+ }
+
+ /* Clear interrupt status flags */
+ writel(int_status & mask, &cdns_i2c->interrupt_status);
+
+ return int_status & mask;
+}
+
+static int cdns_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
+{
+ if (speed != 100000) {
+ printf("%s, failed to set clock speed to %u\n", __func__,
+ speed);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* Probe to see if a chip is present. */
+static int cdns_i2c_probe_chip(struct udevice *bus, uint chip_addr,
+ uint chip_flags)
+{
+ struct i2c_cdns_bus *i2c_bus = dev_get_priv(bus);
+ struct cdns_i2c_regs *regs = i2c_bus->regs;
+
+ /* Attempt to read a byte */
+ setbits_le32(®s->control, CDNS_I2C_CONTROL_CLR_FIFO |
+ CDNS_I2C_CONTROL_RW);
+ clrbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD);
+ writel(0xFF, ®s->interrupt_status);
+ writel(chip_addr, ®s->address);
+ writel(1, ®s->transfer_size);
+
+ return (cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP |
+ CDNS_I2C_INTERRUPT_NACK) &
+ CDNS_I2C_INTERRUPT_COMP) ? 0 : -ETIMEDOUT;
+}
+
+static int cdns_i2c_write_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data,
+ u32 len, bool next_is_read)
+{
+ u8 *cur_data = data;
+
+ struct cdns_i2c_regs *regs = i2c_bus->regs;
+
+ setbits_le32(®s->control, CDNS_I2C_CONTROL_CLR_FIFO |
+ CDNS_I2C_CONTROL_HOLD);
+
+ /* if next is a read, we need to clear HOLD, doesn't work */
+ if (next_is_read)
+ clrbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD);
+
+ clrbits_le32(®s->control, CDNS_I2C_CONTROL_RW);
+
+ writel(0xFF, ®s->interrupt_status);
+ writel(addr, ®s->address);
+
+ while (len--) {
+ writel(*(cur_data++), ®s->data);
+ if (readl(®s->transfer_size) == CDNS_I2C_FIFO_DEPTH) {
+ if (!cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP)) {
+ /* Release the bus */
+ clrbits_le32(®s->control,
+ CDNS_I2C_CONTROL_HOLD);
+ return -ETIMEDOUT;
+ }
+ }
+ }
+
+ /* All done... release the bus */
+ clrbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD);
+ /* Wait for the address and data to be sent */
+ if (!cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP))
+ return -ETIMEDOUT;
+ return 0;
+}
+
+static int cdns_i2c_read_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data,
+ u32 len)
+{
+ u32 status;
+ u32 i = 0;
+ u8 *cur_data = data;
+
+ /* TODO: Fix this */
+ struct cdns_i2c_regs *regs = i2c_bus->regs;
+
+ /* Check the hardware can handle the requested bytes */
+ if ((len < 0) || (len > CDNS_I2C_TRANSFER_SIZE_MAX))
+ return -EINVAL;
+
+ setbits_le32(®s->control, CDNS_I2C_CONTROL_CLR_FIFO |
+ CDNS_I2C_CONTROL_RW);
+
+ /* Start reading data */
+ writel(addr, ®s->address);
+ writel(len, ®s->transfer_size);
+
+ /* Wait for data */
+ do {
+ status = cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP |
+ CDNS_I2C_INTERRUPT_DATA);
+ if (!status) {
+ /* Release the bus */
+ clrbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD);
+ return -ETIMEDOUT;
+ }
+ debug("Read %d bytes\n",
+ len - readl(®s->transfer_size));
+ for (; i < len - readl(®s->transfer_size); i++)
+ *(cur_data++) = readl(®s->data);
+ } while (readl(®s->transfer_size) != 0);
+ /* All done... release the bus */
+ clrbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD);
+
+#ifdef DEBUG
+ cdns_i2c_debug_status(regs);
+#endif
+ return 0;
+}
+
+static int cdns_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
+ int nmsgs)
+{
+ struct i2c_cdns_bus *i2c_bus = dev_get_priv(dev);
+ int ret;
+
+ debug("i2c_xfer: %d messages\n", nmsgs);
+ for (; nmsgs > 0; nmsgs--, msg++) {
+ bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD);
+
+ debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
+ if (msg->flags & I2C_M_RD) {
+ ret = cdns_i2c_read_data(i2c_bus, msg->addr, msg->buf,
+ msg->len);
+ } else {
+ ret = cdns_i2c_write_data(i2c_bus, msg->addr, msg->buf,
+ msg->len, next_is_read);
+ }
+ if (ret) {
+ debug("i2c_write: error sending\n");
+ return -EREMOTEIO;
+ }
+ }
+
+ return 0;
+}
+
+static const struct dm_i2c_ops cdns_i2c_ops = {
+ .xfer = cdns_i2c_xfer,
+ .probe_chip = cdns_i2c_probe_chip,
+ .set_bus_speed = cdns_i2c_set_bus_speed,
+};
+
+static const struct udevice_id cdns_i2c_of_match[] = {
+ { .compatible = "cdns,i2c-r1p10" },
+ { /* end of table */ }
+};
+
+U_BOOT_DRIVER(cdns_i2c) = {
+ .name = "i2c-cdns",
+ .id = UCLASS_I2C,
+ .of_match = cdns_i2c_of_match,
+ .probe = cdns_i2c_probe,
+ .remove = cdns_i2c_remove,
+ .priv_auto_alloc_size = sizeof(struct i2c_cdns_bus),
+ .ops = &cdns_i2c_ops,
+};
--
2.4.3
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c
2015-12-28 17:47 [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c Moritz Fischer
2015-12-28 17:47 ` [U-Boot] [RFC 1/2] i2c: Describe Cadence I2C devicetree bindings Moritz Fischer
2015-12-28 17:47 ` [U-Boot] [RFC 2/2] dm: i2c: Add driver for Cadence I2C IP Moritz Fischer
@ 2015-12-28 18:35 ` Michal Simek
2015-12-28 19:15 ` Moritz Fischer
2016-01-05 15:44 ` Michal Simek
3 siblings, 1 reply; 15+ messages in thread
From: Michal Simek @ 2015-12-28 18:35 UTC (permalink / raw)
To: u-boot
Hi,
2015-12-28 18:47 GMT+01:00 Moritz Fischer <moritz.fischer@ettus.com>:
> Hi all,
>
> I spent some time moving over the zynq-i2c.c to support dm.
>
ok then where is the series for converting orgin driver to this DM one?
> While doing that I realized that renaming it to cdns-i2c might
> make sense since it now could be used with other SoCs that also use the
> the Cadence IP.
>
No problem with renaming but I would like to see change from origin driver
to this new one
instead of just adding completely new one and keeping old one there.
> This is a first shot, but I'd like to get some early feedback ;-)
>
I will look at it and test it in January.
Thanks,
Michal
^ permalink raw reply [flat|nested] 15+ messages in thread
* [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c
2015-12-28 18:35 ` [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c Michal Simek
@ 2015-12-28 19:15 ` Moritz Fischer
0 siblings, 0 replies; 15+ messages in thread
From: Moritz Fischer @ 2015-12-28 19:15 UTC (permalink / raw)
To: u-boot
Hi Michal,
On Mon, Dec 28, 2015 at 10:35 AM, Michal Simek <monstr@monstr.eu> wrote:
> ok then where is the series for converting orgin driver to this DM one?
Umhh, well it would look like:
$ git rm drivers/i2c/zynq-i2c.c
$ git add drivers/i2c/i2c-cdns.c
Do you want me to add that to the v1?
> No problem with renaming but I would like to see change from origin driver
> to this new one
> instead of just adding completely new one and keeping old one there.
See above. To clarify you mean I should also add the edits to convert the actual
zynq boards over? I need to take a look which ones actually use i2c.
> I will look at it and test it in January.
Thanks.
Cheers,
Moritz
^ permalink raw reply [flat|nested] 15+ messages in thread
* [U-Boot] [RFC 1/2] i2c: Describe Cadence I2C devicetree bindings
2015-12-28 17:47 ` [U-Boot] [RFC 1/2] i2c: Describe Cadence I2C devicetree bindings Moritz Fischer
@ 2016-01-04 7:09 ` Heiko Schocher
0 siblings, 0 replies; 15+ messages in thread
From: Heiko Schocher @ 2016-01-04 7:09 UTC (permalink / raw)
To: u-boot
Hello Moritz,
Am 28.12.2015 um 18:47 schrieb Moritz Fischer:
> Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
> ---
> doc/device-tree-bindings/i2c/i2c-cdns.txt | 20 ++++++++++++++++++++
> 1 file changed, 20 insertions(+)
> create mode 100644 doc/device-tree-bindings/i2c/i2c-cdns.txt
Looks good to me:
Acked-by: Heiko Schocher <hs@denx.de>
bye,
Heiko
>
> diff --git a/doc/device-tree-bindings/i2c/i2c-cdns.txt b/doc/device-tree-bindings/i2c/i2c-cdns.txt
> new file mode 100644
> index 0000000..202e0b7
> --- /dev/null
> +++ b/doc/device-tree-bindings/i2c/i2c-cdns.txt
> @@ -0,0 +1,20 @@
> +Cadence I2C controller Device Tree Bindings
> +-------------------------------------------
> +
> +Required properties:
> +- compatible : Should be "cdns,i2c-r1p10" or "xlnx,zynq-spi-r1p10".
> +- reg : Physical base address and size of I2C registers map.
> +- interrupts : Property with a value describing the interrupt
> + number.
> +- interrupt-parent : Must be core interrupt controller
> +- clocks : Clock phandles (see clock bindings for details).
> +
> +Example:
> + i2c0: i2c at e0004000 {
> + compatible = "cdns,i2c-r1p10";
> + reg = <0xe0004000 0x1000>;
> + clocks = <&clkc 38>;
> + interrupts = <0 25 4>;
> + interrupt-parent = <&intc>;
> + status = "disabled";
> + };
>
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply [flat|nested] 15+ messages in thread
* [U-Boot] [RFC 2/2] dm: i2c: Add driver for Cadence I2C IP
2015-12-28 17:47 ` [U-Boot] [RFC 2/2] dm: i2c: Add driver for Cadence I2C IP Moritz Fischer
@ 2016-01-04 7:15 ` Heiko Schocher
2016-04-11 12:50 ` Michal Simek
0 siblings, 1 reply; 15+ messages in thread
From: Heiko Schocher @ 2016-01-04 7:15 UTC (permalink / raw)
To: u-boot
Hello Moritz,
Am 28.12.2015 um 18:47 schrieb Moritz Fischer:
> This is a possible drop in replacement for drivers/i2c/zynq-i2c.c
>
> Since this is cadence IP it has been renamed to cdns-i2c,
> to make sense with the compatible string.
>
> Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
> ---
> drivers/i2c/Kconfig | 7 +
> drivers/i2c/Makefile | 1 +
> drivers/i2c/i2c-cdns.c | 339 +++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 347 insertions(+)
> create mode 100644 drivers/i2c/i2c-cdns.c
Hmm.. I di not see the remove of "drivers/i2c/zynq-i2c.c" as
you wrote it is a replacement for it ... Can you do this, and
of course adapt the boards which use this driver?
> diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
> index 14adda2..c058dc5 100644
> --- a/drivers/i2c/Kconfig
> +++ b/drivers/i2c/Kconfig
> @@ -58,6 +58,13 @@ config DM_I2C_GPIO
> bindings are supported.
> Binding info: doc/device-tree-bindings/i2c/i2c-gpio.txt
>
> +config SYS_I2C_CADENCE
> + tristate "Cadence I2C Controller"
> + depends on DM_I2C && (ARCH_ZYNQ || ARM64)
> + help
> + Say yes here to select Cadence I2C Host Controller. This controller is
> + e.g. used by Xilinx Zynq.
> +
> config SYS_I2C_ROCKCHIP
> bool "Rockchip I2C driver"
> depends on DM_I2C
> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
> index 811ad9b..35ad0d3 100644
> --- a/drivers/i2c/Makefile
> +++ b/drivers/i2c/Makefile
> @@ -16,6 +16,7 @@ obj-$(CONFIG_PCA9564_I2C) += pca9564_i2c.o
> obj-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
> obj-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o
> obj-$(CONFIG_SYS_I2C) += i2c_core.o
> +obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o
> obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o
> obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o
> obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o
> diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c
> new file mode 100644
> index 0000000..fab9609
> --- /dev/null
> +++ b/drivers/i2c/i2c-cdns.c
> @@ -0,0 +1,339 @@
> +/*
> + * Copyright (C) 2015 Moritz Fischer <moritz.fischer@ettus.com>
> + * IP from Cadence (ID T-CS-PE-0007-100, Version R1p10f2)
> + *
> + * This file is based on: drivers/i2c/zynq_i2c.c,
> + * with added driver-model support and code cleanup.
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <linux/types.h>
> +#include <linux/io.h>
> +#include <asm/errno.h>
> +#include <dm/device.h>
> +#include <dm/root.h>
> +#include <i2c.h>
> +#include <fdtdec.h>
> +#include <mapmem.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/* i2c register set */
> +struct cdns_i2c_regs {
> + u32 control;
> + u32 status;
> + u32 address;
> + u32 data;
> + u32 interrupt_status;
> + u32 transfer_size;
> + u32 slave_mon_pause;
> + u32 time_out;
> + u32 interrupt_mask;
> + u32 interrupt_enable;
> + u32 interrupt_disable;
> +};
> +
> +/* Control register fields */
> +#define CDNS_I2C_CONTROL_RW 0x00000001
> +#define CDNS_I2C_CONTROL_MS 0x00000002
> +#define CDNS_I2C_CONTROL_NEA 0x00000004
> +#define CDNS_I2C_CONTROL_ACKEN 0x00000008
> +#define CDNS_I2C_CONTROL_HOLD 0x00000010
> +#define CDNS_I2C_CONTROL_SLVMON 0x00000020
> +#define CDNS_I2C_CONTROL_CLR_FIFO 0x00000040
> +#define CDNS_I2C_CONTROL_DIV_B_SHIFT 8
> +#define CDNS_I2C_CONTROL_DIV_B_MASK 0x00003F00
> +#define CDNS_I2C_CONTROL_DIV_A_SHIFT 14
> +#define CDNS_I2C_CONTROL_DIV_A_MASK 0x0000C000
> +
> +/* Status register values */
> +#define CDNS_I2C_STATUS_RXDV 0x00000020
> +#define CDNS_I2C_STATUS_TXDV 0x00000040
> +#define CDNS_I2C_STATUS_RXOVF 0x00000080
> +#define CDNS_I2C_STATUS_BA 0x00000100
> +
> +/* Interrupt register fields */
> +#define CDNS_I2C_INTERRUPT_COMP 0x00000001
> +#define CDNS_I2C_INTERRUPT_DATA 0x00000002
> +#define CDNS_I2C_INTERRUPT_NACK 0x00000004
> +#define CDNS_I2C_INTERRUPT_TO 0x00000008
> +#define CDNS_I2C_INTERRUPT_SLVRDY 0x00000010
> +#define CDNS_I2C_INTERRUPT_RXOVF 0x00000020
> +#define CDNS_I2C_INTERRUPT_TXOVF 0x00000040
> +#define CDNS_I2C_INTERRUPT_RXUNF 0x00000080
> +#define CDNS_I2C_INTERRUPT_ARBLOST 0x00000200
> +
> +#define CDNS_I2C_FIFO_DEPTH 16
> +#define CDNS_I2C_TRANSFER_SIZE_MAX 255 /* Controller transfer limit */
> +
> +#ifdef DEBUG
> +static void cdns_i2c_debug_status(struct cdns_i2c_regs *cdns_i2c)
> +{
> + int int_status;
> + int status;
> + int_status = readl(&cdns_i2c->interrupt_status);
> +
> + status = readl(&cdns_i2c->status);
> + if (int_status || status) {
> + debug("Status: ");
> + if (int_status & CDNS_I2C_INTERRUPT_COMP)
> + debug("COMP ");
> + if (int_status & CDNS_I2C_INTERRUPT_DATA)
> + debug("DATA ");
> + if (int_status & CDNS_I2C_INTERRUPT_NACK)
> + debug("NACK ");
> + if (int_status & CDNS_I2C_INTERRUPT_TO)
> + debug("TO ");
> + if (int_status & CDNS_I2C_INTERRUPT_SLVRDY)
> + debug("SLVRDY ");
> + if (int_status & CDNS_I2C_INTERRUPT_RXOVF)
> + debug("RXOVF ");
> + if (int_status & CDNS_I2C_INTERRUPT_TXOVF)
> + debug("TXOVF ");
> + if (int_status & CDNS_I2C_INTERRUPT_RXUNF)
> + debug("RXUNF ");
> + if (int_status & CDNS_I2C_INTERRUPT_ARBLOST)
> + debug("ARBLOST ");
> + if (status & CDNS_I2C_STATUS_RXDV)
> + debug("RXDV ");
> + if (status & CDNS_I2C_STATUS_TXDV)
> + debug("TXDV ");
> + if (status & CDNS_I2C_STATUS_RXOVF)
> + debug("RXOVF ");
> + if (status & CDNS_I2C_STATUS_BA)
> + debug("BA ");
> + debug("TS%d ", readl(&cdns_i2c->transfer_size));
> + debug("\n");
> + }
> +}
> +#endif
> +
> +struct i2c_cdns_bus {
> + int id;
> + struct cdns_i2c_regs __iomem *regs; /* register base */
> +};
> +
> +
> +/** cdns_i2c_probe() - Probe method
> + * @dev: udevice pointer
> + *
> + * DM callback called when device is probed
> + */
> +static int cdns_i2c_probe(struct udevice *dev)
> +{
> + struct i2c_cdns_bus *bus = dev_get_priv(dev);
> + fdt_addr_t addr;
> + fdt_size_t size;
> +
> + addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size);
> + bus->regs = map_sysmem(addr, size);
> +
> + if (!bus->regs)
> + return -ENOMEM;
> +
> + /* TODO: Calculate dividers based on CPU_CLK_1X */
> + /* 111MHz / ( (3 * 17) * 22 ) = ~100KHz */
> + writel((16 << CDNS_I2C_CONTROL_DIV_B_SHIFT) |
> + (2 << CDNS_I2C_CONTROL_DIV_A_SHIFT), &bus->regs->control);
We really need a clk framework ...
> +
> + /* Enable master mode, ack, and 7-bit addressing */
> + setbits_le32(&bus->regs->control, CDNS_I2C_CONTROL_MS |
> + CDNS_I2C_CONTROL_ACKEN | CDNS_I2C_CONTROL_NEA);
> +
> + debug("%s bus %d at %p\n", __func__, dev->seq, bus->regs);
> +
> + return 0;
> +}
> +
> +static int cdns_i2c_remove(struct udevice *dev)
> +{
> + struct i2c_cdns_bus *bus = dev_get_priv(dev);
> +
> + debug("%s bus %d at %p\n", __func__, dev->seq, bus->regs);
> +
> + unmap_sysmem(bus->regs);
> +
> + return 0;
> +}
> +
> +/* Wait for an interrupt */
> +static u32 cdns_i2c_wait(struct cdns_i2c_regs *cdns_i2c, u32 mask)
> +{
> + int timeout, int_status;
> +
> + for (timeout = 0; timeout < 100; timeout++) {
> + udelay(100);
> + int_status = readl(&cdns_i2c->interrupt_status);
> + if (int_status & mask)
> + break;
> + }
> +
> + /* Clear interrupt status flags */
> + writel(int_status & mask, &cdns_i2c->interrupt_status);
> +
> + return int_status & mask;
> +}
> +
> +static int cdns_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
> +{
> + if (speed != 100000) {
> + printf("%s, failed to set clock speed to %u\n", __func__,
> + speed);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +/* Probe to see if a chip is present. */
> +static int cdns_i2c_probe_chip(struct udevice *bus, uint chip_addr,
> + uint chip_flags)
> +{
> + struct i2c_cdns_bus *i2c_bus = dev_get_priv(bus);
> + struct cdns_i2c_regs *regs = i2c_bus->regs;
> +
> + /* Attempt to read a byte */
> + setbits_le32(®s->control, CDNS_I2C_CONTROL_CLR_FIFO |
> + CDNS_I2C_CONTROL_RW);
> + clrbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD);
> + writel(0xFF, ®s->interrupt_status);
> + writel(chip_addr, ®s->address);
> + writel(1, ®s->transfer_size);
> +
> + return (cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP |
> + CDNS_I2C_INTERRUPT_NACK) &
> + CDNS_I2C_INTERRUPT_COMP) ? 0 : -ETIMEDOUT;
> +}
> +
> +static int cdns_i2c_write_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data,
> + u32 len, bool next_is_read)
> +{
> + u8 *cur_data = data;
> +
> + struct cdns_i2c_regs *regs = i2c_bus->regs;
> +
> + setbits_le32(®s->control, CDNS_I2C_CONTROL_CLR_FIFO |
> + CDNS_I2C_CONTROL_HOLD);
> +
> + /* if next is a read, we need to clear HOLD, doesn't work */
> + if (next_is_read)
> + clrbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD);
> +
> + clrbits_le32(®s->control, CDNS_I2C_CONTROL_RW);
> +
> + writel(0xFF, ®s->interrupt_status);
> + writel(addr, ®s->address);
> +
> + while (len--) {
> + writel(*(cur_data++), ®s->data);
> + if (readl(®s->transfer_size) == CDNS_I2C_FIFO_DEPTH) {
> + if (!cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP)) {
> + /* Release the bus */
> + clrbits_le32(®s->control,
> + CDNS_I2C_CONTROL_HOLD);
> + return -ETIMEDOUT;
> + }
> + }
> + }
> +
> + /* All done... release the bus */
> + clrbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD);
> + /* Wait for the address and data to be sent */
> + if (!cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP))
> + return -ETIMEDOUT;
> + return 0;
> +}
> +
> +static int cdns_i2c_read_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data,
> + u32 len)
> +{
> + u32 status;
> + u32 i = 0;
> + u8 *cur_data = data;
> +
> + /* TODO: Fix this */
> + struct cdns_i2c_regs *regs = i2c_bus->regs;
> +
> + /* Check the hardware can handle the requested bytes */
> + if ((len < 0) || (len > CDNS_I2C_TRANSFER_SIZE_MAX))
> + return -EINVAL;
> +
> + setbits_le32(®s->control, CDNS_I2C_CONTROL_CLR_FIFO |
> + CDNS_I2C_CONTROL_RW);
> +
> + /* Start reading data */
> + writel(addr, ®s->address);
> + writel(len, ®s->transfer_size);
> +
> + /* Wait for data */
> + do {
> + status = cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP |
> + CDNS_I2C_INTERRUPT_DATA);
> + if (!status) {
> + /* Release the bus */
> + clrbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD);
> + return -ETIMEDOUT;
> + }
> + debug("Read %d bytes\n",
> + len - readl(®s->transfer_size));
> + for (; i < len - readl(®s->transfer_size); i++)
> + *(cur_data++) = readl(®s->data);
> + } while (readl(®s->transfer_size) != 0);
> + /* All done... release the bus */
> + clrbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD);
> +
> +#ifdef DEBUG
> + cdns_i2c_debug_status(regs);
> +#endif
> + return 0;
> +}
> +
> +static int cdns_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
> + int nmsgs)
> +{
> + struct i2c_cdns_bus *i2c_bus = dev_get_priv(dev);
> + int ret;
> +
> + debug("i2c_xfer: %d messages\n", nmsgs);
> + for (; nmsgs > 0; nmsgs--, msg++) {
> + bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD);
> +
> + debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
> + if (msg->flags & I2C_M_RD) {
> + ret = cdns_i2c_read_data(i2c_bus, msg->addr, msg->buf,
> + msg->len);
> + } else {
> + ret = cdns_i2c_write_data(i2c_bus, msg->addr, msg->buf,
> + msg->len, next_is_read);
> + }
> + if (ret) {
> + debug("i2c_write: error sending\n");
> + return -EREMOTEIO;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static const struct dm_i2c_ops cdns_i2c_ops = {
> + .xfer = cdns_i2c_xfer,
> + .probe_chip = cdns_i2c_probe_chip,
> + .set_bus_speed = cdns_i2c_set_bus_speed,
> +};
> +
> +static const struct udevice_id cdns_i2c_of_match[] = {
> + { .compatible = "cdns,i2c-r1p10" },
> + { /* end of table */ }
> +};
> +
> +U_BOOT_DRIVER(cdns_i2c) = {
> + .name = "i2c-cdns",
> + .id = UCLASS_I2C,
> + .of_match = cdns_i2c_of_match,
> + .probe = cdns_i2c_probe,
> + .remove = cdns_i2c_remove,
> + .priv_auto_alloc_size = sizeof(struct i2c_cdns_bus),
> + .ops = &cdns_i2c_ops,
> +};
>
Looks good to me, but I cannot test it ...
bye,
Heiko
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply [flat|nested] 15+ messages in thread
* [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c
2015-12-28 17:47 [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c Moritz Fischer
` (2 preceding siblings ...)
2015-12-28 18:35 ` [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c Michal Simek
@ 2016-01-05 15:44 ` Michal Simek
2016-01-05 17:30 ` Moritz Fischer
3 siblings, 1 reply; 15+ messages in thread
From: Michal Simek @ 2016-01-05 15:44 UTC (permalink / raw)
To: u-boot
On 28.12.2015 18:47, Moritz Fischer wrote:
> Hi all,
>
> I spent some time moving over the zynq-i2c.c to support dm.
> While doing that I realized that renaming it to cdns-i2c might
> make sense since it now could be used with other SoCs that also use the
> the Cadence IP.
>
> This is a first shot, but I'd like to get some early feedback ;-)
>
> Cheers,
>
> Moritz
>
> PS: I skipped touching the Zynq board files for now, since I wanted to make sure
> I get the driver right first ;-)
>
> Moritz Fischer (2):
> i2c: Describe Cadence I2C devicetree bindings
> dm: i2c: Add driver for Cadence I2C IP
>
> doc/device-tree-bindings/i2c/i2c-cdns.txt | 20 ++
> drivers/i2c/Kconfig | 7 +
> drivers/i2c/Makefile | 1 +
> drivers/i2c/i2c-cdns.c | 339 ++++++++++++++++++++++++++++++
> 4 files changed, 367 insertions(+)
> create mode 100644 doc/device-tree-bindings/i2c/i2c-cdns.txt
> create mode 100644 drivers/i2c/i2c-cdns.c
>
I have looked at these patches and I don't know why there is 100k
limitation in cdns_i2c_set_bus_speed. DTS is using 400k in Linux without
any problem.
Unfortunately I found that i2c muxes like pca9548 are not supported yet
but I have create sort of skeleton for that but it looks like that there
is no standard binding where i2c-parent is required. Also every muxes
bus needs to have correct label and alias.
Also I have found that there is eeprom dependency which needs to be
resolved to be able to use this driver instead of old one.
Thanks,
Michal
^ permalink raw reply [flat|nested] 15+ messages in thread
* [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c
2016-01-05 15:44 ` Michal Simek
@ 2016-01-05 17:30 ` Moritz Fischer
2016-01-06 7:53 ` Michal Simek
0 siblings, 1 reply; 15+ messages in thread
From: Moritz Fischer @ 2016-01-05 17:30 UTC (permalink / raw)
To: u-boot
Hi Michal,
On Tue, Jan 5, 2016 at 7:44 AM, Michal Simek <michal.simek@xilinx.com> wrote:
> I have looked at these patches and I don't know why there is 100k
> limitation in cdns_i2c_set_bus_speed. DTS is using 400k in Linux without
> any problem.
Well I could statically calculate the values for 400K, too but anyway that works
only if your CPU_CLK_1X is 111MHz. Is there a way to figure out the CPU_CLK_1X
frequency?
> Unfortunately I found that i2c muxes like pca9548 are not supported yet
> but I have create sort of skeleton for that but it looks like that there
> is no standard binding where i2c-parent is required. Also every muxes
> bus needs to have correct label and alias.
Yeah, I realized that last night when I started playing around with
it. I was trying
to pull in the linux one but didn't get around to finish that yet.
> Also I have found that there is eeprom dependency which needs to be
> resolved to be able to use this driver instead of old one.
Yeah I realized that. Do any of the zynq boards actually use CMD_EEPROM?
Thanks for you feedback,
Moritz
^ permalink raw reply [flat|nested] 15+ messages in thread
* [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c
2016-01-05 17:30 ` Moritz Fischer
@ 2016-01-06 7:53 ` Michal Simek
2016-01-07 5:18 ` Moritz Fischer
0 siblings, 1 reply; 15+ messages in thread
From: Michal Simek @ 2016-01-06 7:53 UTC (permalink / raw)
To: u-boot
On 5.1.2016 18:30, Moritz Fischer wrote:
> Hi Michal,
>
> On Tue, Jan 5, 2016 at 7:44 AM, Michal Simek <michal.simek@xilinx.com> wrote:
>
>> I have looked at these patches and I don't know why there is 100k
>> limitation in cdns_i2c_set_bus_speed. DTS is using 400k in Linux without
>> any problem.
>
> Well I could statically calculate the values for 400K, too but anyway that works
> only if your CPU_CLK_1X is 111MHz. Is there a way to figure out the CPU_CLK_1X
> frequency?
Check the clock driver.
>> Unfortunately I found that i2c muxes like pca9548 are not supported yet
>> but I have create sort of skeleton for that but it looks like that there
>> is no standard binding where i2c-parent is required. Also every muxes
>> bus needs to have correct label and alias.
>
> Yeah, I realized that last night when I started playing around with
> it. I was trying
> to pull in the linux one but didn't get around to finish that yet.
It is simple to create that mux drivers but I am scared about that need
for aliases and also i2c-parent has to go out of mux class too.
I see that it is used in the mainline kernel but it has be changed.
>> Also I have found that there is eeprom dependency which needs to be
>> resolved to be able to use this driver instead of old one.
>
> Yeah I realized that. Do any of the zynq boards actually use CMD_EEPROM?
We have a code for zc702 to save internal variables to EEPROM. zc706
should have that memory too.
Thanks,
Michal
^ permalink raw reply [flat|nested] 15+ messages in thread
* [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c
2016-01-06 7:53 ` Michal Simek
@ 2016-01-07 5:18 ` Moritz Fischer
2016-01-07 8:13 ` Michal Simek
0 siblings, 1 reply; 15+ messages in thread
From: Moritz Fischer @ 2016-01-07 5:18 UTC (permalink / raw)
To: u-boot
On Tue, Jan 5, 2016 at 11:53 PM, Michal Simek <michal.simek@xilinx.com> wrote:
> On 5.1.2016 18:30, Moritz Fischer wrote:
>> Hi Michal,
>>
>> On Tue, Jan 5, 2016 at 7:44 AM, Michal Simek <michal.simek@xilinx.com> wrote:
>>
>>> I have looked at these patches and I don't know why there is 100k
>>> limitation in cdns_i2c_set_bus_speed. DTS is using 400k in Linux without
>>> any problem.
>>
>> Well I could statically calculate the values for 400K, too but anyway that works
>> only if your CPU_CLK_1X is 111MHz. Is there a way to figure out the CPU_CLK_1X
>> frequency?
>
> Check the clock driver.
Wouldn't that nececitate dm capable clk drivers? Were you talking about
arch/arm/mach-zynq/clk.c?
> It is simple to create that mux drivers but I am scared about that need
> for aliases and also i2c-parent has to go out of mux class too.
> I see that it is used in the mainline kernel but it has be changed.
I'll need to further investigate that.
>
>
>>> Also I have found that there is eeprom dependency which needs to be
>>> resolved to be able to use this driver instead of old one.
>>
>> Yeah I realized that. Do any of the zynq boards actually use CMD_EEPROM?
>
> We have a code for zc702 to save internal variables to EEPROM. zc706
> should have that memory too.
Ok, I'll look into it.
Moritz
^ permalink raw reply [flat|nested] 15+ messages in thread
* [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c
2016-01-07 5:18 ` Moritz Fischer
@ 2016-01-07 8:13 ` Michal Simek
0 siblings, 0 replies; 15+ messages in thread
From: Michal Simek @ 2016-01-07 8:13 UTC (permalink / raw)
To: u-boot
On 7.1.2016 06:18, Moritz Fischer wrote:
> On Tue, Jan 5, 2016 at 11:53 PM, Michal Simek <michal.simek@xilinx.com> wrote:
>> On 5.1.2016 18:30, Moritz Fischer wrote:
>>> Hi Michal,
>>>
>>> On Tue, Jan 5, 2016 at 7:44 AM, Michal Simek <michal.simek@xilinx.com> wrote:
>>>
>>>> I have looked at these patches and I don't know why there is 100k
>>>> limitation in cdns_i2c_set_bus_speed. DTS is using 400k in Linux without
>>>> any problem.
>>>
>>> Well I could statically calculate the values for 400K, too but anyway that works
>>> only if your CPU_CLK_1X is 111MHz. Is there a way to figure out the CPU_CLK_1X
>>> frequency?
>>
>> Check the clock driver.
>
> Wouldn't that nececitate dm capable clk drivers? Were you talking about
> arch/arm/mach-zynq/clk.c?
yes. clk dump shows that information. It means you should be able to get
that information. Probably we will need to create clk driver.
Thanks,
Michal
=> clk dump
clk frequency
armpll 1333333320
ddrpll 1066666656
iopll 999999990
cpu_6or4x 666666660
cpu_3or2x 333333330
cpu_2x 222222220
cpu_1x 111111110
ddr_2x 355555552
ddr_3x 533333328
dci 10158730
lqspi 199999998
smc 22222222
pcap 199999998
gem0 25000000
gem1 16666667
fclk0 50000000
fclk1 50000000
fclk2 50000000
fclk3 50000000
sdio0 50000000
sdio1 50000000
uart0 50000000
uart1 50000000
spi0 15873016
spi1 15873016
usb0_aper 111111110
usb1_aper 111111110
gem0_aper 111111110
gem1_aper 111111110
sdio0_aper 111111110
sdio1_aper 111111110
spi0_aper 111111110
spi1_aper 111111110
can0_aper 111111110
can1_aper 111111110
i2c0_aper 111111110
i2c1_aper 111111110
uart0_aper 111111110
uart1_aper 111111110
gpio_aper 111111110
lqspi_aper 111111110
smc_aper 111111110
dbg_trc 66666666
dbg_apb 66666666
^ permalink raw reply [flat|nested] 15+ messages in thread
* [U-Boot] [RFC 2/2] dm: i2c: Add driver for Cadence I2C IP
2016-01-04 7:15 ` Heiko Schocher
@ 2016-04-11 12:50 ` Michal Simek
2016-04-12 7:45 ` Heiko Schocher
0 siblings, 1 reply; 15+ messages in thread
From: Michal Simek @ 2016-04-11 12:50 UTC (permalink / raw)
To: u-boot
Hi Heiko,
On 4.1.2016 08:15, Heiko Schocher wrote:
> Hello Moritz,
>
> Am 28.12.2015 um 18:47 schrieb Moritz Fischer:
>> This is a possible drop in replacement for drivers/i2c/zynq-i2c.c
>>
>> Since this is cadence IP it has been renamed to cdns-i2c,
>> to make sense with the compatible string.
>>
>> Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
>> ---
>> drivers/i2c/Kconfig | 7 +
>> drivers/i2c/Makefile | 1 +
>> drivers/i2c/i2c-cdns.c | 339
>> +++++++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 347 insertions(+)
>> create mode 100644 drivers/i2c/i2c-cdns.c
>
> Hmm.. I di not see the remove of "drivers/i2c/zynq-i2c.c" as
> you wrote it is a replacement for it ... Can you do this, and
> of course adapt the boards which use this driver?
I would like to start to use this driver for ZynqMP and use old driver
for Zynq because there eeprom hasn't been moved.
I found just one problem regarding reading addr from DT which I have fixed.
Thanks,
Michal
--
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20160411/a2cbb4cb/attachment.sig>
^ permalink raw reply [flat|nested] 15+ messages in thread
* [U-Boot] [RFC 2/2] dm: i2c: Add driver for Cadence I2C IP
2016-04-11 12:50 ` Michal Simek
@ 2016-04-12 7:45 ` Heiko Schocher
2016-04-12 7:59 ` Michal Simek
0 siblings, 1 reply; 15+ messages in thread
From: Heiko Schocher @ 2016-04-12 7:45 UTC (permalink / raw)
To: u-boot
Hello Michal,
Sorry for the late reply...
Am 11.04.2016 um 14:50 schrieb Michal Simek:
> Hi Heiko,
>
> On 4.1.2016 08:15, Heiko Schocher wrote:
>> Hello Moritz,
>>
>> Am 28.12.2015 um 18:47 schrieb Moritz Fischer:
>>> This is a possible drop in replacement for drivers/i2c/zynq-i2c.c
>>>
>>> Since this is cadence IP it has been renamed to cdns-i2c,
>>> to make sense with the compatible string.
>>>
>>> Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
>>> ---
>>> drivers/i2c/Kconfig | 7 +
>>> drivers/i2c/Makefile | 1 +
>>> drivers/i2c/i2c-cdns.c | 339
>>> +++++++++++++++++++++++++++++++++++++++++++++++++
>>> 3 files changed, 347 insertions(+)
>>> create mode 100644 drivers/i2c/i2c-cdns.c
>>
>> Hmm.. I di not see the remove of "drivers/i2c/zynq-i2c.c" as
>> you wrote it is a replacement for it ... Can you do this, and
>> of course adapt the boards which use this driver?
>
> I would like to start to use this driver for ZynqMP and use old driver
> for Zynq because there eeprom hasn't been moved.
>
> I found just one problem regarding reading addr from DT which I have fixed.
Yes, I just saw the v2 versions... I review them soon.
bye,
Heiko
--
DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply [flat|nested] 15+ messages in thread
* [U-Boot] [RFC 2/2] dm: i2c: Add driver for Cadence I2C IP
2016-04-12 7:45 ` Heiko Schocher
@ 2016-04-12 7:59 ` Michal Simek
0 siblings, 0 replies; 15+ messages in thread
From: Michal Simek @ 2016-04-12 7:59 UTC (permalink / raw)
To: u-boot
Hi Heiko,
On 12.4.2016 09:45, Heiko Schocher wrote:
> Hello Michal,
>
> Sorry for the late reply...
>
> Am 11.04.2016 um 14:50 schrieb Michal Simek:
>> Hi Heiko,
>>
>> On 4.1.2016 08:15, Heiko Schocher wrote:
>>> Hello Moritz,
>>>
>>> Am 28.12.2015 um 18:47 schrieb Moritz Fischer:
>>>> This is a possible drop in replacement for drivers/i2c/zynq-i2c.c
>>>>
>>>> Since this is cadence IP it has been renamed to cdns-i2c,
>>>> to make sense with the compatible string.
>>>>
>>>> Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
>>>> ---
>>>> drivers/i2c/Kconfig | 7 +
>>>> drivers/i2c/Makefile | 1 +
>>>> drivers/i2c/i2c-cdns.c | 339
>>>> +++++++++++++++++++++++++++++++++++++++++++++++++
>>>> 3 files changed, 347 insertions(+)
>>>> create mode 100644 drivers/i2c/i2c-cdns.c
>>>
>>> Hmm.. I di not see the remove of "drivers/i2c/zynq-i2c.c" as
>>> you wrote it is a replacement for it ... Can you do this, and
>>> of course adapt the boards which use this driver?
>>
>> I would like to start to use this driver for ZynqMP and use old driver
>> for Zynq because there eeprom hasn't been moved.
>>
>> I found just one problem regarding reading addr from DT which I have
>> fixed.
>
> Yes, I just saw the v2 versions... I review them soon.
Thanks,
Michal
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2016-04-12 7:59 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-12-28 17:47 [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c Moritz Fischer
2015-12-28 17:47 ` [U-Boot] [RFC 1/2] i2c: Describe Cadence I2C devicetree bindings Moritz Fischer
2016-01-04 7:09 ` Heiko Schocher
2015-12-28 17:47 ` [U-Boot] [RFC 2/2] dm: i2c: Add driver for Cadence I2C IP Moritz Fischer
2016-01-04 7:15 ` Heiko Schocher
2016-04-11 12:50 ` Michal Simek
2016-04-12 7:45 ` Heiko Schocher
2016-04-12 7:59 ` Michal Simek
2015-12-28 18:35 ` [U-Boot] [RFC 0/2] Add cdns-i2c driver as drop in for zynq-i2c Michal Simek
2015-12-28 19:15 ` Moritz Fischer
2016-01-05 15:44 ` Michal Simek
2016-01-05 17:30 ` Moritz Fischer
2016-01-06 7:53 ` Michal Simek
2016-01-07 5:18 ` Moritz Fischer
2016-01-07 8:13 ` Michal Simek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox