1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights 3*91f16700Schasinglulu * reserved. 4*91f16700Schasinglulu * 5*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 6*91f16700Schasinglulu */ 7*91f16700Schasinglulu 8*91f16700Schasinglulu #include <stddef.h> 9*91f16700Schasinglulu 10*91f16700Schasinglulu #include <lib/mmio.h> 11*91f16700Schasinglulu 12*91f16700Schasinglulu #include "emmc_config.h" 13*91f16700Schasinglulu #include "emmc_def.h" 14*91f16700Schasinglulu #include "emmc_hal.h" 15*91f16700Schasinglulu #include "emmc_registers.h" 16*91f16700Schasinglulu #include "emmc_std.h" 17*91f16700Schasinglulu #include "rcar_def.h" 18*91f16700Schasinglulu 19*91f16700Schasinglulu static EMMC_ERROR_CODE emmc_trans_sector(uint32_t *buff_address_virtual); 20*91f16700Schasinglulu 21*91f16700Schasinglulu uint32_t emmc_interrupt(void) 22*91f16700Schasinglulu { 23*91f16700Schasinglulu EMMC_ERROR_CODE result; 24*91f16700Schasinglulu uint32_t prr_data; 25*91f16700Schasinglulu uint32_t cut_ver; 26*91f16700Schasinglulu uint32_t end_bit; 27*91f16700Schasinglulu 28*91f16700Schasinglulu prr_data = mmio_read_32((uintptr_t) RCAR_PRR); 29*91f16700Schasinglulu cut_ver = prr_data & PRR_CUT_MASK; 30*91f16700Schasinglulu if ((prr_data & PRR_PRODUCT_MASK) == PRR_PRODUCT_H3) { 31*91f16700Schasinglulu if (cut_ver == PRR_PRODUCT_10) { 32*91f16700Schasinglulu end_bit = BIT17; 33*91f16700Schasinglulu } else if (cut_ver == PRR_PRODUCT_11) { 34*91f16700Schasinglulu end_bit = BIT17; 35*91f16700Schasinglulu } else { 36*91f16700Schasinglulu end_bit = BIT20; 37*91f16700Schasinglulu } 38*91f16700Schasinglulu } else if ((prr_data & PRR_PRODUCT_MASK) == PRR_PRODUCT_M3) { 39*91f16700Schasinglulu if (cut_ver == PRR_PRODUCT_10) { 40*91f16700Schasinglulu end_bit = BIT17; 41*91f16700Schasinglulu } else { 42*91f16700Schasinglulu end_bit = BIT20; 43*91f16700Schasinglulu } 44*91f16700Schasinglulu } else { 45*91f16700Schasinglulu end_bit = BIT20; 46*91f16700Schasinglulu } 47*91f16700Schasinglulu 48*91f16700Schasinglulu /* SD_INFO */ 49*91f16700Schasinglulu mmc_drv_obj.error_info.info1 = GETR_32(SD_INFO1); 50*91f16700Schasinglulu mmc_drv_obj.error_info.info2 = GETR_32(SD_INFO2); 51*91f16700Schasinglulu 52*91f16700Schasinglulu /* SD_INFO EVENT */ 53*91f16700Schasinglulu mmc_drv_obj.int_event1 = 54*91f16700Schasinglulu mmc_drv_obj.error_info.info1 & GETR_32(SD_INFO1_MASK); 55*91f16700Schasinglulu mmc_drv_obj.int_event2 = 56*91f16700Schasinglulu mmc_drv_obj.error_info.info2 & GETR_32(SD_INFO2_MASK); 57*91f16700Schasinglulu 58*91f16700Schasinglulu /* ERR_STS */ 59*91f16700Schasinglulu mmc_drv_obj.error_info.status1 = GETR_32(SD_ERR_STS1); 60*91f16700Schasinglulu mmc_drv_obj.error_info.status2 = GETR_32(SD_ERR_STS2); 61*91f16700Schasinglulu 62*91f16700Schasinglulu /* DM_CM_INFO */ 63*91f16700Schasinglulu mmc_drv_obj.error_info.dm_info1 = GETR_32(DM_CM_INFO1); 64*91f16700Schasinglulu mmc_drv_obj.error_info.dm_info2 = GETR_32(DM_CM_INFO2); 65*91f16700Schasinglulu 66*91f16700Schasinglulu /* DM_CM_INFO EVENT */ 67*91f16700Schasinglulu mmc_drv_obj.dm_event1 = 68*91f16700Schasinglulu mmc_drv_obj.error_info.dm_info1 & GETR_32(DM_CM_INFO1_MASK); 69*91f16700Schasinglulu mmc_drv_obj.dm_event2 = 70*91f16700Schasinglulu mmc_drv_obj.error_info.dm_info2 & GETR_32(DM_CM_INFO2_MASK); 71*91f16700Schasinglulu 72*91f16700Schasinglulu /* ERR SD_INFO2 */ 73*91f16700Schasinglulu if ((SD_INFO2_ALL_ERR & mmc_drv_obj.int_event2) != 0) { 74*91f16700Schasinglulu SETR_32(SD_INFO1_MASK, 0x00000000U); /* interrupt disable */ 75*91f16700Schasinglulu SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); /* interrupt disable */ 76*91f16700Schasinglulu SETR_32(SD_INFO1, 0x00000000U); /* interrupt clear */ 77*91f16700Schasinglulu SETR_32(SD_INFO2, SD_INFO2_CLEAR); /* interrupt clear */ 78*91f16700Schasinglulu mmc_drv_obj.state_machine_blocking = FALSE; 79*91f16700Schasinglulu } 80*91f16700Schasinglulu 81*91f16700Schasinglulu /* PIO Transfer */ 82*91f16700Schasinglulu /* BWE/BRE */ 83*91f16700Schasinglulu else if (((SD_INFO2_BWE | SD_INFO2_BRE) & mmc_drv_obj.int_event2)) { 84*91f16700Schasinglulu /* BWE */ 85*91f16700Schasinglulu if (SD_INFO2_BWE & mmc_drv_obj.int_event2) { 86*91f16700Schasinglulu SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BWE)); 87*91f16700Schasinglulu } 88*91f16700Schasinglulu /* BRE */ 89*91f16700Schasinglulu else { 90*91f16700Schasinglulu SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BRE)); 91*91f16700Schasinglulu } 92*91f16700Schasinglulu 93*91f16700Schasinglulu result = emmc_trans_sector(mmc_drv_obj.buff_address_virtual); 94*91f16700Schasinglulu mmc_drv_obj.buff_address_virtual += EMMC_BLOCK_LENGTH; 95*91f16700Schasinglulu mmc_drv_obj.remain_size -= EMMC_BLOCK_LENGTH; 96*91f16700Schasinglulu 97*91f16700Schasinglulu if (result != EMMC_SUCCESS) { 98*91f16700Schasinglulu /* data transfer error */ 99*91f16700Schasinglulu emmc_write_error_info(EMMC_FUNCNO_NONE, result); 100*91f16700Schasinglulu 101*91f16700Schasinglulu /* Panic */ 102*91f16700Schasinglulu SETR_32(SD_INFO1_MASK, 0x00000000U); 103*91f16700Schasinglulu SETR_32(SD_INFO2_MASK, SD_INFO2_CLEAR); 104*91f16700Schasinglulu SETR_32(SD_INFO1, 0x00000000U); 105*91f16700Schasinglulu /* interrupt clear */ 106*91f16700Schasinglulu SETR_32(SD_INFO2, SD_INFO2_CLEAR); 107*91f16700Schasinglulu mmc_drv_obj.force_terminate = TRUE; 108*91f16700Schasinglulu } else { 109*91f16700Schasinglulu mmc_drv_obj.during_transfer = FALSE; 110*91f16700Schasinglulu } 111*91f16700Schasinglulu mmc_drv_obj.state_machine_blocking = FALSE; 112*91f16700Schasinglulu } 113*91f16700Schasinglulu 114*91f16700Schasinglulu /* DMA_TRANSFER */ 115*91f16700Schasinglulu /* DM_CM_INFO1: DMA-ch0 transfer complete or error occurred */ 116*91f16700Schasinglulu else if ((BIT16 & mmc_drv_obj.dm_event1) != 0) { 117*91f16700Schasinglulu SETR_32(DM_CM_INFO1, 0x00000000U); 118*91f16700Schasinglulu SETR_32(DM_CM_INFO2, 0x00000000U); 119*91f16700Schasinglulu /* interrupt clear */ 120*91f16700Schasinglulu SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BWE)); 121*91f16700Schasinglulu /* DM_CM_INFO2: DMA-ch0 error occurred */ 122*91f16700Schasinglulu if ((BIT16 & mmc_drv_obj.dm_event2) != 0) { 123*91f16700Schasinglulu mmc_drv_obj.dma_error_flag = TRUE; 124*91f16700Schasinglulu } else { 125*91f16700Schasinglulu mmc_drv_obj.during_dma_transfer = FALSE; 126*91f16700Schasinglulu mmc_drv_obj.during_transfer = FALSE; 127*91f16700Schasinglulu } 128*91f16700Schasinglulu /* wait next interrupt */ 129*91f16700Schasinglulu mmc_drv_obj.state_machine_blocking = FALSE; 130*91f16700Schasinglulu } 131*91f16700Schasinglulu /* DM_CM_INFO1: DMA-ch1 transfer complete or error occurred */ 132*91f16700Schasinglulu else if ((end_bit & mmc_drv_obj.dm_event1) != 0U) { 133*91f16700Schasinglulu SETR_32(DM_CM_INFO1, 0x00000000U); 134*91f16700Schasinglulu SETR_32(DM_CM_INFO2, 0x00000000U); 135*91f16700Schasinglulu /* interrupt clear */ 136*91f16700Schasinglulu SETR_32(SD_INFO2, (GETR_32(SD_INFO2) & ~SD_INFO2_BRE)); 137*91f16700Schasinglulu /* DM_CM_INFO2: DMA-ch1 error occurred */ 138*91f16700Schasinglulu if ((BIT17 & mmc_drv_obj.dm_event2) != 0) { 139*91f16700Schasinglulu mmc_drv_obj.dma_error_flag = TRUE; 140*91f16700Schasinglulu } else { 141*91f16700Schasinglulu mmc_drv_obj.during_dma_transfer = FALSE; 142*91f16700Schasinglulu mmc_drv_obj.during_transfer = FALSE; 143*91f16700Schasinglulu } 144*91f16700Schasinglulu /* wait next interrupt */ 145*91f16700Schasinglulu mmc_drv_obj.state_machine_blocking = FALSE; 146*91f16700Schasinglulu } 147*91f16700Schasinglulu 148*91f16700Schasinglulu /* Response end */ 149*91f16700Schasinglulu else if ((SD_INFO1_INFO0 & mmc_drv_obj.int_event1) != 0) { 150*91f16700Schasinglulu /* interrupt clear */ 151*91f16700Schasinglulu SETR_32(SD_INFO1, (GETR_32(SD_INFO1) & ~SD_INFO1_INFO0)); 152*91f16700Schasinglulu mmc_drv_obj.state_machine_blocking = FALSE; 153*91f16700Schasinglulu } 154*91f16700Schasinglulu /* Access end */ 155*91f16700Schasinglulu else if ((SD_INFO1_INFO2 & mmc_drv_obj.int_event1) != 0) { 156*91f16700Schasinglulu /* interrupt clear */ 157*91f16700Schasinglulu SETR_32(SD_INFO1, (GETR_32(SD_INFO1) & ~SD_INFO1_INFO2)); 158*91f16700Schasinglulu mmc_drv_obj.state_machine_blocking = FALSE; 159*91f16700Schasinglulu } else { 160*91f16700Schasinglulu /* nothing to do. */ 161*91f16700Schasinglulu } 162*91f16700Schasinglulu 163*91f16700Schasinglulu return (uint32_t) 0; 164*91f16700Schasinglulu } 165*91f16700Schasinglulu 166*91f16700Schasinglulu static EMMC_ERROR_CODE emmc_trans_sector(uint32_t *buff_address_virtual) 167*91f16700Schasinglulu { 168*91f16700Schasinglulu uint32_t length, i; 169*91f16700Schasinglulu uint64_t *bufPtrLL; 170*91f16700Schasinglulu 171*91f16700Schasinglulu if (buff_address_virtual == NULL) { 172*91f16700Schasinglulu return EMMC_ERR_PARAM; 173*91f16700Schasinglulu } 174*91f16700Schasinglulu 175*91f16700Schasinglulu if ((mmc_drv_obj.during_transfer != TRUE) 176*91f16700Schasinglulu || (mmc_drv_obj.remain_size == 0)) { 177*91f16700Schasinglulu return EMMC_ERR_STATE; 178*91f16700Schasinglulu } 179*91f16700Schasinglulu 180*91f16700Schasinglulu bufPtrLL = (uint64_t *) buff_address_virtual; 181*91f16700Schasinglulu length = mmc_drv_obj.remain_size; 182*91f16700Schasinglulu 183*91f16700Schasinglulu /* data transefer */ 184*91f16700Schasinglulu for (i = 0; i < (length >> 3); i++) { 185*91f16700Schasinglulu /* Write */ 186*91f16700Schasinglulu if (mmc_drv_obj.cmd_info.dir == HAL_MEMCARD_WRITE) { 187*91f16700Schasinglulu SETR_64(SD_BUF0, *bufPtrLL); /* buffer --> FIFO */ 188*91f16700Schasinglulu } 189*91f16700Schasinglulu /* Read */ 190*91f16700Schasinglulu else { 191*91f16700Schasinglulu /* Checks when the read data reaches SD_SIZE. */ 192*91f16700Schasinglulu /* The BRE bit is cleared at emmc_interrupt function. */ 193*91f16700Schasinglulu if (((i % 194*91f16700Schasinglulu (uint32_t) (EMMC_BLOCK_LENGTH >> 195*91f16700Schasinglulu EMMC_BUF_SIZE_SHIFT)) == 0U) 196*91f16700Schasinglulu && (i != 0U)) { 197*91f16700Schasinglulu /* BRE check */ 198*91f16700Schasinglulu while (((GETR_32(SD_INFO2)) & SD_INFO2_BRE) == 199*91f16700Schasinglulu 0U) { 200*91f16700Schasinglulu /* ERROR check */ 201*91f16700Schasinglulu if (((GETR_32(SD_INFO2)) & 202*91f16700Schasinglulu SD_INFO2_ALL_ERR) != 0U) { 203*91f16700Schasinglulu return EMMC_ERR_TRANSFER; 204*91f16700Schasinglulu } 205*91f16700Schasinglulu } 206*91f16700Schasinglulu /* BRE clear */ 207*91f16700Schasinglulu SETR_32(SD_INFO2, 208*91f16700Schasinglulu (uint32_t) (GETR_32(SD_INFO2) & 209*91f16700Schasinglulu ~SD_INFO2_BRE)); 210*91f16700Schasinglulu } 211*91f16700Schasinglulu *bufPtrLL = GETR_64(SD_BUF0); /* FIFO --> buffer */ 212*91f16700Schasinglulu } 213*91f16700Schasinglulu bufPtrLL++; 214*91f16700Schasinglulu } 215*91f16700Schasinglulu 216*91f16700Schasinglulu return EMMC_SUCCESS; 217*91f16700Schasinglulu } 218