xref: /openbmc/linux/drivers/mmc/host/dw_mmc.c (revision f95f3850)
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