Skip to content

Commit

Permalink
MMC: OMAP: Power functions modified to MMC multislot support
Browse files Browse the repository at this point in the history
Modifications at power functions to MMC multislot support. This patch
also move board-specific code out of MMC OMAP driver.

Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com>
Signed-off-by: Carlos Eduardo Aguiar <carlos.aguiar@indt.org.br>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
  • Loading branch information
Juha Yrjola authored and Pierre Ossman committed Apr 18, 2008
1 parent b8f9f0e commit 65b5b6e
Showing 1 changed file with 37 additions and 51 deletions.
88 changes: 37 additions & 51 deletions drivers/mmc/host/omap.c
Original file line number Diff line number Diff line change
Expand Up @@ -983,52 +983,27 @@ static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req)
mmc_omap_start_request(host, req);
}

static void innovator_fpga_socket_power(int on)
static void mmc_omap_set_power(struct mmc_omap_slot *slot, int power_on,
int vdd)
{
#if defined(CONFIG_MACH_OMAP_INNOVATOR) && defined(CONFIG_ARCH_OMAP15XX)
if (on) {
fpga_write(fpga_read(OMAP1510_FPGA_POWER) | (1 << 3),
OMAP1510_FPGA_POWER);
} else {
fpga_write(fpga_read(OMAP1510_FPGA_POWER) & ~(1 << 3),
OMAP1510_FPGA_POWER);
}
#endif
}
struct mmc_omap_host *host;

/*
* Turn the socket power on/off. Innovator uses FPGA, most boards
* probably use GPIO.
*/
static void mmc_omap_power(struct mmc_omap_host *host, int on)
{
if (on) {
if (machine_is_omap_innovator())
innovator_fpga_socket_power(1);
else if (machine_is_omap_h2())
tps65010_set_gpio_out_value(GPIO3, HIGH);
else if (machine_is_omap_h3())
/* GPIO 4 of TPS65010 sends SD_EN signal */
tps65010_set_gpio_out_value(GPIO4, HIGH);
else if (cpu_is_omap24xx()) {
u16 reg = OMAP_MMC_READ(host, CON);
OMAP_MMC_WRITE(host, CON, reg | (1 << 11));
} else
if (host->power_pin >= 0)
omap_set_gpio_dataout(host->power_pin, 1);
} else {
if (machine_is_omap_innovator())
innovator_fpga_socket_power(0);
else if (machine_is_omap_h2())
tps65010_set_gpio_out_value(GPIO3, LOW);
else if (machine_is_omap_h3())
tps65010_set_gpio_out_value(GPIO4, LOW);
else if (cpu_is_omap24xx()) {
u16 reg = OMAP_MMC_READ(host, CON);
OMAP_MMC_WRITE(host, CON, reg & ~(1 << 11));
} else
if (host->power_pin >= 0)
omap_set_gpio_dataout(host->power_pin, 0);
host = slot->host;

if (slot->pdata->set_power != NULL)
slot->pdata->set_power(mmc_dev(slot->mmc), slot->id, power_on,
vdd);

if (cpu_is_omap24xx()) {
u16 w;

if (power_on) {
w = OMAP_MMC_READ(host, CON);
OMAP_MMC_WRITE(host, CON, w | (1 << 11));
} else {
w = OMAP_MMC_READ(host, CON);
OMAP_MMC_WRITE(host, CON, w & ~(1 << 11));
}
}
}

Expand Down Expand Up @@ -1067,30 +1042,39 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
int i, dsor;

dsor = mmc_omap_calc_divisor(mmc, ios);
host->bus_mode = ios->bus_mode;
host->hw_bus_mode = host->bus_mode;

mmc_omap_select_slot(slot, 0);

if (ios->vdd != slot->vdd)
slot->vdd = ios->vdd;

switch (ios->power_mode) {
case MMC_POWER_OFF:
mmc_omap_power(host, 0);
mmc_omap_set_power(slot, 0, ios->vdd);
break;
case MMC_POWER_UP:
/* Cannot touch dsor yet, just power up MMC */
mmc_omap_power(host, 1);
return;
mmc_omap_set_power(slot, 1, ios->vdd);
goto exit;
case MMC_POWER_ON:
dsor |= 1 << 11;
break;
}

clk_enable(host->fclk);
if (slot->bus_mode != ios->bus_mode) {
if (slot->pdata->set_bus_mode != NULL)
slot->pdata->set_bus_mode(mmc_dev(mmc), slot->id,
ios->bus_mode);
slot->bus_mode = ios->bus_mode;
}

/* On insanely high arm_per frequencies something sometimes
* goes somehow out of sync, and the POW bit is not being set,
* which results in the while loop below getting stuck.
* Writing to the CON register twice seems to do the trick. */
for (i = 0; i < 2; i++)
OMAP_MMC_WRITE(host, CON, dsor);
slot->saved_con = dsor;
if (ios->power_mode == MMC_POWER_ON) {
/* Send clock cycles, poll completion */
OMAP_MMC_WRITE(host, IE, 0);
Expand All @@ -1099,7 +1083,9 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
while ((OMAP_MMC_READ(host, STAT) & 1) == 0);
OMAP_MMC_WRITE(host, STAT, 1);
}
clk_disable(host->fclk);

exit:
mmc_omap_release_slot(slot);
}

static const struct mmc_host_ops mmc_omap_ops = {
Expand Down

0 comments on commit 65b5b6e

Please sign in to comment.