/* 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 <platform/iomap.h>
#include <platform/irqs.h>
#include <platform/interrupts.h>
#include <platform/timer.h>
#include <kernel/event.h>
#include <target.h>
#include <string.h>
#include <stdlib.h>
#include <bits.h>
#include <debug.h>
#include <sdhci.h>
#include <sdhci_msm.h>

static void sdhci_dumpregs(struct sdhci_host *host)
{
	DBG("****************** SDHC REG DUMP START ********************\n");

	DBG("Version:      0x%08x\n", REG_READ32(host, SDHCI_ARG2_REG));
	DBG("Arg2:         0x%08x\t Blk Cnt:      0x%08x\n",
							REG_READ32(host, SDHCI_ARG2_REG),
							REG_READ16(host, SDHCI_BLK_CNT_REG));
	DBG("Arg1:         0x%08x\t Blk Sz :      0x%08x\n",
							REG_READ32(host, SDHCI_ARGUMENT_REG),
							REG_READ16(host, SDHCI_BLKSZ_REG));
	DBG("Command:      0x%08x\t Trans mode:   0x%08x\n",
							REG_READ16(host, SDHCI_CMD_REG),
							REG_READ16(host, SDHCI_TRANS_MODE_REG));
	DBG("Resp0:        0x%08x\t Resp1:        0x%08x\n",
							REG_READ32(host, SDHCI_RESP_REG),
							REG_READ32(host, SDHCI_RESP_REG + 0x4));
	DBG("Resp2:        0x%08x\t Resp3:        0x%08x\n",
							REG_READ32(host, SDHCI_RESP_REG + 0x8),
							REG_READ32(host, SDHCI_RESP_REG + 0xC));
	DBG("Prsnt State:  0x%08x\t Host Ctrl1:   0x%08x\n",
							REG_READ32(host, SDHCI_PRESENT_STATE_REG),
							REG_READ8(host, SDHCI_HOST_CTRL1_REG));
	DBG("Timeout ctrl: 0x%08x\t Power Ctrl:   0x%08x\n",
							REG_READ8(host, SDHCI_TIMEOUT_REG),
							REG_READ8(host, SDHCI_PWR_CTRL_REG));
	DBG("Error stat:   0x%08x\t Int Status:   0x%08x\n",
							REG_READ32(host, SDHCI_ERR_INT_STS_REG),
							REG_READ32(host, SDHCI_NRML_INT_STS_REG));
	DBG("Host Ctrl2:   0x%08x\t Clock ctrl:   0x%08x\n",
							REG_READ32(host, SDHCI_HOST_CTRL2_REG),
							REG_READ32(host, SDHCI_CLK_CTRL_REG));
	DBG("Caps1:        0x%08x\t Caps2:        0x%08x\n",
							REG_READ32(host, SDHCI_CAPS_REG1),
							REG_READ32(host, SDHCI_CAPS_REG1));
	DBG("Adma Err:     0x%08x\t Auto Cmd err: 0x%08x\n",
							REG_READ8(host, SDHCI_ADM_ERR_REG),
							REG_READ16(host, SDHCI_AUTO_CMD_ERR));
	DBG("Adma addr1:   0x%08x\t Adma addr2:   0x%08x\n",
							REG_READ32(host, SDHCI_ADM_ADDR_REG),
							REG_READ32(host, SDHCI_ADM_ADDR_REG + 0x4));

	DBG("****************** SDHC REG DUMP END ********************\n");

	DBG("************* SDHC VENDOR REG DUMPS START ***************\n");
	DBG("SDCC_DLL_CONFIG_REG:       0x%08x\n", REG_READ32(host, SDCC_DLL_CONFIG_REG));
	DBG("SDCC_VENDOR_SPECIFIC_FUNC: 0x%08x\n", REG_READ32(host, SDCC_VENDOR_SPECIFIC_FUNC));
	DBG("SDCC_REG_DLL_STATUS:       0x%08x\n", REG_READ32(host, SDCC_REG_DLL_STATUS));
	DBG("************* SDHC VENDOR REG DUMPS END   ***************\n");
}

/*
 * Function: sdhci reset
 * Arg     : Host structure & mask to write to reset register
 * Return  : None
 * Flow:   : Reset the host controller
 */
void sdhci_reset(struct sdhci_host *host, uint8_t mask)
{
	uint32_t reg;
	uint32_t timeout = SDHCI_RESET_MAX_TIMEOUT;

	REG_WRITE8(host, mask, SDHCI_RESET_REG);

	/* Wait for the reset to complete */
	do {
		reg = REG_READ8(host, SDHCI_RESET_REG);
		reg &= mask;

		if (!reg)
			break;
		if (!timeout)
		{
			dprintf(CRITICAL, "Error: sdhci reset failed for: %x\n", mask);
			break;
		}

		timeout--;
		mdelay(1);

	} while(1);
}

