From patchwork Tue Sep 26 23:48:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Packham X-Patchwork-Id: 145101 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:cae8:0:b0:403:3b70:6f57 with SMTP id r8csp2322999vqu; Tue, 26 Sep 2023 19:06:27 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEfNLgj3V1xVlR+AxakMq5uoYyX/hqL64UsCwS2JLX8LLE39ywFge9oC9xkMYO75rBt/Jcl X-Received: by 2002:aca:f11:0:b0:3a4:2485:85a1 with SMTP id 17-20020aca0f11000000b003a4248585a1mr817214oip.3.1695780387562; Tue, 26 Sep 2023 19:06:27 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1695780387; cv=none; d=google.com; s=arc-20160816; b=EoAqBOYJRWJ4wJ5pU9Zi16HLuq7fUcc/A91RnPoXEgmRpWEJoPHShs3zc57kespuK1 OG6skDf4DLarSUQCJrlhIX747OlbZ4ckNlAmCg1ajjAkYHMuaA6ZL1rHO0vwcyvlsLwY EA4AaKJuLyzu/x0v6aFNdv/8kdU40mPGNfYtcMLP8uwzOZO1sAtFocz+hwP6mdGSR+iv ybWsZwkWnC1+0shJGzsGK+w0F2MdtNpdLRJMgab5SJCHb/p865zT1xwf+INE1FA7Ll6k CK3E0qbMdcM3RHLQhafMG+9cu7aqRq3q7BcLLEeJz4gJE4IfB/Q+/eJhPBTJEwqSsysd bjSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=KR9YXJasf5jtvRl6VEb7GUZv9d995ayF9hchctxuvZ8=; fh=HVwtvmm9c22OJQLCUZL2inZSf9v419gurWyvDvs4c/s=; b=xatbiKfHRn6QrjBu6kxaxnvnsJ1At0ZGPLxXsOOa260GU0nSdzUKIBMI3oYitD+kVt TjX5Sz1uAfhVNZ3Rhy22aLSlyqba93jvPEEQoRElS0Rnm91DsNyUrQcdKmvy0RBCYl/M osAnNUBw+qrclGyEfaYedKIHVE3lHa1KPBOtzCH8Wy5nq1nDBYXxlX0OPHP0JDj27GBN u6MD86epy1zr7BzEG2DyroT6gSjT1lz1SnR9WSw6n7l3nIgj3Ntrt/JSNNYbXYoBynNo srD5fJZUr1JRLPh4of1D9Ro4BmtNS4LwTj3/PWdgAIXPxSEweOkNG1iU5iJ7niGaMI21 wwHA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@alliedtelesis.co.nz header.s=mail181024 header.b=yoC0VhJ3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=REJECT dis=NONE) header.from=alliedtelesis.co.nz Received: from howler.vger.email (howler.vger.email. [2620:137:e000::3:4]) by mx.google.com with ESMTPS id be3-20020a656e43000000b0057e5d66c200si11105309pgb.462.2023.09.26.19.06.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Sep 2023 19:06:27 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) client-ip=2620:137:e000::3:4; Authentication-Results: mx.google.com; dkim=pass header.i=@alliedtelesis.co.nz header.s=mail181024 header.b=yoC0VhJ3; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=REJECT dis=NONE) header.from=alliedtelesis.co.nz Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by howler.vger.email (Postfix) with ESMTP id 8E365832272A; Tue, 26 Sep 2023 17:39:09 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at howler.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231449AbjI0AjF (ORCPT + 28 others); Tue, 26 Sep 2023 20:39:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36836 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233192AbjI0AhE (ORCPT ); Tue, 26 Sep 2023 20:37:04 -0400 Received: from gate2.alliedtelesis.co.nz (gate2.alliedtelesis.co.nz [IPv6:2001:df5:b000:5::4]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 12B972D79 for ; Tue, 26 Sep 2023 16:48:10 -0700 (PDT) Received: from svr-chch-seg1.atlnz.lc (mmarshal3.atlnz.lc [10.32.18.43]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by gate2.alliedtelesis.co.nz (Postfix) with ESMTPS id 537702C066D; Wed, 27 Sep 2023 12:48:08 +1300 (NZDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alliedtelesis.co.nz; s=mail181024; t=1695772088; bh=KR9YXJasf5jtvRl6VEb7GUZv9d995ayF9hchctxuvZ8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=yoC0VhJ3EZVg8XM27manwPD9Ghj7zbdpeYO8W3Rt8RMx51ekI/8P/sLS2PUgmHiOV Dr+Ud48fuzjmUEjJ19Wg+u6uEiTV/5gpmyYWtqZU0/TDMsaTqHgl+EWVhjYML7wv9y A5rB17Td1K15jIfaY+UAldwsWx7/aS/Q/ifhehHS+r5SPCfVznZF2XBeRGskUH+z80 JyDAvq8+odXGb637ey7EQonPxThtMD+nwqu83r7tckchFf4v/eoYEEXnhnjjBikutB PaZIBQIYChyEDoLMDfJ2ldYyzMNQYhVVC1oKR58c4aU9iXDUc67h0hMbKDhY2wr3wJ syOVqhNgBL0Kg== Received: from pat.atlnz.lc (Not Verified[10.32.16.33]) by svr-chch-seg1.atlnz.lc with Trustwave SEG (v8,2,6,11305) id ; Wed, 27 Sep 2023 12:48:08 +1300 Received: from chrisp-dl.ws.atlnz.lc (chrisp-dl.ws.atlnz.lc [10.33.22.30]) by pat.atlnz.lc (Postfix) with ESMTP id EED7813EEA1; Wed, 27 Sep 2023 12:48:07 +1300 (NZDT) Received: by chrisp-dl.ws.atlnz.lc (Postfix, from userid 1030) id EDCB028160F; Wed, 27 Sep 2023 12:48:07 +1300 (NZDT) From: Chris Packham To: gregory.clement@bootlin.com, andi.shyti@kernel.org, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org, pierre.gondois@arm.com Cc: linux-i2c@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Chris Packham Subject: [PATCH 3/3] i2c: mv64xxx: add support for FSM based recovery Date: Wed, 27 Sep 2023 12:48:01 +1300 Message-ID: <20230926234801.4078042-4-chris.packham@alliedtelesis.co.nz> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230926234801.4078042-1-chris.packham@alliedtelesis.co.nz> References: <20230926234801.4078042-1-chris.packham@alliedtelesis.co.nz> MIME-Version: 1.0 X-SEG-SpamProfiler-Analysis: v=2.3 cv=fOpHIqSe c=1 sm=1 tr=0 a=KLBiSEs5mFS1a/PbTCJxuA==:117 a=zNV7Rl7Rt7sA:10 a=B8jpvDMl2VDXHxTB5w4A:9 X-SEG-SpamProfiler-Score: 0 x-atlnz-ls: pat X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (howler.vger.email [0.0.0.0]); Tue, 26 Sep 2023 17:39:09 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1778154615499983457 X-GMAIL-MSGID: 1778154615499983457 Some newer Marvell SoCs (AC5 and CN9130, possibly more) support a I2C unstuck function. This provides a recovery function as part of the FSM as an alternative to changing pinctrl modes and using the generic GPIO based recovery. Allow for using this by adding an optional resource to the platform data which contains the address of the I2C unstuck register for the I2C controller. Signed-off-by: Chris Packham --- drivers/i2c/busses/i2c-mv64xxx.c | 71 ++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index fd8403b07fa6..4345ab19b89c 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -82,6 +83,13 @@ /* Bridge Status values */ #define MV64XXX_I2C_BRIDGE_STATUS_ERROR BIT(0) +/* Unstuck Register values */ +#define MV64XXX_I2C_UNSTUCK_TRIGGER BIT(0) +#define MV64XXX_I2C_UNSTUCK_ON_GOING BIT(1) +#define MV64XXX_I2C_UNSTUCK_ERROR BIT(2) +#define MV64XXX_I2C_UNSTUCK_COUNT(val) ((val & 0xf0) >> 4) +#define MV64XXX_I2C_UNSTUCK_INPROGRESS (MV64XXX_I2C_UNSTUCK_TRIGGER|MV64XXX_I2C_UNSTUCK_ON_GOING) + /* Driver states */ enum { MV64XXX_I2C_STATE_INVALID, @@ -126,6 +134,7 @@ struct mv64xxx_i2c_data { u32 aborting; u32 cntl_bits; void __iomem *reg_base; + void __iomem *unstuck_reg; struct mv64xxx_i2c_regs reg_offsets; u32 addr1; u32 addr2; @@ -735,6 +744,33 @@ mv64xxx_i2c_can_offload(struct mv64xxx_i2c_data *drv_data) return false; } +static int +mv64xxx_i2c_recover_bus(struct i2c_adapter *adap) +{ + struct mv64xxx_i2c_data *drv_data = i2c_get_adapdata(adap); + int ret; + u32 val; + + dev_dbg(&adap->dev, "Trying i2c bus recovery\n"); + writel(MV64XXX_I2C_UNSTUCK_TRIGGER, drv_data->unstuck_reg); + ret = readl_poll_timeout_atomic(drv_data->unstuck_reg, val, + !(val & MV64XXX_I2C_UNSTUCK_INPROGRESS), + 1000, 5000); + if (ret) { + dev_err(&adap->dev, "recovery timeout\n"); + return ret; + } + + if (val & MV64XXX_I2C_UNSTUCK_ERROR) { + dev_err(&adap->dev, "recovery failed\n"); + return -EBUSY; + } + + dev_info(&adap->dev, "recovery complete after %d pulses\n", MV64XXX_I2C_UNSTUCK_COUNT(val)); + + return 0; +} + /* ***************************************************************************** * @@ -914,7 +950,8 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data, drv_data->errata_delay = true; } - if (of_device_is_compatible(np, "marvell,mv78230-a0-i2c")) { + if (of_device_is_compatible(np, "marvell,mv78230-a0-i2c") || + of_device_is_compatible(np, "marvell,armada-8k-i2c")) { drv_data->offload_enabled = false; /* The delay is only needed in standard mode (100kHz) */ if (bus_freq <= I2C_MAX_STANDARD_MODE_FREQ) @@ -936,8 +973,21 @@ mv64xxx_of_config(struct mv64xxx_i2c_data *drv_data, } #endif /* CONFIG_OF */ -static int mv64xxx_i2c_init_recovery_info(struct mv64xxx_i2c_data *drv_data, - struct device *dev) +static int mv64xxx_i2c_init_fsm_recovery_info(struct mv64xxx_i2c_data *drv_data, + struct device *dev) +{ + struct i2c_bus_recovery_info *rinfo = &drv_data->rinfo; + + dev_info(dev, "using FSM for recovery\n"); + rinfo->recover_bus = mv64xxx_i2c_recover_bus; + drv_data->adapter.bus_recovery_info = rinfo; + + return 0; + +} + +static int mv64xxx_i2c_init_gpio_recovery_info(struct mv64xxx_i2c_data *drv_data, + struct device *dev) { struct i2c_bus_recovery_info *rinfo = &drv_data->rinfo; @@ -986,6 +1036,7 @@ mv64xxx_i2c_probe(struct platform_device *pd) { struct mv64xxx_i2c_data *drv_data; struct mv64xxx_i2c_pdata *pdata = dev_get_platdata(&pd->dev); + struct resource *res; int rc; if ((!pdata && !pd->dev.of_node)) @@ -1000,6 +1051,14 @@ mv64xxx_i2c_probe(struct platform_device *pd) if (IS_ERR(drv_data->reg_base)) return PTR_ERR(drv_data->reg_base); + /* optional unstuck support */ + res = platform_get_resource(pd, IORESOURCE_MEM, 1); + if (res) { + drv_data->unstuck_reg = devm_ioremap_resource(&pd->dev, res); + if (IS_ERR(drv_data->unstuck_reg)) + return PTR_ERR(drv_data->unstuck_reg); + } + strscpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME " adapter", sizeof(drv_data->adapter.name)); @@ -1037,7 +1096,11 @@ mv64xxx_i2c_probe(struct platform_device *pd) return rc; } - rc = mv64xxx_i2c_init_recovery_info(drv_data, &pd->dev); + if (drv_data->unstuck_reg) + rc = mv64xxx_i2c_init_fsm_recovery_info(drv_data, &pd->dev); + else + rc = mv64xxx_i2c_init_gpio_recovery_info(drv_data, &pd->dev); + if (rc == -EPROBE_DEFER) return rc;