aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/at91_mci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/at91_mci.c')
-rw-r--r--drivers/mmc/at91_mci.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c
index d500b6b21ea0..08a33c33f6ed 100644
--- a/drivers/mmc/at91_mci.c
+++ b/drivers/mmc/at91_mci.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/mmc/at91_mci.c - ATMEL AT91RM9200 MCI Driver 2 * linux/drivers/mmc/at91_mci.c - ATMEL AT91 MCI Driver
3 * 3 *
4 * Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved 4 * Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved
5 * 5 *
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13/* 13/*
14 This is the AT91RM9200 MCI driver that has been tested with both MMC cards 14 This is the AT91 MCI driver that has been tested with both MMC cards
15 and SD-cards. Boards that support write protect are now supported. 15 and SD-cards. Boards that support write protect are now supported.
16 The CCAT91SBC001 board does not support SD cards. 16 The CCAT91SBC001 board does not support SD cards.
17 17
@@ -38,8 +38,8 @@
38 controller to manage the transfers. 38 controller to manage the transfers.
39 39
40 A read is done from the controller directly to the scatterlist passed in from the request. 40 A read is done from the controller directly to the scatterlist passed in from the request.
41 Due to a bug in the controller, when a read is completed, all the words are byte 41 Due to a bug in the AT91RM9200 controller, when a read is completed, all the words are byte
42 swapped in the scatterlist buffers. 42 swapped in the scatterlist buffers. AT91SAM926x are not affected by this bug.
43 43
44 The sequence of read interrupts is: ENDRX, RXBUFF, CMDRDY 44 The sequence of read interrupts is: ENDRX, RXBUFF, CMDRDY
45 45
@@ -72,6 +72,7 @@
72#include <asm/irq.h> 72#include <asm/irq.h>
73#include <asm/mach/mmc.h> 73#include <asm/mach/mmc.h>
74#include <asm/arch/board.h> 74#include <asm/arch/board.h>
75#include <asm/arch/cpu.h>
75#include <asm/arch/gpio.h> 76#include <asm/arch/gpio.h>
76#include <asm/arch/at91_mci.h> 77#include <asm/arch/at91_mci.h>
77#include <asm/arch/at91_pdc.h> 78#include <asm/arch/at91_pdc.h>
@@ -147,7 +148,6 @@ static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
147 for (i = 0; i < len; i++) { 148 for (i = 0; i < len; i++) {
148 struct scatterlist *sg; 149 struct scatterlist *sg;
149 int amount; 150 int amount;
150 int index;
151 unsigned int *sgbuffer; 151 unsigned int *sgbuffer;
152 152
153 sg = &data->sg[i]; 153 sg = &data->sg[i];
@@ -155,10 +155,15 @@ static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
155 sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset; 155 sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
156 amount = min(size, sg->length); 156 amount = min(size, sg->length);
157 size -= amount; 157 size -= amount;
158 amount /= 4;
159 158
160 for (index = 0; index < amount; index++) 159 if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */
161 *dmabuf++ = swab32(sgbuffer[index]); 160 int index;
161
162 for (index = 0; index < (amount / 4); index++)
163 *dmabuf++ = swab32(sgbuffer[index]);
164 }
165 else
166 memcpy(dmabuf, sgbuffer, amount);
162 167
163 kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); 168 kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
164 169
@@ -265,8 +270,6 @@ static void at91mci_post_dma_read(struct at91mci_host *host)
265 270
266 while (host->in_use_index < host->transfer_index) { 271 while (host->in_use_index < host->transfer_index) {
267 unsigned int *buffer; 272 unsigned int *buffer;
268 int index;
269 int len;
270 273
271 struct scatterlist *sg; 274 struct scatterlist *sg;
272 275
@@ -284,11 +287,13 @@ static void at91mci_post_dma_read(struct at91mci_host *host)
284 287
285 data->bytes_xfered += sg->length; 288 data->bytes_xfered += sg->length;
286 289
287 len = sg->length / 4; 290 if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */
291 int index;
288 292
289 for (index = 0; index < len; index++) { 293 for (index = 0; index < (sg->length / 4); index++)
290 buffer[index] = swab32(buffer[index]); 294 buffer[index] = swab32(buffer[index]);
291 } 295 }
296
292 kunmap_atomic(buffer, KM_BIO_SRC_IRQ); 297 kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
293 flush_dcache_page(sg->page); 298 flush_dcache_page(sg->page);
294 } 299 }
@@ -339,7 +344,9 @@ static void at91_mci_enable(struct at91mci_host *host)
339 at91_mci_write(host, AT91_MCI_IDR, 0xffffffff); 344 at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
340 at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC); 345 at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
341 at91_mci_write(host, AT91_MCI_MR, AT91_MCI_PDCMODE | 0x34a); 346 at91_mci_write(host, AT91_MCI_MR, AT91_MCI_PDCMODE | 0x34a);
342 at91_mci_write(host, AT91_MCI_SDCR, 0); 347
348 /* use Slot A or B (only one at same time) */
349 at91_mci_write(host, AT91_MCI_SDCR, host->board->slot_b);
343} 350}
344 351
345/* 352/*
@@ -637,11 +644,11 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
637 if (host->board->vcc_pin) { 644 if (host->board->vcc_pin) {
638 switch (ios->power_mode) { 645 switch (ios->power_mode) {
639 case MMC_POWER_OFF: 646 case MMC_POWER_OFF:
640 at91_set_gpio_output(host->board->vcc_pin, 0); 647 at91_set_gpio_value(host->board->vcc_pin, 0);
641 break; 648 break;
642 case MMC_POWER_UP: 649 case MMC_POWER_UP:
643 case MMC_POWER_ON: 650 case MMC_POWER_ON:
644 at91_set_gpio_output(host->board->vcc_pin, 1); 651 at91_set_gpio_value(host->board->vcc_pin, 1);
645 break; 652 break;
646 } 653 }
647 } 654 }
@@ -754,7 +761,7 @@ static irqreturn_t at91_mmc_det_irq(int irq, void *_host)
754 present ? "insert" : "remove"); 761 present ? "insert" : "remove");
755 if (!present) { 762 if (!present) {
756 pr_debug("****** Resetting SD-card bus width ******\n"); 763 pr_debug("****** Resetting SD-card bus width ******\n");
757 at91_mci_write(host, AT91_MCI_SDCR, 0); 764 at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS);
758 } 765 }
759 mmc_detect_change(host->mmc, msecs_to_jiffies(100)); 766 mmc_detect_change(host->mmc, msecs_to_jiffies(100));
760 } 767 }