diff options
author | Heiner Kallweit <hkallweit1@gmail.com> | 2017-03-25 11:28:13 +0100 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2017-04-24 21:41:51 +0200 |
commit | e5e4a3eb131f79af49f48a741807318c32f29427 (patch) | |
tree | ad90b25cfb18f75fb09009e52f81555f88e216d1 | |
parent | mmc: meson-gx: switch to dynamic timeout values (diff) | |
download | linux-e5e4a3eb131f79af49f48a741807318c32f29427.tar.xz linux-e5e4a3eb131f79af49f48a741807318c32f29427.zip |
mmc: meson-gx: add CMD23 mode
CMD23 mode (use "set block count" command before transferring multiple
data blocks) typically is more performant as host / card know upfront
how many data blocks to expect. Therefore add support for this mode to
the driver.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
-rw-r--r-- | drivers/mmc/host/meson-gx-mmc.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 810b68d5067b..f5dd5cc71040 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c @@ -175,6 +175,17 @@ static unsigned int meson_mmc_get_timeout_msecs(struct mmc_data *data) return min(timeout, 32768U); /* max. 2^15 ms */ } +static struct mmc_command *meson_mmc_get_next_command(struct mmc_command *cmd) +{ + if (cmd->opcode == MMC_SET_BLOCK_COUNT && !cmd->error) + return cmd->mrq->cmd; + else if (mmc_op_multi(cmd->opcode) && + (!cmd->mrq->sbc || cmd->error || cmd->data->error)) + return cmd->mrq->stop; + else + return NULL; +} + static int meson_mmc_clk_set(struct meson_host *host, unsigned long clk_rate) { struct mmc_host *mmc = host->mmc; @@ -620,7 +631,7 @@ out: static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) { struct meson_host *host = dev_id; - struct mmc_command *cmd = host->cmd; + struct mmc_command *next_cmd, *cmd = host->cmd; struct mmc_data *data; unsigned int xfer_bytes; @@ -635,10 +646,11 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) host->bounce_buf, xfer_bytes); } - if (!data || !data->stop || cmd->mrq->sbc) - meson_mmc_request_done(host->mmc, cmd->mrq); + next_cmd = meson_mmc_get_next_command(cmd); + if (next_cmd) + meson_mmc_start_cmd(host->mmc, next_cmd); else - meson_mmc_start_cmd(host->mmc, data->stop); + meson_mmc_request_done(host->mmc, cmd->mrq); return IRQ_HANDLED; } @@ -750,6 +762,7 @@ static int meson_mmc_probe(struct platform_device *pdev) if (ret) goto err_div_clk; + mmc->caps |= MMC_CAP_CMD23; mmc->max_blk_count = CMD_CFG_LENGTH_MASK; mmc->max_req_size = mmc->max_blk_count * mmc->max_blk_size; |