diff mbox

[v2] mmc: enable Enhance Strobe for HS400.

Message ID 1433472602-3851-1-git-send-email-yi.y.sun@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

yisun1 June 5, 2015, 2:50 a.m. UTC
Enhance Strobe is defined in v5.1 eMMC spec. This commit
is to implement it.

Normal Strobe signal for HS400 is only provided during
Data Out and CRC Response. While Enhance Strobe is enabled,
Strobe signal is provided during Data Out, CRC Response and
CMD Response.

While enabling Enhance Strobe, the initialization of HS400
does not need enabling HS200 and executing tuning anymore.
This simplifies the HS400 initialization process much.

Per spec, there is a STROBE_SUPPORT added in EXT_CSD register
to indicate that card supports Enhance Strobe or not. If it is
supported, host can enable this feature by enabling the most
significant bit of BUS_WIDTH before set HS_TIMING to HS400.

Signed-off-by: Yi Sun <yi.y.sun@intel.com>
---
 drivers/mmc/core/mmc.c   |   61 ++++++++++++++++++++++++++++++++++++++++++----
 include/linux/mmc/card.h |    1 +
 include/linux/mmc/mmc.h  |    2 ++
 3 files changed, 59 insertions(+), 5 deletions(-)

Comments

Ritesh Harjani (IBM) June 5, 2015, 9:50 p.m. UTC | #1
Hi Sun,

Did you get to test this feature on any of the target?



On Fri, Jun 5, 2015 at 8:20 AM, Yi Sun <yi.y.sun@intel.com> wrote:
> Enhance Strobe is defined in v5.1 eMMC spec. This commit
> is to implement it.
>
> Normal Strobe signal for HS400 is only provided during
> Data Out and CRC Response. While Enhance Strobe is enabled,
> Strobe signal is provided during Data Out, CRC Response and
> CMD Response.
>
> While enabling Enhance Strobe, the initialization of HS400
> does not need enabling HS200 and executing tuning anymore.
If enhanced strobe is enabled, what about SDHCI_NEEDS_RETUNING flag ?
In case of CRC error, we do execute tuning, but now after support of
enhanced strobe, how will that be taken care of?


> This simplifies the HS400 initialization process much.
>
> Per spec, there is a STROBE_SUPPORT added in EXT_CSD register
> to indicate that card supports Enhance Strobe or not. If it is
> supported, host can enable this feature by enabling the most
> significant bit of BUS_WIDTH before set HS_TIMING to HS400.
enhanced strobe feature also requires support from host controller
side as well. Dont you think we should provide some ops here for that?
>
> Signed-off-by: Yi Sun <yi.y.sun@intel.com>
> ---
>  drivers/mmc/core/mmc.c   |   61 ++++++++++++++++++++++++++++++++++++++++++----
>  include/linux/mmc/card.h |    1 +
>  include/linux/mmc/mmc.h  |    2 ++
>  3 files changed, 59 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index e519e31..c9ef2de 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -585,6 +585,12 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
>                 card->ext_csd.ffu_capable =
>                         (ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) &&
>                         !(ext_csd[EXT_CSD_FW_CONFIG] & 0x1);
> +
> +               /* Enhance Strobe is supported since v5.1 which rev should be
> +                * 8 but some eMMC devices can support it with rev 7. So handle
> +                * Enhance Strobe here.
> +                */
> +               card->ext_csd.strobe_support = ext_csd[EXT_CSD_STROBE_SUPPORT];
>         }
>  out:
>         return err;
> @@ -1049,9 +1055,28 @@ static int mmc_select_hs400(struct mmc_card *card)
>         /*
>          * HS400 mode requires 8-bit bus width
>          */
comment not valid?

> -       if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
> -             host->ios.bus_width == MMC_BUS_WIDTH_8))
> -               return 0;
> +       if (card->ext_csd.strobe_support) {
> +               if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
> +                   host->caps & MMC_CAP_8_BIT_DATA))
> +                       return 0;
> +
> +               /* For Enhance Strobe flow. For non Enhance Strobe, signal
> +                * voltage will not be set.
> +                */
> +               if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V)
> +                       err = __mmc_set_signal_voltage(host,
> +                                       MMC_SIGNAL_VOLTAGE_120);
> +
> +               if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V)
> +                       err = __mmc_set_signal_voltage(host,
> +                                       MMC_SIGNAL_VOLTAGE_180);
> +               if (err)
> +                       return err;
> +       } else {
> +               if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
> +                   host->ios.bus_width == MMC_BUS_WIDTH_8))
> +                       return 0;
> +       }
>
>         /*
>          * Before switching to dual data rate operation for HS400,
> @@ -1072,15 +1097,36 @@ static int mmc_select_hs400(struct mmc_card *card)
>                 return err;
>         }
>
> +       val = EXT_CSD_DDR_BUS_WIDTH_8;
> +       if (card->ext_csd.strobe_support)
> +               val |= EXT_CSD_BUS_WIDTH_STROBE;
>         err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>                          EXT_CSD_BUS_WIDTH,
> -                        EXT_CSD_DDR_BUS_WIDTH_8,
> +                        val,
>                          card->ext_csd.generic_cmd6_time);
>         if (err) {
>                 pr_err("%s: switch to bus width for hs400 failed, err:%d\n",
>                         mmc_hostname(host), err);
>                 return err;
>         }
> +       if (card->ext_csd.strobe_support) {
> +               mmc_set_bus_width(host, MMC_BUS_WIDTH_8);
> +               /*
> +                * If controller can't handle bus width test,
> +                * compare ext_csd previously read in 1 bit mode
> +                * against ext_csd at new bus width
> +                */
> +               if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
> +                       err = mmc_compare_ext_csds(card, MMC_BUS_WIDTH_8);
> +               else
> +                       err = mmc_bus_test(card, MMC_BUS_WIDTH_8);
> +
> +               if (err) {
> +                       pr_warn("%s: switch to bus width %d failed\n",
> +                               mmc_hostname(host), MMC_BUS_WIDTH_8);
> +                       return err;
> +               }
> +       }
>
>         val = EXT_CSD_TIMING_HS400 |
>               card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
> @@ -1263,7 +1309,12 @@ static int mmc_select_timing(struct mmc_card *card)
>         if (!mmc_can_ext_csd(card))
>                 goto bus_speed;
>
> -       if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
> +       /* For Enhance Strobe HS400 flow */
> +       if (card->ext_csd.strobe_support &&
> +           card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
> +           card->host->caps & MMC_CAP_8_BIT_DATA)
> +               err = mmc_select_hs400(card);
> +       else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
>                 err = mmc_select_hs200(card);
>         else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS)
>                 err = mmc_select_hs(card);
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index 4d3776d..b793b61 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -95,6 +95,7 @@ struct mmc_ext_csd {
>         u8                      raw_partition_support;  /* 160 */
>         u8                      raw_rpmb_size_mult;     /* 168 */
>         u8                      raw_erased_mem_count;   /* 181 */
> +       u8                      strobe_support;         /* 184 */
>         u8                      raw_ext_csd_structure;  /* 194 */
>         u8                      raw_card_type;          /* 196 */
>         u8                      raw_driver_strength;    /* 197 */
> diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
> index 15f2c4a..a1bb32c 100644
> --- a/include/linux/mmc/mmc.h
> +++ b/include/linux/mmc/mmc.h
> @@ -297,6 +297,7 @@ struct _mmc_csd {
>  #define EXT_CSD_PART_CONFIG            179     /* R/W */
>  #define EXT_CSD_ERASED_MEM_CONT                181     /* RO */
>  #define EXT_CSD_BUS_WIDTH              183     /* R/W */
> +#define EXT_CSD_STROBE_SUPPORT         184     /* RO */
>  #define EXT_CSD_HS_TIMING              185     /* R/W */
>  #define EXT_CSD_POWER_CLASS            187     /* R/W */
>  #define EXT_CSD_REV                    192     /* RO */
> @@ -386,6 +387,7 @@ struct _mmc_csd {
>  #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_BUS_WIDTH_STROBE       0x80    /* Card is in 8 bit DDR mode */
>
>  #define EXT_CSD_TIMING_BC      0       /* Backwards compatility */
>  #define EXT_CSD_TIMING_HS      1       /* High speed */
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
yisun1 June 11, 2015, 1:58 p.m. UTC | #2
SGksDQoNClRoYW5rcyBmb3IgcmV2aWV3IGFuZCBzb3JyeSBmb3IgbGF0ZSB0byByZXBseS4gSSBh
bSBvbiBhIGJ1c2luZXNzIHRyYXZlbC4NCg0KLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCkZy
b206IHJpdGVzaC5oYXJqYW5pQGdtYWlsLmNvbSBbbWFpbHRvOnJpdGVzaC5oYXJqYW5pQGdtYWls
LmNvbV0gT24gQmVoYWxmIE9mIFJpdGVzaCBIYXJqYW5pDQpTZW50OiBTYXR1cmRheSwgSnVuZSAw
NiwgMjAxNSA1OjUwIEFNDQpUbzogU3VuLCBZaSBZDQpDYzogbGludXgtbW1jQHZnZXIua2VybmVs
Lm9yZzsgdWxmLmhhbnNzb25AbGluYXJvLm9yZw0KU3ViamVjdDogUmU6IFtQQVRDSCB2Ml0gbW1j
OiBlbmFibGUgRW5oYW5jZSBTdHJvYmUgZm9yIEhTNDAwLg0KDQo+IEhpIFN1biwNCg0KPiBEaWQg
eW91IGdldCB0byB0ZXN0IHRoaXMgZmVhdHVyZSBvbiBhbnkgb2YgdGhlIHRhcmdldD8NClllcywg
dGhpcyBmZWF0dXJlIGlzIHRlc3RlZCBvbiBGUEdBIGJvYXJkLiBIUzQwMCBpbml0aWFsaXphdGlv
biBwYXNzIGFuZCByZWFkL3dyaXRlIHdvcmsgd2VsbC4NCg0KDQpPbiBGcmksIEp1biA1LCAyMDE1
IGF0IDg6MjAgQU0sIFlpIFN1biA8eWkueS5zdW5AaW50ZWwuY29tPj4gd3JvdGU6DQo+PiBFbmhh
bmNlIFN0cm9iZSBpcyBkZWZpbmVkIGluIHY1LjEgZU1NQyBzcGVjLiBUaGlzIGNvbW1pdCBpcyB0
byANCj4+IGltcGxlbWVudCBpdC4NCj4+DQo+PiBOb3JtYWwgU3Ryb2JlIHNpZ25hbCBmb3IgSFM0
MDAgaXMgb25seSBwcm92aWRlZCBkdXJpbmcgRGF0YSBPdXQgYW5kIA0KPj4gQ1JDIFJlc3BvbnNl
LiBXaGlsZSBFbmhhbmNlIFN0cm9iZSBpcyBlbmFibGVkLCBTdHJvYmUgc2lnbmFsIGlzIA0KPj4g
cHJvdmlkZWQgZHVyaW5nIERhdGEgT3V0LCBDUkMgUmVzcG9uc2UgYW5kIENNRCBSZXNwb25zZS4N
Cj4+DQo+PiBXaGlsZSBlbmFibGluZyBFbmhhbmNlIFN0cm9iZSwgdGhlIGluaXRpYWxpemF0aW9u
IG9mIEhTNDAwIGRvZXMgbm90IA0KPj4gbmVlZCBlbmFibGluZyBIUzIwMCBhbmQgZXhlY3V0aW5n
IHR1bmluZyBhbnltb3JlLg0KPiBJZiBlbmhhbmNlZCBzdHJvYmUgaXMgZW5hYmxlZCwgd2hhdCBh
Ym91dCBTREhDSV9ORUVEU19SRVRVTklORyBmbGFnID8NCj4gSW4gY2FzZSBvZiBDUkMgZXJyb3Is
IHdlIGRvIGV4ZWN1dGUgdHVuaW5nLCBidXQgbm93IGFmdGVyIHN1cHBvcnQgb2YgZW5oYW5jZWQg
c3Ryb2JlLCBob3cgd2lsbCB0aGF0IGJlIHRha2VuIGNhcmUgb2Y/DQpQZXIgbXkga25vd2xlZGdl
LCByZS10dW5pbmcgaXMgbm90IG5lZWRlZCBmb3IgRW5oYW5jZSBTdHJvYmUuIE90aGVyd2lzZSwg
dGhlIGVNTUMgSFM0MDAgaW5pdGlhbGl6YXRpb24gcHJvY2VzcyBzaG91bGQgZG8gaXQgdG9vLCBs
aWtlIEhTMjAwLiBCdXQgSSByZWFsbHkgbWlzcyBzb21ldGhpbmcgaGVyZSBub3QgdG8gZG8gcmUt
dHVuaW5nIGlmIEVuaGFuY2UgU3Ryb2JlIGlzIGVuYWJsZWQuIEkgd2lsbCBhZGQgaXQuIFRvIGJl
IGZyYW5rbHksIG9uIEZQR0EsIHRoZXJlIGlzIG5vIFBNIGFuZCBDUkMgZXJyb3IgaGFwcGVuZWQg
c28gSSBkbyBub3QgdmVyaWZ5IGl0LiBJIHdpbGwgYWxzbyB0cnkgdG8gc2ltdWxhdGUgc29tZSBz
Y2VuYXJpb3MgdG8gdmVyaWZ5IHRoZSBwcm9jZXNzLg0KDQo+PiBUaGlzIHNpbXBsaWZpZXMgdGhl
IEhTNDAwIGluaXRpYWxpemF0aW9uIHByb2Nlc3MgbXVjaC4NCj4+DQo+PiBQZXIgc3BlYywgdGhl
cmUgaXMgYSBTVFJPQkVfU1VQUE9SVCBhZGRlZCBpbiBFWFRfQ1NEIHJlZ2lzdGVyIHRvIA0KPj4g
aW5kaWNhdGUgdGhhdCBjYXJkIHN1cHBvcnRzIEVuaGFuY2UgU3Ryb2JlIG9yIG5vdC4gSWYgaXQg
aXMgc3VwcG9ydGVkLCANCj4+IGhvc3QgY2FuIGVuYWJsZSB0aGlzIGZlYXR1cmUgYnkgZW5hYmxp
bmcgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgYml0IG9mIA0KPj4gQlVTX1dJRFRIIGJlZm9yZSBzZXQg
SFNfVElNSU5HIHRvIEhTNDAwLg0KPiBlbmhhbmNlZCBzdHJvYmUgZmVhdHVyZSBhbHNvIHJlcXVp
cmVzIHN1cHBvcnQgZnJvbSBob3N0IGNvbnRyb2xsZXIgc2lkZSBhcyB3ZWxsLiBEb250IHlvdSB0
aGluayB3ZSBzaG91bGQgcHJvdmlkZSBzb21lIG9wcyBoZXJlIGZvciB0aGF0Pw0KWWVzLCB0aGFu
a3MgZm9yIHN1Z2dlc3Rpb24hDQoNCj4+DQo+PiBTaWduZWQtb2ZmLWJ5OiBZaSBTdW4gPHlpLnku
c3VuQGludGVsLmNvbT4+DQo+PiAtLS0NCj4+ICBkcml2ZXJzL21tYy9jb3JlL21tYy5jICAgfCAg
IDYxICsrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0tLS0NCj4+ICBp
bmNsdWRlL2xpbnV4L21tYy9jYXJkLmggfCAgICAxICsNCj4+ICBpbmNsdWRlL2xpbnV4L21tYy9t
bWMuaCAgfCAgICAyICsrDQo+PiAgMyBmaWxlcyBjaGFuZ2VkLCA1OSBpbnNlcnRpb25zKCspLCA1
IGRlbGV0aW9ucygtKQ0KPj4NCj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL21tYy9jb3JlL21tYy5j
IGIvZHJpdmVycy9tbWMvY29yZS9tbWMuYyBpbmRleCANCj4+IGU1MTllMzEuLmM5ZWYyZGUgMTAw
NjQ0DQo+PiAtLS0gYS9kcml2ZXJzL21tYy9jb3JlL21tYy5jDQo+PiArKysgYi9kcml2ZXJzL21t
Yy9jb3JlL21tYy5jDQo+PiBAQCAtNTg1LDYgKzU4NSwxMiBAQCBzdGF0aWMgaW50IG1tY19kZWNv
ZGVfZXh0X2NzZChzdHJ1Y3QgbW1jX2NhcmQgKmNhcmQsIHU4ICpleHRfY3NkKQ0KPj4gICAgICAg
ICAgICAgICAgIGNhcmQtPmV4dF9jc2QuZmZ1X2NhcGFibGUgPQ0KPj4gICAgICAgICAgICAgICAg
ICAgICAgICAgKGV4dF9jc2RbRVhUX0NTRF9TVVBQT1JURURfTU9ERV0gJiAweDEpICYmDQo+PiAg
ICAgICAgICAgICAgICAgICAgICAgICAhKGV4dF9jc2RbRVhUX0NTRF9GV19DT05GSUddICYgMHgx
KTsNCj4+ICsNCj4+ICsgICAgICAgICAgICAgICAvKiBFbmhhbmNlIFN0cm9iZSBpcyBzdXBwb3J0
ZWQgc2luY2UgdjUuMSB3aGljaCByZXYgc2hvdWxkIGJlDQo+PiArICAgICAgICAgICAgICAgICog
OCBidXQgc29tZSBlTU1DIGRldmljZXMgY2FuIHN1cHBvcnQgaXQgd2l0aCByZXYgNy4gU28gaGFu
ZGxlDQo+PiArICAgICAgICAgICAgICAgICogRW5oYW5jZSBTdHJvYmUgaGVyZS4NCj4+ICsgICAg
ICAgICAgICAgICAgKi8NCj4+ICsgICAgICAgICAgICAgICBjYXJkLT5leHRfY3NkLnN0cm9iZV9z
dXBwb3J0ID0gDQo+PiArIGV4dF9jc2RbRVhUX0NTRF9TVFJPQkVfU1VQUE9SVF07DQo+PiAgICAg
ICAgIH0NCj4+ICBvdXQ6DQo+PiAgICAgICAgIHJldHVybiBlcnI7DQo+PiBAQCAtMTA0OSw5ICsx
MDU1LDI4IEBAIHN0YXRpYyBpbnQgbW1jX3NlbGVjdF9oczQwMChzdHJ1Y3QgbW1jX2NhcmQgKmNh
cmQpDQo+PiAgICAgICAgIC8qDQo+PiAgICAgICAgICAqIEhTNDAwIG1vZGUgcmVxdWlyZXMgOC1i
aXQgYnVzIHdpZHRoDQo+PiAgICAgICAgICAqLw0KY29tbWVudCBub3QgdmFsaWQ/DQoNCj4+IC0g
ICAgICAgaWYgKCEoY2FyZC0+bW1jX2F2YWlsX3R5cGUgJiBFWFRfQ1NEX0NBUkRfVFlQRV9IUzQw
MCAmJg0KPj4gLSAgICAgICAgICAgICBob3N0LT5pb3MuYnVzX3dpZHRoID09IE1NQ19CVVNfV0lE
VEhfOCkpDQo+PiAtICAgICAgICAgICAgICAgcmV0dXJuIDA7DQo+PiArICAgICAgIGlmIChjYXJk
LT5leHRfY3NkLnN0cm9iZV9zdXBwb3J0KSB7DQo+PiArICAgICAgICAgICAgICAgaWYgKCEoY2Fy
ZC0+bW1jX2F2YWlsX3R5cGUgJiBFWFRfQ1NEX0NBUkRfVFlQRV9IUzQwMCAmJg0KPj4gKyAgICAg
ICAgICAgICAgICAgICBob3N0LT5jYXBzICYgTU1DX0NBUF84X0JJVF9EQVRBKSkNCj4+ICsgICAg
ICAgICAgICAgICAgICAgICAgIHJldHVybiAwOw0KPj4gKw0KPj4gKyAgICAgICAgICAgICAgIC8q
IEZvciBFbmhhbmNlIFN0cm9iZSBmbG93LiBGb3Igbm9uIEVuaGFuY2UgU3Ryb2JlLCBzaWduYWwN
Cj4+ICsgICAgICAgICAgICAgICAgKiB2b2x0YWdlIHdpbGwgbm90IGJlIHNldC4NCj4+ICsgICAg
ICAgICAgICAgICAgKi8NCj4+ICsgICAgICAgICAgICAgICBpZiAoY2FyZC0+bW1jX2F2YWlsX3R5
cGUgJiBFWFRfQ1NEX0NBUkRfVFlQRV9IUzIwMF8xXzJWKQ0KPj4gKyAgICAgICAgICAgICAgICAg
ICAgICAgZXJyID0gX19tbWNfc2V0X3NpZ25hbF92b2x0YWdlKGhvc3QsDQo+PiArICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTU1DX1NJR05BTF9WT0xUQUdFXzEyMCk7DQo+
PiArDQo+PiArICAgICAgICAgICAgICAgaWYgKGVyciAmJiBjYXJkLT5tbWNfYXZhaWxfdHlwZSAm
IEVYVF9DU0RfQ0FSRF9UWVBFX0hTMjAwXzFfOFYpDQo+PiArICAgICAgICAgICAgICAgICAgICAg
ICBlcnIgPSBfX21tY19zZXRfc2lnbmFsX3ZvbHRhZ2UoaG9zdCwNCj4+ICsgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICBNTUNfU0lHTkFMX1ZPTFRBR0VfMTgwKTsNCj4+ICsg
ICAgICAgICAgICAgICBpZiAoZXJyKQ0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJu
IGVycjsNCj4+ICsgICAgICAgfSBlbHNlIHsNCj4+ICsgICAgICAgICAgICAgICBpZiAoIShjYXJk
LT5tbWNfYXZhaWxfdHlwZSAmIEVYVF9DU0RfQ0FSRF9UWVBFX0hTNDAwICYmDQo+PiArICAgICAg
ICAgICAgICAgICAgIGhvc3QtPmlvcy5idXNfd2lkdGggPT0gTU1DX0JVU19XSURUSF84KSkNCj4+
ICsgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAwOw0KPj4gKyAgICAgICB9DQo+Pg0KPj4g
ICAgICAgICAvKg0KPj4gICAgICAgICAgKiBCZWZvcmUgc3dpdGNoaW5nIHRvIGR1YWwgZGF0YSBy
YXRlIG9wZXJhdGlvbiBmb3IgSFM0MDAsIEBAIA0KPj4gLTEwNzIsMTUgKzEwOTcsMzYgQEAgc3Rh
dGljIGludCBtbWNfc2VsZWN0X2hzNDAwKHN0cnVjdCBtbWNfY2FyZCAqY2FyZCkNCj4+ICAgICAg
ICAgICAgICAgICByZXR1cm4gZXJyOw0KPj4gICAgICAgICB9DQo+Pg0KPj4gKyAgICAgICB2YWwg
PSBFWFRfQ1NEX0REUl9CVVNfV0lEVEhfODsNCj4+ICsgICAgICAgaWYgKGNhcmQtPmV4dF9jc2Qu
c3Ryb2JlX3N1cHBvcnQpDQo+PiArICAgICAgICAgICAgICAgdmFsIHw9IEVYVF9DU0RfQlVTX1dJ
RFRIX1NUUk9CRTsNCj4+ICAgICAgICAgZXJyID0gbW1jX3N3aXRjaChjYXJkLCBFWFRfQ1NEX0NN
RF9TRVRfTk9STUFMLA0KPj4gICAgICAgICAgICAgICAgICAgICAgICAgIEVYVF9DU0RfQlVTX1dJ
RFRILA0KPj4gLSAgICAgICAgICAgICAgICAgICAgICAgIEVYVF9DU0RfRERSX0JVU19XSURUSF84
LA0KPj4gKyAgICAgICAgICAgICAgICAgICAgICAgIHZhbCwNCj4+ICAgICAgICAgICAgICAgICAg
ICAgICAgICBjYXJkLT5leHRfY3NkLmdlbmVyaWNfY21kNl90aW1lKTsNCj4+ICAgICAgICAgaWYg
KGVycikgew0KPj4gICAgICAgICAgICAgICAgIHByX2VycigiJXM6IHN3aXRjaCB0byBidXMgd2lk
dGggZm9yIGhzNDAwIGZhaWxlZCwgZXJyOiVkXG4iLA0KPj4gICAgICAgICAgICAgICAgICAgICAg
ICAgbW1jX2hvc3RuYW1lKGhvc3QpLCBlcnIpOw0KPj4gICAgICAgICAgICAgICAgIHJldHVybiBl
cnI7DQo+PiAgICAgICAgIH0NCj4+ICsgICAgICAgaWYgKGNhcmQtPmV4dF9jc2Quc3Ryb2JlX3N1
cHBvcnQpIHsNCj4+ICsgICAgICAgICAgICAgICBtbWNfc2V0X2J1c193aWR0aChob3N0LCBNTUNf
QlVTX1dJRFRIXzgpOw0KPj4gKyAgICAgICAgICAgICAgIC8qDQo+PiArICAgICAgICAgICAgICAg
ICogSWYgY29udHJvbGxlciBjYW4ndCBoYW5kbGUgYnVzIHdpZHRoIHRlc3QsDQo+PiArICAgICAg
ICAgICAgICAgICogY29tcGFyZSBleHRfY3NkIHByZXZpb3VzbHkgcmVhZCBpbiAxIGJpdCBtb2Rl
DQo+PiArICAgICAgICAgICAgICAgICogYWdhaW5zdCBleHRfY3NkIGF0IG5ldyBidXMgd2lkdGgN
Cj4+ICsgICAgICAgICAgICAgICAgKi8NCj4+ICsgICAgICAgICAgICAgICBpZiAoIShob3N0LT5j
YXBzICYgTU1DX0NBUF9CVVNfV0lEVEhfVEVTVCkpDQo+PiArICAgICAgICAgICAgICAgICAgICAg
ICBlcnIgPSBtbWNfY29tcGFyZV9leHRfY3NkcyhjYXJkLCBNTUNfQlVTX1dJRFRIXzgpOw0KPj4g
KyAgICAgICAgICAgICAgIGVsc2UNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIGVyciA9IG1t
Y19idXNfdGVzdChjYXJkLCBNTUNfQlVTX1dJRFRIXzgpOw0KPj4gKw0KPj4gKyAgICAgICAgICAg
ICAgIGlmIChlcnIpIHsNCj4+ICsgICAgICAgICAgICAgICAgICAgICAgIHByX3dhcm4oIiVzOiBz
d2l0Y2ggdG8gYnVzIHdpZHRoICVkIGZhaWxlZFxuIiwNCj4+ICsgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgbW1jX2hvc3RuYW1lKGhvc3QpLCBNTUNfQlVTX1dJRFRIXzgpOw0KPj4gKyAg
ICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVycjsNCj4+ICsgICAgICAgICAgICAgICB9DQo+
PiArICAgICAgIH0NCj4+DQo+PiAgICAgICAgIHZhbCA9IEVYVF9DU0RfVElNSU5HX0hTNDAwIHwN
Cj4+ICAgICAgICAgICAgICAgY2FyZC0+ZHJpdmVfc3RyZW5ndGggPDwgRVhUX0NTRF9EUlZfU1RS
X1NISUZUOyBAQCANCj4+IC0xMjYzLDcgKzEzMDksMTIgQEAgc3RhdGljIGludCBtbWNfc2VsZWN0
X3RpbWluZyhzdHJ1Y3QgbW1jX2NhcmQgKmNhcmQpDQo+PiAgICAgICAgIGlmICghbW1jX2Nhbl9l
eHRfY3NkKGNhcmQpKQ0KPj4gICAgICAgICAgICAgICAgIGdvdG8gYnVzX3NwZWVkOw0KPj4NCj4+
IC0gICAgICAgaWYgKGNhcmQtPm1tY19hdmFpbF90eXBlICYgRVhUX0NTRF9DQVJEX1RZUEVfSFMy
MDApDQo+PiArICAgICAgIC8qIEZvciBFbmhhbmNlIFN0cm9iZSBIUzQwMCBmbG93ICovDQo+PiAr
ICAgICAgIGlmIChjYXJkLT5leHRfY3NkLnN0cm9iZV9zdXBwb3J0ICYmDQo+PiArICAgICAgICAg
ICBjYXJkLT5tbWNfYXZhaWxfdHlwZSAmIEVYVF9DU0RfQ0FSRF9UWVBFX0hTNDAwICYmDQo+PiAr
ICAgICAgICAgICBjYXJkLT5ob3N0LT4+Y2FwcyAmIE1NQ19DQVBfOF9CSVRfREFUQSkNCj4+ICsg
ICAgICAgICAgICAgICBlcnIgPSBtbWNfc2VsZWN0X2hzNDAwKGNhcmQpOw0KPj4gKyAgICAgICBl
bHNlIGlmIChjYXJkLT5tbWNfYXZhaWxfdHlwZSAmIEVYVF9DU0RfQ0FSRF9UWVBFX0hTMjAwKQ0K
Pj4gICAgICAgICAgICAgICAgIGVyciA9IG1tY19zZWxlY3RfaHMyMDAoY2FyZCk7DQo+PiAgICAg
ICAgIGVsc2UgaWYgKGNhcmQtPm1tY19hdmFpbF90eXBlICYgRVhUX0NTRF9DQVJEX1RZUEVfSFMp
DQo+PiAgICAgICAgICAgICAgICAgZXJyID0gbW1jX3NlbGVjdF9ocyhjYXJkKTsgZGlmZiAtLWdp
dCANCj4+IGEvaW5jbHVkZS9saW51eC9tbWMvY2FyZC5oIGIvaW5jbHVkZS9saW51eC9tbWMvY2Fy
ZC5oIGluZGV4IA0KPj4gNGQzNzc2ZC4uYjc5M2I2MSAxMDA2NDQNCj4+IC0tLSBhL2luY2x1ZGUv
bGludXgvbW1jL2NhcmQuaA0KPj4gKysrIGIvaW5jbHVkZS9saW51eC9tbWMvY2FyZC5oDQo+PiBA
QCAtOTUsNiArOTUsNyBAQCBzdHJ1Y3QgbW1jX2V4dF9jc2Qgew0KPj4gICAgICAgICB1OCAgICAg
ICAgICAgICAgICAgICAgICByYXdfcGFydGl0aW9uX3N1cHBvcnQ7ICAvKiAxNjAgKi8NCj4+ICAg
ICAgICAgdTggICAgICAgICAgICAgICAgICAgICAgcmF3X3JwbWJfc2l6ZV9tdWx0OyAgICAgLyog
MTY4ICovDQo+PiAgICAgICAgIHU4ICAgICAgICAgICAgICAgICAgICAgIHJhd19lcmFzZWRfbWVt
X2NvdW50OyAgIC8qIDE4MSAqLw0KPj4gKyAgICAgICB1OCAgICAgICAgICAgICAgICAgICAgICBz
dHJvYmVfc3VwcG9ydDsgICAgICAgICAvKiAxODQgKi8NCj4+ICAgICAgICAgdTggICAgICAgICAg
ICAgICAgICAgICAgcmF3X2V4dF9jc2Rfc3RydWN0dXJlOyAgLyogMTk0ICovDQo+PiAgICAgICAg
IHU4ICAgICAgICAgICAgICAgICAgICAgIHJhd19jYXJkX3R5cGU7ICAgICAgICAgIC8qIDE5NiAq
Lw0KPj4gICAgICAgICB1OCAgICAgICAgICAgICAgICAgICAgICByYXdfZHJpdmVyX3N0cmVuZ3Ro
OyAgICAvKiAxOTcgKi8NCj4+IGRpZmYgLS1naXQgYS9pbmNsdWRlL2xpbnV4L21tYy9tbWMuaCBi
L2luY2x1ZGUvbGludXgvbW1jL21tYy5oIGluZGV4IA0KPj4gMTVmMmM0YS4uYTFiYjMyYyAxMDA2
NDQNCj4+IC0tLSBhL2luY2x1ZGUvbGludXgvbW1jL21tYy5oDQo+PiArKysgYi9pbmNsdWRlL2xp
bnV4L21tYy9tbWMuaA0KPj4gQEAgLTI5Nyw2ICsyOTcsNyBAQCBzdHJ1Y3QgX21tY19jc2Qgew0K
Pj4gICNkZWZpbmUgRVhUX0NTRF9QQVJUX0NPTkZJRyAgICAgICAgICAgIDE3OSAgICAgLyogUi9X
ICovDQo+PiAgI2RlZmluZSBFWFRfQ1NEX0VSQVNFRF9NRU1fQ09OVCAgICAgICAgICAgICAgICAx
ODEgICAgIC8qIFJPICovDQo+PiAgI2RlZmluZSBFWFRfQ1NEX0JVU19XSURUSCAgICAgICAgICAg
ICAgMTgzICAgICAvKiBSL1cgKi8NCj4+ICsjZGVmaW5lIEVYVF9DU0RfU1RST0JFX1NVUFBPUlQg
ICAgICAgICAxODQgICAgIC8qIFJPICovDQo+PiAgI2RlZmluZSBFWFRfQ1NEX0hTX1RJTUlORyAg
ICAgICAgICAgICAgMTg1ICAgICAvKiBSL1cgKi8NCj4+ICAjZGVmaW5lIEVYVF9DU0RfUE9XRVJf
Q0xBU1MgICAgICAgICAgICAxODcgICAgIC8qIFIvVyAqLw0KPj4gICNkZWZpbmUgRVhUX0NTRF9S
RVYgICAgICAgICAgICAgICAgICAgIDE5MiAgICAgLyogUk8gKi8NCj4+IEBAIC0zODYsNiArMzg3
LDcgQEAgc3RydWN0IF9tbWNfY3NkIHsNCj4+ICAjZGVmaW5lIEVYVF9DU0RfQlVTX1dJRFRIXzgg
ICAgMiAgICAgICAvKiBDYXJkIGlzIGluIDggYml0IG1vZGUgKi8NCj4+ICAjZGVmaW5lIEVYVF9D
U0RfRERSX0JVU19XSURUSF80ICAgICAgICA1ICAgICAgIC8qIENhcmQgaXMgaW4gNCBiaXQgRERS
IG1vZGUgKi8NCj4+ICAjZGVmaW5lIEVYVF9DU0RfRERSX0JVU19XSURUSF84ICAgICAgICA2ICAg
ICAgIC8qIENhcmQgaXMgaW4gOCBiaXQgRERSIG1vZGUgKi8NCj4+ICsjZGVmaW5lIEVYVF9DU0Rf
QlVTX1dJRFRIX1NUUk9CRSAgICAgICAweDgwICAgIC8qIENhcmQgaXMgaW4gOCBiaXQgRERSIG1v
ZGUgKi8NCj4+DQo+PiAgI2RlZmluZSBFWFRfQ1NEX1RJTUlOR19CQyAgICAgIDAgICAgICAgLyog
QmFja3dhcmRzIGNvbXBhdGlsaXR5ICovDQo+PiAgI2RlZmluZSBFWFRfQ1NEX1RJTUlOR19IUyAg
ICAgIDEgICAgICAgLyogSGlnaCBzcGVlZCAqLw0KPj4gLS0NCj4+IDEuNy45LjUNCj4+DQo+PiAt
LQ0KPj4gVG8gdW5zdWJzY3JpYmUgZnJvbSB0aGlzIGxpc3Q6IHNlbmQgdGhlIGxpbmUgInVuc3Vi
c2NyaWJlIGxpbnV4LW1tYyIgDQo+PiBpbiB0aGUgYm9keSBvZiBhIG1lc3NhZ2UgdG8gbWFqb3Jk
b21vQHZnZXIua2VybmVsLm9yZyBNb3JlIG1ham9yZG9tbyANCj4+IGluZm8gYXQgIGh0dHA6Ly92
Z2VyLmtlcm5lbC5vcmcvbWFqb3Jkb21vLWluZm8uaHRtbA0K
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Venkat Gopalakrishnan June 12, 2015, 10:47 p.m. UTC | #3
Hi Yi,

I tested your patch on msm platform and found few issues. Please see my
comments inline.

On Thu, June 4, 2015 7:50 pm, Yi Sun wrote:
> Enhance Strobe is defined in v5.1 eMMC spec. This commit
Please replace "Enhance Strobe" to "Enhanced Strobe" as per spec
throughout the documentation and code.

> is to implement it.
>
> Normal Strobe signal for HS400 is only provided during
> Data Out and CRC Response. While Enhance Strobe is enabled,
> Strobe signal is provided during Data Out, CRC Response and
> CMD Response.
>
> While enabling Enhance Strobe, the initialization of HS400
> does not need enabling HS200 and executing tuning anymore.
> This simplifies the HS400 initialization process much.
>
> Per spec, there is a STROBE_SUPPORT added in EXT_CSD register
> to indicate that card supports Enhance Strobe or not. If it is
> supported, host can enable this feature by enabling the most
> significant bit of BUS_WIDTH before set HS_TIMING to HS400.
>
> Signed-off-by: Yi Sun <yi.y.sun@intel.com>
> ---
>  drivers/mmc/core/mmc.c   |   61
> ++++++++++++++++++++++++++++++++++++++++++----
>  include/linux/mmc/card.h |    1 +
>  include/linux/mmc/mmc.h  |    2 ++
>  3 files changed, 59 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
> index e519e31..c9ef2de 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -585,6 +585,12 @@ static int mmc_decode_ext_csd(struct mmc_card *card,
> u8 *ext_csd)
>  		card->ext_csd.ffu_capable =
>  			(ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) &&
>  			!(ext_csd[EXT_CSD_FW_CONFIG] & 0x1);
> +
> +		/* Enhance Strobe is supported since v5.1 which rev should be
> +		 * 8 but some eMMC devices can support it with rev 7. So handle
> +		 * Enhance Strobe here.
> +		 */
> +		card->ext_csd.strobe_support = ext_csd[EXT_CSD_STROBE_SUPPORT];
>  	}
>  out:
>  	return err;
> @@ -1049,9 +1055,28 @@ static int mmc_select_hs400(struct mmc_card *card)
>  	/*
>  	 * HS400 mode requires 8-bit bus width
>  	 */
> -	if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
> -	      host->ios.bus_width == MMC_BUS_WIDTH_8))
> -		return 0;
> +	if (card->ext_csd.strobe_support) {
> +		if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
> +		    host->caps & MMC_CAP_8_BIT_DATA))
> +			return 0;
> +
> +		/* For Enhance Strobe flow. For non Enhance Strobe, signal
> +		 * voltage will not be set.
> +		 */
> +		if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V)
> +			err = __mmc_set_signal_voltage(host,
> +					MMC_SIGNAL_VOLTAGE_120);
> +
> +		if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V)
> +			err = __mmc_set_signal_voltage(host,
> +					MMC_SIGNAL_VOLTAGE_180);
> +		if (err)
> +			return err;
> +	} else {
> +		if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
> +		    host->ios.bus_width == MMC_BUS_WIDTH_8))
> +			return 0;
> +	}
>
>  	/*
>  	 * Before switching to dual data rate operation for HS400,
> @@ -1072,15 +1097,36 @@ static int mmc_select_hs400(struct mmc_card *card)
>  		return err;
>  	}
>
We can use mmc_select_bus_width to set 8 bit bus width here, see my
comment below.

> +	val = EXT_CSD_DDR_BUS_WIDTH_8;
> +	if (card->ext_csd.strobe_support)
> +		val |= EXT_CSD_BUS_WIDTH_STROBE;
>  	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>  			 EXT_CSD_BUS_WIDTH,
> -			 EXT_CSD_DDR_BUS_WIDTH_8,
> +			 val,
>  			 card->ext_csd.generic_cmd6_time);
>  	if (err) {
>  		pr_err("%s: switch to bus width for hs400 failed, err:%d\n",
>  			mmc_hostname(host), err);
>  		return err;
>  	}
> +	if (card->ext_csd.strobe_support) {
> +		mmc_set_bus_width(host, MMC_BUS_WIDTH_8);
> +		/*
> +		 * If controller can't handle bus width test,
> +		 * compare ext_csd previously read in 1 bit mode
> +		 * against ext_csd at new bus width
> +		 */
> +		if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
> +			err = mmc_compare_ext_csds(card, MMC_BUS_WIDTH_8);
Reading the ext csd here fails with CRC error since the card is switched
to DDR bus width above while the host remains in SDR. We should have both
the host and card in the same timing/bus width before reading data from
card.

I would recommend using mmc_select_bus_width after switching the timing to
HS instead of replicating the code in this if block.

> +		else
> +			err = mmc_bus_test(card, MMC_BUS_WIDTH_8);
> +
> +		if (err) {
> +			pr_warn("%s: switch to bus width %d failed\n",
> +				mmc_hostname(host), MMC_BUS_WIDTH_8);
> +			return err;
> +		}
> +	}
>
Please do add a call to host ops for hosts that need and provide
additional programming.

>  	val = EXT_CSD_TIMING_HS400 |
>  	      card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
> @@ -1263,7 +1309,12 @@ static int mmc_select_timing(struct mmc_card *card)
>  	if (!mmc_can_ext_csd(card))
>  		goto bus_speed;
>
> -	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
> +	/* For Enhance Strobe HS400 flow */
> +	if (card->ext_csd.strobe_support &&
> +	    card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
> +	    card->host->caps & MMC_CAP_8_BIT_DATA)
> +		err = mmc_select_hs400(card);
> +	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
>  		err = mmc_select_hs200(card);
>  	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS)
>  		err = mmc_select_hs(card);
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
> index 4d3776d..b793b61 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -95,6 +95,7 @@ struct mmc_ext_csd {
>  	u8			raw_partition_support;	/* 160 */
>  	u8			raw_rpmb_size_mult;	/* 168 */
>  	u8			raw_erased_mem_count;	/* 181 */
> +	u8			strobe_support;		/* 184 */
>  	u8			raw_ext_csd_structure;	/* 194 */
>  	u8			raw_card_type;		/* 196 */
>  	u8			raw_driver_strength;	/* 197 */
> diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
> index 15f2c4a..a1bb32c 100644
> --- a/include/linux/mmc/mmc.h
> +++ b/include/linux/mmc/mmc.h
> @@ -297,6 +297,7 @@ struct _mmc_csd {
>  #define EXT_CSD_PART_CONFIG		179	/* R/W */
>  #define EXT_CSD_ERASED_MEM_CONT		181	/* RO */
>  #define EXT_CSD_BUS_WIDTH		183	/* R/W */
> +#define EXT_CSD_STROBE_SUPPORT		184	/* RO */
>  #define EXT_CSD_HS_TIMING		185	/* R/W */
>  #define EXT_CSD_POWER_CLASS		187	/* R/W */
>  #define EXT_CSD_REV			192	/* RO */
> @@ -386,6 +387,7 @@ struct _mmc_csd {
>  #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_BUS_WIDTH_STROBE	0x80	/* Card is in 8 bit DDR mode */
>
>  #define EXT_CSD_TIMING_BC	0	/* Backwards compatility */
>  #define EXT_CSD_TIMING_HS	1	/* High speed */
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
yisun1 July 1, 2015, 3:15 a.m. UTC | #4
Hi,

Sorry for late and thanks a lot for your test and suggestions! I have completed the business travel and will check them in detail.

BRs,
Sun Yi

-----Original Message-----
From: Venkat Gopalakrishnan [mailto:venkatg@codeaurora.org] 
Sent: Saturday, June 13, 2015 6:48 AM
To: Sun, Yi Y
Cc: linux-mmc@vger.kernel.org; ulf.hansson@linaro.org; Sun, Yi Y
Subject: Re: [PATCH v2] mmc: enable Enhance Strobe for HS400.

Hi Yi,

I tested your patch on msm platform and found few issues. Please see my comments inline.

On Thu, June 4, 2015 7:50 pm, Yi Sun wrote:
> Enhance Strobe is defined in v5.1 eMMC spec. This commit
Please replace "Enhance Strobe" to "Enhanced Strobe" as per spec throughout the documentation and code.

> is to implement it.
>
> Normal Strobe signal for HS400 is only provided during Data Out and 
> CRC Response. While Enhance Strobe is enabled, Strobe signal is 
> provided during Data Out, CRC Response and CMD Response.
>
> While enabling Enhance Strobe, the initialization of HS400 does not 
> need enabling HS200 and executing tuning anymore.
> This simplifies the HS400 initialization process much.
>
> Per spec, there is a STROBE_SUPPORT added in EXT_CSD register to 
> indicate that card supports Enhance Strobe or not. If it is supported, 
> host can enable this feature by enabling the most significant bit of 
> BUS_WIDTH before set HS_TIMING to HS400.
>
> Signed-off-by: Yi Sun <yi.y.sun@intel.com>
> ---
>  drivers/mmc/core/mmc.c   |   61
> ++++++++++++++++++++++++++++++++++++++++++----
>  include/linux/mmc/card.h |    1 +
>  include/linux/mmc/mmc.h  |    2 ++
>  3 files changed, 59 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 
> e519e31..c9ef2de 100644
> --- a/drivers/mmc/core/mmc.c
> +++ b/drivers/mmc/core/mmc.c
> @@ -585,6 +585,12 @@ static int mmc_decode_ext_csd(struct mmc_card 
> *card,
> u8 *ext_csd)
>  		card->ext_csd.ffu_capable =
>  			(ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) &&
>  			!(ext_csd[EXT_CSD_FW_CONFIG] & 0x1);
> +
> +		/* Enhance Strobe is supported since v5.1 which rev should be
> +		 * 8 but some eMMC devices can support it with rev 7. So handle
> +		 * Enhance Strobe here.
> +		 */
> +		card->ext_csd.strobe_support = ext_csd[EXT_CSD_STROBE_SUPPORT];
>  	}
>  out:
>  	return err;
> @@ -1049,9 +1055,28 @@ static int mmc_select_hs400(struct mmc_card *card)
>  	/*
>  	 * HS400 mode requires 8-bit bus width
>  	 */
> -	if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
> -	      host->ios.bus_width == MMC_BUS_WIDTH_8))
> -		return 0;
> +	if (card->ext_csd.strobe_support) {
> +		if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
> +		    host->caps & MMC_CAP_8_BIT_DATA))
> +			return 0;
> +
> +		/* For Enhance Strobe flow. For non Enhance Strobe, signal
> +		 * voltage will not be set.
> +		 */
> +		if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V)
> +			err = __mmc_set_signal_voltage(host,
> +					MMC_SIGNAL_VOLTAGE_120);
> +
> +		if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V)
> +			err = __mmc_set_signal_voltage(host,
> +					MMC_SIGNAL_VOLTAGE_180);
> +		if (err)
> +			return err;
> +	} else {
> +		if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
> +		    host->ios.bus_width == MMC_BUS_WIDTH_8))
> +			return 0;
> +	}
>
>  	/*
>  	 * Before switching to dual data rate operation for HS400, @@ 
> -1072,15 +1097,36 @@ static int mmc_select_hs400(struct mmc_card *card)
>  		return err;
>  	}
>
We can use mmc_select_bus_width to set 8 bit bus width here, see my comment below.

> +	val = EXT_CSD_DDR_BUS_WIDTH_8;
> +	if (card->ext_csd.strobe_support)
> +		val |= EXT_CSD_BUS_WIDTH_STROBE;
>  	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
>  			 EXT_CSD_BUS_WIDTH,
> -			 EXT_CSD_DDR_BUS_WIDTH_8,
> +			 val,
>  			 card->ext_csd.generic_cmd6_time);
>  	if (err) {
>  		pr_err("%s: switch to bus width for hs400 failed, err:%d\n",
>  			mmc_hostname(host), err);
>  		return err;
>  	}
> +	if (card->ext_csd.strobe_support) {
> +		mmc_set_bus_width(host, MMC_BUS_WIDTH_8);
> +		/*
> +		 * If controller can't handle bus width test,
> +		 * compare ext_csd previously read in 1 bit mode
> +		 * against ext_csd at new bus width
> +		 */
> +		if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
> +			err = mmc_compare_ext_csds(card, MMC_BUS_WIDTH_8);
Reading the ext csd here fails with CRC error since the card is switched to DDR bus width above while the host remains in SDR. We should have both the host and card in the same timing/bus width before reading data from card.

