diff options
author | Ulf Hansson <ulf.hansson@linaro.org> | 2021-05-04 18:12:21 +0200 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2021-06-14 13:57:36 +0200 |
commit | 4e6306e0b83c6251699c2202e859b55ddf7b8c5f (patch) | |
tree | e8530ac73b15b0b698a2b7a21b4230136f4e5457 /drivers/mmc/core/sd.c | |
parent | c784f92769ae8eafb2eb489408757528ff7525df (diff) |
mmc: core: Read performance enhancements registers for SD cards
In SD spec v6.x the SD function extension registers for performance
enhancements were introduced. These registers let the SD card announce
supports for various performance related features, like "self-maintenance",
"cache" and "command queuing".
Let's extend the parsing of SD function extension registers and store the
information in the struct mmc_card. This prepares for subsequent changes to
implement the complete support for new the performance enhancement
features.
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Acked-by: Avri Altman <avri.altman@wdc.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com>
Link: https://lore.kernel.org/r/20210504161222.101536-11-ulf.hansson@linaro.org
Diffstat (limited to 'drivers/mmc/core/sd.c')
-rw-r--r-- | drivers/mmc/core/sd.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 2e687f1f4542..0b882aaedf78 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -1058,6 +1058,55 @@ out: return err; } +static int sd_parse_ext_reg_perf(struct mmc_card *card, u8 fno, u8 page, + u16 offset) +{ + int err; + u8 *reg_buf; + + reg_buf = kzalloc(512, GFP_KERNEL); + if (!reg_buf) + return -ENOMEM; + + err = sd_read_ext_reg(card, fno, page, offset, 512, reg_buf); + if (err) { + pr_warn("%s: error %d reading PERF func of ext reg\n", + mmc_hostname(card->host), err); + goto out; + } + + /* PERF revision. */ + card->ext_perf.rev = reg_buf[0]; + + /* FX_EVENT support at bit 0. */ + if (reg_buf[1] & BIT(0)) + card->ext_perf.feature_support |= SD_EXT_PERF_FX_EVENT; + + /* Card initiated self-maintenance support at bit 0. */ + if (reg_buf[2] & BIT(0)) + card->ext_perf.feature_support |= SD_EXT_PERF_CARD_MAINT; + + /* Host initiated self-maintenance support at bit 1. */ + if (reg_buf[2] & BIT(1)) + card->ext_perf.feature_support |= SD_EXT_PERF_HOST_MAINT; + + /* Cache support at bit 0. */ + if (reg_buf[4] & BIT(0)) + card->ext_perf.feature_support |= SD_EXT_PERF_CACHE; + + /* Command queue support indicated via queue depth bits (0 to 4). */ + if (reg_buf[6] & 0x1f) + card->ext_perf.feature_support |= SD_EXT_PERF_CMD_QUEUE; + + card->ext_perf.fno = fno; + card->ext_perf.page = page; + card->ext_perf.offset = offset; + +out: + kfree(reg_buf); + return err; +} + static int sd_parse_ext_reg(struct mmc_card *card, u8 *gen_info_buf, u16 *next_ext_addr) { @@ -1102,6 +1151,10 @@ static int sd_parse_ext_reg(struct mmc_card *card, u8 *gen_info_buf, if (sfc == 0x1) return sd_parse_ext_reg_power(card, fno, page, offset); + /* Standard Function Code for performance enhancement. */ + if (sfc == 0x2) + return sd_parse_ext_reg_perf(card, fno, page, offset); + return 0; } |