Re: i2c: designware: multi master problem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux GPIO]     [Linux SPI]     [Linux Hardward Monitoring]     [LM Sensors]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux