diff options
author | Kenji Chen <kenji.chen@intel.com> | 2014-12-30 23:21:54 (GMT) |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-01-12 17:20:40 (GMT) |
commit | 1b2ddb1a72b7143e2bc5ea438e28fb459c7b93cc (patch) | |
tree | 76810b406b662d4165835c5dc40e36dbd27f1c59 | |
parent | 24acf58bf92179a4c4af5844631900561e150c9a (diff) | |
download | depthcharge-firmware-winky-5216.265.B.tar.gz depthcharge-firmware-winky-5216.265.B.tar.xz |
Depthcharge: Enable eMMC HS200 to enhance boot time.firmware-winky-5216.265.B
BRANCH=master
BUG=chrome-os-partner:34675
TEST=Build images run on Chrome OS devices and got ~12% BIOS boot
time enhancement.
Signed-off-by: Kenji Chen <kenji.chen@intel.com>
Change-Id: Ic9b4bdf4a5f933249c394ba58f29409b60bd4b66
Reviewed-on: https://chromium-review.googlesource.com/239332
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Commit-Queue: Kenji Chen <kenji.chen@intel.com>
Tested-by: Kenji Chen <kenji.chen@intel.com>
-rw-r--r-- | src/drivers/storage/mmc.c | 50 | ||||
-rw-r--r-- | src/drivers/storage/mmc.h | 5 | ||||
-rw-r--r-- | src/drivers/storage/sdhci.c | 11 | ||||
-rw-r--r-- | src/drivers/storage/sdhci.h | 18 |
4 files changed, 71 insertions, 13 deletions
diff --git a/src/drivers/storage/mmc.c b/src/drivers/storage/mmc.c index 59befb1..18aeddf 100644 --- a/src/drivers/storage/mmc.c +++ b/src/drivers/storage/mmc.c @@ -491,6 +491,12 @@ static int mmc_switch(MmcMedia *media, uint8_t set, uint8_t index, } +static void mmc_set_bus_width(MmcCtrlr *ctrlr, uint32_t width) +{ + ctrlr->bus_width = width; + ctrlr->set_ios(ctrlr); +} + static int mmc_change_freq(MmcMedia *media) { char cardtype; @@ -507,9 +513,28 @@ static int mmc_change_freq(MmcMedia *media) if (err) return err; - cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0xf; - err = mmc_switch(media, EXT_CSD_CMD_SET_NORMAL, + cardtype = ext_csd[EXT_CSD_CARD_TYPE] & 0x1f; + if (cardtype & MMC_HS_200MHZ) { + /* Switch to 8-bit since HS200 only support 8-bit bus width */ + err = mmc_switch(media, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_BUS_WIDTH, EXT_CSD_BUS_WIDTH_8); + if (err) + return err; + + /* Switch to HS200 */ + err = mmc_switch(media, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_HS_TIMING, 0x2); + if (err) + return err; + + /* Adjust Host Bus Wisth to 8-bit */ + mmc_set_bus_width(media->ctrlr, 8); + media->caps |= EXT_CSD_BUS_WIDTH_8; + } else { + err = mmc_switch(media, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1); + } + if (err) return err; @@ -522,8 +547,11 @@ static int mmc_change_freq(MmcMedia *media) if (!ext_csd[EXT_CSD_HS_TIMING]) return 0; - /* High Speed is set, there are two types: 52MHz and 26MHz */ - if (cardtype & MMC_HS_52MHZ) + /* High Speed is set, there are types: HS200, 52MHz, 26MHz */ + if (cardtype & MMC_HS_200MHZ) + media->caps |= (MMC_MODE_HS_200MHz + | MMC_MODE_HS_52MHz | MMC_MODE_HS); + else if (cardtype & MMC_HS_52MHZ) media->caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; else media->caps |= MMC_MODE_HS; @@ -662,12 +690,6 @@ static void mmc_set_clock(MmcCtrlr *ctrlr, uint32_t clock) ctrlr->set_ios(ctrlr); } -static void mmc_set_bus_width(MmcCtrlr *ctrlr, uint32_t width) -{ - ctrlr->bus_width = width; - ctrlr->set_ios(ctrlr); -} - static uint32_t mmc_calculate_transfer_speed(uint32_t csd0) { uint32_t mult, freq; @@ -875,6 +897,10 @@ static int mmc_startup(MmcMedia *media) clock = MMC_CLOCK_25MHZ; } else { for (width = EXT_CSD_BUS_WIDTH_8; width >= 0; width--) { + /* If HS200 is switched, Bus Width has been 8-bit */ + if (media->caps & MMC_MODE_HS_200MHz) + break; + /* Set the card to use 4 bit*/ err = mmc_switch(media, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH, width); @@ -905,7 +931,9 @@ static int mmc_startup(MmcMedia *media) } if (media->caps & MMC_MODE_HS) { - if (media->caps & MMC_MODE_HS_52MHz) + if (media->caps & MMC_MODE_HS_200MHz) + clock = MMC_CLOCK_200MHZ; + else if (media->caps & MMC_MODE_HS_52MHz) clock = MMC_CLOCK_52MHZ; else clock = MMC_CLOCK_26MHZ; diff --git a/src/drivers/storage/mmc.h b/src/drivers/storage/mmc.h index 477da1e..5ea48ba 100644 --- a/src/drivers/storage/mmc.h +++ b/src/drivers/storage/mmc.h @@ -45,6 +45,7 @@ #define MMC_MODE_HS 0x001 #define MMC_MODE_HS_52MHz 0x010 +#define MMC_MODE_HS_200MHz 0x020 #define MMC_MODE_4BIT 0x100 #define MMC_MODE_8BIT 0x200 #define MMC_MODE_SPI 0x400 @@ -104,6 +105,7 @@ #define MMC_HS_TIMING 0x00000100 #define MMC_HS_52MHZ 0x2 +#define MMC_HS_200MHZ 0x10 #define OCR_BUSY 0x80000000 #define OCR_HCS 0x40000000 @@ -135,6 +137,8 @@ #define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */ #define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */ +#define MMC_VDD_165_195_SHIFT 7 + #define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */ #define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits in EXT_CSD byte addressed by index which are @@ -202,6 +206,7 @@ #define MMC_CLOCK_26MHZ (26000000) #define MMC_CLOCK_50MHZ (50000000) #define MMC_CLOCK_52MHZ (52000000) +#define MMC_CLOCK_200MHZ (200000000) #define MMC_CLOCK_DEFAULT_MHZ (MMC_CLOCK_20MHZ) #define EXT_CSD_SIZE (512) diff --git a/src/drivers/storage/sdhci.c b/src/drivers/storage/sdhci.c index a676c5f..e120745 100644 --- a/src/drivers/storage/sdhci.c +++ b/src/drivers/storage/sdhci.c @@ -373,6 +373,11 @@ static int sdhci_set_clock(SdhciHost *host, unsigned int clock) if (host->set_clock) host->set_clock(host, div); + if (clock == MMC_CLOCK_200MHZ) { + sdhci_writew(host, SDHCI_CTRL_UHS_SDR104 + | SDHCI_CTRL_VDD_180 | SDHCI_CTRL_DRV_TYPE_A + , SDHCI_HOST_CONTROL2); + } clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) << SDHCI_DIVIDER_HI_SHIFT; @@ -471,6 +476,10 @@ static void sdhci_set_ios(MmcCtrlr *mmc_ctrlr) if (mmc_ctrlr->bus_hz != host->clock) sdhci_set_clock(host, mmc_ctrlr->bus_hz); + /* Switch to 1.8 volt for HS200 */ + if (mmc_ctrlr->bus_hz == MMC_CLOCK_200MHZ) + sdhci_set_power(host, MMC_VDD_165_195_SHIFT); + /* Set bus width */ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL); if (mmc_ctrlr->bus_width == 8) { @@ -560,7 +569,7 @@ static int sdhci_pre_init(SdhciHost *host) host->mmc_ctrlr.voltages |= host->voltages; host->mmc_ctrlr.caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | - MMC_MODE_4BIT | MMC_MODE_HC; + MMC_MODE_4BIT | MMC_MODE_HC | MMC_MODE_HS_200MHz; if (caps & SDHCI_CAN_DO_8BIT) host->mmc_ctrlr.caps |= MMC_MODE_8BIT; if (host->host_caps) diff --git a/src/drivers/storage/sdhci.h b/src/drivers/storage/sdhci.h index 1d8816b..f5b7f46 100644 --- a/src/drivers/storage/sdhci.h +++ b/src/drivers/storage/sdhci.h @@ -160,7 +160,23 @@ #define SDHCI_ACMD12_ERR 0x3C -/* 3E-3F reserved */ +#define SDHCI_HOST_CONTROL2 0x3E +#define SDHCI_CTRL_UHS_MASK 0x0007 +#define SDHCI_CTRL_UHS_SDR12 0x0000 +#define SDHCI_CTRL_UHS_SDR25 0x0001 +#define SDHCI_CTRL_UHS_SDR50 0x0002 +#define SDHCI_CTRL_UHS_SDR104 0x0003 +#define SDHCI_CTRL_UHS_DDR50 0x0004 +#define SDHCI_CTRL_HS_SDR200 0x0005 /* reserved value in SDIO spec */ +#define SDHCI_CTRL_VDD_180 0x0008 +#define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 +#define SDHCI_CTRL_DRV_TYPE_B 0x0000 +#define SDHCI_CTRL_DRV_TYPE_A 0x0010 +#define SDHCI_CTRL_DRV_TYPE_C 0x0020 +#define SDHCI_CTRL_DRV_TYPE_D 0x0030 +#define SDHCI_CTRL_EXEC_TUNING 0x0040 +#define SDHCI_CTRL_TUNED_CLK 0x0080 +#define SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000 #define SDHCI_CAPABILITIES 0x40 #define SDHCI_TIMEOUT_CLK_MASK 0x0000003F |