1f707079dSWolfram Sang // SPDX-License-Identifier: GPL-2.0 2426e95d1SSimon Horman /* 3426e95d1SSimon Horman * Driver for the MMC / SD / SDIO IP found in: 4426e95d1SSimon Horman * 5426e95d1SSimon Horman * TC6393XB, TC6391XB, TC6387XB, T7L66XB, ASIC3, SH-Mobile SoCs 6426e95d1SSimon Horman * 7f49bdcdeSWolfram Sang * Copyright (C) 2015-19 Renesas Electronics Corporation 8f49bdcdeSWolfram Sang * Copyright (C) 2016-19 Sang Engineering, Wolfram Sang 987317c4dSSimon Horman * Copyright (C) 2017 Horms Solutions, Simon Horman 10426e95d1SSimon Horman * Copyright (C) 2011 Guennadi Liakhovetski 11426e95d1SSimon Horman * Copyright (C) 2007 Ian Molton 12426e95d1SSimon Horman * Copyright (C) 2004 Ian Molton 13426e95d1SSimon Horman * 14426e95d1SSimon Horman * This driver draws mainly on scattered spec sheets, Reverse engineering 15426e95d1SSimon Horman * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit 16426e95d1SSimon Horman * support). (Further 4 bit support from a later datasheet). 17426e95d1SSimon Horman * 18426e95d1SSimon Horman * TODO: 19426e95d1SSimon Horman * Investigate using a workqueue for PIO transfers 20426e95d1SSimon Horman * Eliminate FIXMEs 21426e95d1SSimon Horman * Better Power management 22426e95d1SSimon Horman * Handle MMC errors better 23426e95d1SSimon Horman * double buffer support 24426e95d1SSimon Horman * 25426e95d1SSimon Horman */ 26426e95d1SSimon Horman 27426e95d1SSimon Horman #include <linux/delay.h> 28426e95d1SSimon Horman #include <linux/device.h> 2963624d13SYoshihiro Shimoda #include <linux/dma-mapping.h> 30426e95d1SSimon Horman #include <linux/highmem.h> 31426e95d1SSimon Horman #include <linux/interrupt.h> 32426e95d1SSimon Horman #include <linux/io.h> 33426e95d1SSimon Horman #include <linux/irq.h> 34426e95d1SSimon Horman #include <linux/mfd/tmio.h> 35426e95d1SSimon Horman #include <linux/mmc/card.h> 36426e95d1SSimon Horman #include <linux/mmc/host.h> 37426e95d1SSimon Horman #include <linux/mmc/mmc.h> 38426e95d1SSimon Horman #include <linux/mmc/slot-gpio.h> 39426e95d1SSimon Horman #include <linux/module.h> 40426e95d1SSimon Horman #include <linux/pagemap.h> 41426e95d1SSimon Horman #include <linux/platform_device.h> 42426e95d1SSimon Horman #include <linux/pm_qos.h> 43426e95d1SSimon Horman #include <linux/pm_runtime.h> 44426e95d1SSimon Horman #include <linux/regulator/consumer.h> 45426e95d1SSimon Horman #include <linux/mmc/sdio.h> 46426e95d1SSimon Horman #include <linux/scatterlist.h> 475603731aSTakeshi Saito #include <linux/sizes.h> 48426e95d1SSimon Horman #include <linux/spinlock.h> 49426e95d1SSimon Horman #include <linux/workqueue.h> 50426e95d1SSimon Horman 51426e95d1SSimon Horman #include "tmio_mmc.h" 52426e95d1SSimon Horman 53426e95d1SSimon Horman static inline void tmio_mmc_start_dma(struct tmio_mmc_host *host, 54426e95d1SSimon Horman struct mmc_data *data) 55426e95d1SSimon Horman { 56426e95d1SSimon Horman if (host->dma_ops) 57426e95d1SSimon Horman host->dma_ops->start(host, data); 58426e95d1SSimon Horman } 59426e95d1SSimon Horman 60426e95d1SSimon Horman static inline void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable) 61426e95d1SSimon Horman { 62426e95d1SSimon Horman if (host->dma_ops) 63426e95d1SSimon Horman host->dma_ops->enable(host, enable); 64426e95d1SSimon Horman } 65426e95d1SSimon Horman 66426e95d1SSimon Horman static inline void tmio_mmc_request_dma(struct tmio_mmc_host *host, 67426e95d1SSimon Horman struct tmio_mmc_data *pdata) 68426e95d1SSimon Horman { 69426e95d1SSimon Horman if (host->dma_ops) { 70426e95d1SSimon Horman host->dma_ops->request(host, pdata); 71426e95d1SSimon Horman } else { 72426e95d1SSimon Horman host->chan_tx = NULL; 73426e95d1SSimon Horman host->chan_rx = NULL; 74426e95d1SSimon Horman } 75426e95d1SSimon Horman } 76426e95d1SSimon Horman 77426e95d1SSimon Horman static inline void tmio_mmc_release_dma(struct tmio_mmc_host *host) 78426e95d1SSimon Horman { 79426e95d1SSimon Horman if (host->dma_ops) 80426e95d1SSimon Horman host->dma_ops->release(host); 81426e95d1SSimon Horman } 82426e95d1SSimon Horman 83426e95d1SSimon Horman static inline void tmio_mmc_abort_dma(struct tmio_mmc_host *host) 84426e95d1SSimon Horman { 85426e95d1SSimon Horman if (host->dma_ops) 86426e95d1SSimon Horman host->dma_ops->abort(host); 87426e95d1SSimon Horman } 88426e95d1SSimon Horman 8992d0f925SSimon Horman static inline void tmio_mmc_dataend_dma(struct tmio_mmc_host *host) 9092d0f925SSimon Horman { 9192d0f925SSimon Horman if (host->dma_ops) 9292d0f925SSimon Horman host->dma_ops->dataend(host); 9392d0f925SSimon Horman } 9492d0f925SSimon Horman 95426e95d1SSimon Horman void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i) 96426e95d1SSimon Horman { 97426e95d1SSimon Horman host->sdcard_irq_mask &= ~(i & TMIO_MASK_IRQ); 98426e95d1SSimon Horman sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask); 99426e95d1SSimon Horman } 1006106ecf3SSimon Horman EXPORT_SYMBOL_GPL(tmio_mmc_enable_mmc_irqs); 101426e95d1SSimon Horman 102426e95d1SSimon Horman void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i) 103426e95d1SSimon Horman { 104426e95d1SSimon Horman host->sdcard_irq_mask |= (i & TMIO_MASK_IRQ); 105426e95d1SSimon Horman sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask); 106426e95d1SSimon Horman } 1076106ecf3SSimon Horman EXPORT_SYMBOL_GPL(tmio_mmc_disable_mmc_irqs); 108426e95d1SSimon Horman 109426e95d1SSimon Horman static void tmio_mmc_ack_mmc_irqs(struct tmio_mmc_host *host, u32 i) 110426e95d1SSimon Horman { 111426e95d1SSimon Horman sd_ctrl_write32_as_16_and_16(host, CTL_STATUS, ~i); 112426e95d1SSimon Horman } 113426e95d1SSimon Horman 114426e95d1SSimon Horman static void tmio_mmc_init_sg(struct tmio_mmc_host *host, struct mmc_data *data) 115426e95d1SSimon Horman { 116426e95d1SSimon Horman host->sg_len = data->sg_len; 117426e95d1SSimon Horman host->sg_ptr = data->sg; 118426e95d1SSimon Horman host->sg_orig = data->sg; 119426e95d1SSimon Horman host->sg_off = 0; 120426e95d1SSimon Horman } 121426e95d1SSimon Horman 122426e95d1SSimon Horman static int tmio_mmc_next_sg(struct tmio_mmc_host *host) 123426e95d1SSimon Horman { 124426e95d1SSimon Horman host->sg_ptr = sg_next(host->sg_ptr); 125426e95d1SSimon Horman host->sg_off = 0; 126426e95d1SSimon Horman return --host->sg_len; 127426e95d1SSimon Horman } 128426e95d1SSimon Horman 129426e95d1SSimon Horman #define CMDREQ_TIMEOUT 5000 130426e95d1SSimon Horman 131426e95d1SSimon Horman static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) 132426e95d1SSimon Horman { 133426e95d1SSimon Horman struct tmio_mmc_host *host = mmc_priv(mmc); 134426e95d1SSimon Horman 135426e95d1SSimon Horman if (enable && !host->sdio_irq_enabled) { 136426e95d1SSimon Horman u16 sdio_status; 137426e95d1SSimon Horman 138426e95d1SSimon Horman /* Keep device active while SDIO irq is enabled */ 139426e95d1SSimon Horman pm_runtime_get_sync(mmc_dev(mmc)); 140426e95d1SSimon Horman 141426e95d1SSimon Horman host->sdio_irq_enabled = true; 142f2218db8SSimon Horman host->sdio_irq_mask = TMIO_SDIO_MASK_ALL & ~TMIO_SDIO_STAT_IOIRQ; 143426e95d1SSimon Horman 144426e95d1SSimon Horman /* Clear obsolete interrupts before enabling */ 145426e95d1SSimon Horman sdio_status = sd_ctrl_read16(host, CTL_SDIO_STATUS) & ~TMIO_SDIO_MASK_ALL; 146426e95d1SSimon Horman if (host->pdata->flags & TMIO_MMC_SDIO_STATUS_SETBITS) 147426e95d1SSimon Horman sdio_status |= TMIO_SDIO_SETBITS_MASK; 148426e95d1SSimon Horman sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status); 149426e95d1SSimon Horman 150426e95d1SSimon Horman sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); 151426e95d1SSimon Horman } else if (!enable && host->sdio_irq_enabled) { 152426e95d1SSimon Horman host->sdio_irq_mask = TMIO_SDIO_MASK_ALL; 153426e95d1SSimon Horman sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); 154426e95d1SSimon Horman 155426e95d1SSimon Horman host->sdio_irq_enabled = false; 156426e95d1SSimon Horman pm_runtime_mark_last_busy(mmc_dev(mmc)); 157426e95d1SSimon Horman pm_runtime_put_autosuspend(mmc_dev(mmc)); 158426e95d1SSimon Horman } 159426e95d1SSimon Horman } 160426e95d1SSimon Horman 161426e95d1SSimon Horman static void tmio_mmc_reset(struct tmio_mmc_host *host) 162426e95d1SSimon Horman { 163426e95d1SSimon Horman /* FIXME - should we set stop clock reg here */ 164426e95d1SSimon Horman sd_ctrl_write16(host, CTL_RESET_SD, 0x0000); 1651f27ddf0SMasaharu Hayakawa usleep_range(10000, 11000); 166426e95d1SSimon Horman sd_ctrl_write16(host, CTL_RESET_SD, 0x0001); 1671f27ddf0SMasaharu Hayakawa usleep_range(10000, 11000); 16886beb538SWolfram Sang 16986beb538SWolfram Sang if (host->pdata->flags & TMIO_MMC_SDIO_IRQ) { 17086beb538SWolfram Sang sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, host->sdio_irq_mask); 17186beb538SWolfram Sang sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001); 17286beb538SWolfram Sang } 173426e95d1SSimon Horman } 174426e95d1SSimon Horman 175a87852c6SNiklas Söderlund static void tmio_mmc_hw_reset(struct mmc_host *mmc) 176a87852c6SNiklas Söderlund { 177a87852c6SNiklas Söderlund struct tmio_mmc_host *host = mmc_priv(mmc); 178a87852c6SNiklas Söderlund 179a87852c6SNiklas Söderlund host->reset(host); 180a87852c6SNiklas Söderlund 181a87852c6SNiklas Söderlund tmio_mmc_abort_dma(host); 182a87852c6SNiklas Söderlund 183a87852c6SNiklas Söderlund if (host->hw_reset) 184a87852c6SNiklas Söderlund host->hw_reset(host); 185a87852c6SNiklas Söderlund } 186a87852c6SNiklas Söderlund 187426e95d1SSimon Horman static void tmio_mmc_reset_work(struct work_struct *work) 188426e95d1SSimon Horman { 189426e95d1SSimon Horman struct tmio_mmc_host *host = container_of(work, struct tmio_mmc_host, 190426e95d1SSimon Horman delayed_reset_work.work); 191426e95d1SSimon Horman struct mmc_request *mrq; 192426e95d1SSimon Horman unsigned long flags; 193426e95d1SSimon Horman 194426e95d1SSimon Horman spin_lock_irqsave(&host->lock, flags); 195426e95d1SSimon Horman mrq = host->mrq; 196426e95d1SSimon Horman 197426e95d1SSimon Horman /* 198426e95d1SSimon Horman * is request already finished? Since we use a non-blocking 199426e95d1SSimon Horman * cancel_delayed_work(), it can happen, that a .set_ios() call preempts 200426e95d1SSimon Horman * us, so, have to check for IS_ERR(host->mrq) 201426e95d1SSimon Horman */ 202f2218db8SSimon Horman if (IS_ERR_OR_NULL(mrq) || 203f2218db8SSimon Horman time_is_after_jiffies(host->last_req_ts + 204426e95d1SSimon Horman msecs_to_jiffies(CMDREQ_TIMEOUT))) { 205426e95d1SSimon Horman spin_unlock_irqrestore(&host->lock, flags); 206426e95d1SSimon Horman return; 207426e95d1SSimon Horman } 208426e95d1SSimon Horman 209426e95d1SSimon Horman dev_warn(&host->pdev->dev, 210426e95d1SSimon Horman "timeout waiting for hardware interrupt (CMD%u)\n", 211426e95d1SSimon Horman mrq->cmd->opcode); 212426e95d1SSimon Horman 213426e95d1SSimon Horman if (host->data) 214426e95d1SSimon Horman host->data->error = -ETIMEDOUT; 215426e95d1SSimon Horman else if (host->cmd) 216426e95d1SSimon Horman host->cmd->error = -ETIMEDOUT; 217426e95d1SSimon Horman else 218426e95d1SSimon Horman mrq->cmd->error = -ETIMEDOUT; 219426e95d1SSimon Horman 220426e95d1SSimon Horman host->cmd = NULL; 221426e95d1SSimon Horman host->data = NULL; 222426e95d1SSimon Horman 223426e95d1SSimon Horman spin_unlock_irqrestore(&host->lock, flags); 224426e95d1SSimon Horman 225a87852c6SNiklas Söderlund tmio_mmc_hw_reset(host->mmc); 226426e95d1SSimon Horman 227426e95d1SSimon Horman /* Ready for new calls */ 228426e95d1SSimon Horman host->mrq = NULL; 229426e95d1SSimon Horman 230426e95d1SSimon Horman mmc_request_done(host->mmc, mrq); 231426e95d1SSimon Horman } 232426e95d1SSimon Horman 233426e95d1SSimon Horman /* These are the bitmasks the tmio chip requires to implement the MMC response 234426e95d1SSimon Horman * types. Note that R1 and R6 are the same in this scheme. */ 235426e95d1SSimon Horman #define APP_CMD 0x0040 236426e95d1SSimon Horman #define RESP_NONE 0x0300 237426e95d1SSimon Horman #define RESP_R1 0x0400 238426e95d1SSimon Horman #define RESP_R1B 0x0500 239426e95d1SSimon Horman #define RESP_R2 0x0600 240426e95d1SSimon Horman #define RESP_R3 0x0700 241426e95d1SSimon Horman #define DATA_PRESENT 0x0800 242426e95d1SSimon Horman #define TRANSFER_READ 0x1000 243426e95d1SSimon Horman #define TRANSFER_MULTI 0x2000 244426e95d1SSimon Horman #define SECURITY_CMD 0x4000 245426e95d1SSimon Horman #define NO_CMD12_ISSUE 0x4000 /* TMIO_MMC_HAVE_CMD12_CTRL */ 246426e95d1SSimon Horman 247f2218db8SSimon Horman static int tmio_mmc_start_command(struct tmio_mmc_host *host, 248f2218db8SSimon Horman struct mmc_command *cmd) 249426e95d1SSimon Horman { 250426e95d1SSimon Horman struct mmc_data *data = host->data; 251426e95d1SSimon Horman int c = cmd->opcode; 252426e95d1SSimon Horman 253426e95d1SSimon Horman switch (mmc_resp_type(cmd)) { 254426e95d1SSimon Horman case MMC_RSP_NONE: c |= RESP_NONE; break; 255426e95d1SSimon Horman case MMC_RSP_R1: 256426e95d1SSimon Horman case MMC_RSP_R1_NO_CRC: 257426e95d1SSimon Horman c |= RESP_R1; break; 258426e95d1SSimon Horman case MMC_RSP_R1B: c |= RESP_R1B; break; 259426e95d1SSimon Horman case MMC_RSP_R2: c |= RESP_R2; break; 260426e95d1SSimon Horman case MMC_RSP_R3: c |= RESP_R3; break; 261426e95d1SSimon Horman default: 262426e95d1SSimon Horman pr_debug("Unknown response type %d\n", mmc_resp_type(cmd)); 263426e95d1SSimon Horman return -EINVAL; 264426e95d1SSimon Horman } 265426e95d1SSimon Horman 266426e95d1SSimon Horman host->cmd = cmd; 267426e95d1SSimon Horman 268426e95d1SSimon Horman /* FIXME - this seems to be ok commented out but the spec suggest this bit 269426e95d1SSimon Horman * should be set when issuing app commands. 270426e95d1SSimon Horman * if(cmd->flags & MMC_FLAG_ACMD) 271426e95d1SSimon Horman * c |= APP_CMD; 272426e95d1SSimon Horman */ 273426e95d1SSimon Horman if (data) { 274426e95d1SSimon Horman c |= DATA_PRESENT; 275426e95d1SSimon Horman if (data->blocks > 1) { 276426e95d1SSimon Horman sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, TMIO_STOP_SEC); 277426e95d1SSimon Horman c |= TRANSFER_MULTI; 278426e95d1SSimon Horman 279426e95d1SSimon Horman /* 280f2218db8SSimon Horman * Disable auto CMD12 at IO_RW_EXTENDED and 281f2218db8SSimon Horman * SET_BLOCK_COUNT when doing multiple block transfer 282426e95d1SSimon Horman */ 283426e95d1SSimon Horman if ((host->pdata->flags & TMIO_MMC_HAVE_CMD12_CTRL) && 2848b22c3c1SWolfram Sang (cmd->opcode == SD_IO_RW_EXTENDED || host->mrq->sbc)) 285426e95d1SSimon Horman c |= NO_CMD12_ISSUE; 286426e95d1SSimon Horman } 287426e95d1SSimon Horman if (data->flags & MMC_DATA_READ) 288426e95d1SSimon Horman c |= TRANSFER_READ; 289426e95d1SSimon Horman } 290426e95d1SSimon Horman 291e401bfdaSMasahiro Yamada tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_CMD); 292426e95d1SSimon Horman 293426e95d1SSimon Horman /* Fire off the command */ 294426e95d1SSimon Horman sd_ctrl_write32_as_16_and_16(host, CTL_ARG_REG, cmd->arg); 295426e95d1SSimon Horman sd_ctrl_write16(host, CTL_SD_CMD, c); 296426e95d1SSimon Horman 297426e95d1SSimon Horman return 0; 298426e95d1SSimon Horman } 299426e95d1SSimon Horman 300426e95d1SSimon Horman static void tmio_mmc_transfer_data(struct tmio_mmc_host *host, 301426e95d1SSimon Horman unsigned short *buf, 302426e95d1SSimon Horman unsigned int count) 303426e95d1SSimon Horman { 304426e95d1SSimon Horman int is_read = host->data->flags & MMC_DATA_READ; 305426e95d1SSimon Horman u8 *buf8; 306426e95d1SSimon Horman 307426e95d1SSimon Horman /* 308426e95d1SSimon Horman * Transfer the data 309426e95d1SSimon Horman */ 310426e95d1SSimon Horman if (host->pdata->flags & TMIO_MMC_32BIT_DATA_PORT) { 3119c284c41SChris Brandt u32 data = 0; 3129c284c41SChris Brandt u32 *buf32 = (u32 *)buf; 313426e95d1SSimon Horman 314426e95d1SSimon Horman if (is_read) 3159c284c41SChris Brandt sd_ctrl_read32_rep(host, CTL_SD_DATA_PORT, buf32, 316426e95d1SSimon Horman count >> 2); 317426e95d1SSimon Horman else 3189c284c41SChris Brandt sd_ctrl_write32_rep(host, CTL_SD_DATA_PORT, buf32, 319426e95d1SSimon Horman count >> 2); 320426e95d1SSimon Horman 321426e95d1SSimon Horman /* if count was multiple of 4 */ 322426e95d1SSimon Horman if (!(count & 0x3)) 323426e95d1SSimon Horman return; 324426e95d1SSimon Horman 3259c284c41SChris Brandt buf32 += count >> 2; 326426e95d1SSimon Horman count %= 4; 327426e95d1SSimon Horman 328426e95d1SSimon Horman if (is_read) { 3299c284c41SChris Brandt sd_ctrl_read32_rep(host, CTL_SD_DATA_PORT, &data, 1); 3309c284c41SChris Brandt memcpy(buf32, &data, count); 331426e95d1SSimon Horman } else { 3329c284c41SChris Brandt memcpy(&data, buf32, count); 3339c284c41SChris Brandt sd_ctrl_write32_rep(host, CTL_SD_DATA_PORT, &data, 1); 334426e95d1SSimon Horman } 335426e95d1SSimon Horman 336426e95d1SSimon Horman return; 337426e95d1SSimon Horman } 338426e95d1SSimon Horman 339426e95d1SSimon Horman if (is_read) 340426e95d1SSimon Horman sd_ctrl_read16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1); 341426e95d1SSimon Horman else 342426e95d1SSimon Horman sd_ctrl_write16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1); 343426e95d1SSimon Horman 344426e95d1SSimon Horman /* if count was even number */ 345426e95d1SSimon Horman if (!(count & 0x1)) 346426e95d1SSimon Horman return; 347426e95d1SSimon Horman 348426e95d1SSimon Horman /* if count was odd number */ 349426e95d1SSimon Horman buf8 = (u8 *)(buf + (count >> 1)); 350426e95d1SSimon Horman 351426e95d1SSimon Horman /* 352426e95d1SSimon Horman * FIXME 353426e95d1SSimon Horman * 354426e95d1SSimon Horman * driver and this function are assuming that 355426e95d1SSimon Horman * it is used as little endian 356426e95d1SSimon Horman */ 357426e95d1SSimon Horman if (is_read) 358426e95d1SSimon Horman *buf8 = sd_ctrl_read16(host, CTL_SD_DATA_PORT) & 0xff; 359426e95d1SSimon Horman else 360426e95d1SSimon Horman sd_ctrl_write16(host, CTL_SD_DATA_PORT, *buf8); 361426e95d1SSimon Horman } 362426e95d1SSimon Horman 363426e95d1SSimon Horman /* 364426e95d1SSimon Horman * This chip always returns (at least?) as much data as you ask for. 365426e95d1SSimon Horman * I'm unsure what happens if you ask for less than a block. This should be 366426e95d1SSimon Horman * looked into to ensure that a funny length read doesn't hose the controller. 367426e95d1SSimon Horman */ 368426e95d1SSimon Horman static void tmio_mmc_pio_irq(struct tmio_mmc_host *host) 369426e95d1SSimon Horman { 370426e95d1SSimon Horman struct mmc_data *data = host->data; 371426e95d1SSimon Horman void *sg_virt; 372426e95d1SSimon Horman unsigned short *buf; 373426e95d1SSimon Horman unsigned int count; 374426e95d1SSimon Horman unsigned long flags; 375426e95d1SSimon Horman 376d3dd5db0SMasahiro Yamada if (host->dma_on) { 377426e95d1SSimon Horman pr_err("PIO IRQ in DMA mode!\n"); 378426e95d1SSimon Horman return; 379426e95d1SSimon Horman } else if (!data) { 380426e95d1SSimon Horman pr_debug("Spurious PIO IRQ\n"); 381426e95d1SSimon Horman return; 382426e95d1SSimon Horman } 383426e95d1SSimon Horman 384426e95d1SSimon Horman sg_virt = tmio_mmc_kmap_atomic(host->sg_ptr, &flags); 385426e95d1SSimon Horman buf = (unsigned short *)(sg_virt + host->sg_off); 386426e95d1SSimon Horman 387426e95d1SSimon Horman count = host->sg_ptr->length - host->sg_off; 388426e95d1SSimon Horman if (count > data->blksz) 389426e95d1SSimon Horman count = data->blksz; 390426e95d1SSimon Horman 391426e95d1SSimon Horman pr_debug("count: %08x offset: %08x flags %08x\n", 392426e95d1SSimon Horman count, host->sg_off, data->flags); 393426e95d1SSimon Horman 394426e95d1SSimon Horman /* Transfer the data */ 395426e95d1SSimon Horman tmio_mmc_transfer_data(host, buf, count); 396426e95d1SSimon Horman 397426e95d1SSimon Horman host->sg_off += count; 398426e95d1SSimon Horman 399426e95d1SSimon Horman tmio_mmc_kunmap_atomic(host->sg_ptr, &flags, sg_virt); 400426e95d1SSimon Horman 401426e95d1SSimon Horman if (host->sg_off == host->sg_ptr->length) 402426e95d1SSimon Horman tmio_mmc_next_sg(host); 403426e95d1SSimon Horman } 404426e95d1SSimon Horman 405426e95d1SSimon Horman static void tmio_mmc_check_bounce_buffer(struct tmio_mmc_host *host) 406426e95d1SSimon Horman { 407426e95d1SSimon Horman if (host->sg_ptr == &host->bounce_sg) { 408426e95d1SSimon Horman unsigned long flags; 409426e95d1SSimon Horman void *sg_vaddr = tmio_mmc_kmap_atomic(host->sg_orig, &flags); 410f2218db8SSimon Horman 411426e95d1SSimon Horman memcpy(sg_vaddr, host->bounce_buf, host->bounce_sg.length); 412426e95d1SSimon Horman tmio_mmc_kunmap_atomic(host->sg_orig, &flags, sg_vaddr); 413426e95d1SSimon Horman } 414426e95d1SSimon Horman } 415426e95d1SSimon Horman 416426e95d1SSimon Horman /* needs to be called with host->lock held */ 417426e95d1SSimon Horman void tmio_mmc_do_data_irq(struct tmio_mmc_host *host) 418426e95d1SSimon Horman { 419426e95d1SSimon Horman struct mmc_data *data = host->data; 420426e95d1SSimon Horman struct mmc_command *stop; 421426e95d1SSimon Horman 422426e95d1SSimon Horman host->data = NULL; 423426e95d1SSimon Horman 424426e95d1SSimon Horman if (!data) { 425426e95d1SSimon Horman dev_warn(&host->pdev->dev, "Spurious data end IRQ\n"); 426426e95d1SSimon Horman return; 427426e95d1SSimon Horman } 428426e95d1SSimon Horman stop = data->stop; 429426e95d1SSimon Horman 430426e95d1SSimon Horman /* FIXME - return correct transfer count on errors */ 431426e95d1SSimon Horman if (!data->error) 432426e95d1SSimon Horman data->bytes_xfered = data->blocks * data->blksz; 433426e95d1SSimon Horman else 434426e95d1SSimon Horman data->bytes_xfered = 0; 435426e95d1SSimon Horman 436426e95d1SSimon Horman pr_debug("Completed data request\n"); 437426e95d1SSimon Horman 438426e95d1SSimon Horman /* 439426e95d1SSimon Horman * FIXME: other drivers allow an optional stop command of any given type 440426e95d1SSimon Horman * which we dont do, as the chip can auto generate them. 441426e95d1SSimon Horman * Perhaps we can be smarter about when to use auto CMD12 and 442426e95d1SSimon Horman * only issue the auto request when we know this is the desired 443426e95d1SSimon Horman * stop command, allowing fallback to the stop command the 444426e95d1SSimon Horman * upper layers expect. For now, we do what works. 445426e95d1SSimon Horman */ 446426e95d1SSimon Horman 447426e95d1SSimon Horman if (data->flags & MMC_DATA_READ) { 448d3dd5db0SMasahiro Yamada if (host->dma_on) 449426e95d1SSimon Horman tmio_mmc_check_bounce_buffer(host); 450426e95d1SSimon Horman dev_dbg(&host->pdev->dev, "Complete Rx request %p\n", 451426e95d1SSimon Horman host->mrq); 452426e95d1SSimon Horman } else { 453426e95d1SSimon Horman dev_dbg(&host->pdev->dev, "Complete Tx request %p\n", 454426e95d1SSimon Horman host->mrq); 455426e95d1SSimon Horman } 456426e95d1SSimon Horman 4578b22c3c1SWolfram Sang if (stop && !host->mrq->sbc) { 458426e95d1SSimon Horman if (stop->opcode != MMC_STOP_TRANSMISSION || stop->arg) 459426e95d1SSimon Horman dev_err(&host->pdev->dev, "unsupported stop: CMD%u,0x%x. We did CMD12,0\n", 460426e95d1SSimon Horman stop->opcode, stop->arg); 461426e95d1SSimon Horman 462426e95d1SSimon Horman /* fill in response from auto CMD12 */ 463426e95d1SSimon Horman stop->resp[0] = sd_ctrl_read16_and_16_as_32(host, CTL_RESPONSE); 464426e95d1SSimon Horman 465426e95d1SSimon Horman sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0); 466426e95d1SSimon Horman } 467426e95d1SSimon Horman 468426e95d1SSimon Horman schedule_work(&host->done); 469426e95d1SSimon Horman } 4706106ecf3SSimon Horman EXPORT_SYMBOL_GPL(tmio_mmc_do_data_irq); 471426e95d1SSimon Horman 472426e95d1SSimon Horman static void tmio_mmc_data_irq(struct tmio_mmc_host *host, unsigned int stat) 473426e95d1SSimon Horman { 474426e95d1SSimon Horman struct mmc_data *data; 475f2218db8SSimon Horman 476426e95d1SSimon Horman spin_lock(&host->lock); 477426e95d1SSimon Horman data = host->data; 478426e95d1SSimon Horman 479426e95d1SSimon Horman if (!data) 480426e95d1SSimon Horman goto out; 481426e95d1SSimon Horman 482426e95d1SSimon Horman if (stat & TMIO_STAT_CRCFAIL || stat & TMIO_STAT_STOPBIT_ERR || 483426e95d1SSimon Horman stat & TMIO_STAT_TXUNDERRUN) 484426e95d1SSimon Horman data->error = -EILSEQ; 485d3dd5db0SMasahiro Yamada if (host->dma_on && (data->flags & MMC_DATA_WRITE)) { 486426e95d1SSimon Horman u32 status = sd_ctrl_read16_and_16_as_32(host, CTL_STATUS); 487426e95d1SSimon Horman bool done = false; 488426e95d1SSimon Horman 489426e95d1SSimon Horman /* 490426e95d1SSimon Horman * Has all data been written out yet? Testing on SuperH showed, 491426e95d1SSimon Horman * that in most cases the first interrupt comes already with the 492426e95d1SSimon Horman * BUSY status bit clear, but on some operations, like mount or 493426e95d1SSimon Horman * in the beginning of a write / sync / umount, there is one 494426e95d1SSimon Horman * DATAEND interrupt with the BUSY bit set, in this cases 495426e95d1SSimon Horman * waiting for one more interrupt fixes the problem. 496426e95d1SSimon Horman */ 497426e95d1SSimon Horman if (host->pdata->flags & TMIO_MMC_HAS_IDLE_WAIT) { 498426e95d1SSimon Horman if (status & TMIO_STAT_SCLKDIVEN) 499426e95d1SSimon Horman done = true; 500426e95d1SSimon Horman } else { 501426e95d1SSimon Horman if (!(status & TMIO_STAT_CMD_BUSY)) 502426e95d1SSimon Horman done = true; 503426e95d1SSimon Horman } 504426e95d1SSimon Horman 505426e95d1SSimon Horman if (done) { 506426e95d1SSimon Horman tmio_mmc_disable_mmc_irqs(host, TMIO_STAT_DATAEND); 50792d0f925SSimon Horman tmio_mmc_dataend_dma(host); 508426e95d1SSimon Horman } 509d3dd5db0SMasahiro Yamada } else if (host->dma_on && (data->flags & MMC_DATA_READ)) { 510426e95d1SSimon Horman tmio_mmc_disable_mmc_irqs(host, TMIO_STAT_DATAEND); 51192d0f925SSimon Horman tmio_mmc_dataend_dma(host); 512426e95d1SSimon Horman } else { 513426e95d1SSimon Horman tmio_mmc_do_data_irq(host); 514426e95d1SSimon Horman tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_READOP | TMIO_MASK_WRITEOP); 515426e95d1SSimon Horman } 516426e95d1SSimon Horman out: 517426e95d1SSimon Horman spin_unlock(&host->lock); 518426e95d1SSimon Horman } 519426e95d1SSimon Horman 520f2218db8SSimon Horman static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host, unsigned int stat) 521426e95d1SSimon Horman { 522426e95d1SSimon Horman struct mmc_command *cmd = host->cmd; 523426e95d1SSimon Horman int i, addr; 524426e95d1SSimon Horman 525426e95d1SSimon Horman spin_lock(&host->lock); 526426e95d1SSimon Horman 527426e95d1SSimon Horman if (!host->cmd) { 528426e95d1SSimon Horman pr_debug("Spurious CMD irq\n"); 529426e95d1SSimon Horman goto out; 530426e95d1SSimon Horman } 531426e95d1SSimon Horman 532426e95d1SSimon Horman /* This controller is sicker than the PXA one. Not only do we need to 533426e95d1SSimon Horman * drop the top 8 bits of the first response word, we also need to 534426e95d1SSimon Horman * modify the order of the response for short response command types. 535426e95d1SSimon Horman */ 536426e95d1SSimon Horman 537426e95d1SSimon Horman for (i = 3, addr = CTL_RESPONSE ; i >= 0 ; i--, addr += 4) 538426e95d1SSimon Horman cmd->resp[i] = sd_ctrl_read16_and_16_as_32(host, addr); 539426e95d1SSimon Horman 540426e95d1SSimon Horman if (cmd->flags & MMC_RSP_136) { 541426e95d1SSimon Horman cmd->resp[0] = (cmd->resp[0] << 8) | (cmd->resp[1] >> 24); 542426e95d1SSimon Horman cmd->resp[1] = (cmd->resp[1] << 8) | (cmd->resp[2] >> 24); 543426e95d1SSimon Horman cmd->resp[2] = (cmd->resp[2] << 8) | (cmd->resp[3] >> 24); 544426e95d1SSimon Horman cmd->resp[3] <<= 8; 545426e95d1SSimon Horman } else if (cmd->flags & MMC_RSP_R3) { 546426e95d1SSimon Horman cmd->resp[0] = cmd->resp[3]; 547426e95d1SSimon Horman } 548426e95d1SSimon Horman 549426e95d1SSimon Horman if (stat & TMIO_STAT_CMDTIMEOUT) 550426e95d1SSimon Horman cmd->error = -ETIMEDOUT; 551426e95d1SSimon Horman else if ((stat & TMIO_STAT_CRCFAIL && cmd->flags & MMC_RSP_CRC) || 552426e95d1SSimon Horman stat & TMIO_STAT_STOPBIT_ERR || 553426e95d1SSimon Horman stat & TMIO_STAT_CMD_IDX_ERR) 554426e95d1SSimon Horman cmd->error = -EILSEQ; 555426e95d1SSimon Horman 556426e95d1SSimon Horman /* If there is data to handle we enable data IRQs here, and 557426e95d1SSimon Horman * we will ultimatley finish the request in the data_end handler. 558426e95d1SSimon Horman * If theres no data or we encountered an error, finish now. 559426e95d1SSimon Horman */ 560426e95d1SSimon Horman if (host->data && (!cmd->error || cmd->error == -EILSEQ)) { 561426e95d1SSimon Horman if (host->data->flags & MMC_DATA_READ) { 562d3dd5db0SMasahiro Yamada if (!host->dma_on) { 563426e95d1SSimon Horman tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_READOP); 564426e95d1SSimon Horman } else { 565b12a7a28SMasahiro Yamada tmio_mmc_disable_mmc_irqs(host, 566b12a7a28SMasahiro Yamada TMIO_MASK_READOP); 567426e95d1SSimon Horman tasklet_schedule(&host->dma_issue); 568426e95d1SSimon Horman } 569426e95d1SSimon Horman } else { 570d3dd5db0SMasahiro Yamada if (!host->dma_on) { 571b12a7a28SMasahiro Yamada tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_WRITEOP); 572b12a7a28SMasahiro Yamada } else { 573b12a7a28SMasahiro Yamada tmio_mmc_disable_mmc_irqs(host, 574b12a7a28SMasahiro Yamada TMIO_MASK_WRITEOP); 575b12a7a28SMasahiro Yamada tasklet_schedule(&host->dma_issue); 576b12a7a28SMasahiro Yamada } 577b12a7a28SMasahiro Yamada } 578b12a7a28SMasahiro Yamada } else { 579426e95d1SSimon Horman schedule_work(&host->done); 580426e95d1SSimon Horman } 581426e95d1SSimon Horman 582426e95d1SSimon Horman out: 583426e95d1SSimon Horman spin_unlock(&host->lock); 584426e95d1SSimon Horman } 585426e95d1SSimon Horman 586426e95d1SSimon Horman static bool __tmio_mmc_card_detect_irq(struct tmio_mmc_host *host, 587426e95d1SSimon Horman int ireg, int status) 588426e95d1SSimon Horman { 589426e95d1SSimon Horman struct mmc_host *mmc = host->mmc; 590426e95d1SSimon Horman 591426e95d1SSimon Horman /* Card insert / remove attempts */ 592426e95d1SSimon Horman if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) { 593426e95d1SSimon Horman tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT | 594426e95d1SSimon Horman TMIO_STAT_CARD_REMOVE); 595426e95d1SSimon Horman if ((((ireg & TMIO_STAT_CARD_REMOVE) && mmc->card) || 596426e95d1SSimon Horman ((ireg & TMIO_STAT_CARD_INSERT) && !mmc->card)) && 597426e95d1SSimon Horman !work_pending(&mmc->detect.work)) 598426e95d1SSimon Horman mmc_detect_change(host->mmc, msecs_to_jiffies(100)); 599426e95d1SSimon Horman return true; 600426e95d1SSimon Horman } 601426e95d1SSimon Horman 602426e95d1SSimon Horman return false; 603426e95d1SSimon Horman } 604426e95d1SSimon Horman 605f2218db8SSimon Horman static bool __tmio_mmc_sdcard_irq(struct tmio_mmc_host *host, int ireg, 606f2218db8SSimon Horman int status) 607426e95d1SSimon Horman { 608426e95d1SSimon Horman /* Command completion */ 609426e95d1SSimon Horman if (ireg & (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT)) { 610f2218db8SSimon Horman tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_CMDRESPEND | 611426e95d1SSimon Horman TMIO_STAT_CMDTIMEOUT); 612426e95d1SSimon Horman tmio_mmc_cmd_irq(host, status); 613426e95d1SSimon Horman return true; 614426e95d1SSimon Horman } 615426e95d1SSimon Horman 616426e95d1SSimon Horman /* Data transfer */ 617426e95d1SSimon Horman if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) { 618426e95d1SSimon Horman tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ); 619426e95d1SSimon Horman tmio_mmc_pio_irq(host); 620426e95d1SSimon Horman return true; 621426e95d1SSimon Horman } 622426e95d1SSimon Horman 623426e95d1SSimon Horman /* Data transfer completion */ 624426e95d1SSimon Horman if (ireg & TMIO_STAT_DATAEND) { 625426e95d1SSimon Horman tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_DATAEND); 626426e95d1SSimon Horman tmio_mmc_data_irq(host, status); 627426e95d1SSimon Horman return true; 628426e95d1SSimon Horman } 629426e95d1SSimon Horman 630426e95d1SSimon Horman return false; 631426e95d1SSimon Horman } 632426e95d1SSimon Horman 6335c27ff5dSSergei Shtylyov static bool __tmio_mmc_sdio_irq(struct tmio_mmc_host *host) 634426e95d1SSimon Horman { 635426e95d1SSimon Horman struct mmc_host *mmc = host->mmc; 636426e95d1SSimon Horman struct tmio_mmc_data *pdata = host->pdata; 637426e95d1SSimon Horman unsigned int ireg, status; 638426e95d1SSimon Horman unsigned int sdio_status; 639426e95d1SSimon Horman 640426e95d1SSimon Horman if (!(pdata->flags & TMIO_MMC_SDIO_IRQ)) 6415c27ff5dSSergei Shtylyov return false; 642426e95d1SSimon Horman 643426e95d1SSimon Horman status = sd_ctrl_read16(host, CTL_SDIO_STATUS); 644426e95d1SSimon Horman ireg = status & TMIO_SDIO_MASK_ALL & ~host->sdio_irq_mask; 645426e95d1SSimon Horman 646426e95d1SSimon Horman sdio_status = status & ~TMIO_SDIO_MASK_ALL; 647426e95d1SSimon Horman if (pdata->flags & TMIO_MMC_SDIO_STATUS_SETBITS) 648426e95d1SSimon Horman sdio_status |= TMIO_SDIO_SETBITS_MASK; 649426e95d1SSimon Horman 650426e95d1SSimon Horman sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status); 651426e95d1SSimon Horman 652426e95d1SSimon Horman if (mmc->caps & MMC_CAP_SDIO_IRQ && ireg & TMIO_SDIO_STAT_IOIRQ) 653426e95d1SSimon Horman mmc_signal_sdio_irq(mmc); 6545c27ff5dSSergei Shtylyov 6555c27ff5dSSergei Shtylyov return ireg; 656426e95d1SSimon Horman } 657426e95d1SSimon Horman 658426e95d1SSimon Horman irqreturn_t tmio_mmc_irq(int irq, void *devid) 659426e95d1SSimon Horman { 660426e95d1SSimon Horman struct tmio_mmc_host *host = devid; 661426e95d1SSimon Horman unsigned int ireg, status; 662426e95d1SSimon Horman 663426e95d1SSimon Horman status = sd_ctrl_read16_and_16_as_32(host, CTL_STATUS); 664426e95d1SSimon Horman ireg = status & TMIO_MASK_IRQ & ~host->sdcard_irq_mask; 665426e95d1SSimon Horman 666426e95d1SSimon Horman /* Clear the status except the interrupt status */ 667426e95d1SSimon Horman sd_ctrl_write32_as_16_and_16(host, CTL_STATUS, TMIO_MASK_IRQ); 668426e95d1SSimon Horman 669426e95d1SSimon Horman if (__tmio_mmc_card_detect_irq(host, ireg, status)) 670426e95d1SSimon Horman return IRQ_HANDLED; 671426e95d1SSimon Horman if (__tmio_mmc_sdcard_irq(host, ireg, status)) 672426e95d1SSimon Horman return IRQ_HANDLED; 673426e95d1SSimon Horman 6745c27ff5dSSergei Shtylyov if (__tmio_mmc_sdio_irq(host)) 675426e95d1SSimon Horman return IRQ_HANDLED; 6765c27ff5dSSergei Shtylyov 6775c27ff5dSSergei Shtylyov return IRQ_NONE; 678426e95d1SSimon Horman } 6796106ecf3SSimon Horman EXPORT_SYMBOL_GPL(tmio_mmc_irq); 680426e95d1SSimon Horman 681426e95d1SSimon Horman static int tmio_mmc_start_data(struct tmio_mmc_host *host, 682426e95d1SSimon Horman struct mmc_data *data) 683426e95d1SSimon Horman { 684426e95d1SSimon Horman struct tmio_mmc_data *pdata = host->pdata; 685426e95d1SSimon Horman 686426e95d1SSimon Horman pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n", 687426e95d1SSimon Horman data->blksz, data->blocks); 688426e95d1SSimon Horman 689426e95d1SSimon Horman /* Some hardware cannot perform 2 byte requests in 4/8 bit mode */ 690426e95d1SSimon Horman if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4 || 691426e95d1SSimon Horman host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) { 692426e95d1SSimon Horman int blksz_2bytes = pdata->flags & TMIO_MMC_BLKSZ_2BYTES; 693426e95d1SSimon Horman 694426e95d1SSimon Horman if (data->blksz < 2 || (data->blksz < 4 && !blksz_2bytes)) { 695426e95d1SSimon Horman pr_err("%s: %d byte block unsupported in 4/8 bit mode\n", 696426e95d1SSimon Horman mmc_hostname(host->mmc), data->blksz); 697426e95d1SSimon Horman return -EINVAL; 698426e95d1SSimon Horman } 699426e95d1SSimon Horman } 700426e95d1SSimon Horman 701426e95d1SSimon Horman tmio_mmc_init_sg(host, data); 702426e95d1SSimon Horman host->data = data; 703d3dd5db0SMasahiro Yamada host->dma_on = false; 704426e95d1SSimon Horman 705426e95d1SSimon Horman /* Set transfer length / blocksize */ 706426e95d1SSimon Horman sd_ctrl_write16(host, CTL_SD_XFER_LEN, data->blksz); 7075603731aSTakeshi Saito if (host->mmc->max_blk_count >= SZ_64K) 7085603731aSTakeshi Saito sd_ctrl_write32(host, CTL_XFER_BLK_COUNT, data->blocks); 7095603731aSTakeshi Saito else 710426e95d1SSimon Horman sd_ctrl_write16(host, CTL_XFER_BLK_COUNT, data->blocks); 711426e95d1SSimon Horman 712426e95d1SSimon Horman tmio_mmc_start_dma(host, data); 713426e95d1SSimon Horman 714426e95d1SSimon Horman return 0; 715426e95d1SSimon Horman } 716426e95d1SSimon Horman 717426e95d1SSimon Horman static int tmio_mmc_execute_tuning(struct mmc_host *mmc, u32 opcode) 718426e95d1SSimon Horman { 719426e95d1SSimon Horman struct tmio_mmc_host *host = mmc_priv(mmc); 720426e95d1SSimon Horman int i, ret = 0; 721426e95d1SSimon Horman 722426e95d1SSimon Horman if (!host->init_tuning || !host->select_tuning) 723426e95d1SSimon Horman /* Tuning is not supported */ 724426e95d1SSimon Horman goto out; 725426e95d1SSimon Horman 726426e95d1SSimon Horman host->tap_num = host->init_tuning(host); 727426e95d1SSimon Horman if (!host->tap_num) 728426e95d1SSimon Horman /* Tuning is not supported */ 729426e95d1SSimon Horman goto out; 730426e95d1SSimon Horman 731426e95d1SSimon Horman if (host->tap_num * 2 >= sizeof(host->taps) * BITS_PER_BYTE) { 732426e95d1SSimon Horman dev_warn_once(&host->pdev->dev, 733426e95d1SSimon Horman "Too many taps, skipping tuning. Please consider updating size of taps field of tmio_mmc_host\n"); 734426e95d1SSimon Horman goto out; 735426e95d1SSimon Horman } 736426e95d1SSimon Horman 737426e95d1SSimon Horman bitmap_zero(host->taps, host->tap_num * 2); 738426e95d1SSimon Horman 739426e95d1SSimon Horman /* Issue CMD19 twice for each tap */ 740426e95d1SSimon Horman for (i = 0; i < 2 * host->tap_num; i++) { 741426e95d1SSimon Horman if (host->prepare_tuning) 742426e95d1SSimon Horman host->prepare_tuning(host, i % host->tap_num); 743426e95d1SSimon Horman 744426e95d1SSimon Horman ret = mmc_send_tuning(mmc, opcode, NULL); 745426e95d1SSimon Horman if (ret == 0) 746426e95d1SSimon Horman set_bit(i, host->taps); 747426e95d1SSimon Horman } 748426e95d1SSimon Horman 749426e95d1SSimon Horman ret = host->select_tuning(host); 750426e95d1SSimon Horman 751426e95d1SSimon Horman out: 752426e95d1SSimon Horman if (ret < 0) { 753426e95d1SSimon Horman dev_warn(&host->pdev->dev, "Tuning procedure failed\n"); 754426e95d1SSimon Horman tmio_mmc_hw_reset(mmc); 755426e95d1SSimon Horman } 756426e95d1SSimon Horman 757426e95d1SSimon Horman return ret; 758426e95d1SSimon Horman } 759426e95d1SSimon Horman 760f2218db8SSimon Horman static void tmio_process_mrq(struct tmio_mmc_host *host, 761f2218db8SSimon Horman struct mmc_request *mrq) 762426e95d1SSimon Horman { 7638b22c3c1SWolfram Sang struct mmc_command *cmd; 764426e95d1SSimon Horman int ret; 765426e95d1SSimon Horman 7668b22c3c1SWolfram Sang if (mrq->sbc && host->cmd != mrq->sbc) { 7678b22c3c1SWolfram Sang cmd = mrq->sbc; 7688b22c3c1SWolfram Sang } else { 7698b22c3c1SWolfram Sang cmd = mrq->cmd; 770426e95d1SSimon Horman if (mrq->data) { 771426e95d1SSimon Horman ret = tmio_mmc_start_data(host, mrq->data); 772426e95d1SSimon Horman if (ret) 773426e95d1SSimon Horman goto fail; 774426e95d1SSimon Horman } 7758b22c3c1SWolfram Sang } 776426e95d1SSimon Horman 7778b22c3c1SWolfram Sang ret = tmio_mmc_start_command(host, cmd); 77810c998efSWolfram Sang if (ret) 77910c998efSWolfram Sang goto fail; 78010c998efSWolfram Sang 781426e95d1SSimon Horman schedule_delayed_work(&host->delayed_reset_work, 782426e95d1SSimon Horman msecs_to_jiffies(CMDREQ_TIMEOUT)); 783426e95d1SSimon Horman return; 784426e95d1SSimon Horman 785426e95d1SSimon Horman fail: 786426e95d1SSimon Horman host->mrq = NULL; 787426e95d1SSimon Horman mrq->cmd->error = ret; 788de2a6bb9SWolfram Sang mmc_request_done(host->mmc, mrq); 789de2a6bb9SWolfram Sang } 790de2a6bb9SWolfram Sang 791de2a6bb9SWolfram Sang /* Process requests from the MMC layer */ 792de2a6bb9SWolfram Sang static void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) 793de2a6bb9SWolfram Sang { 794de2a6bb9SWolfram Sang struct tmio_mmc_host *host = mmc_priv(mmc); 795de2a6bb9SWolfram Sang unsigned long flags; 796de2a6bb9SWolfram Sang 797de2a6bb9SWolfram Sang spin_lock_irqsave(&host->lock, flags); 798de2a6bb9SWolfram Sang 799de2a6bb9SWolfram Sang if (host->mrq) { 800de2a6bb9SWolfram Sang pr_debug("request not null\n"); 801de2a6bb9SWolfram Sang if (IS_ERR(host->mrq)) { 802de2a6bb9SWolfram Sang spin_unlock_irqrestore(&host->lock, flags); 803de2a6bb9SWolfram Sang mrq->cmd->error = -EAGAIN; 804426e95d1SSimon Horman mmc_request_done(mmc, mrq); 805de2a6bb9SWolfram Sang return; 806de2a6bb9SWolfram Sang } 807de2a6bb9SWolfram Sang } 808de2a6bb9SWolfram Sang 809de2a6bb9SWolfram Sang host->last_req_ts = jiffies; 810de2a6bb9SWolfram Sang wmb(); 811de2a6bb9SWolfram Sang host->mrq = mrq; 812de2a6bb9SWolfram Sang 813de2a6bb9SWolfram Sang spin_unlock_irqrestore(&host->lock, flags); 814de2a6bb9SWolfram Sang 815de2a6bb9SWolfram Sang tmio_process_mrq(host, mrq); 816426e95d1SSimon Horman } 817426e95d1SSimon Horman 818f5fdcd1dSWolfram Sang static void tmio_mmc_finish_request(struct tmio_mmc_host *host) 819f5fdcd1dSWolfram Sang { 820f5fdcd1dSWolfram Sang struct mmc_request *mrq; 821f5fdcd1dSWolfram Sang unsigned long flags; 822f5fdcd1dSWolfram Sang 823f5fdcd1dSWolfram Sang spin_lock_irqsave(&host->lock, flags); 824f5fdcd1dSWolfram Sang 825f5fdcd1dSWolfram Sang mrq = host->mrq; 826f5fdcd1dSWolfram Sang if (IS_ERR_OR_NULL(mrq)) { 827f5fdcd1dSWolfram Sang spin_unlock_irqrestore(&host->lock, flags); 828f5fdcd1dSWolfram Sang return; 829f5fdcd1dSWolfram Sang } 830f5fdcd1dSWolfram Sang 8318b22c3c1SWolfram Sang /* If not SET_BLOCK_COUNT, clear old data */ 8328b22c3c1SWolfram Sang if (host->cmd != mrq->sbc) { 833f5fdcd1dSWolfram Sang host->cmd = NULL; 834f5fdcd1dSWolfram Sang host->data = NULL; 8358b22c3c1SWolfram Sang host->mrq = NULL; 8368b22c3c1SWolfram Sang } 837f5fdcd1dSWolfram Sang 838f5fdcd1dSWolfram Sang cancel_delayed_work(&host->delayed_reset_work); 839f5fdcd1dSWolfram Sang 840f5fdcd1dSWolfram Sang spin_unlock_irqrestore(&host->lock, flags); 841f5fdcd1dSWolfram Sang 842f5fdcd1dSWolfram Sang if (mrq->cmd->error || (mrq->data && mrq->data->error)) 843f5fdcd1dSWolfram Sang tmio_mmc_abort_dma(host); 844f5fdcd1dSWolfram Sang 84551b72656STakeshi Saito /* SCC error means retune, but executed command was still successful */ 846b85fb0a1SMasaharu Hayakawa if (host->check_scc_error && host->check_scc_error(host)) 84751b72656STakeshi Saito mmc_retune_needed(host->mmc); 848f5fdcd1dSWolfram Sang 8498b22c3c1SWolfram Sang /* If SET_BLOCK_COUNT, continue with main command */ 850fc167dafSMasaharu Hayakawa if (host->mrq && !mrq->cmd->error) { 8518b22c3c1SWolfram Sang tmio_process_mrq(host, mrq); 8528b22c3c1SWolfram Sang return; 8538b22c3c1SWolfram Sang } 8548b22c3c1SWolfram Sang 855f5fdcd1dSWolfram Sang mmc_request_done(host->mmc, mrq); 856f5fdcd1dSWolfram Sang } 857f5fdcd1dSWolfram Sang 858f5fdcd1dSWolfram Sang static void tmio_mmc_done_work(struct work_struct *work) 859f5fdcd1dSWolfram Sang { 860f5fdcd1dSWolfram Sang struct tmio_mmc_host *host = container_of(work, struct tmio_mmc_host, 861f5fdcd1dSWolfram Sang done); 862f5fdcd1dSWolfram Sang tmio_mmc_finish_request(host); 863f5fdcd1dSWolfram Sang } 864f5fdcd1dSWolfram Sang 865426e95d1SSimon Horman static void tmio_mmc_power_on(struct tmio_mmc_host *host, unsigned short vdd) 866426e95d1SSimon Horman { 867426e95d1SSimon Horman struct mmc_host *mmc = host->mmc; 868426e95d1SSimon Horman int ret = 0; 869426e95d1SSimon Horman 870426e95d1SSimon Horman /* .set_ios() is returning void, so, no chance to report an error */ 871426e95d1SSimon Horman 872426e95d1SSimon Horman if (host->set_pwr) 873426e95d1SSimon Horman host->set_pwr(host->pdev, 1); 874426e95d1SSimon Horman 875426e95d1SSimon Horman if (!IS_ERR(mmc->supply.vmmc)) { 876426e95d1SSimon Horman ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd); 877426e95d1SSimon Horman /* 878426e95d1SSimon Horman * Attention: empiric value. With a b43 WiFi SDIO card this 879426e95d1SSimon Horman * delay proved necessary for reliable card-insertion probing. 880426e95d1SSimon Horman * 100us were not enough. Is this the same 140us delay, as in 881426e95d1SSimon Horman * tmio_mmc_set_ios()? 882426e95d1SSimon Horman */ 883754febccSWolfram Sang usleep_range(200, 300); 884426e95d1SSimon Horman } 885426e95d1SSimon Horman /* 886426e95d1SSimon Horman * It seems, VccQ should be switched on after Vcc, this is also what the 887426e95d1SSimon Horman * omap_hsmmc.c driver does. 888426e95d1SSimon Horman */ 889426e95d1SSimon Horman if (!IS_ERR(mmc->supply.vqmmc) && !ret) { 890426e95d1SSimon Horman ret = regulator_enable(mmc->supply.vqmmc); 891754febccSWolfram Sang usleep_range(200, 300); 892426e95d1SSimon Horman } 893426e95d1SSimon Horman 894426e95d1SSimon Horman if (ret < 0) 895426e95d1SSimon Horman dev_dbg(&host->pdev->dev, "Regulators failed to power up: %d\n", 896426e95d1SSimon Horman ret); 897426e95d1SSimon Horman } 898426e95d1SSimon Horman 899426e95d1SSimon Horman static void tmio_mmc_power_off(struct tmio_mmc_host *host) 900426e95d1SSimon Horman { 901426e95d1SSimon Horman struct mmc_host *mmc = host->mmc; 902426e95d1SSimon Horman 903426e95d1SSimon Horman if (!IS_ERR(mmc->supply.vqmmc)) 904426e95d1SSimon Horman regulator_disable(mmc->supply.vqmmc); 905426e95d1SSimon Horman 906426e95d1SSimon Horman if (!IS_ERR(mmc->supply.vmmc)) 907426e95d1SSimon Horman mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); 908426e95d1SSimon Horman 909426e95d1SSimon Horman if (host->set_pwr) 910426e95d1SSimon Horman host->set_pwr(host->pdev, 0); 911426e95d1SSimon Horman } 912426e95d1SSimon Horman 913426e95d1SSimon Horman static void tmio_mmc_set_bus_width(struct tmio_mmc_host *host, 914426e95d1SSimon Horman unsigned char bus_width) 915426e95d1SSimon Horman { 916426e95d1SSimon Horman u16 reg = sd_ctrl_read16(host, CTL_SD_MEM_CARD_OPT) 917426e95d1SSimon Horman & ~(CARD_OPT_WIDTH | CARD_OPT_WIDTH8); 918426e95d1SSimon Horman 919426e95d1SSimon Horman /* reg now applies to MMC_BUS_WIDTH_4 */ 920426e95d1SSimon Horman if (bus_width == MMC_BUS_WIDTH_1) 921426e95d1SSimon Horman reg |= CARD_OPT_WIDTH; 922426e95d1SSimon Horman else if (bus_width == MMC_BUS_WIDTH_8) 923426e95d1SSimon Horman reg |= CARD_OPT_WIDTH8; 924426e95d1SSimon Horman 925426e95d1SSimon Horman sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, reg); 926426e95d1SSimon Horman } 927426e95d1SSimon Horman 928426e95d1SSimon Horman /* Set MMC clock / power. 929426e95d1SSimon Horman * Note: This controller uses a simple divider scheme therefore it cannot 930426e95d1SSimon Horman * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as 931426e95d1SSimon Horman * MMC wont run that fast, it has to be clocked at 12MHz which is the next 932426e95d1SSimon Horman * slowest setting. 933426e95d1SSimon Horman */ 934426e95d1SSimon Horman static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 935426e95d1SSimon Horman { 936426e95d1SSimon Horman struct tmio_mmc_host *host = mmc_priv(mmc); 937426e95d1SSimon Horman struct device *dev = &host->pdev->dev; 938426e95d1SSimon Horman unsigned long flags; 939426e95d1SSimon Horman 940426e95d1SSimon Horman mutex_lock(&host->ios_lock); 941426e95d1SSimon Horman 942426e95d1SSimon Horman spin_lock_irqsave(&host->lock, flags); 943426e95d1SSimon Horman if (host->mrq) { 944426e95d1SSimon Horman if (IS_ERR(host->mrq)) { 945426e95d1SSimon Horman dev_dbg(dev, 946426e95d1SSimon Horman "%s.%d: concurrent .set_ios(), clk %u, mode %u\n", 947426e95d1SSimon Horman current->comm, task_pid_nr(current), 948426e95d1SSimon Horman ios->clock, ios->power_mode); 949426e95d1SSimon Horman host->mrq = ERR_PTR(-EINTR); 950426e95d1SSimon Horman } else { 951426e95d1SSimon Horman dev_dbg(dev, 952426e95d1SSimon Horman "%s.%d: CMD%u active since %lu, now %lu!\n", 953426e95d1SSimon Horman current->comm, task_pid_nr(current), 954f2218db8SSimon Horman host->mrq->cmd->opcode, host->last_req_ts, 955f2218db8SSimon Horman jiffies); 956426e95d1SSimon Horman } 957426e95d1SSimon Horman spin_unlock_irqrestore(&host->lock, flags); 958426e95d1SSimon Horman 959426e95d1SSimon Horman mutex_unlock(&host->ios_lock); 960426e95d1SSimon Horman return; 961426e95d1SSimon Horman } 962426e95d1SSimon Horman 963426e95d1SSimon Horman host->mrq = ERR_PTR(-EBUSY); 964426e95d1SSimon Horman 965426e95d1SSimon Horman spin_unlock_irqrestore(&host->lock, flags); 966426e95d1SSimon Horman 967426e95d1SSimon Horman switch (ios->power_mode) { 968426e95d1SSimon Horman case MMC_POWER_OFF: 969426e95d1SSimon Horman tmio_mmc_power_off(host); 9700196c8dbSMasahiro Yamada host->set_clock(host, 0); 971426e95d1SSimon Horman break; 972426e95d1SSimon Horman case MMC_POWER_UP: 973426e95d1SSimon Horman tmio_mmc_power_on(host, ios->vdd); 9740196c8dbSMasahiro Yamada host->set_clock(host, ios->clock); 975426e95d1SSimon Horman tmio_mmc_set_bus_width(host, ios->bus_width); 976426e95d1SSimon Horman break; 977426e95d1SSimon Horman case MMC_POWER_ON: 9780196c8dbSMasahiro Yamada host->set_clock(host, ios->clock); 979426e95d1SSimon Horman tmio_mmc_set_bus_width(host, ios->bus_width); 980426e95d1SSimon Horman break; 981426e95d1SSimon Horman } 982426e95d1SSimon Horman 983426e95d1SSimon Horman /* Let things settle. delay taken from winCE driver */ 984754febccSWolfram Sang usleep_range(140, 200); 985426e95d1SSimon Horman if (PTR_ERR(host->mrq) == -EINTR) 986426e95d1SSimon Horman dev_dbg(&host->pdev->dev, 987426e95d1SSimon Horman "%s.%d: IOS interrupted: clk %u, mode %u", 988426e95d1SSimon Horman current->comm, task_pid_nr(current), 989426e95d1SSimon Horman ios->clock, ios->power_mode); 990426e95d1SSimon Horman host->mrq = NULL; 991426e95d1SSimon Horman 992426e95d1SSimon Horman host->clk_cache = ios->clock; 993426e95d1SSimon Horman 994426e95d1SSimon Horman mutex_unlock(&host->ios_lock); 995426e95d1SSimon Horman } 996426e95d1SSimon Horman 997426e95d1SSimon Horman static int tmio_mmc_get_ro(struct mmc_host *mmc) 998426e95d1SSimon Horman { 999426e95d1SSimon Horman struct tmio_mmc_host *host = mmc_priv(mmc); 1000f2218db8SSimon Horman 1001218f6024SMasahiro Yamada return !(sd_ctrl_read16_and_16_as_32(host, CTL_STATUS) & 1002218f6024SMasahiro Yamada TMIO_STAT_WRPROTECT); 1003426e95d1SSimon Horman } 1004426e95d1SSimon Horman 1005497d1f96SMasahiro Yamada static int tmio_mmc_get_cd(struct mmc_host *mmc) 1006497d1f96SMasahiro Yamada { 1007497d1f96SMasahiro Yamada struct tmio_mmc_host *host = mmc_priv(mmc); 1008497d1f96SMasahiro Yamada 1009497d1f96SMasahiro Yamada return !!(sd_ctrl_read16_and_16_as_32(host, CTL_STATUS) & 1010497d1f96SMasahiro Yamada TMIO_STAT_SIGSTATE); 1011497d1f96SMasahiro Yamada } 1012497d1f96SMasahiro Yamada 1013426e95d1SSimon Horman static int tmio_multi_io_quirk(struct mmc_card *card, 1014426e95d1SSimon Horman unsigned int direction, int blk_size) 1015426e95d1SSimon Horman { 1016426e95d1SSimon Horman struct tmio_mmc_host *host = mmc_priv(card->host); 1017426e95d1SSimon Horman 1018426e95d1SSimon Horman if (host->multi_io_quirk) 1019426e95d1SSimon Horman return host->multi_io_quirk(card, direction, blk_size); 1020426e95d1SSimon Horman 1021426e95d1SSimon Horman return blk_size; 1022426e95d1SSimon Horman } 1023426e95d1SSimon Horman 1024db924bbaSMasaharu Hayakawa static int tmio_mmc_prepare_hs400_tuning(struct mmc_host *mmc, 1025db924bbaSMasaharu Hayakawa struct mmc_ios *ios) 1026db924bbaSMasaharu Hayakawa { 1027db924bbaSMasaharu Hayakawa struct tmio_mmc_host *host = mmc_priv(mmc); 1028db924bbaSMasaharu Hayakawa 1029db924bbaSMasaharu Hayakawa if (host->prepare_hs400_tuning) 1030db924bbaSMasaharu Hayakawa host->prepare_hs400_tuning(host); 1031db924bbaSMasaharu Hayakawa 1032db924bbaSMasaharu Hayakawa return 0; 1033db924bbaSMasaharu Hayakawa } 1034db924bbaSMasaharu Hayakawa 1035db924bbaSMasaharu Hayakawa static void tmio_mmc_hs400_downgrade(struct mmc_host *mmc) 1036db924bbaSMasaharu Hayakawa { 1037db924bbaSMasaharu Hayakawa struct tmio_mmc_host *host = mmc_priv(mmc); 1038db924bbaSMasaharu Hayakawa 1039db924bbaSMasaharu Hayakawa if (host->hs400_downgrade) 1040db924bbaSMasaharu Hayakawa host->hs400_downgrade(host); 1041db924bbaSMasaharu Hayakawa } 1042db924bbaSMasaharu Hayakawa 1043db924bbaSMasaharu Hayakawa static void tmio_mmc_hs400_complete(struct mmc_host *mmc) 1044db924bbaSMasaharu Hayakawa { 1045db924bbaSMasaharu Hayakawa struct tmio_mmc_host *host = mmc_priv(mmc); 1046db924bbaSMasaharu Hayakawa 1047db924bbaSMasaharu Hayakawa if (host->hs400_complete) 1048db924bbaSMasaharu Hayakawa host->hs400_complete(host); 1049db924bbaSMasaharu Hayakawa } 1050db924bbaSMasaharu Hayakawa 1051c055fc75SMasahiro Yamada static const struct mmc_host_ops tmio_mmc_ops = { 1052426e95d1SSimon Horman .request = tmio_mmc_request, 1053426e95d1SSimon Horman .set_ios = tmio_mmc_set_ios, 1054426e95d1SSimon Horman .get_ro = tmio_mmc_get_ro, 1055497d1f96SMasahiro Yamada .get_cd = tmio_mmc_get_cd, 1056426e95d1SSimon Horman .enable_sdio_irq = tmio_mmc_enable_sdio_irq, 1057426e95d1SSimon Horman .multi_io_quirk = tmio_multi_io_quirk, 1058426e95d1SSimon Horman .hw_reset = tmio_mmc_hw_reset, 1059426e95d1SSimon Horman .execute_tuning = tmio_mmc_execute_tuning, 1060db924bbaSMasaharu Hayakawa .prepare_hs400_tuning = tmio_mmc_prepare_hs400_tuning, 1061db924bbaSMasaharu Hayakawa .hs400_downgrade = tmio_mmc_hs400_downgrade, 1062db924bbaSMasaharu Hayakawa .hs400_complete = tmio_mmc_hs400_complete, 1063426e95d1SSimon Horman }; 1064426e95d1SSimon Horman 1065426e95d1SSimon Horman static int tmio_mmc_init_ocr(struct tmio_mmc_host *host) 1066426e95d1SSimon Horman { 1067426e95d1SSimon Horman struct tmio_mmc_data *pdata = host->pdata; 1068426e95d1SSimon Horman struct mmc_host *mmc = host->mmc; 1069a3d95d1dSFabrizio Castro int err; 1070426e95d1SSimon Horman 1071a3d95d1dSFabrizio Castro err = mmc_regulator_get_supply(mmc); 1072a3d95d1dSFabrizio Castro if (err) 1073a3d95d1dSFabrizio Castro return err; 1074426e95d1SSimon Horman 1075426e95d1SSimon Horman /* use ocr_mask if no regulator */ 1076426e95d1SSimon Horman if (!mmc->ocr_avail) 1077426e95d1SSimon Horman mmc->ocr_avail = pdata->ocr_mask; 1078426e95d1SSimon Horman 1079426e95d1SSimon Horman /* 1080426e95d1SSimon Horman * try again. 1081426e95d1SSimon Horman * There is possibility that regulator has not been probed 1082426e95d1SSimon Horman */ 1083426e95d1SSimon Horman if (!mmc->ocr_avail) 1084426e95d1SSimon Horman return -EPROBE_DEFER; 1085426e95d1SSimon Horman 1086426e95d1SSimon Horman return 0; 1087426e95d1SSimon Horman } 1088426e95d1SSimon Horman 1089426e95d1SSimon Horman static void tmio_mmc_of_parse(struct platform_device *pdev, 10907c53b797SMasahiro Yamada struct mmc_host *mmc) 1091426e95d1SSimon Horman { 1092426e95d1SSimon Horman const struct device_node *np = pdev->dev.of_node; 1093f2218db8SSimon Horman 1094426e95d1SSimon Horman if (!np) 1095426e95d1SSimon Horman return; 1096426e95d1SSimon Horman 1097788778b0SMasahiro Yamada /* 1098788778b0SMasahiro Yamada * DEPRECATED: 1099788778b0SMasahiro Yamada * For new platforms, please use "disable-wp" instead of 1100788778b0SMasahiro Yamada * "toshiba,mmc-wrprotect-disable" 1101788778b0SMasahiro Yamada */ 1102426e95d1SSimon Horman if (of_get_property(np, "toshiba,mmc-wrprotect-disable", NULL)) 11037c53b797SMasahiro Yamada mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT; 1104426e95d1SSimon Horman } 1105426e95d1SSimon Horman 1106b21fc294SMasahiro Yamada struct tmio_mmc_host *tmio_mmc_host_alloc(struct platform_device *pdev, 1107b21fc294SMasahiro Yamada struct tmio_mmc_data *pdata) 1108426e95d1SSimon Horman { 1109426e95d1SSimon Horman struct tmio_mmc_host *host; 1110426e95d1SSimon Horman struct mmc_host *mmc; 11118d09a133SMasahiro Yamada struct resource *res; 11128d09a133SMasahiro Yamada void __iomem *ctl; 11136fb294f7SMasahiro Yamada int ret; 11148d09a133SMasahiro Yamada 11158d09a133SMasahiro Yamada res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 11168d09a133SMasahiro Yamada ctl = devm_ioremap_resource(&pdev->dev, res); 11178d09a133SMasahiro Yamada if (IS_ERR(ctl)) 11188d09a133SMasahiro Yamada return ERR_CAST(ctl); 1119426e95d1SSimon Horman 1120426e95d1SSimon Horman mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &pdev->dev); 1121426e95d1SSimon Horman if (!mmc) 11228d09a133SMasahiro Yamada return ERR_PTR(-ENOMEM); 1123426e95d1SSimon Horman 1124426e95d1SSimon Horman host = mmc_priv(mmc); 11258d09a133SMasahiro Yamada host->ctl = ctl; 1126426e95d1SSimon Horman host->mmc = mmc; 1127426e95d1SSimon Horman host->pdev = pdev; 1128b21fc294SMasahiro Yamada host->pdata = pdata; 1129c055fc75SMasahiro Yamada host->ops = tmio_mmc_ops; 1130c055fc75SMasahiro Yamada mmc->ops = &host->ops; 1131426e95d1SSimon Horman 11326fb294f7SMasahiro Yamada ret = mmc_of_parse(host->mmc); 11336fb294f7SMasahiro Yamada if (ret) { 11346fb294f7SMasahiro Yamada host = ERR_PTR(ret); 11356fb294f7SMasahiro Yamada goto free; 11366fb294f7SMasahiro Yamada } 11376fb294f7SMasahiro Yamada 11387c53b797SMasahiro Yamada tmio_mmc_of_parse(pdev, mmc); 11396fb294f7SMasahiro Yamada 1140b21fc294SMasahiro Yamada platform_set_drvdata(pdev, host); 1141b21fc294SMasahiro Yamada 1142426e95d1SSimon Horman return host; 11436fb294f7SMasahiro Yamada free: 11446fb294f7SMasahiro Yamada mmc_free_host(mmc); 11456fb294f7SMasahiro Yamada 11466fb294f7SMasahiro Yamada return host; 1147426e95d1SSimon Horman } 11486106ecf3SSimon Horman EXPORT_SYMBOL_GPL(tmio_mmc_host_alloc); 1149426e95d1SSimon Horman 1150426e95d1SSimon Horman void tmio_mmc_host_free(struct tmio_mmc_host *host) 1151426e95d1SSimon Horman { 1152426e95d1SSimon Horman mmc_free_host(host->mmc); 1153426e95d1SSimon Horman } 11546106ecf3SSimon Horman EXPORT_SYMBOL_GPL(tmio_mmc_host_free); 1155426e95d1SSimon Horman 1156bc45719cSMasahiro Yamada int tmio_mmc_host_probe(struct tmio_mmc_host *_host) 1157426e95d1SSimon Horman { 1158426e95d1SSimon Horman struct platform_device *pdev = _host->pdev; 1159b21fc294SMasahiro Yamada struct tmio_mmc_data *pdata = _host->pdata; 1160426e95d1SSimon Horman struct mmc_host *mmc = _host->mmc; 1161426e95d1SSimon Horman int ret; 1162426e95d1SSimon Horman 1163b21fc294SMasahiro Yamada /* 11640196c8dbSMasahiro Yamada * Check the sanity of mmc->f_min to prevent host->set_clock() from 1165b21fc294SMasahiro Yamada * looping forever... 1166b21fc294SMasahiro Yamada */ 1167b21fc294SMasahiro Yamada if (mmc->f_min == 0) 1168b21fc294SMasahiro Yamada return -EINVAL; 1169b21fc294SMasahiro Yamada 1170426e95d1SSimon Horman if (!(pdata->flags & TMIO_MMC_HAS_IDLE_WAIT)) 1171426e95d1SSimon Horman _host->write16_hook = NULL; 1172426e95d1SSimon Horman 1173426e95d1SSimon Horman _host->set_pwr = pdata->set_pwr; 1174426e95d1SSimon Horman 1175426e95d1SSimon Horman ret = tmio_mmc_init_ocr(_host); 1176426e95d1SSimon Horman if (ret < 0) 1177426e95d1SSimon Horman return ret; 1178426e95d1SSimon Horman 1179faed9303SLinus Walleij /* 1180faed9303SLinus Walleij * Look for a card detect GPIO, if it fails with anything 1181faed9303SLinus Walleij * else than a probe deferral, just live without it. 1182faed9303SLinus Walleij */ 1183faed9303SLinus Walleij ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL); 1184faed9303SLinus Walleij if (ret == -EPROBE_DEFER) 1185cd82cd21SMasahiro Yamada return ret; 1186cd82cd21SMasahiro Yamada 1187426e95d1SSimon Horman mmc->caps |= MMC_CAP_4_BIT_DATA | pdata->capabilities; 1188426e95d1SSimon Horman mmc->caps2 |= pdata->capabilities2; 1189603aa14dSYoshihiro Shimoda mmc->max_segs = pdata->max_segs ? : 32; 1190609e5fbaSWolfram Sang mmc->max_blk_size = TMIO_MAX_BLK_SIZE; 1191603aa14dSYoshihiro Shimoda mmc->max_blk_count = pdata->max_blk_count ? : 1192603aa14dSYoshihiro Shimoda (PAGE_SIZE / mmc->max_blk_size) * mmc->max_segs; 119363624d13SYoshihiro Shimoda mmc->max_req_size = min_t(size_t, 119463624d13SYoshihiro Shimoda mmc->max_blk_size * mmc->max_blk_count, 119563624d13SYoshihiro Shimoda dma_max_mapping_size(&pdev->dev)); 1196426e95d1SSimon Horman mmc->max_seg_size = mmc->max_req_size; 1197426e95d1SSimon Horman 11981910b87fSMasahiro Yamada if (mmc_can_gpio_ro(mmc)) 11991910b87fSMasahiro Yamada _host->ops.get_ro = mmc_gpio_get_ro; 12001910b87fSMasahiro Yamada 1201497d1f96SMasahiro Yamada if (mmc_can_gpio_cd(mmc)) 1202497d1f96SMasahiro Yamada _host->ops.get_cd = mmc_gpio_get_cd; 1203497d1f96SMasahiro Yamada 1204de21dc1dSMasahiro Yamada _host->native_hotplug = !(mmc_can_gpio_cd(mmc) || 1205426e95d1SSimon Horman mmc->caps & MMC_CAP_NEEDS_POLL || 1206426e95d1SSimon Horman !mmc_card_is_removable(mmc)); 1207426e95d1SSimon Horman 1208acb9fce7SMasahiro Yamada if (!_host->reset) 1209acb9fce7SMasahiro Yamada _host->reset = tmio_mmc_reset; 1210acb9fce7SMasahiro Yamada 1211426e95d1SSimon Horman /* 1212426e95d1SSimon Horman * On Gen2+, eMMC with NONREMOVABLE currently fails because native 1213426e95d1SSimon Horman * hotplug gets disabled. It seems RuntimePM related yet we need further 1214426e95d1SSimon Horman * research. Since we are planning a PM overhaul anyway, let's enforce 1215426e95d1SSimon Horman * for now the device being active by enabling native hotplug always. 1216426e95d1SSimon Horman */ 1217426e95d1SSimon Horman if (pdata->flags & TMIO_MMC_MIN_RCAR2) 1218426e95d1SSimon Horman _host->native_hotplug = true; 1219426e95d1SSimon Horman 1220426e95d1SSimon Horman /* 1221426e95d1SSimon Horman * While using internal tmio hardware logic for card detection, we need 1222426e95d1SSimon Horman * to ensure it stays powered for it to work. 1223426e95d1SSimon Horman */ 1224426e95d1SSimon Horman if (_host->native_hotplug) 1225426e95d1SSimon Horman pm_runtime_get_noresume(&pdev->dev); 1226426e95d1SSimon Horman 122786beb538SWolfram Sang _host->sdio_irq_enabled = false; 122886beb538SWolfram Sang if (pdata->flags & TMIO_MMC_SDIO_IRQ) 122986beb538SWolfram Sang _host->sdio_irq_mask = TMIO_SDIO_MASK_ALL; 123086beb538SWolfram Sang 12310196c8dbSMasahiro Yamada _host->set_clock(_host, 0); 1232a87852c6SNiklas Söderlund tmio_mmc_hw_reset(mmc); 1233426e95d1SSimon Horman 1234426e95d1SSimon Horman _host->sdcard_irq_mask = sd_ctrl_read16_and_16_as_32(_host, CTL_IRQ_MASK); 1235426e95d1SSimon Horman tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL); 1236426e95d1SSimon Horman 1237c7cd630aSMasahiro Yamada if (_host->native_hotplug) 1238c7cd630aSMasahiro Yamada tmio_mmc_enable_mmc_irqs(_host, 1239c7cd630aSMasahiro Yamada TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT); 1240c7cd630aSMasahiro Yamada 1241426e95d1SSimon Horman spin_lock_init(&_host->lock); 1242426e95d1SSimon Horman mutex_init(&_host->ios_lock); 1243426e95d1SSimon Horman 1244426e95d1SSimon Horman /* Init delayed work for request timeouts */ 1245426e95d1SSimon Horman INIT_DELAYED_WORK(&_host->delayed_reset_work, tmio_mmc_reset_work); 1246426e95d1SSimon Horman INIT_WORK(&_host->done, tmio_mmc_done_work); 1247426e95d1SSimon Horman 1248426e95d1SSimon Horman /* See if we also get DMA */ 1249426e95d1SSimon Horman tmio_mmc_request_dma(_host, pdata); 1250426e95d1SSimon Horman 1251426e95d1SSimon Horman pm_runtime_set_autosuspend_delay(&pdev->dev, 50); 1252426e95d1SSimon Horman pm_runtime_use_autosuspend(&pdev->dev); 12538861474aSUlf Hansson pm_runtime_enable(&pdev->dev); 1254aa86f1a3SUlf Hansson pm_runtime_get_sync(&pdev->dev); 1255426e95d1SSimon Horman 1256426e95d1SSimon Horman ret = mmc_add_host(mmc); 12577f8e446bSMarkus Elfring if (ret) 12587f8e446bSMarkus Elfring goto remove_host; 1259426e95d1SSimon Horman 1260426e95d1SSimon Horman dev_pm_qos_expose_latency_limit(&pdev->dev, 100); 1261aa86f1a3SUlf Hansson pm_runtime_put(&pdev->dev); 1262426e95d1SSimon Horman 1263426e95d1SSimon Horman return 0; 12647f8e446bSMarkus Elfring 12657f8e446bSMarkus Elfring remove_host: 1266aa86f1a3SUlf Hansson pm_runtime_put_noidle(&pdev->dev); 12677f8e446bSMarkus Elfring tmio_mmc_host_remove(_host); 12687f8e446bSMarkus Elfring return ret; 1269426e95d1SSimon Horman } 12706106ecf3SSimon Horman EXPORT_SYMBOL_GPL(tmio_mmc_host_probe); 1271426e95d1SSimon Horman 1272426e95d1SSimon Horman void tmio_mmc_host_remove(struct tmio_mmc_host *host) 1273426e95d1SSimon Horman { 1274426e95d1SSimon Horman struct platform_device *pdev = host->pdev; 1275426e95d1SSimon Horman struct mmc_host *mmc = host->mmc; 1276426e95d1SSimon Horman 1277426e95d1SSimon Horman if (host->pdata->flags & TMIO_MMC_SDIO_IRQ) 1278426e95d1SSimon Horman sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000); 1279426e95d1SSimon Horman 1280426e95d1SSimon Horman if (!host->native_hotplug) 1281426e95d1SSimon Horman pm_runtime_get_sync(&pdev->dev); 1282426e95d1SSimon Horman 1283426e95d1SSimon Horman dev_pm_qos_hide_latency_limit(&pdev->dev); 1284426e95d1SSimon Horman 1285426e95d1SSimon Horman mmc_remove_host(mmc); 1286426e95d1SSimon Horman cancel_work_sync(&host->done); 1287426e95d1SSimon Horman cancel_delayed_work_sync(&host->delayed_reset_work); 1288426e95d1SSimon Horman tmio_mmc_release_dma(host); 1289426e95d1SSimon Horman 1290bb60023cSNiklas Söderlund pm_runtime_dont_use_autosuspend(&pdev->dev); 1291426e95d1SSimon Horman pm_runtime_put_sync(&pdev->dev); 12928861474aSUlf Hansson pm_runtime_disable(&pdev->dev); 1293426e95d1SSimon Horman } 12946106ecf3SSimon Horman EXPORT_SYMBOL_GPL(tmio_mmc_host_remove); 1295426e95d1SSimon Horman 1296426e95d1SSimon Horman #ifdef CONFIG_PM 12974a09d0b8SArnd Bergmann static int tmio_mmc_clk_enable(struct tmio_mmc_host *host) 12984a09d0b8SArnd Bergmann { 12994a09d0b8SArnd Bergmann if (!host->clk_enable) 13004a09d0b8SArnd Bergmann return -ENOTSUPP; 13014a09d0b8SArnd Bergmann 13024a09d0b8SArnd Bergmann return host->clk_enable(host); 13034a09d0b8SArnd Bergmann } 13044a09d0b8SArnd Bergmann 13054a09d0b8SArnd Bergmann static void tmio_mmc_clk_disable(struct tmio_mmc_host *host) 13064a09d0b8SArnd Bergmann { 13074a09d0b8SArnd Bergmann if (host->clk_disable) 13084a09d0b8SArnd Bergmann host->clk_disable(host); 13094a09d0b8SArnd Bergmann } 13104a09d0b8SArnd Bergmann 1311426e95d1SSimon Horman int tmio_mmc_host_runtime_suspend(struct device *dev) 1312426e95d1SSimon Horman { 1313a3b05373SMasahiro Yamada struct tmio_mmc_host *host = dev_get_drvdata(dev); 1314426e95d1SSimon Horman 1315426e95d1SSimon Horman tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL); 1316426e95d1SSimon Horman 1317426e95d1SSimon Horman if (host->clk_cache) 13180196c8dbSMasahiro Yamada host->set_clock(host, 0); 1319426e95d1SSimon Horman 1320426e95d1SSimon Horman tmio_mmc_clk_disable(host); 1321426e95d1SSimon Horman 1322426e95d1SSimon Horman return 0; 1323426e95d1SSimon Horman } 13246106ecf3SSimon Horman EXPORT_SYMBOL_GPL(tmio_mmc_host_runtime_suspend); 1325426e95d1SSimon Horman 1326426e95d1SSimon Horman static bool tmio_mmc_can_retune(struct tmio_mmc_host *host) 1327426e95d1SSimon Horman { 1328426e95d1SSimon Horman return host->tap_num && mmc_can_retune(host->mmc); 1329426e95d1SSimon Horman } 1330426e95d1SSimon Horman 1331426e95d1SSimon Horman int tmio_mmc_host_runtime_resume(struct device *dev) 1332426e95d1SSimon Horman { 1333a3b05373SMasahiro Yamada struct tmio_mmc_host *host = dev_get_drvdata(dev); 1334426e95d1SSimon Horman 1335aa86f1a3SUlf Hansson if (!host->runtime_synced) { 1336aa86f1a3SUlf Hansson host->runtime_synced = true; 1337aa86f1a3SUlf Hansson return 0; 1338aa86f1a3SUlf Hansson } 1339aa86f1a3SUlf Hansson 1340426e95d1SSimon Horman tmio_mmc_clk_enable(host); 1341a87852c6SNiklas Söderlund tmio_mmc_hw_reset(host->mmc); 1342426e95d1SSimon Horman 1343426e95d1SSimon Horman if (host->clk_cache) 13440196c8dbSMasahiro Yamada host->set_clock(host, host->clk_cache); 1345426e95d1SSimon Horman 1346c7cd630aSMasahiro Yamada if (host->native_hotplug) 1347c7cd630aSMasahiro Yamada tmio_mmc_enable_mmc_irqs(host, 1348c7cd630aSMasahiro Yamada TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT); 1349c7cd630aSMasahiro Yamada 1350426e95d1SSimon Horman tmio_mmc_enable_dma(host, true); 1351426e95d1SSimon Horman 1352426e95d1SSimon Horman if (tmio_mmc_can_retune(host) && host->select_tuning(host)) 1353426e95d1SSimon Horman dev_warn(&host->pdev->dev, "Tuning selection failed\n"); 1354426e95d1SSimon Horman 1355426e95d1SSimon Horman return 0; 1356426e95d1SSimon Horman } 13576106ecf3SSimon Horman EXPORT_SYMBOL_GPL(tmio_mmc_host_runtime_resume); 1358426e95d1SSimon Horman #endif 1359426e95d1SSimon Horman 1360426e95d1SSimon Horman MODULE_LICENSE("GPL v2"); 1361