Add cdns-i2c driver as drop in for zynq-i2c
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
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
@@ -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
RFC 1/2 i2c: Describe Cadence I2C devicetree bindings
Hello Moritz,
Am 28.12.2015 um 18:47 schrieb Moritz Fischer:
Quoted 5 lines
Signed-off-by Moritz Fischer <[email protected]>--- 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@@ -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
RFC 2/2 dm: i2c: Add driver for Cadence I2C IP
In reply to Moritz FischerThis 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
@@ -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
@@ -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
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.cSince this is cadence IP it has been renamed to cdns-i2c, to make sense with the compatible string.
Quoted 7 lines
Signed-off-by Moritz Fischer <[email protected]>--- 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@@ -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_I2Cdrivers/i2c/Makefile +1
-0@@ -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.odrivers/i2c/i2c-cdns.c new file +129
-0@@ -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 (®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 */ } +};
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
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.cSince this is cadence IP it has been renamed to cdns-i2c, to make sense with the compatible string.
Quoted 8 lines
Signed-off-by Moritz Fischer <[email protected]>--- 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>
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.cSince this is cadence IP it has been renamed to cdns-i2c, to make sense with the compatible string.
Signed-off-by Moritz Fischer <[email protected]>--- 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
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.cSince this is cadence IP it has been renamed to cdns-i2c, to make sense with the compatible string.
Quoted 8 lines
Signed-off-by Moritz Fischer <[email protected]>--- 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.cHmm.. 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
cover Add cdns-i2c driver as drop in for zynq-i2c
In reply to Moritz FischerHi,
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.cto 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
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
cover Add cdns-i2c driver as drop in for zynq-i2c
In reply to Moritz FischerQuoted 20 lines · Moritz Fischer
Hi all,
I spent some time moving over the
zynq-i2c.cto 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
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
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_1Xis 111MHz. Is there a way to figure out theCPU_CLK_1Xfrequency?
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
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_1Xis 111MHz. Is there a way to figure out theCPU_CLK_1Xfrequency?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
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_1Xis 111MHz. Is there a way to figure out theCPU_CLK_1Xfrequency?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