/*
 * Function: sdhci error status enable
 * Arg     : Host structure
 * Return  : None
 * Flow:   : Enable command error status
 */
static void sdhci_error_status_enable(struct sdhci_host *host)
{
	/* Enable all interrupt status */
	REG_WRITE16(host, SDHCI_NRML_INT_STS_EN, SDHCI_NRML_INT_STS_EN_REG);
	REG_WRITE16(host, SDHCI_ERR_INT_STS_EN, SDHCI_ERR_INT_STS_EN_REG);
	/* Enable all interrupt signal */
	REG_WRITE16(host, SDHCI_NRML_INT_SIG_EN, SDHCI_NRML_INT_SIG_EN_REG);
	REG_WRITE16(host, SDHCI_ERR_INT_SIG_EN, SDHCI_ERR_INT_SIG_EN_REG);
}

/*
 * Function: sdhci clock supply
 * Arg     : Host structure
 * Return  : 0 on Success, 1 on Failure
 * Flow:   : 1. Calculate the clock divider
 *           2. Set the clock divider
 *           3. Check if clock stable
 *           4. Enable Clock
 */
uint32_t sdhci_clk_supply(struct sdhci_host *host, uint32_t clk)
{
	uint32_t div = 0;
	uint32_t freq = 0;
	uint16_t clk_val = 0;

	if (clk >= host->caps.base_clk_rate)
		goto clk_ctrl;

	/* As per the sd spec div should be a multiplier of 2 */
	for (div = 2; div < SDHCI_CLK_MAX_DIV; div += 2) {
		freq = host->caps.base_clk_rate / div;
		if (freq <= clk)
			break;
	}

	div >>= 1;

clk_ctrl:
	/* As per the sdhci spec 3.0, bits 6-7 of the clock
	 * control registers will be mapped to bit 8-9, to
	 * support a 10 bit divider value.
	 * This is needed when the divider value overflows
	 * the 8 bit range.
	 */
	clk_val = ((div & SDHCI_SDCLK_FREQ_MASK) << SDHCI_SDCLK_FREQ_SEL);
	clk_val |= ((div & SDHC_SDCLK_UP_BIT_MASK) >> SDHCI_SDCLK_FREQ_SEL)
				<< SDHCI_SDCLK_UP_BIT_SEL;

	clk_val |= SDHCI_INT_CLK_EN;
	REG_WRITE16(host, clk_val, SDHCI_CLK_CTRL_REG);

	/* Check for clock stable */
	while (!(REG_READ16(host, SDHCI_CLK_CTRL_REG) & SDHCI_CLK_STABLE));

	/* Now clock is stable, enable it */
	clk_val = REG_READ16(host, SDHCI_CLK_CTRL_REG);
	clk_val |= SDHCI_CLK_EN;
	REG_WRITE16(host, clk_val, SDHCI_CLK_CTRL_REG);

	host->cur_clk_rate = clk;

	DBG("\n %s: clock_rate: %d clock_div:0x%08x\n", __func__, clk, div);

	return 0;
}

/*
 * Function: sdhci stop sdcc clock
 * Arg     : Host structure
 * Return  : 0 on Success, 1 on Failure
 * Flow:   : 1. Stop the clock
 */
static uint32_t sdhci_stop_sdcc_clk(struct sdhci_host *host)
{
	uint32_t reg;

	reg = REG_READ32(host, SDHCI_PRESENT_STATE_REG);

	if (reg & (SDHCI_CMD_ACT | SDHCI_DAT_ACT)) {
		dprintf(CRITICAL, "Error: SDCC command & data line are active\n");
		return 1;
	}

	REG_WRITE16(host, SDHCI_CLK_DIS, SDHCI_CLK_CTRL_REG);

	return 0;
}

/*
 * Function: sdhci change frequency
 * Arg     : Host structure & clock value
 * Return  : 0 on Success, 1 on Failure
 * Flow:   : 1. Stop the clock
 *           2. Star the clock with new frequency
 */
static uint32_t sdhci_change_freq_clk(struct sdhci_host *host, uint32_t clk)
{
	if (sdhci_stop_sdcc_clk(host)) {
		dprintf(CRITICAL, "Error: Card is busy, cannot change frequency\n");
		return 1;
	}

	if (sdhci_clk_supply(host, clk)) {
		dprintf(CRITICAL, "Error: cannot change frequency\n");
		return 1;
	}

	return 0;
}

/*
 * Function: sdhci set bus power
 * Arg     : Host structure
 * Return  : None
 * Flow:   : 1. Set the voltage
 *           2. Set the sd power control register
 */
static void sdhci_set_bus_power_on(struct sdhci_host *host)
{
	uint8_t voltage;

	voltage = host->caps.voltage;

	voltage <<= SDHCI_BUS_VOL_SEL;
	REG_WRITE8(host, voltage, SDHCI_PWR_CTRL_REG);

	voltage |= SDHCI_BUS_PWR_EN;

	DBG("\n %s: voltage: 0x%02x\n", __func__, voltage);

	REG_WRITE8(host, voltage, SDHCI_PWR_CTRL_REG);

}


/*
 * Function: sdhci set SDR mode
 * Arg     : Host structure, UHS mode
 * Return  : None
 * Flow:   : 1. Disable the clock
 *           2. Enable UHS mode
 *           3. Enable the clock
 * Details : SDR50/SDR104 mode is nothing but HS200
 *			 mode SDCC spec refers to it as SDR mode
 *			 & emmc spec refers as HS200 mode.
 */
void sdhci_set_uhs_mode(struct sdhci_host *host, uint32_t mode)
{
	uint16_t clk;
	uint16_t ctrl = 0;
	uint32_t clk_val = 0;

	/* Disable the clock */
	clk = REG_READ16(host, SDHCI_CLK_CTRL_REG);
	clk &= ~SDHCI_CLK_EN;
	REG_WRITE16(host, clk, SDHCI_CLK_CTRL_REG);

	ctrl = REG_READ16(host, SDHCI_HOST_CTRL2_REG);

	ctrl &= ~SDHCI_UHS_MODE_MASK;

	/* Enable SDR50/SDR104/DDR50 mode */
	switch (mode)
	{
		case SDHCI_SDR104_MODE:
			ctrl |= SDHCI_SDR104_MODE_EN;
			clk_val = SDHCI_CLK_200MHZ;
			break;
		case SDHCI_SDR50_MODE:
			ctrl |= SDHCI_SDR50_MODE_EN;
			clk_val = SDHCI_CLK_100MHZ;
			break;
		case SDHCI_DDR50_MODE:
			ctrl |= SDHCI_DDR50_MODE_EN;
			clk_val = SDHCI_CLK_50MHZ;
			break;
		case SDHCI_SDR25_MODE:
			ctrl |= SDHCI_SDR25_MODE_EN;
			clk_val = SDHCI_CLK_50MHZ;
			break;
		case SDHCI_SDR12_MODE_EN:
			ctrl |= SDHCI_SDR12_MODE_EN;
			clk_val = SDHCI_CLK_25MHZ;
			break;
		default:
			dprintf(CRITICAL, "Error: Invalid UHS mode: %x\n", mode);
			ASSERT(0);
	};

	REG_WRITE16(host, ctrl, SDHCI_HOST_CTRL2_REG);

	/* Run the clock back */
	sdhci_clk_supply(host, clk_val);
}

/*
 * Function: sdhci set adma mode
 * Arg     : Host structure
 * Return  : None
 * Flow:   : Set adma mode
 */
static void sdhci_set_adma_mode(struct sdhci_host *host)
{
	/* Select 32 Bit ADMA2 type */
	REG_WRITE8(host, SDHCI_ADMA_32BIT, SDHCI_HOST_CTRL1_REG);
}

/*
 * Function: sdhci set bus width
 * Arg     : Host & width
 * Return  : 0 on Sucess, 1 on Failure
 * Flow:   : Set the bus width for controller
 */
uint8_t sdhci_set_bus_width(struct sdhci_host *host, uint16_t width)
{
	uint16_t reg = 0;

	reg = REG_READ8(host, SDHCI_HOST_CTRL1_REG);

	switch(width) {
		case DATA_BUS_WIDTH_8BIT:
			width = SDHCI_BUS_WITDH_8BIT;
			break;
		case DATA_BUS_WIDTH_4BIT:
			width = SDHCI_BUS_WITDH_4BIT;
			break;
		case DATA_BUS_WIDTH_1BIT:
			width = SDHCI_BUS_WITDH_1BIT;
			break;
		default:
			dprintf(CRITICAL, "Bus width is invalid: %u\n", width);
			return 1;
	}

	DBG("\n %s: bus width:0x%04x\n", __func__, width);

	REG_WRITE8(host, (reg | width), SDHCI_HOST_CTRL1_REG);

	return 0;
}

/*
 * Function: sdhci command err status
 * Arg     : Host structure
 * Return  : 0 on Sucess, 1 on Failure
 * Flow:   : Look for error status
 */
static uint8_t sdhci_cmd_err_status(struct sdhci_host *host)
{
	uint32_t err;

	err = REG_READ16(host, SDHCI_ERR_INT_STS_REG);

	if (err & SDHCI_CMD_TIMEOUT_MASK) {
		dprintf(CRITICAL, "Error: Command timeout error\n");
		return 1;
	} else if (err & SDHCI_CMD_CRC_MASK) {
		dprintf(CRITICAL, "Error: Command CRC error\n");
		return 1;
	} else if (err & SDHCI_CMD_END_BIT_MASK) {
		dprintf(CRITICAL, "Error: CMD end bit error\n");
		return 1;
	} else if (err & SDHCI_CMD_IDX_MASK) {
		dprintf(CRITICAL, "Error: Command Index error\n");
		return 1;
	} else if (err & SDHCI_DAT_TIMEOUT_MASK) {
		dprintf(CRITICAL, "Error: DATA time out error\n");
		return 1;
	} else if (err & SDHCI_DAT_CRC_MASK) {
		dprintf(CRITICAL, "Error: DATA CRC error\n");
		return 1;
	} else if (err & SDHCI_DAT_END_BIT_MASK) {
		dprintf(CRITICAL, "Error: DATA end bit error\n");
		return 1;
	} else if (err & SDHCI_CUR_LIM_MASK) {
		dprintf(CRITICAL, "Error: Current limit error\n");
		return 1;
	} else if (err & SDHCI_AUTO_CMD12_MASK) {
		dprintf(CRITICAL, "Error: Auto CMD12 error\n");
		return 1;
	} else if (err & SDHCI_ADMA_MASK) {
		dprintf(CRITICAL, "Error: ADMA error\n");
		return 1;
	}

	return 0;
}

/*
 * Function: sdhci command complete
 * Arg     : Host & command structure
 * Return  : 0 on Sucess, 1 on Failure
 * Flow:   : 1. Check for command complete
 *           2. Check for transfer complete
 *           3. Get the command response
 *           4. Check for errors
 */
static uint8_t sdhci_cmd_complete(struct sdhci_host *host, struct mmc_command *cmd)
{
	uint8_t i;
	uint8_t ret = 0;
	uint8_t need_reset = 0;
	uint32_t retry = 0;
	uint32_t int_status;
	uint32_t trans_complete = 0;
	uint32_t err_status;

	do {
		int_status = REG_READ16(host, SDHCI_NRML_INT_STS_REG);
		int_status &= SDHCI_INT_STS_CMD_COMPLETE;

		if (int_status == SDHCI_INT_STS_CMD_COMPLETE)
			break;

		/*
		 * If Tuning is in progress ignore cmd crc & cmd end bit errors
		 */
		if (host->tuning_in_progress)
		{
			err_status = REG_READ16(host, SDHCI_ERR_INT_STS_REG);
			if ((err_status & SDHCI_CMD_CRC_MASK) || (err_status & SDHCI_DAT_END_BIT_MASK))
			{
				sdhci_reset(host, (SOFT_RESET_CMD | SOFT_RESET_DATA));
				return 0;
			}
		}

		retry++;
		udelay(500);
		if (retry == SDHCI_MAX_CMD_RETRY) {
			dprintf(CRITICAL, "Error: Command never completed\n");
			ret = 1;
			goto err;
		}
	} while(1);

	/* Command is complete, clear the interrupt bit */
	REG_WRITE16(host, SDHCI_INT_STS_CMD_COMPLETE, SDHCI_NRML_INT_STS_REG);

	/* Copy the command response,
	 * The valid bits for R2 response are 0-119, & but the actual response
	 * is stored in bits 8-128. We need to move 8 bits of MSB of each
	 * response to register 8 bits of LSB of next response register.
	 * As:
	 * MSB 8 bits of RESP0 --> LSB 8 bits of RESP1
	 * MSB 8 bits of RESP1 --> LSB 8 bits of RESP2
	 * MSB 8 bits of RESP2 --> LSB 8 bits of RESP3
	 */
	if (cmd->resp_type == SDHCI_CMD_RESP_R2) {
		for (i = 0; i < 4; i++) {
			cmd->resp[i] = REG_READ32(host, SDHCI_RESP_REG + (i * 4));
			cmd->resp[i] <<= SDHCI_RESP_LSHIFT;

			if (i != 0)
				cmd->resp[i] |= (REG_READ32(host, SDHCI_RESP_REG + ((i-1) * 4)) >> SDHCI_RESP_RSHIFT);
		}
	} else
			cmd->resp[0] = REG_READ32(host, SDHCI_RESP_REG);

	retry = 0;

	/*
	 * Clear the transfer complete interrupt
	 */
	if (cmd->data_present || cmd->resp_type == SDHCI_CMD_RESP_R1B) {
		do {
			int_status = REG_READ16(host, SDHCI_NRML_INT_STS_REG);
			int_status &= SDHCI_INT_STS_TRANS_COMPLETE;

			if (int_status & SDHCI_INT_STS_TRANS_COMPLETE)
			{
				trans_complete = 1;
				break;
			}

			/*
			 * If we are in tuning then we need to wait until Data timeout , Data end
			 * or Data CRC error
			 */
			if (host->tuning_in_progress)
			{
				err_status = REG_READ16(host, SDHCI_ERR_INT_STS_REG);
				if ((err_status & SDHCI_DAT_TIMEOUT_MASK) || (err_status & SDHCI_DAT_CRC_MASK))
				{
					sdhci_reset(host, (SOFT_RESET_CMD | SOFT_RESET_DATA));
					return 0;
				}
			}

			retry++;
			udelay(1000);
			if (retry == SDHCI_MAX_TRANS_RETRY) {
				dprintf(CRITICAL, "Error: Transfer never completed\n");
				ret = 1;
				goto err;
			}
		} while(1);

		/* Transfer is complete, clear the interrupt bit */
		REG_WRITE16(host, SDHCI_INT_STS_TRANS_COMPLETE, SDHCI_NRML_INT_STS_REG);
	}

err:
	/* Look for errors */
	int_status = REG_READ16(host, SDHCI_NRML_INT_STS_REG);

	if (int_status & SDHCI_ERR_INT_STAT_MASK)
	{
		/*
		 * As per SDHC spec transfer complete has higher priority than data timeout
		 * If both transfer complete & data timeout are set then we should ignore
		 * data timeout error.
		 * ---------------------------------------------------------------------------
		 * | Transfer complete | Data timeout error | Meaning of the Status           |
		 * |--------------------------------------------------------------------------|
		 * |      0            |       0            | Interrupted by another factor   |
		 * |--------------------------------------------------------------------------|
		 * |      0            |       1            | Time out occured during transfer|
		 * |--------------------------------------------------------------------------|
		 * |      1            |  Don't Care        | Command execution complete      |
		 *  --------------------------------------------------------------------------
		 */
		if ((REG_READ16(host, SDHCI_ERR_INT_STS_REG) & SDHCI_DAT_TIMEOUT_MASK) && trans_complete)
		{
			ret = 0;
		}
		else if (sdhci_cmd_err_status(host))
		{
			ret = 1;
			/* Dump sdhc registers on error */
			sdhci_dumpregs(host);
		}
		/* Reset Command & Dat lines on error */
		need_reset = 1;
	}

	/* Reset data & command line */
	if (cmd->data_present || need_reset)
		sdhci_reset(host, (SOFT_RESET_CMD | SOFT_RESET_DATA));

	return ret;
}

/*
 * Function: sdhci prep desc table
 * Arg     : Pointer data & length
 * Return  : Pointer to desc table
 * Flow:   : Prepare the adma table as per the sd spec v 3.0
 */
static struct desc_entry *sdhci_prep_desc_table(void *data, uint32_t len)
{
	struct desc_entry *sg_list;
	uint32_t sg_len = 0;
	uint32_t remain = 0;
	uint32_t i;
	uint32_t table_len = 0;

