aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/mmc
diff options
context:
space:
mode:
authorJaehoon Chung <jh80.chung@samsung.com>2012-09-17 04:42:02 -0400
committerChris Ball <cjb@laptop.org>2012-10-03 10:05:12 -0400
commit950d56acce5d401f477b91d0177605b543d63d07 (patch)
tree205505f3976d02c6ef2fa9d6c911407f0e0f6c80 /include/linux/mmc
parentbec9d4e5939987053169a9bb48fc58b6a2d3e237 (diff)
mmc: support BKOPS feature for eMMC
Enable eMMC background operations (BKOPS) feature. If URGENT_BKOPS is set after a response, note that BKOPS are required. Immediately run BKOPS if required. Read/write operations should be requested during BKOPS(LEVEL-1), then issue HPI to interrupt the ongoing BKOPS and service the foreground operation. (This patch only controls the LEVEL2/3.) When repeating the writing 1GB data, at a certain time, performance is decreased. At that time, card triggers the Level-3 or Level-2. After running bkops, performance is recovered. Future considerations: * Check BKOPS_LEVEL=1 and start BKOPS in a preventive manner. * Interrupt ongoing BKOPS before powering off the card. * How do we get BKOPS_STATUS value (periodically send ext_csd command)? * If using periodic bkops, also consider runtime_pm control. Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Konstantin Dorfman <kdorfman@codeaurora.org> Reviewed-by: Maya Erez <merez@codeaurora.org> Signed-off-by: Chris Ball <cjb@laptop.org>
Diffstat (limited to 'include/linux/mmc')
-rw-r--r--include/linux/mmc/card.h8
-rw-r--r--include/linux/mmc/core.h4
-rw-r--r--include/linux/mmc/mmc.h19
3 files changed, 31 insertions, 0 deletions
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 4b27f9f503e4..78cc3be85391 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -76,10 +76,13 @@ struct mmc_ext_csd {
76 bool hpi_en; /* HPI enablebit */ 76 bool hpi_en; /* HPI enablebit */
77 bool hpi; /* HPI support bit */ 77 bool hpi; /* HPI support bit */
78 unsigned int hpi_cmd; /* cmd used as HPI */ 78 unsigned int hpi_cmd; /* cmd used as HPI */
79 bool bkops; /* background support bit */
80 bool bkops_en; /* background enable bit */
79 unsigned int data_sector_size; /* 512 bytes or 4KB */ 81 unsigned int data_sector_size; /* 512 bytes or 4KB */
80 unsigned int data_tag_unit_size; /* DATA TAG UNIT size */ 82 unsigned int data_tag_unit_size; /* DATA TAG UNIT size */
81 unsigned int boot_ro_lock; /* ro lock support */ 83 unsigned int boot_ro_lock; /* ro lock support */
82 bool boot_ro_lockable; 84 bool boot_ro_lockable;
85 u8 raw_exception_status; /* 53 */
83 u8 raw_partition_support; /* 160 */ 86 u8 raw_partition_support; /* 160 */
84 u8 raw_erased_mem_count; /* 181 */ 87 u8 raw_erased_mem_count; /* 181 */
85 u8 raw_ext_csd_structure; /* 194 */ 88 u8 raw_ext_csd_structure; /* 194 */
@@ -93,6 +96,7 @@ struct mmc_ext_csd {
93 u8 raw_sec_erase_mult; /* 230 */ 96 u8 raw_sec_erase_mult; /* 230 */
94 u8 raw_sec_feature_support;/* 231 */ 97 u8 raw_sec_feature_support;/* 231 */
95 u8 raw_trim_mult; /* 232 */ 98 u8 raw_trim_mult; /* 232 */
99 u8 raw_bkops_status; /* 246 */
96 u8 raw_sectors[4]; /* 212 - 4 bytes */ 100 u8 raw_sectors[4]; /* 212 - 4 bytes */
97 101
98 unsigned int feature_support; 102 unsigned int feature_support;
@@ -226,6 +230,7 @@ struct mmc_card {
226#define MMC_CARD_REMOVED (1<<7) /* card has been removed */ 230#define MMC_CARD_REMOVED (1<<7) /* card has been removed */
227#define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */ 231#define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */
228#define MMC_STATE_SLEEP (1<<9) /* card is in sleep state */ 232#define MMC_STATE_SLEEP (1<<9) /* card is in sleep state */
233#define MMC_STATE_DOING_BKOPS (1<<10) /* card is doing BKOPS */
229 unsigned int quirks; /* card quirks */ 234 unsigned int quirks; /* card quirks */
230#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ 235#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
231#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ 236#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
@@ -393,6 +398,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
393#define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) 398#define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
394#define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) 399#define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED))
395#define mmc_card_is_sleep(c) ((c)->state & MMC_STATE_SLEEP) 400#define mmc_card_is_sleep(c) ((c)->state & MMC_STATE_SLEEP)
401#define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS)
396 402
397#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) 403#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
398#define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) 404#define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
@@ -405,7 +411,9 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
405#define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) 411#define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
406#define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED) 412#define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
407#define mmc_card_set_sleep(c) ((c)->state |= MMC_STATE_SLEEP) 413#define mmc_card_set_sleep(c) ((c)->state |= MMC_STATE_SLEEP)
414#define mmc_card_set_doing_bkops(c) ((c)->state |= MMC_STATE_DOING_BKOPS)
408 415
416#define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS)
409#define mmc_card_clr_sleep(c) ((c)->state &= ~MMC_STATE_SLEEP) 417#define mmc_card_clr_sleep(c) ((c)->state &= ~MMC_STATE_SLEEP)
410/* 418/*
411 * Quirk add/remove for MMC products. 419 * Quirk add/remove for MMC products.
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 1b431c728b9a..9b9cdafc7737 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -134,6 +134,8 @@ struct mmc_host;
134struct mmc_card; 134struct mmc_card;
135struct mmc_async_req; 135struct mmc_async_req;
136 136
137extern int mmc_stop_bkops(struct mmc_card *);
138extern int mmc_read_bkops_status(struct mmc_card *);
137extern struct mmc_async_req *mmc_start_req(struct mmc_host *, 139extern struct mmc_async_req *mmc_start_req(struct mmc_host *,
138 struct mmc_async_req *, int *); 140 struct mmc_async_req *, int *);
139extern int mmc_interrupt_hpi(struct mmc_card *); 141extern int mmc_interrupt_hpi(struct mmc_card *);
@@ -142,6 +144,8 @@ extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int);
142extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *); 144extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *);
143extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, 145extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
144 struct mmc_command *, int); 146 struct mmc_command *, int);
147extern void mmc_start_bkops(struct mmc_card *card, bool from_exception);
148extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool);
145extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); 149extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
146 150
147#define MMC_ERASE_ARG 0x00000000 151#define MMC_ERASE_ARG 0x00000000
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index d425cab144d9..01e4b394029b 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -139,6 +139,7 @@ static inline bool mmc_op_multi(u32 opcode)
139#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */ 139#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
140#define R1_READY_FOR_DATA (1 << 8) /* sx, a */ 140#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
141#define R1_SWITCH_ERROR (1 << 7) /* sx, c */ 141#define R1_SWITCH_ERROR (1 << 7) /* sx, c */
142#define R1_EXCEPTION_EVENT (1 << 6) /* sx, a */
142#define R1_APP_CMD (1 << 5) /* sr, c */ 143#define R1_APP_CMD (1 << 5) /* sr, c */
143 144
144#define R1_STATE_IDLE 0 145#define R1_STATE_IDLE 0
@@ -274,12 +275,15 @@ struct _mmc_csd {
274#define EXT_CSD_FLUSH_CACHE 32 /* W */ 275#define EXT_CSD_FLUSH_CACHE 32 /* W */
275#define EXT_CSD_CACHE_CTRL 33 /* R/W */ 276#define EXT_CSD_CACHE_CTRL 33 /* R/W */
276#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */ 277#define EXT_CSD_POWER_OFF_NOTIFICATION 34 /* R/W */
278#define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO */
277#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */ 279#define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */
278#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ 280#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */
279#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */ 281#define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */
280#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */ 282#define EXT_CSD_PARTITION_SUPPORT 160 /* RO */
281#define EXT_CSD_HPI_MGMT 161 /* R/W */ 283#define EXT_CSD_HPI_MGMT 161 /* R/W */
282#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */ 284#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
285#define EXT_CSD_BKOPS_EN 163 /* R/W */
286#define EXT_CSD_BKOPS_START 164 /* W */
283#define EXT_CSD_SANITIZE_START 165 /* W */ 287#define EXT_CSD_SANITIZE_START 165 /* W */
284#define EXT_CSD_WR_REL_PARAM 166 /* RO */ 288#define EXT_CSD_WR_REL_PARAM 166 /* RO */
285#define EXT_CSD_BOOT_WP 173 /* R/W */ 289#define EXT_CSD_BOOT_WP 173 /* R/W */
@@ -313,11 +317,13 @@ struct _mmc_csd {
313#define EXT_CSD_PWR_CL_200_360 237 /* RO */ 317#define EXT_CSD_PWR_CL_200_360 237 /* RO */
314#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */ 318#define EXT_CSD_PWR_CL_DDR_52_195 238 /* RO */
315#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */ 319#define EXT_CSD_PWR_CL_DDR_52_360 239 /* RO */
320#define EXT_CSD_BKOPS_STATUS 246 /* RO */
316#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */ 321#define EXT_CSD_POWER_OFF_LONG_TIME 247 /* RO */
317#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */ 322#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
318#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */ 323#define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */
319#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ 324#define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */
320#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */ 325#define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */
326#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
321#define EXT_CSD_HPI_FEATURES 503 /* RO */ 327#define EXT_CSD_HPI_FEATURES 503 /* RO */
322 328
323/* 329/*
@@ -378,6 +384,19 @@ struct _mmc_csd {
378#define EXT_CSD_PWR_CL_8BIT_SHIFT 4 384#define EXT_CSD_PWR_CL_8BIT_SHIFT 4
379#define EXT_CSD_PWR_CL_4BIT_SHIFT 0 385#define EXT_CSD_PWR_CL_4BIT_SHIFT 0
380/* 386/*
387 * EXCEPTION_EVENT_STATUS field
388 */
389#define EXT_CSD_URGENT_BKOPS BIT(0)
390#define EXT_CSD_DYNCAP_NEEDED BIT(1)
391#define EXT_CSD_SYSPOOL_EXHAUSTED BIT(2)
392#define EXT_CSD_PACKED_FAILURE BIT(3)
393
394/*
395 * BKOPS status level
396 */
397#define EXT_CSD_BKOPS_LEVEL_2 0x2
398
399/*
381 * MMC_SWITCH access modes 400 * MMC_SWITCH access modes
382 */ 401 */
383 402