Skip to contentSkip to conversation

Add cdns-i2c driver as drop in for zynq-i2c

RFC New Moritz Fischer 4 participants 15 messages Dec 28, 2015 – Apr 12, 2016 I2C

lore
Share & tools
lore
#0 lore raw

cover Add cdns-i2c driver as drop in for zynq-i2c

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
Signature · 1 line
2.4.3
#1 lore raw

RFC 1/2 i2c: Describe Cadence I2C devicetree bindings

---
 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
doc/device-tree-bindings/i2c/i2c-cdns.txt new file +20 -0
new file mode 100644
index 0000000..202e0b7
@@ -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";
+	};
Signature · 1 line
2.4.3
#2 lore raw

RFC 1/2 i2c: Describe Cadence I2C devicetree bindings

Hello Moritz,

Am 28.12.2015 um 18:47 schrieb Moritz Fischer:

Quoted 5 lines
---
  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:

bye,
Heiko

Quoted 28 lines
doc/device-tree-bindings/i2c/i2c-cdns.txt new file +20 -0
new file mode 100644
index 0000000..202e0b7
@@ -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";
+	};
Signature · 2 lines
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#3 lore raw

RFC 2/2 dm: i2c: Add driver for Cadence I2C IP

In reply to 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.

---
 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
drivers/i2c/Kconfig +7 -0
index 14adda2..c058dc5 100644
@@ -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
drivers/i2c/Makefile +1 -0
index 811ad9b..35ad0d3 100644
@@ -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
drivers/i2c/i2c-cdns.c new file +339 -0

339 lines not on this page · raw message

Signature · 1 line
2.4.3
#4 lore raw

RFC 2/2 dm: i2c: Add driver for Cadence I2C IP

Hello Moritz,

Am 28.12.2015 um 18:47 schrieb Moritz Fischer:

Quoted 5 lines

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.

Quoted 7 lines
---
  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?

Quoted 165 lines
drivers/i2c/Kconfig +7 -0
index 14adda2..c058dc5 100644
@@ -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
drivers/i2c/Makefile +1 -0
index 811ad9b..35ad0d3 100644
@@ -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
drivers/i2c/i2c-cdns.c new file +129 -0
new file mode 100644
index 0000000..fab9609
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2015 Moritz Fischer <[email protected]>
+ * 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;
+

drivers/i2c/i2c-cdns.c line 139

Quoted 10 lines
drivers/i2c/i2c-cdns.c new file +10 -0
+	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 ...

Quoted 191 lines
drivers/i2c/i2c-cdns.c new file +190 -0
+
+	/* 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(&regs->control, CDNS_I2C_CONTROL_CLR_FIFO |
+		CDNS_I2C_CONTROL_RW);
+	clrbits_le32(&regs->control, CDNS_I2C_CONTROL_HOLD);
+	writel(0xFF, &regs->interrupt_status);
+	writel(chip_addr, &regs->address);
+	writel(1, &regs->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(&regs->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(&regs->control, CDNS_I2C_CONTROL_HOLD);
+
+	clrbits_le32(&regs->control, CDNS_I2C_CONTROL_RW);
+
+	writel(0xFF, &regs->interrupt_status);
+	writel(addr, &regs->address);
+
+	while (len--) {
+		writel(*(cur_data++), &regs->data);
+		if (readl(&regs->transfer_size) == CDNS_I2C_FIFO_DEPTH) {
+			if (!cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP)) {
+				/* Release the bus */
+				clrbits_le32(&regs->control,
+					     CDNS_I2C_CONTROL_HOLD);
+				return -ETIMEDOUT;
+			}
+		}
+	}
+
+	/* All done... release the bus */
+	clrbits_le32(&regs->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(&regs->control, CDNS_I2C_CONTROL_CLR_FIFO |
+		CDNS_I2C_CONTROL_RW);
+
+	/* Start reading data */
+	writel(addr, &regs->address);
+	writel(len, &regs->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(&regs->control, CDNS_I2C_CONTROL_HOLD);
+			return -ETIMEDOUT;
+		}
+		debug("Read %d bytes\n",
+		      len - readl(&regs->transfer_size));
+		for (; i < len - readl(&regs->transfer_size); i++)
+			*(cur_data++) = readl(&regs->data);
+	} while (readl(&regs->transfer_size) != 0);
+	/* All done... release the bus */
+	clrbits_le32(&regs->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 */ }
+};

