From patchwork Fri May 8 06:50:50 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: yangbo lu X-Patchwork-Id: 6362931 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.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 4330BBEEE1 for ; Fri, 8 May 2015 06:54:35 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1AE922014A for ; Fri, 8 May 2015 06:54:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D363F20131 for ; Fri, 8 May 2015 06:54:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752291AbbEHGyc (ORCPT ); Fri, 8 May 2015 02:54:32 -0400 Received: from mail-bn1bon0134.outbound.protection.outlook.com ([157.56.111.134]:21401 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750943AbbEHGyb (ORCPT ); Fri, 8 May 2015 02:54:31 -0400 Received: from BN3PR0301CA0023.namprd03.prod.outlook.com (10.160.180.161) by BN3PR0301MB1188.namprd03.prod.outlook.com (10.160.156.15) with Microsoft SMTP Server (TLS) id 15.1.154.19; Fri, 8 May 2015 06:54:29 +0000 Received: from BN1BFFO11FD027.protection.gbl (2a01:111:f400:7c10::1:157) by BN3PR0301CA0023.outlook.office365.com (2a01:111:e400:4000::33) with Microsoft SMTP Server (TLS) id 15.1.160.16 via Frontend Transport; Fri, 8 May 2015 06:54:29 +0000 Authentication-Results: spf=fail (sender IP is 192.88.158.2) smtp.mailfrom=freescale.com; freescale.mail.onmicrosoft.com; dkim=none (message not signed) header.d=none; Received-SPF: Fail (protection.outlook.com: domain of freescale.com does not designate 192.88.158.2 as permitted sender) receiver=protection.outlook.com; client-ip=192.88.158.2; helo=az84smr01.freescale.net; Received: from az84smr01.freescale.net (192.88.158.2) by BN1BFFO11FD027.mail.protection.outlook.com (10.58.144.90) with Microsoft SMTP Server (TLS) id 15.1.160.8 via Frontend Transport; Fri, 8 May 2015 06:54:29 +0000 Received: from titan.ap.freescale.net ([10.192.208.233]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id t486sP1B019954; Thu, 7 May 2015 23:54:26 -0700 From: Yangbo Lu To: , , CC: Yangbo Lu Subject: [v3, 4/6] mmc: sdhci: apply both LE and BE mode support to sdhci-of-esdhc Date: Fri, 8 May 2015 14:50:50 +0800 Message-ID: <1431067850-41473-1-git-send-email-yangbo.lu@freescale.com> X-Mailer: git-send-email 2.1.0.27.g96db324 X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:192.88.158.2; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(339900001)(199003)(189002)(86362001)(36756003)(50466002)(19580405001)(85426001)(50986999)(48376002)(2201001)(105606002)(87936001)(19580395003)(6806004)(77096005)(92566002)(189998001)(5001770100001)(62966003)(77156002)(5001960100002)(107886002)(50226001)(230783001)(229853001)(47776003)(46102003)(33646002)(104016003)(106466001)(4001430100001); DIR:OUT; SFP:1102; SCL:1; SRVR:BN3PR0301MB1188; H:az84smr01.freescale.net; FPR:; SPF:Fail; MLV:sfv; A:1; MX:1; LANG:en; MIME-Version: 1.0 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BN3PR0301MB1188; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(5005006)(3002001); SRVR:BN3PR0301MB1188; BCL:0; PCL:0; RULEID:; SRVR:BN3PR0301MB1188; X-Forefront-PRVS: 0570F1F193 X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 May 2015 06:54:29.2334 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d; Ip=[192.88.158.2]; Helo=[az84smr01.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN3PR0301MB1188 Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_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 Signed-off-by: Yangbo Lu --- Changes for v3: - Modified the commit message --- drivers/mmc/host/sdhci-of-esdhc.c | 105 +++++++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 36 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 22e9111..858d65d 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -28,7 +28,7 @@ static u32 esdhc_readl(struct sdhci_host *host, int reg) { u32 ret; - ret = in_be32(host->ioaddr + reg); + ret = sdhci_32bs_readl(host, reg); /* * The bit of ADMA flag in eSDHC is not compatible with standard * SDHC register, so set fake flag SDHCI_CAN_DO_ADMA2 when ADMA is @@ -40,7 +40,7 @@ static u32 esdhc_readl(struct sdhci_host *host, int reg) * the verdor version number, oxFE is SDHCI_HOST_VERSION. */ if ((reg == SDHCI_CAPABILITIES) && (ret & SDHCI_CAN_DO_ADMA1)) { - u32 tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); + u32 tmp = sdhci_32bs_readl(host, SDHCI_SLOT_INT_STATUS); tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; if (tmp > VENDOR_V_22) ret |= SDHCI_CAN_DO_ADMA2; @@ -56,9 +56,9 @@ static u16 esdhc_readw(struct sdhci_host *host, int reg) int shift = (reg & 0x2) * 8; if (unlikely(reg == SDHCI_HOST_VERSION)) - ret = in_be32(host->ioaddr + base) & 0xffff; + ret = sdhci_32bs_readl(host, base) & 0xffff; else - ret = (in_be32(host->ioaddr + base) >> shift) & 0xffff; + ret = (sdhci_32bs_readl(host, base) >> shift) & 0xffff; return ret; } @@ -66,7 +66,10 @@ static u8 esdhc_readb(struct sdhci_host *host, int reg) { int base = reg & ~0x3; int shift = (reg & 0x3) * 8; - u8 ret = (in_be32(host->ioaddr + base) >> shift) & 0xff; + u32 ret; + u8 val; + + ret = sdhci_32bs_readl(host, base); /* * "DMA select" locates at offset 0x28 in SD specification, but on @@ -75,16 +78,18 @@ static u8 esdhc_readb(struct sdhci_host *host, int reg) if (reg == SDHCI_HOST_CONTROL) { u32 dma_bits; - dma_bits = in_be32(host->ioaddr + reg); /* DMA select is 22,23 bits in Protocol Control Register */ - dma_bits = (dma_bits >> 5) & SDHCI_CTRL_DMA_MASK; + dma_bits = (ret >> 5) & SDHCI_CTRL_DMA_MASK; /* fixup the result */ ret &= ~SDHCI_CTRL_DMA_MASK; ret |= dma_bits; + val = (ret & 0xff); } - return ret; + val = (ret >> shift) & 0xff; + + return val; } static void esdhc_writel(struct sdhci_host *host, u32 val, int reg) @@ -96,11 +101,28 @@ static void esdhc_writel(struct sdhci_host *host, u32 val, int reg) */ if (reg == SDHCI_INT_ENABLE) val |= SDHCI_INT_BLK_GAP; - sdhci_be32bs_writel(host, val, reg); + sdhci_32bs_writel(host, val, reg); } static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) { + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + + switch (reg) { + case SDHCI_TRANSFER_MODE: + /* + * Postpone this write, we must do it together with a + * command write that is down below. + */ + pltfm_host->xfer_mode_shadow = val; + return; + case SDHCI_COMMAND: + sdhci_32bs_writel(host, val << 16 | + pltfm_host->xfer_mode_shadow, + SDHCI_TRANSFER_MODE); + return; + } + if (reg == SDHCI_BLOCK_SIZE) { /* * Two last DMA bits are reserved, and first one is used for @@ -109,7 +131,7 @@ static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) */ val &= ~SDHCI_MAKE_BLKSZ(0x7, 0); } - sdhci_be32bs_writew(host, val, reg); + sdhci_clrsetbits(host, 0xffff, val, reg); } static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) @@ -130,16 +152,16 @@ static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) /* DMA select is 22,23 bits in Protocol Control Register */ dma_bits = (val & SDHCI_CTRL_DMA_MASK) << 5; - clrsetbits_be32(host->ioaddr + reg , SDHCI_CTRL_DMA_MASK << 5, - dma_bits); + sdhci_clrsetbits(host, SDHCI_CTRL_DMA_MASK << 5, dma_bits, + SDHCI_HOST_CONTROL); val &= ~SDHCI_CTRL_DMA_MASK; - val |= in_be32(host->ioaddr + reg) & SDHCI_CTRL_DMA_MASK; + val |= sdhci_32bs_readl(host, reg) & SDHCI_CTRL_DMA_MASK; } /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ if (reg == SDHCI_HOST_CONTROL) val &= ~ESDHC_HOST_CONTROL_RES; - sdhci_be32bs_writeb(host, val, reg); + sdhci_clrsetbits(host, 0xff, val, reg); } /* @@ -156,7 +178,7 @@ static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask) dma_addr_t dmastart; dma_addr_t dmanow; - tmp = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); + tmp = esdhc_readl(host, SDHCI_SLOT_INT_STATUS); tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; applicable = (intmask & SDHCI_INT_DATA_END) && @@ -174,12 +196,13 @@ static void esdhci_of_adma_workaround(struct sdhci_host *host, u32 intmask) dmanow = (dmanow & ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) + SDHCI_DEFAULT_BOUNDARY_SIZE; host->data->bytes_xfered = dmanow - dmastart; - sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS); + esdhc_writel(host, dmanow, SDHCI_DMA_ADDRESS); } static int esdhc_of_enable_dma(struct sdhci_host *host) { - setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP); + esdhc_writel(host, esdhc_readl(host, ESDHC_DMA_SYSCTL) + | ESDHC_DMA_SNOOP, ESDHC_DMA_SYSCTL); return 0; } @@ -245,7 +268,7 @@ static void esdhc_of_platform_init(struct sdhci_host *host) { u32 vvn; - vvn = in_be32(host->ioaddr + SDHCI_SLOT_INT_STATUS); + vvn = esdhc_readl(host, SDHCI_SLOT_INT_STATUS); vvn = (vvn & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; if (vvn == VENDOR_V_22) host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23; @@ -272,8 +295,8 @@ static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width) break; } - clrsetbits_be32(host->ioaddr + SDHCI_HOST_CONTROL, - ESDHC_CTRL_BUSWIDTH_MASK, ctrl); + sdhci_clrsetbits(host, ESDHC_CTRL_BUSWIDTH_MASK, ctrl, + SDHCI_HOST_CONTROL); } static void esdhc_reset(struct sdhci_host *host, u8 mask) @@ -309,7 +332,7 @@ static int esdhc_of_suspend(struct device *dev) { struct sdhci_host *host = dev_get_drvdata(dev); - esdhc_proctl = sdhci_be32bs_readl(host, SDHCI_HOST_CONTROL); + esdhc_proctl = esdhc_readl(host, SDHCI_HOST_CONTROL); return sdhci_suspend_host(host); } @@ -322,7 +345,7 @@ static int esdhc_of_resume(struct device *dev) if (ret == 0) { /* Isn't this already done by sdhci_resume_host() ? --rmk */ esdhc_of_enable_dma(host); - sdhci_be32bs_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL); + esdhc_writel(host, esdhc_proctl, SDHCI_HOST_CONTROL); } return ret; @@ -348,19 +371,18 @@ static const struct sdhci_pltfm_data sdhci_esdhc_pdata = { .ops = &sdhci_esdhc_ops, }; -static int sdhci_esdhc_probe(struct platform_device *pdev) +static void esdhc_get_property(struct platform_device *pdev) { - struct sdhci_host *host; - struct device_node *np; - int ret; - - host = sdhci_pltfm_init(pdev, &sdhci_esdhc_pdata, 0); - if (IS_ERR(host)) - return PTR_ERR(host); + struct device_node *np = pdev->dev.of_node; + struct sdhci_host *host = platform_get_drvdata(pdev); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); sdhci_get_of_property(pdev); - np = pdev->dev.of_node; + /* call to generic mmc_of_parse to support additional capabilities */ + mmc_of_parse(host->mmc); + mmc_of_parse_voltage(np, &host->ocr_mask); + if (of_device_is_compatible(np, "fsl,p2020-esdhc")) { /* * Freescale messed up with P2020 as it has a non-standard @@ -369,13 +391,24 @@ static int sdhci_esdhc_probe(struct platform_device *pdev) host->quirks2 |= SDHCI_QUIRK2_BROKEN_HOST_CONTROL; } - /* call to generic mmc_of_parse to support additional capabilities */ - ret = mmc_of_parse(host->mmc); - if (ret) - goto err; + if (!pltfm_host->clock) { + pltfm_host->clk = devm_clk_get(&pdev->dev, NULL); + pltfm_host->clock = clk_get_rate(pltfm_host->clk); + clk_prepare_enable(pltfm_host->clk); + } +} - mmc_of_parse_voltage(np, &host->ocr_mask); +static int sdhci_esdhc_probe(struct platform_device *pdev) +{ + struct sdhci_host *host; + int ret; + + + host = sdhci_pltfm_init(pdev, &sdhci_esdhc_pdata, 0); + if (IS_ERR(host)) + return PTR_ERR(host); + esdhc_get_property(pdev); ret = sdhci_add_host(host); if (ret) goto err;