From 173ec3519118767f50f335ade987cf3e6a94759f Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Thu, 7 Jun 2018 12:38:10 +0300 Subject: [PATCH 1/2] i2c: mvtwsi: disable i2c slave on Armada 38x Equivalent code that disables the hidden i2c0 slave already exists in the Turris Omnia platform specific code. But this hidden i2c0 slave that interferes the i2c bus is not board specific. Armada 38x SoCs and at least some Kirkwood variants are affected as well. Add code to disable this slave to the i2c bus driver to make it work on all affected hardware. Use the bind callback because we want this to always run at boot, regardless of whether U-Boot uses the i2c bus. Cc: Rabeeh Khoury Cc: Chris Packham Reviewed-by: Stefan Roese Reviewed-by: Heiko Schocher Signed-off-by: Baruch Siach --- drivers/i2c/mvtwsi.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/mvtwsi.c b/drivers/i2c/mvtwsi.c index f9822e5..74ac0a4 100644 --- a/drivers/i2c/mvtwsi.c +++ b/drivers/i2c/mvtwsi.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #ifdef CONFIG_DM_I2C #include @@ -57,6 +58,7 @@ struct mvtwsi_registers { u32 status; u32 baudrate; u32 soft_reset; + u32 debug; /* Dummy field for build compatibility with mvebu */ }; #else @@ -70,8 +72,10 @@ struct mvtwsi_registers { u32 baudrate; /* When writing */ }; u32 xtnd_slave_addr; - u32 reserved[2]; + u32 reserved0[2]; u32 soft_reset; + u32 reserved1[27]; + u32 debug; }; #endif @@ -795,6 +799,23 @@ static int mvtwsi_i2c_ofdata_to_platdata(struct udevice *bus) return 0; } +static void twsi_disable_i2c_slave(struct mvtwsi_registers *twsi) +{ + clrbits_le32(&twsi->debug, BIT(18)); +} + +static int mvtwsi_i2c_bind(struct udevice *bus) +{ + struct mvtwsi_registers *twsi = devfdt_get_addr_ptr(bus); + + /* Disable the hidden slave in i2c0 of these platforms */ + if ((IS_ENABLED(CONFIG_ARMADA_38X) || IS_ENABLED(CONFIG_KIRKWOOD)) + && bus->req_seq == 0) + twsi_disable_i2c_slave(twsi); + + return 0; +} + static int mvtwsi_i2c_probe(struct udevice *bus) { struct mvtwsi_i2c_dev *dev = dev_get_priv(bus); @@ -850,6 +871,7 @@ U_BOOT_DRIVER(i2c_mvtwsi) = { .name = "i2c_mvtwsi", .id = UCLASS_I2C, .of_match = mvtwsi_i2c_ids, + .bind = mvtwsi_i2c_bind, .probe = mvtwsi_i2c_probe, .ofdata_to_platdata = mvtwsi_i2c_ofdata_to_platdata, .priv_auto_alloc_size = sizeof(struct mvtwsi_i2c_dev), From d78ecc733988d07a87c97f7f1c19171c437a8712 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Thu, 7 Jun 2018 12:38:11 +0300 Subject: [PATCH 2/2] mvebu: turris_omnia: add note about i2c slave disable Code that disables the i2c slave is now in the mvtwsi i2c driver. Platform must enable DM_I2C to use that code. Add a comment in the code as a reminder for the planned DM_I2C migration of Turris Omnia. Reviewed-by: Heiko Schocher Signed-off-by: Baruch Siach --- board/CZ.NIC/turris_omnia/turris_omnia.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c index da663cf..160d30c 100644 --- a/board/CZ.NIC/turris_omnia/turris_omnia.c +++ b/board/CZ.NIC/turris_omnia/turris_omnia.c @@ -321,7 +321,11 @@ int board_early_init_f(void) writel(OMNIA_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04); writel(OMNIA_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04); - /* Disable I2C debug mode blocking 0x64 I2C address */ + /* + * Disable I2C debug mode blocking 0x64 I2C address. + * Note: that would be redundant once Turris Omnia migrates to DM_I2C, + * because the mvtwsi driver includes equivalent code. + */ i2c_debug_reg = readl(MVEBU_TWSI_BASE + MVTWSI_ARMADA_DEBUG_REG); i2c_debug_reg &= ~(1<<18); writel(i2c_debug_reg, MVEBU_TWSI_BASE + MVTWSI_ARMADA_DEBUG_REG);