I would recommend using mmc_select_bus_width after switching the timing to HS instead of replicating the code in this if block.

> +		else
> +			err = mmc_bus_test(card, MMC_BUS_WIDTH_8);
> +
> +		if (err) {
> +			pr_warn("%s: switch to bus width %d failed\n",
> +				mmc_hostname(host), MMC_BUS_WIDTH_8);
> +			return err;
> +		}
> +	}
>
Please do add a call to host ops for hosts that need and provide additional programming.

>  	val = EXT_CSD_TIMING_HS400 |
>  	      card->drive_strength << EXT_CSD_DRV_STR_SHIFT; @@ -1263,7 
> +1309,12 @@ static int mmc_select_timing(struct mmc_card *card)
>  	if (!mmc_can_ext_csd(card))
>  		goto bus_speed;
>
> -	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
> +	/* For Enhance Strobe HS400 flow */
> +	if (card->ext_csd.strobe_support &&
> +	    card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
> +	    card->host->caps & MMC_CAP_8_BIT_DATA)
> +		err = mmc_select_hs400(card);
> +	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
>  		err = mmc_select_hs200(card);
>  	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS)
>  		err = mmc_select_hs(card);
> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 
> 4d3776d..b793b61 100644
> --- a/include/linux/mmc/card.h
> +++ b/include/linux/mmc/card.h
> @@ -95,6 +95,7 @@ struct mmc_ext_csd {
>  	u8			raw_partition_support;	/* 160 */
>  	u8			raw_rpmb_size_mult;	/* 168 */
>  	u8			raw_erased_mem_count;	/* 181 */
> +	u8			strobe_support;		/* 184 */
>  	u8			raw_ext_csd_structure;	/* 194 */
>  	u8			raw_card_type;		/* 196 */
>  	u8			raw_driver_strength;	/* 197 */
> diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 
> 15f2c4a..a1bb32c 100644
> --- a/include/linux/mmc/mmc.h
> +++ b/include/linux/mmc/mmc.h
> @@ -297,6 +297,7 @@ struct _mmc_csd {
>  #define EXT_CSD_PART_CONFIG		179	/* R/W */
>  #define EXT_CSD_ERASED_MEM_CONT		181	/* RO */
>  #define EXT_CSD_BUS_WIDTH		183	/* R/W */
> +#define EXT_CSD_STROBE_SUPPORT		184	/* RO */
>  #define EXT_CSD_HS_TIMING		185	/* R/W */
>  #define EXT_CSD_POWER_CLASS		187	/* R/W */
>  #define EXT_CSD_REV			192	/* RO */
> @@ -386,6 +387,7 @@ struct _mmc_csd {
>  #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_BUS_WIDTH_STROBE	0x80	/* Card is in 8 bit DDR mode */
>
>  #define EXT_CSD_TIMING_BC	0	/* Backwards compatility */
>  #define EXT_CSD_TIMING_HS	1	/* High speed */
> --
> 1.7.9.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" 
> in the body of a message to majordomo@vger.kernel.org More majordomo 
> info at  http://vger.kernel.org/majordomo-info.html
>


--
Venkat Gopalakrishnan,
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index e519e31..c9ef2de 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -585,6 +585,12 @@  static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
 		card->ext_csd.ffu_capable =
 			(ext_csd[EXT_CSD_SUPPORTED_MODE] & 0x1) &&
 			!(ext_csd[EXT_CSD_FW_CONFIG] & 0x1);
+
+		/* Enhance Strobe is supported since v5.1 which rev should be
+		 * 8 but some eMMC devices can support it with rev 7. So handle
+		 * Enhance Strobe here.
+		 */
+		card->ext_csd.strobe_support = ext_csd[EXT_CSD_STROBE_SUPPORT];
 	}
 out:
 	return err;
@@ -1049,9 +1055,28 @@  static int mmc_select_hs400(struct mmc_card *card)
 	/*
 	 * HS400 mode requires 8-bit bus width
 	 */
-	if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
-	      host->ios.bus_width == MMC_BUS_WIDTH_8))
-		return 0;
+	if (card->ext_csd.strobe_support) {
+		if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
+		    host->caps & MMC_CAP_8_BIT_DATA))
+			return 0;
+
+		/* For Enhance Strobe flow. For non Enhance Strobe, signal
+		 * voltage will not be set.
+		 */
+		if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_2V)
+			err = __mmc_set_signal_voltage(host,
+					MMC_SIGNAL_VOLTAGE_120);
+
+		if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200_1_8V)
+			err = __mmc_set_signal_voltage(host,
+					MMC_SIGNAL_VOLTAGE_180);
+		if (err)
+			return err;
+	} else {
+		if (!(card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
+		    host->ios.bus_width == MMC_BUS_WIDTH_8))
+			return 0;
+	}
 
 	/*
 	 * Before switching to dual data rate operation for HS400,
@@ -1072,15 +1097,36 @@  static int mmc_select_hs400(struct mmc_card *card)
 		return err;
 	}
 
+	val = EXT_CSD_DDR_BUS_WIDTH_8;
+	if (card->ext_csd.strobe_support)
+		val |= EXT_CSD_BUS_WIDTH_STROBE;
 	err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 			 EXT_CSD_BUS_WIDTH,
-			 EXT_CSD_DDR_BUS_WIDTH_8,
+			 val,
 			 card->ext_csd.generic_cmd6_time);
 	if (err) {
 		pr_err("%s: switch to bus width for hs400 failed, err:%d\n",
 			mmc_hostname(host), err);
 		return err;
 	}
+	if (card->ext_csd.strobe_support) {
+		mmc_set_bus_width(host, MMC_BUS_WIDTH_8);
+		/*
+		 * If controller can't handle bus width test,
+		 * compare ext_csd previously read in 1 bit mode
+		 * against ext_csd at new bus width
+		 */
+		if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
+			err = mmc_compare_ext_csds(card, MMC_BUS_WIDTH_8);
+		else
+			err = mmc_bus_test(card, MMC_BUS_WIDTH_8);
+
+		if (err) {
+			pr_warn("%s: switch to bus width %d failed\n",
+				mmc_hostname(host), MMC_BUS_WIDTH_8);
+			return err;
+		}
+	}
 
 	val = EXT_CSD_TIMING_HS400 |
 	      card->drive_strength << EXT_CSD_DRV_STR_SHIFT;
