From patchwork Mon Aug 13 08:20:46 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: srikanth.reddy@lntinfotech.com X-Patchwork-Id: 176881 X-Patchwork-Delegate: afleming@freescale.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 6BF6F2C008A for ; Mon, 13 Aug 2012 18:52:28 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 54141280C4; Mon, 13 Aug 2012 10:52:21 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id V3DtyNzve-u9; Mon, 13 Aug 2012 10:52:20 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 3277C280A6; Mon, 13 Aug 2012 10:52:08 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id EEE06280AF for ; Mon, 13 Aug 2012 10:52:02 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id AAvcXIbf4FlB for ; Mon, 13 Aug 2012 10:52:02 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail1.bemta12.messagelabs.com (mail1.bemta12.messagelabs.com [216.82.250.242]) by theia.denx.de (Postfix) with ESMTPS id 0E42C280B6 for ; Mon, 13 Aug 2012 10:51:57 +0200 (CEST) Received: from [216.82.249.99:62603] by server-8.bemta-12.messagelabs.com id 19/B9-11309-DAEB8205; Mon, 13 Aug 2012 08:45:33 +0000 X-Env-Sender: Srikanth.Reddy@lntinfotech.com X-Msg-Ref: server-9.tower-142.messagelabs.com!1344847259!7606120!16 X-Originating-IP: [203.101.96.7] X-StarScan-Received: X-StarScan-Version: 6.6.1.2; banners=-,-,- X-VirusChecked: Checked Received: (qmail 23049 invoked from network); 13 Aug 2012 08:45:22 -0000 Received: from unknown (HELO BLRINMSHTCAS01.bglrodc.lntinfotech.com) (203.101.96.7) by server-9.tower-142.messagelabs.com with AES128-SHA encrypted SMTP; 13 Aug 2012 08:45:22 -0000 Received: from INFBA02474.BGLRODC.lntinfotech.com (172.28.9.86) by BLRINMSHTCAS01.bglrodc.lntinfotech.com (172.28.0.81) with Microsoft SMTP Server id 8.2.176.0; Mon, 13 Aug 2012 13:50:42 +0530 From: Srikanth Reddy Vintha To: u-boot@lists.denx.de Date: Mon, 13 Aug 2012 13:50:46 +0530 Message-ID: <1344846046-11111-6-git-send-email-srikanth.reddy@lntinfotech.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: References: MIME-Version: 1.0 Cc: Shrinivas Sahukar , srikanth.reddy@lntinfotech.com Subject: [U-Boot] [PATCH 5/5] fix for MMC write issue X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de From: Shrinivas Sahukar Signed-off-by: Shrinivas Sahukar --- 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); }