summaryrefslogtreecommitdiff
path: root/drivers/mmc/core/mmc_ops.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-08-19 12:45:51 +0400
committerUlf Hansson <ulf.hansson@linaro.org>2014-09-09 15:59:07 +0400
commit3d705d14fe4c72be83bae1610680e209ee226b9d (patch)
treef62e06a2feffe512962cf2ec00baccf52460cdbf /drivers/mmc/core/mmc_ops.c
parentb315376573778b195e640a163675fb9f5937ddca (diff)
downloadlinux-3d705d14fe4c72be83bae1610680e209ee226b9d.tar.xz
mmc: implement Driver Stage Register handling
Some eMMC and SD cards implement a DSR register that allows to tune raise/fall times and drive strength of the CMD and DATA outputs. The values to use depend on the card in use and the host. It might be needed to reduce the drive strength to prevent voltage peaks above the host's specification. Implement a 'dsr' devicetree property that allows to specify the value to set the DSR to. For non-dt setups the new members of mmc_host can be set by board code. This patch was initially authored by Sascha Hauer. It contains improvements authored by Markus Niebel and Uwe Kleine-König. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: Markus Niebel <Markus.Niebel@tq-group.com> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/core/mmc_ops.c')
-rw-r--r--drivers/mmc/core/mmc_ops.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index f51b5ba3bbea..ba0275e90617 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -93,6 +93,26 @@ int mmc_deselect_cards(struct mmc_host *host)
return _mmc_select_card(host, NULL);
}
+/*
+ * Write the value specified in the device tree or board code into the optional
+ * 16 bit Driver Stage Register. This can be used to tune raise/fall times and
+ * drive strength of the DAT and CMD outputs. The actual meaning of a given
+ * value is hardware dependant.
+ * The presence of the DSR register can be determined from the CSD register,
+ * bit 76.
+ */
+int mmc_set_dsr(struct mmc_host *host)
+{
+ struct mmc_command cmd = {0};
+
+ cmd.opcode = MMC_SET_DSR;
+
+ cmd.arg = (host->dsr << 16) | 0xffff;
+ cmd.flags = MMC_RSP_NONE | MMC_CMD_AC;
+
+ return mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
+}
+
int mmc_go_idle(struct mmc_host *host)
{
int err;