From: Shrinivas Sahukar <shrinivas.sahu...@lntinfotech.com>

Signed-off-by: Shrinivas Sahukar <shrinivas.sahu...@lntinfotech.com>
---
 drivers/mmc/qc_mmc.c |   71 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/drivers/mmc/qc_mmc.c b/drivers/mmc/qc_mmc.c
index 930c410..9949cda 100644
--- a/drivers/mmc/qc_mmc.c
+++ b/drivers/mmc/qc_mmc.c
@@ -180,6 +180,65 @@ static unsigned int mmc_boot_fifo_read(unsigned int 
*mmc_ptr,
        return mmc_ret;
 }
 
+/*
+ * Write data to SDC FIFO.
+ */
+static unsigned int mmc_boot_fifo_write(unsigned int *mmc_ptr,
+                       unsigned int data_len, struct mmc *mmc)
+{
+       unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+       unsigned int mmc_status = 0;
+       unsigned int mmc_count = 0;
+       unsigned int write_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL |
+       MMC_BOOT_MCI_STAT_DATA_TIMEOUT | MMC_BOOT_MCI_STAT_TX_UNDRUN;
+       unsigned int i;
+       struct mmc_priv *priv = (struct mmc_priv  *)mmc->priv;
+       unsigned long reg_status, reg_fifo;
+
+       reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
+       reg_fifo = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_FIFO);
+
+       /* Write the transfer data to SDCC3 FIFO */
+       do {
+               mmc_ret = MMC_BOOT_E_SUCCESS;
+               mmc_status = readl(reg_status);
+               if (mmc_status & write_error) {
+                       mmc_ret = mmc_boot_status_error(mmc_status);
+                       break;
+               }
+               /* Write the data in MCI_FIFO register as long as TXFIFO_FULL
+                  bit of MCI_STATUS register is 0. Continue the writes until
+                  the whole transfer data is written. */
+               if (((data_len - mmc_count) >= MMC_BOOT_MCI_FIFO_SIZE / 2) &&
+                   (mmc_status & MMC_BOOT_MCI_STAT_TX_FIFO_HFULL)) {
+                       unsigned write_count = 1;
+                       write_count = MMC_BOOT_MCI_HFIFO_COUNT;
+                       for (i = 0; i < write_count; i++) {
+                               /* FIFO contains 16 32-bit data buffer
+                                  on 16 sequential addresses */
+                               writel(*mmc_ptr, reg_fifo +
+                                       (mmc_count % MMC_BOOT_MCI_FIFO_SIZE));
+                               mmc_ptr++;
+                               /* increase mmc_count by word size */
+                               mmc_count += sizeof(unsigned int);
+                       }
+
+               } else if (!(mmc_status & MMC_BOOT_MCI_STAT_TX_FIFO_FULL)
+                               && (mmc_count != data_len)) {
+                               /* FIFO contains 16 32-bit data buffer
+                                  on 16 sequential addresses */
+                               writel(*mmc_ptr, reg_fifo +
+                                       (mmc_count % MMC_BOOT_MCI_FIFO_SIZE));
+                               mmc_ptr++;
+                       /* increase mmc_count by word size */
+                       mmc_count += sizeof(unsigned int);
+               } else if ((mmc_status & MMC_BOOT_MCI_STAT_DATA_END)) {
+                       break;
+               }
+       } while (1);
+       return mmc_ret;
+}
+
 static unsigned int mmc_boot_fifo_data_transfer(unsigned int *data_ptr,
                                                        unsigned int  data_len,
                                                        unsigned char direction,
@@ -189,6 +248,8 @@ static unsigned int mmc_boot_fifo_data_transfer(unsigned 
int *data_ptr,
 
        if (direction == MMC_BOOT_DATA_READ)
                mmc_ret = mmc_boot_fifo_read(data_ptr, data_len, mmc);
+       else
+               mmc_ret = mmc_boot_fifo_write(data_ptr, data_len, mmc);
 
        return mmc_ret;
 }
@@ -350,7 +411,7 @@ static unsigned int mmc_boot_send_command(struct mmc_cmd 
*cmd,
                        break;
                }
 
-       }  while (1);
+       } while (1);
 
        return mmc_return;
 }
@@ -413,6 +474,7 @@ int mmc_boot_send_command_map(struct mmc *mmc,
                                struct mmc_data *data)
 {
        unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+       unsigned char direction = 0;
 
        /*  todo: do we need to fill in command type ?? */
 
@@ -434,6 +496,10 @@ int mmc_boot_send_command_map(struct mmc *mmc,
                                mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
                                data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
                        }
+                       direction = MMC_BOOT_DATA_READ;
+       } else if ((cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK) ||
+                       (cmd->cmdidx == MMC_CMD_WRITE_SINGLE_BLOCK)) {
+                       direction = MMC_BOOT_DATA_WRITE;
        } else if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) {
                        /* explicitly disable the prg enabled flag */
                        cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
@@ -441,7 +507,6 @@ int mmc_boot_send_command_map(struct mmc *mmc,
                        cmd->flags |= MMC_BOOT_XFER_MODE_BLOCK;
        }
 
-
        /* For Data cmd's */
        if (data != NULL)
                mmc_boot_init_data(mmc, cmd, data);
@@ -460,7 +525,7 @@ int mmc_boot_send_command_map(struct mmc *mmc,
                        return mmc_ret;
                mmc_boot_fifo_data_transfer((unsigned int *) data->dest,
                                        data->blocks * data->blocksize,
-                                       MMC_BOOT_DATA_READ,
+                                       direction,
                                        mmc);
        }
 
-- 
1.7.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to