From patchwork Fri Nov 15 23:56:22 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grant Grundler X-Patchwork-Id: 3190791 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 6AC899F432 for ; Fri, 15 Nov 2013 23:57:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4AE6E2053E for ; Fri, 15 Nov 2013 23:57:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3599A20561 for ; Fri, 15 Nov 2013 23:57:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752148Ab3KOX5A (ORCPT ); Fri, 15 Nov 2013 18:57:00 -0500 Received: from mail-pa0-f45.google.com ([209.85.220.45]:34753 "EHLO mail-pa0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751067Ab3KOX46 (ORCPT ); Fri, 15 Nov 2013 18:56:58 -0500 Received: by mail-pa0-f45.google.com with SMTP id kx10so3512653pab.4 for ; Fri, 15 Nov 2013 15:56:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id; bh=5TIvS5gut7TpfNR7G2SaLRZqZCauMivocsWrm3YaUFk=; b=aiIlYzesiHHhRyWy+pB8PQA2gpib025jkqKggK6Ers7WLyJO9dvwHZOeX+OXMas8k1 pMtO/X6vQk0/W3zK8kB7NxQ4CdQoBil1PbAzD9uYSTizH7QvTcEaTMwt6XXtGQvy3U4E MMQGU3Mv7iDal3xRHzzQuTYLvWPlCea44qFIQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=5TIvS5gut7TpfNR7G2SaLRZqZCauMivocsWrm3YaUFk=; b=Yk+za7YnHctgMc1QZ8DaYNmfXeY++VoGSEEB20YevU6FiOdKvAiiigs0zc9OeuK77b RVlI6aIcUOZ+7Rz/npA4W9zbUnvy9LTIh3U962RJC1XxB8MKrTF+2oflMRcA7VPWwDgD H5us+aV+uYI498AJLAdh59Hs+Y+l0nWIdZhwztHlA0iCLc6rxcUvYC6E3e+FuyqKLxNK LeN8gfSAYnIJsgts/vGtDOs6I2w/dbXXWvxIweGXkTdv1JKntNVL/vYV7F++N5yqAaKU LA5V22UTFd3ggHq6eJHdvig9kZbGNpidDHkfQ6v20SW5cHRbMExoimJjcG5yuhH1UR5v GPZA== X-Gm-Message-State: ALoCoQnBzh/qMQ+prCu5W4uGM9onnQmgUMAPQP0w7LbrNk1IkbV7ezRZQYzKcz3B+yGybqLYx32U X-Received: by 10.66.100.227 with SMTP id fb3mr9526208pab.26.1384559818144; Fri, 15 Nov 2013 15:56:58 -0800 (PST) Received: from firesword.mtv.corp.google.com (firesword.mtv.corp.google.com [172.22.73.90]) by mx.google.com with ESMTPSA id ry3sm7058607pbc.8.2013.11.15.15.56.56 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 15 Nov 2013 15:56:57 -0800 (PST) From: Grant Grundler To: Chris Ball Cc: linux-mmc@vger.kernel.org, Olof Johansson , Stephen Hurd , linux-kernel@vger.kernel.org, Grant Grundler Subject: [PATCH] mmc: disable UHS on broadcom sdhci Date: Fri, 15 Nov 2013 15:56:22 -0800 Message-Id: <1384559782-7614-1-git-send-email-grundler@chromium.org> X-Mailer: git-send-email 1.8.4.1 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.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,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 From: Stephen Hurd Add two new quirks needed by BCM57785 card reader: SDHCI_QUIRK2_BROKEN_UHS: Disables all UHS modes. SDHCI_QUIRK2_BCM57785_CR: Bit twiddles some Broadcom-specific registers and supresses an error about the 64k bar0. Add sdhci_pci_fixes for: o the chip itself with the required quirks in general (lightly tested). o "parrot" (Acer C7 Chromebook) which uses the SDHCI_QUIRK2_BROKEN_UHS quirk: disables ADMA mode, and adds a delay after power. Signed-off-by: Stephen Hurd Signed-off-by: Grant Grundler --- drivers/mmc/host/sdhci-pci.c | 38 ++++++++++++++++++++++++++++++++++++++ drivers/mmc/host/sdhci.c | 33 +++++++++++++++++++++++++++++++-- include/linux/mmc/sdhci.h | 6 ++++++ 3 files changed, 75 insertions(+), 2 deletions(-) This patch is "V2" of what ChromeOS has been using for the past year to support Acer C7 Chromebook card reader: https://chromium.googlesource.com/chromiumos/third_party/kernel-next/+/fd1acc54a6b3db4e6503ccc4a9349f28b436031a This patch is for linux-2.6 3.12.0 and is "Compile Tested" only. diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index d7d6bc8..96e3116 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -168,6 +168,28 @@ static const struct sdhci_pci_fixes sdhci_cafe = { SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, }; +#define BRCM_SDHCI_QUIRKS ( \ + SDHCI_QUIRK_32BIT_DMA_ADDR | \ + SDHCI_QUIRK_32BIT_DMA_SIZE | \ + SDHCI_QUIRK_32BIT_ADMA_SIZE | \ + SDHCI_QUIRK_BROKEN_TIMEOUT_VAL | \ + SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 | \ + 0) + +#define BRCM_SDHCI_QUIRKS2 (SDHCI_QUIRK2_BCM57785_CR | 0) + +static const struct sdhci_pci_fixes sdhci_brcm = { + .quirks = BRCM_SDHCI_QUIRKS, + .quirks2 = BRCM_SDHCI_QUIRKS2, +}; + +static const struct sdhci_pci_fixes sdhci_nouhs_brcm = { + .quirks = BRCM_SDHCI_QUIRKS | + SDHCI_QUIRK_DELAY_AFTER_POWER | + SDHCI_QUIRK_BROKEN_ADMA, + .quirks2 = BRCM_SDHCI_QUIRKS2 | SDHCI_QUIRK2_BROKEN_UHS, +}; + static int mrst_hc_probe_slot(struct sdhci_pci_slot *slot) { slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA; @@ -979,6 +1001,22 @@ static const struct pci_device_id pci_ids[] = { .driver_data = (kernel_ulong_t)&sdhci_o2, }, + { + .vendor = PCI_VENDOR_ID_BROADCOM, + .device = 0x16bc, + .subvendor = PCI_VENDOR_ID_AI, + .subdevice = 0x0742, + .driver_data = (kernel_ulong_t)&sdhci_nouhs_brcm, + }, + + { + .vendor = PCI_VENDOR_ID_BROADCOM, + .device = 0x16bc, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = (kernel_ulong_t)&sdhci_brcm, + }, + { /* Generic SD host controller */ PCI_DEVICE_CLASS((PCI_CLASS_SYSTEM_SDHCI << 8), 0xFFFF00) }, diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 7a7fb4f..cf26c0f 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1144,6 +1144,27 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) return; } + if (host->quirks2 & SDHCI_QUIRK2_BCM57785_CR) { + u32 tmp; + + /* + * Register descriptions from: + * http://www.broadcom.com/collateral/pg/57785-PG103-R.pdf + */ + tmp = sdhci_readl(host, BCM57785_CR_MUX_CTL); + tmp &= ~0x3000; /* bits 12:15 are reserved */ + sdhci_writel(host, tmp, BCM57785_CR_MUX_CTL); + + tmp = sdhci_readl(host, BCM57785_CR_CLK_CTL); + tmp &= ~(0x01a03f30); /* Internal debug for SD3.0 */ + tmp |= (0x00500000); + + if ((sdhci_readw(host, SDHCI_HOST_CONTROL2) & + SDHCI_CTRL_VDD_180) && (clock >= 200000000)) + tmp |= (1<<24); + sdhci_writel(host, tmp, BCM57785_CR_CLK_CTL); + } + sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); if (clock == 0) @@ -1546,9 +1567,11 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) if ((ios->timing == MMC_TIMING_MMC_HS200) || (ios->timing == MMC_TIMING_UHS_SDR104)) ctrl_2 |= SDHCI_CTRL_UHS_SDR104; - else if (ios->timing == MMC_TIMING_UHS_SDR12) + else if ((ios->timing == MMC_TIMING_UHS_SDR12) && + (host->mmc->caps & MMC_CAP_UHS_SDR12)) ctrl_2 |= SDHCI_CTRL_UHS_SDR12; - else if (ios->timing == MMC_TIMING_UHS_SDR25) + else if ((ios->timing == MMC_TIMING_UHS_SDR25) && + (host->mmc->caps & MMC_CAP_UHS_SDR25)) ctrl_2 |= SDHCI_CTRL_UHS_SDR25; else if (ios->timing == MMC_TIMING_UHS_SDR50) ctrl_2 |= SDHCI_CTRL_UHS_SDR50; @@ -2791,12 +2814,18 @@ int sdhci_add_host(struct sdhci_host *host) caps[0] = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps : sdhci_readl(host, SDHCI_CAPABILITIES); + if (host->quirks2 & SDHCI_QUIRK2_BROKEN_UHS) + caps[0] &= ~(SDHCI_CAN_VDD_180); if (host->version >= SDHCI_SPEC_300) caps[1] = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps1 : sdhci_readl(host, SDHCI_CAPABILITIES_1); + if (host->quirks2 & SDHCI_QUIRK2_BROKEN_UHS) + caps[1] &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 | + SDHCI_SUPPORT_DDR50 | SDHCI_USE_SDR50_TUNING); + if (host->quirks & SDHCI_QUIRK_FORCE_DMA) host->flags |= SDHCI_USE_SDMA; else if (!(caps[0] & SDHCI_CAN_DO_SDMA)) diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h index 3e781b8..664003a 100644 --- a/include/linux/mmc/sdhci.h +++ b/include/linux/mmc/sdhci.h @@ -98,6 +98,12 @@ struct sdhci_host { #define SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON (1<<4) /* Controller has a non-standard host control register */ #define SDHCI_QUIRK2_BROKEN_HOST_CONTROL (1<<5) +/* UHS modes do not work */ +#define SDHCI_QUIRK2_BROKEN_UHS (1<<6) +/* hacks for Broadcom-specific card reader bugs */ +#define SDHCI_QUIRK2_BCM57785_CR (1<<7) +#define BCM57785_CR_MUX_CTL 0x198 /* Card Reader MUX control */ +#define BCM57785_CR_CLK_CTL 0x19c /* Card Reader Clock Status/Ctl */ int irq; /* Device IRQ */ void __iomem *ioaddr; /* Mapped address */