Merge branch 'master' of git://git.denx.de/u-boot-mmc

This commit is contained in:
Tom Rini 2015-08-13 07:20:44 -04:00
commit 0741701acf
2 changed files with 47 additions and 22 deletions

View File

@ -8,6 +8,7 @@
#include <bouncebuf.h> #include <bouncebuf.h>
#include <common.h> #include <common.h>
#include <errno.h>
#include <malloc.h> #include <malloc.h>
#include <mmc.h> #include <mmc.h>
#include <dwmmc.h> #include <dwmmc.h>
@ -110,7 +111,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
struct dwmci_host *host = mmc->priv; struct dwmci_host *host = mmc->priv;
ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac, ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac,
data ? DIV_ROUND_UP(data->blocks, 8) : 0); data ? DIV_ROUND_UP(data->blocks, 8) : 0);
int flags = 0, i; int ret = 0, flags = 0, i;
unsigned int timeout = 100000; unsigned int timeout = 100000;
u32 retry = 10000; u32 retry = 10000;
u32 mask, ctrl; u32 mask, ctrl;
@ -119,7 +120,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) { while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
if (get_timer(start) > timeout) { if (get_timer(start) > timeout) {
printf("%s: Timeout on data busy\n", __func__); debug("%s: Timeout on data busy\n", __func__);
return TIMEOUT; return TIMEOUT;
} }
} }
@ -178,7 +179,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
} }
if (i == retry) { if (i == retry) {
printf("%s: Timeout.\n", __func__); debug("%s: Timeout.\n", __func__);
return TIMEOUT; return TIMEOUT;
} }
@ -194,8 +195,8 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
debug("%s: Response Timeout.\n", __func__); debug("%s: Response Timeout.\n", __func__);
return TIMEOUT; return TIMEOUT;
} else if (mask & DWMCI_INTMSK_RE) { } else if (mask & DWMCI_INTMSK_RE) {
printf("%s: Response Error.\n", __func__); debug("%s: Response Error.\n", __func__);
return -1; return -EIO;
} }
@ -211,13 +212,31 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
} }
if (data) { if (data) {
do { start = get_timer(0);
timeout = 1000;
for (;;) {
mask = dwmci_readl(host, DWMCI_RINTSTS); mask = dwmci_readl(host, DWMCI_RINTSTS);
/* Error during data transfer. */
if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) { if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) {
printf("%s: DATA ERROR!\n", __func__); debug("%s: DATA ERROR!\n", __func__);
return -1; ret = -EINVAL;
break;
} }
} while (!(mask & DWMCI_INTMSK_DTO));
/* Data arrived correctly. */
if (mask & DWMCI_INTMSK_DTO) {
ret = 0;
break;
}
/* Check for timeout. */
if (get_timer(start) > timeout) {
debug("%s: Timeout waiting for data!\n",
__func__);
ret = TIMEOUT;
break;
}
}
dwmci_writel(host, DWMCI_RINTSTS, mask); dwmci_writel(host, DWMCI_RINTSTS, mask);
@ -230,7 +249,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
udelay(100); udelay(100);
return 0; return ret;
} }
static int dwmci_setup_bus(struct dwmci_host *host, u32 freq) static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
@ -251,7 +270,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
else if (host->bus_hz) else if (host->bus_hz)
sclk = host->bus_hz; sclk = host->bus_hz;
else { else {
printf("%s: Didn't get source clock value.\n", __func__); debug("%s: Didn't get source clock value.\n", __func__);
return -EINVAL; return -EINVAL;
} }
@ -270,7 +289,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
do { do {
status = dwmci_readl(host, DWMCI_CMD); status = dwmci_readl(host, DWMCI_CMD);
if (timeout-- < 0) { if (timeout-- < 0) {
printf("%s: Timeout!\n", __func__); debug("%s: Timeout!\n", __func__);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
} while (status & DWMCI_CMD_START); } while (status & DWMCI_CMD_START);
@ -285,7 +304,7 @@ static int dwmci_setup_bus(struct dwmci_host *host, u32 freq)
do { do {
status = dwmci_readl(host, DWMCI_CMD); status = dwmci_readl(host, DWMCI_CMD);
if (timeout-- < 0) { if (timeout-- < 0) {
printf("%s: Timeout!\n", __func__); debug("%s: Timeout!\n", __func__);
return -ETIMEDOUT; return -ETIMEDOUT;
} }
} while (status & DWMCI_CMD_START); } while (status & DWMCI_CMD_START);
@ -339,8 +358,8 @@ static int dwmci_init(struct mmc *mmc)
dwmci_writel(host, DWMCI_PWREN, 1); dwmci_writel(host, DWMCI_PWREN, 1);
if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) { if (!dwmci_wait_reset(host, DWMCI_RESET_ALL)) {
printf("%s[%d] Fail-reset!!\n", __func__, __LINE__); debug("%s[%d] Fail-reset!!\n", __func__, __LINE__);
return -1; return -EIO;
} }
/* Enumerate at 400KHz */ /* Enumerate at 400KHz */
@ -354,9 +373,15 @@ static int dwmci_init(struct mmc *mmc)
dwmci_writel(host, DWMCI_IDINTEN, 0); dwmci_writel(host, DWMCI_IDINTEN, 0);
dwmci_writel(host, DWMCI_BMOD, 1); dwmci_writel(host, DWMCI_BMOD, 1);
if (host->fifoth_val) { if (!host->fifoth_val) {
dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val); uint32_t fifo_size;
fifo_size = dwmci_readl(host, DWMCI_FIFOTH);
fifo_size = ((fifo_size & RX_WMARK_MASK) >> RX_WMARK_SHIFT) + 1;
host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_size / 2 - 1) |
TX_WMARK(fifo_size / 2);
} }
dwmci_writel(host, DWMCI_FIFOTH, host->fifoth_val);
dwmci_writel(host, DWMCI_CLKENA, 0); dwmci_writel(host, DWMCI_CLKENA, 0);
dwmci_writel(host, DWMCI_CLKSRC, 0); dwmci_writel(host, DWMCI_CLKSRC, 0);

