From patchwork Thu Mar 7 10:52:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Simek X-Patchwork-Id: 1052798 X-Patchwork-Delegate: hs@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=xilinx.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=monstr-eu.20150623.gappssmtp.com header.i=@monstr-eu.20150623.gappssmtp.com header.b="nAKJCj0m"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44FSCJ44LYz9s47 for ; Thu, 7 Mar 2019 21:53:00 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 1E94EC21C38; Thu, 7 Mar 2019 10:52:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 98B27C21C38; Thu, 7 Mar 2019 10:52:55 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 2DDFAC21C38; Thu, 7 Mar 2019 10:52:53 +0000 (UTC) Received: from mail-wr1-f65.google.com (mail-wr1-f65.google.com [209.85.221.65]) by lists.denx.de (Postfix) with ESMTPS id 159E8C21C27 for ; Thu, 7 Mar 2019 10:52:52 +0000 (UTC) Received: by mail-wr1-f65.google.com with SMTP id w17so16849413wrn.12 for ; Thu, 07 Mar 2019 02:52:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=monstr-eu.20150623.gappssmtp.com; s=20150623; h=sender:from:to:cc:subject:date:message-id; bh=7JDApsy8F6khxH1z1QfMkKjbbBeOao8/EgvDX13IEIU=; b=nAKJCj0meZ7jn8RzUKOEFRsABceeRHqiN7JRp4yxq9vaE37EbenyFZnKWDdjEGVhdU eEM5gk3Uq943YhgeEzmawkVVLLWHnk6mP2rE2qjjsSi00qcVtbWPGwiTvD6T/pzq0NGZ G5qAf8Ymcn7nLDujIQfWegOu6vHNB9kQ+WKN9aWsM4jvxxhNLIVNqbCWtNL/HIGTRnl5 rwB/QbkYvpOMXFZN16lUpvhdFy0WCsIcnTDYlyrdQAf1GQuUO7aqiGVBFFCqqjor+i7e GUvIuw23LA0w2jxoe9KG7Ptu2DWIUtFLifBP0Hy6vT/njUwj039yIEndbTscJrisWpqc NKzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=7JDApsy8F6khxH1z1QfMkKjbbBeOao8/EgvDX13IEIU=; b=FHOx4LvO/Q8UZi5dV/TeqRg4/DIlxZcq1FirE0EoOBEqx6D5tGeAontiIpm0jCZepd St792beWisiJJVLDG3IjYmb/YeHjg9JCKBFyPSu3pOnB4c0bq0PlF0f5NRMYFqToe9yD toRZJqf+uP+/xqchXd0I3pneCQK8493+b6SBz0kdfn5C5jFjVjfNWYTyqJjeu2kgflwJ o383ArDqCyvm8Q8HEsjGU//aILE3hycqUrGXwpQnokrmOIJ5Doxo/srLpnYqwvmvKq4f 3adGeuAAK/XMni6v+DvPpn5ngwEgm9i/UskJfDEg5/X5FX1/okx1XznufON6YTfA3O3q EETg== X-Gm-Message-State: APjAAAV0tvlv5WIWsxZivz6exygA5oas6EeacUHh6lnFDwMYZ+2aAIxF uR0bSGQ8kjx+tiSaVpAdFCdcIR1W3xGnXg== X-Google-Smtp-Source: APXvYqygx+pDd9olRHZtOTfriu6n18HzeCSdXz7uVzcxrJiVquQTlzcRe9LgSgkPNQ1W2bYXHrPhWg== X-Received: by 2002:adf:8224:: with SMTP id 33mr6547009wrb.264.1551955971408; Thu, 07 Mar 2019 02:52:51 -0800 (PST) Received: from localhost (nat-35.starnet.cz. [178.255.168.35]) by smtp.gmail.com with ESMTPSA id p12sm6351575wrt.4.2019.03.07.02.52.50 (version=TLS1_2 cipher=AES128-SHA bits=128/128); Thu, 07 Mar 2019 02:52:50 -0800 (PST) From: Michal Simek To: u-boot@lists.denx.de Date: Thu, 7 Mar 2019 11:52:48 +0100 Message-Id: <5bc238a7377dbc310af40a265561290c5d3147b4.1551955966.git.michal.simek@xilinx.com> X-Mailer: git-send-email 1.9.1 Subject: [U-Boot] [PATCH 1/2] i2c: i2c_cdns: Fix clearing of all interrupts X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" From: Siva Durga Prasad Paladugu The arbitration lost interrupt was not getting cleared while clearing interrupts. This patch fixes this by adding arbitration lost interrupt as well during clear. This patch also removes hardcoded value and defined a macro for it. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek Reviewed-by: Heiko Schocher --- drivers/i2c/i2c-cdns.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c index 4330d28c2b0d..b391c0ba49b8 100644 --- a/drivers/i2c/i2c-cdns.c +++ b/drivers/i2c/i2c-cdns.c @@ -64,6 +64,16 @@ struct cdns_i2c_regs { #define CDNS_I2C_INTERRUPT_RXUNF 0x00000080 #define CDNS_I2C_INTERRUPT_ARBLOST 0x00000200 +#define CDNS_I2C_INTERRUPTS_MASK (CDNS_I2C_INTERRUPT_COMP | \ + CDNS_I2C_INTERRUPT_DATA | \ + CDNS_I2C_INTERRUPT_NACK | \ + CDNS_I2C_INTERRUPT_TO | \ + CDNS_I2C_INTERRUPT_SLVRDY | \ + CDNS_I2C_INTERRUPT_RXOVF | \ + CDNS_I2C_INTERRUPT_TXOVF | \ + CDNS_I2C_INTERRUPT_RXUNF | \ + CDNS_I2C_INTERRUPT_ARBLOST) + #define CDNS_I2C_FIFO_DEPTH 16 #define CDNS_I2C_TRANSFER_SIZE_MAX 255 /* Controller transfer limit */ #define CDNS_I2C_TRANSFER_SIZE (CDNS_I2C_TRANSFER_SIZE_MAX - 3) @@ -241,7 +251,7 @@ static int cdns_i2c_write_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, setbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD); /* Clear the interrupts in status register */ - writel(0xFF, ®s->interrupt_status); + writel(CDNS_I2C_INTERRUPTS_MASK, ®s->interrupt_status); writel(addr, ®s->address); From patchwork Thu Mar 7 10:52:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michal Simek X-Patchwork-Id: 1052799 X-Patchwork-Delegate: hs@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=xilinx.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=monstr-eu.20150623.gappssmtp.com header.i=@monstr-eu.20150623.gappssmtp.com header.b="Wp5cAzU3"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 44FSCl0rL3z9s47 for ; Thu, 7 Mar 2019 21:53:23 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id A9A9EC21C27; Thu, 7 Mar 2019 10:53:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RCVD_IN_MSPIKE_H2, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 0A462C21C27; Thu, 7 Mar 2019 10:52:56 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 8B942C21D72; Thu, 7 Mar 2019 10:52:54 +0000 (UTC) Received: from mail-wm1-f68.google.com (mail-wm1-f68.google.com [209.85.128.68]) by lists.denx.de (Postfix) with ESMTPS id 3064FC21C38 for ; Thu, 7 Mar 2019 10:52:54 +0000 (UTC) Received: by mail-wm1-f68.google.com with SMTP id x10so8705304wmg.2 for ; Thu, 07 Mar 2019 02:52:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=monstr-eu.20150623.gappssmtp.com; s=20150623; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=Qe+WPiULiwwqi+vpTZw4pwRiJIUJQ9TJ0OrYl2H8FGo=; b=Wp5cAzU365BhQRKah5zuvCOhEVEAZffQtIECcVXvUptaSxk9Y+y9x87KNFko5mBrjs 6GhKmcAkSaAroDNWls8pekyQbh4/h35dXmZ5NXQCMfDTUbqBC976MiMS7Astacy9YX1y 2mLEAq/FqgAg+5NRJ3JqiKxIMcM5IzY086O2KYaM2Rn9FqetO5r2qTQrMZ0+nMs8EJTb E55xBXQDHrDsor6Hd3bVZZ8F6j3tve9T+qzV1BRvdgHbBz65uXhaqqUGDKQKkXpKbbV7 N3NMRKLsKHhuqD75js42+ik1/t6G52MxXGu6cBOlib63Rw6FWjSAz9V5yEjgRn7XJk4B oR5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:in-reply-to:references; bh=Qe+WPiULiwwqi+vpTZw4pwRiJIUJQ9TJ0OrYl2H8FGo=; b=CcdsEz9OoImyxeXw/4uu9AXWWmkAIb/mi4QPhA1S0px2oBvopIlsFoM5xwDBUOAuWV 3Fwqcg3Veb1MYmxlm9rRzDBpdG0VBJG5tasTc7cPHKIuhSECdc0ypKoOK8pJMzU9vKh6 kT/leEJgizb/RMQJoLkZRguIjlCisjxCthAiJOZpweWoXwzaeosM9uf5al3Wl7gYOAvS UCQHwnkPX5drwFnpibdbRXXTGrHKp+zoDuG3xgkw3zpnaHAnRS7WOs5ubUfV3vJGi5V/ /ZceqAKxJU4tHkQSxd35QAbRKeoUrwSpvWfC7elStNoo8Rr6S3m5sZ03QyNMnwaMqayL jyxA== X-Gm-Message-State: APjAAAXz0+RtfKqMUIdqrmP8a6k5591BKZKQDUV6tciLbe/eQGstu32l akKmjlfyPuBCY4gRCyqIgIdvSAqTTmLt8g== X-Google-Smtp-Source: APXvYqxWlMeF+j5Vrmas6Emj1Emof1kw1gwV8bOLLMaMkpQ4Vek7X+0Lkb7mGU4WJmzW+DSAN2H/zA== X-Received: by 2002:a1c:4155:: with SMTP id o82mr5185483wma.122.1551955973098; Thu, 07 Mar 2019 02:52:53 -0800 (PST) Received: from localhost (nat-35.starnet.cz. [178.255.168.35]) by smtp.gmail.com with ESMTPSA id 203sm5678444wme.30.2019.03.07.02.52.52 (version=TLS1_2 cipher=AES128-SHA bits=128/128); Thu, 07 Mar 2019 02:52:52 -0800 (PST) From: Michal Simek To: u-boot@lists.denx.de Date: Thu, 7 Mar 2019 11:52:49 +0100 Message-Id: <5e4751d833058b0d0720ba17420e31104bdf40fd.1551955966.git.michal.simek@xilinx.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <5bc238a7377dbc310af40a265561290c5d3147b4.1551955966.git.michal.simek@xilinx.com> References: <5bc238a7377dbc310af40a265561290c5d3147b4.1551955966.git.michal.simek@xilinx.com> In-Reply-To: <5bc238a7377dbc310af40a265561290c5d3147b4.1551955966.git.michal.simek@xilinx.com> References: <5bc238a7377dbc310af40a265561290c5d3147b4.1551955966.git.michal.simek@xilinx.com> Subject: [U-Boot] [PATCH 2/2] i2c: i2c_cdns: Add support for handling arbitration lost X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" From: Siva Durga Prasad Paladugu This patch adds support for handling arbitration lost in case of multi master mode. When an arbitration lost is detected, it retries for 10 times before failing. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek Reviewed-by: Heiko Schocher --- drivers/i2c/i2c-cdns.c | 66 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c index b391c0ba49b8..1af94d176145 100644 --- a/drivers/i2c/i2c-cdns.c +++ b/drivers/i2c/i2c-cdns.c @@ -80,6 +80,8 @@ struct cdns_i2c_regs { #define CDNS_I2C_BROKEN_HOLD_BIT BIT(0) +#define CDNS_I2C_ARB_LOST_MAX_RETRIES 10 + #ifdef DEBUG static void cdns_i2c_debug_status(struct cdns_i2c_regs *cdns_i2c) { @@ -234,11 +236,17 @@ static int cdns_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) return 0; } +static inline u32 is_arbitration_lost(struct cdns_i2c_regs *regs) +{ + return (readl(®s->interrupt_status) & CDNS_I2C_INTERRUPT_ARBLOST); +} + static int cdns_i2c_write_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, u32 len) { u8 *cur_data = data; struct cdns_i2c_regs *regs = i2c_bus->regs; + u32 ret; /* Set the controller in Master transmit mode and clear FIFO */ setbits_le32(®s->control, CDNS_I2C_CONTROL_CLR_FIFO); @@ -255,25 +263,38 @@ static int cdns_i2c_write_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, writel(addr, ®s->address); - while (len--) { + while (len-- && !is_arbitration_lost(regs)) { writel(*(cur_data++), ®s->data); if (readl(®s->transfer_size) == CDNS_I2C_FIFO_DEPTH) { - if (!cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP)) { - /* Release the bus */ - clrbits_le32(®s->control, - CDNS_I2C_CONTROL_HOLD); - return -ETIMEDOUT; - } + ret = cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP | + CDNS_I2C_INTERRUPT_ARBLOST); + if (ret & CDNS_I2C_INTERRUPT_ARBLOST) + return -EAGAIN; + if (ret & CDNS_I2C_INTERRUPT_COMP) + continue; + /* Release the bus */ + clrbits_le32(®s->control, + CDNS_I2C_CONTROL_HOLD); + return -ETIMEDOUT; } } + if (len && is_arbitration_lost(regs)) + return -EAGAIN; + /* All done... release the bus */ if (!i2c_bus->hold_flag) clrbits_le32(®s->control, CDNS_I2C_CONTROL_HOLD); /* Wait for the address and data to be sent */ - if (!cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP)) + ret = cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP | + CDNS_I2C_INTERRUPT_ARBLOST); + if (!(ret & (CDNS_I2C_INTERRUPT_ARBLOST | + CDNS_I2C_INTERRUPT_COMP))) return -ETIMEDOUT; + if (ret & CDNS_I2C_INTERRUPT_ARBLOST) + return -EAGAIN; + return 0; } @@ -289,6 +310,7 @@ static int cdns_i2c_read_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, struct cdns_i2c_regs *regs = i2c_bus->regs; int curr_recv_count; int updatetx, hold_quirk; + u32 ret; /* Check the hardware can handle the requested bytes */ if ((recv_count < 0)) @@ -317,7 +339,7 @@ static int cdns_i2c_read_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, hold_quirk = (i2c_bus->quirks & CDNS_I2C_BROKEN_HOLD_BIT) && updatetx; - while (recv_count) { + while (recv_count && !is_arbitration_lost(regs)) { while (readl(®s->status) & CDNS_I2C_STATUS_RXDV) { if (recv_count < CDNS_I2C_FIFO_DEPTH && !i2c_bus->hold_flag) { @@ -366,8 +388,13 @@ static int cdns_i2c_read_data(struct i2c_cdns_bus *i2c_bus, u32 addr, u8 *data, } /* Wait for the address and data to be sent */ - if (!cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP)) + ret = cdns_i2c_wait(regs, CDNS_I2C_INTERRUPT_COMP | + CDNS_I2C_INTERRUPT_ARBLOST); + if (!(ret & (CDNS_I2C_INTERRUPT_ARBLOST | + CDNS_I2C_INTERRUPT_COMP))) return -ETIMEDOUT; + if (ret & CDNS_I2C_INTERRUPT_ARBLOST) + return -EAGAIN; return 0; } @@ -376,8 +403,11 @@ static int cdns_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs) { struct i2c_cdns_bus *i2c_bus = dev_get_priv(dev); - int ret, count; + int ret = 0; + int count; bool hold_quirk; + struct i2c_msg *message = msg; + int num_msgs = nmsgs; hold_quirk = !!(i2c_bus->quirks & CDNS_I2C_BROKEN_HOLD_BIT); @@ -403,7 +433,8 @@ static int cdns_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, } debug("i2c_xfer: %d messages\n", nmsgs); - for (; nmsgs > 0; nmsgs--, msg++) { + for (u8 retry = 0; retry < CDNS_I2C_ARB_LOST_MAX_RETRIES && + nmsgs > 0; nmsgs--, msg++) { debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len); if (msg->flags & I2C_M_RD) { ret = cdns_i2c_read_data(i2c_bus, msg->addr, msg->buf, @@ -412,13 +443,22 @@ static int cdns_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, ret = cdns_i2c_write_data(i2c_bus, msg->addr, msg->buf, msg->len); } + if (ret == -EAGAIN) { + msg = message; + nmsgs = num_msgs; + retry++; + printf("%s,arbitration lost, retrying:%d\n", __func__, + retry); + continue; + } + if (ret) { debug("i2c_write: error sending\n"); return -EREMOTEIO; } } - return 0; + return ret; } static int cdns_i2c_ofdata_to_platdata(struct udevice *dev)