/* Copyright (c) 2013-2015,2018 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_sdhci.h>
#include <sdhci.h>
#include <sdhci_msm.h>
#include <partition_parser.h>
#include <platform/iomap.h>
#include <platform/timer.h>
#include <platform.h>

extern void clock_init_mmc(uint32_t);
extern void clock_config_mmc(uint32_t, uint32_t);

/* data access time unit in ns */
static const uint32_t taac_unit[] =
{
	1, 10, 100, 1000, 10000, 100000, 1000000, 10000000
};

/* data access time value x 10 */
static const uint32_t 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 uint32_t xfer_rate_unit[] =
{
	100, 1000, 10000, 100000, 0, 0, 0, 0
};

/* data transfer rate value x 10*/
static const uint32_t xfer_rate_value[] =
{
	0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 52, 55, 60, 70, 80
};

/*
 * Function: mmc decode and save csd
 * Arg     : Card structure & raw csd
 * Return  : 0 on Success, 1 on Failure
 * Flow    : 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 uint32_t mmc_decode_and_save_csd(struct mmc_card *card)
{
	uint32_t mmc_sizeof = 0;
	uint32_t mmc_unit = 0;
	uint32_t mmc_value = 0;
	uint32_t mmc_temp = 0;
	uint32_t *raw_csd = card->raw_csd;

	struct mmc_csd mmc_csd;

	mmc_sizeof = sizeof(uint32_t) * 8;

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

	if (MMC_CARD_SD(card)) {
		/* 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);
			/* Fixed value is 9 = 2^9 = 512 */
			mmc_csd.write_blk_len = 512;
			/* Fixed value is 9 = 512 */
			mmc_csd.read_blk_len = 512;
			/* Fixed value: 010b */
			mmc_csd.r2w_factor = 0x2;
			/* Not there in version 2.0 */
			mmc_csd.c_size_mult = 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;

			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 = (unsigned long long) (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 = (unsigned long long)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);

		/* Ignore -- no use of this value. */
		mmc_csd.tran_speed = 0x00;

		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 = (unsigned long long) 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.
			 */
			uint64_t sec_count;

			sec_count = (card->ext_csd[MMC_SEC_COUNT4] << MMC_SEC_COUNT4_SHIFT)
						| (card->ext_csd[MMC_SEC_COUNT3] << MMC_SEC_COUNT3_SHIFT)
						| (card->ext_csd[MMC_SEC_COUNT2] << MMC_SEC_COUNT2_SHIFT)
						| card->ext_csd[MMC_SEC_COUNT1];
			card->capacity = sec_count * MMC_BLK_SZ;
		}
	}

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

	if (MMC_CARD_MMC(card)) {

		/* Calculate the wp grp size */
		if (card->ext_csd[MMC_ERASE_GRP_DEF])
			card->wp_grp_size = MMC_HC_ERASE_MULT * card->ext_csd[MMC_HC_ERASE_GRP_SIZE] / MMC_BLK_SZ;
		else
			card->wp_grp_size = (card->csd.wp_grp_size + 1) * (card->csd.erase_grp_size + 1) \
						  * (card->csd.erase_grp_mult + 1);

		card->rpmb_size = RPMB_PART_MIN_SIZE * card->ext_csd[RPMB_SIZE_MULT];
		card->rel_wr_count = card->ext_csd[REL_WR_SEC_C];
	}
	else {
		card->wp_grp_size = (card->csd.wp_grp_size + 1) * (card->csd.erase_grp_size + 1) \
						* (card->csd.erase_grp_mult + 1);
	}

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

	return 0;
}

/*
 * Function: mmc decode & save cid
 * Arg     : card structure & raw cid
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Decode CID sent by the card.
 */
static uint32_t mmc_decode_and_save_cid(struct mmc_card *card,
										uint32_t *raw_cid)
{
	struct mmc_cid mmc_cid;
	uint32_t mmc_sizeof = 0;
	int i = 0;

	if (!raw_cid) {
		return 1;
	}

	mmc_sizeof = sizeof(uint32_t) * 8;

	if (MMC_CARD_SD(card)) {
		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] = (uint8_t)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] = (uint8_t)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 0;
}

/*
 * Function: mmc reset cards
 * Arg     : host structure
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Reset all the cards to idle condition (CMD 0)
 */
static uint8_t mmc_reset_card(struct sdhci_host *host)
{
	struct mmc_command cmd;

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

	cmd.cmd_index = CMD0_GO_IDLE_STATE;
	cmd.argument = 0;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_NONE;

	/* send command */
	return sdhci_send_command(host, &cmd);
}

/*
 * Function: mmc operations command
 * Arg     : host & card structure
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Send CMD1 to know whether the card supports host VDD profile or not.
 */
static uint32_t mmc_send_op_cond(struct sdhci_host *host, struct mmc_card *card)
{
	struct mmc_command cmd;
	uint32_t mmc_resp = 0;
	uint32_t mmc_ret = 0;
	uint32_t mmc_retry = 0;

	memset((struct mmc_command *)&cmd, 0, sizeof(struct mmc_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 = card->ocr;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R3;

	do {
		mmc_ret = sdhci_send_command(host, &cmd);
		if (mmc_ret)
			return mmc_ret;

		/* Command returned success, now it's time to examine response */
		mmc_resp = cmd.resp[0];

		/* Check the response for busy status */
		if (!(mmc_resp & MMC_OCR_BUSY)) {
			mmc_retry++;
			mdelay(1);
			continue;
		} else
			break;
	} while (mmc_retry < MMC_MAX_COMMAND_RETRY);

	/* If we reached here after max retries, we failed to get OCR */
	if (mmc_retry == MMC_MAX_COMMAND_RETRY && !(mmc_resp & MMC_OCR_BUSY)) {
		dprintf(CRITICAL, "Card has busy status set. Init did not complete\n");
		return 1;
	}

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

	if (mmc_resp & MMC_OCR_SEC_MODE)
		card->type = MMC_TYPE_MMCHC;
	else
		card->type = MMC_TYPE_STD_MMC;

	return 0;
}

/*
 * Function: mmc send cid
 * Arg     : host & card structure
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Request any card to send its uniquie card identification
 *           (CID) number (CMD2).
 */
static uint32_t mmc_all_send_cid(struct sdhci_host *host, struct mmc_card *card)
{
	struct mmc_command cmd;
	uint32_t mmc_ret = 0;

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

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

	/* send command */
	mmc_ret = sdhci_send_command(host, &cmd);
	if (mmc_ret) {
		return mmc_ret;
	}

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

	return 0;
}

/*
 * Function: mmc send relative address
 * Arg     : host & card structure
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Ask 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 uint32_t mmc_send_relative_address(struct sdhci_host *host,
										  struct mmc_card *card)
{
	struct mmc_command cmd;
	uint32_t mmc_ret = 0;

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

	/* CMD3 Format:
	 * [31:0] stuff bits
	 */
	if (MMC_CARD_SD(card)) {
		cmd.cmd_index = CMD3_SEND_RELATIVE_ADDR;
		cmd.argument = 0;
		cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
		cmd.resp_type = SDHCI_CMD_RESP_R6;

		/* send command */
		mmc_ret = sdhci_send_command(host, &cmd);
		if (mmc_ret)
			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 = SDHCI_CMD_TYPE_NORMAL;
		cmd.resp_type = SDHCI_CMD_RESP_R6;

		/* send command */
		mmc_ret = sdhci_send_command(host, &cmd);
		if (mmc_ret)
			return mmc_ret;
	}

	return 0;
}

/*
 * Function: mmc send csd
 * Arg     : host, card structure & o/p arg to store csd
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Requests card to send it's CSD register's contents. (CMD9)
 */
static uint32_t mmc_send_csd(struct sdhci_host *host, struct mmc_card *card)
{
	struct mmc_command cmd;
	uint32_t mmc_arg = 0;
	uint32_t mmc_ret = 0;

	memset((struct mmc_command *)&cmd, 0, sizeof(struct mmc_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 = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R2;

	/* send command */
	mmc_ret = sdhci_send_command(host, &cmd);
	if (mmc_ret)
		return mmc_ret;

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

	return 0;
}

/*
 * Function: mmc select card
 * Arg     : host, card structure
 * Return  : 0 on Success, 1 on Failure
 * Flow    : 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 uint32_t mmc_select_card(struct sdhci_host *host, struct mmc_card *card)
{
	struct mmc_command cmd;
	uint32_t mmc_arg = 0;
	uint32_t mmc_ret = 0;

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

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

	cmd.cmd_index = CMD7_SELECT_DESELECT_CARD;
	cmd.argument = mmc_arg;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;

	/* If we are deselecting card, we do not get response */
	if (card->rca) {
		if (MMC_CARD_SD(card))
			cmd.resp_type = SDHCI_CMD_RESP_R1B;
		else
			cmd.resp_type = SDHCI_CMD_RESP_R1;
	} else
		cmd.resp_type = SDHCI_CMD_RESP_NONE;

	/* send command */
	mmc_ret = sdhci_send_command(host, &cmd);
	if (mmc_ret)
		return mmc_ret;

	return 0;
}

/*
 * Function: mmc set block len
 * Arg     : host, card structure & block length
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Send command to set block length.
 */
static uint32_t mmc_set_block_len(struct sdhci_host *host,
								  struct mmc_card *card,
								  uint32_t block_len)
{
	struct mmc_command cmd;
	uint32_t mmc_ret = 0;

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

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

	cmd.cmd_index = CMD16_SET_BLOCKLEN;
	cmd.argument = block_len;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1;

	/* send command */
	mmc_ret = sdhci_send_command(host, &cmd);
	if (mmc_ret)
		return mmc_ret;

	/*
	 * If blocklength is larger than 512 bytes,
	 * the card sets BLOCK_LEN_ERROR bit.
	 */
	if (cmd.resp[0] & MMC_R1_BLOCK_LEN_ERR) {
		dprintf(CRITICAL, "The block length is not supported by the card\n");
		return 1;
	}

	return 0;
}

/*
 * Function: mmc get card status
 * Arg     : host, card structure & o/p argument card status
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Get the current status of the card
 */
static uint32_t mmc_get_card_status(struct sdhci_host *host,
									struct mmc_card *card, uint32_t *status)
{
	struct mmc_command cmd;
	uint32_t mmc_ret = 0;

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

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

	/* send command */
	mmc_ret = sdhci_send_command(host, &cmd);
	if (mmc_ret)
		return mmc_ret;

	/* Checking ADDR_OUT_OF_RANGE error in CMD13 response */
	if ((cmd.resp[0] >> 31) & 0x01)
		return 1;

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

/*
 * Function: mmc get ext csd
 * Arg     : host, card structure & array to hold ext attributes
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Send ext csd command & get the card attributes
 */
static uint32_t mmc_get_ext_csd(struct sdhci_host *host, struct mmc_card *card)
{
	struct mmc_command cmd;
	uint32_t mmc_ret = 0;

	card->ext_csd = memalign(CACHE_LINE, ROUNDUP(512, CACHE_LINE));

	ASSERT(card->ext_csd);

	memset(card->ext_csd, 0, sizeof(card->ext_csd));

	/* invalidate any cached buf data (controller updates main memory) */
	arch_invalidate_cache_range((addr_t) card->ext_csd, 512);

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

	/* CMD8 */
	cmd.cmd_index = CMD8_SEND_EXT_CSD;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1;
	cmd.data.data_ptr = card->ext_csd;
	cmd.data.num_blocks = 1;
	cmd.data_present = 0x1;
	cmd.trans_mode = SDHCI_MMC_READ;

	/* send command */
	mmc_ret = sdhci_send_command(host, &cmd);
	if (mmc_ret)
		return mmc_ret;

	return mmc_ret;
}

/*
 * Function: mmc switch command
 * Arg     : Host, card structure, access mode, index & value to be set
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Send switch command to the card to set the ext attribute @ index
 */
static uint32_t mmc_switch_cmd(struct sdhci_host *host, struct mmc_card *card,
							   uint32_t access, uint32_t index, uint32_t value)
{

	struct mmc_command cmd;
	uint32_t mmc_ret = 0;
	uint32_t mmc_status;

	memset((struct mmc_command *)&cmd, 0, sizeof(struct mmc_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 = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1B;

	mmc_ret = sdhci_send_command(host, &cmd);
	if (mmc_ret) {
		dprintf(CRITICAL, "CMD6 send failed\n");
		return mmc_ret;
	}

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

	if (MMC_CARD_STATUS(mmc_status) != MMC_TRAN_STATE) {
		dprintf(CRITICAL, "Switch cmd failed. Card not in tran state %x\n", mmc_status);
		mmc_ret = 1;
	}

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

	return mmc_ret;
}

bool mmc_set_drv_type(struct sdhci_host *host, struct mmc_card *card, uint8_t drv_type)
{
	bool drv_type_changed = false;

	uint32_t value = ((drv_type << 4) | MMC_HS200_TIMING);

	if (MMC_CARD_MMC(card)) {
		if (card->ext_csd[MMC_EXT_MMC_DRV_STRENGTH] & (1 << drv_type)){
			mmc_switch_cmd(host, card, MMC_ACCESS_WRITE, MMC_EXT_MMC_HS_TIMING, value);
			drv_type_changed = true;
		}
	}
	return drv_type_changed;
}
/*
 * Function: mmc set bus width
 * Arg     : Host, card structure & width
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Send switch command to set bus width
 */
static uint32_t mmc_set_bus_width(struct sdhci_host *host,
								  struct mmc_card *card,
								  uint32_t width)
{
	uint32_t mmc_ret = 0;

	mmc_ret = mmc_switch_cmd(host, card, MMC_ACCESS_WRITE,
							 MMC_EXT_MMC_BUS_WIDTH, width);

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

	return 0;
}


/*
 * Function: mmc card supports hs400 mode
 * Arg     : None
 * Return  : 1 if hs400 mode is supported, 0 otherwise
 * Flow    : Check the ext csd attributes of the card
 */
static uint8_t mmc_card_supports_hs400_mode(struct mmc_card *card)
{
	if (MMC_CARD_MMC(card)) {
		if (card->ext_csd[MMC_DEVICE_TYPE] & MMC_HS_HS400_MODE)
			return 1;
		else
			return 0;
	}
	else
		return 0;
}

/*
 * Function: mmc card supports hs200 mode
 * Arg     : None
 * Return  : 1 if HS200 mode is supported, 0 otherwise
 * Flow    : Check the ext csd attributes of the card
 */
static uint8_t mmc_card_supports_hs200_mode(struct mmc_card *card)
{
	if (MMC_CARD_MMC(card)) {
		if (card->ext_csd[MMC_DEVICE_TYPE] & MMC_HS_HS200_MODE)
			return 1;
		else
			return 0;
	}
	else
		return 0;
}

/*
 * Function: mmc card supports ddr mode
 * Arg     : None
 * Return  : 1 if DDR mode is supported, 0 otherwise
 * Flow    : Check the ext csd attributes of the card
 */
static uint8_t mmc_card_supports_ddr_mode(struct mmc_card *card)
{
	if (MMC_CARD_MMC(card)) {
		if (card->ext_csd[MMC_DEVICE_TYPE] & MMC_HS_DDR_MODE)
			return 1;
		else
			return 0;
	}
	else
		return 0;
}

/*
 * Function : Enable HS200 mode
 * Arg      : Host, card structure and bus width
 * Return   : 0 on Success, 1 on Failure
 * Flow     :
 *           - Set the bus width to 4/8 bit SDR as supported by the target & host
 *           - Set the HS_TIMING on ext_csd 185 for the card
 */
static uint32_t mmc_set_hs200_mode(struct sdhci_host *host,
								   struct mmc_card *card, uint32_t width)
{
	uint32_t mmc_ret = 0;

	DBG("\n Enabling HS200 Mode Start\n");

	/* Set 4/8 bit SDR bus width */
	mmc_ret = mmc_set_bus_width(host, card, width);
	if (mmc_ret) {
		dprintf(CRITICAL, "Failure to set wide bus for Card(RCA:%x)\n",
						  card->rca);
		return mmc_ret;
	}

	/* Setting HS200 in HS_TIMING using EXT_CSD (CMD6) */
	mmc_ret = mmc_switch_cmd(host, card, MMC_ACCESS_WRITE, MMC_EXT_MMC_HS_TIMING, MMC_HS200_TIMING);

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

	/* Enable SDR104 mode in controller */
	sdhci_set_uhs_mode(host, SDHCI_SDR104_MODE);

	/* Run the clock @ 400 Mhz */
	if (host->caps.hs400_support && mmc_card_supports_hs400_mode(card))
	{
		/* Save the timing value, before changing the clock */
		MMC_SAVE_TIMING(host, MMC_HS400_TIMING);
		/*
		* Set the MCI_CLK divider before changing the sdcc core
		* core clk to ensure card receives no more than 200 MHZ
		* clock frequency
		*/
		sdhci_msm_set_mci_clk(host);
		clock_config_mmc(host->msm_host->slot, SDHCI_CLK_400MHZ);
	}

	/* Execute Tuning for hs200 mode */
	if ((mmc_ret = sdhci_msm_execute_tuning(host, card, width)))
		dprintf(CRITICAL, "Tuning for hs200 failed\n");

	/* Once the tuning is executed revert back the clock to 200MHZ
	 * and disable the MCI_CLK divider so that we can use SDHC clock
	 * divider to supply clock to the card
	 */
	if (host->timing == MMC_HS400_TIMING)
	{
		MMC_SAVE_TIMING(host, MMC_HS200_TIMING);
		sdhci_msm_set_mci_clk(host);
		clock_config_mmc(host->msm_host->slot, MMC_CLK_192MHZ);
	}
	else
	{
		/* Save the timing value, before changing the clock */
		MMC_SAVE_TIMING(host, MMC_HS200_TIMING);
	}


	DBG("\n Enabling HS200 Mode Done\n");

	return mmc_ret;
}

/*
 * Function: mmc set ddr mode
 * Arg     : Host & card structure
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Set bus width for ddr mode & set controller in DDR mode
*/
static uint8_t mmc_set_ddr_mode(struct sdhci_host *host, struct mmc_card *card)
{
	uint8_t mmc_ret = 0;

	DBG("\n Enabling DDR Mode Start\n");

	/* Set width for 8 bit DDR mode by default */
	mmc_ret = mmc_set_bus_width(host, card, DATA_DDR_BUS_WIDTH_8BIT);

	if (mmc_ret) {
		dprintf(CRITICAL, "Failure to set DDR mode for Card(RCA:%x)\n",
						  card->rca);
		return mmc_ret;
	}

	/* Save the timing value, before changing the clock */
	MMC_SAVE_TIMING(host, SDHCI_DDR50_MODE);

	/* Set the DDR mode in controller */
	sdhci_set_uhs_mode(host, SDHCI_DDR50_MODE);

	DBG("\n Enabling DDR Mode Done\n");

	return 0;
}

/*
 * Function: mmc set high speed interface
 * Arg     : Host & card structure
 * Return  : None
 * Flow    : Sets the sdcc clock & clock divider in the host controller
 *           Adjust the interface speed to optimal speed
 */
static uint32_t mmc_set_hs_interface(struct sdhci_host *host,
									 struct mmc_card *card)
{
	uint32_t mmc_ret = 0;

	/* Setting HS_TIMING in EXT_CSD (CMD6) */
	mmc_ret = mmc_switch_cmd(host, card, MMC_ACCESS_WRITE,
							 MMC_EXT_MMC_HS_TIMING, MMC_HS_TIMING);

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

	/* Save the timing value, before changing the clock */
	MMC_SAVE_TIMING(host, SDHCI_SDR25_MODE);

	/* Set the SDR25 mode in controller */
	sdhci_set_uhs_mode(host, SDHCI_SDR25_MODE);

	return 0;
}

/*
 * Function : Enable HS400 mode
 * Arg      : Host, card structure and bus width
 * Return   : 0 on Success, 1 on Failure
 * Flow     :
 *           - Set the bus width to 8 bit DDR
 *           - Set the HS_TIMING on ext_csd 185 for the card
 */
uint32_t mmc_set_hs400_mode(struct sdhci_host *host,
								   struct mmc_card *card, uint32_t width)
{
	uint32_t mmc_ret = 0;

	/*
	 * Emmc 5.0 spec does not allow changing to hs400 mode directly
	 * Need to follow the sequence to change to hs400 mode
	 * 1. Enable HS200 mode, perform tuning
	 * 2. Change to high speed mode
	 * 3. Enable DDR mode
	 * 4. Enable HS400 mode & execute tuning
	 */

	DBG("\n Enabling HS400 Mode Start\n");
	/* HS400 mode is supported only in DDR 8-bit */
	if (width != DATA_BUS_WIDTH_8BIT)
	{
		dprintf(CRITICAL, "Bus width is not 8-bit, cannot switch to hs400: %u\n", width);
		return 1;
	}

	/* 1.Enable HS200 mode */
	mmc_ret = mmc_set_hs200_mode(host, card, width);

	if (mmc_ret)
	{
		dprintf(CRITICAL, "Failure Setting HS200 mode %s\t%d\n",__func__, __LINE__);
		return mmc_ret;
	}

	/* 2. Enable High speed mode */
	/* This is needed to set the clock to a low value &
	 * so that we can switch to hs_timing --> 0x1 */
	/* Save the timing value, before changing the clock */
	MMC_SAVE_TIMING(host, SDHCI_SDR12_MODE);
	sdhci_set_uhs_mode(host, SDHCI_SDR12_MODE);

	/* 3. Set HS_TIMING to 0x1 */
	mmc_ret = mmc_set_hs_interface(host, card);
	if (mmc_ret)
	{
		dprintf(CRITICAL, "Error adjusting interface speed!:%s\t%d\n", __func__, __LINE__);
		return mmc_ret;
	}

	/*4. Enable DDR mode */
	mmc_ret = mmc_set_ddr_mode(host, card);
	if (mmc_ret)
	{
		dprintf(CRITICAL, "Failure setting DDR mode:%s\t%d\n", __func__, __LINE__);
		return mmc_ret;
	}

	/*5. Set hs400 timing */
	mmc_ret = mmc_switch_cmd(host, card, MMC_ACCESS_WRITE, MMC_EXT_MMC_HS_TIMING, MMC_HS400_TIMING);

	if (mmc_ret)
	{
		dprintf(CRITICAL, "Switch cmd returned failure %s\t%d\n",__func__,  __LINE__);
		return mmc_ret;
	}

	/* 6. Enable SDR104 mode in controller */
	/* Save the timing value, before changing the clock */
	MMC_SAVE_TIMING(host, MMC_HS400_TIMING);
	sdhci_set_uhs_mode(host, SDHCI_SDR104_MODE);
	/*
	* Enable HS400 mode
	*/
	sdhci_msm_set_mci_clk(host);
	/* Set the clock back to 400 MHZ */
	clock_config_mmc(host->msm_host->slot, SDHCI_CLK_400MHZ);

	/* 7. Execute Tuning for hs400 mode */
	if ((mmc_ret = sdhci_msm_execute_tuning(host, card, width)))
		dprintf(CRITICAL, "Tuning for hs400 failed\n");

	DBG("\n Enabling HS400 Mode Done\n");

	return mmc_ret;
}

/*
 * Function: mmc_host_init
 * Arg     : mmc device structure
 * Return  : 0 on success, 1 on Failure
 * Flow    : Initialize the host contoller
 *           Set the clock rate to 400 KHZ for init
 */
static uint8_t mmc_host_init(struct mmc_device *dev)
{
	uint8_t mmc_ret = 0;

	struct sdhci_host *host;
	struct mmc_config_data *cfg;
	struct sdhci_msm_data *data;

	event_t sdhc_event;

	host = &dev->host;
	cfg = &dev->config;

	event_init(&sdhc_event, false, EVENT_FLAG_AUTOUNSIGNAL);

	host->base = cfg->sdhc_base;
	host->sdhc_event = &sdhc_event;
	host->caps.hs200_support = cfg->hs200_support;
	host->caps.hs400_support = cfg->hs400_support;

	data = (struct sdhci_msm_data *) malloc(sizeof(struct sdhci_msm_data));
	ASSERT(data);

	data->sdhc_event = &sdhc_event;
	data->pwrctl_base = cfg->pwrctl_base;
	data->pwr_irq = cfg->pwr_irq;
	data->slot = cfg->slot;
	data->use_io_switch = cfg->use_io_switch;

	host->msm_host = data;

	/* Initialize any clocks needed for SDC controller */
	clock_init_mmc(cfg->slot);

	clock_config_mmc(cfg->slot, cfg->max_clk_rate);

	/* Configure the CDC clocks needed for emmc storage
	 * we use slot '1' for emmc
	 */
	if (cfg->slot == 1)
		clock_config_cdc(cfg->slot);

	/*
	 * MSM specific sdhc init
	 */
	sdhci_msm_init(host, data);

	/*
	 * Initialize the controller, read the host capabilities
	 * set power on mode
	 */
	sdhci_init(host);

	/* Setup initial freq to 400KHz */
	mmc_ret = sdhci_clk_supply(host, SDHCI_CLK_400KHZ);

	return mmc_ret;
}

/*
 * Function: mmc identify card
 * Arg     : host & card structure
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Performs card identification process:
 *           1. Get card's unique identification number (CID)
 *           2. Get(for sd)/set (for mmc) relative card address (RCA)
 *           3. Select the card to put it in TRAN state
 */
static uint32_t mmc_identify_card(struct sdhci_host *host, struct mmc_card *card)
{
	uint32_t mmc_return = 0;

	/* Ask card to send its unique card identification (CID) number (CMD2) */
	mmc_return = mmc_all_send_cid(host, card);
	if (mmc_return) {
		dprintf(CRITICAL,"Failure getting card's CID number!\n");
		return mmc_return;
	}

	/* Ask card to send a relative card address (RCA) (CMD3) */
	mmc_return = mmc_send_relative_address(host, card);
	if (mmc_return) {
		dprintf(CRITICAL, "Failure getting card's RCA!\n");
		return mmc_return;
	}

	/* Get card's CSD register (CMD9) */
	mmc_return = mmc_send_csd(host, card);
	if (mmc_return) {
		dprintf(CRITICAL,"Failure getting card's CSD information!\n");
		return mmc_return;
	}

	/* Select the card (CMD7) */
	mmc_return = mmc_select_card(host, card);
	if (mmc_return) {
		dprintf(CRITICAL, "Failure selecting the Card with RCA: %x\n",card->rca);
		return mmc_return;
	}

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

	return 0;
}

/*
 * Function: mmc_reset_card_and_send_op
 * Arg     : Host & Card structure
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Routine to initialize MMC card. It resets a card to idle state,
 *           verify operating voltage and set the card in ready state.
 */
static uint32_t mmc_reset_card_and_send_op(struct sdhci_host *host, struct mmc_card *card)
{
	uint32_t mmc_return = 0;

	/* 1. Card Reset - CMD0 */
	mmc_return = mmc_reset_card(host);
	if (mmc_return) {
		dprintf(CRITICAL, "Failure resetting MMC cards!\n");
		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_return = mmc_send_op_cond(host, card);

	/* OCR is not received, init could not complete */
	if (mmc_return) {
		dprintf(CRITICAL, "Failure getting OCR response from MMC Card\n");
		return mmc_return;
	}

	return 0;
}

static uint32_t mmc_send_app_cmd(struct sdhci_host *host, struct mmc_card *card)
{
	struct mmc_command cmd = {0};

	cmd.cmd_index = CMD55_APP_CMD;
	cmd.argument = (card->rca << 16);
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1;

	if (sdhci_send_command(host, &cmd))
	{
		dprintf(CRITICAL, "Failed Sending CMD55\n");
		return 1;
	}
	return 0;
}

uint32_t mmc_sd_card_init(struct sdhci_host *host, struct mmc_card *card)
{
	uint8_t i;
	struct mmc_command cmd;

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

	/* Use the SD card RCA 0x0 during init */
	card->rca = SD_CARD_RCA;

	/* Send CMD8 for voltage check*/
	for (i = 0 ;i < SD_CMD8_MAX_RETRY; i++)
	{
		cmd.cmd_index = CMD8_SEND_IF_COND;
		cmd.argument = MMC_SD_HC_VOLT_SUPPLIED;
		cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
		cmd.resp_type = SDHCI_CMD_RESP_R7;

		if (sdhci_send_command(host, &cmd))
		{
			dprintf(CRITICAL, "The response for CMD8 does not match the supplied value\n");
			return 1;
		}
		else
		{
			/* If the command response echos the voltage back */
			if (cmd.resp[0] == MMC_SD_HC_VOLT_SUPPLIED)
				break;
		}
		/* As per SDCC the spec try for max three times with
		 * 1 ms delay
		 */
		mdelay(1);
	}

	if (i == SD_CMD8_MAX_RETRY && (cmd.resp[0] != MMC_SD_HC_VOLT_SUPPLIED))
	{
		dprintf(CRITICAL, "Error: CMD8 response timed out\n");
		return 1;
	}

	/* Send ACMD41 for OCR */
	for (i = 0; i < SD_ACMD41_MAX_RETRY; i++)
	{
		/* Send APP_CMD before ACMD41*/
		if (mmc_send_app_cmd(host, card))
		{
			dprintf(CRITICAL, "Failed sending App command\n");
			return 1;
		}

		/* APP_CMD is successful, send ACMD41 now */
		cmd.cmd_index = ACMD41_SEND_OP_COND;
		cmd.argument = MMC_SD_OCR | MMC_SD_HC_HCS;
		cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
		cmd.resp_type = SDHCI_CMD_RESP_R3;

		if (sdhci_send_command(host, &cmd))
		{
			dprintf(CRITICAL, "Failure sending ACMD41\n");
			return 1;
		}
		else
		{
			if (cmd.resp[0] & MMC_SD_DEV_READY)
			{
				if (cmd.resp[0] & (1 << 30))
					card->type = MMC_CARD_TYPE_SDHC;
				else
					card->type = MMC_CARD_TYPE_STD_SD;

				break;
			}
		}
		/*
		 * As per SDCC spec try for max 1 second
		 */
		mdelay(50);
	}

	if (i == SD_ACMD41_MAX_RETRY && !(cmd.resp[0] & MMC_SD_DEV_READY))
	{
		dprintf(CRITICAL, "Error: ACMD41 response timed out\n");
		return 1;
	}

	return 0;
}

/*
 * Function to read SD card information from SD status
 */
static uint32_t mmc_sd_get_card_ssr(struct sdhci_host *host, struct mmc_card *card)
{
	BUF_DMA_ALIGN(raw_sd_status, 64);
	struct mmc_command cmd = {0};
	uint32_t sd_status[16];
	uint32_t *status = sd_status;
	uint32_t au_size;
	int i;
	int j;

	if (mmc_send_app_cmd(host, card))
	{
		dprintf(CRITICAL, "Failed sending App command\n");
		return 1;
	}

	cmd.cmd_index = ACMD13_SEND_SD_STATUS;
	cmd.argument = 0x0;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1;
	cmd.trans_mode = SDHCI_MMC_READ;
	cmd.data_present = 0x1;
	cmd.data.data_ptr = raw_sd_status;
	cmd.data.num_blocks = 0x1;
	cmd.data.blk_sz = 0x40;

	/* send command */
	if (sdhci_send_command(host, &cmd))
		return 1;

	memcpy(sd_status, raw_sd_status, sizeof(sd_status));

	for (i = 15, j = 0; i >=0 ; i--, j++)
		sd_status[i] = swap_endian32(sd_status[j]);

	au_size = UNPACK_BITS(status, MMC_SD_AU_SIZE_BIT, MMC_SD_AU_SIZE_LEN, 32);
	/* Card AU size in sectors */
	card->ssr.au_size = 1 << (au_size + 4);
	card->ssr.num_aus = UNPACK_BITS(status, MMC_SD_ERASE_SIZE_BIT, MMC_SD_ERASE_SIZE_LEN, 32);
	/*if num_aus is 0 then host should assign number of AU erased at a time*/
	if (!card->ssr.num_aus)
		card->ssr.num_aus = 0x10;
	return 0;
}

/*
 * Function to read the SD CARD configuration register
 */
static uint32_t mmc_sd_get_card_scr(struct sdhci_host *host, struct mmc_card *card)
{
	BUF_DMA_ALIGN(scr_resp, 8);
	struct mmc_command cmd = {0};
	uint32_t raw_scr[2];

	/* Now read the SCR register */
	/* Send APP_CMD before ACMD51*/
	if (mmc_send_app_cmd(host, card))
	{
		dprintf(CRITICAL, "Failed sending App command\n");
		return 1;
	}

	cmd.cmd_index = ACMD51_READ_CARD_SCR;
	cmd.argument = 0x0;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1;
	cmd.trans_mode = SDHCI_MMC_READ;
	cmd.data_present = 0x1;
	cmd.data.data_ptr = scr_resp;
	cmd.data.num_blocks = 0x1;
	cmd.data.blk_sz = 0x8;

	/* send command */
	if (sdhci_send_command(host, &cmd))
		return 1;

	memcpy(raw_scr, scr_resp, sizeof(raw_scr));

	card->raw_scr[0] = swap_endian32(raw_scr[0]);
	card->raw_scr[1] = swap_endian32(raw_scr[1]);

	/*
	 * Parse & Populate the SCR data as per sdcc spec
	 */
	card->scr.bus_widths = (card->raw_scr[0] & SD_SCR_BUS_WIDTH_MASK) >> SD_SCR_BUS_WIDTH;
	card->scr.cmd23_support = (card->raw_scr[0] & SD_SCR_CMD23_SUPPORT);
	card->scr.sd_spec = (card->raw_scr[0] & SD_SCR_SD_SPEC_MASK) >> SD_SCR_SD_SPEC;
	card->scr.sd3_spec = (card->raw_scr[0] & SD_SCR_SD_SPEC3_MASK) >> SD_SCR_SD_SPEC3;

	return 0;
}

/*
 * Function: mmc_set_sd_bus_width
 * Arg     : host, device structure & width
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Set the bus width for the card
 */
uint32_t mmc_sd_set_bus_width(struct sdhci_host *host, struct mmc_card *card, uint8_t width)
{
	struct mmc_command cmd = {0};

	/* Send APP_CMD before ACMD6*/
	if (mmc_send_app_cmd(host, card))
	{
		dprintf(CRITICAL, "Failed sending App command\n");
		return 1;
	}

	cmd.cmd_index = ACMD6_SET_BUS_WIDTH;
	cmd.argument = (width == DATA_BUS_WIDTH_4BIT) ? (1<<1) : 0;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1;

	/* send command */
	if (sdhci_send_command(host, &cmd))
		return 1;

	return 0;
}

uint32_t mmc_sd_set_hs(struct sdhci_host *host, struct mmc_card *card)
{
       struct mmc_command cmd = {0};
       BUF_DMA_ALIGN(switch_resp, 64);

       cmd.cmd_index = CMD6_SWITCH_FUNC;
       cmd.argument = MMC_SD_SWITCH_HS;
       cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
       cmd.resp_type = SDHCI_CMD_RESP_R1;
       cmd.trans_mode = SDHCI_MMC_READ;
       cmd.data_present = 0x1;
       cmd.data.data_ptr = switch_resp;
       cmd.data.num_blocks = 0x1;
       cmd.data.blk_sz = 0x40;

       /* send command */
       if (sdhci_send_command(host, &cmd))
             return 1;

	/* Set the SDR25 mode in controller*/
	sdhci_set_uhs_mode(host, SDHCI_SDR25_MODE);

	return 0;
}

/*
 * Function: mmc_init_card
 * Arg     : mmc device structure
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Performs initialization and identification of eMMC cards connected
 *           to the host.
 */

static uint32_t mmc_card_init(struct mmc_device *dev)
{
	uint32_t mmc_return = 0;
	uint8_t bus_width = 0;

	struct sdhci_host *host;
	struct mmc_card *card;
	struct mmc_config_data *cfg;

	host = &dev->host;
	card = &dev->card;
	cfg  = &dev->config;

	/* Initialize MMC card structure */
	card->status = MMC_STATUS_INACTIVE;

	/* TODO: Get the OCR params from target */
	card->ocr = MMC_OCR_27_36 | MMC_OCR_SEC_MODE;

	/* Initialize the internal MMC */
	mmc_return = mmc_reset_card_and_send_op(host, card);
	if (mmc_return)
	{
		dprintf(CRITICAL, "MMC card failed to respond, try for SD card\n");
		/* Reset the card & get the OCR */
		mmc_return = mmc_sd_card_init(host, card);
		if (mmc_return)
		{
			dprintf(CRITICAL, "Failed to initialize SD card\n");
			return mmc_return;
		}
	}

	/* Identify (CMD2, CMD3 & CMD9) and select the card (CMD7) */
	mmc_return = mmc_identify_card(host, card);
	if (mmc_return)
		return mmc_return;

	/* set interface speed */
	if (MMC_CARD_SD(card))
	{
		mmc_return = mmc_sd_set_hs(host, card);
		if (mmc_return)
		{
			dprintf(CRITICAL, "Failed to set HS for SD card\n");
			return mmc_return;
		}
	}
	else
	{
		mmc_return = mmc_set_hs_interface(host, card);
		if (mmc_return) {
			dprintf(CRITICAL, "Error adjusting interface speed!\n");
			return mmc_return;
		}
	}

	/* Now get the extended CSD for the card */
	if (MMC_CARD_MMC(card))
	{
			/* For MMC cards, also get the extended csd */
			mmc_return = mmc_get_ext_csd(host, card);

			if (mmc_return) {
				dprintf(CRITICAL, "Failure getting card's ExtCSD information!\n");
				return mmc_return;
			}
	}
	else
	{
		/*Read SCR for sd card */
		if (mmc_sd_get_card_scr(host, card))
		{
			dprintf(CRITICAL, "Failure getting card's SCR register\n");
			return 1;
		}
		/* Read SSR for the SD card */
		if (mmc_sd_get_card_ssr(host, card))
		{
			dprintf(CRITICAL, "Failed to get SSR from the card\n");
			return 1;
		}
	}

	/* Decode and save the CSD register */
	mmc_return = mmc_decode_and_save_csd(card);
	if (mmc_return) {
		dprintf(CRITICAL, "Failure decoding card's CSD information!\n");
		return mmc_return;
	}


	if (MMC_CARD_MMC(card))
	{
		/* Set the bus width based on host, target capbilities */
		if (cfg->bus_width == DATA_BUS_WIDTH_8BIT && host->caps.bus_width_8bit)
				bus_width = DATA_BUS_WIDTH_8BIT;
		/*
		 * Host contoller by default supports 4 bit & 1 bit mode.
		 * No need to check for host support here
		 */
		else if (cfg->bus_width == DATA_BUS_WIDTH_4BIT)
				bus_width = DATA_BUS_WIDTH_4BIT;
		else
				bus_width = DATA_BUS_WIDTH_1BIT;

		/* Set 4/8 bit SDR bus width in controller */
		mmc_return = sdhci_set_bus_width(host, bus_width);

		if (mmc_return) {
			dprintf(CRITICAL, "Failed to set bus width for host controller\n");
			return 1;
		}

		/* Enable high speed mode in the follwing order:
		 * 1. HS400 mode if supported by host & card
		 * 1. HS200 mode if supported by host & card
		 * 2. DDR mode host, if supported by host & card
		 * 3. Use normal speed mode with supported bus width
		 */
		if (host->caps.hs400_support && mmc_card_supports_hs400_mode(card))
		{
			dprintf(INFO, "SDHC Running in HS400 mode\n");
			mmc_return = mmc_set_hs400_mode(host, card, bus_width);
			if (mmc_return)
			{
				dprintf(CRITICAL, "Failure to set HS400 mode for Card(RCA:%x)\n",
								  card->rca);
				return mmc_return;
			}
		}
#if USE_TARGET_HS200_CAPS
		else if (host->caps.hs200_support && host->caps.sdr104_support && mmc_card_supports_hs200_mode(card))
#else
		else if (host->caps.sdr104_support && mmc_card_supports_hs200_mode(card))
#endif
		{
			dprintf(INFO, "SDHC Running in HS200 mode\n");
			mmc_return = mmc_set_hs200_mode(host, card, bus_width);

			if (mmc_return) {
				dprintf(CRITICAL, "Failure to set HS200 mode for Card(RCA:%x)\n",
								  card->rca);
				return mmc_return;
			}
		} else if (host->caps.ddr_support && mmc_card_supports_ddr_mode(card)) {
			dprintf(INFO, "SDHC Running in DDR mode\n");
			mmc_return = mmc_set_ddr_mode(host, card);

			if (mmc_return) {
				dprintf(CRITICAL, "Failure to set DDR mode for Card(RCA:%x)\n",
								  card->rca);
				return mmc_return;
			}
		} else {
			dprintf(INFO, "SDHC Running in High Speed mode\n");
			/* Set HS_TIMING mode */
			mmc_return = mmc_set_hs_interface(host, card);
			if (mmc_return) {
				dprintf(CRITICAL, "Failure to enalbe HS mode for Card(RCA:%x)\n",
								  card->rca);
				return mmc_return;
			}
			/* Set wide bus mode */
			mmc_return = mmc_set_bus_width(host, card, bus_width);
			if (mmc_return) {
				dprintf(CRITICAL, "Failure to set wide bus for Card(RCA:%x)\n",
								  card->rca);
				return mmc_return;
			}
		}
	}
	else
	{
		/* Check the supported bus width for the card from SCR register */
		if (card->scr.bus_widths & SD_SCR_WIDTH_4BIT)
			bus_width = DATA_BUS_WIDTH_4BIT;
		else
			bus_width = DATA_BUS_WIDTH_1BIT;

		mmc_return = mmc_sd_set_bus_width(host, card, bus_width);
		if (mmc_return)
		{
			dprintf(CRITICAL, "Failed to set bus width for the card\n");
			return mmc_return;
		}

		/* Set bit SDR bus width in controller */
		mmc_return = sdhci_set_bus_width(host, bus_width);
		if (mmc_return)
		{
			dprintf(CRITICAL, "Failed to set bus width for host controller\n");
			return mmc_return;
		}
	}


	card->block_size = MMC_BLK_SZ;

	if (MMC_CARD_MMC(card)) {
		/* Enable RST_n_FUNCTION */
		if (!card->ext_csd[MMC_EXT_CSD_RST_N_FUNC])
		{
			mmc_return = mmc_switch_cmd(host, card, MMC_SET_BIT, MMC_EXT_CSD_RST_N_FUNC, RST_N_FUNC_ENABLE);

			if (mmc_return)
			{
				dprintf(CRITICAL, "Failed to enable RST_n_FUNCTION\n");
				return mmc_return;
			}
		}

	}
	return mmc_return;
}

/*
 * Function: mmc display csd
 * Arg     : None
 * Return  : None
 * Flow    : Displays the csd information
 */
static void mmc_display_csd(struct mmc_card *card)
{
	dprintf(SPEW, "erase_grpsize: %d\n", card->csd.erase_grp_size);
	dprintf(SPEW, "erase_grpmult: %d\n", card->csd.erase_grp_mult);
	dprintf(SPEW, "wp_grpsize: %d\n", card->csd.wp_grp_size);
	dprintf(SPEW, "wp_grpen: %d\n", card->csd.wp_grp_enable);
	dprintf(SPEW, "perm_wp: %d\n", card->csd.perm_wp);
	dprintf(SPEW, "temp_wp: %d\n", card->csd.temp_wp);
}

/*
 * Function: mmc_init
 * Arg     : MMC configuration data
 * Return  : Pointer to mmc device
 * Flow    : Entry point to MMC boot process
 *           Initialize the sd host controller
 *           Initialize the mmc card
 *           Set the clock & high speed mode
 */
struct mmc_device *mmc_init(struct mmc_config_data *data)
{
	uint8_t mmc_ret = 0;
	struct mmc_device *dev;

	dev = (struct mmc_device *) malloc (sizeof(struct mmc_device));

	if (!dev) {
		dprintf(CRITICAL, "Error allocating mmc device\n");
		return NULL;
	}

	ASSERT(data);

	memcpy((void*)&dev->config, (void*)data, sizeof(struct mmc_config_data));

	memset((struct mmc_card *)&dev->card, 0, sizeof(struct mmc_card));

	/* Initialize the host & clock */
	dprintf(SPEW, " Initializing MMC host data structure and clock!\n");

	mmc_ret = mmc_host_init(dev);
	if (mmc_ret) {
		dprintf(CRITICAL, "Error Initializing MMC host : %u\n", mmc_ret);
		return NULL;
	}

	/* Initialize and identify cards connected to host */
	mmc_ret = mmc_card_init(dev);
	if (mmc_ret) {
		dprintf(CRITICAL, "Failed detecting MMC/SDC @ slot%d\n",
						  dev->config.slot);
		return NULL;
	}

	dprintf(INFO, "Done initialization of the card\n");

	mmc_display_csd(&dev->card);

	return dev;
}

static uint32_t mmc_parse_response(uint32_t resp)
{
	/* Trying to write beyond card capacity */
	if (resp & MMC_R1_ADDR_OUT_OF_RANGE) {
		dprintf(CRITICAL, "Attempting to read or write beyond the Device capacity\n");
		return 1;
	}

	/* Misaligned address not matching block length */
	if (resp & MMC_R1_ADDR_ERR) {
		dprintf(CRITICAL, "The misaligned address did not match the block length used\n");
		return 1;
	}

	/* Invalid block length */
	if (resp & MMC_R1_BLOCK_LEN_ERR) {
		dprintf(CRITICAL, "The transferred bytes does not match the block length\n");
		return 1;
	}

	/* Tried to program write protected block */
	if (resp & MMC_R1_WP_VIOLATION) {
		dprintf(CRITICAL, "Attempt to program a write protected block\n");
		return 1;
	}

	/* card controller error */
	if (resp & MMC_R1_CC_ERROR) {
		dprintf(CRITICAL, "Device error occurred, which is not related to the host command\n");
		return 1;
	}

	/* Generic error */
	if (resp & MMC_R1_GENERIC_ERR) {
		dprintf(CRITICAL, "A generic Device error\n");
		return 1;
	}

	/* Finally check for card in TRAN state */
	if (MMC_CARD_STATUS(resp) != MMC_TRAN_STATE) {
		dprintf(CRITICAL, "MMC card is not in TRAN state\n");
		return 1;
	}

	return 0;
}

static uint32_t mmc_stop_command(struct mmc_device *dev)
{
	struct mmc_command cmd;
	uint32_t mmc_ret = 0;

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

	cmd.cmd_index = CMD12_STOP_TRANSMISSION;
	cmd.argument = (dev->card.rca << 16);
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1;

	mmc_ret = sdhci_send_command(&dev->host, &cmd);
	if(mmc_ret)
	{
		dprintf(CRITICAL, "Failed to send stop command\n");
		return mmc_ret;
	}

	/* Response contains 32 bit Card status.
	 * Parse the errors & provide relevant information */

	return mmc_parse_response(cmd.resp[0]);
}

/*
 * Function: mmc sdhci read
 * Arg     : mmc device structure, block address, number of blocks & destination
 * Return  : 0 on Success, non zero on success
 * Flow    : Fill in the command structure & send the command
 */
uint32_t mmc_sdhci_read(struct mmc_device *dev, void *dest,
						uint64_t blk_addr, uint32_t num_blocks)
{
	uint32_t mmc_ret = 0;
	struct mmc_command cmd;
	struct mmc_card *card = &dev->card;

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

	/* CMD17/18 Format:
	 * [31:0] Data Address
	 */
	if (num_blocks == 1)
		cmd.cmd_index = CMD17_READ_SINGLE_BLOCK;
	else
		cmd.cmd_index = CMD18_READ_MULTIPLE_BLOCK;

	/*
	 * Standard emmc cards use byte mode addressing
	 * convert the block address to byte address before
	 * sending the command
	 */
	if (card->type == MMC_TYPE_STD_MMC)
		cmd.argument = blk_addr * card->block_size;
	else
		cmd.argument = blk_addr;

	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1;
	cmd.trans_mode = SDHCI_MMC_READ;
	cmd.data_present = 0x1;

	/* Use CMD23 If card supports CMD23:
	 * For SD card use the value read from SCR register
	 * For emmc by default use CMD23.
	 * Also as per SDCC spec always use CMD23 to stop
	 * multiblock read/write if UHS (Ultra High Speed) is
	 * enabled
	 */
	if (MMC_CARD_SD(card))
		cmd.cmd23_support = dev->card.scr.cmd23_support;
	else
		cmd.cmd23_support = 0x1;

	cmd.data.data_ptr = dest;
	cmd.data.num_blocks = num_blocks;

	/* send command */
	mmc_ret = sdhci_send_command(&dev->host, &cmd);

	/* For multi block read failures send stop command */
	if (mmc_ret && num_blocks > 1)
	{
		return mmc_stop_command(dev);
	}

	/*
	 * Response contains 32 bit Card status.
	 * Parse the errors & provide relevant information
	 */
	return mmc_parse_response(cmd.resp[0]);
}

/*
 * Function: mmc sdhci write
 * Arg     : mmc device structure, block address, number of blocks & source
 * Return  : 0 on Success, non zero on success
 * Flow    : Fill in the command structure & send the command
 */
uint32_t mmc_sdhci_write(struct mmc_device *dev, void *src,
						 uint64_t blk_addr, uint32_t num_blocks)
{
	uint32_t mmc_ret = 0;
	struct mmc_command cmd;
	struct mmc_card *card = &dev->card;

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

	/* CMD24/25 Format:
	 * [31:0] Data Address
	 */

	if (num_blocks == 1)
		cmd.cmd_index = CMD24_WRITE_SINGLE_BLOCK;
	else
		cmd.cmd_index = CMD25_WRITE_MULTIPLE_BLOCK;

	/*
	 * Standard emmc cards use byte mode addressing
	 * convert the block address to byte address before
	 * sending the command
	 */
	if (card->type == MMC_TYPE_STD_MMC)
		cmd.argument = blk_addr * card->block_size;
	else
		cmd.argument = blk_addr;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1;
	cmd.trans_mode = SDHCI_MMC_WRITE;

	/* Use CMD23 If card supports CMD23:
	 * For SD card use the value read from SCR register
	 * For emmc by default use CMD23.
	 * Also as per SDCC spec always use CMD23 to stop
	 * multiblock read/write if UHS (Ultra High Speed) is
	 * enabled
	 */
	if (MMC_CARD_SD(card))
		cmd.cmd23_support = dev->card.scr.cmd23_support;
	else
		cmd.cmd23_support = 0x1;

	cmd.data_present = 0x1;
	cmd.data.data_ptr = src;
	cmd.data.num_blocks = num_blocks;

	/* send command */
	mmc_ret = sdhci_send_command(&dev->host, &cmd);

	/* For multi block write failures send stop command */
	if (mmc_ret && num_blocks > 1)
	{
		return mmc_stop_command(dev);
	}

	/*
	 * Response contains 32 bit Card status.
	 * Parse the errors & provide relevant information
	 */
	return mmc_parse_response(cmd.resp[0]);
}

/*
 * Send the erase group start address using CMD35
 */
static uint32_t mmc_send_erase_grp_start(struct mmc_device *dev, uint32_t erase_start)
{
	struct mmc_command cmd;
	struct mmc_card *card = &dev->card;

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

	if (MMC_CARD_MMC(card))
		cmd.cmd_index = CMD35_ERASE_GROUP_START;
	else
		cmd.cmd_index = CMD32_ERASE_WR_BLK_START;

	/*
	 * Standard emmc cards use byte mode addressing
	 * convert the block address to byte address before
	 * sending the command
	 */
	if (card->type == MMC_TYPE_STD_MMC)
		cmd.argument = erase_start * card->block_size;
	else
		cmd.argument = erase_start;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1;

	/* send command */
	if (sdhci_send_command(&dev->host, &cmd))
		return 1;

	/*
	 * CMD35 on failure returns address out of range error
	 */
	if (MMC_ADDR_OUT_OF_RANGE(cmd.resp[0]))
	{
		dprintf(CRITICAL, "Address for CMD35 is out of range\n");
		return 1;
	}

	return 0;
}

/*
 * Send the erase group end address using CMD36
 */
static uint32_t mmc_send_erase_grp_end(struct mmc_device *dev, uint32_t erase_end)
{
	struct mmc_command cmd;
	struct mmc_card *card = &dev->card;

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

	if (MMC_CARD_MMC(card))
		cmd.cmd_index = CMD36_ERASE_GROUP_END;
	else
		cmd.cmd_index = CMD33_ERASE_WR_BLK_END;

	/*
	 * Standard emmc cards use byte mode addressing
	 * convert the block address to byte address before
	 * sending the command
	 */
	if (card->type == MMC_TYPE_STD_MMC)
		cmd.argument = erase_end * card->block_size;
	else
		cmd.argument = erase_end;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1;

	/* send command */
	if (sdhci_send_command(&dev->host, &cmd))
		return 1;

	/*
	 * CMD3 on failure returns address out of range error
	 */
	if (MMC_ADDR_OUT_OF_RANGE(cmd.resp[0]))
	{
		dprintf(CRITICAL, "Address for CMD36 is out of range\n");
		return 1;
	}

	return 0;
}

/*
 * Send the erase CMD38, to erase the selected erase groups
 */
static uint32_t mmc_send_erase(struct mmc_device *dev, uint64_t erase_timeout)
{
	struct mmc_command cmd;
	uint32_t status;
	uint32_t retry = 0;

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

	cmd.cmd_index = CMD38_ERASE;
	cmd.argument = 0x00000000;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1B;
	cmd.cmd_timeout = erase_timeout;

	/* send command */
	if (sdhci_send_command(&dev->host, &cmd))
		return 1;

	do
	{
		if (mmc_get_card_status(&dev->host, &dev->card, &status))
		{
			dprintf(CRITICAL, "Failed to get card status after erase\n");
			return 1;
		}
		/* Check if the response of erase command has eras skip status set */
		if (status & MMC_R1_WP_ERASE_SKIP)
			dprintf(CRITICAL, "Write Protect set for the region, only partial space was erased\n");

		retry++;
		udelay(1000);
		if (retry == MMC_MAX_CARD_STAT_RETRY)
		{
			dprintf(CRITICAL, "Card status check timed out after sending erase command\n");
			return 1;
		}
	} while(!(status & MMC_READY_FOR_DATA) || (MMC_CARD_STATUS(status) == MMC_PROG_STATE));


	return 0;
}


/*
 * Function: mmc sdhci erase
 * Arg     : mmc device structure, block address and length
 * Return  : 0 on Success, non zero on failure
 * Flow    : Fill in the command structure & send the command
 */
uint32_t mmc_sdhci_erase(struct mmc_device *dev, uint32_t blk_addr, uint64_t len)
{
	uint32_t erase_unit_sz = 0;
	uint32_t erase_start;
	uint32_t erase_end;
	uint32_t blk_end;
	uint32_t num_erase_grps;
	uint64_t erase_timeout = 0;
	struct mmc_card *card;


	card = &dev->card;

	/*
	 * Calculate the erase unit size,
	 * 1. Based on emmc 4.5 spec for emmc card
	 * 2. Use SD Card Status info for SD cards
	 */
	if (MMC_CARD_MMC(card))
	{
		/*
		 * Calculate the erase unit size as per the emmc specification v4.5
		 */
		if (dev->card.ext_csd[MMC_ERASE_GRP_DEF])
			erase_unit_sz = (MMC_HC_ERASE_MULT * dev->card.ext_csd[MMC_HC_ERASE_GRP_SIZE]) / MMC_BLK_SZ;
		else
			erase_unit_sz = (dev->card.csd.erase_grp_size + 1) * (dev->card.csd.erase_grp_mult + 1);
	}
	else
		erase_unit_sz = dev->card.ssr.au_size * dev->card.ssr.num_aus;


	/* Convert length in blocks */
	len = len / MMC_BLK_SZ;

	if (len < erase_unit_sz)
	{
		dprintf(CRITICAL, "Requested length is less than min erase group size\n");
		return 1;
	}

	/* Calculate erase groups based on the length in blocks */
	num_erase_grps = len / erase_unit_sz;

	/* Start address of the erase range */
	erase_start = blk_addr;

	/* Last address of the erase range */
	erase_end = blk_addr + ((num_erase_grps - 1) * erase_unit_sz);

	/* Boundary check for overlap */
	blk_end = blk_addr + len;

	if (erase_end > blk_end)
	{
		dprintf(CRITICAL, "The erase group overlaps the max requested for erase\n");
		erase_end -= erase_unit_sz;
	}

	/* Send CMD35 for erase group start */
	if (mmc_send_erase_grp_start(dev, erase_start))
	{
		dprintf(CRITICAL, "Failed to send erase grp start address\n");
		return 1;
	}

	/* Send CMD36 for erase group end */
	if (mmc_send_erase_grp_end(dev, erase_end))
	{
		dprintf(CRITICAL, "Failed to send erase grp end address\n");
		return 1;
	}

	/*
	 * As per emmc 4.5 spec section 7.4.27, calculate the erase timeout
	 * erase_timeout = 300ms * ERASE_TIMEOUT_MULT * num_erase_grps
	 */
	if (MMC_CARD_MMC(card))
		erase_timeout = (300 * 1000 * card->ext_csd[MMC_ERASE_TIMEOUT_MULT] * num_erase_grps);
	else
		erase_timeout = (300 * 1000 * num_erase_grps);

	/* Send CMD38 to perform erase */
	if (mmc_send_erase(dev, erase_timeout))
	{
		dprintf(CRITICAL, "Failed to erase the specified partition\n");
		return 1;
	}

	return 0;
}

/*
 * Function: mmc get wp status
 * Arg     : mmc device structure, block address and buffer for getting wp status
 * Return  : 0 on Success, 1 on Failure
 * Flow    : Get the WP group status by sending CMD31
 */
uint32_t mmc_get_wp_status(struct mmc_device *dev, uint32_t addr, uint8_t *wp_status)
{
	struct mmc_command cmd;

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

	cmd.cmd_index = CMD31_SEND_WRITE_PROT_TYPE;
	cmd.argument = addr;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1;
	cmd.trans_mode = SDHCI_MMC_READ;
	cmd.data_present = 0x1;
	cmd.data.data_ptr = wp_status;
	cmd.data.num_blocks = 0x1;
	cmd.data.blk_sz = 0x8;

	if (sdhci_send_command(&dev->host, &cmd))
	{
		dprintf(CRITICAL, "Failed to get status of write protect bits\n");
		return 1;
	}

	return 0;
}

/*
 * Function: mmc set/clear WP on user area
 * Arg     : mmc device structure, block address,len, & flag to set or clear
 * Return  : 0 on success, 1 on failure
 * Flow    : Function to set/clear power on write protect on user area
 */

uint32_t mmc_set_clr_power_on_wp_user(struct mmc_device *dev, uint32_t addr, uint64_t len, uint8_t set_clr)
{
	struct mmc_command cmd;
	struct mmc_card *card = &dev->card;
	uint32_t wp_grp_size;
	uint32_t status;
	uint32_t num_wp_grps;
	uint32_t ret;
	uint32_t retry = 0;
	uint32_t i;

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

	/* Convert len into blocks */
	len = len / MMC_BLK_SZ;
	wp_grp_size = dev->card.wp_grp_size;

	/* Disable PERM WP */
	ret = mmc_switch_cmd(&dev->host, &dev->card, MMC_SET_BIT, MMC_USR_WP, MMC_US_PERM_WP_DIS);

	if (ret)
	{
		dprintf(CRITICAL, "Failed to Disable PERM WP\n");
		return ret;
	}

	/* Read the default values for user WP */
	ret = mmc_get_ext_csd(&dev->host, &dev->card);

	if (ret)
	{
		dprintf(CRITICAL, "Failed to read ext csd for the card\n");
		return ret;
	}

	/* Check if user power on WP is disabled or perm WP is enabled */
	if ((dev->card.ext_csd[MMC_USR_WP] & MMC_US_PWR_WP_DIS)
		|| (dev->card.ext_csd[MMC_USR_WP] & MMC_US_PERM_WP_EN))
	{
		dprintf(CRITICAL, "Power on protection is disabled, cannot be set\n");
		return 1;
	}

	if (len < wp_grp_size)
	{
		dprintf(CRITICAL, "Length is less than min WP size, WP was not set\n");
		return 1;
	}

	/* Set power on USER WP */
	ret = mmc_switch_cmd(&dev->host, &dev->card, MMC_SET_BIT, MMC_USR_WP, MMC_US_PWR_WP_EN);

	if (ret)
	{
		dprintf(CRITICAL, "Failed to set power on WP for user\n");
		return ret;
	}

	num_wp_grps = ROUNDUP(len, wp_grp_size) / wp_grp_size;

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

	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1B;

	for(i = 0; i < num_wp_grps; i++)
	{
		/*
		* Standard emmc cards use byte mode addressing
		* convert the block address to byte address before
		* sending the command
		*/
		if (card->type == MMC_TYPE_STD_MMC)
			cmd.argument = (addr + (i * wp_grp_size)) * card->block_size;
		else
			cmd.argument = addr + (i * wp_grp_size);

		if (sdhci_send_command(&dev->host, &cmd))
			return 1;

		/* CMD28/CMD29 On failure returns address out of range error */
		if (MMC_ADDR_OUT_OF_RANGE(cmd.resp[0]))
		{
			dprintf(CRITICAL, "Address for CMD28/29 is out of range\n");
			return 1;
		}

		/* Check the card status */
		do
		{
			if (mmc_get_card_status(&dev->host, &dev->card, &status))
			{
				dprintf(CRITICAL, "Failed to get card status afterapplying write protect\n");
				return 1;
			}

		/* Time out for WP command */
		retry++;
		udelay(1000);
		if (retry == MMC_MAX_CARD_STAT_RETRY)
		{
			dprintf(CRITICAL, "Card status timed out after sending write protect command\n");
			return 1;
		}
		} while (!(status & MMC_READY_FOR_DATA) || (MMC_CARD_STATUS(status) == MMC_PROG_STATE));

	}

	return 0;
}

/* Function to put the mmc card to sleep */
void mmc_put_card_to_sleep(struct mmc_device *dev)
{
	struct mmc_command cmd = {0};
	struct mmc_card *card = &dev->card;

	cmd.cmd_index = CMD7_SELECT_DESELECT_CARD;
	cmd.argument = 0x00000000;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_NONE;

	/* send command */
	if(sdhci_send_command(&dev->host, &cmd))
	{
		dprintf(CRITICAL, "card deselect error: %s\n", __func__);
		return;
	}
	if(MMC_CARD_MMC(card)){
		/*CMD5 is reserved in SD card */
		cmd.cmd_index = CMD5_SLEEP_AWAKE;
		cmd.argument = (card->rca << MMC_CARD_RCA_BIT) | MMC_CARD_SLEEP;
		cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
		cmd.resp_type = SDHCI_CMD_RESP_R1B;

		/* send command */
		if(sdhci_send_command(&dev->host, &cmd))
			dprintf(CRITICAL, "card sleep error: %s\n", __func__);
	}
}

/*
 * Switch the partition access type to rpmb or default
 */
static uint32_t mmc_sdhci_switch_part(struct mmc_device *dev, uint32_t type)
{
	uint32_t part_access;
	uint32_t ret;

	/* Clear the partition access */
	part_access = dev->card.ext_csd[MMC_PARTITION_CONFIG] & ~PARTITION_ACCESS_MASK;
	part_access |= type;

	ret = mmc_switch_cmd(&dev->host, &dev->card, MMC_ACCESS_WRITE, MMC_PARTITION_CONFIG, part_access);

	if (ret)
	{
		dprintf(CRITICAL, "Failed to switch partition to type: %u\n", type);
		return 1;
	}

	dev->card.ext_csd[MMC_PARTITION_CONFIG] = part_access;
	return 0;
}

static uint32_t mmc_sdhci_set_blk_cnt(struct mmc_device *dev, uint32_t blk_cnt, uint32_t rel_write)
{
	struct mmc_command cmd = {0};

	cmd.cmd_index = CMD23_SET_BLOCK_COUNT;
	cmd.argument = blk_cnt & 0x0000ffff;
	cmd.argument |= rel_write;
	cmd.cmd_type = SDHCI_CMD_TYPE_NORMAL;
	cmd.resp_type = SDHCI_CMD_RESP_R1;

	if (sdhci_send_command(&dev->host, &cmd))
	{
		dprintf(CRITICAL, "Set block count failed: %s\n", __func__);
		return 1;
	}

	return 0;
}

uint32_t mmc_sdhci_rpmb_send(struct mmc_device *dev, struct mmc_command *cmd)
{
	int i;
	uint32_t retry = 5;
	uint32_t status;
	uint32_t rel_write = 0;
	uint32_t ret = 1;

	ASSERT(cmd);

	/* 1. Set the partition type to rpmb */
	if (mmc_sdhci_switch_part(dev, PART_ACCESS_RPMB))
		return 1;

	for (i = 0; i < MAX_RPMB_CMDS; i++)
	{
		if (!cmd[i].cmd_index)
			break;

		if (cmd[i].write_flag == true)
			rel_write = BIT(31);
		else
			rel_write = 0;

		/* 2. Set the block count using cmd23 */
		if (mmc_sdhci_set_blk_cnt(dev, cmd[i].data.num_blocks, rel_write))
			goto err;

		/* 3. Send the command */
		if (sdhci_send_command(&dev->host, &cmd[i]))
			goto err;
		do
		{
			/* 4. Poll for card status to ensure rpmb operation completeness */
			if (mmc_get_card_status(&dev->host, &dev->card, &status))
			{
				dprintf(CRITICAL, "Failed to get card status after rpmb operations\n");
				goto err;
			}

			retry--;
			udelay(500);
			if (!retry)
			{
				dprintf(CRITICAL, "Card status check timed out after rpmb operations\n");
				goto err;
			}
		} while(!(status & MMC_READY_FOR_DATA) || (MMC_CARD_STATUS(status) == MMC_PROG_STATE));
	}

	/* If we reach here, that means success */
	ret = 0;

err:
	/* 5. Switch the partition back to default type */
	if (mmc_sdhci_switch_part(dev, PART_ACCESS_DEFAULT))
		ret = 1;

	return ret;
}
