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

#include <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>


/*
 * 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) {
		dprintf(CRITICAL, "Error: Requested clk freq is more than supported\n");
		return 1;
	}

	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 = freq;

	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;

	REG_WRITE8(host, voltage, SDHCI_PWR_CTRL_REG);

}

/*
 * Function: sdhci set SDR mode
 * Arg     : Host structure
 * Return  : None
 * Flow:   : 1. Disable the clock
 *           2. Enable sdr 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_sdr_mode(struct sdhci_host *host)
{
	uint16_t clk;
	uint16_t ctrl = 0;

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

	/* Enable SDR50 mode:
	 * Right now we support only SDR50 mode which runs at
	 * 100 MHZ sdcc clock, we dont need tuning with SDR50
	 * mode
	 */
	ctrl = REG_READ16(host, SDHCI_HOST_CTRL2_REG);

	/* Enable SDR50/SDR104 mode based on the controller
	 * capabilities.
	 */
	if (host->caps.sdr50_support)
		ctrl |= SDHCI_SDR50_MODE_EN;

	REG_WRITE16(host, ctrl, SDHCI_HOST_CTRL2_REG);

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

/*
 * Function: sdhci set ddr mode
 * Arg     : Host structure
 * Return  : None
 * Flow:   : 1. Disable the clock
 *           2. Enable DDR mode
 *           3. Enable the clock
 */
void sdhci_set_ddr_mode(struct sdhci_host *host)
{
	uint16_t clk;
	uint16_t ctrl = 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_DDR_MODE_EN;

	/* Enalbe DDR mode */
	REG_WRITE16(host, ctrl, SDHCI_HOST_CTRL2_REG);

	/* Run the clock back */
	sdhci_clk_supply(host, host->cur_clk_rate);
}

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

	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;
	uint32_t retry = 0;
	uint32_t int_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;

		retry++;
		udelay(500);
		if (retry == SDHCI_MAX_CMD_RETRY) {
			dprintf(CRITICAL, "Error: Command never completed\n");
			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)
				break;

			retry++;
			udelay(1000);
			if (retry == SDHCI_MAX_TRANS_RETRY) {
				dprintf(CRITICAL, "Error: Transfer never completed\n");
				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) {
		if (sdhci_cmd_err_status(host)) {
			dprintf(CRITICAL, "Error: Command completed with errors\n");
			/* Reset the command & Data line */
			REG_WRITE8(host, (SOFT_RESET_CMD | SOFT_RESET_DATA), SDHCI_RESET_REG);
			return 1;
		}
	}

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

	return 0;
}

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

		arch_clean_invalidate_cache_range((addr_t)sg_list, 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);

	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;

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

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

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

	return 0;
}

/*
 * Function: sdhci reset
 * Arg     : Host structure
 * Return  : None
 * Flow:   : Reset the host controller
 */
static void sdhci_reset(struct sdhci_host *host)
{
	uint32_t reg;

	REG_WRITE8(host, SDHCI_SOFT_RESET, SDHCI_RESET_REG);

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

		if (!reg)
			break;
	} while(1);
}

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

	/*
	 * Reset the controller
	 */
	sdhci_reset(host);

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

	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_DDR_MODE_MASK) ? 1 : 0;

	/* SDR50 mode support */
	host->caps.sdr50_support = (caps[1] & SDHCI_SDR50_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);
}