	if (len <= SDHCI_ADMA_DESC_LINE_SZ) {
		/* Allocate only one descriptor */
		sg_list = (struct desc_entry *) memalign(lcm(4, CACHE_LINE), ROUNDUP(sizeof(struct desc_entry), CACHE_LINE));

		if (!sg_list) {
			dprintf(CRITICAL, "Error allocating memory\n");
			ASSERT(0);
		}

		sg_list[0].addr = (uint32_t)data;
		sg_list[0].len = (len < SDHCI_ADMA_DESC_LINE_SZ) ? len : (SDHCI_ADMA_DESC_LINE_SZ & 0xffff);
		sg_list[0].tran_att = SDHCI_ADMA_TRANS_VALID | SDHCI_ADMA_TRANS_DATA
							  | SDHCI_ADMA_TRANS_END;

		sg_len = 1;
		table_len = sizeof(struct desc_entry);
	} else {
		/* Calculate the number of entries in desc table */
		sg_len = len / SDHCI_ADMA_DESC_LINE_SZ;
		remain = len - (sg_len * SDHCI_ADMA_DESC_LINE_SZ);

		/* Allocate sg_len + 1 entries if there are remaining bytes at the end */
		if (remain)
			sg_len++;

		table_len = (sg_len * sizeof(struct desc_entry));

		sg_list = (struct desc_entry *) memalign(lcm(4, CACHE_LINE), ROUNDUP(table_len, CACHE_LINE));

		if (!sg_list) {
			dprintf(CRITICAL, "Error allocating memory\n");
			ASSERT(0);
		}

		memset((void *) sg_list, 0, table_len);

		/*
		 * Prepare sglist in the format:
		 *  ___________________________________________________
		 * |Transfer Len | Transfer ATTR | Data Address        |
		 * | (16 bit)    | (16 bit)      | (32 bit)            |
		 * |_____________|_______________|_____________________|
		 */
		for (i = 0; i < (sg_len - 1); i++) {
				sg_list[i].addr = (uint32_t)data;
				/*
				 * Length attribute is 16 bit value & max transfer size for one
				 * descriptor line is 65536 bytes, As per SD Spec3.0 'len = 0'
				 * implies 65536 bytes. Truncate the length to limit to 16 bit
				 * range.
				 */
				sg_list[i].len = (SDHCI_ADMA_DESC_LINE_SZ & 0xffff);
				sg_list[i].tran_att = SDHCI_ADMA_TRANS_VALID | SDHCI_ADMA_TRANS_DATA;
				data += SDHCI_ADMA_DESC_LINE_SZ;
				len -= SDHCI_ADMA_DESC_LINE_SZ;
			}

			/* Fill the last entry of the table with Valid & End
			 * attributes
			 */
			sg_list[sg_len - 1].addr = (uint32_t)data;
			sg_list[sg_len - 1].len = (len < SDHCI_ADMA_DESC_LINE_SZ) ? len : (SDHCI_ADMA_DESC_LINE_SZ & 0xffff);
			sg_list[sg_len - 1].tran_att = SDHCI_ADMA_TRANS_VALID | SDHCI_ADMA_TRANS_DATA |
										   SDHCI_ADMA_TRANS_END;
		}

	arch_clean_invalidate_cache_range((addr_t)sg_list, table_len);

	for (i = 0; i < sg_len; i++)
	{
		DBG("\n %s: sg_list: addr: 0x%08x len: 0x%04x attr: 0x%04x\n", __func__, sg_list[i].addr,
			(sg_list[i].len ? sg_list[i].len : SDHCI_ADMA_DESC_LINE_SZ), sg_list[i].tran_att);
	}

	return sg_list;
}

/*
 * Function: sdhci adma transfer
 * Arg     : Host structure & command stucture
 * Return  : Pointer to desc table
 * Flow    : 1. Prepare descriptor table
 *           2. Write adma register
 *           3. Write block size & block count register
 */
static struct desc_entry *sdhci_adma_transfer(struct sdhci_host *host,
											  struct mmc_command *cmd)
{
	uint32_t num_blks = 0;
	uint32_t sz;
	void *data;
	struct desc_entry *adma_addr;


	num_blks = cmd->data.num_blocks;
	data = cmd->data.data_ptr;

	/*
	 * Some commands send data on DAT lines which is less
	 * than SDHCI_MMC_BLK_SZ, in that case trying to read
	 * more than the data sent by the card results in data
	 * CRC errors. To avoid such errors allow data to pass
	 * the required block size, if the block size is not
	 * passed use the default value
	 */
	if (cmd->data.blk_sz)
		sz = num_blks * cmd->data.blk_sz;
	else
		sz = num_blks * SDHCI_MMC_BLK_SZ;

	/* Prepare adma descriptor table */
	adma_addr = sdhci_prep_desc_table(data, sz);

	/* Write adma address to adma register */
	REG_WRITE32(host, (uint32_t) adma_addr, SDHCI_ADM_ADDR_REG);

	/* Write the block size */
	if (cmd->data.blk_sz)
		REG_WRITE16(host, cmd->data.blk_sz, SDHCI_BLKSZ_REG);
	else
		REG_WRITE16(host, SDHCI_MMC_BLK_SZ, SDHCI_BLKSZ_REG);

	/*
	 * Set block count in block count register
	 */
	REG_WRITE16(host, num_blks, SDHCI_BLK_CNT_REG);

	return adma_addr;
}

