From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933802AbcALCiE (ORCPT ); Mon, 11 Jan 2016 21:38:04 -0500 Received: from mailout2.samsung.com ([203.254.224.25]:56113 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933349AbcALCiB (ORCPT ); Mon, 11 Jan 2016 21:38:01 -0500 MIME-version: 1.0 Content-type: text/plain; charset=utf-8 X-AuditID: cbfee690-f79646d000001316-1b-569466f6b25e Content-transfer-encoding: 8BIT Message-id: <569466F1.403@samsung.com> Date: Tue, 12 Jan 2016 11:37:37 +0900 From: Jaehoon Chung User-Agent: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 To: Shawn Lin Cc: Ulf Hansson , linux-mmc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v2] mmc: dw_mmc: add hw_reset support References: <1451875854-12521-1-git-send-email-shawn.lin@rock-chips.com> <568A089B.20109@samsung.com> <568A1E19.2050708@rock-chips.com> In-reply-to: <568A1E19.2050708@rock-chips.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpjkeLIzCtJLcpLzFFi42JZI2JSoPstbUqYwbxpnBaXd81hszjyv5/R 4s6T9awWx9eGO7B43Lm2h83j76z9LB6fN8kFMEdx2aSk5mSWpRbp2yVwZfxbsIK94KRBRev6 6YwNjOtUuxg5OSQETCRmL3rFDmGLSVy4t56ti5GLQ0hgBaPEn0v3WGCKTh2dBpWYxSix6MUx VpAEr4CgxI/JIEUcHMwC8hJHLmVDmOoSU6bkQpQ/YJR42XKfHaJcTeLk5xY2EJtFQFVi59l5 YHE2AR2J7d+OM4HYogJhEg/W7QUbLyKgIXHj7HWwemaBZImOf0fB7hEWsJRY2viPEWJBJ6PE 9E9rwG7gFNCTeDU7DiQuIbCKXeLm7FuMEMsEJL5NPgRWIyEgK7HpADPEX5ISB1fcYJnAKDYL yTezEL6ZhfDNAkbmVYyiqQXJBcVJ6UUmesWJucWleel6yfm5mxiB0XP637MJOxjvHbA+xCjA wajEw3uQc0qYEGtiWXFl7iFGU6AbJjJLiSbnA2M0ryTe0NjMyMLUxNTYyNzSTEmc97XUz2Ah gfTEktTs1NSC1KL4otKc1OJDjEwcnFINjD0uRbfaTkv8cznJVfUmkosjVWADn392qsE787eX pRpSn+2+YvWq+l7joVfL3NTYEy/Xl9uIMK6fsSxb56myjFyU+tsfk+6q/L+zQ7HW7DYjt5C5 6Mm9VyWUf5t8OeDGlim9tEp/XU3v5Ir1Vct3BEWetKwo0fv14JJnc2ihhNv8x7ouhZWHlFiK MxINtZiLihMBq9p46ZkCAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFrrMIsWRmVeSWpSXmKPExsVy+t9jQd1vaVPCDHY8ZLK4vGsOm8WR//2M FneerGe1OL423IHF4861PWwef2ftZ/H4vEkugDmqgdEmIzUxJbVIITUvOT8lMy/dVsk7ON45 3tTMwFDX0NLCXEkhLzE31VbJxSdA1y0zB2ibkkJZYk4pUCggsbhYSd8O04TQEDddC5jGCF3f kCC4HiMDNJCwhjHj34IV7AUnDSpa109nbGBcp9rFyMkhIWAiceroNDYIW0ziwr31QDYXh5DA LEaJRS+OsYIkeAUEJX5MvsfSxcjBwSwgL3HkUjaEqS4xZUouRPkDRomXLffZIcrVJE5+bgGb ySKgKrHz7DywOJuAjsT2b8eZQGxRgTCJB+v2go0XEdCQuHH2Olg9s0CyRMe/oywgtrCApcTS xn+MEAs6GSWmf1oDdgOngJ7Eq9lxExiBjkS4bhbCdbMQrlvAyLyKUSK1ILmgOCk91ygvtVyv ODG3uDQvXS85P3cTIzhCn0nvYDy8y/0QowAHoxIP7wHOKWFCrIllxZW5hxglOJiVRHidgoBC vCmJlVWpRfnxRaU5qcWHGE2B3pvILCWanA9MHnkl8YbGJmZGlkbmhhZGxuZK4rz7LkWGCQmk J5akZqemFqQWwfQxcXBKNTByaaw+YrH/b+ATnV0HZt8vP393tkHbJ17tg72tB/aHnVgj9Ukn 9MMfj3lhk8IYX1zL4vi7++Wkzh8bP1/blnt50zH+txN6OdoEXX21r0RfFWWKtw8yf7C8ssj+ 1le5e0dePI670bHy89afae8WvkruuLDZZdmNhj81Wm/194kcOPVFlXvP1HjzLUosxRmJhlrM RcWJAAhsAMHmAgAA DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, Shawn. On 01/04/2016 04:24 PM, Shawn Lin wrote: > On 2016/1/4 13:52, Jaehoon Chung wrote: >> Hi, Shawn. >> >> On 01/04/2016 11:50 AM, Shawn Lin wrote: >>> This patch implement hw_reset function for DesignWare >>> MMC controller. By adding this feature, mmc blk can >>> do some basic recovery. >>> >>> >From Synopsys DesignWare Cores Mobile Storage Host Databook >>> (Section 7.4.4), we get the details: >>> 1. Program CMD12 to end any transfer in process. >>> 2. Wait for DTO, even if no response is sent back by the card. >>> 3. Set the following resets: >>> Software reset – BMOD[0] for IDMAC only >>> DMA reset– CTRL[2] >>> FIFO reset – CTRL[1] bits >>> 4. Program the CARD_RESET register with a value of 0 for the bit >>> corresponding to the card number; This can be done at any time when >>> the card is connected to the controller. This programming asserts the >>> RST_n signal and resets the card. >>> 5. Wait for minimum of 1 μs or cclk_in period, which ever is greater >>> 6. After a minimum of 1 μs, the application should program a value of >>> 0 into the CARD_RESET register for the bit corresponding to the card >>> number. This de-asserts the RST_n signal and takes the card out of reset. >>> 7. The application can program a new CMD only after a minimum of 200 us >>> after the de-assertion of the RST_n signal, as per the MMC 4.41 standard. >>> >>> HW reset producer will be call in mmc_init_card before mmc_go_idle. At that >>> time,dw mmc hasn't update clk for itself, so CMD12 is inappropriate and >>> unnecessary. Moreover, if mmc device runs into broken states, DRTO or RTO >>> generated by previous cmd w/ data will make mmc core issue stop already. Then >>> it will retry again and again, issue stop and card status again until the >>> cmd's retry number decrease to zero. That will finally trigger HW reset producer >>> if we declare MMC_CAP_HW_RESET. So there's no need to do step 1 and 2 for the >>> reasons we mentioned above. I think it doesn't need to write the all contents mentioned in Designware IP Spec. So As you possible, how about adding the more simple commit message than now? Best Regards, Jaehoon Chung >> >> Which IP version did you use? Could you share it..? >> Did you know about CHIP RESET sequence? >> > > My dw_mmc IP version is 270a(0x5342270a from VERID register). > Do you mean "emmc chip hardware reset sequence"? > From JESD84-B51 spec(section 6.15.10), > > host pull down reset pin for at least 1us, and pull high it. > then emmc device will detect it as a IO interrupt to enter internal reset flow. Host should not issue CMD1 within 200us, which means emmc device MUST finish internal reset flow within 200us. > >>> >>> This implementation can be easily tested by cutting off->On vmmc while doing data >>> accessing in background to simulate that case. And dw_mmc can generate timeout >>> interrupt and make mmc core trigger hw reset producer before re-init mmc card >>> to recover itself. >>> >>> Signed-off-by: Shawn Lin >>> >>> --- >>> >>> Changes in v2: >>> - remove unecessary mb >>> - reduce time cost for hw_reset >>> - combine SDMMC_CTRL_DMA_RESET and SDMMC_CTRL_FIFO_RESET >>> >>> drivers/mmc/host/dw_mmc.c | 25 +++++++++++++++++++++++++ >>> drivers/mmc/host/dw_mmc.h | 4 ++++ >>> 2 files changed, 29 insertions(+) >>> >>> diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c >>> index 7128351..98e75fc 100644 >>> --- a/drivers/mmc/host/dw_mmc.c >>> +++ b/drivers/mmc/host/dw_mmc.c >>> @@ -1477,6 +1477,30 @@ static int dw_mci_get_cd(struct mmc_host *mmc) >>> return present; >>> } >>> >>> +static void dw_mci_hw_reset(struct mmc_host *mmc) >>> +{ >>> + struct dw_mci_slot *slot = mmc_priv(mmc); >>> + struct dw_mci *host = slot->host; >>> + >>> + if (host->use_dma == TRANS_MODE_IDMAC) >>> + dw_mci_idmac_reset(host); >>> + >>> + if (!dw_mci_ctrl_reset(host, SDMMC_CTRL_DMA_RESET | >>> + SDMMC_CTRL_FIFO_RESET)) >>> + return; >>> + >>> + /* >>> + * According to eMMC spec, card reset procedure: >>> + * tRstW >= 1us: RST_n pulse width >>> + * tRSCA >= 200us: RST_n to Command time >>> + * tRSTH >= 1us: RST_n high period >>> + */ >>> + mci_writel(slot->host, RST_N, SDMMC_RST_HWRESET); >> >> Even though we used only one slot, but it needs to control bit with slot->id. >> > > yep, got it. > >> Best Regards, >> Jaehoon Chung >> >>> + usleep_range(1, 2); >>> + mci_writel(slot->host, RST_N, SDMMC_RST_HWACTIVE); >>> + usleep_range(200, 300); >>> +} >>> + >>> static void dw_mci_init_card(struct mmc_host *mmc, struct mmc_card *card) >>> { >>> struct dw_mci_slot *slot = mmc_priv(mmc); >>> @@ -1563,6 +1587,7 @@ static const struct mmc_host_ops dw_mci_ops = { >>> .set_ios = dw_mci_set_ios, >>> .get_ro = dw_mci_get_ro, >>> .get_cd = dw_mci_get_cd, >>> + .hw_reset = dw_mci_hw_reset, >>> .enable_sdio_irq = dw_mci_enable_sdio_irq, >>> .execute_tuning = dw_mci_execute_tuning, >>> .card_busy = dw_mci_card_busy, >>> diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h >>> index f695b58..684ee34 100644 >>> --- a/drivers/mmc/host/dw_mmc.h >>> +++ b/drivers/mmc/host/dw_mmc.h >>> @@ -46,6 +46,7 @@ >>> #define SDMMC_VERID 0x06c >>> #define SDMMC_HCON 0x070 >>> #define SDMMC_UHS_REG 0x074 >>> +#define SDMMC_RST_N 0x078 >>> #define SDMMC_BMOD 0x080 >>> #define SDMMC_PLDMND 0x084 >>> #define SDMMC_DBADDR 0x088 >>> @@ -169,6 +170,9 @@ >>> #define SDMMC_IDMAC_ENABLE BIT(7) >>> #define SDMMC_IDMAC_FB BIT(1) >>> #define SDMMC_IDMAC_SWRESET BIT(0) >>> +/* H/W reset */ >>> +#define SDMMC_RST_HWACTIVE 0x1 >>> +#define SDMMC_RST_HWRESET 0x0 >>> /* Version ID register define */ >>> #define SDMMC_GET_VERID(x) ((x) & 0xFFFF) >>> /* Card read threshold */ >>> >> >> >> >> > >