Fix problem with A-Data 2GB microSD card - Revisited
Sean McNeil
sean at mcneil.com
Sun May 11 06:09:54 CEST 2008
Second try. It turns out I was just masking a problem and these
particular cards can't run faster than /5 for f_max:
diff --git a/drivers/mfd/glamo/Kconfig b/drivers/mfd/glamo/Kconfig
index 86a7c40..7317807 100644
--- a/drivers/mfd/glamo/Kconfig
+++ b/drivers/mfd/glamo/Kconfig
@@ -36,6 +36,7 @@ config MFD_GLAMO_SPI_FB
config MFD_GLAMO_MCI
tristate "Glamo S3C SD/MMC Card Interface support"
depends on MFD_GLAMO && MMC
+ select CRC7
help
This selects a driver for the MCI interface found in
the S-Media GLAMO chip, as used in Openmoko
diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c
index 789352d..9eaba86 100644
--- a/drivers/mfd/glamo/glamo-mci.c
+++ b/drivers/mfd/glamo/glamo-mci.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/clk.h>
+#include <linux/crc7.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/host.h>
#include <linux/platform_device.h>
@@ -38,23 +39,6 @@ extern struct glamo_mci_pdata glamo_mci_def_pdata;
static void glamo_mci_send_request(struct mmc_host *mmc);
-unsigned char CRC7(u8 * pu8, int cnt)
-{
- u8 crc = 0;
-
- while (cnt--) {
- int n;
- u8 d = *pu8++;
- for (n = 0; n < 8; n++) {
- crc <<= 1;
- if ((d & 0x80) ^ (crc & 0x80))
- crc ^= 0x09;
- d <<= 1;
- }
- }
- return (crc << 1) | 1;
-}
-
/* these _dly versions account for the dead time rules for reg access */
static u16 readw_dly(u16 __iomem * pu16)
{
@@ -188,15 +172,15 @@ static void glamo_mci_irq(unsigned int irq, struct irq_desc *desc)
writew(GLAMO_IRQ_MMC,
glamo_mci_def_pdata.pglamo->base + GLAMO_REG_IRQ_CLEAR);
- if (status & (GLAMO_STAT1_MMC_RTOUT |
- GLAMO_STAT1_MMC_DTOUT))
+ if (status & GLAMO_STAT1_MMC_DTOUT)
cmd->error = -ETIMEDOUT;
if (status & (GLAMO_STAT1_MMC_BWERR |
GLAMO_STAT1_MMC_BRERR))
cmd->error = -EILSEQ;
if (cmd->error) {
- dev_info(&host->pdev->dev, "Error after cmd: 0x%x\n", status);
- goto done;
+ dev_info(&host->pdev->dev, "Error in irq after cmd: 0x%x\n", status);
+ if (!(status & GLAMO_STAT1_MMC_RB_DRDY))
+ goto done;
}
if (host->pio_active == XFER_READ)
@@ -227,7 +211,7 @@ static int glamo_mci_send_command(struct glamo_mci_host *host,
/* if we can't do it, reject as busy */
if (!(readw_dly(host->base + GLAMO_REG_MMC_RB_STAT1) &
- GLAMO_STAT1_MMC_IDLE)) {
+ GLAMO_STAT1_MMC_IDLE)) {
host->mrq = NULL;
cmd->error = -EBUSY;
mmc_request_done(host->mmc, cmd->mrq);
@@ -240,7 +224,7 @@ static int glamo_mci_send_command(struct glamo_mci_host *host,
u8a[2] = (u8)(cmd->arg >> 16);
u8a[3] = (u8)(cmd->arg >> 8);
u8a[4] = (u8)cmd->arg;
- u8a[5] = CRC7(&u8a[0], 5); /* CRC7 on first 5 bytes of packet */
+ u8a[5] = crc7(0, &u8a[0], 5) | 0x01; /* CRC7 on first 5 bytes of packet */
/* issue the wire-order array including CRC in register order */
writew_dly((u8a[4] << 8) | u8a[5], host->base + GLAMO_REG_MMC_CMD_REG1);
@@ -336,7 +320,7 @@ static int glamo_mci_send_command(struct glamo_mci_host *host,
/* enforce timeout */
if (cmd->data) {
if (cmd->data->timeout_clks)
- writew_dly(cmd->data->timeout_clks >> 4, /* / 16 clks */
+ writew_dly((cmd->data->timeout_clks >> 4) | 1, /* / 16 clks */
host->base + GLAMO_REG_MMC_TIMEOUT);
else
writew_dly(0xfff, host->base + GLAMO_REG_MMC_TIMEOUT);
@@ -468,20 +452,22 @@ static void glamo_mci_send_request(struct mmc_host *mmc)
if (cmd->error) {
dev_info(&host->pdev->dev, "Error after cmd: 0x%x\n", status);
- goto done;
}
- /*
- * mangle the response registers in two different exciting
- * undocumented ways discovered by trial and error
- */
- if (mmc_resp_type(cmd) == MMC_RSP_R2)
- /* grab the response */
- for (n = 0; n < 8; n++) /* super mangle power 1 */
- pu16[n ^ 6] = readw_dly(®_resp[n]);
- else
- for (n = 0; n < 3; n++) /* super mangle power 2 */
- pu16[n] = (readw_dly(®_resp[n]) >> 8) |
- (readw_dly(®_resp[n + 1]) << 8);
+
+ if (status & GLAMO_STAT1_MMC_RB_RRDY) {
+ /*
+ * mangle the response registers in two different exciting
+ * undocumented ways discovered by trial and error
+ */
+ if (mmc_resp_type(cmd) == MMC_RSP_R2)
+ /* grab the response */
+ for (n = 0; n < 8; n++) /* super mangle power 1 */
+ pu16[n ^ 6] = readw_dly(®_resp[n]);
+ else
+ for (n = 0; n < 3; n++) /* super mangle power 2 */
+ pu16[n] = (readw_dly(®_resp[n]) >> 8) |
+ (readw_dly(®_resp[n + 1]) << 8);
+ }
/*
* if we don't have bulk data to take care of, we're done
*/
@@ -753,7 +739,7 @@ static int glamo_mci_probe(struct platform_device *pdev)
* held at /4 due to concerns of 100R recommended series resistor
* allows 16MHz @ 4-bit --> 8MBytes/sec raw
*/
- mmc->f_max = host->clk_rate / 3;
+ mmc->f_max = host->clk_rate / 5;
mmc->max_blk_count = (1 << 16) - 1; /* GLAMO_REG_MMC_RB_BLKCNT */
mmc->max_blk_size = (1 << 12) - 1; /* GLAMO_REG_MMC_RB_BLKLEN */
More information about the openmoko-kernel
mailing list