From patchwork Wed Sep 4 12:54:12 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aisheng Dong X-Patchwork-Id: 2853642 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 517C6C0AB5 for ; Wed, 4 Sep 2013 13:01:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 0204B20319 for ; Wed, 4 Sep 2013 13:01:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id BBEAF202C7 for ; Wed, 4 Sep 2013 13:01:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1762470Ab3IDNBU (ORCPT ); Wed, 4 Sep 2013 09:01:20 -0400 Received: from co1ehsobe006.messaging.microsoft.com ([216.32.180.189]:53971 "EHLO co1outboundpool.messaging.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1760087Ab3IDNBU (ORCPT ); Wed, 4 Sep 2013 09:01:20 -0400 Received: from mail155-co1-R.bigfish.com (10.243.78.250) by CO1EHSOBE001.bigfish.com (10.243.66.64) with Microsoft SMTP Server id 14.1.225.22; Wed, 4 Sep 2013 13:01:19 +0000 Received: from mail155-co1 (localhost [127.0.0.1]) by mail155-co1-R.bigfish.com (Postfix) with ESMTP id 697AB78013D; Wed, 4 Sep 2013 13:01:19 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 6 X-BigFish: VS6(zcb8kzzz1f42h208ch1ee6h1de0h1fdah2073h1202h1e76h1d1ah1d2ah1fc6h1082kzz1de098h1de097h8275bhz2dh2a8h839hd24he5bhf0ah1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah1b2fh1fb3h1d0ch1d2eh1d3fh1dfeh1dffh1e23h1fe8h1ff5h1155h) Received: from mail155-co1 (localhost.localdomain [127.0.0.1]) by mail155-co1 (MessageSwitch) id 1378299677348448_12998; Wed, 4 Sep 2013 13:01:17 +0000 (UTC) Received: from CO1EHSMHS027.bigfish.com (unknown [10.243.78.234]) by mail155-co1.bigfish.com (Postfix) with ESMTP id 4688560004D; Wed, 4 Sep 2013 13:01:17 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by CO1EHSMHS027.bigfish.com (10.243.66.37) with Microsoft SMTP Server (TLS) id 14.16.227.3; Wed, 4 Sep 2013 13:01:16 +0000 Received: from tx30smr01.am.freescale.net (10.81.153.31) by 039-SN1MMR1-001.039d.mgd.msft.net (10.84.1.13) with Microsoft SMTP Server (TLS) id 14.3.158.2; Wed, 4 Sep 2013 13:01:15 +0000 Received: from shlinux2.ap.freescale.net (shlinux2.ap.freescale.net [10.192.224.44]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id r84D138L027984; Wed, 4 Sep 2013 06:01:13 -0700 From: Dong Aisheng To: CC: , , , , , Subject: [PATCH 3/8] sdhci: sdhci-esdhc-imx: support real clock on and off for imx6q Date: Wed, 4 Sep 2013 20:54:12 +0800 Message-ID: <1378299257-2980-4-git-send-email-b29396@freescale.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1378299257-2980-1-git-send-email-b29396@freescale.com> References: <1378299257-2980-1-git-send-email-b29396@freescale.com> MIME-Version: 1.0 X-OriginatorOrg: freescale.com X-FOPE-CONNECTOR: Id%0$Dn%*$RO%0$TLS%0$FQDN%$TlsDn% Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Spam-Status: No, score=-9.3 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The signal voltage switch follow requires to shutdown and output clock in a specific sequence according to standard host controller v3.0 spec. In that timing, the card must really receive clock or not. However, for i.MX6Q, the uSDHC will not output clock even the clock is enabled until there is command or data in transfer on the bus, which will then cause singal voltage switch always to fail. For i.MX6Q, we clear ESDHC_VENDOR_SPEC_FRC_SDCLK_ON bit to let controller to gate off clock automatically and set that bit to force clock output if clock is on. This is required by SD3.0 support. Signed-off-by: Dong Aisheng --- drivers/mmc/host/sdhci-esdhc-imx.c | 3 --- drivers/mmc/host/sdhci-esdhc.h | 29 ++++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 1dd5ba8..3118a82 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -31,9 +31,6 @@ #include "sdhci-esdhc.h" #define ESDHC_CTRL_D3CD 0x08 -/* VENDOR SPEC register */ -#define ESDHC_VENDOR_SPEC 0xc0 -#define ESDHC_VENDOR_SPEC_SDIO_QUIRK (1 << 1) #define ESDHC_WTMK_LVL 0x44 #define ESDHC_MIX_CTRL 0x48 #define ESDHC_MIX_CTRL_AC23EN (1 << 7) diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h index a2a0642..86fcd5b 100644 --- a/drivers/mmc/host/sdhci-esdhc.h +++ b/drivers/mmc/host/sdhci-esdhc.h @@ -14,6 +14,8 @@ #ifndef _DRIVERS_MMC_SDHCI_ESDHC_H #define _DRIVERS_MMC_SDHCI_ESDHC_H +#include + /* * Ops and quirks for the Freescale eSDHC controller. */ @@ -33,6 +35,12 @@ #define ESDHC_CLOCK_HCKEN 0x00000002 #define ESDHC_CLOCK_IPGEN 0x00000001 +/* VENDOR SPEC register */ +#define ESDHC_VENDOR_SPEC 0xc0 +#define ESDHC_VENDOR_SPEC_SDIO_QUIRK (1 << 1) +#define ESDHC_VENDOR_SPEC_VSELECT (1 << 1) +#define ESDHC_VENDOR_SPEC_FRC_SDCLK_ON (1 << 8) + /* pltfm-specific */ #define ESDHC_HOST_CONTROL_LE 0x20 @@ -52,12 +60,20 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock, unsigned int host_clock) { + struct device *dev; int pre_div = 2; int div = 1; - u32 temp; - - if (clock == 0) + u32 temp, val; + + dev = mmc_dev(host->mmc); + if (clock == 0) { + if (of_device_is_compatible(dev->of_node, "fsl,imx6q-usdhc")) { + val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); + writel(val & ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON, + host->ioaddr + ESDHC_VENDOR_SPEC); + } goto out; + } temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL); temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN @@ -81,6 +97,13 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock, | (div << ESDHC_DIVIDER_SHIFT) | (pre_div << ESDHC_PREDIV_SHIFT)); sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); + + if (of_device_is_compatible(dev->of_node, "fsl,imx6q-usdhc")) { + val = readl(host->ioaddr + ESDHC_VENDOR_SPEC); + writel(val | ESDHC_VENDOR_SPEC_FRC_SDCLK_ON, + host->ioaddr + ESDHC_VENDOR_SPEC); + } + mdelay(1); out: host->clock = clock;