View File

@ -11,7 +11,7 @@
#include <spi.h> #include <spi.h>
#include <crc.h> #include <crc.h>
#include <linux/crc7.h> #include <linux/crc7.h>
#include <linux/byteorder/swab.h> #include <asm/byteorder.h>
/* MMC/SD in SPI mode reports R1 status always */ /* MMC/SD in SPI mode reports R1 status always */
#define R1_SPI_IDLE (1 << 0) #define R1_SPI_IDLE (1 << 0)
@ -91,7 +91,7 @@ static uint mmc_spi_readdata(struct mmc *mmc, void *xbuf,
spi_xfer(spi, bsize * 8, NULL, buf, 0); spi_xfer(spi, bsize * 8, NULL, buf, 0);
spi_xfer(spi, 2 * 8, NULL, &crc, 0); spi_xfer(spi, 2 * 8, NULL, &crc, 0);
#ifdef CONFIG_MMC_SPI_CRC_ON #ifdef CONFIG_MMC_SPI_CRC_ON
if (swab16(cyg_crc16(buf, bsize)) != crc) { if (be_to_cpu16(cyg_crc16(buf, bsize)) != crc) {
debug("%s: CRC error\n", mmc->cfg->name); debug("%s: CRC error\n", mmc->cfg->name);
r1 = R1_SPI_COM_CRC; r1 = R1_SPI_COM_CRC;
break; break;
@ -120,7 +120,7 @@ static uint mmc_spi_writedata(struct mmc *mmc, const void *xbuf,
tok[1] = multi ? SPI_TOKEN_MULTI_WRITE : SPI_TOKEN_SINGLE; tok[1] = multi ? SPI_TOKEN_MULTI_WRITE : SPI_TOKEN_SINGLE;
while (bcnt--) { while (bcnt--) {
#ifdef CONFIG_MMC_SPI_CRC_ON #ifdef CONFIG_MMC_SPI_CRC_ON
crc = swab16(cyg_crc16((u8 *)buf, bsize)); crc = cpu_to_be16(cyg_crc16((u8 *)buf, bsize));
#endif #endif
spi_xfer(spi, 2 * 8, tok, NULL, 0); spi_xfer(spi, 2 * 8, tok, NULL, 0);
spi_xfer(spi, bsize * 8, buf, NULL, 0); spi_xfer(spi, bsize * 8, buf, NULL, 0);
@ -193,7 +193,7 @@ static int mmc_spi_request(struct mmc *mmc, struct mmc_cmd *cmd,
} else if (cmd->resp_type == MMC_RSP_R2) { } else if (cmd->resp_type == MMC_RSP_R2) {
r1 = mmc_spi_readdata(mmc, cmd->response, 1, 16); r1 = mmc_spi_readdata(mmc, cmd->response, 1, 16);
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
cmd->response[i] = swab32(cmd->response[i]); cmd->response[i] = be32_to_cpu(cmd->response[i]);
debug("r128 %x %x %x %x\n", cmd->response[0], cmd->response[1], debug("r128 %x %x %x %x\n", cmd->response[0], cmd->response[1],
cmd->response[2], cmd->response[3]); cmd->response[2], cmd->response[3]);
} else if (!data) { } else if (!data) {
@ -205,7 +205,7 @@ static int mmc_spi_request(struct mmc *mmc, struct mmc_cmd *cmd,
case SD_CMD_SEND_IF_COND: case SD_CMD_SEND_IF_COND:
case MMC_CMD_SPI_READ_OCR: case MMC_CMD_SPI_READ_OCR:
spi_xfer(spi, 4 * 8, NULL, cmd->response, 0); spi_xfer(spi, 4 * 8, NULL, cmd->response, 0);
cmd->response[0] = swab32(cmd->response[0]); cmd->response[0] = be32_to_cpu(cmd->response[0]);
debug("r32 %x\n", cmd->response[0]); debug("r32 %x\n", cmd->response[0]);
break; break;
case MMC_CMD_SEND_STATUS: case MMC_CMD_SEND_STATUS: