/* Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of The Linux Foundation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <string.h>
#include <stdlib.h>
#include <debug.h>
#include <reg.h>
#include "mmc.h"
#include <partition_parser.h>
#include <platform/iomap.h>
#include <platform/timer.h>
#include <bits.h>

#if MMC_BOOT_ADM
#include "adm.h"
#endif

#if MMC_BOOT_BAM
#include "bam.h"
#include "mmc_dml.h"
#endif

#ifndef NULL
#define NULL        0
#endif

#define USEC_PER_SEC           (1000000L)

#define MMC_BOOT_DATA_READ     0
#define MMC_BOOT_DATA_WRITE    1

static unsigned int mmc_boot_data_transfer(unsigned int *data_ptr,
						unsigned int data_len,
						unsigned char direction);

static unsigned int mmc_boot_fifo_read(unsigned int *data_ptr,
				       unsigned int data_len);

static unsigned int mmc_boot_fifo_write(unsigned int *data_ptr,
					unsigned int data_len);

static unsigned int mmc_boot_status_error(unsigned mmc_status);

#if MMC_BOOT_BAM

void mmc_boot_dml_init();

static void mmc_boot_dml_producer_trans_init(unsigned trans_end,
										     unsigned size);

static void mmc_boot_dml_consumer_trans_init();

static uint32_t mmc_boot_dml_chk_producer_idle();

static void mmc_boot_dml_wait_producer_idle();
static void mmc_boot_dml_wait_consumer_idle();
static void mmc_boot_dml_reset();
static int mmc_bam_init(uint32_t bam_base);
static int mmc_bam_transfer_data();
static unsigned int
mmc_boot_bam_setup_desc(unsigned int *data_ptr,
			    unsigned int data_len, unsigned char direction);


#endif


#define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y)))

/* data access time unit in ns */
static const unsigned int taac_unit[] =
    { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 };
/* data access time value x 10 */
static const unsigned int taac_value[] =
    { 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 };

/* data transfer rate in kbit/s */
static const unsigned int xfer_rate_unit[] =
    { 100, 1000, 10000, 100000, 0, 0, 0, 0 };
/* data transfer rate value x 10*/
static const unsigned int xfer_rate_value[] =
    { 0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 52, 55, 60, 70, 80 };

unsigned char mmc_slot = 0;
unsigned int mmc_boot_mci_base = 0;

static unsigned char ext_csd_buf[512];
static unsigned char wp_status_buf[8];

#if MMC_BOOT_BAM

static uint32_t mmc_sdc_bam_base[] =
	{ MSM_SDC1_BAM_BASE, MSM_SDC2_BAM_BASE, MSM_SDC3_BAM_BASE, MSM_SDC4_BAM_BASE };

static uint32_t mmc_sdc_dml_base[] =
	{ MSM_SDC1_DML_BASE, MSM_SDC2_DML_BASE, MSM_SDC3_DML_BASE, MSM_SDC4_DML_BASE };

uint32_t dml_base;
static struct bam_instance bam;

#define MMC_BOOT_BAM_FIFO_SIZE           100

#define MMC_BOOT_BAM_READ_PIPE_INDEX     0
#define MMC_BOOT_BAM_WRITE_PIPE_INDEX    1

#define MMC_BOOT_BAM_READ_PIPE           0
#define MMC_BOOT_BAM_WRITE_PIPE          1

/* Align at BAM_DESC_SIZE boundary */
static struct bam_desc desc_fifo[MMC_BOOT_BAM_FIFO_SIZE] __attribute__ ((aligned(BAM_DESC_SIZE)));

#endif

int mmc_clock_enable_disable(unsigned id, unsigned enable);
int mmc_clock_get_rate(unsigned id);
int mmc_clock_set_rate(unsigned id, unsigned rate);

struct mmc_host mmc_host;
struct mmc_card mmc_card;

static unsigned int mmc_wp(unsigned int addr, unsigned int size,
			   unsigned char set_clear_wp);
static unsigned int mmc_boot_send_ext_cmd(struct mmc_card *card,
					  unsigned char *buf);
static unsigned int mmc_boot_read_reg(struct mmc_card *card,
				      unsigned int data_len,
				      unsigned int command,
				      unsigned int addr, unsigned int *out);

unsigned int SWAP_ENDIAN(unsigned int val)
{
	return ((val & 0xFF) << 24) |
	    (((val >> 8) & 0xFF) << 16) | (((val >> 16) & 0xFF) << 8) | (val >>
									 24);
}

void mmc_mclk_reg_wr_delay()
{
	if (mmc_host.mmc_cont_version)
	{
		/* Wait for the MMC_BOOT_MCI register write to go through. */
		while(readl(MMC_BOOT_MCI_STATUS2) & MMC_BOOT_MCI_MCLK_REG_WR_ACTIVE);
	}
	else
		udelay((1 + ((3 * USEC_PER_SEC) / (mmc_host.mclk_rate? mmc_host.mclk_rate : MMC_CLK_400KHZ))));
}

/* Sets a timeout for read operation.
 */
static unsigned int
mmc_boot_set_read_timeout(struct mmc_host *host,
			  struct mmc_card *card)
{
	unsigned int timeout_ns = 0;

	if ((host == NULL) || (card == NULL)) {
		return MMC_BOOT_E_INVAL;
	}

	if ((card->type == MMC_BOOT_TYPE_MMCHC)
	    || (card->type == MMC_BOOT_TYPE_SDHC)) {
		card->rd_timeout_ns = 100000000;
	} else if ((card->type == MMC_BOOT_TYPE_STD_SD)
		   || (card->type == MMC_BOOT_TYPE_STD_MMC)) {
		timeout_ns = 10 * ((card->csd.taac_ns) +
				   (card->csd.nsac_clk_cycle /
				    (host->mclk_rate / 1000000000)));
		card->rd_timeout_ns = timeout_ns;
	} else {
		return MMC_BOOT_E_NOT_SUPPORTED;
	}

	dprintf(SPEW, " Read timeout set: %d ns\n", card->rd_timeout_ns);

	return MMC_BOOT_E_SUCCESS;
}

/* Sets a timeout for write operation.
 */
static unsigned int
mmc_boot_set_write_timeout(struct mmc_host *host,
			   struct mmc_card *card)
{
	unsigned int timeout_ns = 0;

	if ((host == NULL) || (card == NULL)) {
		return MMC_BOOT_E_INVAL;
	}

	if ((card->type == MMC_BOOT_TYPE_MMCHC)
	    || (card->type == MMC_BOOT_TYPE_SDHC)) {
		card->wr_timeout_ns = 100000000;
	} else if (card->type == MMC_BOOT_TYPE_STD_SD
		   || (card->type == MMC_BOOT_TYPE_STD_MMC)) {
		timeout_ns = 10 * ((card->csd.taac_ns) +
				   (card->csd.nsac_clk_cycle /
				    (host->mclk_rate / 1000000000)));
		timeout_ns = timeout_ns << card->csd.r2w_factor;
		card->wr_timeout_ns = timeout_ns;
	} else {
		return MMC_BOOT_E_NOT_SUPPORTED;
	}

	dprintf(SPEW, " Write timeout set: %d ns\n", card->wr_timeout_ns);

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Decodes CSD response received from the card. Note that we have defined only
 * few of the CSD elements in csd structure. We'll only decode those values.
 */
static unsigned int
mmc_boot_decode_and_save_csd(struct mmc_card *card, unsigned int *raw_csd)
{
	unsigned int mmc_sizeof = 0;
	unsigned int mmc_unit = 0;
	unsigned int mmc_value = 0;
	unsigned int mmc_temp = 0;

	struct mmc_csd mmc_csd;

	if ((card == NULL) || (raw_csd == NULL)) {
		return MMC_BOOT_E_INVAL;
	}

	mmc_sizeof = sizeof(unsigned int) * 8;

	mmc_csd.cmmc_structure = UNPACK_BITS(raw_csd, 126, 2, mmc_sizeof);

	if ((card->type == MMC_BOOT_TYPE_SDHC)
	    || (card->type == MMC_BOOT_TYPE_STD_SD)) {
		/* Parse CSD according to SD card spec. */

		/* CSD register is little bit differnet for CSD version 2.0 High Capacity
		 * and CSD version 1.0/2.0 Standard memory cards. In Version 2.0 some of
		 * the fields have fixed values and it's not necessary for host to refer
		 * these fields in CSD sent by card */

		if (mmc_csd.cmmc_structure == 1) {
			/* CSD Version 2.0 */
			mmc_csd.card_cmd_class =
			    UNPACK_BITS(raw_csd, 84, 12, mmc_sizeof);
			mmc_csd.write_blk_len = 512;	/* Fixed value is 9 = 2^9 = 512 */
			mmc_csd.read_blk_len = 512;	/* Fixed value is 9 = 512 */
			mmc_csd.r2w_factor = 0x2;	/* Fixed value: 010b */
			mmc_csd.c_size_mult = 0;	/* not there in version 2.0 */
			mmc_csd.c_size =
			    UNPACK_BITS(raw_csd, 48, 22, mmc_sizeof);
			mmc_csd.nsac_clk_cycle =
			    UNPACK_BITS(raw_csd, 104, 8, mmc_sizeof) * 100;

//TODO: Investigate the nsac and taac. Spec suggests not using this for timeouts.

			mmc_unit = UNPACK_BITS(raw_csd, 112, 3, mmc_sizeof);
			mmc_value = UNPACK_BITS(raw_csd, 115, 4, mmc_sizeof);
			mmc_csd.taac_ns =
			    (taac_value[mmc_value] * taac_unit[mmc_unit]) / 10;

			mmc_csd.erase_blk_len = 1;
			mmc_csd.read_blk_misalign = 0;
			mmc_csd.write_blk_misalign = 0;
			mmc_csd.read_blk_partial = 0;
			mmc_csd.write_blk_partial = 0;

			mmc_unit = UNPACK_BITS(raw_csd, 96, 3, mmc_sizeof);
			mmc_value = UNPACK_BITS(raw_csd, 99, 4, mmc_sizeof);
			mmc_csd.tran_speed =
			    (xfer_rate_value[mmc_value] *
			     xfer_rate_unit[mmc_unit]) / 10;

			mmc_csd.wp_grp_size = 0x0;
			mmc_csd.wp_grp_enable = 0x0;
			mmc_csd.perm_wp =
			    UNPACK_BITS(raw_csd, 13, 1, mmc_sizeof);
			mmc_csd.temp_wp =
			    UNPACK_BITS(raw_csd, 12, 1, mmc_sizeof);

			/* Calculate the card capcity */
			card->capacity = (1 + mmc_csd.c_size) * 512 * 1024;
		} else {
			/* CSD Version 1.0 */
			mmc_csd.card_cmd_class =
			    UNPACK_BITS(raw_csd, 84, 12, mmc_sizeof);

			mmc_temp = UNPACK_BITS(raw_csd, 22, 4, mmc_sizeof);
			mmc_csd.write_blk_len = (mmc_temp > 8
						 && mmc_temp <
						 12) ? (1 << mmc_temp) : 512;

			mmc_temp = UNPACK_BITS(raw_csd, 80, 4, mmc_sizeof);
			mmc_csd.read_blk_len = (mmc_temp > 8
						&& mmc_temp <
						12) ? (1 << mmc_temp) : 512;

			mmc_unit = UNPACK_BITS(raw_csd, 112, 3, mmc_sizeof);
			mmc_value = UNPACK_BITS(raw_csd, 115, 4, mmc_sizeof);
			mmc_csd.taac_ns =
			    (taac_value[mmc_value] * taac_unit[mmc_unit]) / 10;

			mmc_unit = UNPACK_BITS(raw_csd, 96, 3, mmc_sizeof);
			mmc_value = UNPACK_BITS(raw_csd, 99, 4, mmc_sizeof);
			mmc_csd.tran_speed =
			    (xfer_rate_value[mmc_value] *
			     xfer_rate_unit[mmc_unit]) / 10;

			mmc_csd.nsac_clk_cycle =
			    UNPACK_BITS(raw_csd, 104, 8, mmc_sizeof) * 100;

			mmc_csd.r2w_factor =
			    UNPACK_BITS(raw_csd, 26, 3, mmc_sizeof);
			mmc_csd.sector_size =
			    UNPACK_BITS(raw_csd, 39, 7, mmc_sizeof) + 1;

			mmc_csd.erase_blk_len =
			    UNPACK_BITS(raw_csd, 46, 1, mmc_sizeof);
			mmc_csd.read_blk_misalign =
			    UNPACK_BITS(raw_csd, 77, 1, mmc_sizeof);
			mmc_csd.write_blk_misalign =
			    UNPACK_BITS(raw_csd, 78, 1, mmc_sizeof);
			mmc_csd.read_blk_partial =
			    UNPACK_BITS(raw_csd, 79, 1, mmc_sizeof);
			mmc_csd.write_blk_partial =
			    UNPACK_BITS(raw_csd, 21, 1, mmc_sizeof);

			mmc_csd.c_size_mult =
			    UNPACK_BITS(raw_csd, 47, 3, mmc_sizeof);
			mmc_csd.c_size =
			    UNPACK_BITS(raw_csd, 62, 12, mmc_sizeof);
			mmc_csd.wp_grp_size =
			    UNPACK_BITS(raw_csd, 32, 7, mmc_sizeof);
			mmc_csd.wp_grp_enable =
			    UNPACK_BITS(raw_csd, 31, 1, mmc_sizeof);
			mmc_csd.perm_wp =
			    UNPACK_BITS(raw_csd, 13, 1, mmc_sizeof);
			mmc_csd.temp_wp =
			    UNPACK_BITS(raw_csd, 12, 1, mmc_sizeof);

			/* Calculate the card capacity */
			mmc_temp =
			    (1 << (mmc_csd.c_size_mult + 2)) * (mmc_csd.c_size +
								1);
			card->capacity = mmc_temp * mmc_csd.read_blk_len;
		}
	} else {
		/* Parse CSD according to MMC card spec. */
		mmc_csd.spec_vers = UNPACK_BITS(raw_csd, 122, 4, mmc_sizeof);
		mmc_csd.card_cmd_class =
		    UNPACK_BITS(raw_csd, 84, 12, mmc_sizeof);
		mmc_csd.write_blk_len =
		    1 << UNPACK_BITS(raw_csd, 22, 4, mmc_sizeof);
		mmc_csd.read_blk_len =
		    1 << UNPACK_BITS(raw_csd, 80, 4, mmc_sizeof);
		mmc_csd.r2w_factor = UNPACK_BITS(raw_csd, 26, 3, mmc_sizeof);
		mmc_csd.c_size_mult = UNPACK_BITS(raw_csd, 47, 3, mmc_sizeof);
		mmc_csd.c_size = UNPACK_BITS(raw_csd, 62, 12, mmc_sizeof);
		mmc_csd.nsac_clk_cycle =
		    UNPACK_BITS(raw_csd, 104, 8, mmc_sizeof) * 100;

		mmc_unit = UNPACK_BITS(raw_csd, 112, 3, mmc_sizeof);
		mmc_value = UNPACK_BITS(raw_csd, 115, 4, mmc_sizeof);
		mmc_csd.taac_ns =
		    (taac_value[mmc_value] * taac_unit[mmc_unit]) / 10;

		mmc_csd.read_blk_misalign =
		    UNPACK_BITS(raw_csd, 77, 1, mmc_sizeof);
		mmc_csd.write_blk_misalign =
		    UNPACK_BITS(raw_csd, 78, 1, mmc_sizeof);
		mmc_csd.read_blk_partial =
		    UNPACK_BITS(raw_csd, 79, 1, mmc_sizeof);
		mmc_csd.write_blk_partial =
		    UNPACK_BITS(raw_csd, 21, 1, mmc_sizeof);
		mmc_csd.tran_speed = 0x00;	/* Ignore -- no use of this value. */

		mmc_csd.erase_grp_size =
		    UNPACK_BITS(raw_csd, 42, 5, mmc_sizeof);
		mmc_csd.erase_grp_mult =
		    UNPACK_BITS(raw_csd, 37, 5, mmc_sizeof);
		mmc_csd.wp_grp_size = UNPACK_BITS(raw_csd, 32, 5, mmc_sizeof);
		mmc_csd.wp_grp_enable = UNPACK_BITS(raw_csd, 31, 1, mmc_sizeof);
		mmc_csd.perm_wp = UNPACK_BITS(raw_csd, 13, 1, mmc_sizeof);
		mmc_csd.temp_wp = UNPACK_BITS(raw_csd, 12, 1, mmc_sizeof);

		/* Calculate the card capcity */
		if (mmc_csd.c_size != 0xFFF) {
			/* For cards less than or equal to 2GB */
			mmc_temp =
			    (1 << (mmc_csd.c_size_mult + 2)) * (mmc_csd.c_size +
								1);
			card->capacity = mmc_temp * mmc_csd.read_blk_len;
		} else {
			/* For cards greater than 2GB, Ext CSD register's SEC_COUNT
			 * is used to calculate the size.
			 */
			unsigned long long sec_count;

			sec_count = (ext_csd_buf[215] << 24) |
			    (ext_csd_buf[214] << 16) |
			    (ext_csd_buf[213] << 8) | ext_csd_buf[212];

			card->capacity = sec_count * 512;
		}
	}

	/* save the information in card structure */
	memcpy((struct mmc_csd *)&card->csd,
	       (struct mmc_csd *)&mmc_csd, sizeof(struct mmc_csd));

	dprintf(SPEW, "Decoded CSD fields:\n");
	dprintf(SPEW, "cmmc_structure: %d\n", mmc_csd.cmmc_structure);
	dprintf(SPEW, "card_cmd_class: %x\n", mmc_csd.card_cmd_class);
	dprintf(SPEW, "write_blk_len: %d\n", mmc_csd.write_blk_len);
	dprintf(SPEW, "read_blk_len: %d\n", mmc_csd.read_blk_len);
	dprintf(SPEW, "r2w_factor: %d\n", mmc_csd.r2w_factor);
	dprintf(SPEW, "sector_size: %d\n", mmc_csd.sector_size);
	dprintf(SPEW, "c_size_mult:%d\n", mmc_csd.c_size_mult);
	dprintf(SPEW, "c_size: %d\n", mmc_csd.c_size);
	dprintf(SPEW, "nsac_clk_cycle: %d\n", mmc_csd.nsac_clk_cycle);
	dprintf(SPEW, "taac_ns: %d\n", mmc_csd.taac_ns);
	dprintf(SPEW, "tran_speed: %d kbps\n", mmc_csd.tran_speed);
	dprintf(SPEW, "erase_blk_len: %d\n", mmc_csd.erase_blk_len);
	dprintf(SPEW, "read_blk_misalign: %d\n", mmc_csd.read_blk_misalign);
	dprintf(SPEW, "write_blk_misalign: %d\n", mmc_csd.write_blk_misalign);
	dprintf(SPEW, "read_blk_partial: %d\n", mmc_csd.read_blk_partial);
	dprintf(SPEW, "write_blk_partial: %d\n", mmc_csd.write_blk_partial);
	dprintf(SPEW, "Card Capacity: %llu Bytes\n", card->capacity);

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Decode CID sent by the card.
 */
static unsigned int
mmc_boot_decode_and_save_cid(struct mmc_card *card, unsigned int *raw_cid)
{
	struct mmc_cid mmc_cid;
	unsigned int mmc_sizeof = 0;
	int i = 0;

	if ((card == NULL) || (raw_cid == NULL)) {
		return MMC_BOOT_E_INVAL;
	}

	mmc_sizeof = sizeof(unsigned int) * 8;

	if ((card->type == MMC_BOOT_TYPE_SDHC)
	    || (card->type == MMC_BOOT_TYPE_STD_SD)) {
		mmc_cid.mid = UNPACK_BITS(raw_cid, 120, 8, mmc_sizeof);
		mmc_cid.oid = UNPACK_BITS(raw_cid, 104, 16, mmc_sizeof);

		for (i = 0; i < 5; i++) {
			mmc_cid.pnm[i] = (unsigned char)UNPACK_BITS(raw_cid,
								    (104 -
								     8 * (i +
									  1)),
								    8,
								    mmc_sizeof);
		}
		mmc_cid.pnm[5] = 0;
		mmc_cid.pnm[6] = 0;

		mmc_cid.prv = UNPACK_BITS(raw_cid, 56, 8, mmc_sizeof);
		mmc_cid.psn = UNPACK_BITS(raw_cid, 24, 32, mmc_sizeof);
		mmc_cid.month = UNPACK_BITS(raw_cid, 8, 4, mmc_sizeof);
		mmc_cid.year = UNPACK_BITS(raw_cid, 12, 8, mmc_sizeof);
		mmc_cid.year += 2000;
	} else {
		mmc_cid.mid = UNPACK_BITS(raw_cid, 120, 8, mmc_sizeof);
		mmc_cid.oid = UNPACK_BITS(raw_cid, 104, 16, mmc_sizeof);

		for (i = 0; i < 6; i++) {
			mmc_cid.pnm[i] = (unsigned char)UNPACK_BITS(raw_cid,
								    (104 -
								     8 * (i +
									  1)),
								    8,
								    mmc_sizeof);
		}
		mmc_cid.pnm[6] = 0;

		mmc_cid.prv = UNPACK_BITS(raw_cid, 48, 8, mmc_sizeof);
		mmc_cid.psn = UNPACK_BITS(raw_cid, 16, 32, mmc_sizeof);
		mmc_cid.month = UNPACK_BITS(raw_cid, 8, 4, mmc_sizeof);
		mmc_cid.year = UNPACK_BITS(raw_cid, 12, 4, mmc_sizeof);
		mmc_cid.year += 1997;
	}

	/* save it in card database */
	memcpy((struct mmc_cid *)&card->cid,
	       (struct mmc_cid *)&mmc_cid, sizeof(struct mmc_cid));

	dprintf(SPEW, "Decoded CID fields:\n");
	dprintf(SPEW, "Manufacturer ID: %x\n", mmc_cid.mid);
	dprintf(SPEW, "OEM ID: 0x%x\n", mmc_cid.oid);
	dprintf(SPEW, "Product Name: %s\n", mmc_cid.pnm);
	dprintf(SPEW, "Product revision: %d.%d\n", (mmc_cid.prv >> 4),
		(mmc_cid.prv & 0xF));
	dprintf(SPEW, "Product serial number: %X\n", mmc_cid.psn);
	dprintf(SPEW, "Manufacturing date: %d %d\n", mmc_cid.month,
		mmc_cid.year);

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Sends specified command to a card and waits for a response.
 */
static unsigned int mmc_boot_send_command(struct mmc_boot_command *cmd)
{
	unsigned int mmc_cmd = 0;
	unsigned int mmc_status = 0;
	unsigned int mmc_resp = 0;
	unsigned int mmc_return = MMC_BOOT_E_SUCCESS;
	unsigned int cmd_index = 0;
	int i = 0;

	/* basic check */
	if (cmd == NULL) {
		return MMC_BOOT_E_INVAL;
	}

	/* 1. Write command argument to MMC_BOOT_MCI_ARGUMENT register */
	writel(cmd->argument, MMC_BOOT_MCI_ARGUMENT);

	/* 2. Set appropriate fields and write MMC_BOOT_MCI_CMD */
	/* 2a. Write command index in CMD_INDEX field */
	cmd_index = cmd->cmd_index;
	mmc_cmd |= cmd->cmd_index;
	/* 2b. Set RESPONSE bit to 1 for all cmds except CMD0
	 * And dont set RESPONSE bit for commands with no response
	 */
	if (cmd_index != CMD0_GO_IDLE_STATE && cmd->resp_type != MMC_BOOT_RESP_NONE) {
		mmc_cmd |= MMC_BOOT_MCI_CMD_RESPONSE;
	}

	/* 2c. Set LONGRESP bit to 1 for CMD2, CMD9 and CMD10 */
	if (IS_RESP_136_BITS(cmd->resp_type)) {
		mmc_cmd |= MMC_BOOT_MCI_CMD_LONGRSP;
	}

	/* 2d. Set INTERRUPT bit to 1 to disable command timeout */

	/* 2e. Set PENDING bit to 1 for CMD12 in the beginning of stream
	   mode data transfer */
	if (cmd->xfer_mode == MMC_BOOT_XFER_MODE_STREAM) {
		mmc_cmd |= MMC_BOOT_MCI_CMD_PENDING;
	}

	/* 2f. Set ENABLE bit to 1 */
	mmc_cmd |= MMC_BOOT_MCI_CMD_ENABLE;

	/* 2g. Set PROG_ENA bit */
	if (cmd->prg_enabled) {
		mmc_cmd |= MMC_BOOT_MCI_CMD_PROG_ENA;
	}

	/* 2h. Set MCIABORT bit to 1 for CMD12 when working with SDIO card */
	/* 2i. Set CCS_ENABLE bit to 1 for CMD61 when Command Completion Signal
	   of CE-ATA device is enabled */

	/* 2j. clear all static status bits */
	writel(MMC_BOOT_MCI_STATIC_STATUS, MMC_BOOT_MCI_CLEAR);

	/* 2k. Write to MMC_BOOT_MCI_CMD register */
	writel(mmc_cmd, MMC_BOOT_MCI_CMD);

	/* Wait for the MMC_BOOT_MCI_CMD write to go through. */
	mmc_mclk_reg_wr_delay();

	dprintf(SPEW, "Command sent: CMD%d MCI_CMD_REG:%x MCI_ARG:%x\n",
		cmd_index, mmc_cmd, cmd->argument);

	/* 3. Wait for interrupt or poll on the following bits of MCI_STATUS
	   register */
	do {
		/* 3a. Read MCI_STATUS register */
		while (readl(MMC_BOOT_MCI_STATUS) &
		       MMC_BOOT_MCI_STAT_CMD_ACTIVE) ;

		mmc_status = readl(MMC_BOOT_MCI_STATUS);

		/* 3b. CMD_SENT bit supposed to be set to 1 only after CMD0 is sent -
		   no response required. */
		if ((cmd->resp_type == MMC_BOOT_RESP_NONE) &&
		    (mmc_status & MMC_BOOT_MCI_STAT_CMD_SENT)) {
			break;
		}

		/* 3c. If CMD_TIMEOUT bit is set then no response was received */
		else if (mmc_status & MMC_BOOT_MCI_STAT_CMD_TIMEOUT) {
			mmc_return = MMC_BOOT_E_TIMEOUT;
			break;
		}
		/* 3d. If CMD_RESPONSE_END bit is set to 1 then command's response was
		   received and CRC check passed
		   Spcial case for ACMD41: it seems to always fail CRC even if
		   the response is valid
		 */
		else if ((mmc_status & MMC_BOOT_MCI_STAT_CMD_RESP_END)
			 || (cmd_index == CMD1_SEND_OP_COND)
			 || (cmd_index == CMD8_SEND_IF_COND)) {
			/* 3i. Read MCI_RESP_CMD register to verify that response index is
			   equal to command index */
			mmc_resp = readl(MMC_BOOT_MCI_RESP_CMD) & 0x3F;

			/* However, long response does not contain the command index field.
			 * In that case, response index field must be set to 111111b (0x3F) */
			if ((mmc_resp == cmd_index) ||
			    (cmd->resp_type == MMC_BOOT_RESP_R2 ||
			     cmd->resp_type == MMC_BOOT_RESP_R3 ||
			     cmd->resp_type == MMC_BOOT_RESP_R6 ||
			     cmd->resp_type == MMC_BOOT_RESP_R7)) {
				/* 3j. If resp index is equal to cmd index, read command resp
				   from MCI_RESPn registers
				   - MCI_RESP0/1/2/3 for CMD2/9/10
				   - MCI_RESP0 for all other registers */
				if (IS_RESP_136_BITS(cmd->resp_type)) {
					for (i = 0; i < 4; i++) {
						cmd->resp[3 - i] =
						    readl(MMC_BOOT_MCI_RESP_0 +
							  (i * 4));

					}
				} else {
					cmd->resp[0] =
					    readl(MMC_BOOT_MCI_RESP_0);
				}
			} else {
				/* command index mis-match */
				mmc_return = MMC_BOOT_E_CMD_INDX_MISMATCH;
			}

			dprintf(SPEW, "Command response received: %X\n",
				cmd->resp[0]);
			break;
		}

		/* 3e. If CMD_CRC_FAIL bit is set to 1 then cmd's response was recvd,
		   but CRC check failed. */
		else if ((mmc_status & MMC_BOOT_MCI_STAT_CMD_CRC_FAIL)) {
			if (cmd_index == ACMD41_SEND_OP_COND) {
				cmd->resp[0] = readl(MMC_BOOT_MCI_RESP_0);
			} else
				mmc_return = MMC_BOOT_E_CRC_FAIL;
			break;
		}

	}
	while (1);


	/* 2k. Write to MMC_BOOT_MCI_CMD register */
	writel(0, MMC_BOOT_MCI_CMD);

	/* Wait for the MMC_BOOT_MCI_CMD write to go through. */
	mmc_mclk_reg_wr_delay();

	return mmc_return;
}

/*
 * Reset all the cards to idle condition (CMD 0)
 */
static unsigned int mmc_boot_reset_cards(void)
{
	struct mmc_boot_command cmd;

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	cmd.cmd_index = CMD0_GO_IDLE_STATE;
	cmd.argument = 0;	// stuff bits - ignored
	cmd.cmd_type = MMC_BOOT_CMD_BCAST;
	cmd.resp_type = MMC_BOOT_RESP_NONE;

	/* send command */
	return mmc_boot_send_command(&cmd);
}

/*
 * Send CMD1 to know whether the card supports host VDD profile or not.
 */
static unsigned int
mmc_boot_send_op_cond(struct mmc_host *host, struct mmc_card *card)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_resp = 0;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	/* basic check */
	if ((host == NULL) || (card == NULL)) {
		return MMC_BOOT_E_INVAL;
	}

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* CMD1 format:
	 * [31] Busy bit
	 * [30:29] Access mode
	 * [28:24] reserved
	 * [23:15] 2.7-3.6
	 * [14:8]  2.0-2.6
	 * [7]     1.7-1.95
	 * [6:0]   reserved
	 */

	cmd.cmd_index = CMD1_SEND_OP_COND;
	cmd.argument = host->ocr;
	cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP;
	cmd.resp_type = MMC_BOOT_RESP_R3;

	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* Now it's time to examine response */
	mmc_resp = cmd.resp[0];

	/* Response contains card's ocr. Update card's information */
	card->ocr = mmc_resp;

	/* Check the response for busy status */
	if (!(mmc_resp & MMC_BOOT_OCR_BUSY)) {
		return MMC_BOOT_E_CARD_BUSY;
	}

	if (mmc_resp & MMC_BOOT_OCR_SEC_MODE) {
		card->type = MMC_BOOT_TYPE_MMCHC;
	} else {
		card->type = MMC_BOOT_TYPE_STD_MMC;
	}
	return MMC_BOOT_E_SUCCESS;
}

/*
 * Request any card to send its uniquie card identification (CID) number (CMD2).
 */
static unsigned int mmc_boot_all_send_cid(struct mmc_card *card)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	/* basic check */
	if (card == NULL) {
		return MMC_BOOT_E_INVAL;
	}

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* CMD2 Format:
	 * [31:0] stuff bits
	 */
	cmd.cmd_index = CMD2_ALL_SEND_CID;
	cmd.argument = 0;
	cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP;
	cmd.resp_type = MMC_BOOT_RESP_R2;

	/* send command */
	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* Response contains card's 128 bits CID register */
	mmc_ret = mmc_boot_decode_and_save_cid(card, cmd.resp);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}
	return MMC_BOOT_E_SUCCESS;
}

/*
 * Ask any card to send it's relative card address (RCA).This RCA number is
 * shorter than CID and is used by the host to address the card in future (CMD3)
 */
static unsigned int mmc_boot_send_relative_address(struct mmc_card *card)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	/* basic check */
	if (card == NULL) {
		return MMC_BOOT_E_INVAL;
	}

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* CMD3 Format:
	 * [31:0] stuff bits
	 */
	if (card->type == MMC_BOOT_TYPE_SDHC
	    || card->type == MMC_BOOT_TYPE_STD_SD) {
		cmd.cmd_index = CMD3_SEND_RELATIVE_ADDR;
		cmd.argument = 0;
		cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP;
		cmd.resp_type = MMC_BOOT_RESP_R6;

		/* send command */
		mmc_ret = mmc_boot_send_command(&cmd);
		if (mmc_ret != MMC_BOOT_E_SUCCESS) {
			return mmc_ret;
		}
		/* For sD, card will send RCA. Store it */
		card->rca = (cmd.resp[0] >> 16);
	} else {
		cmd.cmd_index = CMD3_SEND_RELATIVE_ADDR;
		cmd.argument = (MMC_RCA << 16);
		card->rca = (cmd.argument >> 16);
		cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
		cmd.resp_type = MMC_BOOT_RESP_R1;

		/* send command */
		mmc_ret = mmc_boot_send_command(&cmd);
		if (mmc_ret != MMC_BOOT_E_SUCCESS) {
			return mmc_ret;
		}
	}

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Requests card to send it's CSD register's contents. (CMD9)
 */
static unsigned int
mmc_boot_send_csd(struct mmc_card *card, unsigned int *raw_csd)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_arg = 0;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	/* basic check */
	if (card == NULL) {
		return MMC_BOOT_E_INVAL;
	}

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* CMD9 Format:
	 * [31:16] RCA
	 * [15:0] stuff bits
	 */
	mmc_arg |= card->rca << 16;

	cmd.cmd_index = CMD9_SEND_CSD;
	cmd.argument = mmc_arg;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R2;

	/* send command */
	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* response contains the card csd */
	memcpy(raw_csd, cmd.resp, sizeof(cmd.resp));

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Selects a card by sending CMD7 to the card with its RCA.
 * If RCA field is set as 0 ( or any other address ),
 * the card will be de-selected. (CMD7)
 */
static unsigned int
mmc_boot_select_card(struct mmc_card *card, unsigned int rca)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_arg = 0;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	/* basic check */
	if (card == NULL) {
		return MMC_BOOT_E_INVAL;
	}

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* CMD7 Format:
	 * [31:16] RCA
	 * [15:0] stuff bits
	 */
	mmc_arg |= rca << 16;

	cmd.cmd_index = CMD7_SELECT_DESELECT_CARD;
	cmd.argument = mmc_arg;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	/* If we are deselecting card, we do not get response */
	if (rca == card->rca && rca) {
		if (card->type == MMC_BOOT_TYPE_SDHC
		    || card->type == MMC_BOOT_TYPE_STD_SD)
			cmd.resp_type = MMC_BOOT_RESP_R1B;
		else
			cmd.resp_type = MMC_BOOT_RESP_R1;
	} else {
		cmd.resp_type = MMC_BOOT_RESP_NONE;
	}

	/* send command */
	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* As of now no need to look into a response. If it's required
	 * we'll explore later on */

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Send command to set block length.
 */
static unsigned int
mmc_boot_set_block_len(struct mmc_card *card, unsigned int block_len)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	/* basic check */
	if (card == NULL) {
		return MMC_BOOT_E_INVAL;
	}

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* CMD16 Format:
	 * [31:0] block length
	 */

	cmd.cmd_index = CMD16_SET_BLOCKLEN;
	cmd.argument = block_len;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1;

	/* send command */
	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* If blocklength is larger than 512 bytes,
	 * the card sets BLOCK_LEN_ERROR bit. */
	if (cmd.resp[0] & MMC_BOOT_R1_BLOCK_LEN_ERR) {
		return MMC_BOOT_E_BLOCKLEN_ERR;
	}
	return MMC_BOOT_E_SUCCESS;
}

/*
 * Requests the card to stop transmission of data.
 */
static unsigned int
mmc_boot_send_stop_transmission(struct mmc_card *card,
				unsigned int prg_enabled)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	/* basic check */
	if (card == NULL) {
		return MMC_BOOT_E_INVAL;
	}

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* CMD12 Format:
	 * [31:0] stuff bits
	 */

	cmd.cmd_index = CMD12_STOP_TRANSMISSION;
	cmd.argument = 0;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1B;
	cmd.xfer_mode = MMC_BOOT_XFER_MODE_BLOCK;
	cmd.prg_enabled = prg_enabled;

	/* send command */
	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}
	return MMC_BOOT_E_SUCCESS;
}

/*
 * Get the card's current status
 */
static unsigned int
mmc_boot_get_card_status(struct mmc_card *card,
			 unsigned int prg_enabled, unsigned int *status)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	/* basic check */
	if (card == NULL) {
		return MMC_BOOT_E_INVAL;
	}

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* CMD13 Format:
	 * [31:16] RCA
	 * [15:0] stuff bits
	 */
	cmd.cmd_index = CMD13_SEND_STATUS;
	cmd.argument = card->rca << 16;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1;
	cmd.prg_enabled = prg_enabled;

	/* send command */
	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* Checking ADDR_OUT_OF_RANGE error in CMD13 response */
	if (IS_ADDR_OUT_OF_RANGE(cmd.resp[0])) {
		return MMC_BOOT_E_FAILURE;
	}

	*status = cmd.resp[0];
	return MMC_BOOT_E_SUCCESS;
}

/*
 * Decode type of error caused during read and write
 */
static unsigned int mmc_boot_status_error(unsigned mmc_status)
{
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	/* If DATA_CRC_FAIL bit is set to 1 then CRC error was detected by
	   card/device during the data transfer */
	if (mmc_status & MMC_BOOT_MCI_STAT_DATA_CRC_FAIL) {
		mmc_ret = MMC_BOOT_E_DATA_CRC_FAIL;
	}
	/* If DATA_TIMEOUT bit is set to 1 then the data transfer time exceeded
	   the data timeout period without completing the transfer */
	else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_TIMEOUT) {
		mmc_ret = MMC_BOOT_E_DATA_TIMEOUT;
	}
	/* If RX_OVERRUN bit is set to 1 then SDCC2 tried to receive data from
	   the card before empty storage for new received data was available.
	   Verify that bit FLOW_ENA in MCI_CLK is set to 1 during the data xfer. */
	else if (mmc_status & MMC_BOOT_MCI_STAT_RX_OVRRUN) {
		/* Note: We've set FLOW_ENA bit in MCI_CLK to 1. so no need to verify
		   for now */
		mmc_ret = MMC_BOOT_E_RX_OVRRUN;
	}
	/* If TX_UNDERRUN bit is set to 1 then SDCC2 tried to send data to
	   the card before new data for sending was available. Verify that bit
	   FLOW_ENA in MCI_CLK is set to 1 during the data xfer. */
	else if (mmc_status & MMC_BOOT_MCI_STAT_TX_UNDRUN) {
		/* Note: We've set FLOW_ENA bit in MCI_CLK to 1.so skipping it now */
		mmc_ret = MMC_BOOT_E_RX_OVRRUN;
	}
	return mmc_ret;
}

/*
 * Send ext csd command.
 */
static unsigned int
mmc_boot_send_ext_cmd(struct mmc_card *card, unsigned char *buf)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
	unsigned int mmc_reg = 0;
	unsigned int *mmc_ptr = (unsigned int *)buf;

	memset(buf, 0, 512);

	/* basic check */
	if (card == NULL) {
		return MMC_BOOT_E_INVAL;
	}

	/* set block len */
	if ((card->type != MMC_BOOT_TYPE_MMCHC)
	    && (card->type != MMC_BOOT_TYPE_SDHC)) {
		mmc_ret = mmc_boot_set_block_len(card, 512);
		if (mmc_ret != MMC_BOOT_E_SUCCESS) {
			dprintf(CRITICAL,
				"Error No.%d: Failure setting block length for Card (RCA:%s)\n",
				mmc_ret, (char *)(card->rca));
			return mmc_ret;
		}
	}

	/* Set the FLOW_ENA bit of MCI_CLK register to 1 */
	mmc_reg = readl(MMC_BOOT_MCI_CLK);
	mmc_reg |= MMC_BOOT_MCI_CLK_ENA_FLOW;
	writel(mmc_reg, MMC_BOOT_MCI_CLK);

	/* Wait for the MMC_BOOT_MCI_CLK write to go through. */
	mmc_mclk_reg_wr_delay();

	/* Write data timeout period to MCI_DATA_TIMER register. */
	/* Data timeout period should be in card bus clock periods */
	mmc_reg = 0xFFFFFFFF;
	writel(mmc_reg, MMC_BOOT_MCI_DATA_TIMER);
	writel(512, MMC_BOOT_MCI_DATA_LENGTH);

	/* Set appropriate fields and write the MCI_DATA_CTL register. */
	/* Set ENABLE bit to 1 to enable the data transfer. */
	mmc_reg =
	    MMC_BOOT_MCI_DATA_ENABLE | MMC_BOOT_MCI_DATA_DIR | (512 <<
								MMC_BOOT_MCI_BLKSIZE_POS);

#if MMC_BOOT_ADM || MMC_BOOT_BAM
	mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;
#endif

	writel(mmc_reg, MMC_BOOT_MCI_DATA_CTL);

	/* Wait for the MMC_BOOT_MCI_DATA_CTL write to go through. */
	mmc_mclk_reg_wr_delay();

#if MMC_BOOT_BAM
	/*  Setup SDCC BAM descriptors for Read operation. */
	mmc_ret = mmc_boot_bam_setup_desc(mmc_ptr, 512, MMC_BOOT_DATA_READ);
#endif

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));
	/* CMD8 */
	cmd.cmd_index = CMD8_SEND_EXT_CSD;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1;
	cmd.xfer_mode = MMC_BOOT_XFER_MODE_BLOCK;

	/* send command */
	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* Read the transfer data from SDCC FIFO. */
	mmc_ret = mmc_boot_data_transfer(mmc_ptr, 512, MMC_BOOT_DATA_READ);

	/* Reset DPSM */
	writel(0, MMC_BOOT_MCI_DATA_CTL);

	/* Wait for the MMC_BOOT_MCI_DATA_CTL write to go through. */
	mmc_mclk_reg_wr_delay();

	return mmc_ret;
}

/*
 * Switch command
 */
static unsigned int
mmc_boot_switch_cmd(struct mmc_card *card,
		    unsigned access, unsigned index, unsigned value)
{

	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
	uint32_t mmc_status;

	/* basic check */
	if (card == NULL) {
		return MMC_BOOT_E_INVAL;
	}

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* CMD6 Format:
	 * [31:26] set to 0
	 * [25:24] access
	 * [23:16] index
	 * [15:8] value
	 * [7:3] set to 0
	 * [2:0] cmd set
	 */
	cmd.cmd_index = CMD6_SWITCH_FUNC;
	cmd.argument |= (access << 24);
	cmd.argument |= (index << 16);
	cmd.argument |= (value << 8);
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1B;
	cmd.prg_enabled = 1;

	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL,"Send cmd6 failed\n");
		return mmc_ret;
	}

	/* Wait for interrupt or poll on PROG_DONE bit of MCI_STATUS register.
	 * If PROG_DONE bit is set to 1 it means that the card finished it programming
	 * and stopped driving DAT0 line to 0.
	 */
	do {
		mmc_status = readl(MMC_BOOT_MCI_STATUS);
		if (mmc_status & MMC_BOOT_MCI_STAT_PROG_DONE) {
			break;
		}
	}
	while (1);

	/* Check if the card completed the switch command processing */
	mmc_ret = mmc_boot_get_card_status(card, 0, &mmc_status);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL, "Get card status failed\n");
		return mmc_ret;
	}

	if (MMC_BOOT_CARD_STATUS(mmc_status) != MMC_BOOT_TRAN_STATE)
	{
		dprintf(CRITICAL, "Switch cmd failed. Card not in tran state\n");
		mmc_ret = MMC_BOOT_E_FAILURE;
	}

	if (mmc_status & MMC_BOOT_SWITCH_FUNC_ERR_FLAG)
	{
		dprintf(CRITICAL, "Switch cmd failed. Switch Error.\n");
		mmc_ret = MMC_BOOT_E_FAILURE;
	}

	return mmc_ret;
}

/*
 * A command to set the data bus width for card. Set width to either
 */
static unsigned int
mmc_boot_set_bus_width(struct mmc_card *card, unsigned int width)
{
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
	unsigned int mmc_reg = 0;
	unsigned int mmc_width = 0;

	if (width != MMC_BOOT_BUS_WIDTH_1_BIT) {
		mmc_width = width - 1;
	}

	mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE,
				      MMC_BOOT_EXT_CMMC_BUS_WIDTH, mmc_width);

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL, "Switch cmd failed\n");
		return mmc_ret;
	}

	/* set MCI_CLK accordingly */
	mmc_reg = readl(MMC_BOOT_MCI_CLK);
	mmc_reg &= ~MMC_BOOT_MCI_CLK_WIDEBUS_MODE;
	if (width == MMC_BOOT_BUS_WIDTH_1_BIT) {
		mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT;
	} else if (width == MMC_BOOT_BUS_WIDTH_4_BIT) {
		mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT;
	} else if (width == MMC_BOOT_BUS_WIDTH_8_BIT) {
		mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT;
	}

	writel(mmc_reg, MMC_BOOT_MCI_CLK);

	/* Wait for the MMC_BOOT_MCI_CLK write to go through. */
	mmc_mclk_reg_wr_delay();

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Function to enable HS200 mode
 * 1. Set the clock frequency to 100 MHZ
 * 2. Set the bus width to 4/8 bit SDR as supported byt the target & host
 * 3. Set the HS_TIMING on ext_csd 185 for the card
 */
static uint32_t mmc_set_hs200_mode(struct mmc_host *host,
								   struct mmc_card *card)
{
	uint32_t mmc_ret = MMC_BOOT_E_SUCCESS;

	/* Set Clock @ 100 MHZ */
	clock_config_mmc(mmc_slot, host->caps.hs_clk_rate);
	host->mclk_rate = host->caps.hs_clk_rate;

	/* Set 4/8 bit SDR bus width */
	mmc_ret = mmc_boot_set_bus_width(card, host->caps.bus_width);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL,
			"Error No.%d: Failure to set wide bus for Card(RCA:%x)\n",
			mmc_ret, card->rca);
			return mmc_ret;
	}

	/* Setting HS200 in HS_TIMING using EXT_CSD (CMD6) */
	mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE,
				      MMC_BOOT_EXT_CMMC_HS_TIMING, 2);

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL, "Switch cmd returned failure %d\n", __LINE__);
		return mmc_ret;
	}

	return mmc_ret;
}

/*
 * Function to enable DDR mode
 * 1. Set the bus width to 8 bit DDR
 * 1. Set the clock frequency to 100 MHZ
 * 3. Set DDR mode in mci clk register
 * 4. Set Widebus enable in mci clock register
 */
static uint32_t mmc_set_ddr_mode(struct mmc_host *host,
								 struct mmc_card *card)
{
	uint8_t mmc_ret = MMC_BOOT_E_SUCCESS;
	uint32_t mmc_reg = 0;
	uint32_t width = 0;

	switch (host->caps.bus_width) {
		case MMC_BOOT_BUS_WIDTH_4_BIT:
			width = MMC_DDR_BUS_WIDTH_4_BIT;
			break;
		case MMC_BOOT_BUS_WIDTH_8_BIT:
			width = MMC_DDR_BUS_WIDTH_8_BIT;
			break;
		default:
			dprintf(CRITICAL, "Invalid bus width, DDR mode is not enabled\n");
			mmc_ret = MMC_BOOT_E_FAILURE;
			goto end;
	};

	/* Set width for 4/8 bit DDR bus width */
	mmc_ret = mmc_boot_set_bus_width(card, width);

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL,
			"Error No.%d: Failure to set wide bus for Card(RCA:%x)\n",
			mmc_ret, card->rca);
		return mmc_ret;
	}

	/* Bump up the clock frequency */
	clock_config_mmc(mmc_slot, host->caps.hs_clk_rate);
	host->mclk_rate = host->caps.hs_clk_rate;

	/* Select DDR mode in mci register */
	mmc_reg = readl(MMC_BOOT_MCI_CLK);
	mmc_reg |= (MMC_MCI_DDR_MODE_EN << MMC_MCI_MODE_SELECT);

	writel(mmc_reg, MMC_BOOT_MCI_CLK);

	/* Wait for the MMC_BOOT_MCI_CLK write to go through. */
	mmc_mclk_reg_wr_delay();

	/* Enable wide bus for DDR */
	mmc_reg = readl(MMC_BOOT_MCI_CLK);
	mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_MODE;
	writel(mmc_reg, MMC_BOOT_MCI_CLK);

	/* Wait for the MMC_BOOT_MCI_CLK write to go through. */
	mmc_mclk_reg_wr_delay();

end:
	return MMC_BOOT_E_SUCCESS;
}

/*
 * A command to start data read from card. Either a single block or
 * multiple blocks can be read. Multiple blocks read will continuously
 * transfer data from card to host unless requested to stop by issuing
 * CMD12 - STOP_TRANSMISSION.
 */
static unsigned int
mmc_boot_send_read_command(struct mmc_card *card,
			   unsigned int xfer_type, unsigned int data_addr)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	/* basic check */
	if (card == NULL) {
		return MMC_BOOT_E_INVAL;
	}

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* CMD17/18 Format:
	 * [31:0] Data Address
	 */
	if (xfer_type == MMC_BOOT_XFER_MULTI_BLOCK) {
		cmd.cmd_index = CMD18_READ_MULTIPLE_BLOCK;
	} else {
		cmd.cmd_index = CMD17_READ_SINGLE_BLOCK;
	}

	cmd.argument = data_addr;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1;

	/* send command */
	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* Response contains 32 bit Card status. Here we'll check
	   BLOCK_LEN_ERROR and ADDRESS_ERROR */
	if (cmd.resp[0] & MMC_BOOT_R1_BLOCK_LEN_ERR) {
		return MMC_BOOT_E_BLOCKLEN_ERR;
	}
	/* Misaligned address not matching block length */
	if (cmd.resp[0] & MMC_BOOT_R1_ADDR_ERR) {
		return MMC_BOOT_E_ADDRESS_ERR;
	}

	return MMC_BOOT_E_SUCCESS;
}

/*
 * A command to start data write to card. Either a single block or
 * multiple blocks can be written. Multiple block write will continuously
 * transfer data from host to card unless requested to stop by issuing
 * CMD12 - STOP_TRANSMISSION.
 */
static unsigned int
mmc_boot_send_write_command(struct mmc_card *card,
			    unsigned int xfer_type, unsigned int data_addr)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	/* basic check */
	if (card == NULL) {
		return MMC_BOOT_E_INVAL;
	}

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* CMD24/25 Format:
	 * [31:0] Data Address
	 */
	if (xfer_type == MMC_BOOT_XFER_MULTI_BLOCK) {
		cmd.cmd_index = CMD25_WRITE_MULTIPLE_BLOCK;
	} else {
		cmd.cmd_index = CMD24_WRITE_SINGLE_BLOCK;
	}

	cmd.argument = data_addr;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1;

	/* send command */
	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* Response contains 32 bit Card status. Here we'll check
	   BLOCK_LEN_ERROR and ADDRESS_ERROR */
	if (cmd.resp[0] & MMC_BOOT_R1_BLOCK_LEN_ERR) {
		return MMC_BOOT_E_BLOCKLEN_ERR;
	}
	/* Misaligned address not matching block length */
	if (cmd.resp[0] & MMC_BOOT_R1_ADDR_ERR) {
		return MMC_BOOT_E_ADDRESS_ERR;
	}

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Write data_len data to address specified by data_addr. data_len is
 * multiple of blocks for block data transfer.
 */
static unsigned int
mmc_boot_write_to_card(struct mmc_host *host,
		       struct mmc_card *card,
		       unsigned long long data_addr,
		       unsigned int data_len, unsigned int *in)
{
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
	unsigned int mmc_status = 0;
	unsigned int mmc_reg = 0;
	unsigned int addr;
	unsigned int xfer_type;
	unsigned int status;

	if ((host == NULL) || (card == NULL)) {
		return MMC_BOOT_E_INVAL;
	}

	/* Set block length. High Capacity MMC/SD card uses fixed 512 bytes block
	   length. So no need to send CMD16. */
	if ((card->type != MMC_BOOT_TYPE_MMCHC)
	    && (card->type != MMC_BOOT_TYPE_SDHC)) {
		mmc_ret = mmc_boot_set_block_len(card, card->wr_block_len);
		if (mmc_ret != MMC_BOOT_E_SUCCESS) {
			dprintf(CRITICAL, "Error No.%d: Failure setting block length for Card\
                    (RCA:%s)\n", mmc_ret,
				(char *)(card->rca));
			return mmc_ret;
		}
	}

	/* use multi-block mode to transfer for data larger than a block */
	xfer_type =
	    (data_len >
	     card->
	     rd_block_len) ? MMC_BOOT_XFER_MULTI_BLOCK :
	    MMC_BOOT_XFER_SINGLE_BLOCK;

	/* For MMCHC/SDHC data address is specified in unit of 512B */
	addr = ((card->type != MMC_BOOT_TYPE_MMCHC)
		&& (card->type !=
		    MMC_BOOT_TYPE_SDHC)) ? (unsigned int)data_addr : (unsigned
								      int)
	    (data_addr / 512);

	/* Set the FLOW_ENA bit of MCI_CLK register to 1 */
	mmc_reg = readl(MMC_BOOT_MCI_CLK);
	mmc_reg |= MMC_BOOT_MCI_CLK_ENA_FLOW;
	writel(mmc_reg, MMC_BOOT_MCI_CLK);

	/* Wait for the MMC_BOOT_MCI_CLK write to go through. */
	mmc_mclk_reg_wr_delay();

	/* Write data timeout period to MCI_DATA_TIMER register */
	/* Data timeout period should be in card bus clock periods */
	/*TODO: Fix timeout value */
	mmc_reg = 0xFFFFFFFF;
	writel(mmc_reg, MMC_BOOT_MCI_DATA_TIMER);

	/* Write the total size of the transfer data to MCI_DATA_LENGTH register */
	writel(data_len, MMC_BOOT_MCI_DATA_LENGTH);

#if MMC_BOOT_BAM
		mmc_boot_bam_setup_desc(in, data_len, MMC_BOOT_DATA_WRITE);
#endif

	/* Send command to the card/device in order to start the write data xfer.
	   The possible commands are CMD24/25/53/60/61 */
	mmc_ret = mmc_boot_send_write_command(card, xfer_type, addr);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL, "Error No.%d: Failure sending write command to the\
                Card(RCA:%x)\n", mmc_ret,
			card->rca);
		return mmc_ret;
	}

	/* Set appropriate fields and write the MCI_DATA_CTL register */
	/* Set ENABLE bit to 1 to enable the data transfer. */
	mmc_reg = 0;
	mmc_reg |= MMC_BOOT_MCI_DATA_ENABLE;
	/* Clear DIRECTION bit to 0 to enable transfer from host to card */
	/* Clear MODE bit to 0 to enable block oriented data transfer. For
	   MMC cards only, if stream data transfer mode is desired, set
	   MODE bit to 1. */

	/* Set DM_ENABLE bit to 1 in order to enable DMA, otherwise set 0 */

#if MMC_BOOT_ADM || MMC_BOOT_BAM
	mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;
#endif

	/* Write size of block to be used during the data transfer to
	   BLOCKSIZE field */
	mmc_reg |= card->wr_block_len << MMC_BOOT_MCI_BLKSIZE_POS;
	writel(mmc_reg, MMC_BOOT_MCI_DATA_CTL);

	/* Wait for the MMC_BOOT_MCI_DATA_CTL write to go through. */
	mmc_mclk_reg_wr_delay();

	/* write data to FIFO */
	mmc_ret =
	    mmc_boot_data_transfer(in, data_len, MMC_BOOT_DATA_WRITE);

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL, "Error No.%d: Failure on data transfer from the \
                Card(RCA:%x)\n", mmc_ret,
			card->rca);
		/* In case of any failure happening for multi block transfer */
		if (xfer_type == MMC_BOOT_XFER_MULTI_BLOCK)
			mmc_boot_send_stop_transmission(card, 1);
		return mmc_ret;
	}

	/* Send command to the card/device in order to poll the de-assertion of
	   card/device BUSY condition. It is important to set PROG_ENA bit in
	   MCI_CLK register before sending the command. Possible commands are
	   CMD12/13. */
	if (xfer_type == MMC_BOOT_XFER_MULTI_BLOCK) {
		mmc_ret = mmc_boot_send_stop_transmission(card, 1);
		if (mmc_ret != MMC_BOOT_E_SUCCESS) {
			dprintf(CRITICAL, "Error No.%d: Failure sending Stop Transmission \
                    command to the Card(RCA:%x)\n", mmc_ret,
				card->rca);
			return mmc_ret;
		}
	} else {
		mmc_ret = mmc_boot_get_card_status(card, 1, &status);
		if (mmc_ret != MMC_BOOT_E_SUCCESS) {
			dprintf(CRITICAL,
				"Error No.%d: Failure getting card status of Card(RCA:%x)\n",
				mmc_ret, card->rca);
			return mmc_ret;
		}
	}

	/* Wait for interrupt or poll on PROG_DONE bit of MCI_STATUS register. If
	   PROG_DONE bit is set to 1 it means that the card finished it programming
	   and stopped driving DAT0 line to 0 */
	do {
		mmc_status = readl(MMC_BOOT_MCI_STATUS);
		if (mmc_status & MMC_BOOT_MCI_STAT_PROG_DONE) {
			break;
		}
	}
	while (1);

#if MMC_BOOT_BAM
	/* Wait for DML trasaction to end */
	mmc_boot_dml_wait_consumer_idle();
#endif

	/* Reset DPSM */
	writel(0, MMC_BOOT_MCI_DATA_CTL);

	/* Wait for the MMC_BOOT_MCI_DATA_CTL write to go through. */
	mmc_mclk_reg_wr_delay();

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Adjust the interface speed to optimal speed
 */
static unsigned int
mmc_boot_adjust_interface_speed(struct mmc_host *host,
				struct mmc_card *card)
{
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	/* Setting HS_TIMING in EXT_CSD (CMD6) */
	mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE,
				      MMC_BOOT_EXT_CMMC_HS_TIMING, 1);

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL, "Switch cmd returned failure %d\n", __LINE__);
		return mmc_ret;
	}

	clock_config_mmc(mmc_slot, MMC_CLK_50MHZ);

	host->mclk_rate = MMC_CLK_50MHZ;

	return MMC_BOOT_E_SUCCESS;
}

static unsigned int
mmc_boot_set_block_count(struct mmc_card *card, unsigned int block_count)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	/* basic check */
	if (card == NULL) {
		return MMC_BOOT_E_INVAL;
	}

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* CMD23 Format:
	 * [15:0] number of blocks
	 */

	cmd.cmd_index = CMD23_SET_BLOCK_COUNT;
	cmd.argument = block_count;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1;

	/* send command */
	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	if (cmd.resp[0] & MMC_BOOT_R1_OUT_OF_RANGE) {
		return MMC_BOOT_E_BLOCKLEN_ERR;
	}

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Reads a data of data_len from the address specified. data_len
 * should be multiple of block size for block data transfer.
 */
static unsigned int
mmc_boot_read_from_card(struct mmc_host *host,
			struct mmc_card *card,
			unsigned long long data_addr,
			unsigned int data_len, unsigned int *out)
{
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
	unsigned int mmc_reg = 0;
	unsigned int xfer_type;
	unsigned int addr = 0;
	unsigned char open_ended_read = 1;

	if ((host == NULL) || (card == NULL)) {
		return MMC_BOOT_E_INVAL;
	}

	/* Set block length. High Capacity MMC/SD card uses fixed 512 bytes block
	   length. So no need to send CMD16. */
	if ((card->type != MMC_BOOT_TYPE_MMCHC)
	    && (card->type != MMC_BOOT_TYPE_SDHC)) {
		mmc_ret = mmc_boot_set_block_len(card, card->rd_block_len);
		if (mmc_ret != MMC_BOOT_E_SUCCESS) {
			dprintf(CRITICAL,
				"Error No.%d: Failure setting block length for Card (RCA:%s)\n",
				mmc_ret, (char *)(card->rca));
			return mmc_ret;
		}
	}

	/* use multi-block mode to transfer for data larger than a block */
	xfer_type =
	    (data_len >
	     card->
	     rd_block_len) ? MMC_BOOT_XFER_MULTI_BLOCK :
	    MMC_BOOT_XFER_SINGLE_BLOCK;

	if (xfer_type == MMC_BOOT_XFER_MULTI_BLOCK) {
		if ((card->type == MMC_BOOT_TYPE_MMCHC)
		    || (card->type == MMC_BOOT_TYPE_STD_MMC)) {
			/* Virtio model does not support open-ended multi-block reads.
			 * So, block count must be set before sending read command.
			 * All SD cards do not support this command. Restrict this to MMC.
			 */
			mmc_ret =
			    mmc_boot_set_block_count(card,
						     data_len /
						     (card->rd_block_len));
			if (mmc_ret != MMC_BOOT_E_SUCCESS) {
				dprintf(CRITICAL,
					"Error No.%d: Failure setting read block count for Card (RCA:%s)\n",
					mmc_ret, (char *)(card->rca));
				return mmc_ret;
			}

			open_ended_read = 0;
		}
	}

	/* Set the FLOW_ENA bit of MCI_CLK register to 1 */
	/* Note: It's already enabled */

	/* If Data Mover is used for data transfer then prepare Command
	   List Entry and enable the Data mover to work with SDCC2 */

	/* Write data timeout period to MCI_DATA_TIMER register. */
	/* Data timeout period should be in card bus clock periods */
	mmc_reg = (unsigned long)(card->rd_timeout_ns / 1000000) *
	    (host->mclk_rate / 1000);
	mmc_reg += 1000;	// add some extra clock cycles to be safe
	mmc_reg = mmc_reg / 2;
	writel(mmc_reg, MMC_BOOT_MCI_DATA_TIMER);

	/* Write the total size of the transfer data to MCI_DATA_LENGTH
	   register. For block xfer it must be multiple of the block
	   size. */
	writel(data_len, MMC_BOOT_MCI_DATA_LENGTH);

	/* For MMCHC/SDHC data address is specified in unit of 512B */
	addr = ((card->type != MMC_BOOT_TYPE_MMCHC)
		&& (card->type !=
		    MMC_BOOT_TYPE_SDHC)) ? (unsigned int)data_addr : (unsigned
								      int)
	    (data_addr / 512);

	/* Set appropriate fields and write the MCI_DATA_CTL register. */
	/* Set ENABLE bit to 1 to enable the data transfer. */
	mmc_reg = 0;
	mmc_reg |= MMC_BOOT_MCI_DATA_ENABLE;
	/* Clear DIRECTION bit to 1 to enable transfer from card to host */
	mmc_reg |= MMC_BOOT_MCI_DATA_DIR;
	/* Clear MODE bit to 0 to enable block oriented data transfer. For
	   MMC cards only, if stream data transfer mode is desired, set
	   MODE bit to 1. */

	/* If DMA is to be used, Set DM_ENABLE bit to 1 */

#if MMC_BOOT_ADM || MMC_BOOT_BAM
	mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;
#endif

	/* Write size of block to be used during the data transfer to
	   BLOCKSIZE field */
	mmc_reg |= (card->rd_block_len << MMC_BOOT_MCI_BLKSIZE_POS);
	writel(mmc_reg, MMC_BOOT_MCI_DATA_CTL);

	/* Wait for the MMC_BOOT_MCI_DATA_CTL write to go through. */
	mmc_mclk_reg_wr_delay();

#if MMC_BOOT_BAM
	/* Setup SDCC FIFO descriptors for Read operation. */
	mmc_ret = mmc_boot_bam_setup_desc(out, data_len, MMC_BOOT_DATA_READ);
#endif
	/* Send command to the card/device in order to start the read data
	   transfer. Possible commands: CMD17/18/53/60/61. */
	mmc_ret = mmc_boot_send_read_command(card, xfer_type, addr);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL,
			"Error No.%d: Failure sending read command to the Card(RCA:%x)\n",
			mmc_ret, card->rca);
		return mmc_ret;
	}

	/* Read the transfer data from SDCC FIFO. */
	mmc_ret = mmc_boot_data_transfer(out, data_len, MMC_BOOT_DATA_READ);

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL, "Error No.%d: Failure on data transfer from the \
                Card(RCA:%x)\n", mmc_ret,
			card->rca);
		return mmc_ret;
	}

	/* In case a multiple block transfer was performed, send CMD12 to the
	   card/device in order to indicate the end of read data transfer */
	if ((xfer_type == MMC_BOOT_XFER_MULTI_BLOCK) && open_ended_read) {
		mmc_ret = mmc_boot_send_stop_transmission(card, 0);
		if (mmc_ret != MMC_BOOT_E_SUCCESS) {
			dprintf(CRITICAL, "Error No.%d: Failure sending Stop Transmission \
                    command to the Card(RCA:%x)\n", mmc_ret,
				card->rca);
			return mmc_ret;
		}
	}

	/* Reset DPSM */
	writel(0, MMC_BOOT_MCI_DATA_CTL);

	/* Wait for the MMC_BOOT_MCI_DATA_CTL write to go through. */
	mmc_mclk_reg_wr_delay();

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Initialize host structure, set and enable clock-rate and power mode.
 */
unsigned int mmc_boot_init(struct mmc_host *host)
{
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
	unsigned int mmc_pwr = 0;

	host->ocr = MMC_BOOT_OCR_27_36 | MMC_BOOT_OCR_SEC_MODE;
	host->cmd_retry = MMC_BOOT_MAX_COMMAND_RETRY;

	/* Initialize any clocks needed for SDC controller */
	clock_init_mmc(mmc_slot);

	/* Save the verison on the mmc controller. */
	host->mmc_cont_version = readl(MMC_BOOT_MCI_VERSION);

	/* Setup initial freq to 400KHz */
	clock_config_mmc(mmc_slot, MMC_CLK_400KHZ);

	host->mclk_rate = MMC_CLK_400KHZ;

	/* set power mode */
	/* give some time to reach minimum voltate */

	mmc_pwr &= ~MMC_BOOT_MCI_PWR_UP;
	mmc_pwr |= MMC_BOOT_MCI_PWR_ON;
	mmc_pwr |= MMC_BOOT_MCI_PWR_UP;
	writel(mmc_pwr, MMC_BOOT_MCI_POWER);

	/* Wait for the MMC_BOOT_MCI_POWER write to go through. */
	mmc_mclk_reg_wr_delay();

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Performs card identification process:
 * - get card's unique identification number (CID)
 * - get(for sd)/set (for mmc) relative card address (RCA)
 * - get CSD
 * - select the card, thus transitioning it to Transfer State
 * - get Extended CSD (for mmc)
 */
static unsigned int
mmc_boot_identify_card(struct mmc_host *host, struct mmc_card *card)
{
	unsigned int mmc_return = MMC_BOOT_E_SUCCESS;
	unsigned int raw_csd[4];

	/* basic check */
	if ((host == NULL) || (card == NULL)) {
		return MMC_BOOT_E_INVAL;
	}

	/* Ask card to send its unique card identification (CID) number (CMD2) */
	mmc_return = mmc_boot_all_send_cid(card);
	if (mmc_return != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL,
			"Error No. %d: Failure getting card's CID number!\n",
			mmc_return);
		return mmc_return;
	}

	/* Ask card to send a relative card address (RCA) (CMD3) */
	mmc_return = mmc_boot_send_relative_address(card);
	if (mmc_return != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL, "Error No. %d: Failure getting card's RCA!\n",
			mmc_return);
		return mmc_return;
	}

	/* Get card's CSD register (CMD9) */
	mmc_return = mmc_boot_send_csd(card, raw_csd);
	if (mmc_return != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL,
			"Error No.%d: Failure getting card's CSD information!\n",
			mmc_return);
		return mmc_return;
	}

	/* Select the card (CMD7) */
	mmc_return = mmc_boot_select_card(card, card->rca);
	if (mmc_return != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL,
			"Error No.%d: Failure selecting the Card with RCA: %x\n",
			mmc_return, card->rca);
		return mmc_return;
	}

	/* Set the card status as active */
	card->status = MMC_BOOT_STATUS_ACTIVE;

	if ((card->type == MMC_BOOT_TYPE_STD_MMC)
	    || (card->type == MMC_BOOT_TYPE_MMCHC)) {
		/* For MMC cards, also get the extended csd */
		mmc_return = mmc_boot_send_ext_cmd(card, ext_csd_buf);

		if (mmc_return != MMC_BOOT_E_SUCCESS) {
			dprintf(CRITICAL,
				"Error No.%d: Failure getting card's ExtCSD information!\n",
				mmc_return);

			return mmc_return;
		}

	}

	/* Decode and save the CSD register */
	mmc_return = mmc_boot_decode_and_save_csd(card, raw_csd);
	if (mmc_return != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL,
			"Error No.%d: Failure decoding card's CSD information!\n",
			mmc_return);
		return mmc_return;
	}

	/* Once CSD is received, set read and write timeout value now itself */
	mmc_return = mmc_boot_set_read_timeout(host, card);
	if (mmc_return != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL,
			"Error No.%d: Failure setting Read Timeout value!\n",
			mmc_return);
		return mmc_return;
	}

	mmc_return = mmc_boot_set_write_timeout(host, card);
	if (mmc_return != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL,
			"Error No.%d: Failure setting Write Timeout value!\n",
			mmc_return);
		return mmc_return;
	}

	return MMC_BOOT_E_SUCCESS;
}

static unsigned int mmc_boot_send_app_cmd(unsigned int rca)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	cmd.cmd_index = CMD55_APP_CMD;
	cmd.argument = (rca << 16);
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1;

	mmc_ret = mmc_boot_send_command(&cmd);

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	return MMC_BOOT_E_SUCCESS;
}

static unsigned int mmc_boot_sd_init_card(struct mmc_card *card)
{
	unsigned int i, mmc_ret;
	unsigned int ocr_cmd_arg;
	struct mmc_boot_command cmd;

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* Send CMD8 to set interface condition */
	for (i = 0; i < 3; i++) {
		cmd.cmd_index = CMD8_SEND_IF_COND;
		cmd.argument = MMC_BOOT_SD_HC_VOLT_SUPPLIED;
		cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP;
		cmd.resp_type = MMC_BOOT_RESP_R7;

		mmc_ret = mmc_boot_send_command(&cmd);
		if (mmc_ret == MMC_BOOT_E_SUCCESS) {
			if (cmd.resp[0] != MMC_BOOT_SD_HC_VOLT_SUPPLIED)
				return MMC_BOOT_E_FAILURE;
			/* Set argument for ACMD41 */
			ocr_cmd_arg = MMC_BOOT_SD_NEG_OCR | MMC_BOOT_SD_HC_HCS;
			break;
		}
		mdelay(1);
	}

	/* Send ACMD41 to set operating condition */
	/* Try for a max of 1 sec as per spec */
	for (i = 0; i < 20; i++) {
		mmc_ret = mmc_boot_send_app_cmd(0);
		if (mmc_ret != MMC_BOOT_E_SUCCESS) {
			return mmc_ret;
		}

		cmd.cmd_index = ACMD41_SEND_OP_COND;
		cmd.argument = ocr_cmd_arg;
		cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP;
		cmd.resp_type = MMC_BOOT_RESP_R3;

		mmc_ret = mmc_boot_send_command(&cmd);
		if (mmc_ret != MMC_BOOT_E_SUCCESS) {
			return mmc_ret;
		} else if (cmd.resp[0] & MMC_BOOT_SD_DEV_READY) {
			/* Check for HC */
			if (cmd.resp[0] & (1 << 30)) {
				card->type = MMC_BOOT_TYPE_SDHC;
			} else {
				card->type = MMC_BOOT_TYPE_STD_SD;
			}
			break;
		}
		mdelay(50);
	}
	return MMC_BOOT_E_SUCCESS;
}

/*
 * Routine to initialize MMC card. It resets a card to idle state, verify operating
 * voltage and set the card inready state.
 */
static unsigned int
mmc_boot_init_card(struct mmc_host *host, struct mmc_card *card)
{
	unsigned int mmc_retry = 0;
	unsigned int mmc_return = MMC_BOOT_E_SUCCESS;

	/* basic check */
	if ((host == NULL) || (card == NULL)) {
		return MMC_BOOT_E_INVAL;
	}

	/* 1. Card Reset - CMD0 */
	mmc_return = mmc_boot_reset_cards();
	if (mmc_return != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL,
			"Error No.:%d: Failure resetting MMC cards!\n",
			mmc_return);
		return mmc_return;
	}

	/* 2. Card Initialization process */

	/* Send CMD1 to identify and reject cards that do not match host's VDD range
	   profile. Cards sends its OCR register in response.
	 */
	mmc_retry = 0;
	do {
		mmc_return = mmc_boot_send_op_cond(host, card);
		/* Card returns busy status. We'll retry again! */
		if (mmc_return == MMC_BOOT_E_CARD_BUSY) {
			mmc_retry++;
			mdelay(1);
			continue;
		} else if (mmc_return == MMC_BOOT_E_SUCCESS) {
			break;
		} else {
			dprintf(CRITICAL,
				"Error No. %d: Failure Initializing MMC Card!\n",
				mmc_return);

			/* Check for sD card */
			mmc_return = mmc_boot_sd_init_card(card);
			return mmc_return;
		}
	}
	while (mmc_retry < host->cmd_retry);

	/* If card still returned busy status we are out of luck.
	 * Card cannot be initialized */
	if (mmc_return == MMC_BOOT_E_CARD_BUSY) {
		dprintf(CRITICAL, "Error No. %d: Card has busy status set. \
                Initialization not completed\n", mmc_return);
		return MMC_BOOT_E_CARD_BUSY;
	}

	card->block_size = BLOCK_SIZE;

	return MMC_BOOT_E_SUCCESS;
}

static unsigned int
mmc_boot_set_sd_bus_width(struct mmc_card *card, unsigned int width)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
	unsigned int sd_reg;

	mmc_ret = mmc_boot_send_app_cmd(card->rca);

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* Send ACMD6 to set bus width */
	cmd.cmd_index = ACMD6_SET_BUS_WIDTH;
	/* 10 => 4 bit wide */
	if (width == MMC_BOOT_BUS_WIDTH_1_BIT) {
		cmd.argument = 0;
	} else if (width == MMC_BOOT_BUS_WIDTH_4_BIT) {
		cmd.argument = (1 << 1);
	}
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1;

	mmc_ret = mmc_boot_send_command(&cmd);

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* set MCI_CLK accordingly */
	sd_reg = readl(MMC_BOOT_MCI_CLK);
	sd_reg &= ~MMC_BOOT_MCI_CLK_WIDEBUS_MODE;
	if (width == MMC_BOOT_BUS_WIDTH_1_BIT) {
		sd_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT;
	} else if (width == MMC_BOOT_BUS_WIDTH_4_BIT) {
		sd_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT;
	} else if (width == MMC_BOOT_BUS_WIDTH_8_BIT) {
		sd_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT;
	}
	writel(sd_reg, MMC_BOOT_MCI_CLK);

	/* Wait for the MMC_BOOT_MCI_CLK write to go through. */
	mmc_mclk_reg_wr_delay();

	return MMC_BOOT_E_SUCCESS;
}

static unsigned int
mmc_boot_set_sd_hs(struct mmc_host *host, struct mmc_card *card)
{
	unsigned char sw_buf[64];
	unsigned int mmc_ret;

	/* CMD6 is a data transfer command. sD card returns 512 bits of data */
	/* Refer 4.3.10 of sD card specification 3.0 */
	mmc_ret =
	    mmc_boot_read_reg(card, 64, CMD6_SWITCH_FUNC, MMC_BOOT_SD_SWITCH_HS,
			      (unsigned int *)&sw_buf);

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	clock_config_mmc(mmc_slot, MMC_CLK_50MHZ);

	host->mclk_rate = MMC_CLK_50MHZ;

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Performs initialization and identification of all the MMC cards connected
 * to the host.
 */

static unsigned int
mmc_boot_init_and_identify_cards(struct mmc_host *host,
				 struct mmc_card *card)
{
	unsigned int mmc_return = MMC_BOOT_E_SUCCESS;
	unsigned int status;
	uint8_t mmc_bus_width = 0;

	/* Basic check */
	if (host == NULL) {
		return MMC_BOOT_E_INVAL;
	}

	/* Initialize MMC card structure */
	card->status = MMC_BOOT_STATUS_INACTIVE;
	card->rd_block_len = MMC_BOOT_RD_BLOCK_LEN;
	card->wr_block_len = MMC_BOOT_WR_BLOCK_LEN;

	/* Start initialization process (CMD0 & CMD1) */
	mmc_return = mmc_boot_init_card(host, card);
	if (mmc_return != MMC_BOOT_E_SUCCESS) {
		return mmc_return;
	}

	/* Identify (CMD2, CMD3 & CMD9) and select the card (CMD7) */
	mmc_return = mmc_boot_identify_card(host, card);
	if (mmc_return != MMC_BOOT_E_SUCCESS) {
		return mmc_return;
	}

	if (card->type == MMC_BOOT_TYPE_SDHC
	    || card->type == MMC_BOOT_TYPE_STD_SD) {
		/* Setting sD card to high speed without checking card's capability.
		   Cards that do not support high speed may fail to boot */
		mmc_return = mmc_boot_set_sd_hs(host, card);
		if (mmc_return != MMC_BOOT_E_SUCCESS) {
			return mmc_return;
		}

		mmc_return =
		    mmc_boot_set_sd_bus_width(card, MMC_BOOT_BUS_WIDTH_4_BIT);
		if (mmc_return != MMC_BOOT_E_SUCCESS) {
			dprintf(CRITICAL,
				"Couldn't set 4bit mode for sD card\n");
			mmc_return =
			    mmc_boot_set_sd_bus_width(card,
						      MMC_BOOT_BUS_WIDTH_1_BIT);
			if (mmc_return != MMC_BOOT_E_SUCCESS) {
				dprintf(CRITICAL,
					"Error No.%d: Failed in setting bus width!\n",
					mmc_return);
				return mmc_return;
			}
		}
	} else {
		/* set interface speed */
		mmc_return = mmc_boot_adjust_interface_speed(host, card);
		if (mmc_return != MMC_BOOT_E_SUCCESS) {
			dprintf(CRITICAL,
				"Error No.%d: Error adjusting interface speed!\n",
				mmc_return);
			return mmc_return;
		}

		/* Enable HS200 mode by default if supported,
		 * else if DDR mode is supported enable it.
		 * else use default 4/8 bit mode
		 */
		if (card_supports_hs200_mode() && host->caps.hs200_mode) {
			mmc_return = mmc_set_hs200_mode(host, card);
			if (mmc_return != MMC_BOOT_E_SUCCESS) {
				dprintf(CRITICAL,
					"Error No.%d: Failure to set HS200 mode for Card(RCA:%x)\n",
					mmc_return, card->rca);
				return mmc_return;
			}
		} else if (card_supports_ddr_mode() && host->caps.ddr_mode) {
			mmc_return = mmc_set_ddr_mode(host, card);
			if (mmc_return != MMC_BOOT_E_SUCCESS) {
				dprintf(CRITICAL,
					"Error No.%d: Failure to set DDR mode for Card(RCA:%x)\n",
					mmc_return, card->rca);
				return mmc_return;
			}
		} else {
			mmc_return =
				mmc_boot_set_bus_width(card, host->caps.bus_width);
			if (mmc_return != MMC_BOOT_E_SUCCESS) {
				dprintf(CRITICAL,
					"Error No.%d: Failure to set wide bus for Card(RCA:%x)\n",
					mmc_return, card->rca);
				return mmc_return;
			}
		}
	}

	/* Just checking whether we're in TRAN state after changing speed and bus width */
	mmc_return = mmc_boot_get_card_status(card, 0, &status);
	if (mmc_return != MMC_BOOT_E_SUCCESS) {
		return mmc_return;
	}

	if (MMC_BOOT_CARD_STATUS(status) != MMC_BOOT_TRAN_STATE)
		return MMC_BOOT_E_FAILURE;

	return MMC_BOOT_E_SUCCESS;
}

void mmc_display_ext_csd(void)
{
	dprintf(SPEW, "part_config: %x\n", ext_csd_buf[179]);
	dprintf(SPEW, "erase_group_def: %x\n", ext_csd_buf[175]);
	dprintf(SPEW, "user_wp: %x\n", ext_csd_buf[171]);
}

void mmc_display_csd(void)
{
	dprintf(SPEW, "erase_grpsize: %d\n", mmc_card.csd.erase_grp_size);
	dprintf(SPEW, "erase_grpmult: %d\n", mmc_card.csd.erase_grp_mult);
	dprintf(SPEW, "wp_grpsize: %d\n", mmc_card.csd.wp_grp_size);
	dprintf(SPEW, "wp_grpen: %d\n", mmc_card.csd.wp_grp_enable);
	dprintf(SPEW, "perm_wp: %d\n", mmc_card.csd.perm_wp);
	dprintf(SPEW, "temp_wp: %d\n", mmc_card.csd.temp_wp);
}

/*
 * Entry point to MMC boot process
 */
unsigned int mmc_boot_main(unsigned char slot, unsigned int base)
{
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	memset((struct mmc_host *)&mmc_host, 0,
	       sizeof(struct mmc_host));
	memset((struct mmc_card *)&mmc_card, 0,
	       sizeof(struct mmc_card));

	mmc_slot = slot;
	mmc_boot_mci_base = base;

	/* Get the capabilities for the host/target */
	target_mmc_caps(&mmc_host);

	/* Initialize necessary data structure and enable/set clock and power */
	dprintf(SPEW, " Initializing MMC host data structure and clock!\n");
	mmc_ret = mmc_boot_init(&mmc_host);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL, "MMC Boot: Error Initializing MMC Card!!!\n");
		return MMC_BOOT_E_FAILURE;
	}

#if MMC_BOOT_BAM

	mmc_ret = mmc_bam_init(mmc_sdc_bam_base[slot - 1]);
	dml_base = mmc_sdc_dml_base[slot - 1];
#endif

	/* Initialize and identify cards connected to host */
	mmc_ret = mmc_boot_init_and_identify_cards(&mmc_host, &mmc_card);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL,
			"MMC Boot: Failed detecting MMC/SDC @ slot%d\n", slot);
		return MMC_BOOT_E_FAILURE;
	}

	mmc_display_csd();
	mmc_display_ext_csd();

	mmc_ret = partition_read_table();
	return mmc_ret;
}

/*
 * MMC write function
 */
unsigned int
mmc_write(unsigned long long data_addr, unsigned int data_len, unsigned int *in)
{
	int val = 0;
	unsigned int write_size = ((unsigned)(0xFFFFFF / 512)) * 512;
	unsigned offset = 0;
	unsigned int *sptr = in;

	if (data_len % 512)
		data_len = ROUND_TO_PAGE(data_len, 511);

	while (data_len > write_size) {
		val = mmc_boot_write_to_card(&mmc_host, &mmc_card,
					     data_addr + offset, write_size,
					     sptr);
		if (val) {
			return val;
		}

		sptr += (write_size / sizeof(unsigned));
		offset += write_size;
		data_len -= write_size;
	}
	if (data_len) {
		val = mmc_boot_write_to_card(&mmc_host, &mmc_card,
					     data_addr + offset, data_len,
					     sptr);
	}
	return val;
}

/*
 * MMC read function
 */

unsigned int
mmc_read(unsigned long long data_addr, unsigned int *out, unsigned int data_len)
{
	int val = 0;
	val =
	    mmc_boot_read_from_card(&mmc_host, &mmc_card, data_addr, data_len,
				    out);
	return val;
}

/*
 * Function to read registers from MMC or SD card
 */
static unsigned int
mmc_boot_read_reg(struct mmc_card *card,
		  unsigned int data_len,
		  unsigned int command, unsigned int addr, unsigned int *out)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
	unsigned int mmc_reg = 0;

	/* Set the FLOW_ENA bit of MCI_CLK register to 1 */
	mmc_reg = readl(MMC_BOOT_MCI_CLK);
	mmc_reg |= MMC_BOOT_MCI_CLK_ENA_FLOW;
	writel(mmc_reg, MMC_BOOT_MCI_CLK);

	/* Wait for the MMC_BOOT_MCI_CLK write to go through. */
	mmc_mclk_reg_wr_delay();

	/* Write data timeout period to MCI_DATA_TIMER register. */
	/* Data timeout period should be in card bus clock periods */
	mmc_reg = 0xFFFFFFFF;
	writel(mmc_reg, MMC_BOOT_MCI_DATA_TIMER);
	writel(data_len, MMC_BOOT_MCI_DATA_LENGTH);

	/* Set appropriate fields and write the MCI_DATA_CTL register. */
	/* Set ENABLE bit to 1 to enable the data transfer. */
	mmc_reg =
	    MMC_BOOT_MCI_DATA_ENABLE | MMC_BOOT_MCI_DATA_DIR | (data_len <<
								MMC_BOOT_MCI_BLKSIZE_POS);

#if MMC_BOOT_ADM || MMC_BOOT_BAM
	mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;
#endif

	writel(mmc_reg, MMC_BOOT_MCI_DATA_CTL);

	/* Wait for the MMC_BOOT_MCI_DATA_CTL write to go through. */
	mmc_mclk_reg_wr_delay();

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	cmd.cmd_index = command;
	cmd.argument = addr;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1;

	/* send command */
	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* Read the transfer data from SDCC FIFO. */
	mmc_ret =
	    mmc_boot_data_transfer(out, data_len, MMC_BOOT_DATA_READ);

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL, "Error No.%d: Failure on data transfer from the \
                Card(RCA:%x)\n", mmc_ret,
			card->rca);
		return mmc_ret;
	}

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Function to set/clear power-on write protection for the user area partitions
 */
static unsigned int
mmc_boot_set_clr_power_on_wp_user(struct mmc_card *card,
				  unsigned int addr,
				  unsigned int size, unsigned char set_clear_wp)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
	unsigned int wp_group_size, loop_count;
	unsigned int status;

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	/* Disabling PERM_WP for USER AREA (CMD6) */
	mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_SET_BIT,
				      MMC_BOOT_EXT_USER_WP,
				      MMC_BOOT_US_PERM_WP_DIS);

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	mmc_ret = mmc_boot_send_ext_cmd(card, ext_csd_buf);

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* Make sure power-on write protection for user area is not disabled
	   and permanent write protection for user area is not enabled */

	if ((IS_BIT_SET_EXT_CSD(MMC_BOOT_EXT_USER_WP, MMC_BOOT_US_PERM_WP_EN))
	    ||
	    (IS_BIT_SET_EXT_CSD(MMC_BOOT_EXT_USER_WP, MMC_BOOT_US_PWR_WP_DIS)))
	{
		return MMC_BOOT_E_FAILURE;
	}

	if (ext_csd_buf[MMC_BOOT_EXT_ERASE_GROUP_DEF]) {
		/* wp_group_size = 512KB * HC_WP_GRP_SIZE * HC_ERASE_GRP_SIZE.
		   Getting write protect group size in sectors here. */

		wp_group_size =
		    (512 * 1024) * ext_csd_buf[MMC_BOOT_EXT_HC_WP_GRP_SIZE] *
		    ext_csd_buf[MMC_BOOT_EXT_HC_ERASE_GRP_SIZE] /
		    MMC_BOOT_WR_BLOCK_LEN;
	} else {
		/* wp_group_size = (WP_GRP_SIZE + 1) * (ERASE_GRP_SIZE + 1)
		 * (ERASE_GRP_MULT + 1).
		 This is defined as the number of write blocks directly */

		wp_group_size = (card->csd.erase_grp_size + 1) *
		    (card->csd.erase_grp_mult + 1) * (card->csd.wp_grp_size +
						      1);
	}

	if (wp_group_size == 0) {
		return MMC_BOOT_E_FAILURE;
	}

	/* Setting POWER_ON_WP for USER AREA (CMD6) */
	mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_SET_BIT,
				      MMC_BOOT_EXT_USER_WP,
				      MMC_BOOT_US_PWR_WP_EN);

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* Calculating the loop count for sending SET_WRITE_PROTECT (CMD28)
	   or CLEAR_WRITE_PROTECT (CMD29).
	   We are write protecting the partitions in blocks of write protect
	   group sizes only */

	if (size % wp_group_size) {
		loop_count = (size / wp_group_size) + 1;
	} else {
		loop_count = (size / wp_group_size);
	}

	if (set_clear_wp)
		cmd.cmd_index = CMD28_SET_WRITE_PROTECT;
	else
		cmd.cmd_index = CMD29_CLEAR_WRITE_PROTECT;

	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1B;

	for (unsigned int i = 0; i < loop_count; i++) {
		/* Sending CMD28 for each WP group size
		   address is in sectors already */
		cmd.argument = (addr + (i * wp_group_size));

		mmc_ret = mmc_boot_send_command(&cmd);

		if (mmc_ret != MMC_BOOT_E_SUCCESS) {
			return mmc_ret;
		}

		/* Checking ADDR_OUT_OF_RANGE error in CMD28 response */
		if (IS_ADDR_OUT_OF_RANGE(cmd.resp[0])) {
			return MMC_BOOT_E_FAILURE;
		}

		/* Sending CMD13 to check card status */
		do {
			mmc_ret = mmc_boot_get_card_status(card, 0, &status);
			if (MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_TRAN_STATE)
				break;
		}
		while ((mmc_ret == MMC_BOOT_E_SUCCESS) &&
		       (MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_PROG_STATE));

		if (mmc_ret != MMC_BOOT_E_SUCCESS) {
			return mmc_ret;
		}
	}

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Function to get Write Protect status of the given sector
 */
static unsigned int
mmc_boot_get_wp_status(struct mmc_card *card, unsigned int sector)
{
	unsigned int rc = MMC_BOOT_E_SUCCESS;
	memset(wp_status_buf, 0, 8);

	rc = mmc_boot_read_reg(card, 8, CMD31_SEND_WRITE_PROT_TYPE, sector,
			       (unsigned int *)wp_status_buf);
	return rc;
}

/*
 * Test Function for setting Write protect for given sector
 */
static unsigned int
mmc_wp(unsigned int sector, unsigned int size, unsigned char set_clear_wp)
{
	unsigned int rc = MMC_BOOT_E_SUCCESS;

	/* Checking whether group write protection feature is available */
	if (mmc_card.csd.wp_grp_enable)
	{
		rc = mmc_boot_get_wp_status(&mmc_card, sector);
		if (rc != MMC_BOOT_E_SUCCESS)
		{
			dprintf(CRITICAL, "Failure in getting wp_status (%u):%s:%u\n", rc, __FILE__, __LINE__);
			return rc;
		}
		rc = mmc_boot_set_clr_power_on_wp_user(&mmc_card, sector, size,
						       set_clear_wp);
		if (rc != MMC_BOOT_E_SUCCESS)
		{
			dprintf(CRITICAL, "Failure in setting power on wp user (%u):%s:%u\n", rc, __FILE__, __LINE__);
			return rc;
		}
		rc = mmc_boot_get_wp_status(&mmc_card, sector);
		if (rc != MMC_BOOT_E_SUCCESS)
		{
			dprintf(CRITICAL, "Failure in getting wp_status (%u)%s:%u\n", rc, __FILE__, __LINE__);
			return rc;
		}
	}
	else
		return MMC_BOOT_E_FAILURE;
}

void mmc_wp_test(void)
{
	unsigned int mmc_ret = 0;
	mmc_ret = mmc_wp(0xE06000, 0x5000, 1);
}

unsigned mmc_get_psn(void)
{
	return mmc_card.cid.psn;
}

/*
 * Read/write data from/to SDC FIFO.
 */
static unsigned int
mmc_boot_data_transfer(unsigned int *data_ptr,
			    unsigned int data_len, unsigned char direction)
{
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

#if MMC_BOOT_ADM
	adm_result_t ret;
	adm_dir_t adm_dir;

	if (direction == MMC_BOOT_DATA_READ) {
		adm_dir = ADM_MMC_READ;
	} else {
		adm_dir = ADM_MMC_WRITE;
	}

	ret = adm_transfer_mmc_data(mmc_slot,
				    (unsigned char *)data_ptr, data_len,
				    adm_dir);

	if (ret != ADM_RESULT_SUCCESS) {
		dprintf(CRITICAL, "MMC ADM transfer error: %d\n", ret);
		mmc_ret = MMC_BOOT_E_FAILURE;
	}

#elif MMC_BOOT_BAM
	mmc_ret = mmc_bam_transfer_data(data_ptr, data_len, direction);
#else

	if (direction == MMC_BOOT_DATA_READ) {
		mmc_ret = mmc_boot_fifo_read(data_ptr, data_len);
	} else {
		mmc_ret = mmc_boot_fifo_write(data_ptr, data_len);
	}
#endif

	return mmc_ret;
}

/*
 * Read data to SDC FIFO.
 */
static unsigned int
mmc_boot_fifo_read(unsigned int *mmc_ptr, unsigned int data_len)
{
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
	unsigned int mmc_status = 0;
	unsigned int mmc_count = 0;
	unsigned int read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL |
	    MMC_BOOT_MCI_STAT_DATA_TIMEOUT | MMC_BOOT_MCI_STAT_RX_OVRRUN;

	/* Read the data from the MCI_FIFO register as long as RXDATA_AVLBL
	   bit of MCI_STATUS register is set to 1 and bits DATA_CRC_FAIL,
	   DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS register are cleared to 0.
	   Continue the reads until the whole transfer data is received */

	do {
		mmc_ret = MMC_BOOT_E_SUCCESS;
		mmc_status = readl(MMC_BOOT_MCI_STATUS);

		if (mmc_status & read_error) {
			mmc_ret = mmc_boot_status_error(mmc_status);
			break;
		}

		if (mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL) {
			unsigned read_count = 1;
			if (mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL) {
				read_count = MMC_BOOT_MCI_HFIFO_COUNT;
			}

			for (unsigned int i = 0; i < read_count; i++) {
				/* FIFO contains 16 32-bit data buffer on 16 sequential addresses */
				*mmc_ptr = readl(MMC_BOOT_MCI_FIFO +
						 (mmc_count %
						  MMC_BOOT_MCI_FIFO_SIZE));
				mmc_ptr++;
				/* increase mmc_count by word size */
				mmc_count += sizeof(unsigned int);
			}
			/* quit if we have read enough of data */
			if (mmc_count == data_len)
				break;
		} else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_END) {
			break;
		}
	}
	while (1);

	return mmc_ret;
}

/*
 * Write data to SDC FIFO.
 */
static unsigned int
mmc_boot_fifo_write(unsigned int *mmc_ptr, unsigned int data_len)
{
	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 count = 0;
	unsigned int sz = 0;

	/* Write the transfer data to SDCC3 FIFO */
	do {
		mmc_status = readl(MMC_BOOT_MCI_STATUS);

		/* Bytes left to write */
		count = data_len - mmc_count;

		/* Break if whole data is transferred */
		if (!count)
			break;

		/* Write half FIFO or less (remaining) words in MCI_FIFO as long as either
		   TX_FIFO_EMPTY or TX_FIFO_HFULL bits of MCI_STATUS register are set. */
		if ((mmc_status & MMC_BOOT_MCI_STAT_TX_FIFO_EMPTY) ||
			(mmc_status & MMC_BOOT_MCI_STAT_TX_FIFO_HFULL)) {

			/* Write minimum of half FIFO and remaining words */
			sz = ((count >> 2) >  MMC_BOOT_MCI_HFIFO_COUNT) \
				 ? MMC_BOOT_MCI_HFIFO_COUNT : (count >> 2);

			for (int i = 0; i < sz; i++) {
				writel(*mmc_ptr, MMC_BOOT_MCI_FIFO);
				mmc_ptr++;
				/* increase mmc_count by word size */
				mmc_count += sizeof(unsigned int);
			}
		}
	}
	while (1);

	do
	{
		mmc_status = readl(MMC_BOOT_MCI_STATUS);
		if (mmc_status & write_error) {
			mmc_ret = mmc_boot_status_error(mmc_status);
			break;
		}
	}
	while (!(mmc_status & MMC_BOOT_MCI_STAT_DATA_END));

	return mmc_ret;
}

/*
 * CMD35_ERASE_GROUP_START
 */

static unsigned int
mmc_boot_send_erase_group_start(struct mmc_card *card,
				unsigned long long data_addr)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	if (card == NULL)
		return MMC_BOOT_E_INVAL;

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	cmd.cmd_index = CMD35_ERASE_GROUP_START;
	cmd.argument = data_addr;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1;

	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* Checking for address error */
	if (IS_ADDR_OUT_OF_RANGE(cmd.resp[0])) {
		return MMC_BOOT_E_BLOCKLEN_ERR;
	}

	return MMC_BOOT_E_SUCCESS;

}

/*
 * CMD36 ERASE GROUP END
 */
static unsigned int
mmc_boot_send_erase_group_end(struct mmc_card *card,
			      unsigned long long data_addr)
{
	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	if (card == NULL)
		return MMC_BOOT_E_INVAL;

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	cmd.cmd_index = CMD36_ERASE_GROUP_END;
	cmd.argument = data_addr;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1;

	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* Checking for address error */
	if (IS_ADDR_OUT_OF_RANGE(cmd.resp[0])) {
		return MMC_BOOT_E_BLOCKLEN_ERR;
	}

	return MMC_BOOT_E_SUCCESS;
}

/*
 * CMD38 ERASE
 */
static unsigned int mmc_boot_send_erase(struct mmc_card *card)
{

	struct mmc_boot_command cmd;
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
	unsigned int status;

	if (card == NULL)
		return MMC_BOOT_E_INVAL;

	memset((struct mmc_boot_command *)&cmd, 0,
	       sizeof(struct mmc_boot_command));

	cmd.cmd_index = CMD38_ERASE;
	cmd.argument = 0x00000000;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1B;

	/* Checking if the card is in the transfer state */
	do {
		mmc_ret = mmc_boot_get_card_status(card, 0, &status);
		if (MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_TRAN_STATE)
			break;
	}
	while ((mmc_ret == MMC_BOOT_E_SUCCESS) &&
	       (MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_PROG_STATE));

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}
	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	/* Checking for write protect */
	if (cmd.resp[0] & MMC_BOOT_R1_WP_ERASE_SKIP) {
		dprintf(CRITICAL, "Write protect enabled for sector \n");
		return;
	}

	/* Checking if the erase operation for the card is compelete */
	do {
		mmc_ret = mmc_boot_get_card_status(card, 0, &status);
		if (MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_TRAN_STATE)
			break;
	}
	while ((mmc_ret == MMC_BOOT_E_SUCCESS) &&
	       (MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_PROG_STATE));

	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		return mmc_ret;
	}

	return MMC_BOOT_E_SUCCESS;
}

/*
 * Function to erase data on the eMMC card
 */
unsigned int
mmc_erase_card(unsigned long long data_addr, unsigned long long size)
{
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
	unsigned long long erase_grp_size;
	unsigned long long data_end = 0x00000000;
	unsigned long long loop_count;
	unsigned int out[512] = { 0 };

	/* Converting size to sectors */
	size = size / 512;

	if (ext_csd_buf[MMC_BOOT_EXT_ERASE_GROUP_DEF]) {
		erase_grp_size =
		    (512 * ext_csd_buf[MMC_BOOT_EXT_HC_ERASE_GRP_SIZE] * 1024);
		erase_grp_size = erase_grp_size / 512;
	} else {
		erase_grp_size = (mmc_card.csd.erase_grp_size + 1) *
		    (mmc_card.csd.erase_grp_mult + 1);
	}

	if (erase_grp_size == 0) {
		return MMC_BOOT_E_FAILURE;
	}

	if (size % erase_grp_size) {
		dprintf(CRITICAL, "Overflow beyond ERASE_GROUP_SIZE:%llu\n",
			(size % erase_grp_size));

	}
	loop_count = (size / erase_grp_size);
	/*
	 *In case the partition size is less than the erase_grp_size
	 0 is written to the first block of the partition.
	 */
	if (loop_count < 1) {
		mmc_ret = mmc_write(data_addr, 512, (unsigned int *)out);
		if (mmc_ret != MMC_BOOT_E_SUCCESS)
			return mmc_ret;
		else
			return MMC_BOOT_E_SUCCESS;
	} else {
		data_addr = ((mmc_card.type != MMC_BOOT_TYPE_MMCHC) &&
			     (mmc_card.type != MMC_BOOT_TYPE_SDHC))
		    ? (unsigned int)data_addr : (unsigned int)(data_addr / 512);
		data_end = data_addr + erase_grp_size * (loop_count - 1);
	}

	/* Sending CMD35 */
	mmc_ret = mmc_boot_send_erase_group_start(&mmc_card, data_addr);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL, "Error %d: Failure sending erase group start "
			"command to the card (RCA:%x)\n", mmc_ret,
			mmc_card.rca);
		return mmc_ret;
	}

	/* Sending CMD36 */
	mmc_ret = mmc_boot_send_erase_group_end(&mmc_card, data_end);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL, "Error %d: Failure sending erase group end "
			"command to the card (RCA:%x)\n", mmc_ret,
			mmc_card.rca);
		return mmc_ret;
	}

	/* Sending CMD38 */
	mmc_ret = mmc_boot_send_erase(&mmc_card);
	if (mmc_ret != MMC_BOOT_E_SUCCESS) {
		dprintf(CRITICAL,
			"Error %d: Failure sending erase command "
			"to the card (RCA:%x)\n", mmc_ret, mmc_card.rca);
		return mmc_ret;

	}

	dprintf(CRITICAL, "ERASE SUCCESSFULLY COMPLETED\n");
	return MMC_BOOT_E_SUCCESS;
}

/*
 * Disable MCI clk
 */
void mmc_boot_mci_clk_disable()
{
	uint32_t reg = 0;

	reg |= MMC_BOOT_MCI_CLK_DISABLE;
	writel(reg, MMC_BOOT_MCI_CLK);

	/* Wait for the MMC_BOOT_MCI_CLK write to go through. */
	mmc_mclk_reg_wr_delay();
}

/*
 * Enable MCI CLK
 */
void mmc_boot_mci_clk_enable()
{
	uint32_t reg = 0;

	reg |= MMC_BOOT_MCI_CLK_ENABLE;
	reg |= MMC_BOOT_MCI_CLK_ENA_FLOW;
	reg |= MMC_BOOT_MCI_CLK_IN_FEEDBACK;
	writel(reg, MMC_BOOT_MCI_CLK);

	/* Wait for the MMC_BOOT_MCI_CLK write to go through. */
	mmc_mclk_reg_wr_delay();
}

#if MMC_BOOT_BAM

void mmc_boot_dml_init()
{
	uint32_t val = 0;

	/* Initialize s/w reset for DML core */
	mmc_boot_dml_reset();

	/* Program DML config:
	 * 1. Disable producer and consumer CRCI.
	 * 2. Set Bypass mode for the DML for Direct access.
	 */
	val = 0;
	val |= 1 >> SDCC_BYPASS_SHIFT;
	writel(val, SDCC_DML_CONFIG(dml_base));

	/* Program consumer logic size:
	 * This is for handshaking between the BAM and the DML blocks.
	 */
	writel(4096, SDCC_DML_CONSUMER_PIPE_LOGICAL_SIZE(dml_base));

	/* Program producer logic size
	 * This is for handshaking between the BAM and the DML blocks.
	 */
	writel(4096, SDCC_DML_PRODUCER_PIPE_LOGICAL_SIZE(dml_base));


	/* Write the pipe id numbers. */
	val = 0;
	val |= bam.pipe[MMC_BOOT_BAM_READ_PIPE_INDEX].pipe_num << SDCC_PRODUCER_PIPE_ID_SHIFT;
	val |= bam.pipe[MMC_BOOT_BAM_WRITE_PIPE_INDEX].pipe_num << SDCC_CONSUMER_PIPE_ID_SHIFT;

	writel(val, SDCC_DML_PIPE_ID(dml_base));

}

/* Function to set up SDCC dml for System producer transaction. */
static void mmc_boot_dml_consumer_trans_init()
{
	uint32_t val = 0;

	val = 0 << SDCC_PRODUCER_CRCI_SEL_SHIFT;
	val |= 1 << SDCC_CONSUMER_CRCI_SEL_SHIFT;
	writel(val, SDCC_DML_CONFIG(dml_base));


	/* Start the consumer transaction */
	writel(1, SDCC_DML_CONSUMER_START(dml_base));

}

/* Function to set up SDCC dml for System consumer transaction.
 * trans_end: 1: Assert DML trasaction signal
 *                 at the end of transaction.
 *                 0: Do not assert DML transaction signal.
 * size: Transaction size
 */
static void mmc_boot_dml_producer_trans_init(unsigned trans_end,
                                             unsigned size)
{
	uint32_t val = 0;

	val = 1 << SDCC_PRODUCER_CRCI_SEL_SHIFT;
	val |= 0 << SDCC_CONSUMER_CRCI_SEL_SHIFT;
	val |=  trans_end << SDCC_PRODUCER_TRANS_END_EN_SHIFT;
	writel(val, SDCC_DML_CONFIG(dml_base));

	/* Set block size */
    writel(BLOCK_SIZE, SDCC_DML_PRODUCER_BAM_BLOCK_SIZE(dml_base));

	/* Write transaction size */
	writel(size, SDCC_DML_PRODUCER_BAM_TRANS_SIZE(dml_base));

	/* Start the producer transaction */
	writel(1, SDCC_DML_PRODUCER_START(dml_base));
}

/* Function to check producer idle status of the DML.
 * return value: 1: Producer is idle
 *                    0: Producer is busy
 */
static uint32_t mmc_boot_dml_chk_producer_idle()
{
	uint32_t val = 0;

	val = readl(SDCC_DML_STATUS(dml_base));

	/* Read only the producer idle status */
	val &= (1 << SDCC_DML_PRODUCER_IDLE_SHIFT);

	return val;
}

/* Function to clear transaction complete flag */
static void mmc_boot_dml_clr_trans_complete()
{
	uint32_t val;

	val = readl(SDCC_DML_CONFIG(dml_base));

	val &=  ~(1 << SDCC_PRODUCER_TRANS_END_EN_SHIFT);
	writel(val, SDCC_DML_CONFIG(dml_base));
}

/* Blocking function to wait until DML is idle. */
static void mmc_boot_dml_wait_producer_idle()
{
	while(!(readl(SDCC_DML_STATUS(dml_base)) & 1));
}

/* Blocking function to wait until DML is idle. */
static void mmc_boot_dml_wait_consumer_idle()
{
	while(!(readl(SDCC_DML_STATUS(dml_base)) & (1 << SDCC_DML_CONSUMER_IDLE_SHIFT)));
}

/* Initialize S/W reset */
static void mmc_boot_dml_reset()
{
	/* Initialize s/w reset for DML core */
	writel(1, SDCC_DML_SW_RESET(dml_base));

}

static int mmc_bam_init(uint32_t bam_base)
{

	uint32_t mmc_ret = MMC_BOOT_E_SUCCESS;

	bam.base = bam_base;
	/* Read pipe parameter initializations. */
	bam.pipe[MMC_BOOT_BAM_READ_PIPE_INDEX].pipe_num = MMC_BOOT_BAM_READ_PIPE;
	/* System consumer */
	bam.pipe[MMC_BOOT_BAM_READ_PIPE_INDEX].trans_type = BAM2SYS;
	/* Set the descriptor FIFO start ptr */
	bam.pipe[MMC_BOOT_BAM_READ_PIPE_INDEX].fifo.head = desc_fifo;
	/* Set the descriptor FIFO lengths */
	bam.pipe[MMC_BOOT_BAM_READ_PIPE_INDEX].fifo.size = MMC_BOOT_BAM_FIFO_SIZE;

	/* Write pipe parameter initializations.*/
	bam.pipe[MMC_BOOT_BAM_WRITE_PIPE_INDEX].pipe_num = MMC_BOOT_BAM_WRITE_PIPE;
	/* System producer */
	bam.pipe[MMC_BOOT_BAM_WRITE_PIPE_INDEX].trans_type = SYS2BAM;
	/* Write fifo uses the same fifo as read */
	bam.pipe[MMC_BOOT_BAM_WRITE_PIPE_INDEX].fifo.head = desc_fifo;
	/* Set the descriptor FIFO lengths */
	bam.pipe[MMC_BOOT_BAM_WRITE_PIPE_INDEX].fifo.size = MMC_BOOT_BAM_FIFO_SIZE;

	/* Programs the minimum threshold for BAM transfer*/
	bam.threshold = BLOCK_SIZE;

	/* Initialize MMC BAM */
	bam_init(&bam);

	/* Initialize BAM MMC read pipe */
	bam_sys_pipe_init(&bam, MMC_BOOT_BAM_READ_PIPE_INDEX);

	mmc_ret = bam_pipe_fifo_init(&bam, bam.pipe[MMC_BOOT_BAM_READ_PIPE_INDEX].pipe_num);

	if (mmc_ret)
	{
		dprintf(CRITICAL, "MMC: BAM Read pipe fifo init error\n");
		goto mmc_bam_init_error;
	}

	/* Initialize BAM MMC write pipe */
	bam_sys_pipe_init(&bam, MMC_BOOT_BAM_WRITE_PIPE_INDEX);

	mmc_ret = bam_pipe_fifo_init(&bam, bam.pipe[MMC_BOOT_BAM_WRITE_PIPE_INDEX].pipe_num);

	if (mmc_ret)
	{
		dprintf(CRITICAL, "MMC: BAM Write pipe fifo init error\n");
		goto mmc_bam_init_error;
	}

	mmc_boot_dml_init();

	mmc_bam_init_error:

	return mmc_ret;
}

static int mmc_bam_transfer_data(unsigned int *data_ptr,
                                 unsigned int data_len,
			                     unsigned int dir)
{
	uint32_t mmc_ret;
	uint32_t offset;

	mmc_ret = MMC_BOOT_E_SUCCESS;

	if(dir == MMC_BOOT_DATA_READ)
	{
		/* Check BAM IRQ status reg to verify the desc has been processed */
		mmc_ret = bam_wait_for_interrupt(&bam,
					MMC_BOOT_BAM_READ_PIPE_INDEX, P_PRCSD_DESC_EN_MASK);

		if (mmc_ret != BAM_RESULT_SUCCESS)
		{
			dprintf(CRITICAL, "BAM transfer error \n");
			mmc_ret = MMC_BOOT_E_FAILURE;
			goto mmc_bam_transfer_err;
		}

		mmc_boot_dml_wait_producer_idle();

		/* Update BAM pipe fifo offsets */
		offset = bam_read_offset_update(&bam, MMC_BOOT_BAM_READ_PIPE_INDEX);

		/* Reset DPSM */
		writel(0, MMC_BOOT_MCI_DATA_CTL);

		/* Wait for the MMC_BOOT_MCI_DATA_CTL write to go through. */
		mmc_mclk_reg_wr_delay();

		dprintf(SPEW, "Offset value is %d \n", offset);
	}
	else
	{
		/* Check BAM IRQ status reg to verify the desc has been processed */
		mmc_ret = bam_wait_for_interrupt(&bam,
					MMC_BOOT_BAM_WRITE_PIPE_INDEX, P_TRNSFR_END_EN_MASK);

		if (mmc_ret != BAM_RESULT_SUCCESS)
		{
			dprintf(CRITICAL, "BAM transfer error \n");
			mmc_ret = MMC_BOOT_E_FAILURE;
			goto mmc_bam_transfer_err;
		}

		/* Update BAM pipe fifo offsets */
		offset = bam_read_offset_update(&bam, MMC_BOOT_BAM_WRITE_PIPE_INDEX);

		dprintf(SPEW, "Offset value is %d \n", offset);
	}

mmc_bam_transfer_err:

	return mmc_ret;
}

static unsigned int
mmc_boot_bam_setup_desc(unsigned int *data_ptr,
                        unsigned int data_len,
                        unsigned char direction)
{
	unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;

	if (direction == MMC_BOOT_DATA_READ)
	{
		mmc_boot_dml_producer_trans_init(1, data_len);
		mmc_ret = bam_add_desc(&bam, MMC_BOOT_BAM_READ_PIPE_INDEX,
					(unsigned char *)data_ptr, data_len);
	}
	else
	{
		mmc_boot_dml_consumer_trans_init();
		mmc_ret = bam_add_desc(&bam, MMC_BOOT_BAM_WRITE_PIPE_INDEX,
					(unsigned char *)data_ptr, data_len);
	}

	/* Update return value enums */
	if (mmc_ret != BAM_RESULT_SUCCESS)
	{
		dprintf(CRITICAL, "MMC BAM transfer error: %d\n", mmc_ret);
		mmc_ret = MMC_BOOT_E_FAILURE;
	}
}

#endif

/*
 * Check if card supports DDR mode
 */
uint8_t card_supports_ddr_mode()
{
	if (IS_BIT_SET_EXT_CSD(MMC_DEVICE_TYPE, 2) ||
		IS_BIT_SET_EXT_CSD(MMC_DEVICE_TYPE, 3))
		return 1;
	else
		return 0;
}

/*
 * Check if card suppports HS200 mode
 */
uint8_t card_supports_hs200_mode()
{
	if (IS_BIT_SET_EXT_CSD(MMC_DEVICE_TYPE, 4) ||
		IS_BIT_SET_EXT_CSD(MMC_DEVICE_TYPE, 5))
		return 1;
	else
		return 0;
}

/* Return the density of the mmc device */
uint64_t mmc_get_device_capacity()
{
	return mmc_card.capacity;
}

/* Return the block size of the mmc device */
uint32_t mmc_get_device_blocksize()
{
	return mmc_card.block_size;
}

void mmc_put_card_to_sleep(void)
{
	uint32_t mmc_ret;
	struct mmc_boot_command cmd = {0};

	cmd.cmd_index = CMD7_SELECT_DESELECT_CARD;
	cmd.argument = 0x00000000;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_NONE;

	/* send command */
	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS)
	{
		dprintf(CRITICAL, "card deselect error: %d\n", mmc_ret);
		return;
	}

	cmd.cmd_index = CMD5_SLEEP_AWAKE;
	cmd.argument = (mmc_card.rca << MMC_CARD_RCA_BIT) | MMC_CARD_SLEEP;
	cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
	cmd.resp_type = MMC_BOOT_RESP_R1B;

	/* send command */
	mmc_ret = mmc_boot_send_command(&cmd);
	if (mmc_ret != MMC_BOOT_E_SUCCESS)
		dprintf(CRITICAL, "card sleep error: %d\n", mmc_ret);
}
