The driver is usable on the newer SAM9 processors so replace all text
references to AT91RM9200 with just AT91.

The controller bug where all the words are byte-swapped is fixed on the
AT91SAM9 processors.  The byte-swapping work-around therefore only needs
to be done if cpu_is_at91rm9200().
[Original patch from Wojtek Kaniewski]

The AT91RM9200 and AT91SAM9260 processors support two MMC/SD slots - the
slot which is connected is now passed via the platform_data and the
correct slot selected in the AT91_MCI_SDCR register.

The driver should not be calling at91_set_gpio_output() since the VCC
pin should have already been configured as an output in the
processor/board setup code.  The driver should call
at91_set_gpio_value().

Signed-off-by: Andrew Victor <andrew@sanpeople.com>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
This commit is contained in:
Andrew Victor 2006-12-11 12:40:23 +01:00 коммит произвёл Pierre Ossman
Родитель a98087cf81
Коммит 99eeb8dfb1
1 изменённых файлов: 24 добавлений и 17 удалений

Просмотреть файл

@ -1,5 +1,5 @@
/*
* linux/drivers/mmc/at91_mci.c - ATMEL AT91RM9200 MCI Driver
* linux/drivers/mmc/at91_mci.c - ATMEL AT91 MCI Driver
*
* Copyright (C) 2005 Cougar Creek Computing Devices Ltd, All Rights Reserved
*
@ -11,7 +11,7 @@
*/
/*
This is the AT91RM9200 MCI driver that has been tested with both MMC cards
This is the AT91 MCI driver that has been tested with both MMC cards
and SD-cards. Boards that support write protect are now supported.
The CCAT91SBC001 board does not support SD cards.
@ -38,8 +38,8 @@
controller to manage the transfers.
A read is done from the controller directly to the scatterlist passed in from the request.
Due to a bug in the controller, when a read is completed, all the words are byte
swapped in the scatterlist buffers.
Due to a bug in the AT91RM9200 controller, when a read is completed, all the words are byte
swapped in the scatterlist buffers. AT91SAM926x are not affected by this bug.
The sequence of read interrupts is: ENDRX, RXBUFF, CMDRDY
@ -72,6 +72,7 @@
#include <asm/irq.h>
#include <asm/mach/mmc.h>
#include <asm/arch/board.h>
#include <asm/arch/cpu.h>
#include <asm/arch/gpio.h>
#include <asm/arch/at91_mci.h>
#include <asm/arch/at91_pdc.h>
@ -147,7 +148,6 @@ static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
for (i = 0; i < len; i++) {
struct scatterlist *sg;
int amount;
int index;
unsigned int *sgbuffer;
sg = &data->sg[i];
@ -155,10 +155,15 @@ static inline void at91mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
sgbuffer = kmap_atomic(sg->page, KM_BIO_SRC_IRQ) + sg->offset;
amount = min(size, sg->length);
size -= amount;
amount /= 4;
for (index = 0; index < amount; index++)
*dmabuf++ = swab32(sgbuffer[index]);
if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */
int index;
for (index = 0; index < (amount / 4); index++)
*dmabuf++ = swab32(sgbuffer[index]);
}
else
memcpy(dmabuf, sgbuffer, amount);
kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
@ -265,8 +270,6 @@ static void at91mci_post_dma_read(struct at91mci_host *host)
while (host->in_use_index < host->transfer_index) {
unsigned int *buffer;
int index;
int len;
struct scatterlist *sg;
@ -284,11 +287,13 @@ static void at91mci_post_dma_read(struct at91mci_host *host)
data->bytes_xfered += sg->length;
len = sg->length / 4;
if (cpu_is_at91rm9200()) { /* AT91RM9200 errata */
int index;
for (index = 0; index < len; index++) {
buffer[index] = swab32(buffer[index]);
for (index = 0; index < (sg->length / 4); index++)
buffer[index] = swab32(buffer[index]);
}
kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
flush_dcache_page(sg->page);
}
@ -339,7 +344,9 @@ static void at91_mci_enable(struct at91mci_host *host)
at91_mci_write(host, AT91_MCI_IDR, 0xffffffff);
at91_mci_write(host, AT91_MCI_DTOR, AT91_MCI_DTOMUL_1M | AT91_MCI_DTOCYC);
at91_mci_write(host, AT91_MCI_MR, AT91_MCI_PDCMODE | 0x34a);
at91_mci_write(host, AT91_MCI_SDCR, 0);
/* use Slot A or B (only one at same time) */
at91_mci_write(host, AT91_MCI_SDCR, host->board->slot_b);
}
/*
@ -637,11 +644,11 @@ static void at91_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
if (host->board->vcc_pin) {
switch (ios->power_mode) {
case MMC_POWER_OFF:
at91_set_gpio_output(host->board->vcc_pin, 0);
at91_set_gpio_value(host->board->vcc_pin, 0);
break;
case MMC_POWER_UP:
case MMC_POWER_ON:
at91_set_gpio_output(host->board->vcc_pin, 1);
at91_set_gpio_value(host->board->vcc_pin, 1);
break;
}
}
@ -754,7 +761,7 @@ static irqreturn_t at91_mmc_det_irq(int irq, void *_host)
present ? "insert" : "remove");
if (!present) {
pr_debug("****** Resetting SD-card bus width ******\n");
at91_mci_write(host, AT91_MCI_SDCR, 0);
at91_mci_write(host, AT91_MCI_SDCR, at91_mci_read(host, AT91_MCI_SDCR) & ~AT91_MCI_SDCBUS);
}
mmc_detect_change(host->mmc, msecs_to_jiffies(100));
}