diff options
-rw-r--r-- | drivers/mmc/core/mmc.c | 28 | ||||
-rw-r--r-- | include/linux/mmc/card.h | 3 | ||||
-rw-r--r-- | include/linux/mmc/host.h | 4 | ||||
-rw-r--r-- | include/linux/mmc/mmc.h | 15 |
4 files changed, 48 insertions, 2 deletions
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 8a3ad602a877..c8f3d6e0684e 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -538,6 +538,11 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
538 | } else { | 538 | } else { |
539 | card->ext_csd.data_tag_unit_size = 0; | 539 | card->ext_csd.data_tag_unit_size = 0; |
540 | } | 540 | } |
541 | |||
542 | card->ext_csd.max_packed_writes = | ||
543 | ext_csd[EXT_CSD_MAX_PACKED_WRITES]; | ||
544 | card->ext_csd.max_packed_reads = | ||
545 | ext_csd[EXT_CSD_MAX_PACKED_READS]; | ||
541 | } else { | 546 | } else { |
542 | card->ext_csd.data_sector_size = 512; | 547 | card->ext_csd.data_sector_size = 512; |
543 | } | 548 | } |
@@ -1275,6 +1280,29 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1275 | } | 1280 | } |
1276 | } | 1281 | } |
1277 | 1282 | ||
1283 | /* | ||
1284 | * The mandatory minimum values are defined for packed command. | ||
1285 | * read: 5, write: 3 | ||
1286 | */ | ||
1287 | if (card->ext_csd.max_packed_writes >= 3 && | ||
1288 | card->ext_csd.max_packed_reads >= 5 && | ||
1289 | host->caps2 & MMC_CAP2_PACKED_CMD) { | ||
1290 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
1291 | EXT_CSD_EXP_EVENTS_CTRL, | ||
1292 | EXT_CSD_PACKED_EVENT_EN, | ||
1293 | card->ext_csd.generic_cmd6_time); | ||
1294 | if (err && err != -EBADMSG) | ||
1295 | goto free_card; | ||
1296 | if (err) { | ||
1297 | pr_warn("%s: Enabling packed event failed\n", | ||
1298 | mmc_hostname(card->host)); | ||
1299 | card->ext_csd.packed_event_en = 0; | ||
1300 | err = 0; | ||
1301 | } else { | ||
1302 | card->ext_csd.packed_event_en = 1; | ||
1303 | } | ||
1304 | } | ||
1305 | |||
1278 | if (!oldcard) | 1306 | if (!oldcard) |
1279 | host->card = card; | 1307 | host->card = card; |
1280 | 1308 | ||
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 7069dcea27c5..237f253f2fe0 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
@@ -53,6 +53,9 @@ struct mmc_ext_csd { | |||
53 | u8 part_config; | 53 | u8 part_config; |
54 | u8 cache_ctrl; | 54 | u8 cache_ctrl; |
55 | u8 rst_n_function; | 55 | u8 rst_n_function; |
56 | u8 max_packed_writes; | ||
57 | u8 max_packed_reads; | ||
58 | u8 packed_event_en; | ||
56 | unsigned int part_time; /* Units: ms */ | 59 | unsigned int part_time; /* Units: ms */ |
57 | unsigned int sa_timeout; /* Units: 100ns */ | 60 | unsigned int sa_timeout; /* Units: 100ns */ |
58 | unsigned int generic_cmd6_time; /* Units: 10ms */ | 61 | unsigned int generic_cmd6_time; /* Units: 10ms */ |
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 6c235e03de29..a0466c03f5e1 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h | |||
@@ -276,6 +276,10 @@ struct mmc_host { | |||
276 | #define MMC_CAP2_HC_ERASE_SZ (1 << 9) /* High-capacity erase size */ | 276 | #define MMC_CAP2_HC_ERASE_SZ (1 << 9) /* High-capacity erase size */ |
277 | #define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */ | 277 | #define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */ |
278 | #define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal active high */ | 278 | #define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal active high */ |
279 | #define MMC_CAP2_PACKED_RD (1 << 12) /* Allow packed read */ | ||
280 | #define MMC_CAP2_PACKED_WR (1 << 13) /* Allow packed write */ | ||
281 | #define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \ | ||
282 | MMC_CAP2_PACKED_WR) | ||
279 | 283 | ||
280 | mmc_pm_flag_t pm_caps; /* supported pm features */ | 284 | mmc_pm_flag_t pm_caps; /* supported pm features */ |
281 | 285 | ||
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index 94d532e41c61..50bcde3677ca 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h | |||
@@ -139,7 +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_EXCEPTION_EVENT (1 << 6) /* sr, a */ |
143 | #define R1_APP_CMD (1 << 5) /* sr, c */ | 143 | #define R1_APP_CMD (1 << 5) /* sr, c */ |
144 | 144 | ||
145 | #define R1_STATE_IDLE 0 | 145 | #define R1_STATE_IDLE 0 |
@@ -275,7 +275,10 @@ struct _mmc_csd { | |||
275 | #define EXT_CSD_FLUSH_CACHE 32 /* W */ | 275 | #define EXT_CSD_FLUSH_CACHE 32 /* W */ |
276 | #define EXT_CSD_CACHE_CTRL 33 /* R/W */ | 276 | #define EXT_CSD_CACHE_CTRL 33 /* R/W */ |
277 | #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 */ | 278 | #define EXT_CSD_PACKED_FAILURE_INDEX 35 /* RO */ |
279 | #define EXT_CSD_PACKED_CMD_STATUS 36 /* RO */ | ||
280 | #define EXT_CSD_EXP_EVENTS_STATUS 54 /* RO, 2 bytes */ | ||
281 | #define EXT_CSD_EXP_EVENTS_CTRL 56 /* R/W, 2 bytes */ | ||
279 | #define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */ | 282 | #define EXT_CSD_DATA_SECTOR_SIZE 61 /* R */ |
280 | #define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ | 283 | #define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ |
281 | #define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */ | 284 | #define EXT_CSD_PARTITION_ATTRIBUTE 156 /* R/W */ |
@@ -324,6 +327,8 @@ struct _mmc_csd { | |||
324 | #define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */ | 327 | #define EXT_CSD_CACHE_SIZE 249 /* RO, 4 bytes */ |
325 | #define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ | 328 | #define EXT_CSD_TAG_UNIT_SIZE 498 /* RO */ |
326 | #define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */ | 329 | #define EXT_CSD_DATA_TAG_SUPPORT 499 /* RO */ |
330 | #define EXT_CSD_MAX_PACKED_WRITES 500 /* RO */ | ||
331 | #define EXT_CSD_MAX_PACKED_READS 501 /* RO */ | ||
327 | #define EXT_CSD_BKOPS_SUPPORT 502 /* RO */ | 332 | #define EXT_CSD_BKOPS_SUPPORT 502 /* RO */ |
328 | #define EXT_CSD_HPI_FEATURES 503 /* RO */ | 333 | #define EXT_CSD_HPI_FEATURES 503 /* RO */ |
329 | 334 | ||
@@ -385,6 +390,9 @@ struct _mmc_csd { | |||
385 | #define EXT_CSD_PWR_CL_4BIT_MASK 0x0F /* 8 bit PWR CLS */ | 390 | #define EXT_CSD_PWR_CL_4BIT_MASK 0x0F /* 8 bit PWR CLS */ |
386 | #define EXT_CSD_PWR_CL_8BIT_SHIFT 4 | 391 | #define EXT_CSD_PWR_CL_8BIT_SHIFT 4 |
387 | #define EXT_CSD_PWR_CL_4BIT_SHIFT 0 | 392 | #define EXT_CSD_PWR_CL_4BIT_SHIFT 0 |
393 | |||
394 | #define EXT_CSD_PACKED_EVENT_EN BIT(3) | ||
395 | |||
388 | /* | 396 | /* |
389 | * EXCEPTION_EVENT_STATUS field | 397 | * EXCEPTION_EVENT_STATUS field |
390 | */ | 398 | */ |
@@ -393,6 +401,9 @@ struct _mmc_csd { | |||
393 | #define EXT_CSD_SYSPOOL_EXHAUSTED BIT(2) | 401 | #define EXT_CSD_SYSPOOL_EXHAUSTED BIT(2) |
394 | #define EXT_CSD_PACKED_FAILURE BIT(3) | 402 | #define EXT_CSD_PACKED_FAILURE BIT(3) |
395 | 403 | ||
404 | #define EXT_CSD_PACKED_GENERIC_ERROR BIT(0) | ||
405 | #define EXT_CSD_PACKED_INDEXED_ERROR BIT(1) | ||
406 | |||
396 | /* | 407 | /* |
397 | * BKOPS status level | 408 | * BKOPS status level |
398 | */ | 409 | */ |