Message ID | 1433472602-3851-1-git-send-email-yi.y.sun@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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
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
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 >
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 --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 */
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(-)