/* Copyright (c) 2013-2014, 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>

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));

	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, "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));

	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\n");
		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;
}

/*
 * 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 (card->ext_csd[MMC_DEVICE_TYPE] & MMC_HS_HS400_MODE)
		return 1;
	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 (card->ext_csd[MMC_DEVICE_TYPE] & MMC_HS_HS200_MODE)
		return 1;
	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 (card->ext_csd[MMC_DEVICE_TYPE] & MMC_HS_DDR_MODE)
		return 1;
	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);
	}
	else
	{
		/* Save the timing value, before changing the clock */
		MMC_SAVE_TIMING(host, MMC_HS200_TIMING);
	}

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

	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);

	/* 7. Execute Tuning for hs400 mode */
	if ((mmc_ret = sdhci_msm_execute_tuning(host, 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.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;

	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;
	uint32_t raw_csd[4];

	/* 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;
	uint32_t mmc_ret;
	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_R2;
	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);

	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;
	uint32_t status;
	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))
		{
			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;
			}
		}
		else if (host->caps.sdr104_support && mmc_card_supports_hs200_mode(card))
		{
			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)) {
			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 {
			/* Set 4/8 bit bus width for the card */
			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;
		}
	}


	/* Verify TRAN state after changing speed and bus width */
	mmc_return = mmc_get_card_status(host, card, &status);
	if (mmc_return)
		return mmc_return;

	if (MMC_CARD_STATUS(status) != MMC_TRAN_STATE)
		mmc_return = 1;

	card->block_size = MMC_BLK_SZ;

	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;
}

/*
 * 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);
	if (mmc_ret) {
		return mmc_ret;
	}

	/* Response contains 32 bit Card status. Here we'll check
		BLOCK_LEN_ERROR and ADDRESS_ERROR */
	if (cmd.resp[0] & MMC_R1_BLOCK_LEN_ERR) {
		dprintf(CRITICAL, "The transferred bytes does not match the block length\n");
		return 1;
	}

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

	if (MMC_CARD_STATUS(cmd.resp[0]) != MMC_TRAN_STATE) {
		dprintf(CRITICAL, "MMC read failed, card is not in TRAN state\n");
		return 1;
	}

	return mmc_ret;
}

/*
 * 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);
	if (mmc_ret)
		return mmc_ret;

	/* Response contains 32 bit Card status. Here we'll check
		BLOCK_LEN_ERROR and ADDRESS_ERROR */
	if (cmd.resp[0] & MMC_R1_BLOCK_LEN_ERR) {
		dprintf(CRITICAL, "The transferred bytes does not match the block length\n");
		return 1;
	}

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

	if (MMC_CARD_STATUS(cmd.resp[0]) != MMC_TRAN_STATE) {
		dprintf(CRITICAL, "MMC read failed, card is not in TRAN state\n");
		return 1;
	}

	return mmc_ret;
}

/*
 * 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)
{
	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;

	/* 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;
	uint32_t *out;
	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;
	}

	/* Send CMD38 to perform erase */
	if (mmc_send_erase(dev))
	{
		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;
	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;

	/* 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;
	}

	/* Calculate the wp grp size */
	if (dev->card.ext_csd[MMC_ERASE_GRP_DEF])
		wp_grp_size = MMC_HC_ERASE_MULT * dev->card.ext_csd[MMC_HC_ERASE_GRP_SIZE] / MMC_BLK_SZ;
	else
		wp_grp_size = (dev->card.csd.wp_grp_size + 1) * (dev->card.csd.erase_grp_size + 1) \
					  * (dev->card.csd.erase_grp_mult + 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++)
	{
		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;
	}

	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__);
}
