|
@@ -72,8 +72,10 @@ uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
|
|
uint xfertyp = 0;
|
|
uint xfertyp = 0;
|
|
|
|
|
|
if (data) {
|
|
if (data) {
|
|
- xfertyp |= XFERTYP_DPSEL | XFERTYP_DMAEN;
|
|
|
|
-
|
|
|
|
|
|
+ xfertyp |= XFERTYP_DPSEL;
|
|
|
|
+#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
|
|
|
|
+ xfertyp |= XFERTYP_DMAEN;
|
|
|
|
+#endif
|
|
if (data->blocks > 1) {
|
|
if (data->blocks > 1) {
|
|
xfertyp |= XFERTYP_MSBSEL;
|
|
xfertyp |= XFERTYP_MSBSEL;
|
|
xfertyp |= XFERTYP_BCEN;
|
|
xfertyp |= XFERTYP_BCEN;
|
|
@@ -97,6 +99,71 @@ uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
|
|
return XFERTYP_CMD(cmd->cmdidx) | xfertyp;
|
|
return XFERTYP_CMD(cmd->cmdidx) | xfertyp;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
|
|
|
|
+/*
|
|
|
|
+ * PIO Read/Write Mode reduce the performace as DMA is not used in this mode.
|
|
|
|
+ */
|
|
|
|
+static int
|
|
|
|
+esdhc_pio_read_write(struct mmc *mmc, struct mmc_data *data)
|
|
|
|
+{
|
|
|
|
+ struct fsl_esdhc *regs = mmc->priv;
|
|
|
|
+ uint blocks;
|
|
|
|
+ char *buffer;
|
|
|
|
+ uint databuf;
|
|
|
|
+ uint size;
|
|
|
|
+ uint irqstat;
|
|
|
|
+ uint timeout;
|
|
|
|
+
|
|
|
|
+ if (data->flags & MMC_DATA_READ) {
|
|
|
|
+ blocks = data->blocks;
|
|
|
|
+ buffer = data->dest;
|
|
|
|
+ while (blocks) {
|
|
|
|
+ timeout = PIO_TIMEOUT;
|
|
|
|
+ size = data->blocksize;
|
|
|
|
+ irqstat = esdhc_read32(®s->irqstat);
|
|
|
|
+ while (!(esdhc_read32(®s->prsstat) & PRSSTAT_BREN)
|
|
|
|
+ && --timeout);
|
|
|
|
+ if (timeout <= 0) {
|
|
|
|
+ printf("\nData Read Failed in PIO Mode.");
|
|
|
|
+ return timeout;
|
|
|
|
+ }
|
|
|
|
+ while (size && (!(irqstat & IRQSTAT_TC))) {
|
|
|
|
+ udelay(100); /* Wait before last byte transfer complete */
|
|
|
|
+ irqstat = esdhc_read32(®s->irqstat);
|
|
|
|
+ databuf = in_le32(®s->datport);
|
|
|
|
+ *((uint *)buffer) = databuf;
|
|
|
|
+ buffer += 4;
|
|
|
|
+ size -= 4;
|
|
|
|
+ }
|
|
|
|
+ blocks--;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ blocks = data->blocks;
|
|
|
|
+ buffer = data->src;
|
|
|
|
+ while (blocks) {
|
|
|
|
+ timeout = PIO_TIMEOUT;
|
|
|
|
+ size = data->blocksize;
|
|
|
|
+ irqstat = esdhc_read32(®s->irqstat);
|
|
|
|
+ while (!(esdhc_read32(®s->prsstat) & PRSSTAT_BWEN)
|
|
|
|
+ && --timeout);
|
|
|
|
+ if (timeout <= 0) {
|
|
|
|
+ printf("\nData Write Failed in PIO Mode.");
|
|
|
|
+ return timeout;
|
|
|
|
+ }
|
|
|
|
+ while (size && (!(irqstat & IRQSTAT_TC))) {
|
|
|
|
+ udelay(100); /* Wait before last byte transfer complete */
|
|
|
|
+ databuf = *((uint *)buffer);
|
|
|
|
+ buffer += 4;
|
|
|
|
+ size -= 4;
|
|
|
|
+ irqstat = esdhc_read32(®s->irqstat);
|
|
|
|
+ out_le32(®s->datport, databuf);
|
|
|
|
+ }
|
|
|
|
+ blocks--;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
|
|
static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
|
|
{
|
|
{
|
|
uint wml_value;
|
|
uint wml_value;
|
|
@@ -104,6 +171,17 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
|
|
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
|
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
|
|
struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
|
|
struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
|
|
|
|
|
|
|
|
+#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
|
|
|
|
+ if (!(data->flags & MMC_DATA_READ)) {
|
|
|
|
+ if ((esdhc_read32(®s->prsstat) & PRSSTAT_WPSPL) == 0) {
|
|
|
|
+ printf("\nThe SD card is locked. "
|
|
|
|
+ "Can not write to a locked card.\n\n");
|
|
|
|
+ return TIMEOUT;
|
|
|
|
+ }
|
|
|
|
+ esdhc_write32(®s->dsaddr, (u32)data->src);
|
|
|
|
+ } else
|
|
|
|
+ esdhc_write32(®s->dsaddr, (u32)data->dest);
|
|
|
|
+#else
|
|
wml_value = data->blocksize/4;
|
|
wml_value = data->blocksize/4;
|
|
|
|
|
|
if (data->flags & MMC_DATA_READ) {
|
|
if (data->flags & MMC_DATA_READ) {
|
|
@@ -124,6 +202,7 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
|
|
wml_value << 16);
|
|
wml_value << 16);
|
|
esdhc_write32(®s->dsaddr, (u32)data->src);
|
|
esdhc_write32(®s->dsaddr, (u32)data->src);
|
|
}
|
|
}
|
|
|
|
+#endif
|
|
|
|
|
|
esdhc_write32(®s->blkattr, data->blocks << 16 | data->blocksize);
|
|
esdhc_write32(®s->blkattr, data->blocks << 16 | data->blocksize);
|
|
|
|
|
|
@@ -220,6 +299,9 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
|
|
|
|
|
/* Wait until all of the blocks are transferred */
|
|
/* Wait until all of the blocks are transferred */
|
|
if (data) {
|
|
if (data) {
|
|
|
|
+#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
|
|
|
|
+ esdhc_pio_read_write(mmc, data);
|
|
|
|
+#else
|
|
do {
|
|
do {
|
|
irqstat = esdhc_read32(®s->irqstat);
|
|
irqstat = esdhc_read32(®s->irqstat);
|
|
|
|
|
|
@@ -230,6 +312,7 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
|
return TIMEOUT;
|
|
return TIMEOUT;
|
|
} while (!(irqstat & IRQSTAT_TC) &&
|
|
} while (!(irqstat & IRQSTAT_TC) &&
|
|
(esdhc_read32(®s->prsstat) & PRSSTAT_DLA));
|
|
(esdhc_read32(®s->prsstat) & PRSSTAT_DLA));
|
|
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
|
|
esdhc_write32(®s->irqstat, -1);
|
|
esdhc_write32(®s->irqstat, -1);
|