From mboxrd@z Thu Jan 1 00:00:00 1970 From: Shawn Lin Subject: Re: [PATCH v2] mmc: sunxi: Don't start commands while the card is busy Date: Wed, 29 Jul 2015 08:40:52 +0800 Message-ID: <55B82114.5000505@rock-chips.com> References: <1436541284-11800-1-git-send-email-hdegoede@redhat.com> <55B7D676.1020800@broadcom.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: QUOTED-PRINTABLE Return-path: In-Reply-To: <55B7D676.1020800@broadcom.com> Sender: linux-mmc-owner@vger.kernel.org To: Arend van Spriel , Ulf Hansson , Hans de Goede Cc: shawn.lin@rock-chips.com, Chris Ball , Mike Turquette , Maxime Ripard , Sascha Hauer , linux-mmc , "linux-arm-kernel@lists.infradead.org" , devicetree , linux-sunxi@googlegroups.com, Eugene K List-Id: devicetree@vger.kernel.org =E5=9C=A8 2015/7/29 3:22, Arend van Spriel =E5=86=99=E9=81=93: > On 07/21/2015 02:15 PM, Ulf Hansson wrote: >> On 10 July 2015 at 17:14, Hans de Goede wrote: >>> Some sdio wifi modules have not been working reliable with the sunx= i-mmc >>> host code. This turns out to be caused by it starting new commands = while >>> the card signals that it is still busy processing a previous comman= d. >> >> Which are those commands? Or more interesting, which response types = do >> these commands expect? >> I don't think this is a sunxi specific issue, I have seen similar >> issues for other host controllers. > > Indeed. A similar fix was needed for dw_mmc host controller. bit 10 in STATUS register of sysnopsys dw_mmc should be issued each tim= e=20 you start a new cmd. It's hard to say whetehr a local hack or not,=20 because it's a mandatory requirement from IP databook(refer to=20 "Sysnopsys DesignWare cores Mobile Storage Host Databook" Chapter 7-=20 Programming the DWC_mobile_storage). Bit 10: indicate state-machine is ready, controller MUST guarantee all I/O used in "free state", actually high. If dw_mmc's state-machine isn't ready, NO cmd can be issued, which mean= s=20 even we configure cmd and cmdarg, start bit cannot be auto-clean by=20 controller that leads to no cmd_done interrupt generated which dw_mmc's= =20 tasklet state-machine need. > >> I am thinking that perhaps this should be managed by the mmc core >> instead of local hacks to sunxi. Potentially we could make the core = to >> invoke the already existing host_ops->card_busy() callback when >> needed... > > The problem here is that there are a number of host controllers out > there not implementing that callback. That may be because the hardwar= e > is dealing properly with busy signalling, but I would not bet on that= =2E > > Regards, > Arend > >> Within this context, could I ask whether you controller supports IRQ >> based HW-busy detection? Or you need polling of the status register? >> >>> >>> This commit fixes this, thereby fixing the wifi reliability issues = on >>> the Cubietruck and other sunxi boards using sdio wifi. >>> >>> Reported-by: Eugene K >>> Suggested-by: Eugene K >>> Cc: Eugene K >>> Cc: Arend van Spriel >>> Signed-off-by: Hans de Goede >>> --- >>> Changes in v2: >>> -Properly accredit Eugene K for coming up with the fix for this >>> --- >>> drivers/mmc/host/sunxi-mmc.c | 32 +++++++++++++++++++++++++++++++= + >>> 1 file changed, 32 insertions(+) >>> >>> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-= mmc.c >>> index 4d3e1ff..daa90b7 100644 >>> --- a/drivers/mmc/host/sunxi-mmc.c >>> +++ b/drivers/mmc/host/sunxi-mmc.c >>> @@ -289,6 +289,24 @@ static int sunxi_mmc_init_host(struct mmc_host >>> *mmc) >>> return 0; >>> } >>> >>> +/* Wait for card to report ready before starting a new cmd */ >>> +static int sunxi_mmc_wait_card_ready(struct sunxi_mmc_host *host) >>> +{ >>> + unsigned long expire =3D jiffies + msecs_to_jiffies(500); >>> + u32 rval; >>> + >>> + do { >>> + rval =3D mmc_readl(host, REG_STAS); >>> + } while (time_before(jiffies, expire) && (rval & >>> SDXC_CARD_DATA_BUSY)); >>> + >>> + if (rval & SDXC_CARD_DATA_BUSY) { >>> + dev_err(mmc_dev(host->mmc), "Error R1 ready timeout= \n"); >>> + return -EIO; >>> + } >>> + >>> + return 0; >>> +} >>> + >>> static void sunxi_mmc_init_idma_des(struct sunxi_mmc_host *host, >>> struct mmc_data *data) >>> { >>> @@ -383,6 +401,8 @@ static void sunxi_mmc_send_manual_stop(struct >>> sunxi_mmc_host *host, >>> u32 arg, cmd_val, ri; >>> unsigned long expire =3D jiffies + msecs_to_jiffies(1000); >>> >>> + sunxi_mmc_wait_card_ready(host); >>> + >>> cmd_val =3D SDXC_START | SDXC_RESP_EXPIRE | >>> SDXC_STOP_ABORT_CMD | SDXC_CHECK_RESPONSE_CRC; >>> >>> @@ -597,6 +617,11 @@ static int sunxi_mmc_oclk_onoff(struct >>> sunxi_mmc_host *host, u32 oclk_en) >>> { >>> unsigned long expire =3D jiffies + msecs_to_jiffies(250); >>> u32 rval; >>> + int ret; >>> + >>> + ret =3D sunxi_mmc_wait_card_ready(host); >>> + if (ret) >>> + return ret; >>> >>> rval =3D mmc_readl(host, REG_CLKCR); >>> rval &=3D ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON); >>> @@ -785,6 +810,13 @@ static void sunxi_mmc_request(struct mmc_host >>> *mmc, struct mmc_request *mrq) >>> return; >>> } >>> >>> + ret =3D sunxi_mmc_wait_card_ready(host); >>> + if (ret) { >>> + mrq->cmd->error =3D ret; >>> + mmc_request_done(mmc, mrq); >>> + return; >>> + } >>> + >>> if (data) { >>> ret =3D sunxi_mmc_map_dma(host, data); >>> if (ret < 0) { >>> -- >>> 2.4.3 >>> >> >> Kind regards >> Uffe >> > > -- > To unsubscribe from this list: send the line "unsubscribe linux-mmc" = in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > > > --=20 Shawn Lin