From patchwork Fri Feb 13 14:47:39 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Vorontsov X-Patchwork-Id: 23122 X-Patchwork-Delegate: galak@kernel.crashing.org Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix) with ESMTP id 02CB3DDF34 for ; Sat, 14 Feb 2009 02:34:26 +1100 (EST) X-Original-To: linuxppc-dev@ozlabs.org Delivered-To: linuxppc-dev@ozlabs.org Received: from buildserver.ru.mvista.com (unknown [85.21.88.6]) by ozlabs.org (Postfix) with ESMTP id 48595DE0B2 for ; Sat, 14 Feb 2009 01:47:41 +1100 (EST) Received: from localhost (unknown [10.150.0.9]) by buildserver.ru.mvista.com (Postfix) with ESMTP id 4777F882D; Fri, 13 Feb 2009 19:47:42 +0400 (SAMT) Date: Fri, 13 Feb 2009 17:47:39 +0300 From: Anton Vorontsov To: Pierre Ossman Subject: [PATCH 12/13] sdhci: Add quirk for controllers with max. block size up to 4096 bytes Message-ID: <20090213144739.GL23889@oksana.dev.rtsoft.ru> References: <20090213144630.GA13436@oksana.dev.rtsoft.ru> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20090213144630.GA13436@oksana.dev.rtsoft.ru> User-Agent: Mutt/1.5.18 (2008-05-17) Cc: Ben Dooks , Arnd Bergmann , Liu Dave , linux-kernel@vger.kernel.org, linuxppc-dev@ozlabs.org, sdhci-devel@list.drzeus.cx X-BeenThere: linuxppc-dev@ozlabs.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org FSL eSDHC controllers can support maximum block size up to 4096 bytes. The MBL (Maximum Block Length) field in the capabilities register extended by one bit, and bits 13:15 in the block size register reserved. Signed-off-by: Anton Vorontsov --- drivers/mmc/host/sdhci.c | 28 ++++++++++++++++++++-------- drivers/mmc/host/sdhci.h | 2 ++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index b308dbf..b341a9a 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -682,6 +682,7 @@ static void sdhci_set_transfer_irqs(struct sdhci_host *host) static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) { + u16 blksz; u8 count; u8 ctrl; int ret; @@ -831,7 +832,12 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) sdhci_set_transfer_irqs(host); /* We do not handle DMA boundaries, so set it to max (512 KiB) */ - sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE); + if (host->quirks & SDHCI_QUIRK_MAX_BLK_SZ_4096) + blksz = data->blksz; + else + blksz = SDHCI_MAKE_BLKSZ(7, data->blksz); + + sdhci_writew(host, blksz, SDHCI_BLOCK_SIZE); sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT); } @@ -1840,13 +1846,19 @@ int sdhci_add_host(struct sdhci_host *host) * Maximum block size. This varies from controller to controller and * is specified in the capabilities register. */ - mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT; - if (mmc->max_blk_size >= 3) { - printk(KERN_WARNING "%s: Invalid maximum block size, " - "assuming 512 bytes\n", mmc_hostname(mmc)); - mmc->max_blk_size = 512; - } else - mmc->max_blk_size = 512 << mmc->max_blk_size; + if (host->quirks & SDHCI_QUIRK_MAX_BLK_SZ_4096) { + mmc->max_blk_size = 3; + } else { + mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> + SDHCI_MAX_BLOCK_SHIFT; + if (mmc->max_blk_size >= 3) { + printk(KERN_WARNING "%s: Invalid maximum block size, " + "assuming 512 bytes\n", mmc_hostname(mmc)); + mmc->max_blk_size = 0; + } + } + + mmc->max_blk_size = 512 << mmc->max_blk_size; /* * Maximum block count. diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 5c5a950..c8628b4 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -231,6 +231,8 @@ struct sdhci_host { #define SDHCI_QUIRK_PIO_NEEDS_DELAY (1<<20) /* Controller losing signal/interrupt enable states after reset */ #define SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET (1<<21) +/* Controller supports nonstandard maximum block length of 4096 bytes */ +#define SDHCI_QUIRK_MAX_BLK_SZ_4096 (1<<22) int irq; /* Device IRQ */ void __iomem * ioaddr; /* Mapped address */