Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CQE incremental fixes part 2 #6419

Merged
merged 6 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions arch/arm/boot/dts/overlays/README
Original file line number Diff line number Diff line change
Expand Up @@ -378,9 +378,9 @@ Params:
non-lite SKU of CM4).
(default "on")

sd_cqe Use to enable Command Queueing on the SD
interface for faster Class A2 card performance
(Pi 5 only, default "off")
sd_cqe Set to "off" to disable Command Queueing if you
have an incompatible Class A2 SD card
(Pi 5 only, default "on")

sd_overclock Clock (in MHz) to use when the MMC framework
requests 50MHz
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ dpi_16bit_gpio2: &rp1_dpi_16bit_gpio2 { };
sd-uhs-sdr50;
sd-uhs-ddr50;
sd-uhs-sdr104;
supports-cqe;
cd-gpios = <&gio_aon 5 GPIO_ACTIVE_LOW>;
//no-1-8-v;
status = "okay";
Expand Down
30 changes: 26 additions & 4 deletions drivers/mmc/core/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -1177,12 +1177,26 @@ static void mmc_blk_issue_erase_rq(struct mmc_queue *mq, struct request *req,
unsigned int from, nr;
int err = 0;
blk_status_t status = BLK_STS_OK;
bool restart_cmdq = false;

if (!mmc_can_erase(card)) {
status = BLK_STS_NOTSUPP;
goto fail;
}

/*
* Only Discard ops are supported with SD cards in CQ mode
* (SD Physical Spec v9.00 4.19.2)
*/
if (mmc_card_sd(card) && card->ext_csd.cmdq_en && erase_arg != SD_DISCARD_ARG) {
restart_cmdq = true;
err = mmc_sd_cmdq_disable(card);
if (err) {
status = BLK_STS_IOERR;
goto fail;
}
}

from = blk_rq_pos(req);
nr = blk_rq_sectors(req);

Expand All @@ -1203,6 +1217,11 @@ static void mmc_blk_issue_erase_rq(struct mmc_queue *mq, struct request *req,
status = BLK_STS_IOERR;
else
mmc_blk_reset_success(md, type);

if (restart_cmdq)
err = mmc_sd_cmdq_enable(card);
if (err)
status = BLK_STS_IOERR;
fail:
blk_mq_end_request(req, status);
}
Expand Down Expand Up @@ -1524,6 +1543,7 @@ static void mmc_blk_cqe_complete_rq(struct mmc_queue *mq, struct request *req)
struct request_queue *q = req->q;
struct mmc_host *host = mq->card->host;
enum mmc_issue_type issue_type = mmc_issue_type(mq, req);
bool write = req_op(req) == REQ_OP_WRITE;
unsigned long flags;
bool put_card;
int err;
Expand Down Expand Up @@ -1555,7 +1575,7 @@ static void mmc_blk_cqe_complete_rq(struct mmc_queue *mq, struct request *req)

spin_lock_irqsave(&mq->lock, flags);

if (req_op(req) == REQ_OP_WRITE)
if (write)
mq->pending_writes--;
mq->in_flight[issue_type] -= 1;

Expand Down Expand Up @@ -2170,15 +2190,16 @@ static void mmc_blk_mq_poll_completion(struct mmc_queue *mq,
}

static void mmc_blk_mq_dec_in_flight(struct mmc_queue *mq, enum mmc_issue_type issue_type,
struct request *req)
bool write)
{
unsigned long flags;
bool put_card;

spin_lock_irqsave(&mq->lock, flags);

if (req_op(req) == REQ_OP_WRITE)
if (write)
mq->pending_writes--;

mq->in_flight[issue_type] -= 1;

put_card = (mmc_tot_in_flight(mq) == 0);
Expand All @@ -2193,6 +2214,7 @@ static void mmc_blk_mq_post_req(struct mmc_queue *mq, struct request *req,
bool can_sleep)
{
enum mmc_issue_type issue_type = mmc_issue_type(mq, req);
bool write = req_op(req) == REQ_OP_WRITE;
struct mmc_queue_req *mqrq = req_to_mmc_queue_req(req);
struct mmc_request *mrq = &mqrq->brq.mrq;
struct mmc_host *host = mq->card->host;
Expand All @@ -2212,7 +2234,7 @@ static void mmc_blk_mq_post_req(struct mmc_queue *mq, struct request *req,
blk_mq_complete_request(req);
}

mmc_blk_mq_dec_in_flight(mq, issue_type, req);
mmc_blk_mq_dec_in_flight(mq, issue_type, write);
}

void mmc_blk_mq_recovery(struct mmc_queue *mq)
Expand Down
21 changes: 21 additions & 0 deletions drivers/mmc/core/quirks.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = {
0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),

/*
* Early Sandisk Extreme and Extreme Pro A2 cards never finish SD cache
* flush in CQ mode. Latest card date this was seen on is 10/2020.
*/
_FIXUP_EXT(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, 2019, CID_MONTH_ANY,
0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),

_FIXUP_EXT(CID_NAME_ANY, CID_MANFID_SANDISK_SD, 0x5344, 2020, CID_MONTH_ANY,
0, -1ull, SDIO_ANY_ID, SDIO_ANY_ID, add_quirk_sd,
MMC_QUIRK_BROKEN_SD_CACHE, EXT_CSD_REV_ANY),

END_FIXUP
};

Expand Down Expand Up @@ -150,6 +162,15 @@ static const struct mmc_fixup __maybe_unused mmc_blk_fixups[] = {
MMC_FIXUP("SD32G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN),
MMC_FIXUP("SD64G", 0x41, 0x3432, add_quirk, MMC_QUIRK_ERASE_BROKEN),

/*
* Larger Integral SD cards using rebranded Phison controllers trash
* nearby flash blocks after erases.
*/
MMC_FIXUP("SD64G", 0x27, 0x5048, add_quirk, MMC_QUIRK_ERASE_BROKEN),
MMC_FIXUP("SD128", 0x27, 0x5048, add_quirk, MMC_QUIRK_ERASE_BROKEN),
MMC_FIXUP("SD256", 0x27, 0x5048, add_quirk, MMC_QUIRK_ERASE_BROKEN),
MMC_FIXUP("SD512", 0x27, 0x5048, add_quirk, MMC_QUIRK_ERASE_BROKEN),

END_FIXUP
};

Expand Down
8 changes: 0 additions & 8 deletions drivers/mmc/core/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1273,14 +1273,6 @@ static int sd_flush_cache(struct mmc_host *host)

reg_buf = card->ext_reg_buf;

/*
* Flushing requires sending CMD49 (adtc), which can't be done as a DCMD
* and conflicts with CQHCI - temporarily turn CQE off to use the SDHCI
* command/argument registers.
*/
if (host->cqe_on)
host->cqe_ops->cqe_off(host);

/*
* Set Flush Cache at bit 0 in the performance enhancement register at
* 261 bytes offset.
Expand Down
Loading