Skip to content

Commit

Permalink
mmc: sdhci: track whether preset mode is currently enabled in hardware
Browse files Browse the repository at this point in the history
Track whether preset mode is currently enabled in hardware, and use that
when making decisions elsewhere in the code rather than reading the
register and checking the bit.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Tested-by: Markus Pargmann <mpa@pengutronix.de>
Tested-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Chris Ball <chris@printf.net>
  • Loading branch information
Russell King authored and Chris Ball committed May 22, 2014
1 parent 24fbb3c commit da91a8f
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 18 deletions.
44 changes: 26 additions & 18 deletions drivers/mmc/host/sdhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,14 @@ static void sdhci_do_reset(struct sdhci_host *host, u8 mask)

host->ops->reset(host, mask);

if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL))
host->ops->enable_dma(host);
if (mask & SDHCI_RESET_ALL) {
if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
if (host->ops->enable_dma)
host->ops->enable_dma(host);
}

/* Resetting the controller clears many */
host->preset_enabled = false;
}
}

Expand Down Expand Up @@ -1126,8 +1131,7 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
return;

if (host->version >= SDHCI_SPEC_300) {
if (sdhci_readw(host, SDHCI_HOST_CONTROL2) &
SDHCI_CTRL_PRESET_VAL_ENABLE) {
if (host->preset_enabled) {
u16 pre_val;

clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
Expand Down Expand Up @@ -1493,13 +1497,13 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
(ios->timing == MMC_TIMING_UHS_SDR25))
ctrl |= SDHCI_CTRL_HISPD;

ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
if (!host->preset_enabled) {
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
/*
* We only need to set Driver Strength if the
* preset value enable is not set.
*/
ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK;
if (ios->drv_type == MMC_SET_DRIVER_TYPE_A)
ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A;
Expand Down Expand Up @@ -2018,26 +2022,30 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)

static void sdhci_enable_preset_value(struct sdhci_host *host, bool enable)
{
u16 ctrl;

/* Host Controller v3.00 defines preset value registers */
if (host->version < SDHCI_SPEC_300)
return;

ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);

/*
* We only enable or disable Preset Value if they are not already
* enabled or disabled respectively. Otherwise, we bail out.
*/
if (enable && !(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
host->flags |= SDHCI_PV_ENABLED;
} else if (!enable && (ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
if (host->preset_enabled != enable) {
u16 ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);

if (enable)
ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
else
ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;

sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
host->flags &= ~SDHCI_PV_ENABLED;

if (enable)
host->flags |= SDHCI_PV_ENABLED;
else
host->flags &= ~SDHCI_PV_ENABLED;

host->preset_enabled = enable;
}
}

Expand Down
1 change: 1 addition & 0 deletions include/linux/mmc/sdhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ struct sdhci_host {

bool runtime_suspended; /* Host is runtime suspended */
bool bus_on; /* Bus power prevents runtime suspend */
bool preset_enabled; /* Preset is enabled */

struct mmc_request *mrq; /* Current request */
struct mmc_command *cmd; /* Current command */
Expand Down

0 comments on commit da91a8f

Please sign in to comment.