veyron: Turn off SD card power in romstage

The only way to reliably reset an SD card in an unknown state is by
power-cycling. Since a kernel may crash and reboot at any point, SD
cards may be left in one of them fancy high-throughput modes that
depthcharge (or, in fact, a newly booting kernel without prior
knowledge) doesn't support, so we need to reset the card on every boot.

This patch adds support to turn off an RK808 regulator completely and
uses that to turn off SD card power rails in early romstage. The time
until configure_sdmmc() in ramstage turns them back on should be more
than enough to drain the power rail for an effective power-cycle.

BRANCH=None
BUG=chrome-os-partner:34289
TEST=Booted a Pinky from SD card, noticed that it works before and
after this patch.

Change-Id: Iaa5f7adaa59da69a964785c5e369ad73c6620224
Signed-off-by: Stefan Reinauer <reinauer@chromium.org>
Original-Commit-Id: 95fba21907f1f3f686cb5a95b993736247db8f96
Original-Change-Id: I904b2d23ca35f765c000f9bee7637044f674eff9
Original-Signed-off-by: Julius Werner <jwerner@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/233713
Original-Reviewed-by: Alexandru Stan <amstan@chromium.org>
Original-Tested-by: Alexandru Stan <amstan@chromium.org>
Original-Reviewed-by: David Hendricks <dhendrix@chromium.org>
Reviewed-on: http://review.coreboot.org/9626
Tested-by: build bot (Jenkins)
Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-by: Marc Jones <marc.jones@se-eng.com>
This commit is contained in:
Julius Werner 2014-12-05 17:29:42 -08:00 committed by Stefan Reinauer
parent 13cee14c9c
commit dbfa9d5e8d
8 changed files with 50 additions and 3 deletions

View File

@ -52,6 +52,7 @@ static void configure_sdmmc(void)
/* use sdmmc0 io, disable JTAG function */ /* use sdmmc0 io, disable JTAG function */
writel(RK_CLRBITS(1 << 12), &rk3288_grf->soc_con0); writel(RK_CLRBITS(1 << 12), &rk3288_grf->soc_con0);
/* Note: these power rail definitions are copied in romstage.c */
rk808_configure_ldo(PMIC_BUS, 4, 3300); /* VCCIO_SD */ rk808_configure_ldo(PMIC_BUS, 4, 3300); /* VCCIO_SD */
rk808_configure_ldo(PMIC_BUS, 5, 3300); /* VCC33_SD */ rk808_configure_ldo(PMIC_BUS, 5, 3300); /* VCC33_SD */

View File