/*
 * Function: sdhci send command
 * Arg     : Host structure & command stucture
 * Return  : 0 on Success, 1 on Failure
 * Flow:   : 1. Prepare the command register
 *           2. If data is present, prepare adma table
 *           3. Run the command
 *           4. Check for command results & take action
 */
uint32_t sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
{
	uint8_t retry = 0;
	uint32_t resp_type = 0;
	uint16_t trans_mode = 0;
	uint16_t present_state;
	uint32_t flags;
	struct desc_entry *sg_list = NULL;

	DBG("\n %s: START: cmd:0x%04d, arg:0x%08x, resp_type:0x%04x, data_present:%d\n",
				__func__, cmd->cmd_index, cmd->argument, cmd->resp_type, cmd->data_present);

	if (cmd->data_present)
		ASSERT(cmd->data.data_ptr);

	/*
	 * Assert if the data buffer is not aligned to cache
	 * line size for read operations.
	 * For write operations this function assumes that
	 * the cache is already flushed by the caller. As
	 * the data buffer we receive for write operation
	 * may not be aligned to cache boundary due to
	 * certain image formats like sparse image.
	 */
	if (cmd->trans_mode == SDHCI_READ_MODE)
		ASSERT(IS_CACHE_LINE_ALIGNED(cmd->data.data_ptr));

	do {
		present_state = REG_READ32(host, SDHCI_PRESENT_STATE_REG);
		/* check if CMD & DAT lines are free */
		present_state &= SDHCI_STATE_CMD_DAT_MASK;

		if (!present_state)
			break;
		udelay(1000);
		retry++;
		if (retry == 10) {
			dprintf(CRITICAL, "Error: CMD or DAT lines were never freed\n");
			return 1;
		}
	} while(1);

	switch(cmd->resp_type) {
		case SDHCI_CMD_RESP_R1:
		case SDHCI_CMD_RESP_R3:
		case SDHCI_CMD_RESP_R6:
		case SDHCI_CMD_RESP_R7:
			/* Response of length 48 have 32 bits
			 * of response data stored in RESP0[0:31]
			 */
			resp_type = SDHCI_CMD_RESP_48;
			break;

		case SDHCI_CMD_RESP_R2:
			/* Response of length 136 have 120 bits
			 * of response data stored in RESP0[0:119]
			 */
			resp_type = SDHCI_CMD_RESP_136;
			break;

		case SDHCI_CMD_RESP_R1B:
			/* Response of length 48 have 32 bits
			 * of response data stored in RESP0[0:31]
			 * & set CARD_BUSY status if card is busy
			 */
			resp_type = SDHCI_CMD_RESP_48_BUSY;
			break;

		case SDHCI_CMD_RESP_NONE:
			resp_type = SDHCI_CMD_RESP_NONE;
			break;

		default:
			dprintf(CRITICAL, "Invalid response type for the command\n");
			return 1;
	};

	flags =  (resp_type << SDHCI_CMD_RESP_TYPE_SEL_BIT);
	flags |= (cmd->data_present << SDHCI_CMD_DATA_PRESENT_BIT);
	flags |= (cmd->cmd_type << SDHCI_CMD_CMD_TYPE_BIT);

	/* Enable Command CRC & Index check for commands with response
	 * R1, R6, R7 & R1B. Also only CRC check for R2 response
	 */
	switch(cmd->resp_type) {
		case SDHCI_CMD_RESP_R1:
		case SDHCI_CMD_RESP_R6:
		case SDHCI_CMD_RESP_R7:
		case SDHCI_CMD_RESP_R1B:
			flags |= (1 << SDHCI_CMD_CRC_CHECK_BIT) | (1 << SDHCI_CMD_IDX_CHECK_BIT);
			break;
		case SDHCI_CMD_RESP_R2:
			flags |= (1 << SDHCI_CMD_CRC_CHECK_BIT);
			break;
		default:
			break;
	};

	/* Set the timeout value */
	REG_WRITE8(host, SDHCI_CMD_TIMEOUT, SDHCI_TIMEOUT_REG);

	/* Check if data needs to be processed */
	if (cmd->data_present)
		sg_list = sdhci_adma_transfer(host, cmd);

	/* Write the argument 1 */
	REG_WRITE32(host, cmd->argument, SDHCI_ARGUMENT_REG);

	/* Set the Transfer mode */
	if (cmd->data_present)
	{
		/* Enable DMA */
		trans_mode |= SDHCI_DMA_EN;

		if (cmd->trans_mode == SDHCI_MMC_READ)
		{
			trans_mode |= SDHCI_READ_MODE;
			sdhci_msm_toggle_cdr(host, true);
		}
		else
		{
			sdhci_msm_toggle_cdr(host, false);
		}

		/* Enable auto cmd23 or cmd12 for multi block transfer
		 * based on what command card supports
		 */
		if (cmd->data.num_blocks > 1) {
			if (cmd->cmd23_support) {
				trans_mode |= SDHCI_TRANS_MULTI | SDHCI_AUTO_CMD23_EN | SDHCI_BLK_CNT_EN;
				REG_WRITE32(host, cmd->data.num_blocks, SDHCI_ARG2_REG);
			}
			else
				trans_mode |= SDHCI_TRANS_MULTI | SDHCI_AUTO_CMD12_EN | SDHCI_BLK_CNT_EN;
		}
	}

	/* Write to transfer mode register */
	REG_WRITE16(host, trans_mode, SDHCI_TRANS_MODE_REG);

	/* Write the command register */
	REG_WRITE16(host, SDHCI_PREP_CMD(cmd->cmd_index, flags), SDHCI_CMD_REG);

	/* Command complete sequence */
	if (sdhci_cmd_complete(host, cmd))
		return 1;

	/* Invalidate the cache only for read operations */
	if (cmd->trans_mode == SDHCI_MMC_READ)
		arch_invalidate_cache_range((addr_t)cmd->data.data_ptr, (cmd->data.num_blocks * SDHCI_MMC_BLK_SZ));

	/* Free the scatter/gather list */
	if (sg_list)
		free(sg_list);

	DBG("\n %s: END: cmd:%04d, arg:0x%08x, resp:0x%08x 0x%08x 0x%08x 0x%08x\n",
				__func__, cmd->cmd_index, cmd->argument, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);

	return 0;
}

/*
 * Function: sdhci init
 * Arg     : Host structure
 * Return  : None
 * Flow:   : 1. Reset the controller
 *           2. Read the capabilities register & populate the host
 *           controller capabilities for use by other functions
 *           3. Enable the power control
 *           4. Set initial bus width
 *           5. Set Adma mode
 *           6. Enable the error status
 */
void sdhci_init(struct sdhci_host *host)
{
	uint32_t caps[2];

	/* Read the capabilities register & store the info */
	caps[0] = REG_READ32(host, SDHCI_CAPS_REG1);
	caps[1] = REG_READ32(host, SDHCI_CAPS_REG2);


	DBG("\n %s: Host capability: cap1:0x%08x, cap2: 0x%08x\n", __func__, caps[0], caps[1]);

	host->caps.base_clk_rate = (caps[0] & SDHCI_CLK_RATE_MASK) >> SDHCI_CLK_RATE_BIT;
	host->caps.base_clk_rate *= 1000000;

	/* Get the max block length for mmc */
	host->caps.max_blk_len = (caps[0] & SDHCI_BLK_LEN_MASK) >> SDHCI_BLK_LEN_BIT;

	/* 8 bit Bus width */
	if (caps[0] & SDHCI_8BIT_WIDTH_MASK)
		host->caps.bus_width_8bit = 1;

	/* Adma support */
	if (caps[0] & SDHCI_BLK_ADMA_MASK)
		host->caps.adma_support = 1;

	/* Supported voltage */
	if (caps[0] & SDHCI_3_3_VOL_MASK)
		host->caps.voltage = SDHCI_VOL_3_3;
	else if (caps[0] & SDHCI_3_0_VOL_MASK)
		host->caps.voltage = SDHCI_VOL_3_0;
	else if (caps[0] & SDHCI_1_8_VOL_MASK)
		host->caps.voltage = SDHCI_VOL_1_8;

	/* DDR mode support */
	host->caps.ddr_support = (caps[1] & SDHCI_DDR50_MODE_MASK) ? 1 : 0;

	/* SDR50 mode support */
	host->caps.sdr50_support = (caps[1] & SDHCI_SDR50_MODE_MASK) ? 1 : 0;

	/* SDR104 mode support */
	host->caps.sdr104_support = (caps[1] & SDHCI_SDR104_MODE_MASK) ? 1 : 0;

	/* Set bus power on */
	sdhci_set_bus_power_on(host);

	/* Wait for power interrupt to be handled */
	event_wait(host->sdhc_event);

	/* Set bus width */
	sdhci_set_bus_width(host, SDHCI_BUS_WITDH_1BIT);

	/* Set Adma mode */
	sdhci_set_adma_mode(host);

	/*
	 * Enable error status
	 */
	sdhci_error_status_enable(host);
}
