summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaehoon Chung <jh80.chung@samsung.com>2014-05-16 13:59:54 +0900
committerMinkyu Kang <mk7.kang@samsung.com>2014-05-16 14:54:26 +0900
commitd22e3d46a918bde2e6d3bc3f5782548d5ed75358 (patch)
treeb1f31b604bbb1ca8e8cc0c746ec38428d0ed291e
parent8caf46d1890b625aafe9cc16114b3c65842dbb98 (diff)
mmc: support the DDR mode for eMMC
Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Tested-by: Lukasz Majewski <l.majewski@samsung.com> Acked-by: Lukasz Majewski <l.majewski@samsung.com> Signed-off-by: Minkyu Kang <mk7.kang@samsung.com>
-rw-r--r--drivers/mmc/mmc.c16
-rw-r--r--include/mmc.h7
2 files changed, 20 insertions, 3 deletions
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index dd6a6ef57c..08187d5f3e 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -158,6 +158,9 @@ int mmc_set_blocklen(struct mmc *mmc, int len)
{
struct mmc_cmd cmd;
+ if (mmc->card_caps & MMC_MODE_DDR_52MHz)
+ return 0;
+
cmd.cmdidx = MMC_CMD_SET_BLOCKLEN;
cmd.resp_type = MMC_RSP_R1;
cmd.cmdarg = len;
@@ -514,10 +517,13 @@ static int mmc_change_freq(struct mmc *mmc)
return 0;
/* High Speed is set, there are two types: 52MHz and 26MHz */
- if (cardtype & EXT_CSD_CARD_TYPE_52)
+ if (cardtype & EXT_CSD_CARD_TYPE_52) {
+ if (cardtype & EXT_CSD_CARD_TYPE_DDR_52)
+ mmc->card_caps |= MMC_MODE_DDR_52MHz;
mmc->card_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
- else
+ } else {
mmc->card_caps |= MMC_MODE_HS;
+ }
return 0;
}
@@ -1054,6 +1060,8 @@ static int mmc_startup(struct mmc *mmc)
/* An array of possible bus widths in order of preference */
static unsigned ext_csd_bits[] = {
+ EXT_CSD_DDR_BUS_WIDTH_8,
+ EXT_CSD_DDR_BUS_WIDTH_4,
EXT_CSD_BUS_WIDTH_8,
EXT_CSD_BUS_WIDTH_4,
EXT_CSD_BUS_WIDTH_1,
@@ -1061,13 +1069,15 @@ static int mmc_startup(struct mmc *mmc)
/* An array to map CSD bus widths to host cap bits */
static unsigned ext_to_hostcaps[] = {
+ [EXT_CSD_DDR_BUS_WIDTH_4] = MMC_MODE_DDR_52MHz,
+ [EXT_CSD_DDR_BUS_WIDTH_8] = MMC_MODE_DDR_52MHz,
[EXT_CSD_BUS_WIDTH_4] = MMC_MODE_4BIT,
[EXT_CSD_BUS_WIDTH_8] = MMC_MODE_8BIT,
};
/* An array to map chosen bus width to an integer */
static unsigned widths[] = {
- 8, 4, 1,
+ 8, 4, 8, 4, 1,
};
for (idx=0; idx < ARRAY_SIZE(ext_csd_bits); idx++) {
diff --git a/include/mmc.h b/include/mmc.h
index d5a896fbb1..aa2d1ca360 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -38,6 +38,7 @@
#define MMC_MODE_8BIT (1 << 3)
#define MMC_MODE_SPI (1 << 4)
#define MMC_MODE_HC (1 << 5)
+#define MMC_MODE_DDR_52MHz (1 << 6)
#define SD_DATA_4BIT 0x00040000
@@ -169,10 +170,16 @@
#define EXT_CSD_CARD_TYPE_26 (1 << 0) /* Card can run at 26MHz */
#define EXT_CSD_CARD_TYPE_52 (1 << 1) /* Card can run at 52MHz */
+#define EXT_CSD_CARD_TYPE_DDR_1_8V (1 << 2)
+#define EXT_CSD_CARD_TYPE_DDR_1_2V (1 << 3)
+#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
+ | EXT_CSD_CARD_TYPE_DDR_1_2V)
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
+#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
+#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
#define EXT_CSD_BOOT_ACK_ENABLE (1 << 6)
#define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3)