From 7cc9ec9f2a3a92def752ed31253fa0b89484b39f Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Tue, 19 Apr 2016 16:21:16 -0700 Subject: Revert "mmc: core: Remove MMC_CLKGATE" This reverts commit 9eadcc0581a8ccaf4c2378aa1c193fb164304f1d. Clock gating is needed for Qualcomm Platforms hence reverting this upstream patch. Change-Id: I96ac0c1c7627e8e5c2d18782e2fc08608f0a7f91 Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 1 + include/linux/mmc/host.h | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index eb0151bac50c..fdd0779ccdfa 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -269,6 +269,7 @@ struct mmc_card { /* for byte mode */ #define MMC_QUIRK_NONSTD_SDIO (1<<2) /* non-standard SDIO card attached */ /* (missing CIA registers) */ +#define MMC_QUIRK_BROKEN_CLK_GATING (1<<3) /* clock gating the sdio bus will make card fail */ #define MMC_QUIRK_NONSTD_FUNC_IF (1<<4) /* SDIO card has nonstd function interfaces */ #define MMC_QUIRK_DISABLE_CD (1<<5) /* disconnect CD/DAT[3] resistor */ #define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */ diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 40025b28c1fb..2f0d67880f44 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -292,6 +292,18 @@ struct mmc_host { mmc_pm_flag_t pm_caps; /* supported pm features */ +#ifdef CONFIG_MMC_CLKGATE + int clk_requests; /* internal reference counter */ + unsigned int clk_delay; /* number of MCI clk hold cycles */ + bool clk_gated; /* clock gated */ + struct delayed_work clk_gate_work; /* delayed clock gate */ + unsigned int clk_old; /* old clock value cache */ + spinlock_t clk_lock; /* lock for clk fields */ + struct mutex clk_gate_mutex; /* mutex for clock gating */ + struct device_attribute clkgate_delay_attr; + unsigned long clkgate_delay; +#endif + /* host specific block data */ unsigned int max_seg_size; /* see blk_queue_max_segment_size */ unsigned short max_segs; /* see blk_queue_max_segments */ @@ -491,6 +503,26 @@ static inline int mmc_host_packed_wr(struct mmc_host *host) return host->caps2 & MMC_CAP2_PACKED_WR; } +#ifdef CONFIG_MMC_CLKGATE +void mmc_host_clk_hold(struct mmc_host *host); +void mmc_host_clk_release(struct mmc_host *host); +unsigned int mmc_host_clk_rate(struct mmc_host *host); + +#else +static inline void mmc_host_clk_hold(struct mmc_host *host) +{ +} + +static inline void mmc_host_clk_release(struct mmc_host *host) +{ +} + +static inline unsigned int mmc_host_clk_rate(struct mmc_host *host) +{ + return host->ios.clock; +} +#endif + static inline int mmc_card_hs(struct mmc_card *card) { return card->host->ios.timing == MMC_TIMING_SD_HS || -- cgit v1.2.3 From 9df78479e4fd99ed6502a8be222c0b00e6e6615b Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Wed, 27 Apr 2016 17:19:29 -0700 Subject: Revert "mmc: core: Remove the ->enable|disable() callbacks" This reverts commit 40433267331bc6b9d70d5cdd14bfa2c8e3e5f0ec as MSM platforms still needs ->enable/disable() callbacks. Conflicts: drivers/mmc/core/core.c Change-Id: Ifd986825c10f1475bfcdac37ea1f3b99e5f6daaf Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 2f0d67880f44..2b6159a85a15 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -80,6 +80,12 @@ struct mmc_ios { }; struct mmc_host_ops { + /* + * 'enable' is called when the host is claimed and 'disable' is called + * when the host is released. 'enable' and 'disable' are deprecated. + */ + int (*enable)(struct mmc_host *host); + int (*disable)(struct mmc_host *host); /* * It is optional for the host to implement pre_req and post_req in * order to support double buffering of requests (prepare one -- cgit v1.2.3 From 0c196acfcbb766a07151cfae76c2318eca661c40 Mon Sep 17 00:00:00 2001 From: Sujit Reddy Thumma Date: Wed, 19 Jun 2013 20:15:37 +0530 Subject: mmc: sdhci: Defer release of CPU DMA PM QoS vote in high load cases PM QoS vote of default value mean that the CPU is allowed to move into deepest low power mode whenever possible. Currently, if there are back-to-back MMC requests, with a short delay, the PM QoS vote to default value is done immediately which cause the immediate request to have high latency as the CPU might have idle'd and moved to deepest low power mode. To avoid this defer the PM QoS vote till a defined timeout (pm_qos_timeout_us), so that back-to-back requests may not suffer from additional latencies. In addition, if the load on MMC is low, the additional latency may be sustainable. Hence, aggressively release the vote in order to achieve additional power savings. CRs-Fixed: 501712 Change-Id: I82166b0ce9416eb0d519f7da26e5a96956093cb2 Signed-off-by: Sujit Reddy Thumma [subhashj@codeaurora.org: fixed minor merge conflict and fixed compilation errors] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 2b6159a85a15..1939cd47b3aa 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -79,6 +79,12 @@ struct mmc_ios { #define MMC_SET_DRIVER_TYPE_D 3 }; +/* states to represent load on the host */ +enum mmc_load { + MMC_LOAD_HIGH, + MMC_LOAD_LOW, +}; + struct mmc_host_ops { /* * 'enable' is called when the host is claimed and 'disable' is called @@ -150,6 +156,7 @@ struct mmc_host_ops { */ int (*multi_io_quirk)(struct mmc_card *card, unsigned int direction, int blk_size); + int (*notify_load)(struct mmc_host *, enum mmc_load); }; struct mmc_card; -- cgit v1.2.3 From c2037aa944ca2f3decbefa620d4392652b51f286 Mon Sep 17 00:00:00 2001 From: Sahitya Tummala Date: Tue, 20 Aug 2013 15:32:09 +0530 Subject: mmc: sdhci-msm: Fix issue with 1.8v switch sequence in 3.10 kernel The SD3.0 voltage switch sequence to 1.8v would involve stopping the SDCLK before changing the voltage level and with recent changes in 3.10 kernel, the peripheral clocks are also getting disabled instead of just stopping the clock to the card. This patch makes sure this doesn't happen by marking the flag card_clock_off in struct mmc_host before starting the voltage switch sequence and checking it in host controller driver. Change-Id: If62378ba1dd369e69524365a4421d57317c22ca2 Signed-off-by: Sahitya Tummala --- include/linux/mmc/host.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 1939cd47b3aa..63a10df66b87 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -404,6 +404,11 @@ struct mmc_host { } embedded_sdio_data; #endif + /* + * Set to 1 to just stop the SDCLK to the card without + * actually disabling the clock from it's source. + */ + bool card_clock_off; unsigned long private[0] ____cacheline_aligned; }; -- cgit v1.2.3 From eef1739c4479c2ad5a69daf8a4092da630a96136 Mon Sep 17 00:00:00 2001 From: Guoping Yu Date: Wed, 20 Aug 2014 16:42:55 +0800 Subject: mmc: sdhci: add support nonhotplug With some devices, SD card could not support hotplug as there is no cd-gpio, and also could not use polling way due to power comsumption. So add nonhotplug to meet such requirement and when SD card lost or removed manually, device will not crash until next reboot process to detect SD card. Change-Id: Ie8ea8ec57015f36689a119249003eeaa48391393 Signed-off-by: Guoping Yu [subhashj@codeaurora.org: fixed minor merge conflict] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 63a10df66b87..43796e98b324 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -302,6 +302,7 @@ struct mmc_host { #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) #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_NONHOTPLUG (1 << 25) /*Don't support hotplug*/ mmc_pm_flag_t pm_caps; /* supported pm features */ -- cgit v1.2.3 From 03dbfc78cfc416b57f246520f14a4566b7cc888e Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Wed, 3 Dec 2014 11:12:14 +0200 Subject: mmc: core: export mmc_host_may_gate_card function MMC Host driver might want to use the mmc_host_may_gate_card() API to know whether the clock can be gated to the card or not hence export this function for usage outside its current scope. Change-Id: I9ec4173063e2505eca179161cdf8cda033a3fd4b Signed-off-by: Subhash Jadavani [merez@codeaurora.org: fix trivial conflicts] Signed-off-by: Maya Erez --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 43796e98b324..4378be90366a 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -414,6 +414,7 @@ struct mmc_host { }; struct mmc_host *mmc_alloc_host(int extra, struct device *); +extern bool mmc_host_may_gate_card(struct mmc_card *); int mmc_add_host(struct mmc_host *); void mmc_remove_host(struct mmc_host *); void mmc_free_host(struct mmc_host *); -- cgit v1.2.3 From 40c3ea6a0ce412f38d19a998c55054a879ec1071 Mon Sep 17 00:00:00 2001 From: Sahitya Tummala Date: Thu, 13 Jun 2013 10:34:48 +0530 Subject: mmc: core: Fix MMC clock scaling in case of tuning failure When the clock scaling state is changed from MMC_LOAD_LOW to MMC_LOAD_HIGH, the clocks are first scaled up and then tuning is performed. But in case of tuning failure, the current code does nothing but still retain the previous clock scale stats (state and curr_freq within struct clk_scaling). Hence, correct it to scale down the clocks in case of tuning failure so that clock scaling stats reflect the correct status. This also helps proceed with data transfers at lower clock rate in such cases. Change-Id: I7e9379d1e3ddc863132af31019604c22a42f8d59 Signed-off-by: Sahitya Tummala [subhashj@codeaurora.org: fixed compilation error] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 4378be90366a..e173a6e3462e 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -405,6 +405,23 @@ struct mmc_host { } embedded_sdio_data; #endif + struct { + unsigned long busy_time_us; + unsigned long window_time; + unsigned long curr_freq; + unsigned long polling_delay_ms; + unsigned int up_threshold; + unsigned int down_threshold; + ktime_t start_busy; + bool enable; + bool initialized; + bool in_progress; + /* freq. transitions are not allowed in invalid state */ + bool invalid_state; + struct delayed_work work; + enum mmc_load state; + } clk_scaling; + /* * Set to 1 to just stop the SDCLK to the card without * actually disabling the clock from it's source. -- cgit v1.2.3 From 6b2e9c4ce0645fee95ba0aa24d7875706d9cfd04 Mon Sep 17 00:00:00 2001 From: Sujith Reddy Thumma Date: Thu, 17 Feb 2011 21:37:48 +0530 Subject: mmc: core: Fix race between runtime PM suspend and block requests There is a possible race with mmc_claim_host() in mmc_sd_suspend()/ mmc_suspend() and mmc_claim_host() in mmc_blk_issue_rq() when runtime pm is enabled. Fix this by blocking processing of requests until the previous runtime suspend is processed and then resume as part of msmsdcc_enable(). Previous fix has card detection failure as a side effect during resume. Change-Id: I9cb31269638d9db4e630eb22b973a5335af1bda4 Signed-off-by: Sujith Reddy Thumma [sboyd: Dropped msm driver change] Signed-off-by: Stephen Boyd [subhashj@codeaurora.org: fixed trivial merge conflict] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index e173a6e3462e..01ae900ef4bf 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -357,6 +357,7 @@ struct mmc_host { wait_queue_head_t wq; struct task_struct *claimer; /* task that has host claimed */ + struct task_struct *suspend_task; int claim_cnt; /* "claim" nesting count */ struct delayed_work detect; -- cgit v1.2.3 From abc814b36465209cbc31cc7094e61455cac5c78f Mon Sep 17 00:00:00 2001 From: Murali Palnati Date: Mon, 11 Apr 2011 18:05:58 +0530 Subject: mmc: sdio: Fix sdio_disable_wide to properly handle 8 bit bus width. Change-Id: I2e712f5d8f6ff8da9fdabe8cf30e378c560e067f Signed-off-by: Murali Palnati --- include/linux/mmc/sdio.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h index 17446d3c3602..2c274d0530d2 100644 --- a/include/linux/mmc/sdio.h +++ b/include/linux/mmc/sdio.h @@ -102,6 +102,7 @@ #define SDIO_BUS_WIDTH_1BIT 0x00 #define SDIO_BUS_WIDTH_RESERVED 0x01 #define SDIO_BUS_WIDTH_4BIT 0x02 +#define SDIO_BUS_WIDTH_8BIT 0x03 #define SDIO_BUS_ECSI 0x20 /* Enable continuous SPI interrupt */ #define SDIO_BUS_SCSI 0x40 /* Support continuous SPI interrupt */ -- cgit v1.2.3 From 267e3b25f4327741a6790bc957b99afd1e4c9e4b Mon Sep 17 00:00:00 2001 From: Sujith Reddy Thumma Date: Mon, 20 Dec 2010 16:27:20 +0530 Subject: mmc: core: Determine correct access mode for eMMC cards by reading OCR MMC core reads SEC_COUNT information from EXT_CSD register and assumes that the card supports sector access mode. Some eMMC cards (<=2GB) do not support this mode even though they have SEC_COUNT value defined, causing failure while populating extended partitions. Sector/Byte access mode information is stored in OCR register. Hence, read OCR bit 30 and then confirm it with SEC_COUNT value to know whether the card supports sector access mode or byte access mode. Change-Id: Ifdfff35309e8667cd2c2ac2761b9a708d5b785d3 Signed-off-by: Sujith Reddy Thumma --- include/linux/mmc/mmc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 5b085532fc2d..6f5b437311c2 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -165,6 +165,7 @@ struct _mmc_csd { * OCR bits are mostly in host.h */ #define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */ +#define MMC_CARD_SECTOR_ADDR 0x40000000 /* Card supports sectors */ /* * Card Command Classes (CCC) -- cgit v1.2.3 From 6e40d1440803a1ad8aff848f151a848b91c88188 Mon Sep 17 00:00:00 2001 From: Sujit Reddy Thumma Date: Wed, 3 Dec 2014 18:10:07 +0200 Subject: mmc: core: Export mmc_set_ios so that host drivers can use it mmc_set_ios() is used by host drivers during suspend/resume routines in indirect way i.e., by calling host->ops->set_ios(). But now with MMC_CLKGATE enabled, mmc_set_ios() also updates host->clk_gated flag. So export this API so that host controller drivers can use it. Change-Id: Ib0c177635bb8d87ba68c98e08b8d940c73f2b80c Signed-off-by: Sujit Reddy Thumma [merez@codeaurora.org: fix trivial conflicts] Signed-off-by: Maya Erez --- include/linux/mmc/core.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index f7b930b735fc..c5f305249919 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -161,6 +161,7 @@ extern void mmc_release_host(struct mmc_host *host); extern void mmc_get_card(struct mmc_card *card); extern void mmc_put_card(struct mmc_card *card); +extern void mmc_set_ios(struct mmc_host *host); extern int mmc_flush_cache(struct mmc_card *); extern int mmc_detect_card_removed(struct mmc_host *host); -- cgit v1.2.3 From 0f618d04ba4734411cebfdf2f3f2dbcb47326e0c Mon Sep 17 00:00:00 2001 From: Aparna Mallavarapu Date: Fri, 11 Jun 2010 18:13:05 +0530 Subject: mmc: Add profiling code to measure performance at MMC layers. Profiling code is added to measure read, write times for the MMC requests at various MMC layers. Profiling is done at the MMC queue and at the driver level. This information can be viewed through a sysfs entry called perf. Change-Id: I7c65bfe25a1f7774e3a9abf1f9539e690b3718ec Signed-off-by: Aparna Mallavarapu Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflict] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 01ae900ef4bf..30d33363079b 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -428,6 +428,22 @@ struct mmc_host { * actually disabling the clock from it's source. */ bool card_clock_off; + +#ifdef CONFIG_MMC_PERF_PROFILING + struct { + + unsigned long rbytes_mmcq; /* Rd bytes MMC queue */ + unsigned long wbytes_mmcq; /* Wr bytes MMC queue */ + unsigned long rbytes_drv; /* Rd bytes MMC Host */ + unsigned long wbytes_drv; /* Wr bytes MMC Host */ + ktime_t rtime_mmcq; /* Rd time MMC queue */ + ktime_t wtime_mmcq; /* Wr time MMC queue */ + ktime_t rtime_drv; /* Rd time MMC Host */ + ktime_t wtime_drv; /* Wr time MMC Host */ + ktime_t start; + } perf; +#endif + unsigned long private[0] ____cacheline_aligned; }; -- cgit v1.2.3 From 9a092183816a05f802ce3d4d7815b214413d6ad8 Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Sun, 25 Mar 2012 11:15:41 +0530 Subject: mmc: core: capture performance numbers only when asked Currently performance numbers are captured for each SDCC transfers unconditionally which may add the overhead and could reduce the SDCC read/write throughput numbers. This change adds additional control for enabling/disabling the capturing of performance numbers at runtime. We already have sysfs entry named "perf" for msm sdcc devices. Currently setting this entry to 0 clears the performance statistics. But now we are changing the definition of this entry as mentioned below: Disable performance capturing and clear the performance statistics: "echo 0 > /sys/devices/platform/msm_sdcc./perf" Enable performance capturing: "echo 1 > /sys/devices/platform/msm_sdcc./perf" CRs-fixed: 345170 Change-Id: I3ab9288fd87cc8a8ada6c0c3d066cac4f68d79b7 Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 30d33363079b..0600ae0d3cb5 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -442,6 +442,7 @@ struct mmc_host { ktime_t wtime_drv; /* Wr time MMC Host */ ktime_t start; } perf; + bool perf_enable; #endif unsigned long private[0] ____cacheline_aligned; -- cgit v1.2.3 From 0513b6cb1ebfc6b3eb505842f4b5ffffce231351 Mon Sep 17 00:00:00 2001 From: Pratibhasagar V Date: Wed, 3 Dec 2014 18:26:42 +0200 Subject: mmc: quirks: Fix data timeout values for certain SanDisk eMMC cards Some INAND MCP devices advertise incorrect data timeout values. This leads to data timeout errors on the platform. So, add a quirk for such devices to facilitate proper functionality. CRs-Fixed: 355347 Change-Id: If4fdd2724dc407450da8529222efca7ee94f50df Signed-off-by: Pratibhasagar V [merez@codeaurora.org: fix num of quirk to an additional quirk on 3.14] Signed-off-by: Maya Erez [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index fdd0779ccdfa..d89132c1b067 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -280,6 +280,8 @@ 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 */ + /* byte mode */ +#define MMC_QUIRK_INAND_DATA_TIMEOUT (1<<13) /* For incorrect data timeout */ unsigned int erase_size; /* erase size in sectors */ -- cgit v1.2.3 From 357f7f515e66f86627ad7f3dfd04263ebfb775f9 Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Tue, 22 May 2012 22:59:54 +0530 Subject: mmc: host: remove mmcq performance numbers statistics mmcq performance numbers are not captured since asynchronous MMC request support got added in MMC block driver. So printing out these numbers (which are all zeros) just adds confusion. This patch removes the printing of mmcq performance numbers statistics. CRs-Fixed: 364206 Change-Id: I7213b11c8e9e055894c9902af7e975de3be1c519 Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 0600ae0d3cb5..996969baca0a 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -432,12 +432,8 @@ struct mmc_host { #ifdef CONFIG_MMC_PERF_PROFILING struct { - unsigned long rbytes_mmcq; /* Rd bytes MMC queue */ - unsigned long wbytes_mmcq; /* Wr bytes MMC queue */ unsigned long rbytes_drv; /* Rd bytes MMC Host */ unsigned long wbytes_drv; /* Wr bytes MMC Host */ - ktime_t rtime_mmcq; /* Rd time MMC queue */ - ktime_t wtime_mmcq; /* Wr time MMC queue */ ktime_t rtime_drv; /* Rd time MMC Host */ ktime_t wtime_drv; /* Wr time MMC Host */ ktime_t start; -- cgit v1.2.3 From fd7c52accff9a54a6ce2e82f06fb50ad22d775e2 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Fri, 27 Jul 2012 18:10:19 +0530 Subject: mmc: block: do not query the sd card if a fault is injected When the fault injection framework introduces an error to the data block, the current code queries the SD card to find the number of blocks actually programmed. This value would be as requested by the generic block layer. So the entire request would be completed. Say, request 0 is pulled from queue and submitted. When this is being processed, request 1 is pulled from queue and prepared. Request 0 though is successful, fault-injection framework injects an error and modifies the bytes_xferred variable to a random value less than requested transfer. Request 1 is not processed and during the handling of error, the SD card is queried for the actual bytes programmed. This would be the correct value. Thus blk_end_request would complete this request and the control would return to fetch request 2. In this process, request 1 is not processed at all and the application waits indefinitely for request 1 to be processed. No further requests are issued to the queue. This patch identifies, if the fault injection-framework has inserted an error to this request and doesn't query the card and uses bytes_xferred to complete the request. Change-Id: I496802e244745bc7550402027a594d967cf7b756 Signed-off-by: Asutosh Das [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/core.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index c5f305249919..0c2f98ba1d84 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -93,6 +93,7 @@ struct mmc_data { int sg_count; /* mapped sg entries */ struct scatterlist *sg; /* I/O scatter list */ s32 host_cookie; /* host private data */ + bool fault_injected; /* fault injected */ }; struct mmc_host; -- cgit v1.2.3 From 86dc987a4fc46b6fdad7cae3c28993e852567e84 Mon Sep 17 00:00:00 2001 From: Tatyana Brokhman Date: Wed, 3 Dec 2014 23:38:06 +0200 Subject: mmc: block: Add write packing control The write packing control will ensure that read requests latency is not increased due to long write packed commands. The trigger for enabling the write packing is managing to pack several write requests. The number of potential packed requests that will trigger the packing can be configured via sysfs by writing the required value to: /sys/block//num_wr_reqs_to_start_packing. The trigger for disabling the write packing is fetching a read request. Change-Id: I22e8ab04cd9aca220678784c39306068a0996790 Signed-off-by: Maya Erez Signed-off-by: Tatyana Brokhman [merez@codeaurora.org: fixed trivial conflicts] Signed-off-by: Maya Erez [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 996969baca0a..1f4c2cc72b8c 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -302,6 +302,7 @@ struct mmc_host { #define MMC_CAP2_HSX00_1_2V (MMC_CAP2_HS200_1_2V_SDR | MMC_CAP2_HS400_1_2V) #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_PACKED_WR_CONTROL (1 << 19) /* Allow write packing control */ #define MMC_CAP2_NONHOTPLUG (1 << 25) /*Don't support hotplug*/ mmc_pm_flag_t pm_caps; /* supported pm features */ -- cgit v1.2.3 From a37b4470259d3ef6e523b296775198de64e43362 Mon Sep 17 00:00:00 2001 From: Tatyana Brokhman Date: Sun, 7 Oct 2012 10:33:13 +0200 Subject: mmc: block: Add MMC write packing statistics The write packing statistics are used for the packed commands unit tests in order to determine test success or failure Change-Id: I5eea513991c794543fbb3d009d8b7db0b0912fc5 Signed-off-by: Maya Erez Signed-off-by: Tatyana Brokhman [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index d89132c1b067..8c70e624325b 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -218,6 +218,26 @@ enum mmc_blk_status { MMC_BLK_NEW_REQUEST, }; +enum mmc_packed_stop_reasons { + EXCEEDS_SEGMENTS = 0, + EXCEEDS_SECTORS, + WRONG_DATA_DIR, + FLUSH_OR_DISCARD, + EMPTY_QUEUE, + REL_WRITE, + THRESHOLD, + LARGE_SEC_ALIGN, + MAX_REASONS, +}; + +struct mmc_wr_pack_stats { + u32 *packing_events; + u32 pack_stop_reason[MAX_REASONS]; + spinlock_t lock; + bool enabled; + bool print_in_read; +}; + /* The number of MMC physical partitions. These consist of: * boot partitions (2), general purpose partitions (4) and * RPMB partition (1) in MMC v4.4. @@ -316,6 +336,8 @@ struct mmc_card { struct dentry *debugfs_root; struct mmc_part part[MMC_NUM_PHY_PARTITION]; /* physical partitions */ unsigned int nr_parts; + + struct mmc_wr_pack_stats wr_pack_stats; /* packed commands stats*/ }; /* @@ -534,5 +556,8 @@ extern void mmc_unregister_driver(struct mmc_driver *); extern void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table); +extern struct mmc_wr_pack_stats *mmc_blk_get_packed_statistics( + struct mmc_card *card); +extern void mmc_blk_init_packed_statistics(struct mmc_card *card); #endif /* LINUX_MMC_CARD_H */ -- cgit v1.2.3 From baf82d92c551c8d87e124ead42e9b603a9bd9b1b Mon Sep 17 00:00:00 2001 From: Sujit Reddy Thumma Date: Thu, 4 Dec 2014 09:57:23 +0200 Subject: mmc: core: Add load based clock scaling support The SD3.0/eMMC4.5/SDIO3.0 cards can support clock rates upto 200MHz (SDR104 or HS200 bus speed modes). For some workloads like video playback it isn't necessary for these cards to run at such high speed. Running at lower frequency, say 50MHz, in such cases can still meet the deadlines for data transfers. Scaling down the clock frequency dynamically has huge power savings not only because the bus is running at lower frequency but also has an advantage of scaling down the system core voltage, if supported. Provide an ondemand clock scaling support similar to cpufreq ondemand governor having two thresholds, up_threshold and down_threshold to decide whether to increase the frequency or scale it down respectively. The sampling interval is in the order of milliseconds and should be chosen by host drivers that enable MMC_CAP2_CLK_SCALE capability to take advantage of clock scaling. The sampling interval mainly depends on the the clock switching delays and hence a host driver decision. If sampling interval is too low frequent switching of frequencies can lead to high power consumption and if sampling interval is too high, the clock scaling logic would take long time to realize that the underlying hardware (controller and card) is busy and scale up the clocks. Change-Id: I22a5054beec41b0b66b3bf030ddfcf284de448b3 Signed-off-by: Sujit Reddy Thumma [merez@codeaurora.org: fixed conflicts due to changes in 3.14] Signed-off-by: Maya Erez [venkatg@codeaurora.org: runtime pm related changes to accommodate pm framework from 3.14 kernel] Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed merge conflicts and fixed compilation errors] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 1f4c2cc72b8c..dd68bc9a805d 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -156,6 +156,10 @@ struct mmc_host_ops { */ int (*multi_io_quirk)(struct mmc_card *card, unsigned int direction, int blk_size); + + unsigned long (*get_max_frequency)(struct mmc_host *host); + unsigned long (*get_min_frequency)(struct mmc_host *host); + int (*notify_load)(struct mmc_host *, enum mmc_load); }; @@ -303,6 +307,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_PACKED_WR_CONTROL (1 << 19) /* Allow write packing control */ +#define MMC_CAP2_CLK_SCALE (1 << 20) /* Allow dynamic clk scaling */ #define MMC_CAP2_NONHOTPLUG (1 << 25) /*Don't support hotplug*/ mmc_pm_flag_t pm_caps; /* supported pm features */ @@ -407,23 +412,6 @@ struct mmc_host { } embedded_sdio_data; #endif - struct { - unsigned long busy_time_us; - unsigned long window_time; - unsigned long curr_freq; - unsigned long polling_delay_ms; - unsigned int up_threshold; - unsigned int down_threshold; - ktime_t start_busy; - bool enable; - bool initialized; - bool in_progress; - /* freq. transitions are not allowed in invalid state */ - bool invalid_state; - struct delayed_work work; - enum mmc_load state; - } clk_scaling; - /* * Set to 1 to just stop the SDCLK to the card without * actually disabling the clock from it's source. @@ -441,7 +429,19 @@ struct mmc_host { } perf; bool perf_enable; #endif - + struct { + unsigned long busy_time_us; + unsigned long window_time; + unsigned long curr_freq; + unsigned long polling_delay_ms; + unsigned int up_threshold; + unsigned int down_threshold; + ktime_t start_busy; + bool enable; + bool initialized; + bool in_progress; + struct delayed_work work; + } clk_scaling; unsigned long private[0] ____cacheline_aligned; }; -- cgit v1.2.3 From 62649ebdb6dd7a6e4b558dcfd23b32212ff685e7 Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Thu, 4 Dec 2014 15:07:32 +0200 Subject: mmc: core: interrupt Background Operations if it takes too long Currently we have 4 mins timeout for the blocking BKOPs to complete but we have seen instances where card is surprisingly taking even longer time to complete background operations. If card doesn't complete the BKOPs within specified timeout, we will send the HPI command to interrupt the ongoing BKOPs. Change-Id: I5df81bdfd9b19bee30a394ee0ff4390b292691d0 Signed-off-by: Subhash Jadavani [merez@codeaurora.org: fix conflicts due to changes in 3.14] Signed-off-by: Maya Erez --- include/linux/mmc/core.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 0c2f98ba1d84..ba296ab25899 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -67,6 +67,8 @@ struct mmc_command { unsigned int busy_timeout; /* busy detect timeout in ms */ /* Set this flag only for blocking sanitize request */ bool sanitize_busy; + /* Set this flag only for blocking bkops request */ + bool bkops_busy; struct mmc_data *data; /* data segment associated with cmd */ struct mmc_request *mrq; /* associated request */ -- cgit v1.2.3 From 23bf7111217b01b45af465f2cb4cf4bf37c0842b Mon Sep 17 00:00:00 2001 From: Maya Erez Date: Thu, 4 Dec 2014 15:13:59 +0200 Subject: mmc: do not pack random requests Packed commands causes higher latency since the completion of each request is sent to the upper layer upon completion of the complete packed request. The benefit from this feature is card dependent. Some of the card vendors do not have any benefit from using packed commands for random requests. In case there is no benefit in random requests packing, it is better to disable the packing to prevent this high latency. This patch also add the new stop packing reason to the write packing statistics. Change-Id: I141887dcef2ceee14848634cc27c3c85f8edc7a5 Signed-off-by: Maya Erez [merez@codeaurora.org: fix conflicts due to removal of BKOPS] Signed-off-by: Maya Erez --- include/linux/mmc/card.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 8c70e624325b..01fe9263d2f2 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -227,6 +227,7 @@ enum mmc_packed_stop_reasons { REL_WRITE, THRESHOLD, LARGE_SEC_ALIGN, + RANDOM, MAX_REASONS, }; -- cgit v1.2.3 From 93896acd78892518724a2a4f2342bc85da1d74f2 Mon Sep 17 00:00:00 2001 From: Oluwafemi Adeyemi Date: Thu, 3 Jan 2013 11:32:53 -0800 Subject: mmc: Keep track of current hard partition eMMC may have several hard partitions such as BOOT and RPMB in addition to the main USER partition. On resume(if card is reinitialized), the current hard partition is always switched to the default USER partition. But this switch to default partition is not propagated to the MMC block driver, which may have set the hard partition to any partition(BOOT/RPMB) other than USER before suspend. After resume, the MMC block driver still assumes it is accessing the previously set partition(BOOT/RPMB), and instead overwrites the USER partition(the current selected partition on the eMMC device). To prevent this, make MMC block driver aware of the partition switches done as part of card reinitialization. CRs-Fixed: 439313 Change-Id: I3e959101a1c56c1e6631da3d660f4b914e100503 Signed-off-by: Oluwafemi Adeyemi Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 01fe9263d2f2..20630f657db5 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -337,6 +337,7 @@ struct mmc_card { struct dentry *debugfs_root; struct mmc_part part[MMC_NUM_PHY_PARTITION]; /* physical partitions */ unsigned int nr_parts; + unsigned int part_curr; struct mmc_wr_pack_stats wr_pack_stats; /* packed commands stats*/ }; -- cgit v1.2.3 From 8cd10b13a9bd1d815f69a4bd1a49d11972091a0d Mon Sep 17 00:00:00 2001 From: Konstantin Dorfman Date: Tue, 5 Feb 2013 16:26:19 +0200 Subject: mmc: block: do not pack REQ_FUA request This change will prevent packing of a request marked with REQ_FUA flag, because it has the same semantics as REQ_FLUSH. Also packing statistics are updated with FUA stop reason. Change-Id: Iaad37044ec43f93e898ed0c011b0bce7b91ae13d Signed-off-by: Konstantin Dorfman --- include/linux/mmc/card.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 20630f657db5..04a6c02d7b32 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -228,6 +228,7 @@ enum mmc_packed_stop_reasons { THRESHOLD, LARGE_SEC_ALIGN, RANDOM, + FUA, MAX_REASONS, }; -- cgit v1.2.3 From b4b98fb480f72639d3a4166cdb2f1015b4c331f9 Mon Sep 17 00:00:00 2001 From: Sujit Reddy Thumma Date: Thu, 14 Feb 2013 08:13:52 +0530 Subject: mmc: core: Log MMC clock frequency transitions Use kernel's ftrace support to capture MMC clock frequency transitions which can be useful for debugging issues related to power consumption. Usage: mount -t debugfs none /sys/kernel/debug echo 1 > /sys/kernel/debug/tracing/events/mmc/mmc_clk/enable cat /sys/kernel/debug/tracing/trace_pipe Change-Id: I25c4ee39dcbe30e7665902a9f723a5a421b55ca3 Signed-off-by: Sujit Reddy Thumma --- include/linux/mmc/host.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index dd68bc9a805d..246151e79477 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -23,6 +23,8 @@ struct mmc_ios { unsigned int clock; /* clock rate */ + unsigned int old_rate; /* saved clock rate */ + unsigned long clk_ts; /* time stamp of last updated clock */ unsigned short vdd; /* vdd stores the bit number of the selected voltage range from below. */ -- cgit v1.2.3 From 2023cd8d36564268d3859b64a61b94e9791b2d5f Mon Sep 17 00:00:00 2001 From: Sujit Reddy Thumma Date: Thu, 4 Dec 2014 16:03:03 +0200 Subject: mmc: core: Add support for notifying host driver while scaling clocks Host drivers can participate in clock scaling by registering ->notify_load host operation, which allows host driver to carry out platform specific operations for further power savings or increasing throughput based on whether load is LOW or HIGH respectively. This can be applicable to non-ultra high speed cards as well so remove the check for ultra high speed cards to initialize clock scaling. Change-Id: Icaab9520135e384f5470db68b2f25c5cdce5663a Signed-off-by: Sujit Reddy Thumma [merez:codeaurora@org: fix conflicts due to removal of stop transmission] Signed-off-by: Maya Erez [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 246151e79477..959d52b324ec 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -443,6 +443,7 @@ struct mmc_host { bool initialized; bool in_progress; struct delayed_work work; + enum mmc_load state; } clk_scaling; unsigned long private[0] ____cacheline_aligned; }; -- cgit v1.2.3 From 83d95c50fb7c138177290641436a926ed4700e9b Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Thu, 4 Dec 2014 21:42:45 +0200 Subject: mmc: sdio: enable asynchronous interrupt support in 4-bit mode SDIO 3.0 specification has added the support for asynchronous interrupt period during which card allows the clock to be gated off. Host needs to first read the "Support Asynchronous Interrupt" bit in CCCR register space to check if the card supports the feature or not. If yes and if the host wants to enable the feature, host needs to write '1' to "Enable Asynchronous Interrupt" bit in CCCR register space. This change allows the host controller driver to control whether to enable the asynchronous interrupt in card or not and if the asynchronous interrupt is enabled then clock gating feature would be enabled for such cards. Change-Id: I678cffb63af6a2013640a5eafa6ce9bfad8a51d6 Signed-off-by: Subhash Jadavani [merez@codeaurora.org: fix CAPS2 index] Signed-off-by: Maya Erez [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 3 ++- include/linux/mmc/host.h | 2 ++ include/linux/mmc/sdio.h | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 04a6c02d7b32..968bf8b113e6 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -189,7 +189,8 @@ struct sdio_cccr { wide_bus:1, high_power:1, high_speed:1, - disable_cd:1; + disable_cd:1, + async_intr_sup:1; }; struct sdio_cis { diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 959d52b324ec..8b459bdcc797 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -310,6 +310,8 @@ 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_PACKED_WR_CONTROL (1 << 19) /* Allow write packing control */ #define MMC_CAP2_CLK_SCALE (1 << 20) /* Allow dynamic clk scaling */ +/* Allows Asynchronous SDIO irq while card is in 4-bit mode */ +#define MMC_CAP2_ASYNC_SDIO_IRQ_4BIT_MODE (1 << 21) #define MMC_CAP2_NONHOTPLUG (1 << 25) /*Don't support hotplug*/ mmc_pm_flag_t pm_caps; /* supported pm features */ diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h index 2c274d0530d2..3fc07d701cd1 100644 --- a/include/linux/mmc/sdio.h +++ b/include/linux/mmc/sdio.h @@ -164,6 +164,10 @@ #define SDIO_DTSx_SET_TYPE_A (1 << SDIO_DRIVE_DTSx_SHIFT) #define SDIO_DTSx_SET_TYPE_C (2 << SDIO_DRIVE_DTSx_SHIFT) #define SDIO_DTSx_SET_TYPE_D (3 << SDIO_DRIVE_DTSx_SHIFT) + +#define SDIO_CCCR_INTERRUPT_EXTENSION 0x16 +#define SDIO_SUPPORT_ASYNC_INTR (1<<0) +#define SDIO_ENABLE_ASYNC_INTR (1<<1) /* * Function Basic Registers (FBR) */ -- cgit v1.2.3 From 15209ec725e499e1e53b6e1104b6249e0430bf94 Mon Sep 17 00:00:00 2001 From: Tatyana Brokhman Date: Thu, 4 Dec 2014 22:03:42 +0200 Subject: mmc: Add long power off notification support At the moment only POWER_OFF_SHORT is sent to the device in case the host is suspended. This patch adds the support of sending POWER_OFF_LONG notification in case the device is powered off. According to device vendors the POWER_OFF_LONG notification will shorten the initialization time of the eMMC card during next boot up. Change-Id: I3c6f224398450cf10463cbb316613fd430d1e8d2 Signed-off-by: Tatyana Brokhman Signed-off-by: Sujit Reddy Thumma [merez@codeaurora.org: fix conflicts as some of the code was already included] Signed-off-by: Maya Erez [venkatg@codeaurora.org: Remove PM related code] Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 968bf8b113e6..c18556450f08 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -13,6 +13,7 @@ #include #include #include +#include struct mmc_cid { unsigned int manfid; @@ -342,6 +343,8 @@ struct mmc_card { unsigned int part_curr; struct mmc_wr_pack_stats wr_pack_stats; /* packed commands stats*/ + struct notifier_block reboot_notify; + bool issue_long_pon; }; /* @@ -563,5 +566,5 @@ extern void mmc_fixup_device(struct mmc_card *card, extern struct mmc_wr_pack_stats *mmc_blk_get_packed_statistics( struct mmc_card *card); extern void mmc_blk_init_packed_statistics(struct mmc_card *card); - +extern int mmc_send_long_pon(struct mmc_card *card); #endif /* LINUX_MMC_CARD_H */ -- cgit v1.2.3 From 3c0c23354a0c200f2f52c4be8de85f8949daa0c4 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Thu, 4 Dec 2014 23:05:50 +0200 Subject: mmc: core: add wakeup functionality to sdio cards This patch initializes wakeup source if the detected card is a sdio card and enables the wakeup capability. Platform drivers would have to invoke: * pm_wakeup_event on this card device to signal a wakeup * corresponding pm_relax have to be invoked Change-Id: Ic8d5c98073e8ed3f676eb42fc0ce1f13a11cb40f Signed-off-by: Asutosh Das [merez@codeaurora.org: fix conflicts due to different PM in 3.14] Signed-off-by: Maya Erez [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 8b459bdcc797..82cb8b901e8b 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -218,6 +218,12 @@ struct mmc_supply { struct regulator *vqmmc; /* Optional Vccq supply */ }; +enum dev_state { + DEV_SUSPENDING = 1, + DEV_SUSPENDED, + DEV_RESUMED, +}; + struct mmc_host { struct device *parent; struct device class_dev; @@ -447,6 +453,7 @@ struct mmc_host { struct delayed_work work; enum mmc_load state; } clk_scaling; + enum dev_state dev_status; unsigned long private[0] ____cacheline_aligned; }; -- cgit v1.2.3 From 0c758bb6b206df527df06eb2e2fb2a784b063148 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Tue, 1 Oct 2013 16:03:16 +0530 Subject: mmc: core: add clock-scaling support to HS400 cards This patch adds clock scaling support to HS400 cards. Scaling down to 52MHz from HS400 involves: - switching the bus-speed mode to HS at 52MHz Scaling up to HS400 would require all of the initialization process upto HS400 mode selection. Change-Id: I8196d6666bcc0ef327659253df53a17792fa51f7 Signed-off-by: Asutosh Das Signed-off-by: Krishna Konda [venkatg@codeaurora.org: fix mmc_select_hs args and MAX_DTRs as used in 3.14 kernel] Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index c18556450f08..258efa6c2edc 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -345,6 +345,7 @@ struct mmc_card { struct mmc_wr_pack_stats wr_pack_stats; /* packed commands stats*/ struct notifier_block reboot_notify; bool issue_long_pon; + u8 cached_ext_csd; }; /* -- cgit v1.2.3 From 02bf86d2b1559651b6f86771167f00b0037ca06a Mon Sep 17 00:00:00 2001 From: Sujit Reddy Thumma Date: Thu, 5 Dec 2013 19:35:43 +0530 Subject: mmc: core: fix buffer overflow during memcpy of ext_csd Fix buffer overflow while caching the mmc ext_csd content. Also, to avoid duplicate allocation keep the allocated ext_csd till the card is removed. CRs-Fixed: 583929 Change-Id: I5d69e37f6fd1f5249479d454c353be050df40b6d Signed-off-by: Sujit Reddy Thumma [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 258efa6c2edc..809ba6f07147 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -345,7 +345,7 @@ struct mmc_card { struct mmc_wr_pack_stats wr_pack_stats; /* packed commands stats*/ struct notifier_block reboot_notify; bool issue_long_pon; - u8 cached_ext_csd; + u8 *cached_ext_csd; }; /* -- cgit v1.2.3 From 3332d5a9e4fe04b14c3008d432a031c22a38bd2c Mon Sep 17 00:00:00 2001 From: Sujit Reddy Thumma Date: Tue, 9 Dec 2014 12:55:38 +0200 Subject: mmc: core: Fix clock frequency transitions during invalid states eMMC and SD card specifications restrict the usage of a class of commands while commands in other class are in progress. For example, during erase operations the SD/eMMC spec. allows only CMD35, CMD36, CMD38. If clock scaling is enabled and decide to scale up the clocks it may be possible that CMD19/21 tuning commands are sent in between erase commands, which is illegal as per specification. Fix such illegal transactions to the card and also make clock scaling statistics accountable only for read/write commands instead of time consuming commands, like CMD38 erase, where transactions are independent of bus frequency. Change-Id: Iffba175787837e7f95bde8970f19d0f0f9d7d67d Signed-off-by: Sujit Reddy Thumma [merez@codeaurora.org: fix conflicts as mmc_update_clk_scaling is missing on 3.14] Signed-off-by: Maya Erez --- include/linux/mmc/host.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 82cb8b901e8b..ff861fd2517b 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -450,6 +450,8 @@ struct mmc_host { bool enable; bool initialized; bool in_progress; + /* freq. transitions are not allowed in invalid state */ + bool invalid_state; struct delayed_work work; enum mmc_load state; } clk_scaling; -- cgit v1.2.3 From 58821ee5f6552ebfcf22e8a8ee00cf9da7aad947 Mon Sep 17 00:00:00 2001 From: Venkat Gopalakrishnan Date: Fri, 9 Jan 2015 15:11:57 -0800 Subject: mmc: core: Add workaround for hosts that need addtional tuning for HS400 Add a capability to identify hosts that need additional tuning for HS400 and perform a post tuning process that maybe needed for proper HS400 functionality. Change-Id: I3895aabddce4dbecb208e3c522957e656f37e30d Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index ff861fd2517b..fca8e4a04c3b 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -318,6 +318,8 @@ struct mmc_host { #define MMC_CAP2_CLK_SCALE (1 << 20) /* Allow dynamic clk scaling */ /* Allows Asynchronous SDIO irq while card is in 4-bit mode */ #define MMC_CAP2_ASYNC_SDIO_IRQ_4BIT_MODE (1 << 21) +/* Some hosts need additional tuning */ +#define MMC_CAP2_HS400_POST_TUNING (1 << 22) #define MMC_CAP2_NONHOTPLUG (1 << 25) /*Don't support hotplug*/ mmc_pm_flag_t pm_caps; /* supported pm features */ -- cgit v1.2.3 From 4f32644877e95bbd76894683fced2ef601a76eae Mon Sep 17 00:00:00 2001 From: Talel Shenhar Date: Tue, 10 Feb 2015 13:10:12 +0200 Subject: mmc: quirks: add support for quirks based on EXT_CSD_REV This change allows the usage of quirks based on the register value of EXT_CSD_REV. It was seen for several eMMC cards that same issues, such as data corruption while using cache, were relevant for all eMMC cards having the same EXT_CSD_REV value. This change allows us to distinguish between cards based on this register. Change-Id: I1663891c367a59b520bc505641c6c4ddad56fd1a Signed-off-by: Talel Shenhar --- include/linux/mmc/card.h | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 809ba6f07147..a9c756549c2f 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -386,19 +386,41 @@ struct mmc_fixup { /* SDIO-specfic fields. You can use SDIO_ANY_ID here of course */ u16 cis_vendor, cis_device; + /* MMC-specific field, You can use EXT_CSD_REV_ANY here of course */ + unsigned int ext_csd_rev; + void (*vendor_fixup)(struct mmc_card *card, int data); int data; }; +#define CID_MANFID_SANDISK 0x2 +#define CID_MANFID_TOSHIBA 0x11 +#define CID_MANFID_MICRON 0x13 +#define CID_MANFID_SAMSUNG 0x15 + #define CID_MANFID_ANY (-1u) #define CID_OEMID_ANY ((unsigned short) -1) #define CID_NAME_ANY (NULL) +#define EXT_CSD_REV_ANY (-1u) #define END_FIXUP { NULL } +/* extended CSD mapping to mmc version */ +enum mmc_version_ext_csd_rev { + MMC_V4_0, + MMC_V4_1, + MMC_V4_2, + MMC_V4_41 = 5, + MMC_V4_5, + MMC_V4_51 = MMC_V4_5, + MMC_V5_0, + MMC_V5_01 = MMC_V5_0, + MMC_V5_1 +}; + #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), \ @@ -409,23 +431,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 | \ -- cgit v1.2.3 From a89dfb1bbd09b7625eca50ce02448a517c7156c6 Mon Sep 17 00:00:00 2001 From: Talel Shenhar Date: Thu, 5 Feb 2015 14:44:15 +0200 Subject: mmc: quirks: add new quirk that allows HPI disable Certain cards might get broken when HPI feature is used. This patch allows host to avoid using HPI for such buggy cards by adding new quirk. As some of the other features like BKOPs/Cache are dependent on HPI feature, those features would also get disabled if HPI is disabled. Change-Id: I93a8810e4031eafcd44b5152296e065dc3330b63 Signed-off-by: Talel Shenhar --- include/linux/mmc/card.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index a9c756549c2f..a16fd1739371 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -306,6 +306,8 @@ struct mmc_card { #define MMC_QUIRK_TRIM_BROKEN (1<<12) /* Skip trim */ /* byte mode */ #define MMC_QUIRK_INAND_DATA_TIMEOUT (1<<13) /* For incorrect data timeout */ +#define MMC_QUIRK_BROKEN_HPI (1 << 14) /* For devices which gets */ + /* broken due to HPI feature */ unsigned int erase_size; /* erase size in sectors */ -- cgit v1.2.3 From 96c1215f259dc55a463dd0094a61f86798358f5a Mon Sep 17 00:00:00 2001 From: Talel Shenhar Date: Sun, 8 Feb 2015 13:36:57 +0200 Subject: mmc: block: avoid HPI for some Kingston cards Certain cards might get broken when HPI feature is used. This patch uses the HPI quirk to avoid the usage of HPI on Kingston MMC16G cards that have EXT_CSD_REV = 5 (mmc version 4.41) Change-Id: I4572eb9e71a281b56e25e5b4864d5777b16e2bc2 Signed-off-by: Talel Shenhar --- include/linux/mmc/card.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index a16fd1739371..4cab91c56616 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -399,6 +399,7 @@ struct mmc_fixup { #define CID_MANFID_TOSHIBA 0x11 #define CID_MANFID_MICRON 0x13 #define CID_MANFID_SAMSUNG 0x15 +#define CID_MANFID_KINGSTON 0x70 #define CID_MANFID_ANY (-1u) #define CID_OEMID_ANY ((unsigned short) -1) -- cgit v1.2.3 From 4a897cf6aa31fbb9e81dab20ac5f73515499b89d Mon Sep 17 00:00:00 2001 From: Talel Shenhar Date: Wed, 4 Feb 2015 17:59:23 +0200 Subject: mmc: quirks: add new quirk that allows Cache disable This change allows us to prevent cache enable for certain cards that have broken cache functionality. Change-Id: Iea3f8c8f4e5498a8742fa408a19e3e169d1fa8cb Signed-off-by: Talel Shenhar [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 4cab91c56616..c3e6fbfbcfab 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -308,6 +308,7 @@ struct mmc_card { #define MMC_QUIRK_INAND_DATA_TIMEOUT (1<<13) /* For incorrect data timeout */ #define MMC_QUIRK_BROKEN_HPI (1 << 14) /* For devices which gets */ /* broken due to HPI feature */ +#define MMC_QUIRK_CACHE_DISABLE (1 << 14) /* prevent cache enable */ unsigned int erase_size; /* erase size in sectors */ -- cgit v1.2.3 From 71e326e07801e6499e7e9c23b4b78b9b498e270a Mon Sep 17 00:00:00 2001 From: Sahitya Tummala Date: Fri, 8 May 2015 11:12:30 +0530 Subject: mmc: block: add req pointer to mmc request This is needed by ICE (Inline Crypto Engine) driver to get the ICE configuration data from the request. Change-Id: Ie69c64f4dc0c31290dec50d905e8b3d436c86d62 Signed-off-by: Sahitya Tummala Signed-off-by: Venkat Gopalakrishnan --- include/linux/mmc/core.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index ba296ab25899..07f96aa5ff6b 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -108,6 +108,7 @@ struct mmc_request { struct completion completion; void (*done)(struct mmc_request *);/* completion function */ struct mmc_host *host; + struct request *req; }; struct mmc_card; -- cgit v1.2.3 From f4a166292806342ea74935954a493650ec2cface Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Fri, 21 Mar 2014 11:14:51 +0530 Subject: mmc: core: Add support to read command queue parameters eMMC cards with EXT_CSD version >= 7, optionally support command queuing feature as defined by JEDEC eMMC5.1. Add support for probing command queue feature for such type of cards. Change-Id: I9454d0d6997ccbd1778a147354859467f4a9a7d3 Signed-off-by: Sujit Reddy Thumma Signed-off-by: Asutosh Das Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 2 ++ include/linux/mmc/mmc.h | 3 +++ 2 files changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index c3e6fbfbcfab..59ef4e717beb 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -119,6 +119,8 @@ struct mmc_ext_csd { u8 raw_pwr_cl_ddr_200_360; /* 253 */ u8 raw_bkops_status; /* 246 */ u8 raw_sectors[4]; /* 212 - 4 bytes */ + u8 cmdq_depth; /* 307 */ + u8 cmdq_support; /* 308 */ unsigned int feature_support; #define MMC_DISCARD_FEATURE BIT(0) /* CMD38 feature */ diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 6f5b437311c2..a85e7e3f9bb6 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -273,6 +273,9 @@ struct _mmc_csd { #define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */ #define EXT_CSD_PWR_CL_DDR_200_360 253 /* RO */ #define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */ +#define EXT_CSD_CMDQ_DEPTH 307 /* RO */ +#define EXT_CSD_CMDQ_SUPPORT 308 /* RO */ + #define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ #define EXT_CSD_SUPPORTED_MODE 493 /* RO */ #define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ #define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */ -- cgit v1.2.3 From ed9551c160f8c072a3db5d9a91810b599b86497a Mon Sep 17 00:00:00 2001 From: Dov Levenglick Date: Tue, 10 Mar 2015 16:00:56 +0200 Subject: mmc: add support for scheduling mmcqd on idle CPU In order to boost mmc performance on various platforms, add support for configuring whether set_wake_up_idle() should be called on the mmc queue thread (mmcqd). The decision will be set in each individual platform's dts file. CRs-Fixed: 787554 Change-Id: I3989d3f5b8228785e6d3bc49c7eb01ebf2fa2f38 Signed-off-by: Dov Levenglick [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index fca8e4a04c3b..2ba8ba249e00 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -458,6 +458,7 @@ struct mmc_host { enum mmc_load state; } clk_scaling; enum dev_state dev_status; + bool wakeup_on_idle; unsigned long private[0] ____cacheline_aligned; }; -- cgit v1.2.3 From ae479fa29fc8cc9fd3ab36dde46a0638da2a4fcc Mon Sep 17 00:00:00 2001 From: Talel Shenhar Date: Mon, 18 May 2015 12:12:48 +0300 Subject: mmc: core: devfreq: migrate to devfreq based clock scaling This change adds the use of devfreq to MMC. Both eMMC and SD card will use it. For some workloads, such as video playback, it isn't necessary for these cards to run at high speed. Running at lower frequency, for example 52MHz, in such cases can still meet the deadlines for data transfers. Scaling down the clock frequency dynamically has power savings not only because the bus is running at lower frequency but also has an advantage of scaling down the system core voltage, if supported. Provide an ondemand clock scaling support similar to the cpufreq ondemand governor having two thresholds, up_threshold and down_threshold to decide whether to increase the frequency or scale it down respectively. The sampling interval is in the order of milliseconds. If sampling interval is too low, frequent switching of frequencies can lead to high power consumption and if sampling interval is too high, the clock scaling logic would take long time to realize that the underlying hardware (controller and card) is busy and scale up the clocks. Change-Id: I58ddbd93648ded82b304411956e035fb353cd97e Signed-off-by: Talel Shenhar [subhashj@codeaurora.org: fixed trivial merge conflicts & compilation errors] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 4 +++ include/linux/mmc/host.h | 65 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 53 insertions(+), 16 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 59ef4e717beb..ae943ccb331e 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -275,6 +275,10 @@ struct mmc_card { struct mmc_host *host; /* the host this device belongs to */ struct device dev; /* the device */ u32 ocr; /* the current OCR setting */ + unsigned long clk_scaling_lowest; /* lowest scaleable + * frequency */ + unsigned long clk_scaling_highest; /* highest scaleable + * frequency */ unsigned int rca; /* relative card address of device */ unsigned int type; /* card type */ #define MMC_TYPE_MMC 0 /* MMC card */ diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 2ba8ba249e00..5afbac264ddd 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -224,9 +225,57 @@ enum dev_state { DEV_RESUMED, }; +/** + * struct mmc_devfeq_clk_scaling - main context for MMC clock scaling logic + * + * @lock: spinlock to protect statistics + * @devfreq: struct that represent mmc-host as a client for devfreq + * @devfreq_profile: MMC device profile, mostly polling interval and callbacks + * @ondemand_gov_data: struct supplied to ondemmand governor (thresholds) + * @state: load state, can be HIGH or LOW. used to notify mmc_host_ops callback + * @start_busy: timestamped armed once a data request is started + * @measure_interval_start: timestamped armed once a measure interval started + * @devfreq_abort: flag to sync between different contexts relevant to devfreq + * @skip_clk_scale_freq_update: flag that enable/disable frequency change + * @freq_table_sz: table size of frequencies supplied to devfreq + * @freq_table: frequencies table supplied to devfreq + * @curr_freq: current frequency + * @polling_delay_ms: polling interval for status collection used by devfreq + * @upthreshold: up-threshold supplied to ondemand governor + * @downthreshold: down-threshold supplied to ondemand governor + * @need_freq_change: flag indicating if a frequency change is required + * @clk_scaling_in_progress: flag indicating if there's ongoing frequency change + * @is_busy_started: flag indicating if a request is handled by the HW + * @enable: flag indicating if the clock scaling logic is enabled for this host + */ +struct mmc_devfeq_clk_scaling { + spinlock_t lock; + struct devfreq *devfreq; + struct devfreq_dev_profile devfreq_profile; + struct devfreq_simple_ondemand_data ondemand_gov_data; + enum mmc_load state; + ktime_t start_busy; + ktime_t measure_interval_start; + atomic_t devfreq_abort; + bool skip_clk_scale_freq_update; + int freq_table_sz; + u32 *freq_table; + unsigned long total_busy_time_us; + unsigned long target_freq; + unsigned long curr_freq; + unsigned long polling_delay_ms; + unsigned int upthreshold; + unsigned int downthreshold; + bool need_freq_change; + bool clk_scaling_in_progress; + bool is_busy_started; + bool enable; +}; + struct mmc_host { struct device *parent; struct device class_dev; + struct mmc_devfeq_clk_scaling clk_scaling; int index; const struct mmc_host_ops *ops; struct mmc_pwrseq *pwrseq; @@ -441,22 +490,6 @@ struct mmc_host { } perf; bool perf_enable; #endif - struct { - unsigned long busy_time_us; - unsigned long window_time; - unsigned long curr_freq; - unsigned long polling_delay_ms; - unsigned int up_threshold; - unsigned int down_threshold; - ktime_t start_busy; - bool enable; - bool initialized; - bool in_progress; - /* freq. transitions are not allowed in invalid state */ - bool invalid_state; - struct delayed_work work; - enum mmc_load state; - } clk_scaling; enum dev_state dev_status; bool wakeup_on_idle; unsigned long private[0] ____cacheline_aligned; -- cgit v1.2.3 From 6d1be7e42b9e5f2dbdf6e8c1909c20cdfa6edc02 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Thu, 21 May 2015 13:29:51 +0530 Subject: mmc: queue: initialization of command queue Command Queueing (CQ) feature is introduced to eMMC standard in revision 5.1. CQ includes new commands for issuing tasks to the device, for ordering the execution of previously issued tasks and for additional task management functions. The idea is to keep the legacy and CQ code as discrete as possible. Hence, a separate queue is created for CQ. The issuing path is non-blocking since several requests (max. 32) can be queued at a time. Change-Id: I5b48d1b3ed17585b907ec70ff7c8d583003ec9e1 Signed-off-by: Asutosh Das Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflicts & compilation error] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 5afbac264ddd..2324a76123cf 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -195,6 +195,23 @@ struct mmc_slot { void *handler_priv; }; + +/** + * mmc_cmdq_context_info - describes the contexts of cmdq + * @active_reqs requests being processed + * @curr_state state of cmdq engine + * @req_starved completion should invoke the request_fn since + * no tags were available + * @cmdq_ctx_lock acquire this before accessing this structure + */ +struct mmc_cmdq_context_info { + unsigned long active_reqs; /* in-flight requests */ + unsigned long curr_state; +#define CMDQ_STATE_ERR 0 + /* no free tag available */ + unsigned long req_starved; +}; + /** * mmc_context_info - synchronization details for mmc context * @is_done_rcv wake up reason was done request @@ -370,6 +387,7 @@ struct mmc_host { /* Some hosts need additional tuning */ #define MMC_CAP2_HS400_POST_TUNING (1 << 22) #define MMC_CAP2_NONHOTPLUG (1 << 25) /*Don't support hotplug*/ +#define MMC_CAP2_CMD_QUEUE (1 << 26) /* support eMMC command queue */ mmc_pm_flag_t pm_caps; /* supported pm features */ @@ -492,6 +510,7 @@ struct mmc_host { #endif enum dev_state dev_status; bool wakeup_on_idle; + struct mmc_cmdq_context_info cmdq_ctx; unsigned long private[0] ____cacheline_aligned; }; -- cgit v1.2.3 From ee66ddaa077507729c911f8a9cad2b3376fe8284 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Thu, 21 May 2015 13:43:24 +0530 Subject: mmc: core: Add command queue initialzation support Command Queueing (CQ) feature is introduced to eMMC standard in revision 5.1. CQ includes new commands for issuing tasks to the device, for ordering the execution of previously issued tasks and for additional task management functions. This patch adds initialization and enabling of command queue in the card and controller. If the card and the controller support CQ, then it is enabled. Change-Id: I92d893d1503396d4b00848813cc546fc263e77fd Signed-off-by: Asutosh Das Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 6 ++++++ include/linux/mmc/host.h | 6 ++++++ include/linux/mmc/mmc.h | 1 + 3 files changed, 13 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index ae943ccb331e..9885e75d196b 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -15,6 +15,8 @@ #include #include +#define MMC_CARD_CMDQ_BLK_SIZE 512 + struct mmc_cid { unsigned int manfid; char prod_name[8]; @@ -293,6 +295,7 @@ struct mmc_card { #define MMC_CARD_REMOVED (1<<4) /* card has been removed */ #define MMC_STATE_DOING_BKOPS (1<<5) /* card is doing BKOPS */ #define MMC_STATE_SUSPENDED (1<<6) /* card is suspended */ +#define MMC_STATE_CMDQ (1<<12) /* card is in cmd queue mode */ unsigned int quirks; /* card quirks */ #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ @@ -503,6 +506,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) #define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS) #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) +#define mmc_card_cmdq(c) ((c)->state & MMC_STATE_CMDQ) #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) @@ -513,6 +517,8 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS) #define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED) #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED) +#define mmc_card_set_cmdq(c) ((c)->state |= MMC_STATE_CMDQ) +#define mmc_card_clr_cmdq(c) ((c)->state &= ~MMC_STATE_CMDQ) /* * Quirk add/remove for MMC products. diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 2324a76123cf..a2fbb73996a7 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -88,6 +88,11 @@ enum mmc_load { MMC_LOAD_LOW, }; +struct mmc_cmdq_host_ops { + int (*enable)(struct mmc_host *host); + void (*disable)(struct mmc_host *host, bool soft); +}; + struct mmc_host_ops { /* * 'enable' is called when the host is claimed and 'disable' is called @@ -295,6 +300,7 @@ struct mmc_host { struct mmc_devfeq_clk_scaling clk_scaling; int index; const struct mmc_host_ops *ops; + const struct mmc_cmdq_host_ops *cmdq_ops; struct mmc_pwrseq *pwrseq; unsigned int f_min; unsigned int f_max; diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index a85e7e3f9bb6..71b5c75a0995 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -215,6 +215,7 @@ struct _mmc_csd { * EXT_CSD fields */ +#define EXT_CSD_CMDQ 15 /* R/W */ #define EXT_CSD_FLUSH_CACHE 32 /* W */ #define EXT_CSD_CACHE_CTRL 33 /* R/W */ #define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */ -- cgit v1.2.3 From fc4b531dfdca023ac59389e7acf24f21aa6074ed Mon Sep 17 00:00:00 2001 From: Venkat Gopalakrishnan Date: Fri, 29 May 2015 16:51:43 -0700 Subject: mmc: card: add read/write support in command queue mode Command queueing is defined in eMMC-5.1. It is designed for higher performance by ensuring upto 32 requests to be serviced at a time. Adds read/write support for CMDQ enabled devices. Change-Id: I136ddea8e5ca57eb4f85ca6e72c60001a7e24f78 Signed-off-by: Sujit Reddy Thumma Signed-off-by: Asutosh Das Signed-off-by: Konstantin Dorfman Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 2 ++ include/linux/mmc/core.h | 7 +++++++ include/linux/mmc/host.h | 22 ++++++++++++++++++++++ 3 files changed, 31 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 9885e75d196b..e7fdaff68d7e 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -358,6 +358,7 @@ struct mmc_card { struct notifier_block reboot_notify; bool issue_long_pon; u8 *cached_ext_csd; + bool cmdq_init; }; /* @@ -613,4 +614,5 @@ extern struct mmc_wr_pack_stats *mmc_blk_get_packed_statistics( struct mmc_card *card); extern void mmc_blk_init_packed_statistics(struct mmc_card *card); extern int mmc_send_long_pon(struct mmc_card *card); +extern void mmc_blk_cmdq_req_done(struct mmc_request *mrq); #endif /* LINUX_MMC_CARD_H */ diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 07f96aa5ff6b..8139a58e6d8e 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -108,11 +108,18 @@ struct mmc_request { struct completion completion; void (*done)(struct mmc_request *);/* completion function */ struct mmc_host *host; + struct mmc_cmdq_req *cmdq_req; struct request *req; }; struct mmc_card; struct mmc_async_req; +struct mmc_cmdq_req; + +extern void mmc_cmdq_post_req(struct mmc_host *host, struct mmc_request *mrq, + int err); +extern int mmc_cmdq_start_req(struct mmc_host *host, + struct mmc_cmdq_req *cmdq_req); extern int mmc_stop_bkops(struct mmc_card *); extern int mmc_read_bkops_status(struct mmc_card *); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index a2fbb73996a7..12b8d5505985 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -91,6 +91,9 @@ enum mmc_load { struct mmc_cmdq_host_ops { int (*enable)(struct mmc_host *host); void (*disable)(struct mmc_host *host, bool soft); + int (*request)(struct mmc_host *host, struct mmc_request *mrq); + void (*post_req)(struct mmc_host *host, struct mmc_request *mrq, + int err); }; struct mmc_host_ops { @@ -174,6 +177,25 @@ struct mmc_host_ops { struct mmc_card; struct device; +struct mmc_cmdq_req { + unsigned int cmd_flags; + u32 blk_addr; + /* active mmc request */ + struct mmc_request mrq; + struct mmc_data data; + struct mmc_command cmd; +#define DCMD (1 << 0) +#define QBR (1 << 1) +#define DIR (1 << 2) +#define PRIO (1 << 3) +#define REL_WR (1 << 4) +#define DAT_TAG (1 << 5) +#define FORCED_PRG (1 << 6) + unsigned int cmdq_req_flags; + int tag; /* used for command queuing */ + u8 ctx_id; +}; + struct mmc_async_req { /* active mmc request */ struct mmc_request *mrq; -- cgit v1.2.3 From 89ada7fc6d8bc5cc9b198f84517003d5886a1c30 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Thu, 23 Apr 2015 16:00:45 +0530 Subject: mmc: core: add flush request support to command queue Adds flush request support to command-queue. This uses DCMD feature of the controller for sending commands in command-queue mode. DCMD is a direct command feature that uses a pre-configured slot for sending commands other than Class 11. Change-Id: Iebf6b74173dc91b0dc7230d1e87c65983d15148e Signed-off-by: Asutosh Das Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/core.h | 4 ++++ include/linux/mmc/host.h | 1 + 2 files changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 8139a58e6d8e..809398c612bf 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -120,6 +120,7 @@ extern void mmc_cmdq_post_req(struct mmc_host *host, struct mmc_request *mrq, int err); extern int mmc_cmdq_start_req(struct mmc_host *host, struct mmc_cmdq_req *cmdq_req); +extern int mmc_cmdq_prepare_flush(struct mmc_command *cmd); extern int mmc_stop_bkops(struct mmc_card *); extern int mmc_read_bkops_status(struct mmc_card *); @@ -133,6 +134,9 @@ extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, struct mmc_command *, int); extern void mmc_start_bkops(struct mmc_card *card, bool from_exception); extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); +extern int __mmc_switch_cmdq_mode(struct mmc_command *cmd, u8 set, u8 index, + u8 value, unsigned int timeout_ms, + bool use_busy_signal, bool ignore_timeout); extern int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error); extern int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 12b8d5505985..8968fa6d1eb1 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -235,6 +235,7 @@ struct mmc_cmdq_context_info { unsigned long active_reqs; /* in-flight requests */ unsigned long curr_state; #define CMDQ_STATE_ERR 0 +#define CMDQ_STATE_DCMD_ACTIVE 1 /* no free tag available */ unsigned long req_starved; }; -- cgit v1.2.3 From c811ac59932ffbe91526e2eaa3cb02bc200bdac5 Mon Sep 17 00:00:00 2001 From: Venkat Gopalakrishnan Date: Fri, 29 May 2015 17:25:46 -0700 Subject: mmc: cmdq: support for command queue enabled host This patch adds CMDQ support for command-queue compatible hosts. Command queue is added in eMMC-5.1 specification. This enables the controller to process upto 32 requests at a time. Change-Id: I0486495ef57c64bf8427e917daeb184c69b8dc73 Signed-off-by: Asutosh Das Signed-off-by: Sujit Reddy Thumma Signed-off-by: Konstantin Dorfman Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 8968fa6d1eb1..2159303f111f 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -540,6 +540,13 @@ struct mmc_host { enum dev_state dev_status; bool wakeup_on_idle; struct mmc_cmdq_context_info cmdq_ctx; + /* + * several cmdq supporting host controllers are extensions + * of legacy controllers. This variable can be used to store + * a reference to the cmdq extension of the existing host + * controller. + */ + void *cmdq_private; unsigned long private[0] ____cacheline_aligned; }; @@ -563,6 +570,11 @@ static inline void *mmc_priv(struct mmc_host *host) return (void *)host->private; } +static inline void *mmc_cmdq_private(struct mmc_host *host) +{ + return host->cmdq_private; +} + #define mmc_host_is_spi(host) ((host)->caps & MMC_CAP_SPI) #define mmc_dev(x) ((x)->parent) -- cgit v1.2.3 From 44a464b93ce11a63b43e0f05b9baf9756fed1117 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Thu, 21 May 2015 17:21:07 +0530 Subject: mmc: core: Add halt support Halt is a controller feature that can change the controller mode from command-queue to legacy. This feature is very helpful in error cases. Change-Id: I7f1465b609afed68886256bd605d4019716964f4 Signed-off-by: Asutosh Das Signed-off-by: Venkat Gopalakrishnan --- include/linux/mmc/core.h | 1 + include/linux/mmc/host.h | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 809398c612bf..8bf192d6a7d4 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -116,6 +116,7 @@ struct mmc_card; struct mmc_async_req; struct mmc_cmdq_req; +extern int mmc_cmdq_halt(struct mmc_host *host, bool enable); extern void mmc_cmdq_post_req(struct mmc_host *host, struct mmc_request *mrq, int err); extern int mmc_cmdq_start_req(struct mmc_host *host, diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 2159303f111f..4e555b99223e 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -94,6 +94,7 @@ struct mmc_cmdq_host_ops { int (*request)(struct mmc_host *host, struct mmc_request *mrq); void (*post_req)(struct mmc_host *host, struct mmc_request *mrq, int err); + int (*halt)(struct mmc_host *host, bool halt); }; struct mmc_host_ops { @@ -236,6 +237,7 @@ struct mmc_cmdq_context_info { unsigned long curr_state; #define CMDQ_STATE_ERR 0 #define CMDQ_STATE_DCMD_ACTIVE 1 +#define CMDQ_STATE_HALT 2 /* no free tag available */ unsigned long req_starved; }; @@ -665,6 +667,21 @@ static inline int mmc_host_packed_wr(struct mmc_host *host) return host->caps2 & MMC_CAP2_PACKED_WR; } +static inline void mmc_host_set_halt(struct mmc_host *host) +{ + set_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state); +} + +static inline void mmc_host_clr_halt(struct mmc_host *host) +{ + clear_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state); +} + +static inline int mmc_host_halt(struct mmc_host *host) +{ + return test_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state); +} + #ifdef CONFIG_MMC_CLKGATE void mmc_host_clk_hold(struct mmc_host *host); void mmc_host_clk_release(struct mmc_host *host); -- cgit v1.2.3 From 99b730eb035d2f1057f558928471c8b78d56371e Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Thu, 23 Apr 2015 09:55:43 +0530 Subject: mmc: block: add support for partition switch There could be a switch of partition while RPMB access. RPMB thread would then hand-off the control to mmc-cmdq-thread in the following state: - partition set to RPMB in card - CMDQ mode disabled in card - Controller in halt state When the next request is received, the following has to be done - switch partition to the current partition - enable CMDQ in card - unhalt controller Change-Id: I9eca350572fd88476dfee9642696a223c5cd7ada Signed-off-by: Asutosh Das Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed compilation error] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index e7fdaff68d7e..609a792e9e5c 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -594,6 +594,8 @@ static inline int mmc_card_broken_irq_polling(const struct mmc_card *c) #define mmc_card_id(c) (dev_name(&(c)->dev)) #define mmc_dev_to_card(d) container_of(d, struct mmc_card, dev) +#define mmc_get_drvdata(c) dev_get_drvdata(&(c)->dev) +#define mmc_set_drvdata(c,d) dev_set_drvdata(&(c)->dev, d) /* * MMC device driver (e.g., Flash card, I/O card...) -- cgit v1.2.3 From 444223d88485b28d8b4f02906c314c3081c8aa96 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Wed, 20 May 2015 16:52:04 +0530 Subject: mmc: block: Add error handling to command queue host On error, the CMDQ engine stops processing requests. It is then halted and error handled. The error have been categorized as below: 1. Command error a. time-out - invalidate all pending tags & requeue - reset both card & controller b. crc - end the error mrq - tune - unhalt 2. Data error a. time-out - invalidate all pending tags & requeue - reset both card and controller b. crc - end the error mrq - tune - unhalt 3. RED error This is device specific error and is not recoverable. The card and controller are reset in this case and all pending tags are invalidated and requeued. Change-Id: I791d05f6b31d8f9b35a56fe85007b320c14e8b46 Signed-off-by: Asutosh Das Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/core.h | 1 + include/linux/mmc/host.h | 7 +++++++ include/linux/mmc/mmc.h | 5 +++++ 3 files changed, 13 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 8bf192d6a7d4..59d9196250c1 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -116,6 +116,7 @@ struct mmc_card; struct mmc_async_req; struct mmc_cmdq_req; +extern int mmc_cmdq_discard_queue(struct mmc_host *host, u32 tasks); extern int mmc_cmdq_halt(struct mmc_host *host, bool enable); extern void mmc_cmdq_post_req(struct mmc_host *host, struct mmc_request *mrq, int err); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 4e555b99223e..18d041f85f95 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -95,6 +95,7 @@ struct mmc_cmdq_host_ops { void (*post_req)(struct mmc_host *host, struct mmc_request *mrq, int err); int (*halt)(struct mmc_host *host, bool halt); + void (*reset)(struct mmc_host *host, bool soft); }; struct mmc_host_ops { @@ -193,6 +194,11 @@ struct mmc_cmdq_req { #define DAT_TAG (1 << 5) #define FORCED_PRG (1 << 6) unsigned int cmdq_req_flags; + + unsigned int resp_idx; + unsigned int resp_arg; + unsigned int dev_pend_tasks; + bool resp_err; int tag; /* used for command queuing */ u8 ctx_id; }; @@ -549,6 +555,7 @@ struct mmc_host { * controller. */ void *cmdq_private; + struct mmc_request *err_mrq; unsigned long private[0] ____cacheline_aligned; }; diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 71b5c75a0995..07b04c6e5c64 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -26,6 +26,11 @@ #include +/* class 11 */ +#define MMC_CMDQ_TASK_MGMT 48 /* ac [31:0] task ID R1b */ +#define DISCARD_QUEUE 0x1 +#define DISCARD_TASK 0x2 + static inline bool mmc_op_multi(u32 opcode) { return opcode == MMC_WRITE_MULTIPLE_BLOCK || -- cgit v1.2.3 From eb2587ce536bffd12bc2cd2a59e3331ba34d4d68 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Mon, 2 Mar 2015 23:14:05 +0530 Subject: mmc: queue: add timeout capability to requests Individual requests can have timeouts defined. The default timeout is set to 120 seconds. On a timeout, the block layer notifies the driver and error can be handled thereafter. Change-Id: Ifcd690411770ab266c12a01bb0993f92b0f18bc6 Signed-off-by: Asutosh Das Signed-off-by: Venkat Gopalakrishnan --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 18d041f85f95..6c6a699abea9 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -96,6 +96,7 @@ struct mmc_cmdq_host_ops { int err); int (*halt)(struct mmc_host *host, bool halt); void (*reset)(struct mmc_host *host, bool soft); + void (*dumpstate)(struct mmc_host *host); }; struct mmc_host_ops { -- cgit v1.2.3 From 10fc703640d923a86b56b8703dbf6862b9acfd35 Mon Sep 17 00:00:00 2001 From: Sahitya Tummala Date: Tue, 9 Jun 2015 09:38:36 +0530 Subject: mmc: block: add discard and secdiscard support for CMDQ mode Discard is supported in CMDQ mode only when device queue is empty. Hence, discard commands should be sent using DCMD slot with QBR (Queue Barrier) flag set. Change-Id: I630091cbd94ffcdcec71626257f912c15fd2e21e Signed-off-by: Sahitya Tummala [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/core.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 59d9196250c1..fcad0aa31b2e 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -123,6 +123,11 @@ extern void mmc_cmdq_post_req(struct mmc_host *host, struct mmc_request *mrq, extern int mmc_cmdq_start_req(struct mmc_host *host, struct mmc_cmdq_req *cmdq_req); extern int mmc_cmdq_prepare_flush(struct mmc_command *cmd); +extern int mmc_cmdq_wait_for_dcmd(struct mmc_host *host, + struct mmc_cmdq_req *cmdq_req); +extern int mmc_cmdq_erase(struct mmc_cmdq_req *cmdq_req, + struct mmc_card *card, unsigned int from, unsigned int nr, + unsigned int arg); extern int mmc_stop_bkops(struct mmc_card *); extern int mmc_read_bkops_status(struct mmc_card *); -- cgit v1.2.3 From 83ed2ae95e1dc8e07faa82f570cb7cbbc58754ff Mon Sep 17 00:00:00 2001 From: Sahitya Tummala Date: Thu, 28 May 2015 16:54:19 +0530 Subject: mmc: block: Add cache barrier support eMMC cache barrier provides a way to perform delayed and in-order flushing of cached data. Host can use this to avoid flushing delays but still maintain the order between the data requests in cache. In case the device gets more barrier requests than it supports, then a barrier request is treated as a normal flush request in the device. If the eMMC cache flushing policy is set to 1, then the device inherently flushes all the cached requests in FIFO order. For such devices, as per spec, it is redundant to send any barrier requests to the device. This may add unnecessary overhead to both host and the device. So make sure to not send barrier requests in such cases. Change-Id: Ia7af316800a6895942d3cabcd64600d56fab25a6 Signed-off-by: Sahitya Tummala [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 3 +++ include/linux/mmc/core.h | 1 + include/linux/mmc/mmc.h | 3 +++ 3 files changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 609a792e9e5c..0f4e22db31ab 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -119,10 +119,13 @@ struct mmc_ext_csd { u8 raw_pwr_cl_ddr_52_195; /* 238 */ u8 raw_pwr_cl_ddr_52_360; /* 239 */ u8 raw_pwr_cl_ddr_200_360; /* 253 */ + u8 cache_flush_policy; /* 240 */ u8 raw_bkops_status; /* 246 */ u8 raw_sectors[4]; /* 212 - 4 bytes */ u8 cmdq_depth; /* 307 */ u8 cmdq_support; /* 308 */ + u8 barrier_support; /* 486 */ + u8 barrier_en; unsigned int feature_support; #define MMC_DISCARD_FEATURE BIT(0) /* CMD38 feature */ diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index fcad0aa31b2e..22c610609a25 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -185,6 +185,7 @@ extern void mmc_put_card(struct mmc_card *card); extern void mmc_set_ios(struct mmc_host *host); extern int mmc_flush_cache(struct mmc_card *); +extern int mmc_cache_barrier(struct mmc_card *); extern int mmc_detect_card_removed(struct mmc_host *host); diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 07b04c6e5c64..5612781ef522 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -221,6 +221,7 @@ struct _mmc_csd { */ #define EXT_CSD_CMDQ 15 /* R/W */ +#define EXT_CSD_BARRIER_CTRL 31 /* R/W */ #define EXT_CSD_FLUSH_CACHE 32 /* W */ #define EXT_CSD_CACHE_CTRL 33 /* R/W */ #define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */ @@ -273,6 +274,7 @@ struct _mmc_csd { #define EXT_CSD_PWR_CL_200_360 237 /* RO */ #define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */ #define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */ +#define EXT_CSD_CACHE_FLUSH_POLICY 240 /* RO */ #define EXT_CSD_BKOPS_STATUS 246 /* RO */ #define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */ #define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */ @@ -281,6 +283,7 @@ struct _mmc_csd { #define EXT_CSD_FIRMWARE_VERSION 254 /* RO, 8 bytes */ #define EXT_CSD_CMDQ_DEPTH 307 /* RO */ #define EXT_CSD_CMDQ_SUPPORT 308 /* RO */ +#define EXT_CSD_BARRIER_SUPPORT 486 /* RO */ #define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ #define EXT_CSD_SUPPORTED_MODE 493 /* RO */ #define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ -- cgit v1.2.3 From 57a1c4c67eab157f6f6519b79862a09ead9e3fba Mon Sep 17 00:00:00 2001 From: Yi Sun Date: Wed, 10 Jun 2015 16:40:06 -0700 Subject: mmc: enable Enhance Strobe for HS400 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. Change-Id: I1003352cb31dfaec01fde352da7b879a13c94b3f Signed-off-by: Yi Sun [venkatg@codeaurora.org: Fix minor conflicts & compilation failure] Patch-mainline: linux-mmc @ 06/04/15, 19:50 Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 1 + include/linux/mmc/mmc.h | 2 ++ 2 files changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 0f4e22db31ab..8289add95151 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -98,6 +98,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 5612781ef522..aa1db902745f 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -247,6 +247,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 */ @@ -341,6 +342,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 */ -- cgit v1.2.3 From 506b393bf6e69fb7dbad718e18f0d033ef19da8f Mon Sep 17 00:00:00 2001 From: Venkat Gopalakrishnan Date: Wed, 10 Jun 2015 17:20:00 -0700 Subject: mmc: Add host ops for enhanced strobe Some hosts may need additional steps to get HS400 functional in enhanced strobe mode. Add host ops to facilitate that. Change-Id: I9663830e7ccedf8bf7970d0724a4c7ce212073fd Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 6c6a699abea9..42e7b412e6f1 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -158,6 +158,7 @@ struct mmc_host_ops { /* Prepare HS400 target operating frequency depending host driver */ int (*prepare_hs400_tuning)(struct mmc_host *host, struct mmc_ios *ios); + int (*enhanced_strobe)(struct mmc_host *host); int (*select_drive_strength)(struct mmc_card *card, unsigned int max_dtr, int host_drv, int card_drv, int *drv_type); -- cgit v1.2.3 From fda56078bbf3b05a9bb1c2ffe3d3616dd15714d5 Mon Sep 17 00:00:00 2001 From: Dov Levenglick Date: Wed, 24 Jun 2015 19:51:58 +0300 Subject: mmc: add support for bkops Add support for manual and auto bkops for legacy (not command-queue) mode. Change-Id: I1333e1d4330393e446ba48a9474c83295744c050 Signed-off-by: Dov Levenglick [subhashj@codeaurora.org: fixed merge conflicts and compilation errors] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 29 +++++++++++++++++++++++++++-- include/linux/mmc/core.h | 21 ++++++++++++++++++++- include/linux/mmc/host.h | 2 ++ include/linux/mmc/mmc.h | 3 +++ 4 files changed, 52 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 8289add95151..80ce6cc36b88 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -86,7 +87,7 @@ struct mmc_ext_csd { bool hpi; /* HPI support bit */ unsigned int hpi_cmd; /* cmd used as HPI */ bool bkops; /* background support bit */ - bool man_bkops_en; /* manual bkops enable bit */ + u8 man_bkops_en; /* manual bkops enable */ unsigned int data_sector_size; /* 512 bytes or 4KB */ unsigned int data_tag_unit_size; /* DATA TAG UNIT size */ unsigned int boot_ro_lock; /* ro lock support */ @@ -274,6 +275,15 @@ struct mmc_part { #define MMC_BLK_DATA_AREA_RPMB (1<<3) }; +/** + * struct mmc_bkops_info - BKOPS data + * @need_manual: indication whether have to send START_BKOPS + * to the device + */ +struct mmc_bkops_info { + bool needs_manual; +}; + /* * MMC device */ @@ -297,9 +307,10 @@ struct mmc_card { #define MMC_STATE_BLOCKADDR (1<<2) /* card uses block-addressing */ #define MMC_CARD_SDXC (1<<3) /* card is SDXC */ #define MMC_CARD_REMOVED (1<<4) /* card has been removed */ -#define MMC_STATE_DOING_BKOPS (1<<5) /* card is doing BKOPS */ +#define MMC_STATE_DOING_BKOPS (1<<5) /* card is doing manual BKOPS */ #define MMC_STATE_SUSPENDED (1<<6) /* card is suspended */ #define MMC_STATE_CMDQ (1<<12) /* card is in cmd queue mode */ +#define MMC_STATE_AUTO_BKOPS (1<<13) /* card is doing auto BKOPS */ unsigned int quirks; /* card quirks */ #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ @@ -363,6 +374,7 @@ struct mmc_card { bool issue_long_pon; u8 *cached_ext_csd; bool cmdq_init; + struct mmc_bkops_info bkops; }; /* @@ -512,6 +524,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS) #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) #define mmc_card_cmdq(c) ((c)->state & MMC_STATE_CMDQ) +#define mmc_card_doing_auto_bkops(c) ((c)->state & MMC_STATE_AUTO_BKOPS) #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) @@ -524,6 +537,8 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED) #define mmc_card_set_cmdq(c) ((c)->state |= MMC_STATE_CMDQ) #define mmc_card_clr_cmdq(c) ((c)->state &= ~MMC_STATE_CMDQ) +#define mmc_card_set_auto_bkops(c) ((c)->state |= MMC_STATE_AUTO_BKOPS) +#define mmc_card_clr_auto_bkops(c) ((c)->state &= ~MMC_STATE_AUTO_BKOPS) /* * Quirk add/remove for MMC products. @@ -594,6 +609,16 @@ static inline int mmc_card_broken_irq_polling(const struct mmc_card *c) return c->quirks & MMC_QUIRK_BROKEN_IRQ_POLLING; } +static inline bool mmc_card_support_auto_bkops(const struct mmc_card *c) +{ + return c->ext_csd.rev >= MMC_V5_1; +} + +static inline bool mmc_card_configured_manual_bkops(const struct mmc_card *c) +{ + return c->ext_csd.man_bkops_en & EXT_CSD_BKOPS_MANUAL_EN; +} + #define mmc_card_name(c) ((c)->cid.prod_name) #define mmc_card_id(c) (dev_name(&(c)->dev)) diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 22c610609a25..446b56765dbb 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -112,6 +112,23 @@ struct mmc_request { struct request *req; }; +struct mmc_bus_ops { + void (*remove)(struct mmc_host *); + void (*detect)(struct mmc_host *); + int (*pre_suspend)(struct mmc_host *); + int (*suspend)(struct mmc_host *); + int (*resume)(struct mmc_host *); + int (*runtime_suspend)(struct mmc_host *); + int (*runtime_resume)(struct mmc_host *); + int (*runtime_idle)(struct mmc_host *); + int (*power_save)(struct mmc_host *); + int (*power_restore)(struct mmc_host *); + int (*alive)(struct mmc_host *); + int (*shutdown)(struct mmc_host *); + int (*reset)(struct mmc_host *); + int (*change_bus_speed)(struct mmc_host *, unsigned long *); +}; + struct mmc_card; struct mmc_async_req; struct mmc_cmdq_req; @@ -139,13 +156,15 @@ extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *); extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, struct mmc_command *, int); -extern void mmc_start_bkops(struct mmc_card *card, bool from_exception); +extern void mmc_check_bkops(struct mmc_card *card); +extern void mmc_start_manual_bkops(struct mmc_card *card); extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); extern int __mmc_switch_cmdq_mode(struct mmc_command *cmd, u8 set, u8 index, u8 value, unsigned int timeout_ms, bool use_busy_signal, bool ignore_timeout); extern int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error); extern int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd); +extern int mmc_set_auto_bkops(struct mmc_card *card, bool enable); #define MMC_ERASE_ARG 0x00000000 #define MMC_SECURE_ERASE_ARG 0x80000000 diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 42e7b412e6f1..cb46cdf8dcf3 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -22,6 +22,8 @@ #include #include +#define MMC_AUTOSUSPEND_DELAY_MS 3000 + struct mmc_ios { unsigned int clock; /* clock rate */ unsigned int old_rate; /* saved clock rate */ diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index aa1db902745f..1cde2e5eb283 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -370,6 +370,9 @@ struct _mmc_csd { #define EXT_CSD_PACKED_EVENT_EN BIT(3) +#define EXT_CSD_BKOPS_MANUAL_EN BIT(0) +#define EXT_CSD_BKOPS_AUTO_EN BIT(1) + /* * EXCEPTION_EVENT_STATUS field */ -- cgit v1.2.3 From b98e6c2fa1dd4f4d3ec89f7a9674174b539f83c2 Mon Sep 17 00:00:00 2001 From: Dov Levenglick Date: Sun, 28 Jun 2015 16:45:41 +0300 Subject: mmc: core: Add MMC BKOPS statistics and debugfs ability to print them The BKOPS statistics are used for BKOPS unit tests and APT tests to determine test success or failure. The BKOPS statstics provide the following information: The number of times BKOPS were issued according to its severity level The number of times manual BKOPS was started/stopped (HPI) The number of times auto BKOPS was enabled/disabled In order to enable and reset the statistics: echo 1 > /sys/kernel/debug/mmc0/mmc0:0001/bkops_stats In order to disable the statistics: echo 0 > /sys/kernel/debug/mmc0/mmc0:0001/bkops_stats In order to view the statistics: cat /sys/kernel/debug/mmc0/mmc0:0001/bkops_stats Change-Id: Ib84319aedfb49dc022bc27efbda842a5db38c7e9 Signed-off-by: Yaniv Gardi Signed-off-by: Dov Levenglick [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 36 ++++++++++++++++++++++++++++++++++++ include/linux/mmc/core.h | 2 ++ 2 files changed, 38 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 80ce6cc36b88..895fc0ceaf6f 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -275,12 +275,48 @@ struct mmc_part { #define MMC_BLK_DATA_AREA_RPMB (1<<3) }; +enum { + MMC_BKOPS_NO_OP, + MMC_BKOPS_NOT_CRITICAL, + MMC_BKOPS_PERF_IMPACT, + MMC_BKOPS_CRITICAL, + MMC_BKOPS_NUM_SEVERITY_LEVELS, +}; + +/** + * struct mmc_bkops_stats - BKOPS statistics + * @lock: spinlock used for synchronizing the debugfs and the runtime accesses + * to this structure. No need to call with spin_lock_irq api + * @manual_start: number of times START_BKOPS was sent to the device + * @hpi: number of times HPI was sent to the device + * @auto_start: number of times AUTO_EN was set to 1 + * @auto_stop: number of times AUTO_EN was set to 0 + * @level: number of times the device reported the need for each level of + * bkops handling + * @enabled: control over whether statistics should be gathered + * + * This structure is used to collect statistics regarding the bkops + * configuration and use-patterns. It is collected during runtime and can be + * shown to the user via a debugfs entry. + */ +struct mmc_bkops_stats { + spinlock_t lock; + unsigned int manual_start; + unsigned int hpi; + unsigned int auto_start; + unsigned int auto_stop; + unsigned int level[MMC_BKOPS_NUM_SEVERITY_LEVELS]; + bool enabled; +}; + /** * struct mmc_bkops_info - BKOPS data + * @stats: statistic information regarding bkops * @need_manual: indication whether have to send START_BKOPS * to the device */ struct mmc_bkops_info { + struct mmc_bkops_stats stats; bool needs_manual; }; diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 446b56765dbb..9a3e44f993c2 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -208,6 +208,8 @@ extern int mmc_cache_barrier(struct mmc_card *); extern int mmc_detect_card_removed(struct mmc_host *host); +extern void mmc_blk_init_bkops_statistics(struct mmc_card *card); + /** * mmc_claim_host - exclusively claim a host * @host: mmc host to claim -- cgit v1.2.3 From a9c940c044ad74de4d0fe3fdb41432703e61e23a Mon Sep 17 00:00:00 2001 From: Talel Shenhar Date: Mon, 29 Jun 2015 10:50:19 +0300 Subject: mmc: cmdq: add clock scaling for CMDQ mode This change adds clock scaling ability to command-queueing mode, it does so by adding next logic: * Statistics collection for CMDQ data path * Empty the queue and Halt it before frequency change * Scale from data path in case host claiming is not possible Change-Id: I53a323b55df4d7c27e3ee3426ee4e856e533522c Signed-off-by: Talel Shenhar --- include/linux/mmc/core.h | 6 ++++++ include/linux/mmc/host.h | 5 +++++ 2 files changed, 11 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 9a3e44f993c2..014eb7e272c6 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -210,6 +210,12 @@ extern int mmc_detect_card_removed(struct mmc_host *host); extern void mmc_blk_init_bkops_statistics(struct mmc_card *card); +extern void mmc_deferred_scaling(struct mmc_host *host); +extern void mmc_cmdq_clk_scaling_start_busy(struct mmc_host *host, + bool lock_needed); +extern void mmc_cmdq_clk_scaling_stop_busy(struct mmc_host *host, + bool lock_needed, bool is_cmdq_dcmd); + /** * mmc_claim_host - exclusively claim a host * @host: mmc host to claim diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index cb46cdf8dcf3..a0b472ba414a 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -237,19 +237,24 @@ struct mmc_slot { /** * mmc_cmdq_context_info - describes the contexts of cmdq * @active_reqs requests being processed + * @data_active_reqs data requests being processed * @curr_state state of cmdq engine * @req_starved completion should invoke the request_fn since * no tags were available * @cmdq_ctx_lock acquire this before accessing this structure + * @queue_empty_wq workqueue for waiting for all + * the outstanding requests to be completed */ struct mmc_cmdq_context_info { unsigned long active_reqs; /* in-flight requests */ + unsigned long data_active_reqs; /* in-flight data requests */ unsigned long curr_state; #define CMDQ_STATE_ERR 0 #define CMDQ_STATE_DCMD_ACTIVE 1 #define CMDQ_STATE_HALT 2 /* no free tag available */ unsigned long req_starved; + wait_queue_head_t queue_empty_wq; }; /** -- cgit v1.2.3 From 2941d9d5bdbabca9a8302aa1571bdf85d00300a0 Mon Sep 17 00:00:00 2001 From: Talel Shenhar Date: Thu, 25 Jun 2015 09:33:24 +0300 Subject: mmc: sdhci: cmdq: add notification for cmdq halt During halted CMDQ mode, HW expects descriptors sizes same as used in CMDQ mode. Our SW uses the legacy path (SDHCI) in case CMDQ is halted, thus, we need to update legacy path of the fact that we are in Halted CMDQ state so it can adjust the descriptors size accordingly. This change adds a notification mechanism for that purpose. Change-Id: Iabb473696fb11827dfcce9b137c26b2c5a5a879d Signed-off-by: Talel Shenhar [subhashj@codeaurora.org: fixed trivial merge conflicts & compilation errors] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index a0b472ba414a..7f624c5338b5 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -178,6 +178,7 @@ struct mmc_host_ops { unsigned long (*get_min_frequency)(struct mmc_host *host); int (*notify_load)(struct mmc_host *, enum mmc_load); + void (*notify_halt)(struct mmc_host *mmc, bool halt); }; struct mmc_card; -- cgit v1.2.3 From d3e52fdfea833ef55f07ce6b135fa35c600aa8d6 Mon Sep 17 00:00:00 2001 From: Krishna Konda Date: Mon, 29 Jun 2015 19:34:35 -0700 Subject: mmc: core: expose info about enhanced rpmb support Following eMMC JEDEC JESD84-B51 standard, an ehannced form of rpmb is supported. What this enhanced mode supports is in addition to be able to write one rpmb or two rpmb frames at a time, 32 frames can be written at a time. Expose this information present in ext csd field so that the user space application that wants to make use of this can do so. Change-Id: I53fd962fd7e04b5d2d7804c289d7865c2c5618d5 Signed-off-by: Krishna Konda [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 1 + include/linux/mmc/mmc.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 895fc0ceaf6f..5c6c10be3fd1 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -56,6 +56,7 @@ struct mmc_ext_csd { u8 sec_feature_support; u8 rel_sectors; u8 rel_param; + bool enhanced_rpmb_supported; u8 part_config; u8 cache_ctrl; u8 rst_n_function; diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 1cde2e5eb283..9cd5afaef626 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -298,7 +298,8 @@ struct _mmc_csd { * EXT_CSD field definitions */ -#define EXT_CSD_WR_REL_PARAM_EN (1<<2) +#define EXT_CSD_WR_REL_PARAM_EN (1<<2) +#define EXT_CSD_WR_REL_PARAM_EN_RPMB_REL_WR (1<<4) #define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40) #define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10) -- cgit v1.2.3 From b6c1c166809f7141efb13c2805027f189a75597a Mon Sep 17 00:00:00 2001 From: Dov Levenglick Date: Wed, 1 Jul 2015 14:24:20 +0300 Subject: mmc: core: add support for bkops during cmdq Add support for handling both manual and auto bkops when command queuing is running. Change-Id: Ib967ca3c0420f4e54b3e93c497eb538d7347199a Signed-off-by: Dov Levenglick [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 12 +++++++++++- include/linux/mmc/core.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 5c6c10be3fd1..2430ba0e1182 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -313,11 +313,14 @@ struct mmc_bkops_stats { /** * struct mmc_bkops_info - BKOPS data * @stats: statistic information regarding bkops - * @need_manual: indication whether have to send START_BKOPS + * @needs_check: indication whether need to check with the device + * whether it requires handling of BKOPS (CMD8) + * @needs_manual: indication whether have to send START_BKOPS * to the device */ struct mmc_bkops_info { struct mmc_bkops_stats stats; + bool needs_check; bool needs_manual; }; @@ -656,6 +659,13 @@ static inline bool mmc_card_configured_manual_bkops(const struct mmc_card *c) return c->ext_csd.man_bkops_en & EXT_CSD_BKOPS_MANUAL_EN; } +/* + * By software design, auto_bkops will be enabled on the device if it supports + * it. Therefore, testing if a card is configured to run bkops is synonymous + * to checking if it supports bkops + */ +#define mmc_card_configured_auto_bkops(c) mmc_card_support_auto_bkops(c) + #define mmc_card_name(c) ((c)->cid.prod_name) #define mmc_card_id(c) (dev_name(&(c)->dev)) diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 014eb7e272c6..2f797fb527b0 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -201,6 +201,7 @@ extern void mmc_release_host(struct mmc_host *host); extern void mmc_get_card(struct mmc_card *card); extern void mmc_put_card(struct mmc_card *card); +extern void __mmc_put_card(struct mmc_card *card); extern void mmc_set_ios(struct mmc_host *host); extern int mmc_flush_cache(struct mmc_card *); -- cgit v1.2.3 From 62c8dce6e1b42fe6ee356550a3092ca2db90ec22 Mon Sep 17 00:00:00 2001 From: Krishna Konda Date: Mon, 29 Jun 2015 19:20:05 -0700 Subject: mmc: core: Update PON based on the system state As per eMMC specification, the PON (Power Off Notification) must be sent by host to the card before turning off the power. This will allow card to prepare itself for the power off and may even reduce the initialization of eMMC upon next boot-up. Send long PON during system power off and send short PON during system reboot to reduce the reboot latency. Change-Id: If4188b8b80aaa0e6c4e00e1807aa9589d5e7efdb Signed-off-by: Sahitya Tummala Signed-off-by: Krishna Konda [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 2430ba0e1182..c8faf8b146ee 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -324,6 +324,11 @@ struct mmc_bkops_info { bool needs_manual; }; +enum mmc_pon_type { + MMC_LONG_PON = 1, + MMC_SHRT_PON, +}; + /* * MMC device */ @@ -411,7 +416,7 @@ struct mmc_card { struct mmc_wr_pack_stats wr_pack_stats; /* packed commands stats*/ struct notifier_block reboot_notify; - bool issue_long_pon; + enum mmc_pon_type pon_type; u8 *cached_ext_csd; bool cmdq_init; struct mmc_bkops_info bkops; @@ -691,6 +696,6 @@ extern void mmc_fixup_device(struct mmc_card *card, extern struct mmc_wr_pack_stats *mmc_blk_get_packed_statistics( struct mmc_card *card); extern void mmc_blk_init_packed_statistics(struct mmc_card *card); -extern int mmc_send_long_pon(struct mmc_card *card); +extern int mmc_send_pon(struct mmc_card *card); extern void mmc_blk_cmdq_req_done(struct mmc_request *mrq); #endif /* LINUX_MMC_CARD_H */ -- cgit v1.2.3 From 348a140b51c072d00ca66d56e8d20e5fcab758ad Mon Sep 17 00:00:00 2001 From: Dov Levenglick Date: Mon, 20 Jul 2015 16:50:03 +0300 Subject: mmc: host: add detect vops chain Add call from sdio to host_ops to sdhci_ops in order to indicate when a sdio card is detected. This will be used by hosts that require special handling for card detection. Change-Id: I65ec6ee464d658cd938d9254a0a748e6137f9223 Signed-off-by: Dov Levenglick [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 7f624c5338b5..9bf53de32a07 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -179,6 +179,7 @@ struct mmc_host_ops { int (*notify_load)(struct mmc_host *, enum mmc_load); void (*notify_halt)(struct mmc_host *mmc, bool halt); + void (*detect)(struct mmc_host *host, bool detected); }; struct mmc_card; -- cgit v1.2.3 From 8ee51daf1c95730aefbc700d51abd147c4fac435 Mon Sep 17 00:00:00 2001 From: Dov Levenglick Date: Thu, 16 Jul 2015 11:58:38 +0300 Subject: mmc: schci: add support for MMC_PM_KEEP_POWER in eMMC There are eMMC cards that should not be powered off during suspend/resume cycles. This patch adds support for such cards and avoids powering the card off during suspend or powering it back on during resume when MMC_PM_KEEP_POWER is set. Change-Id: Iec1a0aac80ee41dff56f192e7253c2bd00c15694 Signed-off-by: Dov Levenglick --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 9bf53de32a07..c6d0ff9f1cbe 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -287,6 +287,7 @@ enum dev_state { DEV_SUSPENDING = 1, DEV_SUSPENDED, DEV_RESUMED, + DEV_UNKNOWN, /* Device is in an unknown state */ }; /** -- cgit v1.2.3 From d25b9c4733136c2f14d2fe2a1c130869e01f76a1 Mon Sep 17 00:00:00 2001 From: Dov Levenglick Date: Tue, 14 Jul 2015 14:10:57 +0300 Subject: mmc: core: set MMC_PM_KEEP_POWER for certain Hynix mmc cards Certain Hynix eMMC 5.0 cards might reach a fast EOL if the card's power is disabled between CMD5 and CMD0 (power off during reset). This patch sets the MMC_PM_KEEP_POWER flag to indicate that the card's power should be retained for suspend/resume sequences. Change-Id: I4bcc0f4bfd608745626816ca261369b432602c45 Signed-off-by: Dov Levenglick --- include/linux/mmc/card.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index c8faf8b146ee..ce2a0aa79425 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -472,6 +472,7 @@ struct mmc_fixup { #define CID_MANFID_MICRON 0x13 #define CID_MANFID_SAMSUNG 0x15 #define CID_MANFID_KINGSTON 0x70 +#define CID_MANFID_HYNIX 0x90 #define CID_MANFID_ANY (-1u) #define CID_OEMID_ANY ((unsigned short) -1) -- cgit v1.2.3 From 42dd0264d115e4b70a4a044679dd121689e422f0 Mon Sep 17 00:00:00 2001 From: Dov Levenglick Date: Mon, 20 Jul 2015 17:33:03 +0300 Subject: mmc: core: change test of auto_bkops configured Changing the test of whether auto_bkops is configured allows for a case where the host tried to configure auto_bkops yet the CMD6 failed in configuring the device. This allows a case where manual bkops is configured on a eMMC 5.1 device Change-Id: Ia6c411f516bf27b8a5865109dcf4b290eb3d8e46 Signed-off-by: Dov Levenglick [subhashj@codeaurora.org: fixed trivial merge conflicts & fixed compilation error] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index ce2a0aa79425..b652076be866 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -665,12 +665,10 @@ static inline bool mmc_card_configured_manual_bkops(const struct mmc_card *c) return c->ext_csd.man_bkops_en & EXT_CSD_BKOPS_MANUAL_EN; } -/* - * By software design, auto_bkops will be enabled on the device if it supports - * it. Therefore, testing if a card is configured to run bkops is synonymous - * to checking if it supports bkops - */ -#define mmc_card_configured_auto_bkops(c) mmc_card_support_auto_bkops(c) +static inline bool mmc_card_configured_auto_bkops(const struct mmc_card *c) +{ + return c->ext_csd.man_bkops_en & EXT_CSD_BKOPS_AUTO_EN; +} #define mmc_card_name(c) ((c)->cid.prod_name) #define mmc_card_id(c) (dev_name(&(c)->dev)) -- cgit v1.2.3 From e0ee5ff565543bcc9f91635e27090c229c7e4750 Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Mon, 13 Jul 2015 10:52:36 +0530 Subject: mmc: core: Fix debugfs and IOCTL calls in cmdq mode Currently getting status/ext_csd using debugfs or IOCTL calls in cmdq mode is not working. Fix it by halting the cmdq engine and making sure that card queue is empty before issuing these cmds. Change-Id: Idb89def9ff5c2fee6866759b9a8c652049552933 Signed-off-by: Ritesh Harjani [subhashj@codeaurora.org: fixed merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/core.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 2f797fb527b0..87332656e0fd 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -135,6 +135,7 @@ struct mmc_cmdq_req; extern int mmc_cmdq_discard_queue(struct mmc_host *host, u32 tasks); extern int mmc_cmdq_halt(struct mmc_host *host, bool enable); +extern int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host); extern void mmc_cmdq_post_req(struct mmc_host *host, struct mmc_request *mrq, int err); extern int mmc_cmdq_start_req(struct mmc_host *host, -- cgit v1.2.3 From 9bc36b07a2c375ad4fac740f273cf2b83b5cd4e8 Mon Sep 17 00:00:00 2001 From: Gilad Broner Date: Thu, 13 Aug 2015 17:58:30 +0300 Subject: mmc: core: kick block queue after unhalting cmdq If request has to be requeued due to cmdq being halted and if we change the task status to interruptible before going to sleep then cmdq thread may not wakeup again. Note that blk_requeue_request() doesn't trigger ->request_fn() again to wakeup the cmdq thread. Fix this issue by kicking the queue once cmdq state machine is unhalted. Change-Id: Icbfb3b6560285fa0a0ce7e83eee66b651d4594a0 Signed-off-by: Gilad Broner Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index c6d0ff9f1cbe..aa9df4ce96e5 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -257,6 +257,7 @@ struct mmc_cmdq_context_info { /* no free tag available */ unsigned long req_starved; wait_queue_head_t queue_empty_wq; + struct request_queue *q; }; /** -- cgit v1.2.3 From 0b56648089c3e1ad0fe211c772f86544281a1bd5 Mon Sep 17 00:00:00 2001 From: Pavan Anamula Date: Mon, 24 Aug 2015 18:56:22 +0530 Subject: mmc: host: add support to allow SANITIZE operation SANITIZE is an operation performed by the storage device and its purpose is to delete its unmap memory regions. This change adds support for the SANITIZE capability. Change-Id: I58b647fb576c694aaa16c1e827d0784d4a5b4456 Signed-off-by: Yaniv Gardi Signed-off-by: Pavan Anamula [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index aa9df4ce96e5..001cde15242b 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -438,7 +438,7 @@ struct mmc_host { #define MMC_CAP2_HS400_POST_TUNING (1 << 22) #define MMC_CAP2_NONHOTPLUG (1 << 25) /*Don't support hotplug*/ #define MMC_CAP2_CMD_QUEUE (1 << 26) /* support eMMC command queue */ - +#define MMC_CAP2_SANITIZE (1 << 27) /* Support Sanitize */ mmc_pm_flag_t pm_caps; /* supported pm features */ #ifdef CONFIG_MMC_CLKGATE -- cgit v1.2.3 From d409a3b3d9572d40cd5b128df0e90d322d0c71ca Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Tue, 25 Aug 2015 11:30:48 +0530 Subject: mmc: core: Check if card supports strobe before calling host ops Should check if mmc_card supports strobe before calling enhanced strobe host ops. This also adds a macro for use by LLD to know if card supports strobe Change-Id: Id79098ff66bd36be2496b86bf71556204aca7fe3 Signed-off-by: Ritesh Harjani [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index b652076be866..1b891365653f 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -101,6 +101,7 @@ struct mmc_ext_csd { u8 raw_rpmb_size_mult; /* 168 */ u8 raw_erased_mem_count; /* 181 */ u8 strobe_support; /* 184 */ +#define MMC_STROBE_SUPPORT (1 << 0) u8 raw_ext_csd_structure; /* 194 */ u8 raw_card_type; /* 196 */ u8 raw_driver_strength; /* 197 */ @@ -586,6 +587,8 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_card_set_auto_bkops(c) ((c)->state |= MMC_STATE_AUTO_BKOPS) #define mmc_card_clr_auto_bkops(c) ((c)->state &= ~MMC_STATE_AUTO_BKOPS) +#define mmc_card_strobe(c) (((c)->ext_csd).strobe_support & MMC_STROBE_SUPPORT) + /* * Quirk add/remove for MMC products. */ -- cgit v1.2.3 From 64be1cd3e02145b3ab5918b4526081840cbff477 Mon Sep 17 00:00:00 2001 From: Gilad Broner Date: Tue, 29 Sep 2015 16:05:39 +0300 Subject: mmc: sdhci-msm: add PM QoS voting Add PM QoS voting mechanism to sdhci-msm driver for command queueing. Two types of voting schemes are supported: 1) Vote for HW IRQ 2) Vote for a cpu group according to the request's designated cpu Using PM QoS voting should benefit performance. Change-Id: I8a20653eeb6348d5b442c846708d92c8fb64a8e9 Signed-off-by: Gilad Broner [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 001cde15242b..0759649084dd 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -91,6 +91,7 @@ enum mmc_load { }; struct mmc_cmdq_host_ops { + int (*init)(struct mmc_host *host); int (*enable)(struct mmc_host *host); void (*disable)(struct mmc_host *host, bool soft); int (*request)(struct mmc_host *host, struct mmc_request *mrq); -- cgit v1.2.3 From 17a072dd256d9a3246abf28e78e62a65c63f84f1 Mon Sep 17 00:00:00 2001 From: Gilad Broner Date: Tue, 29 Sep 2015 16:57:21 +0300 Subject: mmc: sdhci-msm: add PM QoS legacy voting Add PM QoS voting mechanism to sdhci-msm driver for legacy eMMC. Two types of voting schemes are supported: 1) Vote for HW IRQ 2) Vote for a cpu group according to the request's designated cpu Using PM QoS voting should benefit performance. Change-Id: I5d2b71fc4eabfa5060f343634fbc7363f2ee1344 Signed-off-by: Konstantin Dorfman Signed-off-by: Gilad Broner [subhashj@codeaurora.org: fixed merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 0759649084dd..367e122d1f2f 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -103,6 +103,7 @@ struct mmc_cmdq_host_ops { }; struct mmc_host_ops { + int (*init)(struct mmc_host *host); /* * 'enable' is called when the host is claimed and 'disable' is called * when the host is released. 'enable' and 'disable' are deprecated. -- cgit v1.2.3 From 21a32a7af8ca151dff4f3710742864705a5a7e7d Mon Sep 17 00:00:00 2001 From: Maya Erez Date: Tue, 29 Sep 2015 17:34:03 +0300 Subject: mmc: core: add partial initialization support This change adds the ability to partially initialize the MMC card by using card Sleep/Awake sequence (CMD5). Card will be sent to Sleep state during runtime/system suspend and will be woken up during runtime/system resume. By using this sequence the card doesn't need full initialization which gives time reduction in system/runtime resume path. Change-Id: Id8dadf03ef4226f7c4675fadbacac7bb15c0289e Signed-off-by: Talel Shenhar Signed-off-by: Maya Erez [subhashj@codeaurora.org: fixed merge conflicts & compilation errors] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 4 ++++ include/linux/mmc/host.h | 3 +++ 2 files changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 1b891365653f..b8430181704a 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -93,6 +93,8 @@ struct mmc_ext_csd { unsigned int data_tag_unit_size; /* DATA TAG UNIT size */ unsigned int boot_ro_lock; /* ro lock support */ bool boot_ro_lockable; + u8 raw_ext_csd_cmdq; /* 15 */ + u8 raw_ext_csd_cache_ctrl; /* 33 */ bool ffu_capable; /* Firmware upgrade support */ #define MMC_FIRMWARE_LEN 8 u8 fwrev[MMC_FIRMWARE_LEN]; /* FW version */ @@ -100,8 +102,10 @@ struct mmc_ext_csd { u8 raw_partition_support; /* 160 */ u8 raw_rpmb_size_mult; /* 168 */ u8 raw_erased_mem_count; /* 181 */ + u8 raw_ext_csd_bus_width; /* 183 */ u8 strobe_support; /* 184 */ #define MMC_STROBE_SUPPORT (1 << 0) + u8 raw_ext_csd_hs_timing; /* 185 */ 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 367e122d1f2f..0f8d285a1192 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -441,6 +441,8 @@ struct mmc_host { #define MMC_CAP2_NONHOTPLUG (1 << 25) /*Don't support hotplug*/ #define MMC_CAP2_CMD_QUEUE (1 << 26) /* support eMMC command queue */ #define MMC_CAP2_SANITIZE (1 << 27) /* Support Sanitize */ +#define MMC_CAP2_SLEEP_AWAKE (1 << 28) /* Use Sleep/Awake (CMD5) */ + mmc_pm_flag_t pm_caps; /* supported pm features */ #ifdef CONFIG_MMC_CLKGATE @@ -468,6 +470,7 @@ struct mmc_host { spinlock_t lock; /* lock for claim and bus ops */ struct mmc_ios ios; /* current io bus settings */ + struct mmc_ios cached_ios; /* group bitfields together to minimize padding */ unsigned int use_spi_crc:1; -- cgit v1.2.3 From 2906eb31e5867f13e6bc4c5a3b2d01deb97e9181 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Thu, 9 Jul 2015 17:35:22 +0530 Subject: mmc: card: read the firmware version from ext_csd Read the firmware version from ext_csd register and print it for debugging purpose. Change-Id: I4c1fefd5bff753915c9858fb35c958335986c778 Signed-off-by: Asutosh Das Signed-off-by: Sahitya Tummala [subhashj@codeaurora.org: fixed trivial merge conflicts and compilation errors] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index b8430181704a..4f49a254d3f3 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -135,6 +135,7 @@ struct mmc_ext_csd { u8 barrier_support; /* 486 */ u8 barrier_en; + u8 fw_version; /* 254 */ unsigned int feature_support; #define MMC_DISCARD_FEATURE BIT(0) /* CMD38 feature */ }; -- cgit v1.2.3 From 6d9a04f1b112e5afd57bafb1fb80e67778656844 Mon Sep 17 00:00:00 2001 From: Krishna Konda Date: Sat, 26 Sep 2015 17:38:26 -0700 Subject: mmc: core: allow hosts to specify a large discard size max_busy_timeout is used to decide whether R1B response should be used or a R1 response should be used. This is also used to decide what the discard size of mmc queue (registered with block layer) can be set to. In order to keep both the features in place, this change will allow for hosts to specify a larger discard size while still specifying max_busy_timeout. Change-Id: I1e607329c4377897a7cb4086db02cbc150bd02b7 Signed-off-by: Krishna Konda --- include/linux/mmc/host.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 0f8d285a1192..87f90a7d061a 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -442,6 +442,8 @@ struct mmc_host { #define MMC_CAP2_CMD_QUEUE (1 << 26) /* support eMMC command queue */ #define MMC_CAP2_SANITIZE (1 << 27) /* Support Sanitize */ #define MMC_CAP2_SLEEP_AWAKE (1 << 28) /* Use Sleep/Awake (CMD5) */ +/* use max discard ignoring max_busy_timeout parameter */ +#define MMC_CAP2_MAX_DISCARD_SIZE (1 << 29) mmc_pm_flag_t pm_caps; /* supported pm features */ -- cgit v1.2.3 From b78e1b402589663b584111e24b6756beccef4797 Mon Sep 17 00:00:00 2001 From: Venkat Gopalakrishnan Date: Tue, 15 Sep 2015 15:57:35 -0700 Subject: mmc: debugfs: add debugfs entry to force raise host errors The SDHC spec allows to force raise errors that is useful for debugging error handler routines. Add debugfs entry force_error to trigger host errors from userspace. Check SDHCI_SET_INT_ERROR register for error bitmask info. Usage: echo 0x1 > /sys/kernel/debug/mmcX/force_error X - denotes the slot id Change-Id: I9f67442a79b2645cbdc3020d1a10c0b32840ce32 Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 87f90a7d061a..a312467be721 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -182,6 +182,7 @@ struct mmc_host_ops { int (*notify_load)(struct mmc_host *, enum mmc_load); void (*notify_halt)(struct mmc_host *mmc, bool halt); void (*detect)(struct mmc_host *host, bool detected); + void (*force_err_irq)(struct mmc_host *host, u64 errmask); }; struct mmc_card; -- cgit v1.2.3 From 38c20819fce7eb22a3d0f560049fc8f5c0292bf7 Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Wed, 12 Aug 2015 17:53:21 -0700 Subject: mmc: queue: fix the cmdq thread wake up handling If request has to be requeued (due to any DCMD commmand pending or cmdq being halted) and if we change the task status to interruptible before going to sleep then thread may not wakeup again. Note that blk_requeue_request() doesn't trigger ->request_fn() again to wakeup the thread. Fix this issue by making cmdq thread wait for the completion of DCMD or until the cmdq is unhalted. This change also simplifies the cmdq thread function. Change-Id: Iebffc993241e5fadb2962fedc44576566dc66e9c Signed-off-by: Subhash Jadavani Signed-off-by: Venkat Gopalakrishnan --- include/linux/mmc/host.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index a312467be721..3b028e566282 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -244,11 +244,12 @@ struct mmc_slot { * @active_reqs requests being processed * @data_active_reqs data requests being processed * @curr_state state of cmdq engine - * @req_starved completion should invoke the request_fn since - * no tags were available * @cmdq_ctx_lock acquire this before accessing this structure * @queue_empty_wq workqueue for waiting for all * the outstanding requests to be completed + * @wait waiting for all conditions described in + * mmc_cmdq_ready_wait to be satisified before + * issuing the new request to LLD. */ struct mmc_cmdq_context_info { unsigned long active_reqs; /* in-flight requests */ @@ -257,10 +258,8 @@ struct mmc_cmdq_context_info { #define CMDQ_STATE_ERR 0 #define CMDQ_STATE_DCMD_ACTIVE 1 #define CMDQ_STATE_HALT 2 - /* no free tag available */ - unsigned long req_starved; wait_queue_head_t queue_empty_wq; - struct request_queue *q; + wait_queue_head_t wait; }; /** -- cgit v1.2.3 From 603e5ef719b620ebddb2d61681a80dc44ea0c8a9 Mon Sep 17 00:00:00 2001 From: Venkat Gopalakrishnan Date: Mon, 28 Sep 2015 18:53:18 -0700 Subject: mmc: cmdq_hci: Add cyclic buffer to keep history of last 32 tasks Keep track of task history for the last 32 tasks and dump it along with registers in case of any error for debugging. The log is of the following format: [index] Task: | Args: of the task descriptor structure. The values need to be decoded accordingly depending on the data or dcmd task descriptor. The last entry index denotes the latest entry in this list. ---- Circular Task History ---- cmdq-host: Last entry index: 1 cmdq-host: [00]DATA Task: 0x0400002f | Args: 0x00d37d18 cmdq-host: [01]DATA Task: 0x0400002f | Args: 0x00d38118 cmdq-host: [02]DCMD Task: 0x0186402f | Args: 0x03200101 Add a debugfs entry to enable/disable this dynamically. It is disabled by default. This applies only to eMMC devices. Usage: echo Y > /sys/kernel/debug/mmcX/cmdq_task_history X - denotes the slot id Change-Id: I6abf29aa928d3d8270405cfc104241043dadfe45 Signed-off-by: Venkat Gopalakrishnan [subhashj@codeaurora.org: fixed compilation error] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 3b028e566282..959713837423 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -568,6 +568,7 @@ struct mmc_host { enum dev_state dev_status; bool wakeup_on_idle; struct mmc_cmdq_context_info cmdq_ctx; + bool cmdq_thist_enabled; /* * several cmdq supporting host controllers are extensions * of legacy controllers. This variable can be used to store -- cgit v1.2.3 From 98afc17278b691b950dd003c3a0d7958de78aec7 Mon Sep 17 00:00:00 2001 From: Pavan Anamula Date: Wed, 28 Oct 2015 22:20:24 +0530 Subject: mmc: core: Card specific custom settings for SDIO Add quirk to modify custom settings for QCA6574 and QCA9377 cards. Change-Id: I05e70efa71a8b8b931dfff758194af6220a8bc46 Signed-off-by: Pavan Anamula Signed-off-by: Sahitya Tummala [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 4f49a254d3f3..6fba3afcc2fb 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -384,6 +384,8 @@ struct mmc_card { #define MMC_QUIRK_BROKEN_HPI (1 << 14) /* For devices which gets */ /* broken due to HPI feature */ #define MMC_QUIRK_CACHE_DISABLE (1 << 14) /* prevent cache enable */ +#define MMC_QUIRK_QCA6574_SETTINGS (1 << 15) /* QCA6574 card settings*/ +#define MMC_QUIRK_QCA9377_SETTINGS (1 << 16) /* QCA9377 card settings*/ unsigned int erase_size; /* erase size in sectors */ @@ -678,6 +680,16 @@ static inline bool mmc_card_configured_auto_bkops(const struct mmc_card *c) return c->ext_csd.man_bkops_en & EXT_CSD_BKOPS_AUTO_EN; } +static inline bool mmc_enable_qca6574_settings(const struct mmc_card *c) +{ + return c->quirks & MMC_QUIRK_QCA6574_SETTINGS; +} + +static inline bool mmc_enable_qca9377_settings(const struct mmc_card *c) +{ + return c->quirks & MMC_QUIRK_QCA9377_SETTINGS; +} + #define mmc_card_name(c) ((c)->cid.prod_name) #define mmc_card_id(c) (dev_name(&(c)->dev)) -- cgit v1.2.3 From 0c86067ea8daf55a6a5b7f136bc930f71a2bdf76 Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Tue, 3 Nov 2015 19:03:41 -0800 Subject: mmc: block: ensure CMDQ is empty before queuing cache flush Some devices might stop responding to new commands if device cache flush is queued to host controller while host controller is still processing outstanding requests. To workaround this issue, we are making the cmdq thread to wait for all the oustanding requests to be finished before queuing cache flush command on host controller. Change-Id: I15387734f51ca4cadfc9e11270f14d8a0806a00f Signed-off-by: Subhash Jadavani [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 6fba3afcc2fb..2574e8af91fe 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -388,6 +388,9 @@ struct mmc_card { #define MMC_QUIRK_QCA9377_SETTINGS (1 << 16) /* QCA9377 card settings*/ +/* Make sure CMDQ is empty before queuing cache flush */ +#define MMC_QUIRK_CMDQ_EMPTY_BEFORE_FLUSH (1 << 17) + unsigned int erase_size; /* erase size in sectors */ unsigned int erase_shift; /* if erase unit is power 2 */ unsigned int pref_erase; /* in sectors */ -- cgit v1.2.3 From 6c8e3e70c92fdfe2813817c401ec05f2bc6c6a9d Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Fri, 13 Nov 2015 12:15:53 -0800 Subject: mmc: block: workaround for timeout issue with some vendor devices Commit 66a7393a3ba9685d1eddfbce72e3ef8f4848f19f ("mmc: block: ensure CMDQ is empty before queuing cache flush") added a workaround for particular vendor's eMMC devices. Workaround was to wait for all the outstanding requests to finish up before queuing the flush request. Now detailed root cause analysis from vendor shows that original issue can happen only if DCMD command is sent to device too quickly (within less than 6 microseconds) after completion of previous small sector (less than 8 sectors) read operations. Hence with this change, we are fine tuning the previous workaround such that it would almost have no impact on the storage benchmark performance numbers. Change-Id: I1df1c5d7bbcd7b526236651077b7dade2626cb30 Signed-off-by: Subhash Jadavani [subhashj@codeaurora.org: fixed trivial merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 6 ++++-- include/linux/mmc/host.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 2574e8af91fe..5ee1a379b82b 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -335,6 +335,8 @@ enum mmc_pon_type { MMC_SHRT_PON, }; +#define MMC_QUIRK_CMDQ_DELAY_BEFORE_DCMD 6 /* microseconds */ + /* * MMC device */ @@ -388,8 +390,8 @@ struct mmc_card { #define MMC_QUIRK_QCA9377_SETTINGS (1 << 16) /* QCA9377 card settings*/ -/* Make sure CMDQ is empty before queuing cache flush */ -#define MMC_QUIRK_CMDQ_EMPTY_BEFORE_FLUSH (1 << 17) +/* Make sure CMDQ is empty before queuing DCMD */ +#define MMC_QUIRK_CMDQ_EMPTY_BEFORE_DCMD (1 << 17) unsigned int erase_size; /* erase size in sectors */ unsigned int erase_shift; /* if erase unit is power 2 */ diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 959713837423..6dd6add52d64 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -260,6 +260,7 @@ struct mmc_cmdq_context_info { #define CMDQ_STATE_HALT 2 wait_queue_head_t queue_empty_wq; wait_queue_head_t wait; + int active_small_sector_read_reqs; }; /** -- cgit v1.2.3 From 3aeae55f8a7688f88c952f84921337e8577d8ccc Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Wed, 25 Nov 2015 10:37:21 +0530 Subject: mmc: sdhci: Add asynchronous interrupt support for sdio cards SD host controller have asynchronous interrupt support capability to detect card(sdio) interrupt even when clocks are gated(to save power). This patch add support and enable this capability/feature to of SD host controllers for sdio cards. Change-Id: Ic1945355a19ebfdb3bd000bf8138d8001cea53f6 Signed-off-by: Ritesh Harjani [subhashj@codeaurora.org: fixed merge conflicts & compilatione error] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 6dd6add52d64..e6dd9eb4ead4 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -683,6 +683,12 @@ static inline int mmc_boot_partition_access(struct mmc_host *host) return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC); } +static inline bool mmc_card_and_host_support_async_int(struct mmc_host *host) +{ + return ((host->caps2 & MMC_CAP2_ASYNC_SDIO_IRQ_4BIT_MODE) && + (host->card->cccr.async_intr_sup)); +} + static inline int mmc_host_uhs(struct mmc_host *host) { return host->caps & -- cgit v1.2.3 From f47dba1b3132907fdafe320ecd052d6b4e239d60 Mon Sep 17 00:00:00 2001 From: Asutosh Das Date: Wed, 9 Dec 2015 10:48:18 +0530 Subject: mmc: core: support DDR52 bus-speed during eMMC clock scaling Add support for DDR52 bus-speed mode during clock scaling. The reason for this change is DDR52 can be supported at SVS mode. Change-Id: I68e5fca57ae5cbc154f5dd7001df368900cb3f57 Signed-off-by: Asutosh Das --- include/linux/mmc/host.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index e6dd9eb4ead4..38731725cc80 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -335,6 +335,8 @@ struct mmc_devfeq_clk_scaling { unsigned long polling_delay_ms; unsigned int upthreshold; unsigned int downthreshold; + unsigned int lower_bus_speed_mode; +#define MMC_SCALING_LOWER_DDR52_MODE 1 bool need_freq_change; bool clk_scaling_in_progress; bool is_busy_started; -- cgit v1.2.3 From 13e2446bf85d8679095c24bb450cc6007d4bbb24 Mon Sep 17 00:00:00 2001 From: Sahitya Tummala Date: Mon, 21 Dec 2015 14:43:42 +0530 Subject: mmc: sdhci: revert MMC_PM_KEEP_POWER changes related to emmc This change reverts the following gerrits as they cause the timeout issues with Hynix cards. Also, the latest code supports sleep/awake through CMD5 and hence MMC_PM_KEEP_POWER need not be set for Hynix eMMC cards. edcf5be "mmc: host: add detect vops chain" 09287cb "mmc: sdhci-msm: configure MMC_PM_KEEP_POWER for SDIO" 7cf603a "mmc: schci: add support for MMC_PM_KEEP_POWER in eMMC" c085820 "mmc: core: set MMC_PM_KEEP_POWER for certain Hynix mmc cards" CRs-Fixed: 947299 Change-Id: If863771191ee7c2b717d5817f4a88e4ad936653a Signed-off-by: Sahitya Tummala [subhashj@codeaurora.org: fixed merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 1 - include/linux/mmc/host.h | 2 -- 2 files changed, 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 5ee1a379b82b..d88f6a027679 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -485,7 +485,6 @@ struct mmc_fixup { #define CID_MANFID_MICRON 0x13 #define CID_MANFID_SAMSUNG 0x15 #define CID_MANFID_KINGSTON 0x70 -#define CID_MANFID_HYNIX 0x90 #define CID_MANFID_ANY (-1u) #define CID_OEMID_ANY ((unsigned short) -1) diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 38731725cc80..cd79dd903a8b 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -181,7 +181,6 @@ struct mmc_host_ops { int (*notify_load)(struct mmc_host *, enum mmc_load); void (*notify_halt)(struct mmc_host *mmc, bool halt); - void (*detect)(struct mmc_host *host, bool detected); void (*force_err_irq)(struct mmc_host *host, u64 errmask); }; @@ -291,7 +290,6 @@ enum dev_state { DEV_SUSPENDING = 1, DEV_SUSPENDED, DEV_RESUMED, - DEV_UNKNOWN, /* Device is in an unknown state */ }; /** -- cgit v1.2.3 From 2f69844aa86701a0a4c1ea8ca8fa8e55506a1329 Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Tue, 27 Oct 2015 11:51:25 +0530 Subject: mmc: cmdq_hci: Helper API/info in cmdq for halt This patch adds following helper API/info - 1. cmdq_halt_poll to halt the controller using polling method. This is to be mainly used in case of an error from cmdq_irq context. 2. Adds num_cq_slots & dcmd_cq_slot info to mmc_host structure. This can be useful info for mmc host structure like in case of handling of multiple error requests 3. Adds CMDQ_STATE_CQ_DISABLE for cmdq host. In case of an error if halt also fails, CQE error handling code will disable CQ. So block layer needs to know - to not pull any requests in such case. Change-Id: I8e9a8d5094db82336917fcca4361ce84316c34ef Signed-off-by: Ritesh Harjani [subhashj@codeaurora.org: fixed merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index cd79dd903a8b..4743f46bf9b3 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -257,6 +257,7 @@ struct mmc_cmdq_context_info { #define CMDQ_STATE_ERR 0 #define CMDQ_STATE_DCMD_ACTIVE 1 #define CMDQ_STATE_HALT 2 +#define CMDQ_STATE_CQ_DISABLE 3 wait_queue_head_t queue_empty_wq; wait_queue_head_t wait; int active_small_sector_read_reqs; @@ -569,6 +570,8 @@ struct mmc_host { enum dev_state dev_status; bool wakeup_on_idle; struct mmc_cmdq_context_info cmdq_ctx; + int num_cq_slots; + int dcmd_cq_slot; bool cmdq_thist_enabled; /* * several cmdq supporting host controllers are extensions @@ -717,6 +720,21 @@ static inline int mmc_host_halt(struct mmc_host *host) return test_bit(CMDQ_STATE_HALT, &host->cmdq_ctx.curr_state); } +static inline void mmc_host_set_cq_disable(struct mmc_host *host) +{ + set_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state); +} + +static inline void mmc_host_clr_cq_disable(struct mmc_host *host) +{ + clear_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state); +} + +static inline int mmc_host_cq_disable(struct mmc_host *host) +{ + return test_bit(CMDQ_STATE_CQ_DISABLE, &host->cmdq_ctx.curr_state); +} + #ifdef CONFIG_MMC_CLKGATE void mmc_host_clk_hold(struct mmc_host *host); void mmc_host_clk_release(struct mmc_host *host); -- cgit v1.2.3 From 84de99e1ded4e96ac36c2287b7d9e4b9cdd8dcc4 Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Sun, 27 Sep 2015 21:51:01 +0530 Subject: mmc: core: Call cmdq_post_req with tag info instead of mrq Call mmc_/cmdq_post_req with tag number instead of mrq. This is needed in error handling as part of multiple request error handling. Change-Id: I175432639d28378ec74669e31deb4d1667c49bb8 Signed-off-by: Ritesh Harjani --- include/linux/mmc/core.h | 3 +-- include/linux/mmc/host.h | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 87332656e0fd..8b5197ba6759 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -136,8 +136,7 @@ struct mmc_cmdq_req; extern int mmc_cmdq_discard_queue(struct mmc_host *host, u32 tasks); extern int mmc_cmdq_halt(struct mmc_host *host, bool enable); extern int mmc_cmdq_halt_on_empty_queue(struct mmc_host *host); -extern void mmc_cmdq_post_req(struct mmc_host *host, struct mmc_request *mrq, - int err); +extern void mmc_cmdq_post_req(struct mmc_host *host, int tag, int err); extern int mmc_cmdq_start_req(struct mmc_host *host, struct mmc_cmdq_req *cmdq_req); extern int mmc_cmdq_prepare_flush(struct mmc_command *cmd); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 4743f46bf9b3..b923a74add1d 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -95,8 +95,7 @@ struct mmc_cmdq_host_ops { int (*enable)(struct mmc_host *host); void (*disable)(struct mmc_host *host, bool soft); int (*request)(struct mmc_host *host, struct mmc_request *mrq); - void (*post_req)(struct mmc_host *host, struct mmc_request *mrq, - int err); + void (*post_req)(struct mmc_host *host, int tag, int err); int (*halt)(struct mmc_host *host, bool halt); void (*reset)(struct mmc_host *host, bool soft); void (*dumpstate)(struct mmc_host *host); -- cgit v1.2.3 From bbd570a9b13e15b7b16034157b67f464f88f9546 Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Mon, 28 Sep 2015 15:55:01 +0530 Subject: mmc: core: cmdq helper for reset and claim host context This patch does following- This adds an API(mmc_cmdq_hw_reset), for RESET_ALL of SDHCI, power cycle mmc card and reintialize it, which enables cmdq as well(if supported). This acquires claim_host before calling mmc_power_restore. mmc_power_restore should be called with claim_host acquired, since this function is required from non-claim-host context in cmdq error handling. Change-Id: I31c4449dead1d4ad4e10a4822cce2298ec5fb4b6 Signed-off-by: Ritesh Harjani [subhashj@codeaurora.org: fixed merge conflicts, dropped some changes related to mmc_do_hw_reset] Signed-off-by: Subhash Jadavani --- include/linux/mmc/core.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h index 8b5197ba6759..89efaa67cc59 100644 --- a/include/linux/mmc/core.h +++ b/include/linux/mmc/core.h @@ -191,6 +191,7 @@ extern int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen); extern int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount, bool is_rel_write); extern int mmc_hw_reset(struct mmc_host *host); +extern int mmc_cmdq_hw_reset(struct mmc_host *host); extern int mmc_can_reset(struct mmc_card *card); extern void mmc_set_data_timeout(struct mmc_data *, const struct mmc_card *); -- cgit v1.2.3 From b90443c63bacb73da137a13811500816a07194ae Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Wed, 7 Oct 2015 16:42:47 +0530 Subject: mmc: block: Error handling fixes and support of reset_all This does following: 1. Adds support to handle multiple cmdq software requests timeout. Currently we schedule error handling work for the first timedout request. We requeue all pending tasks, knock off all tasks from device queue and reset card and controller as part of this, then for all other software requests timeout, if it comes while executing error work, we return BLK_EH_NOT_HANDLED. This fixes BUG_ON in case of multiple requests timesout together. 2. Current code resets CQE, power cycle the card and requeue all the requests in case of any error. 3. mmc_blk_cmdq_err work takes care freeing up all resource allocation like clk and rpm hold, in case of reset_all. 4. Currently we were never clearing error CMDQ_STATE_ERR in case of any error. This patch takes care of this bug. Change-Id: I83d483c11fe2d7f2e462086cc3c0932057304c0d Signed-off-by: Ritesh Harjani [subhashj@codeaurora.org: fixed compilation error] Signed-off-by: Subhash Jadavani --- include/linux/mmc/host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index b923a74add1d..4438833ca935 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -257,6 +257,7 @@ struct mmc_cmdq_context_info { #define CMDQ_STATE_DCMD_ACTIVE 1 #define CMDQ_STATE_HALT 2 #define CMDQ_STATE_CQ_DISABLE 3 +#define CMDQ_STATE_REQ_TIMED_OUT 4 wait_queue_head_t queue_empty_wq; wait_queue_head_t wait; int active_small_sector_read_reqs; -- cgit v1.2.3 From 5c8d7435461c642e7d807e474bf11a6de1e9c052 Mon Sep 17 00:00:00 2001 From: Konstantin Dorfman Date: Thu, 31 Dec 2015 14:45:48 +0200 Subject: mmc: core: postpone runtime suspend in case BKOPS is required Some devices require long BKOPs time in order to provide high performance. In the current solution, the host disables auto BKOPs or stops manual BKOPs in runtime suspend, regardless of the device need for BKOPs. This patch adds a check for device BKOPs status and defers suspend in case when BKOPs need. CRs-Fixed: 979630 Change-Id: Ib38d1ce58e4195d4969e9a367b5738c8e598d0ba Signed-off-by: Konstantin Dorfman [subhashj@codeaurora.org: fixed merge conflicts] Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index d88f6a027679..0f0c9963950e 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -327,7 +327,8 @@ struct mmc_bkops_stats { struct mmc_bkops_info { struct mmc_bkops_stats stats; bool needs_check; - bool needs_manual; + bool needs_bkops; + u32 retry_counter; }; enum mmc_pon_type { -- cgit v1.2.3 From e4db7c6cf66a4a9bbb4e9657f6852ba4cdeef8fa Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Thu, 25 Feb 2016 17:54:58 +0530 Subject: mmc: block: Add quirk and increase read data timeout for hynix emmc Hynix emmc cards are causing read data timeout. Increase timeout value to max of 4sec and add card quirk for all Hynix emmc cards. Change-Id: I78637dc787964ec5cafe297587d6a12ecf1d31c6 Signed-off-by: Ritesh Harjani --- include/linux/mmc/card.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 0f0c9963950e..8ebf9988b04e 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -486,6 +486,7 @@ struct mmc_fixup { #define CID_MANFID_MICRON 0x13 #define CID_MANFID_SAMSUNG 0x15 #define CID_MANFID_KINGSTON 0x70 +#define CID_MANFID_HYNIX 0x90 #define CID_MANFID_ANY (-1u) #define CID_OEMID_ANY ((unsigned short) -1) -- cgit v1.2.3 From 79d2f1626ba69198feff3376684f39b9e0838169 Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Thu, 12 May 2016 11:43:55 -0700 Subject: mmc: card: fix quirk bit map There seems to be bit map usage overlap between few MMC_QUIRKS_*, this change fixes it. Change-Id: I717a2de1261ed2de1a8c730b005b137f0687d969 Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 8ebf9988b04e..40665cb0ccde 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -386,9 +386,9 @@ struct mmc_card { #define MMC_QUIRK_INAND_DATA_TIMEOUT (1<<13) /* For incorrect data timeout */ #define MMC_QUIRK_BROKEN_HPI (1 << 14) /* For devices which gets */ /* broken due to HPI feature */ -#define MMC_QUIRK_CACHE_DISABLE (1 << 14) /* prevent cache enable */ -#define MMC_QUIRK_QCA6574_SETTINGS (1 << 15) /* QCA6574 card settings*/ -#define MMC_QUIRK_QCA9377_SETTINGS (1 << 16) /* QCA9377 card settings*/ +#define MMC_QUIRK_CACHE_DISABLE (1 << 15) /* prevent cache enable */ +#define MMC_QUIRK_QCA6574_SETTINGS (1 << 16) /* QCA6574 card settings*/ +#define MMC_QUIRK_QCA9377_SETTINGS (1 << 17) /* QCA9377 card settings*/ /* Make sure CMDQ is empty before queuing DCMD */ -- cgit v1.2.3 From e8032e07d1fbe7f71be0af640981f3a587df1d4d Mon Sep 17 00:00:00 2001 From: Subhash Jadavani Date: Thu, 12 May 2016 11:58:15 -0700 Subject: mmc: auto bkops fixes Change "man_bkops_en" to "bkops_en" to hold the status of both manual and auto bkops. Change-Id: I60029bae67cebb2c91147ad741b96f4caed9c1d9 Signed-off-by: Subhash Jadavani --- include/linux/mmc/card.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 40665cb0ccde..e7578be38ddf 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -88,7 +88,7 @@ struct mmc_ext_csd { bool hpi; /* HPI support bit */ unsigned int hpi_cmd; /* cmd used as HPI */ bool bkops; /* background support bit */ - u8 man_bkops_en; /* manual bkops enable */ + u8 bkops_en; /* bkops enable */ unsigned int data_sector_size; /* 512 bytes or 4KB */ unsigned int data_tag_unit_size; /* DATA TAG UNIT size */ unsigned int boot_ro_lock; /* ro lock support */ @@ -678,12 +678,12 @@ static inline bool mmc_card_support_auto_bkops(const struct mmc_card *c) static inline bool mmc_card_configured_manual_bkops(const struct mmc_card *c) { - return c->ext_csd.man_bkops_en & EXT_CSD_BKOPS_MANUAL_EN; + return c->ext_csd.bkops_en & EXT_CSD_BKOPS_MANUAL_EN; } static inline bool mmc_card_configured_auto_bkops(const struct mmc_card *c) { - return c->ext_csd.man_bkops_en & EXT_CSD_BKOPS_AUTO_EN; + return c->ext_csd.bkops_en & EXT_CSD_BKOPS_AUTO_EN; } static inline bool mmc_enable_qca6574_settings(const struct mmc_card *c) -- cgit v1.2.3