Hello,
We need i2c multimaster working on imx28 customer hardware with one more master (another cpu) on the same i2c bus ideally. So we need to use i2c controller in the multimaster mode. First step is to use only imx28 as the only master.
The exact part of the cpu is imx283. We are using linux kernel 5.4.93. NO changes to the i2c driver(i2c-mxs.c)
As soon as we added I2C_MULTIMASTER bit set in control register, our i2c master transaction fails with arbitration lost(MASTER_LOSS_IRQ status bit in the HW_I2C_CTRL1 register) even when we have the only imx28 as master.
Index: kernel-source/drivers/i2c/busses/i2c-mxs.c
===================================================================
--- kernel-source.orig/drivers/i2c/busses/i2c-mxs.c
+++ kernel-source/drivers/i2c/busses/i2c-mxs.c
@@ -37,6 +37,7 @@
#define MXS_I2C_CTRL0_RUN 0x20000000
#define MXS_I2C_CTRL0_SEND_NAK_ON_LAST 0x02000000
#define MXS_I2C_CTRL0_PIO_MODE 0x01000000
+#define MXS_I2C_CTRL0_MULTIMASTER_MODE 0x00800000
#define MXS_I2C_CTRL0_RETAIN_CLOCK 0x00200000
#define MXS_I2C_CTRL0_POST_SEND_STOP 0x00100000
#define MXS_I2C_CTRL0_PRE_SEND_START 0x00080000
@@ -83,15 +84,18 @@
#define MXS_CMD_I2C_SELECT (MXS_I2C_CTRL0_RETAIN_CLOCK | \
MXS_I2C_CTRL0_PRE_SEND_START | \
+ MXS_I2C_CTRL0_MULTIMASTER_MODE | \
MXS_I2C_CTRL0_MASTER_MODE | \
MXS_I2C_CTRL0_DIRECTION | \
MXS_I2C_CTRL0_XFER_COUNT(1))
#define MXS_CMD_I2C_WRITE (MXS_I2C_CTRL0_PRE_SEND_START | \
+ MXS_I2C_CTRL0_MULTIMASTER_MODE | \
MXS_I2C_CTRL0_MASTER_MODE | \
MXS_I2C_CTRL0_DIRECTION)
#define MXS_CMD_I2C_READ (MXS_I2C_CTRL0_SEND_NAK_ON_LAST | \
+ MXS_I2C_CTRL0_MULTIMASTER_MODE | \
MXS_I2C_CTRL0_MASTER_MODE)
enum mxs_i2c_devtype {
@@ -515,6 +519,7 @@ static int mxs_i2c_pio_setup_xfer(struct
mxs_i2c_pio_trigger_write_cmd(i2c,
start | MXS_I2C_CTRL0_MASTER_MODE |
+ MXS_I2C_CTRL0_MULTIMASTER_MODE |
MXS_I2C_CTRL0_DIRECTION |
MXS_I2C_CTRL0_XFER_COUNT(xlen), data);
Our dts is based on imx28.dtsi and the controllers are defined like this in imx28.dtsi:
i2c0: i2c@80058000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx28-i2c";
reg = <0x80058000 0x2000>;
interrupts = <111>;
clock-frequency = <100000>;
dmas = <&dma_apbx 6>;
dma-names = "rx-tx";
status = "disabled";
};
i2c1: i2c@8005a000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx28-i2c";
reg = <0x8005a000 0x2000>;
interrupts = <110>;
clock-frequency = <100000>;
dmas = <&dma_apbx 7>;
dma-names = "rx-tx";
status = "disabled";
};
and at board level:
&i2c0 {
pinctrl-names = "default";
pinctrl-0 = <&i2c0_pins_b>;
status = "okay";
....
};
&i2c1 {
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins_a>;
status = "okay";
...
}
We don't have any other masters on our hardware atm. The only master is i.mx28 itself. As soon as we directly set MULTIMASTER bit in the driver as shown above, it stops working.
What might be wrong , how we can enbale i2c multmaster on our soc properly? What we need to do, when get arbitration lost irq?