summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Zhu <r65037@freescale.com>2010-07-12 17:31:44 +0800
committerJustin Waters <justin.waters@timesys.com>2010-12-17 12:10:51 -0500
commitbec565eeac7d78aa6ea07a16724fcee0858ac0df (patch)
treeb3685796b2072866a980880e6dff6c6708b30f0e
parent3e6b10acd47ba89d902219f1d3eb352e6e31becc (diff)
ENGR00125052-1 Common codes changes when enable the eMMC44 DDR
The modifications of linux kernel common codes when enable the eMMC44 DDR mode Signed-off-by: Richard Zhu <r65037@freescale.com>
-rw-r--r--drivers/mmc/core/mmc.c25
-rw-r--r--include/linux/mmc/card.h2
-rw-r--r--include/linux/mmc/host.h2
-rw-r--r--include/linux/mmc/mmc.h3
4 files changed, 29 insertions, 3 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index e207dcf9e754..40b3851c3ed7 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -121,7 +121,7 @@ static int mmc_decode_csd(struct mmc_card *card)
* v1.2 has extra information in bits 15, 11 and 10.
*/
csd_struct = UNSTUFF_BITS(resp, 126, 2);
- if (csd_struct != 1 && csd_struct != 2) {
+ if (csd_struct < 1 || csd_struct > 3) {
printk(KERN_ERR "%s: unrecognised CSD structure version %d\n",
mmc_hostname(card->host), csd_struct);
return -EINVAL;
@@ -226,7 +226,13 @@ static int mmc_read_ext_csd(struct mmc_card *card)
mmc_card_set_blockaddr(card);
}
+ card->ext_csd.card_type = ext_csd[EXT_CSD_CARD_TYPE];
+
switch (ext_csd[EXT_CSD_CARD_TYPE]) {
+ case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52
+ | EXT_CSD_CARD_TYPE_26:
+ card->ext_csd.hs_max_dtr = 52000000;
+ break;
case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
card->ext_csd.hs_max_dtr = 52000000;
break;
@@ -238,6 +244,8 @@ static int mmc_read_ext_csd(struct mmc_card *card)
printk(KERN_WARNING "%s: card is mmc v4 but doesn't "
"support any high-speed modes.\n",
mmc_hostname(card->host));
+ printk(KERN_WARNING "%s: card type is 0x%x\n",
+ mmc_hostname(card->host), ext_csd[EXT_CSD_CARD_TYPE]);
goto out;
}
@@ -434,10 +442,21 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
* Activate wide bus (if supported).
*/
if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
- (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) {
+ (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA
+ | MMC_CAP_DATA_DDR))) {
unsigned ext_csd_bit, bus_width;
- if (host->caps & MMC_CAP_8_BIT_DATA) {
+ if ((host->caps & MMC_CAP_8_BIT_DATA) &&
+ (host->caps & MMC_CAP_DATA_DDR) &&
+ (card->ext_csd.card_type & MMC_DDR_MODE_MASK)) {
+ ext_csd_bit = EXT_CSD_BUS_WIDTH_8_DDR;
+ bus_width = MMC_BUS_WIDTH_8 | MMC_BUS_WIDTH_DDR;
+ } else if ((host->caps & MMC_CAP_4_BIT_DATA) &&
+ (host->caps & MMC_CAP_DATA_DDR) &&
+ (card->ext_csd.card_type & MMC_DDR_MODE_MASK)) {
+ ext_csd_bit = EXT_CSD_BUS_WIDTH_4_DDR;
+ bus_width = MMC_BUS_WIDTH_4 | MMC_BUS_WIDTH_DDR;
+ } else if (host->caps & MMC_CAP_8_BIT_DATA) {
ext_csd_bit = EXT_CSD_BUS_WIDTH_8;
bus_width = MMC_BUS_WIDTH_8;
} else {
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 403aa505f27e..c0f729f07db8 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -42,6 +42,8 @@ struct mmc_csd {
struct mmc_ext_csd {
unsigned int hs_max_dtr;
unsigned int sectors;
+ unsigned int card_type;
+#define MMC_DDR_MODE_MASK (0x3<<2)
};
struct sd_scr {
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 3e7615e9087e..ea3a90d237b9 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -42,6 +42,7 @@ struct mmc_ios {
#define MMC_BUS_WIDTH_1 0
#define MMC_BUS_WIDTH_4 2
#define MMC_BUS_WIDTH_8 3
+#define MMC_BUS_WIDTH_DDR 8
unsigned char timing; /* timing specification used */
@@ -118,6 +119,7 @@ struct mmc_host {
#define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */
#define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */
#define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */
+#define MMC_CAP_DATA_DDR (1 << 7) /* Can the host do ddr transfers */
/* host specific block data */
unsigned int max_seg_size; /* see blk_queue_max_segment_size */
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 14b81f3e5232..3fb7289fce73 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -265,10 +265,13 @@ struct _mmc_csd {
#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_52 (2<<1) /* Card can run at DDR 52MHz */
#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_BUS_WIDTH_4_DDR 5 /* Card is in 4 bit ddr mode */
+#define EXT_CSD_BUS_WIDTH_8_DDR 6 /* Card is in 8 bit ddr mode */
/*
* MMC_SWITCH access modes