blob: 91dc60cd032b37b676226f508d87329b6af065ae [file] [log] [blame]
Andrew Victor65dbf342006-04-02 19:18:51 +01001/*
Pierre Ossman70f10482007-07-11 20:04:50 +02002 * linux/drivers/mmc/host/at91_mci.c - ATMEL AT91 MCI Driver
Andrew Victor65dbf342006-04-02 19:18:51 +01003 *
4 * Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved
5 *
6 * Copyright (C) 2006 Malcolm Noyes
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13/*
Andrew Victor99eeb8d2006-12-11 12:40:23 +010014 This is the AT91 MCI driver that has been tested with both MMC cards
Andrew Victor65dbf342006-04-02 19:18:51 +010015 and SD-cards. Boards that support write protect are now supported.
16 The CCAT91SBC001 board does not support SD cards.
17
18 The three entry points are at91_mci_request, at91_mci_set_ios
19 and at91_mci_get_ro.
20
21 SET IOS
22 This configures the device to put it into the correct mode and clock speed
23 required.
24
25 MCI REQUEST
26 MCI request processes the commands sent in the mmc_request structure. This
27 can consist of a processing command and a stop command in the case of
28 multiple block transfers.
29
30 There are three main types of request, commands, reads and writes.
31
32 Commands are straight forward. The command is submitted to the controller and
33 the request function returns. When the controller generates an interrupt to indicate
34 the command is finished, the response to the command are read and the mmc_request_done
35 function called to end the request.
36
37 Reads and writes work in a similar manner to normal commands but involve the PDC (DMA)
38 controller to manage the transfers.
39
40 A read is done from the controller directly to the scatterlist passed in from the request.
Andrew Victor99eeb8d2006-12-11 12:40:23 +010041 Due to a bug in the AT91RM9200 controller, when a read is completed, all the words are byte
42 swapped in the scatterlist buffers. AT91SAM926x are not affected by this bug.
Andrew Victor65dbf342006-04-02 19:18:51 +010043
44 The sequence of read interrupts is: ENDRX, RXBUFF, CMDRDY
45
46 A write is slightly different in that the bytes to write are read from the scatterlist
47 into a dma memory buffer (this is in case the source buffer should be read only). The
48 entire write buffer is then done from this single dma memory buffer.
49
50 The sequence of write interrupts is: ENDTX, TXBUFE, NOTBUSY, CMDRDY
51
52 GET RO
53 Gets the status of the write protect pin, if available.
54*/
55
Andrew Victor65dbf342006-04-02 19:18:51 +010056#include <linux/module.h>
57#include <linux/moduleparam.h>
58#include <linux/init.h>
59#include <linux/ioport.h>
60#include <linux/platform_device.h>
61#include <linux/interrupt.h>
62#include <linux/blkdev.h>
63#include <linux/delay.h>
64#include <linux/err.h>
65#include <linux/dma-mapping.h>
66#include <linux/clk.h>
Andrew Victor93a3ddc2007-02-08 11:31:22 +010067#include <linux/atmel_pdc.h>
Andrew Victor65dbf342006-04-02 19:18:51 +010068
69#include <linux/mmc/host.h>
Andrew Victor65dbf342006-04-02 19:18:51 +010070
71#include <asm/io.h>
72#include <asm/irq.h>
David Brownell6e996ee2008-02-04 18:12:48 +010073#include <asm/gpio.h>
74
Russell Kinga09e64f2008-08-05 16:14:15 +010075#include <mach/board.h>
76#include <mach/cpu.h>
77#include <mach/at91_mci.h>
Andrew Victor65dbf342006-04-02 19:18:51 +010078
79#define DRIVER_NAME "at91_mci"
80
Nicolas Ferre5b27a1a2010-03-05 13:43:44 -080081static inline int at91mci_is_mci1rev2xx(void)
82{
83 return ( cpu_is_at91sam9260()
84 || cpu_is_at91sam9263()
85 || cpu_is_at91cap9()
86 || cpu_is_at91sam9rl()
87 || cpu_is_at91sam9g10()
88 || cpu_is_at91sam9g20()
89 );
90}
91
Andrew Victordf05a302006-10-23 14:50:09 +020092#define FL_SENT_COMMAND (1 << 0)
93#define FL_SENT_STOP (1 << 1)
Andrew Victor65dbf342006-04-02 19:18:51 +010094
Andrew Victordf05a302006-10-23 14:50:09 +020095#define AT91_MCI_ERRORS (AT91_MCI_RINDE | AT91_MCI_RDIRE | AT91_MCI_RCRCE \
96 | AT91_MCI_RENDE | AT91_MCI_RTOE | AT91_MCI_DCRCE \
Nicolas Ferre37b758e2007-08-08 12:01:44 +020097 | AT91_MCI_DTOE | AT91_MCI_OVRE | AT91_MCI_UNRE)
Andrew Victor65dbf342006-04-02 19:18:51 +010098
Andrew Victore0b19b82006-10-25 19:42:38 +020099#define at91_mci_read(host, reg) __raw_readl((host)->baseaddr + (reg))
100#define at91_mci_write(host, reg, val) __raw_writel((val), (host)->baseaddr + (reg))
Andrew Victor65dbf342006-04-02 19:18:51 +0100101
Wolfgang Muees3780d902010-03-05 13:43:40 -0800102#define MCI_BLKSIZE 512
103#define MCI_MAXBLKSIZE 4095
104#define MCI_BLKATONCE 256
105#define MCI_BUFSIZE (MCI_BLKSIZE * MCI_BLKATONCE)
Andrew Victor65dbf342006-04-02 19:18:51 +0100106
107/*
108 * Low level type for this driver
109 */
110struct at91mci_host
111{
112 struct mmc_host *mmc;
113 struct mmc_command *cmd;
114 struct mmc_request *request;
115
Andrew Victore0b19b82006-10-25 19:42:38 +0200116 void __iomem *baseaddr;
Andrew Victor17ea0592006-10-23 14:44:40 +0200117 int irq;
Andrew Victore0b19b82006-10-25 19:42:38 +0200118
Andrew Victor65dbf342006-04-02 19:18:51 +0100119 struct at91_mmc_data *board;
120 int present;
121
Andrew Victor3dd3b032006-10-23 14:46:54 +0200122 struct clk *mci_clk;
123
Andrew Victor65dbf342006-04-02 19:18:51 +0100124 /*
125 * Flag indicating when the command has been sent. This is used to
126 * work out whether or not to send the stop
127 */
128 unsigned int flags;
129 /* flag for current bus settings */
130 u32 bus_mode;
131
132 /* DMA buffer used for transmitting */
133 unsigned int* buffer;
134 dma_addr_t physical_address;
135 unsigned int total_length;
136
137 /* Latest in the scatterlist that has been enabled for transfer, but not freed */
138 int in_use_index;
139
140 /* Latest in the scatterlist that has been enabled for transfer */
141 int transfer_index;
Marc Pignate181dce2008-05-30 14:06:32 +0200142
143 /* Timer for timeouts */
144 struct timer_list timer;
Andrew Victor65dbf342006-04-02 19:18:51 +0100145};
146
Marc Pignatc5a89c62008-05-30 14:07:47 +0200147/*
148 * Reset the controller and restore most of the state
149 */
150static void at91_reset_host(struct at91mci_host *host)
151{
152 unsigned long flags;
153 u32 mr;
154 u32 sdcr;
155 u32 dtor;
156 u32 imr;
157
158 local_irq_save(flags);
159 imr = at91_mci_read(host, AT91_MCI_IMR);
160
161 at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
162
163 /* save current state */
164 mr = at91_mci_read(host, AT91_MCI_MR) & 0x7fff;
165 sdcr = at91_mci_read(host, AT91_MCI_SDCR);
166 dtor = at91_mci_read(host, AT91_MCI_DTOR);
167
168 /* reset the controller */
169 at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST);
170
171 /* restore state */
172 at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN);
173 at91_mci_write(host, AT91_MCI_MR, mr);
174 at91_mci_write(host, AT91_MCI_SDCR, sdcr);
175 at91_mci_write(host, AT91_MCI_DTOR, dtor);
176 at91_mci_write(host, AT91_MCI_IER, imr);
177
178 /* make sure sdio interrupts will fire */
179 at91_mci_read(host, AT91_MCI_SR);
180
181 local_irq_restore(flags);
182}
183
Marc Pignate181dce2008-05-30 14:06:32 +0200184static void at91_timeout_timer(unsigned long data)
185{
186 struct at91mci_host *host;
187
188 host = (struct at91mci_host *)data;
189
190 if (host->request) {
191 dev_err(host->mmc->parent, "Timeout waiting end of packet\n");
192
193 if (host->cmd && host->cmd->data) {
194 host->cmd->data->error = -ETIMEDOUT;
195 } else {
196 if (host->cmd)
197 host->cmd->error = -ETIMEDOUT;
198 else
199 host->request->cmd->error = -ETIMEDOUT;
200 }
201
Marc Pignatc5a89c62008-05-30 14:07:47 +0200202 at91_reset_host(host);
Marc Pignate181dce2008-05-30 14:06:32 +0200203 mmc_request_done(host->mmc, host->request);
204 }
205}
206
Andrew Victor65dbf342006-04-02 19:18:51 +0100207/*
208 * Copy from sg to a dma block - used for transfers
209 */
Nicolas Ferree8d04d32007-06-19 18:32:34 +0200210static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data *data)
Andrew Victor65dbf342006-04-02 19:18:51 +0100211{
212 unsigned int len, i, size;
213 unsigned *dmabuf = host->buffer;
214
Ville Syrjala5385edc2008-06-14 20:27:20 +0300215 size = data->blksz * data->blocks;
Andrew Victor65dbf342006-04-02 19:18:51 +0100216 len = data->sg_len;
217
Nicolas Ferre5b27a1a2010-03-05 13:43:44 -0800218 /* MCI1 rev2xx Data Write Operation and number of bytes erratum */
219 if (at91mci_is_mci1rev2xx())
Ville Syrjala5385edc2008-06-14 20:27:20 +0300220 if (host->total_length == 12)
221 memset(dmabuf, 0, 12);
222
Andrew Victor65dbf342006-04-02 19:18:51 +0100223 /*
224 * Just loop through all entries. Size might not
225 * be the entire list though so make sure that
226 * we do not transfer too much.
227 */
228 for (i = 0; i < len; i++) {
229 struct scatterlist *sg;
230 int amount;
Andrew Victor65dbf342006-04-02 19:18:51 +0100231 unsigned int *sgbuffer;
232
233 sg = &data->sg[i];
234
Jens Axboe45711f12007-10-22 21:19:53 +0200235 sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
Andrew Victor65dbf342006-04-02 19:18:51 +0100236 amount = min(size, sg->length);
237 size -= amount;
Andrew Victor65dbf342006-04-02 19:18:51 +0100238
Andrew Victor99eeb8d2006-12-11 12:40:23 +0100239 if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */
240 int index;
241
242 for (index = 0; index < (amount / 4); index++)
243 *dmabuf++ = swab32(sgbuffer[index]);
Ville Syrjala5385edc2008-06-14 20:27:20 +0300244 } else {
Wolfgang Muees0b3520f2010-03-05 13:43:38 -0800245 char *tmpv = (char *)dmabuf;
246 memcpy(tmpv, sgbuffer, amount);
247 tmpv += amount;
248 dmabuf = (unsigned *)tmpv;
Ville Syrjala5385edc2008-06-14 20:27:20 +0300249 }
Andrew Victor65dbf342006-04-02 19:18:51 +0100250
Nicolas Ferre752993e2010-03-05 13:43:45 -0800251 kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
Andrew Victor65dbf342006-04-02 19:18:51 +0100252
253 if (size == 0)
254 break;
255 }
256
257 /*
258 * Check that we didn't get a request to transfer
259 * more data than can fit into the SG list.
260 */
261 BUG_ON(size != 0);
262}
263
264/*
Andrew Victor65dbf342006-04-02 19:18:51 +0100265 * Handle after a dma read
266 */
Nicolas Ferree8d04d32007-06-19 18:32:34 +0200267static void at91_mci_post_dma_read(struct at91mci_host *host)
Andrew Victor65dbf342006-04-02 19:18:51 +0100268{
269 struct mmc_command *cmd;
270 struct mmc_data *data;
Wolfgang Muees86ee26f2010-03-05 13:43:41 -0800271 unsigned int len, i, size;
272 unsigned *dmabuf = host->buffer;
Andrew Victor65dbf342006-04-02 19:18:51 +0100273
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100274 pr_debug("post dma read\n");
Andrew Victor65dbf342006-04-02 19:18:51 +0100275
276 cmd = host->cmd;
277 if (!cmd) {
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100278 pr_debug("no command\n");
Andrew Victor65dbf342006-04-02 19:18:51 +0100279 return;
280 }
281
282 data = cmd->data;
283 if (!data) {
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100284 pr_debug("no data\n");
Andrew Victor65dbf342006-04-02 19:18:51 +0100285 return;
286 }
287
Wolfgang Muees86ee26f2010-03-05 13:43:41 -0800288 size = data->blksz * data->blocks;
289 len = data->sg_len;
290
291 at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_ENDRX);
292 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
293
294 for (i = 0; i < len; i++) {
Andrew Victor65dbf342006-04-02 19:18:51 +0100295 struct scatterlist *sg;
Wolfgang Muees86ee26f2010-03-05 13:43:41 -0800296 int amount;
297 unsigned int *sgbuffer;
Andrew Victor65dbf342006-04-02 19:18:51 +0100298
Wolfgang Muees86ee26f2010-03-05 13:43:41 -0800299 sg = &data->sg[i];
Andrew Victor65dbf342006-04-02 19:18:51 +0100300
Wolfgang Muees86ee26f2010-03-05 13:43:41 -0800301 sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
302 amount = min(size, sg->length);
303 size -= amount;
Andrew Victor65dbf342006-04-02 19:18:51 +0100304
Andrew Victor99eeb8d2006-12-11 12:40:23 +0100305 if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */
306 int index;
Wolfgang Muees86ee26f2010-03-05 13:43:41 -0800307 for (index = 0; index < (amount / 4); index++)
308 sgbuffer[index] = swab32(*dmabuf++);
309 } else {
310 char *tmpv = (char *)dmabuf;
311 memcpy(sgbuffer, tmpv, amount);
312 tmpv += amount;
313 dmabuf = (unsigned *)tmpv;
Andrew Victor65dbf342006-04-02 19:18:51 +0100314 }
Andrew Victor99eeb8d2006-12-11 12:40:23 +0100315
Nicolas Ferre752993e2010-03-05 13:43:45 -0800316 kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
Wolfgang Muees86ee26f2010-03-05 13:43:41 -0800317 dmac_flush_range((void *)sgbuffer, ((void *)sgbuffer) + amount);
318 data->bytes_xfered += amount;
319 if (size == 0)
320 break;
Andrew Victor65dbf342006-04-02 19:18:51 +0100321 }
322
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100323 pr_debug("post dma read done\n");
Andrew Victor65dbf342006-04-02 19:18:51 +0100324}
325
326/*
327 * Handle transmitted data
328 */
329static void at91_mci_handle_transmitted(struct at91mci_host *host)
330{
331 struct mmc_command *cmd;
332 struct mmc_data *data;
333
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100334 pr_debug("Handling the transmit\n");
Andrew Victor65dbf342006-04-02 19:18:51 +0100335
336 /* Disable the transfer */
Andrew Victor93a3ddc2007-02-08 11:31:22 +0100337 at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
Andrew Victor65dbf342006-04-02 19:18:51 +0100338
339 /* Now wait for cmd ready */
Andrew Victore0b19b82006-10-25 19:42:38 +0200340 at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_TXBUFE);
Andrew Victor65dbf342006-04-02 19:18:51 +0100341
342 cmd = host->cmd;
343 if (!cmd) return;
344
345 data = cmd->data;
346 if (!data) return;
347
Pierre Ossmanbe0192a2007-07-24 21:11:47 +0200348 if (cmd->data->blocks > 1) {
Nicolas Ferreed99c542007-07-09 14:58:16 +0200349 pr_debug("multiple write : wait for BLKE...\n");
350 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_BLKE);
351 } else
352 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
Andrew Victor65dbf342006-04-02 19:18:51 +0100353}
354
Nicolas Ferre4ac24a82008-05-30 14:18:57 +0200355/*
356 * Update bytes tranfered count during a write operation
357 */
358static void at91_mci_update_bytes_xfered(struct at91mci_host *host)
359{
360 struct mmc_data *data;
361
362 /* always deal with the effective request (and not the current cmd) */
363
364 if (host->request->cmd && host->request->cmd->error != 0)
365 return;
366
367 if (host->request->data) {
368 data = host->request->data;
369 if (data->flags & MMC_DATA_WRITE) {
370 /* card is in IDLE mode now */
371 pr_debug("-> bytes_xfered %d, total_length = %d\n",
372 data->bytes_xfered, host->total_length);
Ville Syrjala5385edc2008-06-14 20:27:20 +0300373 data->bytes_xfered = data->blksz * data->blocks;
Nicolas Ferre4ac24a82008-05-30 14:18:57 +0200374 }
375 }
376}
377
378
Nicolas Ferreed99c542007-07-09 14:58:16 +0200379/*Handle after command sent ready*/
380static int at91_mci_handle_cmdrdy(struct at91mci_host *host)
381{
382 if (!host->cmd)
383 return 1;
384 else if (!host->cmd->data) {
385 if (host->flags & FL_SENT_STOP) {
386 /*After multi block write, we must wait for NOTBUSY*/
387 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
388 } else return 1;
389 } else if (host->cmd->data->flags & MMC_DATA_WRITE) {
390 /*After sendding multi-block-write command, start DMA transfer*/
Nicolas Ferre4ac24a82008-05-30 14:18:57 +0200391 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_TXBUFE | AT91_MCI_BLKE);
Nicolas Ferreed99c542007-07-09 14:58:16 +0200392 at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
393 }
394
395 /* command not completed, have to wait */
396 return 0;
397}
398
399
Andrew Victor65dbf342006-04-02 19:18:51 +0100400/*
401 * Enable the controller
402 */
Andrew Victore0b19b82006-10-25 19:42:38 +0200403static void at91_mci_enable(struct at91mci_host *host)
Andrew Victor65dbf342006-04-02 19:18:51 +0100404{
Nicolas Ferreed99c542007-07-09 14:58:16 +0200405 unsigned int mr;
406
Andrew Victore0b19b82006-10-25 19:42:38 +0200407 at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN);
Andrew Victorf3a8efa2006-10-23 14:53:20 +0200408 at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
Andrew Victore0b19b82006-10-25 19:42:38 +0200409 at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
Nicolas Ferreed99c542007-07-09 14:58:16 +0200410 mr = AT91_MCI_PDCMODE | 0x34a;
411
Nicolas Ferre5b27a1a2010-03-05 13:43:44 -0800412 if (at91mci_is_mci1rev2xx())
Nicolas Ferreed99c542007-07-09 14:58:16 +0200413 mr |= AT91_MCI_RDPROOF | AT91_MCI_WRPROOF;
414
415 at91_mci_write(host, AT91_MCI_MR, mr);
Andrew Victor99eeb8d2006-12-11 12:40:23 +0100416
417 /* use Slot A or B (only one at same time) */
418 at91_mci_write(host, AT91_MCI_SDCR, host->board->slot_b);
Andrew Victor65dbf342006-04-02 19:18:51 +0100419}
420
421/*
422 * Disable the controller
423 */
Andrew Victore0b19b82006-10-25 19:42:38 +0200424static void at91_mci_disable(struct at91mci_host *host)
Andrew Victor65dbf342006-04-02 19:18:51 +0100425{
Andrew Victore0b19b82006-10-25 19:42:38 +0200426 at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS | AT91_MCI_SWRST);
Andrew Victor65dbf342006-04-02 19:18:51 +0100427}
428
429/*
430 * Send a command
Andrew Victor65dbf342006-04-02 19:18:51 +0100431 */
Nicolas Ferreed99c542007-07-09 14:58:16 +0200432static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command *cmd)
Andrew Victor65dbf342006-04-02 19:18:51 +0100433{
434 unsigned int cmdr, mr;
435 unsigned int block_length;
436 struct mmc_data *data = cmd->data;
437
438 unsigned int blocks;
439 unsigned int ier = 0;
440
441 host->cmd = cmd;
442
Nicolas Ferreed99c542007-07-09 14:58:16 +0200443 /* Needed for leaving busy state before CMD1 */
Andrew Victore0b19b82006-10-25 19:42:38 +0200444 if ((at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_RTOE) && (cmd->opcode == 1)) {
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100445 pr_debug("Clearing timeout\n");
Andrew Victore0b19b82006-10-25 19:42:38 +0200446 at91_mci_write(host, AT91_MCI_ARGR, 0);
447 at91_mci_write(host, AT91_MCI_CMDR, AT91_MCI_OPDCMD);
448 while (!(at91_mci_read(host, AT91_MCI_SR) & AT91_MCI_CMDRDY)) {
Andrew Victor65dbf342006-04-02 19:18:51 +0100449 /* spin */
Andrew Victore0b19b82006-10-25 19:42:38 +0200450 pr_debug("Clearing: SR = %08X\n", at91_mci_read(host, AT91_MCI_SR));
Andrew Victor65dbf342006-04-02 19:18:51 +0100451 }
452 }
Nicolas Ferreed99c542007-07-09 14:58:16 +0200453
Andrew Victor65dbf342006-04-02 19:18:51 +0100454 cmdr = cmd->opcode;
455
456 if (mmc_resp_type(cmd) == MMC_RSP_NONE)
457 cmdr |= AT91_MCI_RSPTYP_NONE;
458 else {
459 /* if a response is expected then allow maximum response latancy */
460 cmdr |= AT91_MCI_MAXLAT;
461 /* set 136 bit response for R2, 48 bit response otherwise */
462 if (mmc_resp_type(cmd) == MMC_RSP_R2)
463 cmdr |= AT91_MCI_RSPTYP_136;
464 else
465 cmdr |= AT91_MCI_RSPTYP_48;
466 }
467
468 if (data) {
Marc Pignat1d4de9e2007-08-09 13:56:29 +0200469
Ville Syrjala9da3cba2008-06-09 22:06:44 +0300470 if (cpu_is_at91rm9200() || cpu_is_at91sam9261()) {
471 if (data->blksz & 0x3) {
472 pr_debug("Unsupported block size\n");
473 cmd->error = -EINVAL;
474 mmc_request_done(host->mmc, host->request);
475 return;
476 }
477 if (data->flags & MMC_DATA_STREAM) {
478 pr_debug("Stream commands not supported\n");
479 cmd->error = -EINVAL;
480 mmc_request_done(host->mmc, host->request);
481 return;
482 }
Marc Pignat1d4de9e2007-08-09 13:56:29 +0200483 }
484
Russell Kinga3fd4a12006-06-04 17:51:15 +0100485 block_length = data->blksz;
Andrew Victor65dbf342006-04-02 19:18:51 +0100486 blocks = data->blocks;
487
488 /* always set data start - also set direction flag for read */
489 if (data->flags & MMC_DATA_READ)
490 cmdr |= (AT91_MCI_TRDIR | AT91_MCI_TRCMD_START);
491 else if (data->flags & MMC_DATA_WRITE)
492 cmdr |= AT91_MCI_TRCMD_START;
493
494 if (data->flags & MMC_DATA_STREAM)
495 cmdr |= AT91_MCI_TRTYP_STREAM;
Pierre Ossmanbe0192a2007-07-24 21:11:47 +0200496 if (data->blocks > 1)
Andrew Victor65dbf342006-04-02 19:18:51 +0100497 cmdr |= AT91_MCI_TRTYP_MULTIPLE;
498 }
499 else {
500 block_length = 0;
501 blocks = 0;
502 }
503
Marc Pignatb6cedb32007-06-06 20:27:59 +0200504 if (host->flags & FL_SENT_STOP)
Andrew Victor65dbf342006-04-02 19:18:51 +0100505 cmdr |= AT91_MCI_TRCMD_STOP;
506
507 if (host->bus_mode == MMC_BUSMODE_OPENDRAIN)
508 cmdr |= AT91_MCI_OPDCMD;
509
510 /*
511 * Set the arguments and send the command
512 */
Andrew Victorf3a8efa2006-10-23 14:53:20 +0200513 pr_debug("Sending command %d as %08X, arg = %08X, blocks = %d, length = %d (MR = %08X)\n",
Andrew Victore0b19b82006-10-25 19:42:38 +0200514 cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(host, AT91_MCI_MR));
Andrew Victor65dbf342006-04-02 19:18:51 +0100515
516 if (!data) {
Andrew Victor93a3ddc2007-02-08 11:31:22 +0100517 at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS | ATMEL_PDC_RXTDIS);
518 at91_mci_write(host, ATMEL_PDC_RPR, 0);
519 at91_mci_write(host, ATMEL_PDC_RCR, 0);
520 at91_mci_write(host, ATMEL_PDC_RNPR, 0);
521 at91_mci_write(host, ATMEL_PDC_RNCR, 0);
522 at91_mci_write(host, ATMEL_PDC_TPR, 0);
523 at91_mci_write(host, ATMEL_PDC_TCR, 0);
524 at91_mci_write(host, ATMEL_PDC_TNPR, 0);
525 at91_mci_write(host, ATMEL_PDC_TNCR, 0);
Nicolas Ferreed99c542007-07-09 14:58:16 +0200526 ier = AT91_MCI_CMDRDY;
527 } else {
528 /* zero block length and PDC mode */
Ville Syrjala12bd2572008-06-09 22:06:45 +0300529 mr = at91_mci_read(host, AT91_MCI_MR) & 0x5fff;
Marc Pignat80f92542008-05-30 14:05:24 +0200530 mr |= (data->blksz & 0x3) ? AT91_MCI_PDCFBYTE : 0;
531 mr |= (block_length << 16);
532 mr |= AT91_MCI_PDCMODE;
533 at91_mci_write(host, AT91_MCI_MR, mr);
Andrew Victor65dbf342006-04-02 19:18:51 +0100534
Ville Syrjala9da3cba2008-06-09 22:06:44 +0300535 if (!(cpu_is_at91rm9200() || cpu_is_at91sam9261()))
Marc Pignatc5a89c62008-05-30 14:07:47 +0200536 at91_mci_write(host, AT91_MCI_BLKR,
537 AT91_MCI_BLKR_BCNT(blocks) |
538 AT91_MCI_BLKR_BLKLEN(block_length));
539
Nicolas Ferreed99c542007-07-09 14:58:16 +0200540 /*
541 * Disable the PDC controller
542 */
543 at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
Andrew Victor65dbf342006-04-02 19:18:51 +0100544
Nicolas Ferreed99c542007-07-09 14:58:16 +0200545 if (cmdr & AT91_MCI_TRCMD_START) {
546 data->bytes_xfered = 0;
547 host->transfer_index = 0;
548 host->in_use_index = 0;
549 if (cmdr & AT91_MCI_TRDIR) {
550 /*
551 * Handle a read
552 */
Nicolas Ferreed99c542007-07-09 14:58:16 +0200553 host->total_length = 0;
Andrew Victor65dbf342006-04-02 19:18:51 +0100554
Wolfgang Muees86ee26f2010-03-05 13:43:41 -0800555 at91_mci_write(host, ATMEL_PDC_RPR, host->physical_address);
556 at91_mci_write(host, ATMEL_PDC_RCR, (data->blksz & 0x3) ?
557 (blocks * block_length) : (blocks * block_length) / 4);
558 at91_mci_write(host, ATMEL_PDC_RNPR, 0);
559 at91_mci_write(host, ATMEL_PDC_RNCR, 0);
560
Nicolas Ferreed99c542007-07-09 14:58:16 +0200561 ier = AT91_MCI_ENDRX /* | AT91_MCI_RXBUFF */;
562 }
563 else {
564 /*
565 * Handle a write
566 */
567 host->total_length = block_length * blocks;
Ville Syrjala5385edc2008-06-14 20:27:20 +0300568 /*
Nicolas Ferre5b27a1a2010-03-05 13:43:44 -0800569 * MCI1 rev2xx Data Write Operation and
Ville Syrjala5385edc2008-06-14 20:27:20 +0300570 * number of bytes erratum
571 */
Nicolas Ferre5b27a1a2010-03-05 13:43:44 -0800572 if (at91mci_is_mci1rev2xx())
Ville Syrjala5385edc2008-06-14 20:27:20 +0300573 if (host->total_length < 12)
574 host->total_length = 12;
David Brownelle385ea62008-09-02 14:35:46 -0700575
Nicolas Ferreed99c542007-07-09 14:58:16 +0200576 at91_mci_sg_to_dma(host, data);
Andrew Victor65dbf342006-04-02 19:18:51 +0100577
Nicolas Ferreed99c542007-07-09 14:58:16 +0200578 pr_debug("Transmitting %d bytes\n", host->total_length);
Andrew Victor65dbf342006-04-02 19:18:51 +0100579
Nicolas Ferreed99c542007-07-09 14:58:16 +0200580 at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
Marc Pignat80f92542008-05-30 14:05:24 +0200581 at91_mci_write(host, ATMEL_PDC_TCR, (data->blksz & 0x3) ?
582 host->total_length : host->total_length / 4);
583
Nicolas Ferreed99c542007-07-09 14:58:16 +0200584 ier = AT91_MCI_CMDRDY;
585 }
Andrew Victor65dbf342006-04-02 19:18:51 +0100586 }
587 }
588
589 /*
590 * Send the command and then enable the PDC - not the other way round as
591 * the data sheet says
592 */
593
Andrew Victore0b19b82006-10-25 19:42:38 +0200594 at91_mci_write(host, AT91_MCI_ARGR, cmd->arg);
595 at91_mci_write(host, AT91_MCI_CMDR, cmdr);
Andrew Victor65dbf342006-04-02 19:18:51 +0100596
597 if (cmdr & AT91_MCI_TRCMD_START) {
598 if (cmdr & AT91_MCI_TRDIR)
Andrew Victor93a3ddc2007-02-08 11:31:22 +0100599 at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);
Andrew Victor65dbf342006-04-02 19:18:51 +0100600 }
Andrew Victor65dbf342006-04-02 19:18:51 +0100601
Nicolas Ferreed99c542007-07-09 14:58:16 +0200602 /* Enable selected interrupts */
Andrew Victordf05a302006-10-23 14:50:09 +0200603 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_ERRORS | ier);
Andrew Victor65dbf342006-04-02 19:18:51 +0100604}
605
606/*
607 * Process the next step in the request
608 */
Nicolas Ferree8d04d32007-06-19 18:32:34 +0200609static void at91_mci_process_next(struct at91mci_host *host)
Andrew Victor65dbf342006-04-02 19:18:51 +0100610{
611 if (!(host->flags & FL_SENT_COMMAND)) {
612 host->flags |= FL_SENT_COMMAND;
Nicolas Ferreed99c542007-07-09 14:58:16 +0200613 at91_mci_send_command(host, host->request->cmd);
Andrew Victor65dbf342006-04-02 19:18:51 +0100614 }
615 else if ((!(host->flags & FL_SENT_STOP)) && host->request->stop) {
616 host->flags |= FL_SENT_STOP;
Nicolas Ferreed99c542007-07-09 14:58:16 +0200617 at91_mci_send_command(host, host->request->stop);
Marc Pignate181dce2008-05-30 14:06:32 +0200618 } else {
619 del_timer(&host->timer);
Marc Pignatc5a89c62008-05-30 14:07:47 +0200620 /* the at91rm9200 mci controller hangs after some transfers,
621 * and the workaround is to reset it after each transfer.
622 */
623 if (cpu_is_at91rm9200())
624 at91_reset_host(host);
Andrew Victor65dbf342006-04-02 19:18:51 +0100625 mmc_request_done(host->mmc, host->request);
Marc Pignate181dce2008-05-30 14:06:32 +0200626 }
Andrew Victor65dbf342006-04-02 19:18:51 +0100627}
628
629/*
630 * Handle a command that has been completed
631 */
Nicolas Ferreba7deee2008-05-30 14:28:45 +0200632static void at91_mci_completed_command(struct at91mci_host *host, unsigned int status)
Andrew Victor65dbf342006-04-02 19:18:51 +0100633{
634 struct mmc_command *cmd = host->cmd;
Nicolas Ferrefa1fe012008-06-10 11:27:29 +0200635 struct mmc_data *data = cmd->data;
Andrew Victor65dbf342006-04-02 19:18:51 +0100636
Eric Benard7a6588b2008-05-30 14:26:05 +0200637 at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
Andrew Victor65dbf342006-04-02 19:18:51 +0100638
Andrew Victore0b19b82006-10-25 19:42:38 +0200639 cmd->resp[0] = at91_mci_read(host, AT91_MCI_RSPR(0));
640 cmd->resp[1] = at91_mci_read(host, AT91_MCI_RSPR(1));
641 cmd->resp[2] = at91_mci_read(host, AT91_MCI_RSPR(2));
642 cmd->resp[3] = at91_mci_read(host, AT91_MCI_RSPR(3));
Andrew Victor65dbf342006-04-02 19:18:51 +0100643
Nicolas Ferreba7deee2008-05-30 14:28:45 +0200644 pr_debug("Status = %08X/%08x [%08X %08X %08X %08X]\n",
645 status, at91_mci_read(host, AT91_MCI_SR),
646 cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
Andrew Victor65dbf342006-04-02 19:18:51 +0100647
Andrew Victor9e3866b2007-10-17 11:53:40 +0200648 if (status & AT91_MCI_ERRORS) {
Marc Pignatb6cedb32007-06-06 20:27:59 +0200649 if ((status & AT91_MCI_RCRCE) && !(mmc_resp_type(cmd) & MMC_RSP_CRC)) {
Pierre Ossman17b04292007-07-22 22:18:46 +0200650 cmd->error = 0;
Andrew Victor65dbf342006-04-02 19:18:51 +0100651 }
652 else {
Nicolas Ferrefa1fe012008-06-10 11:27:29 +0200653 if (status & (AT91_MCI_DTOE | AT91_MCI_DCRCE)) {
654 if (data) {
655 if (status & AT91_MCI_DTOE)
656 data->error = -ETIMEDOUT;
657 else if (status & AT91_MCI_DCRCE)
658 data->error = -EILSEQ;
659 }
660 } else {
661 if (status & AT91_MCI_RTOE)
662 cmd->error = -ETIMEDOUT;
663 else if (status & AT91_MCI_RCRCE)
664 cmd->error = -EILSEQ;
665 else
666 cmd->error = -EIO;
667 }
Andrew Victor65dbf342006-04-02 19:18:51 +0100668
Nicolas Ferrefa1fe012008-06-10 11:27:29 +0200669 pr_debug("Error detected and set to %d/%d (cmd = %d, retries = %d)\n",
670 cmd->error, data ? data->error : 0,
671 cmd->opcode, cmd->retries);
Andrew Victor65dbf342006-04-02 19:18:51 +0100672 }
673 }
674 else
Pierre Ossman17b04292007-07-22 22:18:46 +0200675 cmd->error = 0;
Andrew Victor65dbf342006-04-02 19:18:51 +0100676
Nicolas Ferree8d04d32007-06-19 18:32:34 +0200677 at91_mci_process_next(host);
Andrew Victor65dbf342006-04-02 19:18:51 +0100678}
679
680/*
681 * Handle an MMC request
682 */
683static void at91_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
684{
685 struct at91mci_host *host = mmc_priv(mmc);
686 host->request = mrq;
687 host->flags = 0;
688
Wolfgang Mueesa04ac5b2010-03-05 13:43:39 -0800689 /* more than 1s timeout needed with slow SD cards */
690 mod_timer(&host->timer, jiffies + msecs_to_jiffies(2000));
Marc Pignate181dce2008-05-30 14:06:32 +0200691
Nicolas Ferree8d04d32007-06-19 18:32:34 +0200692 at91_mci_process_next(host);
Andrew Victor65dbf342006-04-02 19:18:51 +0100693}
694
695/*
696 * Set the IOS
697 */
698static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
699{
700 int clkdiv;
701 struct at91mci_host *host = mmc_priv(mmc);
Andrew Victor3dd3b032006-10-23 14:46:54 +0200702 unsigned long at91_master_clock = clk_get_rate(host->mci_clk);
Andrew Victor65dbf342006-04-02 19:18:51 +0100703
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100704 host->bus_mode = ios->bus_mode;
Andrew Victor65dbf342006-04-02 19:18:51 +0100705
706 if (ios->clock == 0) {
707 /* Disable the MCI controller */
Andrew Victore0b19b82006-10-25 19:42:38 +0200708 at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIDIS);
Andrew Victor65dbf342006-04-02 19:18:51 +0100709 clkdiv = 0;
710 }
711 else {
712 /* Enable the MCI controller */
Andrew Victore0b19b82006-10-25 19:42:38 +0200713 at91_mci_write(host, AT91_MCI_CR, AT91_MCI_MCIEN);
Andrew Victor65dbf342006-04-02 19:18:51 +0100714
715 if ((at91_master_clock % (ios->clock * 2)) == 0)
716 clkdiv = ((at91_master_clock / ios->clock) / 2) - 1;
717 else
718 clkdiv = (at91_master_clock / ios->clock) / 2;
719
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100720 pr_debug("clkdiv = %d. mcck = %ld\n", clkdiv,
Andrew Victor65dbf342006-04-02 19:18:51 +0100721 at91_master_clock / (2 * (clkdiv + 1)));
722 }
723 if (ios->bus_width == MMC_BUS_WIDTH_4 && host->board->wire4) {
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100724 pr_debug("MMC: Setting controller bus width to 4\n");
Andrew Victore0b19b82006-10-25 19:42:38 +0200725 at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) | AT91_MCI_SDCBUS);
Andrew Victor65dbf342006-04-02 19:18:51 +0100726 }
727 else {
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100728 pr_debug("MMC: Setting controller bus width to 1\n");
Andrew Victore0b19b82006-10-25 19:42:38 +0200729 at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS);
Andrew Victor65dbf342006-04-02 19:18:51 +0100730 }
731
732 /* Set the clock divider */
Andrew Victore0b19b82006-10-25 19:42:38 +0200733 at91_mci_write(host, AT91_MCI_MR, (at91_mci_read(host, AT91_MCI_MR) & ~AT91_MCI_CLKDIV) | clkdiv);
Andrew Victor65dbf342006-04-02 19:18:51 +0100734
735 /* maybe switch power to the card */
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100736 if (host->board->vcc_pin) {
Andrew Victor65dbf342006-04-02 19:18:51 +0100737 switch (ios->power_mode) {
738 case MMC_POWER_OFF:
David Brownell6e996ee2008-02-04 18:12:48 +0100739 gpio_set_value(host->board->vcc_pin, 0);
Andrew Victor65dbf342006-04-02 19:18:51 +0100740 break;
741 case MMC_POWER_UP:
David Brownell6e996ee2008-02-04 18:12:48 +0100742 gpio_set_value(host->board->vcc_pin, 1);
Andrew Victor65dbf342006-04-02 19:18:51 +0100743 break;
Marc Pignate5c0ef92008-05-09 11:07:07 +0200744 case MMC_POWER_ON:
745 break;
746 default:
747 WARN_ON(1);
Andrew Victor65dbf342006-04-02 19:18:51 +0100748 }
749 }
750}
751
752/*
753 * Handle an interrupt
754 */
David Howells7d12e782006-10-05 14:55:46 +0100755static irqreturn_t at91_mci_irq(int irq, void *devid)
Andrew Victor65dbf342006-04-02 19:18:51 +0100756{
757 struct at91mci_host *host = devid;
758 int completed = 0;
Andrew Victordf05a302006-10-23 14:50:09 +0200759 unsigned int int_status, int_mask;
Andrew Victor65dbf342006-04-02 19:18:51 +0100760
Andrew Victore0b19b82006-10-25 19:42:38 +0200761 int_status = at91_mci_read(host, AT91_MCI_SR);
Andrew Victordf05a302006-10-23 14:50:09 +0200762 int_mask = at91_mci_read(host, AT91_MCI_IMR);
Nicolas Ferre37b758e2007-08-08 12:01:44 +0200763
Andrew Victorf3a8efa2006-10-23 14:53:20 +0200764 pr_debug("MCI irq: status = %08X, %08X, %08X\n", int_status, int_mask,
Andrew Victordf05a302006-10-23 14:50:09 +0200765 int_status & int_mask);
Nicolas Ferre37b758e2007-08-08 12:01:44 +0200766
Andrew Victordf05a302006-10-23 14:50:09 +0200767 int_status = int_status & int_mask;
Andrew Victor65dbf342006-04-02 19:18:51 +0100768
Andrew Victordf05a302006-10-23 14:50:09 +0200769 if (int_status & AT91_MCI_ERRORS) {
Andrew Victor65dbf342006-04-02 19:18:51 +0100770 completed = 1;
Nicolas Ferre37b758e2007-08-08 12:01:44 +0200771
Andrew Victordf05a302006-10-23 14:50:09 +0200772 if (int_status & AT91_MCI_UNRE)
773 pr_debug("MMC: Underrun error\n");
774 if (int_status & AT91_MCI_OVRE)
775 pr_debug("MMC: Overrun error\n");
776 if (int_status & AT91_MCI_DTOE)
777 pr_debug("MMC: Data timeout\n");
778 if (int_status & AT91_MCI_DCRCE)
779 pr_debug("MMC: CRC error in data\n");
780 if (int_status & AT91_MCI_RTOE)
781 pr_debug("MMC: Response timeout\n");
782 if (int_status & AT91_MCI_RENDE)
783 pr_debug("MMC: Response end bit error\n");
784 if (int_status & AT91_MCI_RCRCE)
785 pr_debug("MMC: Response CRC error\n");
786 if (int_status & AT91_MCI_RDIRE)
787 pr_debug("MMC: Response direction error\n");
788 if (int_status & AT91_MCI_RINDE)
789 pr_debug("MMC: Response index error\n");
790 } else {
791 /* Only continue processing if no errors */
Andrew Victor65dbf342006-04-02 19:18:51 +0100792
Andrew Victor65dbf342006-04-02 19:18:51 +0100793 if (int_status & AT91_MCI_TXBUFE) {
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100794 pr_debug("TX buffer empty\n");
Andrew Victor65dbf342006-04-02 19:18:51 +0100795 at91_mci_handle_transmitted(host);
796 }
797
Nicolas Ferreed99c542007-07-09 14:58:16 +0200798 if (int_status & AT91_MCI_ENDRX) {
799 pr_debug("ENDRX\n");
800 at91_mci_post_dma_read(host);
801 }
802
Andrew Victor65dbf342006-04-02 19:18:51 +0100803 if (int_status & AT91_MCI_RXBUFF) {
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100804 pr_debug("RX buffer full\n");
Nicolas Ferreed99c542007-07-09 14:58:16 +0200805 at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
806 at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_RXBUFF | AT91_MCI_ENDRX);
807 completed = 1;
Andrew Victor65dbf342006-04-02 19:18:51 +0100808 }
809
Andrew Victordf05a302006-10-23 14:50:09 +0200810 if (int_status & AT91_MCI_ENDTX)
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100811 pr_debug("Transmit has ended\n");
Andrew Victor65dbf342006-04-02 19:18:51 +0100812
Andrew Victor65dbf342006-04-02 19:18:51 +0100813 if (int_status & AT91_MCI_NOTBUSY) {
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100814 pr_debug("Card is ready\n");
Nicolas Ferre4ac24a82008-05-30 14:18:57 +0200815 at91_mci_update_bytes_xfered(host);
Nicolas Ferreed99c542007-07-09 14:58:16 +0200816 completed = 1;
Andrew Victor65dbf342006-04-02 19:18:51 +0100817 }
818
Andrew Victordf05a302006-10-23 14:50:09 +0200819 if (int_status & AT91_MCI_DTIP)
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100820 pr_debug("Data transfer in progress\n");
Andrew Victor65dbf342006-04-02 19:18:51 +0100821
Nicolas Ferreed99c542007-07-09 14:58:16 +0200822 if (int_status & AT91_MCI_BLKE) {
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100823 pr_debug("Block transfer has ended\n");
Nicolas Ferre4ac24a82008-05-30 14:18:57 +0200824 if (host->request->data && host->request->data->blocks > 1) {
825 /* multi block write : complete multi write
826 * command and send stop */
827 completed = 1;
828 } else {
829 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_NOTBUSY);
830 }
Nicolas Ferreed99c542007-07-09 14:58:16 +0200831 }
Andrew Victor65dbf342006-04-02 19:18:51 +0100832
Eric Benard7a6588b2008-05-30 14:26:05 +0200833 if (int_status & AT91_MCI_SDIOIRQA)
834 mmc_signal_sdio_irq(host->mmc);
835
836 if (int_status & AT91_MCI_SDIOIRQB)
837 mmc_signal_sdio_irq(host->mmc);
838
Andrew Victordf05a302006-10-23 14:50:09 +0200839 if (int_status & AT91_MCI_TXRDY)
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100840 pr_debug("Ready to transmit\n");
Andrew Victor65dbf342006-04-02 19:18:51 +0100841
Andrew Victordf05a302006-10-23 14:50:09 +0200842 if (int_status & AT91_MCI_RXRDY)
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100843 pr_debug("Ready to receive\n");
Andrew Victor65dbf342006-04-02 19:18:51 +0100844
845 if (int_status & AT91_MCI_CMDRDY) {
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100846 pr_debug("Command ready\n");
Nicolas Ferreed99c542007-07-09 14:58:16 +0200847 completed = at91_mci_handle_cmdrdy(host);
Andrew Victor65dbf342006-04-02 19:18:51 +0100848 }
849 }
Andrew Victor65dbf342006-04-02 19:18:51 +0100850
851 if (completed) {
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100852 pr_debug("Completed command\n");
Eric Benard7a6588b2008-05-30 14:26:05 +0200853 at91_mci_write(host, AT91_MCI_IDR, 0xffffffff & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
Nicolas Ferreba7deee2008-05-30 14:28:45 +0200854 at91_mci_completed_command(host, int_status);
Andrew Victordf05a302006-10-23 14:50:09 +0200855 } else
Eric Benard7a6588b2008-05-30 14:26:05 +0200856 at91_mci_write(host, AT91_MCI_IDR, int_status & ~(AT91_MCI_SDIOIRQA | AT91_MCI_SDIOIRQB));
Andrew Victor65dbf342006-04-02 19:18:51 +0100857
858 return IRQ_HANDLED;
859}
860
David Howells7d12e782006-10-05 14:55:46 +0100861static irqreturn_t at91_mmc_det_irq(int irq, void *_host)
Andrew Victor65dbf342006-04-02 19:18:51 +0100862{
863 struct at91mci_host *host = _host;
David Brownell6e996ee2008-02-04 18:12:48 +0100864 int present = !gpio_get_value(irq_to_gpio(irq));
Andrew Victor65dbf342006-04-02 19:18:51 +0100865
866 /*
867 * we expect this irq on both insert and remove,
868 * and use a short delay to debounce.
869 */
870 if (present != host->present) {
871 host->present = present;
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100872 pr_debug("%s: card %s\n", mmc_hostname(host->mmc),
Andrew Victor65dbf342006-04-02 19:18:51 +0100873 present ? "insert" : "remove");
874 if (!present) {
Andrew Victorb44fb7a2006-06-19 13:06:05 +0100875 pr_debug("****** Resetting SD-card bus width ******\n");
Andrew Victor99eeb8d2006-12-11 12:40:23 +0100876 at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS);
Andrew Victor65dbf342006-04-02 19:18:51 +0100877 }
Wolfgang Mueesa04ac5b2010-03-05 13:43:39 -0800878 /* 0.5s needed because of early card detect switch firing */
879 mmc_detect_change(host->mmc, msecs_to_jiffies(500));
Andrew Victor65dbf342006-04-02 19:18:51 +0100880 }
881 return IRQ_HANDLED;
882}
883
David Brownella26b4982006-12-26 14:45:26 -0800884static int at91_mci_get_ro(struct mmc_host *mmc)
Andrew Victor65dbf342006-04-02 19:18:51 +0100885{
Andrew Victor65dbf342006-04-02 19:18:51 +0100886 struct at91mci_host *host = mmc_priv(mmc);
887
Anton Vorontsov08f80bb2008-06-17 18:17:39 +0400888 if (host->board->wp_pin)
889 return !!gpio_get_value(host->board->wp_pin);
890 /*
891 * Board doesn't support read only detection; let the mmc core
892 * decide what to do.
893 */
894 return -ENOSYS;
Andrew Victor65dbf342006-04-02 19:18:51 +0100895}
896
Eric Benard7a6588b2008-05-30 14:26:05 +0200897static void at91_mci_enable_sdio_irq(struct mmc_host *mmc, int enable)
898{
899 struct at91mci_host *host = mmc_priv(mmc);
900
901 pr_debug("%s: sdio_irq %c : %s\n", mmc_hostname(host->mmc),
902 host->board->slot_b ? 'B':'A', enable ? "enable" : "disable");
903 at91_mci_write(host, enable ? AT91_MCI_IER : AT91_MCI_IDR,
904 host->board->slot_b ? AT91_MCI_SDIOIRQB : AT91_MCI_SDIOIRQA);
905
906}
907
David Brownellab7aefd2006-11-12 17:55:30 -0800908static const struct mmc_host_ops at91_mci_ops = {
Andrew Victor65dbf342006-04-02 19:18:51 +0100909 .request = at91_mci_request,
910 .set_ios = at91_mci_set_ios,
911 .get_ro = at91_mci_get_ro,
Eric Benard7a6588b2008-05-30 14:26:05 +0200912 .enable_sdio_irq = at91_mci_enable_sdio_irq,
Andrew Victor65dbf342006-04-02 19:18:51 +0100913};
914
915/*
916 * Probe for the device
917 */
David Brownella26b4982006-12-26 14:45:26 -0800918static int __init at91_mci_probe(struct platform_device *pdev)
Andrew Victor65dbf342006-04-02 19:18:51 +0100919{
920 struct mmc_host *mmc;
921 struct at91mci_host *host;
Andrew Victor17ea0592006-10-23 14:44:40 +0200922 struct resource *res;
Andrew Victor65dbf342006-04-02 19:18:51 +0100923 int ret;
924
Andrew Victor17ea0592006-10-23 14:44:40 +0200925 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
926 if (!res)
927 return -ENXIO;
928
929 if (!request_mem_region(res->start, res->end - res->start + 1, DRIVER_NAME))
930 return -EBUSY;
931
Andrew Victor65dbf342006-04-02 19:18:51 +0100932 mmc = mmc_alloc_host(sizeof(struct at91mci_host), &pdev->dev);
933 if (!mmc) {
David Brownell6e996ee2008-02-04 18:12:48 +0100934 ret = -ENOMEM;
935 dev_dbg(&pdev->dev, "couldn't allocate mmc host\n");
936 goto fail6;
Andrew Victor65dbf342006-04-02 19:18:51 +0100937 }
938
939 mmc->ops = &at91_mci_ops;
940 mmc->f_min = 375000;
941 mmc->f_max = 25000000;
942 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
Nicolas Ferre541e7ef2010-03-05 13:43:43 -0800943 mmc->caps = 0;
Andrew Victor65dbf342006-04-02 19:18:51 +0100944
Wolfgang Muees3780d902010-03-05 13:43:40 -0800945 mmc->max_blk_size = MCI_MAXBLKSIZE;
946 mmc->max_blk_count = MCI_BLKATONCE;
947 mmc->max_req_size = MCI_BUFSIZE;
Wolfgang Muees9af13be2010-03-05 13:43:42 -0800948 mmc->max_phys_segs = MCI_BLKATONCE;
949 mmc->max_hw_segs = MCI_BLKATONCE;
950 mmc->max_seg_size = MCI_BUFSIZE;
Pierre Ossmanfe4a3c72006-11-21 17:54:23 +0100951
Andrew Victor65dbf342006-04-02 19:18:51 +0100952 host = mmc_priv(mmc);
953 host->mmc = mmc;
Andrew Victor65dbf342006-04-02 19:18:51 +0100954 host->bus_mode = 0;
955 host->board = pdev->dev.platform_data;
956 if (host->board->wire4) {
Nicolas Ferre5b27a1a2010-03-05 13:43:44 -0800957 if (at91mci_is_mci1rev2xx())
Nicolas Ferreed99c542007-07-09 14:58:16 +0200958 mmc->caps |= MMC_CAP_4_BIT_DATA;
959 else
David Brownell6e996ee2008-02-04 18:12:48 +0100960 dev_warn(&pdev->dev, "4 wire bus mode not supported"
Nicolas Ferreed99c542007-07-09 14:58:16 +0200961 " - using 1 wire\n");
Andrew Victor65dbf342006-04-02 19:18:51 +0100962 }
963
Wolfgang Muees3780d902010-03-05 13:43:40 -0800964 host->buffer = dma_alloc_coherent(&pdev->dev, MCI_BUFSIZE,
965 &host->physical_address, GFP_KERNEL);
966 if (!host->buffer) {
967 ret = -ENOMEM;
968 dev_err(&pdev->dev, "Can't allocate transmit buffer\n");
969 goto fail5;
970 }
971
Nicolas Ferre541e7ef2010-03-05 13:43:43 -0800972 /* Add SDIO capability when available */
Nicolas Ferre5b27a1a2010-03-05 13:43:44 -0800973 if (at91mci_is_mci1rev2xx()) {
974 /* at91mci MCI1 rev2xx sdio interrupt erratum */
Nicolas Ferre541e7ef2010-03-05 13:43:43 -0800975 if (host->board->wire4 || !host->board->slot_b)
976 mmc->caps |= MMC_CAP_SDIO_IRQ;
977 }
978
Andrew Victor65dbf342006-04-02 19:18:51 +0100979 /*
David Brownell6e996ee2008-02-04 18:12:48 +0100980 * Reserve GPIOs ... board init code makes sure these pins are set
981 * up as GPIOs with the right direction (input, except for vcc)
982 */
983 if (host->board->det_pin) {
984 ret = gpio_request(host->board->det_pin, "mmc_detect");
985 if (ret < 0) {
986 dev_dbg(&pdev->dev, "couldn't claim card detect pin\n");
Wolfgang Muees3780d902010-03-05 13:43:40 -0800987 goto fail4b;
David Brownell6e996ee2008-02-04 18:12:48 +0100988 }
989 }
990 if (host->board->wp_pin) {
991 ret = gpio_request(host->board->wp_pin, "mmc_wp");
992 if (ret < 0) {
993 dev_dbg(&pdev->dev, "couldn't claim wp sense pin\n");
994 goto fail4;
995 }
996 }
997 if (host->board->vcc_pin) {
998 ret = gpio_request(host->board->vcc_pin, "mmc_vcc");
999 if (ret < 0) {
1000 dev_dbg(&pdev->dev, "couldn't claim vcc switch pin\n");
1001 goto fail3;
1002 }
1003 }
1004
1005 /*
Andrew Victor65dbf342006-04-02 19:18:51 +01001006 * Get Clock
1007 */
Andrew Victor3dd3b032006-10-23 14:46:54 +02001008 host->mci_clk = clk_get(&pdev->dev, "mci_clk");
1009 if (IS_ERR(host->mci_clk)) {
David Brownell6e996ee2008-02-04 18:12:48 +01001010 ret = -ENODEV;
1011 dev_dbg(&pdev->dev, "no mci_clk?\n");
1012 goto fail2;
Andrew Victor65dbf342006-04-02 19:18:51 +01001013 }
Andrew Victor65dbf342006-04-02 19:18:51 +01001014
Andrew Victor17ea0592006-10-23 14:44:40 +02001015 /*
1016 * Map I/O region
1017 */
1018 host->baseaddr = ioremap(res->start, res->end - res->start + 1);
1019 if (!host->baseaddr) {
David Brownell6e996ee2008-02-04 18:12:48 +01001020 ret = -ENOMEM;
1021 goto fail1;
Andrew Victor17ea0592006-10-23 14:44:40 +02001022 }
Andrew Victore0b19b82006-10-25 19:42:38 +02001023
1024 /*
1025 * Reset hardware
1026 */
Andrew Victor3dd3b032006-10-23 14:46:54 +02001027 clk_enable(host->mci_clk); /* Enable the peripheral clock */
Andrew Victore0b19b82006-10-25 19:42:38 +02001028 at91_mci_disable(host);
1029 at91_mci_enable(host);
1030
Andrew Victor65dbf342006-04-02 19:18:51 +01001031 /*
1032 * Allocate the MCI interrupt
1033 */
Andrew Victor17ea0592006-10-23 14:44:40 +02001034 host->irq = platform_get_irq(pdev, 0);
David Brownell6e996ee2008-02-04 18:12:48 +01001035 ret = request_irq(host->irq, at91_mci_irq, IRQF_SHARED,
1036 mmc_hostname(mmc), host);
Andrew Victor65dbf342006-04-02 19:18:51 +01001037 if (ret) {
David Brownell6e996ee2008-02-04 18:12:48 +01001038 dev_dbg(&pdev->dev, "request MCI interrupt failed\n");
1039 goto fail0;
Andrew Victor65dbf342006-04-02 19:18:51 +01001040 }
1041
Nicolas Ferre99ba0402008-11-27 17:23:49 +01001042 setup_timer(&host->timer, at91_timeout_timer, (unsigned long)host);
1043
Andrew Victor65dbf342006-04-02 19:18:51 +01001044 platform_set_drvdata(pdev, mmc);
1045
1046 /*
1047 * Add host to MMC layer
1048 */
Marc Pignat63b66432007-07-16 11:07:02 +02001049 if (host->board->det_pin) {
David Brownell6e996ee2008-02-04 18:12:48 +01001050 host->present = !gpio_get_value(host->board->det_pin);
Marc Pignat63b66432007-07-16 11:07:02 +02001051 }
Andrew Victor65dbf342006-04-02 19:18:51 +01001052 else
1053 host->present = -1;
1054
1055 mmc_add_host(mmc);
1056
1057 /*
1058 * monitor card insertion/removal if we can
1059 */
1060 if (host->board->det_pin) {
David Brownell6e996ee2008-02-04 18:12:48 +01001061 ret = request_irq(gpio_to_irq(host->board->det_pin),
1062 at91_mmc_det_irq, 0, mmc_hostname(mmc), host);
Andrew Victor65dbf342006-04-02 19:18:51 +01001063 if (ret)
David Brownell6e996ee2008-02-04 18:12:48 +01001064 dev_warn(&pdev->dev, "request MMC detect irq failed\n");
1065 else
1066 device_init_wakeup(&pdev->dev, 1);
Andrew Victor65dbf342006-04-02 19:18:51 +01001067 }
1068
Andrew Victorf3a8efa2006-10-23 14:53:20 +02001069 pr_debug("Added MCI driver\n");
Andrew Victor65dbf342006-04-02 19:18:51 +01001070
1071 return 0;
David Brownell6e996ee2008-02-04 18:12:48 +01001072
1073fail0:
1074 clk_disable(host->mci_clk);
1075 iounmap(host->baseaddr);
1076fail1:
1077 clk_put(host->mci_clk);
1078fail2:
1079 if (host->board->vcc_pin)
1080 gpio_free(host->board->vcc_pin);
1081fail3:
1082 if (host->board->wp_pin)
1083 gpio_free(host->board->wp_pin);
1084fail4:
1085 if (host->board->det_pin)
1086 gpio_free(host->board->det_pin);
Wolfgang Muees3780d902010-03-05 13:43:40 -08001087fail4b:
1088 if (host->buffer)
1089 dma_free_coherent(&pdev->dev, MCI_BUFSIZE,
1090 host->buffer, host->physical_address);
David Brownell6e996ee2008-02-04 18:12:48 +01001091fail5:
1092 mmc_free_host(mmc);
1093fail6:
1094 release_mem_region(res->start, res->end - res->start + 1);
1095 dev_err(&pdev->dev, "probe failed, err %d\n", ret);
1096 return ret;
Andrew Victor65dbf342006-04-02 19:18:51 +01001097}
1098
1099/*
1100 * Remove a device
1101 */
David Brownella26b4982006-12-26 14:45:26 -08001102static int __exit at91_mci_remove(struct platform_device *pdev)
Andrew Victor65dbf342006-04-02 19:18:51 +01001103{
1104 struct mmc_host *mmc = platform_get_drvdata(pdev);
1105 struct at91mci_host *host;
Andrew Victor17ea0592006-10-23 14:44:40 +02001106 struct resource *res;
Andrew Victor65dbf342006-04-02 19:18:51 +01001107
1108 if (!mmc)
1109 return -1;
1110
1111 host = mmc_priv(mmc);
1112
Wolfgang Muees3780d902010-03-05 13:43:40 -08001113 if (host->buffer)
1114 dma_free_coherent(&pdev->dev, MCI_BUFSIZE,
1115 host->buffer, host->physical_address);
1116
Anti Sulline0cda542007-08-30 16:15:16 +02001117 if (host->board->det_pin) {
David Brownell6e996ee2008-02-04 18:12:48 +01001118 if (device_can_wakeup(&pdev->dev))
1119 free_irq(gpio_to_irq(host->board->det_pin), host);
Marc Pignat63b66432007-07-16 11:07:02 +02001120 device_init_wakeup(&pdev->dev, 0);
David Brownell6e996ee2008-02-04 18:12:48 +01001121 gpio_free(host->board->det_pin);
Andrew Victor65dbf342006-04-02 19:18:51 +01001122 }
1123
Andrew Victore0b19b82006-10-25 19:42:38 +02001124 at91_mci_disable(host);
Marc Pignate181dce2008-05-30 14:06:32 +02001125 del_timer_sync(&host->timer);
Andrew Victor17ea0592006-10-23 14:44:40 +02001126 mmc_remove_host(mmc);
1127 free_irq(host->irq, host);
Andrew Victor65dbf342006-04-02 19:18:51 +01001128
Andrew Victor3dd3b032006-10-23 14:46:54 +02001129 clk_disable(host->mci_clk); /* Disable the peripheral clock */
1130 clk_put(host->mci_clk);
Andrew Victor65dbf342006-04-02 19:18:51 +01001131
David Brownell6e996ee2008-02-04 18:12:48 +01001132 if (host->board->vcc_pin)
1133 gpio_free(host->board->vcc_pin);
1134 if (host->board->wp_pin)
1135 gpio_free(host->board->wp_pin);
1136
Andrew Victor17ea0592006-10-23 14:44:40 +02001137 iounmap(host->baseaddr);
1138 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1139 release_mem_region(res->start, res->end - res->start + 1);
Andrew Victor65dbf342006-04-02 19:18:51 +01001140
Andrew Victor17ea0592006-10-23 14:44:40 +02001141 mmc_free_host(mmc);
1142 platform_set_drvdata(pdev, NULL);
Andrew Victorb44fb7a2006-06-19 13:06:05 +01001143 pr_debug("MCI Removed\n");
Andrew Victor65dbf342006-04-02 19:18:51 +01001144
1145 return 0;
1146}
1147
1148#ifdef CONFIG_PM
1149static int at91_mci_suspend(struct platform_device *pdev, pm_message_t state)
1150{
1151 struct mmc_host *mmc = platform_get_drvdata(pdev);
Marc Pignat63b66432007-07-16 11:07:02 +02001152 struct at91mci_host *host = mmc_priv(mmc);
Andrew Victor65dbf342006-04-02 19:18:51 +01001153 int ret = 0;
1154
Anti Sulline0cda542007-08-30 16:15:16 +02001155 if (host->board->det_pin && device_may_wakeup(&pdev->dev))
Marc Pignat63b66432007-07-16 11:07:02 +02001156 enable_irq_wake(host->board->det_pin);
1157
Andrew Victor65dbf342006-04-02 19:18:51 +01001158 if (mmc)
1159 ret = mmc_suspend_host(mmc, state);
1160
1161 return ret;
1162}
1163
1164static int at91_mci_resume(struct platform_device *pdev)
1165{
1166 struct mmc_host *mmc = platform_get_drvdata(pdev);
Marc Pignat63b66432007-07-16 11:07:02 +02001167 struct at91mci_host *host = mmc_priv(mmc);
Andrew Victor65dbf342006-04-02 19:18:51 +01001168 int ret = 0;
1169
Anti Sulline0cda542007-08-30 16:15:16 +02001170 if (host->board->det_pin && device_may_wakeup(&pdev->dev))
Marc Pignat63b66432007-07-16 11:07:02 +02001171 disable_irq_wake(host->board->det_pin);
1172
Andrew Victor65dbf342006-04-02 19:18:51 +01001173 if (mmc)
1174 ret = mmc_resume_host(mmc);
1175
1176 return ret;
1177}
1178#else
1179#define at91_mci_suspend NULL
1180#define at91_mci_resume NULL
1181#endif
1182
1183static struct platform_driver at91_mci_driver = {
David Brownella26b4982006-12-26 14:45:26 -08001184 .remove = __exit_p(at91_mci_remove),
Andrew Victor65dbf342006-04-02 19:18:51 +01001185 .suspend = at91_mci_suspend,
1186 .resume = at91_mci_resume,
1187 .driver = {
1188 .name = DRIVER_NAME,
1189 .owner = THIS_MODULE,
1190 },
1191};
1192
1193static int __init at91_mci_init(void)
1194{
David Brownella26b4982006-12-26 14:45:26 -08001195 return platform_driver_probe(&at91_mci_driver, at91_mci_probe);
Andrew Victor65dbf342006-04-02 19:18:51 +01001196}
1197
1198static void __exit at91_mci_exit(void)
1199{
1200 platform_driver_unregister(&at91_mci_driver);
1201}
1202
1203module_init(at91_mci_init);
1204module_exit(at91_mci_exit);
1205
1206MODULE_DESCRIPTION("AT91 Multimedia Card Interface driver");
1207MODULE_AUTHOR("Nick Randell");
1208MODULE_LICENSE("GPL");
Kay Sieversbc65c722008-04-15 14:34:28 -07001209MODULE_ALIAS("platform:at91_mci");