[meta-xilinx] Strange I2C problem after updating to Sumo
Mike Looijmans
mike.looijmans at topic.nl
Sat Dec 1 01:55:36 PST 2018
One thing you may want to try is replace the cadence I2C driver with the
generic bit-bang GPIO driver (on the same pins).
Example devicetree that does this in the kernel (you'll need to activate
the bitbang gpio i2c driver in the kernel config though):
https://github.com/topic-embedded-products/linux/blob/topic-miami/arch/arm/boot/dts/topic-miami.dtsi#L52
We have had lots of troubles with the I2C controller in the Zynq, it
appears to be broken, and replacing the driver with a bitbang GPIO one
solved all issues. In our case, the problem was with longer transfers
like sending EDID tables to video encoder chips, but we've seen
occasional failures on simple transfers (eeprom, hw monitors, etc) as well.
On 30-11-18 19:47, Martin Townsend wrote:
> Hi,
>
> We are in the process of upgrading to Sumo which has the 4.14
> linux-xlnx kernel and everything is working fine except for our
> LTC-3375 regulator device driver which was working fine with the 4.9
> kernel but with the newer kernel we are getting the following in the
> log.
>
> SW1: failed to get the current voltage(-6)
> ltc3375 6-0034: failed to register regulator SW1: -6
>
> We get this message twice as there are 2 LTC-3375 on different
> channels of the PCA9548, here's a cut down version of the device tree:
>
> &i2c0 {
> status = "okay";
> /* clock-frequency = <400000>; */
> clock-frequency = <100000>;
> pinctrl-names = "default";
> pinctrl-0 = <&pinctrl_i2c0_default>;
>
>
> /* I2C Switch */
> i2cswitch at 70 {
> compatible = "nxp,pca9548";
> #address-cells = <1>;
> #size-cells = <0>;
> reg = <0x70>;
>
> /* PS Power Switcher */
> i2c at 4 {
> #address-cells = <1>;
> #size-cells = <0>;
> reg = <4>;
>
> powerswitcher1 at 34 {
> compatible = "ltc,ltc3375";
> reg = <0x34>;
> interrupt-parent = <&gpiom2>;
> interrupts = <12 1>;
>
> regulators {
> sw1 {
> regulator-min-microvolt = <693987>;
> regulator-max-microvolt = <1306329>;
> lltc,fb-voltage-divider = <100000 158000>;
> regulator-ramp-delay = <7000>;
> regulator-boot-on;
> regulator-always-on;
> };
> sw2 {
> ...
> };
> sw3 {
> ...
> };
> sw4 {
> ...
> };
> sw5 {
> ...
> };
> sw6 {
> ...
> };
> sw7 {
> ...
> };
> sw8 {
> ...
> };
> };
> };
> };
>
> /* PL Power Switcher */
> i2c at 5 {
> #address-cells = <1>;
> #size-cells = <0>;
> reg = <5>;
>
> powerswitcher1 at 34 {
> compatible = "ltc,ltc3375";
> reg = <0x34>;
> interrupt-parent = <&gpiom2>;
> interrupts = <13 1>;
>
> regulators {
> sw1 {
> regulator-min-microvolt = <693987>;
> regulator-max-microvolt = <1306329>;
> lltc,fb-voltage-divider = <100000 158000>;
> regulator-ramp-delay = <7000>;
> regulator-boot-on;
> regulator-always-on;
> };
> sw2 {
> ...
> };
> sw3 {
> ...
> };
> sw4 {
> ...
> };
> sw5 {
> ...
> };
> sw6 {
> ...
> };
> sw7 {
> ...
> };
> sw8 {
> ...
> };
> };
> };
> };
> };
> };
>
> I traced the -6 error code (-ENXIO) to the cadence driver where it
> basically receives a NAK.
>
> static int cdns_i2c_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
> int num)
> {
> ...
> /* Process the msg one by one */
> for (count = 0; count < num; count++, msgs++) {
> if (count == (num - 1))
> id->bus_hold_flag = 0;
>
> ret = cdns_i2c_process_msg(id, msgs, adap);
> if (ret)
> goto out;
>
> /* Report the other error interrupts to application */
> if (id->err_status) {
> cdns_i2c_master_reset(adap);
>
> if (id->err_status & CDNS_I2C_IXR_NACK) {
> ret = -ENXIO;
> goto out;
> }
> ret = -EIO;
> goto out;
> }
> }
> }
>
> After debugging further I can see that it's trying to select the right
> channel of the PCA9548 but the i2c controller on the Xilinx is failing
> with a NAK. So it's not even getting as far as the LTC driver. Here
> is some of my debug that shows it's the PCA9548 that is failing as
> this is address 0x70 whereas the LTC is at 0x34
>
> pca954x_select_chan: chan:4 regval:10
> pca954x_reg_write: addr:70 val:10
> cdns-i2c e0004000.i2c: cdns_i2c_master_xfer: id->err_status=4
> cdns-i2c e0004000.i2c: cdns_i2c_master_xfer: id->p_msg->addr=70
>
> I've done a diff between the 4.9 and 4.14 kernel but can't see any
> obvious in either of these drivers. I've checked the device tree in
> this area but again can see no changes. The second I2C interface is
> working fine, I2C1.
>
> I did a dump_stack on the i2c read that was failing
> [<c010e854>] (unwind_backtrace) from [<c010aa68>] (show_stack+0x10/0x14)
> [<c010aa68>] (show_stack) from [<c064a3e8>] (dump_stack+0x80/0xa0)
> [<c064a3e8>] (dump_stack) from [<c04a2e50>] (cdns_i2c_master_xfer+0x2fc/0x3e4)
> [<c04a2e50>] (cdns_i2c_master_xfer) from [<c049e908>]
> (_i2c_transfer+0x1cc/0x20c)
> [<c049e908>] (_i2c_transfer) from [<c04a38dc>] (pca954x_reg_write+0x4c/0x8c)
> [<c04a38dc>] (pca954x_reg_write) from [<c04a3990>]
> (pca954x_select_chan+0x44/0x5c)
> [<c04a3990>] (pca954x_select_chan) from [<c04a1548>]
> (_i2c_mux_master_xfer+0x28/0x64)
> [<c04a1548>] (_i2c_mux_master_xfer) from [<c049e908>]
> (_i2c_transfer+0x1cc/0x20c)
> [<c049e908>] (_i2c_transfer) from [<c049e9d4>] (i2c_transfer+0x8c/0xac)
> [<c049e9d4>] (i2c_transfer) from [<c03d553c>] (regmap_i2c_read+0x48/0x64)
> [<c03d553c>] (regmap_i2c_read) from [<c03d29fc>] (regmap_raw_read+0x84/0xd0)
> [<c03d29fc>] (_regmap_raw_read) from [<c03d2a70>] (_regmap_bus_read+0x28/0x48)
> [<c03d2a70>] (_regmap_bus_read) from [<c03d2504>] (_regmap_read+0x84/0xac)
> [<c03d2504>] (_regmap_read) from [<c03d256c>] (regmap_read+0x40/0x58)
> [<c03d256c>] (regmap_read) from [<c0364bec>]
> (regulator_get_voltage_sel_regmap+0x1c/0x50)
> [<c0364bec>] (regulator_get_voltage_sel_regmap) from [<bf0472a8>]
> (ltc3375_get_voltage_sel_regmap+0xc/0x4c [oina_regulator_ltc3375])
> [<bf0472a8>] (ltc3375_get_voltage_sel_regmap [oina_regulator_ltc3375])
> from [<c0361a10>] (_regulator_get_voltage+0x8c/0x128)
> [<c0361a10>] (_regulator_get_voltage) from [<c03637f4>]
> (regulator_register+0x3ec/0xb60)
> [<c03637f4>] (regulator_register) from [<bf0475a4>]
> (ltc3375_probe+0x2bc/0x394 [oina_regulator_ltc3375])
> [<bf0475a4>] (ltc3375_probe [regulator_ltc3375]) from [<c049e3d0>]
> (i2c_device_probe+0x22c/0x244)
>
> I'll look into the regulator_register code next but was just wondering
> if anyone else has seen this or if anyone knows if there's a fix
> available for this?
>
> Any help appreciated,
>
> Cheers,
> Martin
>
--
Mike Looijmans
More information about the meta-xilinx
mailing list