Commit 4c4cb171054230c2e58ed6574d7faa1871c75bbe

Authored by Philip Rakity
Committed by Chris Ball
1 parent 261bbd463a

mmc: core: add support for eMMC Dual Data Rate

eMMC voltage change not required for 1.8V.  3.3V and 1.8V vcc
are capable of doing DDR. vccq of 1.8v is not required.

Signed-off-by: Philip Rakity <prakity@marvell.com>
Reviewed-by: Arindam Nath <arindam.nath@amd.com>
Signed-off-by: Chris Ball <cjb@laptop.org>

Showing 4 changed files with 33 additions and 19 deletions Side-by-side Diff

drivers/mmc/core/core.c
... ... @@ -718,22 +718,12 @@
718 718 }
719 719  
720 720 /*
721   - * Change data bus width and DDR mode of a host.
722   - */
723   -void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width,
724   - unsigned int ddr)
725   -{
726   - host->ios.bus_width = width;
727   - host->ios.ddr = ddr;
728   - mmc_set_ios(host);
729   -}
730   -
731   -/*
732 721 * Change data bus width of a host.
733 722 */
734 723 void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
735 724 {
736   - mmc_set_bus_width_ddr(host, width, MMC_SDR_MODE);
  725 + host->ios.bus_width = width;
  726 + mmc_set_ios(host);
737 727 }
738 728  
739 729 /**
drivers/mmc/core/core.h
... ... @@ -38,8 +38,6 @@
38 38 void mmc_set_ungated(struct mmc_host *host);
39 39 void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode);
40 40 void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
41   -void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width,
42   - unsigned int ddr);
43 41 u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
44 42 int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage,
45 43 bool cmd11);
drivers/mmc/core/mmc.c
... ... @@ -20,6 +20,7 @@
20 20 #include "core.h"
21 21 #include "bus.h"
22 22 #include "mmc_ops.h"
  23 +#include "sd_ops.h"
23 24  
24 25 static const unsigned int tran_exp[] = {
25 26 10000, 100000, 1000000, 10000000,
26 27  
... ... @@ -633,10 +634,14 @@
633 634 */
634 635 if (mmc_card_highspeed(card)) {
635 636 if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V)
636   - && (host->caps & (MMC_CAP_1_8V_DDR)))
  637 + && ((host->caps & (MMC_CAP_1_8V_DDR |
  638 + MMC_CAP_UHS_DDR50))
  639 + == (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50)))
637 640 ddr = MMC_1_8V_DDR_MODE;
638 641 else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V)
639   - && (host->caps & (MMC_CAP_1_2V_DDR)))
  642 + && ((host->caps & (MMC_CAP_1_2V_DDR |
  643 + MMC_CAP_UHS_DDR50))
  644 + == (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50)))
640 645 ddr = MMC_1_2V_DDR_MODE;
641 646 }
642 647  
... ... @@ -670,8 +675,7 @@
670 675 ext_csd_bits[idx][0],
671 676 0);
672 677 if (!err) {
673   - mmc_set_bus_width_ddr(card->host,
674   - bus_width, MMC_SDR_MODE);
  678 + mmc_set_bus_width(card->host, bus_width);
675 679 /*
676 680 * If controller can't handle bus width test,
677 681 * use the highest bus width to maintain
678 682  
... ... @@ -697,8 +701,29 @@
697 701 1 << bus_width, ddr);
698 702 goto free_card;
699 703 } else if (ddr) {
  704 + /*
  705 + * eMMC cards can support 3.3V to 1.2V i/o (vccq)
  706 + * signaling.
  707 + *
  708 + * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq.
  709 + *
  710 + * 1.8V vccq at 3.3V core voltage (vcc) is not required
  711 + * in the JEDEC spec for DDR.
  712 + *
  713 + * Do not force change in vccq since we are obviously
  714 + * working and no change to vccq is needed.
  715 + *
  716 + * WARNING: eMMC rules are NOT the same as SD DDR
  717 + */
  718 + if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) {
  719 + err = mmc_set_signal_voltage(host,
  720 + MMC_SIGNAL_VOLTAGE_120, 0);
  721 + if (err)
  722 + goto err;
  723 + }
700 724 mmc_card_set_ddr_mode(card);
701   - mmc_set_bus_width_ddr(card->host, bus_width, ddr);
  725 + mmc_set_timing(card->host, MMC_TIMING_UHS_DDR50);
  726 + mmc_set_bus_width(card->host, bus_width);
702 727 }
703 728 }
704 729  
include/linux/mmc/host.h
... ... @@ -66,6 +66,7 @@
66 66  
67 67 #define MMC_SIGNAL_VOLTAGE_330 0
68 68 #define MMC_SIGNAL_VOLTAGE_180 1
  69 +#define MMC_SIGNAL_VOLTAGE_120 2
69 70  
70 71 unsigned char drv_type; /* driver type (A, B, C, D) */
71 72