/* * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights * reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include "emmc_config.h" #include "emmc_def.h" #include "emmc_hal.h" #include "emmc_registers.h" #include "emmc_std.h" #include "rcar_def.h" static EMMC_ERROR_CODE emmc_trans_sector(uint32_t *buff_address_virtual); uint32_t emmc_interrupt(void) { EMMC_ERROR_CODE result; uint32_t prr_data; uint32_t cut_ver; uint32_t end_bit; prr_data = mmio_read_32((uintptr_t) RCAR_PRR); cut_ver = prr_data & RCAR_CUT_MASK; if ((prr_data & RCAR_PRODUCT_MASK) == RCAR_PRODUCT_H3) { if (cut_ver == RCAR_CUT_VER10) { end_bit = BIT17; } else if (cut_ver == RCAR_CUT_VER11) { end_bit = BIT17; } else { end_bit = BIT20; } } else if ((prr_data & RCAR_PRODUCT_MASK) == RCAR_PRODUCT_M3) { if (cut_ver == RCAR_CUT_VER10) { end_bit = BIT17; } else { end_bit = BIT20; } } else { end_bit = BIT20; } /* SD_INFO */ mmc_drv_obj.error_info.info1 = GETR_32(SD_INFO1); mmc_drv_obj.error_info.info2 = GETR_32(SD_INFO2); /* SD_INFO EVENT */ mmc_drv_obj.int_event1 = mmc_drv_obj.error_info.info1 & GETR_32(SD_INFO1_MASK); mmc_drv_obj.int_event2 = mmc_drv_obj.error_info.info2 & GETR_32(SD_INFO2_MASK); /* ERR_STS */ mmc_drv_obj.error_info.status1 = GETR_32(SD_ERR_STS1); mmc_drv_obj.error_info.status2 = GETR_32(SD_ERR_STS2); /* DM_CM_INFO */ mmc_drv_obj.error_info.dm_info1 = GETR_32(DM_CM_INFO1); mmc_drv_obj.error_info.dm_info2 = GETR_32(DM_CM_INFO2); /* DM_CM_INFO EVENT */ mmc_drv_obj.dm_event1 = mmc_drv_obj.error_info.dm_info1 & GETR_32(DM_CM_INFO1_MASK); mmc_drv_obj.dm_event2 = mmc_drv_obj.error_info.dm_info2 & GETR_32(DM_CM_INFO2_MASK); /* ERR SD_INFO2 */ if ((SD_INFO2_ALL_ERR & mmc_drv_obj.int_event2) != 0) { SETR_32(SD_INFO1_MASK, 0x00000000U); /* interrupt disable */ SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* interrupt disable */ SETR_32(SD_INFO1, 0x00000000U); /* interrupt clear */ SETR_32(SD_INFO2, SD_INFO2_CLEAR); /* interrupt clear */ mmc_drv_obj.state_machine_blocking = FALSE; } /* PIO Transfer */ /* BWE/BRE */ else if (((SD_INFO2_BWE | SD_INFO2_BRE) & mmc_drv_obj.int_event2)) { /* BWE */ if (SD_INFO2_BWE & mmc_drv_obj.int_event2) { SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BWE)); } /* BRE */ else { SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BRE)); } result = emmc_trans_sector(mmc_drv_obj.buff_address_virtual); mmc_drv_obj.buff_address_virtual += EMMC_BLOCK_LENGTH; mmc_drv_obj.remain_size -= EMMC_BLOCK_LENGTH; if (result != EMMC_SUCCESS) { /* data transfer error */ emmc_write_error_info(EMMC_FUNCNO_NONE, result); /* Panic */ SETR_32(SD_INFO1_MASK, 0x00000000U); SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); SETR_32(SD_INFO1, 0x00000000U); /* interrupt clear */ SETR_32(SD_INFO2, SD_INFO2_CLEAR); mmc_drv_obj.force_terminate = TRUE; } else { mmc_drv_obj.during_transfer = FALSE; } mmc_drv_obj.state_machine_blocking = FALSE; } /* DMA_TRANSFER */ /* DM_CM_INFO1: DMA-ch0 transfer complete or error occurred */ else if ((BIT16 & mmc_drv_obj.dm_event1) != 0) { SETR_32(DM_CM_INFO1, 0x00000000U); SETR_32(DM_CM_INFO2, 0x00000000U); /* interrupt clear */ SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BWE)); /* DM_CM_INFO2: DMA-ch0 error occured */ if ((BIT16 & mmc_drv_obj.dm_event2) != 0) { mmc_drv_obj.dma_error_flag = TRUE; } else { mmc_drv_obj.during_dma_transfer = FALSE; mmc_drv_obj.during_transfer = FALSE; } /* wait next interrupt */ mmc_drv_obj.state_machine_blocking = FALSE; } /* DM_CM_INFO1: DMA-ch1 transfer complete or error occured */ else if ((end_bit & mmc_drv_obj.dm_event1) != 0U) { SETR_32(DM_CM_INFO1, 0x00000000U); SETR_32(DM_CM_INFO2, 0x00000000U); /* interrupt clear */ SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BRE)); /* DM_CM_INFO2: DMA-ch1 error occured */ if ((BIT17 & mmc_drv_obj.dm_event2) != 0) { mmc_drv_obj.dma_error_flag = TRUE; } else { mmc_drv_obj.during_dma_transfer = FALSE; mmc_drv_obj.during_transfer = FALSE; } /* wait next interrupt */ mmc_drv_obj.state_machine_blocking = FALSE; } /* Response end */ else if ((SD_INFO1_INFO0 & mmc_drv_obj.int_event1) != 0) { /* interrupt clear */ SETR_32(SD_INFO1, (GETR_32(SD_INFO1) & ~SD_INFO1_INFO0)); mmc_drv_obj.state_machine_blocking = FALSE; } /* Access end */ else if ((SD_INFO1_INFO2 & mmc_drv_obj.int_event1) != 0) { /* interrupt clear */ SETR_32(SD_INFO1, (GETR_32(SD_INFO1) & ~SD_INFO1_INFO2)); mmc_drv_obj.state_machine_blocking = FALSE; } else { /* nothing to do. */ } return (uint32_t) 0; } static EMMC_ERROR_CODE emmc_trans_sector(uint32_t *buff_address_virtual) { uint32_t length, i; uint64_t *bufPtrLL; if (buff_address_virtual == NULL) { return EMMC_ERR_PARAM; } if ((mmc_drv_obj.during_transfer != TRUE) || (mmc_drv_obj.remain_size == 0)) { return EMMC_ERR_STATE; } bufPtrLL = (uint64_t *) buff_address_virtual; length = mmc_drv_obj.remain_size; /* data transefer */ for (i = 0; i < (length >> 3); i++) { /* Write */ if (mmc_drv_obj.cmd_info.dir == HAL_MEMCARD_WRITE) { SETR_64(SD_BUF0, *bufPtrLL); /* buffer --> FIFO */ } /* Read */ else { /* Checks when the read data reaches SD_SIZE. */ /* The BRE bit is cleared at emmc_interrupt function. */ if (((i % (uint32_t) (EMMC_BLOCK_LENGTH >> EMMC_BUF_SIZE_SHIFT)) == 0U) && (i != 0U)) { /* BRE check */ while (((GETR_32(SD_INFO2)) & SD_INFO2_BRE) == 0U) { /* ERROR check */ if (((GETR_32(SD_INFO2)) & SD_INFO2_ALL_ERR) != 0U) { return EMMC_ERR_TRANSFER; } } /* BRE clear */ SETR_32(SD_INFO2, (uint32_t) (GETR_32(SD_INFO2) & ~SD_INFO2_BRE)); } *bufPtrLL = GETR_64(SD_BUF0); /* FIFO --> buffer */ } bufPtrLL++; } return EMMC_SUCCESS; }