1*f95f3850SWill Newton /* 2*f95f3850SWill Newton * Synopsys DesignWare Multimedia Card Interface driver 3*f95f3850SWill Newton * (Based on NXP driver for lpc 31xx) 4*f95f3850SWill Newton * 5*f95f3850SWill Newton * Copyright (C) 2009 NXP Semiconductors 6*f95f3850SWill Newton * Copyright (C) 2009, 2010 Imagination Technologies Ltd. 7*f95f3850SWill Newton * 8*f95f3850SWill Newton * This program is free software; you can redistribute it and/or modify 9*f95f3850SWill Newton * it under the terms of the GNU General Public License as published by 10*f95f3850SWill Newton * the Free Software Foundation; either version 2 of the License, or 11*f95f3850SWill Newton * (at your option) any later version. 12*f95f3850SWill Newton */ 13*f95f3850SWill Newton 14*f95f3850SWill Newton #include <linux/blkdev.h> 15*f95f3850SWill Newton #include <linux/clk.h> 16*f95f3850SWill Newton #include <linux/debugfs.h> 17*f95f3850SWill Newton #include <linux/device.h> 18*f95f3850SWill Newton #include <linux/dma-mapping.h> 19*f95f3850SWill Newton #include <linux/err.h> 20*f95f3850SWill Newton #include <linux/init.h> 21*f95f3850SWill Newton #include <linux/interrupt.h> 22*f95f3850SWill Newton #include <linux/ioport.h> 23*f95f3850SWill Newton #include <linux/module.h> 24*f95f3850SWill Newton #include <linux/platform_device.h> 25*f95f3850SWill Newton #include <linux/scatterlist.h> 26*f95f3850SWill Newton #include <linux/seq_file.h> 27*f95f3850SWill Newton #include <linux/slab.h> 28*f95f3850SWill Newton #include <linux/stat.h> 29*f95f3850SWill Newton #include <linux/delay.h> 30*f95f3850SWill Newton #include <linux/irq.h> 31*f95f3850SWill Newton #include <linux/mmc/host.h> 32*f95f3850SWill Newton #include <linux/mmc/mmc.h> 33*f95f3850SWill Newton #include <linux/mmc/dw_mmc.h> 34*f95f3850SWill Newton #include <linux/bitops.h> 35*f95f3850SWill Newton 36*f95f3850SWill Newton #include "dw_mmc.h" 37*f95f3850SWill Newton 38*f95f3850SWill Newton /* Common flag combinations */ 39*f95f3850SWill Newton #define DW_MCI_DATA_ERROR_FLAGS (SDMMC_INT_DTO | SDMMC_INT_DCRC | \ 40*f95f3850SWill Newton SDMMC_INT_HTO | SDMMC_INT_SBE | \ 41*f95f3850SWill Newton SDMMC_INT_EBE) 42*f95f3850SWill Newton #define DW_MCI_CMD_ERROR_FLAGS (SDMMC_INT_RTO | SDMMC_INT_RCRC | \ 43*f95f3850SWill Newton SDMMC_INT_RESP_ERR) 44*f95f3850SWill Newton #define DW_MCI_ERROR_FLAGS (DW_MCI_DATA_ERROR_FLAGS | \ 45*f95f3850SWill Newton DW_MCI_CMD_ERROR_FLAGS | SDMMC_INT_HLE) 46*f95f3850SWill Newton #define DW_MCI_SEND_STATUS 1 47*f95f3850SWill Newton #define DW_MCI_RECV_STATUS 2 48*f95f3850SWill Newton #define DW_MCI_DMA_THRESHOLD 16 49*f95f3850SWill Newton 50*f95f3850SWill Newton #ifdef CONFIG_MMC_DW_IDMAC 51*f95f3850SWill Newton struct idmac_desc { 52*f95f3850SWill Newton u32 des0; /* Control Descriptor */ 53*f95f3850SWill Newton #define IDMAC_DES0_DIC BIT(1) 54*f95f3850SWill Newton #define IDMAC_DES0_LD BIT(2) 55*f95f3850SWill Newton #define IDMAC_DES0_FD BIT(3) 56*f95f3850SWill Newton #define IDMAC_DES0_CH BIT(4) 57*f95f3850SWill Newton #define IDMAC_DES0_ER BIT(5) 58*f95f3850SWill Newton #define IDMAC_DES0_CES BIT(30) 59*f95f3850SWill Newton #define IDMAC_DES0_OWN BIT(31) 60*f95f3850SWill Newton 61*f95f3850SWill Newton u32 des1; /* Buffer sizes */ 62*f95f3850SWill Newton #define IDMAC_SET_BUFFER1_SIZE(d, s) \ 63*f95f3850SWill Newton ((d)->des1 = ((d)->des1 & 0x03ffc000) | ((s) & 0x3fff)) 64*f95f3850SWill Newton 65*f95f3850SWill Newton u32 des2; /* buffer 1 physical address */ 66*f95f3850SWill Newton 67*f95f3850SWill Newton u32 des3; /* buffer 2 physical address */ 68*f95f3850SWill Newton }; 69*f95f3850SWill Newton #endif /* CONFIG_MMC_DW_IDMAC */ 70*f95f3850SWill Newton 71*f95f3850SWill Newton /** 72*f95f3850SWill Newton * struct dw_mci_slot - MMC slot state 73*f95f3850SWill Newton * @mmc: The mmc_host representing this slot. 74*f95f3850SWill Newton * @host: The MMC controller this slot is using. 75*f95f3850SWill Newton * @ctype: Card type for this slot. 76*f95f3850SWill Newton * @mrq: mmc_request currently being processed or waiting to be 77*f95f3850SWill Newton * processed, or NULL when the slot is idle. 78*f95f3850SWill Newton * @queue_node: List node for placing this node in the @queue list of 79*f95f3850SWill Newton * &struct dw_mci. 80*f95f3850SWill Newton * @clock: Clock rate configured by set_ios(). Protected by host->lock. 81*f95f3850SWill Newton * @flags: Random state bits associated with the slot. 82*f95f3850SWill Newton * @id: Number of this slot. 83*f95f3850SWill Newton * @last_detect_state: Most recently observed card detect state. 84*f95f3850SWill Newton */ 85*f95f3850SWill Newton struct dw_mci_slot { 86*f95f3850SWill Newton struct mmc_host *mmc; 87*f95f3850SWill Newton struct dw_mci *host; 88*f95f3850SWill Newton 89*f95f3850SWill Newton u32 ctype; 90*f95f3850SWill Newton 91*f95f3850SWill Newton struct mmc_request *mrq; 92*f95f3850SWill Newton struct list_head queue_node; 93*f95f3850SWill Newton 94*f95f3850SWill Newton unsigned int clock; 95*f95f3850SWill Newton unsigned long flags; 96*f95f3850SWill Newton #define DW_MMC_CARD_PRESENT 0 97*f95f3850SWill Newton #define DW_MMC_CARD_NEED_INIT 1 98*f95f3850SWill Newton int id; 99*f95f3850SWill Newton int last_detect_state; 100*f95f3850SWill Newton }; 101*f95f3850SWill Newton 102*f95f3850SWill Newton #if defined(CONFIG_DEBUG_FS) 103*f95f3850SWill Newton static int dw_mci_req_show(struct seq_file *s, void *v) 104*f95f3850SWill Newton { 105*f95f3850SWill Newton struct dw_mci_slot *slot = s->private; 106*f95f3850SWill Newton struct mmc_request *mrq; 107*f95f3850SWill Newton struct mmc_command *cmd; 108*f95f3850SWill Newton struct mmc_command *stop; 109*f95f3850SWill Newton struct mmc_data *data; 110*f95f3850SWill Newton 111*f95f3850SWill Newton /* Make sure we get a consistent snapshot */ 112*f95f3850SWill Newton spin_lock_bh(&slot->host->lock); 113*f95f3850SWill Newton mrq = slot->mrq; 114*f95f3850SWill Newton 115*f95f3850SWill Newton if (mrq) { 116*f95f3850SWill Newton cmd = mrq->cmd; 117*f95f3850SWill Newton data = mrq->data; 118*f95f3850SWill Newton stop = mrq->stop; 119*f95f3850SWill Newton 120*f95f3850SWill Newton if (cmd) 121*f95f3850SWill Newton seq_printf(s, 122*f95f3850SWill Newton "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", 123*f95f3850SWill Newton cmd->opcode, cmd->arg, cmd->flags, 124*f95f3850SWill Newton cmd->resp[0], cmd->resp[1], cmd->resp[2], 125*f95f3850SWill Newton cmd->resp[2], cmd->error); 126*f95f3850SWill Newton if (data) 127*f95f3850SWill Newton seq_printf(s, "DATA %u / %u * %u flg %x err %d\n", 128*f95f3850SWill Newton data->bytes_xfered, data->blocks, 129*f95f3850SWill Newton data->blksz, data->flags, data->error); 130*f95f3850SWill Newton if (stop) 131*f95f3850SWill Newton seq_printf(s, 132*f95f3850SWill Newton "CMD%u(0x%x) flg %x rsp %x %x %x %x err %d\n", 133*f95f3850SWill Newton stop->opcode, stop->arg, stop->flags, 134*f95f3850SWill Newton stop->resp[0], stop->resp[1], stop->resp[2], 135*f95f3850SWill Newton stop->resp[2], stop->error); 136*f95f3850SWill Newton } 137*f95f3850SWill Newton 138*f95f3850SWill Newton spin_unlock_bh(&slot->host->lock); 139*f95f3850SWill Newton 140*f95f3850SWill Newton return 0; 141*f95f3850SWill Newton } 142*f95f3850SWill Newton 143*f95f3850SWill Newton static int dw_mci_req_open(struct inode *inode, struct file *file) 144*f95f3850SWill Newton { 145*f95f3850SWill Newton return single_open(file, dw_mci_req_show, inode->i_private); 146*f95f3850SWill Newton } 147*f95f3850SWill Newton 148*f95f3850SWill Newton static const struct file_operations dw_mci_req_fops = { 149*f95f3850SWill Newton .owner = THIS_MODULE, 150*f95f3850SWill Newton .open = dw_mci_req_open, 151*f95f3850SWill Newton .read = seq_read, 152*f95f3850SWill Newton .llseek = seq_lseek, 153*f95f3850SWill Newton .release = single_release, 154*f95f3850SWill Newton }; 155*f95f3850SWill Newton 156*f95f3850SWill Newton static int dw_mci_regs_show(struct seq_file *s, void *v) 157*f95f3850SWill Newton { 158*f95f3850SWill Newton seq_printf(s, "STATUS:\t0x%08x\n", SDMMC_STATUS); 159*f95f3850SWill Newton seq_printf(s, "RINTSTS:\t0x%08x\n", SDMMC_RINTSTS); 160*f95f3850SWill Newton seq_printf(s, "CMD:\t0x%08x\n", SDMMC_CMD); 161*f95f3850SWill Newton seq_printf(s, "CTRL:\t0x%08x\n", SDMMC_CTRL); 162*f95f3850SWill Newton seq_printf(s, "INTMASK:\t0x%08x\n", SDMMC_INTMASK); 163*f95f3850SWill Newton seq_printf(s, "CLKENA:\t0x%08x\n", SDMMC_CLKENA); 164*f95f3850SWill Newton 165*f95f3850SWill Newton return 0; 166*f95f3850SWill Newton } 167*f95f3850SWill Newton 168*f95f3850SWill Newton static int dw_mci_regs_open(struct inode *inode, struct file *file) 169*f95f3850SWill Newton { 170*f95f3850SWill Newton return single_open(file, dw_mci_regs_show, inode->i_private); 171*f95f3850SWill Newton } 172*f95f3850SWill Newton 173*f95f3850SWill Newton static const struct file_operations dw_mci_regs_fops = { 174*f95f3850SWill Newton .owner = THIS_MODULE, 175*f95f3850SWill Newton .open = dw_mci_regs_open, 176*f95f3850SWill Newton .read = seq_read, 177*f95f3850SWill Newton .llseek = seq_lseek, 178*f95f3850SWill Newton .release = single_release, 179*f95f3850SWill Newton }; 180*f95f3850SWill Newton 181*f95f3850SWill Newton static void dw_mci_init_debugfs(struct dw_mci_slot *slot) 182*f95f3850SWill Newton { 183*f95f3850SWill Newton struct mmc_host *mmc = slot->mmc; 184*f95f3850SWill Newton struct dw_mci *host = slot->host; 185*f95f3850SWill Newton struct dentry *root; 186*f95f3850SWill Newton struct dentry *node; 187*f95f3850SWill Newton 188*f95f3850SWill Newton root = mmc->debugfs_root; 189*f95f3850SWill Newton if (!root) 190*f95f3850SWill Newton return; 191*f95f3850SWill Newton 192*f95f3850SWill Newton node = debugfs_create_file("regs", S_IRUSR, root, host, 193*f95f3850SWill Newton &dw_mci_regs_fops); 194*f95f3850SWill Newton if (!node) 195*f95f3850SWill Newton goto err; 196*f95f3850SWill Newton 197*f95f3850SWill Newton node = debugfs_create_file("req", S_IRUSR, root, slot, 198*f95f3850SWill Newton &dw_mci_req_fops); 199*f95f3850SWill Newton if (!node) 200*f95f3850SWill Newton goto err; 201*f95f3850SWill Newton 202*f95f3850SWill Newton node = debugfs_create_u32("state", S_IRUSR, root, (u32 *)&host->state); 203*f95f3850SWill Newton if (!node) 204*f95f3850SWill Newton goto err; 205*f95f3850SWill Newton 206*f95f3850SWill Newton node = debugfs_create_x32("pending_events", S_IRUSR, root, 207*f95f3850SWill Newton (u32 *)&host->pending_events); 208*f95f3850SWill Newton if (!node) 209*f95f3850SWill Newton goto err; 210*f95f3850SWill Newton 211*f95f3850SWill Newton node = debugfs_create_x32("completed_events", S_IRUSR, root, 212*f95f3850SWill Newton (u32 *)&host->completed_events); 213*f95f3850SWill Newton if (!node) 214*f95f3850SWill Newton goto err; 215*f95f3850SWill Newton 216*f95f3850SWill Newton return; 217*f95f3850SWill Newton 218*f95f3850SWill Newton err: 219*f95f3850SWill Newton dev_err(&mmc->class_dev, "failed to initialize debugfs for slot\n"); 220*f95f3850SWill Newton } 221*f95f3850SWill Newton #endif /* defined(CONFIG_DEBUG_FS) */ 222*f95f3850SWill Newton 223*f95f3850SWill Newton static void dw_mci_set_timeout(struct dw_mci *host) 224*f95f3850SWill Newton { 225*f95f3850SWill Newton /* timeout (maximum) */ 226*f95f3850SWill Newton mci_writel(host, TMOUT, 0xffffffff); 227*f95f3850SWill Newton } 228*f95f3850SWill Newton 229*f95f3850SWill Newton static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd) 230*f95f3850SWill Newton { 231*f95f3850SWill Newton struct mmc_data *data; 232*f95f3850SWill Newton u32 cmdr; 233*f95f3850SWill Newton cmd->error = -EINPROGRESS; 234*f95f3850SWill Newton 235*f95f3850SWill Newton cmdr = cmd->opcode; 236*f95f3850SWill Newton 237*f95f3850SWill Newton if (cmdr == MMC_STOP_TRANSMISSION) 238*f95f3850SWill Newton cmdr |= SDMMC_CMD_STOP; 239*f95f3850SWill Newton else 240*f95f3850SWill Newton cmdr |= SDMMC_CMD_PRV_DAT_WAIT; 241*f95f3850SWill Newton 242*f95f3850SWill Newton if (cmd->flags & MMC_RSP_PRESENT) { 243*f95f3850SWill Newton /* We expect a response, so set this bit */ 244*f95f3850SWill Newton cmdr |= SDMMC_CMD_RESP_EXP; 245*f95f3850SWill Newton if (cmd->flags & MMC_RSP_136) 246*f95f3850SWill Newton cmdr |= SDMMC_CMD_RESP_LONG; 247*f95f3850SWill Newton } 248*f95f3850SWill Newton 249*f95f3850SWill Newton if (cmd->flags & MMC_RSP_CRC) 250*f95f3850SWill Newton cmdr |= SDMMC_CMD_RESP_CRC; 251*f95f3850SWill Newton 252*f95f3850SWill Newton data = cmd->data; 253*f95f3850SWill Newton if (data) { 254*f95f3850SWill Newton cmdr |= SDMMC_CMD_DAT_EXP; 255*f95f3850SWill Newton if (data->flags & MMC_DATA_STREAM) 256*f95f3850SWill Newton cmdr |= SDMMC_CMD_STRM_MODE; 257*f95f3850SWill Newton if (data->flags & MMC_DATA_WRITE) 258*f95f3850SWill Newton cmdr |= SDMMC_CMD_DAT_WR; 259*f95f3850SWill Newton } 260*f95f3850SWill Newton 261*f95f3850SWill Newton return cmdr; 262*f95f3850SWill Newton } 263*f95f3850SWill Newton 264*f95f3850SWill Newton static void dw_mci_start_command(struct dw_mci *host, 265*f95f3850SWill Newton struct mmc_command *cmd, u32 cmd_flags) 266*f95f3850SWill Newton { 267*f95f3850SWill Newton host->cmd = cmd; 268*f95f3850SWill Newton dev_vdbg(&host->pdev->dev, 269*f95f3850SWill Newton "start command: ARGR=0x%08x CMDR=0x%08x\n", 270*f95f3850SWill Newton cmd->arg, cmd_flags); 271*f95f3850SWill Newton 272*f95f3850SWill Newton mci_writel(host, CMDARG, cmd->arg); 273*f95f3850SWill Newton wmb(); 274*f95f3850SWill Newton 275*f95f3850SWill Newton mci_writel(host, CMD, cmd_flags | SDMMC_CMD_START); 276*f95f3850SWill Newton } 277*f95f3850SWill Newton 278*f95f3850SWill Newton static void send_stop_cmd(struct dw_mci *host, struct mmc_data *data) 279*f95f3850SWill Newton { 280*f95f3850SWill Newton dw_mci_start_command(host, data->stop, host->stop_cmdr); 281*f95f3850SWill Newton } 282*f95f3850SWill Newton 283*f95f3850SWill Newton /* DMA interface functions */ 284*f95f3850SWill Newton static void dw_mci_stop_dma(struct dw_mci *host) 285*f95f3850SWill Newton { 286*f95f3850SWill Newton if (host->use_dma) { 287*f95f3850SWill Newton host->dma_ops->stop(host); 288*f95f3850SWill Newton host->dma_ops->cleanup(host); 289*f95f3850SWill Newton } else { 290*f95f3850SWill Newton /* Data transfer was stopped by the interrupt handler */ 291*f95f3850SWill Newton set_bit(EVENT_XFER_COMPLETE, &host->pending_events); 292*f95f3850SWill Newton } 293*f95f3850SWill Newton } 294*f95f3850SWill Newton 295*f95f3850SWill Newton #ifdef CONFIG_MMC_DW_IDMAC 296*f95f3850SWill Newton static void dw_mci_dma_cleanup(struct dw_mci *host) 297*f95f3850SWill Newton { 298*f95f3850SWill Newton struct mmc_data *data = host->data; 299*f95f3850SWill Newton 300*f95f3850SWill Newton if (data) 301*f95f3850SWill Newton dma_unmap_sg(&host->pdev->dev, data->sg, data->sg_len, 302*f95f3850SWill Newton ((data->flags & MMC_DATA_WRITE) 303*f95f3850SWill Newton ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); 304*f95f3850SWill Newton } 305*f95f3850SWill Newton 306*f95f3850SWill Newton static void dw_mci_idmac_stop_dma(struct dw_mci *host) 307*f95f3850SWill Newton { 308*f95f3850SWill Newton u32 temp; 309*f95f3850SWill Newton 310*f95f3850SWill Newton /* Disable and reset the IDMAC interface */ 311*f95f3850SWill Newton temp = mci_readl(host, CTRL); 312*f95f3850SWill Newton temp &= ~SDMMC_CTRL_USE_IDMAC; 313*f95f3850SWill Newton temp |= SDMMC_CTRL_DMA_RESET; 314*f95f3850SWill Newton mci_writel(host, CTRL, temp); 315*f95f3850SWill Newton 316*f95f3850SWill Newton /* Stop the IDMAC running */ 317*f95f3850SWill Newton temp = mci_readl(host, BMOD); 318*f95f3850SWill Newton temp &= ~SDMMC_IDMAC_ENABLE; 319*f95f3850SWill Newton mci_writel(host, BMOD, temp); 320*f95f3850SWill Newton } 321*f95f3850SWill Newton 322*f95f3850SWill Newton static void dw_mci_idmac_complete_dma(struct dw_mci *host) 323*f95f3850SWill Newton { 324*f95f3850SWill Newton struct mmc_data *data = host->data; 325*f95f3850SWill Newton 326*f95f3850SWill Newton dev_vdbg(&host->pdev->dev, "DMA complete\n"); 327*f95f3850SWill Newton 328*f95f3850SWill Newton host->dma_ops->cleanup(host); 329*f95f3850SWill Newton 330*f95f3850SWill Newton /* 331*f95f3850SWill Newton * If the card was removed, data will be NULL. No point in trying to 332*f95f3850SWill Newton * send the stop command or waiting for NBUSY in this case. 333*f95f3850SWill Newton */ 334*f95f3850SWill Newton if (data) { 335*f95f3850SWill Newton set_bit(EVENT_XFER_COMPLETE, &host->pending_events); 336*f95f3850SWill Newton tasklet_schedule(&host->tasklet); 337*f95f3850SWill Newton } 338*f95f3850SWill Newton } 339*f95f3850SWill Newton 340*f95f3850SWill Newton static void dw_mci_translate_sglist(struct dw_mci *host, struct mmc_data *data, 341*f95f3850SWill Newton unsigned int sg_len) 342*f95f3850SWill Newton { 343*f95f3850SWill Newton int i; 344*f95f3850SWill Newton struct idmac_desc *desc = host->sg_cpu; 345*f95f3850SWill Newton 346*f95f3850SWill Newton for (i = 0; i < sg_len; i++, desc++) { 347*f95f3850SWill Newton unsigned int length = sg_dma_len(&data->sg[i]); 348*f95f3850SWill Newton u32 mem_addr = sg_dma_address(&data->sg[i]); 349*f95f3850SWill Newton 350*f95f3850SWill Newton /* Set the OWN bit and disable interrupts for this descriptor */ 351*f95f3850SWill Newton desc->des0 = IDMAC_DES0_OWN | IDMAC_DES0_DIC | IDMAC_DES0_CH; 352*f95f3850SWill Newton 353*f95f3850SWill Newton /* Buffer length */ 354*f95f3850SWill Newton IDMAC_SET_BUFFER1_SIZE(desc, length); 355*f95f3850SWill Newton 356*f95f3850SWill Newton /* Physical address to DMA to/from */ 357*f95f3850SWill Newton desc->des2 = mem_addr; 358*f95f3850SWill Newton } 359*f95f3850SWill Newton 360*f95f3850SWill Newton /* Set first descriptor */ 361*f95f3850SWill Newton desc = host->sg_cpu; 362*f95f3850SWill Newton desc->des0 |= IDMAC_DES0_FD; 363*f95f3850SWill Newton 364*f95f3850SWill Newton /* Set last descriptor */ 365*f95f3850SWill Newton desc = host->sg_cpu + (i - 1) * sizeof(struct idmac_desc); 366*f95f3850SWill Newton desc->des0 &= ~(IDMAC_DES0_CH | IDMAC_DES0_DIC); 367*f95f3850SWill Newton desc->des0 |= IDMAC_DES0_LD; 368*f95f3850SWill Newton 369*f95f3850SWill Newton wmb(); 370*f95f3850SWill Newton } 371*f95f3850SWill Newton 372*f95f3850SWill Newton static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len) 373*f95f3850SWill Newton { 374*f95f3850SWill Newton u32 temp; 375*f95f3850SWill Newton 376*f95f3850SWill Newton dw_mci_translate_sglist(host, host->data, sg_len); 377*f95f3850SWill Newton 378*f95f3850SWill Newton /* Select IDMAC interface */ 379*f95f3850SWill Newton temp = mci_readl(host, CTRL); 380*f95f3850SWill Newton temp |= SDMMC_CTRL_USE_IDMAC; 381*f95f3850SWill Newton mci_writel(host, CTRL, temp); 382*f95f3850SWill Newton 383*f95f3850SWill Newton wmb(); 384*f95f3850SWill Newton 385*f95f3850SWill Newton /* Enable the IDMAC */ 386*f95f3850SWill Newton temp = mci_readl(host, BMOD); 387*f95f3850SWill Newton temp |= SDMMC_IDMAC_ENABLE; 388*f95f3850SWill Newton mci_writel(host, BMOD, temp); 389*f95f3850SWill Newton 390*f95f3850SWill Newton /* Start it running */ 391*f95f3850SWill Newton mci_writel(host, PLDMND, 1); 392*f95f3850SWill Newton } 393*f95f3850SWill Newton 394*f95f3850SWill Newton static int dw_mci_idmac_init(struct dw_mci *host) 395*f95f3850SWill Newton { 396*f95f3850SWill Newton struct idmac_desc *p; 397*f95f3850SWill Newton int i; 398*f95f3850SWill Newton 399*f95f3850SWill Newton /* Number of descriptors in the ring buffer */ 400*f95f3850SWill Newton host->ring_size = PAGE_SIZE / sizeof(struct idmac_desc); 401*f95f3850SWill Newton 402*f95f3850SWill Newton /* Forward link the descriptor list */ 403*f95f3850SWill Newton for (i = 0, p = host->sg_cpu; i < host->ring_size - 1; i++, p++) 404*f95f3850SWill Newton p->des3 = host->sg_dma + (sizeof(struct idmac_desc) * (i + 1)); 405*f95f3850SWill Newton 406*f95f3850SWill Newton /* Set the last descriptor as the end-of-ring descriptor */ 407*f95f3850SWill Newton p->des3 = host->sg_dma; 408*f95f3850SWill Newton p->des0 = IDMAC_DES0_ER; 409*f95f3850SWill Newton 410*f95f3850SWill Newton /* Mask out interrupts - get Tx & Rx complete only */ 411*f95f3850SWill Newton mci_writel(host, IDINTEN, SDMMC_IDMAC_INT_NI | SDMMC_IDMAC_INT_RI | 412*f95f3850SWill Newton SDMMC_IDMAC_INT_TI); 413*f95f3850SWill Newton 414*f95f3850SWill Newton /* Set the descriptor base address */ 415*f95f3850SWill Newton mci_writel(host, DBADDR, host->sg_dma); 416*f95f3850SWill Newton return 0; 417*f95f3850SWill Newton } 418*f95f3850SWill Newton 419*f95f3850SWill Newton static struct dw_mci_dma_ops dw_mci_idmac_ops = { 420*f95f3850SWill Newton .init = dw_mci_idmac_init, 421*f95f3850SWill Newton .start = dw_mci_idmac_start_dma, 422*f95f3850SWill Newton .stop = dw_mci_idmac_stop_dma, 423*f95f3850SWill Newton .complete = dw_mci_idmac_complete_dma, 424*f95f3850SWill Newton .cleanup = dw_mci_dma_cleanup, 425*f95f3850SWill Newton }; 426*f95f3850SWill Newton #endif /* CONFIG_MMC_DW_IDMAC */ 427*f95f3850SWill Newton 428*f95f3850SWill Newton static int dw_mci_submit_data_dma(struct dw_mci *host, struct mmc_data *data) 429*f95f3850SWill Newton { 430*f95f3850SWill Newton struct scatterlist *sg; 431*f95f3850SWill Newton unsigned int i, direction, sg_len; 432*f95f3850SWill Newton u32 temp; 433*f95f3850SWill Newton 434*f95f3850SWill Newton /* If we don't have a channel, we can't do DMA */ 435*f95f3850SWill Newton if (!host->use_dma) 436*f95f3850SWill Newton return -ENODEV; 437*f95f3850SWill Newton 438*f95f3850SWill Newton /* 439*f95f3850SWill Newton * We don't do DMA on "complex" transfers, i.e. with 440*f95f3850SWill Newton * non-word-aligned buffers or lengths. Also, we don't bother 441*f95f3850SWill Newton * with all the DMA setup overhead for short transfers. 442*f95f3850SWill Newton */ 443*f95f3850SWill Newton if (data->blocks * data->blksz < DW_MCI_DMA_THRESHOLD) 444*f95f3850SWill Newton return -EINVAL; 445*f95f3850SWill Newton if (data->blksz & 3) 446*f95f3850SWill Newton return -EINVAL; 447*f95f3850SWill Newton 448*f95f3850SWill Newton for_each_sg(data->sg, sg, data->sg_len, i) { 449*f95f3850SWill Newton if (sg->offset & 3 || sg->length & 3) 450*f95f3850SWill Newton return -EINVAL; 451*f95f3850SWill Newton } 452*f95f3850SWill Newton 453*f95f3850SWill Newton if (data->flags & MMC_DATA_READ) 454*f95f3850SWill Newton direction = DMA_FROM_DEVICE; 455*f95f3850SWill Newton else 456*f95f3850SWill Newton direction = DMA_TO_DEVICE; 457*f95f3850SWill Newton 458*f95f3850SWill Newton sg_len = dma_map_sg(&host->pdev->dev, data->sg, data->sg_len, 459*f95f3850SWill Newton direction); 460*f95f3850SWill Newton 461*f95f3850SWill Newton dev_vdbg(&host->pdev->dev, 462*f95f3850SWill Newton "sd sg_cpu: %#lx sg_dma: %#lx sg_len: %d\n", 463*f95f3850SWill Newton (unsigned long)host->sg_cpu, (unsigned long)host->sg_dma, 464*f95f3850SWill Newton sg_len); 465*f95f3850SWill Newton 466*f95f3850SWill Newton /* Enable the DMA interface */ 467*f95f3850SWill Newton temp = mci_readl(host, CTRL); 468*f95f3850SWill Newton temp |= SDMMC_CTRL_DMA_ENABLE; 469*f95f3850SWill Newton mci_writel(host, CTRL, temp); 470*f95f3850SWill Newton 471*f95f3850SWill Newton /* Disable RX/TX IRQs, let DMA handle it */ 472*f95f3850SWill Newton temp = mci_readl(host, INTMASK); 473*f95f3850SWill Newton temp &= ~(SDMMC_INT_RXDR | SDMMC_INT_TXDR); 474*f95f3850SWill Newton mci_writel(host, INTMASK, temp); 475*f95f3850SWill Newton 476*f95f3850SWill Newton host->dma_ops->start(host, sg_len); 477*f95f3850SWill Newton 478*f95f3850SWill Newton return 0; 479*f95f3850SWill Newton } 480*f95f3850SWill Newton 481*f95f3850SWill Newton static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data) 482*f95f3850SWill Newton { 483*f95f3850SWill Newton u32 temp; 484*f95f3850SWill Newton 485*f95f3850SWill Newton data->error = -EINPROGRESS; 486*f95f3850SWill Newton 487*f95f3850SWill Newton WARN_ON(host->data); 488*f95f3850SWill Newton host->sg = NULL; 489*f95f3850SWill Newton host->data = data; 490*f95f3850SWill Newton 491*f95f3850SWill Newton if (dw_mci_submit_data_dma(host, data)) { 492*f95f3850SWill Newton host->sg = data->sg; 493*f95f3850SWill Newton host->pio_offset = 0; 494*f95f3850SWill Newton if (data->flags & MMC_DATA_READ) 495*f95f3850SWill Newton host->dir_status = DW_MCI_RECV_STATUS; 496*f95f3850SWill Newton else 497*f95f3850SWill Newton host->dir_status = DW_MCI_SEND_STATUS; 498*f95f3850SWill Newton 499*f95f3850SWill Newton temp = mci_readl(host, INTMASK); 500*f95f3850SWill Newton temp |= SDMMC_INT_TXDR | SDMMC_INT_RXDR; 501*f95f3850SWill Newton mci_writel(host, INTMASK, temp); 502*f95f3850SWill Newton 503*f95f3850SWill Newton temp = mci_readl(host, CTRL); 504*f95f3850SWill Newton temp &= ~SDMMC_CTRL_DMA_ENABLE; 505*f95f3850SWill Newton mci_writel(host, CTRL, temp); 506*f95f3850SWill Newton } 507*f95f3850SWill Newton } 508*f95f3850SWill Newton 509*f95f3850SWill Newton static void mci_send_cmd(struct dw_mci_slot *slot, u32 cmd, u32 arg) 510*f95f3850SWill Newton { 511*f95f3850SWill Newton struct dw_mci *host = slot->host; 512*f95f3850SWill Newton unsigned long timeout = jiffies + msecs_to_jiffies(500); 513*f95f3850SWill Newton unsigned int cmd_status = 0; 514*f95f3850SWill Newton 515*f95f3850SWill Newton mci_writel(host, CMDARG, arg); 516*f95f3850SWill Newton wmb(); 517*f95f3850SWill Newton mci_writel(host, CMD, SDMMC_CMD_START | cmd); 518*f95f3850SWill Newton 519*f95f3850SWill Newton while (time_before(jiffies, timeout)) { 520*f95f3850SWill Newton cmd_status = mci_readl(host, CMD); 521*f95f3850SWill Newton if (!(cmd_status & SDMMC_CMD_START)) 522*f95f3850SWill Newton return; 523*f95f3850SWill Newton } 524*f95f3850SWill Newton dev_err(&slot->mmc->class_dev, 525*f95f3850SWill Newton "Timeout sending command (cmd %#x arg %#x status %#x)\n", 526*f95f3850SWill Newton cmd, arg, cmd_status); 527*f95f3850SWill Newton } 528*f95f3850SWill Newton 529*f95f3850SWill Newton static void dw_mci_setup_bus(struct dw_mci_slot *slot) 530*f95f3850SWill Newton { 531*f95f3850SWill Newton struct dw_mci *host = slot->host; 532*f95f3850SWill Newton u32 div; 533*f95f3850SWill Newton 534*f95f3850SWill Newton if (slot->clock != host->current_speed) { 535*f95f3850SWill Newton if (host->bus_hz % slot->clock) 536*f95f3850SWill Newton /* 537*f95f3850SWill Newton * move the + 1 after the divide to prevent 538*f95f3850SWill Newton * over-clocking the card. 539*f95f3850SWill Newton */ 540*f95f3850SWill Newton div = ((host->bus_hz / slot->clock) >> 1) + 1; 541*f95f3850SWill Newton else 542*f95f3850SWill Newton div = (host->bus_hz / slot->clock) >> 1; 543*f95f3850SWill Newton 544*f95f3850SWill Newton dev_info(&slot->mmc->class_dev, 545*f95f3850SWill Newton "Bus speed (slot %d) = %dHz (slot req %dHz, actual %dHZ" 546*f95f3850SWill Newton " div = %d)\n", slot->id, host->bus_hz, slot->clock, 547*f95f3850SWill Newton div ? ((host->bus_hz / div) >> 1) : host->bus_hz, div); 548*f95f3850SWill Newton 549*f95f3850SWill Newton /* disable clock */ 550*f95f3850SWill Newton mci_writel(host, CLKENA, 0); 551*f95f3850SWill Newton mci_writel(host, CLKSRC, 0); 552*f95f3850SWill Newton 553*f95f3850SWill Newton /* inform CIU */ 554*f95f3850SWill Newton mci_send_cmd(slot, 555*f95f3850SWill Newton SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0); 556*f95f3850SWill Newton 557*f95f3850SWill Newton /* set clock to desired speed */ 558*f95f3850SWill Newton mci_writel(host, CLKDIV, div); 559*f95f3850SWill Newton 560*f95f3850SWill Newton /* inform CIU */ 561*f95f3850SWill Newton mci_send_cmd(slot, 562*f95f3850SWill Newton SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0); 563*f95f3850SWill Newton 564*f95f3850SWill Newton /* enable clock */ 565*f95f3850SWill Newton mci_writel(host, CLKENA, SDMMC_CLKEN_ENABLE); 566*f95f3850SWill Newton 567*f95f3850SWill Newton /* inform CIU */ 568*f95f3850SWill Newton mci_send_cmd(slot, 569*f95f3850SWill Newton SDMMC_CMD_UPD_CLK | SDMMC_CMD_PRV_DAT_WAIT, 0); 570*f95f3850SWill Newton 571*f95f3850SWill Newton host->current_speed = slot->clock; 572*f95f3850SWill Newton } 573*f95f3850SWill Newton 574*f95f3850SWill Newton /* Set the current slot bus width */ 575*f95f3850SWill Newton mci_writel(host, CTYPE, slot->ctype); 576*f95f3850SWill Newton } 577*f95f3850SWill Newton 578*f95f3850SWill Newton static void dw_mci_start_request(struct dw_mci *host, 579*f95f3850SWill Newton struct dw_mci_slot *slot) 580*f95f3850SWill Newton { 581*f95f3850SWill Newton struct mmc_request *mrq; 582*f95f3850SWill Newton struct mmc_command *cmd; 583*f95f3850SWill Newton struct mmc_data *data; 584*f95f3850SWill Newton u32 cmdflags; 585*f95f3850SWill Newton 586*f95f3850SWill Newton mrq = slot->mrq; 587*f95f3850SWill Newton if (host->pdata->select_slot) 588*f95f3850SWill Newton host->pdata->select_slot(slot->id); 589*f95f3850SWill Newton 590*f95f3850SWill Newton /* Slot specific timing and width adjustment */ 591*f95f3850SWill Newton dw_mci_setup_bus(slot); 592*f95f3850SWill Newton 593*f95f3850SWill Newton host->cur_slot = slot; 594*f95f3850SWill Newton host->mrq = mrq; 595*f95f3850SWill Newton 596*f95f3850SWill Newton host->pending_events = 0; 597*f95f3850SWill Newton host->completed_events = 0; 598*f95f3850SWill Newton host->data_status = 0; 599*f95f3850SWill Newton 600*f95f3850SWill Newton data = mrq->data; 601*f95f3850SWill Newton if (data) { 602*f95f3850SWill Newton dw_mci_set_timeout(host); 603*f95f3850SWill Newton mci_writel(host, BYTCNT, data->blksz*data->blocks); 604*f95f3850SWill Newton mci_writel(host, BLKSIZ, data->blksz); 605*f95f3850SWill Newton } 606*f95f3850SWill Newton 607*f95f3850SWill Newton cmd = mrq->cmd; 608*f95f3850SWill Newton cmdflags = dw_mci_prepare_command(slot->mmc, cmd); 609*f95f3850SWill Newton 610*f95f3850SWill Newton /* this is the first command, send the initialization clock */ 611*f95f3850SWill Newton if (test_and_clear_bit(DW_MMC_CARD_NEED_INIT, &slot->flags)) 612*f95f3850SWill Newton cmdflags |= SDMMC_CMD_INIT; 613*f95f3850SWill Newton 614*f95f3850SWill Newton if (data) { 615*f95f3850SWill Newton dw_mci_submit_data(host, data); 616*f95f3850SWill Newton wmb(); 617*f95f3850SWill Newton } 618*f95f3850SWill Newton 619*f95f3850SWill Newton dw_mci_start_command(host, cmd, cmdflags); 620*f95f3850SWill Newton 621*f95f3850SWill Newton if (mrq->stop) 622*f95f3850SWill Newton host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop); 623*f95f3850SWill Newton } 624*f95f3850SWill Newton 625*f95f3850SWill Newton static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot, 626*f95f3850SWill Newton struct mmc_request *mrq) 627*f95f3850SWill Newton { 628*f95f3850SWill Newton dev_vdbg(&slot->mmc->class_dev, "queue request: state=%d\n", 629*f95f3850SWill Newton host->state); 630*f95f3850SWill Newton 631*f95f3850SWill Newton spin_lock_bh(&host->lock); 632*f95f3850SWill Newton slot->mrq = mrq; 633*f95f3850SWill Newton 634*f95f3850SWill Newton if (host->state == STATE_IDLE) { 635*f95f3850SWill Newton host->state = STATE_SENDING_CMD; 636*f95f3850SWill Newton dw_mci_start_request(host, slot); 637*f95f3850SWill Newton } else { 638*f95f3850SWill Newton list_add_tail(&slot->queue_node, &host->queue); 639*f95f3850SWill Newton } 640*f95f3850SWill Newton 641*f95f3850SWill Newton spin_unlock_bh(&host->lock); 642*f95f3850SWill Newton } 643*f95f3850SWill Newton 644*f95f3850SWill Newton static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) 645*f95f3850SWill Newton { 646*f95f3850SWill Newton struct dw_mci_slot *slot = mmc_priv(mmc); 647*f95f3850SWill Newton struct dw_mci *host = slot->host; 648*f95f3850SWill Newton 649*f95f3850SWill Newton WARN_ON(slot->mrq); 650*f95f3850SWill Newton 651*f95f3850SWill Newton if (!test_bit(DW_MMC_CARD_PRESENT, &slot->flags)) { 652*f95f3850SWill Newton mrq->cmd->error = -ENOMEDIUM; 653*f95f3850SWill Newton mmc_request_done(mmc, mrq); 654*f95f3850SWill Newton return; 655*f95f3850SWill Newton } 656*f95f3850SWill Newton 657*f95f3850SWill Newton /* We don't support multiple blocks of weird lengths. */ 658*f95f3850SWill Newton dw_mci_queue_request(host, slot, mrq); 659*f95f3850SWill Newton } 660*f95f3850SWill Newton 661*f95f3850SWill Newton static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) 662*f95f3850SWill Newton { 663*f95f3850SWill Newton struct dw_mci_slot *slot = mmc_priv(mmc); 664*f95f3850SWill Newton 665*f95f3850SWill Newton /* set default 1 bit mode */ 666*f95f3850SWill Newton slot->ctype = SDMMC_CTYPE_1BIT; 667*f95f3850SWill Newton 668*f95f3850SWill Newton switch (ios->bus_width) { 669*f95f3850SWill Newton case MMC_BUS_WIDTH_1: 670*f95f3850SWill Newton slot->ctype = SDMMC_CTYPE_1BIT; 671*f95f3850SWill Newton break; 672*f95f3850SWill Newton case MMC_BUS_WIDTH_4: 673*f95f3850SWill Newton slot->ctype = SDMMC_CTYPE_4BIT; 674*f95f3850SWill Newton break; 675*f95f3850SWill Newton } 676*f95f3850SWill Newton 677*f95f3850SWill Newton if (ios->clock) { 678*f95f3850SWill Newton /* 679*f95f3850SWill Newton * Use mirror of ios->clock to prevent race with mmc 680*f95f3850SWill Newton * core ios update when finding the minimum. 681*f95f3850SWill Newton */ 682*f95f3850SWill Newton slot->clock = ios->clock; 683*f95f3850SWill Newton } 684*f95f3850SWill Newton 685*f95f3850SWill Newton switch (ios->power_mode) { 686*f95f3850SWill Newton case MMC_POWER_UP: 687*f95f3850SWill Newton set_bit(DW_MMC_CARD_NEED_INIT, &slot->flags); 688*f95f3850SWill Newton break; 689*f95f3850SWill Newton default: 690*f95f3850SWill Newton break; 691*f95f3850SWill Newton } 692*f95f3850SWill Newton } 693*f95f3850SWill Newton 694*f95f3850SWill Newton static int dw_mci_get_ro(struct mmc_host *mmc) 695*f95f3850SWill Newton { 696*f95f3850SWill Newton int read_only; 697*f95f3850SWill Newton struct dw_mci_slot *slot = mmc_priv(mmc); 698*f95f3850SWill Newton struct dw_mci_board *brd = slot->host->pdata; 699*f95f3850SWill Newton 700*f95f3850SWill Newton /* Use platform get_ro function, else try on board write protect */ 701*f95f3850SWill Newton if (brd->get_ro) 702*f95f3850SWill Newton read_only = brd->get_ro(slot->id); 703*f95f3850SWill Newton else 704*f95f3850SWill Newton read_only = 705*f95f3850SWill Newton mci_readl(slot->host, WRTPRT) & (1 << slot->id) ? 1 : 0; 706*f95f3850SWill Newton 707*f95f3850SWill Newton dev_dbg(&mmc->class_dev, "card is %s\n", 708*f95f3850SWill Newton read_only ? "read-only" : "read-write"); 709*f95f3850SWill Newton 710*f95f3850SWill Newton return read_only; 711*f95f3850SWill Newton } 712*f95f3850SWill Newton 713*f95f3850SWill Newton static int dw_mci_get_cd(struct mmc_host *mmc) 714*f95f3850SWill Newton { 715*f95f3850SWill Newton int present; 716*f95f3850SWill Newton struct dw_mci_slot *slot = mmc_priv(mmc); 717*f95f3850SWill Newton struct dw_mci_board *brd = slot->host->pdata; 718*f95f3850SWill Newton 719*f95f3850SWill Newton /* Use platform get_cd function, else try onboard card detect */ 720*f95f3850SWill Newton if (brd->get_cd) 721*f95f3850SWill Newton present = !brd->get_cd(slot->id); 722*f95f3850SWill Newton else 723*f95f3850SWill Newton present = (mci_readl(slot->host, CDETECT) & (1 << slot->id)) 724*f95f3850SWill Newton == 0 ? 1 : 0; 725*f95f3850SWill Newton 726*f95f3850SWill Newton if (present) 727*f95f3850SWill Newton dev_dbg(&mmc->class_dev, "card is present\n"); 728*f95f3850SWill Newton else 729*f95f3850SWill Newton dev_dbg(&mmc->class_dev, "card is not present\n"); 730*f95f3850SWill Newton 731*f95f3850SWill Newton return present; 732*f95f3850SWill Newton } 733*f95f3850SWill Newton 734*f95f3850SWill Newton static const struct mmc_host_ops dw_mci_ops = { 735*f95f3850SWill Newton .request = dw_mci_request, 736*f95f3850SWill Newton .set_ios = dw_mci_set_ios, 737*f95f3850SWill Newton .get_ro = dw_mci_get_ro, 738*f95f3850SWill Newton .get_cd = dw_mci_get_cd, 739*f95f3850SWill Newton }; 740*f95f3850SWill Newton 741*f95f3850SWill Newton static void dw_mci_request_end(struct dw_mci *host, struct mmc_request *mrq) 742*f95f3850SWill Newton __releases(&host->lock) 743*f95f3850SWill Newton __acquires(&host->lock) 744*f95f3850SWill Newton { 745*f95f3850SWill Newton struct dw_mci_slot *slot; 746*f95f3850SWill Newton struct mmc_host *prev_mmc = host->cur_slot->mmc; 747*f95f3850SWill Newton 748*f95f3850SWill Newton WARN_ON(host->cmd || host->data); 749*f95f3850SWill Newton 750*f95f3850SWill Newton host->cur_slot->mrq = NULL; 751*f95f3850SWill Newton host->mrq = NULL; 752*f95f3850SWill Newton if (!list_empty(&host->queue)) { 753*f95f3850SWill Newton slot = list_entry(host->queue.next, 754*f95f3850SWill Newton struct dw_mci_slot, queue_node); 755*f95f3850SWill Newton list_del(&slot->queue_node); 756*f95f3850SWill Newton dev_vdbg(&host->pdev->dev, "list not empty: %s is next\n", 757*f95f3850SWill Newton mmc_hostname(slot->mmc)); 758*f95f3850SWill Newton host->state = STATE_SENDING_CMD; 759*f95f3850SWill Newton dw_mci_start_request(host, slot); 760*f95f3850SWill Newton } else { 761*f95f3850SWill Newton dev_vdbg(&host->pdev->dev, "list empty\n"); 762*f95f3850SWill Newton host->state = STATE_IDLE; 763*f95f3850SWill Newton } 764*f95f3850SWill Newton 765*f95f3850SWill Newton spin_unlock(&host->lock); 766*f95f3850SWill Newton mmc_request_done(prev_mmc, mrq); 767*f95f3850SWill Newton spin_lock(&host->lock); 768*f95f3850SWill Newton } 769*f95f3850SWill Newton 770*f95f3850SWill Newton static void dw_mci_command_complete(struct dw_mci *host, struct mmc_command *cmd) 771*f95f3850SWill Newton { 772*f95f3850SWill Newton u32 status = host->cmd_status; 773*f95f3850SWill Newton 774*f95f3850SWill Newton host->cmd_status = 0; 775*f95f3850SWill Newton 776*f95f3850SWill Newton /* Read the response from the card (up to 16 bytes) */ 777*f95f3850SWill Newton if (cmd->flags & MMC_RSP_PRESENT) { 778*f95f3850SWill Newton if (cmd->flags & MMC_RSP_136) { 779*f95f3850SWill Newton cmd->resp[3] = mci_readl(host, RESP0); 780*f95f3850SWill Newton cmd->resp[2] = mci_readl(host, RESP1); 781*f95f3850SWill Newton cmd->resp[1] = mci_readl(host, RESP2); 782*f95f3850SWill Newton cmd->resp[0] = mci_readl(host, RESP3); 783*f95f3850SWill Newton } else { 784*f95f3850SWill Newton cmd->resp[0] = mci_readl(host, RESP0); 785*f95f3850SWill Newton cmd->resp[1] = 0; 786*f95f3850SWill Newton cmd->resp[2] = 0; 787*f95f3850SWill Newton cmd->resp[3] = 0; 788*f95f3850SWill Newton } 789*f95f3850SWill Newton } 790*f95f3850SWill Newton 791*f95f3850SWill Newton if (status & SDMMC_INT_RTO) 792*f95f3850SWill Newton cmd->error = -ETIMEDOUT; 793*f95f3850SWill Newton else if ((cmd->flags & MMC_RSP_CRC) && (status & SDMMC_INT_RCRC)) 794*f95f3850SWill Newton cmd->error = -EILSEQ; 795*f95f3850SWill Newton else if (status & SDMMC_INT_RESP_ERR) 796*f95f3850SWill Newton cmd->error = -EIO; 797*f95f3850SWill Newton else 798*f95f3850SWill Newton cmd->error = 0; 799*f95f3850SWill Newton 800*f95f3850SWill Newton if (cmd->error) { 801*f95f3850SWill Newton /* newer ip versions need a delay between retries */ 802*f95f3850SWill Newton if (host->quirks & DW_MCI_QUIRK_RETRY_DELAY) 803*f95f3850SWill Newton mdelay(20); 804*f95f3850SWill Newton 805*f95f3850SWill Newton if (cmd->data) { 806*f95f3850SWill Newton host->data = NULL; 807*f95f3850SWill Newton dw_mci_stop_dma(host); 808*f95f3850SWill Newton } 809*f95f3850SWill Newton } 810*f95f3850SWill Newton } 811*f95f3850SWill Newton 812*f95f3850SWill Newton static void dw_mci_tasklet_func(unsigned long priv) 813*f95f3850SWill Newton { 814*f95f3850SWill Newton struct dw_mci *host = (struct dw_mci *)priv; 815*f95f3850SWill Newton struct mmc_data *data; 816*f95f3850SWill Newton struct mmc_command *cmd; 817*f95f3850SWill Newton enum dw_mci_state state; 818*f95f3850SWill Newton enum dw_mci_state prev_state; 819*f95f3850SWill Newton u32 status; 820*f95f3850SWill Newton 821*f95f3850SWill Newton spin_lock(&host->lock); 822*f95f3850SWill Newton 823*f95f3850SWill Newton state = host->state; 824*f95f3850SWill Newton data = host->data; 825*f95f3850SWill Newton 826*f95f3850SWill Newton do { 827*f95f3850SWill Newton prev_state = state; 828*f95f3850SWill Newton 829*f95f3850SWill Newton switch (state) { 830*f95f3850SWill Newton case STATE_IDLE: 831*f95f3850SWill Newton break; 832*f95f3850SWill Newton 833*f95f3850SWill Newton case STATE_SENDING_CMD: 834*f95f3850SWill Newton if (!test_and_clear_bit(EVENT_CMD_COMPLETE, 835*f95f3850SWill Newton &host->pending_events)) 836*f95f3850SWill Newton break; 837*f95f3850SWill Newton 838*f95f3850SWill Newton cmd = host->cmd; 839*f95f3850SWill Newton host->cmd = NULL; 840*f95f3850SWill Newton set_bit(EVENT_CMD_COMPLETE, &host->completed_events); 841*f95f3850SWill Newton dw_mci_command_complete(host, host->mrq->cmd); 842*f95f3850SWill Newton if (!host->mrq->data || cmd->error) { 843*f95f3850SWill Newton dw_mci_request_end(host, host->mrq); 844*f95f3850SWill Newton goto unlock; 845*f95f3850SWill Newton } 846*f95f3850SWill Newton 847*f95f3850SWill Newton prev_state = state = STATE_SENDING_DATA; 848*f95f3850SWill Newton /* fall through */ 849*f95f3850SWill Newton 850*f95f3850SWill Newton case STATE_SENDING_DATA: 851*f95f3850SWill Newton if (test_and_clear_bit(EVENT_DATA_ERROR, 852*f95f3850SWill Newton &host->pending_events)) { 853*f95f3850SWill Newton dw_mci_stop_dma(host); 854*f95f3850SWill Newton if (data->stop) 855*f95f3850SWill Newton send_stop_cmd(host, data); 856*f95f3850SWill Newton state = STATE_DATA_ERROR; 857*f95f3850SWill Newton break; 858*f95f3850SWill Newton } 859*f95f3850SWill Newton 860*f95f3850SWill Newton if (!test_and_clear_bit(EVENT_XFER_COMPLETE, 861*f95f3850SWill Newton &host->pending_events)) 862*f95f3850SWill Newton break; 863*f95f3850SWill Newton 864*f95f3850SWill Newton set_bit(EVENT_XFER_COMPLETE, &host->completed_events); 865*f95f3850SWill Newton prev_state = state = STATE_DATA_BUSY; 866*f95f3850SWill Newton /* fall through */ 867*f95f3850SWill Newton 868*f95f3850SWill Newton case STATE_DATA_BUSY: 869*f95f3850SWill Newton if (!test_and_clear_bit(EVENT_DATA_COMPLETE, 870*f95f3850SWill Newton &host->pending_events)) 871*f95f3850SWill Newton break; 872*f95f3850SWill Newton 873*f95f3850SWill Newton host->data = NULL; 874*f95f3850SWill Newton set_bit(EVENT_DATA_COMPLETE, &host->completed_events); 875*f95f3850SWill Newton status = host->data_status; 876*f95f3850SWill Newton 877*f95f3850SWill Newton if (status & DW_MCI_DATA_ERROR_FLAGS) { 878*f95f3850SWill Newton if (status & SDMMC_INT_DTO) { 879*f95f3850SWill Newton dev_err(&host->pdev->dev, 880*f95f3850SWill Newton "data timeout error\n"); 881*f95f3850SWill Newton data->error = -ETIMEDOUT; 882*f95f3850SWill Newton } else if (status & SDMMC_INT_DCRC) { 883*f95f3850SWill Newton dev_err(&host->pdev->dev, 884*f95f3850SWill Newton "data CRC error\n"); 885*f95f3850SWill Newton data->error = -EILSEQ; 886*f95f3850SWill Newton } else { 887*f95f3850SWill Newton dev_err(&host->pdev->dev, 888*f95f3850SWill Newton "data FIFO error " 889*f95f3850SWill Newton "(status=%08x)\n", 890*f95f3850SWill Newton status); 891*f95f3850SWill Newton data->error = -EIO; 892*f95f3850SWill Newton } 893*f95f3850SWill Newton } else { 894*f95f3850SWill Newton data->bytes_xfered = data->blocks * data->blksz; 895*f95f3850SWill Newton data->error = 0; 896*f95f3850SWill Newton } 897*f95f3850SWill Newton 898*f95f3850SWill Newton if (!data->stop) { 899*f95f3850SWill Newton dw_mci_request_end(host, host->mrq); 900*f95f3850SWill Newton goto unlock; 901*f95f3850SWill Newton } 902*f95f3850SWill Newton 903*f95f3850SWill Newton prev_state = state = STATE_SENDING_STOP; 904*f95f3850SWill Newton if (!data->error) 905*f95f3850SWill Newton send_stop_cmd(host, data); 906*f95f3850SWill Newton /* fall through */ 907*f95f3850SWill Newton 908*f95f3850SWill Newton case STATE_SENDING_STOP: 909*f95f3850SWill Newton if (!test_and_clear_bit(EVENT_CMD_COMPLETE, 910*f95f3850SWill Newton &host->pending_events)) 911*f95f3850SWill Newton break; 912*f95f3850SWill Newton 913*f95f3850SWill Newton host->cmd = NULL; 914*f95f3850SWill Newton dw_mci_command_complete(host, host->mrq->stop); 915*f95f3850SWill Newton dw_mci_request_end(host, host->mrq); 916*f95f3850SWill Newton goto unlock; 917*f95f3850SWill Newton 918*f95f3850SWill Newton case STATE_DATA_ERROR: 919*f95f3850SWill Newton if (!test_and_clear_bit(EVENT_XFER_COMPLETE, 920*f95f3850SWill Newton &host->pending_events)) 921*f95f3850SWill Newton break; 922*f95f3850SWill Newton 923*f95f3850SWill Newton state = STATE_DATA_BUSY; 924*f95f3850SWill Newton break; 925*f95f3850SWill Newton } 926*f95f3850SWill Newton } while (state != prev_state); 927*f95f3850SWill Newton 928*f95f3850SWill Newton host->state = state; 929*f95f3850SWill Newton unlock: 930*f95f3850SWill Newton spin_unlock(&host->lock); 931*f95f3850SWill Newton 932*f95f3850SWill Newton } 933*f95f3850SWill Newton 934*f95f3850SWill Newton static void dw_mci_push_data16(struct dw_mci *host, void *buf, int cnt) 935*f95f3850SWill Newton { 936*f95f3850SWill Newton u16 *pdata = (u16 *)buf; 937*f95f3850SWill Newton 938*f95f3850SWill Newton WARN_ON(cnt % 2 != 0); 939*f95f3850SWill Newton 940*f95f3850SWill Newton cnt = cnt >> 1; 941*f95f3850SWill Newton while (cnt > 0) { 942*f95f3850SWill Newton mci_writew(host, DATA, *pdata++); 943*f95f3850SWill Newton cnt--; 944*f95f3850SWill Newton } 945*f95f3850SWill Newton } 946*f95f3850SWill Newton 947*f95f3850SWill Newton static void dw_mci_pull_data16(struct dw_mci *host, void *buf, int cnt) 948*f95f3850SWill Newton { 949*f95f3850SWill Newton u16 *pdata = (u16 *)buf; 950*f95f3850SWill Newton 951*f95f3850SWill Newton WARN_ON(cnt % 2 != 0); 952*f95f3850SWill Newton 953*f95f3850SWill Newton cnt = cnt >> 1; 954*f95f3850SWill Newton while (cnt > 0) { 955*f95f3850SWill Newton *pdata++ = mci_readw(host, DATA); 956*f95f3850SWill Newton cnt--; 957*f95f3850SWill Newton } 958*f95f3850SWill Newton } 959*f95f3850SWill Newton 960*f95f3850SWill Newton static void dw_mci_push_data32(struct dw_mci *host, void *buf, int cnt) 961*f95f3850SWill Newton { 962*f95f3850SWill Newton u32 *pdata = (u32 *)buf; 963*f95f3850SWill Newton 964*f95f3850SWill Newton WARN_ON(cnt % 4 != 0); 965*f95f3850SWill Newton WARN_ON((unsigned long)pdata & 0x3); 966*f95f3850SWill Newton 967*f95f3850SWill Newton cnt = cnt >> 2; 968*f95f3850SWill Newton while (cnt > 0) { 969*f95f3850SWill Newton mci_writel(host, DATA, *pdata++); 970*f95f3850SWill Newton cnt--; 971*f95f3850SWill Newton } 972*f95f3850SWill Newton } 973*f95f3850SWill Newton 974*f95f3850SWill Newton static void dw_mci_pull_data32(struct dw_mci *host, void *buf, int cnt) 975*f95f3850SWill Newton { 976*f95f3850SWill Newton u32 *pdata = (u32 *)buf; 977*f95f3850SWill Newton 978*f95f3850SWill Newton WARN_ON(cnt % 4 != 0); 979*f95f3850SWill Newton WARN_ON((unsigned long)pdata & 0x3); 980*f95f3850SWill Newton 981*f95f3850SWill Newton cnt = cnt >> 2; 982*f95f3850SWill Newton while (cnt > 0) { 983*f95f3850SWill Newton *pdata++ = mci_readl(host, DATA); 984*f95f3850SWill Newton cnt--; 985*f95f3850SWill Newton } 986*f95f3850SWill Newton } 987*f95f3850SWill Newton 988*f95f3850SWill Newton static void dw_mci_push_data64(struct dw_mci *host, void *buf, int cnt) 989*f95f3850SWill Newton { 990*f95f3850SWill Newton u64 *pdata = (u64 *)buf; 991*f95f3850SWill Newton 992*f95f3850SWill Newton WARN_ON(cnt % 8 != 0); 993*f95f3850SWill Newton 994*f95f3850SWill Newton cnt = cnt >> 3; 995*f95f3850SWill Newton while (cnt > 0) { 996*f95f3850SWill Newton mci_writeq(host, DATA, *pdata++); 997*f95f3850SWill Newton cnt--; 998*f95f3850SWill Newton } 999*f95f3850SWill Newton } 1000*f95f3850SWill Newton 1001*f95f3850SWill Newton static void dw_mci_pull_data64(struct dw_mci *host, void *buf, int cnt) 1002*f95f3850SWill Newton { 1003*f95f3850SWill Newton u64 *pdata = (u64 *)buf; 1004*f95f3850SWill Newton 1005*f95f3850SWill Newton WARN_ON(cnt % 8 != 0); 1006*f95f3850SWill Newton 1007*f95f3850SWill Newton cnt = cnt >> 3; 1008*f95f3850SWill Newton while (cnt > 0) { 1009*f95f3850SWill Newton *pdata++ = mci_readq(host, DATA); 1010*f95f3850SWill Newton cnt--; 1011*f95f3850SWill Newton } 1012*f95f3850SWill Newton } 1013*f95f3850SWill Newton 1014*f95f3850SWill Newton static void dw_mci_read_data_pio(struct dw_mci *host) 1015*f95f3850SWill Newton { 1016*f95f3850SWill Newton struct scatterlist *sg = host->sg; 1017*f95f3850SWill Newton void *buf = sg_virt(sg); 1018*f95f3850SWill Newton unsigned int offset = host->pio_offset; 1019*f95f3850SWill Newton struct mmc_data *data = host->data; 1020*f95f3850SWill Newton int shift = host->data_shift; 1021*f95f3850SWill Newton u32 status; 1022*f95f3850SWill Newton unsigned int nbytes = 0, len, old_len, count = 0; 1023*f95f3850SWill Newton 1024*f95f3850SWill Newton do { 1025*f95f3850SWill Newton len = SDMMC_GET_FCNT(mci_readl(host, STATUS)) << shift; 1026*f95f3850SWill Newton if (count == 0) 1027*f95f3850SWill Newton old_len = len; 1028*f95f3850SWill Newton 1029*f95f3850SWill Newton if (offset + len <= sg->length) { 1030*f95f3850SWill Newton host->pull_data(host, (void *)(buf + offset), len); 1031*f95f3850SWill Newton 1032*f95f3850SWill Newton offset += len; 1033*f95f3850SWill Newton nbytes += len; 1034*f95f3850SWill Newton 1035*f95f3850SWill Newton if (offset == sg->length) { 1036*f95f3850SWill Newton flush_dcache_page(sg_page(sg)); 1037*f95f3850SWill Newton host->sg = sg = sg_next(sg); 1038*f95f3850SWill Newton if (!sg) 1039*f95f3850SWill Newton goto done; 1040*f95f3850SWill Newton 1041*f95f3850SWill Newton offset = 0; 1042*f95f3850SWill Newton buf = sg_virt(sg); 1043*f95f3850SWill Newton } 1044*f95f3850SWill Newton } else { 1045*f95f3850SWill Newton unsigned int remaining = sg->length - offset; 1046*f95f3850SWill Newton host->pull_data(host, (void *)(buf + offset), 1047*f95f3850SWill Newton remaining); 1048*f95f3850SWill Newton nbytes += remaining; 1049*f95f3850SWill Newton 1050*f95f3850SWill Newton flush_dcache_page(sg_page(sg)); 1051*f95f3850SWill Newton host->sg = sg = sg_next(sg); 1052*f95f3850SWill Newton if (!sg) 1053*f95f3850SWill Newton goto done; 1054*f95f3850SWill Newton 1055*f95f3850SWill Newton offset = len - remaining; 1056*f95f3850SWill Newton buf = sg_virt(sg); 1057*f95f3850SWill Newton host->pull_data(host, buf, offset); 1058*f95f3850SWill Newton nbytes += offset; 1059*f95f3850SWill Newton } 1060*f95f3850SWill Newton 1061*f95f3850SWill Newton status = mci_readl(host, MINTSTS); 1062*f95f3850SWill Newton mci_writel(host, RINTSTS, SDMMC_INT_RXDR); 1063*f95f3850SWill Newton if (status & DW_MCI_DATA_ERROR_FLAGS) { 1064*f95f3850SWill Newton host->data_status = status; 1065*f95f3850SWill Newton data->bytes_xfered += nbytes; 1066*f95f3850SWill Newton smp_wmb(); 1067*f95f3850SWill Newton 1068*f95f3850SWill Newton set_bit(EVENT_DATA_ERROR, &host->pending_events); 1069*f95f3850SWill Newton 1070*f95f3850SWill Newton tasklet_schedule(&host->tasklet); 1071*f95f3850SWill Newton return; 1072*f95f3850SWill Newton } 1073*f95f3850SWill Newton count++; 1074*f95f3850SWill Newton } while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/ 1075*f95f3850SWill Newton len = SDMMC_GET_FCNT(mci_readl(host, STATUS)); 1076*f95f3850SWill Newton host->pio_offset = offset; 1077*f95f3850SWill Newton data->bytes_xfered += nbytes; 1078*f95f3850SWill Newton return; 1079*f95f3850SWill Newton 1080*f95f3850SWill Newton done: 1081*f95f3850SWill Newton data->bytes_xfered += nbytes; 1082*f95f3850SWill Newton smp_wmb(); 1083*f95f3850SWill Newton set_bit(EVENT_XFER_COMPLETE, &host->pending_events); 1084*f95f3850SWill Newton } 1085*f95f3850SWill Newton 1086*f95f3850SWill Newton static void dw_mci_write_data_pio(struct dw_mci *host) 1087*f95f3850SWill Newton { 1088*f95f3850SWill Newton struct scatterlist *sg = host->sg; 1089*f95f3850SWill Newton void *buf = sg_virt(sg); 1090*f95f3850SWill Newton unsigned int offset = host->pio_offset; 1091*f95f3850SWill Newton struct mmc_data *data = host->data; 1092*f95f3850SWill Newton int shift = host->data_shift; 1093*f95f3850SWill Newton u32 status; 1094*f95f3850SWill Newton unsigned int nbytes = 0, len; 1095*f95f3850SWill Newton 1096*f95f3850SWill Newton do { 1097*f95f3850SWill Newton len = SDMMC_FIFO_SZ - 1098*f95f3850SWill Newton (SDMMC_GET_FCNT(mci_readl(host, STATUS)) << shift); 1099*f95f3850SWill Newton if (offset + len <= sg->length) { 1100*f95f3850SWill Newton host->push_data(host, (void *)(buf + offset), len); 1101*f95f3850SWill Newton 1102*f95f3850SWill Newton offset += len; 1103*f95f3850SWill Newton nbytes += len; 1104*f95f3850SWill Newton if (offset == sg->length) { 1105*f95f3850SWill Newton host->sg = sg = sg_next(sg); 1106*f95f3850SWill Newton if (!sg) 1107*f95f3850SWill Newton goto done; 1108*f95f3850SWill Newton 1109*f95f3850SWill Newton offset = 0; 1110*f95f3850SWill Newton buf = sg_virt(sg); 1111*f95f3850SWill Newton } 1112*f95f3850SWill Newton } else { 1113*f95f3850SWill Newton unsigned int remaining = sg->length - offset; 1114*f95f3850SWill Newton 1115*f95f3850SWill Newton host->push_data(host, (void *)(buf + offset), 1116*f95f3850SWill Newton remaining); 1117*f95f3850SWill Newton nbytes += remaining; 1118*f95f3850SWill Newton 1119*f95f3850SWill Newton host->sg = sg = sg_next(sg); 1120*f95f3850SWill Newton if (!sg) 1121*f95f3850SWill Newton goto done; 1122*f95f3850SWill Newton 1123*f95f3850SWill Newton offset = len - remaining; 1124*f95f3850SWill Newton buf = sg_virt(sg); 1125*f95f3850SWill Newton host->push_data(host, (void *)buf, offset); 1126*f95f3850SWill Newton nbytes += offset; 1127*f95f3850SWill Newton } 1128*f95f3850SWill Newton 1129*f95f3850SWill Newton status = mci_readl(host, MINTSTS); 1130*f95f3850SWill Newton mci_writel(host, RINTSTS, SDMMC_INT_TXDR); 1131*f95f3850SWill Newton if (status & DW_MCI_DATA_ERROR_FLAGS) { 1132*f95f3850SWill Newton host->data_status = status; 1133*f95f3850SWill Newton data->bytes_xfered += nbytes; 1134*f95f3850SWill Newton 1135*f95f3850SWill Newton smp_wmb(); 1136*f95f3850SWill Newton 1137*f95f3850SWill Newton set_bit(EVENT_DATA_ERROR, &host->pending_events); 1138*f95f3850SWill Newton 1139*f95f3850SWill Newton tasklet_schedule(&host->tasklet); 1140*f95f3850SWill Newton return; 1141*f95f3850SWill Newton } 1142*f95f3850SWill Newton } while (status & SDMMC_INT_TXDR); /* if TXDR write again */ 1143*f95f3850SWill Newton 1144*f95f3850SWill Newton host->pio_offset = offset; 1145*f95f3850SWill Newton data->bytes_xfered += nbytes; 1146*f95f3850SWill Newton 1147*f95f3850SWill Newton return; 1148*f95f3850SWill Newton 1149*f95f3850SWill Newton done: 1150*f95f3850SWill Newton data->bytes_xfered += nbytes; 1151*f95f3850SWill Newton smp_wmb(); 1152*f95f3850SWill Newton set_bit(EVENT_XFER_COMPLETE, &host->pending_events); 1153*f95f3850SWill Newton } 1154*f95f3850SWill Newton 1155*f95f3850SWill Newton static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status) 1156*f95f3850SWill Newton { 1157*f95f3850SWill Newton if (!host->cmd_status) 1158*f95f3850SWill Newton host->cmd_status = status; 1159*f95f3850SWill Newton 1160*f95f3850SWill Newton smp_wmb(); 1161*f95f3850SWill Newton 1162*f95f3850SWill Newton set_bit(EVENT_CMD_COMPLETE, &host->pending_events); 1163*f95f3850SWill Newton tasklet_schedule(&host->tasklet); 1164*f95f3850SWill Newton } 1165*f95f3850SWill Newton 1166*f95f3850SWill Newton static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) 1167*f95f3850SWill Newton { 1168*f95f3850SWill Newton struct dw_mci *host = dev_id; 1169*f95f3850SWill Newton u32 status, pending; 1170*f95f3850SWill Newton unsigned int pass_count = 0; 1171*f95f3850SWill Newton 1172*f95f3850SWill Newton do { 1173*f95f3850SWill Newton status = mci_readl(host, RINTSTS); 1174*f95f3850SWill Newton pending = mci_readl(host, MINTSTS); /* read-only mask reg */ 1175*f95f3850SWill Newton 1176*f95f3850SWill Newton /* 1177*f95f3850SWill Newton * DTO fix - version 2.10a and below, and only if internal DMA 1178*f95f3850SWill Newton * is configured. 1179*f95f3850SWill Newton */ 1180*f95f3850SWill Newton if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) { 1181*f95f3850SWill Newton if (!pending && 1182*f95f3850SWill Newton ((mci_readl(host, STATUS) >> 17) & 0x1fff)) 1183*f95f3850SWill Newton pending |= SDMMC_INT_DATA_OVER; 1184*f95f3850SWill Newton } 1185*f95f3850SWill Newton 1186*f95f3850SWill Newton if (!pending) 1187*f95f3850SWill Newton break; 1188*f95f3850SWill Newton 1189*f95f3850SWill Newton if (pending & DW_MCI_CMD_ERROR_FLAGS) { 1190*f95f3850SWill Newton mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS); 1191*f95f3850SWill Newton host->cmd_status = status; 1192*f95f3850SWill Newton smp_wmb(); 1193*f95f3850SWill Newton set_bit(EVENT_CMD_COMPLETE, &host->pending_events); 1194*f95f3850SWill Newton tasklet_schedule(&host->tasklet); 1195*f95f3850SWill Newton } 1196*f95f3850SWill Newton 1197*f95f3850SWill Newton if (pending & DW_MCI_DATA_ERROR_FLAGS) { 1198*f95f3850SWill Newton /* if there is an error report DATA_ERROR */ 1199*f95f3850SWill Newton mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS); 1200*f95f3850SWill Newton host->data_status = status; 1201*f95f3850SWill Newton smp_wmb(); 1202*f95f3850SWill Newton set_bit(EVENT_DATA_ERROR, &host->pending_events); 1203*f95f3850SWill Newton tasklet_schedule(&host->tasklet); 1204*f95f3850SWill Newton } 1205*f95f3850SWill Newton 1206*f95f3850SWill Newton if (pending & SDMMC_INT_DATA_OVER) { 1207*f95f3850SWill Newton mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER); 1208*f95f3850SWill Newton if (!host->data_status) 1209*f95f3850SWill Newton host->data_status = status; 1210*f95f3850SWill Newton smp_wmb(); 1211*f95f3850SWill Newton if (host->dir_status == DW_MCI_RECV_STATUS) { 1212*f95f3850SWill Newton if (host->sg != NULL) 1213*f95f3850SWill Newton dw_mci_read_data_pio(host); 1214*f95f3850SWill Newton } 1215*f95f3850SWill Newton set_bit(EVENT_DATA_COMPLETE, &host->pending_events); 1216*f95f3850SWill Newton tasklet_schedule(&host->tasklet); 1217*f95f3850SWill Newton } 1218*f95f3850SWill Newton 1219*f95f3850SWill Newton if (pending & SDMMC_INT_RXDR) { 1220*f95f3850SWill Newton mci_writel(host, RINTSTS, SDMMC_INT_RXDR); 1221*f95f3850SWill Newton if (host->sg) 1222*f95f3850SWill Newton dw_mci_read_data_pio(host); 1223*f95f3850SWill Newton } 1224*f95f3850SWill Newton 1225*f95f3850SWill Newton if (pending & SDMMC_INT_TXDR) { 1226*f95f3850SWill Newton mci_writel(host, RINTSTS, SDMMC_INT_TXDR); 1227*f95f3850SWill Newton if (host->sg) 1228*f95f3850SWill Newton dw_mci_write_data_pio(host); 1229*f95f3850SWill Newton } 1230*f95f3850SWill Newton 1231*f95f3850SWill Newton if (pending & SDMMC_INT_CMD_DONE) { 1232*f95f3850SWill Newton mci_writel(host, RINTSTS, SDMMC_INT_CMD_DONE); 1233*f95f3850SWill Newton dw_mci_cmd_interrupt(host, status); 1234*f95f3850SWill Newton } 1235*f95f3850SWill Newton 1236*f95f3850SWill Newton if (pending & SDMMC_INT_CD) { 1237*f95f3850SWill Newton mci_writel(host, RINTSTS, SDMMC_INT_CD); 1238*f95f3850SWill Newton tasklet_schedule(&host->card_tasklet); 1239*f95f3850SWill Newton } 1240*f95f3850SWill Newton 1241*f95f3850SWill Newton } while (pass_count++ < 5); 1242*f95f3850SWill Newton 1243*f95f3850SWill Newton #ifdef CONFIG_MMC_DW_IDMAC 1244*f95f3850SWill Newton /* Handle DMA interrupts */ 1245*f95f3850SWill Newton pending = mci_readl(host, IDSTS); 1246*f95f3850SWill Newton if (pending & (SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI)) { 1247*f95f3850SWill Newton mci_writel(host, IDSTS, SDMMC_IDMAC_INT_TI | SDMMC_IDMAC_INT_RI); 1248*f95f3850SWill Newton mci_writel(host, IDSTS, SDMMC_IDMAC_INT_NI); 1249*f95f3850SWill Newton set_bit(EVENT_DATA_COMPLETE, &host->pending_events); 1250*f95f3850SWill Newton host->dma_ops->complete(host); 1251*f95f3850SWill Newton } 1252*f95f3850SWill Newton #endif 1253*f95f3850SWill Newton 1254*f95f3850SWill Newton return IRQ_HANDLED; 1255*f95f3850SWill Newton } 1256*f95f3850SWill Newton 1257*f95f3850SWill Newton static void dw_mci_tasklet_card(unsigned long data) 1258*f95f3850SWill Newton { 1259*f95f3850SWill Newton struct dw_mci *host = (struct dw_mci *)data; 1260*f95f3850SWill Newton int i; 1261*f95f3850SWill Newton 1262*f95f3850SWill Newton for (i = 0; i < host->num_slots; i++) { 1263*f95f3850SWill Newton struct dw_mci_slot *slot = host->slot[i]; 1264*f95f3850SWill Newton struct mmc_host *mmc = slot->mmc; 1265*f95f3850SWill Newton struct mmc_request *mrq; 1266*f95f3850SWill Newton int present; 1267*f95f3850SWill Newton u32 ctrl; 1268*f95f3850SWill Newton 1269*f95f3850SWill Newton present = dw_mci_get_cd(mmc); 1270*f95f3850SWill Newton while (present != slot->last_detect_state) { 1271*f95f3850SWill Newton spin_lock(&host->lock); 1272*f95f3850SWill Newton 1273*f95f3850SWill Newton dev_dbg(&slot->mmc->class_dev, "card %s\n", 1274*f95f3850SWill Newton present ? "inserted" : "removed"); 1275*f95f3850SWill Newton 1276*f95f3850SWill Newton /* Card change detected */ 1277*f95f3850SWill Newton slot->last_detect_state = present; 1278*f95f3850SWill Newton 1279*f95f3850SWill Newton /* Power up slot */ 1280*f95f3850SWill Newton if (present != 0) { 1281*f95f3850SWill Newton if (host->pdata->setpower) 1282*f95f3850SWill Newton host->pdata->setpower(slot->id, 1283*f95f3850SWill Newton mmc->ocr_avail); 1284*f95f3850SWill Newton 1285*f95f3850SWill Newton set_bit(DW_MMC_CARD_PRESENT, &slot->flags); 1286*f95f3850SWill Newton } 1287*f95f3850SWill Newton 1288*f95f3850SWill Newton /* Clean up queue if present */ 1289*f95f3850SWill Newton mrq = slot->mrq; 1290*f95f3850SWill Newton if (mrq) { 1291*f95f3850SWill Newton if (mrq == host->mrq) { 1292*f95f3850SWill Newton host->data = NULL; 1293*f95f3850SWill Newton host->cmd = NULL; 1294*f95f3850SWill Newton 1295*f95f3850SWill Newton switch (host->state) { 1296*f95f3850SWill Newton case STATE_IDLE: 1297*f95f3850SWill Newton break; 1298*f95f3850SWill Newton case STATE_SENDING_CMD: 1299*f95f3850SWill Newton mrq->cmd->error = -ENOMEDIUM; 1300*f95f3850SWill Newton if (!mrq->data) 1301*f95f3850SWill Newton break; 1302*f95f3850SWill Newton /* fall through */ 1303*f95f3850SWill Newton case STATE_SENDING_DATA: 1304*f95f3850SWill Newton mrq->data->error = -ENOMEDIUM; 1305*f95f3850SWill Newton dw_mci_stop_dma(host); 1306*f95f3850SWill Newton break; 1307*f95f3850SWill Newton case STATE_DATA_BUSY: 1308*f95f3850SWill Newton case STATE_DATA_ERROR: 1309*f95f3850SWill Newton if (mrq->data->error == -EINPROGRESS) 1310*f95f3850SWill Newton mrq->data->error = -ENOMEDIUM; 1311*f95f3850SWill Newton if (!mrq->stop) 1312*f95f3850SWill Newton break; 1313*f95f3850SWill Newton /* fall through */ 1314*f95f3850SWill Newton case STATE_SENDING_STOP: 1315*f95f3850SWill Newton mrq->stop->error = -ENOMEDIUM; 1316*f95f3850SWill Newton break; 1317*f95f3850SWill Newton } 1318*f95f3850SWill Newton 1319*f95f3850SWill Newton dw_mci_request_end(host, mrq); 1320*f95f3850SWill Newton } else { 1321*f95f3850SWill Newton list_del(&slot->queue_node); 1322*f95f3850SWill Newton mrq->cmd->error = -ENOMEDIUM; 1323*f95f3850SWill Newton if (mrq->data) 1324*f95f3850SWill Newton mrq->data->error = -ENOMEDIUM; 1325*f95f3850SWill Newton if (mrq->stop) 1326*f95f3850SWill Newton mrq->stop->error = -ENOMEDIUM; 1327*f95f3850SWill Newton 1328*f95f3850SWill Newton spin_unlock(&host->lock); 1329*f95f3850SWill Newton mmc_request_done(slot->mmc, mrq); 1330*f95f3850SWill Newton spin_lock(&host->lock); 1331*f95f3850SWill Newton } 1332*f95f3850SWill Newton } 1333*f95f3850SWill Newton 1334*f95f3850SWill Newton /* Power down slot */ 1335*f95f3850SWill Newton if (present == 0) { 1336*f95f3850SWill Newton if (host->pdata->setpower) 1337*f95f3850SWill Newton host->pdata->setpower(slot->id, 0); 1338*f95f3850SWill Newton clear_bit(DW_MMC_CARD_PRESENT, &slot->flags); 1339*f95f3850SWill Newton 1340*f95f3850SWill Newton /* 1341*f95f3850SWill Newton * Clear down the FIFO - doing so generates a 1342*f95f3850SWill Newton * block interrupt, hence setting the 1343*f95f3850SWill Newton * scatter-gather pointer to NULL. 1344*f95f3850SWill Newton */ 1345*f95f3850SWill Newton host->sg = NULL; 1346*f95f3850SWill Newton 1347*f95f3850SWill Newton ctrl = mci_readl(host, CTRL); 1348*f95f3850SWill Newton ctrl |= SDMMC_CTRL_FIFO_RESET; 1349*f95f3850SWill Newton mci_writel(host, CTRL, ctrl); 1350*f95f3850SWill Newton 1351*f95f3850SWill Newton #ifdef CONFIG_MMC_DW_IDMAC 1352*f95f3850SWill Newton ctrl = mci_readl(host, BMOD); 1353*f95f3850SWill Newton ctrl |= 0x01; /* Software reset of DMA */ 1354*f95f3850SWill Newton mci_writel(host, BMOD, ctrl); 1355*f95f3850SWill Newton #endif 1356*f95f3850SWill Newton 1357*f95f3850SWill Newton } 1358*f95f3850SWill Newton 1359*f95f3850SWill Newton spin_unlock(&host->lock); 1360*f95f3850SWill Newton present = dw_mci_get_cd(mmc); 1361*f95f3850SWill Newton } 1362*f95f3850SWill Newton 1363*f95f3850SWill Newton mmc_detect_change(slot->mmc, 1364*f95f3850SWill Newton msecs_to_jiffies(host->pdata->detect_delay_ms)); 1365*f95f3850SWill Newton } 1366*f95f3850SWill Newton } 1367*f95f3850SWill Newton 1368*f95f3850SWill Newton static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id) 1369*f95f3850SWill Newton { 1370*f95f3850SWill Newton struct mmc_host *mmc; 1371*f95f3850SWill Newton struct dw_mci_slot *slot; 1372*f95f3850SWill Newton 1373*f95f3850SWill Newton mmc = mmc_alloc_host(sizeof(struct dw_mci_slot), &host->pdev->dev); 1374*f95f3850SWill Newton if (!mmc) 1375*f95f3850SWill Newton return -ENOMEM; 1376*f95f3850SWill Newton 1377*f95f3850SWill Newton slot = mmc_priv(mmc); 1378*f95f3850SWill Newton slot->id = id; 1379*f95f3850SWill Newton slot->mmc = mmc; 1380*f95f3850SWill Newton slot->host = host; 1381*f95f3850SWill Newton 1382*f95f3850SWill Newton mmc->ops = &dw_mci_ops; 1383*f95f3850SWill Newton mmc->f_min = DIV_ROUND_UP(host->bus_hz, 510); 1384*f95f3850SWill Newton mmc->f_max = host->bus_hz; 1385*f95f3850SWill Newton 1386*f95f3850SWill Newton if (host->pdata->get_ocr) 1387*f95f3850SWill Newton mmc->ocr_avail = host->pdata->get_ocr(id); 1388*f95f3850SWill Newton else 1389*f95f3850SWill Newton mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; 1390*f95f3850SWill Newton 1391*f95f3850SWill Newton /* 1392*f95f3850SWill Newton * Start with slot power disabled, it will be enabled when a card 1393*f95f3850SWill Newton * is detected. 1394*f95f3850SWill Newton */ 1395*f95f3850SWill Newton if (host->pdata->setpower) 1396*f95f3850SWill Newton host->pdata->setpower(id, 0); 1397*f95f3850SWill Newton 1398*f95f3850SWill Newton mmc->caps = 0; 1399*f95f3850SWill Newton if (host->pdata->get_bus_wd) 1400*f95f3850SWill Newton if (host->pdata->get_bus_wd(slot->id) >= 4) 1401*f95f3850SWill Newton mmc->caps |= MMC_CAP_4_BIT_DATA; 1402*f95f3850SWill Newton 1403*f95f3850SWill Newton if (host->pdata->quirks & DW_MCI_QUIRK_HIGHSPEED) 1404*f95f3850SWill Newton mmc->caps |= MMC_CAP_SD_HIGHSPEED; 1405*f95f3850SWill Newton 1406*f95f3850SWill Newton #ifdef CONFIG_MMC_DW_IDMAC 1407*f95f3850SWill Newton mmc->max_segs = host->ring_size; 1408*f95f3850SWill Newton mmc->max_blk_size = 65536; 1409*f95f3850SWill Newton mmc->max_blk_count = host->ring_size; 1410*f95f3850SWill Newton mmc->max_seg_size = 0x1000; 1411*f95f3850SWill Newton mmc->max_req_size = mmc->max_seg_size * mmc->max_blk_count; 1412*f95f3850SWill Newton #else 1413*f95f3850SWill Newton if (host->pdata->blk_settings) { 1414*f95f3850SWill Newton mmc->max_segs = host->pdata->blk_settings->max_segs; 1415*f95f3850SWill Newton mmc->max_blk_size = host->pdata->blk_settings->max_blk_size; 1416*f95f3850SWill Newton mmc->max_blk_count = host->pdata->blk_settings->max_blk_count; 1417*f95f3850SWill Newton mmc->max_req_size = host->pdata->blk_settings->max_req_size; 1418*f95f3850SWill Newton mmc->max_seg_size = host->pdata->blk_settings->max_seg_size; 1419*f95f3850SWill Newton } else { 1420*f95f3850SWill Newton /* Useful defaults if platform data is unset. */ 1421*f95f3850SWill Newton mmc->max_segs = 64; 1422*f95f3850SWill Newton mmc->max_blk_size = 65536; /* BLKSIZ is 16 bits */ 1423*f95f3850SWill Newton mmc->max_blk_count = 512; 1424*f95f3850SWill Newton mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; 1425*f95f3850SWill Newton mmc->max_seg_size = mmc->max_req_size; 1426*f95f3850SWill Newton } 1427*f95f3850SWill Newton #endif /* CONFIG_MMC_DW_IDMAC */ 1428*f95f3850SWill Newton 1429*f95f3850SWill Newton if (dw_mci_get_cd(mmc)) 1430*f95f3850SWill Newton set_bit(DW_MMC_CARD_PRESENT, &slot->flags); 1431*f95f3850SWill Newton else 1432*f95f3850SWill Newton clear_bit(DW_MMC_CARD_PRESENT, &slot->flags); 1433*f95f3850SWill Newton 1434*f95f3850SWill Newton host->slot[id] = slot; 1435*f95f3850SWill Newton mmc_add_host(mmc); 1436*f95f3850SWill Newton 1437*f95f3850SWill Newton #if defined(CONFIG_DEBUG_FS) 1438*f95f3850SWill Newton dw_mci_init_debugfs(slot); 1439*f95f3850SWill Newton #endif 1440*f95f3850SWill Newton 1441*f95f3850SWill Newton /* Card initially undetected */ 1442*f95f3850SWill Newton slot->last_detect_state = 0; 1443*f95f3850SWill Newton 1444*f95f3850SWill Newton return 0; 1445*f95f3850SWill Newton } 1446*f95f3850SWill Newton 1447*f95f3850SWill Newton static void dw_mci_cleanup_slot(struct dw_mci_slot *slot, unsigned int id) 1448*f95f3850SWill Newton { 1449*f95f3850SWill Newton /* Shutdown detect IRQ */ 1450*f95f3850SWill Newton if (slot->host->pdata->exit) 1451*f95f3850SWill Newton slot->host->pdata->exit(id); 1452*f95f3850SWill Newton 1453*f95f3850SWill Newton /* Debugfs stuff is cleaned up by mmc core */ 1454*f95f3850SWill Newton mmc_remove_host(slot->mmc); 1455*f95f3850SWill Newton slot->host->slot[id] = NULL; 1456*f95f3850SWill Newton mmc_free_host(slot->mmc); 1457*f95f3850SWill Newton } 1458*f95f3850SWill Newton 1459*f95f3850SWill Newton static void dw_mci_init_dma(struct dw_mci *host) 1460*f95f3850SWill Newton { 1461*f95f3850SWill Newton /* Alloc memory for sg translation */ 1462*f95f3850SWill Newton host->sg_cpu = dma_alloc_coherent(&host->pdev->dev, PAGE_SIZE, 1463*f95f3850SWill Newton &host->sg_dma, GFP_KERNEL); 1464*f95f3850SWill Newton if (!host->sg_cpu) { 1465*f95f3850SWill Newton dev_err(&host->pdev->dev, "%s: could not alloc DMA memory\n", 1466*f95f3850SWill Newton __func__); 1467*f95f3850SWill Newton goto no_dma; 1468*f95f3850SWill Newton } 1469*f95f3850SWill Newton 1470*f95f3850SWill Newton /* Determine which DMA interface to use */ 1471*f95f3850SWill Newton #ifdef CONFIG_MMC_DW_IDMAC 1472*f95f3850SWill Newton host->dma_ops = &dw_mci_idmac_ops; 1473*f95f3850SWill Newton dev_info(&host->pdev->dev, "Using internal DMA controller.\n"); 1474*f95f3850SWill Newton #endif 1475*f95f3850SWill Newton 1476*f95f3850SWill Newton if (!host->dma_ops) 1477*f95f3850SWill Newton goto no_dma; 1478*f95f3850SWill Newton 1479*f95f3850SWill Newton if (host->dma_ops->init) { 1480*f95f3850SWill Newton if (host->dma_ops->init(host)) { 1481*f95f3850SWill Newton dev_err(&host->pdev->dev, "%s: Unable to initialize " 1482*f95f3850SWill Newton "DMA Controller.\n", __func__); 1483*f95f3850SWill Newton goto no_dma; 1484*f95f3850SWill Newton } 1485*f95f3850SWill Newton } else { 1486*f95f3850SWill Newton dev_err(&host->pdev->dev, "DMA initialization not found.\n"); 1487*f95f3850SWill Newton goto no_dma; 1488*f95f3850SWill Newton } 1489*f95f3850SWill Newton 1490*f95f3850SWill Newton host->use_dma = 1; 1491*f95f3850SWill Newton return; 1492*f95f3850SWill Newton 1493*f95f3850SWill Newton no_dma: 1494*f95f3850SWill Newton dev_info(&host->pdev->dev, "Using PIO mode.\n"); 1495*f95f3850SWill Newton host->use_dma = 0; 1496*f95f3850SWill Newton return; 1497*f95f3850SWill Newton } 1498*f95f3850SWill Newton 1499*f95f3850SWill Newton static bool mci_wait_reset(struct device *dev, struct dw_mci *host) 1500*f95f3850SWill Newton { 1501*f95f3850SWill Newton unsigned long timeout = jiffies + msecs_to_jiffies(500); 1502*f95f3850SWill Newton unsigned int ctrl; 1503*f95f3850SWill Newton 1504*f95f3850SWill Newton mci_writel(host, CTRL, (SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET | 1505*f95f3850SWill Newton SDMMC_CTRL_DMA_RESET)); 1506*f95f3850SWill Newton 1507*f95f3850SWill Newton /* wait till resets clear */ 1508*f95f3850SWill Newton do { 1509*f95f3850SWill Newton ctrl = mci_readl(host, CTRL); 1510*f95f3850SWill Newton if (!(ctrl & (SDMMC_CTRL_RESET | SDMMC_CTRL_FIFO_RESET | 1511*f95f3850SWill Newton SDMMC_CTRL_DMA_RESET))) 1512*f95f3850SWill Newton return true; 1513*f95f3850SWill Newton } while (time_before(jiffies, timeout)); 1514*f95f3850SWill Newton 1515*f95f3850SWill Newton dev_err(dev, "Timeout resetting block (ctrl %#x)\n", ctrl); 1516*f95f3850SWill Newton 1517*f95f3850SWill Newton return false; 1518*f95f3850SWill Newton } 1519*f95f3850SWill Newton 1520*f95f3850SWill Newton static int dw_mci_probe(struct platform_device *pdev) 1521*f95f3850SWill Newton { 1522*f95f3850SWill Newton struct dw_mci *host; 1523*f95f3850SWill Newton struct resource *regs; 1524*f95f3850SWill Newton struct dw_mci_board *pdata; 1525*f95f3850SWill Newton int irq, ret, i, width; 1526*f95f3850SWill Newton u32 fifo_size; 1527*f95f3850SWill Newton 1528*f95f3850SWill Newton regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1529*f95f3850SWill Newton if (!regs) 1530*f95f3850SWill Newton return -ENXIO; 1531*f95f3850SWill Newton 1532*f95f3850SWill Newton irq = platform_get_irq(pdev, 0); 1533*f95f3850SWill Newton if (irq < 0) 1534*f95f3850SWill Newton return irq; 1535*f95f3850SWill Newton 1536*f95f3850SWill Newton host = kzalloc(sizeof(struct dw_mci), GFP_KERNEL); 1537*f95f3850SWill Newton if (!host) 1538*f95f3850SWill Newton return -ENOMEM; 1539*f95f3850SWill Newton 1540*f95f3850SWill Newton host->pdev = pdev; 1541*f95f3850SWill Newton host->pdata = pdata = pdev->dev.platform_data; 1542*f95f3850SWill Newton if (!pdata || !pdata->init) { 1543*f95f3850SWill Newton dev_err(&pdev->dev, 1544*f95f3850SWill Newton "Platform data must supply init function\n"); 1545*f95f3850SWill Newton ret = -ENODEV; 1546*f95f3850SWill Newton goto err_freehost; 1547*f95f3850SWill Newton } 1548*f95f3850SWill Newton 1549*f95f3850SWill Newton if (!pdata->select_slot && pdata->num_slots > 1) { 1550*f95f3850SWill Newton dev_err(&pdev->dev, 1551*f95f3850SWill Newton "Platform data must supply select_slot function\n"); 1552*f95f3850SWill Newton ret = -ENODEV; 1553*f95f3850SWill Newton goto err_freehost; 1554*f95f3850SWill Newton } 1555*f95f3850SWill Newton 1556*f95f3850SWill Newton if (!pdata->bus_hz) { 1557*f95f3850SWill Newton dev_err(&pdev->dev, 1558*f95f3850SWill Newton "Platform data must supply bus speed\n"); 1559*f95f3850SWill Newton ret = -ENODEV; 1560*f95f3850SWill Newton goto err_freehost; 1561*f95f3850SWill Newton } 1562*f95f3850SWill Newton 1563*f95f3850SWill Newton host->bus_hz = pdata->bus_hz; 1564*f95f3850SWill Newton host->quirks = pdata->quirks; 1565*f95f3850SWill Newton 1566*f95f3850SWill Newton spin_lock_init(&host->lock); 1567*f95f3850SWill Newton INIT_LIST_HEAD(&host->queue); 1568*f95f3850SWill Newton 1569*f95f3850SWill Newton ret = -ENOMEM; 1570*f95f3850SWill Newton host->regs = ioremap(regs->start, regs->end - regs->start + 1); 1571*f95f3850SWill Newton if (!host->regs) 1572*f95f3850SWill Newton goto err_freehost; 1573*f95f3850SWill Newton 1574*f95f3850SWill Newton host->dma_ops = pdata->dma_ops; 1575*f95f3850SWill Newton dw_mci_init_dma(host); 1576*f95f3850SWill Newton 1577*f95f3850SWill Newton /* 1578*f95f3850SWill Newton * Get the host data width - this assumes that HCON has been set with 1579*f95f3850SWill Newton * the correct values. 1580*f95f3850SWill Newton */ 1581*f95f3850SWill Newton i = (mci_readl(host, HCON) >> 7) & 0x7; 1582*f95f3850SWill Newton if (!i) { 1583*f95f3850SWill Newton host->push_data = dw_mci_push_data16; 1584*f95f3850SWill Newton host->pull_data = dw_mci_pull_data16; 1585*f95f3850SWill Newton width = 16; 1586*f95f3850SWill Newton host->data_shift = 1; 1587*f95f3850SWill Newton } else if (i == 2) { 1588*f95f3850SWill Newton host->push_data = dw_mci_push_data64; 1589*f95f3850SWill Newton host->pull_data = dw_mci_pull_data64; 1590*f95f3850SWill Newton width = 64; 1591*f95f3850SWill Newton host->data_shift = 3; 1592*f95f3850SWill Newton } else { 1593*f95f3850SWill Newton /* Check for a reserved value, and warn if it is */ 1594*f95f3850SWill Newton WARN((i != 1), 1595*f95f3850SWill Newton "HCON reports a reserved host data width!\n" 1596*f95f3850SWill Newton "Defaulting to 32-bit access.\n"); 1597*f95f3850SWill Newton host->push_data = dw_mci_push_data32; 1598*f95f3850SWill Newton host->pull_data = dw_mci_pull_data32; 1599*f95f3850SWill Newton width = 32; 1600*f95f3850SWill Newton host->data_shift = 2; 1601*f95f3850SWill Newton } 1602*f95f3850SWill Newton 1603*f95f3850SWill Newton /* Reset all blocks */ 1604*f95f3850SWill Newton if (!mci_wait_reset(&pdev->dev, host)) { 1605*f95f3850SWill Newton ret = -ENODEV; 1606*f95f3850SWill Newton goto err_dmaunmap; 1607*f95f3850SWill Newton } 1608*f95f3850SWill Newton 1609*f95f3850SWill Newton /* Clear the interrupts for the host controller */ 1610*f95f3850SWill Newton mci_writel(host, RINTSTS, 0xFFFFFFFF); 1611*f95f3850SWill Newton mci_writel(host, INTMASK, 0); /* disable all mmc interrupt first */ 1612*f95f3850SWill Newton 1613*f95f3850SWill Newton /* Put in max timeout */ 1614*f95f3850SWill Newton mci_writel(host, TMOUT, 0xFFFFFFFF); 1615*f95f3850SWill Newton 1616*f95f3850SWill Newton /* 1617*f95f3850SWill Newton * FIFO threshold settings RxMark = fifo_size / 2 - 1, 1618*f95f3850SWill Newton * Tx Mark = fifo_size / 2 DMA Size = 8 1619*f95f3850SWill Newton */ 1620*f95f3850SWill Newton fifo_size = mci_readl(host, FIFOTH); 1621*f95f3850SWill Newton fifo_size = (fifo_size >> 16) & 0x7ff; 1622*f95f3850SWill Newton mci_writel(host, FIFOTH, ((0x2 << 28) | ((fifo_size/2 - 1) << 16) | 1623*f95f3850SWill Newton ((fifo_size/2) << 0))); 1624*f95f3850SWill Newton 1625*f95f3850SWill Newton /* disable clock to CIU */ 1626*f95f3850SWill Newton mci_writel(host, CLKENA, 0); 1627*f95f3850SWill Newton mci_writel(host, CLKSRC, 0); 1628*f95f3850SWill Newton 1629*f95f3850SWill Newton tasklet_init(&host->tasklet, dw_mci_tasklet_func, (unsigned long)host); 1630*f95f3850SWill Newton tasklet_init(&host->card_tasklet, 1631*f95f3850SWill Newton dw_mci_tasklet_card, (unsigned long)host); 1632*f95f3850SWill Newton 1633*f95f3850SWill Newton ret = request_irq(irq, dw_mci_interrupt, 0, "dw-mci", host); 1634*f95f3850SWill Newton if (ret) 1635*f95f3850SWill Newton goto err_dmaunmap; 1636*f95f3850SWill Newton 1637*f95f3850SWill Newton platform_set_drvdata(pdev, host); 1638*f95f3850SWill Newton 1639*f95f3850SWill Newton if (host->pdata->num_slots) 1640*f95f3850SWill Newton host->num_slots = host->pdata->num_slots; 1641*f95f3850SWill Newton else 1642*f95f3850SWill Newton host->num_slots = ((mci_readl(host, HCON) >> 1) & 0x1F) + 1; 1643*f95f3850SWill Newton 1644*f95f3850SWill Newton /* We need at least one slot to succeed */ 1645*f95f3850SWill Newton for (i = 0; i < host->num_slots; i++) { 1646*f95f3850SWill Newton ret = dw_mci_init_slot(host, i); 1647*f95f3850SWill Newton if (ret) { 1648*f95f3850SWill Newton ret = -ENODEV; 1649*f95f3850SWill Newton goto err_init_slot; 1650*f95f3850SWill Newton } 1651*f95f3850SWill Newton } 1652*f95f3850SWill Newton 1653*f95f3850SWill Newton /* 1654*f95f3850SWill Newton * Enable interrupts for command done, data over, data empty, card det, 1655*f95f3850SWill Newton * receive ready and error such as transmit, receive timeout, crc error 1656*f95f3850SWill Newton */ 1657*f95f3850SWill Newton mci_writel(host, RINTSTS, 0xFFFFFFFF); 1658*f95f3850SWill Newton mci_writel(host, INTMASK, SDMMC_INT_CMD_DONE | SDMMC_INT_DATA_OVER | 1659*f95f3850SWill Newton SDMMC_INT_TXDR | SDMMC_INT_RXDR | 1660*f95f3850SWill Newton DW_MCI_ERROR_FLAGS | SDMMC_INT_CD); 1661*f95f3850SWill Newton mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); /* Enable mci interrupt */ 1662*f95f3850SWill Newton 1663*f95f3850SWill Newton dev_info(&pdev->dev, "DW MMC controller at irq %d, " 1664*f95f3850SWill Newton "%d bit host data width\n", irq, width); 1665*f95f3850SWill Newton if (host->quirks & DW_MCI_QUIRK_IDMAC_DTO) 1666*f95f3850SWill Newton dev_info(&pdev->dev, "Internal DMAC interrupt fix enabled.\n"); 1667*f95f3850SWill Newton 1668*f95f3850SWill Newton return 0; 1669*f95f3850SWill Newton 1670*f95f3850SWill Newton err_init_slot: 1671*f95f3850SWill Newton /* De-init any initialized slots */ 1672*f95f3850SWill Newton while (i > 0) { 1673*f95f3850SWill Newton if (host->slot[i]) 1674*f95f3850SWill Newton dw_mci_cleanup_slot(host->slot[i], i); 1675*f95f3850SWill Newton i--; 1676*f95f3850SWill Newton } 1677*f95f3850SWill Newton free_irq(irq, host); 1678*f95f3850SWill Newton 1679*f95f3850SWill Newton err_dmaunmap: 1680*f95f3850SWill Newton if (host->use_dma && host->dma_ops->exit) 1681*f95f3850SWill Newton host->dma_ops->exit(host); 1682*f95f3850SWill Newton dma_free_coherent(&host->pdev->dev, PAGE_SIZE, 1683*f95f3850SWill Newton host->sg_cpu, host->sg_dma); 1684*f95f3850SWill Newton iounmap(host->regs); 1685*f95f3850SWill Newton 1686*f95f3850SWill Newton err_freehost: 1687*f95f3850SWill Newton kfree(host); 1688*f95f3850SWill Newton return ret; 1689*f95f3850SWill Newton } 1690*f95f3850SWill Newton 1691*f95f3850SWill Newton static int __exit dw_mci_remove(struct platform_device *pdev) 1692*f95f3850SWill Newton { 1693*f95f3850SWill Newton struct dw_mci *host = platform_get_drvdata(pdev); 1694*f95f3850SWill Newton int i; 1695*f95f3850SWill Newton 1696*f95f3850SWill Newton mci_writel(host, RINTSTS, 0xFFFFFFFF); 1697*f95f3850SWill Newton mci_writel(host, INTMASK, 0); /* disable all mmc interrupt first */ 1698*f95f3850SWill Newton 1699*f95f3850SWill Newton platform_set_drvdata(pdev, NULL); 1700*f95f3850SWill Newton 1701*f95f3850SWill Newton for (i = 0; i < host->num_slots; i++) { 1702*f95f3850SWill Newton dev_dbg(&pdev->dev, "remove slot %d\n", i); 1703*f95f3850SWill Newton if (host->slot[i]) 1704*f95f3850SWill Newton dw_mci_cleanup_slot(host->slot[i], i); 1705*f95f3850SWill Newton } 1706*f95f3850SWill Newton 1707*f95f3850SWill Newton /* disable clock to CIU */ 1708*f95f3850SWill Newton mci_writel(host, CLKENA, 0); 1709*f95f3850SWill Newton mci_writel(host, CLKSRC, 0); 1710*f95f3850SWill Newton 1711*f95f3850SWill Newton free_irq(platform_get_irq(pdev, 0), host); 1712*f95f3850SWill Newton dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); 1713*f95f3850SWill Newton 1714*f95f3850SWill Newton if (host->use_dma && host->dma_ops->exit) 1715*f95f3850SWill Newton host->dma_ops->exit(host); 1716*f95f3850SWill Newton 1717*f95f3850SWill Newton iounmap(host->regs); 1718*f95f3850SWill Newton 1719*f95f3850SWill Newton kfree(host); 1720*f95f3850SWill Newton return 0; 1721*f95f3850SWill Newton } 1722*f95f3850SWill Newton 1723*f95f3850SWill Newton #ifdef CONFIG_PM 1724*f95f3850SWill Newton /* 1725*f95f3850SWill Newton * TODO: we should probably disable the clock to the card in the suspend path. 1726*f95f3850SWill Newton */ 1727*f95f3850SWill Newton static int dw_mci_suspend(struct platform_device *pdev, pm_message_t mesg) 1728*f95f3850SWill Newton { 1729*f95f3850SWill Newton int i, ret; 1730*f95f3850SWill Newton struct dw_mci *host = platform_get_drvdata(pdev); 1731*f95f3850SWill Newton 1732*f95f3850SWill Newton for (i = 0; i < host->num_slots; i++) { 1733*f95f3850SWill Newton struct dw_mci_slot *slot = host->slot[i]; 1734*f95f3850SWill Newton if (!slot) 1735*f95f3850SWill Newton continue; 1736*f95f3850SWill Newton ret = mmc_suspend_host(slot->mmc); 1737*f95f3850SWill Newton if (ret < 0) { 1738*f95f3850SWill Newton while (--i >= 0) { 1739*f95f3850SWill Newton slot = host->slot[i]; 1740*f95f3850SWill Newton if (slot) 1741*f95f3850SWill Newton mmc_resume_host(host->slot[i]->mmc); 1742*f95f3850SWill Newton } 1743*f95f3850SWill Newton return ret; 1744*f95f3850SWill Newton } 1745*f95f3850SWill Newton } 1746*f95f3850SWill Newton 1747*f95f3850SWill Newton return 0; 1748*f95f3850SWill Newton } 1749*f95f3850SWill Newton 1750*f95f3850SWill Newton static int dw_mci_resume(struct platform_device *pdev) 1751*f95f3850SWill Newton { 1752*f95f3850SWill Newton int i, ret; 1753*f95f3850SWill Newton struct dw_mci *host = platform_get_drvdata(pdev); 1754*f95f3850SWill Newton 1755*f95f3850SWill Newton for (i = 0; i < host->num_slots; i++) { 1756*f95f3850SWill Newton struct dw_mci_slot *slot = host->slot[i]; 1757*f95f3850SWill Newton if (!slot) 1758*f95f3850SWill Newton continue; 1759*f95f3850SWill Newton ret = mmc_resume_host(host->slot[i]->mmc); 1760*f95f3850SWill Newton if (ret < 0) 1761*f95f3850SWill Newton return ret; 1762*f95f3850SWill Newton } 1763*f95f3850SWill Newton 1764*f95f3850SWill Newton return 0; 1765*f95f3850SWill Newton } 1766*f95f3850SWill Newton #else 1767*f95f3850SWill Newton #define dw_mci_suspend NULL 1768*f95f3850SWill Newton #define dw_mci_resume NULL 1769*f95f3850SWill Newton #endif /* CONFIG_PM */ 1770*f95f3850SWill Newton 1771*f95f3850SWill Newton static struct platform_driver dw_mci_driver = { 1772*f95f3850SWill Newton .remove = __exit_p(dw_mci_remove), 1773*f95f3850SWill Newton .suspend = dw_mci_suspend, 1774*f95f3850SWill Newton .resume = dw_mci_resume, 1775*f95f3850SWill Newton .driver = { 1776*f95f3850SWill Newton .name = "dw_mmc", 1777*f95f3850SWill Newton }, 1778*f95f3850SWill Newton }; 1779*f95f3850SWill Newton 1780*f95f3850SWill Newton static int __init dw_mci_init(void) 1781*f95f3850SWill Newton { 1782*f95f3850SWill Newton return platform_driver_probe(&dw_mci_driver, dw_mci_probe); 1783*f95f3850SWill Newton } 1784*f95f3850SWill Newton 1785*f95f3850SWill Newton static void __exit dw_mci_exit(void) 1786*f95f3850SWill Newton { 1787*f95f3850SWill Newton platform_driver_unregister(&dw_mci_driver); 1788*f95f3850SWill Newton } 1789*f95f3850SWill Newton 1790*f95f3850SWill Newton module_init(dw_mci_init); 1791*f95f3850SWill Newton module_exit(dw_mci_exit); 1792*f95f3850SWill Newton 1793*f95f3850SWill Newton MODULE_DESCRIPTION("DW Multimedia Card Interface driver"); 1794*f95f3850SWill Newton MODULE_AUTHOR("NXP Semiconductor VietNam"); 1795*f95f3850SWill Newton MODULE_AUTHOR("Imagination Technologies Ltd"); 1796*f95f3850SWill Newton MODULE_LICENSE("GPL v2"); 1797