From ef29c0e273b874018f1802d12957d22008138240 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Thu, 26 May 2016 09:56:12 +0800 Subject: mmc: core: add mmc-hs400-enhanced-strobe support This patch introduce mmc-hs400-enhanced-strobe for platforms which want to enable enhanced strobe function from DT if the mmc host controller claims to support enhanced strobe. Signed-off-by: Shawn Lin Reviewed-by: Douglas Anderson Tested-by: Jaehoon Chung Signed-off-by: Ulf Hansson --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 45cde8cd39f2..b836a271e2df 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -302,6 +302,7 @@ struct mmc_host { #define MMC_CAP2_SDIO_IRQ_NOTHREAD (1 << 17) #define MMC_CAP2_NO_WRITE_PROTECT (1 << 18) /* No physical write protect pin, assume that card is always read-write */ #define MMC_CAP2_NO_SDIO (1 << 19) /* Do not send SDIO commands during initialization */ +#define MMC_CAP2_HS400_ES (1 << 20) /* Host supports enhanced strobe */ mmc_pm_flag_t pm_caps; /* supported pm features */ -- cgit v1.2.3 From 81ac2af65793ecfbd79875d45043ff4adc0982b8 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Thu, 26 May 2016 09:56:22 +0800 Subject: mmc: core: implement enhanced strobe support Controllers use data strobe line to latch data from devices under hs400 mode, but not for cmd line. So since emmc 5.1, JEDEC introduces enhanced strobe mode for latching cmd response from emmc devices to host controllers. This new feature is optional, so it depends both on device's cap and host's cap to decide whether to use it or not. Signed-off-by: Shawn Lin Reviewed-by: Jaehoon Chung Tested-by: Douglas Anderson Tested-by: Jaehoon Chung Acked-by: Adrian Hunter Signed-off-by: Ulf Hansson --- include/linux/mmc/card.h | 1 + include/linux/mmc/host.h | 11 +++++++++++ include/linux/mmc/mmc.h | 3 +++ 3 files changed, 15 insertions(+) (limited to 'include') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index eb0151bac50c..22defc2a83b7 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/host.h b/include/linux/mmc/host.h index b836a271e2df..d72c0c34c21d 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -19,6 +19,7 @@ #include #include +#include #include struct mmc_ios { @@ -77,6 +78,8 @@ struct mmc_ios { #define MMC_SET_DRIVER_TYPE_A 1 #define MMC_SET_DRIVER_TYPE_C 2 #define MMC_SET_DRIVER_TYPE_D 3 + + bool enhanced_strobe; /* hs400es selection */ }; struct mmc_host_ops { @@ -143,6 +146,9 @@ struct mmc_host_ops { /* Prepare HS400 target operating frequency depending host driver */ int (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios); + /* Prepare enhanced strobe depending host driver */ + void (*hs400_enhanced_strobe)(struct mmc_host *host, + struct mmc_ios *ios); int (*select_drive_strength)(struct mmc_card *card, unsigned int max_dtr, int host_drv, int card_drv, int *drv_type); @@ -514,6 +520,11 @@ static inline bool mmc_card_hs400(struct mmc_card *card) return card->host->ios.timing == MMC_TIMING_MMC_HS400; } +static inline bool mmc_card_hs400es(struct mmc_card *card) +{ + return card->host->ios.enhanced_strobe; +} + void mmc_retune_timer_stop(struct mmc_host *host); static inline void mmc_retune_needed(struct mmc_host *host) diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 15f2c4a0a62c..c376209c70ef 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 */ @@ -380,12 +381,14 @@ struct _mmc_csd { #define EXT_CSD_CARD_TYPE_HS400_1_2V (1<<7) /* Card can run at 200MHz DDR, 1.2V */ #define EXT_CSD_CARD_TYPE_HS400 (EXT_CSD_CARD_TYPE_HS400_1_8V | \ EXT_CSD_CARD_TYPE_HS400_1_2V) +#define EXT_CSD_CARD_TYPE_HS400ES (1<<8) /* Card can run at HS400ES */ #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_BUS_WIDTH_STROBE BIT(7) /* Enhanced strobe mode */ #define EXT_CSD_TIMING_BC 0 /* Backwards compatility */ #define EXT_CSD_TIMING_HS 1 /* High speed */ -- cgit v1.2.3 From 5320226a051248b50cc2d80f2cb9599dfb56d422 Mon Sep 17 00:00:00 2001 From: Pratibhasagar V Date: Thu, 9 Jun 2016 18:09:31 -0400 Subject: mmc: core: Disable HPI for certain Hynix eMMC cards Certain Hynix eMMC 4.41 cards might get broken when HPI feature is used and hence this patch disables the HPI feature for such buggy cards. As some of the other features like BKOPs/Cache/Sanitize are dependent on HPI feature, those features would also get disabled if HPI is disabled. Signed-off-by: Pratibhasagar V Signed-off-by: Subhash Jadavani [gdavis: Forward port and cleanup] Signed-off-by: George G. Davis Signed-off-by: Ulf Hansson --- include/linux/mmc/card.h | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 22defc2a83b7..d8673ca968ba 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -280,6 +280,7 @@ struct mmc_card { #define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10) /* Skip secure for erase/trim */ #define MMC_QUIRK_BROKEN_IRQ_POLLING (1<<11) /* Polling SDIO_CCCR_INTx could create a fake interrupt */ #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */ +#define MMC_QUIRK_BROKEN_HPI (1<<13) /* Disable broken HPI support */ unsigned int erase_size; /* erase size in sectors */ @@ -354,6 +355,9 @@ struct mmc_fixup { /* SDIO-specfic fields. You can use SDIO_ANY_ID here of course */ u16 cis_vendor, cis_device; + /* for MMC cards */ + unsigned int ext_csd_rev; + void (*vendor_fixup)(struct mmc_card *card, int data); int data; }; @@ -362,11 +366,20 @@ struct mmc_fixup { #define CID_OEMID_ANY ((unsigned short) -1) #define CID_NAME_ANY (NULL) +#define EXT_CSD_REV_ANY (-1u) + +#define CID_MANFID_SANDISK 0x2 +#define CID_MANFID_TOSHIBA 0x11 +#define CID_MANFID_MICRON 0x13 +#define CID_MANFID_SAMSUNG 0x15 +#define CID_MANFID_KINGSTON 0x70 +#define CID_MANFID_HYNIX 0x90 + #define END_FIXUP { NULL } #define _FIXUP_EXT(_name, _manfid, _oemid, _rev_start, _rev_end, \ _cis_vendor, _cis_device, \ - _fixup, _data) \ + _fixup, _data, _ext_csd_rev) \ { \ .name = (_name), \ .manfid = (_manfid), \ @@ -377,23 +390,30 @@ struct mmc_fixup { .cis_device = (_cis_device), \ .vendor_fixup = (_fixup), \ .data = (_data), \ + .ext_csd_rev = (_ext_csd_rev), \ } #define MMC_FIXUP_REV(_name, _manfid, _oemid, _rev_start, _rev_end, \ - _fixup, _data) \ + _fixup, _data, _ext_csd_rev) \ _FIXUP_EXT(_name, _manfid, \ _oemid, _rev_start, _rev_end, \ SDIO_ANY_ID, SDIO_ANY_ID, \ - _fixup, _data) \ + _fixup, _data, _ext_csd_rev) \ #define MMC_FIXUP(_name, _manfid, _oemid, _fixup, _data) \ - MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data) + MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \ + EXT_CSD_REV_ANY) + +#define MMC_FIXUP_EXT_CSD_REV(_name, _manfid, _oemid, _fixup, _data, \ + _ext_csd_rev) \ + MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \ + _ext_csd_rev) #define SDIO_FIXUP(_vendor, _device, _fixup, _data) \ _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, \ CID_OEMID_ANY, 0, -1ull, \ _vendor, _device, \ - _fixup, _data) \ + _fixup, _data, EXT_CSD_REV_ANY) \ #define cid_rev(hwrev, fwrev, year, month) \ (((u64) hwrev) << 40 | \ @@ -512,6 +532,11 @@ static inline int mmc_card_broken_irq_polling(const struct mmc_card *c) return c->quirks & MMC_QUIRK_BROKEN_IRQ_POLLING; } +static inline int mmc_card_broken_hpi(const struct mmc_card *c) +{ + return c->quirks & MMC_QUIRK_BROKEN_HPI; +} + #define mmc_card_name(c) ((c)->cid.prod_name) #define mmc_card_id(c) (dev_name(&(c)->dev)) -- cgit v1.2.3 From 1b8d79c5494484d140f2a19101412b51e2d5f6b5 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 21 Jun 2016 15:12:46 +0200 Subject: mmc: core: Allow hosts to specify non-support for SD commands There are host drivers which needs to valdiate for non-supported SD commands and returnn error code for such requests. To improve and simplify the behaviour, let's invent MMC_CAP2_NO_SD which these host drivers can set to tell the mmc core to skip sending SD commands during card initialization. Signed-off-by: Ulf Hansson --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index d72c0c34c21d..c22476d23b84 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -309,6 +309,7 @@ struct mmc_host { #define MMC_CAP2_NO_WRITE_PROTECT (1 << 18) /* No physical write protect pin, assume that card is always read-write */ #define MMC_CAP2_NO_SDIO (1 << 19) /* Do not send SDIO commands during initialization */ #define MMC_CAP2_HS400_ES (1 << 20) /* Host supports enhanced strobe */ +#define MMC_CAP2_NO_SD (1 << 21) /* Do not send SD commands during initialization */ mmc_pm_flag_t pm_caps; /* supported pm features */ -- cgit v1.2.3 From 16a34574c6ca12bb8fd73ae034acd5b536d3cdaa Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Tue, 21 Jun 2016 14:35:37 +0900 Subject: mmc: dw_mmc: remove the quirks flags Remove the quirks flag. (DW_MCI_QUIRK_BROKEN_DTO) For removing this, enabled the dto_timer by defaults. It doesn't see any I/O performance degression. In future, dwmmc controller should not use the quirks flag. Signed-off-by: Jaehoon Chung Reviewed-by: Shawn Lin Signed-off-by: Ulf Hansson --- include/linux/mmc/dw_mmc.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'include') diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h index f7ed271a1d54..83b0edfce471 100644 --- a/include/linux/mmc/dw_mmc.h +++ b/include/linux/mmc/dw_mmc.h @@ -112,7 +112,6 @@ struct dw_mci_dma_slave { * @part_buf: Simple buffer for partial fifo reads/writes. * @push_data: Pointer to FIFO push function. * @pull_data: Pointer to FIFO pull function. - * @quirks: Set of quirks that apply to specific versions of the IP. * @vqmmc_enabled: Status of vqmmc, should be true or false. * @irq_flags: The flags to be passed to request_irq. * @irq: The irq value to be passed to request_irq. @@ -218,9 +217,6 @@ struct dw_mci { void (*push_data)(struct dw_mci *host, void *buf, int cnt); void (*pull_data)(struct dw_mci *host, void *buf, int cnt); - /* Workaround flags */ - u32 quirks; - bool vqmmc_enabled; unsigned long irq_flags; /* IRQ flags */ int irq; @@ -242,17 +238,12 @@ struct dw_mci_dma_ops { void (*exit)(struct dw_mci *host); }; -/* IP Quirks/flags. */ -/* Timer for broken data transfer over scheme */ -#define DW_MCI_QUIRK_BROKEN_DTO BIT(0) - struct dma_pdata; /* Board platform data */ struct dw_mci_board { u32 num_slots; - u32 quirks; /* Workaround / Quirk flags */ unsigned int bus_hz; /* Clock speed at the cclk_in pad */ u32 caps; /* Capabilities */ -- cgit v1.2.3 From a0c3b68c72a355f5dab33c3ddcd257e5a718de0c Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Fri, 1 Jul 2016 15:45:28 +0800 Subject: mmc: core: Allow hosts to specify non-support for MMC commands Host drivers which needs to valdiate for non-supported MMC commands and returnn error code for such requests. To improve and simplify the behaviour, let's invent MMC_CAP2_NO_MMC which these host drivers can set to tell the mmc core to skip sending MMC commands during card initialization. Signed-off-by: Shawn Lin Signed-off-by: Ulf Hansson --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index c22476d23b84..aa4bfbf129e4 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -310,6 +310,7 @@ struct mmc_host { #define MMC_CAP2_NO_SDIO (1 << 19) /* Do not send SDIO commands during initialization */ #define MMC_CAP2_HS400_ES (1 << 20) /* Host supports enhanced strobe */ #define MMC_CAP2_NO_SD (1 << 21) /* Do not send SD commands during initialization */ +#define MMC_CAP2_NO_MMC (1 << 22) /* Do not send (e)MMC commands during initialization */ mmc_pm_flag_t pm_caps; /* supported pm features */ -- cgit v1.2.3 From d87fc96636884430278bc3b425a5a6e2c071a377 Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Tue, 12 Jul 2016 15:46:15 +0800 Subject: mmc: sdhci-esdhc-imx: support setting tuning start point The delay cells of some SoCs may have less delay per one cell, for such SoCs, user could set the start delay cell point to bypass the first a few meaningless tuning commands. Acked-by: Adrian Hunter Signed-off-by: Dong Aisheng Signed-off-by: Ulf Hansson --- include/linux/platform_data/mmc-esdhc-imx.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/platform_data/mmc-esdhc-imx.h b/include/linux/platform_data/mmc-esdhc-imx.h index 95ccab3f454a..7daa78a2f342 100644 --- a/include/linux/platform_data/mmc-esdhc-imx.h +++ b/include/linux/platform_data/mmc-esdhc-imx.h @@ -46,5 +46,6 @@ struct esdhc_platform_data { bool support_vsel; unsigned int delay_line; unsigned int tuning_step; /* The delay cell steps in tuning procedure */ + unsigned int tuning_start_tap; /* The start delay cell point in tuning procedure */ }; #endif /* __ASM_ARCH_IMX_ESDHC_H */ -- cgit v1.2.3