mmc: tmio: add eMMC HS400 mode support
This patch adds processing for selecting HS400 mode. Signed-off-by: Masaharu Hayakawa <masaharu.hayakawa.ry@renesas.com> Signed-off-by: Simon Horman <horms+renesas@verge.net.au> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
parent
ba6c7ac3a2
commit
db924bba47
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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))
|
||||
clk |= 0xff;
|
||||
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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue