/*
 * Copyright (c) 2016 - 2020, Broadcom
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <arch_helpers.h>
#include <lib/mmio.h>

#include "bcm_emmc.h"
#include "emmc_chal_types.h"
#include "emmc_csl_sdprot.h"
#include "emmc_chal_sd.h"
#include "emmc_csl_sdcmd.h"
#include "emmc_csl_sd.h"
#include "emmc_pboot_hal_memory_drv.h"

#define SD_CARD_BUSY                    0x80000000
#define SD_CARD_RETRY_LIMIT             1000
#define SD_CARD_HIGH_SPEED_PS           13
#define SD_CHK_HIGH_SPEED_MODE          0x00FFFFF1
#define SD_SET_HIGH_SPEED_MODE          0x80FFFFF1
#define SD_MMC_ENABLE_HIGH_SPEED        0x03b90100	//0x03b90103
#define SD_MMC_8BIT_MODE                0x03b70200
#define SD_MMC_4BIT_MODE                0x03b70100
#define SD_MMC_1BIT_MODE                0x03b70000

#define SD_MMC_BOOT_8BIT_MODE           0x03b10200
#define SD_MMC_BOOT_4BIT_MODE           0x03b10100
#define SD_MMC_BOOT_1BIT_MODE           0x03b10000
#define SDIO_HW_EMMC_EXT_CSD_BOOT_CNF   0X03B30000

#ifdef USE_EMMC_FIP_TOC_CACHE
/*
 * Cache size mirrors the size of the global eMMC temp buffer
 * which is used for non-image body reads such as headers, ToC etc.
 */
#define CACHE_SIZE           ((EMMC_BLOCK_SIZE) * 2)
#define PARTITION_BLOCK_ADDR ((PLAT_FIP_ATTEMPT_OFFSET)/(EMMC_BLOCK_SIZE))

static uint32_t cached_partition_block;
static uint8_t cached_block[CACHE_SIZE];
#endif

static int set_card_data_width(struct sd_handle *handle, int width);
static int abort_err(struct sd_handle *handle);
static int err_recovery(struct sd_handle *handle, uint32_t errors);
static int xfer_data(struct sd_handle *handle, uint32_t mode, uint32_t addr,
		     uint32_t length, uint8_t *base);

int set_boot_config(struct sd_handle *handle, uint32_t config)
{
	return mmc_cmd6(handle, SDIO_HW_EMMC_EXT_CSD_BOOT_CNF | config);
}

void process_csd_mmc_speed(struct sd_handle *handle, uint32_t csd_mmc_speed)
{
	uint32_t div_ctrl_setting;

	/* CSD field TRAN_SPEED:
	 * Bits [2:0] 0 = 100 KHz
	 *            1 = 1 MHz
	 *            2 = 10 MHz
	 *            3 = 100 MHz
	 *            4...7 Reserved.
	 * Bits [6:3] 0 = Reserved
	 *            1 = 1.0
	 *            2 = 1.2
	 *            3 = 1.3
	 *            4 = 1.5
	 *            5 = 2.0
	 *            6 = 2.6
	 *            7 = 3.0
	 *            8 = 3.5
	 *            9 = 4.0
	 *            A = 4.5
	 *            B = 5.2
	 *            C = 5.5
	 *            D = 6.0
	 *            E = 7.0
	 *            F = 8.0
	 * For cards supporting version 4.0, 4.1, and 4.2 of the standard,
	 * the value shall be 20 MHz (0x2A).
	 * For cards supporting version 4.3 , the value shall be 26 MHz (0x32)
	 */

	switch (csd_mmc_speed & 0x7F) {
	case 0x2A:
		EMMC_TRACE("Speeding up eMMC clock to 20MHz\n");
		div_ctrl_setting =
		    chal_sd_freq_2_div_ctrl_setting(20 * 1000 * 1000);
		break;
	case 0x32:
		EMMC_TRACE("Speeding up eMMC clock to 26MHz\n");
		div_ctrl_setting =
		    chal_sd_freq_2_div_ctrl_setting(26 * 1000 * 1000);
		break;
	default:
		/* Unknown */
		return;
	}

	chal_sd_set_clock((CHAL_HANDLE *) handle->device, div_ctrl_setting, 0);

	chal_sd_set_clock((CHAL_HANDLE *) handle->device, div_ctrl_setting, 1);

	SD_US_DELAY(1000);
}


/*
 * The function changes SD/SDIO/MMC card data width if
 * the card support configurable data width. The host controller
 * and the card has to be in the same bus data width.
 */
int set_card_data_width(struct sd_handle *handle, int width)
{
	uint32_t data_width = 0;
	int is_valid_arg = 1;
	int rc = SD_FAIL;
	char *bitwidth_str = " ";
	char *result_str = "failed";

	switch (width) {
#ifdef DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT
	case SD_BUS_DATA_WIDTH_8BIT:
		data_width = SD_MMC_8BIT_MODE;
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
		bitwidth_str = "8_BIT";
#endif
		break;
#endif
	case SD_BUS_DATA_WIDTH_4BIT:
		data_width = SD_MMC_4BIT_MODE;
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
		bitwidth_str = "4_BIT";
#endif
		break;

	case SD_BUS_DATA_WIDTH_1BIT:
		data_width = SD_MMC_1BIT_MODE;
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
		bitwidth_str = "1_BIT";
#endif
		break;

	default:
		is_valid_arg = 0;
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
		bitwidth_str = "unknown";
#endif
		break;
	}

	if (is_valid_arg) {
		rc = mmc_cmd6(handle, data_width);
		if (rc == SD_OK) {
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
			result_str = "succeeded";
#endif
			chal_sd_config_bus_width((CHAL_HANDLE *) handle->device,
						 width);
		} else {
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
			result_str = "failed";
#endif
		}
	} else {
		rc = SD_FAIL;
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
		result_str = "ignored";
#endif
	}

	VERBOSE("SDIO Data Width(%s) %s.\n", bitwidth_str, result_str);

	return rc;
}


/*
 * Error handling routine. Does abort data
 * transmission if error is found.
 */
static int abort_err(struct sd_handle *handle)
{
	uint32_t present, options, event, rel = 0;
	struct sd_resp cmdRsp;

	handle->device->ctrl.argReg = 0;
	handle->device->ctrl.cmdIndex = SD_CMD_STOP_TRANSMISSION;

	options = (SD_CMD_STOP_TRANSMISSION << 24) |
		  (SD_CMDR_RSP_TYPE_R1b_5b << SD_CMDR_RSP_TYPE_S) |
		  SD4_EMMC_TOP_CMD_CRC_EN_MASK |
		  SD4_EMMC_TOP_CMD_CCHK_EN_MASK;

	chal_sd_send_cmd((CHAL_HANDLE *) handle->device,
			 handle->device->ctrl.cmdIndex,
			 handle->device->ctrl.argReg, options);

	event = wait_for_event(handle,
			       SD4_EMMC_TOP_INTR_CMDDONE_MASK |
			       SD_ERR_INTERRUPTS,
			       handle->device->cfg.wfe_retry);

	if (event & SD_CMD_ERROR_INT) {
		rel = SD_ERROR_NON_RECOVERABLE;
	} else {
		if (event & SD_DAT_TIMEOUT) {
			return SD_ERROR_NON_RECOVERABLE;
		}

		chal_sd_get_response((CHAL_HANDLE *) handle->device,
				     (uint32_t *)&cmdRsp);

		process_cmd_response(handle, handle->device->ctrl.cmdIndex,
				     cmdRsp.data.r2.rsp1, cmdRsp.data.r2.rsp2,
				     cmdRsp.data.r2.rsp3, cmdRsp.data.r2.rsp4,
				     &cmdRsp);

		SD_US_DELAY(2000);

		present =
		    chal_sd_get_present_status((CHAL_HANDLE *) handle->device);

		if ((present & 0x00F00000) == 0x00F00000)
			rel = SD_ERROR_RECOVERABLE;
		else
			rel = SD_ERROR_NON_RECOVERABLE;
	}

	return rel;
}


/*
 * The function handles real data transmission on both DMA and
 * none DMA mode, In None DMA mode the data transfer starts
 * when the command is sent to the card, data has to be written
 * into the host contollers buffer at this time one block
 * at a time.
 * In DMA mode, the real data transfer is done by the DMA engine
 * and this functions just waits for the data transfer to complete.
 *
 */
int process_data_xfer(struct sd_handle *handle, uint8_t *buffer, uint32_t addr,
		      uint32_t length, int dir)
{
	if (dir == SD_XFER_HOST_TO_CARD) {
#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
		if (handle->device->cfg.dma == SD_DMA_OFF) {
			/*
			 * In NON DMA mode, the real data xfer starts from here
			 */
			if (write_buffer(handle, length, buffer))
				return SD_WRITE_ERROR;
		} else {
			wait_for_event(handle,
				       SD4_EMMC_TOP_INTR_TXDONE_MASK |
				       SD_ERR_INTERRUPTS,
				       handle->device->cfg.wfe_retry);

			if (handle->device->ctrl.cmdStatus == SD_OK)
				return SD_OK;

			check_error(handle, handle->device->ctrl.cmdStatus);
			return SD_WRITE_ERROR;
		}
#else
		return SD_WRITE_ERROR;
#endif
	} else {		/* SD_XFER_CARD_TO_HOST */

		if (handle->device->cfg.dma == SD_DMA_OFF) {
			/* In NON DMA mode, the real data
			 * transfer starts from here
			 */
			if (read_buffer(handle, length, buffer))
				return SD_READ_ERROR;

		} else {	/* for DMA mode */

			/*
			 * once the data transmission is done
			 * copy data to the host buffer.
			 */
			wait_for_event(handle,
				       SD4_EMMC_TOP_INTR_TXDONE_MASK |
				       SD_ERR_INTERRUPTS,
				       handle->device->cfg.wfe_retry);

			if (handle->device->ctrl.cmdStatus == SD_OK)
				return SD_OK;

			check_error(handle, handle->device->ctrl.cmdStatus);
			return SD_READ_ERROR;
		}
	}
	return SD_OK;
}


/*
 * The function sets block size for the next SD/SDIO/MMC
 * card read/write command.
 */
int select_blk_sz(struct sd_handle *handle, uint16_t size)
{
	return sd_cmd16(handle, size);
}


/*
 * The function initalizes the SD/SDIO/MMC/CEATA and detects
 * the card according to the flag of detection.
 * Once this function is called, the card is put into ready state
 * so application can do data transfer to and from the card.
 */
int init_card(struct sd_handle *handle, int detection)
{
	/*
	 * After Reset, eMMC comes up in 1 Bit Data Width by default.
	 * Set host side to match.
	 */
	chal_sd_config_bus_width((CHAL_HANDLE *) handle->device,
				 SD_BUS_DATA_WIDTH_1BIT);

#ifdef USE_EMMC_FIP_TOC_CACHE
	cached_partition_block = 0;
#endif
	handle->device->ctrl.present = 0; /* init card present to be no card */

	init_mmc_card(handle);

	handle->device->ctrl.present = 1; /* card is detected */

	/* switch the data width back */
	if (handle->card->type != SD_CARD_MMC)
		return SD_FAIL;

	/*
	 * Dynamically set Data Width to highest supported value.
	 * Try different data width settings (highest to lowest).
	 * Verify each setting by reading EXT_CSD and comparing
	 * against the EXT_CSD contents previously read in call to
	 * init_mmc_card() earlier. Stop at first verified data width
	 * setting.
	 */
	{
#define EXT_CSD_PROPERTIES_SECTION_START_INDEX	192
#define EXT_CSD_PROPERTIES_SECTION_END_INDEX	511
		uint8_t buffer[EXT_CSD_SIZE];
#ifdef DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT
		/* Try 8 Bit Data Width */
		chal_sd_config_bus_width((CHAL_HANDLE *) handle->device,
					 SD_BUS_DATA_WIDTH_8BIT);
		if ((!set_card_data_width(handle, SD_BUS_DATA_WIDTH_8BIT)) &&
		    (!mmc_cmd8(handle, buffer)) &&
		    (!memcmp(&buffer[EXT_CSD_PROPERTIES_SECTION_START_INDEX],
			     &(emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_PROPERTIES_SECTION_START_INDEX]),
			     EXT_CSD_PROPERTIES_SECTION_END_INDEX - EXT_CSD_PROPERTIES_SECTION_START_INDEX + 1)))

			return SD_OK;
#endif
		/* Fall back to 4 Bit Data Width */
		chal_sd_config_bus_width((CHAL_HANDLE *) handle->device,
					 SD_BUS_DATA_WIDTH_4BIT);
		if ((!set_card_data_width(handle, SD_BUS_DATA_WIDTH_4BIT)) &&
		    (!mmc_cmd8(handle, buffer)) &&
		    (!memcmp(&buffer[EXT_CSD_PROPERTIES_SECTION_START_INDEX],
			     &(emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_PROPERTIES_SECTION_START_INDEX]),
			     EXT_CSD_PROPERTIES_SECTION_END_INDEX - EXT_CSD_PROPERTIES_SECTION_START_INDEX + 1)))

			return SD_OK;

		/* Fall back to 1 Bit Data Width */
		chal_sd_config_bus_width((CHAL_HANDLE *) handle->device,
					 SD_BUS_DATA_WIDTH_1BIT);
		/* Just use 1 Bit Data Width then. */
		if (!set_card_data_width(handle, SD_BUS_DATA_WIDTH_1BIT))
			return SD_OK;

	}
	return SD_CARD_INIT_ERROR;
}


/*
 * The function handles MMC/CEATA card initalization.
 */
int init_mmc_card(struct sd_handle *handle)
{
	uint32_t ocr = 0, newOcr, rc, limit = 0;
	uint32_t cmd1_option = 0x40300000;
	uint32_t sec_count;

	handle->card->type = SD_CARD_MMC;

	do {
		SD_US_DELAY(1000);
		newOcr = 0;
		ocr = 0;
		rc = sd_cmd1(handle, cmd1_option, &newOcr);
		limit++;

		if (rc == SD_OK)
			ocr = newOcr;

	} while (((ocr & SD_CARD_BUSY) == 0) && (limit < SD_CARD_RETRY_LIMIT));

	if (limit >= SD_CARD_RETRY_LIMIT) {
		handle->card->type = SD_CARD_UNKNOWN;
		EMMC_TRACE("CMD1 Timeout: Device is not ready\n");
		return SD_CARD_UNKNOWN;
	}

	/* Save the ocr register */
	handle->device->ctrl.ocr = ocr;

	/* Ready State */
	rc = sd_cmd2(handle);
	if (rc != SD_OK) {
		handle->card->type = SD_CARD_UNKNOWN;
		return SD_CARD_UNKNOWN;
	}

	rc = sd_cmd3(handle);
	if (rc != SD_OK) {
		handle->card->type = SD_CARD_UNKNOWN;
		return SD_CARD_UNKNOWN;
	}
	/* read CSD */
	rc = sd_cmd9(handle, &emmc_global_vars_ptr->cardData);
	if (rc != SD_OK) {
		handle->card->type = SD_CARD_UNKNOWN;
		return SD_CARD_UNKNOWN;
	}

	/* Increase clock frequency according to what the card advertises */
	EMMC_TRACE("From CSD...  cardData.csd.mmc.speed = 0x%X\n",
		   emmc_global_vars_ptr->cardData.csd.mmc.speed);
	process_csd_mmc_speed(handle,
			      emmc_global_vars_ptr->cardData.csd.mmc.speed);

	/* goto transfer mode */
	rc = sd_cmd7(handle, handle->device->ctrl.rca);
	if (rc != SD_OK) {
		handle->card->type = SD_CARD_UNKNOWN;
		return SD_CARD_UNKNOWN;
	}

	rc = mmc_cmd8(handle, emmc_global_buf_ptr->u.Ext_CSD_storage);
	if (rc == SD_OK) {
		/* calcul real capacity */
		sec_count = emmc_global_buf_ptr->u.Ext_CSD_storage[212] |
			    emmc_global_buf_ptr->u.Ext_CSD_storage[213] << 8 |
			    emmc_global_buf_ptr->u.Ext_CSD_storage[214] << 16 |
			    emmc_global_buf_ptr->u.Ext_CSD_storage[215] << 24;

		EMMC_TRACE("Device density = %ldMBytes\n",
			   handle->card->size / (1024 * 1024));

		if (sec_count > 0) {
			handle->card->size = (uint64_t)sec_count * 512;

			EMMC_TRACE("Updated Device density = %ldMBytes\n",
				   handle->card->size / (1024 * 1024));
		}

		if (sec_count > (2u * 1024 * 1024 * 1024) / 512) {
			handle->device->ctrl.ocr |= SD_CARD_HIGH_CAPACITY;
			handle->device->cfg.blockSize = 512;
		}

		if (handle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY)
			EMMC_TRACE("Sector addressing\n");
		else
			EMMC_TRACE("Byte addressing\n");

		EMMC_TRACE("Ext_CSD_storage[162]: 0x%02X  Ext_CSD_storage[179]: 0x%02X\n",
			   emmc_global_buf_ptr->u.Ext_CSD_storage[162],
			   emmc_global_buf_ptr->u.Ext_CSD_storage[179]);
	}

	return handle->card->type;
}


/*
 * The function send reset command to the card.
 * The card will be in ready status after the reset.
 */
int reset_card(struct sd_handle *handle)
{
	int res = SD_OK;

	/* on reset, card's RCA should return to 0 */
	handle->device->ctrl.rca = 0;

	res = sd_cmd0(handle);

	if (res != SD_OK)
		return SD_RESET_ERROR;

	return res;
}


/*
 * The function sends command to the card and starts
 * data transmission.
 */
static int xfer_data(struct sd_handle *handle,
		     uint32_t mode,
		     uint32_t addr, uint32_t length, uint8_t *base)
{
	int rc = SD_OK;

	VERBOSE("XFER: dest: 0x%" PRIx64 ", addr: 0x%x, size: 0x%x bytes\n",
		(uint64_t)base, addr, length);

	if ((length / handle->device->cfg.blockSize) > 1) {
		if (mode == SD_OP_READ) {
			inv_dcache_range((uintptr_t)base, (uint64_t)length);
			rc = sd_cmd18(handle, addr, length, base);
		} else {
#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
			flush_dcache_range((uintptr_t)base, (uint64_t)length);
			rc = sd_cmd25(handle, addr, length, base);
#else
			rc = SD_DATA_XFER_ERROR;
#endif
		}
	} else {
		if (mode == SD_OP_READ) {
			inv_dcache_range((uintptr_t)base, (uint64_t)length);
			rc = sd_cmd17(handle, addr,
				      handle->device->cfg.blockSize, base);
		} else {
#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
			flush_dcache_range((uintptr_t)base, (uint64_t)length);
			rc = sd_cmd24(handle, addr,
				      handle->device->cfg.blockSize, base);
#else
			rc = SD_DATA_XFER_ERROR;
#endif
		}
	}

	if (rc != SD_OK)
		return SD_DATA_XFER_ERROR;

	return SD_OK;
}

#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE
int erase_card(struct sd_handle *handle, uint32_t addr, uint32_t blocks)
{
	uint32_t end_addr;

	INFO("ERASE: addr: 0x%x, num of sectors: 0x%x\n", addr, blocks);

	if (sd_cmd35(handle, addr) != SD_OK)
		return SD_FAIL;

	end_addr = addr + blocks - 1;
	if (sd_cmd36(handle, end_addr) != SD_OK)
		return SD_FAIL;

	if (sd_cmd38(handle) != SD_OK)
		return SD_FAIL;

	return SD_OK;
}
#endif

/*
 * The function reads block data from a card.
 */
#ifdef USE_EMMC_FIP_TOC_CACHE
int read_block(struct sd_handle *handle,
	       uint8_t *dst, uint32_t addr, uint32_t len)
{
	int rel = SD_OK;

	/*
	 * Avoid doing repeated reads of the partition block
	 * by caching.
	 */
	if (cached_partition_block &&
	    addr == PARTITION_BLOCK_ADDR &&
	    len == CACHE_SIZE) {
		memcpy(dst, cached_block, len);
	} else {
		rel = xfer_data(handle, SD_OP_READ, addr, len, dst);

		if (len == CACHE_SIZE && addr == PARTITION_BLOCK_ADDR) {
			cached_partition_block = 1;
			memcpy(cached_block, dst, len);
		}
	}

	return rel;
}
#else
int read_block(struct sd_handle *handle,
	       uint8_t *dst, uint32_t addr, uint32_t len)
{
	return xfer_data(handle, SD_OP_READ, addr, len, dst);
}
#endif

#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE

/*
 * The function writes block data to a card.
 */
int write_block(struct sd_handle *handle,
		uint8_t *src, uint32_t addr, uint32_t len)
{
	int rel = SD_OK;

	/*
	 * Current HC has problem to get response of cmd16 after cmd12,
	 * the delay is necessary to sure the next cmd16 will not be timed out.
	 * The delay has to be at least 4 ms.
	 * The code removed cmd16 and use cmd13 to get card status before
	 * sending cmd18 or cmd25 to make sure the card is ready and thus
	 * no need to have delay here.
	 */

	rel = xfer_data(handle, SD_OP_WRITE, addr, len, src);

	EMMC_TRACE("wr_blk addr:0x%08X src:0x%08X len:0x%08X result:%d\n",
		   addr, src, len, rel);

	return rel;
}


/*
 * The function is called to write one block data directly to
 * a card's data buffer.
 * it is used in Non-DMA mode for card data transmission.
 */
int write_buffer(struct sd_handle *handle, uint32_t length, uint8_t *data)
{
	uint32_t rem, blockSize, event;
	uint8_t *pData = data;

	blockSize = handle->device->cfg.blockSize;
	rem = length;

	if (rem == 0)
		return SD_OK;

	while (rem > 0) {

		event = wait_for_event(handle,
				       SD4_EMMC_TOP_INTR_BWRDY_MASK |
				       SD_ERR_INTERRUPTS,
				       handle->device->cfg.wfe_retry);

		if (handle->device->ctrl.cmdStatus) {
			check_error(handle, handle->device->ctrl.cmdStatus);
			return SD_WRITE_ERROR;
		}

		if (rem >= blockSize)
			chal_sd_write_buffer((CHAL_HANDLE *) handle->device,
					     blockSize, pData);
		else
			chal_sd_write_buffer((CHAL_HANDLE *) handle->device,
					     rem, pData);

		if (rem > blockSize) {
			rem -= blockSize;
			pData += blockSize;
		} else {
			pData += rem;
			rem = 0;
		}
	}

	if ((event & SD4_EMMC_TOP_INTR_TXDONE_MASK) !=
	    SD4_EMMC_TOP_INTR_TXDONE_MASK) {
		event = wait_for_event(handle,
				       SD4_EMMC_TOP_INTR_TXDONE_MASK |
				       SD_ERR_INTERRUPTS,
				       handle->device->cfg.wfe_retry);

		if (handle->device->ctrl.cmdStatus != SD_OK) {
			check_error(handle, handle->device->ctrl.cmdStatus);
			return SD_WRITE_ERROR;
		}
	} else {
		handle->device->ctrl.eventList &= ~SD4_EMMC_TOP_INTR_TXDONE_MASK;
	}

	return SD_OK;
}
#endif /* INCLUDE_EMMC_DRIVER_WRITE_CODE */


/*
 * The function is called to read maximal one block data
 * directly from a card
 * It is used in Non-DMA mode for card data transmission.
 */
int read_buffer(struct sd_handle *handle, uint32_t length, uint8_t *data)
{
	uint32_t rem, blockSize, event = 0;
	uint8_t *pData = data;

	blockSize = handle->device->cfg.blockSize;
	rem = length;

	if (rem == 0)
		return SD_OK;

	while (rem > 0) {
		event = wait_for_event(handle,
				       SD4_EMMC_TOP_INTR_BRRDY_MASK |
				       SD_ERR_INTERRUPTS,
				       handle->device->cfg.wfe_retry);

		if (handle->device->ctrl.cmdStatus) {
			check_error(handle, handle->device->ctrl.cmdStatus);
			return SD_READ_ERROR;
		}

		if (rem >= blockSize)
			chal_sd_read_buffer((CHAL_HANDLE *) handle->device,
					    blockSize, pData);
		else
			chal_sd_read_buffer((CHAL_HANDLE *) handle->device, rem,
					    pData);

		if (rem > blockSize) {
			rem -= blockSize;
			pData += blockSize;
		} else {
			pData += rem;
			rem = 0;
		}
	}

	/* In case, there are extra data in the SD FIFO, just dump them. */
	chal_sd_dump_fifo((CHAL_HANDLE *) handle->device);

	if ((event & SD4_EMMC_TOP_INTR_TXDONE_MASK) !=
	    SD4_EMMC_TOP_INTR_TXDONE_MASK) {
		event = wait_for_event(handle, SD4_EMMC_TOP_INTR_TXDONE_MASK,
				       handle->device->cfg.wfe_retry);

		if (handle->device->ctrl.cmdStatus) {
			check_error(handle, handle->device->ctrl.cmdStatus);
			return SD_READ_ERROR;
		}
	} else {
		handle->device->ctrl.eventList &= ~SD4_EMMC_TOP_INTR_TXDONE_MASK;
	}

	return SD_OK;
}


/*
 * Error handling routine.
 * The function just reset the DAT
 * and CMD line if an error occures during data transmission.
 */
int check_error(struct sd_handle *handle, uint32_t ints)
{
	uint32_t rel;

	chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device,
			       SD_ERR_INTERRUPTS, 0);

	if (ints & SD4_EMMC_TOP_INTR_CMDERROR_MASK) {

		chal_sd_reset_line((CHAL_HANDLE *) handle->device,
				   SD4_EMMC_TOP_CTRL1_CMDRST_MASK);
		rel = abort_err(handle);

		chal_sd_reset_line((CHAL_HANDLE *) handle->device,
				   SD4_EMMC_TOP_CTRL1_DATRST_MASK);
		chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device,
				       SD_ERR_INTERRUPTS, 1);

		return (rel == SD_ERROR_NON_RECOVERABLE) ?
				SD_ERROR_NON_RECOVERABLE : SD_ERROR_RECOVERABLE;
	} else {
		rel = err_recovery(handle, ints);
	}

	chal_sd_set_irq_signal((CHAL_HANDLE *) handle->device,
			       SD_ERR_INTERRUPTS, 1);

	return rel;
}


/*
 * Error recovery routine.
 * Try to recover from the error.
 */
static int err_recovery(struct sd_handle *handle, uint32_t errors)
{
	uint32_t rel = 0;

	/*
	 * In case of timeout error, the cmd line and data line maybe
	 * still active or stuck at atcitve so it is needed to reset
	 * either data line or cmd line to make sure a new cmd can be sent.
	 */

	if (errors & SD_CMD_ERROR_INT)
		chal_sd_reset_line((CHAL_HANDLE *) handle->device,
				   SD4_EMMC_TOP_CTRL1_CMDRST_MASK);

	if (errors & SD_DAT_ERROR_INT)
		chal_sd_reset_line((CHAL_HANDLE *) handle->device,
				   SD4_EMMC_TOP_CTRL1_DATRST_MASK);

	/* Abort transaction by sending out stop command */
	if ((handle->device->ctrl.cmdIndex == 18) ||
	    (handle->device->ctrl.cmdIndex == 25))
		rel = abort_err(handle);

	return rel;
}


/*
 * The function is called to read one block data directly from a card.
 * It is used in Non-DMA mode for card data transmission.
 */
int process_cmd_response(struct sd_handle *handle,
			 uint32_t cmdIndex,
			 uint32_t rsp0,
			 uint32_t rsp1,
			 uint32_t rsp2, uint32_t rsp3, struct sd_resp *resp)
{
	int result = SD_OK;

	/* R6 */
	uint32_t rca = (rsp0 >> 16) & 0xffff;
	uint32_t cardStatus = rsp0;

	/* R4 */
	uint32_t cBit = (rsp0 >> 31) & 0x1;
	uint32_t funcs = (rsp0 >> 28) & 0x7;
	uint32_t memPresent = (rsp0 >> 27) & 0x1;

	resp->r1 = 0x3f;
	resp->cardStatus = cardStatus;

	if (cmdIndex == SD_CMD_IO_SEND_OP_COND) {
		resp->data.r4.cardReady = cBit;
		resp->data.r4.funcs = funcs;
		resp->data.r4.memPresent = memPresent;
		resp->data.r4.ocr = cardStatus;
	}

	if (cmdIndex == SD_CMD_MMC_SET_RCA) {
		resp->data.r6.rca = rca;
		resp->data.r6.cardStatus = cardStatus & 0xFFFF;
	}

	if (cmdIndex == SD_CMD_SELECT_DESELECT_CARD) {
		resp->data.r7.rca = rca;
	}

	if (cmdIndex == SD_CMD_IO_RW_DIRECT) {
		if (((rsp0 >> 16) & 0xffff) != 0)
			result = SD_CMD_ERR_INVALID_RESPONSE;

		resp->data.r5.data = rsp0 & 0xff;
	}

	if (cmdIndex == SD_CMD_IO_RW_EXTENDED) {
		if (((rsp0 >> 16) & 0xffff) != 0)
			result = SD_CMD_ERR_INVALID_RESPONSE;

		resp->data.r5.data = rsp0 & 0xff;
	}

	if (cmdIndex == SD_ACMD_SD_SEND_OP_COND ||
	    cmdIndex == SD_CMD_SEND_OPCOND)
		resp->data.r3.ocr = cardStatus;

	if (cmdIndex == SD_CMD_SEND_CSD ||
	    cmdIndex == SD_CMD_SEND_CID ||
	    cmdIndex == SD_CMD_ALL_SEND_CID) {
		resp->data.r2.rsp4 = rsp3;
		resp->data.r2.rsp3 = rsp2;
		resp->data.r2.rsp2 = rsp1;
		resp->data.r2.rsp1 = rsp0;
	}

	if ((cmdIndex == SD_CMD_READ_EXT_CSD) &&
	    (handle->card->type == SD_CARD_SD)) {
		if ((resp->cardStatus & 0xAA) != 0xAA) {
			result = SD_CMD_ERR_INVALID_RESPONSE;
		}
	}

	return result;
}


/*
 * The function sets DMA buffer and data length, process
 * block size and the number of blocks to be transferred.
 * It returns the DMA buffer address.
 * It copies dma data from user buffer to the DMA buffer
 * if the operation is to write data to the SD card.
 */
void data_xfer_setup(struct sd_handle *handle, uint8_t *data, uint32_t length,
		     int dir)
{
	chal_sd_setup_xfer((CHAL_HANDLE *)handle->device, data, length, dir);
}


/*
 * The function does soft reset the host SD controller. After
 * the function call all host controller's register are reset
 * to default vallue;
 *
 * Note    This function only resets the host controller it does not
 *          reset the controller's handler.
 */
int reset_host_ctrl(struct sd_handle *handle)
{
	chal_sd_stop();

	return SD_OK;
}

static void pstate_log(struct sd_handle *handle)
{
	ERROR("PSTATE: 0x%x\n", mmio_read_32
		(handle->device->ctrl.sdRegBaseAddr +
			SD4_EMMC_TOP_PSTATE_SD4_OFFSET));
	ERROR("ERRSTAT: 0x%x\n", mmio_read_32
		(handle->device->ctrl.sdRegBaseAddr +
			SD4_EMMC_TOP_ERRSTAT_OFFSET));
}

/*
 * The function waits for one or a group of interrupts specified
 * by mask. The function returns if any one the interrupt status
 * is set. If interrupt mode is not enabled then it will poll
 * the interrupt status register until a interrupt status is set
 * an error interrupt happens. If interrupt mode is enabled then
 * this function should be called after the interrupt
 * is received by ISR routine.
 */
uint32_t wait_for_event(struct sd_handle *handle,
			uint32_t mask, uint32_t retry)
{
	uint32_t regval, cmd12, time = 0;

	handle->device->ctrl.cmdStatus = 0;	/* no error */
	EMMC_TRACE("%s %d mask:0x%x timeout:%d irq_status:0x%x\n",
		   __func__, __LINE__, mask, retry,
		   chal_sd_get_irq_status((CHAL_HANDLE *)handle->device));

	/* Polling mode */
	do {
		regval = chal_sd_get_irq_status((CHAL_HANDLE *)handle->device);

		if (regval & SD4_EMMC_TOP_INTR_DMAIRQ_MASK) {
			chal_sd_set_dma_addr((CHAL_HANDLE *)handle->device,
					(uintptr_t)
				chal_sd_get_dma_addr((CHAL_HANDLE *)
						handle->device));
			chal_sd_clear_irq((CHAL_HANDLE *)handle->device,
					  SD4_EMMC_TOP_INTR_DMAIRQ_MASK);
		}

		if (time++ > retry) {
			ERROR("EMMC: No response (cmd%d) after %dus.\n",
			      handle->device->ctrl.cmdIndex,
			      time * EMMC_WFE_RETRY_DELAY_US);
			handle->device->ctrl.cmdStatus = SD_CMD_MISSING;
			pstate_log(handle);
			ERROR("EMMC: INT[0x%x]\n", regval);
			break;
		}

		if (regval & SD4_EMMC_TOP_INTR_CTOERR_MASK) {
			ERROR("EMMC: Cmd%d timeout INT[0x%x]\n",
			      handle->device->ctrl.cmdIndex, regval);
			handle->device->ctrl.cmdStatus =
			    SD4_EMMC_TOP_INTR_CTOERR_MASK;
			pstate_log(handle);
			break;
		}
		if (regval & SD_CMD_ERROR_FLAGS) {
			ERROR("EMMC: Cmd%d error INT[0x%x]\n",
			      handle->device->ctrl.cmdIndex, regval);
			handle->device->ctrl.cmdStatus = SD_CMD_ERROR_FLAGS;
			pstate_log(handle);
			break;
		}

		cmd12 = chal_sd_get_atuo12_error((CHAL_HANDLE *)handle->device);
		if (cmd12) {
			ERROR("EMMC: Cmd%d auto cmd12 err:0x%x\n",
			      handle->device->ctrl.cmdIndex, cmd12);
			handle->device->ctrl.cmdStatus = cmd12;
			pstate_log(handle);
			break;
		}

		if (SD_DATA_ERROR_FLAGS & regval) {
			ERROR("EMMC: Data for cmd%d error, INT[0x%x]\n",
			      handle->device->ctrl.cmdIndex, regval);
			handle->device->ctrl.cmdStatus =
			    (SD_DATA_ERROR_FLAGS & regval);
			pstate_log(handle);
			break;
		}

		if ((regval & mask) == 0)
			udelay(EMMC_WFE_RETRY_DELAY_US);

	} while ((regval & mask) == 0);

	/* clear the interrupt since it is processed */
	chal_sd_clear_irq((CHAL_HANDLE *)handle->device, (regval & mask));

	return (regval & mask);
}

int32_t set_config(struct sd_handle *handle, uint32_t speed, uint32_t retry,
		    uint32_t dma, uint32_t dmaBound, uint32_t blkSize,
		    uint32_t wfe_retry)
{
	int32_t rel = 0;

	if (handle == NULL)
		return SD_FAIL;

	handle->device->cfg.wfe_retry = wfe_retry;

	rel = chal_sd_config((CHAL_HANDLE *)handle->device, speed, retry,
			     dmaBound, blkSize, dma);
	return rel;

}

int mmc_cmd1(struct sd_handle *handle)
{
	uint32_t newOcr, res;
	uint32_t cmd1_option = MMC_OCR_OP_VOLT | MMC_OCR_SECTOR_ACCESS_MODE;

	/*
	 * After Reset, eMMC comes up in 1 Bit Data Width by default.
	 * Set host side to match.
	 */
	chal_sd_config_bus_width((CHAL_HANDLE *) handle->device,
				 SD_BUS_DATA_WIDTH_1BIT);

#ifdef USE_EMMC_FIP_TOC_CACHE
	cached_partition_block = 0;
#endif
	handle->device->ctrl.present = 0; /* init card present to be no card */

	handle->card->type = SD_CARD_MMC;

	res = sd_cmd1(handle, cmd1_option, &newOcr);

	if (res != SD_OK) {
		EMMC_TRACE("CMD1 Timeout: Device is not ready\n");
		res = SD_CARD_UNKNOWN;
	}
	return res;
}
