From patchwork Mon Aug 5 09:56:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ludovic BARRE X-Patchwork-Id: 11076427 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 00FA8912 for ; Mon, 5 Aug 2019 09:57:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DEAEF28821 for ; Mon, 5 Aug 2019 09:57:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D002E28876; Mon, 5 Aug 2019 09:57:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 64FD328821 for ; Mon, 5 Aug 2019 09:57:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=12D1rSGOza2t6NkA8wZ/O7HQhoSoxw4U03IN176DkLQ=; b=JMprVbjolfqSlr 6OhUqmJQmNGy5h5MveffWQfhqVxrRJv4ucMLlqBfAw961oTlSi2CnKShS0DO0+aGp88MyBK3gdT8u ZtN+uvm+N8TtHWpb9EmTt6x61XvfulM4fGzmInrqzHmQtObNG66SZKWW5R6GiddemjKZD0eCKueOW MrK4r7X4IyW7qvUwOpTDHgwm0N7jKcpMg9pYGndcosoBqjW3xWl5fqH9TeyD+0mone1Yl1XDHbRkL +Ck6wjtP+g2iP9gvxy5glPDmEtf+ILCSGfpy+DxQKboVFetxGg4KAYfjefci0kC1rTR087OdY9zSG VuT18Qf1e7RE8XV7N3Qw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1huZkL-0003Aj-SV; Mon, 05 Aug 2019 09:57:42 +0000 Received: from mx08-00178001.pphosted.com ([91.207.212.93] helo=mx07-00178001.pphosted.com) by bombadil.infradead.org with esmtps (Exim 4.92 #3 (Red Hat Linux)) id 1huZjl-0002cq-Dv for linux-arm-kernel@lists.infradead.org; Mon, 05 Aug 2019 09:57:08 +0000 Received: from pps.filterd (m0046661.ppops.net [127.0.0.1]) by mx08-00178001.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x758asfg025755; Mon, 5 Aug 2019 11:57:00 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=STMicroelectronics; bh=wuSEYQ/MVeznlvXAHY047ivvLEOAFrfYgBPlSUOUncM=; b=ZRBcDBjIaGGzGjohNTqHqzM/OUpHtM0lRm08NzQKbw6+2MLPHNjhtXags1ddVKLqEL8+ x40xlsCPSN1gU9Ew5+3NKTtdlYQ+iwmpb35YkRdgxWy8o5B8ijABbh3PwuET4RwumaPT RzDRVpZbJIS5K8ti/OFW1D3Bwwjw9u2MMgY493MMGDG9rtaVUGtU6bYE92IMCfP0kv1v YxAx48ki7Pa4r0PTNfv2QpQWoD2zz0qKoWHAvv7rHF+UR3BQLolmMlZZAQj5IhqqEFC4 7luvxL/9CkJ4yhmJva+y0XhhIdCBFoZUeI9x8ArtQlH9AGnF6fTjsXAebaFwia4zxrV2 IQ== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx08-00178001.pphosted.com with ESMTP id 2u515mamub-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Mon, 05 Aug 2019 11:57:00 +0200 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id C4F2C41; Mon, 5 Aug 2019 09:56:59 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas22.st.com [10.75.90.92]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id B65AD3023C2; Mon, 5 Aug 2019 11:56:59 +0200 (CEST) Received: from SAFEX1HUBCAS23.st.com (10.75.90.47) by Safex1hubcas22.st.com (10.75.90.92) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 5 Aug 2019 11:56:59 +0200 Received: from lmecxl0923.lme.st.com (10.48.0.237) by webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 5 Aug 2019 11:56:59 +0200 From: Ludovic Barre To: Ulf Hansson , Rob Herring Subject: [PATCH V4 1/3] mmc: mmci: add hardware busy timeout feature Date: Mon, 5 Aug 2019 11:56:24 +0200 Message-ID: <20190805095626.25998-2-ludovic.Barre@st.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190805095626.25998-1-ludovic.Barre@st.com> References: <20190805095626.25998-1-ludovic.Barre@st.com> MIME-Version: 1.0 X-Originating-IP: [10.48.0.237] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-08-05_04:, , signatures=0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190805_025705_763595_7D7225CB X-CRM114-Status: GOOD ( 20.13 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Alexandre Torgue , linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, srinivas.kandagatla@linaro.org, Ludovic Barre , Maxime Coquelin , linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ludovic Barre In some variants, the data timer starts and decrements when the DPSM enters in Wait_R or Busy state (while data transfer or MMC_RSP_BUSY), and generates a data timeout error if the counter reach 0. -Define max_busy_timeout (in ms) according to clock. -Set data timer register if the command has rsp_busy flag. If busy_timeout is not defined by framework, the busy length after Data Burst is defined as 1 second (refer: 4.6.2.2 Write of sd specification part1 v6-0). -Add MCI_DATATIMEOUT error management in mmci_cmd_irq. Signed-off-by: Ludovic Barre --- drivers/mmc/host/mmci.c | 37 ++++++++++++++++++++++++++++++++----- drivers/mmc/host/mmci.h | 3 +++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 4c35e7609c89..e79c9148af84 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1078,6 +1078,7 @@ static void mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) { void __iomem *base = host->base; + unsigned long long clks = 0; dev_dbg(mmc_dev(host->mmc), "op %02x arg %08x flags %08x\n", cmd->opcode, cmd->arg, cmd->flags); @@ -1100,6 +1101,19 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) else c |= host->variant->cmdreg_srsp; } + + if (host->variant->busy_timeout && !cmd->data) { + if (cmd->flags & MMC_RSP_BUSY) { + if (!cmd->busy_timeout) + cmd->busy_timeout = 1000; + + clks = (unsigned long long)cmd->busy_timeout; + clks *= host->cclk; + do_div(clks, MSEC_PER_SEC); + } + writel_relaxed(clks, host->base + MMCIDATATIMER); + } + if (/*interrupt*/0) c |= MCI_CPSM_INTERRUPT; @@ -1206,6 +1220,7 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, { void __iomem *base = host->base; bool sbc, busy_resp; + u32 err_msk; if (!cmd) return; @@ -1218,8 +1233,12 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, * handling. Note that we tag on any latent IRQs postponed * due to waiting for busy status. */ - if (!((status|host->busy_status) & - (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT|MCI_CMDRESPEND))) + err_msk = MCI_CMDCRCFAIL | MCI_CMDTIMEOUT; + if (host->variant->busy_timeout && busy_resp) + err_msk |= MCI_DATATIMEOUT; + + if (!((status | host->busy_status) & + (err_msk | MCI_CMDSENT | MCI_CMDRESPEND))) return; /* Handle busy detection on DAT0 if the variant supports it. */ @@ -1238,8 +1257,7 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, * while, to allow it to be set, but tests indicates that it * isn't needed. */ - if (!host->busy_status && - !(status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT)) && + if (!host->busy_status && !(status & err_msk) && (readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) { writel(readl(base + MMCIMASK0) | @@ -1293,6 +1311,9 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, cmd->error = -ETIMEDOUT; } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) { cmd->error = -EILSEQ; + } else if (host->variant->busy_timeout && busy_resp && + status & MCI_DATATIMEOUT) { + cmd->error = -ETIMEDOUT; } else { cmd->resp[0] = readl(base + MMCIRESPONSE0); cmd->resp[1] = readl(base + MMCIRESPONSE1); @@ -1951,6 +1972,8 @@ static int mmci_probe(struct amba_device *dev, * Enable busy detection. */ if (variant->busy_detect) { + u32 max_busy_timeout = 0; + mmci_ops.card_busy = mmci_card_busy; /* * Not all variants have a flag to enable busy detection @@ -1960,7 +1983,11 @@ static int mmci_probe(struct amba_device *dev, mmci_write_datactrlreg(host, host->variant->busy_dpsm_flag); mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY; - mmc->max_busy_timeout = 0; + + if (variant->busy_timeout) + max_busy_timeout = ~0UL / (mmc->f_max / MSEC_PER_SEC); + + mmc->max_busy_timeout = max_busy_timeout; } /* Prepare a CMD12 - needed to clear the DPSM on some variants. */ diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 4f071bd34e59..8f86130af566 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -290,6 +290,8 @@ struct mmci_host; * @signal_direction: input/out direction of bus signals can be indicated * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock * @busy_detect: true if the variant supports busy detection on DAT0. + * @busy_timeout: true if the variant starts data timer when the DPSM + * enter in Wait_R or Busy state. * @busy_dpsm_flag: bitmask enabling busy detection in the DPSM * @busy_detect_flag: bitmask identifying the bit in the MMCISTATUS register * indicating that the card is busy @@ -336,6 +338,7 @@ struct variant_data { u8 signal_direction:1; u8 pwrreg_clkgate:1; u8 busy_detect:1; + u8 busy_timeout:1; u32 busy_dpsm_flag; u32 busy_detect_flag; u32 busy_detect_mask; From patchwork Mon Aug 5 09:56:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ludovic BARRE X-Patchwork-Id: 11076425 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 742DA912 for ; Mon, 5 Aug 2019 09:57:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5DFF628821 for ; Mon, 5 Aug 2019 09:57:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5197928876; Mon, 5 Aug 2019 09:57:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A8C1028821 for ; Mon, 5 Aug 2019 09:57:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=8CWo975pP2KL7A5zLJ7kITu2b+q/qLsAXMNYJ7e5YZU=; b=PLALD4qlEaTh+i DxSLOVkghm7ZUX/s/3IrMO3b9KLWV4SOMeqcUcIbNc7XidtERv1rDu0OpiDZwtpl30w81durnyxVI vgCv2NH+dIZ52YkKfNaQto89cHNrTp6g6XXXphUNli2JKtQLiAuuEK3AwrKtNn2pwXuUa0osyAOKm BydpBFtnlPvf3f+U3blNIoYS6O4t6GuCdnUE5nngsdaJYP/zI0HwhOJn1af7S8wvVpH6GMBTp9kgL ldxdsO5N8qakWqrVVdaazhUWO0XoqzNqdSk+3ffKrqHXFaVlsxmAHPCC4c+/CcFHSkzI/VTyqyFhd mw7WsCcpfxUUpvkpbD7g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1huZk1-0002rK-36; Mon, 05 Aug 2019 09:57:21 +0000 Received: from mx08-00178001.pphosted.com ([91.207.212.93] helo=mx07-00178001.pphosted.com) by bombadil.infradead.org with esmtps (Exim 4.92 #3 (Red Hat Linux)) id 1huZjl-0002cr-DS for linux-arm-kernel@lists.infradead.org; Mon, 05 Aug 2019 09:57:07 +0000 Received: from pps.filterd (m0046661.ppops.net [127.0.0.1]) by mx08-00178001.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x758b0Bf025774; Mon, 5 Aug 2019 11:57:01 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=STMicroelectronics; bh=HhMLvIci0XNKBxu8OuxEsLilXfrP4DiUeaBHrlEWBIA=; b=d7FxkcHBasHY2AtACKgcp26n9gNkG21/BXwYnjhEPWD7kxgbUCnY9fuRTyYrCxcoTRkF tRe9tL/qgsM/wvt6zARiiteD3d35VOPI5iAdPpONfgmkAemKnww8hMhjjaHrDNqekSM4 b1KJnP27R8i5jQ5ps27A9bM//bmtYyi8tz0TbMvTvHZAeJlsmpyeylpDbuNNX6M9Oypp fTAOW2o+WzFbLuYLOnmIWxuytqDLpyfJ8ibdCbCiYTW4kW6uM1ozIFVs7LwzET9LfYaE zr7t+bhOWfg4HWuzpskvUk2zJ9qJ4U/o/LnX+7gPoOJ31xZBEQFcQbdWWXXPDaRSR33B og== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx08-00178001.pphosted.com with ESMTP id 2u515mamue-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Mon, 05 Aug 2019 11:57:01 +0200 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id CC59331; Mon, 5 Aug 2019 09:57:00 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas21.st.com [10.75.90.44]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id B433C3023C1; Mon, 5 Aug 2019 11:57:00 +0200 (CEST) Received: from SAFEX1HUBCAS23.st.com (10.75.90.47) by SAFEX1HUBCAS21.st.com (10.75.90.44) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 5 Aug 2019 11:57:00 +0200 Received: from lmecxl0923.lme.st.com (10.48.0.237) by webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 5 Aug 2019 11:57:00 +0200 From: Ludovic Barre To: Ulf Hansson , Rob Herring Subject: [PATCH V4 2/3] mmc: mmci: add busy_complete callback Date: Mon, 5 Aug 2019 11:56:25 +0200 Message-ID: <20190805095626.25998-3-ludovic.Barre@st.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190805095626.25998-1-ludovic.Barre@st.com> References: <20190805095626.25998-1-ludovic.Barre@st.com> MIME-Version: 1.0 X-Originating-IP: [10.48.0.237] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-08-05_04:, , signatures=0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190805_025705_750052_0342F58D X-CRM114-Status: GOOD ( 24.24 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Alexandre Torgue , linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, srinivas.kandagatla@linaro.org, Ludovic Barre , Maxime Coquelin , linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ludovic Barre This patch adds busy_completion callback at mmci_host_ops to allow to define a specific busy completion by variant. The legacy code corresponding to busy completion used by ux500 variants is moved to ux500_busy_complete function. The busy_detect boolean property is replaced by busy_complete callback definition. Signed-off-by: Ludovic Barre --- drivers/mmc/host/mmci.c | 140 +++++++++++++++++++++------------------- drivers/mmc/host/mmci.h | 3 +- 2 files changed, 75 insertions(+), 68 deletions(-) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index e79c9148af84..17948615d4a5 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -47,6 +47,7 @@ #define DRIVER_NAME "mmci-pl18x" static void mmci_variant_init(struct mmci_host *host); +static void ux500_variant_init(struct mmci_host *host); static void ux500v2_variant_init(struct mmci_host *host); static unsigned int fmax = 515633; @@ -178,7 +179,6 @@ static struct variant_data variant_ux500 = { .f_max = 100000000, .signal_direction = true, .pwrreg_clkgate = true, - .busy_detect = true, .busy_dpsm_flag = MCI_DPSM_ST_BUSYMODE, .busy_detect_flag = MCI_ST_CARDBUSY, .busy_detect_mask = MCI_ST_BUSYENDMASK, @@ -187,7 +187,7 @@ static struct variant_data variant_ux500 = { .irq_pio_mask = MCI_IRQ_PIO_MASK, .start_err = MCI_STARTBITERR, .opendrain = MCI_OD, - .init = mmci_variant_init, + .init = ux500_variant_init, }; static struct variant_data variant_ux500v2 = { @@ -211,7 +211,6 @@ static struct variant_data variant_ux500v2 = { .f_max = 100000000, .signal_direction = true, .pwrreg_clkgate = true, - .busy_detect = true, .busy_dpsm_flag = MCI_DPSM_ST_BUSYMODE, .busy_detect_flag = MCI_ST_CARDBUSY, .busy_detect_mask = MCI_ST_BUSYENDMASK, @@ -613,6 +612,67 @@ static u32 ux500v2_get_dctrl_cfg(struct mmci_host *host) return MCI_DPSM_ENABLE | (host->data->blksz << 16); } +static bool ux500_busy_complete(struct mmci_host *host, u32 status, u32 err_msk) +{ + void __iomem *base = host->base; + + /* + * Before unmasking for the busy end IRQ, confirm that the + * command was sent successfully. To keep track of having a + * command in-progress, waiting for busy signaling to end, + * store the status in host->busy_status. + * + * Note that, the card may need a couple of clock cycles before + * it starts signaling busy on DAT0, hence re-read the + * MMCISTATUS register here, to allow the busy bit to be set. + * Potentially we may even need to poll the register for a + * while, to allow it to be set, but tests indicates that it + * isn't needed. + */ + if (!host->busy_status && !(status & err_msk) && + (readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) { + writel(readl(base + MMCIMASK0) | + host->variant->busy_detect_mask, + base + MMCIMASK0); + + host->busy_status = status & (MCI_CMDSENT | MCI_CMDRESPEND); + return false; + } + + /* + * If there is a command in-progress that has been successfully + * sent, then bail out if busy status is set and wait for the + * busy end IRQ. + * + * Note that, the HW triggers an IRQ on both edges while + * monitoring DAT0 for busy completion, but there is only one + * status bit in MMCISTATUS for the busy state. Therefore + * both the start and the end interrupts needs to be cleared, + * one after the other. So, clear the busy start IRQ here. + */ + if (host->busy_status && + (status & host->variant->busy_detect_flag)) { + writel(host->variant->busy_detect_mask, base + MMCICLEAR); + return false; + } + + /* + * If there is a command in-progress that has been successfully + * sent and the busy bit isn't set, it means we have received + * the busy end IRQ. Clear and mask the IRQ, then continue to + * process the command. + */ + if (host->busy_status) { + writel(host->variant->busy_detect_mask, base + MMCICLEAR); + + writel(readl(base + MMCIMASK0) & + ~host->variant->busy_detect_mask, base + MMCIMASK0); + host->busy_status = 0; + } + + return true; +} + /* * All the DMA operation mode stuff goes inside this ifdef. * This assumes that you have a generic DMA device interface, @@ -956,9 +1016,16 @@ void mmci_variant_init(struct mmci_host *host) host->ops = &mmci_variant_ops; } +void ux500_variant_init(struct mmci_host *host) +{ + host->ops = &mmci_variant_ops; + host->ops->busy_complete = ux500_busy_complete; +} + void ux500v2_variant_init(struct mmci_host *host) { host->ops = &mmci_variant_ops; + host->ops->busy_complete = ux500_busy_complete; host->ops->get_datactrl_cfg = ux500v2_get_dctrl_cfg; } @@ -1242,68 +1309,9 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd, return; /* Handle busy detection on DAT0 if the variant supports it. */ - if (busy_resp && host->variant->busy_detect) { - - /* - * Before unmasking for the busy end IRQ, confirm that the - * command was sent successfully. To keep track of having a - * command in-progress, waiting for busy signaling to end, - * store the status in host->busy_status. - * - * Note that, the card may need a couple of clock cycles before - * it starts signaling busy on DAT0, hence re-read the - * MMCISTATUS register here, to allow the busy bit to be set. - * Potentially we may even need to poll the register for a - * while, to allow it to be set, but tests indicates that it - * isn't needed. - */ - if (!host->busy_status && !(status & err_msk) && - (readl(base + MMCISTATUS) & host->variant->busy_detect_flag)) { - - writel(readl(base + MMCIMASK0) | - host->variant->busy_detect_mask, - base + MMCIMASK0); - - host->busy_status = - status & (MCI_CMDSENT|MCI_CMDRESPEND); - return; - } - - /* - * If there is a command in-progress that has been successfully - * sent, then bail out if busy status is set and wait for the - * busy end IRQ. - * - * Note that, the HW triggers an IRQ on both edges while - * monitoring DAT0 for busy completion, but there is only one - * status bit in MMCISTATUS for the busy state. Therefore - * both the start and the end interrupts needs to be cleared, - * one after the other. So, clear the busy start IRQ here. - */ - if (host->busy_status && - (status & host->variant->busy_detect_flag)) { - writel(host->variant->busy_detect_mask, - host->base + MMCICLEAR); + if (busy_resp && host->ops->busy_complete) + if (!host->ops->busy_complete(host, status, err_msk)) return; - } - - /* - * If there is a command in-progress that has been successfully - * sent and the busy bit isn't set, it means we have received - * the busy end IRQ. Clear and mask the IRQ, then continue to - * process the command. - */ - if (host->busy_status) { - - writel(host->variant->busy_detect_mask, - host->base + MMCICLEAR); - - writel(readl(base + MMCIMASK0) & - ~host->variant->busy_detect_mask, - base + MMCIMASK0); - host->busy_status = 0; - } - } host->cmd = NULL; @@ -1544,7 +1552,7 @@ static irqreturn_t mmci_irq(int irq, void *dev_id) * clear the corresponding IRQ. */ status &= readl(host->base + MMCIMASK0); - if (host->variant->busy_detect) + if (host->ops->busy_complete) writel(status & ~host->variant->busy_detect_mask, host->base + MMCICLEAR); else @@ -1971,7 +1979,7 @@ static int mmci_probe(struct amba_device *dev, /* * Enable busy detection. */ - if (variant->busy_detect) { + if (host->ops->busy_complete) { u32 max_busy_timeout = 0; mmci_ops.card_busy = mmci_card_busy; diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 8f86130af566..03eb21f1c258 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -289,7 +289,6 @@ struct mmci_host; * @f_max: maximum clk frequency supported by the controller. * @signal_direction: input/out direction of bus signals can be indicated * @pwrreg_clkgate: MMCIPOWER register must be used to gate the clock - * @busy_detect: true if the variant supports busy detection on DAT0. * @busy_timeout: true if the variant starts data timer when the DPSM * enter in Wait_R or Busy state. * @busy_dpsm_flag: bitmask enabling busy detection in the DPSM @@ -337,7 +336,6 @@ struct variant_data { u32 f_max; u8 signal_direction:1; u8 pwrreg_clkgate:1; - u8 busy_detect:1; u8 busy_timeout:1; u32 busy_dpsm_flag; u32 busy_detect_flag; @@ -372,6 +370,7 @@ struct mmci_host_ops { void (*dma_error)(struct mmci_host *host); void (*set_clkreg)(struct mmci_host *host, unsigned int desired); void (*set_pwrreg)(struct mmci_host *host, unsigned int pwr); + bool (*busy_complete)(struct mmci_host *host, u32 status, u32 err_msk); }; struct mmci_host { From patchwork Mon Aug 5 09:56:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ludovic BARRE X-Patchwork-Id: 11076431 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B051C13A4 for ; Mon, 5 Aug 2019 09:57:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9B48F28821 for ; Mon, 5 Aug 2019 09:57:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8F10128876; Mon, 5 Aug 2019 09:57:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 32B9328821 for ; Mon, 5 Aug 2019 09:57:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=4HUJmLdzZo6H/wQ1WrKy8lzBWypyg+ZuFKiLTzChMC4=; b=RJHSxciYToPpyE 5xcTA2hqY0LxZqKo/V6j+daj13UZgPeqoXL/MOWm+0bXRtGIwR6jb0KjdxFC0CIsXJKCcXbS0P7bI so1t9gqbLuThtdGkcM2QhqwhHlq/25OVXR+yfK5njU12IY8+CeiFk0Lbe7mA/91xN5x0CKC0DKEF3 YYu2QHvrf6xItF5iWiVWEetkXrqQJYsO4dqj22ISsuJROj2qxuvlFjDwgpcHoTMtkrIxjb8lk9tt/ I2pRPbnBA8fI8TQSumdNW8rtYsP+P4uMYXWlZjB9HrxAcssasGXcSsndHYPQoCuYH/jXQ0dXsyJ7K 5Gc17tgPnfUIRB4VQ20g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92 #3 (Red Hat Linux)) id 1huZkZ-0003Qc-GB; Mon, 05 Aug 2019 09:57:55 +0000 Received: from mx08-00178001.pphosted.com ([91.207.212.93] helo=mx07-00178001.pphosted.com) by bombadil.infradead.org with esmtps (Exim 4.92 #3 (Red Hat Linux)) id 1huZjm-0002cv-9c for linux-arm-kernel@lists.infradead.org; Mon, 05 Aug 2019 09:57:08 +0000 Received: from pps.filterd (m0046661.ppops.net [127.0.0.1]) by mx08-00178001.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x758asW8025758; Mon, 5 Aug 2019 11:57:02 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=STMicroelectronics; bh=FIN1+WtDIWXZ7utxK2//s0wwSgswbkM3U9ncM0xs0qw=; b=YPP9bYTuL6rDIP5MrIbvl/sp/wjHoVvcQnT78jxzrbRrjEjqnFG2G2pPBS/gHUE6UKMr v26o/hzkPlSr46QjhMd7uOnnqYTcGqcIqa5VZXalTnmhrLOqyqs8Xl9u+qvbAkBPyCjU OCwBYagL1SpMi69hw1Cl4Ajpqjgft57GLuIaKmIlgdy9V7pCkXYcZFACPCrqy9kcCoL+ Q2QqJZyjoqVsQs1W0iUuGP6CmafzDy/NS+RAU/r/EW/yh1WIBQyt34Uf2eG9gvlPrwr9 GHzPmL1ExSayKiTHaU2almPfXzmSkbeQArxdSLfGMGW39E712i+KjOEeECouXOJrKWgw nQ== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx08-00178001.pphosted.com with ESMTP id 2u515mamuf-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Mon, 05 Aug 2019 11:57:02 +0200 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id BDA2C34; Mon, 5 Aug 2019 09:57:01 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas24.st.com [10.75.90.94]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id AF6A13023C1; Mon, 5 Aug 2019 11:57:01 +0200 (CEST) Received: from SAFEX1HUBCAS23.st.com (10.75.90.47) by Safex1hubcas24.st.com (10.75.90.94) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 5 Aug 2019 11:57:01 +0200 Received: from lmecxl0923.lme.st.com (10.48.0.237) by webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.439.0; Mon, 5 Aug 2019 11:57:01 +0200 From: Ludovic Barre To: Ulf Hansson , Rob Herring Subject: [PATCH V4 3/3] mmc: mmci: sdmmc: add busy_complete callback Date: Mon, 5 Aug 2019 11:56:26 +0200 Message-ID: <20190805095626.25998-4-ludovic.Barre@st.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190805095626.25998-1-ludovic.Barre@st.com> References: <20190805095626.25998-1-ludovic.Barre@st.com> MIME-Version: 1.0 X-Originating-IP: [10.48.0.237] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2019-08-05_04:, , signatures=0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190805_025706_614166_766A3AA6 X-CRM114-Status: GOOD ( 19.63 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Alexandre Torgue , linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org, srinivas.kandagatla@linaro.org, Ludovic Barre , Maxime Coquelin , linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Ludovic Barre This patch adds a specific busy_complete callback for sdmmc variant. sdmmc has 2 status flags: -busyd0: This is a hardware status flag (inverted value of d0 line). it does not generate an interrupt. -busyd0end: This indicates only end of busy following a CMD response. On busy to Not busy changes, an interrupt is generated (if unmask) and BUSYD0END status flag is set. Status flag is cleared by writing corresponding interrupt clear bit in MMCICLEAR. The legacy busy completion monitors step by step the busy progression start/in-progress/end. On sdmmc variant, the monitoring of busy steps is difficult and not adapted (the software can miss a step and locks the monitoring), the sdmmc has just need to wait the busyd0end bit without monitoring all the changes. Signed-off-by: Ludovic Barre --- drivers/mmc/host/mmci.c | 3 +++ drivers/mmc/host/mmci.h | 1 + drivers/mmc/host/mmci_stm32_sdmmc.c | 38 +++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 17948615d4a5..2751415d0fd1 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -263,6 +263,9 @@ static struct variant_data variant_stm32_sdmmc = { .datalength_bits = 25, .datactrl_blocksz = 14, .stm32_idmabsize_mask = GENMASK(12, 5), + .busy_timeout = true, + .busy_detect_flag = MCI_STM32_BUSYD0, + .busy_detect_mask = MCI_STM32_BUSYD0ENDMASK, .init = sdmmc_variant_init, }; diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 03eb21f1c258..64ae7720477c 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -167,6 +167,7 @@ #define MCI_ST_CARDBUSY (1 << 24) /* Extended status bits for the STM32 variants */ #define MCI_STM32_BUSYD0 BIT(20) +#define MCI_STM32_BUSYD0END BIT(21) #define MMCICLEAR 0x038 #define MCI_CMDCRCFAILCLR (1 << 0) diff --git a/drivers/mmc/host/mmci_stm32_sdmmc.c b/drivers/mmc/host/mmci_stm32_sdmmc.c index 8e83ae6920ae..bb5499cc9e81 100644 --- a/drivers/mmc/host/mmci_stm32_sdmmc.c +++ b/drivers/mmc/host/mmci_stm32_sdmmc.c @@ -282,6 +282,43 @@ static u32 sdmmc_get_dctrl_cfg(struct mmci_host *host) return datactrl; } +bool sdmmc_busy_complete(struct mmci_host *host, u32 status, u32 err_msk) +{ + void __iomem *base = host->base; + u32 busy_d0, busy_d0end, mask; + + mask = readl_relaxed(base + MMCIMASK0); + busy_d0end = readl_relaxed(base + MMCISTATUS) & MCI_STM32_BUSYD0END; + busy_d0 = readl_relaxed(base + MMCISTATUS) & MCI_STM32_BUSYD0; + + /* complete if there is an error or busy_d0end */ + if ((status & err_msk) || busy_d0end) + goto complete; + + /* + * On response the busy signaling is reflected in the BUSYD0 flag. + * if busy_d0 is in-progress we must activate busyd0end interrupt + * to wait this completion. Else this request has no busy step. + */ + if (busy_d0) { + if (!host->busy_status) { + writel_relaxed(mask | host->variant->busy_detect_mask, + base + MMCIMASK0); + host->busy_status = status & + (MCI_CMDSENT | MCI_CMDRESPEND); + } + return false; + } + +complete: + writel_relaxed(mask & ~host->variant->busy_detect_mask, + base + MMCIMASK0); + writel_relaxed(host->variant->busy_detect_mask, base + MMCICLEAR); + host->busy_status = 0; + + return true; +} + static struct mmci_host_ops sdmmc_variant_ops = { .validate_data = sdmmc_idma_validate_data, .prep_data = sdmmc_idma_prep_data, @@ -292,6 +329,7 @@ static struct mmci_host_ops sdmmc_variant_ops = { .dma_finalize = sdmmc_idma_finalize, .set_clkreg = mmci_sdmmc_set_clkreg, .set_pwrreg = mmci_sdmmc_set_pwrreg, + .busy_complete = sdmmc_busy_complete, }; void sdmmc_variant_init(struct mmci_host *host)