1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
|
/*
* Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights
* reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stddef.h>
#include <lib/mmio.h>
#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 & PRR_CUT_MASK;
if ((prr_data & PRR_PRODUCT_MASK) == PRR_PRODUCT_H3) {
if (cut_ver == PRR_PRODUCT_10) {
end_bit = BIT17;
} else if (cut_ver == PRR_PRODUCT_11) {
end_bit = BIT17;
} else {
end_bit = BIT20;
}
} else if ((prr_data & PRR_PRODUCT_MASK) == PRR_PRODUCT_M3) {
if (cut_ver == PRR_PRODUCT_10) {
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 occurred */
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 occurred */
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 occurred */
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;
}
|