Commit 0bc0b6e8 authored by Wolfram Sang's avatar Wolfram Sang Committed by Ulf Hansson

mmc: tmio: add eMMC support

We need to add R1 without CRC support, refactor the bus width routine a
little and extend a quirk check. To support "non-removable;" we need a
workaround which will be hopefully removed when reworking PM soon.
Signed-off-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent f7dd5462
...@@ -79,6 +79,9 @@ ...@@ -79,6 +79,9 @@
#define CLK_CTL_DIV_MASK 0xff #define CLK_CTL_DIV_MASK 0xff
#define CLK_CTL_SCLKEN BIT(8) #define CLK_CTL_SCLKEN BIT(8)
#define CARD_OPT_WIDTH8 BIT(13)
#define CARD_OPT_WIDTH BIT(15)
#define TMIO_BBS 512 /* Boot block size */ #define TMIO_BBS 512 /* Boot block size */
/* Definitions for values the CTRL_SDIO_STATUS register can take. */ /* Definitions for values the CTRL_SDIO_STATUS register can take. */
......
...@@ -336,7 +336,9 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command ...@@ -336,7 +336,9 @@ static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command
switch (mmc_resp_type(cmd)) { switch (mmc_resp_type(cmd)) {
case MMC_RSP_NONE: c |= RESP_NONE; break; case MMC_RSP_NONE: c |= RESP_NONE; break;
case MMC_RSP_R1: c |= RESP_R1; break; case MMC_RSP_R1:
case MMC_RSP_R1_NO_CRC:
c |= RESP_R1; break;
case MMC_RSP_R1B: c |= RESP_R1B; break; case MMC_RSP_R1B: c |= RESP_R1B; break;
case MMC_RSP_R2: c |= RESP_R2; break; case MMC_RSP_R2: c |= RESP_R2; break;
case MMC_RSP_R3: c |= RESP_R3; break; case MMC_RSP_R3: c |= RESP_R3; break;
...@@ -730,12 +732,13 @@ static int tmio_mmc_start_data(struct tmio_mmc_host *host, ...@@ -730,12 +732,13 @@ static int tmio_mmc_start_data(struct tmio_mmc_host *host,
pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n", pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n",
data->blksz, data->blocks); data->blksz, data->blocks);
/* Some hardware cannot perform 2 byte requests in 4 bit mode */ /* Some hardware cannot perform 2 byte requests in 4/8 bit mode */
if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) { if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4 ||
host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) {
int blksz_2bytes = pdata->flags & TMIO_MMC_BLKSZ_2BYTES; int blksz_2bytes = pdata->flags & TMIO_MMC_BLKSZ_2BYTES;
if (data->blksz < 2 || (data->blksz < 4 && !blksz_2bytes)) { if (data->blksz < 2 || (data->blksz < 4 && !blksz_2bytes)) {
pr_err("%s: %d byte block unsupported in 4 bit mode\n", pr_err("%s: %d byte block unsupported in 4/8 bit mode\n",
mmc_hostname(host->mmc), data->blksz); mmc_hostname(host->mmc), data->blksz);
return -EINVAL; return -EINVAL;
} }
...@@ -857,14 +860,16 @@ static void tmio_mmc_power_off(struct tmio_mmc_host *host) ...@@ -857,14 +860,16 @@ static void tmio_mmc_power_off(struct tmio_mmc_host *host)
static void tmio_mmc_set_bus_width(struct tmio_mmc_host *host, static void tmio_mmc_set_bus_width(struct tmio_mmc_host *host,
unsigned char bus_width) unsigned char bus_width)
{ {
switch (bus_width) { u16 reg = sd_ctrl_read16(host, CTL_SD_MEM_CARD_OPT)
case MMC_BUS_WIDTH_1: & ~(CARD_OPT_WIDTH | CARD_OPT_WIDTH8);
sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0);
break; /* reg now applies to MMC_BUS_WIDTH_4 */
case MMC_BUS_WIDTH_4: if (bus_width == MMC_BUS_WIDTH_1)
sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0); reg |= CARD_OPT_WIDTH;
break; else if (bus_width == MMC_BUS_WIDTH_8)
} reg |= CARD_OPT_WIDTH8;
sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, reg);
} }
/* Set MMC clock / power. /* Set MMC clock / power.
...@@ -1082,6 +1087,15 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host, ...@@ -1082,6 +1087,15 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
!mmc_card_is_removable(mmc) || !mmc_card_is_removable(mmc) ||
mmc->slot.cd_irq >= 0); mmc->slot.cd_irq >= 0);
/*
* On Gen2+, eMMC with NONREMOVABLE currently fails because native
* hotplug gets disabled. It seems RuntimePM related yet we need further
* research. Since we are planning a PM overhaul anyway, let's enforce
* for now the device being active by enabling native hotplug always.
*/
if (pdata->flags & TMIO_MMC_MIN_RCAR2)
_host->native_hotplug = true;
if (tmio_mmc_clk_enable(_host) < 0) { if (tmio_mmc_clk_enable(_host) < 0) {
mmc->f_max = pdata->hclk; mmc->f_max = pdata->hclk;
mmc->f_min = mmc->f_max / 512; mmc->f_min = mmc->f_max / 512;
......
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