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