11c6a0718SPierre Ossman /* 270f10482SPierre Ossman * linux/drivers/mmc/host/sdhci.c - Secure Digital Host Controller Interface driver 31c6a0718SPierre Ossman * 4b69c9058SPierre Ossman * Copyright (C) 2005-2008 Pierre Ossman, All Rights Reserved. 51c6a0718SPierre Ossman * 61c6a0718SPierre Ossman * This program is free software; you can redistribute it and/or modify 71c6a0718SPierre Ossman * it under the terms of the GNU General Public License as published by 81c6a0718SPierre Ossman * the Free Software Foundation; either version 2 of the License, or (at 91c6a0718SPierre Ossman * your option) any later version. 1084c46a53SPierre Ossman * 1184c46a53SPierre Ossman * Thanks to the following companies for their support: 1284c46a53SPierre Ossman * 1384c46a53SPierre Ossman * - JMicron (hardware and technical support) 141c6a0718SPierre Ossman */ 151c6a0718SPierre Ossman 161c6a0718SPierre Ossman #include <linux/delay.h> 171c6a0718SPierre Ossman #include <linux/highmem.h> 18b8c86fc5SPierre Ossman #include <linux/io.h> 191c6a0718SPierre Ossman #include <linux/dma-mapping.h> 205a0e3ad6STejun Heo #include <linux/slab.h> 2111763609SRalf Baechle #include <linux/scatterlist.h> 229bea3c85SMarek Szyprowski #include <linux/regulator/consumer.h> 231c6a0718SPierre Ossman 242f730fecSPierre Ossman #include <linux/leds.h> 252f730fecSPierre Ossman 2622113efdSAries Lee #include <linux/mmc/mmc.h> 271c6a0718SPierre Ossman #include <linux/mmc/host.h> 281c6a0718SPierre Ossman 291c6a0718SPierre Ossman #include "sdhci.h" 301c6a0718SPierre Ossman 311c6a0718SPierre Ossman #define DRIVER_NAME "sdhci" 321c6a0718SPierre Ossman 331c6a0718SPierre Ossman #define DBG(f, x...) \ 341c6a0718SPierre Ossman pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) 351c6a0718SPierre Ossman 36f9134319SPierre Ossman #if defined(CONFIG_LEDS_CLASS) || (defined(CONFIG_LEDS_CLASS_MODULE) && \ 37f9134319SPierre Ossman defined(CONFIG_MMC_SDHCI_MODULE)) 38f9134319SPierre Ossman #define SDHCI_USE_LEDS_CLASS 39f9134319SPierre Ossman #endif 40f9134319SPierre Ossman 411c6a0718SPierre Ossman static unsigned int debug_quirks = 0; 421c6a0718SPierre Ossman 431c6a0718SPierre Ossman static void sdhci_finish_data(struct sdhci_host *); 441c6a0718SPierre Ossman 451c6a0718SPierre Ossman static void sdhci_send_command(struct sdhci_host *, struct mmc_command *); 461c6a0718SPierre Ossman static void sdhci_finish_command(struct sdhci_host *); 471c6a0718SPierre Ossman 481c6a0718SPierre Ossman static void sdhci_dumpregs(struct sdhci_host *host) 491c6a0718SPierre Ossman { 50412ab659SPhilip Rakity printk(KERN_DEBUG DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n", 51412ab659SPhilip Rakity mmc_hostname(host->mmc)); 521c6a0718SPierre Ossman 531c6a0718SPierre Ossman printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n", 544e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_DMA_ADDRESS), 554e4141a5SAnton Vorontsov sdhci_readw(host, SDHCI_HOST_VERSION)); 561c6a0718SPierre Ossman printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n", 574e4141a5SAnton Vorontsov sdhci_readw(host, SDHCI_BLOCK_SIZE), 584e4141a5SAnton Vorontsov sdhci_readw(host, SDHCI_BLOCK_COUNT)); 591c6a0718SPierre Ossman printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n", 604e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_ARGUMENT), 614e4141a5SAnton Vorontsov sdhci_readw(host, SDHCI_TRANSFER_MODE)); 621c6a0718SPierre Ossman printk(KERN_DEBUG DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n", 634e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_PRESENT_STATE), 644e4141a5SAnton Vorontsov sdhci_readb(host, SDHCI_HOST_CONTROL)); 651c6a0718SPierre Ossman printk(KERN_DEBUG DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n", 664e4141a5SAnton Vorontsov sdhci_readb(host, SDHCI_POWER_CONTROL), 674e4141a5SAnton Vorontsov sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL)); 681c6a0718SPierre Ossman printk(KERN_DEBUG DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n", 694e4141a5SAnton Vorontsov sdhci_readb(host, SDHCI_WAKE_UP_CONTROL), 704e4141a5SAnton Vorontsov sdhci_readw(host, SDHCI_CLOCK_CONTROL)); 711c6a0718SPierre Ossman printk(KERN_DEBUG DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n", 724e4141a5SAnton Vorontsov sdhci_readb(host, SDHCI_TIMEOUT_CONTROL), 734e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_INT_STATUS)); 741c6a0718SPierre Ossman printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n", 754e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_INT_ENABLE), 764e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_SIGNAL_ENABLE)); 771c6a0718SPierre Ossman printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n", 784e4141a5SAnton Vorontsov sdhci_readw(host, SDHCI_ACMD12_ERR), 794e4141a5SAnton Vorontsov sdhci_readw(host, SDHCI_SLOT_INT_STATUS)); 80e8120ad1SPhilip Rakity printk(KERN_DEBUG DRIVER_NAME ": Caps: 0x%08x | Caps_1: 0x%08x\n", 814e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_CAPABILITIES), 82e8120ad1SPhilip Rakity sdhci_readl(host, SDHCI_CAPABILITIES_1)); 83e8120ad1SPhilip Rakity printk(KERN_DEBUG DRIVER_NAME ": Cmd: 0x%08x | Max curr: 0x%08x\n", 84e8120ad1SPhilip Rakity sdhci_readw(host, SDHCI_COMMAND), 854e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_MAX_CURRENT)); 86f2119df6SArindam Nath printk(KERN_DEBUG DRIVER_NAME ": Host ctl2: 0x%08x\n", 87f2119df6SArindam Nath sdhci_readw(host, SDHCI_HOST_CONTROL2)); 881c6a0718SPierre Ossman 89be3f4ae0SBen Dooks if (host->flags & SDHCI_USE_ADMA) 90be3f4ae0SBen Dooks printk(KERN_DEBUG DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n", 91be3f4ae0SBen Dooks readl(host->ioaddr + SDHCI_ADMA_ERROR), 92be3f4ae0SBen Dooks readl(host->ioaddr + SDHCI_ADMA_ADDRESS)); 93be3f4ae0SBen Dooks 941c6a0718SPierre Ossman printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n"); 951c6a0718SPierre Ossman } 961c6a0718SPierre Ossman 971c6a0718SPierre Ossman /*****************************************************************************\ 981c6a0718SPierre Ossman * * 991c6a0718SPierre Ossman * Low level functions * 1001c6a0718SPierre Ossman * * 1011c6a0718SPierre Ossman \*****************************************************************************/ 1021c6a0718SPierre Ossman 1037260cf5eSAnton Vorontsov static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set) 1047260cf5eSAnton Vorontsov { 1057260cf5eSAnton Vorontsov u32 ier; 1067260cf5eSAnton Vorontsov 1077260cf5eSAnton Vorontsov ier = sdhci_readl(host, SDHCI_INT_ENABLE); 1087260cf5eSAnton Vorontsov ier &= ~clear; 1097260cf5eSAnton Vorontsov ier |= set; 1107260cf5eSAnton Vorontsov sdhci_writel(host, ier, SDHCI_INT_ENABLE); 1117260cf5eSAnton Vorontsov sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE); 1127260cf5eSAnton Vorontsov } 1137260cf5eSAnton Vorontsov 1147260cf5eSAnton Vorontsov static void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs) 1157260cf5eSAnton Vorontsov { 1167260cf5eSAnton Vorontsov sdhci_clear_set_irqs(host, 0, irqs); 1177260cf5eSAnton Vorontsov } 1187260cf5eSAnton Vorontsov 1197260cf5eSAnton Vorontsov static void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs) 1207260cf5eSAnton Vorontsov { 1217260cf5eSAnton Vorontsov sdhci_clear_set_irqs(host, irqs, 0); 1227260cf5eSAnton Vorontsov } 1237260cf5eSAnton Vorontsov 1247260cf5eSAnton Vorontsov static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) 1257260cf5eSAnton Vorontsov { 1267260cf5eSAnton Vorontsov u32 irqs = SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT; 1277260cf5eSAnton Vorontsov 12868d1fb7eSAnton Vorontsov if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) 12968d1fb7eSAnton Vorontsov return; 13068d1fb7eSAnton Vorontsov 1317260cf5eSAnton Vorontsov if (enable) 1327260cf5eSAnton Vorontsov sdhci_unmask_irqs(host, irqs); 1337260cf5eSAnton Vorontsov else 1347260cf5eSAnton Vorontsov sdhci_mask_irqs(host, irqs); 1357260cf5eSAnton Vorontsov } 1367260cf5eSAnton Vorontsov 1377260cf5eSAnton Vorontsov static void sdhci_enable_card_detection(struct sdhci_host *host) 1387260cf5eSAnton Vorontsov { 1397260cf5eSAnton Vorontsov sdhci_set_card_detection(host, true); 1407260cf5eSAnton Vorontsov } 1417260cf5eSAnton Vorontsov 1427260cf5eSAnton Vorontsov static void sdhci_disable_card_detection(struct sdhci_host *host) 1437260cf5eSAnton Vorontsov { 1447260cf5eSAnton Vorontsov sdhci_set_card_detection(host, false); 1457260cf5eSAnton Vorontsov } 1467260cf5eSAnton Vorontsov 1471c6a0718SPierre Ossman static void sdhci_reset(struct sdhci_host *host, u8 mask) 1481c6a0718SPierre Ossman { 1491c6a0718SPierre Ossman unsigned long timeout; 150063a9dbbSAnton Vorontsov u32 uninitialized_var(ier); 1511c6a0718SPierre Ossman 152b8c86fc5SPierre Ossman if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { 1534e4141a5SAnton Vorontsov if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & 1541c6a0718SPierre Ossman SDHCI_CARD_PRESENT)) 1551c6a0718SPierre Ossman return; 1561c6a0718SPierre Ossman } 1571c6a0718SPierre Ossman 158063a9dbbSAnton Vorontsov if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) 159063a9dbbSAnton Vorontsov ier = sdhci_readl(host, SDHCI_INT_ENABLE); 160063a9dbbSAnton Vorontsov 161393c1a34SPhilip Rakity if (host->ops->platform_reset_enter) 162393c1a34SPhilip Rakity host->ops->platform_reset_enter(host, mask); 163393c1a34SPhilip Rakity 1644e4141a5SAnton Vorontsov sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET); 1651c6a0718SPierre Ossman 1661c6a0718SPierre Ossman if (mask & SDHCI_RESET_ALL) 1671c6a0718SPierre Ossman host->clock = 0; 1681c6a0718SPierre Ossman 1691c6a0718SPierre Ossman /* Wait max 100 ms */ 1701c6a0718SPierre Ossman timeout = 100; 1711c6a0718SPierre Ossman 1721c6a0718SPierre Ossman /* hw clears the bit when it's done */ 1734e4141a5SAnton Vorontsov while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) { 1741c6a0718SPierre Ossman if (timeout == 0) { 1751c6a0718SPierre Ossman printk(KERN_ERR "%s: Reset 0x%x never completed.\n", 1761c6a0718SPierre Ossman mmc_hostname(host->mmc), (int)mask); 1771c6a0718SPierre Ossman sdhci_dumpregs(host); 1781c6a0718SPierre Ossman return; 1791c6a0718SPierre Ossman } 1801c6a0718SPierre Ossman timeout--; 1811c6a0718SPierre Ossman mdelay(1); 1821c6a0718SPierre Ossman } 183063a9dbbSAnton Vorontsov 184393c1a34SPhilip Rakity if (host->ops->platform_reset_exit) 185393c1a34SPhilip Rakity host->ops->platform_reset_exit(host, mask); 186393c1a34SPhilip Rakity 187063a9dbbSAnton Vorontsov if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) 188063a9dbbSAnton Vorontsov sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier); 1891c6a0718SPierre Ossman } 1901c6a0718SPierre Ossman 1912f4cbb3dSNicolas Pitre static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); 1922f4cbb3dSNicolas Pitre 1932f4cbb3dSNicolas Pitre static void sdhci_init(struct sdhci_host *host, int soft) 1941c6a0718SPierre Ossman { 1952f4cbb3dSNicolas Pitre if (soft) 1962f4cbb3dSNicolas Pitre sdhci_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA); 1972f4cbb3dSNicolas Pitre else 1981c6a0718SPierre Ossman sdhci_reset(host, SDHCI_RESET_ALL); 1991c6a0718SPierre Ossman 2007260cf5eSAnton Vorontsov sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, 2017260cf5eSAnton Vorontsov SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | 2021c6a0718SPierre Ossman SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX | 2031c6a0718SPierre Ossman SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT | 2046aa943abSAnton Vorontsov SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE); 2052f4cbb3dSNicolas Pitre 2062f4cbb3dSNicolas Pitre if (soft) { 2072f4cbb3dSNicolas Pitre /* force clock reconfiguration */ 2082f4cbb3dSNicolas Pitre host->clock = 0; 2092f4cbb3dSNicolas Pitre sdhci_set_ios(host->mmc, &host->mmc->ios); 2102f4cbb3dSNicolas Pitre } 2117260cf5eSAnton Vorontsov } 2121c6a0718SPierre Ossman 2137260cf5eSAnton Vorontsov static void sdhci_reinit(struct sdhci_host *host) 2147260cf5eSAnton Vorontsov { 2152f4cbb3dSNicolas Pitre sdhci_init(host, 0); 2167260cf5eSAnton Vorontsov sdhci_enable_card_detection(host); 2171c6a0718SPierre Ossman } 2181c6a0718SPierre Ossman 2191c6a0718SPierre Ossman static void sdhci_activate_led(struct sdhci_host *host) 2201c6a0718SPierre Ossman { 2211c6a0718SPierre Ossman u8 ctrl; 2221c6a0718SPierre Ossman 2234e4141a5SAnton Vorontsov ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 2241c6a0718SPierre Ossman ctrl |= SDHCI_CTRL_LED; 2254e4141a5SAnton Vorontsov sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 2261c6a0718SPierre Ossman } 2271c6a0718SPierre Ossman 2281c6a0718SPierre Ossman static void sdhci_deactivate_led(struct sdhci_host *host) 2291c6a0718SPierre Ossman { 2301c6a0718SPierre Ossman u8 ctrl; 2311c6a0718SPierre Ossman 2324e4141a5SAnton Vorontsov ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 2331c6a0718SPierre Ossman ctrl &= ~SDHCI_CTRL_LED; 2344e4141a5SAnton Vorontsov sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 2351c6a0718SPierre Ossman } 2361c6a0718SPierre Ossman 237f9134319SPierre Ossman #ifdef SDHCI_USE_LEDS_CLASS 2382f730fecSPierre Ossman static void sdhci_led_control(struct led_classdev *led, 2392f730fecSPierre Ossman enum led_brightness brightness) 2402f730fecSPierre Ossman { 2412f730fecSPierre Ossman struct sdhci_host *host = container_of(led, struct sdhci_host, led); 2422f730fecSPierre Ossman unsigned long flags; 2432f730fecSPierre Ossman 2442f730fecSPierre Ossman spin_lock_irqsave(&host->lock, flags); 2452f730fecSPierre Ossman 2462f730fecSPierre Ossman if (brightness == LED_OFF) 2472f730fecSPierre Ossman sdhci_deactivate_led(host); 2482f730fecSPierre Ossman else 2492f730fecSPierre Ossman sdhci_activate_led(host); 2502f730fecSPierre Ossman 2512f730fecSPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 2522f730fecSPierre Ossman } 2532f730fecSPierre Ossman #endif 2542f730fecSPierre Ossman 2551c6a0718SPierre Ossman /*****************************************************************************\ 2561c6a0718SPierre Ossman * * 2571c6a0718SPierre Ossman * Core functions * 2581c6a0718SPierre Ossman * * 2591c6a0718SPierre Ossman \*****************************************************************************/ 2601c6a0718SPierre Ossman 2611c6a0718SPierre Ossman static void sdhci_read_block_pio(struct sdhci_host *host) 2621c6a0718SPierre Ossman { 2637659150cSPierre Ossman unsigned long flags; 2647659150cSPierre Ossman size_t blksize, len, chunk; 2657244b85bSSteven Noonan u32 uninitialized_var(scratch); 2667659150cSPierre Ossman u8 *buf; 2671c6a0718SPierre Ossman 2681c6a0718SPierre Ossman DBG("PIO reading\n"); 2691c6a0718SPierre Ossman 2701c6a0718SPierre Ossman blksize = host->data->blksz; 2717659150cSPierre Ossman chunk = 0; 2721c6a0718SPierre Ossman 2737659150cSPierre Ossman local_irq_save(flags); 2741c6a0718SPierre Ossman 2751c6a0718SPierre Ossman while (blksize) { 2767659150cSPierre Ossman if (!sg_miter_next(&host->sg_miter)) 2777659150cSPierre Ossman BUG(); 2787659150cSPierre Ossman 2797659150cSPierre Ossman len = min(host->sg_miter.length, blksize); 2807659150cSPierre Ossman 2817659150cSPierre Ossman blksize -= len; 2827659150cSPierre Ossman host->sg_miter.consumed = len; 2837659150cSPierre Ossman 2847659150cSPierre Ossman buf = host->sg_miter.addr; 2857659150cSPierre Ossman 2867659150cSPierre Ossman while (len) { 2877659150cSPierre Ossman if (chunk == 0) { 2884e4141a5SAnton Vorontsov scratch = sdhci_readl(host, SDHCI_BUFFER); 2897659150cSPierre Ossman chunk = 4; 2901c6a0718SPierre Ossman } 2911c6a0718SPierre Ossman 2927659150cSPierre Ossman *buf = scratch & 0xFF; 2931c6a0718SPierre Ossman 2947659150cSPierre Ossman buf++; 2957659150cSPierre Ossman scratch >>= 8; 2967659150cSPierre Ossman chunk--; 2977659150cSPierre Ossman len--; 2987659150cSPierre Ossman } 2991c6a0718SPierre Ossman } 3001c6a0718SPierre Ossman 3017659150cSPierre Ossman sg_miter_stop(&host->sg_miter); 3027659150cSPierre Ossman 3037659150cSPierre Ossman local_irq_restore(flags); 3041c6a0718SPierre Ossman } 3051c6a0718SPierre Ossman 3061c6a0718SPierre Ossman static void sdhci_write_block_pio(struct sdhci_host *host) 3071c6a0718SPierre Ossman { 3087659150cSPierre Ossman unsigned long flags; 3097659150cSPierre Ossman size_t blksize, len, chunk; 3107659150cSPierre Ossman u32 scratch; 3117659150cSPierre Ossman u8 *buf; 3121c6a0718SPierre Ossman 3131c6a0718SPierre Ossman DBG("PIO writing\n"); 3141c6a0718SPierre Ossman 3151c6a0718SPierre Ossman blksize = host->data->blksz; 3167659150cSPierre Ossman chunk = 0; 3177659150cSPierre Ossman scratch = 0; 3181c6a0718SPierre Ossman 3197659150cSPierre Ossman local_irq_save(flags); 3201c6a0718SPierre Ossman 3211c6a0718SPierre Ossman while (blksize) { 3227659150cSPierre Ossman if (!sg_miter_next(&host->sg_miter)) 3237659150cSPierre Ossman BUG(); 3241c6a0718SPierre Ossman 3257659150cSPierre Ossman len = min(host->sg_miter.length, blksize); 3261c6a0718SPierre Ossman 3277659150cSPierre Ossman blksize -= len; 3287659150cSPierre Ossman host->sg_miter.consumed = len; 3297659150cSPierre Ossman 3307659150cSPierre Ossman buf = host->sg_miter.addr; 3317659150cSPierre Ossman 3327659150cSPierre Ossman while (len) { 3337659150cSPierre Ossman scratch |= (u32)*buf << (chunk * 8); 3347659150cSPierre Ossman 3357659150cSPierre Ossman buf++; 3367659150cSPierre Ossman chunk++; 3377659150cSPierre Ossman len--; 3387659150cSPierre Ossman 3397659150cSPierre Ossman if ((chunk == 4) || ((len == 0) && (blksize == 0))) { 3404e4141a5SAnton Vorontsov sdhci_writel(host, scratch, SDHCI_BUFFER); 3417659150cSPierre Ossman chunk = 0; 3427659150cSPierre Ossman scratch = 0; 3437659150cSPierre Ossman } 3447659150cSPierre Ossman } 3451c6a0718SPierre Ossman } 3461c6a0718SPierre Ossman 3477659150cSPierre Ossman sg_miter_stop(&host->sg_miter); 3481c6a0718SPierre Ossman 3497659150cSPierre Ossman local_irq_restore(flags); 3501c6a0718SPierre Ossman } 3511c6a0718SPierre Ossman 3521c6a0718SPierre Ossman static void sdhci_transfer_pio(struct sdhci_host *host) 3531c6a0718SPierre Ossman { 3541c6a0718SPierre Ossman u32 mask; 3551c6a0718SPierre Ossman 3561c6a0718SPierre Ossman BUG_ON(!host->data); 3571c6a0718SPierre Ossman 3587659150cSPierre Ossman if (host->blocks == 0) 3591c6a0718SPierre Ossman return; 3601c6a0718SPierre Ossman 3611c6a0718SPierre Ossman if (host->data->flags & MMC_DATA_READ) 3621c6a0718SPierre Ossman mask = SDHCI_DATA_AVAILABLE; 3631c6a0718SPierre Ossman else 3641c6a0718SPierre Ossman mask = SDHCI_SPACE_AVAILABLE; 3651c6a0718SPierre Ossman 3664a3cba32SPierre Ossman /* 3674a3cba32SPierre Ossman * Some controllers (JMicron JMB38x) mess up the buffer bits 3684a3cba32SPierre Ossman * for transfers < 4 bytes. As long as it is just one block, 3694a3cba32SPierre Ossman * we can ignore the bits. 3704a3cba32SPierre Ossman */ 3714a3cba32SPierre Ossman if ((host->quirks & SDHCI_QUIRK_BROKEN_SMALL_PIO) && 3724a3cba32SPierre Ossman (host->data->blocks == 1)) 3734a3cba32SPierre Ossman mask = ~0; 3744a3cba32SPierre Ossman 3754e4141a5SAnton Vorontsov while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) { 3763e3bf207SAnton Vorontsov if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY) 3773e3bf207SAnton Vorontsov udelay(100); 3783e3bf207SAnton Vorontsov 3791c6a0718SPierre Ossman if (host->data->flags & MMC_DATA_READ) 3801c6a0718SPierre Ossman sdhci_read_block_pio(host); 3811c6a0718SPierre Ossman else 3821c6a0718SPierre Ossman sdhci_write_block_pio(host); 3831c6a0718SPierre Ossman 3847659150cSPierre Ossman host->blocks--; 3857659150cSPierre Ossman if (host->blocks == 0) 3861c6a0718SPierre Ossman break; 3871c6a0718SPierre Ossman } 3881c6a0718SPierre Ossman 3891c6a0718SPierre Ossman DBG("PIO transfer complete.\n"); 3901c6a0718SPierre Ossman } 3911c6a0718SPierre Ossman 3922134a922SPierre Ossman static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags) 3932134a922SPierre Ossman { 3942134a922SPierre Ossman local_irq_save(*flags); 3952134a922SPierre Ossman return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; 3962134a922SPierre Ossman } 3972134a922SPierre Ossman 3982134a922SPierre Ossman static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) 3992134a922SPierre Ossman { 4002134a922SPierre Ossman kunmap_atomic(buffer, KM_BIO_SRC_IRQ); 4012134a922SPierre Ossman local_irq_restore(*flags); 4022134a922SPierre Ossman } 4032134a922SPierre Ossman 404118cd17dSBen Dooks static void sdhci_set_adma_desc(u8 *desc, u32 addr, int len, unsigned cmd) 405118cd17dSBen Dooks { 4069e506f35SBen Dooks __le32 *dataddr = (__le32 __force *)(desc + 4); 4079e506f35SBen Dooks __le16 *cmdlen = (__le16 __force *)desc; 408118cd17dSBen Dooks 4099e506f35SBen Dooks /* SDHCI specification says ADMA descriptors should be 4 byte 4109e506f35SBen Dooks * aligned, so using 16 or 32bit operations should be safe. */ 411118cd17dSBen Dooks 4129e506f35SBen Dooks cmdlen[0] = cpu_to_le16(cmd); 4139e506f35SBen Dooks cmdlen[1] = cpu_to_le16(len); 4149e506f35SBen Dooks 4159e506f35SBen Dooks dataddr[0] = cpu_to_le32(addr); 416118cd17dSBen Dooks } 417118cd17dSBen Dooks 4188f1934ceSPierre Ossman static int sdhci_adma_table_pre(struct sdhci_host *host, 4192134a922SPierre Ossman struct mmc_data *data) 4202134a922SPierre Ossman { 4212134a922SPierre Ossman int direction; 4222134a922SPierre Ossman 4232134a922SPierre Ossman u8 *desc; 4242134a922SPierre Ossman u8 *align; 4252134a922SPierre Ossman dma_addr_t addr; 4262134a922SPierre Ossman dma_addr_t align_addr; 4272134a922SPierre Ossman int len, offset; 4282134a922SPierre Ossman 4292134a922SPierre Ossman struct scatterlist *sg; 4302134a922SPierre Ossman int i; 4312134a922SPierre Ossman char *buffer; 4322134a922SPierre Ossman unsigned long flags; 4332134a922SPierre Ossman 4342134a922SPierre Ossman /* 4352134a922SPierre Ossman * The spec does not specify endianness of descriptor table. 4362134a922SPierre Ossman * We currently guess that it is LE. 4372134a922SPierre Ossman */ 4382134a922SPierre Ossman 4392134a922SPierre Ossman if (data->flags & MMC_DATA_READ) 4402134a922SPierre Ossman direction = DMA_FROM_DEVICE; 4412134a922SPierre Ossman else 4422134a922SPierre Ossman direction = DMA_TO_DEVICE; 4432134a922SPierre Ossman 4442134a922SPierre Ossman /* 4452134a922SPierre Ossman * The ADMA descriptor table is mapped further down as we 4462134a922SPierre Ossman * need to fill it with data first. 4472134a922SPierre Ossman */ 4482134a922SPierre Ossman 4492134a922SPierre Ossman host->align_addr = dma_map_single(mmc_dev(host->mmc), 4502134a922SPierre Ossman host->align_buffer, 128 * 4, direction); 4518d8bb39bSFUJITA Tomonori if (dma_mapping_error(mmc_dev(host->mmc), host->align_addr)) 4528f1934ceSPierre Ossman goto fail; 4532134a922SPierre Ossman BUG_ON(host->align_addr & 0x3); 4542134a922SPierre Ossman 4552134a922SPierre Ossman host->sg_count = dma_map_sg(mmc_dev(host->mmc), 4562134a922SPierre Ossman data->sg, data->sg_len, direction); 4578f1934ceSPierre Ossman if (host->sg_count == 0) 4588f1934ceSPierre Ossman goto unmap_align; 4592134a922SPierre Ossman 4602134a922SPierre Ossman desc = host->adma_desc; 4612134a922SPierre Ossman align = host->align_buffer; 4622134a922SPierre Ossman 4632134a922SPierre Ossman align_addr = host->align_addr; 4642134a922SPierre Ossman 4652134a922SPierre Ossman for_each_sg(data->sg, sg, host->sg_count, i) { 4662134a922SPierre Ossman addr = sg_dma_address(sg); 4672134a922SPierre Ossman len = sg_dma_len(sg); 4682134a922SPierre Ossman 4692134a922SPierre Ossman /* 4702134a922SPierre Ossman * The SDHCI specification states that ADMA 4712134a922SPierre Ossman * addresses must be 32-bit aligned. If they 4722134a922SPierre Ossman * aren't, then we use a bounce buffer for 4732134a922SPierre Ossman * the (up to three) bytes that screw up the 4742134a922SPierre Ossman * alignment. 4752134a922SPierre Ossman */ 4762134a922SPierre Ossman offset = (4 - (addr & 0x3)) & 0x3; 4772134a922SPierre Ossman if (offset) { 4782134a922SPierre Ossman if (data->flags & MMC_DATA_WRITE) { 4792134a922SPierre Ossman buffer = sdhci_kmap_atomic(sg, &flags); 4806cefd05fSPierre Ossman WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3)); 4812134a922SPierre Ossman memcpy(align, buffer, offset); 4822134a922SPierre Ossman sdhci_kunmap_atomic(buffer, &flags); 4832134a922SPierre Ossman } 4842134a922SPierre Ossman 485118cd17dSBen Dooks /* tran, valid */ 486118cd17dSBen Dooks sdhci_set_adma_desc(desc, align_addr, offset, 0x21); 4872134a922SPierre Ossman 4882134a922SPierre Ossman BUG_ON(offset > 65536); 4892134a922SPierre Ossman 4902134a922SPierre Ossman align += 4; 4912134a922SPierre Ossman align_addr += 4; 4922134a922SPierre Ossman 4932134a922SPierre Ossman desc += 8; 4942134a922SPierre Ossman 4952134a922SPierre Ossman addr += offset; 4962134a922SPierre Ossman len -= offset; 4972134a922SPierre Ossman } 4982134a922SPierre Ossman 4992134a922SPierre Ossman BUG_ON(len > 65536); 5002134a922SPierre Ossman 501118cd17dSBen Dooks /* tran, valid */ 502118cd17dSBen Dooks sdhci_set_adma_desc(desc, addr, len, 0x21); 5032134a922SPierre Ossman desc += 8; 5042134a922SPierre Ossman 5052134a922SPierre Ossman /* 5062134a922SPierre Ossman * If this triggers then we have a calculation bug 5072134a922SPierre Ossman * somewhere. :/ 5082134a922SPierre Ossman */ 5092134a922SPierre Ossman WARN_ON((desc - host->adma_desc) > (128 * 2 + 1) * 4); 5102134a922SPierre Ossman } 5112134a922SPierre Ossman 51270764a90SThomas Abraham if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) { 51370764a90SThomas Abraham /* 51470764a90SThomas Abraham * Mark the last descriptor as the terminating descriptor 51570764a90SThomas Abraham */ 51670764a90SThomas Abraham if (desc != host->adma_desc) { 51770764a90SThomas Abraham desc -= 8; 51870764a90SThomas Abraham desc[0] |= 0x2; /* end */ 51970764a90SThomas Abraham } 52070764a90SThomas Abraham } else { 5212134a922SPierre Ossman /* 5222134a922SPierre Ossman * Add a terminating entry. 5232134a922SPierre Ossman */ 5242134a922SPierre Ossman 525118cd17dSBen Dooks /* nop, end, valid */ 526118cd17dSBen Dooks sdhci_set_adma_desc(desc, 0, 0, 0x3); 52770764a90SThomas Abraham } 5282134a922SPierre Ossman 5292134a922SPierre Ossman /* 5302134a922SPierre Ossman * Resync align buffer as we might have changed it. 5312134a922SPierre Ossman */ 5322134a922SPierre Ossman if (data->flags & MMC_DATA_WRITE) { 5332134a922SPierre Ossman dma_sync_single_for_device(mmc_dev(host->mmc), 5342134a922SPierre Ossman host->align_addr, 128 * 4, direction); 5352134a922SPierre Ossman } 5362134a922SPierre Ossman 5372134a922SPierre Ossman host->adma_addr = dma_map_single(mmc_dev(host->mmc), 5382134a922SPierre Ossman host->adma_desc, (128 * 2 + 1) * 4, DMA_TO_DEVICE); 539980167b7SPierre Ossman if (dma_mapping_error(mmc_dev(host->mmc), host->adma_addr)) 5408f1934ceSPierre Ossman goto unmap_entries; 5412134a922SPierre Ossman BUG_ON(host->adma_addr & 0x3); 5428f1934ceSPierre Ossman 5438f1934ceSPierre Ossman return 0; 5448f1934ceSPierre Ossman 5458f1934ceSPierre Ossman unmap_entries: 5468f1934ceSPierre Ossman dma_unmap_sg(mmc_dev(host->mmc), data->sg, 5478f1934ceSPierre Ossman data->sg_len, direction); 5488f1934ceSPierre Ossman unmap_align: 5498f1934ceSPierre Ossman dma_unmap_single(mmc_dev(host->mmc), host->align_addr, 5508f1934ceSPierre Ossman 128 * 4, direction); 5518f1934ceSPierre Ossman fail: 5528f1934ceSPierre Ossman return -EINVAL; 5532134a922SPierre Ossman } 5542134a922SPierre Ossman 5552134a922SPierre Ossman static void sdhci_adma_table_post(struct sdhci_host *host, 5562134a922SPierre Ossman struct mmc_data *data) 5572134a922SPierre Ossman { 5582134a922SPierre Ossman int direction; 5592134a922SPierre Ossman 5602134a922SPierre Ossman struct scatterlist *sg; 5612134a922SPierre Ossman int i, size; 5622134a922SPierre Ossman u8 *align; 5632134a922SPierre Ossman char *buffer; 5642134a922SPierre Ossman unsigned long flags; 5652134a922SPierre Ossman 5662134a922SPierre Ossman if (data->flags & MMC_DATA_READ) 5672134a922SPierre Ossman direction = DMA_FROM_DEVICE; 5682134a922SPierre Ossman else 5692134a922SPierre Ossman direction = DMA_TO_DEVICE; 5702134a922SPierre Ossman 5712134a922SPierre Ossman dma_unmap_single(mmc_dev(host->mmc), host->adma_addr, 5722134a922SPierre Ossman (128 * 2 + 1) * 4, DMA_TO_DEVICE); 5732134a922SPierre Ossman 5742134a922SPierre Ossman dma_unmap_single(mmc_dev(host->mmc), host->align_addr, 5752134a922SPierre Ossman 128 * 4, direction); 5762134a922SPierre Ossman 5772134a922SPierre Ossman if (data->flags & MMC_DATA_READ) { 5782134a922SPierre Ossman dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg, 5792134a922SPierre Ossman data->sg_len, direction); 5802134a922SPierre Ossman 5812134a922SPierre Ossman align = host->align_buffer; 5822134a922SPierre Ossman 5832134a922SPierre Ossman for_each_sg(data->sg, sg, host->sg_count, i) { 5842134a922SPierre Ossman if (sg_dma_address(sg) & 0x3) { 5852134a922SPierre Ossman size = 4 - (sg_dma_address(sg) & 0x3); 5862134a922SPierre Ossman 5872134a922SPierre Ossman buffer = sdhci_kmap_atomic(sg, &flags); 5886cefd05fSPierre Ossman WARN_ON(((long)buffer & PAGE_MASK) > (PAGE_SIZE - 3)); 5892134a922SPierre Ossman memcpy(buffer, align, size); 5902134a922SPierre Ossman sdhci_kunmap_atomic(buffer, &flags); 5912134a922SPierre Ossman 5922134a922SPierre Ossman align += 4; 5932134a922SPierre Ossman } 5942134a922SPierre Ossman } 5952134a922SPierre Ossman } 5962134a922SPierre Ossman 5972134a922SPierre Ossman dma_unmap_sg(mmc_dev(host->mmc), data->sg, 5982134a922SPierre Ossman data->sg_len, direction); 5992134a922SPierre Ossman } 6002134a922SPierre Ossman 601a3c7778fSAndrei Warkentin static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) 6021c6a0718SPierre Ossman { 6031c6a0718SPierre Ossman u8 count; 604a3c7778fSAndrei Warkentin struct mmc_data *data = cmd->data; 6051c6a0718SPierre Ossman unsigned target_timeout, current_timeout; 6061c6a0718SPierre Ossman 607ee53ab5dSPierre Ossman /* 608ee53ab5dSPierre Ossman * If the host controller provides us with an incorrect timeout 609ee53ab5dSPierre Ossman * value, just skip the check and use 0xE. The hardware may take 610ee53ab5dSPierre Ossman * longer to time out, but that's much better than having a too-short 611ee53ab5dSPierre Ossman * timeout value. 612ee53ab5dSPierre Ossman */ 61311a2f1b7SPierre Ossman if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL) 614ee53ab5dSPierre Ossman return 0xE; 615e538fbe8SPierre Ossman 616a3c7778fSAndrei Warkentin /* Unspecified timeout, assume max */ 617a3c7778fSAndrei Warkentin if (!data && !cmd->cmd_timeout_ms) 618a3c7778fSAndrei Warkentin return 0xE; 619a3c7778fSAndrei Warkentin 6201c6a0718SPierre Ossman /* timeout in us */ 621a3c7778fSAndrei Warkentin if (!data) 622a3c7778fSAndrei Warkentin target_timeout = cmd->cmd_timeout_ms * 1000; 623a3c7778fSAndrei Warkentin else 6241c6a0718SPierre Ossman target_timeout = data->timeout_ns / 1000 + 6251c6a0718SPierre Ossman data->timeout_clks / host->clock; 6261c6a0718SPierre Ossman 6274b01681cSMark Brown if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK) 6284b01681cSMark Brown host->timeout_clk = host->clock / 1000; 6294b01681cSMark Brown 6301c6a0718SPierre Ossman /* 6311c6a0718SPierre Ossman * Figure out needed cycles. 6321c6a0718SPierre Ossman * We do this in steps in order to fit inside a 32 bit int. 6331c6a0718SPierre Ossman * The first step is the minimum timeout, which will have a 6341c6a0718SPierre Ossman * minimum resolution of 6 bits: 6351c6a0718SPierre Ossman * (1) 2^13*1000 > 2^22, 6361c6a0718SPierre Ossman * (2) host->timeout_clk < 2^16 6371c6a0718SPierre Ossman * => 6381c6a0718SPierre Ossman * (1) / (2) > 2^6 6391c6a0718SPierre Ossman */ 6404b01681cSMark Brown BUG_ON(!host->timeout_clk); 6411c6a0718SPierre Ossman count = 0; 6421c6a0718SPierre Ossman current_timeout = (1 << 13) * 1000 / host->timeout_clk; 6431c6a0718SPierre Ossman while (current_timeout < target_timeout) { 6441c6a0718SPierre Ossman count++; 6451c6a0718SPierre Ossman current_timeout <<= 1; 6461c6a0718SPierre Ossman if (count >= 0xF) 6471c6a0718SPierre Ossman break; 6481c6a0718SPierre Ossman } 6491c6a0718SPierre Ossman 6501c6a0718SPierre Ossman if (count >= 0xF) { 651a3c7778fSAndrei Warkentin printk(KERN_WARNING "%s: Too large timeout requested for CMD%d!\n", 652a3c7778fSAndrei Warkentin mmc_hostname(host->mmc), cmd->opcode); 6531c6a0718SPierre Ossman count = 0xE; 6541c6a0718SPierre Ossman } 6551c6a0718SPierre Ossman 656ee53ab5dSPierre Ossman return count; 657ee53ab5dSPierre Ossman } 658ee53ab5dSPierre Ossman 6596aa943abSAnton Vorontsov static void sdhci_set_transfer_irqs(struct sdhci_host *host) 6606aa943abSAnton Vorontsov { 6616aa943abSAnton Vorontsov u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL; 6626aa943abSAnton Vorontsov u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR; 6636aa943abSAnton Vorontsov 6646aa943abSAnton Vorontsov if (host->flags & SDHCI_REQ_USE_DMA) 6656aa943abSAnton Vorontsov sdhci_clear_set_irqs(host, pio_irqs, dma_irqs); 6666aa943abSAnton Vorontsov else 6676aa943abSAnton Vorontsov sdhci_clear_set_irqs(host, dma_irqs, pio_irqs); 6686aa943abSAnton Vorontsov } 6696aa943abSAnton Vorontsov 670a3c7778fSAndrei Warkentin static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) 671ee53ab5dSPierre Ossman { 672ee53ab5dSPierre Ossman u8 count; 6732134a922SPierre Ossman u8 ctrl; 674a3c7778fSAndrei Warkentin struct mmc_data *data = cmd->data; 6758f1934ceSPierre Ossman int ret; 676ee53ab5dSPierre Ossman 677ee53ab5dSPierre Ossman WARN_ON(host->data); 678ee53ab5dSPierre Ossman 679a3c7778fSAndrei Warkentin if (data || (cmd->flags & MMC_RSP_BUSY)) { 680a3c7778fSAndrei Warkentin count = sdhci_calc_timeout(host, cmd); 681a3c7778fSAndrei Warkentin sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL); 682a3c7778fSAndrei Warkentin } 683a3c7778fSAndrei Warkentin 684a3c7778fSAndrei Warkentin if (!data) 685ee53ab5dSPierre Ossman return; 686ee53ab5dSPierre Ossman 687ee53ab5dSPierre Ossman /* Sanity checks */ 688ee53ab5dSPierre Ossman BUG_ON(data->blksz * data->blocks > 524288); 689ee53ab5dSPierre Ossman BUG_ON(data->blksz > host->mmc->max_blk_size); 690ee53ab5dSPierre Ossman BUG_ON(data->blocks > 65535); 691ee53ab5dSPierre Ossman 692ee53ab5dSPierre Ossman host->data = data; 693ee53ab5dSPierre Ossman host->data_early = 0; 694f6a03cbfSMikko Vinni host->data->bytes_xfered = 0; 695ee53ab5dSPierre Ossman 696a13abc7bSRichard Röjfors if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) 697c9fddbc4SPierre Ossman host->flags |= SDHCI_REQ_USE_DMA; 698c9fddbc4SPierre Ossman 6992134a922SPierre Ossman /* 7002134a922SPierre Ossman * FIXME: This doesn't account for merging when mapping the 7012134a922SPierre Ossman * scatterlist. 7022134a922SPierre Ossman */ 7032134a922SPierre Ossman if (host->flags & SDHCI_REQ_USE_DMA) { 7042134a922SPierre Ossman int broken, i; 7052134a922SPierre Ossman struct scatterlist *sg; 7062134a922SPierre Ossman 7072134a922SPierre Ossman broken = 0; 7082134a922SPierre Ossman if (host->flags & SDHCI_USE_ADMA) { 7092134a922SPierre Ossman if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE) 7102134a922SPierre Ossman broken = 1; 7112134a922SPierre Ossman } else { 7122134a922SPierre Ossman if (host->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE) 7132134a922SPierre Ossman broken = 1; 7142134a922SPierre Ossman } 7152134a922SPierre Ossman 7162134a922SPierre Ossman if (unlikely(broken)) { 7172134a922SPierre Ossman for_each_sg(data->sg, sg, data->sg_len, i) { 7182134a922SPierre Ossman if (sg->length & 0x3) { 7192134a922SPierre Ossman DBG("Reverting to PIO because of " 7202134a922SPierre Ossman "transfer size (%d)\n", 7212134a922SPierre Ossman sg->length); 722c9fddbc4SPierre Ossman host->flags &= ~SDHCI_REQ_USE_DMA; 7232134a922SPierre Ossman break; 7242134a922SPierre Ossman } 7252134a922SPierre Ossman } 7262134a922SPierre Ossman } 727c9fddbc4SPierre Ossman } 728c9fddbc4SPierre Ossman 729c9fddbc4SPierre Ossman /* 730c9fddbc4SPierre Ossman * The assumption here being that alignment is the same after 731c9fddbc4SPierre Ossman * translation to device address space. 732c9fddbc4SPierre Ossman */ 7332134a922SPierre Ossman if (host->flags & SDHCI_REQ_USE_DMA) { 7342134a922SPierre Ossman int broken, i; 7352134a922SPierre Ossman struct scatterlist *sg; 7362134a922SPierre Ossman 7372134a922SPierre Ossman broken = 0; 7382134a922SPierre Ossman if (host->flags & SDHCI_USE_ADMA) { 7392134a922SPierre Ossman /* 7402134a922SPierre Ossman * As we use 3 byte chunks to work around 7412134a922SPierre Ossman * alignment problems, we need to check this 7422134a922SPierre Ossman * quirk. 7432134a922SPierre Ossman */ 7442134a922SPierre Ossman if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE) 7452134a922SPierre Ossman broken = 1; 7462134a922SPierre Ossman } else { 7472134a922SPierre Ossman if (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) 7482134a922SPierre Ossman broken = 1; 7492134a922SPierre Ossman } 7502134a922SPierre Ossman 7512134a922SPierre Ossman if (unlikely(broken)) { 7522134a922SPierre Ossman for_each_sg(data->sg, sg, data->sg_len, i) { 7532134a922SPierre Ossman if (sg->offset & 0x3) { 7542134a922SPierre Ossman DBG("Reverting to PIO because of " 7552134a922SPierre Ossman "bad alignment\n"); 756c9fddbc4SPierre Ossman host->flags &= ~SDHCI_REQ_USE_DMA; 7572134a922SPierre Ossman break; 7582134a922SPierre Ossman } 7592134a922SPierre Ossman } 7602134a922SPierre Ossman } 7612134a922SPierre Ossman } 7622134a922SPierre Ossman 7638f1934ceSPierre Ossman if (host->flags & SDHCI_REQ_USE_DMA) { 7648f1934ceSPierre Ossman if (host->flags & SDHCI_USE_ADMA) { 7658f1934ceSPierre Ossman ret = sdhci_adma_table_pre(host, data); 7668f1934ceSPierre Ossman if (ret) { 7678f1934ceSPierre Ossman /* 7688f1934ceSPierre Ossman * This only happens when someone fed 7698f1934ceSPierre Ossman * us an invalid request. 7708f1934ceSPierre Ossman */ 7718f1934ceSPierre Ossman WARN_ON(1); 772ebd6d357SPierre Ossman host->flags &= ~SDHCI_REQ_USE_DMA; 7738f1934ceSPierre Ossman } else { 7744e4141a5SAnton Vorontsov sdhci_writel(host, host->adma_addr, 7754e4141a5SAnton Vorontsov SDHCI_ADMA_ADDRESS); 7768f1934ceSPierre Ossman } 7778f1934ceSPierre Ossman } else { 778c8b3e02eSTomas Winkler int sg_cnt; 7798f1934ceSPierre Ossman 780c8b3e02eSTomas Winkler sg_cnt = dma_map_sg(mmc_dev(host->mmc), 7818f1934ceSPierre Ossman data->sg, data->sg_len, 7828f1934ceSPierre Ossman (data->flags & MMC_DATA_READ) ? 7838f1934ceSPierre Ossman DMA_FROM_DEVICE : 7848f1934ceSPierre Ossman DMA_TO_DEVICE); 785c8b3e02eSTomas Winkler if (sg_cnt == 0) { 7868f1934ceSPierre Ossman /* 7878f1934ceSPierre Ossman * This only happens when someone fed 7888f1934ceSPierre Ossman * us an invalid request. 7898f1934ceSPierre Ossman */ 7908f1934ceSPierre Ossman WARN_ON(1); 791ebd6d357SPierre Ossman host->flags &= ~SDHCI_REQ_USE_DMA; 7928f1934ceSPierre Ossman } else { 793719a61b4SPierre Ossman WARN_ON(sg_cnt != 1); 7944e4141a5SAnton Vorontsov sdhci_writel(host, sg_dma_address(data->sg), 7954e4141a5SAnton Vorontsov SDHCI_DMA_ADDRESS); 7968f1934ceSPierre Ossman } 7978f1934ceSPierre Ossman } 7988f1934ceSPierre Ossman } 7998f1934ceSPierre Ossman 8002134a922SPierre Ossman /* 8012134a922SPierre Ossman * Always adjust the DMA selection as some controllers 8022134a922SPierre Ossman * (e.g. JMicron) can't do PIO properly when the selection 8032134a922SPierre Ossman * is ADMA. 8042134a922SPierre Ossman */ 8052134a922SPierre Ossman if (host->version >= SDHCI_SPEC_200) { 8064e4141a5SAnton Vorontsov ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 8072134a922SPierre Ossman ctrl &= ~SDHCI_CTRL_DMA_MASK; 8082134a922SPierre Ossman if ((host->flags & SDHCI_REQ_USE_DMA) && 8092134a922SPierre Ossman (host->flags & SDHCI_USE_ADMA)) 8102134a922SPierre Ossman ctrl |= SDHCI_CTRL_ADMA32; 8112134a922SPierre Ossman else 8122134a922SPierre Ossman ctrl |= SDHCI_CTRL_SDMA; 8134e4141a5SAnton Vorontsov sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 814c9fddbc4SPierre Ossman } 815c9fddbc4SPierre Ossman 8168f1934ceSPierre Ossman if (!(host->flags & SDHCI_REQ_USE_DMA)) { 817da60a91dSSebastian Andrzej Siewior int flags; 818da60a91dSSebastian Andrzej Siewior 819da60a91dSSebastian Andrzej Siewior flags = SG_MITER_ATOMIC; 820da60a91dSSebastian Andrzej Siewior if (host->data->flags & MMC_DATA_READ) 821da60a91dSSebastian Andrzej Siewior flags |= SG_MITER_TO_SG; 822da60a91dSSebastian Andrzej Siewior else 823da60a91dSSebastian Andrzej Siewior flags |= SG_MITER_FROM_SG; 824da60a91dSSebastian Andrzej Siewior sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); 8257659150cSPierre Ossman host->blocks = data->blocks; 8261c6a0718SPierre Ossman } 8271c6a0718SPierre Ossman 8286aa943abSAnton Vorontsov sdhci_set_transfer_irqs(host); 8296aa943abSAnton Vorontsov 830f6a03cbfSMikko Vinni /* Set the DMA boundary value and block size */ 831f6a03cbfSMikko Vinni sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, 832f6a03cbfSMikko Vinni data->blksz), SDHCI_BLOCK_SIZE); 8334e4141a5SAnton Vorontsov sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT); 8341c6a0718SPierre Ossman } 8351c6a0718SPierre Ossman 8361c6a0718SPierre Ossman static void sdhci_set_transfer_mode(struct sdhci_host *host, 8371c6a0718SPierre Ossman struct mmc_data *data) 8381c6a0718SPierre Ossman { 8391c6a0718SPierre Ossman u16 mode; 8401c6a0718SPierre Ossman 8411c6a0718SPierre Ossman if (data == NULL) 8421c6a0718SPierre Ossman return; 8431c6a0718SPierre Ossman 844e538fbe8SPierre Ossman WARN_ON(!host->data); 845e538fbe8SPierre Ossman 8461c6a0718SPierre Ossman mode = SDHCI_TRNS_BLK_CNT_EN; 847c4512f79SJerry Huang if (data->blocks > 1) { 848c4512f79SJerry Huang if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) 849c4512f79SJerry Huang mode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_ACMD12; 850c4512f79SJerry Huang else 8511c6a0718SPierre Ossman mode |= SDHCI_TRNS_MULTI; 852c4512f79SJerry Huang } 8531c6a0718SPierre Ossman if (data->flags & MMC_DATA_READ) 8541c6a0718SPierre Ossman mode |= SDHCI_TRNS_READ; 855c9fddbc4SPierre Ossman if (host->flags & SDHCI_REQ_USE_DMA) 8561c6a0718SPierre Ossman mode |= SDHCI_TRNS_DMA; 8571c6a0718SPierre Ossman 8584e4141a5SAnton Vorontsov sdhci_writew(host, mode, SDHCI_TRANSFER_MODE); 8591c6a0718SPierre Ossman } 8601c6a0718SPierre Ossman 8611c6a0718SPierre Ossman static void sdhci_finish_data(struct sdhci_host *host) 8621c6a0718SPierre Ossman { 8631c6a0718SPierre Ossman struct mmc_data *data; 8641c6a0718SPierre Ossman 8651c6a0718SPierre Ossman BUG_ON(!host->data); 8661c6a0718SPierre Ossman 8671c6a0718SPierre Ossman data = host->data; 8681c6a0718SPierre Ossman host->data = NULL; 8691c6a0718SPierre Ossman 870c9fddbc4SPierre Ossman if (host->flags & SDHCI_REQ_USE_DMA) { 8712134a922SPierre Ossman if (host->flags & SDHCI_USE_ADMA) 8722134a922SPierre Ossman sdhci_adma_table_post(host, data); 8732134a922SPierre Ossman else { 8742134a922SPierre Ossman dma_unmap_sg(mmc_dev(host->mmc), data->sg, 8752134a922SPierre Ossman data->sg_len, (data->flags & MMC_DATA_READ) ? 876b8c86fc5SPierre Ossman DMA_FROM_DEVICE : DMA_TO_DEVICE); 8771c6a0718SPierre Ossman } 8782134a922SPierre Ossman } 8791c6a0718SPierre Ossman 8801c6a0718SPierre Ossman /* 881c9b74c5bSPierre Ossman * The specification states that the block count register must 882c9b74c5bSPierre Ossman * be updated, but it does not specify at what point in the 883c9b74c5bSPierre Ossman * data flow. That makes the register entirely useless to read 884c9b74c5bSPierre Ossman * back so we have to assume that nothing made it to the card 885c9b74c5bSPierre Ossman * in the event of an error. 8861c6a0718SPierre Ossman */ 887c9b74c5bSPierre Ossman if (data->error) 888c9b74c5bSPierre Ossman data->bytes_xfered = 0; 8891c6a0718SPierre Ossman else 890c9b74c5bSPierre Ossman data->bytes_xfered = data->blksz * data->blocks; 8911c6a0718SPierre Ossman 8921c6a0718SPierre Ossman if (data->stop) { 8931c6a0718SPierre Ossman /* 8941c6a0718SPierre Ossman * The controller needs a reset of internal state machines 8951c6a0718SPierre Ossman * upon error conditions. 8961c6a0718SPierre Ossman */ 89717b0429dSPierre Ossman if (data->error) { 8981c6a0718SPierre Ossman sdhci_reset(host, SDHCI_RESET_CMD); 8991c6a0718SPierre Ossman sdhci_reset(host, SDHCI_RESET_DATA); 9001c6a0718SPierre Ossman } 9011c6a0718SPierre Ossman 9021c6a0718SPierre Ossman sdhci_send_command(host, data->stop); 9031c6a0718SPierre Ossman } else 9041c6a0718SPierre Ossman tasklet_schedule(&host->finish_tasklet); 9051c6a0718SPierre Ossman } 9061c6a0718SPierre Ossman 9071c6a0718SPierre Ossman static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) 9081c6a0718SPierre Ossman { 9091c6a0718SPierre Ossman int flags; 9101c6a0718SPierre Ossman u32 mask; 9111c6a0718SPierre Ossman unsigned long timeout; 9121c6a0718SPierre Ossman 9131c6a0718SPierre Ossman WARN_ON(host->cmd); 9141c6a0718SPierre Ossman 9151c6a0718SPierre Ossman /* Wait max 10 ms */ 9161c6a0718SPierre Ossman timeout = 10; 9171c6a0718SPierre Ossman 9181c6a0718SPierre Ossman mask = SDHCI_CMD_INHIBIT; 9191c6a0718SPierre Ossman if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY)) 9201c6a0718SPierre Ossman mask |= SDHCI_DATA_INHIBIT; 9211c6a0718SPierre Ossman 9221c6a0718SPierre Ossman /* We shouldn't wait for data inihibit for stop commands, even 9231c6a0718SPierre Ossman though they might use busy signaling */ 9241c6a0718SPierre Ossman if (host->mrq->data && (cmd == host->mrq->data->stop)) 9251c6a0718SPierre Ossman mask &= ~SDHCI_DATA_INHIBIT; 9261c6a0718SPierre Ossman 9274e4141a5SAnton Vorontsov while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) { 9281c6a0718SPierre Ossman if (timeout == 0) { 9291c6a0718SPierre Ossman printk(KERN_ERR "%s: Controller never released " 9301c6a0718SPierre Ossman "inhibit bit(s).\n", mmc_hostname(host->mmc)); 9311c6a0718SPierre Ossman sdhci_dumpregs(host); 93217b0429dSPierre Ossman cmd->error = -EIO; 9331c6a0718SPierre Ossman tasklet_schedule(&host->finish_tasklet); 9341c6a0718SPierre Ossman return; 9351c6a0718SPierre Ossman } 9361c6a0718SPierre Ossman timeout--; 9371c6a0718SPierre Ossman mdelay(1); 9381c6a0718SPierre Ossman } 9391c6a0718SPierre Ossman 9401c6a0718SPierre Ossman mod_timer(&host->timer, jiffies + 10 * HZ); 9411c6a0718SPierre Ossman 9421c6a0718SPierre Ossman host->cmd = cmd; 9431c6a0718SPierre Ossman 944a3c7778fSAndrei Warkentin sdhci_prepare_data(host, cmd); 9451c6a0718SPierre Ossman 9464e4141a5SAnton Vorontsov sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT); 9471c6a0718SPierre Ossman 9481c6a0718SPierre Ossman sdhci_set_transfer_mode(host, cmd->data); 9491c6a0718SPierre Ossman 9501c6a0718SPierre Ossman if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { 9511c6a0718SPierre Ossman printk(KERN_ERR "%s: Unsupported response type!\n", 9521c6a0718SPierre Ossman mmc_hostname(host->mmc)); 95317b0429dSPierre Ossman cmd->error = -EINVAL; 9541c6a0718SPierre Ossman tasklet_schedule(&host->finish_tasklet); 9551c6a0718SPierre Ossman return; 9561c6a0718SPierre Ossman } 9571c6a0718SPierre Ossman 9581c6a0718SPierre Ossman if (!(cmd->flags & MMC_RSP_PRESENT)) 9591c6a0718SPierre Ossman flags = SDHCI_CMD_RESP_NONE; 9601c6a0718SPierre Ossman else if (cmd->flags & MMC_RSP_136) 9611c6a0718SPierre Ossman flags = SDHCI_CMD_RESP_LONG; 9621c6a0718SPierre Ossman else if (cmd->flags & MMC_RSP_BUSY) 9631c6a0718SPierre Ossman flags = SDHCI_CMD_RESP_SHORT_BUSY; 9641c6a0718SPierre Ossman else 9651c6a0718SPierre Ossman flags = SDHCI_CMD_RESP_SHORT; 9661c6a0718SPierre Ossman 9671c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_CRC) 9681c6a0718SPierre Ossman flags |= SDHCI_CMD_CRC; 9691c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_OPCODE) 9701c6a0718SPierre Ossman flags |= SDHCI_CMD_INDEX; 9711c6a0718SPierre Ossman if (cmd->data) 9721c6a0718SPierre Ossman flags |= SDHCI_CMD_DATA; 9731c6a0718SPierre Ossman 9744e4141a5SAnton Vorontsov sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); 9751c6a0718SPierre Ossman } 9761c6a0718SPierre Ossman 9771c6a0718SPierre Ossman static void sdhci_finish_command(struct sdhci_host *host) 9781c6a0718SPierre Ossman { 9791c6a0718SPierre Ossman int i; 9801c6a0718SPierre Ossman 9811c6a0718SPierre Ossman BUG_ON(host->cmd == NULL); 9821c6a0718SPierre Ossman 9831c6a0718SPierre Ossman if (host->cmd->flags & MMC_RSP_PRESENT) { 9841c6a0718SPierre Ossman if (host->cmd->flags & MMC_RSP_136) { 9851c6a0718SPierre Ossman /* CRC is stripped so we need to do some shifting. */ 9861c6a0718SPierre Ossman for (i = 0;i < 4;i++) { 9874e4141a5SAnton Vorontsov host->cmd->resp[i] = sdhci_readl(host, 9881c6a0718SPierre Ossman SDHCI_RESPONSE + (3-i)*4) << 8; 9891c6a0718SPierre Ossman if (i != 3) 9901c6a0718SPierre Ossman host->cmd->resp[i] |= 9914e4141a5SAnton Vorontsov sdhci_readb(host, 9921c6a0718SPierre Ossman SDHCI_RESPONSE + (3-i)*4-1); 9931c6a0718SPierre Ossman } 9941c6a0718SPierre Ossman } else { 9954e4141a5SAnton Vorontsov host->cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE); 9961c6a0718SPierre Ossman } 9971c6a0718SPierre Ossman } 9981c6a0718SPierre Ossman 99917b0429dSPierre Ossman host->cmd->error = 0; 10001c6a0718SPierre Ossman 1001e538fbe8SPierre Ossman if (host->data && host->data_early) 1002e538fbe8SPierre Ossman sdhci_finish_data(host); 1003e538fbe8SPierre Ossman 1004e538fbe8SPierre Ossman if (!host->cmd->data) 10051c6a0718SPierre Ossman tasklet_schedule(&host->finish_tasklet); 10061c6a0718SPierre Ossman 10071c6a0718SPierre Ossman host->cmd = NULL; 10081c6a0718SPierre Ossman } 10091c6a0718SPierre Ossman 10101c6a0718SPierre Ossman static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) 10111c6a0718SPierre Ossman { 10121c6a0718SPierre Ossman int div; 10131c6a0718SPierre Ossman u16 clk; 10141c6a0718SPierre Ossman unsigned long timeout; 10151c6a0718SPierre Ossman 10161c6a0718SPierre Ossman if (clock == host->clock) 10171c6a0718SPierre Ossman return; 10181c6a0718SPierre Ossman 10198114634cSAnton Vorontsov if (host->ops->set_clock) { 10208114634cSAnton Vorontsov host->ops->set_clock(host, clock); 10218114634cSAnton Vorontsov if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) 10228114634cSAnton Vorontsov return; 10238114634cSAnton Vorontsov } 10248114634cSAnton Vorontsov 10254e4141a5SAnton Vorontsov sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); 10261c6a0718SPierre Ossman 10271c6a0718SPierre Ossman if (clock == 0) 10281c6a0718SPierre Ossman goto out; 10291c6a0718SPierre Ossman 103085105c53SZhangfei Gao if (host->version >= SDHCI_SPEC_300) { 103185105c53SZhangfei Gao /* Version 3.00 divisors must be a multiple of 2. */ 103285105c53SZhangfei Gao if (host->max_clk <= clock) 103385105c53SZhangfei Gao div = 1; 103485105c53SZhangfei Gao else { 10350397526dSZhangfei Gao for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) { 103685105c53SZhangfei Gao if ((host->max_clk / div) <= clock) 103785105c53SZhangfei Gao break; 103885105c53SZhangfei Gao } 103985105c53SZhangfei Gao } 104085105c53SZhangfei Gao } else { 104185105c53SZhangfei Gao /* Version 2.00 divisors must be a power of 2. */ 10420397526dSZhangfei Gao for (div = 1; div < SDHCI_MAX_DIV_SPEC_200; div *= 2) { 10431c6a0718SPierre Ossman if ((host->max_clk / div) <= clock) 10441c6a0718SPierre Ossman break; 10451c6a0718SPierre Ossman } 104685105c53SZhangfei Gao } 10471c6a0718SPierre Ossman div >>= 1; 10481c6a0718SPierre Ossman 104985105c53SZhangfei Gao clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; 105085105c53SZhangfei Gao clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) 105185105c53SZhangfei Gao << SDHCI_DIVIDER_HI_SHIFT; 10521c6a0718SPierre Ossman clk |= SDHCI_CLOCK_INT_EN; 10534e4141a5SAnton Vorontsov sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 10541c6a0718SPierre Ossman 105527f6cb16SChris Ball /* Wait max 20 ms */ 105627f6cb16SChris Ball timeout = 20; 10574e4141a5SAnton Vorontsov while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) 10581c6a0718SPierre Ossman & SDHCI_CLOCK_INT_STABLE)) { 10591c6a0718SPierre Ossman if (timeout == 0) { 10601c6a0718SPierre Ossman printk(KERN_ERR "%s: Internal clock never " 10611c6a0718SPierre Ossman "stabilised.\n", mmc_hostname(host->mmc)); 10621c6a0718SPierre Ossman sdhci_dumpregs(host); 10631c6a0718SPierre Ossman return; 10641c6a0718SPierre Ossman } 10651c6a0718SPierre Ossman timeout--; 10661c6a0718SPierre Ossman mdelay(1); 10671c6a0718SPierre Ossman } 10681c6a0718SPierre Ossman 10691c6a0718SPierre Ossman clk |= SDHCI_CLOCK_CARD_EN; 10704e4141a5SAnton Vorontsov sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 10711c6a0718SPierre Ossman 10721c6a0718SPierre Ossman out: 10731c6a0718SPierre Ossman host->clock = clock; 10741c6a0718SPierre Ossman } 10751c6a0718SPierre Ossman 10761c6a0718SPierre Ossman static void sdhci_set_power(struct sdhci_host *host, unsigned short power) 10771c6a0718SPierre Ossman { 10788364248aSGiuseppe Cavallaro u8 pwr = 0; 10791c6a0718SPierre Ossman 10808364248aSGiuseppe Cavallaro if (power != (unsigned short)-1) { 1081ae628903SPierre Ossman switch (1 << power) { 1082ae628903SPierre Ossman case MMC_VDD_165_195: 1083ae628903SPierre Ossman pwr = SDHCI_POWER_180; 1084ae628903SPierre Ossman break; 1085ae628903SPierre Ossman case MMC_VDD_29_30: 1086ae628903SPierre Ossman case MMC_VDD_30_31: 1087ae628903SPierre Ossman pwr = SDHCI_POWER_300; 1088ae628903SPierre Ossman break; 1089ae628903SPierre Ossman case MMC_VDD_32_33: 1090ae628903SPierre Ossman case MMC_VDD_33_34: 1091ae628903SPierre Ossman pwr = SDHCI_POWER_330; 1092ae628903SPierre Ossman break; 1093ae628903SPierre Ossman default: 1094ae628903SPierre Ossman BUG(); 1095ae628903SPierre Ossman } 1096ae628903SPierre Ossman } 1097ae628903SPierre Ossman 1098ae628903SPierre Ossman if (host->pwr == pwr) 10991c6a0718SPierre Ossman return; 11001c6a0718SPierre Ossman 1101ae628903SPierre Ossman host->pwr = pwr; 1102ae628903SPierre Ossman 1103ae628903SPierre Ossman if (pwr == 0) { 11044e4141a5SAnton Vorontsov sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); 1105ae628903SPierre Ossman return; 11061c6a0718SPierre Ossman } 11071c6a0718SPierre Ossman 11081c6a0718SPierre Ossman /* 11091c6a0718SPierre Ossman * Spec says that we should clear the power reg before setting 11101c6a0718SPierre Ossman * a new value. Some controllers don't seem to like this though. 11111c6a0718SPierre Ossman */ 1112b8c86fc5SPierre Ossman if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) 11134e4141a5SAnton Vorontsov sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); 11141c6a0718SPierre Ossman 1115e08c1694SAndres Salomon /* 1116c71f6512SAndres Salomon * At least the Marvell CaFe chip gets confused if we set the voltage 1117e08c1694SAndres Salomon * and set turn on power at the same time, so set the voltage first. 1118e08c1694SAndres Salomon */ 111911a2f1b7SPierre Ossman if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER) 11204e4141a5SAnton Vorontsov sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); 11211c6a0718SPierre Ossman 1122ae628903SPierre Ossman pwr |= SDHCI_POWER_ON; 1123ae628903SPierre Ossman 1124ae628903SPierre Ossman sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); 1125557b0697SHarald Welte 1126557b0697SHarald Welte /* 1127557b0697SHarald Welte * Some controllers need an extra 10ms delay of 10ms before they 1128557b0697SHarald Welte * can apply clock after applying power 1129557b0697SHarald Welte */ 113011a2f1b7SPierre Ossman if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER) 1131557b0697SHarald Welte mdelay(10); 11321c6a0718SPierre Ossman } 11331c6a0718SPierre Ossman 11341c6a0718SPierre Ossman /*****************************************************************************\ 11351c6a0718SPierre Ossman * * 11361c6a0718SPierre Ossman * MMC callbacks * 11371c6a0718SPierre Ossman * * 11381c6a0718SPierre Ossman \*****************************************************************************/ 11391c6a0718SPierre Ossman 11401c6a0718SPierre Ossman static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) 11411c6a0718SPierre Ossman { 11421c6a0718SPierre Ossman struct sdhci_host *host; 114368d1fb7eSAnton Vorontsov bool present; 11441c6a0718SPierre Ossman unsigned long flags; 11451c6a0718SPierre Ossman 11461c6a0718SPierre Ossman host = mmc_priv(mmc); 11471c6a0718SPierre Ossman 11481c6a0718SPierre Ossman spin_lock_irqsave(&host->lock, flags); 11491c6a0718SPierre Ossman 11501c6a0718SPierre Ossman WARN_ON(host->mrq != NULL); 11511c6a0718SPierre Ossman 1152f9134319SPierre Ossman #ifndef SDHCI_USE_LEDS_CLASS 11531c6a0718SPierre Ossman sdhci_activate_led(host); 11542f730fecSPierre Ossman #endif 1155c4512f79SJerry Huang if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) { 1156c4512f79SJerry Huang if (mrq->stop) { 1157c4512f79SJerry Huang mrq->data->stop = NULL; 1158c4512f79SJerry Huang mrq->stop = NULL; 1159c4512f79SJerry Huang } 1160c4512f79SJerry Huang } 11611c6a0718SPierre Ossman 11621c6a0718SPierre Ossman host->mrq = mrq; 11631c6a0718SPierre Ossman 116468d1fb7eSAnton Vorontsov /* If polling, assume that the card is always present. */ 116568d1fb7eSAnton Vorontsov if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) 116668d1fb7eSAnton Vorontsov present = true; 116768d1fb7eSAnton Vorontsov else 116868d1fb7eSAnton Vorontsov present = sdhci_readl(host, SDHCI_PRESENT_STATE) & 116968d1fb7eSAnton Vorontsov SDHCI_CARD_PRESENT; 117068d1fb7eSAnton Vorontsov 117168d1fb7eSAnton Vorontsov if (!present || host->flags & SDHCI_DEVICE_DEAD) { 117217b0429dSPierre Ossman host->mrq->cmd->error = -ENOMEDIUM; 11731c6a0718SPierre Ossman tasklet_schedule(&host->finish_tasklet); 11741c6a0718SPierre Ossman } else 11751c6a0718SPierre Ossman sdhci_send_command(host, mrq->cmd); 11761c6a0718SPierre Ossman 11771c6a0718SPierre Ossman mmiowb(); 11781c6a0718SPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 11791c6a0718SPierre Ossman } 11801c6a0718SPierre Ossman 11811c6a0718SPierre Ossman static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 11821c6a0718SPierre Ossman { 11831c6a0718SPierre Ossman struct sdhci_host *host; 11841c6a0718SPierre Ossman unsigned long flags; 11851c6a0718SPierre Ossman u8 ctrl; 11861c6a0718SPierre Ossman 11871c6a0718SPierre Ossman host = mmc_priv(mmc); 11881c6a0718SPierre Ossman 11891c6a0718SPierre Ossman spin_lock_irqsave(&host->lock, flags); 11901c6a0718SPierre Ossman 11911e72859eSPierre Ossman if (host->flags & SDHCI_DEVICE_DEAD) 11921e72859eSPierre Ossman goto out; 11931e72859eSPierre Ossman 11941c6a0718SPierre Ossman /* 11951c6a0718SPierre Ossman * Reset the chip on each power off. 11961c6a0718SPierre Ossman * Should clear out any weird states. 11971c6a0718SPierre Ossman */ 11981c6a0718SPierre Ossman if (ios->power_mode == MMC_POWER_OFF) { 11994e4141a5SAnton Vorontsov sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE); 12007260cf5eSAnton Vorontsov sdhci_reinit(host); 12011c6a0718SPierre Ossman } 12021c6a0718SPierre Ossman 12031c6a0718SPierre Ossman sdhci_set_clock(host, ios->clock); 12041c6a0718SPierre Ossman 12051c6a0718SPierre Ossman if (ios->power_mode == MMC_POWER_OFF) 12061c6a0718SPierre Ossman sdhci_set_power(host, -1); 12071c6a0718SPierre Ossman else 12081c6a0718SPierre Ossman sdhci_set_power(host, ios->vdd); 12091c6a0718SPierre Ossman 1210643a81ffSPhilip Rakity if (host->ops->platform_send_init_74_clocks) 1211643a81ffSPhilip Rakity host->ops->platform_send_init_74_clocks(host, ios->power_mode); 1212643a81ffSPhilip Rakity 121315ec4461SPhilip Rakity /* 121415ec4461SPhilip Rakity * If your platform has 8-bit width support but is not a v3 controller, 121515ec4461SPhilip Rakity * or if it requires special setup code, you should implement that in 121615ec4461SPhilip Rakity * platform_8bit_width(). 121715ec4461SPhilip Rakity */ 121815ec4461SPhilip Rakity if (host->ops->platform_8bit_width) 121915ec4461SPhilip Rakity host->ops->platform_8bit_width(host, ios->bus_width); 122015ec4461SPhilip Rakity else { 12214e4141a5SAnton Vorontsov ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 122215ec4461SPhilip Rakity if (ios->bus_width == MMC_BUS_WIDTH_8) { 122315ec4461SPhilip Rakity ctrl &= ~SDHCI_CTRL_4BITBUS; 122415ec4461SPhilip Rakity if (host->version >= SDHCI_SPEC_300) 1225ae6d6c92SKyungmin Park ctrl |= SDHCI_CTRL_8BITBUS; 122615ec4461SPhilip Rakity } else { 122715ec4461SPhilip Rakity if (host->version >= SDHCI_SPEC_300) 1228ae6d6c92SKyungmin Park ctrl &= ~SDHCI_CTRL_8BITBUS; 12291c6a0718SPierre Ossman if (ios->bus_width == MMC_BUS_WIDTH_4) 12301c6a0718SPierre Ossman ctrl |= SDHCI_CTRL_4BITBUS; 12311c6a0718SPierre Ossman else 12321c6a0718SPierre Ossman ctrl &= ~SDHCI_CTRL_4BITBUS; 123315ec4461SPhilip Rakity } 123415ec4461SPhilip Rakity sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 123515ec4461SPhilip Rakity } 123615ec4461SPhilip Rakity 123715ec4461SPhilip Rakity ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 12381c6a0718SPierre Ossman 12393ab9c8daSPhilip Rakity if ((ios->timing == MMC_TIMING_SD_HS || 12403ab9c8daSPhilip Rakity ios->timing == MMC_TIMING_MMC_HS) 12413ab9c8daSPhilip Rakity && !(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) 12421c6a0718SPierre Ossman ctrl |= SDHCI_CTRL_HISPD; 12431c6a0718SPierre Ossman else 12441c6a0718SPierre Ossman ctrl &= ~SDHCI_CTRL_HISPD; 12451c6a0718SPierre Ossman 1246d6d50a15SArindam Nath if (host->version >= SDHCI_SPEC_300) { 124749c468fcSArindam Nath u16 clk, ctrl_2; 124849c468fcSArindam Nath unsigned int clock; 124949c468fcSArindam Nath 125049c468fcSArindam Nath /* In case of UHS-I modes, set High Speed Enable */ 125149c468fcSArindam Nath if ((ios->timing == MMC_TIMING_UHS_SDR50) || 125249c468fcSArindam Nath (ios->timing == MMC_TIMING_UHS_SDR104) || 125349c468fcSArindam Nath (ios->timing == MMC_TIMING_UHS_DDR50) || 125449c468fcSArindam Nath (ios->timing == MMC_TIMING_UHS_SDR25) || 125549c468fcSArindam Nath (ios->timing == MMC_TIMING_UHS_SDR12)) 125649c468fcSArindam Nath ctrl |= SDHCI_CTRL_HISPD; 1257d6d50a15SArindam Nath 1258d6d50a15SArindam Nath ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1259d6d50a15SArindam Nath if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) { 1260758535c4SArindam Nath sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 1261d6d50a15SArindam Nath /* 1262d6d50a15SArindam Nath * We only need to set Driver Strength if the 1263d6d50a15SArindam Nath * preset value enable is not set. 1264d6d50a15SArindam Nath */ 1265d6d50a15SArindam Nath ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK; 1266d6d50a15SArindam Nath if (ios->drv_type == MMC_SET_DRIVER_TYPE_A) 1267d6d50a15SArindam Nath ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A; 1268d6d50a15SArindam Nath else if (ios->drv_type == MMC_SET_DRIVER_TYPE_C) 1269d6d50a15SArindam Nath ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C; 1270d6d50a15SArindam Nath 1271d6d50a15SArindam Nath sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); 1272758535c4SArindam Nath } else { 1273758535c4SArindam Nath /* 1274758535c4SArindam Nath * According to SDHC Spec v3.00, if the Preset Value 1275758535c4SArindam Nath * Enable in the Host Control 2 register is set, we 1276758535c4SArindam Nath * need to reset SD Clock Enable before changing High 1277758535c4SArindam Nath * Speed Enable to avoid generating clock gliches. 1278758535c4SArindam Nath */ 1279758535c4SArindam Nath 1280758535c4SArindam Nath /* Reset SD Clock Enable */ 1281758535c4SArindam Nath clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 1282758535c4SArindam Nath clk &= ~SDHCI_CLOCK_CARD_EN; 1283758535c4SArindam Nath sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 1284758535c4SArindam Nath 1285758535c4SArindam Nath sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 1286758535c4SArindam Nath 1287758535c4SArindam Nath /* Re-enable SD Clock */ 1288758535c4SArindam Nath clock = host->clock; 1289758535c4SArindam Nath host->clock = 0; 1290758535c4SArindam Nath sdhci_set_clock(host, clock); 1291d6d50a15SArindam Nath } 129249c468fcSArindam Nath 129349c468fcSArindam Nath ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); 129449c468fcSArindam Nath 129549c468fcSArindam Nath /* Select Bus Speed Mode for host */ 129649c468fcSArindam Nath ctrl_2 &= ~SDHCI_CTRL_UHS_MASK; 129749c468fcSArindam Nath if (ios->timing == MMC_TIMING_UHS_SDR12) 129849c468fcSArindam Nath ctrl_2 |= SDHCI_CTRL_UHS_SDR12; 129949c468fcSArindam Nath else if (ios->timing == MMC_TIMING_UHS_SDR25) 130049c468fcSArindam Nath ctrl_2 |= SDHCI_CTRL_UHS_SDR25; 130149c468fcSArindam Nath else if (ios->timing == MMC_TIMING_UHS_SDR50) 130249c468fcSArindam Nath ctrl_2 |= SDHCI_CTRL_UHS_SDR50; 130349c468fcSArindam Nath else if (ios->timing == MMC_TIMING_UHS_SDR104) 130449c468fcSArindam Nath ctrl_2 |= SDHCI_CTRL_UHS_SDR104; 130549c468fcSArindam Nath else if (ios->timing == MMC_TIMING_UHS_DDR50) 130649c468fcSArindam Nath ctrl_2 |= SDHCI_CTRL_UHS_DDR50; 130749c468fcSArindam Nath 130849c468fcSArindam Nath /* Reset SD Clock Enable */ 130949c468fcSArindam Nath clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 131049c468fcSArindam Nath clk &= ~SDHCI_CLOCK_CARD_EN; 131149c468fcSArindam Nath sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 131249c468fcSArindam Nath 131349c468fcSArindam Nath sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); 131449c468fcSArindam Nath 131549c468fcSArindam Nath /* Re-enable SD Clock */ 131649c468fcSArindam Nath clock = host->clock; 131749c468fcSArindam Nath host->clock = 0; 131849c468fcSArindam Nath sdhci_set_clock(host, clock); 1319758535c4SArindam Nath } else 1320758535c4SArindam Nath sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 1321d6d50a15SArindam Nath 1322b8352260SLeandro Dorileo /* 1323b8352260SLeandro Dorileo * Some (ENE) controllers go apeshit on some ios operation, 1324b8352260SLeandro Dorileo * signalling timeout and CRC errors even on CMD0. Resetting 1325b8352260SLeandro Dorileo * it on each ios seems to solve the problem. 1326b8352260SLeandro Dorileo */ 1327b8c86fc5SPierre Ossman if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) 1328b8352260SLeandro Dorileo sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); 1329b8352260SLeandro Dorileo 13301e72859eSPierre Ossman out: 13311c6a0718SPierre Ossman mmiowb(); 13321c6a0718SPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 13331c6a0718SPierre Ossman } 13341c6a0718SPierre Ossman 133582b0e23aSTakashi Iwai static int check_ro(struct sdhci_host *host) 13361c6a0718SPierre Ossman { 13371c6a0718SPierre Ossman unsigned long flags; 13382dfb579cSWolfram Sang int is_readonly; 13391c6a0718SPierre Ossman 13401c6a0718SPierre Ossman spin_lock_irqsave(&host->lock, flags); 13411c6a0718SPierre Ossman 13421e72859eSPierre Ossman if (host->flags & SDHCI_DEVICE_DEAD) 13432dfb579cSWolfram Sang is_readonly = 0; 13442dfb579cSWolfram Sang else if (host->ops->get_ro) 13452dfb579cSWolfram Sang is_readonly = host->ops->get_ro(host); 13461e72859eSPierre Ossman else 13472dfb579cSWolfram Sang is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE) 13482dfb579cSWolfram Sang & SDHCI_WRITE_PROTECT); 13491c6a0718SPierre Ossman 13501c6a0718SPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 13511c6a0718SPierre Ossman 13522dfb579cSWolfram Sang /* This quirk needs to be replaced by a callback-function later */ 13532dfb579cSWolfram Sang return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ? 13542dfb579cSWolfram Sang !is_readonly : is_readonly; 13551c6a0718SPierre Ossman } 13561c6a0718SPierre Ossman 135782b0e23aSTakashi Iwai #define SAMPLE_COUNT 5 135882b0e23aSTakashi Iwai 135982b0e23aSTakashi Iwai static int sdhci_get_ro(struct mmc_host *mmc) 136082b0e23aSTakashi Iwai { 136182b0e23aSTakashi Iwai struct sdhci_host *host; 136282b0e23aSTakashi Iwai int i, ro_count; 136382b0e23aSTakashi Iwai 136482b0e23aSTakashi Iwai host = mmc_priv(mmc); 136582b0e23aSTakashi Iwai 136682b0e23aSTakashi Iwai if (!(host->quirks & SDHCI_QUIRK_UNSTABLE_RO_DETECT)) 136782b0e23aSTakashi Iwai return check_ro(host); 136882b0e23aSTakashi Iwai 136982b0e23aSTakashi Iwai ro_count = 0; 137082b0e23aSTakashi Iwai for (i = 0; i < SAMPLE_COUNT; i++) { 137182b0e23aSTakashi Iwai if (check_ro(host)) { 137282b0e23aSTakashi Iwai if (++ro_count > SAMPLE_COUNT / 2) 137382b0e23aSTakashi Iwai return 1; 137482b0e23aSTakashi Iwai } 137582b0e23aSTakashi Iwai msleep(30); 137682b0e23aSTakashi Iwai } 137782b0e23aSTakashi Iwai return 0; 137882b0e23aSTakashi Iwai } 137982b0e23aSTakashi Iwai 1380f75979b7SPierre Ossman static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable) 1381f75979b7SPierre Ossman { 1382f75979b7SPierre Ossman struct sdhci_host *host; 1383f75979b7SPierre Ossman unsigned long flags; 1384f75979b7SPierre Ossman 1385f75979b7SPierre Ossman host = mmc_priv(mmc); 1386f75979b7SPierre Ossman 1387f75979b7SPierre Ossman spin_lock_irqsave(&host->lock, flags); 1388f75979b7SPierre Ossman 13891e72859eSPierre Ossman if (host->flags & SDHCI_DEVICE_DEAD) 13901e72859eSPierre Ossman goto out; 13911e72859eSPierre Ossman 1392f75979b7SPierre Ossman if (enable) 13937260cf5eSAnton Vorontsov sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT); 13947260cf5eSAnton Vorontsov else 13957260cf5eSAnton Vorontsov sdhci_mask_irqs(host, SDHCI_INT_CARD_INT); 13961e72859eSPierre Ossman out: 1397f75979b7SPierre Ossman mmiowb(); 1398f75979b7SPierre Ossman 1399f75979b7SPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 1400f75979b7SPierre Ossman } 1401f75979b7SPierre Ossman 1402f2119df6SArindam Nath static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, 1403f2119df6SArindam Nath struct mmc_ios *ios) 1404f2119df6SArindam Nath { 1405f2119df6SArindam Nath struct sdhci_host *host; 1406f2119df6SArindam Nath u8 pwr; 1407f2119df6SArindam Nath u16 clk, ctrl; 1408f2119df6SArindam Nath u32 present_state; 1409f2119df6SArindam Nath 1410f2119df6SArindam Nath host = mmc_priv(mmc); 1411f2119df6SArindam Nath 1412f2119df6SArindam Nath /* 1413f2119df6SArindam Nath * Signal Voltage Switching is only applicable for Host Controllers 1414f2119df6SArindam Nath * v3.00 and above. 1415f2119df6SArindam Nath */ 1416f2119df6SArindam Nath if (host->version < SDHCI_SPEC_300) 1417f2119df6SArindam Nath return 0; 1418f2119df6SArindam Nath 1419f2119df6SArindam Nath /* 1420f2119df6SArindam Nath * We first check whether the request is to set signalling voltage 1421f2119df6SArindam Nath * to 3.3V. If so, we change the voltage to 3.3V and return quickly. 1422f2119df6SArindam Nath */ 1423f2119df6SArindam Nath ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1424f2119df6SArindam Nath if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) { 1425f2119df6SArindam Nath /* Set 1.8V Signal Enable in the Host Control2 register to 0 */ 1426f2119df6SArindam Nath ctrl &= ~SDHCI_CTRL_VDD_180; 1427f2119df6SArindam Nath sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 1428f2119df6SArindam Nath 1429f2119df6SArindam Nath /* Wait for 5ms */ 1430f2119df6SArindam Nath usleep_range(5000, 5500); 1431f2119df6SArindam Nath 1432f2119df6SArindam Nath /* 3.3V regulator output should be stable within 5 ms */ 1433f2119df6SArindam Nath ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1434f2119df6SArindam Nath if (!(ctrl & SDHCI_CTRL_VDD_180)) 1435f2119df6SArindam Nath return 0; 1436f2119df6SArindam Nath else { 1437f2119df6SArindam Nath printk(KERN_INFO DRIVER_NAME ": Switching to 3.3V " 1438f2119df6SArindam Nath "signalling voltage failed\n"); 1439f2119df6SArindam Nath return -EIO; 1440f2119df6SArindam Nath } 1441f2119df6SArindam Nath } else if (!(ctrl & SDHCI_CTRL_VDD_180) && 1442f2119df6SArindam Nath (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)) { 1443f2119df6SArindam Nath /* Stop SDCLK */ 1444f2119df6SArindam Nath clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 1445f2119df6SArindam Nath clk &= ~SDHCI_CLOCK_CARD_EN; 1446f2119df6SArindam Nath sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 1447f2119df6SArindam Nath 1448f2119df6SArindam Nath /* Check whether DAT[3:0] is 0000 */ 1449f2119df6SArindam Nath present_state = sdhci_readl(host, SDHCI_PRESENT_STATE); 1450f2119df6SArindam Nath if (!((present_state & SDHCI_DATA_LVL_MASK) >> 1451f2119df6SArindam Nath SDHCI_DATA_LVL_SHIFT)) { 1452f2119df6SArindam Nath /* 1453f2119df6SArindam Nath * Enable 1.8V Signal Enable in the Host Control2 1454f2119df6SArindam Nath * register 1455f2119df6SArindam Nath */ 1456f2119df6SArindam Nath ctrl |= SDHCI_CTRL_VDD_180; 1457f2119df6SArindam Nath sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 1458f2119df6SArindam Nath 1459f2119df6SArindam Nath /* Wait for 5ms */ 1460f2119df6SArindam Nath usleep_range(5000, 5500); 1461f2119df6SArindam Nath 1462f2119df6SArindam Nath ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1463f2119df6SArindam Nath if (ctrl & SDHCI_CTRL_VDD_180) { 1464f2119df6SArindam Nath /* Provide SDCLK again and wait for 1ms*/ 1465f2119df6SArindam Nath clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 1466f2119df6SArindam Nath clk |= SDHCI_CLOCK_CARD_EN; 1467f2119df6SArindam Nath sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 1468f2119df6SArindam Nath usleep_range(1000, 1500); 1469f2119df6SArindam Nath 1470f2119df6SArindam Nath /* 1471f2119df6SArindam Nath * If DAT[3:0] level is 1111b, then the card 1472f2119df6SArindam Nath * was successfully switched to 1.8V signaling. 1473f2119df6SArindam Nath */ 1474f2119df6SArindam Nath present_state = sdhci_readl(host, 1475f2119df6SArindam Nath SDHCI_PRESENT_STATE); 1476f2119df6SArindam Nath if ((present_state & SDHCI_DATA_LVL_MASK) == 1477f2119df6SArindam Nath SDHCI_DATA_LVL_MASK) 1478f2119df6SArindam Nath return 0; 1479f2119df6SArindam Nath } 1480f2119df6SArindam Nath } 1481f2119df6SArindam Nath 1482f2119df6SArindam Nath /* 1483f2119df6SArindam Nath * If we are here, that means the switch to 1.8V signaling 1484f2119df6SArindam Nath * failed. We power cycle the card, and retry initialization 1485f2119df6SArindam Nath * sequence by setting S18R to 0. 1486f2119df6SArindam Nath */ 1487f2119df6SArindam Nath pwr = sdhci_readb(host, SDHCI_POWER_CONTROL); 1488f2119df6SArindam Nath pwr &= ~SDHCI_POWER_ON; 1489f2119df6SArindam Nath sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); 1490f2119df6SArindam Nath 1491f2119df6SArindam Nath /* Wait for 1ms as per the spec */ 1492f2119df6SArindam Nath usleep_range(1000, 1500); 1493f2119df6SArindam Nath pwr |= SDHCI_POWER_ON; 1494f2119df6SArindam Nath sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); 1495f2119df6SArindam Nath 1496f2119df6SArindam Nath printk(KERN_INFO DRIVER_NAME ": Switching to 1.8V signalling " 1497f2119df6SArindam Nath "voltage failed, retrying with S18R set to 0\n"); 1498f2119df6SArindam Nath return -EAGAIN; 1499f2119df6SArindam Nath } else 1500f2119df6SArindam Nath /* No signal voltage switch required */ 1501f2119df6SArindam Nath return 0; 1502f2119df6SArindam Nath } 1503f2119df6SArindam Nath 15041c6a0718SPierre Ossman static const struct mmc_host_ops sdhci_ops = { 15051c6a0718SPierre Ossman .request = sdhci_request, 15061c6a0718SPierre Ossman .set_ios = sdhci_set_ios, 15071c6a0718SPierre Ossman .get_ro = sdhci_get_ro, 1508f75979b7SPierre Ossman .enable_sdio_irq = sdhci_enable_sdio_irq, 1509f2119df6SArindam Nath .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, 15101c6a0718SPierre Ossman }; 15111c6a0718SPierre Ossman 15121c6a0718SPierre Ossman /*****************************************************************************\ 15131c6a0718SPierre Ossman * * 15141c6a0718SPierre Ossman * Tasklets * 15151c6a0718SPierre Ossman * * 15161c6a0718SPierre Ossman \*****************************************************************************/ 15171c6a0718SPierre Ossman 15181c6a0718SPierre Ossman static void sdhci_tasklet_card(unsigned long param) 15191c6a0718SPierre Ossman { 15201c6a0718SPierre Ossman struct sdhci_host *host; 15211c6a0718SPierre Ossman unsigned long flags; 15221c6a0718SPierre Ossman 15231c6a0718SPierre Ossman host = (struct sdhci_host*)param; 15241c6a0718SPierre Ossman 15251c6a0718SPierre Ossman spin_lock_irqsave(&host->lock, flags); 15261c6a0718SPierre Ossman 15274e4141a5SAnton Vorontsov if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) { 15281c6a0718SPierre Ossman if (host->mrq) { 15291c6a0718SPierre Ossman printk(KERN_ERR "%s: Card removed during transfer!\n", 15301c6a0718SPierre Ossman mmc_hostname(host->mmc)); 15311c6a0718SPierre Ossman printk(KERN_ERR "%s: Resetting controller.\n", 15321c6a0718SPierre Ossman mmc_hostname(host->mmc)); 15331c6a0718SPierre Ossman 15341c6a0718SPierre Ossman sdhci_reset(host, SDHCI_RESET_CMD); 15351c6a0718SPierre Ossman sdhci_reset(host, SDHCI_RESET_DATA); 15361c6a0718SPierre Ossman 153717b0429dSPierre Ossman host->mrq->cmd->error = -ENOMEDIUM; 15381c6a0718SPierre Ossman tasklet_schedule(&host->finish_tasklet); 15391c6a0718SPierre Ossman } 15401c6a0718SPierre Ossman } 15411c6a0718SPierre Ossman 15421c6a0718SPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 15431c6a0718SPierre Ossman 154404cf585dSPierre Ossman mmc_detect_change(host->mmc, msecs_to_jiffies(200)); 15451c6a0718SPierre Ossman } 15461c6a0718SPierre Ossman 15471c6a0718SPierre Ossman static void sdhci_tasklet_finish(unsigned long param) 15481c6a0718SPierre Ossman { 15491c6a0718SPierre Ossman struct sdhci_host *host; 15501c6a0718SPierre Ossman unsigned long flags; 15511c6a0718SPierre Ossman struct mmc_request *mrq; 15521c6a0718SPierre Ossman 15531c6a0718SPierre Ossman host = (struct sdhci_host*)param; 15541c6a0718SPierre Ossman 15550c9c99a7SChris Ball /* 15560c9c99a7SChris Ball * If this tasklet gets rescheduled while running, it will 15570c9c99a7SChris Ball * be run again afterwards but without any active request. 15580c9c99a7SChris Ball */ 15590c9c99a7SChris Ball if (!host->mrq) 15600c9c99a7SChris Ball return; 15610c9c99a7SChris Ball 15621c6a0718SPierre Ossman spin_lock_irqsave(&host->lock, flags); 15631c6a0718SPierre Ossman 15641c6a0718SPierre Ossman del_timer(&host->timer); 15651c6a0718SPierre Ossman 15661c6a0718SPierre Ossman mrq = host->mrq; 15671c6a0718SPierre Ossman 15681c6a0718SPierre Ossman /* 15691c6a0718SPierre Ossman * The controller needs a reset of internal state machines 15701c6a0718SPierre Ossman * upon error conditions. 15711c6a0718SPierre Ossman */ 15721e72859eSPierre Ossman if (!(host->flags & SDHCI_DEVICE_DEAD) && 1573b7b4d342SBen Dooks ((mrq->cmd && mrq->cmd->error) || 157417b0429dSPierre Ossman (mrq->data && (mrq->data->error || 157584c46a53SPierre Ossman (mrq->data->stop && mrq->data->stop->error))) || 15761e72859eSPierre Ossman (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) { 15771c6a0718SPierre Ossman 15781c6a0718SPierre Ossman /* Some controllers need this kick or reset won't work here */ 1579b8c86fc5SPierre Ossman if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) { 15801c6a0718SPierre Ossman unsigned int clock; 15811c6a0718SPierre Ossman 15821c6a0718SPierre Ossman /* This is to force an update */ 15831c6a0718SPierre Ossman clock = host->clock; 15841c6a0718SPierre Ossman host->clock = 0; 15851c6a0718SPierre Ossman sdhci_set_clock(host, clock); 15861c6a0718SPierre Ossman } 15871c6a0718SPierre Ossman 15881c6a0718SPierre Ossman /* Spec says we should do both at the same time, but Ricoh 15891c6a0718SPierre Ossman controllers do not like that. */ 15901c6a0718SPierre Ossman sdhci_reset(host, SDHCI_RESET_CMD); 15911c6a0718SPierre Ossman sdhci_reset(host, SDHCI_RESET_DATA); 15921c6a0718SPierre Ossman } 15931c6a0718SPierre Ossman 15941c6a0718SPierre Ossman host->mrq = NULL; 15951c6a0718SPierre Ossman host->cmd = NULL; 15961c6a0718SPierre Ossman host->data = NULL; 15971c6a0718SPierre Ossman 1598f9134319SPierre Ossman #ifndef SDHCI_USE_LEDS_CLASS 15991c6a0718SPierre Ossman sdhci_deactivate_led(host); 16002f730fecSPierre Ossman #endif 16011c6a0718SPierre Ossman 16021c6a0718SPierre Ossman mmiowb(); 16031c6a0718SPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 16041c6a0718SPierre Ossman 16051c6a0718SPierre Ossman mmc_request_done(host->mmc, mrq); 16061c6a0718SPierre Ossman } 16071c6a0718SPierre Ossman 16081c6a0718SPierre Ossman static void sdhci_timeout_timer(unsigned long data) 16091c6a0718SPierre Ossman { 16101c6a0718SPierre Ossman struct sdhci_host *host; 16111c6a0718SPierre Ossman unsigned long flags; 16121c6a0718SPierre Ossman 16131c6a0718SPierre Ossman host = (struct sdhci_host*)data; 16141c6a0718SPierre Ossman 16151c6a0718SPierre Ossman spin_lock_irqsave(&host->lock, flags); 16161c6a0718SPierre Ossman 16171c6a0718SPierre Ossman if (host->mrq) { 16181c6a0718SPierre Ossman printk(KERN_ERR "%s: Timeout waiting for hardware " 16191c6a0718SPierre Ossman "interrupt.\n", mmc_hostname(host->mmc)); 16201c6a0718SPierre Ossman sdhci_dumpregs(host); 16211c6a0718SPierre Ossman 16221c6a0718SPierre Ossman if (host->data) { 162317b0429dSPierre Ossman host->data->error = -ETIMEDOUT; 16241c6a0718SPierre Ossman sdhci_finish_data(host); 16251c6a0718SPierre Ossman } else { 16261c6a0718SPierre Ossman if (host->cmd) 162717b0429dSPierre Ossman host->cmd->error = -ETIMEDOUT; 16281c6a0718SPierre Ossman else 162917b0429dSPierre Ossman host->mrq->cmd->error = -ETIMEDOUT; 16301c6a0718SPierre Ossman 16311c6a0718SPierre Ossman tasklet_schedule(&host->finish_tasklet); 16321c6a0718SPierre Ossman } 16331c6a0718SPierre Ossman } 16341c6a0718SPierre Ossman 16351c6a0718SPierre Ossman mmiowb(); 16361c6a0718SPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 16371c6a0718SPierre Ossman } 16381c6a0718SPierre Ossman 16391c6a0718SPierre Ossman /*****************************************************************************\ 16401c6a0718SPierre Ossman * * 16411c6a0718SPierre Ossman * Interrupt handling * 16421c6a0718SPierre Ossman * * 16431c6a0718SPierre Ossman \*****************************************************************************/ 16441c6a0718SPierre Ossman 16451c6a0718SPierre Ossman static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) 16461c6a0718SPierre Ossman { 16471c6a0718SPierre Ossman BUG_ON(intmask == 0); 16481c6a0718SPierre Ossman 16491c6a0718SPierre Ossman if (!host->cmd) { 1650b67ac3f3SPierre Ossman printk(KERN_ERR "%s: Got command interrupt 0x%08x even " 1651b67ac3f3SPierre Ossman "though no command operation was in progress.\n", 1652b67ac3f3SPierre Ossman mmc_hostname(host->mmc), (unsigned)intmask); 16531c6a0718SPierre Ossman sdhci_dumpregs(host); 16541c6a0718SPierre Ossman return; 16551c6a0718SPierre Ossman } 16561c6a0718SPierre Ossman 16571c6a0718SPierre Ossman if (intmask & SDHCI_INT_TIMEOUT) 165817b0429dSPierre Ossman host->cmd->error = -ETIMEDOUT; 165917b0429dSPierre Ossman else if (intmask & (SDHCI_INT_CRC | SDHCI_INT_END_BIT | 166017b0429dSPierre Ossman SDHCI_INT_INDEX)) 166117b0429dSPierre Ossman host->cmd->error = -EILSEQ; 16621c6a0718SPierre Ossman 1663e809517fSPierre Ossman if (host->cmd->error) { 16641c6a0718SPierre Ossman tasklet_schedule(&host->finish_tasklet); 1665e809517fSPierre Ossman return; 1666e809517fSPierre Ossman } 1667e809517fSPierre Ossman 1668e809517fSPierre Ossman /* 1669e809517fSPierre Ossman * The host can send and interrupt when the busy state has 1670e809517fSPierre Ossman * ended, allowing us to wait without wasting CPU cycles. 1671e809517fSPierre Ossman * Unfortunately this is overloaded on the "data complete" 1672e809517fSPierre Ossman * interrupt, so we need to take some care when handling 1673e809517fSPierre Ossman * it. 1674e809517fSPierre Ossman * 1675e809517fSPierre Ossman * Note: The 1.0 specification is a bit ambiguous about this 1676e809517fSPierre Ossman * feature so there might be some problems with older 1677e809517fSPierre Ossman * controllers. 1678e809517fSPierre Ossman */ 1679e809517fSPierre Ossman if (host->cmd->flags & MMC_RSP_BUSY) { 1680e809517fSPierre Ossman if (host->cmd->data) 1681e809517fSPierre Ossman DBG("Cannot wait for busy signal when also " 1682e809517fSPierre Ossman "doing a data transfer"); 1683f945405cSBen Dooks else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ)) 1684e809517fSPierre Ossman return; 1685f945405cSBen Dooks 1686f945405cSBen Dooks /* The controller does not support the end-of-busy IRQ, 1687f945405cSBen Dooks * fall through and take the SDHCI_INT_RESPONSE */ 1688e809517fSPierre Ossman } 1689e809517fSPierre Ossman 1690e809517fSPierre Ossman if (intmask & SDHCI_INT_RESPONSE) 169143b58b36SPierre Ossman sdhci_finish_command(host); 16921c6a0718SPierre Ossman } 16931c6a0718SPierre Ossman 16940957c333SGeorge G. Davis #ifdef CONFIG_MMC_DEBUG 16956882a8c0SBen Dooks static void sdhci_show_adma_error(struct sdhci_host *host) 16966882a8c0SBen Dooks { 16976882a8c0SBen Dooks const char *name = mmc_hostname(host->mmc); 16986882a8c0SBen Dooks u8 *desc = host->adma_desc; 16996882a8c0SBen Dooks __le32 *dma; 17006882a8c0SBen Dooks __le16 *len; 17016882a8c0SBen Dooks u8 attr; 17026882a8c0SBen Dooks 17036882a8c0SBen Dooks sdhci_dumpregs(host); 17046882a8c0SBen Dooks 17056882a8c0SBen Dooks while (true) { 17066882a8c0SBen Dooks dma = (__le32 *)(desc + 4); 17076882a8c0SBen Dooks len = (__le16 *)(desc + 2); 17086882a8c0SBen Dooks attr = *desc; 17096882a8c0SBen Dooks 17106882a8c0SBen Dooks DBG("%s: %p: DMA 0x%08x, LEN 0x%04x, Attr=0x%02x\n", 17116882a8c0SBen Dooks name, desc, le32_to_cpu(*dma), le16_to_cpu(*len), attr); 17126882a8c0SBen Dooks 17136882a8c0SBen Dooks desc += 8; 17146882a8c0SBen Dooks 17156882a8c0SBen Dooks if (attr & 2) 17166882a8c0SBen Dooks break; 17176882a8c0SBen Dooks } 17186882a8c0SBen Dooks } 17196882a8c0SBen Dooks #else 17206882a8c0SBen Dooks static void sdhci_show_adma_error(struct sdhci_host *host) { } 17216882a8c0SBen Dooks #endif 17226882a8c0SBen Dooks 17231c6a0718SPierre Ossman static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) 17241c6a0718SPierre Ossman { 17251c6a0718SPierre Ossman BUG_ON(intmask == 0); 17261c6a0718SPierre Ossman 17271c6a0718SPierre Ossman if (!host->data) { 17281c6a0718SPierre Ossman /* 1729e809517fSPierre Ossman * The "data complete" interrupt is also used to 1730e809517fSPierre Ossman * indicate that a busy state has ended. See comment 1731e809517fSPierre Ossman * above in sdhci_cmd_irq(). 17321c6a0718SPierre Ossman */ 1733e809517fSPierre Ossman if (host->cmd && (host->cmd->flags & MMC_RSP_BUSY)) { 1734e809517fSPierre Ossman if (intmask & SDHCI_INT_DATA_END) { 1735e809517fSPierre Ossman sdhci_finish_command(host); 17361c6a0718SPierre Ossman return; 1737e809517fSPierre Ossman } 1738e809517fSPierre Ossman } 17391c6a0718SPierre Ossman 1740b67ac3f3SPierre Ossman printk(KERN_ERR "%s: Got data interrupt 0x%08x even " 1741b67ac3f3SPierre Ossman "though no data operation was in progress.\n", 1742b67ac3f3SPierre Ossman mmc_hostname(host->mmc), (unsigned)intmask); 17431c6a0718SPierre Ossman sdhci_dumpregs(host); 17441c6a0718SPierre Ossman 17451c6a0718SPierre Ossman return; 17461c6a0718SPierre Ossman } 17471c6a0718SPierre Ossman 17481c6a0718SPierre Ossman if (intmask & SDHCI_INT_DATA_TIMEOUT) 174917b0429dSPierre Ossman host->data->error = -ETIMEDOUT; 175022113efdSAries Lee else if (intmask & SDHCI_INT_DATA_END_BIT) 175122113efdSAries Lee host->data->error = -EILSEQ; 175222113efdSAries Lee else if ((intmask & SDHCI_INT_DATA_CRC) && 175322113efdSAries Lee SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)) 175422113efdSAries Lee != MMC_BUS_TEST_R) 175517b0429dSPierre Ossman host->data->error = -EILSEQ; 17566882a8c0SBen Dooks else if (intmask & SDHCI_INT_ADMA_ERROR) { 17576882a8c0SBen Dooks printk(KERN_ERR "%s: ADMA error\n", mmc_hostname(host->mmc)); 17586882a8c0SBen Dooks sdhci_show_adma_error(host); 17592134a922SPierre Ossman host->data->error = -EIO; 17606882a8c0SBen Dooks } 17611c6a0718SPierre Ossman 176217b0429dSPierre Ossman if (host->data->error) 17631c6a0718SPierre Ossman sdhci_finish_data(host); 17641c6a0718SPierre Ossman else { 17651c6a0718SPierre Ossman if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) 17661c6a0718SPierre Ossman sdhci_transfer_pio(host); 17671c6a0718SPierre Ossman 17686ba736a1SPierre Ossman /* 17696ba736a1SPierre Ossman * We currently don't do anything fancy with DMA 17706ba736a1SPierre Ossman * boundaries, but as we can't disable the feature 17716ba736a1SPierre Ossman * we need to at least restart the transfer. 1772f6a03cbfSMikko Vinni * 1773f6a03cbfSMikko Vinni * According to the spec sdhci_readl(host, SDHCI_DMA_ADDRESS) 1774f6a03cbfSMikko Vinni * should return a valid address to continue from, but as 1775f6a03cbfSMikko Vinni * some controllers are faulty, don't trust them. 17766ba736a1SPierre Ossman */ 1777f6a03cbfSMikko Vinni if (intmask & SDHCI_INT_DMA_END) { 1778f6a03cbfSMikko Vinni u32 dmastart, dmanow; 1779f6a03cbfSMikko Vinni dmastart = sg_dma_address(host->data->sg); 1780f6a03cbfSMikko Vinni dmanow = dmastart + host->data->bytes_xfered; 1781f6a03cbfSMikko Vinni /* 1782f6a03cbfSMikko Vinni * Force update to the next DMA block boundary. 1783f6a03cbfSMikko Vinni */ 1784f6a03cbfSMikko Vinni dmanow = (dmanow & 1785f6a03cbfSMikko Vinni ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) + 1786f6a03cbfSMikko Vinni SDHCI_DEFAULT_BOUNDARY_SIZE; 1787f6a03cbfSMikko Vinni host->data->bytes_xfered = dmanow - dmastart; 1788f6a03cbfSMikko Vinni DBG("%s: DMA base 0x%08x, transferred 0x%06x bytes," 1789f6a03cbfSMikko Vinni " next 0x%08x\n", 1790f6a03cbfSMikko Vinni mmc_hostname(host->mmc), dmastart, 1791f6a03cbfSMikko Vinni host->data->bytes_xfered, dmanow); 1792f6a03cbfSMikko Vinni sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS); 1793f6a03cbfSMikko Vinni } 17946ba736a1SPierre Ossman 1795e538fbe8SPierre Ossman if (intmask & SDHCI_INT_DATA_END) { 1796e538fbe8SPierre Ossman if (host->cmd) { 1797e538fbe8SPierre Ossman /* 1798e538fbe8SPierre Ossman * Data managed to finish before the 1799e538fbe8SPierre Ossman * command completed. Make sure we do 1800e538fbe8SPierre Ossman * things in the proper order. 1801e538fbe8SPierre Ossman */ 1802e538fbe8SPierre Ossman host->data_early = 1; 1803e538fbe8SPierre Ossman } else { 18041c6a0718SPierre Ossman sdhci_finish_data(host); 18051c6a0718SPierre Ossman } 18061c6a0718SPierre Ossman } 1807e538fbe8SPierre Ossman } 1808e538fbe8SPierre Ossman } 18091c6a0718SPierre Ossman 18101c6a0718SPierre Ossman static irqreturn_t sdhci_irq(int irq, void *dev_id) 18111c6a0718SPierre Ossman { 18121c6a0718SPierre Ossman irqreturn_t result; 18131c6a0718SPierre Ossman struct sdhci_host* host = dev_id; 18141c6a0718SPierre Ossman u32 intmask; 1815f75979b7SPierre Ossman int cardint = 0; 18161c6a0718SPierre Ossman 18171c6a0718SPierre Ossman spin_lock(&host->lock); 18181c6a0718SPierre Ossman 18194e4141a5SAnton Vorontsov intmask = sdhci_readl(host, SDHCI_INT_STATUS); 18201c6a0718SPierre Ossman 18211c6a0718SPierre Ossman if (!intmask || intmask == 0xffffffff) { 18221c6a0718SPierre Ossman result = IRQ_NONE; 18231c6a0718SPierre Ossman goto out; 18241c6a0718SPierre Ossman } 18251c6a0718SPierre Ossman 1826b69c9058SPierre Ossman DBG("*** %s got interrupt: 0x%08x\n", 1827b69c9058SPierre Ossman mmc_hostname(host->mmc), intmask); 18281c6a0718SPierre Ossman 18291c6a0718SPierre Ossman if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) { 18304e4141a5SAnton Vorontsov sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT | 18314e4141a5SAnton Vorontsov SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS); 18321c6a0718SPierre Ossman tasklet_schedule(&host->card_tasklet); 18331c6a0718SPierre Ossman } 18341c6a0718SPierre Ossman 18351c6a0718SPierre Ossman intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE); 18361c6a0718SPierre Ossman 18371c6a0718SPierre Ossman if (intmask & SDHCI_INT_CMD_MASK) { 18384e4141a5SAnton Vorontsov sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK, 18394e4141a5SAnton Vorontsov SDHCI_INT_STATUS); 18401c6a0718SPierre Ossman sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK); 18411c6a0718SPierre Ossman } 18421c6a0718SPierre Ossman 18431c6a0718SPierre Ossman if (intmask & SDHCI_INT_DATA_MASK) { 18444e4141a5SAnton Vorontsov sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK, 18454e4141a5SAnton Vorontsov SDHCI_INT_STATUS); 18461c6a0718SPierre Ossman sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK); 18471c6a0718SPierre Ossman } 18481c6a0718SPierre Ossman 18491c6a0718SPierre Ossman intmask &= ~(SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK); 18501c6a0718SPierre Ossman 1851964f9ce2SPierre Ossman intmask &= ~SDHCI_INT_ERROR; 1852964f9ce2SPierre Ossman 18531c6a0718SPierre Ossman if (intmask & SDHCI_INT_BUS_POWER) { 18541c6a0718SPierre Ossman printk(KERN_ERR "%s: Card is consuming too much power!\n", 18551c6a0718SPierre Ossman mmc_hostname(host->mmc)); 18564e4141a5SAnton Vorontsov sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS); 18571c6a0718SPierre Ossman } 18581c6a0718SPierre Ossman 18599d26a5d3SRolf Eike Beer intmask &= ~SDHCI_INT_BUS_POWER; 18601c6a0718SPierre Ossman 1861f75979b7SPierre Ossman if (intmask & SDHCI_INT_CARD_INT) 1862f75979b7SPierre Ossman cardint = 1; 1863f75979b7SPierre Ossman 1864f75979b7SPierre Ossman intmask &= ~SDHCI_INT_CARD_INT; 1865f75979b7SPierre Ossman 18661c6a0718SPierre Ossman if (intmask) { 18671c6a0718SPierre Ossman printk(KERN_ERR "%s: Unexpected interrupt 0x%08x.\n", 18681c6a0718SPierre Ossman mmc_hostname(host->mmc), intmask); 18691c6a0718SPierre Ossman sdhci_dumpregs(host); 18701c6a0718SPierre Ossman 18714e4141a5SAnton Vorontsov sdhci_writel(host, intmask, SDHCI_INT_STATUS); 18721c6a0718SPierre Ossman } 18731c6a0718SPierre Ossman 18741c6a0718SPierre Ossman result = IRQ_HANDLED; 18751c6a0718SPierre Ossman 18761c6a0718SPierre Ossman mmiowb(); 18771c6a0718SPierre Ossman out: 18781c6a0718SPierre Ossman spin_unlock(&host->lock); 18791c6a0718SPierre Ossman 1880f75979b7SPierre Ossman /* 1881f75979b7SPierre Ossman * We have to delay this as it calls back into the driver. 1882f75979b7SPierre Ossman */ 1883f75979b7SPierre Ossman if (cardint) 1884f75979b7SPierre Ossman mmc_signal_sdio_irq(host->mmc); 1885f75979b7SPierre Ossman 18861c6a0718SPierre Ossman return result; 18871c6a0718SPierre Ossman } 18881c6a0718SPierre Ossman 18891c6a0718SPierre Ossman /*****************************************************************************\ 18901c6a0718SPierre Ossman * * 18911c6a0718SPierre Ossman * Suspend/resume * 18921c6a0718SPierre Ossman * * 18931c6a0718SPierre Ossman \*****************************************************************************/ 18941c6a0718SPierre Ossman 18951c6a0718SPierre Ossman #ifdef CONFIG_PM 18961c6a0718SPierre Ossman 1897b8c86fc5SPierre Ossman int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state) 18981c6a0718SPierre Ossman { 1899b8c86fc5SPierre Ossman int ret; 19001c6a0718SPierre Ossman 19017260cf5eSAnton Vorontsov sdhci_disable_card_detection(host); 19027260cf5eSAnton Vorontsov 19031a13f8faSMatt Fleming ret = mmc_suspend_host(host->mmc); 19041c6a0718SPierre Ossman if (ret) 19051c6a0718SPierre Ossman return ret; 19061c6a0718SPierre Ossman 1907b8c86fc5SPierre Ossman free_irq(host->irq, host); 1908b8c86fc5SPierre Ossman 19099bea3c85SMarek Szyprowski if (host->vmmc) 19109bea3c85SMarek Szyprowski ret = regulator_disable(host->vmmc); 19119bea3c85SMarek Szyprowski 19129bea3c85SMarek Szyprowski return ret; 1913b8c86fc5SPierre Ossman } 1914b8c86fc5SPierre Ossman 1915b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_suspend_host); 1916b8c86fc5SPierre Ossman 1917b8c86fc5SPierre Ossman int sdhci_resume_host(struct sdhci_host *host) 1918b8c86fc5SPierre Ossman { 1919b8c86fc5SPierre Ossman int ret; 1920b8c86fc5SPierre Ossman 19219bea3c85SMarek Szyprowski if (host->vmmc) { 19229bea3c85SMarek Szyprowski int ret = regulator_enable(host->vmmc); 19239bea3c85SMarek Szyprowski if (ret) 19249bea3c85SMarek Szyprowski return ret; 19259bea3c85SMarek Szyprowski } 19269bea3c85SMarek Szyprowski 19279bea3c85SMarek Szyprowski 1928a13abc7bSRichard Röjfors if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { 1929b8c86fc5SPierre Ossman if (host->ops->enable_dma) 1930b8c86fc5SPierre Ossman host->ops->enable_dma(host); 1931b8c86fc5SPierre Ossman } 1932b8c86fc5SPierre Ossman 1933b8c86fc5SPierre Ossman ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, 1934b8c86fc5SPierre Ossman mmc_hostname(host->mmc), host); 19351c6a0718SPierre Ossman if (ret) 19361c6a0718SPierre Ossman return ret; 1937b8c86fc5SPierre Ossman 19382f4cbb3dSNicolas Pitre sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER)); 19391c6a0718SPierre Ossman mmiowb(); 1940b8c86fc5SPierre Ossman 1941b8c86fc5SPierre Ossman ret = mmc_resume_host(host->mmc); 19427260cf5eSAnton Vorontsov sdhci_enable_card_detection(host); 19437260cf5eSAnton Vorontsov 19442f4cbb3dSNicolas Pitre return ret; 19451c6a0718SPierre Ossman } 19461c6a0718SPierre Ossman 1947b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_resume_host); 19481c6a0718SPierre Ossman 19495f619704SDaniel Drake void sdhci_enable_irq_wakeups(struct sdhci_host *host) 19505f619704SDaniel Drake { 19515f619704SDaniel Drake u8 val; 19525f619704SDaniel Drake val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); 19535f619704SDaniel Drake val |= SDHCI_WAKE_ON_INT; 19545f619704SDaniel Drake sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL); 19555f619704SDaniel Drake } 19565f619704SDaniel Drake 19575f619704SDaniel Drake EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups); 19585f619704SDaniel Drake 19591c6a0718SPierre Ossman #endif /* CONFIG_PM */ 19601c6a0718SPierre Ossman 19611c6a0718SPierre Ossman /*****************************************************************************\ 19621c6a0718SPierre Ossman * * 1963b8c86fc5SPierre Ossman * Device allocation/registration * 19641c6a0718SPierre Ossman * * 19651c6a0718SPierre Ossman \*****************************************************************************/ 19661c6a0718SPierre Ossman 1967b8c86fc5SPierre Ossman struct sdhci_host *sdhci_alloc_host(struct device *dev, 1968b8c86fc5SPierre Ossman size_t priv_size) 19691c6a0718SPierre Ossman { 19701c6a0718SPierre Ossman struct mmc_host *mmc; 19711c6a0718SPierre Ossman struct sdhci_host *host; 19721c6a0718SPierre Ossman 1973b8c86fc5SPierre Ossman WARN_ON(dev == NULL); 19741c6a0718SPierre Ossman 1975b8c86fc5SPierre Ossman mmc = mmc_alloc_host(sizeof(struct sdhci_host) + priv_size, dev); 19761c6a0718SPierre Ossman if (!mmc) 1977b8c86fc5SPierre Ossman return ERR_PTR(-ENOMEM); 19781c6a0718SPierre Ossman 19791c6a0718SPierre Ossman host = mmc_priv(mmc); 19801c6a0718SPierre Ossman host->mmc = mmc; 19811c6a0718SPierre Ossman 1982b8c86fc5SPierre Ossman return host; 19831c6a0718SPierre Ossman } 19841c6a0718SPierre Ossman 1985b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_alloc_host); 1986b8c86fc5SPierre Ossman 1987b8c86fc5SPierre Ossman int sdhci_add_host(struct sdhci_host *host) 1988b8c86fc5SPierre Ossman { 1989b8c86fc5SPierre Ossman struct mmc_host *mmc; 1990f2119df6SArindam Nath u32 caps[2]; 1991f2119df6SArindam Nath u32 max_current_caps; 1992f2119df6SArindam Nath unsigned int ocr_avail; 1993b8c86fc5SPierre Ossman int ret; 1994b8c86fc5SPierre Ossman 1995b8c86fc5SPierre Ossman WARN_ON(host == NULL); 1996b8c86fc5SPierre Ossman if (host == NULL) 1997b8c86fc5SPierre Ossman return -EINVAL; 1998b8c86fc5SPierre Ossman 1999b8c86fc5SPierre Ossman mmc = host->mmc; 2000b8c86fc5SPierre Ossman 2001b8c86fc5SPierre Ossman if (debug_quirks) 2002b8c86fc5SPierre Ossman host->quirks = debug_quirks; 2003b8c86fc5SPierre Ossman 20041c6a0718SPierre Ossman sdhci_reset(host, SDHCI_RESET_ALL); 20051c6a0718SPierre Ossman 20064e4141a5SAnton Vorontsov host->version = sdhci_readw(host, SDHCI_HOST_VERSION); 20072134a922SPierre Ossman host->version = (host->version & SDHCI_SPEC_VER_MASK) 20082134a922SPierre Ossman >> SDHCI_SPEC_VER_SHIFT; 200985105c53SZhangfei Gao if (host->version > SDHCI_SPEC_300) { 20101c6a0718SPierre Ossman printk(KERN_ERR "%s: Unknown controller version (%d). " 2011b69c9058SPierre Ossman "You may experience problems.\n", mmc_hostname(mmc), 20122134a922SPierre Ossman host->version); 20131c6a0718SPierre Ossman } 20141c6a0718SPierre Ossman 2015f2119df6SArindam Nath caps[0] = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps : 2016ccc92c23SMaxim Levitsky sdhci_readl(host, SDHCI_CAPABILITIES); 20171c6a0718SPierre Ossman 2018f2119df6SArindam Nath caps[1] = (host->version >= SDHCI_SPEC_300) ? 2019f2119df6SArindam Nath sdhci_readl(host, SDHCI_CAPABILITIES_1) : 0; 2020f2119df6SArindam Nath 2021b8c86fc5SPierre Ossman if (host->quirks & SDHCI_QUIRK_FORCE_DMA) 2022a13abc7bSRichard Röjfors host->flags |= SDHCI_USE_SDMA; 2023f2119df6SArindam Nath else if (!(caps[0] & SDHCI_CAN_DO_SDMA)) 2024a13abc7bSRichard Röjfors DBG("Controller doesn't have SDMA capability\n"); 20251c6a0718SPierre Ossman else 2026a13abc7bSRichard Röjfors host->flags |= SDHCI_USE_SDMA; 20271c6a0718SPierre Ossman 2028b8c86fc5SPierre Ossman if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) && 2029a13abc7bSRichard Röjfors (host->flags & SDHCI_USE_SDMA)) { 2030cee687ceSRolf Eike Beer DBG("Disabling DMA as it is marked broken\n"); 2031a13abc7bSRichard Röjfors host->flags &= ~SDHCI_USE_SDMA; 20327c168e3dSFeng Tang } 20337c168e3dSFeng Tang 2034f2119df6SArindam Nath if ((host->version >= SDHCI_SPEC_200) && 2035f2119df6SArindam Nath (caps[0] & SDHCI_CAN_DO_ADMA2)) 20362134a922SPierre Ossman host->flags |= SDHCI_USE_ADMA; 20372134a922SPierre Ossman 20382134a922SPierre Ossman if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) && 20392134a922SPierre Ossman (host->flags & SDHCI_USE_ADMA)) { 20402134a922SPierre Ossman DBG("Disabling ADMA as it is marked broken\n"); 20412134a922SPierre Ossman host->flags &= ~SDHCI_USE_ADMA; 20422134a922SPierre Ossman } 20432134a922SPierre Ossman 2044a13abc7bSRichard Röjfors if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { 2045b8c86fc5SPierre Ossman if (host->ops->enable_dma) { 2046b8c86fc5SPierre Ossman if (host->ops->enable_dma(host)) { 2047b8c86fc5SPierre Ossman printk(KERN_WARNING "%s: No suitable DMA " 2048b8c86fc5SPierre Ossman "available. Falling back to PIO.\n", 2049b8c86fc5SPierre Ossman mmc_hostname(mmc)); 2050a13abc7bSRichard Röjfors host->flags &= 2051a13abc7bSRichard Röjfors ~(SDHCI_USE_SDMA | SDHCI_USE_ADMA); 20521c6a0718SPierre Ossman } 20531c6a0718SPierre Ossman } 2054b8c86fc5SPierre Ossman } 20551c6a0718SPierre Ossman 20562134a922SPierre Ossman if (host->flags & SDHCI_USE_ADMA) { 20572134a922SPierre Ossman /* 20582134a922SPierre Ossman * We need to allocate descriptors for all sg entries 20592134a922SPierre Ossman * (128) and potentially one alignment transfer for 20602134a922SPierre Ossman * each of those entries. 20612134a922SPierre Ossman */ 20622134a922SPierre Ossman host->adma_desc = kmalloc((128 * 2 + 1) * 4, GFP_KERNEL); 20632134a922SPierre Ossman host->align_buffer = kmalloc(128 * 4, GFP_KERNEL); 20642134a922SPierre Ossman if (!host->adma_desc || !host->align_buffer) { 20652134a922SPierre Ossman kfree(host->adma_desc); 20662134a922SPierre Ossman kfree(host->align_buffer); 20672134a922SPierre Ossman printk(KERN_WARNING "%s: Unable to allocate ADMA " 20682134a922SPierre Ossman "buffers. Falling back to standard DMA.\n", 20692134a922SPierre Ossman mmc_hostname(mmc)); 20702134a922SPierre Ossman host->flags &= ~SDHCI_USE_ADMA; 20712134a922SPierre Ossman } 20722134a922SPierre Ossman } 20732134a922SPierre Ossman 20747659150cSPierre Ossman /* 20757659150cSPierre Ossman * If we use DMA, then it's up to the caller to set the DMA 20767659150cSPierre Ossman * mask, but PIO does not need the hw shim so we set a new 20777659150cSPierre Ossman * mask here in that case. 20787659150cSPierre Ossman */ 2079a13abc7bSRichard Röjfors if (!(host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))) { 20807659150cSPierre Ossman host->dma_mask = DMA_BIT_MASK(64); 20817659150cSPierre Ossman mmc_dev(host->mmc)->dma_mask = &host->dma_mask; 20827659150cSPierre Ossman } 20831c6a0718SPierre Ossman 2084c4687d5fSZhangfei Gao if (host->version >= SDHCI_SPEC_300) 2085f2119df6SArindam Nath host->max_clk = (caps[0] & SDHCI_CLOCK_V3_BASE_MASK) 2086c4687d5fSZhangfei Gao >> SDHCI_CLOCK_BASE_SHIFT; 2087c4687d5fSZhangfei Gao else 2088f2119df6SArindam Nath host->max_clk = (caps[0] & SDHCI_CLOCK_BASE_MASK) 2089c4687d5fSZhangfei Gao >> SDHCI_CLOCK_BASE_SHIFT; 2090c4687d5fSZhangfei Gao 20914240ff0aSBen Dooks host->max_clk *= 1000000; 2092f27f47efSAnton Vorontsov if (host->max_clk == 0 || host->quirks & 2093f27f47efSAnton Vorontsov SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN) { 20944240ff0aSBen Dooks if (!host->ops->get_max_clock) { 20954240ff0aSBen Dooks printk(KERN_ERR 20964240ff0aSBen Dooks "%s: Hardware doesn't specify base clock " 2097b69c9058SPierre Ossman "frequency.\n", mmc_hostname(mmc)); 2098b8c86fc5SPierre Ossman return -ENODEV; 20991c6a0718SPierre Ossman } 21004240ff0aSBen Dooks host->max_clk = host->ops->get_max_clock(host); 21014240ff0aSBen Dooks } 21021c6a0718SPierre Ossman 21031c6a0718SPierre Ossman host->timeout_clk = 2104f2119df6SArindam Nath (caps[0] & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT; 21051c6a0718SPierre Ossman if (host->timeout_clk == 0) { 210681b39802SAnton Vorontsov if (host->ops->get_timeout_clock) { 210781b39802SAnton Vorontsov host->timeout_clk = host->ops->get_timeout_clock(host); 210881b39802SAnton Vorontsov } else if (!(host->quirks & 210981b39802SAnton Vorontsov SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) { 21104240ff0aSBen Dooks printk(KERN_ERR 21114240ff0aSBen Dooks "%s: Hardware doesn't specify timeout clock " 2112b69c9058SPierre Ossman "frequency.\n", mmc_hostname(mmc)); 2113b8c86fc5SPierre Ossman return -ENODEV; 21141c6a0718SPierre Ossman } 21154240ff0aSBen Dooks } 2116f2119df6SArindam Nath if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT) 21171c6a0718SPierre Ossman host->timeout_clk *= 1000; 21181c6a0718SPierre Ossman 21191c6a0718SPierre Ossman /* 21201c6a0718SPierre Ossman * Set host parameters. 21211c6a0718SPierre Ossman */ 21221c6a0718SPierre Ossman mmc->ops = &sdhci_ops; 2123ce5f036bSMarek Szyprowski if (host->ops->get_min_clock) 2124a9e58f25SAnton Vorontsov mmc->f_min = host->ops->get_min_clock(host); 21250397526dSZhangfei Gao else if (host->version >= SDHCI_SPEC_300) 21260397526dSZhangfei Gao mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300; 2127a9e58f25SAnton Vorontsov else 21280397526dSZhangfei Gao mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200; 212915ec4461SPhilip Rakity 21301c6a0718SPierre Ossman mmc->f_max = host->max_clk; 2131a3c7778fSAndrei Warkentin mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE; 21325fe23c7fSAnton Vorontsov 213315ec4461SPhilip Rakity /* 213415ec4461SPhilip Rakity * A controller may support 8-bit width, but the board itself 213515ec4461SPhilip Rakity * might not have the pins brought out. Boards that support 213615ec4461SPhilip Rakity * 8-bit width must set "mmc->caps |= MMC_CAP_8_BIT_DATA;" in 213715ec4461SPhilip Rakity * their platform code before calling sdhci_add_host(), and we 213815ec4461SPhilip Rakity * won't assume 8-bit width for hosts without that CAP. 213915ec4461SPhilip Rakity */ 21405fe23c7fSAnton Vorontsov if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) 214115ec4461SPhilip Rakity mmc->caps |= MMC_CAP_4_BIT_DATA; 21421c6a0718SPierre Ossman 2143f2119df6SArindam Nath if (caps[0] & SDHCI_CAN_DO_HISPD) 2144a29e7e18SZhangfei Gao mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; 21451c6a0718SPierre Ossman 2146176d1ed4SJaehoon Chung if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) && 2147176d1ed4SJaehoon Chung mmc_card_is_removable(mmc)) 214868d1fb7eSAnton Vorontsov mmc->caps |= MMC_CAP_NEEDS_POLL; 214968d1fb7eSAnton Vorontsov 2150f2119df6SArindam Nath /* UHS-I mode(s) supported by the host controller. */ 2151f2119df6SArindam Nath if (host->version >= SDHCI_SPEC_300) 2152f2119df6SArindam Nath mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25; 2153f2119df6SArindam Nath 2154f2119df6SArindam Nath /* SDR104 supports also implies SDR50 support */ 2155f2119df6SArindam Nath if (caps[1] & SDHCI_SUPPORT_SDR104) 2156f2119df6SArindam Nath mmc->caps |= MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50; 2157f2119df6SArindam Nath else if (caps[1] & SDHCI_SUPPORT_SDR50) 2158f2119df6SArindam Nath mmc->caps |= MMC_CAP_UHS_SDR50; 2159f2119df6SArindam Nath 2160f2119df6SArindam Nath if (caps[1] & SDHCI_SUPPORT_DDR50) 2161f2119df6SArindam Nath mmc->caps |= MMC_CAP_UHS_DDR50; 2162f2119df6SArindam Nath 2163d6d50a15SArindam Nath /* Driver Type(s) (A, C, D) supported by the host */ 2164d6d50a15SArindam Nath if (caps[1] & SDHCI_DRIVER_TYPE_A) 2165d6d50a15SArindam Nath mmc->caps |= MMC_CAP_DRIVER_TYPE_A; 2166d6d50a15SArindam Nath if (caps[1] & SDHCI_DRIVER_TYPE_C) 2167d6d50a15SArindam Nath mmc->caps |= MMC_CAP_DRIVER_TYPE_C; 2168d6d50a15SArindam Nath if (caps[1] & SDHCI_DRIVER_TYPE_D) 2169d6d50a15SArindam Nath mmc->caps |= MMC_CAP_DRIVER_TYPE_D; 2170d6d50a15SArindam Nath 21718f230f45STakashi Iwai ocr_avail = 0; 2172f2119df6SArindam Nath /* 2173f2119df6SArindam Nath * According to SD Host Controller spec v3.00, if the Host System 2174f2119df6SArindam Nath * can afford more than 150mA, Host Driver should set XPC to 1. Also 2175f2119df6SArindam Nath * the value is meaningful only if Voltage Support in the Capabilities 2176f2119df6SArindam Nath * register is set. The actual current value is 4 times the register 2177f2119df6SArindam Nath * value. 2178f2119df6SArindam Nath */ 2179f2119df6SArindam Nath max_current_caps = sdhci_readl(host, SDHCI_MAX_CURRENT); 2180f2119df6SArindam Nath 2181f2119df6SArindam Nath if (caps[0] & SDHCI_CAN_VDD_330) { 2182f2119df6SArindam Nath int max_current_330; 2183f2119df6SArindam Nath 21848f230f45STakashi Iwai ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34; 2185f2119df6SArindam Nath 2186f2119df6SArindam Nath max_current_330 = ((max_current_caps & 2187f2119df6SArindam Nath SDHCI_MAX_CURRENT_330_MASK) >> 2188f2119df6SArindam Nath SDHCI_MAX_CURRENT_330_SHIFT) * 2189f2119df6SArindam Nath SDHCI_MAX_CURRENT_MULTIPLIER; 2190f2119df6SArindam Nath 2191f2119df6SArindam Nath if (max_current_330 > 150) 2192f2119df6SArindam Nath mmc->caps |= MMC_CAP_SET_XPC_330; 2193f2119df6SArindam Nath } 2194f2119df6SArindam Nath if (caps[0] & SDHCI_CAN_VDD_300) { 2195f2119df6SArindam Nath int max_current_300; 2196f2119df6SArindam Nath 21978f230f45STakashi Iwai ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31; 2198f2119df6SArindam Nath 2199f2119df6SArindam Nath max_current_300 = ((max_current_caps & 2200f2119df6SArindam Nath SDHCI_MAX_CURRENT_300_MASK) >> 2201f2119df6SArindam Nath SDHCI_MAX_CURRENT_300_SHIFT) * 2202f2119df6SArindam Nath SDHCI_MAX_CURRENT_MULTIPLIER; 2203f2119df6SArindam Nath 2204f2119df6SArindam Nath if (max_current_300 > 150) 2205f2119df6SArindam Nath mmc->caps |= MMC_CAP_SET_XPC_300; 2206f2119df6SArindam Nath } 2207f2119df6SArindam Nath if (caps[0] & SDHCI_CAN_VDD_180) { 2208f2119df6SArindam Nath int max_current_180; 2209f2119df6SArindam Nath 22108f230f45STakashi Iwai ocr_avail |= MMC_VDD_165_195; 22118f230f45STakashi Iwai 2212f2119df6SArindam Nath max_current_180 = ((max_current_caps & 2213f2119df6SArindam Nath SDHCI_MAX_CURRENT_180_MASK) >> 2214f2119df6SArindam Nath SDHCI_MAX_CURRENT_180_SHIFT) * 2215f2119df6SArindam Nath SDHCI_MAX_CURRENT_MULTIPLIER; 2216f2119df6SArindam Nath 2217f2119df6SArindam Nath if (max_current_180 > 150) 2218f2119df6SArindam Nath mmc->caps |= MMC_CAP_SET_XPC_180; 2219f2119df6SArindam Nath } 2220f2119df6SArindam Nath 22218f230f45STakashi Iwai mmc->ocr_avail = ocr_avail; 22228f230f45STakashi Iwai mmc->ocr_avail_sdio = ocr_avail; 22238f230f45STakashi Iwai if (host->ocr_avail_sdio) 22248f230f45STakashi Iwai mmc->ocr_avail_sdio &= host->ocr_avail_sdio; 22258f230f45STakashi Iwai mmc->ocr_avail_sd = ocr_avail; 22268f230f45STakashi Iwai if (host->ocr_avail_sd) 22278f230f45STakashi Iwai mmc->ocr_avail_sd &= host->ocr_avail_sd; 22288f230f45STakashi Iwai else /* normal SD controllers don't support 1.8V */ 22298f230f45STakashi Iwai mmc->ocr_avail_sd &= ~MMC_VDD_165_195; 22308f230f45STakashi Iwai mmc->ocr_avail_mmc = ocr_avail; 22318f230f45STakashi Iwai if (host->ocr_avail_mmc) 22328f230f45STakashi Iwai mmc->ocr_avail_mmc &= host->ocr_avail_mmc; 22331c6a0718SPierre Ossman 22341c6a0718SPierre Ossman if (mmc->ocr_avail == 0) { 22351c6a0718SPierre Ossman printk(KERN_ERR "%s: Hardware doesn't report any " 2236b69c9058SPierre Ossman "support voltages.\n", mmc_hostname(mmc)); 2237b8c86fc5SPierre Ossman return -ENODEV; 22381c6a0718SPierre Ossman } 22391c6a0718SPierre Ossman 22401c6a0718SPierre Ossman spin_lock_init(&host->lock); 22411c6a0718SPierre Ossman 22421c6a0718SPierre Ossman /* 22432134a922SPierre Ossman * Maximum number of segments. Depends on if the hardware 22442134a922SPierre Ossman * can do scatter/gather or not. 22451c6a0718SPierre Ossman */ 22462134a922SPierre Ossman if (host->flags & SDHCI_USE_ADMA) 2247a36274e0SMartin K. Petersen mmc->max_segs = 128; 2248a13abc7bSRichard Röjfors else if (host->flags & SDHCI_USE_SDMA) 2249a36274e0SMartin K. Petersen mmc->max_segs = 1; 22502134a922SPierre Ossman else /* PIO */ 2251a36274e0SMartin K. Petersen mmc->max_segs = 128; 22521c6a0718SPierre Ossman 22531c6a0718SPierre Ossman /* 22541c6a0718SPierre Ossman * Maximum number of sectors in one transfer. Limited by DMA boundary 22551c6a0718SPierre Ossman * size (512KiB). 22561c6a0718SPierre Ossman */ 22571c6a0718SPierre Ossman mmc->max_req_size = 524288; 22581c6a0718SPierre Ossman 22591c6a0718SPierre Ossman /* 22601c6a0718SPierre Ossman * Maximum segment size. Could be one segment with the maximum number 22612134a922SPierre Ossman * of bytes. When doing hardware scatter/gather, each entry cannot 22622134a922SPierre Ossman * be larger than 64 KiB though. 22631c6a0718SPierre Ossman */ 226430652aa3SOlof Johansson if (host->flags & SDHCI_USE_ADMA) { 226530652aa3SOlof Johansson if (host->quirks & SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC) 226630652aa3SOlof Johansson mmc->max_seg_size = 65535; 22672134a922SPierre Ossman else 226830652aa3SOlof Johansson mmc->max_seg_size = 65536; 226930652aa3SOlof Johansson } else { 22701c6a0718SPierre Ossman mmc->max_seg_size = mmc->max_req_size; 227130652aa3SOlof Johansson } 22721c6a0718SPierre Ossman 22731c6a0718SPierre Ossman /* 22741c6a0718SPierre Ossman * Maximum block size. This varies from controller to controller and 22751c6a0718SPierre Ossman * is specified in the capabilities register. 22761c6a0718SPierre Ossman */ 22770633f654SAnton Vorontsov if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) { 22780633f654SAnton Vorontsov mmc->max_blk_size = 2; 22790633f654SAnton Vorontsov } else { 2280f2119df6SArindam Nath mmc->max_blk_size = (caps[0] & SDHCI_MAX_BLOCK_MASK) >> 22810633f654SAnton Vorontsov SDHCI_MAX_BLOCK_SHIFT; 22821c6a0718SPierre Ossman if (mmc->max_blk_size >= 3) { 2283b69c9058SPierre Ossman printk(KERN_WARNING "%s: Invalid maximum block size, " 2284b69c9058SPierre Ossman "assuming 512 bytes\n", mmc_hostname(mmc)); 22850633f654SAnton Vorontsov mmc->max_blk_size = 0; 22860633f654SAnton Vorontsov } 22870633f654SAnton Vorontsov } 22880633f654SAnton Vorontsov 22891c6a0718SPierre Ossman mmc->max_blk_size = 512 << mmc->max_blk_size; 22901c6a0718SPierre Ossman 22911c6a0718SPierre Ossman /* 22921c6a0718SPierre Ossman * Maximum block count. 22931c6a0718SPierre Ossman */ 22941388eefdSBen Dooks mmc->max_blk_count = (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535; 22951c6a0718SPierre Ossman 22961c6a0718SPierre Ossman /* 22971c6a0718SPierre Ossman * Init tasklets. 22981c6a0718SPierre Ossman */ 22991c6a0718SPierre Ossman tasklet_init(&host->card_tasklet, 23001c6a0718SPierre Ossman sdhci_tasklet_card, (unsigned long)host); 23011c6a0718SPierre Ossman tasklet_init(&host->finish_tasklet, 23021c6a0718SPierre Ossman sdhci_tasklet_finish, (unsigned long)host); 23031c6a0718SPierre Ossman 23041c6a0718SPierre Ossman setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); 23051c6a0718SPierre Ossman 23061c6a0718SPierre Ossman ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED, 2307b69c9058SPierre Ossman mmc_hostname(mmc), host); 23081c6a0718SPierre Ossman if (ret) 23091c6a0718SPierre Ossman goto untasklet; 23101c6a0718SPierre Ossman 23119bea3c85SMarek Szyprowski host->vmmc = regulator_get(mmc_dev(mmc), "vmmc"); 23129bea3c85SMarek Szyprowski if (IS_ERR(host->vmmc)) { 23139bea3c85SMarek Szyprowski printk(KERN_INFO "%s: no vmmc regulator found\n", mmc_hostname(mmc)); 23149bea3c85SMarek Szyprowski host->vmmc = NULL; 23159bea3c85SMarek Szyprowski } else { 23169bea3c85SMarek Szyprowski regulator_enable(host->vmmc); 23179bea3c85SMarek Szyprowski } 23189bea3c85SMarek Szyprowski 23192f4cbb3dSNicolas Pitre sdhci_init(host, 0); 23201c6a0718SPierre Ossman 23211c6a0718SPierre Ossman #ifdef CONFIG_MMC_DEBUG 23221c6a0718SPierre Ossman sdhci_dumpregs(host); 23231c6a0718SPierre Ossman #endif 23241c6a0718SPierre Ossman 2325f9134319SPierre Ossman #ifdef SDHCI_USE_LEDS_CLASS 23265dbace0cSHelmut Schaa snprintf(host->led_name, sizeof(host->led_name), 23275dbace0cSHelmut Schaa "%s::", mmc_hostname(mmc)); 23285dbace0cSHelmut Schaa host->led.name = host->led_name; 23292f730fecSPierre Ossman host->led.brightness = LED_OFF; 23302f730fecSPierre Ossman host->led.default_trigger = mmc_hostname(mmc); 23312f730fecSPierre Ossman host->led.brightness_set = sdhci_led_control; 23322f730fecSPierre Ossman 2333b8c86fc5SPierre Ossman ret = led_classdev_register(mmc_dev(mmc), &host->led); 23342f730fecSPierre Ossman if (ret) 23352f730fecSPierre Ossman goto reset; 23362f730fecSPierre Ossman #endif 23372f730fecSPierre Ossman 23381c6a0718SPierre Ossman mmiowb(); 23391c6a0718SPierre Ossman 23401c6a0718SPierre Ossman mmc_add_host(mmc); 23411c6a0718SPierre Ossman 2342a13abc7bSRichard Röjfors printk(KERN_INFO "%s: SDHCI controller on %s [%s] using %s\n", 2343d1b26863SKay Sievers mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), 2344a13abc7bSRichard Röjfors (host->flags & SDHCI_USE_ADMA) ? "ADMA" : 2345a13abc7bSRichard Röjfors (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO"); 23461c6a0718SPierre Ossman 23477260cf5eSAnton Vorontsov sdhci_enable_card_detection(host); 23487260cf5eSAnton Vorontsov 23491c6a0718SPierre Ossman return 0; 23501c6a0718SPierre Ossman 2351f9134319SPierre Ossman #ifdef SDHCI_USE_LEDS_CLASS 23522f730fecSPierre Ossman reset: 23532f730fecSPierre Ossman sdhci_reset(host, SDHCI_RESET_ALL); 23542f730fecSPierre Ossman free_irq(host->irq, host); 23552f730fecSPierre Ossman #endif 23561c6a0718SPierre Ossman untasklet: 23571c6a0718SPierre Ossman tasklet_kill(&host->card_tasklet); 23581c6a0718SPierre Ossman tasklet_kill(&host->finish_tasklet); 23591c6a0718SPierre Ossman 23601c6a0718SPierre Ossman return ret; 23611c6a0718SPierre Ossman } 23621c6a0718SPierre Ossman 2363b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_add_host); 2364b8c86fc5SPierre Ossman 23651e72859eSPierre Ossman void sdhci_remove_host(struct sdhci_host *host, int dead) 23661c6a0718SPierre Ossman { 23671e72859eSPierre Ossman unsigned long flags; 23681e72859eSPierre Ossman 23691e72859eSPierre Ossman if (dead) { 23701e72859eSPierre Ossman spin_lock_irqsave(&host->lock, flags); 23711e72859eSPierre Ossman 23721e72859eSPierre Ossman host->flags |= SDHCI_DEVICE_DEAD; 23731e72859eSPierre Ossman 23741e72859eSPierre Ossman if (host->mrq) { 23751e72859eSPierre Ossman printk(KERN_ERR "%s: Controller removed during " 23761e72859eSPierre Ossman " transfer!\n", mmc_hostname(host->mmc)); 23771e72859eSPierre Ossman 23781e72859eSPierre Ossman host->mrq->cmd->error = -ENOMEDIUM; 23791e72859eSPierre Ossman tasklet_schedule(&host->finish_tasklet); 23801e72859eSPierre Ossman } 23811e72859eSPierre Ossman 23821e72859eSPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 23831e72859eSPierre Ossman } 23841e72859eSPierre Ossman 23857260cf5eSAnton Vorontsov sdhci_disable_card_detection(host); 23867260cf5eSAnton Vorontsov 2387b8c86fc5SPierre Ossman mmc_remove_host(host->mmc); 23881c6a0718SPierre Ossman 2389f9134319SPierre Ossman #ifdef SDHCI_USE_LEDS_CLASS 23902f730fecSPierre Ossman led_classdev_unregister(&host->led); 23912f730fecSPierre Ossman #endif 23922f730fecSPierre Ossman 23931e72859eSPierre Ossman if (!dead) 23941c6a0718SPierre Ossman sdhci_reset(host, SDHCI_RESET_ALL); 23951c6a0718SPierre Ossman 23961c6a0718SPierre Ossman free_irq(host->irq, host); 23971c6a0718SPierre Ossman 23981c6a0718SPierre Ossman del_timer_sync(&host->timer); 23991c6a0718SPierre Ossman 24001c6a0718SPierre Ossman tasklet_kill(&host->card_tasklet); 24011c6a0718SPierre Ossman tasklet_kill(&host->finish_tasklet); 24022134a922SPierre Ossman 24039bea3c85SMarek Szyprowski if (host->vmmc) { 24049bea3c85SMarek Szyprowski regulator_disable(host->vmmc); 24059bea3c85SMarek Szyprowski regulator_put(host->vmmc); 24069bea3c85SMarek Szyprowski } 24079bea3c85SMarek Szyprowski 24082134a922SPierre Ossman kfree(host->adma_desc); 24092134a922SPierre Ossman kfree(host->align_buffer); 24102134a922SPierre Ossman 24112134a922SPierre Ossman host->adma_desc = NULL; 24122134a922SPierre Ossman host->align_buffer = NULL; 24131c6a0718SPierre Ossman } 24141c6a0718SPierre Ossman 2415b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_remove_host); 2416b8c86fc5SPierre Ossman 2417b8c86fc5SPierre Ossman void sdhci_free_host(struct sdhci_host *host) 24181c6a0718SPierre Ossman { 2419b8c86fc5SPierre Ossman mmc_free_host(host->mmc); 24201c6a0718SPierre Ossman } 24211c6a0718SPierre Ossman 2422b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_free_host); 24231c6a0718SPierre Ossman 24241c6a0718SPierre Ossman /*****************************************************************************\ 24251c6a0718SPierre Ossman * * 24261c6a0718SPierre Ossman * Driver init/exit * 24271c6a0718SPierre Ossman * * 24281c6a0718SPierre Ossman \*****************************************************************************/ 24291c6a0718SPierre Ossman 24301c6a0718SPierre Ossman static int __init sdhci_drv_init(void) 24311c6a0718SPierre Ossman { 24321c6a0718SPierre Ossman printk(KERN_INFO DRIVER_NAME 24331c6a0718SPierre Ossman ": Secure Digital Host Controller Interface driver\n"); 24341c6a0718SPierre Ossman printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); 24351c6a0718SPierre Ossman 2436b8c86fc5SPierre Ossman return 0; 24371c6a0718SPierre Ossman } 24381c6a0718SPierre Ossman 24391c6a0718SPierre Ossman static void __exit sdhci_drv_exit(void) 24401c6a0718SPierre Ossman { 24411c6a0718SPierre Ossman } 24421c6a0718SPierre Ossman 24431c6a0718SPierre Ossman module_init(sdhci_drv_init); 24441c6a0718SPierre Ossman module_exit(sdhci_drv_exit); 24451c6a0718SPierre Ossman 24461c6a0718SPierre Ossman module_param(debug_quirks, uint, 0444); 24471c6a0718SPierre Ossman 244832710e8fSPierre Ossman MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>"); 2449b8c86fc5SPierre Ossman MODULE_DESCRIPTION("Secure Digital Host Controller Interface core driver"); 24501c6a0718SPierre Ossman MODULE_LICENSE("GPL"); 24511c6a0718SPierre Ossman 24521c6a0718SPierre Ossman MODULE_PARM_DESC(debug_quirks, "Force certain quirks."); 2453