/*
 * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch_helpers.h>

#include "emmc_config.h"
#include "emmc_hal.h"
#include "emmc_std.h"
#include "emmc_registers.h"
#include "emmc_def.h"

#define MIN_EMMC(a, b)        (((a) < (b)) ? (a) : (b))
#define EMMC_RW_SECTOR_COUNT_MAX        0x0000ffffU

static EMMC_ERROR_CODE emmc_multiple_block_read (uint32_t *buff_address_virtual,
		uint32_t sector_number, uint32_t count,
		HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode)
{
	EMMC_ERROR_CODE result;

	/* parameter check */
	if ((count > EMMC_RW_SECTOR_COUNT_MAX)
	    || (count == 0)
	    || ((transfer_mode != HAL_MEMCARD_DMA)
		&& (transfer_mode != HAL_MEMCARD_NOT_DMA))
	    ) {
		emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_PARAM);
		return EMMC_ERR_PARAM;
	}

	/* CMD23 */
	emmc_make_nontrans_cmd(CMD23_SET_BLOCK_COUNT, count);
	result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
	if (result != EMMC_SUCCESS) {
		return result;
	}
	SETR_32(SD_SECCNT, count);
	SETR_32(SD_STOP, 0x00000100);
	SETR_32(CC_EXT_MODE, (CC_EXT_MODE_CLEAR | CC_EXT_MODE_DMASDRW_ENABLE));	/* SD_BUF Read/Write DMA Transfer enable */

	/* CMD18 */
	emmc_make_trans_cmd(CMD18_READ_MULTIPLE_BLOCK, sector_number,
			    buff_address_virtual,
			    count << EMMC_SECTOR_SIZE_SHIFT, HAL_MEMCARD_READ,
			    transfer_mode);
	result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
	if (result != EMMC_SUCCESS) {
		return result;	/* CMD18 error code */
	}

	/* CMD13 */
	emmc_make_nontrans_cmd(CMD13_SEND_STATUS, EMMC_RCA << 16);
	result = emmc_exec_cmd(EMMC_R1_ERROR_MASK, mmc_drv_obj.response);
	if (result != EMMC_SUCCESS) {
		return result;
	}
#if RCAR_BL2_DCACHE == 1
	if (transfer_mode == HAL_MEMCARD_NOT_DMA) {
		flush_dcache_range((uint64_t) buff_address_virtual,
				   ((size_t) count << EMMC_SECTOR_SIZE_SHIFT));
	}
#endif /* RCAR_BL2_DCACHE == 1 */

	/* ready status check */
	if ((mmc_drv_obj.r1_card_status & EMMC_R1_READY) == 0) {
		emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR,
				      EMMC_ERR_CARD_BUSY);
		return EMMC_ERR_CARD_BUSY;
	}

	/* state check */
	if (mmc_drv_obj.current_state != EMMC_R1_STATE_TRAN) {
		emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR,
				      EMMC_ERR_CARD_STATE);
		return EMMC_ERR_CARD_STATE;
	}

	return EMMC_SUCCESS;
}

EMMC_ERROR_CODE emmc_read_sector(uint32_t *buff_address_virtual,
				 uint32_t sector_number,
				 uint32_t count, uint32_t feature_flags)
{
	uint32_t trans_count;
	uint32_t remain;
	EMMC_ERROR_CODE result;
	HAL_MEMCARD_DATA_TRANSFER_MODE transfer_mode;

	/* parameter check */
	if (count == 0) {
		emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_PARAM);
		return EMMC_ERR_PARAM;
	}

	/* state check */
	if (mmc_drv_obj.mount != TRUE) {
		emmc_write_error_info(EMMC_FUNCNO_READ_SECTOR, EMMC_ERR_STATE);
		return EMMC_ERR_STATE;
	}

	/* DMA? */
	if ((feature_flags & LOADIMAGE_FLAGS_DMA_ENABLE) != 0) {
		transfer_mode = HAL_MEMCARD_DMA;
	} else {
		transfer_mode = HAL_MEMCARD_NOT_DMA;
	}

	remain = count;
	while (remain != 0) {
		trans_count = MIN_EMMC(remain, EMMC_RW_SECTOR_COUNT_MAX);
		result =
		    emmc_multiple_block_read(buff_address_virtual,
					     sector_number, trans_count,
					     transfer_mode);
		if (result != EMMC_SUCCESS) {
			return result;
		}

		buff_address_virtual += (EMMC_BLOCK_LENGTH_DW * trans_count);
		sector_number += trans_count;
		remain -= trans_count;
	}

	return EMMC_SUCCESS;
}
