From patchwork Fri Jun 28 15:34:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 11022685 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 E950376 for ; Fri, 28 Jun 2019 15:34:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DB7B2287E6 for ; Fri, 28 Jun 2019 15:34:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CF4BF2880B; Fri, 28 Jun 2019 15:34: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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C430287E6 for ; Fri, 28 Jun 2019 15:34:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726860AbfF1Pez (ORCPT ); Fri, 28 Jun 2019 11:34:55 -0400 Received: from sauhun.de ([88.99.104.3]:51890 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726796AbfF1Pez (ORCPT ); Fri, 28 Jun 2019 11:34:55 -0400 Received: from localhost (p54B332FA.dip0.t-ipconnect.de [84.179.50.250]) by pokefinder.org (Postfix) with ESMTPSA id D03D03E60A2; Fri, 28 Jun 2019 17:34:52 +0200 (CEST) From: Wolfram Sang To: linux-mmc@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, Yoshihiro Shimoda , Wolfram Sang Subject: [PATCH RFT 1/4] mmc: renesas_sdhi: keep sorting Date: Fri, 28 Jun 2019 17:34:45 +0200 Message-Id: <20190628153448.4167-2-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190628153448.4167-1-wsa+renesas@sang-engineering.com> References: <20190628153448.4167-1-wsa+renesas@sang-engineering.com> MIME-Version: 1.0 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The two devices next to each other are super similar, but still, let's keep the alphanumeric sorting for easier additions later. Signed-off-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven --- drivers/mmc/host/renesas_sdhi_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index 64d3b5fb7fe5..7e07c34b9db1 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c @@ -624,10 +624,10 @@ static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = { }; static const struct soc_device_attribute sdhi_quirks_match[] = { + { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 }, { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap }, { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, - { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, { .soc_id = "r8a77980", .data = &sdhi_quirks_nohs400 }, { /* Sentinel. */ }, }; From patchwork Fri Jun 28 15:34:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 11022687 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 3860514E5 for ; Fri, 28 Jun 2019 15:34:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2BC6E287ED for ; Fri, 28 Jun 2019 15:34:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1FE4428812; Fri, 28 Jun 2019 15:34:57 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A62E2287ED for ; Fri, 28 Jun 2019 15:34:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726863AbfF1Pez (ORCPT ); Fri, 28 Jun 2019 11:34:55 -0400 Received: from sauhun.de ([88.99.104.3]:51898 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726780AbfF1Pez (ORCPT ); Fri, 28 Jun 2019 11:34:55 -0400 Received: from localhost (p54B332FA.dip0.t-ipconnect.de [84.179.50.250]) by pokefinder.org (Postfix) with ESMTPSA id 3BAB33E43D0; Fri, 28 Jun 2019 17:34:53 +0200 (CEST) From: Wolfram Sang To: linux-mmc@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, Yoshihiro Shimoda , Wolfram Sang Subject: [PATCH RFT 2/4] mmc: tmio: add generic hook to fixup after a completed request Date: Fri, 28 Jun 2019 17:34:46 +0200 Message-Id: <20190628153448.4167-3-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190628153448.4167-1-wsa+renesas@sang-engineering.com> References: <20190628153448.4167-1-wsa+renesas@sang-engineering.com> MIME-Version: 1.0 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Sadly, due to HW bugs, we need a callback to work around issues just before completing the request. Signed-off-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven --- drivers/mmc/host/tmio_mmc.h | 1 + drivers/mmc/host/tmio_mmc_core.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index c5ba13fae399..be9d62e30817 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -178,6 +178,7 @@ struct tmio_mmc_host { void (*hw_reset)(struct tmio_mmc_host *host); void (*prepare_tuning)(struct tmio_mmc_host *host, unsigned long tap); bool (*check_scc_error)(struct tmio_mmc_host *host); + void (*fixup_request)(struct tmio_mmc_host *host, struct mmc_request *mrq); /* * Mandatory callback for tuning to occur which is optional for SDR50 diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c index 2cb3f951c3e2..31ffcc32c580 100644 --- a/drivers/mmc/host/tmio_mmc_core.c +++ b/drivers/mmc/host/tmio_mmc_core.c @@ -852,6 +852,9 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host) return; } + if (host->fixup_request) + host->fixup_request(host, mrq); + mmc_request_done(host->mmc, mrq); } From patchwork Fri Jun 28 15:34:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 11022693 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 DC9121932 for ; Fri, 28 Jun 2019 15:34:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C9375287ED for ; Fri, 28 Jun 2019 15:34:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B6BB4287FF; Fri, 28 Jun 2019 15:34:57 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 12824287C5 for ; Fri, 28 Jun 2019 15:34:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726849AbfF1Pez (ORCPT ); Fri, 28 Jun 2019 11:34:55 -0400 Received: from sauhun.de ([88.99.104.3]:51902 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726836AbfF1Pez (ORCPT ); Fri, 28 Jun 2019 11:34:55 -0400 Received: from localhost (p54B332FA.dip0.t-ipconnect.de [84.179.50.250]) by pokefinder.org (Postfix) with ESMTPSA id 997A93E43D1; Fri, 28 Jun 2019 17:34:53 +0200 (CEST) From: Wolfram Sang To: linux-mmc@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, Yoshihiro Shimoda , Wolfram Sang Subject: [PATCH RFT 3/4] mmc: renesas_sdhi: make quirks info accessible outside probe() Date: Fri, 28 Jun 2019 17:34:47 +0200 Message-Id: <20190628153448.4167-4-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190628153448.4167-1-wsa+renesas@sang-engineering.com> References: <20190628153448.4167-1-wsa+renesas@sang-engineering.com> MIME-Version: 1.0 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP We will need that for a later patch. Signed-off-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven --- drivers/mmc/host/renesas_sdhi.h | 6 ++++++ drivers/mmc/host/renesas_sdhi_core.c | 6 +----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h index c0504aa90857..88d05a617d43 100644 --- a/drivers/mmc/host/renesas_sdhi.h +++ b/drivers/mmc/host/renesas_sdhi.h @@ -33,6 +33,11 @@ struct renesas_sdhi_of_data { unsigned short max_segs; }; +struct renesas_sdhi_quirks { + bool hs400_disabled; + bool hs400_4taps; +}; + struct tmio_mmc_dma { enum dma_slave_buswidth dma_buswidth; bool (*filter)(struct dma_chan *chan, void *arg); @@ -46,6 +51,7 @@ struct renesas_sdhi { struct clk *clk_cd; struct tmio_mmc_data mmc_data; struct tmio_mmc_dma dma_priv; + const struct renesas_sdhi_quirks *quirks; struct pinctrl *pinctrl; struct pinctrl_state *pins_default, *pins_uhs; void __iomem *scc_ctl; diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index 7e07c34b9db1..bce1779229a8 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c @@ -46,11 +46,6 @@ #define SDHI_VER_GEN3_SD 0xcc10 #define SDHI_VER_GEN3_SDMMC 0xcd10 -struct renesas_sdhi_quirks { - bool hs400_disabled; - bool hs400_4taps; -}; - static void renesas_sdhi_sdbuf_width(struct tmio_mmc_host *host, int width) { u32 val; @@ -662,6 +657,7 @@ int renesas_sdhi_probe(struct platform_device *pdev, if (!priv) return -ENOMEM; + priv->quirks = quirks; mmc_data = &priv->mmc_data; dma_priv = &priv->dma_priv; From patchwork Fri Jun 28 15:34:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wolfram Sang X-Patchwork-Id: 11022699 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 2A56A14E5 for ; Fri, 28 Jun 2019 15:34:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1C2EF287E6 for ; Fri, 28 Jun 2019 15:34:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0EDC4287C5; Fri, 28 Jun 2019 15:34:58 +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=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3C1ED287F5 for ; Fri, 28 Jun 2019 15:34:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726822AbfF1Pe4 (ORCPT ); Fri, 28 Jun 2019 11:34:56 -0400 Received: from sauhun.de ([88.99.104.3]:51918 "EHLO pokefinder.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726837AbfF1Pe4 (ORCPT ); Fri, 28 Jun 2019 11:34:56 -0400 Received: from localhost (p54B332FA.dip0.t-ipconnect.de [84.179.50.250]) by pokefinder.org (Postfix) with ESMTPSA id 053963E4766; Fri, 28 Jun 2019 17:34:54 +0200 (CEST) From: Wolfram Sang To: linux-mmc@vger.kernel.org Cc: linux-renesas-soc@vger.kernel.org, Yoshihiro Shimoda , Wolfram Sang , Takeshi Saito Subject: [PATCH RFT 4/4] mmc: renesas_sdhi: support manual calibration Date: Fri, 28 Jun 2019 17:34:48 +0200 Message-Id: <20190628153448.4167-5-wsa+renesas@sang-engineering.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190628153448.4167-1-wsa+renesas@sang-engineering.com> References: <20190628153448.4167-1-wsa+renesas@sang-engineering.com> MIME-Version: 1.0 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Some R-Car Gen3 SoCs need some manual correction of timing parameters after the automatic tuning has finished but before next CMD13 is completed. This patch implements that by this state machine: - introducing a configuration flag ('manual_calibration') to mark affected SoCs - iff the configuration flag is set the 'fixup_request' callback is populated during probe - iff the configuration flag is set, a runtime flag ('needs_adjust_hs400') is set when HS400 tuning gets prepared - if tuning HS400 fails, the runtime flag is cleared again - the callback will check the runtime flag and enable the corrected manual mode if the flag is set and CMD13 is encountered - at the end of the enablement the runtime flag is cleared - iff the configuration flag is set, the manual mode will be disabled when HS400 gets downgraded There also some helper functions added to access the TMPPORT registers. The actual fixup value is SoC specific and also added to the quirks struct. Signed-off-by: Takeshi Saito Signed-off-by: Wolfram Sang --- drivers/mmc/host/renesas_sdhi.h | 3 + drivers/mmc/host/renesas_sdhi_core.c | 121 ++++++++++++++++++++++++++- 2 files changed, 123 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h index 88d05a617d43..f45180d16985 100644 --- a/drivers/mmc/host/renesas_sdhi.h +++ b/drivers/mmc/host/renesas_sdhi.h @@ -36,6 +36,8 @@ struct renesas_sdhi_of_data { struct renesas_sdhi_quirks { bool hs400_disabled; bool hs400_4taps; + bool manual_calibration; + u8 manual_calibration_fixup; }; struct tmio_mmc_dma { @@ -57,6 +59,7 @@ struct renesas_sdhi { void __iomem *scc_ctl; u32 scc_tappos; u32 scc_tappos_hs400; + bool needs_adjust_hs400; }; #define host_to_priv(host) \ diff --git a/drivers/mmc/host/renesas_sdhi_core.c b/drivers/mmc/host/renesas_sdhi_core.c index bce1779229a8..c4e9d44302bb 100644 --- a/drivers/mmc/host/renesas_sdhi_core.c +++ b/drivers/mmc/host/renesas_sdhi_core.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -248,6 +249,11 @@ static int renesas_sdhi_start_signal_voltage_switch(struct mmc_host *mmc, #define SH_MOBILE_SDHI_SCC_RVSCNTL 0x008 #define SH_MOBILE_SDHI_SCC_RVSREQ 0x00A #define SH_MOBILE_SDHI_SCC_TMPPORT2 0x00E +#define SH_MOBILE_SDHI_SCC_TMPPORT3 0x014 +#define SH_MOBILE_SDHI_SCC_TMPPORT4 0x016 +#define SH_MOBILE_SDHI_SCC_TMPPORT5 0x018 +#define SH_MOBILE_SDHI_SCC_TMPPORT6 0x01A +#define SH_MOBILE_SDHI_SCC_TMPPORT7 0x01C /* Definitions for values the SH_MOBILE_SDHI_SCC_DTCNTL register */ #define SH_MOBILE_SDHI_SCC_DTCNTL_TAPEN BIT(0) @@ -264,6 +270,19 @@ static int renesas_sdhi_start_signal_voltage_switch(struct mmc_host *mmc, #define SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL BIT(4) #define SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN BIT(31) +/* Definitions for values the SH_MOBILE_SDHI_SCC_TMPPORT4 register */ +#define SH_MOBILE_SDHI_SCC_TMPPORT4_DLL_ACC_START BIT(0) + +/* Definitions for values the SH_MOBILE_SDHI_SCC_TMPPORT5 register */ +#define SH_MOBILE_SDHI_SCC_TMPPORT5_DLL_RW_SEL_R BIT(8) +#define SH_MOBILE_SDHI_SCC_TMPPORT5_DLL_RW_SEL_W (0 << 8) +#define SH_MOBILE_SDHI_SCC_TMPPORT5_DLL_ADR_MASK 0x3F + +/* Definitions for values the SH_MOBILE_SDHI_SCC register */ +#define SH_MOBILE_SDHI_SCC_TMPPORT_DISABLE_WP_CODE 0xa5000000 +#define SH_MOBILE_SDHI_SCC_TMPPORT_CALIB_CODE_MASK 0x1f +#define SH_MOBILE_SDHI_SCC_TMPPORT_MANUAL_MODE BIT(7) + static inline u32 sd_scc_read32(struct tmio_mmc_host *host, struct renesas_sdhi *priv, int addr) { @@ -386,6 +405,76 @@ static void renesas_sdhi_disable_scc(struct tmio_mmc_host *host) sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); } +static u32 sd_scc_tmpport_read32(struct tmio_mmc_host *host, + struct renesas_sdhi *priv, u32 addr) +{ + /* read mode */ + sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT5, + SH_MOBILE_SDHI_SCC_TMPPORT5_DLL_RW_SEL_R | + (SH_MOBILE_SDHI_SCC_TMPPORT5_DLL_ADR_MASK & addr)); + + /* access start and stop */ + sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT4, + SH_MOBILE_SDHI_SCC_TMPPORT4_DLL_ACC_START); + sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT4, 0); + + return sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT7); +} + +static void sd_scc_tmpport_write32(struct tmio_mmc_host *host, + struct renesas_sdhi *priv, u32 addr, u32 val) +{ + /* write mode */ + sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT5, + SH_MOBILE_SDHI_SCC_TMPPORT5_DLL_RW_SEL_W | + (SH_MOBILE_SDHI_SCC_TMPPORT5_DLL_ADR_MASK & addr)); + + sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT6, val); + + /* access start and stop */ + sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT4, + SH_MOBILE_SDHI_SCC_TMPPORT4_DLL_ACC_START); + sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT4, 0); +} + +static void renesas_sdhi_adjust_hs400_mode_enable(struct tmio_mmc_host *host) +{ + struct renesas_sdhi *priv = host_to_priv(host); + u32 calib_code; + + /* disable write protect */ + sd_scc_tmpport_write32(host, priv, 0x00, + SH_MOBILE_SDHI_SCC_TMPPORT_DISABLE_WP_CODE); + /* read calibration code and adjust */ + calib_code = sd_scc_tmpport_read32(host, priv, 0x26); + calib_code &= SH_MOBILE_SDHI_SCC_TMPPORT_CALIB_CODE_MASK; + if (calib_code > priv->quirks->manual_calibration_fixup) + calib_code -= priv->quirks->manual_calibration_fixup; + else + calib_code = 0; + /* enable manual calibration */ + sd_scc_tmpport_write32(host, priv, 0x22, + SH_MOBILE_SDHI_SCC_TMPPORT_MANUAL_MODE | calib_code); + /* set offset value to TMPPORT3, hardcoded to OFFSET0 (= 0x3) for now */ + sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT3, 0x3); + + /* adjustment done, clear flag */ + priv->needs_adjust_hs400 = false; +} + +static void renesas_sdhi_adjust_hs400_mode_disable(struct tmio_mmc_host *host) +{ + struct renesas_sdhi *priv = host_to_priv(host); + + /* disable write protect */ + sd_scc_tmpport_write32(host, priv, 0x00, + SH_MOBILE_SDHI_SCC_TMPPORT_DISABLE_WP_CODE); + /* disable manual calibration */ + sd_scc_tmpport_write32(host, priv, 0x22, 0); + /* clear offset value of TMPPORT3 */ + sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT3, 0); +} + static void renesas_sdhi_reset_hs400_mode(struct tmio_mmc_host *host, struct renesas_sdhi *priv) { @@ -403,13 +492,20 @@ static void renesas_sdhi_reset_hs400_mode(struct tmio_mmc_host *host, SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL) & sd_scc_read32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2)); + if (priv->quirks->manual_calibration) + renesas_sdhi_adjust_hs400_mode_disable(host); + sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN | sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); } static void renesas_sdhi_prepare_hs400_tuning(struct tmio_mmc_host *host) { - renesas_sdhi_reset_hs400_mode(host, host_to_priv(host)); + struct renesas_sdhi *priv = host_to_priv(host); + + renesas_sdhi_reset_hs400_mode(host, priv); + if (priv->quirks->manual_calibration) + priv->needs_adjust_hs400 = true; } #define SH_MOBILE_SDHI_MAX_TAP 3 @@ -520,6 +616,7 @@ static void renesas_sdhi_hw_reset(struct tmio_mmc_host *host) renesas_sdhi_reset_scc(host, priv); renesas_sdhi_reset_hs400_mode(host, priv); + priv->needs_adjust_hs400 = false; sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN | sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); @@ -596,6 +693,13 @@ static int renesas_sdhi_multi_io_quirk(struct mmc_card *card, return blk_size; } +static void renesas_sdhi_fixup_request(struct tmio_mmc_host *host, struct mmc_request *mrq) +{ + struct renesas_sdhi *priv = host_to_priv(host); + + if (priv->needs_adjust_hs400 && mrq->cmd->opcode == MMC_SEND_STATUS) + renesas_sdhi_adjust_hs400_mode_enable(host); +} static void renesas_sdhi_enable_dma(struct tmio_mmc_host *host, bool enable) { /* Iff regs are 8 byte apart, sdbuf is 64 bit. Otherwise always 32. */ @@ -618,12 +722,24 @@ static const struct renesas_sdhi_quirks sdhi_quirks_nohs400 = { .hs400_disabled = true, }; +static const struct renesas_sdhi_quirks sdhi_quirks_manual_calib0 = { + .manual_calibration = true, + .manual_calibration_fixup = 0, +}; + +static const struct renesas_sdhi_quirks sdhi_quirks_manual_calib4 = { + .manual_calibration = true, + .manual_calibration_fixup = 4, +}; + static const struct soc_device_attribute sdhi_quirks_match[] = { { .soc_id = "r8a774a1", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, { .soc_id = "r8a7795", .revision = "ES1.*", .data = &sdhi_quirks_4tap_nohs400 }, { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap }, { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, + { .soc_id = "r8a77965", .data = &sdhi_quirks_manual_calib0 }, { .soc_id = "r8a77980", .data = &sdhi_quirks_nohs400 }, + { .soc_id = "r8a77990", .data = &sdhi_quirks_manual_calib4 }, { /* Sentinel. */ }, }; @@ -720,6 +836,9 @@ int renesas_sdhi_probe(struct platform_device *pdev, if (quirks && quirks->hs400_4taps) mmc_data->flags |= TMIO_MMC_HAVE_4TAP_HS400; + if (quirks && quirks->manual_calibration) + host->fixup_request = renesas_sdhi_fixup_request; + /* For some SoC, we disable internal WP. GPIO may override this */ if (mmc_can_gpio_ro(host->mmc)) mmc_data->capabilities2 &= ~MMC_CAP2_NO_WRITE_PROTECT;