125f21cc7ab9412e9d59d5b722c398cdf62d1c79
[openwrt/staging/xback.git] /
1 From 382e6f9ec8c66b99657922073f5b9b312925dc1f Mon Sep 17 00:00:00 2001
2 From: Jonathan Bell <jonathan@raspberrypi.com>
3 Date: Tue, 26 Mar 2024 13:36:23 +0000
4 Subject: [PATCH 0995/1085] drivers: mmc: be more cautious when manipulating
5 Command Queue enable
6
7 Don't attempt to turn on CQ if the other mandatory features are not
8 indicated as supported by the card. Also make sure that the register write
9 actually stuck, as some cards claim support but never report back that
10 the queue engine is enabled.
11
12 Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
13 ---
14 drivers/mmc/core/sd.c | 8 ++++++--
15 drivers/mmc/core/sd_ops.c | 22 ++++++++++++++++++++++
16 2 files changed, 28 insertions(+), 2 deletions(-)
17
18 --- a/drivers/mmc/core/sd.c
19 +++ b/drivers/mmc/core/sd.c
20 @@ -1088,8 +1088,12 @@ static int sd_parse_ext_reg_perf(struct
21 if ((reg_buf[4] & BIT(0)) && !mmc_card_broken_sd_cache(card))
22 card->ext_perf.feature_support |= SD_EXT_PERF_CACHE;
23
24 - /* Command queue support indicated via queue depth bits (0 to 4). */
25 - if (reg_buf[6] & 0x1f) {
26 + /*
27 + * Command queue support indicated via queue depth bits (0 to 4).
28 + * Qualify this with the other mandatory required features.
29 + */
30 + if (reg_buf[6] & 0x1f && card->ext_power.feature_support & SD_EXT_POWER_OFF_NOTIFY &&
31 + card->ext_perf.feature_support & SD_EXT_PERF_CACHE) {
32 card->ext_perf.feature_support |= SD_EXT_PERF_CMD_QUEUE;
33 card->ext_csd.cmdq_depth = reg_buf[6] & 0x1f;
34 card->ext_csd.cmdq_support = true;
35 --- a/drivers/mmc/core/sd_ops.c
36 +++ b/drivers/mmc/core/sd_ops.c
37 @@ -8,6 +8,7 @@
38 #include <linux/slab.h>
39 #include <linux/types.h>
40 #include <linux/export.h>
41 +#include <linux/ktime.h>
42 #include <linux/scatterlist.h>
43
44 #include <linux/mmc/host.h>
45 @@ -448,6 +449,8 @@ static int mmc_sd_cmdq_switch(struct mmc
46 {
47 int err;
48 u8 reg = 0;
49 + u8 *reg_buf = card->ext_reg_buf;
50 + ktime_t timeout;
51 /*
52 * SD offers two command queueing modes - sequential (in-order) and
53 * voluntary (out-of-order). Apps Class A2 performance is only
54 @@ -460,6 +463,25 @@ static int mmc_sd_cmdq_switch(struct mmc
55 /* Performance enhancement register byte 262 controls command queueing */
56 err = mmc_sd_write_ext_reg(card, card->ext_perf.fno, card->ext_perf.page,
57 card->ext_perf.offset + 262, reg);
58 + if (err)
59 + goto out;
60 +
61 + /* Poll the register - cards may have a lazy init/deinit sequence. */
62 + timeout = ktime_add_ms(ktime_get(), 10);
63 + while (1) {
64 + err = mmc_sd_read_ext_reg(card, card->ext_perf.fno, card->ext_perf.page,
65 + card->ext_perf.offset + 262, 1, reg_buf);
66 + if (err)
67 + break;
68 + if ((reg_buf[0] & BIT(0)) == reg)
69 + break;
70 + if (ktime_after(ktime_get(), timeout)) {
71 + err = -EBADMSG;
72 + break;
73 + }
74 + usleep_range(100, 200);
75 + }
76 +out:
77 if (!err)
78 card->ext_csd.cmdq_en = enable;
79