drivers/i2c/i2c-cdns.c line 339

Quoted 10 lines
drivers/i2c/i2c-cdns.c new file +10 -0
+
+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

Signature · 2 lines
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#5 lore raw

RFC 2/2 dm: i2c: Add driver for Cadence I2C IP

Hi Heiko,

Quoted 17 lines · Heiko Schocher

Hello Moritz,

Am 28.12.2015 um 18:47 schrieb Moritz Fischer:

Quoted 5 lines

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.

Quoted 8 lines
---
  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

Quoted 3 lines

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

Signature · 14 lines
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>
#6 lore raw

RFC 2/2 dm: i2c: Add driver for Cadence I2C IP

Hello Michal,

Sorry for the late reply...

Am 11.04.2016 um 14:50 schrieb Michal Simek:

Quoted 20 lines

Hi Heiko,

Quoted 17 lines · Heiko Schocher

Hello Moritz,

Am 28.12.2015 um 18:47 schrieb Moritz Fischer:

Quoted 13 lines

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.

---
   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

Quoted 8 lines
Quoted 3 lines

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

Signature · 2 lines
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
#7 lore raw

RFC 2/2 dm: i2c: Add driver for Cadence I2C IP

Hi Heiko,

Quoted 29 lines · Heiko Schocher

Hello Michal,

Sorry for the late reply...

Am 11.04.2016 um 14:50 schrieb Michal Simek:

Quoted 24 lines

Hi Heiko,

Quoted 20 lines · Heiko Schocher

Hello Moritz,

Am 28.12.2015 um 18:47 schrieb Moritz Fischer:

Quoted 5 lines

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.

Quoted 8 lines
---
   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?

Quoted 7 lines
Quoted 5 lines

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

#8 lore raw

cover Add cdns-i2c driver as drop in for zynq-i2c

In reply to Moritz Fischer

Hi,

2015-12-28 18:47 GMT+01:00 Moritz Fischer <[email protected]>:

Quoted 4 lines

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?

Quoted 4 lines

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.

Quoted 2 lines

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

#9 lore raw

cover Add cdns-i2c driver as drop in for zynq-i2c

Hi Michal,

Quoted 1 line · Michal Simek

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?

Quoted 3 lines

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.

Quoted 1 line

I will look at it and test it in January.

Thanks.

Cheers,

Moritz

#10 lore raw

cover Add cdns-i2c driver as drop in for zynq-i2c

In reply to Moritz Fischer
Quoted 20 lines · Moritz Fischer

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

Quoted 8 lines
 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

#11 lore raw

cover Add cdns-i2c driver as drop in for zynq-i2c

Hi Michal,

Quoted 3 lines · Michal Simek

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?

Quoted 4 lines

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.

Quoted 2 lines

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

#12 lore raw

cover Add cdns-i2c driver as drop in for zynq-i2c

Quoted 11 lines · Moritz Fischer

Hi Michal,

Quoted 3 lines · Michal Simek

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.

Quoted 8 lines
Quoted 4 lines

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.

Quoted 4 lines
Quoted 2 lines

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

#13 lore raw

cover Add cdns-i2c driver as drop in for zynq-i2c

Quoted 9 lines · Michal Simek
Quoted 8 lines · Moritz Fischer

Hi Michal,

Quoted 3 lines · Michal Simek

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.

Quoted 5 lines
Quoted 3 lines

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?

Quoted 3 lines

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.

Quoted 9 lines
Quoted 6 lines
Quoted 4 lines

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

#14 lore raw

cover Add cdns-i2c driver as drop in for zynq-i2c

Quoted 10 lines · Moritz Fischer
Quoted 9 lines · Michal Simek
Quoted 8 lines · Moritz Fischer

Hi Michal,

Quoted 3 lines · Michal Simek

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.

Quoted 8 lines
Quoted 5 lines
Quoted 3 lines

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