Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit db924bba authored by Masaharu Hayakawa's avatar Masaharu Hayakawa Committed by Ulf Hansson
Browse files

mmc: tmio: add eMMC HS400 mode support



This patch adds processing for selecting HS400 mode.

Signed-off-by: default avatarMasaharu Hayakawa <masaharu.hayakawa.ry@renesas.com>
Signed-off-by: default avatarSimon Horman <horms+renesas@verge.net.au>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent ba6c7ac3
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
#define CTL_DMA_ENABLE 0xd8
#define CTL_RESET_SD 0xe0
#define CTL_VERSION 0xe2
#define CTL_SDIF_MODE 0xe6
#define CTL_SDIO_REGS 0x100
#define CTL_CLK_AND_WAIT_CTL 0x138
#define CTL_RESET_SDIO 0x1e0
@@ -191,6 +192,11 @@ struct tmio_mmc_host {
	/* Tuning values: 1 for success, 0 for failure */
	DECLARE_BITMAP(taps, BITS_PER_BYTE * sizeof(long));
	unsigned int tap_num;
	unsigned long tap_set;

	void (*prepare_hs400_tuning)(struct tmio_mmc_host *host);
	void (*hs400_downgrade)(struct tmio_mmc_host *host);
	void (*hs400_complete)(struct tmio_mmc_host *host);

	const struct tmio_mmc_dma_ops *dma_ops;
};
+45 −2
Original line number Diff line number Diff line
@@ -199,6 +199,14 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
		tmio_mmc_clk_stop(host);
		return;
	}
	/*
	 * Both HS400 and HS200/SD104 set 200MHz, but some devices need to
	 * set 400MHz to distinguish the CPG settings in HS400.
	 */
	if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400 &&
	    host->pdata->flags & TMIO_MMC_HAVE_4TAP_HS400 &&
	    new_clock == 200000000)
		new_clock = 400000000;

	if (host->clk_update)
		clock = host->clk_update(host, new_clock) / 512;
@@ -209,8 +217,13 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
		clock <<= 1;

	/* 1/1 clock is option */
	if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) && ((clk >> 22) & 0x1))
	if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) &&
	    ((clk >> 22) & 0x1)) {
		if (!(host->mmc->ios.timing == MMC_TIMING_MMC_HS400))
			clk |= 0xff;
		else
			clk &= ~0xff;
	}

	if (host->set_clk_div)
		host->set_clk_div(host->pdev, (clk >> 22) & 1);
@@ -1087,6 +1100,33 @@ static int tmio_multi_io_quirk(struct mmc_card *card,
	return blk_size;
}

static int tmio_mmc_prepare_hs400_tuning(struct mmc_host *mmc,
					 struct mmc_ios *ios)
{
	struct tmio_mmc_host *host = mmc_priv(mmc);

	if (host->prepare_hs400_tuning)
		host->prepare_hs400_tuning(host);

	return 0;
}

static void tmio_mmc_hs400_downgrade(struct mmc_host *mmc)
{
	struct tmio_mmc_host *host = mmc_priv(mmc);

	if (host->hs400_downgrade)
		host->hs400_downgrade(host);
}

static void tmio_mmc_hs400_complete(struct mmc_host *mmc)
{
	struct tmio_mmc_host *host = mmc_priv(mmc);

	if (host->hs400_complete)
		host->hs400_complete(host);
}

static const struct mmc_host_ops tmio_mmc_ops = {
	.request	= tmio_mmc_request,
	.set_ios	= tmio_mmc_set_ios,
@@ -1096,6 +1136,9 @@ static const struct mmc_host_ops tmio_mmc_ops = {
	.multi_io_quirk	= tmio_multi_io_quirk,
	.hw_reset	= tmio_mmc_hw_reset,
	.execute_tuning = tmio_mmc_execute_tuning,
	.prepare_hs400_tuning = tmio_mmc_prepare_hs400_tuning,
	.hs400_downgrade = tmio_mmc_hs400_downgrade,
	.hs400_complete	= tmio_mmc_hs400_complete,
};

static int tmio_mmc_init_ocr(struct tmio_mmc_host *host)
+3 −0
Original line number Diff line number Diff line
@@ -90,6 +90,9 @@
/* Some controllers have a CBSY bit */
#define TMIO_MMC_HAVE_CBSY		BIT(11)

/* Some controllers that support HS400 use use 4 taps while others use 8. */
#define TMIO_MMC_HAVE_4TAP_HS400	BIT(13)

int tmio_core_mmc_enable(void __iomem *cnf, int shift, unsigned long base);
int tmio_core_mmc_resume(void __iomem *cnf, int shift, unsigned long base);
void tmio_core_mmc_pwr(void __iomem *cnf, int shift, int state);