Commit e5e4a3eb authored by Heiner Kallweit's avatar Heiner Kallweit Committed by Ulf Hansson

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: default avatarHeiner Kallweit <hkallweit1@gmail.com>
Reviewed-by: default avatarKevin Hilman <khilman@baylibre.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent 4eee86c3
...@@ -175,6 +175,17 @@ static unsigned int meson_mmc_get_timeout_msecs(struct mmc_data *data) ...@@ -175,6 +175,17 @@ static unsigned int meson_mmc_get_timeout_msecs(struct mmc_data *data)
return min(timeout, 32768U); /* max. 2^15 ms */ 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) static int meson_mmc_clk_set(struct meson_host *host, unsigned long clk_rate)
{ {
struct mmc_host *mmc = host->mmc; struct mmc_host *mmc = host->mmc;
...@@ -620,7 +631,7 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id) ...@@ -620,7 +631,7 @@ static irqreturn_t meson_mmc_irq(int irq, void *dev_id)
static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
{ {
struct meson_host *host = 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; struct mmc_data *data;
unsigned int xfer_bytes; unsigned int xfer_bytes;
...@@ -635,10 +646,11 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id) ...@@ -635,10 +646,11 @@ static irqreturn_t meson_mmc_irq_thread(int irq, void *dev_id)
host->bounce_buf, xfer_bytes); host->bounce_buf, xfer_bytes);
} }
if (!data || !data->stop || cmd->mrq->sbc) next_cmd = meson_mmc_get_next_command(cmd);
meson_mmc_request_done(host->mmc, cmd->mrq); if (next_cmd)
meson_mmc_start_cmd(host->mmc, next_cmd);
else else
meson_mmc_start_cmd(host->mmc, data->stop); meson_mmc_request_done(host->mmc, cmd->mrq);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -750,6 +762,7 @@ static int meson_mmc_probe(struct platform_device *pdev) ...@@ -750,6 +762,7 @@ static int meson_mmc_probe(struct platform_device *pdev)
if (ret) if (ret)
goto err_div_clk; goto err_div_clk;
mmc->caps |= MMC_CAP_CMD23;
mmc->max_blk_count = CMD_CFG_LENGTH_MASK; mmc->max_blk_count = CMD_CFG_LENGTH_MASK;
mmc->max_req_size = mmc->max_blk_count * mmc->max_blk_size; mmc->max_req_size = mmc->max_blk_count * mmc->max_blk_size;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment