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

#include <common/debug.h>

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

static void emmc_little_to_big(uint8_t *p, uint32_t value)
{
	if (p == NULL)
		return;

	p[0] = (uint8_t) (value >> 24);
	p[1] = (uint8_t) (value >> 16);
	p[2] = (uint8_t) (value >> 8);
	p[3] = (uint8_t) value;

}

static void emmc_softreset(void)
{
	int32_t loop = 10000;
	int32_t retry = 1000;

	/* flag clear */
	mmc_drv_obj.during_cmd_processing = FALSE;
	mmc_drv_obj.during_transfer = FALSE;
	mmc_drv_obj.during_dma_transfer = FALSE;
	mmc_drv_obj.state_machine_blocking = FALSE;
	mmc_drv_obj.force_terminate = FALSE;
	mmc_drv_obj.dma_error_flag = FALSE;

	/* during operation ? */
	if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) == 0)
		goto reset;

	/* wait CMDSEQ = 0 */
	while (loop > 0) {
		if ((GETR_32(SD_INFO2) & SD_INFO2_CBSY) == 0)
			break;	/* ready */

		loop--;
		if ((loop == 0) && (retry > 0)) {
			rcar_micro_delay(1000U);	/* wait 1ms */
			loop = 10000;
			retry--;
		}
	}

reset:
	/* reset */
	SETR_32(SOFT_RST, (GETR_32(SOFT_RST) & (~SOFT_RST_SDRST)));
	SETR_32(SOFT_RST, (GETR_32(SOFT_RST) | SOFT_RST_SDRST));

	/* initialize */
	SETR_32(SD_INFO1, 0x00000000U);
	SETR_32(SD_INFO2, SD_INFO2_CLEAR);
	SETR_32(SD_INFO1_MASK, 0x00000000U);	/* all interrupt disable */
	SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR);	/* all interrupt disable */
}

static void emmc_read_response(uint32_t *response)
{
	uint8_t *p;

	if (response == NULL)
		return;

	/* read response */
	if (mmc_drv_obj.response_length != EMMC_MAX_RESPONSE_LENGTH) {
		*response = GETR_32(SD_RSP10);	/* [39:8] */
		return;
	}

	/* CSD or CID */
	p = (uint8_t *) (response);
	emmc_little_to_big(p, ((GETR_32(SD_RSP76) << 8)
			| (GETR_32(SD_RSP54) >> 24)));	/* [127:96]     */
	emmc_little_to_big(p + 4, ((GETR_32(SD_RSP54) << 8)
			| (GETR_32(SD_RSP32) >> 24)));	/* [95:64]      */
	emmc_little_to_big(p + 8, ((GETR_32(SD_RSP32) << 8)
			| (GETR_32(SD_RSP10) >> 24)));	/* [63:32]      */
	emmc_little_to_big(p + 12, (GETR_32(SD_RSP10) << 8));
}

static EMMC_ERROR_CODE emmc_response_check(uint32_t *response,
					   uint32_t error_mask)
{

	HAL_MEMCARD_RESPONSE_TYPE response_type =
	    ((HAL_MEMCARD_RESPONSE_TYPE)mmc_drv_obj.cmd_info.cmd & HAL_MEMCARD_RESPONSE_TYPE_MASK);

	if (response == NULL)
		return EMMC_ERR_PARAM;

	if (response_type == HAL_MEMCARD_RESPONSE_NONE)
		return EMMC_SUCCESS;


	if (response_type <= HAL_MEMCARD_RESPONSE_R1b) {
		/* R1 or R1b */
		mmc_drv_obj.current_state =
		    (EMMC_R1_STATE) ((*response & EMMC_R1_STATE_MASK) >>
				     EMMC_R1_STATE_SHIFT);
		if ((*response & error_mask) != 0) {
			if ((0x80 & *response) != 0) {
				ERROR("BL2: emmc SWITCH_ERROR\n");
			}
			return EMMC_ERR_CARD_STATUS_BIT;
		}
		return EMMC_SUCCESS;
	}

	if (response_type == HAL_MEMCARD_RESPONSE_R4) {
		if ((*response & EMMC_R4_STATUS) != 0)
			return EMMC_ERR_CARD_STATUS_BIT;
	}

	return EMMC_SUCCESS;
}

static void emmc_WaitCmd2Cmd_8Cycle(void)
{
	uint32_t dataL, wait = 0;

	dataL = GETR_32(SD_CLK_CTRL);
	dataL &= 0x000000FF;

	switch (dataL) {
	case 0xFF:
	case 0x00:
	case 0x01:
	case 0x02:
	case 0x04:
	case 0x08:
	case 0x10:
	case 0x20:
		wait = 10U;
		break;
	case 0x40:
		wait = 20U;
		break;
	case 0x80:
		wait = 30U;
		break;
	}

	rcar_micro_delay(wait);
}

static void cmdErrSdInfo2Log(void)
{
	ERROR("BL2: emmc ERR SD_INFO2 = 0x%x\n", mmc_drv_obj.error_info.info2);
}

static void emmc_data_transfer_dma(void)
{
	mmc_drv_obj.during_dma_transfer = TRUE;
	mmc_drv_obj.dma_error_flag = FALSE;

	SETR_32(SD_INFO1_MASK, 0x00000000U);
	SETR_32(SD_INFO2_MASK, (SD_INFO2_ALL_ERR | SD_INFO2_CLEAR));

	/* DMAC setting */
	if (mmc_drv_obj.cmd_info.dir == HAL_MEMCARD_WRITE) {
		/* transfer complete interrupt enable */
		SETR_32(DM_CM_INFO1_MASK,
			(DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH0_ENABLE));
		SETR_32(DM_CM_INFO2_MASK,
			(DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH0_ENABLE));
		/* BUFF --> FIFO */
		SETR_32(DM_CM_DTRAN_MODE, (DM_CM_DTRAN_MODE_CH0 |
					   DM_CM_DTRAN_MODE_BIT_WIDTH));
	} else {
		/* transfer complete interrupt enable */
		SETR_32(DM_CM_INFO1_MASK,
			(DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH1_ENABLE));
		SETR_32(DM_CM_INFO2_MASK,
			(DM_CM_INFO_MASK_CLEAR | DM_CM_INFO_CH1_ENABLE));
		/* FIFO --> BUFF */
		SETR_32(DM_CM_DTRAN_MODE, (DM_CM_DTRAN_MODE_CH1
					   | DM_CM_DTRAN_MODE_BIT_WIDTH));
	}
	SETR_32(DM_DTRAN_ADDR, (((uintptr_t) mmc_drv_obj.buff_address_virtual &
				 DM_DTRAN_ADDR_WRITE_MASK)));

	SETR_32(DM_CM_DTRAN_CTRL, DM_CM_DTRAN_CTRL_START);
}

EMMC_ERROR_CODE emmc_exec_cmd(uint32_t error_mask, uint32_t *response)
{
	EMMC_ERROR_CODE rtn_code = EMMC_SUCCESS;
	HAL_MEMCARD_RESPONSE_TYPE response_type;
	HAL_MEMCARD_COMMAND_TYPE cmd_type;
	EMMC_INT_STATE state;
	uint32_t err_not_care_flag = FALSE;

	/* parameter check */
	if (response == NULL) {
		emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, EMMC_ERR_PARAM);
		return EMMC_ERR_PARAM;
	}

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

	if (mmc_drv_obj.state_machine_blocking == TRUE) {
		emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD, EMMC_ERR);
		return EMMC_ERR;
	}

	state = ESTATE_BEGIN;
	response_type =
	    ((HAL_MEMCARD_RESPONSE_TYPE)mmc_drv_obj.cmd_info.cmd &
					HAL_MEMCARD_RESPONSE_TYPE_MASK);
	cmd_type =
	    ((HAL_MEMCARD_COMMAND_TYPE) mmc_drv_obj.cmd_info.cmd &
					HAL_MEMCARD_COMMAND_TYPE_MASK);

	/* state machine */
	while ((mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END)) {
		/* The interrupt factor flag is observed. */
		emmc_interrupt();

		/* wait interrupt */
		if (mmc_drv_obj.state_machine_blocking == TRUE)
			continue;

		switch (state) {
		case ESTATE_BEGIN:
			/* Busy check */
			if ((mmc_drv_obj.error_info.info2 & SD_INFO2_CBSY) != 0) {
				emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD,
						      EMMC_ERR_CARD_BUSY);
				return EMMC_ERR_CARD_BUSY;
			}

			/* clear register */
			SETR_32(SD_INFO1, 0x00000000U);
			SETR_32(SD_INFO2, SD_INFO2_CLEAR);
			SETR_32(SD_INFO1_MASK, SD_INFO1_INFO0);
			SETR_32(SD_INFO2_MASK,
				(SD_INFO2_ALL_ERR | SD_INFO2_CLEAR));

			state = ESTATE_ISSUE_CMD;
			/* through */

		case ESTATE_ISSUE_CMD:
			/* ARG */
			SETR_32(SD_ARG, mmc_drv_obj.cmd_info.arg);
			/* issue cmd */
			SETR_32(SD_CMD, mmc_drv_obj.cmd_info.hw);
			/* Set driver flag */
			mmc_drv_obj.during_cmd_processing = TRUE;
			mmc_drv_obj.state_machine_blocking = TRUE;

			if (response_type == HAL_MEMCARD_RESPONSE_NONE) {
				state = ESTATE_NON_RESP_CMD;
			} else {
				state = ESTATE_RCV_RESP;
			}

			break;

		case ESTATE_NON_RESP_CMD:
			/* interrupt disable */
			SETR_32(SD_INFO1_MASK, 0x00000000U);
			SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR);

			/* check interrupt */
			if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) {
				/* error interrupt */
				cmdErrSdInfo2Log();
				rtn_code = EMMC_ERR_INFO2;
				state = ESTATE_ERROR;
			} else if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO0) ==
				   0) {
				/* not receive expected interrupt */
				rtn_code = EMMC_ERR_RESPONSE;
				state = ESTATE_ERROR;
			} else {
				emmc_WaitCmd2Cmd_8Cycle();
				state = ESTATE_END;
			}
			break;

		case ESTATE_RCV_RESP:
			/* interrupt disable */
			SETR_32(SD_INFO1_MASK, 0x00000000U);
			SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR);

			/* check interrupt */
			if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) {
				if ((mmc_drv_obj.get_partition_access_flag ==
				     TRUE)
				    && ((mmc_drv_obj.int_event2 & SD_INFO2_ERR6)
					!= 0U)) {
					err_not_care_flag = TRUE;
					rtn_code = EMMC_ERR_CMD_TIMEOUT;
				} else {
					/* error interrupt */
					cmdErrSdInfo2Log();
					rtn_code = EMMC_ERR_INFO2;
				}
				state = ESTATE_ERROR;
				break;
			} else if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO0) ==
				   0) {
				/* not receive expected interrupt */
				rtn_code = EMMC_ERR_RESPONSE;
				state = ESTATE_ERROR;
				break;
			}

			/* read response */
			emmc_read_response(response);

			/* check response */
			rtn_code = emmc_response_check(response, error_mask);
			if (rtn_code != EMMC_SUCCESS) {
				state = ESTATE_ERROR;
				break;
			}

			if (response_type == HAL_MEMCARD_RESPONSE_R1b) {
				/* R1b */
				SETR_32(SD_INFO2_MASK,
					(SD_INFO2_ALL_ERR | SD_INFO2_CLEAR));
				state = ESTATE_RCV_RESPONSE_BUSY;
			} else {
				state = ESTATE_CHECK_RESPONSE_COMPLETE;
			}
			break;

		case ESTATE_RCV_RESPONSE_BUSY:
			/* check interrupt */
			if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) {
				/* error interrupt */
				cmdErrSdInfo2Log();
				rtn_code = EMMC_ERR_INFO2;
				state = ESTATE_ERROR;
				break;
			}
			/* DAT0 not Busy */
			if ((SD_INFO2_DAT0 & mmc_drv_obj.error_info.info2) != 0) {
				state = ESTATE_CHECK_RESPONSE_COMPLETE;
				break;
			}
			break;

		case ESTATE_CHECK_RESPONSE_COMPLETE:
			if (cmd_type >= HAL_MEMCARD_COMMAND_TYPE_ADTC_WRITE) {
				state = ESTATE_DATA_TRANSFER;
			} else {
				emmc_WaitCmd2Cmd_8Cycle();
				state = ESTATE_END;
			}
			break;

		case ESTATE_DATA_TRANSFER:
			/* ADTC command  */
			mmc_drv_obj.during_transfer = TRUE;
			mmc_drv_obj.state_machine_blocking = TRUE;

			if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) {
				/* DMA */
				emmc_data_transfer_dma();
			} else {
				/* PIO */
				/* interrupt enable (FIFO read/write enable) */
				if (mmc_drv_obj.cmd_info.dir ==
				    HAL_MEMCARD_WRITE) {
					SETR_32(SD_INFO2_MASK,
						(SD_INFO2_BWE | SD_INFO2_ALL_ERR
						 | SD_INFO2_CLEAR));
				} else {
					SETR_32(SD_INFO2_MASK,
						(SD_INFO2_BRE | SD_INFO2_ALL_ERR
						 | SD_INFO2_CLEAR));
				}
			}
			state = ESTATE_DATA_TRANSFER_COMPLETE;
			break;

		case ESTATE_DATA_TRANSFER_COMPLETE:
			/* check interrupt */
			if ((mmc_drv_obj.int_event2 & SD_INFO2_ALL_ERR) != 0) {
				/* error interrupt */
				cmdErrSdInfo2Log();
				rtn_code = EMMC_ERR_INFO2;
				state = ESTATE_TRANSFER_ERROR;
				break;
			}

			/* DMAC error ? */
			if (mmc_drv_obj.dma_error_flag == TRUE) {
				/* Error occurred in DMAC driver. */
				rtn_code = EMMC_ERR_FROM_DMAC_TRANSFER;
				state = ESTATE_TRANSFER_ERROR;
			} else if (mmc_drv_obj.during_dma_transfer == TRUE) {
				/* DMAC not finished. unknown error */
				rtn_code = EMMC_ERR;
				state = ESTATE_TRANSFER_ERROR;
			} else {
				SETR_32(SD_INFO1_MASK, SD_INFO1_INFO2);
				SETR_32(SD_INFO2_MASK,
					(SD_INFO2_ALL_ERR | SD_INFO2_CLEAR));

				mmc_drv_obj.state_machine_blocking = TRUE;

				state = ESTATE_ACCESS_END;
			}
			break;

		case ESTATE_ACCESS_END:

			/* clear flag */
			if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) {
				/* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */
				SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR);
				SETR_32(SD_STOP, 0x00000000U);
				mmc_drv_obj.during_dma_transfer = FALSE;
			}

			SETR_32(SD_INFO1_MASK, 0x00000000U);
			SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR);
			SETR_32(SD_INFO1, 0x00000000U);
			SETR_32(SD_INFO2, SD_INFO2_CLEAR);

			if ((mmc_drv_obj.int_event1 & SD_INFO1_INFO2) != 0) {
				emmc_WaitCmd2Cmd_8Cycle();
				state = ESTATE_END;
			} else {
				state = ESTATE_ERROR;
			}
			break;

		case ESTATE_TRANSFER_ERROR:
			/* The error occurred in the Data transfer.  */
			if (mmc_drv_obj.transfer_mode == HAL_MEMCARD_DMA) {
				/* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */
				SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR);
				SETR_32(SD_STOP, 0x00000000U);
				mmc_drv_obj.during_dma_transfer = FALSE;
			}
			/* through */

		case ESTATE_ERROR:
			if (err_not_care_flag == TRUE) {
				mmc_drv_obj.during_cmd_processing = FALSE;
			} else {
				emmc_softreset();
				emmc_write_error_info(EMMC_FUNCNO_EXEC_CMD,
						      rtn_code);
			}
			return rtn_code;

		default:
			state = ESTATE_END;
			break;
		} /* switch (state) */
	} /* while ( (mmc_drv_obj.force_terminate != TRUE) && (state != ESTATE_END) ) */

	/* force terminate */
	if (mmc_drv_obj.force_terminate == TRUE) {
		/* timeout timer is expired. Or, PIO data transfer error. */
		/* Timeout occurred in the DMA transfer. */
		if (mmc_drv_obj.during_dma_transfer == TRUE) {
			mmc_drv_obj.during_dma_transfer = FALSE;
		}
		ERROR("BL2: emmc exec_cmd:EMMC_ERR_FORCE_TERMINATE\n");
		emmc_softreset();

		return EMMC_ERR_FORCE_TERMINATE; /* error information has already been written. */
	}

	/* success */
	mmc_drv_obj.during_cmd_processing = FALSE;
	mmc_drv_obj.during_transfer = FALSE;

	return EMMC_SUCCESS;
}
