xref: /arm-trusted-firmware/drivers/renesas/common/emmc/emmc_interrupt.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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