diff options
Diffstat (limited to 'drivers/renesas/rcar/emmc/emmc_cmd.c')
-rw-r--r-- | drivers/renesas/rcar/emmc/emmc_cmd.c | 492 |
1 files changed, 0 insertions, 492 deletions
diff --git a/drivers/renesas/rcar/emmc/emmc_cmd.c b/drivers/renesas/rcar/emmc/emmc_cmd.c deleted file mode 100644 index a2e25e339..000000000 --- a/drivers/renesas/rcar/emmc/emmc_cmd.c +++ /dev/null @@ -1,492 +0,0 @@ -/* - * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <common/debug.h> - -#include "emmc_config.h" -#include "emmc_hal.h" -#include "emmc_std.h" -#include "emmc_registers.h" -#include "emmc_def.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 (HAL_MEMCARD_DMA == mmc_drv_obj.transfer_mode) { - SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR); /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */ - 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 (HAL_MEMCARD_DMA == mmc_drv_obj.transfer_mode) { - SETR_32(CC_EXT_MODE, CC_EXT_MODE_CLEAR); /* W (CC_EXT_MODE, H'0000_1010) SD_BUF DMA transfer disabled */ - 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; -} |