diff options
author | Jaehoon Chung <jh80.chung@samsung.com> | 2012-09-17 04:42:02 -0400 |
---|---|---|
committer | Chris Ball <cjb@laptop.org> | 2012-10-03 10:05:12 -0400 |
commit | 950d56acce5d401f477b91d0177605b543d63d07 (patch) | |
tree | 205505f3976d02c6ef2fa9d6c911407f0e0f6c80 /include/linux/mmc | |
parent | bec9d4e5939987053169a9bb48fc58b6a2d3e237 (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.h | 8 | ||||
-rw-r--r-- | include/linux/mmc/core.h | 4 | ||||
-rw-r--r-- | include/linux/mmc/mmc.h | 19 |
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; | |||
134 | struct mmc_card; | 134 | struct mmc_card; |
135 | struct mmc_async_req; | 135 | struct mmc_async_req; |
136 | 136 | ||
137 | extern int mmc_stop_bkops(struct mmc_card *); | ||
138 | extern int mmc_read_bkops_status(struct mmc_card *); | ||
137 | extern struct mmc_async_req *mmc_start_req(struct mmc_host *, | 139 | extern struct mmc_async_req *mmc_start_req(struct mmc_host *, |
138 | struct mmc_async_req *, int *); | 140 | struct mmc_async_req *, int *); |
139 | extern int mmc_interrupt_hpi(struct mmc_card *); | 141 | extern int mmc_interrupt_hpi(struct mmc_card *); |
@@ -142,6 +144,8 @@ extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int); | |||
142 | extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *); | 144 | extern int mmc_app_cmd(struct mmc_host *, struct mmc_card *); |
143 | extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, | 145 | extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *, |
144 | struct mmc_command *, int); | 146 | struct mmc_command *, int); |
147 | extern void mmc_start_bkops(struct mmc_card *card, bool from_exception); | ||
148 | extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool); | ||
145 | extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int); | 149 | extern 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 | ||