@ -31,6 +31,7 @@
#include <soc/clock.h> #include <soc/clock.h>
#include <soc/pwm.h> #include <soc/pwm.h>
#include <soc/grf.h> #include <soc/grf.h>
#include <soc/rk808.h>
#include <soc/tsadc.h> #include <soc/tsadc.h>
#include <stdlib.h> #include <stdlib.h>
#include <symbols.h> #include <symbols.h>
@ -38,7 +39,7 @@
#include <types.h> #include <types.h>
#include <vendorcode/google/chromeos/chromeos.h> #include <vendorcode/google/chromeos/chromeos.h>
#include "timer.h" #include "board.h"
static void regulate_vdd_log(unsigned int mv) static void regulate_vdd_log(unsigned int mv)
{ {
@ -76,6 +77,12 @@ static void configure_l2ctlr(void)
write_l2ctlr(l2ctlr); write_l2ctlr(l2ctlr);
} }
static void sdmmc_power_off(void)
{
rk808_configure_ldo(PMIC_BUS, 4, 0); /* VCCIO_SD */
rk808_configure_ldo(PMIC_BUS, 5, 0); /* VCC33_SD */
}
void main(void) void main(void)
{ {
#if CONFIG_COLLECT_TIMESTAMPS #if CONFIG_COLLECT_TIMESTAMPS
@ -90,6 +97,9 @@ void main(void)
configure_l2ctlr(); configure_l2ctlr();
tsadc_init(); tsadc_init();
/* Need to power cycle SD card to ensure it is properly reset. */
sdmmc_power_off();
/* vdd_log 1200mv is enough for ddr run 666Mhz */ /* vdd_log 1200mv is enough for ddr run 666Mhz */
regulate_vdd_log(1200); regulate_vdd_log(1200);
#if CONFIG_COLLECT_TIMESTAMPS #if CONFIG_COLLECT_TIMESTAMPS

View File

@ -52,6 +52,7 @@ static void configure_sdmmc(void)
/* use sdmmc0 io, disable JTAG function */ /* use sdmmc0 io, disable JTAG function */
writel(RK_CLRBITS(1 << 12), &rk3288_grf->soc_con0); writel(RK_CLRBITS(1 << 12), &rk3288_grf->soc_con0);
/* Note: these power rail definitions are copied in romstage.c */
rk808_configure_ldo(PMIC_BUS, 4, 3300); /* VCCIO_SD */ rk808_configure_ldo(PMIC_BUS, 4, 3300); /* VCCIO_SD */
rk808_configure_ldo(PMIC_BUS, 5, 3300); /* VCC33_SD */ rk808_configure_ldo(PMIC_BUS, 5, 3300); /* VCC33_SD */

View File

@ -31,6 +31,7 @@
#include <soc/clock.h> #include <soc/clock.h>
#include <soc/pwm.h> #include <soc/pwm.h>
#include <soc/grf.h> #include <soc/grf.h>
#include <soc/rk808.h>
#include <soc/tsadc.h> #include <soc/tsadc.h>
#include <stdlib.h> #include <stdlib.h>
#include <symbols.h> #include <symbols.h>
@ -38,7 +39,7 @@
#include <types.h> #include <types.h>
#include <vendorcode/google/chromeos/chromeos.h> #include <vendorcode/google/chromeos/chromeos.h>
#include "timer.h" #include "board.h"
static void regulate_vdd_log(unsigned int mv) static void regulate_vdd_log(unsigned int mv)
{ {
@ -76,6 +77,12 @@ static void configure_l2ctlr(void)
write_l2ctlr(l2ctlr); write_l2ctlr(l2ctlr);
} }
static void sdmmc_power_off(void)
{
rk808_configure_ldo(PMIC_BUS, 4, 0); /* VCCIO_SD */
rk808_configure_ldo(PMIC_BUS, 5, 0); /* VCC33_SD */
}
void main(void) void main(void)
{ {
#if CONFIG_COLLECT_TIMESTAMPS #if CONFIG_COLLECT_TIMESTAMPS
@ -90,6 +97,9 @@ void main(void)
configure_l2ctlr(); configure_l2ctlr();
tsadc_init(); tsadc_init();
/* Need to power cycle SD card to ensure it is properly reset. */
sdmmc_power_off();
/* vdd_log 1200mv is enough for ddr run 666Mhz */ /* vdd_log 1200mv is enough for ddr run 666Mhz */
regulate_vdd_log(1200); regulate_vdd_log(1200);
#if CONFIG_COLLECT_TIMESTAMPS #if CONFIG_COLLECT_TIMESTAMPS

View File

@ -62,6 +62,7 @@ static void configure_sdmmc(void)
/* use sdmmc0 io, disable JTAG function */ /* use sdmmc0 io, disable JTAG function */
writel(RK_CLRBITS(1 << 12), &rk3288_grf->soc_con0); writel(RK_CLRBITS(1 << 12), &rk3288_grf->soc_con0);
/* Note: these power rail definitions are copied in romstage.c */
switch (board_id()) { switch (board_id()) {
case 0: case 0:
rk808_configure_ldo(PMIC_BUS, 8, 3300); /* VCCIO_SD */ rk808_configure_ldo(PMIC_BUS, 8, 3300); /* VCCIO_SD */

View File

@ -31,6 +31,7 @@
#include <soc/clock.h> #include <soc/clock.h>
#include <soc/pwm.h> #include <soc/pwm.h>
#include <soc/grf.h> #include <soc/grf.h>
#include <soc/rk808.h>
#include <soc/tsadc.h> #include <soc/tsadc.h>
#include <stdlib.h> #include <stdlib.h>
#include <symbols.h> #include <symbols.h>
@ -38,7 +39,7 @@
#include <types.h> #include <types.h>
#include <vendorcode/google/chromeos/chromeos.h> #include <vendorcode/google/chromeos/chromeos.h>
#include "timer.h" #include "board.h"
static void regulate_vdd_log(unsigned int mv) static void regulate_vdd_log(unsigned int mv)
{ {
@ -76,6 +77,20 @@ static void configure_l2ctlr(void)
write_l2ctlr(l2ctlr); write_l2ctlr(l2ctlr);
} }
static void sdmmc_power_off(void)
{
switch (board_id()) {
case 0:
rk808_configure_ldo(PMIC_BUS, 8, 0); /* VCCIO_SD */
gpio_output(GPIO(7, C, 5), 0); /* SD_EN */
break;
default:
rk808_configure_ldo(PMIC_BUS, 4, 0); /* VCCIO_SD */
rk808_configure_ldo(PMIC_BUS, 5, 0); /* VCC33_SD */
break;
}
}
void main(void) void main(void)
{ {
#if CONFIG_COLLECT_TIMESTAMPS #if CONFIG_COLLECT_TIMESTAMPS
@ -90,6 +105,9 @@ void main(void)
configure_l2ctlr(); configure_l2ctlr();
tsadc_init(); tsadc_init();
/* Need to power cycle SD card to ensure it is properly reset. */
sdmmc_power_off();
/* vdd_log 1200mv is enough for ddr run 666Mhz */ /* vdd_log 1200mv is enough for ddr run 666Mhz */
regulate_vdd_log(1200); regulate_vdd_log(1200);
#if CONFIG_COLLECT_TIMESTAMPS #if CONFIG_COLLECT_TIMESTAMPS

View File

@ -49,6 +49,7 @@ romstage-y += gpio.c
romstage-y += spi.c romstage-y += spi.c
romstage-y += media.c romstage-y += media.c
romstage-y += sdram.c romstage-y += sdram.c
romstage-y += rk808.c
romstage-y += pwm.c romstage-y += pwm.c
romstage-y += tsadc.c romstage-y += tsadc.c

View File

@ -53,6 +53,11 @@ void rk808_configure_ldo(uint8_t bus, int ldo, int millivolts)
{ {
uint8_t vsel; uint8_t vsel;
if (!millivolts) {
rk808_clrsetbits(bus, LDO_EN, 1 << (ldo - 1), 0);
return;
}
switch (ldo) { switch (ldo) {
case 1: case 1:
case 2: case 2: