diff options
-rw-r--r-- | arch/arm/mach-mvf/clock.c | 2 | ||||
-rw-r--r-- | drivers/mmc/host/sdhci-esdhc-imx.c | 16 | ||||
-rwxr-xr-x | drivers/mmc/host/sdhci.c | 47 |
3 files changed, 45 insertions, 20 deletions
diff --git a/arch/arm/mach-mvf/clock.c b/arch/arm/mach-mvf/clock.c index 71c51d5230c0..29cc445fc799 100644 --- a/arch/arm/mach-mvf/clock.c +++ b/arch/arm/mach-mvf/clock.c @@ -1727,7 +1727,7 @@ int __init mvf_clocks_init(unsigned long ckil, unsigned long osc, /*clk_set_parent(&enet_clk, &pll5_enet_main_clk);*/ clk_set_parent(&esdhc1_clk, &pll1_pfd3_396M); - clk_set_rate(&esdhc1_clk, 100000000); + clk_set_rate(&esdhc1_clk, 200000000); clk_set_parent(&dcu0_clk, &pll1_pfd2_452M); clk_set_rate(&dcu0_clk, 113000000); diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 2296eb8d1c18..3dcfcb043ef0 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -134,6 +134,16 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg) val |= SDHCI_CARD_PRESENT; } + if (reg == SDHCI_CAPABILITIES && cpu_is_mvf()) + { + if (val & SDHCI_CAN_DO_ADMA1) { + u32 tmp = readl(host->ioaddr + SDHCI_SLOT_INT_STATUS); + tmp = (tmp & SDHCI_VENDOR_VER_MASK) >> SDHCI_VENDOR_VER_SHIFT; + if (tmp >= 0x12) + val |= SDHCI_CAN_DO_ADMA2; + } + } + if (reg == SDHCI_INT_STATUS && cpu_is_mx6() && mx6q_revision() == IMX_CHIP_REVISION_1_0) { /* @@ -786,10 +796,16 @@ static void esdhc_pltfm_exit(struct sdhci_host *host) } struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = { +#ifdef CONFIG_ARCH_MVF + .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION + | SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_NO_CARD_NO_RESET + | SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC, +#else .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_BROKEN_CARD_DETECTION | SDHCI_QUIRK_NO_HISPD_BIT, /* ADMA has issues. Might be fixable */ +#endif .ops = &sdhci_esdhc_ops, .init = esdhc_pltfm_init, .exit = esdhc_pltfm_exit, diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 82afe0522ecc..189dff37e84e 100755 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -2,6 +2,7 @@ * linux/drivers/mmc/host/sdhci.c - Secure Digital Host Controller Interface driver * * Copyright (C) 2005-2011 Pierre Ossman, All Rights Reserved. + * Copyright 2012 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -42,6 +43,12 @@ #define MAX_TUNING_LOOP 40 +#ifdef CONFIG_ARCH_MVF +#define ADDR_ALIGNED 0xF +#else +#define ADDR_ALIGNED 0x3 +#endif + static unsigned int debug_quirks = 0; static void sdhci_finish_data(struct sdhci_host *); @@ -497,10 +504,10 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, */ host->align_addr = dma_map_single(mmc_dev(host->mmc), - host->align_buffer, 128 * 4, direction); + host->align_buffer, 128 * (ADDR_ALIGNED + 1), direction); if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) goto fail; - BUG_ON(host->align_addr & 0x3); + BUG_ON(host->align_addr & ADDR_ALIGNED); host->sg_count = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, direction); @@ -523,22 +530,22 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, * the (up to three) bytes that screw up the * alignment. */ - offset = (4 - (addr & 0x3)) & 0x3; + offset = ((ADDR_ALIGNED + 1) - (addr & ADDR_ALIGNED)) & ADDR_ALIGNED; if (offset) { if (data->flags & MMC_DATA_WRITE) { buffer = sdhci_kmap_atomic(sg, &flags); - WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3)); + WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - ADDR_ALIGNED)); memcpy(align, buffer, offset); sdhci_kunmap_atomic(buffer, &flags); } /* tran, valid */ - sdhci_set_adma_desc(desc, align_addr, offset, 0x21); + sdhci_set_adma_desc(desc, align_addr, (len - offset) ? offset : len, 0x21); BUG_ON(offset > 65536); - align += 4; - align_addr += 4; + align += (ADDR_ALIGNED + 1); + align_addr += (ADDR_ALIGNED + 1); desc += 8; @@ -549,8 +556,10 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, BUG_ON(len > 65536); /* tran, valid */ - sdhci_set_adma_desc(desc, addr, len, 0x21); - desc += 8; + if (len > 0) { + sdhci_set_adma_desc(desc, addr, len, 0x21); + desc += 8; + } /* * If this triggers then we have a calculation bug @@ -581,14 +590,14 @@ static int sdhci_adma_table_pre(struct sdhci_host *host, */ if (data->flags & MMC_DATA_WRITE) { dma_sync_single_for_device(mmc_dev(host->mmc), - host->align_addr, 128 * 4, direction); + host->align_addr, 128 * (ADDR_ALIGNED + 1), direction); } host->adma_addr = dma_map_single(mmc_dev(host->mmc), host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE); if (dma_mapping_error(mmc_dev(host->mmc), host->adma_addr)) goto unmap_entries; - BUG_ON(host->adma_addr & 0x3); + BUG_ON(host->adma_addr & ADDR_ALIGNED); return 0; @@ -597,7 +606,7 @@ unmap_entries: data->sg_len, direction); unmap_align: dma_unmap_single(mmc_dev(host->mmc), host->align_addr, - 128 * 4, direction); + 128 * (ADDR_ALIGNED + 1), direction); fail: return -EINVAL; } @@ -622,7 +631,7 @@ static void sdhci_adma_table_post(struct sdhci_host *host, (128 * 2 + 1) * 4, DMA_TO_DEVICE); dma_unmap_single(mmc_dev(host->mmc), host->align_addr, - 128 * 4, direction); + 128 * (ADDR_ALIGNED + 1), direction); if (data->flags & MMC_DATA_READ) { dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg, @@ -631,15 +640,15 @@ static void sdhci_adma_table_post(struct sdhci_host *host, align = host->align_buffer; for_each_sg(data->sg, sg, host->sg_count, i) { - if (sg_dma_address(sg) & 0x3) { - size = 4 - (sg_dma_address(sg) & 0x3); + if (sg_dma_address(sg) & ADDR_ALIGNED) { + size = (ADDR_ALIGNED + 1) - (sg_dma_address(sg) & ADDR_ALIGNED); buffer = sdhci_kmap_atomic(sg, &flags); - WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3)); - memcpy(buffer, align, size); + WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - ADDR_ALIGNED)); + memcpy(buffer, align, (size - data->sg->length) ? data->sg->length : size); sdhci_kunmap_atomic(buffer, &flags); - align += 4; + align += (ADDR_ALIGNED + 1); } } } @@ -2559,7 +2568,7 @@ int sdhci_add_host(struct sdhci_host *host) * each of those entries. */ host->adma_desc = kmalloc((128 * 2 + 1) * 4, GFP_KERNEL); - host->align_buffer = kmalloc(128 * 4, GFP_KERNEL); + host->align_buffer = kmalloc(128 * (ADDR_ALIGNED + 1), GFP_KERNEL); if (!host->adma_desc || !host->align_buffer) { kfree(host->adma_desc); kfree(host->align_buffer); |