Skip to content

Commit

Permalink
bcm2835-mmc: Add option to disable delays on some writeb calls
Browse files Browse the repository at this point in the history
  • Loading branch information
popcornmix committed May 1, 2015
1 parent 67fd2c5 commit aa6b3e6
Showing 1 changed file with 21 additions and 8 deletions.
29 changes: 21 additions & 8 deletions drivers/mmc/host/bcm2835-mmc.c
Expand Up @@ -240,15 +240,24 @@ static inline void bcm2835_mmc_writew(struct bcm2835_host *host, u16 val, int re

}

static inline void bcm2835_mmc_writeb(struct bcm2835_host *host, u8 val, int reg)
static inline void bcm2835_mmc_writeb(struct bcm2835_host *host, u8 val, int reg, int from)
{
u32 oldval = bcm2835_mmc_readl(host, reg & ~3);
u32 byte_num = reg & 3;
u32 byte_shift = byte_num * 8;
u32 mask = 0xff << byte_shift;
u32 newval = (oldval & ~mask) | (val << byte_shift);

bcm2835_mmc_writel(host, newval, reg & ~3, 1);
if ((reg & ~3) == 0x28) // SDHCI_HOST_CONTROL, SDHCI_POWER_CONTROL, SDHCI_BLOCK_GAP_CONTROL, SDHCI_WAKE_UP_CONTROL
{
WARN_ON(oldval & ((1<<16)|(1<<17)));
}
else if ((reg & ~3) == 0x2C) // SDHCI_CLOCK_CONTROL, SDHCI_TIMEOUT_CONTROL, SDHCI_SOFTWARE_RESET
{
WARN_ON(oldval & ((1<<24)|(1<<25)|(1<<26)));
}

bcm2835_mmc_writel(host, newval, reg & ~3, from + 10);
}


Expand Down Expand Up @@ -333,7 +342,7 @@ static void bcm2835_mmc_reset(struct bcm2835_host *host, u8 mask)
{
unsigned long timeout;

bcm2835_mmc_writeb(host, mask, SDHCI_SOFTWARE_RESET);
bcm2835_mmc_writeb(host, mask, SDHCI_SOFTWARE_RESET, 0);

if (mask & SDHCI_RESET_ALL)
host->clock = 0;
Expand All @@ -347,7 +356,7 @@ static void bcm2835_mmc_reset(struct bcm2835_host *host, u8 mask)
pr_err("%s: Reset 0x%x never completed.\n",
mmc_hostname(host->mmc), (int)mask);
bcm2835_mmc_dumpregs(host);
return;
goto exit;
}
timeout--;
mdelay(1);
Expand All @@ -357,6 +366,9 @@ static void bcm2835_mmc_reset(struct bcm2835_host *host, u8 mask)
host->max_delay = 100-timeout;
pr_warning("Warning: MMC controller hung for %d ms\n", host->max_delay);
}
exit:
if ((mmc_debug & (1<<15)))
bcm2835_mmc_writeb(host, TIMEOUT_VAL, SDHCI_TIMEOUT_CONTROL, 1);
}

static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios);
Expand Down Expand Up @@ -609,9 +621,10 @@ static void bcm2835_mmc_prepare_data(struct bcm2835_host *host, struct mmc_comma

WARN_ON(host->data);

if (!(mmc_debug & (1<<14)))
if (data || (cmd->flags & MMC_RSP_BUSY)) {
count = TIMEOUT_VAL;
bcm2835_mmc_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
bcm2835_mmc_writeb(host, count, SDHCI_TIMEOUT_CONTROL, 1);
}

if (!data)
Expand Down Expand Up @@ -1237,7 +1250,7 @@ static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)

if (host->pwr != SDHCI_POWER_330) {
host->pwr = SDHCI_POWER_330;
bcm2835_mmc_writeb(host, SDHCI_POWER_330 | SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
bcm2835_mmc_writeb(host, SDHCI_POWER_330 | SDHCI_POWER_ON, SDHCI_POWER_CONTROL, 2);
}

ctrl = bcm2835_mmc_readb(host, SDHCI_HOST_CONTROL);
Expand All @@ -1252,7 +1265,7 @@ static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
ctrl &= ~SDHCI_CTRL_HISPD; /* NO_HISPD_BIT */


bcm2835_mmc_writeb(host, ctrl, SDHCI_HOST_CONTROL);
bcm2835_mmc_writeb(host, ctrl, SDHCI_HOST_CONTROL, 3);
/*
* We only need to set Driver Strength if the
* preset value enable is not set.
Expand All @@ -1273,7 +1286,7 @@ static void bcm2835_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)

/* Re-enable SD Clock */
bcm2835_mmc_set_clock(host, host->clock);
bcm2835_mmc_writeb(host, ctrl, SDHCI_HOST_CONTROL);
bcm2835_mmc_writeb(host, ctrl, SDHCI_HOST_CONTROL, 4);

mmiowb();

Expand Down

0 comments on commit aa6b3e6

Please sign in to comment.