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> 1988b47679SPaul Gortmaker #include <linux/module.h> 201c6a0718SPierre Ossman #include <linux/dma-mapping.h> 215a0e3ad6STejun Heo #include <linux/slab.h> 2211763609SRalf Baechle #include <linux/scatterlist.h> 239bea3c85SMarek Szyprowski #include <linux/regulator/consumer.h> 2466fd8ad5SAdrian Hunter #include <linux/pm_runtime.h> 251c6a0718SPierre Ossman 262f730fecSPierre Ossman #include <linux/leds.h> 272f730fecSPierre Ossman 2822113efdSAries Lee #include <linux/mmc/mmc.h> 291c6a0718SPierre Ossman #include <linux/mmc/host.h> 30473b095aSAaron Lu #include <linux/mmc/card.h> 3185cc1c33SCorneliu Doban #include <linux/mmc/sdio.h> 32bec9d4e5SGuennadi Liakhovetski #include <linux/mmc/slot-gpio.h> 331c6a0718SPierre Ossman 341c6a0718SPierre Ossman #include "sdhci.h" 351c6a0718SPierre Ossman 361c6a0718SPierre Ossman #define DRIVER_NAME "sdhci" 371c6a0718SPierre Ossman 381c6a0718SPierre Ossman #define DBG(f, x...) \ 391c6a0718SPierre Ossman pr_debug(DRIVER_NAME " [%s()]: " f, __func__,## x) 401c6a0718SPierre Ossman 41b513ea25SArindam Nath #define MAX_TUNING_LOOP 40 42b513ea25SArindam Nath 431c6a0718SPierre Ossman static unsigned int debug_quirks = 0; 4466fd8ad5SAdrian Hunter static unsigned int debug_quirks2; 451c6a0718SPierre Ossman 461c6a0718SPierre Ossman static void sdhci_finish_data(struct sdhci_host *); 471c6a0718SPierre Ossman 4852983382SKevin Liu static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable); 491c6a0718SPierre Ossman 501c6a0718SPierre Ossman static void sdhci_dumpregs(struct sdhci_host *host) 511c6a0718SPierre Ossman { 52a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": =========== REGISTER DUMP (%s)===========\n", 53412ab659SPhilip Rakity mmc_hostname(host->mmc)); 541c6a0718SPierre Ossman 55a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n", 564e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_DMA_ADDRESS), 574e4141a5SAnton Vorontsov sdhci_readw(host, SDHCI_HOST_VERSION)); 58a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n", 594e4141a5SAnton Vorontsov sdhci_readw(host, SDHCI_BLOCK_SIZE), 604e4141a5SAnton Vorontsov sdhci_readw(host, SDHCI_BLOCK_COUNT)); 61a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n", 624e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_ARGUMENT), 634e4141a5SAnton Vorontsov sdhci_readw(host, SDHCI_TRANSFER_MODE)); 64a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n", 654e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_PRESENT_STATE), 664e4141a5SAnton Vorontsov sdhci_readb(host, SDHCI_HOST_CONTROL)); 67a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n", 684e4141a5SAnton Vorontsov sdhci_readb(host, SDHCI_POWER_CONTROL), 694e4141a5SAnton Vorontsov sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL)); 70a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n", 714e4141a5SAnton Vorontsov sdhci_readb(host, SDHCI_WAKE_UP_CONTROL), 724e4141a5SAnton Vorontsov sdhci_readw(host, SDHCI_CLOCK_CONTROL)); 73a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n", 744e4141a5SAnton Vorontsov sdhci_readb(host, SDHCI_TIMEOUT_CONTROL), 754e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_INT_STATUS)); 76a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n", 774e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_INT_ENABLE), 784e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_SIGNAL_ENABLE)); 79a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n", 804e4141a5SAnton Vorontsov sdhci_readw(host, SDHCI_ACMD12_ERR), 814e4141a5SAnton Vorontsov sdhci_readw(host, SDHCI_SLOT_INT_STATUS)); 82a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": Caps: 0x%08x | Caps_1: 0x%08x\n", 834e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_CAPABILITIES), 84e8120ad1SPhilip Rakity sdhci_readl(host, SDHCI_CAPABILITIES_1)); 85a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": Cmd: 0x%08x | Max curr: 0x%08x\n", 86e8120ad1SPhilip Rakity sdhci_readw(host, SDHCI_COMMAND), 874e4141a5SAnton Vorontsov sdhci_readl(host, SDHCI_MAX_CURRENT)); 88a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": Host ctl2: 0x%08x\n", 89f2119df6SArindam Nath sdhci_readw(host, SDHCI_HOST_CONTROL2)); 901c6a0718SPierre Ossman 91e57a5f61SAdrian Hunter if (host->flags & SDHCI_USE_ADMA) { 92e57a5f61SAdrian Hunter if (host->flags & SDHCI_USE_64_BIT_DMA) 93a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x%08x\n", 94e57a5f61SAdrian Hunter readl(host->ioaddr + SDHCI_ADMA_ERROR), 95e57a5f61SAdrian Hunter readl(host->ioaddr + SDHCI_ADMA_ADDRESS_HI), 96e57a5f61SAdrian Hunter readl(host->ioaddr + SDHCI_ADMA_ADDRESS)); 97e57a5f61SAdrian Hunter else 98a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n", 99be3f4ae0SBen Dooks readl(host->ioaddr + SDHCI_ADMA_ERROR), 100be3f4ae0SBen Dooks readl(host->ioaddr + SDHCI_ADMA_ADDRESS)); 101e57a5f61SAdrian Hunter } 102be3f4ae0SBen Dooks 103a7c53671SChuanxiao Dong pr_err(DRIVER_NAME ": ===========================================\n"); 1041c6a0718SPierre Ossman } 1051c6a0718SPierre Ossman 1061c6a0718SPierre Ossman /*****************************************************************************\ 1071c6a0718SPierre Ossman * * 1081c6a0718SPierre Ossman * Low level functions * 1091c6a0718SPierre Ossman * * 1101c6a0718SPierre Ossman \*****************************************************************************/ 1111c6a0718SPierre Ossman 1127260cf5eSAnton Vorontsov static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) 1137260cf5eSAnton Vorontsov { 1145b4f1f6cSRussell King u32 present; 1157260cf5eSAnton Vorontsov 116c79396c1SAdrian Hunter if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) || 117860951c5SJaehoon Chung !mmc_card_is_removable(host->mmc)) 11866fd8ad5SAdrian Hunter return; 11966fd8ad5SAdrian Hunter 1205b4f1f6cSRussell King if (enable) { 121d25928d1SShawn Guo present = sdhci_readl(host, SDHCI_PRESENT_STATE) & 122d25928d1SShawn Guo SDHCI_CARD_PRESENT; 123d25928d1SShawn Guo 1245b4f1f6cSRussell King host->ier |= present ? SDHCI_INT_CARD_REMOVE : 1255b4f1f6cSRussell King SDHCI_INT_CARD_INSERT; 1265b4f1f6cSRussell King } else { 1275b4f1f6cSRussell King host->ier &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT); 1285b4f1f6cSRussell King } 129b537f94cSRussell King 130b537f94cSRussell King sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); 131b537f94cSRussell King sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); 1327260cf5eSAnton Vorontsov } 1337260cf5eSAnton Vorontsov 1347260cf5eSAnton Vorontsov static void sdhci_enable_card_detection(struct sdhci_host *host) 1357260cf5eSAnton Vorontsov { 1367260cf5eSAnton Vorontsov sdhci_set_card_detection(host, true); 1377260cf5eSAnton Vorontsov } 1387260cf5eSAnton Vorontsov 1397260cf5eSAnton Vorontsov static void sdhci_disable_card_detection(struct sdhci_host *host) 1407260cf5eSAnton Vorontsov { 1417260cf5eSAnton Vorontsov sdhci_set_card_detection(host, false); 1427260cf5eSAnton Vorontsov } 1437260cf5eSAnton Vorontsov 14402d0b685SUlf Hansson static void sdhci_runtime_pm_bus_on(struct sdhci_host *host) 14502d0b685SUlf Hansson { 14602d0b685SUlf Hansson if (host->bus_on) 14702d0b685SUlf Hansson return; 14802d0b685SUlf Hansson host->bus_on = true; 14902d0b685SUlf Hansson pm_runtime_get_noresume(host->mmc->parent); 15002d0b685SUlf Hansson } 15102d0b685SUlf Hansson 15202d0b685SUlf Hansson static void sdhci_runtime_pm_bus_off(struct sdhci_host *host) 15302d0b685SUlf Hansson { 15402d0b685SUlf Hansson if (!host->bus_on) 15502d0b685SUlf Hansson return; 15602d0b685SUlf Hansson host->bus_on = false; 15702d0b685SUlf Hansson pm_runtime_put_noidle(host->mmc->parent); 15802d0b685SUlf Hansson } 15902d0b685SUlf Hansson 16003231f9bSRussell King void sdhci_reset(struct sdhci_host *host, u8 mask) 1611c6a0718SPierre Ossman { 1621c6a0718SPierre Ossman unsigned long timeout; 163393c1a34SPhilip Rakity 1644e4141a5SAnton Vorontsov sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET); 1651c6a0718SPierre Ossman 166f0710a55SAdrian Hunter if (mask & SDHCI_RESET_ALL) { 1671c6a0718SPierre Ossman host->clock = 0; 168f0710a55SAdrian Hunter /* Reset-all turns off SD Bus Power */ 169f0710a55SAdrian Hunter if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) 170f0710a55SAdrian Hunter sdhci_runtime_pm_bus_off(host); 171f0710a55SAdrian Hunter } 1721c6a0718SPierre Ossman 1731c6a0718SPierre Ossman /* Wait max 100 ms */ 1741c6a0718SPierre Ossman timeout = 100; 1751c6a0718SPierre Ossman 1761c6a0718SPierre Ossman /* hw clears the bit when it's done */ 1774e4141a5SAnton Vorontsov while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) { 1781c6a0718SPierre Ossman if (timeout == 0) { 179a3c76eb9SGirish K S pr_err("%s: Reset 0x%x never completed.\n", 1801c6a0718SPierre Ossman mmc_hostname(host->mmc), (int)mask); 1811c6a0718SPierre Ossman sdhci_dumpregs(host); 1821c6a0718SPierre Ossman return; 1831c6a0718SPierre Ossman } 1841c6a0718SPierre Ossman timeout--; 1851c6a0718SPierre Ossman mdelay(1); 1861c6a0718SPierre Ossman } 18703231f9bSRussell King } 18803231f9bSRussell King EXPORT_SYMBOL_GPL(sdhci_reset); 189063a9dbbSAnton Vorontsov 19003231f9bSRussell King static void sdhci_do_reset(struct sdhci_host *host, u8 mask) 19103231f9bSRussell King { 19203231f9bSRussell King if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) { 193d3940f27SAdrian Hunter struct mmc_host *mmc = host->mmc; 194d3940f27SAdrian Hunter 195d3940f27SAdrian Hunter if (!mmc->ops->get_cd(mmc)) 19603231f9bSRussell King return; 19703231f9bSRussell King } 19803231f9bSRussell King 19903231f9bSRussell King host->ops->reset(host, mask); 200393c1a34SPhilip Rakity 201da91a8f9SRussell King if (mask & SDHCI_RESET_ALL) { 2023abc1e80SShaohui Xie if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { 203da91a8f9SRussell King if (host->ops->enable_dma) 2043abc1e80SShaohui Xie host->ops->enable_dma(host); 2053abc1e80SShaohui Xie } 206da91a8f9SRussell King 207da91a8f9SRussell King /* Resetting the controller clears many */ 208da91a8f9SRussell King host->preset_enabled = false; 209da91a8f9SRussell King } 2101c6a0718SPierre Ossman } 2111c6a0718SPierre Ossman 2122f4cbb3dSNicolas Pitre static void sdhci_init(struct sdhci_host *host, int soft) 2131c6a0718SPierre Ossman { 214d3940f27SAdrian Hunter struct mmc_host *mmc = host->mmc; 215d3940f27SAdrian Hunter 2162f4cbb3dSNicolas Pitre if (soft) 21703231f9bSRussell King sdhci_do_reset(host, SDHCI_RESET_CMD|SDHCI_RESET_DATA); 2182f4cbb3dSNicolas Pitre else 21903231f9bSRussell King sdhci_do_reset(host, SDHCI_RESET_ALL); 2201c6a0718SPierre Ossman 221b537f94cSRussell King host->ier = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT | 222b537f94cSRussell King SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | 223b537f94cSRussell King SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC | 224b537f94cSRussell King SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END | 225b537f94cSRussell King SDHCI_INT_RESPONSE; 226b537f94cSRussell King 227b537f94cSRussell King sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); 228b537f94cSRussell King sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); 2292f4cbb3dSNicolas Pitre 2302f4cbb3dSNicolas Pitre if (soft) { 2312f4cbb3dSNicolas Pitre /* force clock reconfiguration */ 2322f4cbb3dSNicolas Pitre host->clock = 0; 233d3940f27SAdrian Hunter mmc->ops->set_ios(mmc, &mmc->ios); 2342f4cbb3dSNicolas Pitre } 2357260cf5eSAnton Vorontsov } 2361c6a0718SPierre Ossman 2377260cf5eSAnton Vorontsov static void sdhci_reinit(struct sdhci_host *host) 2387260cf5eSAnton Vorontsov { 2392f4cbb3dSNicolas Pitre sdhci_init(host, 0); 2407260cf5eSAnton Vorontsov sdhci_enable_card_detection(host); 2411c6a0718SPierre Ossman } 2421c6a0718SPierre Ossman 243061d17a6SAdrian Hunter static void __sdhci_led_activate(struct sdhci_host *host) 2441c6a0718SPierre Ossman { 2451c6a0718SPierre Ossman u8 ctrl; 2461c6a0718SPierre Ossman 2474e4141a5SAnton Vorontsov ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 2481c6a0718SPierre Ossman ctrl |= SDHCI_CTRL_LED; 2494e4141a5SAnton Vorontsov sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 2501c6a0718SPierre Ossman } 2511c6a0718SPierre Ossman 252061d17a6SAdrian Hunter static void __sdhci_led_deactivate(struct sdhci_host *host) 2531c6a0718SPierre Ossman { 2541c6a0718SPierre Ossman u8 ctrl; 2551c6a0718SPierre Ossman 2564e4141a5SAnton Vorontsov ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 2571c6a0718SPierre Ossman ctrl &= ~SDHCI_CTRL_LED; 2584e4141a5SAnton Vorontsov sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 2591c6a0718SPierre Ossman } 2601c6a0718SPierre Ossman 2614f78230fSMasahiro Yamada #if IS_REACHABLE(CONFIG_LEDS_CLASS) 2622f730fecSPierre Ossman static void sdhci_led_control(struct led_classdev *led, 2632f730fecSPierre Ossman enum led_brightness brightness) 2642f730fecSPierre Ossman { 2652f730fecSPierre Ossman struct sdhci_host *host = container_of(led, struct sdhci_host, led); 2662f730fecSPierre Ossman unsigned long flags; 2672f730fecSPierre Ossman 2682f730fecSPierre Ossman spin_lock_irqsave(&host->lock, flags); 2692f730fecSPierre Ossman 27066fd8ad5SAdrian Hunter if (host->runtime_suspended) 27166fd8ad5SAdrian Hunter goto out; 27266fd8ad5SAdrian Hunter 2732f730fecSPierre Ossman if (brightness == LED_OFF) 274061d17a6SAdrian Hunter __sdhci_led_deactivate(host); 2752f730fecSPierre Ossman else 276061d17a6SAdrian Hunter __sdhci_led_activate(host); 27766fd8ad5SAdrian Hunter out: 2782f730fecSPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 2792f730fecSPierre Ossman } 280061d17a6SAdrian Hunter 281061d17a6SAdrian Hunter static int sdhci_led_register(struct sdhci_host *host) 282061d17a6SAdrian Hunter { 283061d17a6SAdrian Hunter struct mmc_host *mmc = host->mmc; 284061d17a6SAdrian Hunter 285061d17a6SAdrian Hunter snprintf(host->led_name, sizeof(host->led_name), 286061d17a6SAdrian Hunter "%s::", mmc_hostname(mmc)); 287061d17a6SAdrian Hunter 288061d17a6SAdrian Hunter host->led.name = host->led_name; 289061d17a6SAdrian Hunter host->led.brightness = LED_OFF; 290061d17a6SAdrian Hunter host->led.default_trigger = mmc_hostname(mmc); 291061d17a6SAdrian Hunter host->led.brightness_set = sdhci_led_control; 292061d17a6SAdrian Hunter 293061d17a6SAdrian Hunter return led_classdev_register(mmc_dev(mmc), &host->led); 294061d17a6SAdrian Hunter } 295061d17a6SAdrian Hunter 296061d17a6SAdrian Hunter static void sdhci_led_unregister(struct sdhci_host *host) 297061d17a6SAdrian Hunter { 298061d17a6SAdrian Hunter led_classdev_unregister(&host->led); 299061d17a6SAdrian Hunter } 300061d17a6SAdrian Hunter 301061d17a6SAdrian Hunter static inline void sdhci_led_activate(struct sdhci_host *host) 302061d17a6SAdrian Hunter { 303061d17a6SAdrian Hunter } 304061d17a6SAdrian Hunter 305061d17a6SAdrian Hunter static inline void sdhci_led_deactivate(struct sdhci_host *host) 306061d17a6SAdrian Hunter { 307061d17a6SAdrian Hunter } 308061d17a6SAdrian Hunter 309061d17a6SAdrian Hunter #else 310061d17a6SAdrian Hunter 311061d17a6SAdrian Hunter static inline int sdhci_led_register(struct sdhci_host *host) 312061d17a6SAdrian Hunter { 313061d17a6SAdrian Hunter return 0; 314061d17a6SAdrian Hunter } 315061d17a6SAdrian Hunter 316061d17a6SAdrian Hunter static inline void sdhci_led_unregister(struct sdhci_host *host) 317061d17a6SAdrian Hunter { 318061d17a6SAdrian Hunter } 319061d17a6SAdrian Hunter 320061d17a6SAdrian Hunter static inline void sdhci_led_activate(struct sdhci_host *host) 321061d17a6SAdrian Hunter { 322061d17a6SAdrian Hunter __sdhci_led_activate(host); 323061d17a6SAdrian Hunter } 324061d17a6SAdrian Hunter 325061d17a6SAdrian Hunter static inline void sdhci_led_deactivate(struct sdhci_host *host) 326061d17a6SAdrian Hunter { 327061d17a6SAdrian Hunter __sdhci_led_deactivate(host); 328061d17a6SAdrian Hunter } 329061d17a6SAdrian Hunter 3302f730fecSPierre Ossman #endif 3312f730fecSPierre Ossman 3321c6a0718SPierre Ossman /*****************************************************************************\ 3331c6a0718SPierre Ossman * * 3341c6a0718SPierre Ossman * Core functions * 3351c6a0718SPierre Ossman * * 3361c6a0718SPierre Ossman \*****************************************************************************/ 3371c6a0718SPierre Ossman 3381c6a0718SPierre Ossman static void sdhci_read_block_pio(struct sdhci_host *host) 3391c6a0718SPierre Ossman { 3407659150cSPierre Ossman unsigned long flags; 3417659150cSPierre Ossman size_t blksize, len, chunk; 3427244b85bSSteven Noonan u32 uninitialized_var(scratch); 3437659150cSPierre Ossman u8 *buf; 3441c6a0718SPierre Ossman 3451c6a0718SPierre Ossman DBG("PIO reading\n"); 3461c6a0718SPierre Ossman 3471c6a0718SPierre Ossman blksize = host->data->blksz; 3487659150cSPierre Ossman chunk = 0; 3491c6a0718SPierre Ossman 3507659150cSPierre Ossman local_irq_save(flags); 3511c6a0718SPierre Ossman 3521c6a0718SPierre Ossman while (blksize) { 353bf3a35acSFabio Estevam BUG_ON(!sg_miter_next(&host->sg_miter)); 3547659150cSPierre Ossman 3557659150cSPierre Ossman len = min(host->sg_miter.length, blksize); 3567659150cSPierre Ossman 3577659150cSPierre Ossman blksize -= len; 3587659150cSPierre Ossman host->sg_miter.consumed = len; 3597659150cSPierre Ossman 3607659150cSPierre Ossman buf = host->sg_miter.addr; 3617659150cSPierre Ossman 3627659150cSPierre Ossman while (len) { 3637659150cSPierre Ossman if (chunk == 0) { 3644e4141a5SAnton Vorontsov scratch = sdhci_readl(host, SDHCI_BUFFER); 3657659150cSPierre Ossman chunk = 4; 3661c6a0718SPierre Ossman } 3671c6a0718SPierre Ossman 3687659150cSPierre Ossman *buf = scratch & 0xFF; 3691c6a0718SPierre Ossman 3707659150cSPierre Ossman buf++; 3717659150cSPierre Ossman scratch >>= 8; 3727659150cSPierre Ossman chunk--; 3737659150cSPierre Ossman len--; 3747659150cSPierre Ossman } 3751c6a0718SPierre Ossman } 3761c6a0718SPierre Ossman 3777659150cSPierre Ossman sg_miter_stop(&host->sg_miter); 3787659150cSPierre Ossman 3797659150cSPierre Ossman local_irq_restore(flags); 3801c6a0718SPierre Ossman } 3811c6a0718SPierre Ossman 3821c6a0718SPierre Ossman static void sdhci_write_block_pio(struct sdhci_host *host) 3831c6a0718SPierre Ossman { 3847659150cSPierre Ossman unsigned long flags; 3857659150cSPierre Ossman size_t blksize, len, chunk; 3867659150cSPierre Ossman u32 scratch; 3877659150cSPierre Ossman u8 *buf; 3881c6a0718SPierre Ossman 3891c6a0718SPierre Ossman DBG("PIO writing\n"); 3901c6a0718SPierre Ossman 3911c6a0718SPierre Ossman blksize = host->data->blksz; 3927659150cSPierre Ossman chunk = 0; 3937659150cSPierre Ossman scratch = 0; 3941c6a0718SPierre Ossman 3957659150cSPierre Ossman local_irq_save(flags); 3961c6a0718SPierre Ossman 3971c6a0718SPierre Ossman while (blksize) { 398bf3a35acSFabio Estevam BUG_ON(!sg_miter_next(&host->sg_miter)); 3991c6a0718SPierre Ossman 4007659150cSPierre Ossman len = min(host->sg_miter.length, blksize); 4011c6a0718SPierre Ossman 4027659150cSPierre Ossman blksize -= len; 4037659150cSPierre Ossman host->sg_miter.consumed = len; 4047659150cSPierre Ossman 4057659150cSPierre Ossman buf = host->sg_miter.addr; 4067659150cSPierre Ossman 4077659150cSPierre Ossman while (len) { 4087659150cSPierre Ossman scratch |= (u32)*buf << (chunk * 8); 4097659150cSPierre Ossman 4107659150cSPierre Ossman buf++; 4117659150cSPierre Ossman chunk++; 4127659150cSPierre Ossman len--; 4137659150cSPierre Ossman 4147659150cSPierre Ossman if ((chunk == 4) || ((len == 0) && (blksize == 0))) { 4154e4141a5SAnton Vorontsov sdhci_writel(host, scratch, SDHCI_BUFFER); 4167659150cSPierre Ossman chunk = 0; 4177659150cSPierre Ossman scratch = 0; 4187659150cSPierre Ossman } 4197659150cSPierre Ossman } 4201c6a0718SPierre Ossman } 4211c6a0718SPierre Ossman 4227659150cSPierre Ossman sg_miter_stop(&host->sg_miter); 4231c6a0718SPierre Ossman 4247659150cSPierre Ossman local_irq_restore(flags); 4251c6a0718SPierre Ossman } 4261c6a0718SPierre Ossman 4271c6a0718SPierre Ossman static void sdhci_transfer_pio(struct sdhci_host *host) 4281c6a0718SPierre Ossman { 4291c6a0718SPierre Ossman u32 mask; 4301c6a0718SPierre Ossman 4317659150cSPierre Ossman if (host->blocks == 0) 4321c6a0718SPierre Ossman return; 4331c6a0718SPierre Ossman 4341c6a0718SPierre Ossman if (host->data->flags & MMC_DATA_READ) 4351c6a0718SPierre Ossman mask = SDHCI_DATA_AVAILABLE; 4361c6a0718SPierre Ossman else 4371c6a0718SPierre Ossman mask = SDHCI_SPACE_AVAILABLE; 4381c6a0718SPierre Ossman 4394a3cba32SPierre Ossman /* 4404a3cba32SPierre Ossman * Some controllers (JMicron JMB38x) mess up the buffer bits 4414a3cba32SPierre Ossman * for transfers < 4 bytes. As long as it is just one block, 4424a3cba32SPierre Ossman * we can ignore the bits. 4434a3cba32SPierre Ossman */ 4444a3cba32SPierre Ossman if ((host->quirks & SDHCI_QUIRK_BROKEN_SMALL_PIO) && 4454a3cba32SPierre Ossman (host->data->blocks == 1)) 4464a3cba32SPierre Ossman mask = ~0; 4474a3cba32SPierre Ossman 4484e4141a5SAnton Vorontsov while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) { 4493e3bf207SAnton Vorontsov if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY) 4503e3bf207SAnton Vorontsov udelay(100); 4513e3bf207SAnton Vorontsov 4521c6a0718SPierre Ossman if (host->data->flags & MMC_DATA_READ) 4531c6a0718SPierre Ossman sdhci_read_block_pio(host); 4541c6a0718SPierre Ossman else 4551c6a0718SPierre Ossman sdhci_write_block_pio(host); 4561c6a0718SPierre Ossman 4577659150cSPierre Ossman host->blocks--; 4587659150cSPierre Ossman if (host->blocks == 0) 4591c6a0718SPierre Ossman break; 4601c6a0718SPierre Ossman } 4611c6a0718SPierre Ossman 4621c6a0718SPierre Ossman DBG("PIO transfer complete.\n"); 4631c6a0718SPierre Ossman } 4641c6a0718SPierre Ossman 46548857d9bSRussell King static int sdhci_pre_dma_transfer(struct sdhci_host *host, 466c0999b72SRussell King struct mmc_data *data, int cookie) 46748857d9bSRussell King { 46848857d9bSRussell King int sg_count; 46948857d9bSRussell King 47094538e51SRussell King /* 47194538e51SRussell King * If the data buffers are already mapped, return the previous 47294538e51SRussell King * dma_map_sg() result. 47394538e51SRussell King */ 47494538e51SRussell King if (data->host_cookie == COOKIE_PRE_MAPPED) 47548857d9bSRussell King return data->sg_count; 47648857d9bSRussell King 47748857d9bSRussell King sg_count = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, 47848857d9bSRussell King data->flags & MMC_DATA_WRITE ? 47948857d9bSRussell King DMA_TO_DEVICE : DMA_FROM_DEVICE); 48048857d9bSRussell King 48148857d9bSRussell King if (sg_count == 0) 48248857d9bSRussell King return -ENOSPC; 48348857d9bSRussell King 48448857d9bSRussell King data->sg_count = sg_count; 485c0999b72SRussell King data->host_cookie = cookie; 48648857d9bSRussell King 48748857d9bSRussell King return sg_count; 48848857d9bSRussell King } 48948857d9bSRussell King 4902134a922SPierre Ossman static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags) 4912134a922SPierre Ossman { 4922134a922SPierre Ossman local_irq_save(*flags); 493482fce99SCong Wang return kmap_atomic(sg_page(sg)) + sg->offset; 4942134a922SPierre Ossman } 4952134a922SPierre Ossman 4962134a922SPierre Ossman static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) 4972134a922SPierre Ossman { 498482fce99SCong Wang kunmap_atomic(buffer); 4992134a922SPierre Ossman local_irq_restore(*flags); 5002134a922SPierre Ossman } 5012134a922SPierre Ossman 502e57a5f61SAdrian Hunter static void sdhci_adma_write_desc(struct sdhci_host *host, void *desc, 503e57a5f61SAdrian Hunter dma_addr_t addr, int len, unsigned cmd) 504118cd17dSBen Dooks { 505e57a5f61SAdrian Hunter struct sdhci_adma2_64_desc *dma_desc = desc; 506118cd17dSBen Dooks 507e57a5f61SAdrian Hunter /* 32-bit and 64-bit descriptors have these members in same position */ 5080545230fSAdrian Hunter dma_desc->cmd = cpu_to_le16(cmd); 5090545230fSAdrian Hunter dma_desc->len = cpu_to_le16(len); 510e57a5f61SAdrian Hunter dma_desc->addr_lo = cpu_to_le32((u32)addr); 511e57a5f61SAdrian Hunter 512e57a5f61SAdrian Hunter if (host->flags & SDHCI_USE_64_BIT_DMA) 513e57a5f61SAdrian Hunter dma_desc->addr_hi = cpu_to_le32((u64)addr >> 32); 514118cd17dSBen Dooks } 515118cd17dSBen Dooks 516b5ffa674SAdrian Hunter static void sdhci_adma_mark_end(void *desc) 517b5ffa674SAdrian Hunter { 518e57a5f61SAdrian Hunter struct sdhci_adma2_64_desc *dma_desc = desc; 519b5ffa674SAdrian Hunter 520e57a5f61SAdrian Hunter /* 32-bit and 64-bit descriptors have 'cmd' in same position */ 5210545230fSAdrian Hunter dma_desc->cmd |= cpu_to_le16(ADMA2_END); 522b5ffa674SAdrian Hunter } 523b5ffa674SAdrian Hunter 52460c64762SRussell King static void sdhci_adma_table_pre(struct sdhci_host *host, 52560c64762SRussell King struct mmc_data *data, int sg_count) 5262134a922SPierre Ossman { 5272134a922SPierre Ossman struct scatterlist *sg; 5282134a922SPierre Ossman unsigned long flags; 529acc3ad13SRussell King dma_addr_t addr, align_addr; 530acc3ad13SRussell King void *desc, *align; 531acc3ad13SRussell King char *buffer; 532acc3ad13SRussell King int len, offset, i; 5332134a922SPierre Ossman 5342134a922SPierre Ossman /* 5352134a922SPierre Ossman * The spec does not specify endianness of descriptor table. 5362134a922SPierre Ossman * We currently guess that it is LE. 5372134a922SPierre Ossman */ 5382134a922SPierre Ossman 53960c64762SRussell King host->sg_count = sg_count; 5402134a922SPierre Ossman 5414efaa6fbSAdrian Hunter desc = host->adma_table; 5422134a922SPierre Ossman align = host->align_buffer; 5432134a922SPierre Ossman 5442134a922SPierre Ossman align_addr = host->align_addr; 5452134a922SPierre Ossman 5462134a922SPierre Ossman for_each_sg(data->sg, sg, host->sg_count, i) { 5472134a922SPierre Ossman addr = sg_dma_address(sg); 5482134a922SPierre Ossman len = sg_dma_len(sg); 5492134a922SPierre Ossman 5502134a922SPierre Ossman /* 551acc3ad13SRussell King * The SDHCI specification states that ADMA addresses must 552acc3ad13SRussell King * be 32-bit aligned. If they aren't, then we use a bounce 553acc3ad13SRussell King * buffer for the (up to three) bytes that screw up the 5542134a922SPierre Ossman * alignment. 5552134a922SPierre Ossman */ 55604a5ae6fSAdrian Hunter offset = (SDHCI_ADMA2_ALIGN - (addr & SDHCI_ADMA2_MASK)) & 55704a5ae6fSAdrian Hunter SDHCI_ADMA2_MASK; 5582134a922SPierre Ossman if (offset) { 5592134a922SPierre Ossman if (data->flags & MMC_DATA_WRITE) { 5602134a922SPierre Ossman buffer = sdhci_kmap_atomic(sg, &flags); 5612134a922SPierre Ossman memcpy(align, buffer, offset); 5622134a922SPierre Ossman sdhci_kunmap_atomic(buffer, &flags); 5632134a922SPierre Ossman } 5642134a922SPierre Ossman 565118cd17dSBen Dooks /* tran, valid */ 566e57a5f61SAdrian Hunter sdhci_adma_write_desc(host, desc, align_addr, offset, 567739d46dcSAdrian Hunter ADMA2_TRAN_VALID); 5682134a922SPierre Ossman 5692134a922SPierre Ossman BUG_ON(offset > 65536); 5702134a922SPierre Ossman 57104a5ae6fSAdrian Hunter align += SDHCI_ADMA2_ALIGN; 57204a5ae6fSAdrian Hunter align_addr += SDHCI_ADMA2_ALIGN; 5732134a922SPierre Ossman 57476fe379aSAdrian Hunter desc += host->desc_sz; 5752134a922SPierre Ossman 5762134a922SPierre Ossman addr += offset; 5772134a922SPierre Ossman len -= offset; 5782134a922SPierre Ossman } 5792134a922SPierre Ossman 5802134a922SPierre Ossman BUG_ON(len > 65536); 5812134a922SPierre Ossman 582347ea32dSAdrian Hunter if (len) { 583118cd17dSBen Dooks /* tran, valid */ 584347ea32dSAdrian Hunter sdhci_adma_write_desc(host, desc, addr, len, 585347ea32dSAdrian Hunter ADMA2_TRAN_VALID); 58676fe379aSAdrian Hunter desc += host->desc_sz; 587347ea32dSAdrian Hunter } 5882134a922SPierre Ossman 5892134a922SPierre Ossman /* 5902134a922SPierre Ossman * If this triggers then we have a calculation bug 5912134a922SPierre Ossman * somewhere. :/ 5922134a922SPierre Ossman */ 59376fe379aSAdrian Hunter WARN_ON((desc - host->adma_table) >= host->adma_table_sz); 5942134a922SPierre Ossman } 5952134a922SPierre Ossman 59670764a90SThomas Abraham if (host->quirks & SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC) { 597acc3ad13SRussell King /* Mark the last descriptor as the terminating descriptor */ 5984efaa6fbSAdrian Hunter if (desc != host->adma_table) { 59976fe379aSAdrian Hunter desc -= host->desc_sz; 600b5ffa674SAdrian Hunter sdhci_adma_mark_end(desc); 60170764a90SThomas Abraham } 60270764a90SThomas Abraham } else { 603acc3ad13SRussell King /* Add a terminating entry - nop, end, valid */ 604e57a5f61SAdrian Hunter sdhci_adma_write_desc(host, desc, 0, 0, ADMA2_NOP_END_VALID); 60570764a90SThomas Abraham } 6062134a922SPierre Ossman } 6072134a922SPierre Ossman 6082134a922SPierre Ossman static void sdhci_adma_table_post(struct sdhci_host *host, 6092134a922SPierre Ossman struct mmc_data *data) 6102134a922SPierre Ossman { 6112134a922SPierre Ossman struct scatterlist *sg; 6122134a922SPierre Ossman int i, size; 6131c3d5f6dSAdrian Hunter void *align; 6142134a922SPierre Ossman char *buffer; 6152134a922SPierre Ossman unsigned long flags; 6162134a922SPierre Ossman 61747fa9613SRussell King if (data->flags & MMC_DATA_READ) { 61847fa9613SRussell King bool has_unaligned = false; 61947fa9613SRussell King 620de0b65a7SRussell King /* Do a quick scan of the SG list for any unaligned mappings */ 621de0b65a7SRussell King for_each_sg(data->sg, sg, host->sg_count, i) 62204a5ae6fSAdrian Hunter if (sg_dma_address(sg) & SDHCI_ADMA2_MASK) { 623de0b65a7SRussell King has_unaligned = true; 624de0b65a7SRussell King break; 625de0b65a7SRussell King } 626de0b65a7SRussell King 62747fa9613SRussell King if (has_unaligned) { 6282134a922SPierre Ossman dma_sync_sg_for_cpu(mmc_dev(host->mmc), data->sg, 629f55c98f7SRussell King data->sg_len, DMA_FROM_DEVICE); 6302134a922SPierre Ossman 6312134a922SPierre Ossman align = host->align_buffer; 6322134a922SPierre Ossman 6332134a922SPierre Ossman for_each_sg(data->sg, sg, host->sg_count, i) { 63404a5ae6fSAdrian Hunter if (sg_dma_address(sg) & SDHCI_ADMA2_MASK) { 63504a5ae6fSAdrian Hunter size = SDHCI_ADMA2_ALIGN - 63604a5ae6fSAdrian Hunter (sg_dma_address(sg) & SDHCI_ADMA2_MASK); 6372134a922SPierre Ossman 6382134a922SPierre Ossman buffer = sdhci_kmap_atomic(sg, &flags); 6392134a922SPierre Ossman memcpy(buffer, align, size); 6402134a922SPierre Ossman sdhci_kunmap_atomic(buffer, &flags); 6412134a922SPierre Ossman 64204a5ae6fSAdrian Hunter align += SDHCI_ADMA2_ALIGN; 6432134a922SPierre Ossman } 6442134a922SPierre Ossman } 6452134a922SPierre Ossman } 64647fa9613SRussell King } 6472134a922SPierre Ossman } 6482134a922SPierre Ossman 649a3c7778fSAndrei Warkentin static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd) 6501c6a0718SPierre Ossman { 6511c6a0718SPierre Ossman u8 count; 652a3c7778fSAndrei Warkentin struct mmc_data *data = cmd->data; 6531c6a0718SPierre Ossman unsigned target_timeout, current_timeout; 6541c6a0718SPierre Ossman 655ee53ab5dSPierre Ossman /* 656ee53ab5dSPierre Ossman * If the host controller provides us with an incorrect timeout 657ee53ab5dSPierre Ossman * value, just skip the check and use 0xE. The hardware may take 658ee53ab5dSPierre Ossman * longer to time out, but that's much better than having a too-short 659ee53ab5dSPierre Ossman * timeout value. 660ee53ab5dSPierre Ossman */ 66111a2f1b7SPierre Ossman if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL) 662ee53ab5dSPierre Ossman return 0xE; 663e538fbe8SPierre Ossman 664a3c7778fSAndrei Warkentin /* Unspecified timeout, assume max */ 6651d4d7744SUlf Hansson if (!data && !cmd->busy_timeout) 666a3c7778fSAndrei Warkentin return 0xE; 667a3c7778fSAndrei Warkentin 6681c6a0718SPierre Ossman /* timeout in us */ 669a3c7778fSAndrei Warkentin if (!data) 6701d4d7744SUlf Hansson target_timeout = cmd->busy_timeout * 1000; 67178a2ca27SAndy Shevchenko else { 672fafcfda9SRussell King target_timeout = DIV_ROUND_UP(data->timeout_ns, 1000); 6737f05538aSRussell King if (host->clock && data->timeout_clks) { 6747f05538aSRussell King unsigned long long val; 6757f05538aSRussell King 6767f05538aSRussell King /* 6777f05538aSRussell King * data->timeout_clks is in units of clock cycles. 6787f05538aSRussell King * host->clock is in Hz. target_timeout is in us. 6797f05538aSRussell King * Hence, us = 1000000 * cycles / Hz. Round up. 6807f05538aSRussell King */ 6817f05538aSRussell King val = 1000000 * data->timeout_clks; 6827f05538aSRussell King if (do_div(val, host->clock)) 6837f05538aSRussell King target_timeout++; 6847f05538aSRussell King target_timeout += val; 6857f05538aSRussell King } 68678a2ca27SAndy Shevchenko } 6871c6a0718SPierre Ossman 6881c6a0718SPierre Ossman /* 6891c6a0718SPierre Ossman * Figure out needed cycles. 6901c6a0718SPierre Ossman * We do this in steps in order to fit inside a 32 bit int. 6911c6a0718SPierre Ossman * The first step is the minimum timeout, which will have a 6921c6a0718SPierre Ossman * minimum resolution of 6 bits: 6931c6a0718SPierre Ossman * (1) 2^13*1000 > 2^22, 6941c6a0718SPierre Ossman * (2) host->timeout_clk < 2^16 6951c6a0718SPierre Ossman * => 6961c6a0718SPierre Ossman * (1) / (2) > 2^6 6971c6a0718SPierre Ossman */ 6981c6a0718SPierre Ossman count = 0; 6991c6a0718SPierre Ossman current_timeout = (1 << 13) * 1000 / host->timeout_clk; 7001c6a0718SPierre Ossman while (current_timeout < target_timeout) { 7011c6a0718SPierre Ossman count++; 7021c6a0718SPierre Ossman current_timeout <<= 1; 7031c6a0718SPierre Ossman if (count >= 0xF) 7041c6a0718SPierre Ossman break; 7051c6a0718SPierre Ossman } 7061c6a0718SPierre Ossman 7071c6a0718SPierre Ossman if (count >= 0xF) { 70809eeff52SChris Ball DBG("%s: Too large timeout 0x%x requested for CMD%d!\n", 70902145977SMark Brown mmc_hostname(host->mmc), count, cmd->opcode); 7101c6a0718SPierre Ossman count = 0xE; 7111c6a0718SPierre Ossman } 7121c6a0718SPierre Ossman 713ee53ab5dSPierre Ossman return count; 714ee53ab5dSPierre Ossman } 715ee53ab5dSPierre Ossman 7166aa943abSAnton Vorontsov static void sdhci_set_transfer_irqs(struct sdhci_host *host) 7176aa943abSAnton Vorontsov { 7186aa943abSAnton Vorontsov u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL; 7196aa943abSAnton Vorontsov u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR; 7206aa943abSAnton Vorontsov 7216aa943abSAnton Vorontsov if (host->flags & SDHCI_REQ_USE_DMA) 722b537f94cSRussell King host->ier = (host->ier & ~pio_irqs) | dma_irqs; 7236aa943abSAnton Vorontsov else 724b537f94cSRussell King host->ier = (host->ier & ~dma_irqs) | pio_irqs; 725b537f94cSRussell King 726b537f94cSRussell King sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); 727b537f94cSRussell King sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); 7286aa943abSAnton Vorontsov } 7296aa943abSAnton Vorontsov 730b45e668aSAisheng Dong static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd) 731ee53ab5dSPierre Ossman { 732ee53ab5dSPierre Ossman u8 count; 733b45e668aSAisheng Dong 734b45e668aSAisheng Dong if (host->ops->set_timeout) { 735b45e668aSAisheng Dong host->ops->set_timeout(host, cmd); 736b45e668aSAisheng Dong } else { 737b45e668aSAisheng Dong count = sdhci_calc_timeout(host, cmd); 738b45e668aSAisheng Dong sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL); 739b45e668aSAisheng Dong } 740b45e668aSAisheng Dong } 741b45e668aSAisheng Dong 742b45e668aSAisheng Dong static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd) 743b45e668aSAisheng Dong { 7442134a922SPierre Ossman u8 ctrl; 745a3c7778fSAndrei Warkentin struct mmc_data *data = cmd->data; 746ee53ab5dSPierre Ossman 747b45e668aSAisheng Dong if (data || (cmd->flags & MMC_RSP_BUSY)) 748b45e668aSAisheng Dong sdhci_set_timeout(host, cmd); 749a3c7778fSAndrei Warkentin 750a3c7778fSAndrei Warkentin if (!data) 751ee53ab5dSPierre Ossman return; 752ee53ab5dSPierre Ossman 75343dea098SAdrian Hunter WARN_ON(host->data); 75443dea098SAdrian Hunter 755ee53ab5dSPierre Ossman /* Sanity checks */ 756ee53ab5dSPierre Ossman BUG_ON(data->blksz * data->blocks > 524288); 757ee53ab5dSPierre Ossman BUG_ON(data->blksz > host->mmc->max_blk_size); 758ee53ab5dSPierre Ossman BUG_ON(data->blocks > 65535); 759ee53ab5dSPierre Ossman 760ee53ab5dSPierre Ossman host->data = data; 761ee53ab5dSPierre Ossman host->data_early = 0; 762f6a03cbfSMikko Vinni host->data->bytes_xfered = 0; 763ee53ab5dSPierre Ossman 764fce14421SRussell King if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { 765fce14421SRussell King struct scatterlist *sg; 766fce14421SRussell King unsigned int length_mask, offset_mask; 767fce14421SRussell King int i; 768fce14421SRussell King 769c9fddbc4SPierre Ossman host->flags |= SDHCI_REQ_USE_DMA; 770c9fddbc4SPierre Ossman 7712134a922SPierre Ossman /* 7722134a922SPierre Ossman * FIXME: This doesn't account for merging when mapping the 7732134a922SPierre Ossman * scatterlist. 774df953925SRussell King * 775df953925SRussell King * The assumption here being that alignment and lengths are 776df953925SRussell King * the same after DMA mapping to device address space. 7772134a922SPierre Ossman */ 778a0eaf0f9SRussell King length_mask = 0; 779df953925SRussell King offset_mask = 0; 7802134a922SPierre Ossman if (host->flags & SDHCI_USE_ADMA) { 781df953925SRussell King if (host->quirks & SDHCI_QUIRK_32BIT_ADMA_SIZE) { 782a0eaf0f9SRussell King length_mask = 3; 783df953925SRussell King /* 784df953925SRussell King * As we use up to 3 byte chunks to work 785df953925SRussell King * around alignment problems, we need to 786df953925SRussell King * check the offset as well. 787df953925SRussell King */ 788df953925SRussell King offset_mask = 3; 789df953925SRussell King } 7902134a922SPierre Ossman } else { 7912134a922SPierre Ossman if (host->quirks & SDHCI_QUIRK_32BIT_DMA_SIZE) 792a0eaf0f9SRussell King length_mask = 3; 793df953925SRussell King if (host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) 794df953925SRussell King offset_mask = 3; 7952134a922SPierre Ossman } 7962134a922SPierre Ossman 797df953925SRussell King if (unlikely(length_mask | offset_mask)) { 7982134a922SPierre Ossman for_each_sg(data->sg, sg, data->sg_len, i) { 799a0eaf0f9SRussell King if (sg->length & length_mask) { 8002e4456f0SMarek Vasut DBG("Reverting to PIO because of transfer size (%d)\n", 8012134a922SPierre Ossman sg->length); 802c9fddbc4SPierre Ossman host->flags &= ~SDHCI_REQ_USE_DMA; 8032134a922SPierre Ossman break; 8042134a922SPierre Ossman } 805a0eaf0f9SRussell King if (sg->offset & offset_mask) { 8062e4456f0SMarek Vasut DBG("Reverting to PIO because of bad alignment\n"); 807c9fddbc4SPierre Ossman host->flags &= ~SDHCI_REQ_USE_DMA; 8082134a922SPierre Ossman break; 8092134a922SPierre Ossman } 8102134a922SPierre Ossman } 8112134a922SPierre Ossman } 8122134a922SPierre Ossman } 8132134a922SPierre Ossman 8148f1934ceSPierre Ossman if (host->flags & SDHCI_REQ_USE_DMA) { 815c0999b72SRussell King int sg_cnt = sdhci_pre_dma_transfer(host, data, COOKIE_MAPPED); 8168f1934ceSPierre Ossman 81762a7f368SJiri Slaby if (sg_cnt <= 0) { 8188f1934ceSPierre Ossman /* 8198f1934ceSPierre Ossman * This only happens when someone fed 8208f1934ceSPierre Ossman * us an invalid request. 8218f1934ceSPierre Ossman */ 8228f1934ceSPierre Ossman WARN_ON(1); 823ebd6d357SPierre Ossman host->flags &= ~SDHCI_REQ_USE_DMA; 82460c64762SRussell King } else if (host->flags & SDHCI_USE_ADMA) { 82560c64762SRussell King sdhci_adma_table_pre(host, data, sg_cnt); 82660c64762SRussell King 82760c64762SRussell King sdhci_writel(host, host->adma_addr, SDHCI_ADMA_ADDRESS); 82860c64762SRussell King if (host->flags & SDHCI_USE_64_BIT_DMA) 82960c64762SRussell King sdhci_writel(host, 83060c64762SRussell King (u64)host->adma_addr >> 32, 83160c64762SRussell King SDHCI_ADMA_ADDRESS_HI); 8328f1934ceSPierre Ossman } else { 833719a61b4SPierre Ossman WARN_ON(sg_cnt != 1); 8344e4141a5SAnton Vorontsov sdhci_writel(host, sg_dma_address(data->sg), 8354e4141a5SAnton Vorontsov SDHCI_DMA_ADDRESS); 8368f1934ceSPierre Ossman } 8378f1934ceSPierre Ossman } 8388f1934ceSPierre Ossman 8392134a922SPierre Ossman /* 8402134a922SPierre Ossman * Always adjust the DMA selection as some controllers 8412134a922SPierre Ossman * (e.g. JMicron) can't do PIO properly when the selection 8422134a922SPierre Ossman * is ADMA. 8432134a922SPierre Ossman */ 8442134a922SPierre Ossman if (host->version >= SDHCI_SPEC_200) { 8454e4141a5SAnton Vorontsov ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 8462134a922SPierre Ossman ctrl &= ~SDHCI_CTRL_DMA_MASK; 8472134a922SPierre Ossman if ((host->flags & SDHCI_REQ_USE_DMA) && 848e57a5f61SAdrian Hunter (host->flags & SDHCI_USE_ADMA)) { 849e57a5f61SAdrian Hunter if (host->flags & SDHCI_USE_64_BIT_DMA) 850e57a5f61SAdrian Hunter ctrl |= SDHCI_CTRL_ADMA64; 8512134a922SPierre Ossman else 852e57a5f61SAdrian Hunter ctrl |= SDHCI_CTRL_ADMA32; 853e57a5f61SAdrian Hunter } else { 8542134a922SPierre Ossman ctrl |= SDHCI_CTRL_SDMA; 855e57a5f61SAdrian Hunter } 8564e4141a5SAnton Vorontsov sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 857c9fddbc4SPierre Ossman } 858c9fddbc4SPierre Ossman 8598f1934ceSPierre Ossman if (!(host->flags & SDHCI_REQ_USE_DMA)) { 860da60a91dSSebastian Andrzej Siewior int flags; 861da60a91dSSebastian Andrzej Siewior 862da60a91dSSebastian Andrzej Siewior flags = SG_MITER_ATOMIC; 863da60a91dSSebastian Andrzej Siewior if (host->data->flags & MMC_DATA_READ) 864da60a91dSSebastian Andrzej Siewior flags |= SG_MITER_TO_SG; 865da60a91dSSebastian Andrzej Siewior else 866da60a91dSSebastian Andrzej Siewior flags |= SG_MITER_FROM_SG; 867da60a91dSSebastian Andrzej Siewior sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); 8687659150cSPierre Ossman host->blocks = data->blocks; 8691c6a0718SPierre Ossman } 8701c6a0718SPierre Ossman 8716aa943abSAnton Vorontsov sdhci_set_transfer_irqs(host); 8726aa943abSAnton Vorontsov 873f6a03cbfSMikko Vinni /* Set the DMA boundary value and block size */ 874f6a03cbfSMikko Vinni sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG, 875f6a03cbfSMikko Vinni data->blksz), SDHCI_BLOCK_SIZE); 8764e4141a5SAnton Vorontsov sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT); 8771c6a0718SPierre Ossman } 8781c6a0718SPierre Ossman 8791c6a0718SPierre Ossman static void sdhci_set_transfer_mode(struct sdhci_host *host, 880e89d456fSAndrei Warkentin struct mmc_command *cmd) 8811c6a0718SPierre Ossman { 882d3fc5d71SVincent Yang u16 mode = 0; 883e89d456fSAndrei Warkentin struct mmc_data *data = cmd->data; 8841c6a0718SPierre Ossman 8852b558c13SDong Aisheng if (data == NULL) { 8869b8ffea6SVincent Wan if (host->quirks2 & 8879b8ffea6SVincent Wan SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD) { 8889b8ffea6SVincent Wan sdhci_writew(host, 0x0, SDHCI_TRANSFER_MODE); 8899b8ffea6SVincent Wan } else { 8902b558c13SDong Aisheng /* clear Auto CMD settings for no data CMDs */ 8912b558c13SDong Aisheng mode = sdhci_readw(host, SDHCI_TRANSFER_MODE); 8922b558c13SDong Aisheng sdhci_writew(host, mode & ~(SDHCI_TRNS_AUTO_CMD12 | 8932b558c13SDong Aisheng SDHCI_TRNS_AUTO_CMD23), SDHCI_TRANSFER_MODE); 8949b8ffea6SVincent Wan } 8951c6a0718SPierre Ossman return; 8962b558c13SDong Aisheng } 8971c6a0718SPierre Ossman 898e538fbe8SPierre Ossman WARN_ON(!host->data); 899e538fbe8SPierre Ossman 900d3fc5d71SVincent Yang if (!(host->quirks2 & SDHCI_QUIRK2_SUPPORT_SINGLE)) 9011c6a0718SPierre Ossman mode = SDHCI_TRNS_BLK_CNT_EN; 902d3fc5d71SVincent Yang 903e89d456fSAndrei Warkentin if (mmc_op_multi(cmd->opcode) || data->blocks > 1) { 904d3fc5d71SVincent Yang mode = SDHCI_TRNS_BLK_CNT_EN | SDHCI_TRNS_MULTI; 905e89d456fSAndrei Warkentin /* 906e89d456fSAndrei Warkentin * If we are sending CMD23, CMD12 never gets sent 907e89d456fSAndrei Warkentin * on successful completion (so no Auto-CMD12). 908e89d456fSAndrei Warkentin */ 909a4c73abaSAdrian Hunter if (!cmd->mrq->sbc && (host->flags & SDHCI_AUTO_CMD12) && 91085cc1c33SCorneliu Doban (cmd->opcode != SD_IO_RW_EXTENDED)) 911e89d456fSAndrei Warkentin mode |= SDHCI_TRNS_AUTO_CMD12; 912a4c73abaSAdrian Hunter else if (cmd->mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) { 9138edf6371SAndrei Warkentin mode |= SDHCI_TRNS_AUTO_CMD23; 914a4c73abaSAdrian Hunter sdhci_writel(host, cmd->mrq->sbc->arg, SDHCI_ARGUMENT2); 915c4512f79SJerry Huang } 9168edf6371SAndrei Warkentin } 9178edf6371SAndrei Warkentin 9181c6a0718SPierre Ossman if (data->flags & MMC_DATA_READ) 9191c6a0718SPierre Ossman mode |= SDHCI_TRNS_READ; 920c9fddbc4SPierre Ossman if (host->flags & SDHCI_REQ_USE_DMA) 9211c6a0718SPierre Ossman mode |= SDHCI_TRNS_DMA; 9221c6a0718SPierre Ossman 9234e4141a5SAnton Vorontsov sdhci_writew(host, mode, SDHCI_TRANSFER_MODE); 9241c6a0718SPierre Ossman } 9251c6a0718SPierre Ossman 9260cc563ceSAdrian Hunter static bool sdhci_needs_reset(struct sdhci_host *host, struct mmc_request *mrq) 9270cc563ceSAdrian Hunter { 9280cc563ceSAdrian Hunter return (!(host->flags & SDHCI_DEVICE_DEAD) && 9290cc563ceSAdrian Hunter ((mrq->cmd && mrq->cmd->error) || 9300cc563ceSAdrian Hunter (mrq->sbc && mrq->sbc->error) || 9310cc563ceSAdrian Hunter (mrq->data && ((mrq->data->error && !mrq->data->stop) || 9320cc563ceSAdrian Hunter (mrq->data->stop && mrq->data->stop->error))) || 9330cc563ceSAdrian Hunter (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))); 9340cc563ceSAdrian Hunter } 9350cc563ceSAdrian Hunter 936a6d3bdd5SAdrian Hunter static void sdhci_finish_mrq(struct sdhci_host *host, struct mmc_request *mrq) 937a6d3bdd5SAdrian Hunter { 9385a8a3fefSAdrian Hunter if (host->cmd && host->cmd->mrq == mrq) 9395a8a3fefSAdrian Hunter host->cmd = NULL; 9405a8a3fefSAdrian Hunter 9415a8a3fefSAdrian Hunter if (host->data_cmd && host->data_cmd->mrq == mrq) 9425a8a3fefSAdrian Hunter host->data_cmd = NULL; 9435a8a3fefSAdrian Hunter 9445a8a3fefSAdrian Hunter if (host->data && host->data->mrq == mrq) 9455a8a3fefSAdrian Hunter host->data = NULL; 9465a8a3fefSAdrian Hunter 947ed1563deSAdrian Hunter if (sdhci_needs_reset(host, mrq)) 948ed1563deSAdrian Hunter host->pending_reset = true; 949ed1563deSAdrian Hunter 950a6d3bdd5SAdrian Hunter tasklet_schedule(&host->finish_tasklet); 951a6d3bdd5SAdrian Hunter } 952a6d3bdd5SAdrian Hunter 9531c6a0718SPierre Ossman static void sdhci_finish_data(struct sdhci_host *host) 9541c6a0718SPierre Ossman { 9551c6a0718SPierre Ossman struct mmc_data *data; 9561c6a0718SPierre Ossman 9571c6a0718SPierre Ossman data = host->data; 9581c6a0718SPierre Ossman host->data = NULL; 9597c89a3d9SAdrian Hunter host->data_cmd = NULL; 9601c6a0718SPierre Ossman 961add8913dSRussell King if ((host->flags & (SDHCI_REQ_USE_DMA | SDHCI_USE_ADMA)) == 962add8913dSRussell King (SDHCI_REQ_USE_DMA | SDHCI_USE_ADMA)) 9632134a922SPierre Ossman sdhci_adma_table_post(host, data); 964f55c98f7SRussell King 9651c6a0718SPierre Ossman /* 966c9b74c5bSPierre Ossman * The specification states that the block count register must 967c9b74c5bSPierre Ossman * be updated, but it does not specify at what point in the 968c9b74c5bSPierre Ossman * data flow. That makes the register entirely useless to read 969c9b74c5bSPierre Ossman * back so we have to assume that nothing made it to the card 970c9b74c5bSPierre Ossman * in the event of an error. 9711c6a0718SPierre Ossman */ 972c9b74c5bSPierre Ossman if (data->error) 973c9b74c5bSPierre Ossman data->bytes_xfered = 0; 9741c6a0718SPierre Ossman else 975c9b74c5bSPierre Ossman data->bytes_xfered = data->blksz * data->blocks; 9761c6a0718SPierre Ossman 977e89d456fSAndrei Warkentin /* 978e89d456fSAndrei Warkentin * Need to send CMD12 if - 979e89d456fSAndrei Warkentin * a) open-ended multiblock transfer (no CMD23) 980e89d456fSAndrei Warkentin * b) error in multiblock transfer 981e89d456fSAndrei Warkentin */ 982e89d456fSAndrei Warkentin if (data->stop && 983e89d456fSAndrei Warkentin (data->error || 984a4c73abaSAdrian Hunter !data->mrq->sbc)) { 985e89d456fSAndrei Warkentin 9861c6a0718SPierre Ossman /* 9871c6a0718SPierre Ossman * The controller needs a reset of internal state machines 9881c6a0718SPierre Ossman * upon error conditions. 9891c6a0718SPierre Ossman */ 99017b0429dSPierre Ossman if (data->error) { 99103231f9bSRussell King sdhci_do_reset(host, SDHCI_RESET_CMD); 99203231f9bSRussell King sdhci_do_reset(host, SDHCI_RESET_DATA); 9931c6a0718SPierre Ossman } 9941c6a0718SPierre Ossman 9951c6a0718SPierre Ossman sdhci_send_command(host, data->stop); 996a6d3bdd5SAdrian Hunter } else { 997a6d3bdd5SAdrian Hunter sdhci_finish_mrq(host, data->mrq); 998a6d3bdd5SAdrian Hunter } 9991c6a0718SPierre Ossman } 10001c6a0718SPierre Ossman 1001c0e55129SDong Aisheng void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) 10021c6a0718SPierre Ossman { 10031c6a0718SPierre Ossman int flags; 10041c6a0718SPierre Ossman u32 mask; 10051c6a0718SPierre Ossman unsigned long timeout; 10061c6a0718SPierre Ossman 10071c6a0718SPierre Ossman WARN_ON(host->cmd); 10081c6a0718SPierre Ossman 100996776200SRussell King /* Initially, a command has no error */ 101096776200SRussell King cmd->error = 0; 101196776200SRussell King 10121c6a0718SPierre Ossman /* Wait max 10 ms */ 10131c6a0718SPierre Ossman timeout = 10; 10141c6a0718SPierre Ossman 10151c6a0718SPierre Ossman mask = SDHCI_CMD_INHIBIT; 10161c6a0718SPierre Ossman if ((cmd->data != NULL) || (cmd->flags & MMC_RSP_BUSY)) 10171c6a0718SPierre Ossman mask |= SDHCI_DATA_INHIBIT; 10181c6a0718SPierre Ossman 10191c6a0718SPierre Ossman /* We shouldn't wait for data inihibit for stop commands, even 10201c6a0718SPierre Ossman though they might use busy signaling */ 1021a4c73abaSAdrian Hunter if (cmd->mrq->data && (cmd == cmd->mrq->data->stop)) 10221c6a0718SPierre Ossman mask &= ~SDHCI_DATA_INHIBIT; 10231c6a0718SPierre Ossman 10244e4141a5SAnton Vorontsov while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) { 10251c6a0718SPierre Ossman if (timeout == 0) { 10262e4456f0SMarek Vasut pr_err("%s: Controller never released inhibit bit(s).\n", 10272e4456f0SMarek Vasut mmc_hostname(host->mmc)); 10281c6a0718SPierre Ossman sdhci_dumpregs(host); 102917b0429dSPierre Ossman cmd->error = -EIO; 1030a6d3bdd5SAdrian Hunter sdhci_finish_mrq(host, cmd->mrq); 10311c6a0718SPierre Ossman return; 10321c6a0718SPierre Ossman } 10331c6a0718SPierre Ossman timeout--; 10341c6a0718SPierre Ossman mdelay(1); 10351c6a0718SPierre Ossman } 10361c6a0718SPierre Ossman 10373e1a6892SAdrian Hunter timeout = jiffies; 10381d4d7744SUlf Hansson if (!cmd->data && cmd->busy_timeout > 9000) 10391d4d7744SUlf Hansson timeout += DIV_ROUND_UP(cmd->busy_timeout, 1000) * HZ + HZ; 10403e1a6892SAdrian Hunter else 10413e1a6892SAdrian Hunter timeout += 10 * HZ; 10423e1a6892SAdrian Hunter mod_timer(&host->timer, timeout); 10431c6a0718SPierre Ossman 10441c6a0718SPierre Ossman host->cmd = cmd; 10457c89a3d9SAdrian Hunter if (cmd->data || cmd->flags & MMC_RSP_BUSY) { 10467c89a3d9SAdrian Hunter WARN_ON(host->data_cmd); 10477c89a3d9SAdrian Hunter host->data_cmd = cmd; 10487c89a3d9SAdrian Hunter } 10491c6a0718SPierre Ossman 1050a3c7778fSAndrei Warkentin sdhci_prepare_data(host, cmd); 10511c6a0718SPierre Ossman 10524e4141a5SAnton Vorontsov sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT); 10531c6a0718SPierre Ossman 1054e89d456fSAndrei Warkentin sdhci_set_transfer_mode(host, cmd); 10551c6a0718SPierre Ossman 10561c6a0718SPierre Ossman if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) { 1057a3c76eb9SGirish K S pr_err("%s: Unsupported response type!\n", 10581c6a0718SPierre Ossman mmc_hostname(host->mmc)); 105917b0429dSPierre Ossman cmd->error = -EINVAL; 1060a6d3bdd5SAdrian Hunter sdhci_finish_mrq(host, cmd->mrq); 10611c6a0718SPierre Ossman return; 10621c6a0718SPierre Ossman } 10631c6a0718SPierre Ossman 10641c6a0718SPierre Ossman if (!(cmd->flags & MMC_RSP_PRESENT)) 10651c6a0718SPierre Ossman flags = SDHCI_CMD_RESP_NONE; 10661c6a0718SPierre Ossman else if (cmd->flags & MMC_RSP_136) 10671c6a0718SPierre Ossman flags = SDHCI_CMD_RESP_LONG; 10681c6a0718SPierre Ossman else if (cmd->flags & MMC_RSP_BUSY) 10691c6a0718SPierre Ossman flags = SDHCI_CMD_RESP_SHORT_BUSY; 10701c6a0718SPierre Ossman else 10711c6a0718SPierre Ossman flags = SDHCI_CMD_RESP_SHORT; 10721c6a0718SPierre Ossman 10731c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_CRC) 10741c6a0718SPierre Ossman flags |= SDHCI_CMD_CRC; 10751c6a0718SPierre Ossman if (cmd->flags & MMC_RSP_OPCODE) 10761c6a0718SPierre Ossman flags |= SDHCI_CMD_INDEX; 1077b513ea25SArindam Nath 1078b513ea25SArindam Nath /* CMD19 is special in that the Data Present Select should be set */ 1079069c9f14SGirish K S if (cmd->data || cmd->opcode == MMC_SEND_TUNING_BLOCK || 1080069c9f14SGirish K S cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200) 10811c6a0718SPierre Ossman flags |= SDHCI_CMD_DATA; 10821c6a0718SPierre Ossman 10834e4141a5SAnton Vorontsov sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); 10841c6a0718SPierre Ossman } 1085c0e55129SDong Aisheng EXPORT_SYMBOL_GPL(sdhci_send_command); 10861c6a0718SPierre Ossman 10871c6a0718SPierre Ossman static void sdhci_finish_command(struct sdhci_host *host) 10881c6a0718SPierre Ossman { 1089e0a5640aSAdrian Hunter struct mmc_command *cmd = host->cmd; 10901c6a0718SPierre Ossman int i; 10911c6a0718SPierre Ossman 1092e0a5640aSAdrian Hunter host->cmd = NULL; 1093e0a5640aSAdrian Hunter 1094e0a5640aSAdrian Hunter if (cmd->flags & MMC_RSP_PRESENT) { 1095e0a5640aSAdrian Hunter if (cmd->flags & MMC_RSP_136) { 10961c6a0718SPierre Ossman /* CRC is stripped so we need to do some shifting. */ 10971c6a0718SPierre Ossman for (i = 0;i < 4;i++) { 1098e0a5640aSAdrian Hunter cmd->resp[i] = sdhci_readl(host, 10991c6a0718SPierre Ossman SDHCI_RESPONSE + (3-i)*4) << 8; 11001c6a0718SPierre Ossman if (i != 3) 1101e0a5640aSAdrian Hunter cmd->resp[i] |= 11024e4141a5SAnton Vorontsov sdhci_readb(host, 11031c6a0718SPierre Ossman SDHCI_RESPONSE + (3-i)*4-1); 11041c6a0718SPierre Ossman } 11051c6a0718SPierre Ossman } else { 1106e0a5640aSAdrian Hunter cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE); 11071c6a0718SPierre Ossman } 11081c6a0718SPierre Ossman } 11091c6a0718SPierre Ossman 11106bde8681SAdrian Hunter /* 11116bde8681SAdrian Hunter * The host can send and interrupt when the busy state has 11126bde8681SAdrian Hunter * ended, allowing us to wait without wasting CPU cycles. 11136bde8681SAdrian Hunter * The busy signal uses DAT0 so this is similar to waiting 11146bde8681SAdrian Hunter * for data to complete. 11156bde8681SAdrian Hunter * 11166bde8681SAdrian Hunter * Note: The 1.0 specification is a bit ambiguous about this 11176bde8681SAdrian Hunter * feature so there might be some problems with older 11186bde8681SAdrian Hunter * controllers. 11196bde8681SAdrian Hunter */ 1120e0a5640aSAdrian Hunter if (cmd->flags & MMC_RSP_BUSY) { 1121e0a5640aSAdrian Hunter if (cmd->data) { 11226bde8681SAdrian Hunter DBG("Cannot wait for busy signal when also doing a data transfer"); 11236bde8681SAdrian Hunter } else if (!(host->quirks & SDHCI_QUIRK_NO_BUSY_IRQ) && 1124ea968023SAdrian Hunter cmd == host->data_cmd) { 1125ea968023SAdrian Hunter /* Command complete before busy is ended */ 11266bde8681SAdrian Hunter return; 11276bde8681SAdrian Hunter } 11286bde8681SAdrian Hunter } 11296bde8681SAdrian Hunter 1130e89d456fSAndrei Warkentin /* Finished CMD23, now send actual command. */ 1131a4c73abaSAdrian Hunter if (cmd == cmd->mrq->sbc) { 1132a4c73abaSAdrian Hunter sdhci_send_command(host, cmd->mrq->cmd); 1133e89d456fSAndrei Warkentin } else { 1134e89d456fSAndrei Warkentin 1135e89d456fSAndrei Warkentin /* Processed actual command. */ 1136e538fbe8SPierre Ossman if (host->data && host->data_early) 1137e538fbe8SPierre Ossman sdhci_finish_data(host); 1138e538fbe8SPierre Ossman 1139e0a5640aSAdrian Hunter if (!cmd->data) 1140a6d3bdd5SAdrian Hunter sdhci_finish_mrq(host, cmd->mrq); 11411c6a0718SPierre Ossman } 1142e89d456fSAndrei Warkentin } 11431c6a0718SPierre Ossman 114452983382SKevin Liu static u16 sdhci_get_preset_value(struct sdhci_host *host) 114552983382SKevin Liu { 1146d975f121SRussell King u16 preset = 0; 114752983382SKevin Liu 1148d975f121SRussell King switch (host->timing) { 1149d975f121SRussell King case MMC_TIMING_UHS_SDR12: 115052983382SKevin Liu preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12); 115152983382SKevin Liu break; 1152d975f121SRussell King case MMC_TIMING_UHS_SDR25: 115352983382SKevin Liu preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR25); 115452983382SKevin Liu break; 1155d975f121SRussell King case MMC_TIMING_UHS_SDR50: 115652983382SKevin Liu preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR50); 115752983382SKevin Liu break; 1158d975f121SRussell King case MMC_TIMING_UHS_SDR104: 1159d975f121SRussell King case MMC_TIMING_MMC_HS200: 116052983382SKevin Liu preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR104); 116152983382SKevin Liu break; 1162d975f121SRussell King case MMC_TIMING_UHS_DDR50: 11630dafa60eSJisheng Zhang case MMC_TIMING_MMC_DDR52: 116452983382SKevin Liu preset = sdhci_readw(host, SDHCI_PRESET_FOR_DDR50); 116552983382SKevin Liu break; 1166e9fb05d5SAdrian Hunter case MMC_TIMING_MMC_HS400: 1167e9fb05d5SAdrian Hunter preset = sdhci_readw(host, SDHCI_PRESET_FOR_HS400); 1168e9fb05d5SAdrian Hunter break; 116952983382SKevin Liu default: 117052983382SKevin Liu pr_warn("%s: Invalid UHS-I mode selected\n", 117152983382SKevin Liu mmc_hostname(host->mmc)); 117252983382SKevin Liu preset = sdhci_readw(host, SDHCI_PRESET_FOR_SDR12); 117352983382SKevin Liu break; 117452983382SKevin Liu } 117552983382SKevin Liu return preset; 117652983382SKevin Liu } 117752983382SKevin Liu 1178fb9ee047SLudovic Desroches u16 sdhci_calc_clk(struct sdhci_host *host, unsigned int clock, 1179fb9ee047SLudovic Desroches unsigned int *actual_clock) 11801c6a0718SPierre Ossman { 1181c3ed3877SArindam Nath int div = 0; /* Initialized for compiler warning */ 1182df16219fSGiuseppe CAVALLARO int real_div = div, clk_mul = 1; 1183c3ed3877SArindam Nath u16 clk = 0; 11845497159cSludovic.desroches@atmel.com bool switch_base_clk = false; 11851c6a0718SPierre Ossman 118685105c53SZhangfei Gao if (host->version >= SDHCI_SPEC_300) { 1187da91a8f9SRussell King if (host->preset_enabled) { 118852983382SKevin Liu u16 pre_val; 118952983382SKevin Liu 119052983382SKevin Liu clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 119152983382SKevin Liu pre_val = sdhci_get_preset_value(host); 119252983382SKevin Liu div = (pre_val & SDHCI_PRESET_SDCLK_FREQ_MASK) 119352983382SKevin Liu >> SDHCI_PRESET_SDCLK_FREQ_SHIFT; 119452983382SKevin Liu if (host->clk_mul && 119552983382SKevin Liu (pre_val & SDHCI_PRESET_CLKGEN_SEL_MASK)) { 119652983382SKevin Liu clk = SDHCI_PROG_CLOCK_MODE; 119752983382SKevin Liu real_div = div + 1; 119852983382SKevin Liu clk_mul = host->clk_mul; 119952983382SKevin Liu } else { 120052983382SKevin Liu real_div = max_t(int, 1, div << 1); 120152983382SKevin Liu } 120252983382SKevin Liu goto clock_set; 120352983382SKevin Liu } 120452983382SKevin Liu 1205c3ed3877SArindam Nath /* 1206c3ed3877SArindam Nath * Check if the Host Controller supports Programmable Clock 1207c3ed3877SArindam Nath * Mode. 1208c3ed3877SArindam Nath */ 1209c3ed3877SArindam Nath if (host->clk_mul) { 1210c3ed3877SArindam Nath for (div = 1; div <= 1024; div++) { 121152983382SKevin Liu if ((host->max_clk * host->clk_mul / div) 121252983382SKevin Liu <= clock) 1213c3ed3877SArindam Nath break; 1214c3ed3877SArindam Nath } 12155497159cSludovic.desroches@atmel.com if ((host->max_clk * host->clk_mul / div) <= clock) { 1216c3ed3877SArindam Nath /* 1217c3ed3877SArindam Nath * Set Programmable Clock Mode in the Clock 1218c3ed3877SArindam Nath * Control register. 1219c3ed3877SArindam Nath */ 1220c3ed3877SArindam Nath clk = SDHCI_PROG_CLOCK_MODE; 1221df16219fSGiuseppe CAVALLARO real_div = div; 1222df16219fSGiuseppe CAVALLARO clk_mul = host->clk_mul; 1223c3ed3877SArindam Nath div--; 1224c3ed3877SArindam Nath } else { 12255497159cSludovic.desroches@atmel.com /* 12265497159cSludovic.desroches@atmel.com * Divisor can be too small to reach clock 12275497159cSludovic.desroches@atmel.com * speed requirement. Then use the base clock. 12285497159cSludovic.desroches@atmel.com */ 12295497159cSludovic.desroches@atmel.com switch_base_clk = true; 12305497159cSludovic.desroches@atmel.com } 12315497159cSludovic.desroches@atmel.com } 12325497159cSludovic.desroches@atmel.com 12335497159cSludovic.desroches@atmel.com if (!host->clk_mul || switch_base_clk) { 123485105c53SZhangfei Gao /* Version 3.00 divisors must be a multiple of 2. */ 123585105c53SZhangfei Gao if (host->max_clk <= clock) 123685105c53SZhangfei Gao div = 1; 123785105c53SZhangfei Gao else { 1238c3ed3877SArindam Nath for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; 1239c3ed3877SArindam Nath div += 2) { 124085105c53SZhangfei Gao if ((host->max_clk / div) <= clock) 124185105c53SZhangfei Gao break; 124285105c53SZhangfei Gao } 124385105c53SZhangfei Gao } 1244df16219fSGiuseppe CAVALLARO real_div = div; 1245c3ed3877SArindam Nath div >>= 1; 1246d1955c3aSSuneel Garapati if ((host->quirks2 & SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN) 1247d1955c3aSSuneel Garapati && !div && host->max_clk <= 25000000) 1248d1955c3aSSuneel Garapati div = 1; 1249c3ed3877SArindam Nath } 125085105c53SZhangfei Gao } else { 125185105c53SZhangfei Gao /* Version 2.00 divisors must be a power of 2. */ 12520397526dSZhangfei Gao for (div = 1; div < SDHCI_MAX_DIV_SPEC_200; div *= 2) { 12531c6a0718SPierre Ossman if ((host->max_clk / div) <= clock) 12541c6a0718SPierre Ossman break; 12551c6a0718SPierre Ossman } 1256df16219fSGiuseppe CAVALLARO real_div = div; 12571c6a0718SPierre Ossman div >>= 1; 1258c3ed3877SArindam Nath } 12591c6a0718SPierre Ossman 126052983382SKevin Liu clock_set: 126103d6f5ffSAisheng Dong if (real_div) 1262fb9ee047SLudovic Desroches *actual_clock = (host->max_clk * clk_mul) / real_div; 1263c3ed3877SArindam Nath clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; 126485105c53SZhangfei Gao clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) 126585105c53SZhangfei Gao << SDHCI_DIVIDER_HI_SHIFT; 1266fb9ee047SLudovic Desroches 1267fb9ee047SLudovic Desroches return clk; 1268fb9ee047SLudovic Desroches } 1269fb9ee047SLudovic Desroches EXPORT_SYMBOL_GPL(sdhci_calc_clk); 1270fb9ee047SLudovic Desroches 1271fb9ee047SLudovic Desroches void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) 1272fb9ee047SLudovic Desroches { 1273fb9ee047SLudovic Desroches u16 clk; 1274fb9ee047SLudovic Desroches unsigned long timeout; 1275fb9ee047SLudovic Desroches 1276fb9ee047SLudovic Desroches host->mmc->actual_clock = 0; 1277fb9ee047SLudovic Desroches 1278fb9ee047SLudovic Desroches sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); 1279fb9ee047SLudovic Desroches 1280fb9ee047SLudovic Desroches if (clock == 0) 1281fb9ee047SLudovic Desroches return; 1282fb9ee047SLudovic Desroches 1283fb9ee047SLudovic Desroches clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock); 1284fb9ee047SLudovic Desroches 12851c6a0718SPierre Ossman clk |= SDHCI_CLOCK_INT_EN; 12864e4141a5SAnton Vorontsov sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 12871c6a0718SPierre Ossman 128827f6cb16SChris Ball /* Wait max 20 ms */ 128927f6cb16SChris Ball timeout = 20; 12904e4141a5SAnton Vorontsov while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL)) 12911c6a0718SPierre Ossman & SDHCI_CLOCK_INT_STABLE)) { 12921c6a0718SPierre Ossman if (timeout == 0) { 12932e4456f0SMarek Vasut pr_err("%s: Internal clock never stabilised.\n", 12942e4456f0SMarek Vasut mmc_hostname(host->mmc)); 12951c6a0718SPierre Ossman sdhci_dumpregs(host); 12961c6a0718SPierre Ossman return; 12971c6a0718SPierre Ossman } 12981c6a0718SPierre Ossman timeout--; 12991c6a0718SPierre Ossman mdelay(1); 13001c6a0718SPierre Ossman } 13011c6a0718SPierre Ossman 13021c6a0718SPierre Ossman clk |= SDHCI_CLOCK_CARD_EN; 13034e4141a5SAnton Vorontsov sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 13041c6a0718SPierre Ossman } 13051771059cSRussell King EXPORT_SYMBOL_GPL(sdhci_set_clock); 13061c6a0718SPierre Ossman 13071dceb041SAdrian Hunter static void sdhci_set_power_reg(struct sdhci_host *host, unsigned char mode, 130824fbb3caSRussell King unsigned short vdd) 13091c6a0718SPierre Ossman { 13103a48edc4STim Kryger struct mmc_host *mmc = host->mmc; 13111dceb041SAdrian Hunter 13121dceb041SAdrian Hunter spin_unlock_irq(&host->lock); 13131dceb041SAdrian Hunter mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); 13141dceb041SAdrian Hunter spin_lock_irq(&host->lock); 13151dceb041SAdrian Hunter 13161dceb041SAdrian Hunter if (mode != MMC_POWER_OFF) 13171dceb041SAdrian Hunter sdhci_writeb(host, SDHCI_POWER_ON, SDHCI_POWER_CONTROL); 13181dceb041SAdrian Hunter else 13191dceb041SAdrian Hunter sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); 13201dceb041SAdrian Hunter } 13211dceb041SAdrian Hunter 13221dceb041SAdrian Hunter void sdhci_set_power(struct sdhci_host *host, unsigned char mode, 13231dceb041SAdrian Hunter unsigned short vdd) 13241dceb041SAdrian Hunter { 13258364248aSGiuseppe Cavallaro u8 pwr = 0; 13261c6a0718SPierre Ossman 132724fbb3caSRussell King if (mode != MMC_POWER_OFF) { 132824fbb3caSRussell King switch (1 << vdd) { 1329ae628903SPierre Ossman case MMC_VDD_165_195: 1330ae628903SPierre Ossman pwr = SDHCI_POWER_180; 1331ae628903SPierre Ossman break; 1332ae628903SPierre Ossman case MMC_VDD_29_30: 1333ae628903SPierre Ossman case MMC_VDD_30_31: 1334ae628903SPierre Ossman pwr = SDHCI_POWER_300; 1335ae628903SPierre Ossman break; 1336ae628903SPierre Ossman case MMC_VDD_32_33: 1337ae628903SPierre Ossman case MMC_VDD_33_34: 1338ae628903SPierre Ossman pwr = SDHCI_POWER_330; 1339ae628903SPierre Ossman break; 1340ae628903SPierre Ossman default: 13419d5de93fSAdrian Hunter WARN(1, "%s: Invalid vdd %#x\n", 13429d5de93fSAdrian Hunter mmc_hostname(host->mmc), vdd); 13439d5de93fSAdrian Hunter break; 1344ae628903SPierre Ossman } 1345ae628903SPierre Ossman } 1346ae628903SPierre Ossman 1347ae628903SPierre Ossman if (host->pwr == pwr) 1348e921a8b6SRussell King return; 13491c6a0718SPierre Ossman 1350ae628903SPierre Ossman host->pwr = pwr; 1351ae628903SPierre Ossman 1352ae628903SPierre Ossman if (pwr == 0) { 13534e4141a5SAnton Vorontsov sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); 1354f0710a55SAdrian Hunter if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) 1355f0710a55SAdrian Hunter sdhci_runtime_pm_bus_off(host); 1356e921a8b6SRussell King } else { 13571c6a0718SPierre Ossman /* 13581c6a0718SPierre Ossman * Spec says that we should clear the power reg before setting 13591c6a0718SPierre Ossman * a new value. Some controllers don't seem to like this though. 13601c6a0718SPierre Ossman */ 1361b8c86fc5SPierre Ossman if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE)) 13624e4141a5SAnton Vorontsov sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); 13631c6a0718SPierre Ossman 1364e08c1694SAndres Salomon /* 1365e921a8b6SRussell King * At least the Marvell CaFe chip gets confused if we set the 1366e921a8b6SRussell King * voltage and set turn on power at the same time, so set the 1367e921a8b6SRussell King * voltage first. 1368e08c1694SAndres Salomon */ 136911a2f1b7SPierre Ossman if (host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER) 13704e4141a5SAnton Vorontsov sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); 13711c6a0718SPierre Ossman 1372ae628903SPierre Ossman pwr |= SDHCI_POWER_ON; 1373ae628903SPierre Ossman 1374ae628903SPierre Ossman sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); 1375557b0697SHarald Welte 1376f0710a55SAdrian Hunter if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON) 1377f0710a55SAdrian Hunter sdhci_runtime_pm_bus_on(host); 1378f0710a55SAdrian Hunter 1379557b0697SHarald Welte /* 1380e921a8b6SRussell King * Some controllers need an extra 10ms delay of 10ms before 1381e921a8b6SRussell King * they can apply clock after applying power 1382557b0697SHarald Welte */ 138311a2f1b7SPierre Ossman if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER) 1384557b0697SHarald Welte mdelay(10); 1385e921a8b6SRussell King } 1386918f4cbdSJisheng Zhang } 13871dceb041SAdrian Hunter EXPORT_SYMBOL_GPL(sdhci_set_power); 13881dceb041SAdrian Hunter 13891dceb041SAdrian Hunter static void __sdhci_set_power(struct sdhci_host *host, unsigned char mode, 13901dceb041SAdrian Hunter unsigned short vdd) 13911dceb041SAdrian Hunter { 13921dceb041SAdrian Hunter struct mmc_host *mmc = host->mmc; 13931dceb041SAdrian Hunter 13941dceb041SAdrian Hunter if (host->ops->set_power) 13951dceb041SAdrian Hunter host->ops->set_power(host, mode, vdd); 13961dceb041SAdrian Hunter else if (!IS_ERR(mmc->supply.vmmc)) 13971dceb041SAdrian Hunter sdhci_set_power_reg(host, mode, vdd); 13981dceb041SAdrian Hunter else 13991dceb041SAdrian Hunter sdhci_set_power(host, mode, vdd); 14001c6a0718SPierre Ossman } 14011c6a0718SPierre Ossman 14021c6a0718SPierre Ossman /*****************************************************************************\ 14031c6a0718SPierre Ossman * * 14041c6a0718SPierre Ossman * MMC callbacks * 14051c6a0718SPierre Ossman * * 14061c6a0718SPierre Ossman \*****************************************************************************/ 14071c6a0718SPierre Ossman 14081c6a0718SPierre Ossman static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) 14091c6a0718SPierre Ossman { 14101c6a0718SPierre Ossman struct sdhci_host *host; 1411505a8680SShawn Guo int present; 14121c6a0718SPierre Ossman unsigned long flags; 14131c6a0718SPierre Ossman 14141c6a0718SPierre Ossman host = mmc_priv(mmc); 14151c6a0718SPierre Ossman 141604e079cfSScott Branden /* Firstly check card presence */ 14178d28b7a7SAdrian Hunter present = mmc->ops->get_cd(mmc); 14182836766aSKrzysztof Kozlowski 14191c6a0718SPierre Ossman spin_lock_irqsave(&host->lock, flags); 14201c6a0718SPierre Ossman 14211c6a0718SPierre Ossman WARN_ON(host->mrq != NULL); 14221c6a0718SPierre Ossman 1423061d17a6SAdrian Hunter sdhci_led_activate(host); 1424e89d456fSAndrei Warkentin 1425e89d456fSAndrei Warkentin /* 1426e89d456fSAndrei Warkentin * Ensure we don't send the STOP for non-SET_BLOCK_COUNTED 1427e89d456fSAndrei Warkentin * requests if Auto-CMD12 is enabled. 1428e89d456fSAndrei Warkentin */ 1429e89d456fSAndrei Warkentin if (!mrq->sbc && (host->flags & SDHCI_AUTO_CMD12)) { 1430c4512f79SJerry Huang if (mrq->stop) { 1431c4512f79SJerry Huang mrq->data->stop = NULL; 1432c4512f79SJerry Huang mrq->stop = NULL; 1433c4512f79SJerry Huang } 1434c4512f79SJerry Huang } 14351c6a0718SPierre Ossman 14361c6a0718SPierre Ossman host->mrq = mrq; 14371c6a0718SPierre Ossman 143868d1fb7eSAnton Vorontsov if (!present || host->flags & SDHCI_DEVICE_DEAD) { 1439a4c73abaSAdrian Hunter mrq->cmd->error = -ENOMEDIUM; 1440a6d3bdd5SAdrian Hunter sdhci_finish_mrq(host, mrq); 1441cf2b5eeaSArindam Nath } else { 14428edf6371SAndrei Warkentin if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23)) 1443e89d456fSAndrei Warkentin sdhci_send_command(host, mrq->sbc); 1444e89d456fSAndrei Warkentin else 14451c6a0718SPierre Ossman sdhci_send_command(host, mrq->cmd); 1446cf2b5eeaSArindam Nath } 14471c6a0718SPierre Ossman 14481c6a0718SPierre Ossman mmiowb(); 14491c6a0718SPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 14501c6a0718SPierre Ossman } 14511c6a0718SPierre Ossman 14522317f56cSRussell King void sdhci_set_bus_width(struct sdhci_host *host, int width) 14532317f56cSRussell King { 14542317f56cSRussell King u8 ctrl; 14552317f56cSRussell King 14562317f56cSRussell King ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 14572317f56cSRussell King if (width == MMC_BUS_WIDTH_8) { 14582317f56cSRussell King ctrl &= ~SDHCI_CTRL_4BITBUS; 14592317f56cSRussell King if (host->version >= SDHCI_SPEC_300) 14602317f56cSRussell King ctrl |= SDHCI_CTRL_8BITBUS; 14612317f56cSRussell King } else { 14622317f56cSRussell King if (host->version >= SDHCI_SPEC_300) 14632317f56cSRussell King ctrl &= ~SDHCI_CTRL_8BITBUS; 14642317f56cSRussell King if (width == MMC_BUS_WIDTH_4) 14652317f56cSRussell King ctrl |= SDHCI_CTRL_4BITBUS; 14662317f56cSRussell King else 14672317f56cSRussell King ctrl &= ~SDHCI_CTRL_4BITBUS; 14682317f56cSRussell King } 14692317f56cSRussell King sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 14702317f56cSRussell King } 14712317f56cSRussell King EXPORT_SYMBOL_GPL(sdhci_set_bus_width); 14722317f56cSRussell King 147396d7b78cSRussell King void sdhci_set_uhs_signaling(struct sdhci_host *host, unsigned timing) 147496d7b78cSRussell King { 147596d7b78cSRussell King u16 ctrl_2; 147696d7b78cSRussell King 147796d7b78cSRussell King ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); 147896d7b78cSRussell King /* Select Bus Speed Mode for host */ 147996d7b78cSRussell King ctrl_2 &= ~SDHCI_CTRL_UHS_MASK; 148096d7b78cSRussell King if ((timing == MMC_TIMING_MMC_HS200) || 148196d7b78cSRussell King (timing == MMC_TIMING_UHS_SDR104)) 148296d7b78cSRussell King ctrl_2 |= SDHCI_CTRL_UHS_SDR104; 148396d7b78cSRussell King else if (timing == MMC_TIMING_UHS_SDR12) 148496d7b78cSRussell King ctrl_2 |= SDHCI_CTRL_UHS_SDR12; 148596d7b78cSRussell King else if (timing == MMC_TIMING_UHS_SDR25) 148696d7b78cSRussell King ctrl_2 |= SDHCI_CTRL_UHS_SDR25; 148796d7b78cSRussell King else if (timing == MMC_TIMING_UHS_SDR50) 148896d7b78cSRussell King ctrl_2 |= SDHCI_CTRL_UHS_SDR50; 148996d7b78cSRussell King else if ((timing == MMC_TIMING_UHS_DDR50) || 149096d7b78cSRussell King (timing == MMC_TIMING_MMC_DDR52)) 149196d7b78cSRussell King ctrl_2 |= SDHCI_CTRL_UHS_DDR50; 1492e9fb05d5SAdrian Hunter else if (timing == MMC_TIMING_MMC_HS400) 1493e9fb05d5SAdrian Hunter ctrl_2 |= SDHCI_CTRL_HS400; /* Non-standard */ 149496d7b78cSRussell King sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); 149596d7b78cSRussell King } 149696d7b78cSRussell King EXPORT_SYMBOL_GPL(sdhci_set_uhs_signaling); 149796d7b78cSRussell King 1498ded97e0bSDong Aisheng static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 14991c6a0718SPierre Ossman { 1500ded97e0bSDong Aisheng struct sdhci_host *host = mmc_priv(mmc); 15011c6a0718SPierre Ossman unsigned long flags; 15021c6a0718SPierre Ossman u8 ctrl; 15031c6a0718SPierre Ossman 15041c6a0718SPierre Ossman spin_lock_irqsave(&host->lock, flags); 15051c6a0718SPierre Ossman 1506ceb6143bSAdrian Hunter if (host->flags & SDHCI_DEVICE_DEAD) { 1507ceb6143bSAdrian Hunter spin_unlock_irqrestore(&host->lock, flags); 15083a48edc4STim Kryger if (!IS_ERR(mmc->supply.vmmc) && 15093a48edc4STim Kryger ios->power_mode == MMC_POWER_OFF) 15104e743f1fSMarkus Mayer mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); 1511ceb6143bSAdrian Hunter return; 1512ceb6143bSAdrian Hunter } 15131e72859eSPierre Ossman 15141c6a0718SPierre Ossman /* 15151c6a0718SPierre Ossman * Reset the chip on each power off. 15161c6a0718SPierre Ossman * Should clear out any weird states. 15171c6a0718SPierre Ossman */ 15181c6a0718SPierre Ossman if (ios->power_mode == MMC_POWER_OFF) { 15194e4141a5SAnton Vorontsov sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE); 15207260cf5eSAnton Vorontsov sdhci_reinit(host); 15211c6a0718SPierre Ossman } 15221c6a0718SPierre Ossman 152352983382SKevin Liu if (host->version >= SDHCI_SPEC_300 && 1524372c4634SDong Aisheng (ios->power_mode == MMC_POWER_UP) && 1525372c4634SDong Aisheng !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) 152652983382SKevin Liu sdhci_enable_preset_value(host, false); 152752983382SKevin Liu 1528373073efSRussell King if (!ios->clock || ios->clock != host->clock) { 15291771059cSRussell King host->ops->set_clock(host, ios->clock); 1530373073efSRussell King host->clock = ios->clock; 153103d6f5ffSAisheng Dong 153203d6f5ffSAisheng Dong if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK && 153303d6f5ffSAisheng Dong host->clock) { 153403d6f5ffSAisheng Dong host->timeout_clk = host->mmc->actual_clock ? 153503d6f5ffSAisheng Dong host->mmc->actual_clock / 1000 : 153603d6f5ffSAisheng Dong host->clock / 1000; 153703d6f5ffSAisheng Dong host->mmc->max_busy_timeout = 153803d6f5ffSAisheng Dong host->ops->get_max_timeout_count ? 153903d6f5ffSAisheng Dong host->ops->get_max_timeout_count(host) : 154003d6f5ffSAisheng Dong 1 << 27; 154103d6f5ffSAisheng Dong host->mmc->max_busy_timeout /= host->timeout_clk; 154203d6f5ffSAisheng Dong } 1543373073efSRussell King } 15441c6a0718SPierre Ossman 15451dceb041SAdrian Hunter __sdhci_set_power(host, ios->power_mode, ios->vdd); 15461c6a0718SPierre Ossman 1547643a81ffSPhilip Rakity if (host->ops->platform_send_init_74_clocks) 1548643a81ffSPhilip Rakity host->ops->platform_send_init_74_clocks(host, ios->power_mode); 1549643a81ffSPhilip Rakity 15502317f56cSRussell King host->ops->set_bus_width(host, ios->bus_width); 155115ec4461SPhilip Rakity 155215ec4461SPhilip Rakity ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); 15531c6a0718SPierre Ossman 15543ab9c8daSPhilip Rakity if ((ios->timing == MMC_TIMING_SD_HS || 15553ab9c8daSPhilip Rakity ios->timing == MMC_TIMING_MMC_HS) 15563ab9c8daSPhilip Rakity && !(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) 15571c6a0718SPierre Ossman ctrl |= SDHCI_CTRL_HISPD; 15581c6a0718SPierre Ossman else 15591c6a0718SPierre Ossman ctrl &= ~SDHCI_CTRL_HISPD; 15601c6a0718SPierre Ossman 1561d6d50a15SArindam Nath if (host->version >= SDHCI_SPEC_300) { 156249c468fcSArindam Nath u16 clk, ctrl_2; 156349c468fcSArindam Nath 156449c468fcSArindam Nath /* In case of UHS-I modes, set High Speed Enable */ 1565e9fb05d5SAdrian Hunter if ((ios->timing == MMC_TIMING_MMC_HS400) || 1566e9fb05d5SAdrian Hunter (ios->timing == MMC_TIMING_MMC_HS200) || 1567bb8175a8SSeungwon Jeon (ios->timing == MMC_TIMING_MMC_DDR52) || 1568069c9f14SGirish K S (ios->timing == MMC_TIMING_UHS_SDR50) || 156949c468fcSArindam Nath (ios->timing == MMC_TIMING_UHS_SDR104) || 157049c468fcSArindam Nath (ios->timing == MMC_TIMING_UHS_DDR50) || 1571dd8df17fSAlexander Elbs (ios->timing == MMC_TIMING_UHS_SDR25)) 157249c468fcSArindam Nath ctrl |= SDHCI_CTRL_HISPD; 1573d6d50a15SArindam Nath 1574da91a8f9SRussell King if (!host->preset_enabled) { 1575758535c4SArindam Nath sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 1576d6d50a15SArindam Nath /* 1577d6d50a15SArindam Nath * We only need to set Driver Strength if the 1578d6d50a15SArindam Nath * preset value enable is not set. 1579d6d50a15SArindam Nath */ 1580da91a8f9SRussell King ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1581d6d50a15SArindam Nath ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK; 1582d6d50a15SArindam Nath if (ios->drv_type == MMC_SET_DRIVER_TYPE_A) 1583d6d50a15SArindam Nath ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A; 158443e943a0SPetri Gynther else if (ios->drv_type == MMC_SET_DRIVER_TYPE_B) 158543e943a0SPetri Gynther ctrl_2 |= SDHCI_CTRL_DRV_TYPE_B; 1586d6d50a15SArindam Nath else if (ios->drv_type == MMC_SET_DRIVER_TYPE_C) 1587d6d50a15SArindam Nath ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C; 158843e943a0SPetri Gynther else if (ios->drv_type == MMC_SET_DRIVER_TYPE_D) 158943e943a0SPetri Gynther ctrl_2 |= SDHCI_CTRL_DRV_TYPE_D; 159043e943a0SPetri Gynther else { 15912e4456f0SMarek Vasut pr_warn("%s: invalid driver type, default to driver type B\n", 15922e4456f0SMarek Vasut mmc_hostname(mmc)); 159343e943a0SPetri Gynther ctrl_2 |= SDHCI_CTRL_DRV_TYPE_B; 159443e943a0SPetri Gynther } 1595d6d50a15SArindam Nath 1596d6d50a15SArindam Nath sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2); 1597758535c4SArindam Nath } else { 1598758535c4SArindam Nath /* 1599758535c4SArindam Nath * According to SDHC Spec v3.00, if the Preset Value 1600758535c4SArindam Nath * Enable in the Host Control 2 register is set, we 1601758535c4SArindam Nath * need to reset SD Clock Enable before changing High 1602758535c4SArindam Nath * Speed Enable to avoid generating clock gliches. 1603758535c4SArindam Nath */ 1604758535c4SArindam Nath 1605758535c4SArindam Nath /* Reset SD Clock Enable */ 1606758535c4SArindam Nath clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 1607758535c4SArindam Nath clk &= ~SDHCI_CLOCK_CARD_EN; 1608758535c4SArindam Nath sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 1609758535c4SArindam Nath 1610758535c4SArindam Nath sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 1611758535c4SArindam Nath 1612758535c4SArindam Nath /* Re-enable SD Clock */ 16131771059cSRussell King host->ops->set_clock(host, host->clock); 1614d6d50a15SArindam Nath } 161549c468fcSArindam Nath 16166322cdd0SPhilip Rakity /* Reset SD Clock Enable */ 16176322cdd0SPhilip Rakity clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL); 16186322cdd0SPhilip Rakity clk &= ~SDHCI_CLOCK_CARD_EN; 16196322cdd0SPhilip Rakity sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL); 16206322cdd0SPhilip Rakity 16216322cdd0SPhilip Rakity host->ops->set_uhs_signaling(host, ios->timing); 1622d975f121SRussell King host->timing = ios->timing; 162349c468fcSArindam Nath 162452983382SKevin Liu if (!(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN) && 162552983382SKevin Liu ((ios->timing == MMC_TIMING_UHS_SDR12) || 162652983382SKevin Liu (ios->timing == MMC_TIMING_UHS_SDR25) || 162752983382SKevin Liu (ios->timing == MMC_TIMING_UHS_SDR50) || 162852983382SKevin Liu (ios->timing == MMC_TIMING_UHS_SDR104) || 16290dafa60eSJisheng Zhang (ios->timing == MMC_TIMING_UHS_DDR50) || 16300dafa60eSJisheng Zhang (ios->timing == MMC_TIMING_MMC_DDR52))) { 163152983382SKevin Liu u16 preset; 163252983382SKevin Liu 163352983382SKevin Liu sdhci_enable_preset_value(host, true); 163452983382SKevin Liu preset = sdhci_get_preset_value(host); 163552983382SKevin Liu ios->drv_type = (preset & SDHCI_PRESET_DRV_MASK) 163652983382SKevin Liu >> SDHCI_PRESET_DRV_SHIFT; 163752983382SKevin Liu } 163852983382SKevin Liu 163949c468fcSArindam Nath /* Re-enable SD Clock */ 16401771059cSRussell King host->ops->set_clock(host, host->clock); 1641758535c4SArindam Nath } else 1642758535c4SArindam Nath sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); 1643d6d50a15SArindam Nath 1644b8352260SLeandro Dorileo /* 1645b8352260SLeandro Dorileo * Some (ENE) controllers go apeshit on some ios operation, 1646b8352260SLeandro Dorileo * signalling timeout and CRC errors even on CMD0. Resetting 1647b8352260SLeandro Dorileo * it on each ios seems to solve the problem. 1648b8352260SLeandro Dorileo */ 1649b8c86fc5SPierre Ossman if (host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) 165003231f9bSRussell King sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); 1651b8352260SLeandro Dorileo 16521c6a0718SPierre Ossman mmiowb(); 16531c6a0718SPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 16541c6a0718SPierre Ossman } 16551c6a0718SPierre Ossman 1656ded97e0bSDong Aisheng static int sdhci_get_cd(struct mmc_host *mmc) 165766fd8ad5SAdrian Hunter { 165866fd8ad5SAdrian Hunter struct sdhci_host *host = mmc_priv(mmc); 1659ded97e0bSDong Aisheng int gpio_cd = mmc_gpio_get_cd(mmc); 166094144a46SKevin Liu 166194144a46SKevin Liu if (host->flags & SDHCI_DEVICE_DEAD) 166294144a46SKevin Liu return 0; 166394144a46SKevin Liu 166488af5655SIvan T. Ivanov /* If nonremovable, assume that the card is always present. */ 1665860951c5SJaehoon Chung if (!mmc_card_is_removable(host->mmc)) 166694144a46SKevin Liu return 1; 166794144a46SKevin Liu 166888af5655SIvan T. Ivanov /* 166988af5655SIvan T. Ivanov * Try slot gpio detect, if defined it take precedence 167088af5655SIvan T. Ivanov * over build in controller functionality 167188af5655SIvan T. Ivanov */ 1672287980e4SArnd Bergmann if (gpio_cd >= 0) 167394144a46SKevin Liu return !!gpio_cd; 167494144a46SKevin Liu 167588af5655SIvan T. Ivanov /* If polling, assume that the card is always present. */ 167688af5655SIvan T. Ivanov if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) 167788af5655SIvan T. Ivanov return 1; 167888af5655SIvan T. Ivanov 167994144a46SKevin Liu /* Host native card detect */ 168094144a46SKevin Liu return !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT); 168194144a46SKevin Liu } 168294144a46SKevin Liu 168366fd8ad5SAdrian Hunter static int sdhci_check_ro(struct sdhci_host *host) 16841c6a0718SPierre Ossman { 16851c6a0718SPierre Ossman unsigned long flags; 16862dfb579cSWolfram Sang int is_readonly; 16871c6a0718SPierre Ossman 16881c6a0718SPierre Ossman spin_lock_irqsave(&host->lock, flags); 16891c6a0718SPierre Ossman 16901e72859eSPierre Ossman if (host->flags & SDHCI_DEVICE_DEAD) 16912dfb579cSWolfram Sang is_readonly = 0; 16922dfb579cSWolfram Sang else if (host->ops->get_ro) 16932dfb579cSWolfram Sang is_readonly = host->ops->get_ro(host); 16941e72859eSPierre Ossman else 16952dfb579cSWolfram Sang is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE) 16962dfb579cSWolfram Sang & SDHCI_WRITE_PROTECT); 16971c6a0718SPierre Ossman 16981c6a0718SPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 16991c6a0718SPierre Ossman 17002dfb579cSWolfram Sang /* This quirk needs to be replaced by a callback-function later */ 17012dfb579cSWolfram Sang return host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT ? 17022dfb579cSWolfram Sang !is_readonly : is_readonly; 17031c6a0718SPierre Ossman } 17041c6a0718SPierre Ossman 170582b0e23aSTakashi Iwai #define SAMPLE_COUNT 5 170682b0e23aSTakashi Iwai 1707ded97e0bSDong Aisheng static int sdhci_get_ro(struct mmc_host *mmc) 170882b0e23aSTakashi Iwai { 1709ded97e0bSDong Aisheng struct sdhci_host *host = mmc_priv(mmc); 171082b0e23aSTakashi Iwai int i, ro_count; 171182b0e23aSTakashi Iwai 171282b0e23aSTakashi Iwai if (!(host->quirks & SDHCI_QUIRK_UNSTABLE_RO_DETECT)) 171366fd8ad5SAdrian Hunter return sdhci_check_ro(host); 171482b0e23aSTakashi Iwai 171582b0e23aSTakashi Iwai ro_count = 0; 171682b0e23aSTakashi Iwai for (i = 0; i < SAMPLE_COUNT; i++) { 171766fd8ad5SAdrian Hunter if (sdhci_check_ro(host)) { 171882b0e23aSTakashi Iwai if (++ro_count > SAMPLE_COUNT / 2) 171982b0e23aSTakashi Iwai return 1; 172082b0e23aSTakashi Iwai } 172182b0e23aSTakashi Iwai msleep(30); 172282b0e23aSTakashi Iwai } 172382b0e23aSTakashi Iwai return 0; 172482b0e23aSTakashi Iwai } 172582b0e23aSTakashi Iwai 172620758b66SAdrian Hunter static void sdhci_hw_reset(struct mmc_host *mmc) 172720758b66SAdrian Hunter { 172820758b66SAdrian Hunter struct sdhci_host *host = mmc_priv(mmc); 172920758b66SAdrian Hunter 173020758b66SAdrian Hunter if (host->ops && host->ops->hw_reset) 173120758b66SAdrian Hunter host->ops->hw_reset(host); 173220758b66SAdrian Hunter } 173320758b66SAdrian Hunter 173466fd8ad5SAdrian Hunter static void sdhci_enable_sdio_irq_nolock(struct sdhci_host *host, int enable) 173566fd8ad5SAdrian Hunter { 1736be138554SRussell King if (!(host->flags & SDHCI_DEVICE_DEAD)) { 173766fd8ad5SAdrian Hunter if (enable) 1738b537f94cSRussell King host->ier |= SDHCI_INT_CARD_INT; 17397260cf5eSAnton Vorontsov else 1740b537f94cSRussell King host->ier &= ~SDHCI_INT_CARD_INT; 1741b537f94cSRussell King 1742b537f94cSRussell King sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); 1743b537f94cSRussell King sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); 1744f75979b7SPierre Ossman mmiowb(); 174566fd8ad5SAdrian Hunter } 1746ef104333SRussell King } 1747f75979b7SPierre Ossman 174866fd8ad5SAdrian Hunter static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable) 174966fd8ad5SAdrian Hunter { 175066fd8ad5SAdrian Hunter struct sdhci_host *host = mmc_priv(mmc); 175166fd8ad5SAdrian Hunter unsigned long flags; 175266fd8ad5SAdrian Hunter 175366fd8ad5SAdrian Hunter spin_lock_irqsave(&host->lock, flags); 1754ef104333SRussell King if (enable) 1755ef104333SRussell King host->flags |= SDHCI_SDIO_IRQ_ENABLED; 1756ef104333SRussell King else 1757ef104333SRussell King host->flags &= ~SDHCI_SDIO_IRQ_ENABLED; 1758ef104333SRussell King 175966fd8ad5SAdrian Hunter sdhci_enable_sdio_irq_nolock(host, enable); 1760f75979b7SPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 1761f75979b7SPierre Ossman } 1762f75979b7SPierre Ossman 1763ded97e0bSDong Aisheng static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, 176421f5998fSFabio Estevam struct mmc_ios *ios) 1765f2119df6SArindam Nath { 1766ded97e0bSDong Aisheng struct sdhci_host *host = mmc_priv(mmc); 176720b92a30SKevin Liu u16 ctrl; 17686231f3deSPhilip Rakity int ret; 1769f2119df6SArindam Nath 177020b92a30SKevin Liu /* 177120b92a30SKevin Liu * Signal Voltage Switching is only applicable for Host Controllers 177220b92a30SKevin Liu * v3.00 and above. 177320b92a30SKevin Liu */ 177420b92a30SKevin Liu if (host->version < SDHCI_SPEC_300) 177520b92a30SKevin Liu return 0; 177620b92a30SKevin Liu 177720b92a30SKevin Liu ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 177820b92a30SKevin Liu 177921f5998fSFabio Estevam switch (ios->signal_voltage) { 178020b92a30SKevin Liu case MMC_SIGNAL_VOLTAGE_330: 17818cb851a4SAdrian Hunter if (!(host->flags & SDHCI_SIGNALING_330)) 17828cb851a4SAdrian Hunter return -EINVAL; 1783f2119df6SArindam Nath /* Set 1.8V Signal Enable in the Host Control2 register to 0 */ 1784f2119df6SArindam Nath ctrl &= ~SDHCI_CTRL_VDD_180; 1785f2119df6SArindam Nath sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 1786f2119df6SArindam Nath 17873a48edc4STim Kryger if (!IS_ERR(mmc->supply.vqmmc)) { 17883a48edc4STim Kryger ret = regulator_set_voltage(mmc->supply.vqmmc, 2700000, 17893a48edc4STim Kryger 3600000); 17906231f3deSPhilip Rakity if (ret) { 17916606110dSJoe Perches pr_warn("%s: Switching to 3.3V signalling voltage failed\n", 17926606110dSJoe Perches mmc_hostname(mmc)); 17936231f3deSPhilip Rakity return -EIO; 17946231f3deSPhilip Rakity } 17956231f3deSPhilip Rakity } 1796f2119df6SArindam Nath /* Wait for 5ms */ 1797f2119df6SArindam Nath usleep_range(5000, 5500); 1798f2119df6SArindam Nath 1799f2119df6SArindam Nath /* 3.3V regulator output should be stable within 5 ms */ 1800f2119df6SArindam Nath ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 1801f2119df6SArindam Nath if (!(ctrl & SDHCI_CTRL_VDD_180)) 1802f2119df6SArindam Nath return 0; 18036231f3deSPhilip Rakity 18046606110dSJoe Perches pr_warn("%s: 3.3V regulator output did not became stable\n", 18054e743f1fSMarkus Mayer mmc_hostname(mmc)); 18066231f3deSPhilip Rakity 180720b92a30SKevin Liu return -EAGAIN; 180820b92a30SKevin Liu case MMC_SIGNAL_VOLTAGE_180: 18098cb851a4SAdrian Hunter if (!(host->flags & SDHCI_SIGNALING_180)) 18108cb851a4SAdrian Hunter return -EINVAL; 18113a48edc4STim Kryger if (!IS_ERR(mmc->supply.vqmmc)) { 18123a48edc4STim Kryger ret = regulator_set_voltage(mmc->supply.vqmmc, 181320b92a30SKevin Liu 1700000, 1950000); 181420b92a30SKevin Liu if (ret) { 18156606110dSJoe Perches pr_warn("%s: Switching to 1.8V signalling voltage failed\n", 18166606110dSJoe Perches mmc_hostname(mmc)); 1817f2119df6SArindam Nath return -EIO; 1818f2119df6SArindam Nath } 181920b92a30SKevin Liu } 18206231f3deSPhilip Rakity 1821f2119df6SArindam Nath /* 1822f2119df6SArindam Nath * Enable 1.8V Signal Enable in the Host Control2 1823f2119df6SArindam Nath * register 1824f2119df6SArindam Nath */ 1825f2119df6SArindam Nath ctrl |= SDHCI_CTRL_VDD_180; 1826f2119df6SArindam Nath sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 1827f2119df6SArindam Nath 18289d967a61SVincent Yang /* Some controller need to do more when switching */ 18299d967a61SVincent Yang if (host->ops->voltage_switch) 18309d967a61SVincent Yang host->ops->voltage_switch(host); 18319d967a61SVincent Yang 183220b92a30SKevin Liu /* 1.8V regulator output should be stable within 5 ms */ 1833f2119df6SArindam Nath ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 183420b92a30SKevin Liu if (ctrl & SDHCI_CTRL_VDD_180) 1835f2119df6SArindam Nath return 0; 1836f2119df6SArindam Nath 18376606110dSJoe Perches pr_warn("%s: 1.8V regulator output did not became stable\n", 18384e743f1fSMarkus Mayer mmc_hostname(mmc)); 18396231f3deSPhilip Rakity 1840f2119df6SArindam Nath return -EAGAIN; 184120b92a30SKevin Liu case MMC_SIGNAL_VOLTAGE_120: 18428cb851a4SAdrian Hunter if (!(host->flags & SDHCI_SIGNALING_120)) 18438cb851a4SAdrian Hunter return -EINVAL; 18443a48edc4STim Kryger if (!IS_ERR(mmc->supply.vqmmc)) { 18453a48edc4STim Kryger ret = regulator_set_voltage(mmc->supply.vqmmc, 1100000, 18463a48edc4STim Kryger 1300000); 184720b92a30SKevin Liu if (ret) { 18486606110dSJoe Perches pr_warn("%s: Switching to 1.2V signalling voltage failed\n", 18496606110dSJoe Perches mmc_hostname(mmc)); 185020b92a30SKevin Liu return -EIO; 18516231f3deSPhilip Rakity } 185220b92a30SKevin Liu } 18536231f3deSPhilip Rakity return 0; 185420b92a30SKevin Liu default: 1855f2119df6SArindam Nath /* No signal voltage switch required */ 1856f2119df6SArindam Nath return 0; 1857f2119df6SArindam Nath } 185820b92a30SKevin Liu } 1859f2119df6SArindam Nath 186020b92a30SKevin Liu static int sdhci_card_busy(struct mmc_host *mmc) 186120b92a30SKevin Liu { 186220b92a30SKevin Liu struct sdhci_host *host = mmc_priv(mmc); 186320b92a30SKevin Liu u32 present_state; 186420b92a30SKevin Liu 1865e613cc47SAdrian Hunter /* Check whether DAT[0] is 0 */ 186620b92a30SKevin Liu present_state = sdhci_readl(host, SDHCI_PRESENT_STATE); 186720b92a30SKevin Liu 1868e613cc47SAdrian Hunter return !(present_state & SDHCI_DATA_0_LVL_MASK); 186920b92a30SKevin Liu } 187020b92a30SKevin Liu 1871b5540ce1SAdrian Hunter static int sdhci_prepare_hs400_tuning(struct mmc_host *mmc, struct mmc_ios *ios) 1872b5540ce1SAdrian Hunter { 1873b5540ce1SAdrian Hunter struct sdhci_host *host = mmc_priv(mmc); 1874b5540ce1SAdrian Hunter unsigned long flags; 1875b5540ce1SAdrian Hunter 1876b5540ce1SAdrian Hunter spin_lock_irqsave(&host->lock, flags); 1877b5540ce1SAdrian Hunter host->flags |= SDHCI_HS400_TUNING; 1878b5540ce1SAdrian Hunter spin_unlock_irqrestore(&host->lock, flags); 1879b5540ce1SAdrian Hunter 1880b5540ce1SAdrian Hunter return 0; 1881b5540ce1SAdrian Hunter } 1882b5540ce1SAdrian Hunter 1883069c9f14SGirish K S static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) 1884b513ea25SArindam Nath { 18854b6f37d3SRussell King struct sdhci_host *host = mmc_priv(mmc); 1886b513ea25SArindam Nath u16 ctrl; 1887b513ea25SArindam Nath int tuning_loop_counter = MAX_TUNING_LOOP; 1888b513ea25SArindam Nath int err = 0; 18892b35bd83SAisheng Dong unsigned long flags; 189038e40bf5SAdrian Hunter unsigned int tuning_count = 0; 1891b5540ce1SAdrian Hunter bool hs400_tuning; 1892b513ea25SArindam Nath 18932b35bd83SAisheng Dong spin_lock_irqsave(&host->lock, flags); 1894b513ea25SArindam Nath 1895b5540ce1SAdrian Hunter hs400_tuning = host->flags & SDHCI_HS400_TUNING; 1896b5540ce1SAdrian Hunter host->flags &= ~SDHCI_HS400_TUNING; 1897b5540ce1SAdrian Hunter 189838e40bf5SAdrian Hunter if (host->tuning_mode == SDHCI_TUNING_MODE_1) 189938e40bf5SAdrian Hunter tuning_count = host->tuning_count; 190038e40bf5SAdrian Hunter 1901b513ea25SArindam Nath /* 19029faac7b9SWeijun Yang * The Host Controller needs tuning in case of SDR104 and DDR50 19039faac7b9SWeijun Yang * mode, and for SDR50 mode when Use Tuning for SDR50 is set in 19049faac7b9SWeijun Yang * the Capabilities register. 1905069c9f14SGirish K S * If the Host Controller supports the HS200 mode then the 1906069c9f14SGirish K S * tuning function has to be executed. 1907b513ea25SArindam Nath */ 19084b6f37d3SRussell King switch (host->timing) { 1909b5540ce1SAdrian Hunter /* HS400 tuning is done in HS200 mode */ 1910e9fb05d5SAdrian Hunter case MMC_TIMING_MMC_HS400: 1911b5540ce1SAdrian Hunter err = -EINVAL; 1912b5540ce1SAdrian Hunter goto out_unlock; 1913b5540ce1SAdrian Hunter 19144b6f37d3SRussell King case MMC_TIMING_MMC_HS200: 1915b5540ce1SAdrian Hunter /* 1916b5540ce1SAdrian Hunter * Periodic re-tuning for HS400 is not expected to be needed, so 1917b5540ce1SAdrian Hunter * disable it here. 1918b5540ce1SAdrian Hunter */ 1919b5540ce1SAdrian Hunter if (hs400_tuning) 1920b5540ce1SAdrian Hunter tuning_count = 0; 1921b5540ce1SAdrian Hunter break; 1922b5540ce1SAdrian Hunter 19234b6f37d3SRussell King case MMC_TIMING_UHS_SDR104: 19249faac7b9SWeijun Yang case MMC_TIMING_UHS_DDR50: 19254b6f37d3SRussell King break; 1926069c9f14SGirish K S 19274b6f37d3SRussell King case MMC_TIMING_UHS_SDR50: 19284228b213SAdrian Hunter if (host->flags & SDHCI_SDR50_NEEDS_TUNING) 19294b6f37d3SRussell King break; 19304b6f37d3SRussell King /* FALLTHROUGH */ 19314b6f37d3SRussell King 19324b6f37d3SRussell King default: 1933d519c863SAdrian Hunter goto out_unlock; 1934b513ea25SArindam Nath } 1935b513ea25SArindam Nath 193645251812SDong Aisheng if (host->ops->platform_execute_tuning) { 19372b35bd83SAisheng Dong spin_unlock_irqrestore(&host->lock, flags); 193845251812SDong Aisheng err = host->ops->platform_execute_tuning(host, opcode); 193945251812SDong Aisheng return err; 194045251812SDong Aisheng } 194145251812SDong Aisheng 19424b6f37d3SRussell King ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 19434b6f37d3SRussell King ctrl |= SDHCI_CTRL_EXEC_TUNING; 194467d0d04aSVincent Yang if (host->quirks2 & SDHCI_QUIRK2_TUNING_WORK_AROUND) 194567d0d04aSVincent Yang ctrl |= SDHCI_CTRL_TUNED_CLK; 1946b513ea25SArindam Nath sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 1947b513ea25SArindam Nath 1948b513ea25SArindam Nath /* 1949b513ea25SArindam Nath * As per the Host Controller spec v3.00, tuning command 1950b513ea25SArindam Nath * generates Buffer Read Ready interrupt, so enable that. 1951b513ea25SArindam Nath * 1952b513ea25SArindam Nath * Note: The spec clearly says that when tuning sequence 1953b513ea25SArindam Nath * is being performed, the controller does not generate 1954b513ea25SArindam Nath * interrupts other than Buffer Read Ready interrupt. But 1955b513ea25SArindam Nath * to make sure we don't hit a controller bug, we _only_ 1956b513ea25SArindam Nath * enable Buffer Read Ready interrupt here. 1957b513ea25SArindam Nath */ 1958b537f94cSRussell King sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE); 1959b537f94cSRussell King sdhci_writel(host, SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE); 1960b513ea25SArindam Nath 1961b513ea25SArindam Nath /* 1962b513ea25SArindam Nath * Issue CMD19 repeatedly till Execute Tuning is set to 0 or the number 19631473bdd5SSimon Horman * of loops reaches 40 times. 1964b513ea25SArindam Nath */ 1965b513ea25SArindam Nath do { 1966b513ea25SArindam Nath struct mmc_command cmd = {0}; 196766fd8ad5SAdrian Hunter struct mmc_request mrq = {NULL}; 1968b513ea25SArindam Nath 1969069c9f14SGirish K S cmd.opcode = opcode; 1970b513ea25SArindam Nath cmd.arg = 0; 1971b513ea25SArindam Nath cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; 1972b513ea25SArindam Nath cmd.retries = 0; 1973b513ea25SArindam Nath cmd.data = NULL; 1974b513ea25SArindam Nath cmd.error = 0; 1975b513ea25SArindam Nath 19767ce45e95SAl Cooper if (tuning_loop_counter-- == 0) 19777ce45e95SAl Cooper break; 19787ce45e95SAl Cooper 1979b513ea25SArindam Nath mrq.cmd = &cmd; 1980b513ea25SArindam Nath host->mrq = &mrq; 1981b513ea25SArindam Nath 1982b513ea25SArindam Nath /* 1983b513ea25SArindam Nath * In response to CMD19, the card sends 64 bytes of tuning 1984b513ea25SArindam Nath * block to the Host Controller. So we set the block size 1985b513ea25SArindam Nath * to 64 here. 1986b513ea25SArindam Nath */ 1987069c9f14SGirish K S if (cmd.opcode == MMC_SEND_TUNING_BLOCK_HS200) { 1988069c9f14SGirish K S if (mmc->ios.bus_width == MMC_BUS_WIDTH_8) 1989069c9f14SGirish K S sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 128), 1990069c9f14SGirish K S SDHCI_BLOCK_SIZE); 1991069c9f14SGirish K S else if (mmc->ios.bus_width == MMC_BUS_WIDTH_4) 1992069c9f14SGirish K S sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), 1993069c9f14SGirish K S SDHCI_BLOCK_SIZE); 1994069c9f14SGirish K S } else { 1995069c9f14SGirish K S sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), 1996069c9f14SGirish K S SDHCI_BLOCK_SIZE); 1997069c9f14SGirish K S } 1998b513ea25SArindam Nath 1999b513ea25SArindam Nath /* 2000b513ea25SArindam Nath * The tuning block is sent by the card to the host controller. 2001b513ea25SArindam Nath * So we set the TRNS_READ bit in the Transfer Mode register. 2002b513ea25SArindam Nath * This also takes care of setting DMA Enable and Multi Block 2003b513ea25SArindam Nath * Select in the same register to 0. 2004b513ea25SArindam Nath */ 2005b513ea25SArindam Nath sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE); 2006b513ea25SArindam Nath 2007b513ea25SArindam Nath sdhci_send_command(host, &cmd); 2008b513ea25SArindam Nath 2009b513ea25SArindam Nath host->cmd = NULL; 2010b513ea25SArindam Nath host->mrq = NULL; 2011b513ea25SArindam Nath 20122b35bd83SAisheng Dong spin_unlock_irqrestore(&host->lock, flags); 2013b513ea25SArindam Nath /* Wait for Buffer Read Ready interrupt */ 2014b513ea25SArindam Nath wait_event_interruptible_timeout(host->buf_ready_int, 2015b513ea25SArindam Nath (host->tuning_done == 1), 2016b513ea25SArindam Nath msecs_to_jiffies(50)); 20172b35bd83SAisheng Dong spin_lock_irqsave(&host->lock, flags); 2018b513ea25SArindam Nath 2019b513ea25SArindam Nath if (!host->tuning_done) { 20202e4456f0SMarek Vasut pr_info(DRIVER_NAME ": Timeout waiting for Buffer Read Ready interrupt during tuning procedure, falling back to fixed sampling clock\n"); 2021b513ea25SArindam Nath ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 2022b513ea25SArindam Nath ctrl &= ~SDHCI_CTRL_TUNED_CLK; 2023b513ea25SArindam Nath ctrl &= ~SDHCI_CTRL_EXEC_TUNING; 2024b513ea25SArindam Nath sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 2025b513ea25SArindam Nath 2026b513ea25SArindam Nath err = -EIO; 2027b513ea25SArindam Nath goto out; 2028b513ea25SArindam Nath } 2029b513ea25SArindam Nath 2030b513ea25SArindam Nath host->tuning_done = 0; 2031b513ea25SArindam Nath 2032b513ea25SArindam Nath ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 2033197160d5SNick Sanders 2034197160d5SNick Sanders /* eMMC spec does not require a delay between tuning cycles */ 2035197160d5SNick Sanders if (opcode == MMC_SEND_TUNING_BLOCK) 2036b513ea25SArindam Nath mdelay(1); 2037b513ea25SArindam Nath } while (ctrl & SDHCI_CTRL_EXEC_TUNING); 2038b513ea25SArindam Nath 2039b513ea25SArindam Nath /* 2040b513ea25SArindam Nath * The Host Driver has exhausted the maximum number of loops allowed, 2041b513ea25SArindam Nath * so use fixed sampling frequency. 2042b513ea25SArindam Nath */ 20437ce45e95SAl Cooper if (tuning_loop_counter < 0) { 2044b513ea25SArindam Nath ctrl &= ~SDHCI_CTRL_TUNED_CLK; 2045b513ea25SArindam Nath sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 20467ce45e95SAl Cooper } 2047b513ea25SArindam Nath if (!(ctrl & SDHCI_CTRL_TUNED_CLK)) { 20482e4456f0SMarek Vasut pr_info(DRIVER_NAME ": Tuning procedure failed, falling back to fixed sampling clock\n"); 2049b513ea25SArindam Nath err = -EIO; 2050b513ea25SArindam Nath } 2051b513ea25SArindam Nath 2052b513ea25SArindam Nath out: 205338e40bf5SAdrian Hunter if (tuning_count) { 205466c39dfcSAdrian Hunter /* 205566c39dfcSAdrian Hunter * In case tuning fails, host controllers which support 205666c39dfcSAdrian Hunter * re-tuning can try tuning again at a later time, when the 205766c39dfcSAdrian Hunter * re-tuning timer expires. So for these controllers, we 205866c39dfcSAdrian Hunter * return 0. Since there might be other controllers who do not 205966c39dfcSAdrian Hunter * have this capability, we return error for them. 206066c39dfcSAdrian Hunter */ 206166c39dfcSAdrian Hunter err = 0; 2062cf2b5eeaSArindam Nath } 2063cf2b5eeaSArindam Nath 206466c39dfcSAdrian Hunter host->mmc->retune_period = err ? 0 : tuning_count; 2065cf2b5eeaSArindam Nath 2066b537f94cSRussell King sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); 2067b537f94cSRussell King sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); 2068d519c863SAdrian Hunter out_unlock: 20692b35bd83SAisheng Dong spin_unlock_irqrestore(&host->lock, flags); 2070b513ea25SArindam Nath return err; 2071b513ea25SArindam Nath } 2072b513ea25SArindam Nath 2073cb849648SAdrian Hunter static int sdhci_select_drive_strength(struct mmc_card *card, 2074cb849648SAdrian Hunter unsigned int max_dtr, int host_drv, 2075cb849648SAdrian Hunter int card_drv, int *drv_type) 2076cb849648SAdrian Hunter { 2077cb849648SAdrian Hunter struct sdhci_host *host = mmc_priv(card->host); 2078cb849648SAdrian Hunter 2079cb849648SAdrian Hunter if (!host->ops->select_drive_strength) 2080cb849648SAdrian Hunter return 0; 2081cb849648SAdrian Hunter 2082cb849648SAdrian Hunter return host->ops->select_drive_strength(host, card, max_dtr, host_drv, 2083cb849648SAdrian Hunter card_drv, drv_type); 2084cb849648SAdrian Hunter } 208552983382SKevin Liu 208652983382SKevin Liu static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable) 20874d55c5a1SArindam Nath { 20884d55c5a1SArindam Nath /* Host Controller v3.00 defines preset value registers */ 20894d55c5a1SArindam Nath if (host->version < SDHCI_SPEC_300) 20904d55c5a1SArindam Nath return; 20914d55c5a1SArindam Nath 20924d55c5a1SArindam Nath /* 20934d55c5a1SArindam Nath * We only enable or disable Preset Value if they are not already 20944d55c5a1SArindam Nath * enabled or disabled respectively. Otherwise, we bail out. 20954d55c5a1SArindam Nath */ 2096da91a8f9SRussell King if (host->preset_enabled != enable) { 2097da91a8f9SRussell King u16 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); 2098da91a8f9SRussell King 2099da91a8f9SRussell King if (enable) 21004d55c5a1SArindam Nath ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE; 2101da91a8f9SRussell King else 21024d55c5a1SArindam Nath ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE; 2103da91a8f9SRussell King 21044d55c5a1SArindam Nath sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2); 2105da91a8f9SRussell King 2106da91a8f9SRussell King if (enable) 2107da91a8f9SRussell King host->flags |= SDHCI_PV_ENABLED; 2108da91a8f9SRussell King else 210966fd8ad5SAdrian Hunter host->flags &= ~SDHCI_PV_ENABLED; 2110da91a8f9SRussell King 2111da91a8f9SRussell King host->preset_enabled = enable; 21124d55c5a1SArindam Nath } 211366fd8ad5SAdrian Hunter } 211466fd8ad5SAdrian Hunter 2115348487cbSHaibo Chen static void sdhci_post_req(struct mmc_host *mmc, struct mmc_request *mrq, 2116348487cbSHaibo Chen int err) 2117348487cbSHaibo Chen { 2118348487cbSHaibo Chen struct sdhci_host *host = mmc_priv(mmc); 2119348487cbSHaibo Chen struct mmc_data *data = mrq->data; 2120348487cbSHaibo Chen 2121f48f039cSRussell King if (data->host_cookie != COOKIE_UNMAPPED) 2122348487cbSHaibo Chen dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, 2123348487cbSHaibo Chen data->flags & MMC_DATA_WRITE ? 2124348487cbSHaibo Chen DMA_TO_DEVICE : DMA_FROM_DEVICE); 2125771a3dc2SRussell King 2126d31911b9SHaibo Chen data->host_cookie = COOKIE_UNMAPPED; 2127348487cbSHaibo Chen } 2128348487cbSHaibo Chen 2129348487cbSHaibo Chen static void sdhci_pre_req(struct mmc_host *mmc, struct mmc_request *mrq, 2130348487cbSHaibo Chen bool is_first_req) 2131348487cbSHaibo Chen { 2132348487cbSHaibo Chen struct sdhci_host *host = mmc_priv(mmc); 2133348487cbSHaibo Chen 2134d31911b9SHaibo Chen mrq->data->host_cookie = COOKIE_UNMAPPED; 2135348487cbSHaibo Chen 2136348487cbSHaibo Chen if (host->flags & SDHCI_REQ_USE_DMA) 213794538e51SRussell King sdhci_pre_dma_transfer(host, mrq->data, COOKIE_PRE_MAPPED); 2138348487cbSHaibo Chen } 2139348487cbSHaibo Chen 214071e69211SGuennadi Liakhovetski static void sdhci_card_event(struct mmc_host *mmc) 21411c6a0718SPierre Ossman { 214271e69211SGuennadi Liakhovetski struct sdhci_host *host = mmc_priv(mmc); 21431c6a0718SPierre Ossman unsigned long flags; 21442836766aSKrzysztof Kozlowski int present; 21451c6a0718SPierre Ossman 2146722e1280SChristian Daudt /* First check if client has provided their own card event */ 2147722e1280SChristian Daudt if (host->ops->card_event) 2148722e1280SChristian Daudt host->ops->card_event(host); 2149722e1280SChristian Daudt 2150d3940f27SAdrian Hunter present = mmc->ops->get_cd(mmc); 21512836766aSKrzysztof Kozlowski 21521c6a0718SPierre Ossman spin_lock_irqsave(&host->lock, flags); 21531c6a0718SPierre Ossman 215466fd8ad5SAdrian Hunter /* Check host->mrq first in case we are runtime suspended */ 21552836766aSKrzysztof Kozlowski if (host->mrq && !present) { 2156a3c76eb9SGirish K S pr_err("%s: Card removed during transfer!\n", 21571c6a0718SPierre Ossman mmc_hostname(host->mmc)); 2158a3c76eb9SGirish K S pr_err("%s: Resetting controller.\n", 21591c6a0718SPierre Ossman mmc_hostname(host->mmc)); 21601c6a0718SPierre Ossman 216103231f9bSRussell King sdhci_do_reset(host, SDHCI_RESET_CMD); 216203231f9bSRussell King sdhci_do_reset(host, SDHCI_RESET_DATA); 21631c6a0718SPierre Ossman 216417b0429dSPierre Ossman host->mrq->cmd->error = -ENOMEDIUM; 2165a6d3bdd5SAdrian Hunter sdhci_finish_mrq(host, host->mrq); 21661c6a0718SPierre Ossman } 21671c6a0718SPierre Ossman 21681c6a0718SPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 216971e69211SGuennadi Liakhovetski } 217071e69211SGuennadi Liakhovetski 217171e69211SGuennadi Liakhovetski static const struct mmc_host_ops sdhci_ops = { 217271e69211SGuennadi Liakhovetski .request = sdhci_request, 2173348487cbSHaibo Chen .post_req = sdhci_post_req, 2174348487cbSHaibo Chen .pre_req = sdhci_pre_req, 217571e69211SGuennadi Liakhovetski .set_ios = sdhci_set_ios, 217694144a46SKevin Liu .get_cd = sdhci_get_cd, 217771e69211SGuennadi Liakhovetski .get_ro = sdhci_get_ro, 217871e69211SGuennadi Liakhovetski .hw_reset = sdhci_hw_reset, 217971e69211SGuennadi Liakhovetski .enable_sdio_irq = sdhci_enable_sdio_irq, 218071e69211SGuennadi Liakhovetski .start_signal_voltage_switch = sdhci_start_signal_voltage_switch, 2181b5540ce1SAdrian Hunter .prepare_hs400_tuning = sdhci_prepare_hs400_tuning, 218271e69211SGuennadi Liakhovetski .execute_tuning = sdhci_execute_tuning, 2183cb849648SAdrian Hunter .select_drive_strength = sdhci_select_drive_strength, 218471e69211SGuennadi Liakhovetski .card_event = sdhci_card_event, 218520b92a30SKevin Liu .card_busy = sdhci_card_busy, 218671e69211SGuennadi Liakhovetski }; 218771e69211SGuennadi Liakhovetski 218871e69211SGuennadi Liakhovetski /*****************************************************************************\ 218971e69211SGuennadi Liakhovetski * * 219071e69211SGuennadi Liakhovetski * Tasklets * 219171e69211SGuennadi Liakhovetski * * 219271e69211SGuennadi Liakhovetski \*****************************************************************************/ 219371e69211SGuennadi Liakhovetski 21941c6a0718SPierre Ossman static void sdhci_tasklet_finish(unsigned long param) 21951c6a0718SPierre Ossman { 21961c6a0718SPierre Ossman struct sdhci_host *host; 21971c6a0718SPierre Ossman unsigned long flags; 21981c6a0718SPierre Ossman struct mmc_request *mrq; 21991c6a0718SPierre Ossman 22001c6a0718SPierre Ossman host = (struct sdhci_host*)param; 22011c6a0718SPierre Ossman 220266fd8ad5SAdrian Hunter spin_lock_irqsave(&host->lock, flags); 220366fd8ad5SAdrian Hunter 22040c9c99a7SChris Ball /* 22050c9c99a7SChris Ball * If this tasklet gets rescheduled while running, it will 22060c9c99a7SChris Ball * be run again afterwards but without any active request. 22070c9c99a7SChris Ball */ 220866fd8ad5SAdrian Hunter if (!host->mrq) { 220966fd8ad5SAdrian Hunter spin_unlock_irqrestore(&host->lock, flags); 22100c9c99a7SChris Ball return; 221166fd8ad5SAdrian Hunter } 22121c6a0718SPierre Ossman 22131c6a0718SPierre Ossman del_timer(&host->timer); 22141c6a0718SPierre Ossman 22151c6a0718SPierre Ossman mrq = host->mrq; 22161c6a0718SPierre Ossman 22171c6a0718SPierre Ossman /* 2218054cedffSRussell King * Always unmap the data buffers if they were mapped by 2219054cedffSRussell King * sdhci_prepare_data() whenever we finish with a request. 2220054cedffSRussell King * This avoids leaking DMA mappings on error. 2221054cedffSRussell King */ 2222054cedffSRussell King if (host->flags & SDHCI_REQ_USE_DMA) { 2223054cedffSRussell King struct mmc_data *data = mrq->data; 2224054cedffSRussell King 2225054cedffSRussell King if (data && data->host_cookie == COOKIE_MAPPED) { 2226054cedffSRussell King dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, 2227054cedffSRussell King (data->flags & MMC_DATA_READ) ? 2228054cedffSRussell King DMA_FROM_DEVICE : DMA_TO_DEVICE); 2229054cedffSRussell King data->host_cookie = COOKIE_UNMAPPED; 2230054cedffSRussell King } 2231054cedffSRussell King } 2232054cedffSRussell King 2233054cedffSRussell King /* 22341c6a0718SPierre Ossman * The controller needs a reset of internal state machines 22351c6a0718SPierre Ossman * upon error conditions. 22361c6a0718SPierre Ossman */ 22370cc563ceSAdrian Hunter if (sdhci_needs_reset(host, mrq)) { 22381c6a0718SPierre Ossman /* Some controllers need this kick or reset won't work here */ 22398213af3bSAndy Shevchenko if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET) 22401c6a0718SPierre Ossman /* This is to force an update */ 22411771059cSRussell King host->ops->set_clock(host, host->clock); 22421c6a0718SPierre Ossman 22431c6a0718SPierre Ossman /* Spec says we should do both at the same time, but Ricoh 22441c6a0718SPierre Ossman controllers do not like that. */ 224503231f9bSRussell King sdhci_do_reset(host, SDHCI_RESET_CMD); 224603231f9bSRussell King sdhci_do_reset(host, SDHCI_RESET_DATA); 2247ed1563deSAdrian Hunter 2248ed1563deSAdrian Hunter host->pending_reset = false; 22491c6a0718SPierre Ossman } 22501c6a0718SPierre Ossman 22511c6a0718SPierre Ossman host->mrq = NULL; 22521c6a0718SPierre Ossman 2253061d17a6SAdrian Hunter sdhci_led_deactivate(host); 22541c6a0718SPierre Ossman 22551c6a0718SPierre Ossman mmiowb(); 22561c6a0718SPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 22571c6a0718SPierre Ossman 22581c6a0718SPierre Ossman mmc_request_done(host->mmc, mrq); 22591c6a0718SPierre Ossman } 22601c6a0718SPierre Ossman 22611c6a0718SPierre Ossman static void sdhci_timeout_timer(unsigned long data) 22621c6a0718SPierre Ossman { 22631c6a0718SPierre Ossman struct sdhci_host *host; 22641c6a0718SPierre Ossman unsigned long flags; 22651c6a0718SPierre Ossman 22661c6a0718SPierre Ossman host = (struct sdhci_host*)data; 22671c6a0718SPierre Ossman 22681c6a0718SPierre Ossman spin_lock_irqsave(&host->lock, flags); 22691c6a0718SPierre Ossman 22701c6a0718SPierre Ossman if (host->mrq) { 22712e4456f0SMarek Vasut pr_err("%s: Timeout waiting for hardware interrupt.\n", 22722e4456f0SMarek Vasut mmc_hostname(host->mmc)); 22731c6a0718SPierre Ossman sdhci_dumpregs(host); 22741c6a0718SPierre Ossman 22751c6a0718SPierre Ossman if (host->data) { 227617b0429dSPierre Ossman host->data->error = -ETIMEDOUT; 22771c6a0718SPierre Ossman sdhci_finish_data(host); 22781c6a0718SPierre Ossman } else { 22791c6a0718SPierre Ossman if (host->cmd) 228017b0429dSPierre Ossman host->cmd->error = -ETIMEDOUT; 22811c6a0718SPierre Ossman else 228217b0429dSPierre Ossman host->mrq->cmd->error = -ETIMEDOUT; 22831c6a0718SPierre Ossman 2284a6d3bdd5SAdrian Hunter sdhci_finish_mrq(host, host->mrq); 22851c6a0718SPierre Ossman } 22861c6a0718SPierre Ossman } 22871c6a0718SPierre Ossman 22881c6a0718SPierre Ossman mmiowb(); 22891c6a0718SPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 22901c6a0718SPierre Ossman } 22911c6a0718SPierre Ossman 22921c6a0718SPierre Ossman /*****************************************************************************\ 22931c6a0718SPierre Ossman * * 22941c6a0718SPierre Ossman * Interrupt handling * 22951c6a0718SPierre Ossman * * 22961c6a0718SPierre Ossman \*****************************************************************************/ 22971c6a0718SPierre Ossman 229861541397SAdrian Hunter static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *mask) 22991c6a0718SPierre Ossman { 23001c6a0718SPierre Ossman if (!host->cmd) { 2301ed1563deSAdrian Hunter /* 2302ed1563deSAdrian Hunter * SDHCI recovers from errors by resetting the cmd and data 2303ed1563deSAdrian Hunter * circuits. Until that is done, there very well might be more 2304ed1563deSAdrian Hunter * interrupts, so ignore them in that case. 2305ed1563deSAdrian Hunter */ 2306ed1563deSAdrian Hunter if (host->pending_reset) 2307ed1563deSAdrian Hunter return; 23082e4456f0SMarek Vasut pr_err("%s: Got command interrupt 0x%08x even though no command operation was in progress.\n", 2309b67ac3f3SPierre Ossman mmc_hostname(host->mmc), (unsigned)intmask); 23101c6a0718SPierre Ossman sdhci_dumpregs(host); 23111c6a0718SPierre Ossman return; 23121c6a0718SPierre Ossman } 23131c6a0718SPierre Ossman 2314ec014cbaSRussell King if (intmask & (SDHCI_INT_TIMEOUT | SDHCI_INT_CRC | 2315ec014cbaSRussell King SDHCI_INT_END_BIT | SDHCI_INT_INDEX)) { 23161c6a0718SPierre Ossman if (intmask & SDHCI_INT_TIMEOUT) 231717b0429dSPierre Ossman host->cmd->error = -ETIMEDOUT; 2318ec014cbaSRussell King else 231917b0429dSPierre Ossman host->cmd->error = -EILSEQ; 23201c6a0718SPierre Ossman 232171fcbda0SRussell King /* 232271fcbda0SRussell King * If this command initiates a data phase and a response 232371fcbda0SRussell King * CRC error is signalled, the card can start transferring 232471fcbda0SRussell King * data - the card may have received the command without 232571fcbda0SRussell King * error. We must not terminate the mmc_request early. 232671fcbda0SRussell King * 232771fcbda0SRussell King * If the card did not receive the command or returned an 232871fcbda0SRussell King * error which prevented it sending data, the data phase 232971fcbda0SRussell King * will time out. 233071fcbda0SRussell King */ 233171fcbda0SRussell King if (host->cmd->data && 233271fcbda0SRussell King (intmask & (SDHCI_INT_CRC | SDHCI_INT_TIMEOUT)) == 233371fcbda0SRussell King SDHCI_INT_CRC) { 233471fcbda0SRussell King host->cmd = NULL; 233571fcbda0SRussell King return; 233671fcbda0SRussell King } 233771fcbda0SRussell King 2338a6d3bdd5SAdrian Hunter sdhci_finish_mrq(host, host->cmd->mrq); 2339e809517fSPierre Ossman return; 2340e809517fSPierre Ossman } 2341e809517fSPierre Ossman 23426bde8681SAdrian Hunter if ((host->quirks2 & SDHCI_QUIRK2_STOP_WITH_TC) && 23436bde8681SAdrian Hunter !(host->cmd->flags & MMC_RSP_BUSY) && !host->data && 23446bde8681SAdrian Hunter host->cmd->opcode == MMC_STOP_TRANSMISSION) 234561541397SAdrian Hunter *mask &= ~SDHCI_INT_DATA_END; 2346e809517fSPierre Ossman 2347e809517fSPierre Ossman if (intmask & SDHCI_INT_RESPONSE) 234843b58b36SPierre Ossman sdhci_finish_command(host); 23491c6a0718SPierre Ossman } 23501c6a0718SPierre Ossman 23510957c333SGeorge G. Davis #ifdef CONFIG_MMC_DEBUG 235208621b18SAdrian Hunter static void sdhci_adma_show_error(struct sdhci_host *host) 23536882a8c0SBen Dooks { 23546882a8c0SBen Dooks const char *name = mmc_hostname(host->mmc); 23551c3d5f6dSAdrian Hunter void *desc = host->adma_table; 23566882a8c0SBen Dooks 23576882a8c0SBen Dooks sdhci_dumpregs(host); 23586882a8c0SBen Dooks 23596882a8c0SBen Dooks while (true) { 2360e57a5f61SAdrian Hunter struct sdhci_adma2_64_desc *dma_desc = desc; 23616882a8c0SBen Dooks 2362e57a5f61SAdrian Hunter if (host->flags & SDHCI_USE_64_BIT_DMA) 2363e57a5f61SAdrian Hunter DBG("%s: %p: DMA 0x%08x%08x, LEN 0x%04x, Attr=0x%02x\n", 2364e57a5f61SAdrian Hunter name, desc, le32_to_cpu(dma_desc->addr_hi), 2365e57a5f61SAdrian Hunter le32_to_cpu(dma_desc->addr_lo), 2366e57a5f61SAdrian Hunter le16_to_cpu(dma_desc->len), 2367e57a5f61SAdrian Hunter le16_to_cpu(dma_desc->cmd)); 2368e57a5f61SAdrian Hunter else 23696882a8c0SBen Dooks DBG("%s: %p: DMA 0x%08x, LEN 0x%04x, Attr=0x%02x\n", 2370e57a5f61SAdrian Hunter name, desc, le32_to_cpu(dma_desc->addr_lo), 23710545230fSAdrian Hunter le16_to_cpu(dma_desc->len), 23720545230fSAdrian Hunter le16_to_cpu(dma_desc->cmd)); 23736882a8c0SBen Dooks 237476fe379aSAdrian Hunter desc += host->desc_sz; 23756882a8c0SBen Dooks 23760545230fSAdrian Hunter if (dma_desc->cmd & cpu_to_le16(ADMA2_END)) 23776882a8c0SBen Dooks break; 23786882a8c0SBen Dooks } 23796882a8c0SBen Dooks } 23806882a8c0SBen Dooks #else 238108621b18SAdrian Hunter static void sdhci_adma_show_error(struct sdhci_host *host) { } 23826882a8c0SBen Dooks #endif 23836882a8c0SBen Dooks 23841c6a0718SPierre Ossman static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) 23851c6a0718SPierre Ossman { 2386069c9f14SGirish K S u32 command; 23871c6a0718SPierre Ossman 2388b513ea25SArindam Nath /* CMD19 generates _only_ Buffer Read Ready interrupt */ 2389b513ea25SArindam Nath if (intmask & SDHCI_INT_DATA_AVAIL) { 2390069c9f14SGirish K S command = SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)); 2391069c9f14SGirish K S if (command == MMC_SEND_TUNING_BLOCK || 2392069c9f14SGirish K S command == MMC_SEND_TUNING_BLOCK_HS200) { 2393b513ea25SArindam Nath host->tuning_done = 1; 2394b513ea25SArindam Nath wake_up(&host->buf_ready_int); 2395b513ea25SArindam Nath return; 2396b513ea25SArindam Nath } 2397b513ea25SArindam Nath } 2398b513ea25SArindam Nath 23991c6a0718SPierre Ossman if (!host->data) { 24007c89a3d9SAdrian Hunter struct mmc_command *data_cmd = host->data_cmd; 24017c89a3d9SAdrian Hunter 24027c89a3d9SAdrian Hunter if (data_cmd) 24037c89a3d9SAdrian Hunter host->data_cmd = NULL; 24047c89a3d9SAdrian Hunter 24051c6a0718SPierre Ossman /* 2406e809517fSPierre Ossman * The "data complete" interrupt is also used to 2407e809517fSPierre Ossman * indicate that a busy state has ended. See comment 2408e809517fSPierre Ossman * above in sdhci_cmd_irq(). 24091c6a0718SPierre Ossman */ 24107c89a3d9SAdrian Hunter if (data_cmd && (data_cmd->flags & MMC_RSP_BUSY)) { 2411c5abd5e8SMatthieu CASTET if (intmask & SDHCI_INT_DATA_TIMEOUT) { 24127c89a3d9SAdrian Hunter data_cmd->error = -ETIMEDOUT; 2413a6d3bdd5SAdrian Hunter sdhci_finish_mrq(host, data_cmd->mrq); 2414c5abd5e8SMatthieu CASTET return; 2415c5abd5e8SMatthieu CASTET } 2416e809517fSPierre Ossman if (intmask & SDHCI_INT_DATA_END) { 2417e99783a4SChanho Min /* 2418e99783a4SChanho Min * Some cards handle busy-end interrupt 2419e99783a4SChanho Min * before the command completed, so make 2420e99783a4SChanho Min * sure we do things in the proper order. 2421e99783a4SChanho Min */ 2422ea968023SAdrian Hunter if (host->cmd == data_cmd) 2423ea968023SAdrian Hunter return; 2424ea968023SAdrian Hunter 2425a6d3bdd5SAdrian Hunter sdhci_finish_mrq(host, data_cmd->mrq); 24261c6a0718SPierre Ossman return; 2427e809517fSPierre Ossman } 2428e809517fSPierre Ossman } 24291c6a0718SPierre Ossman 2430ed1563deSAdrian Hunter /* 2431ed1563deSAdrian Hunter * SDHCI recovers from errors by resetting the cmd and data 2432ed1563deSAdrian Hunter * circuits. Until that is done, there very well might be more 2433ed1563deSAdrian Hunter * interrupts, so ignore them in that case. 2434ed1563deSAdrian Hunter */ 2435ed1563deSAdrian Hunter if (host->pending_reset) 2436ed1563deSAdrian Hunter return; 2437ed1563deSAdrian Hunter 24382e4456f0SMarek Vasut pr_err("%s: Got data interrupt 0x%08x even though no data operation was in progress.\n", 2439b67ac3f3SPierre Ossman mmc_hostname(host->mmc), (unsigned)intmask); 24401c6a0718SPierre Ossman sdhci_dumpregs(host); 24411c6a0718SPierre Ossman 24421c6a0718SPierre Ossman return; 24431c6a0718SPierre Ossman } 24441c6a0718SPierre Ossman 24451c6a0718SPierre Ossman if (intmask & SDHCI_INT_DATA_TIMEOUT) 244617b0429dSPierre Ossman host->data->error = -ETIMEDOUT; 244722113efdSAries Lee else if (intmask & SDHCI_INT_DATA_END_BIT) 244822113efdSAries Lee host->data->error = -EILSEQ; 244922113efdSAries Lee else if ((intmask & SDHCI_INT_DATA_CRC) && 245022113efdSAries Lee SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)) 245122113efdSAries Lee != MMC_BUS_TEST_R) 245217b0429dSPierre Ossman host->data->error = -EILSEQ; 24536882a8c0SBen Dooks else if (intmask & SDHCI_INT_ADMA_ERROR) { 2454a3c76eb9SGirish K S pr_err("%s: ADMA error\n", mmc_hostname(host->mmc)); 245508621b18SAdrian Hunter sdhci_adma_show_error(host); 24562134a922SPierre Ossman host->data->error = -EIO; 2457a4071fbbSHaijun Zhang if (host->ops->adma_workaround) 2458a4071fbbSHaijun Zhang host->ops->adma_workaround(host, intmask); 24596882a8c0SBen Dooks } 24601c6a0718SPierre Ossman 246117b0429dSPierre Ossman if (host->data->error) 24621c6a0718SPierre Ossman sdhci_finish_data(host); 24631c6a0718SPierre Ossman else { 24641c6a0718SPierre Ossman if (intmask & (SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL)) 24651c6a0718SPierre Ossman sdhci_transfer_pio(host); 24661c6a0718SPierre Ossman 24676ba736a1SPierre Ossman /* 24686ba736a1SPierre Ossman * We currently don't do anything fancy with DMA 24696ba736a1SPierre Ossman * boundaries, but as we can't disable the feature 24706ba736a1SPierre Ossman * we need to at least restart the transfer. 2471f6a03cbfSMikko Vinni * 2472f6a03cbfSMikko Vinni * According to the spec sdhci_readl(host, SDHCI_DMA_ADDRESS) 2473f6a03cbfSMikko Vinni * should return a valid address to continue from, but as 2474f6a03cbfSMikko Vinni * some controllers are faulty, don't trust them. 24756ba736a1SPierre Ossman */ 2476f6a03cbfSMikko Vinni if (intmask & SDHCI_INT_DMA_END) { 2477f6a03cbfSMikko Vinni u32 dmastart, dmanow; 2478f6a03cbfSMikko Vinni dmastart = sg_dma_address(host->data->sg); 2479f6a03cbfSMikko Vinni dmanow = dmastart + host->data->bytes_xfered; 2480f6a03cbfSMikko Vinni /* 2481f6a03cbfSMikko Vinni * Force update to the next DMA block boundary. 2482f6a03cbfSMikko Vinni */ 2483f6a03cbfSMikko Vinni dmanow = (dmanow & 2484f6a03cbfSMikko Vinni ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) + 2485f6a03cbfSMikko Vinni SDHCI_DEFAULT_BOUNDARY_SIZE; 2486f6a03cbfSMikko Vinni host->data->bytes_xfered = dmanow - dmastart; 2487f6a03cbfSMikko Vinni DBG("%s: DMA base 0x%08x, transferred 0x%06x bytes," 2488f6a03cbfSMikko Vinni " next 0x%08x\n", 2489f6a03cbfSMikko Vinni mmc_hostname(host->mmc), dmastart, 2490f6a03cbfSMikko Vinni host->data->bytes_xfered, dmanow); 2491f6a03cbfSMikko Vinni sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS); 2492f6a03cbfSMikko Vinni } 24936ba736a1SPierre Ossman 2494e538fbe8SPierre Ossman if (intmask & SDHCI_INT_DATA_END) { 24957c89a3d9SAdrian Hunter if (host->cmd == host->data_cmd) { 2496e538fbe8SPierre Ossman /* 2497e538fbe8SPierre Ossman * Data managed to finish before the 2498e538fbe8SPierre Ossman * command completed. Make sure we do 2499e538fbe8SPierre Ossman * things in the proper order. 2500e538fbe8SPierre Ossman */ 2501e538fbe8SPierre Ossman host->data_early = 1; 2502e538fbe8SPierre Ossman } else { 25031c6a0718SPierre Ossman sdhci_finish_data(host); 25041c6a0718SPierre Ossman } 25051c6a0718SPierre Ossman } 2506e538fbe8SPierre Ossman } 2507e538fbe8SPierre Ossman } 25081c6a0718SPierre Ossman 25091c6a0718SPierre Ossman static irqreturn_t sdhci_irq(int irq, void *dev_id) 25101c6a0718SPierre Ossman { 2511781e989cSRussell King irqreturn_t result = IRQ_NONE; 25121c6a0718SPierre Ossman struct sdhci_host *host = dev_id; 251341005003SRussell King u32 intmask, mask, unexpected = 0; 2514781e989cSRussell King int max_loops = 16; 25151c6a0718SPierre Ossman 25161c6a0718SPierre Ossman spin_lock(&host->lock); 25171c6a0718SPierre Ossman 2518be138554SRussell King if (host->runtime_suspended && !sdhci_sdio_irq_enabled(host)) { 251966fd8ad5SAdrian Hunter spin_unlock(&host->lock); 2520655bca76SAdrian Hunter return IRQ_NONE; 252166fd8ad5SAdrian Hunter } 252266fd8ad5SAdrian Hunter 25234e4141a5SAnton Vorontsov intmask = sdhci_readl(host, SDHCI_INT_STATUS); 25241c6a0718SPierre Ossman if (!intmask || intmask == 0xffffffff) { 25251c6a0718SPierre Ossman result = IRQ_NONE; 25261c6a0718SPierre Ossman goto out; 25271c6a0718SPierre Ossman } 25281c6a0718SPierre Ossman 252941005003SRussell King do { 253041005003SRussell King /* Clear selected interrupts. */ 253141005003SRussell King mask = intmask & (SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK | 253241005003SRussell King SDHCI_INT_BUS_POWER); 253341005003SRussell King sdhci_writel(host, mask, SDHCI_INT_STATUS); 253441005003SRussell King 2535b69c9058SPierre Ossman DBG("*** %s got interrupt: 0x%08x\n", 2536b69c9058SPierre Ossman mmc_hostname(host->mmc), intmask); 25371c6a0718SPierre Ossman 25381c6a0718SPierre Ossman if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) { 2539d25928d1SShawn Guo u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) & 2540d25928d1SShawn Guo SDHCI_CARD_PRESENT; 2541d25928d1SShawn Guo 2542d25928d1SShawn Guo /* 254341005003SRussell King * There is a observation on i.mx esdhc. INSERT 254441005003SRussell King * bit will be immediately set again when it gets 254541005003SRussell King * cleared, if a card is inserted. We have to mask 254641005003SRussell King * the irq to prevent interrupt storm which will 254741005003SRussell King * freeze the system. And the REMOVE gets the 254841005003SRussell King * same situation. 2549d25928d1SShawn Guo * 255041005003SRussell King * More testing are needed here to ensure it works 255141005003SRussell King * for other platforms though. 2552d25928d1SShawn Guo */ 2553b537f94cSRussell King host->ier &= ~(SDHCI_INT_CARD_INSERT | 2554d25928d1SShawn Guo SDHCI_INT_CARD_REMOVE); 2555b537f94cSRussell King host->ier |= present ? SDHCI_INT_CARD_REMOVE : 2556b537f94cSRussell King SDHCI_INT_CARD_INSERT; 2557b537f94cSRussell King sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); 2558b537f94cSRussell King sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); 2559d25928d1SShawn Guo 25604e4141a5SAnton Vorontsov sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT | 25614e4141a5SAnton Vorontsov SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS); 25623560db8eSRussell King 25633560db8eSRussell King host->thread_isr |= intmask & (SDHCI_INT_CARD_INSERT | 25643560db8eSRussell King SDHCI_INT_CARD_REMOVE); 25653560db8eSRussell King result = IRQ_WAKE_THREAD; 25661c6a0718SPierre Ossman } 25671c6a0718SPierre Ossman 256841005003SRussell King if (intmask & SDHCI_INT_CMD_MASK) 256961541397SAdrian Hunter sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK, 257061541397SAdrian Hunter &intmask); 25711c6a0718SPierre Ossman 257241005003SRussell King if (intmask & SDHCI_INT_DATA_MASK) 25731c6a0718SPierre Ossman sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK); 25741c6a0718SPierre Ossman 257541005003SRussell King if (intmask & SDHCI_INT_BUS_POWER) 2576a3c76eb9SGirish K S pr_err("%s: Card is consuming too much power!\n", 25771c6a0718SPierre Ossman mmc_hostname(host->mmc)); 25781c6a0718SPierre Ossman 2579781e989cSRussell King if (intmask & SDHCI_INT_CARD_INT) { 2580781e989cSRussell King sdhci_enable_sdio_irq_nolock(host, false); 2581781e989cSRussell King host->thread_isr |= SDHCI_INT_CARD_INT; 2582781e989cSRussell King result = IRQ_WAKE_THREAD; 2583781e989cSRussell King } 2584f75979b7SPierre Ossman 258541005003SRussell King intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE | 258641005003SRussell King SDHCI_INT_CMD_MASK | SDHCI_INT_DATA_MASK | 258741005003SRussell King SDHCI_INT_ERROR | SDHCI_INT_BUS_POWER | 258841005003SRussell King SDHCI_INT_CARD_INT); 2589f75979b7SPierre Ossman 25901c6a0718SPierre Ossman if (intmask) { 25916379b237SAlexander Stein unexpected |= intmask; 25924e4141a5SAnton Vorontsov sdhci_writel(host, intmask, SDHCI_INT_STATUS); 25931c6a0718SPierre Ossman } 25941c6a0718SPierre Ossman 2595781e989cSRussell King if (result == IRQ_NONE) 25961c6a0718SPierre Ossman result = IRQ_HANDLED; 25971c6a0718SPierre Ossman 25986379b237SAlexander Stein intmask = sdhci_readl(host, SDHCI_INT_STATUS); 259941005003SRussell King } while (intmask && --max_loops); 26001c6a0718SPierre Ossman out: 26011c6a0718SPierre Ossman spin_unlock(&host->lock); 26021c6a0718SPierre Ossman 26036379b237SAlexander Stein if (unexpected) { 26046379b237SAlexander Stein pr_err("%s: Unexpected interrupt 0x%08x.\n", 26056379b237SAlexander Stein mmc_hostname(host->mmc), unexpected); 26066379b237SAlexander Stein sdhci_dumpregs(host); 26076379b237SAlexander Stein } 2608f75979b7SPierre Ossman 26091c6a0718SPierre Ossman return result; 26101c6a0718SPierre Ossman } 26111c6a0718SPierre Ossman 2612781e989cSRussell King static irqreturn_t sdhci_thread_irq(int irq, void *dev_id) 2613781e989cSRussell King { 2614781e989cSRussell King struct sdhci_host *host = dev_id; 2615781e989cSRussell King unsigned long flags; 2616781e989cSRussell King u32 isr; 2617781e989cSRussell King 2618781e989cSRussell King spin_lock_irqsave(&host->lock, flags); 2619781e989cSRussell King isr = host->thread_isr; 2620781e989cSRussell King host->thread_isr = 0; 2621781e989cSRussell King spin_unlock_irqrestore(&host->lock, flags); 2622781e989cSRussell King 26233560db8eSRussell King if (isr & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) { 2624d3940f27SAdrian Hunter struct mmc_host *mmc = host->mmc; 2625d3940f27SAdrian Hunter 2626d3940f27SAdrian Hunter mmc->ops->card_event(mmc); 2627d3940f27SAdrian Hunter mmc_detect_change(mmc, msecs_to_jiffies(200)); 26283560db8eSRussell King } 26293560db8eSRussell King 2630781e989cSRussell King if (isr & SDHCI_INT_CARD_INT) { 2631781e989cSRussell King sdio_run_irqs(host->mmc); 2632781e989cSRussell King 2633781e989cSRussell King spin_lock_irqsave(&host->lock, flags); 2634781e989cSRussell King if (host->flags & SDHCI_SDIO_IRQ_ENABLED) 2635781e989cSRussell King sdhci_enable_sdio_irq_nolock(host, true); 2636781e989cSRussell King spin_unlock_irqrestore(&host->lock, flags); 2637781e989cSRussell King } 2638781e989cSRussell King 2639781e989cSRussell King return isr ? IRQ_HANDLED : IRQ_NONE; 2640781e989cSRussell King } 2641781e989cSRussell King 26421c6a0718SPierre Ossman /*****************************************************************************\ 26431c6a0718SPierre Ossman * * 26441c6a0718SPierre Ossman * Suspend/resume * 26451c6a0718SPierre Ossman * * 26461c6a0718SPierre Ossman \*****************************************************************************/ 26471c6a0718SPierre Ossman 26481c6a0718SPierre Ossman #ifdef CONFIG_PM 264984d62605SLudovic Desroches /* 265084d62605SLudovic Desroches * To enable wakeup events, the corresponding events have to be enabled in 265184d62605SLudovic Desroches * the Interrupt Status Enable register too. See 'Table 1-6: Wakeup Signal 265284d62605SLudovic Desroches * Table' in the SD Host Controller Standard Specification. 265384d62605SLudovic Desroches * It is useless to restore SDHCI_INT_ENABLE state in 265484d62605SLudovic Desroches * sdhci_disable_irq_wakeups() since it will be set by 265584d62605SLudovic Desroches * sdhci_enable_card_detection() or sdhci_init(). 265684d62605SLudovic Desroches */ 2657ad080d79SKevin Liu void sdhci_enable_irq_wakeups(struct sdhci_host *host) 2658ad080d79SKevin Liu { 2659ad080d79SKevin Liu u8 val; 2660ad080d79SKevin Liu u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE 2661ad080d79SKevin Liu | SDHCI_WAKE_ON_INT; 266284d62605SLudovic Desroches u32 irq_val = SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE | 266384d62605SLudovic Desroches SDHCI_INT_CARD_INT; 2664ad080d79SKevin Liu 2665ad080d79SKevin Liu val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); 2666ad080d79SKevin Liu val |= mask ; 2667ad080d79SKevin Liu /* Avoid fake wake up */ 266884d62605SLudovic Desroches if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) { 2669ad080d79SKevin Liu val &= ~(SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE); 267084d62605SLudovic Desroches irq_val &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE); 267184d62605SLudovic Desroches } 2672ad080d79SKevin Liu sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL); 267384d62605SLudovic Desroches sdhci_writel(host, irq_val, SDHCI_INT_ENABLE); 2674ad080d79SKevin Liu } 2675ad080d79SKevin Liu EXPORT_SYMBOL_GPL(sdhci_enable_irq_wakeups); 2676ad080d79SKevin Liu 26770b10f478SFabio Estevam static void sdhci_disable_irq_wakeups(struct sdhci_host *host) 2678ad080d79SKevin Liu { 2679ad080d79SKevin Liu u8 val; 2680ad080d79SKevin Liu u8 mask = SDHCI_WAKE_ON_INSERT | SDHCI_WAKE_ON_REMOVE 2681ad080d79SKevin Liu | SDHCI_WAKE_ON_INT; 2682ad080d79SKevin Liu 2683ad080d79SKevin Liu val = sdhci_readb(host, SDHCI_WAKE_UP_CONTROL); 2684ad080d79SKevin Liu val &= ~mask; 2685ad080d79SKevin Liu sdhci_writeb(host, val, SDHCI_WAKE_UP_CONTROL); 2686ad080d79SKevin Liu } 26871c6a0718SPierre Ossman 268829495aa0SManuel Lauss int sdhci_suspend_host(struct sdhci_host *host) 26891c6a0718SPierre Ossman { 26907260cf5eSAnton Vorontsov sdhci_disable_card_detection(host); 26917260cf5eSAnton Vorontsov 269266c39dfcSAdrian Hunter mmc_retune_timer_stop(host->mmc); 269366c39dfcSAdrian Hunter mmc_retune_needed(host->mmc); 2694cf2b5eeaSArindam Nath 2695ad080d79SKevin Liu if (!device_may_wakeup(mmc_dev(host->mmc))) { 2696b537f94cSRussell King host->ier = 0; 2697b537f94cSRussell King sdhci_writel(host, 0, SDHCI_INT_ENABLE); 2698b537f94cSRussell King sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE); 2699b8c86fc5SPierre Ossman free_irq(host->irq, host); 2700ad080d79SKevin Liu } else { 2701ad080d79SKevin Liu sdhci_enable_irq_wakeups(host); 2702ad080d79SKevin Liu enable_irq_wake(host->irq); 2703ad080d79SKevin Liu } 27044ee14ec6SUlf Hansson return 0; 2705b8c86fc5SPierre Ossman } 2706b8c86fc5SPierre Ossman 2707b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_suspend_host); 2708b8c86fc5SPierre Ossman 2709b8c86fc5SPierre Ossman int sdhci_resume_host(struct sdhci_host *host) 2710b8c86fc5SPierre Ossman { 2711d3940f27SAdrian Hunter struct mmc_host *mmc = host->mmc; 27124ee14ec6SUlf Hansson int ret = 0; 2713b8c86fc5SPierre Ossman 2714a13abc7bSRichard Röjfors if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { 2715b8c86fc5SPierre Ossman if (host->ops->enable_dma) 2716b8c86fc5SPierre Ossman host->ops->enable_dma(host); 2717b8c86fc5SPierre Ossman } 2718b8c86fc5SPierre Ossman 27196308d290SAdrian Hunter if ((host->mmc->pm_flags & MMC_PM_KEEP_POWER) && 27206308d290SAdrian Hunter (host->quirks2 & SDHCI_QUIRK2_HOST_OFF_CARD_ON)) { 27216308d290SAdrian Hunter /* Card keeps power but host controller does not */ 27226308d290SAdrian Hunter sdhci_init(host, 0); 27236308d290SAdrian Hunter host->pwr = 0; 27246308d290SAdrian Hunter host->clock = 0; 2725d3940f27SAdrian Hunter mmc->ops->set_ios(mmc, &mmc->ios); 27266308d290SAdrian Hunter } else { 27272f4cbb3dSNicolas Pitre sdhci_init(host, (host->mmc->pm_flags & MMC_PM_KEEP_POWER)); 27281c6a0718SPierre Ossman mmiowb(); 27296308d290SAdrian Hunter } 2730b8c86fc5SPierre Ossman 273114a7b416SHaibo Chen if (!device_may_wakeup(mmc_dev(host->mmc))) { 273214a7b416SHaibo Chen ret = request_threaded_irq(host->irq, sdhci_irq, 273314a7b416SHaibo Chen sdhci_thread_irq, IRQF_SHARED, 273414a7b416SHaibo Chen mmc_hostname(host->mmc), host); 273514a7b416SHaibo Chen if (ret) 273614a7b416SHaibo Chen return ret; 273714a7b416SHaibo Chen } else { 273814a7b416SHaibo Chen sdhci_disable_irq_wakeups(host); 273914a7b416SHaibo Chen disable_irq_wake(host->irq); 274014a7b416SHaibo Chen } 274114a7b416SHaibo Chen 27427260cf5eSAnton Vorontsov sdhci_enable_card_detection(host); 27437260cf5eSAnton Vorontsov 27442f4cbb3dSNicolas Pitre return ret; 27451c6a0718SPierre Ossman } 27461c6a0718SPierre Ossman 2747b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_resume_host); 274866fd8ad5SAdrian Hunter 274966fd8ad5SAdrian Hunter int sdhci_runtime_suspend_host(struct sdhci_host *host) 275066fd8ad5SAdrian Hunter { 275166fd8ad5SAdrian Hunter unsigned long flags; 275266fd8ad5SAdrian Hunter 275366c39dfcSAdrian Hunter mmc_retune_timer_stop(host->mmc); 275466c39dfcSAdrian Hunter mmc_retune_needed(host->mmc); 275566fd8ad5SAdrian Hunter 275666fd8ad5SAdrian Hunter spin_lock_irqsave(&host->lock, flags); 2757b537f94cSRussell King host->ier &= SDHCI_INT_CARD_INT; 2758b537f94cSRussell King sdhci_writel(host, host->ier, SDHCI_INT_ENABLE); 2759b537f94cSRussell King sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE); 276066fd8ad5SAdrian Hunter spin_unlock_irqrestore(&host->lock, flags); 276166fd8ad5SAdrian Hunter 2762781e989cSRussell King synchronize_hardirq(host->irq); 276366fd8ad5SAdrian Hunter 276466fd8ad5SAdrian Hunter spin_lock_irqsave(&host->lock, flags); 276566fd8ad5SAdrian Hunter host->runtime_suspended = true; 276666fd8ad5SAdrian Hunter spin_unlock_irqrestore(&host->lock, flags); 276766fd8ad5SAdrian Hunter 27688a125badSMarkus Pargmann return 0; 276966fd8ad5SAdrian Hunter } 277066fd8ad5SAdrian Hunter EXPORT_SYMBOL_GPL(sdhci_runtime_suspend_host); 277166fd8ad5SAdrian Hunter 277266fd8ad5SAdrian Hunter int sdhci_runtime_resume_host(struct sdhci_host *host) 277366fd8ad5SAdrian Hunter { 2774d3940f27SAdrian Hunter struct mmc_host *mmc = host->mmc; 277566fd8ad5SAdrian Hunter unsigned long flags; 27768a125badSMarkus Pargmann int host_flags = host->flags; 277766fd8ad5SAdrian Hunter 277866fd8ad5SAdrian Hunter if (host_flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { 277966fd8ad5SAdrian Hunter if (host->ops->enable_dma) 278066fd8ad5SAdrian Hunter host->ops->enable_dma(host); 278166fd8ad5SAdrian Hunter } 278266fd8ad5SAdrian Hunter 278366fd8ad5SAdrian Hunter sdhci_init(host, 0); 278466fd8ad5SAdrian Hunter 278566fd8ad5SAdrian Hunter /* Force clock and power re-program */ 278666fd8ad5SAdrian Hunter host->pwr = 0; 278766fd8ad5SAdrian Hunter host->clock = 0; 2788d3940f27SAdrian Hunter mmc->ops->start_signal_voltage_switch(mmc, &mmc->ios); 2789d3940f27SAdrian Hunter mmc->ops->set_ios(mmc, &mmc->ios); 279066fd8ad5SAdrian Hunter 279152983382SKevin Liu if ((host_flags & SDHCI_PV_ENABLED) && 279252983382SKevin Liu !(host->quirks2 & SDHCI_QUIRK2_PRESET_VALUE_BROKEN)) { 279352983382SKevin Liu spin_lock_irqsave(&host->lock, flags); 279452983382SKevin Liu sdhci_enable_preset_value(host, true); 279552983382SKevin Liu spin_unlock_irqrestore(&host->lock, flags); 279652983382SKevin Liu } 279766fd8ad5SAdrian Hunter 279866fd8ad5SAdrian Hunter spin_lock_irqsave(&host->lock, flags); 279966fd8ad5SAdrian Hunter 280066fd8ad5SAdrian Hunter host->runtime_suspended = false; 280166fd8ad5SAdrian Hunter 280266fd8ad5SAdrian Hunter /* Enable SDIO IRQ */ 2803ef104333SRussell King if (host->flags & SDHCI_SDIO_IRQ_ENABLED) 280466fd8ad5SAdrian Hunter sdhci_enable_sdio_irq_nolock(host, true); 280566fd8ad5SAdrian Hunter 280666fd8ad5SAdrian Hunter /* Enable Card Detection */ 280766fd8ad5SAdrian Hunter sdhci_enable_card_detection(host); 280866fd8ad5SAdrian Hunter 280966fd8ad5SAdrian Hunter spin_unlock_irqrestore(&host->lock, flags); 281066fd8ad5SAdrian Hunter 28118a125badSMarkus Pargmann return 0; 281266fd8ad5SAdrian Hunter } 281366fd8ad5SAdrian Hunter EXPORT_SYMBOL_GPL(sdhci_runtime_resume_host); 281466fd8ad5SAdrian Hunter 2815162d6f98SRafael J. Wysocki #endif /* CONFIG_PM */ 281666fd8ad5SAdrian Hunter 28171c6a0718SPierre Ossman /*****************************************************************************\ 28181c6a0718SPierre Ossman * * 2819b8c86fc5SPierre Ossman * Device allocation/registration * 28201c6a0718SPierre Ossman * * 28211c6a0718SPierre Ossman \*****************************************************************************/ 28221c6a0718SPierre Ossman 2823b8c86fc5SPierre Ossman struct sdhci_host *sdhci_alloc_host(struct device *dev, 2824b8c86fc5SPierre Ossman size_t priv_size) 28251c6a0718SPierre Ossman { 28261c6a0718SPierre Ossman struct mmc_host *mmc; 28271c6a0718SPierre Ossman struct sdhci_host *host; 28281c6a0718SPierre Ossman 2829b8c86fc5SPierre Ossman WARN_ON(dev == NULL); 28301c6a0718SPierre Ossman 2831b8c86fc5SPierre Ossman mmc = mmc_alloc_host(sizeof(struct sdhci_host) + priv_size, dev); 28321c6a0718SPierre Ossman if (!mmc) 2833b8c86fc5SPierre Ossman return ERR_PTR(-ENOMEM); 28341c6a0718SPierre Ossman 28351c6a0718SPierre Ossman host = mmc_priv(mmc); 28361c6a0718SPierre Ossman host->mmc = mmc; 2837bf60e592SAdrian Hunter host->mmc_host_ops = sdhci_ops; 2838bf60e592SAdrian Hunter mmc->ops = &host->mmc_host_ops; 28391c6a0718SPierre Ossman 28408cb851a4SAdrian Hunter host->flags = SDHCI_SIGNALING_330; 28418cb851a4SAdrian Hunter 2842b8c86fc5SPierre Ossman return host; 28431c6a0718SPierre Ossman } 28441c6a0718SPierre Ossman 2845b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_alloc_host); 2846b8c86fc5SPierre Ossman 28477b91369bSAlexandre Courbot static int sdhci_set_dma_mask(struct sdhci_host *host) 28487b91369bSAlexandre Courbot { 28497b91369bSAlexandre Courbot struct mmc_host *mmc = host->mmc; 28507b91369bSAlexandre Courbot struct device *dev = mmc_dev(mmc); 28517b91369bSAlexandre Courbot int ret = -EINVAL; 28527b91369bSAlexandre Courbot 28537b91369bSAlexandre Courbot if (host->quirks2 & SDHCI_QUIRK2_BROKEN_64_BIT_DMA) 28547b91369bSAlexandre Courbot host->flags &= ~SDHCI_USE_64_BIT_DMA; 28557b91369bSAlexandre Courbot 28567b91369bSAlexandre Courbot /* Try 64-bit mask if hardware is capable of it */ 28577b91369bSAlexandre Courbot if (host->flags & SDHCI_USE_64_BIT_DMA) { 28587b91369bSAlexandre Courbot ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); 28597b91369bSAlexandre Courbot if (ret) { 28607b91369bSAlexandre Courbot pr_warn("%s: Failed to set 64-bit DMA mask.\n", 28617b91369bSAlexandre Courbot mmc_hostname(mmc)); 28627b91369bSAlexandre Courbot host->flags &= ~SDHCI_USE_64_BIT_DMA; 28637b91369bSAlexandre Courbot } 28647b91369bSAlexandre Courbot } 28657b91369bSAlexandre Courbot 28667b91369bSAlexandre Courbot /* 32-bit mask as default & fallback */ 28677b91369bSAlexandre Courbot if (ret) { 28687b91369bSAlexandre Courbot ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); 28697b91369bSAlexandre Courbot if (ret) 28707b91369bSAlexandre Courbot pr_warn("%s: Failed to set 32-bit DMA mask.\n", 28717b91369bSAlexandre Courbot mmc_hostname(mmc)); 28727b91369bSAlexandre Courbot } 28737b91369bSAlexandre Courbot 28747b91369bSAlexandre Courbot return ret; 28757b91369bSAlexandre Courbot } 28767b91369bSAlexandre Courbot 28776132a3bfSAdrian Hunter void __sdhci_read_caps(struct sdhci_host *host, u16 *ver, u32 *caps, u32 *caps1) 28786132a3bfSAdrian Hunter { 28796132a3bfSAdrian Hunter u16 v; 28806132a3bfSAdrian Hunter 28816132a3bfSAdrian Hunter if (host->read_caps) 28826132a3bfSAdrian Hunter return; 28836132a3bfSAdrian Hunter 28846132a3bfSAdrian Hunter host->read_caps = true; 28856132a3bfSAdrian Hunter 28866132a3bfSAdrian Hunter if (debug_quirks) 28876132a3bfSAdrian Hunter host->quirks = debug_quirks; 28886132a3bfSAdrian Hunter 28896132a3bfSAdrian Hunter if (debug_quirks2) 28906132a3bfSAdrian Hunter host->quirks2 = debug_quirks2; 28916132a3bfSAdrian Hunter 28926132a3bfSAdrian Hunter sdhci_do_reset(host, SDHCI_RESET_ALL); 28936132a3bfSAdrian Hunter 28946132a3bfSAdrian Hunter v = ver ? *ver : sdhci_readw(host, SDHCI_HOST_VERSION); 28956132a3bfSAdrian Hunter host->version = (v & SDHCI_SPEC_VER_MASK) >> SDHCI_SPEC_VER_SHIFT; 28966132a3bfSAdrian Hunter 28976132a3bfSAdrian Hunter if (host->quirks & SDHCI_QUIRK_MISSING_CAPS) 28986132a3bfSAdrian Hunter return; 28996132a3bfSAdrian Hunter 29006132a3bfSAdrian Hunter host->caps = caps ? *caps : sdhci_readl(host, SDHCI_CAPABILITIES); 29016132a3bfSAdrian Hunter 29026132a3bfSAdrian Hunter if (host->version < SDHCI_SPEC_300) 29036132a3bfSAdrian Hunter return; 29046132a3bfSAdrian Hunter 29056132a3bfSAdrian Hunter host->caps1 = caps1 ? *caps1 : sdhci_readl(host, SDHCI_CAPABILITIES_1); 29066132a3bfSAdrian Hunter } 29076132a3bfSAdrian Hunter EXPORT_SYMBOL_GPL(__sdhci_read_caps); 29086132a3bfSAdrian Hunter 290952f5336dSAdrian Hunter int sdhci_setup_host(struct sdhci_host *host) 2910b8c86fc5SPierre Ossman { 2911b8c86fc5SPierre Ossman struct mmc_host *mmc; 2912f2119df6SArindam Nath u32 max_current_caps; 2913f2119df6SArindam Nath unsigned int ocr_avail; 2914f5fa92e5SAdrian Hunter unsigned int override_timeout_clk; 291559241757SDong Aisheng u32 max_clk; 2916b8c86fc5SPierre Ossman int ret; 2917b8c86fc5SPierre Ossman 2918b8c86fc5SPierre Ossman WARN_ON(host == NULL); 2919b8c86fc5SPierre Ossman if (host == NULL) 2920b8c86fc5SPierre Ossman return -EINVAL; 2921b8c86fc5SPierre Ossman 2922b8c86fc5SPierre Ossman mmc = host->mmc; 2923b8c86fc5SPierre Ossman 29246132a3bfSAdrian Hunter sdhci_read_caps(host); 2925b8c86fc5SPierre Ossman 2926f5fa92e5SAdrian Hunter override_timeout_clk = host->timeout_clk; 2927f5fa92e5SAdrian Hunter 292885105c53SZhangfei Gao if (host->version > SDHCI_SPEC_300) { 29292e4456f0SMarek Vasut pr_err("%s: Unknown controller version (%d). You may experience problems.\n", 29302e4456f0SMarek Vasut mmc_hostname(mmc), host->version); 29311c6a0718SPierre Ossman } 29321c6a0718SPierre Ossman 2933b8c86fc5SPierre Ossman if (host->quirks & SDHCI_QUIRK_FORCE_DMA) 2934a13abc7bSRichard Röjfors host->flags |= SDHCI_USE_SDMA; 293528da3589SAdrian Hunter else if (!(host->caps & SDHCI_CAN_DO_SDMA)) 2936a13abc7bSRichard Röjfors DBG("Controller doesn't have SDMA capability\n"); 29371c6a0718SPierre Ossman else 2938a13abc7bSRichard Röjfors host->flags |= SDHCI_USE_SDMA; 29391c6a0718SPierre Ossman 2940b8c86fc5SPierre Ossman if ((host->quirks & SDHCI_QUIRK_BROKEN_DMA) && 2941a13abc7bSRichard Röjfors (host->flags & SDHCI_USE_SDMA)) { 2942cee687ceSRolf Eike Beer DBG("Disabling DMA as it is marked broken\n"); 2943a13abc7bSRichard Röjfors host->flags &= ~SDHCI_USE_SDMA; 29447c168e3dSFeng Tang } 29457c168e3dSFeng Tang 2946f2119df6SArindam Nath if ((host->version >= SDHCI_SPEC_200) && 294728da3589SAdrian Hunter (host->caps & SDHCI_CAN_DO_ADMA2)) 29482134a922SPierre Ossman host->flags |= SDHCI_USE_ADMA; 29492134a922SPierre Ossman 29502134a922SPierre Ossman if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) && 29512134a922SPierre Ossman (host->flags & SDHCI_USE_ADMA)) { 29522134a922SPierre Ossman DBG("Disabling ADMA as it is marked broken\n"); 29532134a922SPierre Ossman host->flags &= ~SDHCI_USE_ADMA; 29542134a922SPierre Ossman } 29552134a922SPierre Ossman 2956e57a5f61SAdrian Hunter /* 2957e57a5f61SAdrian Hunter * It is assumed that a 64-bit capable device has set a 64-bit DMA mask 2958e57a5f61SAdrian Hunter * and *must* do 64-bit DMA. A driver has the opportunity to change 2959e57a5f61SAdrian Hunter * that during the first call to ->enable_dma(). Similarly 2960e57a5f61SAdrian Hunter * SDHCI_QUIRK2_BROKEN_64_BIT_DMA must be left to the drivers to 2961e57a5f61SAdrian Hunter * implement. 2962e57a5f61SAdrian Hunter */ 296328da3589SAdrian Hunter if (host->caps & SDHCI_CAN_64BIT) 2964e57a5f61SAdrian Hunter host->flags |= SDHCI_USE_64_BIT_DMA; 2965e57a5f61SAdrian Hunter 2966a13abc7bSRichard Röjfors if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { 29677b91369bSAlexandre Courbot ret = sdhci_set_dma_mask(host); 29687b91369bSAlexandre Courbot 29697b91369bSAlexandre Courbot if (!ret && host->ops->enable_dma) 29707b91369bSAlexandre Courbot ret = host->ops->enable_dma(host); 29717b91369bSAlexandre Courbot 29727b91369bSAlexandre Courbot if (ret) { 29736606110dSJoe Perches pr_warn("%s: No suitable DMA available - falling back to PIO\n", 2974b8c86fc5SPierre Ossman mmc_hostname(mmc)); 29757b91369bSAlexandre Courbot host->flags &= ~(SDHCI_USE_SDMA | SDHCI_USE_ADMA); 29767b91369bSAlexandre Courbot 29777b91369bSAlexandre Courbot ret = 0; 29781c6a0718SPierre Ossman } 2979b8c86fc5SPierre Ossman } 29801c6a0718SPierre Ossman 2981e57a5f61SAdrian Hunter /* SDMA does not support 64-bit DMA */ 2982e57a5f61SAdrian Hunter if (host->flags & SDHCI_USE_64_BIT_DMA) 2983e57a5f61SAdrian Hunter host->flags &= ~SDHCI_USE_SDMA; 2984e57a5f61SAdrian Hunter 29852134a922SPierre Ossman if (host->flags & SDHCI_USE_ADMA) { 2986e66e61cbSRussell King dma_addr_t dma; 2987e66e61cbSRussell King void *buf; 2988e66e61cbSRussell King 29892134a922SPierre Ossman /* 299076fe379aSAdrian Hunter * The DMA descriptor table size is calculated as the maximum 299176fe379aSAdrian Hunter * number of segments times 2, to allow for an alignment 299276fe379aSAdrian Hunter * descriptor for each segment, plus 1 for a nop end descriptor, 299376fe379aSAdrian Hunter * all multipled by the descriptor size. 29942134a922SPierre Ossman */ 2995e57a5f61SAdrian Hunter if (host->flags & SDHCI_USE_64_BIT_DMA) { 2996e57a5f61SAdrian Hunter host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * 2997e57a5f61SAdrian Hunter SDHCI_ADMA2_64_DESC_SZ; 2998e57a5f61SAdrian Hunter host->desc_sz = SDHCI_ADMA2_64_DESC_SZ; 2999e57a5f61SAdrian Hunter } else { 3000739d46dcSAdrian Hunter host->adma_table_sz = (SDHCI_MAX_SEGS * 2 + 1) * 3001739d46dcSAdrian Hunter SDHCI_ADMA2_32_DESC_SZ; 3002739d46dcSAdrian Hunter host->desc_sz = SDHCI_ADMA2_32_DESC_SZ; 3003e57a5f61SAdrian Hunter } 3004e66e61cbSRussell King 300504a5ae6fSAdrian Hunter host->align_buffer_sz = SDHCI_MAX_SEGS * SDHCI_ADMA2_ALIGN; 3006e66e61cbSRussell King buf = dma_alloc_coherent(mmc_dev(mmc), host->align_buffer_sz + 3007e66e61cbSRussell King host->adma_table_sz, &dma, GFP_KERNEL); 3008e66e61cbSRussell King if (!buf) { 30096606110dSJoe Perches pr_warn("%s: Unable to allocate ADMA buffers - falling back to standard DMA\n", 30102134a922SPierre Ossman mmc_hostname(mmc)); 30112134a922SPierre Ossman host->flags &= ~SDHCI_USE_ADMA; 3012e66e61cbSRussell King } else if ((dma + host->align_buffer_sz) & 3013e66e61cbSRussell King (SDHCI_ADMA2_DESC_ALIGN - 1)) { 30146606110dSJoe Perches pr_warn("%s: unable to allocate aligned ADMA descriptor\n", 3015d1e49f77SRussell King mmc_hostname(mmc)); 3016d1e49f77SRussell King host->flags &= ~SDHCI_USE_ADMA; 3017e66e61cbSRussell King dma_free_coherent(mmc_dev(mmc), host->align_buffer_sz + 3018e66e61cbSRussell King host->adma_table_sz, buf, dma); 3019e66e61cbSRussell King } else { 3020e66e61cbSRussell King host->align_buffer = buf; 3021e66e61cbSRussell King host->align_addr = dma; 3022edd63fccSRussell King 3023e66e61cbSRussell King host->adma_table = buf + host->align_buffer_sz; 3024e66e61cbSRussell King host->adma_addr = dma + host->align_buffer_sz; 3025e66e61cbSRussell King } 30262134a922SPierre Ossman } 30272134a922SPierre Ossman 30287659150cSPierre Ossman /* 30297659150cSPierre Ossman * If we use DMA, then it's up to the caller to set the DMA 30307659150cSPierre Ossman * mask, but PIO does not need the hw shim so we set a new 30317659150cSPierre Ossman * mask here in that case. 30327659150cSPierre Ossman */ 3033a13abc7bSRichard Röjfors if (!(host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))) { 30347659150cSPierre Ossman host->dma_mask = DMA_BIT_MASK(64); 30354e743f1fSMarkus Mayer mmc_dev(mmc)->dma_mask = &host->dma_mask; 30367659150cSPierre Ossman } 30371c6a0718SPierre Ossman 3038c4687d5fSZhangfei Gao if (host->version >= SDHCI_SPEC_300) 303928da3589SAdrian Hunter host->max_clk = (host->caps & SDHCI_CLOCK_V3_BASE_MASK) 3040c4687d5fSZhangfei Gao >> SDHCI_CLOCK_BASE_SHIFT; 3041c4687d5fSZhangfei Gao else 304228da3589SAdrian Hunter host->max_clk = (host->caps & SDHCI_CLOCK_BASE_MASK) 3043c4687d5fSZhangfei Gao >> SDHCI_CLOCK_BASE_SHIFT; 3044c4687d5fSZhangfei Gao 30454240ff0aSBen Dooks host->max_clk *= 1000000; 3046f27f47efSAnton Vorontsov if (host->max_clk == 0 || host->quirks & 3047f27f47efSAnton Vorontsov SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN) { 30484240ff0aSBen Dooks if (!host->ops->get_max_clock) { 30492e4456f0SMarek Vasut pr_err("%s: Hardware doesn't specify base clock frequency.\n", 30502e4456f0SMarek Vasut mmc_hostname(mmc)); 3051eb5c20deSAdrian Hunter ret = -ENODEV; 3052eb5c20deSAdrian Hunter goto undma; 30531c6a0718SPierre Ossman } 30544240ff0aSBen Dooks host->max_clk = host->ops->get_max_clock(host); 30554240ff0aSBen Dooks } 30561c6a0718SPierre Ossman 30571c6a0718SPierre Ossman /* 3058c3ed3877SArindam Nath * In case of Host Controller v3.00, find out whether clock 3059c3ed3877SArindam Nath * multiplier is supported. 3060c3ed3877SArindam Nath */ 306128da3589SAdrian Hunter host->clk_mul = (host->caps1 & SDHCI_CLOCK_MUL_MASK) >> 3062c3ed3877SArindam Nath SDHCI_CLOCK_MUL_SHIFT; 3063c3ed3877SArindam Nath 3064c3ed3877SArindam Nath /* 3065c3ed3877SArindam Nath * In case the value in Clock Multiplier is 0, then programmable 3066c3ed3877SArindam Nath * clock mode is not supported, otherwise the actual clock 3067c3ed3877SArindam Nath * multiplier is one more than the value of Clock Multiplier 3068c3ed3877SArindam Nath * in the Capabilities Register. 3069c3ed3877SArindam Nath */ 3070c3ed3877SArindam Nath if (host->clk_mul) 3071c3ed3877SArindam Nath host->clk_mul += 1; 3072c3ed3877SArindam Nath 3073c3ed3877SArindam Nath /* 30741c6a0718SPierre Ossman * Set host parameters. 30751c6a0718SPierre Ossman */ 307659241757SDong Aisheng max_clk = host->max_clk; 307759241757SDong Aisheng 3078ce5f036bSMarek Szyprowski if (host->ops->get_min_clock) 3079a9e58f25SAnton Vorontsov mmc->f_min = host->ops->get_min_clock(host); 3080c3ed3877SArindam Nath else if (host->version >= SDHCI_SPEC_300) { 3081c3ed3877SArindam Nath if (host->clk_mul) { 3082c3ed3877SArindam Nath mmc->f_min = (host->max_clk * host->clk_mul) / 1024; 308359241757SDong Aisheng max_clk = host->max_clk * host->clk_mul; 3084c3ed3877SArindam Nath } else 30850397526dSZhangfei Gao mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300; 3086c3ed3877SArindam Nath } else 30870397526dSZhangfei Gao mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200; 308815ec4461SPhilip Rakity 3089d310ae49SAdrian Hunter if (!mmc->f_max || mmc->f_max > max_clk) 309059241757SDong Aisheng mmc->f_max = max_clk; 309159241757SDong Aisheng 309228aab053SAisheng Dong if (!(host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) { 309328da3589SAdrian Hunter host->timeout_clk = (host->caps & SDHCI_TIMEOUT_CLK_MASK) >> 309428aab053SAisheng Dong SDHCI_TIMEOUT_CLK_SHIFT; 3095272308caSAndy Shevchenko if (host->timeout_clk == 0) { 3096272308caSAndy Shevchenko if (host->ops->get_timeout_clock) { 309728aab053SAisheng Dong host->timeout_clk = 309828aab053SAisheng Dong host->ops->get_timeout_clock(host); 309928aab053SAisheng Dong } else { 310028aab053SAisheng Dong pr_err("%s: Hardware doesn't specify timeout clock frequency.\n", 310128aab053SAisheng Dong mmc_hostname(mmc)); 3102eb5c20deSAdrian Hunter ret = -ENODEV; 3103eb5c20deSAdrian Hunter goto undma; 3104272308caSAndy Shevchenko } 3105272308caSAndy Shevchenko } 310628aab053SAisheng Dong 310728da3589SAdrian Hunter if (host->caps & SDHCI_TIMEOUT_CLK_UNIT) 3108272308caSAndy Shevchenko host->timeout_clk *= 1000; 3109272308caSAndy Shevchenko 311099513624SAdrian Hunter if (override_timeout_clk) 311199513624SAdrian Hunter host->timeout_clk = override_timeout_clk; 311299513624SAdrian Hunter 3113a6ff5aebSAisheng Dong mmc->max_busy_timeout = host->ops->get_max_timeout_count ? 3114a6ff5aebSAisheng Dong host->ops->get_max_timeout_count(host) : 1 << 27; 3115a6ff5aebSAisheng Dong mmc->max_busy_timeout /= host->timeout_clk; 311628aab053SAisheng Dong } 311758d1246dSAdrian Hunter 3118e89d456fSAndrei Warkentin mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23; 3119781e989cSRussell King mmc->caps2 |= MMC_CAP2_SDIO_IRQ_NOTHREAD; 3120e89d456fSAndrei Warkentin 3121e89d456fSAndrei Warkentin if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) 3122e89d456fSAndrei Warkentin host->flags |= SDHCI_AUTO_CMD12; 31235fe23c7fSAnton Vorontsov 31248edf6371SAndrei Warkentin /* Auto-CMD23 stuff only works in ADMA or PIO. */ 31254f3d3e9bSAndrei Warkentin if ((host->version >= SDHCI_SPEC_300) && 31268edf6371SAndrei Warkentin ((host->flags & SDHCI_USE_ADMA) || 31273bfa6f03SScott Branden !(host->flags & SDHCI_USE_SDMA)) && 31283bfa6f03SScott Branden !(host->quirks2 & SDHCI_QUIRK2_ACMD23_BROKEN)) { 31298edf6371SAndrei Warkentin host->flags |= SDHCI_AUTO_CMD23; 31308edf6371SAndrei Warkentin DBG("%s: Auto-CMD23 available\n", mmc_hostname(mmc)); 31318edf6371SAndrei Warkentin } else { 31328edf6371SAndrei Warkentin DBG("%s: Auto-CMD23 unavailable\n", mmc_hostname(mmc)); 31338edf6371SAndrei Warkentin } 31348edf6371SAndrei Warkentin 313515ec4461SPhilip Rakity /* 313615ec4461SPhilip Rakity * A controller may support 8-bit width, but the board itself 313715ec4461SPhilip Rakity * might not have the pins brought out. Boards that support 313815ec4461SPhilip Rakity * 8-bit width must set "mmc->caps |= MMC_CAP_8_BIT_DATA;" in 313915ec4461SPhilip Rakity * their platform code before calling sdhci_add_host(), and we 314015ec4461SPhilip Rakity * won't assume 8-bit width for hosts without that CAP. 314115ec4461SPhilip Rakity */ 31425fe23c7fSAnton Vorontsov if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA)) 314315ec4461SPhilip Rakity mmc->caps |= MMC_CAP_4_BIT_DATA; 31441c6a0718SPierre Ossman 314563ef5d8cSJerry Huang if (host->quirks2 & SDHCI_QUIRK2_HOST_NO_CMD23) 314663ef5d8cSJerry Huang mmc->caps &= ~MMC_CAP_CMD23; 314763ef5d8cSJerry Huang 314828da3589SAdrian Hunter if (host->caps & SDHCI_CAN_DO_HISPD) 3149a29e7e18SZhangfei Gao mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED; 31501c6a0718SPierre Ossman 3151176d1ed4SJaehoon Chung if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) && 3152860951c5SJaehoon Chung mmc_card_is_removable(mmc) && 3153287980e4SArnd Bergmann mmc_gpio_get_cd(host->mmc) < 0) 315468d1fb7eSAnton Vorontsov mmc->caps |= MMC_CAP_NEEDS_POLL; 315568d1fb7eSAnton Vorontsov 31563a48edc4STim Kryger /* If there are external regulators, get them */ 3157eb5c20deSAdrian Hunter ret = mmc_regulator_get_supply(mmc); 3158eb5c20deSAdrian Hunter if (ret == -EPROBE_DEFER) 3159eb5c20deSAdrian Hunter goto undma; 31603a48edc4STim Kryger 31616231f3deSPhilip Rakity /* If vqmmc regulator and no 1.8V signalling, then there's no UHS */ 31623a48edc4STim Kryger if (!IS_ERR(mmc->supply.vqmmc)) { 31633a48edc4STim Kryger ret = regulator_enable(mmc->supply.vqmmc); 31643a48edc4STim Kryger if (!regulator_is_supported_voltage(mmc->supply.vqmmc, 1700000, 3165cec2e216SKevin Liu 1950000)) 316628da3589SAdrian Hunter host->caps1 &= ~(SDHCI_SUPPORT_SDR104 | 31678363c374SKevin Liu SDHCI_SUPPORT_SDR50 | 31686231f3deSPhilip Rakity SDHCI_SUPPORT_DDR50); 3169a3361abaSChris Ball if (ret) { 3170a3361abaSChris Ball pr_warn("%s: Failed to enable vqmmc regulator: %d\n", 3171a3361abaSChris Ball mmc_hostname(mmc), ret); 31724bb74313SAdrian Hunter mmc->supply.vqmmc = ERR_PTR(-EINVAL); 3173a3361abaSChris Ball } 31748363c374SKevin Liu } 31756231f3deSPhilip Rakity 317628da3589SAdrian Hunter if (host->quirks2 & SDHCI_QUIRK2_NO_1_8_V) { 317728da3589SAdrian Hunter host->caps1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | 31786a66180aSDaniel Drake SDHCI_SUPPORT_DDR50); 317928da3589SAdrian Hunter } 31806a66180aSDaniel Drake 31814188bba0SAl Cooper /* Any UHS-I mode in caps implies SDR12 and SDR25 support. */ 318228da3589SAdrian Hunter if (host->caps1 & (SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 | 31834188bba0SAl Cooper SDHCI_SUPPORT_DDR50)) 3184f2119df6SArindam Nath mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25; 3185f2119df6SArindam Nath 3186f2119df6SArindam Nath /* SDR104 supports also implies SDR50 support */ 318728da3589SAdrian Hunter if (host->caps1 & SDHCI_SUPPORT_SDR104) { 3188f2119df6SArindam Nath mmc->caps |= MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50; 3189156e14b1SGiuseppe CAVALLARO /* SD3.0: SDR104 is supported so (for eMMC) the caps2 3190156e14b1SGiuseppe CAVALLARO * field can be promoted to support HS200. 3191156e14b1SGiuseppe CAVALLARO */ 3192549c0b18SAdrian Hunter if (!(host->quirks2 & SDHCI_QUIRK2_BROKEN_HS200)) 3193156e14b1SGiuseppe CAVALLARO mmc->caps2 |= MMC_CAP2_HS200; 319428da3589SAdrian Hunter } else if (host->caps1 & SDHCI_SUPPORT_SDR50) { 3195f2119df6SArindam Nath mmc->caps |= MMC_CAP_UHS_SDR50; 319628da3589SAdrian Hunter } 3197f2119df6SArindam Nath 3198e9fb05d5SAdrian Hunter if (host->quirks2 & SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400 && 319928da3589SAdrian Hunter (host->caps1 & SDHCI_SUPPORT_HS400)) 3200e9fb05d5SAdrian Hunter mmc->caps2 |= MMC_CAP2_HS400; 3201e9fb05d5SAdrian Hunter 3202549c0b18SAdrian Hunter if ((mmc->caps2 & MMC_CAP2_HSX00_1_2V) && 3203549c0b18SAdrian Hunter (IS_ERR(mmc->supply.vqmmc) || 3204549c0b18SAdrian Hunter !regulator_is_supported_voltage(mmc->supply.vqmmc, 1100000, 3205549c0b18SAdrian Hunter 1300000))) 3206549c0b18SAdrian Hunter mmc->caps2 &= ~MMC_CAP2_HSX00_1_2V; 3207549c0b18SAdrian Hunter 320828da3589SAdrian Hunter if ((host->caps1 & SDHCI_SUPPORT_DDR50) && 32099107ebbfSMicky Ching !(host->quirks2 & SDHCI_QUIRK2_BROKEN_DDR50)) 3210f2119df6SArindam Nath mmc->caps |= MMC_CAP_UHS_DDR50; 3211f2119df6SArindam Nath 3212069c9f14SGirish K S /* Does the host need tuning for SDR50? */ 321328da3589SAdrian Hunter if (host->caps1 & SDHCI_USE_SDR50_TUNING) 3214b513ea25SArindam Nath host->flags |= SDHCI_SDR50_NEEDS_TUNING; 3215b513ea25SArindam Nath 3216d6d50a15SArindam Nath /* Driver Type(s) (A, C, D) supported by the host */ 321728da3589SAdrian Hunter if (host->caps1 & SDHCI_DRIVER_TYPE_A) 3218d6d50a15SArindam Nath mmc->caps |= MMC_CAP_DRIVER_TYPE_A; 321928da3589SAdrian Hunter if (host->caps1 & SDHCI_DRIVER_TYPE_C) 3220d6d50a15SArindam Nath mmc->caps |= MMC_CAP_DRIVER_TYPE_C; 322128da3589SAdrian Hunter if (host->caps1 & SDHCI_DRIVER_TYPE_D) 3222d6d50a15SArindam Nath mmc->caps |= MMC_CAP_DRIVER_TYPE_D; 3223d6d50a15SArindam Nath 3224cf2b5eeaSArindam Nath /* Initial value for re-tuning timer count */ 322528da3589SAdrian Hunter host->tuning_count = (host->caps1 & SDHCI_RETUNING_TIMER_COUNT_MASK) >> 3226cf2b5eeaSArindam Nath SDHCI_RETUNING_TIMER_COUNT_SHIFT; 3227cf2b5eeaSArindam Nath 3228cf2b5eeaSArindam Nath /* 3229cf2b5eeaSArindam Nath * In case Re-tuning Timer is not disabled, the actual value of 3230cf2b5eeaSArindam Nath * re-tuning timer will be 2 ^ (n - 1). 3231cf2b5eeaSArindam Nath */ 3232cf2b5eeaSArindam Nath if (host->tuning_count) 3233cf2b5eeaSArindam Nath host->tuning_count = 1 << (host->tuning_count - 1); 3234cf2b5eeaSArindam Nath 3235cf2b5eeaSArindam Nath /* Re-tuning mode supported by the Host Controller */ 323628da3589SAdrian Hunter host->tuning_mode = (host->caps1 & SDHCI_RETUNING_MODE_MASK) >> 3237cf2b5eeaSArindam Nath SDHCI_RETUNING_MODE_SHIFT; 3238cf2b5eeaSArindam Nath 32398f230f45STakashi Iwai ocr_avail = 0; 3240bad37e1aSPhilip Rakity 3241f2119df6SArindam Nath /* 3242f2119df6SArindam Nath * According to SD Host Controller spec v3.00, if the Host System 3243f2119df6SArindam Nath * can afford more than 150mA, Host Driver should set XPC to 1. Also 3244f2119df6SArindam Nath * the value is meaningful only if Voltage Support in the Capabilities 3245f2119df6SArindam Nath * register is set. The actual current value is 4 times the register 3246f2119df6SArindam Nath * value. 3247f2119df6SArindam Nath */ 3248f2119df6SArindam Nath max_current_caps = sdhci_readl(host, SDHCI_MAX_CURRENT); 32493a48edc4STim Kryger if (!max_current_caps && !IS_ERR(mmc->supply.vmmc)) { 3250ae906037SChuanxiao.Dong int curr = regulator_get_current_limit(mmc->supply.vmmc); 3251bad37e1aSPhilip Rakity if (curr > 0) { 3252bad37e1aSPhilip Rakity 3253bad37e1aSPhilip Rakity /* convert to SDHCI_MAX_CURRENT format */ 3254bad37e1aSPhilip Rakity curr = curr/1000; /* convert to mA */ 3255bad37e1aSPhilip Rakity curr = curr/SDHCI_MAX_CURRENT_MULTIPLIER; 3256bad37e1aSPhilip Rakity 3257bad37e1aSPhilip Rakity curr = min_t(u32, curr, SDHCI_MAX_CURRENT_LIMIT); 3258bad37e1aSPhilip Rakity max_current_caps = 3259bad37e1aSPhilip Rakity (curr << SDHCI_MAX_CURRENT_330_SHIFT) | 3260bad37e1aSPhilip Rakity (curr << SDHCI_MAX_CURRENT_300_SHIFT) | 3261bad37e1aSPhilip Rakity (curr << SDHCI_MAX_CURRENT_180_SHIFT); 3262bad37e1aSPhilip Rakity } 3263bad37e1aSPhilip Rakity } 3264f2119df6SArindam Nath 326528da3589SAdrian Hunter if (host->caps & SDHCI_CAN_VDD_330) { 32668f230f45STakashi Iwai ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34; 3267f2119df6SArindam Nath 326855c4665eSAaron Lu mmc->max_current_330 = ((max_current_caps & 3269f2119df6SArindam Nath SDHCI_MAX_CURRENT_330_MASK) >> 3270f2119df6SArindam Nath SDHCI_MAX_CURRENT_330_SHIFT) * 3271f2119df6SArindam Nath SDHCI_MAX_CURRENT_MULTIPLIER; 3272f2119df6SArindam Nath } 327328da3589SAdrian Hunter if (host->caps & SDHCI_CAN_VDD_300) { 32748f230f45STakashi Iwai ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31; 3275f2119df6SArindam Nath 327655c4665eSAaron Lu mmc->max_current_300 = ((max_current_caps & 3277f2119df6SArindam Nath SDHCI_MAX_CURRENT_300_MASK) >> 3278f2119df6SArindam Nath SDHCI_MAX_CURRENT_300_SHIFT) * 3279f2119df6SArindam Nath SDHCI_MAX_CURRENT_MULTIPLIER; 3280f2119df6SArindam Nath } 328128da3589SAdrian Hunter if (host->caps & SDHCI_CAN_VDD_180) { 32828f230f45STakashi Iwai ocr_avail |= MMC_VDD_165_195; 32838f230f45STakashi Iwai 328455c4665eSAaron Lu mmc->max_current_180 = ((max_current_caps & 3285f2119df6SArindam Nath SDHCI_MAX_CURRENT_180_MASK) >> 3286f2119df6SArindam Nath SDHCI_MAX_CURRENT_180_SHIFT) * 3287f2119df6SArindam Nath SDHCI_MAX_CURRENT_MULTIPLIER; 3288f2119df6SArindam Nath } 3289f2119df6SArindam Nath 32905fd26c7eSUlf Hansson /* If OCR set by host, use it instead. */ 32915fd26c7eSUlf Hansson if (host->ocr_mask) 32925fd26c7eSUlf Hansson ocr_avail = host->ocr_mask; 32935fd26c7eSUlf Hansson 32945fd26c7eSUlf Hansson /* If OCR set by external regulators, give it highest prio. */ 32953a48edc4STim Kryger if (mmc->ocr_avail) 329652221610STim Kryger ocr_avail = mmc->ocr_avail; 32973a48edc4STim Kryger 32988f230f45STakashi Iwai mmc->ocr_avail = ocr_avail; 32998f230f45STakashi Iwai mmc->ocr_avail_sdio = ocr_avail; 33008f230f45STakashi Iwai if (host->ocr_avail_sdio) 33018f230f45STakashi Iwai mmc->ocr_avail_sdio &= host->ocr_avail_sdio; 33028f230f45STakashi Iwai mmc->ocr_avail_sd = ocr_avail; 33038f230f45STakashi Iwai if (host->ocr_avail_sd) 33048f230f45STakashi Iwai mmc->ocr_avail_sd &= host->ocr_avail_sd; 33058f230f45STakashi Iwai else /* normal SD controllers don't support 1.8V */ 33068f230f45STakashi Iwai mmc->ocr_avail_sd &= ~MMC_VDD_165_195; 33078f230f45STakashi Iwai mmc->ocr_avail_mmc = ocr_avail; 33088f230f45STakashi Iwai if (host->ocr_avail_mmc) 33098f230f45STakashi Iwai mmc->ocr_avail_mmc &= host->ocr_avail_mmc; 33101c6a0718SPierre Ossman 33111c6a0718SPierre Ossman if (mmc->ocr_avail == 0) { 33122e4456f0SMarek Vasut pr_err("%s: Hardware doesn't report any support voltages.\n", 33132e4456f0SMarek Vasut mmc_hostname(mmc)); 3314eb5c20deSAdrian Hunter ret = -ENODEV; 3315eb5c20deSAdrian Hunter goto unreg; 33161c6a0718SPierre Ossman } 33171c6a0718SPierre Ossman 33188cb851a4SAdrian Hunter if ((mmc->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | 33198cb851a4SAdrian Hunter MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | 33208cb851a4SAdrian Hunter MMC_CAP_UHS_DDR50 | MMC_CAP_1_8V_DDR)) || 33218cb851a4SAdrian Hunter (mmc->caps2 & (MMC_CAP2_HS200_1_8V_SDR | MMC_CAP2_HS400_1_8V))) 33228cb851a4SAdrian Hunter host->flags |= SDHCI_SIGNALING_180; 33238cb851a4SAdrian Hunter 33248cb851a4SAdrian Hunter if (mmc->caps2 & MMC_CAP2_HSX00_1_2V) 33258cb851a4SAdrian Hunter host->flags |= SDHCI_SIGNALING_120; 33268cb851a4SAdrian Hunter 33271c6a0718SPierre Ossman spin_lock_init(&host->lock); 33281c6a0718SPierre Ossman 33291c6a0718SPierre Ossman /* 33302134a922SPierre Ossman * Maximum number of segments. Depends on if the hardware 33312134a922SPierre Ossman * can do scatter/gather or not. 33321c6a0718SPierre Ossman */ 33332134a922SPierre Ossman if (host->flags & SDHCI_USE_ADMA) 33344fb213f8SAdrian Hunter mmc->max_segs = SDHCI_MAX_SEGS; 3335a13abc7bSRichard Röjfors else if (host->flags & SDHCI_USE_SDMA) 3336a36274e0SMartin K. Petersen mmc->max_segs = 1; 33372134a922SPierre Ossman else /* PIO */ 33384fb213f8SAdrian Hunter mmc->max_segs = SDHCI_MAX_SEGS; 33391c6a0718SPierre Ossman 33401c6a0718SPierre Ossman /* 3341ac00531dSAdrian Hunter * Maximum number of sectors in one transfer. Limited by SDMA boundary 3342ac00531dSAdrian Hunter * size (512KiB). Note some tuning modes impose a 4MiB limit, but this 3343ac00531dSAdrian Hunter * is less anyway. 33441c6a0718SPierre Ossman */ 33451c6a0718SPierre Ossman mmc->max_req_size = 524288; 33461c6a0718SPierre Ossman 33471c6a0718SPierre Ossman /* 33481c6a0718SPierre Ossman * Maximum segment size. Could be one segment with the maximum number 33492134a922SPierre Ossman * of bytes. When doing hardware scatter/gather, each entry cannot 33502134a922SPierre Ossman * be larger than 64 KiB though. 33511c6a0718SPierre Ossman */ 335230652aa3SOlof Johansson if (host->flags & SDHCI_USE_ADMA) { 335330652aa3SOlof Johansson if (host->quirks & SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC) 335430652aa3SOlof Johansson mmc->max_seg_size = 65535; 33552134a922SPierre Ossman else 335630652aa3SOlof Johansson mmc->max_seg_size = 65536; 335730652aa3SOlof Johansson } else { 33581c6a0718SPierre Ossman mmc->max_seg_size = mmc->max_req_size; 335930652aa3SOlof Johansson } 33601c6a0718SPierre Ossman 33611c6a0718SPierre Ossman /* 33621c6a0718SPierre Ossman * Maximum block size. This varies from controller to controller and 33631c6a0718SPierre Ossman * is specified in the capabilities register. 33641c6a0718SPierre Ossman */ 33650633f654SAnton Vorontsov if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) { 33660633f654SAnton Vorontsov mmc->max_blk_size = 2; 33670633f654SAnton Vorontsov } else { 336828da3589SAdrian Hunter mmc->max_blk_size = (host->caps & SDHCI_MAX_BLOCK_MASK) >> 33690633f654SAnton Vorontsov SDHCI_MAX_BLOCK_SHIFT; 33701c6a0718SPierre Ossman if (mmc->max_blk_size >= 3) { 33716606110dSJoe Perches pr_warn("%s: Invalid maximum block size, assuming 512 bytes\n", 33726606110dSJoe Perches mmc_hostname(mmc)); 33730633f654SAnton Vorontsov mmc->max_blk_size = 0; 33740633f654SAnton Vorontsov } 33750633f654SAnton Vorontsov } 33760633f654SAnton Vorontsov 33771c6a0718SPierre Ossman mmc->max_blk_size = 512 << mmc->max_blk_size; 33781c6a0718SPierre Ossman 33791c6a0718SPierre Ossman /* 33801c6a0718SPierre Ossman * Maximum block count. 33811c6a0718SPierre Ossman */ 33821388eefdSBen Dooks mmc->max_blk_count = (host->quirks & SDHCI_QUIRK_NO_MULTIBLOCK) ? 1 : 65535; 33831c6a0718SPierre Ossman 338452f5336dSAdrian Hunter return 0; 338552f5336dSAdrian Hunter 338652f5336dSAdrian Hunter unreg: 338752f5336dSAdrian Hunter if (!IS_ERR(mmc->supply.vqmmc)) 338852f5336dSAdrian Hunter regulator_disable(mmc->supply.vqmmc); 338952f5336dSAdrian Hunter undma: 339052f5336dSAdrian Hunter if (host->align_buffer) 339152f5336dSAdrian Hunter dma_free_coherent(mmc_dev(mmc), host->align_buffer_sz + 339252f5336dSAdrian Hunter host->adma_table_sz, host->align_buffer, 339352f5336dSAdrian Hunter host->align_addr); 339452f5336dSAdrian Hunter host->adma_table = NULL; 339552f5336dSAdrian Hunter host->align_buffer = NULL; 339652f5336dSAdrian Hunter 339752f5336dSAdrian Hunter return ret; 339852f5336dSAdrian Hunter } 339952f5336dSAdrian Hunter EXPORT_SYMBOL_GPL(sdhci_setup_host); 340052f5336dSAdrian Hunter 340152f5336dSAdrian Hunter int __sdhci_add_host(struct sdhci_host *host) 340252f5336dSAdrian Hunter { 340352f5336dSAdrian Hunter struct mmc_host *mmc = host->mmc; 340452f5336dSAdrian Hunter int ret; 340552f5336dSAdrian Hunter 34061c6a0718SPierre Ossman /* 34071c6a0718SPierre Ossman * Init tasklets. 34081c6a0718SPierre Ossman */ 34091c6a0718SPierre Ossman tasklet_init(&host->finish_tasklet, 34101c6a0718SPierre Ossman sdhci_tasklet_finish, (unsigned long)host); 34111c6a0718SPierre Ossman 34121c6a0718SPierre Ossman setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host); 34131c6a0718SPierre Ossman 3414b513ea25SArindam Nath init_waitqueue_head(&host->buf_ready_int); 3415b513ea25SArindam Nath 34162af502caSShawn Guo sdhci_init(host, 0); 34172af502caSShawn Guo 3418781e989cSRussell King ret = request_threaded_irq(host->irq, sdhci_irq, sdhci_thread_irq, 3419781e989cSRussell King IRQF_SHARED, mmc_hostname(mmc), host); 34200fc81ee3SMark Brown if (ret) { 34210fc81ee3SMark Brown pr_err("%s: Failed to request IRQ %d: %d\n", 34220fc81ee3SMark Brown mmc_hostname(mmc), host->irq, ret); 34231c6a0718SPierre Ossman goto untasklet; 34240fc81ee3SMark Brown } 34251c6a0718SPierre Ossman 34261c6a0718SPierre Ossman #ifdef CONFIG_MMC_DEBUG 34271c6a0718SPierre Ossman sdhci_dumpregs(host); 34281c6a0718SPierre Ossman #endif 34291c6a0718SPierre Ossman 3430061d17a6SAdrian Hunter ret = sdhci_led_register(host); 34310fc81ee3SMark Brown if (ret) { 34320fc81ee3SMark Brown pr_err("%s: Failed to register LED device: %d\n", 34330fc81ee3SMark Brown mmc_hostname(mmc), ret); 3434eb5c20deSAdrian Hunter goto unirq; 34350fc81ee3SMark Brown } 34362f730fecSPierre Ossman 34371c6a0718SPierre Ossman mmiowb(); 34381c6a0718SPierre Ossman 3439eb5c20deSAdrian Hunter ret = mmc_add_host(mmc); 3440eb5c20deSAdrian Hunter if (ret) 3441eb5c20deSAdrian Hunter goto unled; 34421c6a0718SPierre Ossman 3443a3c76eb9SGirish K S pr_info("%s: SDHCI controller on %s [%s] using %s\n", 3444d1b26863SKay Sievers mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)), 3445e57a5f61SAdrian Hunter (host->flags & SDHCI_USE_ADMA) ? 3446e57a5f61SAdrian Hunter (host->flags & SDHCI_USE_64_BIT_DMA) ? "ADMA 64-bit" : "ADMA" : 3447a13abc7bSRichard Röjfors (host->flags & SDHCI_USE_SDMA) ? "DMA" : "PIO"); 34481c6a0718SPierre Ossman 34497260cf5eSAnton Vorontsov sdhci_enable_card_detection(host); 34507260cf5eSAnton Vorontsov 34511c6a0718SPierre Ossman return 0; 34521c6a0718SPierre Ossman 3453eb5c20deSAdrian Hunter unled: 3454061d17a6SAdrian Hunter sdhci_led_unregister(host); 3455eb5c20deSAdrian Hunter unirq: 345603231f9bSRussell King sdhci_do_reset(host, SDHCI_RESET_ALL); 3457b537f94cSRussell King sdhci_writel(host, 0, SDHCI_INT_ENABLE); 3458b537f94cSRussell King sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE); 34592f730fecSPierre Ossman free_irq(host->irq, host); 34601c6a0718SPierre Ossman untasklet: 34611c6a0718SPierre Ossman tasklet_kill(&host->finish_tasklet); 346252f5336dSAdrian Hunter 3463eb5c20deSAdrian Hunter if (!IS_ERR(mmc->supply.vqmmc)) 3464eb5c20deSAdrian Hunter regulator_disable(mmc->supply.vqmmc); 346552f5336dSAdrian Hunter 3466eb5c20deSAdrian Hunter if (host->align_buffer) 3467eb5c20deSAdrian Hunter dma_free_coherent(mmc_dev(mmc), host->align_buffer_sz + 3468eb5c20deSAdrian Hunter host->adma_table_sz, host->align_buffer, 3469eb5c20deSAdrian Hunter host->align_addr); 3470eb5c20deSAdrian Hunter host->adma_table = NULL; 3471eb5c20deSAdrian Hunter host->align_buffer = NULL; 34721c6a0718SPierre Ossman 34731c6a0718SPierre Ossman return ret; 34741c6a0718SPierre Ossman } 347552f5336dSAdrian Hunter EXPORT_SYMBOL_GPL(__sdhci_add_host); 34761c6a0718SPierre Ossman 347752f5336dSAdrian Hunter int sdhci_add_host(struct sdhci_host *host) 347852f5336dSAdrian Hunter { 347952f5336dSAdrian Hunter int ret; 348052f5336dSAdrian Hunter 348152f5336dSAdrian Hunter ret = sdhci_setup_host(host); 348252f5336dSAdrian Hunter if (ret) 348352f5336dSAdrian Hunter return ret; 348452f5336dSAdrian Hunter 348552f5336dSAdrian Hunter return __sdhci_add_host(host); 348652f5336dSAdrian Hunter } 3487b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_add_host); 3488b8c86fc5SPierre Ossman 34891e72859eSPierre Ossman void sdhci_remove_host(struct sdhci_host *host, int dead) 34901c6a0718SPierre Ossman { 34913a48edc4STim Kryger struct mmc_host *mmc = host->mmc; 34921e72859eSPierre Ossman unsigned long flags; 34931e72859eSPierre Ossman 34941e72859eSPierre Ossman if (dead) { 34951e72859eSPierre Ossman spin_lock_irqsave(&host->lock, flags); 34961e72859eSPierre Ossman 34971e72859eSPierre Ossman host->flags |= SDHCI_DEVICE_DEAD; 34981e72859eSPierre Ossman 34991e72859eSPierre Ossman if (host->mrq) { 3500a3c76eb9SGirish K S pr_err("%s: Controller removed during " 35014e743f1fSMarkus Mayer " transfer!\n", mmc_hostname(mmc)); 35021e72859eSPierre Ossman 35031e72859eSPierre Ossman host->mrq->cmd->error = -ENOMEDIUM; 3504a6d3bdd5SAdrian Hunter sdhci_finish_mrq(host, host->mrq); 35051e72859eSPierre Ossman } 35061e72859eSPierre Ossman 35071e72859eSPierre Ossman spin_unlock_irqrestore(&host->lock, flags); 35081e72859eSPierre Ossman } 35091e72859eSPierre Ossman 35107260cf5eSAnton Vorontsov sdhci_disable_card_detection(host); 35117260cf5eSAnton Vorontsov 35124e743f1fSMarkus Mayer mmc_remove_host(mmc); 35131c6a0718SPierre Ossman 3514061d17a6SAdrian Hunter sdhci_led_unregister(host); 35152f730fecSPierre Ossman 35161e72859eSPierre Ossman if (!dead) 351703231f9bSRussell King sdhci_do_reset(host, SDHCI_RESET_ALL); 35181c6a0718SPierre Ossman 3519b537f94cSRussell King sdhci_writel(host, 0, SDHCI_INT_ENABLE); 3520b537f94cSRussell King sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE); 35211c6a0718SPierre Ossman free_irq(host->irq, host); 35221c6a0718SPierre Ossman 35231c6a0718SPierre Ossman del_timer_sync(&host->timer); 35241c6a0718SPierre Ossman 35251c6a0718SPierre Ossman tasklet_kill(&host->finish_tasklet); 35262134a922SPierre Ossman 35273a48edc4STim Kryger if (!IS_ERR(mmc->supply.vqmmc)) 35283a48edc4STim Kryger regulator_disable(mmc->supply.vqmmc); 35296231f3deSPhilip Rakity 3530edd63fccSRussell King if (host->align_buffer) 3531e66e61cbSRussell King dma_free_coherent(mmc_dev(mmc), host->align_buffer_sz + 3532e66e61cbSRussell King host->adma_table_sz, host->align_buffer, 3533e66e61cbSRussell King host->align_addr); 35342134a922SPierre Ossman 35354efaa6fbSAdrian Hunter host->adma_table = NULL; 35362134a922SPierre Ossman host->align_buffer = NULL; 35371c6a0718SPierre Ossman } 35381c6a0718SPierre Ossman 3539b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_remove_host); 3540b8c86fc5SPierre Ossman 3541b8c86fc5SPierre Ossman void sdhci_free_host(struct sdhci_host *host) 35421c6a0718SPierre Ossman { 3543b8c86fc5SPierre Ossman mmc_free_host(host->mmc); 35441c6a0718SPierre Ossman } 35451c6a0718SPierre Ossman 3546b8c86fc5SPierre Ossman EXPORT_SYMBOL_GPL(sdhci_free_host); 35471c6a0718SPierre Ossman 35481c6a0718SPierre Ossman /*****************************************************************************\ 35491c6a0718SPierre Ossman * * 35501c6a0718SPierre Ossman * Driver init/exit * 35511c6a0718SPierre Ossman * * 35521c6a0718SPierre Ossman \*****************************************************************************/ 35531c6a0718SPierre Ossman 35541c6a0718SPierre Ossman static int __init sdhci_drv_init(void) 35551c6a0718SPierre Ossman { 3556a3c76eb9SGirish K S pr_info(DRIVER_NAME 35571c6a0718SPierre Ossman ": Secure Digital Host Controller Interface driver\n"); 3558a3c76eb9SGirish K S pr_info(DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); 35591c6a0718SPierre Ossman 3560b8c86fc5SPierre Ossman return 0; 35611c6a0718SPierre Ossman } 35621c6a0718SPierre Ossman 35631c6a0718SPierre Ossman static void __exit sdhci_drv_exit(void) 35641c6a0718SPierre Ossman { 35651c6a0718SPierre Ossman } 35661c6a0718SPierre Ossman 35671c6a0718SPierre Ossman module_init(sdhci_drv_init); 35681c6a0718SPierre Ossman module_exit(sdhci_drv_exit); 35691c6a0718SPierre Ossman 35701c6a0718SPierre Ossman module_param(debug_quirks, uint, 0444); 357166fd8ad5SAdrian Hunter module_param(debug_quirks2, uint, 0444); 35721c6a0718SPierre Ossman 357332710e8fSPierre Ossman MODULE_AUTHOR("Pierre Ossman <pierre@ossman.eu>"); 3574b8c86fc5SPierre Ossman MODULE_DESCRIPTION("Secure Digital Host Controller Interface core driver"); 35751c6a0718SPierre Ossman MODULE_LICENSE("GPL"); 35761c6a0718SPierre Ossman 35771c6a0718SPierre Ossman MODULE_PARM_DESC(debug_quirks, "Force certain quirks."); 357866fd8ad5SAdrian Hunter MODULE_PARM_DESC(debug_quirks2, "Force certain other quirks."); 3579