@@ -1263,7 +1309,12 @@  static int mmc_select_timing(struct mmc_card *card)
 	if (!mmc_can_ext_csd(card))
 		goto bus_speed;
 
-	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
+	/* For Enhance Strobe HS400 flow */
+	if (card->ext_csd.strobe_support &&
+	    card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400 &&
+	    card->host->caps & MMC_CAP_8_BIT_DATA)
+		err = mmc_select_hs400(card);
+	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
 		err = mmc_select_hs200(card);
 	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS)
 		err = mmc_select_hs(card);
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 4d3776d..b793b61 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -95,6 +95,7 @@  struct mmc_ext_csd {
 	u8			raw_partition_support;	/* 160 */
 	u8			raw_rpmb_size_mult;	/* 168 */
 	u8			raw_erased_mem_count;	/* 181 */
+	u8			strobe_support;		/* 184 */
 	u8			raw_ext_csd_structure;	/* 194 */
 	u8			raw_card_type;		/* 196 */
 	u8			raw_driver_strength;	/* 197 */
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 15f2c4a..a1bb32c 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -297,6 +297,7 @@  struct _mmc_csd {
 #define EXT_CSD_PART_CONFIG		179	/* R/W */
 #define EXT_CSD_ERASED_MEM_CONT		181	/* RO */
 #define EXT_CSD_BUS_WIDTH		183	/* R/W */
+#define EXT_CSD_STROBE_SUPPORT		184	/* RO */
 #define EXT_CSD_HS_TIMING		185	/* R/W */
 #define EXT_CSD_POWER_CLASS		187	/* R/W */
 #define EXT_CSD_REV			192	/* RO */
@@ -386,6 +387,7 @@  struct _mmc_csd {
 #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_BUS_WIDTH_STROBE	0x80	/* Card is in 8 bit DDR mode */
 
 #define EXT_CSD_TIMING_BC	0	/* Backwards compatility */
 #define EXT_CSD_TIMING_HS	1	/* High speed */