On 10/09/2019 21:41, Jarkko Nikula wrote:
+ Luis from Synopsys
On 9/10/19 10:29 AM, Phil Reid wrote:
G'day All,
I'm seeing a problem with the designware driver in a multi-master system.
This is an Altera / Intel Cycloe V SoC.
This is with it connected to a ltc1760 sbs manager which acts as a slave and master.
What I'm seeing is that a requested read of the ltc1760 will return successfully before
the u2c transfer has been done. Read data contain garbage.
In i2c_dw_xfer() I set all read buffers to 0xff and get 0xffff as the return value
from sbsm_read_word().
I've injected a gpio trigger before and after the sbsm_read_word() call and
looked at the traffic in between. I can see the ltc1760 as master talking to
the sbs batteries and after the sbsm_read_word() call returns the start of the
actual sbsm_read_word() call is started with the address and and cmd byte being
sent on the wire. The bus then hangs with scl held low by the
designware driver, while I think it waits for the driver to start the read.
I've been able to isolate which device is driving the bus
by routing the i2c control signal thru the c-v fabric and tapping the OE enables from
the designware core to separate pins.
What I think is going on is the the stop events from the ltc1760 are being
counted by the driver as part of it's transaction.
ie in i2c_dw_irq_handler_master() the completion is only monitoring
if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err) {
complete(&dev->cmd_complete);
Anyone have any thoughts on how to fix this?
Should complete only be called if DW_IC_INTR_RX_FULL or DW_IC_INTR_TX_EMPTY are
also set?
I've logged the DW_IC_RAW_INTR_STAT register in the irq and see the following:
i2c_dw_irq_handler_master: DW_IC_RAW_INTR_STAT register & dev->flags (hex)
sbsm_gpio_get_value: Last value is what was returned from sbsm_read_word() (hex)
After initialising all read buffer to 0xff.
In i2c_dw_xfer I added the following:
for (ret = 0; ret < num; ret++) {
if (msgs[ret].flags == I2C_M_RD) {
memset(msgs[ret].buf, 0xff, msgs[ret].len);
}
}
Prior to this it was returning un-inited values in buf.
Successful transfer
cat-381 [000] .... 167.342035: i2c_dw_xfer: i2c_dw_xfer: msgs: 2
cat-381 [000] d.h1 167.342048: i2c_dw_isr: i2c_dw_irq_handler_master: s 10 0
<idle>-0 [000] d.h1 167.342955: i2c_dw_isr: i2c_dw_irq_handler_master: s 514 0
<idle>-0 [000] d.h1 167.343167: i2c_dw_isr: i2c_dw_irq_handler_master: s 514 0
<idle>-0 [000] dnh1 167.343186: i2c_dw_isr: i2c_dw_irq_handler_master: s 710 0
cat-381 [000] .... 167.343218: sbsm_gpio_get_value: sbsm_gpio_get_value: gpio 0: 1011
Failed transfer
cat-382 [001] .... 168.146166: i2c_dw_xfer: i2c_dw_xfer: msgs: 2
<idle>-0 [000] dnh1 168.146224: i2c_dw_isr: i2c_dw_irq_handler_master: s 410 0
<idle>-0 [000] d.h1 168.147345: i2c_dw_isr: i2c_dw_irq_handler_master: s 610 0
cat-382 [001] .... 168.147639: sbsm_gpio_get_value: sbsm_gpio_get_value: Failed to read gpio 0: ffff
Failed transfer
systemd-journal-146 [001] .... 168.216212: i2c_dw_xfer: i2c_dw_xfer: msgs: 2
<idle>-0 [000] d.h1 168.216583: i2c_dw_isr: i2c_dw_irq_handler_master: s 10 0
<idle>-0 [000] d.h1 168.217277: i2c_dw_isr: i2c_dw_irq_handler_master: s 610 0
systemd-journal-146 [001] .... 168.217524: sbsm_gpio_get_value: sbsm_gpio_get_value: Failed to read gpio 0: ffff
Successful transfer
systemd-journal-146 [001] .... 168.229292: i2c_dw_xfer: i2c_dw_xfer: msgs: 2
<idle>-0 [000] d.h1 168.284968: i2c_dw_isr: i2c_dw_irq_handler_master: s 10 0
<idle>-0 [000] d.h1 168.285871: i2c_dw_isr: i2c_dw_irq_handler_master: s 514 0
<idle>-0 [000] d.h1 168.286082: i2c_dw_isr: i2c_dw_irq_handler_master: s 514 0
<idle>-0 [000] dnh1 168.286103: i2c_dw_isr: i2c_dw_irq_handler_master: s 710 0
systemd-journal-146 [001] .... 168.286150: sbsm_gpio_get_value: sbsm_gpio_get_value: gpio 0: 1011
--
Regards
Phil Reid