]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/drv/mmcsd/src/v2/MMCSD_v2.c
updating the placement of error detection based on testing
[processor-sdk/pdk.git] / packages / ti / drv / mmcsd / src / v2 / MMCSD_v2.c
1 /**
2  *  \file   MMCSD_v2.c
3  *
4  *  \brief  IP version 1 specific MMCSD Driver APIs implementation.
5  *
6  *   This file contains the driver APIs for MMCSD controller.
7  */
9 /*
10  * Copyright (C) 2017-2021 Texas Instruments Incorporated - http://www.ti.com/
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  *
16  * Redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer.
18  *
19  * Redistributions in binary form must reproduce the above copyright
20  * notice, this list of conditions and the following disclaimer in the
21  * documentation and/or other materials provided with the
22  * distribution.
23  *
24  * Neither the name of Texas Instruments Incorporated nor the names of
25  * its contributors may be used to endorse or promote products derived
26  * from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  */
42 #include <stdint.h>
43 #include <stdbool.h>
44 #include <ti/csl/csl_utils.h>
45 #include <ti/csl/hw_types.h>
46 #include <ti/csl/csl_error.h>
47 #include <ti/csl/csl_mmcsd.h>
48 #include <ti/drv/mmcsd/src/MMCSD_drv_log.h>
49 #include <ti/drv/mmcsd/MMCSD.h>
50 #include <ti/drv/mmcsd/soc/MMCSD_v2.h>
51 #include <ti/drv/mmcsd/src/v2/MMCSD_v2_lld.h>
52 #include <ti/drv/mmcsd/soc/MMCSD_soc.h>
53 #include <ti/drv/mmcsd/src/MMCSD_osal.h>
57 #define MMCSD_log                UART_printf
59 #define MMCSD_DEBUG_TRAP   {while(mmcsd_emuwait_trap);}
61 /** \brief Bit mask. */
62 #define BIT(x) (((uint32_t)1U) << (x))
64 /**
65  * SD Card information structure
66  */
68 /** \brief SD Commands enumeration. */
69 #define MMCSD_CMD(x)   (x)
71 /**
72  * Command/Response flags for notifying some information to controller
73  */
75 /** \brief To indicate no response. */
76 #define MMCSD_CMDRSP_NONE           (BIT(0U))
78 /** \brief Response to indicate stop condition. */
79 #define MMCSD_CMDRSP_STOP           (BIT(1U))
81 /** \brief Response to indicate stop condition. */
82 #define MMCSD_CMDRSP_FS             (BIT(2U))
84 /** \brief Response to indicate abort condition. */
85 #define MMCSD_CMDRSP_ABORT          (BIT(3U))
87 /** \brief Response to indicate bust state. */
88 #define MMCSD_CMDRSP_BUSY           (BIT(4U))
90 /** \brief Command to configure for 48bit R1 response */
91 #define MMCSD_CMDRSP_48BITS         (BIT(9U))
93 /** \brief Command to configure for 136 bits data width. */
94 #define MMCSD_CMDRSP_136BITS        (BIT(5U))
96 /** \brief Command to configure for data or response. */
97 #define MMCSD_CMDRSP_DATA           (BIT(6U))
99 /** \brief Command to configure for data read. */
100 #define MMCSD_CMDRSP_READ           (BIT(7U))
102 /** \brief Command to configure for data write. */
103 #define MMCSD_CMDRSP_WRITE          (BIT(8U))
105 /** \brief Command to configure for Read or Write interrupt */
106 #define MMCSD_CMDREQ_WR_RD          (BIT(31U))
108 /** \brief SD voltage enumeration as per VHS field, after the CHECK PATTERN FIELD */
109 #define MMCSD_VOLT_2P7_3P6          (0x000100U)
110 #define MMCSD_VOLT_LOW_RANGE        (0x000200U)
112 /**
113  * SD OCR register definitions.
114  */
116 /** \brief High capacity card type. */
117 #define MMCSD_OCR_HIGH_CAPACITY     (BIT(30U))
119 #define MMCSD_OCR_S18R  (BIT(24U))
120 /**
121  * Voltage configurations.
122  */
124 /** \brief Configure for 2.7V to 2.8V VDD level. */
125 #define MMCSD_OCR_VDD_2P7_2P8       (BIT(15U))
127 /** \brief Configure for 2.8V to 2.9V VDD level. */
128 #define MMCSD_OCR_VDD_2P8_2P9       (BIT(16U))
130 /** \brief Configure for 2.9V to 3.0V VDD level. */
131 #define MMCSD_OCR_VDD_2P9_3P0       (BIT(17U))
133 /** \brief Configure for 3.0V to 3.1V VDD level. */
134 #define MMCSD_OCR_VDD_3P0_3P1       (BIT(18U))
136 /** \brief Configure for 3.1V to 3.2V VDD level. */
137 #define MMCSD_OCR_VDD_3P1_3P2       (BIT(19U))
139 /** \brief Configure for 3.2V to 3.3V VDD level. */
140 #define MMCSD_OCR_VDD_3P2_3P3       (BIT(20U))
142 /** \brief Configure for 3.3V to 3.4V VDD level. */
143 #define MMCSD_OCR_VDD_3P3_3P4       (BIT(21U))
145 /** \brief Configure for 3.4V to 3.5V VDD level. */
146 #define MMCSD_OCR_VDD_3P4_3P5       (BIT(22U))
148 /** \brief Configure for 3.5V to 3.6V VDD level. */
149 #define MMCSD_OCR_VDD_3P5_3P6       (BIT(23U))
151 /** \brief Wild card to configure for VDD level. */
152 #define MMCSD_OCR_VDD_WILDCARD      (((uint32_t)0x1FFU) << 15U)
154 /**
155  * SD CSD register definitions.
156  */
158 /** \brief Card bus frequency configuration for 25 Mbps. */
159 #define MMCSD_TRANSPEED_25MBPS      (0x32U)
161 /** \brief Card bus frequency configuration for 50 Mbps. */
162 #define MMCSD_TRANSPEED_50MBPS      (0x5AU)
163 /** \brief Gives the card version. */
164 #define MMCSD_CARD_CMMCSD_VERSION(crd) \
165     (((crd)->csd[3U] & 0xC0000000U) >> 30U)
167 /** \brief Extract the size of device for SD version 0. */
168 #define MMCSD_CSD0_DEV_SIZE(csd3, csd2, csd1, csd0) \
169     ((uint64_t)(((csd2) & 0x000003FFU) << 2U) | (((csd1) & 0xC0000000U) >> 30U))
171 /** \brief TBD for SD version 0. */
172 #define MMCSD_CSD0_MULT(csd3, csd2, csd1, csd0) \
173     (((csd1) & 0x00038000U) >> 15U)
175 /** \brief Extract the read block length for SD version 0. */
176 #define MMCSD_CSD0_RDBLKLEN(csd3, csd2, csd1, csd0) \
177     (((csd2) & 0x000F0000U) >> 16U)
179 /** \brief Extract the card transfer speed for SD version 0. */
180 #define MMCSD_CSD0_TRANSPEED(csd3, csd2, csd1, csd0) \
181     (((csd3) & 0x000000FFU) >> 0U)
183 /** \brief Extracts the size of card for SD version 0. */
184 #define MMCSD_CARD0_DEV_SIZE(crd) \
185     (MMCSD_CSD0_DEV_SIZE((crd)->csd[3U], (crd)->csd[2U], \
186     (crd)->csd[1U], (crd)->csd[0U]))
188 /** \brief TBD for SD version 0. */
189 #define MMCSD_CARD0_MULT(crd) \
190     (MMCSD_CSD0_MULT((crd)->csd[3U], (crd)->csd[2U], \
191     (crd)->csd[1U], (crd)->csd[0U]))
193 /** \brief Gives the card block length for SD version 0. */
194 #define MMCSD_CARD0_RDBLKLEN(crd) \
195     (MMCSD_CSD0_RDBLKLEN((crd)->csd[3U], (crd)->csd[2U], \
196     (crd)->csd[1U], (crd)->csd[0U]))
198 /** \brief Gives the card transfer speed for SD version 0. */
199 #define MMCSD_CARD0_TRANSPEED(crd) \
200     (MMCSD_CSD0_TRANSPEED((crd)->csd[3U], (crd)->csd[2U], \
201     (crd)->csd[1U], (crd)->csd[0U]))
203 /** \brief Gives number of blocks on card for SD version 0. */
204 #define MMCSD_CARD0_NUMBLK(crd) \
205     ((MMCSD_CARD0_DEV_SIZE((crd)) + 1U) * \
206     (((uint32_t)1U) << (MMCSD_CARD0_MULT((crd)) + 2U)))
208 /** \brief Gives the size of card for SD version 0. */
209 #define MMCSD_CARD0_SIZE(crd) ((MMCSD_CARD0_NUMBLK((crd))) * \
210     (((uint32_t)1U) << (MMCSD_CARD0_RDBLKLEN(crd))))
212 /** \brief Extracts the size of card for SD version 1. */
213 #define MMCSD_CSD1_DEV_SIZE(csd3, csd2, csd1, csd0) \
214     ((uint64_t)(((csd2) & 0x0000003FU) << 16U) | (((csd1) & 0xFFFF0000U) >> 16U))
216 /** \brief Extracts the card block length for SD version 1. */
217 #define MMCSD_CSD1_RDBLKLEN(csd3, csd2, csd1, csd0) \
218     (((csd2) & 0x000F0000U) >> 16U)
220 /** \brief Extracts the card transfer speed for SD version 1. */
221 #define MMCSD_CSD1_TRANSPEED(csd3, csd2, csd1, csd0) \
222     (((csd3) & 0x000000FFU) >> 0U)
224 /** \brief Gives the size of card for SD version 1. */
225 #define MMCSD_CARD1_DEV_SIZE(crd) \
226     (MMCSD_CSD1_DEV_SIZE((crd)->csd[3U], (crd)->csd[2U], \
227     (crd)->csd[1U], (crd)->csd[0U]))
229 /** \brief Reads the card block length for SD version 1. */
230 #define MMCSD_CARD1_RDBLKLEN(crd) \
231     (MMCSD_CSD1_RDBLKLEN((crd)->csd[3U], (crd)->csd[2U], \
232     (crd)->csd[1U], (crd)->csd[0U]))
234 /** \brief Reads the card transfer speed for SD version 1. */
235 #define MMCSD_CARD1_TRANSPEED(crd) \
236     (MMCSD_CSD1_TRANSPEED((crd)->csd[3U], (crd)->csd[2U], \
237     (crd)->csd[1U], (crd)->csd[0U]))
239 /** \brief Gives the size of card for SD version 1. */
240 #define MMCSD_CARD1_SIZE(crd) (((MMCSD_CARD1_DEV_SIZE((crd)) + 1U) * \
241     (512U * 1024U)))
243 /** \brief This is the timeout value for sending CMD13 to the card.
244  * After every write, the CMD13 is sent this many times and wait for
245  * the card to go to transfer state
246  * */
247 #define MMCSD_CARD_TRANS_STATE_THRESHOLD  (10000U)
249 /* Card status value (Bits 9-12) as defined in physical layer
250  * specification section 4.10.1.
251  */
252 #define MMCSD_CARD_STATE_TRANSFER  (4U)
253 /**
254  * Check RCA/status.
255  */
257  /** \brief Command relative address. */
258 #define MMCSD_RCA_ADDR(rca)             (((rca) & 0xFFFF0000U) >> 16U)
260 /** \brief TBD. */
261 #define MMCSD_RCA_STAT(rca)             ((rca) & 0x0xFFFFU)
263 /** \brief Check pattern that can be used for card response validation. */
264 #define MMCSD_CHECK_PATTERN             (0xAAU)
266 /**
267  * SD SCR related macros.
268  */
270 /** \brief Card version 0. */
271 #define MMCSD_VERSION_1P0               (0U)
273 /** \brief Card version 1. */
274 #define MMCSD_VERSION_1P1               (1U)
276 /** \brief Card version 2. */
277 #define MMCSD_VERSION_2P0               (2U)
279 /**
280  * Helper macros.
281  * Note card registers are big endian.
282  */
284 /** \brief Reads card version. */
285 #define MMCSD_CARD_VERSION(sdcard)      (((sdcard)->scr[0U] & 0x0F000000U) >> 24)
287 /** \brief Reads card bus width. */
288 #define MMCSD_CARD_BUSWIDTH(sdcard) (((sdcard)->scr[0U] & 0x000F0000U) >> 16)
290 /** \brief Reads if the SD Card supports CMD23. */
291 #define MMCSD_CARD_CMD23_SUPPORT(sdcard) (((sdcard)->scr[0U] & 0x00000002U) >> 1)
293 /** \brief Check for bus width. Give below values
294  *         - MMCSD_BUS_WIDTH_1BIT for 1-bit.
295  *         - MMCSD_BUS_WIDTH_4BIT for 4-bit.
296  *         - 0xFFU                    for invalid bus width.
297  */
298 #define MMCSD_GET_CARD_BUSWIDTH(sdcard) \
299     (((((sdcard).busWidth) & 0x0FU) == 0x01) ? \
300     0x1 : (((((sdcard).busWidth) & 0x04U) == 0x04U) ? 0x04U : 0xFFU))
302 /** \brief Check for bus width. Give below values
303  *         - 50U for 50 MHz.
304  *         - 25U for 25 Mhz.
305  *         - 0U  for invalid bus width.
306  */
307 #define MMCSD_GET_CARD_FRE(sdcard) ((((sdcard).tranSpeed) == 0x5AU) ? 50U : \
308     ((((sdcard).tranSpeed) == 0x32U) ? 25U : \
309     ((((sdcard).tranSpeed) == 0xBU) ? 100U : \
310     ((((sdcard).tranSpeed) == 0x2BU) ? 200U : 0U))
312 /** \brief Define cache line size for buffer alignment. */
313 #ifndef SOC_CACHELINE_SIZE
314 #define SOC_CACHELINE_SIZE                  (128U)
315 #endif
317 /** \brief Command argument to configure for switch mode. */
318 #define MMCSD_SWITCH_MODE               (0x80FFFFFFU)
319 #define MMCSD_CHECK_MODE                (0x00FFFFFFU)
320 /** \brief Command argument width to configure for transfer speed. */
321 #define MMCSD_CMD6_GRP1_SEL             (0xFFFFFFF0U)
322 #define MMCSD_CMD6_GRP4_SEL             (0xFFFF0FFFU)
324 /** \brief Command argument to configure for default/SDR12 speed. */
325 #define MMCSD_CMD6_GRP1_DEFAULT         (0x0U)
326 /** \brief Command argument to configure for high/SDR25 speed. */
327 #define MMCSD_CMD6_GRP1_HS              (0x1U)
328 /** \brief Command argument to configure for SDR50 speed. */
329 #define MMCSD_CMD6_GRP1_SDR50           (0x2U)
330 /** \brief Command argument to configure for SDR104 speed. */
331 #define MMCSD_CMD6_GRP1_SDR104          (0x3U)
332 /** \brief Command argument to configure for DDR50 speed. */
333 #define MMCSD_CMD6_GRP1_DDR50           (0x4U)
335 #define MMCSD_CMD6_GRP4_200mA           (0x0U)
336 #define MMCSD_CMD6_GRP4_400mA           (0x1U)
337 #define MMCSD_CMD6_GRP4_600mA           (0x2U)
338 #define MMCSD_CMD6_GRP4_800mA           (0x3U)
341 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_INDEX  (196)
342 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_DS       (0x0U)
343 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS_26MHZ (0x1U)
344 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS_52MHZ (0x2U)
345 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS_DDR_52MHZ_1P8V (0x4U)
346 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS_DDR_52MHZ_1P2V (0x8U)
348 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS200_200MHZ_1P8V (0x10U)
349 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS200_200MHZ_1P2V (0x20U)
350 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS400_200MHZ_1P8V (0x40U)
351 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS400_200MHZ_1P2V (0x80U)
353 #define MMCSD_ECSD_BUS_WIDTH_INDEX (183U)
354 #define MMCSD_ECSD_BUS_WIDTH_1BIT       (0U)
355 #define MMCSD_ECSD_BUS_WIDTH_4BIT       (1U)
356 #define MMCSD_ECSD_BUS_WIDTH_8BIT       (2U)
357 #define MMCSD_ECSD_BUS_WIDTH_4BIT_DDR   (5U)
358 #define MMCSD_ECSD_BUS_WIDTH_8BIT_DDR   (6U)
360 #define MMCSD_ECSD_BUS_WIDTH_BUSWIDTH_MASK    (0x0FU)
361 #define MMCSD_ECSD_BUS_WIDTH_BUSWIDTH_SHIFT   (0U)
363 #define MMCSD_ECSD_BUS_WIDTH_ES_ENABLE    (0x80U)
365 #define MMCSD_ECSD_BUS_WIDTH_ES_MASK    (0x80U)
366 #define MMCSD_ECSD_BUS_WIDTH_ES_SHIFT   (7U)
368 #define MMCSD_ECSD_HS_TIMING_INDEX    (185U)
369 #define MMCSD_ECSD_HS_TIMING_BACKWARD_COMPATIBLE       (0U)
370 #define MMCSD_ECSD_HS_TIMING_HIGH_SPEED                (1U)
371 #define MMCSD_ECSD_HS_TIMING_HS200                     (2U)
372 #define MMCSD_ECSD_HS_TIMING_HS400                     (3U)
374 #define MMCSD_ECSD_STROBE_SUPPORT_INDEX         (184U)
375 #define MMCSD_ECSD_STROBE_SUPPORT_ENHANCED_DIS    (0U)
376 #define MMCSD_ECSD_STROBE_SUPPORT_ENHANCED_EN    (1U)
378 #define HS_MMCSD_INTR_ALL_ERR   (\
379         HS_MMCSD_INTR_ADMAERROR |\
380         HS_MMCSD_INTR_ACMDERR |\
381         HS_MMCSD_INTR_DATABITERR |\
382         HS_MMCSD_INTR_DATACRCERR |\
383         HS_MMCSD_INTR_DATATIMEOUT |\
384         HS_MMCSD_INTR_CMDINDXERR |\
385         HS_MMCSD_INTR_CMDBITERR |\
386         HS_MMCSD_INTR_CMDCRCERR |\
387         HS_MMCSD_INTR_CMDTIMEOUT\
390 volatile uint32_t mmcsd_emuwait_trap=1;
393 /* Tuning pattern for SDR104 mode */
394 static const uint8_t tuning_blk_pattern_4bit[] = {
395         0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
396         0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
397         0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
398         0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
399         0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
400         0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
401         0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
402         0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
403 };
404 /* Tuning pattern for HS200 mode */
405 static const uint8_t tuning_blk_pattern_8bit[] = {
406         0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
407         0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
408         0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
409         0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
410         0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
411         0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
412         0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
413         0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
414         0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
415         0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
416         0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
417         0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
418         0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
419         0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
420         0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
421         0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
422 };
424 #define BITMASK(n)      ((1 << (n)) - 1)        //!< Creates a bit mask with bits n:0 set
427 //! \brief insert a field into a 32 bit value using the CSL mask and shift fields
428 //! \param[in] val The initial value which will have the field inserted
429 //! \param[in] field The value to insert
430 //! \param[in] mask  The mask over the input value val where field will be inserted
431 //! \param[in] shift The least significant bit in the mask field
432 //! \return          The input parameter val with the value field inserted starting a bit shift
433 static inline uint32_t Bitfield_csl_set (uint32_t val, uint32_t field, uint32_t mask, int32_t shift)
435     return ( (val & ~mask) | (field << shift) );
438 //! \brief Return the size of an integer field (number of values that a bitfield can have)
439 //! \param[in] msb The most significant bit of the field
440 //! \param[in] lsb The least significant bit of the field
441 //! \return        The number of values the bit field can have
443 /* MMC functions */
444 static MMCSD_Error MMCSD_v2_close(MMCSD_Handle handle);
445 static MMCSD_Error MMCSD_v2_init(MMCSD_Handle handle);
446 static MMCSD_Error MMCSD_v2_open(MMCSD_Handle handle, MMCSD_Params params);
447 static MMCSD_Error MMCSD_v2_write(MMCSD_Handle handle,
448                                   uint8_t *buf,
449                                   uint32_t block,
450                                   uint32_t numBlks);
451 static MMCSD_Error MMCSD_v2_read(MMCSD_Handle handle,
452                                  uint8_t *buf,
453                                  uint32_t block,
454                                  uint32_t numBlks);
455 static MMCSD_Error MMCSD_v2_transfer(MMCSD_Handle handle,
456                                      MMCSD_v2_Transaction *transaction);
457 static MMCSD_Error MMCSD_v2_control(MMCSD_Handle handle, uint32_t cmd, const void *arg);
458 static MMCSD_Error MMCSD_v2_enableBootPartition(MMCSD_Handle handle, const uint8_t *partition);
459 static MMCSD_Error MMCSD_v2_initSd(MMCSD_Handle handle);
460 static MMCSD_Error MMCSD_v2_initEmmc(MMCSD_Handle handle);
461 static MMCSD_Error MMCSD_v2_setBusWidth(MMCSD_Handle handle, const uint32_t *busWidth);
462 static MMCSD_Error MMCSD_v2_setBusFreq(MMCSD_Handle handle, const uint32_t *busFreq);
463 static MMCSD_Error MMCSD_v2_getBusWidth(MMCSD_Handle handle, uint32_t *busWidth);
464 static MMCSD_Error MMCSD_v2_getBusFreq(MMCSD_Handle handle, uint32_t *busFreq);
465 static MMCSD_Error MMCSD_v2_getMediaParams(MMCSD_Handle handle, MMCSD_mediaParams *params);
466 static MMCSD_Error MMCSD_v2_getErrorStatus(MMCSD_Handle handle, uint32_t *errorStat);
467 void MMCSD_v2_hwiFxn(uintptr_t arg);
468 static void MMCSD_v2_cmdStatusFxn(uintptr_t arg);
469 static void MMCSD_v2_xferStatusFxn(uintptr_t arg);
471 static MMCSD_Error mmcsd_tuning_procedure(MMCSD_Handle handle);
472 static void MMCSD_v2_xferStatusFxn_CMD19(uintptr_t arg);
473 static void MMCSD_v2_controllerReset(MMCSD_v2_Object *,MMCSD_v2_HwAttrs const *);
474 static MMCSD_Error MMCSD_switch_card_speed(MMCSD_Handle handle,uint32_t cmd16_grp1_fn);
475 /* Delay function */
476 static void delay(uint32_t delayValue);
478 /* MMC function table for MMC implementation */
479 const MMCSD_FxnTable MMCSD_v2_FxnTable = {
480     &MMCSD_v2_close,
481     &MMCSD_v2_control,
482     &MMCSD_v2_init,
483     &MMCSD_v2_open,
484     &MMCSD_v2_write,
485     &MMCSD_v2_read
486 };
487 typedef struct {
488   uint32_t params;
489   uint32_t addrl;
490   uint32_t addrh;
491 } adma2_desc_t;
493 adma2_desc_t adma2_desc;
494 #if defined(__ARM_ARCH_7A__) || defined(__aarch64__) || ((__ARM_ARCH == 7) && (__ARM_ARCH_PROFILE == 'R'))
495 __attribute__((aligned(SOC_CACHELINE_SIZE))) // GCC way of aligning
496 #endif
498 void mmc_setupDescriptor(
499     adma2_desc_t *desc,  ///< pointer to descriptor head, NOT pointer to the address value within the decriptor.
500     uint32_t params,     ///< parameters for descriptor.
501     uint64_t address     ///< physical address to pack into the descriptor.
502     )
504   desc->params = params;
505   desc->addrl  = address & 0xffffffffu;
506   desc->addrh  = (address >> 32) & 0xffffu;
511 /* Wait for DAT0 to go low */
512 static int32_t MMCSD_v2_waitDat0(MMCSD_v2_HwAttrs const *hwAttrs);
513 static int32_t MMCSD_v2_waitDat0(MMCSD_v2_HwAttrs const *hwAttrs)
515   /* Check for DAT0 to go low */
516   volatile uint32_t present_state_reg;
517   do {
518      present_state_reg= HW_RD_REG32(hwAttrs->baseAddr + MMC_PSTATE);
519   } while( (present_state_reg & (1 << 20))!=(1<<20));
521   return STW_SOK;
524 /* Waits for cmd inhibit to go low */
525 static int32_t MMCSD_v2_waitCmdInhibit(MMCSD_v2_HwAttrs const *hwAttrs);
526 static int32_t MMCSD_v2_waitCmdInhibit(MMCSD_v2_HwAttrs const *hwAttrs)
528   uint32_t ready=1;
529   do {
530      ready=*((volatile uint32_t *)(hwAttrs->baseAddr + MMC_PSTATE)) & 0x1;
531    } while(ready!=0);
532    return STW_SOK;
534 /* Waits for data inhibit to go low */
535 static int32_t MMCSD_v2_waitDatInhibit(MMCSD_v2_HwAttrs const *hwAttrs);
536 static int32_t MMCSD_v2_waitDatInhibit(MMCSD_v2_HwAttrs const *hwAttrs)
538   uint32_t ready=1;
539   /* Check for  DAT inhibit */
540   do {
541     ready=*((volatile uint32_t *)(hwAttrs->baseAddr + MMC_PSTATE)) & 0x2;
542   } while(ready!=0);
543   return STW_SOK;
545 /* Waits for data inhibit to go low */
546 uint32_t MMCSD_v2_getCmdInhibit(MMCSD_v2_HwAttrs *hwAttrs)
548   uint32_t cmd_inhibit;
549   /* Check for  DAT inhibit */
550   cmd_inhibit=*((volatile uint32_t *)(hwAttrs->baseAddr + MMC_PSTATE)) & 0x1;
551   return cmd_inhibit;
553 /* Waits for data inhibit to go low */
554 uint32_t MMCSD_v2_getDatInhibit(MMCSD_v2_HwAttrs *hwAttrs)
556   uint32_t dat_inhibit;
557   /* Check for  DAT inhibit */
558   dat_inhibit=*((volatile uint32_t *)(hwAttrs->baseAddr + MMC_PSTATE)) & 0x2;
559   return dat_inhibit;
562 /* Function to check if the media is ready to accept read/write transfers */
563 static MMCSD_Error mmcsd_check_transfer_ready(MMCSD_Handle handle)
565     MMCSD_Error                 ret = MMCSD_ERR;
566     uint32_t                    cmd13_try_count = 0U;
567     uint32_t                    current_state = 0U;
568     MMCSD_v2_Object            *object = NULL;
569     MMCSD_v2_Transaction        transaction;
571     /* Get the pointer to the object and hwAttrs */
572     object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
573      /*
574       * Send CMD13 to check if the card is still in the programming state.
575       * The card needs to go to transfer state before it can send/receive data
576       */
577      cmd13_try_count=0;
578      do {
579                 memset(&transaction,0,sizeof(transaction));
580         transaction.cmd = MMCSD_CMD(13U);
581         transaction.flags = MMCSD_CMDRSP_48BITS;
582         transaction.arg = object->rca << 16U;
583         ret = MMCSD_v2_transfer(handle, &transaction);
584         cmd13_try_count++;
585         /* 'Current state' can be found from bits[9-12] of Card Status Register
586          * in the response R1 */
587         current_state=(transaction.response[0] >> (9U) & (0xFU));
589         if(current_state==MMCSD_CARD_STATE_TRANSFER) {
590                    ret = MMCSD_OK;
591                    break;
592                 }
593      } while(cmd13_try_count < MMCSD_CARD_TRANS_STATE_THRESHOLD);
595      return(ret);
597 /* Function to send the block count prior to read/write transfers. This is 
598 used for better throughput */
599 static MMCSD_Error mmcsd_send_cmd23(MMCSD_Handle handle, uint32_t numBlks)
601     MMCSD_Error                 ret = MMCSD_ERR;
602     MMCSD_v2_Transaction        transaction;
604      /*
605       * Send CMD13 to check if the card is still in the programming state.
606       * The card needs to go to transfer state before it can send/receive data
607       */
608                 memset(&transaction,0,sizeof(transaction));
609         transaction.cmd = MMCSD_CMD(23U);
610         transaction.flags = MMCSD_CMDRSP_48BITS;
611         transaction.arg = numBlks;
612         ret = MMCSD_v2_transfer(handle, &transaction);
614         return(ret);
618 /*
619  *  ======== MMCSD_v2_write ========
620  */
621 static MMCSD_Error MMCSD_v2_write(MMCSD_Handle handle,
622                            uint8_t *buf,
623                            uint32_t block,
624                            uint32_t numBlks)
626     MMCSD_Error                 ret = MMCSD_ERR;
627     uint32_t                    key;
628     uint32_t                    address = 0U;
629     uint32_t                    isrErr = MMCSD_ISR_RET_OK;
630     MMCSD_v2_Object            *object = NULL;
631     MMCSD_v2_Transaction        transaction;
633     /* Input parameter validation */
634     if ((handle != NULL) && (buf != NULL))
635     {
636         /* Get the pointer to the object and hwAttrs */
637         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
639         object->writeBufIdx = buf;
640         object->writeBlockCount = numBlks;
642         /* Determine if the device index was already opened */
643         key = MMCSD_osalHardwareIntDisable();
644         if(0 != ((MMCSD_v2_Object *)(((MMCSD_Config *) handle)->object))->isOpen)
645         {
646             ret = MMCSD_OK;
647         }
648         MMCSD_osalHardwareIntRestore(key);
649     }
651      /*
652       * Send CMD13 to check if the card is still in the programming state.
653       * The card needs to go to transfer state before it can send/receive data
654       */
655     if(MMCSD_OK == ret)
656     {
657        ret = mmcsd_check_transfer_ready(handle);
658     }
659         
660         if((MMCSD_OK == ret) && object->cmd23Supported)
661         {
662       ret = mmcsd_send_cmd23(handle,numBlks);
663     }
664     if(MMCSD_OK == ret)
665     {
666         /*
667          * Address is in blks for high cap cards and in actual bytes
668          * for standard capacity cards
669          */
670         if (0 != object->highCap)
671         {
672             address = block;
673         }
674         else
675         {
676             address = block * object->blockSize;
677         }
679         transaction.flags = MMCSD_CMDRSP_WRITE | MMCSD_CMDRSP_DATA | MMCSD_CMDREQ_WR_RD;
680         transaction.arg = address;
681         transaction.blockCount = numBlks;
682         transaction.blockSize = object->blockSize;
683         transaction.dataBuf = buf;
685         if (numBlks > 1U)
686         {
687             transaction.cmd = MMCSD_CMD(25U);
688             // transaction.flags |= MMCSD_CMDRSP_ABORT;
689         }
690         else
691         {
692             transaction.cmd = MMCSD_CMD(24U);
693         }
695         ret = MMCSD_v2_transfer(handle, &transaction);
696                 isrErr = object->intStatusErr;
697     } else {
698                 MMCSD_DEBUG_TRAP
699         }       
701     if(MMCSD_OK == ret && (!object->cmd23Supported))
702     {
703                 /* Send a STOP */
704         if (transaction.blockCount > 1U)
705         {
706                         memset(&transaction,0,sizeof(transaction));
707                         transaction.cmd  = MMCSD_CMD(12U);
708             transaction.flags = MMCSD_CMDRSP_BUSY;
709             transaction.arg = 0U;
711             ret = MMCSD_v2_transfer(handle, &transaction);
712         }
713     }
714     if ((ret != MMCSD_OK) || (isrErr != MMCSD_ISR_RET_OK))
715     {
716             ret = MMCSD_ERR;
717         }
718     return (ret);
721 /*
722  *  ======== MMCSD_v2_read ========
723  */
724 static MMCSD_Error MMCSD_v2_read(MMCSD_Handle handle,
725                           uint8_t *buf,
726                           uint32_t block,
727                           uint32_t numBlks)
729     MMCSD_Error                 ret = MMCSD_ERR;
730     uint32_t                    key;
731     uint32_t                    address = 0U;
732     uint32_t                    isrErr = MMCSD_ISR_RET_OK;
733     MMCSD_v2_Object            *object = NULL;
734     MMCSD_v2_Transaction        transaction;
736     /* Input parameter validation */
737     if ((handle != NULL) && (buf != NULL))
738     {
739         /* Get the pointer to the object and hwAttrs */
740         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
742         object->readBufIdx = buf;
743         object->readBlockCount = numBlks;
745         /* Determine if the device index was already opened */
746         key = MMCSD_osalHardwareIntDisable();
747         if(0 != ((MMCSD_v2_Object *)(((MMCSD_Config *) handle)->object))->isOpen)
748         {
749             ret = MMCSD_OK;
750         }
751         MMCSD_osalHardwareIntRestore(key);
752     }
754      /*
755       * Send CMD13 to check if the card is still in the programming state.
756       * The card needs to go to transfer state before it can send/receive data
757       */
758     if(MMCSD_OK == ret)
759     {
760        ret = mmcsd_check_transfer_ready(handle);
761     }
762         
763         if((MMCSD_OK == ret) && object->cmd23Supported)
764         {
765       ret = mmcsd_send_cmd23(handle,numBlks);
766     }
768     if(MMCSD_OK == ret)
769     {
770         /*
771          * Address is in blks for high cap cards and in actual bytes
772          * for standard capacity cards
773          */
774         if (0 != object->highCap)
775         {
776             address = block;
777         }
778         else
779         {
780             address = block * object->blockSize;
781         }
783         transaction.flags = MMCSD_CMDRSP_READ | MMCSD_CMDRSP_DATA | MMCSD_CMDREQ_WR_RD;
784         transaction.arg = address;
785         transaction.blockCount = numBlks;
786         transaction.blockSize = object->blockSize;
787         transaction.dataBuf = buf;
789         if (numBlks > 1U)
790         {
791             transaction.cmd = MMCSD_CMD(18U);
792         }
793         else
794         {
795             transaction.cmd = MMCSD_CMD(17U);
796         }
798         ret = MMCSD_v2_transfer(handle, &transaction);
799                 isrErr = object->intStatusErr;
800     } else {
801                 MMCSD_DEBUG_TRAP
802         }       
804         
805     if((MMCSD_OK == ret)  && (!object->cmd23Supported))
806     {
807         /* Send a STOP */
808         if (transaction.blockCount > 1U)
809         {
810                     memset(&transaction,0,sizeof(transaction));
811                     transaction.cmd  = MMCSD_CMD(12U);
812             transaction.flags = MMCSD_CMDRSP_BUSY;
813             transaction.arg = 0U;
814             ret = MMCSD_v2_transfer(handle, &transaction);
815         }
816     }
817     if ((ret != MMCSD_OK) || (isrErr != MMCSD_ISR_RET_OK))
818     {
819             ret = MMCSD_ERR;
820     }
821     return (ret);
824 /*
825  *  ======== MMCSD_v2_close ========
826  */
827 static MMCSD_Error MMCSD_v2_close(MMCSD_Handle handle)
829     MMCSD_v2_Object        *object = NULL;
830     MMCSD_v2_HwAttrs const *hwAttrs = NULL;
831     MMCSD_Error             ret = MMCSD_OK;
833     /* Input parameter validation */
834     if (handle == NULL)
835     {
836         ret = MMCSD_ERR;
837     }
838     else
839     {
840         /* Get the pointer to the object and hwAttrs */
841         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
842         hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
844         ret = MMCSD_socPhyConfigure((MMCSD_v2_HwAttrs const *)hwAttrs, MODE_DEFAULT, 0, 0);
845         if(ret != MMCSD_OK)
846         {
847             MMCSD_DEBUG_TRAP
848         }
850         if(0U != hwAttrs->enableInterrupt)
851         {
852            /* Release the interrupt path */
853            if (hwAttrs->configSocIntrPath!=NULL) {
854               ret = hwAttrs->configSocIntrPath((const void *)hwAttrs,FALSE);
855             }
857            if(ret==MMCSD_OK) {
858            /* Unregister the interrupt */
859            MMCSD_osalHardwareIntDestruct(object->hwi,hwAttrs->eventId);
860            }
861         }
863         if(object->switched_to_v18)
864         {
866           if(object->switched_to_v18 && hwAttrs->switchVoltageFxn!=NULL) {
867             MMCSD_drv_log(Diags_USER1,"Switch to 1.8V indicated. Switching back to 3.3V\n");
868               ret=hwAttrs->switchVoltageFxn(hwAttrs->instNum,MMCSD_BUS_VOLTAGE_3_3V);
869           }
871           HSMMCSDSwitchSignalVoltage (hwAttrs->baseAddr, MMC_AC12_V1V8_SIGEN_3V3);
872           /* Wait for 5 ms */
873           Osal_delay(5);
875           /* wait if the signal voltage bit is set to 1 */
876           if(HSMMCSDGetSignalVoltage (hwAttrs->baseAddr)==!MMC_AC12_V1V8_SIGEN_3V3) {
877             MMCSD_DEBUG_TRAP
878           }
879         }
880         /* Destruct the instance lock */
881         MMCSD_osalDeleteBlockingLock(object->commandMutex);
882         MMCSD_osalDeleteBlockingLock(object->transferMutex);
883         MMCSD_osalDeleteBlockingLock(object->commandComplete);
884         MMCSD_osalDeleteBlockingLock(object->dataBufferCopyComplete);
885         MMCSD_osalDeleteBlockingLock(object->transferComplete);
887         memset(object, 0, sizeof(MMCSD_v2_Object));
889     #ifdef LOG_EN
890         MMCSD_drv_log4(Diags_USER1, "MMCSD: Object closed 0x%x", hwAttrs->baseAddr);
891     #endif
892     }
893     return (ret);
896 /*
897  *  ======== MMCSD_v2_init ========
898  */
899 static MMCSD_Error MMCSD_v2_init(MMCSD_Handle handle)
901     MMCSD_Error          ret = MMCSD_ERR;
903     /* Input parameter validation */
904     if (handle != NULL)
905     {
906         if (((MMCSD_Config *) handle)->object != NULL)
907         {
908             /* Initialize all variables to 0 */
909             memset(((MMCSD_Config *) handle)->object,0,sizeof(MMCSD_v2_Object));
910             ret = MMCSD_OK;
911         }
912     }
913         
914     return (ret);
917 /*
918  *  ======== MMCSD_enableBootPartitionAccess ========
919  */
920 static MMCSD_Error MMCSD_v2_enableBootPartition(MMCSD_Handle handle, const uint8_t *partition)
922     MMCSD_v2_Transaction transaction;
923     MMCSD_Error          ret = MMCSD_OK;
924     uint32_t             argument = 0;
925     uint8_t              bootAck = 1;
926     uint8_t              bootPartition = 0;
927     uint8_t              bootBusWidth = 0;
929     if((*partition == 1) || (*partition == 2))
930     {
931         bootPartition = ((bootAck << 6) | (*partition << 3) | (*partition));
932         /* Setting x8 bus width */
933         bootBusWidth = 0x02;
934         argument = (uint32_t)((bootPartition << 8) | (0xB3 << 16) | (0x03 << 24));
936         if(MMCSD_OK == ret)
937         {
938             /* Used CMD6(Switch Command) for configuring the extended CSD register */
939             transaction.cmd = MMCSD_CMD(6U);
940             transaction.arg = argument;
941             transaction.flags = 0U;
942             ret = MMCSD_v2_transfer(handle, &transaction);
943         }
944         Osal_delay(5);
946         if(MMCSD_OK == ret)
947         {
948             argument = (uint32_t)((bootBusWidth << 8) | (0xB1 << 16) | (0x03 << 24));
949             /* Used CMD6(Switch Command) for configuring the extended CSD register */
950             transaction.cmd = MMCSD_CMD(6U);
951             transaction.arg = argument;
952             transaction.flags = 0U;
953             ret = MMCSD_v2_transfer(handle, &transaction);
954         }
955         Osal_delay(5);
956     }
957     else
958     {
959         return MMCSD_ERR;
960     }
962     return(ret);
965 /*
966  *  ======== MMCSD_v2_open ========
967  */
968 static MMCSD_Error MMCSD_v2_open(MMCSD_Handle handle, MMCSD_Params params)
970     SemaphoreP_Params           semParams;
971     MMCSD_Error                 ret = MMCSD_ERR;
972     uint32_t                    key;
973     MMCSD_v2_Object            *object = NULL;
974     MMCSD_v2_HwAttrs           *hwAttrs = NULL;
975     OsalRegisterIntrParams_t interruptRegParams;
976     OsalInterruptRetCode_e interruptRegRet;
978     /* Input parameter validation */
979     if (handle != NULL)
980     {
981         /* Get the pointer to the object and hwAttrs */
982         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
983         hwAttrs = (MMCSD_v2_HwAttrs *)((MMCSD_Config *) handle)->hwAttrs;
985         /* Determine if the device index was already opened */
986         key = MMCSD_osalHardwareIntDisable();
987         if (0 == ((MMCSD_v2_Object *)(((MMCSD_Config *) handle)->object))->isOpen)
988         {
989             ret = MMCSD_OK;
990         }
991         MMCSD_osalHardwareIntRestore(key);
992     }
994     if(MMCSD_OK == ret)
995     {
996         /* Store the MMC parameters */
997         if (params == NULL)
998         {
999             /* No params passed in, so use the defaults */
1000             MMCSD_Params_init(&(object->MMCSDConfigParams));
1001         }
1002         else
1003         {
1004             /* Copy the params contents */
1005             object->MMCSDConfigParams.custom = ((MMCSD_ConfigParams *) params)->custom;
1006         }
1007     }
1009     if(MMCSD_OK == ret)
1010     {
1011         if(0U != hwAttrs->enableInterrupt)
1012         {
1014            if(MMCSD_OK == ret && (hwAttrs->configSocIntrPath!=NULL)){
1015              ret = hwAttrs->configSocIntrPath(hwAttrs,TRUE);
1016            }
1017             /* Construct Hwi object for this MMCSD peripheral */
1019                     if(ret==MMCSD_OK) {
1020                     /* Initialize with defaults */
1021             Osal_RegisterInterrupt_initParams(&interruptRegParams);
1023             interruptRegParams.corepacConfig.isrRoutine = (&MMCSD_v2_hwiFxn);
1024             interruptRegParams.corepacConfig.arg = (uintptr_t)handle;
1026                         /* Populate the interrupt parameters */
1027             interruptRegParams.corepacConfig.name=NULL;
1029             interruptRegParams.corepacConfig.corepacEventNum=hwAttrs->eventId; /* Event going in to CPU */
1030             interruptRegParams.corepacConfig.intVecNum=hwAttrs->intNum; /* Host Interrupt vector */
1032                /* Register interrupts */
1033             interruptRegRet=MMCSD_osalRegisterInterrupt(&interruptRegParams,&(object->hwi));
1034             if(interruptRegRet!=OSAL_INT_SUCCESS) {
1035               ret=MMCSD_ERR;
1036             }
1037            } else {
1038                            ret=MMCSD_ERR_SET_SOC_INTERRUPT_PATH;
1039                    }
1040         }
1042         /*
1043          * Construct thread safe handles for this MMCSD peripheral
1044          * Semaphore to provide exclusive access to the MMCSD peripheral
1045          */
1046         MMCSD_osalSemParamsInit(&semParams);
1047         semParams.mode = SemaphoreP_Mode_BINARY;
1048         object->commandMutex = MMCSD_osalCreateBlockingLock(1U, &semParams);
1049         object->transferMutex = MMCSD_osalCreateBlockingLock(1U, &semParams);
1050         object->commandComplete = MMCSD_osalCreateBlockingLock(0, &semParams);
1051                 object->dataBufferCopyComplete = MMCSD_osalCreateBlockingLock(0, &semParams);
1052         object->transferComplete = MMCSD_osalCreateBlockingLock(0, &semParams);
1054     }
1056     if ((MMCSD_OK == ret) && (hwAttrs->inputClockControl)) {
1057        /* Get the input clock value from the system*/
1058         uint32_t inputClockRet;
1059         inputClockRet=hwAttrs->inputClockControl(hwAttrs->instNum,NULL,MMCSD_INPUT_CLOCK_CTRL_GET);
1060         if(inputClockRet!=0) {
1062           if(inputClockRet!=hwAttrs->inputClk) {
1063                   MMCSD_drv_log4(Diags_USER1,"Input clock[%d] to MMC is different from what is set in hwAttrs\n",inputClockRet);
1064              hwAttrs->inputClk=inputClockRet;
1065           }
1066         } else {
1067          MMCSD_drv_log(Diags_USER1,"Something is wrong. Input clock is not enabled!!\n");
1068          ret = MMCSD_ERR;
1069        }
1070     }
1072     if(MMCSD_OK == ret)
1073     {
1074         object->cardType = hwAttrs->cardType;
1076         if (MMCSD_CARD_SD == object->cardType)
1077         {
1078             ret = MMCSD_v2_initSd(handle);
1079         }
1080         else if (MMCSD_CARD_EMMC == object->cardType)
1081         {
1082             ret = MMCSD_v2_initEmmc(handle);
1083         }
1084         else
1085         {
1086             ret = MMCSD_ERR; /*dummy statement for misra warning*/
1087         }
1088     }
1090     /* Mark the object as in use */
1091     if(MMCSD_OK == ret)
1092     {
1093         ((MMCSD_v2_Object *)(((MMCSD_Config *) handle)->object))->isOpen = 1;
1094     }
1096     return (ret);
1098 /* Data buffer for message transmission, it is not stack allocated to allow cache aligning */
1099 static uint8_t dataBuffer[512] __attribute__((aligned(256)));
1101 static uint8_t cmd6_response_buf[512] __attribute__((aligned(256)));
1103 /*
1104  *  ======== MMCSD_v2_initSd ========
1105  */
1106 static MMCSD_Error MMCSD_v2_initSd(MMCSD_Handle handle)
1108     MMCSD_Error                 ret = MMCSD_OK;
1109     uint32_t                    retry = 0xFFFFU;
1110     MMCSD_v2_Object            *object = NULL;
1111     MMCSD_v2_HwAttrs const     *hwAttrs = NULL;
1112     MMCSD_v2_Transaction        transaction;
1113     volatile int32_t            status = CSL_ESYS_FAIL;
1114     stSDMMCHCCapability         hcCap = {0U, 0U, 0U, 0U};
1115     bool support18V_host=FALSE;
1116         bool attempt_18V_switch=TRUE; /* Always be optimistic to start with, unless some cards do not work well with it */
1118     /* Get the pointer to the object and hwAttrs */
1119     object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
1120     hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
1122     if(hwAttrs->switchVoltageFxn != NULL)
1123     {
1124         support18V_host=((hwAttrs->supportedBusVoltages & MMCSD_BUS_VOLTAGE_1_8V))?TRUE:FALSE;
1125     }
1126         memset(dataBuffer,0,sizeof(dataBuffer));
1128     MMCSD_socPhyInit(hwAttrs);
1129         
1130     if(MMCSD_OK == ret)
1131     {
1132         /*
1133          * Refer to the MMC Host and Bus configuration steps in TRM
1134          * controller Reset
1135          */
1136         status = HSMMCSDSoftReset(hwAttrs->baseAddr);
1138         if (STW_SOK != status)
1139         {
1140 #ifdef LOG_EN
1141             MMCSD_drv_log4(Diags_USER1,
1142                     "MMCSD:(%p) HS MMC/SD Reset failed\n", hwAttrs->baseAddr);
1143 #endif
1144             ret = MMCSD_ERR;
1145         }
1146         else
1147         {
1148             ret = MMCSD_OK;
1149         }
1150     }
1152     if (MMCSD_OK == ret)
1153     {
1154         /* Lines Reset */
1155         status = HSMMCSDLinesReset(hwAttrs->baseAddr, HS_MMCSD_ALL_RESET);
1156         if(status!=STW_SOK) {
1157             MMCSD_DEBUG_TRAP
1158         }
1160         /* Set the bus width */
1161         status = HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_1BIT);
1162         if(status!=STW_SOK) {
1163             MMCSD_DEBUG_TRAP
1164         }
1166         /* Set the bus voltage */
1167                 if(hwAttrs->supportedBusVoltages & MMCSD_BUS_VOLTAGE_3_3V) {
1168            status=HSMMCSDBusVoltSet(hwAttrs->baseAddr, MMC_HCTL_SDVS_3V3); /* Default */
1169            if(status!=STW_SOK) {
1170                MMCSD_DEBUG_TRAP
1171            }
1173                 } else  if((hwAttrs->supportedBusVoltages & MMCSD_BUS_VOLTAGE_1_8V) &&
1174                    (hwAttrs->switchVoltageFxn != NULL)) {
1175            status = HSMMCSDBusVoltSet (hwAttrs->baseAddr, MMC_HCTL_SDVS_1V8);
1176            if(status!=STW_SOK) {
1177                MMCSD_DEBUG_TRAP
1178            }
1180         }
1182       /* Card detection */
1183    if(MMCSD_OK == ret)
1184    {
1185       uint32_t slotType,reg=0,ins=0;
1186       slotType = CSL_MMC_CTLCFG_CAPABILITIES_SLOT_TYPE_VAL_REMOVABLE;
1188       reg = *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->CTL_CFG_2_REG));
1189       reg = Bitfield_csl_set (reg, slotType,
1190                             CSL_MMC_SSCFG_CTL_CFG_2_REG_SLOTTYPE_MASK,
1191                             CSL_MMC_SSCFG_CTL_CFG_2_REG_SLOTTYPE_SHIFT);
1192        *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->CTL_CFG_2_REG))=reg;
1194       //
1195       // Enable pins by setting the IO mux field in the phy to 0.
1196       //
1197       reg = *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->PHY_CTRL_1_REG));
1198       reg = Bitfield_csl_set (reg, 0,
1199                             CSL_MMC_SSCFG_PHY_CTRL_1_REG_IOMUX_ENABLE_MASK,
1200                             CSL_MMC_SSCFG_PHY_CTRL_1_REG_IOMUX_ENABLE_SHIFT);
1201       *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->PHY_CTRL_1_REG))=reg;
1203       //
1204       // Wait for card detect.
1205       //
1206        ins=0;
1207        do {
1208           ins = HSMMCSDIsCardInserted(hwAttrs->baseAddr);
1209        } while(ins==0);
1210     }
1211         /* Bus power on */
1212         status = ((int32_t)(HSMMCSDBusPower(hwAttrs->baseAddr, MMC_HCTL_SDBP_PWRON)));
1213         if(status!=STW_SOK) {
1214             MMCSD_DEBUG_TRAP
1215         }
1217          status= HSMMCSDDataTimeoutSet(hwAttrs->baseAddr, MMC_SYSCTL_DTO_15THDTO);
1218         if(status!=STW_SOK) {
1219             MMCSD_DEBUG_TRAP
1220         }
1221         hcCap.flag1=HS_MMCSD_CAPA_ALL;
1222         hcCap.flag2=HS_MMCSD_CAPA_ALL;
1223         status = HSMMCSDHostCapabilityGet(hwAttrs->baseAddr,&hcCap);
1224         if(status!=STW_SOK) {
1225             MMCSD_DEBUG_TRAP
1226         }
1228                 object->switched_to_v18=FALSE;
1229         if (STW_SOK != status)
1230         {
1231 #ifdef LOG_EN
1232             MMCSD_drv_log4(Diags_USER1,
1233                     "MMCSD:(%p) HS MMC/SD Power on failed\n", hwAttrs->baseAddr);
1234 #endif
1235             ret = MMCSD_ERR;
1236         }
1237     }
1239     if (MMCSD_OK == ret)
1240     {
1241         /* Set the initialization frequency */
1242         status = HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk,hwAttrs->outputClk, FALSE);
1244          Osal_delay(10);
1245         if(status !=STW_SOK) {
1246                   MMCSD_DEBUG_TRAP
1247                 }
1248     }
1250     /* SD Card */
1251     if(MMCSD_OK == ret)
1252     {
1253         object->cardType = MMCSD_CARD_SD;
1255         /* CMD0 - reset card */
1256         if(MMCSD_OK == ret)
1257         {
1258             transaction.cmd = MMCSD_CMD(0U);
1259             transaction.flags = MMCSD_CMDRSP_NONE;
1260             transaction.arg = 0U;
1261             ret = MMCSD_v2_transfer(handle, &transaction);
1262         } else { MMCSD_DEBUG_TRAP}
1263         }
1265     /******************* Send Operating Voltage (CMD8) ************************/
1266 #ifndef SIMULATOR // Skip CMD8 when VLAB is used
1267         if(MMCSD_OK == ret)
1268         {
1269             uint32_t curr_bus_voltage;
1270                         /* CMD8 - send oper voltage */
1271             transaction.cmd = MMCSD_CMD(8U);
1272             transaction.flags = MMCSD_CMDRSP_48BITS;
1273             transaction.arg = MMCSD_CHECK_PATTERN ;
1276             curr_bus_voltage=HSMMCSDBusVoltGet(hwAttrs->baseAddr);
1278             if(curr_bus_voltage==MMC_HCTL_SDVS_1V8)  {
1279                transaction.arg |= MMCSD_VOLT_LOW_RANGE;
1280                         } else
1281                         {
1282                transaction.arg |= MMCSD_VOLT_2P7_3P6;
1283             }
1285             ret = MMCSD_v2_transfer(handle, &transaction);
1286         }  else { MMCSD_DEBUG_TRAP}
1287 #endif // CMD8 does not for VLAB
1288         if (MMCSD_OK != ret)
1289         {
1290             /*
1291              * If the cmd fails  , it can be due to version < 2.0, since
1292              * we are currently supporting high voltage cards only
1293              */
1294              ret=MMCSD_OK;
1295                      MMCSD_DEBUG_TRAP
1297         }
1298         /******************************* Send OCR (ACMD41) *********************/
1299         if(MMCSD_OK == ret)
1300         {
1301             /* Poll until we get the card status (BIT31 of OCR) is powered up */
1302             do
1303             {
1304                 /* APP cmd should be preceeded by a CMD55 */
1305                 transaction.cmd = MMCSD_CMD(55U);
1306                 transaction.flags = MMCSD_CMDRSP_48BITS;
1307                 transaction.arg = 0; /* object->rca is zero as the card is in the idle state */
1308                 ret = MMCSD_v2_transfer(handle, &transaction);
1310                 if(MMCSD_OK == ret)
1311                 {
1312                     transaction.cmd = MMCSD_CMD(41U);
1313                     transaction.flags = MMCSD_CMDRSP_48BITS;
1314                     transaction.arg = MMCSD_OCR_HIGH_CAPACITY | MMCSD_OCR_VDD_WILDCARD;
1315                     if(support18V_host) {
1316                         /* Host supports 1.8V and seek if the card supports it */
1317                         transaction.arg|= MMCSD_OCR_S18R;
1318                     }
1319                    ret= MMCSD_v2_transfer(handle, &transaction);
1320                 }
1321                 else
1322                 {
1323                     ret = MMCSD_ERR;
1324                   { MMCSD_DEBUG_TRAP
1325                               }
1326                        break;
1327                 }
1328                 retry--;
1329             } while (((transaction.response[0U] & ((uint32_t)BIT(31U))) == 0U) && (retry != 0));
1331             if (0U == retry)
1332             {
1333                 /* No point in continuing */
1334                 ret = MMCSD_ERR;
1335             }
1336         }
1338         object->uhsCard=FALSE;
1339         /****************************** Switch to 1.8V if needed *********************************/
1340         if(MMCSD_OK == ret)
1341         {
1342             object->ocr = transaction.response[0U];
1343             /* Card capacity status (CCS) Bit 30 */
1344             object->highCap = (object->ocr & MMCSD_OCR_HIGH_CAPACITY) ? 1U : 0U;
1346             /* Bit32 of the response R3 (S18A)*/
1347             object->support1_8V = (transaction.response[0U] & MMCSD_OCR_S18R) ? 1U : 0U;
1349                         if(HSMMCSDBusVoltGet(hwAttrs->baseAddr)==MMC_HCTL_SDVS_1V8) {
1350                            attempt_18V_switch=FALSE;
1351                            object->switched_to_v18=TRUE; /* Already in 1.8V mode */
1352                         }
1354                         /* If 1.8V is supported, configure the card accordingly to switch to SDR modes */
1355             if(object->support1_8V && support18V_host && attempt_18V_switch)
1356             {
1357                 MMCSD_drv_log(Diags_USER1, "MMCSD: S18R indicates 1.8V support\n");
1359                             bool falseloop_1p8V_switch=TRUE;
1360                             do
1361                             {
1363                               falseloop_1p8V_switch=FALSE;
1365                   MMCSD_drv_log(Diags_USER1, "MMCSD: Sending CMD11 \n");
1366                                   /* Start the voltage switching procedure */
1367                   /* Send CMD11 */
1368                   transaction.cmd = MMCSD_CMD(11U);
1369                   transaction.flags = MMCSD_CMDRSP_48BITS;
1370                   transaction.arg = 0U;
1371                   ret = MMCSD_v2_transfer(handle, &transaction);
1374                   if(MMCSD_OK == ret)
1375                                   {
1376                            uint32_t retry_count,dataSigLevel;
1377                            /* Voltage sequence acknowledge */
1378                            MMCSD_drv_log(Diags_USER1,"MMCSD DRV:  Voltage sequence acknowledged via CMD11\n");
1380                            MMCSD_drv_log(Diags_USER1,"MMCSD DRV:  Setting the SDVS and V1V8 SIGEN \n");
1382                        HSMMCSDSDClockDisable(hwAttrs->baseAddr); /* Disable clock to SD card */
1384                        /* Wait for CMD and DAT levels to go low */
1385                            retry_count=10;
1387                        do {
1388                                                  dataSigLevel=HSMMCSDGetDataSignalLevel(hwAttrs->baseAddr);
1389                        } while(dataSigLevel!=0);
1391                                            if(retry_count==0) {
1392                                               /* CMD11 failed. Switch not possible */
1393                                               ret=MMCSD_ERR_1P8V_SWITCH_CARD_CMD11_FAILURE;
1394                                               MMCSD_DEBUG_TRAP
1395                                            }
1398                         /* Switch the board voltage to 1.8V */
1399                                             if(hwAttrs->switchVoltageFxn!=NULL) {
1400                                                   ret = hwAttrs->switchVoltageFxn(hwAttrs->instNum,MMCSD_BUS_VOLTAGE_1_8V);
1401                                             }  
1402                             
1403                                                 if(ret!=MMCSD_OK) {
1404                                                   ret=MMCSD_ERR_1P8V_SWITCH_MMCIO_SWITCH_FAILURE;
1405                                                    break;
1406                                                 }
1407  
1408                        status=HSMMCSDBusVoltSet(hwAttrs->baseAddr, MMC_HCTL_SDVS_1V8);
1410                                            HSMMCSDSwitchSignalVoltage (hwAttrs->baseAddr, MMC_AC12_V1V8_SIGEN_1V8);
1412                                            /* Wait for 5 ms */
1413                                            Osal_delay(5);
1414                        /* Set the bus voltage */
1416                                            /* wait if the signal voltage bit is set to 1 */
1417                                            if(HSMMCSDGetSignalVoltage (hwAttrs->baseAddr)==!MMC_AC12_V1V8_SIGEN_1V8) {
1418                                                    MMCSD_DEBUG_TRAP
1419                                            }
1421                         HSMMCSDUhsModeSet(hwAttrs->baseAddr,MMC_AC12_UHSMS_SDR12);
1422                         HSMMCSDHSModeSet(hwAttrs->baseAddr,MMC_HCTL_HSPE_NORMALSPEED);
1424                         /* Set the initialization frequency */
1425                         status = HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk,hwAttrs->outputClk, FALSE);
1427                         Osal_delay(10);
1428                         if(status !=STW_SOK) {
1429                         MMCSD_DEBUG_TRAP
1430                         }
1432                         /* PHY configurae */
1433                         MMCSD_socPhyDisableDLL((MMCSD_v2_HwAttrs const *)hwAttrs);
1435                         Osal_delay(50);
1437                         /* Configure the Phy accordignly */
1438                         ret = MMCSD_socPhyConfigure((MMCSD_v2_HwAttrs const *)hwAttrs, MODE_SDR12, 25000000U, 0);
1439                         if(ret != MMCSD_OK)
1440                         {
1441                             MMCSD_DEBUG_TRAP
1442                         }
1444                                             /* Wait for 1 ms */
1445                                             Osal_delay(1);
1447                         /* Check if the dat[0-3] level has gone to 0x1111 */
1448                         do {
1449                                                    dataSigLevel=HSMMCSDGetDataSignalLevel(hwAttrs->baseAddr);
1450                         } while(dataSigLevel!=0xf);
1454                                             object->switched_to_v18=TRUE;
1455                                             object->uhsCard=TRUE;
1456                             MMCSD_drv_log(Diags_USER1,"1.8V switching procedure complete\n");
1458                                         }
1459                 } while(falseloop_1p8V_switch);
1461                             if(ret!=MMCSD_OK) {
1463                                 /* Reverse the voltage switch */
1464                                   if(hwAttrs->switchVoltageFxn!=NULL) {
1465                                      ret = hwAttrs->switchVoltageFxn(hwAttrs->instNum,MMCSD_BUS_VOLTAGE_3_3V);
1466                                   }
1467                                   
1468                                   HSMMCSDSwitchSignalVoltage (hwAttrs->baseAddr, MMC_AC12_V1V8_SIGEN_3V3);
1469                       /* Wait for 5 ms */
1470                       Osal_delay(5);
1471                   
1472                       /* wait if the signal voltage bit is set to 1 */
1473                       if(HSMMCSDGetSignalVoltage (hwAttrs->baseAddr)==!MMC_AC12_V1V8_SIGEN_3V3) {
1474                         MMCSD_DEBUG_TRAP
1475                       }
1476                             }
1477             }
1479                 }
1482     if(MMCSD_OK == ret)
1483         {
1484             /* Send CMD2, to get the card identification register */
1485             transaction.cmd = MMCSD_CMD(2U);
1486             transaction.flags = MMCSD_CMDRSP_136BITS;
1487             transaction.arg = 0U;
1489             ret = MMCSD_v2_transfer(handle, &transaction);
1491             object->cid[3]= (transaction.response[3] << 8)| (transaction.response[2] >> 24);
1492             object->cid[2]= (transaction.response[2] << 8)| (transaction.response[1] >> 24);
1493             object->cid[1]= (transaction.response[1] << 8)| (transaction.response[0] >> 24);
1494             object->cid[0]= (transaction.response[0] << 8);
1496      }  else {MMCSD_DEBUG_TRAP}
1498      /************************ Get RCA (CMD3) **********************************/
1499      if(MMCSD_OK == ret)
1500      {
1501             /* Send CMD3, to get the card relative address */
1502             transaction.cmd = MMCSD_CMD(3U);
1503             transaction.flags = 0U;
1504             transaction.arg = 0U;
1506             ret = MMCSD_v2_transfer(handle, &transaction);
1508             object->rca = MMCSD_RCA_ADDR(transaction.response[0U]);
1509       }  else { MMCSD_DEBUG_TRAP}
1511         /******************* Get card specific data(CSD) via CMD9 ***********************/
1512         if(MMCSD_OK == ret)
1513         {
1514             /* Send CMD9, to get the card specific data */
1515             transaction.cmd = MMCSD_CMD(9U);
1516             transaction.flags = MMCSD_CMDRSP_136BITS;
1517             transaction.arg = object->rca << 16U;
1519             ret = MMCSD_v2_transfer(handle, &transaction);
1521             object->csd[3]= (transaction.response[3] << 8)| (transaction.response[2] >> 24);
1522             object->csd[2]= (transaction.response[2] << 8)| (transaction.response[1] >> 24);
1523             object->csd[1]= (transaction.response[1] << 8)| (transaction.response[0] >> 24);
1524             object->csd[0]= (transaction.response[0] << 8);
1525         }  else { MMCSD_DEBUG_TRAP }
1528       /************ Select the card (CMD7) ****************/
1530         if(MMCSD_OK == ret)
1531         {
1532             /* Select the card */
1533             transaction.cmd = MMCSD_CMD(7U);
1534             transaction.flags = MMCSD_CMDRSP_BUSY;
1535             transaction.arg = object->rca << 16U;
1537             ret = MMCSD_v2_transfer(handle, &transaction);
1538         }  else { MMCSD_DEBUG_TRAP }
1540          /* Wait for DAT0 to go low */
1541          MMCSD_v2_waitDat0(hwAttrs);
1543     /******** Set block len (CMD16) based on the CSD register *******/
1544         if(MMCSD_OK == ret)
1545         {
1546             if (MMCSD_CARD_CMMCSD_VERSION(object))
1547             {
1548                 object->tranSpeed = MMCSD_CARD1_TRANSPEED(object);
1549                 object->blockSize = ((uint32_t)1U) << (MMCSD_CARD1_RDBLKLEN(object));
1550                 object->size = MMCSD_CARD1_SIZE(object);
1551                 object->blockCount = object->size / object->blockSize;
1552             }
1553             else
1554             {
1555                 object->tranSpeed = MMCSD_CARD0_TRANSPEED(object);
1556                 object->blockSize = ((uint32_t)1U) << (MMCSD_CARD0_RDBLKLEN(object));
1557                 object->size = MMCSD_CARD0_SIZE(object);
1558                 object->blockCount = MMCSD_CARD0_NUMBLK(object);
1559             }
1562             /* Set data block length to 512 (for byte addressing cards) */
1563             if((object->highCap) == 0U)
1564             {
1565                 transaction.cmd = MMCSD_CMD(16U);
1566                 transaction.flags = MMCSD_CMDRSP_NONE;
1567                 transaction.arg = 512U;
1568                 ret = MMCSD_v2_transfer(handle, &transaction);
1570                 if(MMCSD_OK == ret)
1571                 {
1572                                         object->blockCount = (object->blockCount * object->blockSize) / 512U;
1573                     object->blockSize = 512U;
1574                 }
1575             }
1576         }  else { MMCSD_DEBUG_TRAP }
1578     /************************ Get the SCR Register (ACMD51) *****************************/
1580         if(MMCSD_OK == ret)
1581         {
1582             /*
1583              * Send ACMD51, to get the SD Configuration register details.
1584              * Note, this needs data transfer (on data lines).
1585              */
1586             transaction.cmd = MMCSD_CMD(55U);
1587             transaction.flags = 0U;
1588             transaction.arg = object->rca << 16U;
1590             ret = MMCSD_v2_transfer(handle, &transaction);
1591         }  else { MMCSD_DEBUG_TRAP }
1595         if(MMCSD_OK == ret)
1596         {
1597             transaction.cmd = MMCSD_CMD(51U);
1598             transaction.flags = MMCSD_CMDRSP_48BITS | MMCSD_CMDRSP_READ | MMCSD_CMDRSP_DATA;
1599             transaction.arg = object->rca << 16U;
1600             transaction.blockCount = 1U;
1601             transaction.blockSize = 8U;
1602             transaction.dataBuf = dataBuffer;
1604             ret = MMCSD_v2_transfer(handle, &transaction);
1605         }  else { MMCSD_DEBUG_TRAP }
1607         if(MMCSD_OK == ret)
1608         {
1609              object->scr[0] = dataBuffer[0] << 24 | dataBuffer[1] << 16 | dataBuffer[2] << 8 | dataBuffer[3];
1610              object->scr[1] = dataBuffer[4] << 24 | dataBuffer[5] << 16 | dataBuffer[6] << 8 | dataBuffer[7];
1612             object->sdVer = MMCSD_CARD_VERSION(object);
1613             object->busWidth = MMCSD_CARD_BUSWIDTH(object);
1614                         object->cmd23Supported = MMCSD_CARD_CMD23_SUPPORT(object);
1615         }  else { MMCSD_DEBUG_TRAP }
1617      /*****************  Set the bus width,1bit or 4 bit (ACMD6)   ********************/
1620         if(MMCSD_OK == ret)
1621         {
1622             /* APP cmd should be preceeded by a CMD55 */
1623             transaction.cmd = MMCSD_CMD(55U);
1624             transaction.flags = 0U;
1625             transaction.arg = object->rca << 16U;
1626             ret = MMCSD_v2_transfer(handle, &transaction);
1627         }  else { MMCSD_DEBUG_TRAP }
1629         if(MMCSD_OK == ret)
1630         {
1631             transaction.cmd = MMCSD_CMD(6U);
1632             transaction.arg = MMCSD_BUS_WIDTH_1BIT;
1633             transaction.flags = 0U;
1635             if (((MMCSD_v2_HwAttrs *)(((MMCSD_Config *) handle)->hwAttrs))->supportedBusWidth & MMCSD_BUS_WIDTH_4BIT)
1636             {
1637                 if (object->busWidth & MMCSD_BUS_WIDTH_4BIT)
1638                 {
1639                     transaction.arg = MMCSD_BUS_WIDTH_4BIT;
1640                 }
1641             }
1643             transaction.arg = transaction.arg >> 1U;
1644             ret = MMCSD_v2_transfer(handle, &transaction);
1647             if (MMCSD_OK == ret)
1648             {
1649                 if (0U == transaction.arg)
1650                 {
1651                     HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_1BIT);
1652                 }
1653                 else
1654                 {
1655                     HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_4BIT);
1656                 }
1657             }  else { MMCSD_DEBUG_TRAP }
1658          }
1662         /****************** Find out the speeds supported , to switch to high speeds **************/
1663         MMCSD_drv_log(Diags_USER1,"Checking with CMD6 to see the capabilities\n");
1665                 /* Check the CMD6 to see what function could be switched to */
1666         if(MMCSD_OK == ret)
1667         {
1668             transaction.cmd = MMCSD_CMD(6U);
1669             transaction.arg = ((MMCSD_CHECK_MODE & MMCSD_CMD6_GRP1_SEL) |
1670                 (MMCSD_CMD6_GRP1_DEFAULT));
1671             transaction.flags = MMCSD_CMDRSP_READ | MMCSD_CMDRSP_DATA;
1672             transaction.blockCount = 1U;
1673             transaction.blockSize = 64U;
1674             transaction.dataBuf = dataBuffer;
1675             ret = MMCSD_v2_transfer(handle, &transaction);
1676         }  else { MMCSD_DEBUG_TRAP }
1678          /* Wait for DAT0 to go low */
1679          MMCSD_v2_waitDat0(hwAttrs);
1681                 /* Perform the switch and see what function it switches to */
1682 #ifndef SIMULATOR // Skip CMD8 when VLAB is used
1683         if(MMCSD_OK == ret)
1684         {
1685             uint32_t cmd16_grp1_fn = MMCSD_CMD6_GRP1_DEFAULT;
1686                         int32_t i;
1687                         uint32_t cmd6_groups[5]={MMCSD_CMD6_GRP1_SDR104,MMCSD_CMD6_GRP1_SDR50,MMCSD_CMD6_GRP1_DDR50,MMCSD_CMD6_GRP1_HS,MMCSD_CMD6_GRP1_DEFAULT};
1689             MMCSD_drv_log(Diags_USER1,"With the response from CMD6, Trying each speed starting with preferable ones..\n");
1691                         /* Go through the groups in a preferential manner and select the highest speed possible */
1692                         for(i=0;i<5;i++)
1693                         {
1695              /* Go through the capabilites register and match with the card's speed
1696                 to arrive at an agreeable speed */
1697              /* See if 104 is available in response bits 415-400,  i.e bytes[12] and bytest[13] */
1698                          /* Please refer to the status response to CMD6 in the physical specification */
1699                           if( (hwAttrs->supportedModes & MMCSD_SUPPORT_SD_SDR104) && (cmd6_groups[i]==MMCSD_CMD6_GRP1_SDR104) && object->switched_to_v18 && (hcCap.retValue2 & MMC_CAPA2_SDR104_MASK) && (dataBuffer[13] & (1<< MMCSD_CMD6_GRP1_SDR104))) {
1700                 cmd16_grp1_fn=MMCSD_CMD6_GRP1_SDR104;
1701                 MMCSD_drv_log(Diags_USER1,"CMD6 Says Card Supports SDR104\n");
1702               } else if ( (hwAttrs->supportedModes & MMCSD_SUPPORT_SD_SDR50) &&  (cmd6_groups[i]==MMCSD_CMD6_GRP1_SDR50) && object->switched_to_v18 &&  (hcCap.retValue2 & MMC_CAPA2_SDR50_MASK) && (dataBuffer[13] & (1<< MMCSD_CMD6_GRP1_SDR50))) {
1703                 cmd16_grp1_fn=MMCSD_CMD6_GRP1_SDR50;
1704                 MMCSD_drv_log(Diags_USER1,"CMD6 Says Card Supports SDR50\n");
1705                           } else
1706                           if (  (hwAttrs->supportedModes & MMCSD_SUPPORT_SD_DDR50) &&   (cmd6_groups[i]==MMCSD_CMD6_GRP1_DDR50) && object->switched_to_v18 && (hcCap.retValue2 & MMC_CAPA2_DDR50_MASK) && (dataBuffer[13] & (1<< MMCSD_CMD6_GRP1_DDR50))) {
1707                 cmd16_grp1_fn=MMCSD_CMD6_GRP1_DDR50;
1708                 MMCSD_drv_log(Diags_USER1,"CMD6 Says Card Supports DDR50\n");
1709                           } else
1710                           if ( (hwAttrs->supportedModes & MMCSD_SUPPORT_SD_HS) &&  (cmd6_groups[i]==MMCSD_CMD6_GRP1_HS) && (dataBuffer[13] & (1<< MMCSD_CMD6_GRP1_HS))) {
1711                  cmd16_grp1_fn=MMCSD_CMD6_GRP1_HS;
1712                  MMCSD_drv_log(Diags_USER1,"CMD6 Says Card Supports HS\n");
1713                           } else if ( (hwAttrs->supportedModes & MMCSD_SUPPORT_SD_DS) && (cmd6_groups[i]==MMCSD_CMD6_GRP1_DEFAULT) && (dataBuffer[13] & (1<< MMCSD_CMD6_GRP1_DEFAULT))) {
1714                              cmd16_grp1_fn=MMCSD_CMD6_GRP1_DEFAULT;
1715                  MMCSD_drv_log(Diags_USER1,"CMD6 Says Card Supports default\n");
1716                            } else {
1717                                    continue;
1718                            }
1720                           // ret=MMCSD_switch_card_curr_limit (handle,MMCSD_CMD6_GRP4_800mA);
1721                    if(ret!=MMCSD_OK) {
1722                            MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Current switch not successful\n");
1723                            }
1724               ret=MMCSD_switch_card_speed(handle,cmd16_grp1_fn);
1725                           if(ret==MMCSD_OK) {
1726                              MMCSD_drv_log(Diags_USER1," Successfully switched to the above speed\n");
1727                              break;/* Successful switching */
1728                           }
1729                     }
1731         }  else {MMCSD_DEBUG_TRAP}
1732 #endif  //CMD6 does not work for VLAB
1734         if(MMCSD_OK != ret)
1735         {
1736                         MMCSD_DEBUG_TRAP
1737            MMCSD_v2_close(handle);
1738         }
1739         return (ret);
1741 /***********************************************************************/
1742 static MMCSD_Error MMCSD_switch_card_speed(MMCSD_Handle handle,uint32_t cmd16_grp1_fn)
1744    MMCSD_Error ret=MMCSD_ERR;
1745    MMCSD_v2_Object            *object = NULL;
1746    MMCSD_v2_HwAttrs           *hwAttrs = NULL;
1747    MMCSD_v2_Transaction        transaction;
1748    uint32_t uhsMode=0xFFFF; /* Undefined */
1749    stSDMMCHCCapability hcCapab={0,0,0,0};
1751    Bool sdr104_tuning_required=FALSE,switch_speed_approved=TRUE;
1752    uint32_t phy_mode=0,phy_driverType=0,phy_freq=0;
1753    int32_t retVal=STW_SOK;
1755    object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
1756    hwAttrs = (MMCSD_v2_HwAttrs *)((MMCSD_Config *) handle)->hwAttrs;
1758    //Reading the Capability Register
1759    hcCapab.flag1 = HS_MMCSD_CAPA_ALL;
1760    hcCapab.flag2 = HS_MMCSD_CAPA_ALL;
1762    HSMMCSDHostCapabilityGet(hwAttrs->baseAddr, &hcCapab);
1764 #ifdef  MMCSD_CONFIGURE_PHY
1765    if(hcCapab.retValue2 & MMC_CAPA2_DTA_MASK)
1766    {
1767          phy_driverType = PHY_IO_PADS_CTRL1_DR_TYPE_A;
1768    }
1769    if(hcCapab.retValue2 & MMC_CAPA2_DTD_MASK)
1770    {
1771          phy_driverType = PHY_IO_PADS_CTRL1_DR_TYPE_D;
1772    }
1773    else
1774    {
1775          phy_driverType = PHY_IO_PADS_CTRL1_DR_TYPE_C;
1776    }
1777 #endif
1779    memset(cmd6_response_buf,0,sizeof(cmd6_response_buf));
1780    /* Send CMD16 to switch to the requested group */
1781    transaction.cmd = MMCSD_CMD(6U);
1782    transaction.arg = ((MMCSD_SWITCH_MODE & MMCSD_CMD6_GRP1_SEL) | cmd16_grp1_fn);
1783    transaction.flags = MMCSD_CMDRSP_READ | MMCSD_CMDRSP_DATA;
1784    transaction.blockCount = 1U;
1785    transaction.blockSize = 64U;
1786    transaction.dataBuf = cmd6_response_buf;
1788    ret = MMCSD_v2_transfer(handle, &transaction);
1789    /* Wait for DAT0 to go low */
1790    MMCSD_v2_waitDat0(hwAttrs);
1792    if (MMCSD_OK == ret)
1793    {   /* Checking bits 379:376 of the CMD6 response  to see if the switch happened successfully */
1794         uint32_t clk_freq,tranSpeed;
1796             if ((cmd6_response_buf[16U] & 0xFU) == MMCSD_CMD6_GRP1_SDR104 && (cmd16_grp1_fn==MMCSD_CMD6_GRP1_SDR104))
1797                 {
1798                    tranSpeed = MMCSD_TRANSPEED_SDR104;
1799                    uhsMode=MMC_AC12_UHSMS_SDR104;
1800                    sdr104_tuning_required=TRUE;
1801                    clk_freq=208000000U; /* Max freq supported is 208MHz */
1802                    phy_freq=200000000U;
1803                    phy_mode=MODE_SDR104;
1804                    MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Request to switch to SDR104: 192Mhz\n");
1806         } else if  ( ((cmd6_response_buf[16U] & 0xFU) == MMCSD_CMD6_GRP1_SDR50 ) && (cmd16_grp1_fn==MMCSD_CMD6_GRP1_SDR50))
1807             {
1808                    tranSpeed = MMCSD_TRANSPEED_SDR50;
1809                    uhsMode=MMC_AC12_UHSMS_SDR50;
1810                    sdr104_tuning_required=TRUE;
1811                    clk_freq=100000000U; /* 100MHz for SDR50  */
1812                    phy_freq=100000000U;
1813                    phy_mode = MODE_SDR50;
1814                    MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Request to switch to SDR50: 100Mhz\n");
1815                 } else if  ( ((cmd6_response_buf[16U] & 0xFU) == MMCSD_CMD6_GRP1_DDR50) && (cmd16_grp1_fn==MMCSD_CMD6_GRP1_DDR50))
1816                 {
1817                    tranSpeed = MMCSD_TRANSPEED_DDR50;
1818                    uhsMode=MMC_AC12_UHSMS_DDR50;
1819                    sdr104_tuning_required=TRUE;
1820                    clk_freq=50000000U; /* 50MHz for DDR50  */
1821                    phy_freq=50000000U;
1822                    phy_mode=MODE_DDR50;
1823                    MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Request to switch to DDR50: 100Mhz\n");
1825                 }  else if (((cmd6_response_buf[16U] & 0xFU) == MMCSD_CMD6_GRP1_HS) && (cmd16_grp1_fn==MMCSD_CMD6_GRP1_HS))
1826                 {
1827             tranSpeed = MMCSD_TRANSPEED_50MBPS;
1828             if(object->uhsCard) {
1829                           uhsMode= MMC_AC12_UHSMS_SDR25;
1830                         }
1831                     clk_freq=50000000U; /* 50MHz for HS mode */
1832                     phy_freq=50000000U;
1833             phy_mode = MODE_SDR25;
1834                 MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Request to switch to HS: 50Mhz\n");
1835                 } else if (((cmd6_response_buf[16U] & 0xFU) == MMCSD_CMD6_GRP1_DEFAULT) && (cmd16_grp1_fn==MMCSD_CMD6_GRP1_DEFAULT))
1836                 {
1837            tranSpeed = MMCSD_TRANSPEED_25MBPS;
1838            if(object->uhsCard) {
1839                      uhsMode=MMC_AC12_UHSMS_SDR12;
1840                    }
1841            clk_freq=25000000U;  /* 25MHz for SDR12 */
1842            phy_mode =  MODE_SDR12;
1843                    phy_freq=25000000U;
1844                    MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Request to switch to SDR12: 25Mhz\n");
1846         } else {
1847                    /* Speed switch not approved */
1848            MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Wrong Speed requested\n");
1849                    switch_speed_approved=FALSE;
1850                 }
1852                 if(switch_speed_approved)  {
1853           /* Set input clock to make sure that the input clock is equal or higher to the clock value
1854            * requested */
1855               if(NULL != hwAttrs->inputClockControl) {
1856                   uint32_t inputClockRet = hwAttrs->inputClockControl(hwAttrs->instNum, &clk_freq, MMCSD_INPUT_CLOCK_CTRL_SET);
1857                       if (inputClockRet != 0U) {
1858                 hwAttrs->inputClk=inputClockRet;
1859                       } else {
1860                         MMCSD_drv_log4(Diags_USER1,"Unable to change input clock to %d\n",clk_freq);
1861                       }
1862               }
1864       if(!object->uhsCard) {
1865              /* For non UHS cards, it is the high speed/ Default speed mode */
1866               if(tranSpeed==MMCSD_TRANSPEED_50MBPS) {
1867                       /* For non-high speed modes the data should be on the falling edge */
1868                       HSMMCSDHSModeSet(hwAttrs->baseAddr,MMC_HCTL_HSPE_NORMALSPEED);
1869                           phy_mode = MODE_HS;
1870                }  else if(tranSpeed==MMCSD_TRANSPEED_25MBPS) {
1871                       /* For non-high speed modes the data should be on the falling edge */
1872                           HSMMCSDHSModeSet(hwAttrs->baseAddr,MMC_HCTL_HSPE_NORMALSPEED);
1873                           phy_mode = MODE_DS;
1874                } else {
1875                          /* This shouldn't happen */
1876                          ret = MMCSD_ERR;
1877                          MMCSD_DEBUG_TRAP
1878                    }
1879           } else {
1880                   /* Set the UHS mode accordingly */
1881                   if(uhsMode!=0xffff) {
1882                     HSMMCSDUhsModeSet(hwAttrs->baseAddr,uhsMode);
1883             /* SDR50 is rising edge */
1884             if( (uhsMode==MMC_AC12_UHSMS_SDR12) || 
1885                 (uhsMode==MMC_AC12_UHSMS_SDR25) )
1886             {
1887                       /* For non-high speed modes the data should be on the falling edge */
1888                           HSMMCSDHSModeSet(hwAttrs->baseAddr,MMC_HCTL_HSPE_NORMALSPEED);
1889             } else
1890             {
1891                           HSMMCSDHSModeSet(hwAttrs->baseAddr,MMC_HCTL_HSPE_HIGHSPEED);
1892             }
1893   
1894                   } else { MMCSD_DEBUG_TRAP }
1895           }
1897           
1898           MMCSD_socPhyDisableDLL((MMCSD_v2_HwAttrs const *)hwAttrs);
1900          /* Change clock only if required */
1901        if(STW_SOK == HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk, clk_freq, 0U))
1902        {
1903           ret = MMCSD_OK;
1904        } else {
1905                   MMCSD_DEBUG_TRAP
1906                   return (MMCSD_ERR);
1907            }
1908         Osal_delay(50);
1909         /* Configure the Phy accordignly */
1910         
1911         retVal = MMCSD_socPhyConfigure((MMCSD_v2_HwAttrs const *)hwAttrs,phy_mode, phy_freq, phy_driverType);
1912         
1913             if(retVal != MMCSD_OK)
1914             {
1915                   MMCSD_DEBUG_TRAP
1916             }
1918                 if(hwAttrs->tuningType == MMCSD_AUTO_HW_TUNING) {
1919                   object->manualTuning=FALSE;
1920                 } else if(hwAttrs->tuningType == MMCSD_MANUAL_SW_TUNING) {
1921                   object->manualTuning=TRUE;
1922                 }       
1923                   /* Tuning mandatory for SDR104 */
1924                   if(sdr104_tuning_required) {
1925                     MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: About to execute Tuning procedure\n");
1926                 if(object->manualTuning) {
1927               ret=mmcsd_tuning_procedure_SD_manual(handle);
1928                } else {
1929                           ret=mmcsd_tuning_procedure(handle);   
1930                    }
1932                                                 
1933                         if(ret!=MMCSD_OK) {
1934                            MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Tuning failed!\n");
1935                         } else {
1936                    MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Tuning Successfully completed\n");
1937                         }
1938           }
1940                   if(ret==MMCSD_OK) {
1941                     MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: All OK so far\n");
1942                     object->tranSpeed=tranSpeed;
1943                   }
1945                 } else {
1946                   MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Error!!\n");
1947                   ret=MMCSD_ERR;
1948                 }
1949    }
1951         return ret;
1954 uint32_t mmcsd_send_tuning(MMCSD_Handle handle) {
1956     uint8_t                     dataBuffer[64] = {0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U,
1957                                                    0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U,
1958                                                    0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U,
1959                                                    0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U};
1960     MMCSD_Error                 ret = MMCSD_OK;
1961     MMCSD_v2_Transaction        transaction;
1962     Bool tuning_fail=FALSE;
1963         uint32_t i;
1964         uint32_t enableInterrupts,enableDma;
1965         MMCSD_v2_HwAttrs *hwAttrs;
1966         hwAttrs = (MMCSD_v2_HwAttrs *)((MMCSD_Config *) handle)->hwAttrs;
1968         enableInterrupts=hwAttrs->enableInterrupt;
1969         enableDma=hwAttrs->enableDma;
1971     hwAttrs->enableInterrupt=0;
1972     hwAttrs->enableDma=0;
1974         /* Send CMD19 */
1975     transaction.cmd = MMCSD_CMD(19U);
1976     transaction.arg = 0;
1977     transaction.flags = MMCSD_CMDRSP_48BITS | MMCSD_CMDRSP_READ | MMCSD_CMDRSP_DATA;
1978     transaction.blockCount = 1U;
1979     transaction.blockSize = sizeof(tuning_blk_pattern_4bit); /* 64 bytes */
1980     transaction.dataBuf = dataBuffer;/* Tuning data from the SD card comes here */
1981     ret = MMCSD_v2_transfer(handle, &transaction);
1983     if(ret==MMCSD_OK) {
1984           /* Compare the data recieved from the card to the expected values*/
1985           for(i = 0U; i < sizeof(tuning_blk_pattern_4bit); i++) {
1986             if(dataBuffer[i]!=tuning_blk_pattern_4bit[i]) {
1987                    tuning_fail=TRUE;
1988                  break;
1989                 }
1990           }
1991         } else {
1992            tuning_fail=TRUE;
1993     }
1995     hwAttrs->enableInterrupt=enableInterrupts;
1996     hwAttrs->enableDma=enableDma;
1997     return(tuning_fail);
2000 uint32_t mmcsd_send_tuning_eMMC(MMCSD_Handle handle) {
2002     uint8_t                     dataBuffer[256U] = {0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U,
2003                                                    0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U,
2004                                                    0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U,
2005                                                    0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U};
2007     MMCSD_Error                 ret = MMCSD_OK;
2008     MMCSD_v2_Transaction        transaction;
2009     Bool tuning_fail=FALSE;
2010         uint32_t i;
2011         uint32_t enableInterrupts,enableDma;
2012         MMCSD_v2_HwAttrs *hwAttrs;
2013         hwAttrs = (MMCSD_v2_HwAttrs *)((MMCSD_Config *) handle)->hwAttrs;
2015         enableInterrupts=hwAttrs->enableInterrupt;
2016         enableDma=hwAttrs->enableDma;
2017     hwAttrs->enableInterrupt=0;
2018     hwAttrs->enableDma=0;
2020         /* Send CMD21 */
2021     transaction.cmd = MMCSD_CMD(21U);
2022     transaction.arg = 0;
2023     transaction.flags = MMCSD_CMDRSP_48BITS | MMCSD_CMDRSP_READ | MMCSD_CMDRSP_DATA;
2024     transaction.blockCount = 1U;
2025     transaction.blockSize = sizeof(tuning_blk_pattern_8bit); /* 128 bytes */
2026     transaction.dataBuf = dataBuffer;/* Tuning data from the SD card comes here */
2027     ret = MMCSD_v2_transfer(handle, &transaction);
2029     if(ret==MMCSD_OK) {
2030           /* Compare the data recieved from the card to the expected values*/
2031           for(i = 0U;i < sizeof(tuning_blk_pattern_8bit); i++) {
2032             if(dataBuffer[i]!=tuning_blk_pattern_8bit[i]) {
2033                    tuning_fail=TRUE;
2034                  break;
2035                 }
2036           }
2037         } else {
2038            tuning_fail=TRUE;
2039     }
2041     hwAttrs->enableInterrupt=enableInterrupts;
2042     hwAttrs->enableDma=enableDma;
2044     return(tuning_fail);
2048 MMCSD_Error MMCSD_switch_eMMC_mode(MMCSD_Handle handle, MMCSD_SupportedMMCModes_e mode);
2049 MMCSD_Error MMCSD_switch_eMMC_mode(MMCSD_Handle handle, MMCSD_SupportedMMCModes_e mode)
2051     volatile int32_t            ret=MMCSD_OK;
2052     uint8_t       HS_TIMING_val=0,HS_TIMING_index=185; /* EXT_CSD[185] holds HS_TIMING byte */
2053     uint32_t     phy_clk_freq=26000000,clk_freq=26000000; /* Default 26Mhz */
2054     uint32_t uhsMode=MMC_AC12_UHSMS_SDR12;
2055     uint32_t drvStrength=0;
2056     uint32_t phyDriverType=0; /* Default 60ohms */
2057     uint32_t phyMode= MODE_DS;
2058     bool tuning_required=FALSE;
2059     bool ddrMode=FALSE;
2060     uint32_t enhancedStrobe=0;
2061     MMCSD_v2_Object *object;
2062     MMCSD_v2_HwAttrs const *hwAttrs = NULL;
2063     MMCSD_v2_Transaction    transaction;
2064     uint32_t drvStrength_controller=0;
2066     /* Get the pointer to the object and hwAttrs */
2067     object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
2068     hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
2070     drvStrength = object->ecsd[185] >> 4;/* To be obtained from the EXT_CSD */
2073    if((mode == MMCSD_SUPPORT_MMC_HS200) || (mode == MMCSD_SUPPORT_MMC_HS400))
2074    {
2075      /*
2076     * To switch to HS200, host has to perform the following steps:
2077     1) Select the device (through sending CMD7) and make sure it is unlocked (through CMD42)
2078     2) Read the DEVICE_TYPE [196] field of the Extended CSD register to validate
2079       if the device supports HS200 at the IO voltage appropriate for both host and device
2080     3) Read the DRIVER_STRENGTH [197] field of the Extended CSD register to find
2081       * the supported device Driver Strengths. Note: This step can be skipped if changes of driver strength is not needed
2082      4) Set HS200 bit and Driver Strength value in the HS_TIMING [185] field of
2083        * the Extended CSD register by issuing CMD6. If the host attempts to write an invalid value, the HS_TIMING byte is not changed, the HS200 interface timing is not enabled, the Driver Strength is not changed, and the SWITCH_ERROR bit is set. After the device responds with R1, it might assert Busy signal. Once the busy signal gets de-asserted, the host may send a SEND_STATUS Command (CMD13) using the HS200 timing and after it receives a Trans State indication and No Error it means that the device is set to HS200 timing and the Driver Strength is set to the selected settings.
2084      5) At this point, the host can set the frequency to ≤ 200 MHz.
2085      6) The host may invoke the HS200 tuning sequence,
2086      * by sending CMD21 to the device (see 6.6.5).
2087      NOTE The host should switch to the required bus width before starting the tuning operation to allow the
2088       *  tuning sequence to be done using the proper bus operating conditions.
2089       */
2091       /* Select the device CMD7 */
2092       /* EXT CSD already has been read, so just check if it is supported */
2093       /* Read the driver strength */
2095       /* Send Command 6 to switch the HS_TIMING MODE */
2096       HS_TIMING_val = MMCSD_ECSD_HS_TIMING_HS200;
2097       clk_freq = 200000000;
2098       phyMode = MODE_HS200;
2099       tuning_required=TRUE;
2100       uhsMode =MMC_AC12_UHSMS_SDR104;
2101     } else if ( (mode == MMCSD_SUPPORT_MMC_HS_SDR) || (mode == MMCSD_SUPPORT_MMC_HS_DDR) )
2102     {
2103       HS_TIMING_val = MMCSD_ECSD_HS_TIMING_HIGH_SPEED;
2104       tuning_required=FALSE;
2105       clk_freq = 52000000;
2106       if (mode == MMCSD_SUPPORT_MMC_HS_DDR)
2107       {
2108                   ddrMode=TRUE;
2109                   uhsMode =MMC_AC12_UHSMS_DDR50;
2110                   phyMode=MODE_HSDDR50;
2111           } else {
2112                   uhsMode =MMC_AC12_UHSMS_SDR50;
2113           phyMode = MODE_HSSDR50;
2114           }
2116         } else {
2117       phyMode = MODE_DS;
2118       HS_TIMING_val = MMCSD_ECSD_HS_TIMING_BACKWARD_COMPATIBLE;
2119       tuning_required=FALSE;
2120       clk_freq = 26000000;
2121         }
2124       /* Send the Switch command to change the HS TIMINIG bit of the EXT_CSD[185]  */
2125      if(MMCSD_OK == ret)
2126      {
2127         transaction.cmd = MMCSD_CMD(6U);
2128         transaction.arg = 0x03000000 | (HS_TIMING_index << 16) | (( (drvStrength <<4) | HS_TIMING_val) << 8);
2129         transaction.flags = MMCSD_CMDRSP_BUSY;
2130         ret = MMCSD_v2_transfer(handle, &transaction);
2131      }
2132      Osal_delay(50);
2133      if(MMCSD_OK == ret) {
2134                 /* Wait for DAT0 to go low */
2135        MMCSD_v2_waitDat0(hwAttrs);
2136          }
2138      if(ddrMode==TRUE)
2139      {
2140        uint8_t ecsd_bus_width;
2141        if(object->busWidth==MMCSD_BUS_WIDTH_8BIT) {
2142                   ecsd_bus_width= MMCSD_ECSD_BUS_WIDTH_8BIT_DDR;
2143            } else {
2144                   ecsd_bus_width= MMCSD_ECSD_BUS_WIDTH_4BIT_DDR;
2145            }
2147        transaction.cmd = MMCSD_CMD(6U);
2148        transaction.arg = 0x03000000 | (MMCSD_ECSD_BUS_WIDTH_INDEX << 16) | (( (enhancedStrobe << MMCSD_ECSD_BUS_WIDTH_ES_SHIFT) | ecsd_bus_width) << 8);
2149        transaction.flags = MMCSD_CMDRSP_BUSY;
2150        ret = MMCSD_v2_transfer(handle, &transaction);
2152        Osal_delay(50);
2153        if(MMCSD_OK == ret) {
2154                   /* Wait for DAT0 to go low */
2155           MMCSD_v2_waitDat0(hwAttrs);
2156        }
2157        phy_clk_freq=52000000;
2159      } else {
2160           phy_clk_freq=clk_freq;
2161      }
2163     /* Configure the host controller and Phy */
2164         ret = HSMMCSDUhsModeSet(hwAttrs->baseAddr, uhsMode);
2166     MMCSD_socPhyDisableDLL(hwAttrs);
2168     ret = HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk, clk_freq, 0U);
2169     if(ret!=STW_SOK) {
2170                 return MMCSD_ERR;
2171         }
2173     /* NEW: Enable DLL */
2174     Osal_delay(50);
2175      
2177     MMCSD_socPhyConfigure(hwAttrs,phyMode, phy_clk_freq, phyDriverType);
2179         if(hwAttrs->tuningType == MMCSD_AUTO_HW_TUNING) {
2180            object->manualTuning=FALSE;
2181         } else if(hwAttrs->tuningType == MMCSD_MANUAL_SW_TUNING) {
2182            object->manualTuning=TRUE;
2183         }
2184         
2185      /* Tuning mandatory for HS200 */
2186     if(tuning_required) {
2187                 if(object->manualTuning) {
2188               ret=mmcsd_tuning_procedure_EMMC_manual(handle);
2189             } else {
2190               ret=mmcsd_tuning_procedure(handle);       
2191                 }
2192                 
2193            if(ret!=MMCSD_OK) {
2194           MMCSD_DEBUG_TRAP
2195            }
2196      }
2198      if((mode == MMCSD_SUPPORT_MMC_HS400) || (mode == MMCSD_SUPPORT_MMC_HS400_ES))
2199      {
2200                 if(mode ==MMCSD_SUPPORT_MMC_HS400_ES)
2201                 {
2202                         enhancedStrobe=1;
2203                 }
2204                 /*
2205                  Set the “Timing Interface” parameter in the HS_TIMING [185] field
2206                  * of the Extended CSD register to 0x1 to switch to High Speed mode and
2207                  * then set the clock frequency to a value not greater than 52 MHz,
2208          */
2209          HS_TIMING_val=MMCSD_ECSD_HS_TIMING_HIGH_SPEED;
2210          transaction.cmd = MMCSD_CMD(6U);
2211          transaction.arg = 0x03000000 | (MMCSD_ECSD_HS_TIMING_INDEX << 16) | (( (enhancedStrobe <<4) | HS_TIMING_val) << 8);
2212          transaction.flags = MMCSD_CMDRSP_BUSY;
2213          ret = MMCSD_v2_transfer(handle, &transaction);
2215        Osal_delay(50);
2219           MMCSD_socPhyDisableDLL(hwAttrs);
2221        ret = HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk, 52000000, 0U);
2222        if(ret!=STW_SOK) {
2223                   return MMCSD_ERR;
2224            }
2226        Osal_delay(50);
2228        phyMode = MODE_HSSDR50;
2229        
2230        MMCSD_socPhyConfigure(hwAttrs,phyMode, 50000000, phyDriverType);
2231       
2232        /*Set BUS_WIDTH[183] to 0x06 to select the dual data rate x8 bus mode */
2233        transaction.cmd = MMCSD_CMD(6U);
2234        transaction.arg = 0x03000000 | (MMCSD_ECSD_BUS_WIDTH_INDEX << 16) | (( (enhancedStrobe << MMCSD_ECSD_BUS_WIDTH_ES_SHIFT) | MMCSD_ECSD_BUS_WIDTH_8BIT_DDR) << 8);
2235        transaction.flags = MMCSD_CMDRSP_BUSY;
2236        ret = MMCSD_v2_transfer(handle, &transaction);
2238        Osal_delay(50);
2239        if(MMCSD_OK == ret) {
2240                   /* Wait for DAT0 to go low */
2241           MMCSD_v2_waitDat0(hwAttrs);
2242        }
2244          /*Set the “Timing Interface” parameter in the HS_TIMING [185] field of the
2245          * Extended CSD register to 0x3 to switch to HS400 mode.
2246          */
2247         /* Send the Switch command to change the HS TIMINIG bit of the EXT_CSD[185]  */
2248         if(MMCSD_OK == ret)
2249         {
2250           transaction.cmd = MMCSD_CMD(6U);
2251           transaction.arg = 0x03000000 | (MMCSD_ECSD_HS_TIMING_INDEX << 16) | (( (enhancedStrobe <<4) | MMCSD_ECSD_HS_TIMING_HS400) << 8);
2252           transaction.flags = MMCSD_CMDRSP_BUSY;
2253           ret = MMCSD_v2_transfer(handle, &transaction);
2254         }
2255         Osal_delay(50);
2256         if(MMCSD_OK == ret) {
2257                   /* Wait for DAT0 to go low */
2258           MMCSD_v2_waitDat0(hwAttrs);
2259             }
2261         ret = HSMMCSDUhsModeSet(hwAttrs->baseAddr, MMC_AC12_UHSMS_HS400);
2263          if(enhancedStrobe)
2264          {
2265            HSMMCSDEnhancedStrobeSet(hwAttrs->baseAddr,MMC_VREG_STROBE_ENABLE);
2266                  }
2268         ret = HSMMCSDUhsDrvStrengthSet(hwAttrs->baseAddr, drvStrength_controller);
2270              MMCSD_socPhyDisableDLL(hwAttrs);
2273          /* Host may set the clock frequency to a value not greater than 200 MHz"*/
2274         ret = HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk, 200000000, 0U);
2276          /* NEW: Enable DLL */
2277         Osal_delay(50);
2278         phyMode = MODE_HS400;
2279         
2280         MMCSD_socPhyConfigure(hwAttrs,phyMode, 200000000, phyDriverType);
2282         
2283         if(ret!=STW_SOK) {
2284                   return MMCSD_ERR;
2285             }
2286         Osal_delay(50);
2287          }
2289      return (ret);
2293 /*
2294  ***********************************************************************
2295  *  ======== Returns tuning status ========
2296  **********************************************************************/
2297 static MMCSD_Error mmcsd_tuning_procedure(MMCSD_Handle handle) {
2299      MMCSD_v2_Object        *object = NULL;
2300      MMCSD_v2_HwAttrs const *hwAttrs = NULL;
2301      bool tuning_success = FALSE;
2302      uint32_t i;
2303      uint32_t state,samplingClock;
2305      /* Get the pointer to the object and hwAttrs */
2306      object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
2307          hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
2308      
2309      HSMMCSDCardTuningSet(hwAttrs->baseAddr,HS_MMCSD_EXEC_TUNING_ENABLE, HS_MMCSD_CLCK_SELECT_DISABLE);
2310          /* Read the ET back until it is 1 */
2311          {
2312                 uint32_t state,samplingClock;
2313         do {
2314            HSMMCSDCardTuningGet(hwAttrs->baseAddr,&state, &samplingClock);
2315             } while(state!=MMC_AC12_ET_EXECUTE);
2316      }
2317       for(i=0;i<40;i++)
2318      {
2320            /* Send CMD19 for SD card, CMD21 for eMMC */
2321        if(MMCSD_CARD_EMMC == object->cardType) {
2322              mmcsd_send_tuning_eMMC(handle);
2323            } else {
2324              mmcsd_send_tuning(handle);
2325            }
2326         
2327            HSMMCSDCardTuningGet(hwAttrs->baseAddr,&state, &samplingClock);
2328            if (state==MMC_AC12_ET_COMPLETED && samplingClock == MMC_AC12_SCLK_SEL_TUNED) 
2329            {
2330                    /* Tuninig is succcessful. Return */
2331            tuning_success=TRUE;
2332            break;
2333            }
2335     }
2337         if(!tuning_success) {
2338                 MMCSD_DEBUG_TRAP
2339                 HSMMCSDCardTuningSet(hwAttrs->baseAddr,HS_MMCSD_EXEC_TUNING_DISABLE, HS_MMCSD_CLCK_SELECT_DISABLE);
2340                 return MMCSD_ERR;
2341         }
2344    HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_CMDLINE_RESET);
2345    HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_DATALINE_RESET);
2347         return MMCSD_OK;
2350 /*
2351  *  ======== MMCSD_open ========
2352  */
2353 static MMCSD_Error MMCSD_v2_initEmmc(MMCSD_Handle handle)
2355     MMCSD_Error                 ret = MMCSD_OK;
2356     uint32_t                    retry = 0xFFFFU;
2357     MMCSD_v2_Object            *object = NULL;
2358     MMCSD_v2_HwAttrs const     *hwAttrs = NULL;
2359     MMCSD_v2_Transaction        transaction;
2360     volatile int32_t            status = -1;
2361     uint32_t controller_buswidth = HS_MMCSD_BUS_WIDTH_1BIT;  /* Default */
2362     uint8_t ecsd_bus_with      = MMCSD_ECSD_BUS_WIDTH_1BIT; /* Default */
2364     /* Get the pointer to the object and hwAttrs */
2365     object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
2366     hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
2368     if(MMCSD_OK == ret)
2369     {
2370         /*
2371          * Refer to the MMC Host and Bus configuration ste/home/mahesh/ti/procsdk_keystone3_May7/pdk_am65xx_1_0_0/packages/ti/drv/mmcsdps in TRM
2372          * controller Reset
2373          */
2374         status = HSMMCSDSoftReset(hwAttrs->baseAddr);
2376         if (STW_SOK != status)
2377         {
2378 #ifdef LOG_EN
2379             MMCSD_drv_log4(Diags_USER1,
2380                     "MMCSD:(%p) HS MMC/SD Reset failed\n", hwAttrs->baseAddr);
2381 #endif
2382             ret = MMCSD_ERR;
2383         }
2384         else
2385         {
2386             ret = MMCSD_OK;
2387         }
2388     }
2390     if (MMCSD_OK == ret)
2391     {
2392         /* Lines Reset */
2393         status=HSMMCSDLinesReset(hwAttrs->baseAddr, HS_MMCSD_ALL_RESET);
2394         if(status!=STW_SOK) {
2395            MMCSD_DEBUG_TRAP
2396          }
2398         /* Set the bus width */
2399         status=HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_1BIT);
2400         if(status!=STW_SOK) {
2401            MMCSD_DEBUG_TRAP
2402          }
2404         /* Set the bus voltage */
2405         status=HSMMCSDBusVoltSet(hwAttrs->baseAddr, MMC_HCTL_SDVS_1V8);
2407         if(status!=STW_SOK) {
2408            MMCSD_DEBUG_TRAP
2409          }
2411    if(MMCSD_OK == ret)
2412    {
2413       uint32_t slotType,reg=0;
2414       slotType = CSL_MMC_CTLCFG_CAPABILITIES_SLOT_TYPE_VAL_EMBEDDED;
2416       reg = *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->CTL_CFG_2_REG));
2417       reg = Bitfield_csl_set (reg, slotType,
2418                             CSL_MMC_SSCFG_CTL_CFG_2_REG_SLOTTYPE_MASK,
2419                             CSL_MMC_SSCFG_CTL_CFG_2_REG_SLOTTYPE_SHIFT);
2420        *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->CTL_CFG_2_REG))=reg;
2421  
2422       //
2423       // Enable pins by setting the IO mux field in the phy to 0.
2424       //
2425       reg = *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->PHY_CTRL_1_REG));
2426       reg = Bitfield_csl_set (reg, 0,
2427                             CSL_MMC_SSCFG_PHY_CTRL_1_REG_IOMUX_ENABLE_MASK,
2428                             CSL_MMC_SSCFG_PHY_CTRL_1_REG_IOMUX_ENABLE_SHIFT);
2429       *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->PHY_CTRL_1_REG))=reg;
2431       //
2432       // Wait for card detect.
2433       //
2434        {
2435                    uint32_t ins=0;
2437                do {
2438               ins = HSMMCSDIsCardInserted(hwAttrs->baseAddr);
2439            } while(ins==0);
2440        }
2441     }
2443         MMCSD_socPhyInit(hwAttrs);
2445         /* Bus power on */
2446         status = ((int32_t)(HSMMCSDBusPower(hwAttrs->baseAddr, MMC_HCTL_SDBP_PWRON)));
2447         if(status!=STW_SOK) {
2448            MMCSD_DEBUG_TRAP
2449          }
2451         if (STW_SOK != status)
2452         {
2453 #ifdef LOG_EN
2454             MMCSD_drv_log4(Diags_USER1,
2455                     "MMCSD:(%p) HS MMC/SD Power on failed\n", hwAttrs->baseAddr);
2456 #endif
2457             ret = MMCSD_ERR;
2458         }
2459     }
2461     if (MMCSD_OK == ret)
2462     {
2463         /* Set the initialization frequency */
2464         status = HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk,400000,FALSE);
2466         if (STW_SOK != status)
2467         {
2468 #ifdef LOG_EN
2469         MMCSD_drv_log4(Diags_USER1,
2470           "MMCSD:(%p) HS MMC/SD Bus Frequency set failed\n", hwAttrs->baseAddr);
2471 #endif
2472             ret = MMCSD_ERR;
2473         }
2475     }
2479     if(MMCSD_OK == ret)
2480     {
2481         /* CMD0 - reset card */
2482         if(MMCSD_OK == ret)
2483         {
2484             transaction.cmd = MMCSD_CMD(0U);
2485             transaction.flags = MMCSD_CMDRSP_NONE;
2486             transaction.arg = 0U;
2487             ret = MMCSD_v2_transfer(handle, &transaction);
2488         }
2490         /* NOTE: Add delay */
2491         Osal_delay(50U);
2493         if(MMCSD_OK == ret)
2494         {
2495             stSDMMCHCCapability hcCapab={0,0,0,0};
2496             uint32_t hostOcr=0;
2497             #define MMC_VDD_27_33                                       0x00FF8000U
2498             #define MMC_VDD_17_19                                       0x00000080U
2499             #define SECTOR_MODE                                         0x4U
2501                 //Reading the Capability Register
2502                     hcCapab.flag1 = HS_MMCSD_VOLT_3V3_SUPPORT;
2504                HSMMCSDHostCapabilityGet(hwAttrs->baseAddr, &hcCapab);
2505                if(hcCapab.retValue1)
2506                {
2507                 hostOcr |= MMC_VDD_27_33;
2508                }
2510                    hcCapab.flag1 = HS_MMCSD_VOLT_3V0_SUPPORT;
2511                HSMMCSDHostCapabilityGet(hwAttrs->baseAddr, &hcCapab);
2513                if (hcCapab.retValue1)
2514                {
2515                 hostOcr |= MMC_VDD_27_33;
2516                }
2517                hostOcr |= MMC_VDD_17_19;
2519             /* Poll until we get the card status (BIT31 of OCR) is powered up */
2520             do
2521             {
2522                 /* APP cmd should be preceeded by a CMD55 */
2523                 transaction.cmd = MMCSD_CMD(1U);
2524                 transaction.flags = MMCSD_CMDRSP_48BITS;
2525                 // transaction.arg = 0xC0FF8080U;
2526                 transaction.arg = ( (0x80000000) |  (SECTOR_MODE << 28U) | hostOcr );
2527                 ret = MMCSD_v2_transfer(handle, &transaction);
2528                 retry--;
2529             } while (((transaction.response[0U] & ((uint32_t)BIT(31U))) == 0U) && (retry != 0));
2531             if (0U == retry)
2532             {
2533                 /* No point in continuing */
2534                 ret = MMCSD_ERR;
2535             }
2536         }
2537             object->cmd23Supported = TRUE; /* MMC should always support CMD23 */
2539         if(MMCSD_OK == ret)
2540         {
2541             object->ocr = transaction.response[0U];
2543             object->highCap = (object->ocr & MMCSD_OCR_HIGH_CAPACITY) ? 1U : 0U;
2545             /* Send CMD2, to get the card identification register */
2546             transaction.cmd = MMCSD_CMD(2U);
2547             transaction.flags = MMCSD_CMDRSP_136BITS;
2548             transaction.arg = 0U;
2550             ret = MMCSD_v2_transfer(handle, &transaction);
2552             //  memcpy(object->cid, transaction.response, 16U);
2553             object->cid[3]= (transaction.response[3] << 8)| (transaction.response[2] >> 24);
2554             object->cid[2]= (transaction.response[2] << 8)| (transaction.response[1] >> 24);
2555             object->cid[1]= (transaction.response[1] << 8)| (transaction.response[0] >> 24);
2556             object->cid[0]= (transaction.response[0] << 8);
2557         }
2559         if(MMCSD_OK == ret)
2560         {
2561             object->rca = 2U;
2563             /* Send CMD3, to get the card relative address */
2564             transaction.cmd = MMCSD_CMD(3U);
2565             transaction.flags = 0U;
2566             transaction.arg = object->rca << 16U;
2568             ret = MMCSD_v2_transfer(handle, &transaction);
2569         }
2571         if(MMCSD_OK == ret)
2572         {
2573             /* Send CMD9, to get the card specific data */
2574             transaction.cmd = MMCSD_CMD(9U);
2575             transaction.flags = MMCSD_CMDRSP_136BITS;
2576             transaction.arg = object->rca << 16U;
2578             ret = MMCSD_v2_transfer(handle, &transaction);
2580             object->csd[3]= (transaction.response[3] << 8)| (transaction.response[2] >> 24);
2581             object->csd[2]= (transaction.response[2] << 8)| (transaction.response[1] >> 24);
2582             object->csd[1]= (transaction.response[1] << 8)| (transaction.response[0] >> 24);
2583             object->csd[0]= (transaction.response[0] << 8);
2584         }
2586         if(MMCSD_OK == ret)
2587         {
2588             object->tranSpeed = ((object->csd[3] & 0x000000FFU));
2589             object->blockSize = (((uint32_t)2U)<<(((object->csd[0] & 0x03C00000U) >> 22)-1U));
2591             if (((object->csd[3] & 0x3C000000U) >> 26) != 0x04U)
2592             {
2593                 ret = MMCSD_ERR;
2594             }
2595         }
2597         if(MMCSD_OK == ret)
2598         {
2599             /* Select the card */
2600             transaction.cmd = MMCSD_CMD(7U);
2601             transaction.flags = MMCSD_CMDRSP_BUSY;
2602             transaction.arg = object->rca << 16U;
2604             ret = MMCSD_v2_transfer(handle, &transaction);
2605         }
2607         if(MMCSD_OK == ret)
2608         {
2609             transaction.cmd = MMCSD_CMD(8U);
2610             transaction.flags = MMCSD_CMDRSP_READ | MMCSD_CMDRSP_DATA;
2611             transaction.arg = object->rca << 16U;
2612             transaction.blockCount = 1U;
2613             transaction.blockSize = 512U;
2614             transaction.dataBuf = object->ecsd;
2616             ret = MMCSD_v2_transfer(handle, &transaction);
2617         }
2619         /* NOTE: Add delay */
2620          delay(100U);
2622         if(MMCSD_OK == ret)
2623         {
2624             object->blockCount = (((uint32_t)(object->ecsd[215])) << 24) +
2625                                  (((uint32_t)(object->ecsd[214])) << 16) +
2626                                  (((uint32_t)(object->ecsd[213])) << 8) +
2627                                  (((uint32_t)(object->ecsd[212])));
2628             object->size = (object->blockCount * object->blockSize);
2629             object->busWidth = MMCSD_BUS_WIDTH_8BIT;
2630             object->sdVer = object->ecsd[192];
2631         }
2633         /* NOTE: Add delay */
2634         delay(100U);
2636        /* Setting the bus width as per the allowed configuration */
2637        if(hwAttrs->supportedBusWidth & MMCSD_BUS_WIDTH_8BIT) {
2638           controller_buswidth = HS_MMCSD_BUS_WIDTH_8BIT;
2639           ecsd_bus_with = MMCSD_ECSD_BUS_WIDTH_8BIT;
2640            } else if(hwAttrs->supportedBusWidth & MMCSD_BUS_WIDTH_4BIT) {
2641           controller_buswidth = HS_MMCSD_BUS_WIDTH_4BIT;
2642           ecsd_bus_with = MMCSD_ECSD_BUS_WIDTH_4BIT;
2643            } else if(hwAttrs->supportedBusWidth & MMCSD_BUS_WIDTH_1BIT) {
2644           controller_buswidth = HS_MMCSD_BUS_WIDTH_1BIT;
2645           ecsd_bus_with = MMCSD_ECSD_BUS_WIDTH_1BIT;
2646        }
2648        if(MMCSD_OK == ret)
2649        {
2650           transaction.cmd = MMCSD_CMD(6U);
2651           transaction.arg = 0x03000000 | (MMCSD_ECSD_BUS_WIDTH_INDEX << 16) | (( (0 << MMCSD_ECSD_BUS_WIDTH_ES_SHIFT) | ecsd_bus_with) << 8);
2652           transaction.flags = MMCSD_CMDRSP_BUSY;
2653           ret = MMCSD_v2_transfer(handle, &transaction);
2654         }
2655         object->busWidth = controller_buswidth;
2657         /* NOTE: Add delay */
2658         delay(100U);
2659         if (MMCSD_OK == ret)
2660         {
2661           HSMMCSDBusWidthSet(hwAttrs->baseAddr, controller_buswidth);
2662         }
2664         /* NOTE: Add delay */
2665         delay(100U);
2667         if(MMCSD_OK == ret)
2668         {
2669             transaction.cmd = MMCSD_CMD(6U);
2670             transaction.arg = 0x03A20100;
2671             transaction.flags = MMCSD_CMDRSP_BUSY;
2672             ret = MMCSD_v2_transfer(handle, &transaction);
2673         }
2675         /* NOTE: Add delay */
2676         delay(100U);
2677     }
2678 #ifndef MMCSD_SUPPORT_MMC_HS400_DISABLED
2679     /* Read DEVICE_TYPE in the ECSD[196] to get the supported speeds */
2680     if( ( (hwAttrs->supportedModes & MMCSD_SUPPORT_MMC_HS400) || (hwAttrs->supportedModes & MMCSD_SUPPORT_MMC_HS400)) &&  (object->ecsd[MMCSD_EMMC_ECSD_DEVICE_TYPE_INDEX] & MMCSD_EMMC_ECSD_DEVICE_TYPE_HS400_200MHZ_1P8V))
2681     {
2683       if( (hwAttrs->supportedModes & MMCSD_SUPPORT_MMC_HS400_ES) && (object->ecsd[MMCSD_ECSD_STROBE_SUPPORT_INDEX] == MMCSD_ECSD_STROBE_SUPPORT_ENHANCED_EN) )
2684       {
2685          ret = MMCSD_switch_eMMC_mode(handle,MMCSD_SUPPORT_MMC_HS400_ES);
2686       }
2687       else if((hwAttrs->supportedModes & MMCSD_SUPPORT_MMC_HS400))
2688       {
2689          ret = MMCSD_switch_eMMC_mode(handle,MMCSD_SUPPORT_MMC_HS400);
2690           }
2692       if(ret==MMCSD_OK) {
2693          object->tranSpeed=MMCSD_TRANSPEED_HS400;
2694        } else {
2695                    MMCSD_DEBUG_TRAP
2696            }
2697         } /* Check for HS200 next */
2698         else
2699 #endif
2700         if( (hwAttrs->supportedModes & MMCSD_SUPPORT_MMC_HS200) && (object->ecsd[MMCSD_EMMC_ECSD_DEVICE_TYPE_INDEX] & MMCSD_EMMC_ECSD_DEVICE_TYPE_HS200_200MHZ_1P8V))
2701     {
2702          ret = MMCSD_switch_eMMC_mode(handle,MMCSD_SUPPORT_MMC_HS200);
2703          if(ret==MMCSD_OK) {
2704          object->tranSpeed=MMCSD_TRANSPEED_HS200;
2705          } else {
2706                    MMCSD_DEBUG_TRAP
2707              }
2708         } /* Check for HS-DDR next */
2709         else if ( (hwAttrs->supportedModes & MMCSD_SUPPORT_MMC_HS_DDR) && (object->ecsd[MMCSD_EMMC_ECSD_DEVICE_TYPE_INDEX] & MMCSD_EMMC_ECSD_DEVICE_TYPE_HS_DDR_52MHZ_1P8V))
2710         {
2711          ret = MMCSD_switch_eMMC_mode(handle,MMCSD_SUPPORT_MMC_HS_DDR);
2712          if(ret==MMCSD_OK) {
2713          object->tranSpeed=MMCSD_TRANSPEED_DDR50;
2714          } else {
2715                    MMCSD_DEBUG_TRAP
2716              }
2717         }
2718         else if ( (hwAttrs->supportedModes & MMCSD_SUPPORT_MMC_HS_SDR) && (object->ecsd[MMCSD_EMMC_ECSD_DEVICE_TYPE_INDEX] & MMCSD_EMMC_ECSD_DEVICE_TYPE_HS_52MHZ))
2719         {
2720          ret = MMCSD_switch_eMMC_mode(handle,MMCSD_SUPPORT_MMC_HS_SDR);
2721          if(ret==MMCSD_OK) {
2722          object->tranSpeed=MMCSD_TRANSPEED_DDR50;
2723          } else {
2724                    MMCSD_DEBUG_TRAP
2725              }
2726         }       else if (hwAttrs->supportedModes & MMCSD_SUPPORT_MMC_DS)
2727         {
2728        ret = MMCSD_switch_eMMC_mode(handle,MMCSD_SUPPORT_MMC_DS);
2729        if(ret==MMCSD_OK) {
2730          object->tranSpeed=MMCSD_TRANSPEED_SDR25;
2731        } else {
2732                  MMCSD_DEBUG_TRAP
2733            }
2734          }
2737     if(MMCSD_OK != ret)
2738     {
2739         MMCSD_v2_close(handle);
2740     }
2742     return (ret);
2744 /*
2745  *  ======== MMCSD_v2_transfer ========
2746  */
2747 static MMCSD_Error MMCSD_v2_transfer(MMCSD_Handle handle,
2748                                      MMCSD_v2_Transaction *transaction)
2750     MMCSD_Error             ret = MMCSD_ERR;
2751     hsMmcsdCmdObj_t         cmdObj = {{0U, 0U, 0U, 0U}, 0U, 0U, 0U, 0U};
2752     MMCSD_v2_Object        *object = NULL;
2753     MMCSD_v2_HwAttrs const *hwAttrs = NULL;
2754     uint32_t params;
2756     if ((handle != NULL) && (transaction != NULL))
2757     {
2758         /* Get the pointer to the object and hwAttrs */
2759         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
2760         hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
2762         ret = MMCSD_OK;
2764         if(hwAttrs->enableInterrupt==1) {
2765           /* Check the semaphre counts */
2766           int32_t count;
2767           count = SemaphoreP_getCount(object->commandComplete);
2768           if(count != 0U) {
2769               MMCSD_osalPendLock(object->commandComplete, SemaphoreP_WAIT_FOREVER);
2770           }
2771         }
2772     }
2774     if(MMCSD_OK == ret)
2775     {
2776         object->intStatusErr = MMCSD_ISR_RET_OK;
2778         /* Configure the command type to be executed from the command flags */
2779         if (transaction->flags & MMCSD_CMDRSP_STOP)
2780         {
2781             cmdObj.cmd.cmdType = HS_MMCSD_CMD_TYPE_BUS_SUSPEND;
2782         }
2783         else if (transaction->flags & MMCSD_CMDRSP_FS)
2784         {
2785             cmdObj.cmd.cmdType = HS_MMCSD_CMD_TYPE_FUNC_SEL;
2786         }
2787         else if (transaction->flags & MMCSD_CMDRSP_ABORT)
2788         {
2789             cmdObj.cmd.cmdType = HS_MMCSD_CMD_TYPE_IO_ABORT;
2790         }
2791         else
2792         {
2793             cmdObj.cmd.cmdType = 0U; /*dummy statement for misra warning*/
2794         }
2796         /* Configure the response type from the command flags */
2797         if (transaction->flags & MMCSD_CMDRSP_NONE)
2798         {
2799             cmdObj.cmd.rspType = HS_MMCSD_RSP_TYPE_NONE;
2800         }
2801         else if (transaction->flags & MMCSD_CMDRSP_136BITS)
2802         {
2803             cmdObj.cmd.rspType = HS_MMCSD_RSP_TYPE_LEN_136;
2804         }
2805         else if (transaction->flags & MMCSD_CMDRSP_BUSY)
2806         {
2807             cmdObj.cmd.rspType = HS_MMCSD_RSP_TYPE_LEN_48_BUSY;
2808         }
2809         else
2810         {
2811             cmdObj.cmd.rspType = HS_MMCSD_RSP_TYPE_LEN_48;
2812         }
2814         /* Configure the transfer type */
2815         cmdObj.enableData = (transaction->flags & MMCSD_CMDRSP_DATA) ? (uint32_t)TRUE : (uint32_t)FALSE;
2817         if(0U != hwAttrs->enableInterrupt)
2818         {
2819                         HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2820             HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2821             HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2823         } else {
2824                         HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_SIGEN_ALL);
2825                 }
2827         object->cmdComp = 0;
2828         object->cmdTimeout = 0;
2829         object->cmdCRCError = 0;
2830                 object->cmdIndexError = 0;
2831                 object->cmdEBError = 0;
2832         object->dataCRCError = 0;
2833                 object->dataEBError = 0;
2834                 object->cmdError = 0;
2835                 object->xferInProgress = 0;
2836         object->xferComp = 0;
2837         object->xferTimeout = 0;
2839                 
2840                 if (0 != cmdObj.enableData)
2841         {
2843                            /* Acquire the lock for this particular MMCSD handle */
2844             MMCSD_osalPendLock(object->transferMutex, SemaphoreP_WAIT_FOREVER);
2845             MMCSD_osalPendLock(object->commandMutex, SemaphoreP_WAIT_FOREVER);
2847             /*  MMCSD_osalHardwareIntrDisable(hwAttrs->intNum); */
2849             object->dataBufIdx = (uint8_t*)transaction->dataBuf;
2852             object->dataBlockCount = transaction->blockCount;
2853             object->dataBlockSize = transaction->blockSize;
2854                         
2856 cmdObj.cmd.xferType = (transaction->flags & MMCSD_CMDRSP_READ) ? \
2857                 HS_MMCSD_XFER_TYPE_RX : HS_MMCSD_XFER_TYPE_TX;
2858             cmdObj.numBlks = (TRUE == cmdObj.enableData) ? object->dataBlockCount : 0U;
2859             HSMMCSDIntrStatusClear(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2861             if (HS_MMCSD_XFER_TYPE_RX == cmdObj.cmd.xferType)
2862             {
2863                 /* Configure the transfer for read operation */
2864                 HSMMCSDIntrStatusClear(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2865                 HSMMCSDIntrStatusEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2866                 HSMMCSDIntrStatusDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2868                                 object->readBlockCount=object->dataBlockCount;
2869             }
2870             else
2871             {
2872                 /* Configure the transfer for write operation */
2873                 HSMMCSDIntrStatusClear(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2874                 HSMMCSDIntrStatusEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2875                 HSMMCSDIntrStatusDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2877                 if(0U != hwAttrs->enableInterrupt)
2878                 {
2879                                         HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2880                     HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2881                     HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2883                 }
2884                                 object->writeBlockCount=object->dataBlockCount;
2885             }
2887             HSMMCSDBlkLenSet(hwAttrs->baseAddr, transaction->blockSize);
2889             HSMMCSDIntrStatusClear(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2890             HSMMCSDDataTimeoutSet(hwAttrs->baseAddr, MMC_SYSCTL_DTO_15THDTO);
2892             HSMMCSDIntrStatusEnable(hwAttrs->baseAddr,
2893                 (HS_MMCSD_INTR_CMDCOMP | HS_MMCSD_INTR_CMDTIMEOUT |
2894                  HS_MMCSD_INTR_DATATIMEOUT | HS_MMCSD_INTR_TRNFCOMP | 0x17ff0000 |
2895                  HS_MMCSD_INTR_ALL_ERR));
2897             if(0U != hwAttrs->enableInterrupt)
2898             {
2899                            HSMMCSDIntrEnable(hwAttrs->baseAddr,
2900                     (HS_MMCSD_INTR_CMDCOMP | HS_MMCSD_INTR_CMDTIMEOUT |
2901                      HS_MMCSD_INTR_DATATIMEOUT));
2903                         }
2905             cmdObj.cmd.cmdId = transaction->cmd;
2906             cmdObj.cmdArg = transaction->arg;
2908             MMCSD_osalCache_wbInv(object->dataBufIdx,(transaction->blockSize * transaction->blockCount));
2910             if(hwAttrs->enableDma)
2911             {
2912                 /* Setup the adma descriptor */
2914                 /* Lower16 bits of the size  in bits 16-32 */
2915                 params = (transaction->blockCount * transaction->blockSize) << 16;
2916                 /* Upper bits of size is in bits 6-16, followed by the ADMA transfer flags (bits 0-5)   */
2917                 params= params | ((((transaction->blockCount * transaction->blockSize) >>16) <<6) | 0x0023);
2918                 /* VER4 is enabled for 26 bit sizes */
2919                 HSMMCSDHostVer4Select(hwAttrs->baseAddr, MMC_AC12_HOSTVER4_ENABLE);
2920                 HSMMCSDAdmaLengthSelect(hwAttrs->baseAddr, MMC_ADMA2_LENGTH_MODE_26BIT);
2923                 mmc_setupDescriptor(&adma2_desc,  ///< pointer to descriptor head, NOT pointer to the address value within the decriptor.
2924                                     params,     ///< parameters for descriptor.
2925                    (uint64_t)transaction->dataBuf); ///< physical address to pack into the descriptor.
2927                 HSMMCSDDmaSelect(hwAttrs->baseAddr, MMC_HCTL_DMAS_ADMA2_32BIT);
2930                 /* Write the descriptor address to ADMA2 address */
2931                 HSMMCSDAdmaAddressSet(hwAttrs->baseAddr,(((uint64_t)&adma2_desc)&0xffffffff),(((uint64_t)&adma2_desc) >> 32));
2933                 MMCSD_osalCache_wbInv(&adma2_desc,sizeof(adma2_desc));
2935                 cmdObj.enableDma = 1U;
2936             } else
2937             {
2938                 cmdObj.enableDma = 0U;
2939             }
2940                     /* Wait for command and data inhibit to go low before
2941                      * commands can be issued */
2942                 
2943                 MMCSD_v2_waitCmdInhibit(hwAttrs);
2944             MMCSD_v2_waitDatInhibit(hwAttrs);
2945  
2946             if(0U != hwAttrs->enableInterrupt)
2947             {
2948                if (HS_MMCSD_XFER_TYPE_RX == cmdObj.cmd.xferType)   
2949                            {
2950                    HSMMCSDIntrEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2951                } 
2952                             else 
2953                            {
2954                    HSMMCSDIntrEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2955                }
2956                        HSMMCSDIntrEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2957             }
2959             HSMMCSDCommandSend(hwAttrs->baseAddr,
2960                                HS_MMCSD_CMD(cmdObj.cmd.cmdId, cmdObj.cmd.cmdType, cmdObj.cmd.rspType, cmdObj.cmd.xferType),
2961                                cmdObj.cmdArg,
2962                                (TRUE == cmdObj.enableData)?MMC_CMD_DP_DATA:MMC_CMD_DP_NODATA,
2963                                cmdObj.numBlks,
2964                                cmdObj.enableDma,
2965                                MMC_CMD_ACEN_DISABLE);
2966             /*  MMCSD_osalHardwareIntrEnable(hwAttrs->intNum); */
2968 #ifdef LOG_EN
2969             MMCSD_drv_log4(Diags_USER1,
2970                        "MMCSD:(%p) Pending on commandComplete semaphore\n",
2971                        hwAttrs->baseAddr);
2972 #endif
2974             /*
2975              * Wait for the transfer to complete here.
2976              * It's OK to block from here because the MMCSD's Hwi will unblock
2977              * upon errors
2978              */
2980                     if((object->manualTuning==FALSE) &&    ((cmdObj.cmd.cmdId==MMCSD_CMD(19U)) || (cmdObj.cmd.cmdId==MMCSD_CMD(21U)))    ) 
2981                     {
2982                            object->cmdComp=1;   
2983                     }     
2984                     else 
2985                     {
2986                        if(0U != hwAttrs->enableInterrupt)
2987                {
2988                               MMCSD_osalPendLock(object->commandComplete, SemaphoreP_WAIT_FOREVER);
2989                }
2990                    else
2991                {
2992                     while ( (0 == object->cmdComp) && (0==object->cmdError) )
2993                     {
2994                         MMCSD_v2_cmdStatusFxn((uintptr_t) handle);
2995                     }
2996                 }
2997             }
2998                 
2999 #ifdef LOG_EN
3000             MMCSD_drv_log4(Diags_USER1,
3001                        "MMCSD:(%p) Command transaction completed\n", hwAttrs->baseAddr);
3002 #endif
3004             if ((transaction->flags & MMCSD_CMDREQ_WR_RD) != 0)
3005                         {
3006                  HSMMCSDIntrStatusDisable(hwAttrs->baseAddr,
3007                         (HS_MMCSD_INTR_CMDBITERR | HS_MMCSD_INTR_CMDCRCERR |
3008                          HS_MMCSD_INTR_DATABITERR | HS_MMCSD_INTR_DATACRCERR) );
3009                         }
3011             if( object->manualTuning && object->cmdError && ( (cmdObj.cmd.cmdId==MMCSD_CMD(19U)) || (cmdObj.cmd.cmdId==MMCSD_CMD(21U)) ) )  
3012                     {                              
3013                HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_CMDLINE_RESET);
3014                HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_DATALINE_RESET);
3015                            ret=MMCSD_ERR_TUNING_CMD_ERROR;
3016                     }
3017             else
3018                     {   
3019                      /* Command execution fail */
3020                 if (1 == object->cmdTimeout)
3021                 {
3022                     ret = MMCSD_ERR;
3023                     object->cmdTimeout = 0;
3024                     MMCSD_DEBUG_TRAP
3025                 }
3028                /* Command execution fail */
3029                if (1 == object->cmdCRCError)
3030                {
3031                    ret = MMCSD_ERR;
3032                    object->cmdCRCError = 0;
3033                    MMCSD_DEBUG_TRAP
3034                }
3035             }
3036             
3037                         /* Command execution successful */
3038             if (1 == object->cmdComp)
3039             {
3040                 ret = MMCSD_OK;
3041                 object->cmdComp = 0;
3043                 if(0==hwAttrs->enableInterrupt) 
3044                             {
3045                    object->xferInProgress = 1;
3046                 }
3048                 if(1 == hwAttrs->enableInterrupt) 
3049                             {
3051 #ifdef SEMAPHORE_EMUWAITS
3052                                while(dataBufferCopyComplete_emuwait);
3053 #endif
3054                                MMCSD_osalPendLock(object->dataBufferCopyComplete, SemaphoreP_WAIT_FOREVER);
3056                             }
3058                 /* Git response for command sent to MMC device */
3059                 HSMMCSDResponseGet(hwAttrs->baseAddr, transaction->response);
3060 #ifdef LOG_EN
3061                 MMCSD_drv_log4(Diags_USER1,
3062                         "MMCSD:(%p) Command Execution Failed\n", hwAttrs->baseAddr);
3063 #endif
3064             }
3067                     /* Release the lock for this particular MMCSD handle */
3068             MMCSD_osalPostLock(object->commandMutex);
3070             if(MMCSD_OK == ret)
3071             {
3072 #ifdef LOG_EN
3073             MMCSD_drv_log4(Diags_USER1,
3074                            "MMCSD:(%p) Pending on transferComplete semaphore\n",
3075                            hwAttrs->baseAddr);
3076 #endif
3078                 /*
3079                  * Wait for the transfer to complete here.
3080                  * It's OK to block from here because the MMCSD's Hwi will unblock
3081                  * upon errors
3082                  */
3083                             if(0U != hwAttrs->enableInterrupt)
3084                 {
3085                                MMCSD_osalPendLock(object->transferComplete, SemaphoreP_WAIT_FOREVER);
3086                 }
3087                 else
3088                 {
3089                     if( (object->manualTuning==FALSE) && ( (cmdObj.cmd.cmdId==MMCSD_CMD(19U)) || (cmdObj.cmd.cmdId==MMCSD_CMD(21U)) ) )
3090                                 {
3091                                        while ((0 == object->xferComp) && (0 == object->xferTimeout))
3092                        {
3093                            MMCSD_v2_xferStatusFxn_CMD19((uintptr_t) handle);
3094                        }
3096                                     }
3097                                 else
3098                                     {
3100                                       while (  (0 == object->cmdError) 
3101                                                     && (0 == object->xferComp) 
3102                                                     && (0 == object->xferTimeout) 
3103                                                         && (0 == object->dataCRCError) 
3104                                                         && (0 == object->dataEBError) )
3105                       {
3106                         MMCSD_v2_xferStatusFxn((uintptr_t) handle);
3107                       }
3109                                     }
3110                             }
3112             }
3113 #ifdef LOG_EN
3114                 MMCSD_drv_log4(Diags_USER1,
3115                            "MMCSD:(%p) Data transaction completed\n", hwAttrs->baseAddr);
3116 #endif
3118             if( object->manualTuning && object->cmdError && ( (cmdObj.cmd.cmdId==MMCSD_CMD(19U)) || (cmdObj.cmd.cmdId==MMCSD_CMD(21U)) ) )  
3119                     {                              
3120                /* In case of manual tuning, any of these errors could mean that the CMD lines & data lines are reset and move on to the next 
3121                               tuning sequence */
3122                             HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_CMDLINE_RESET);
3123                 HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_DATALINE_RESET);
3124                 ret=MMCSD_ERR_TUNING_CMD_ERROR;
3126                     }
3127                     else 
3128                     { /* Data transfer successful */
3129                 if (1 == object->xferTimeout)
3130                 {
3131                    ret = MMCSD_ERR;
3132                    MMCSD_DEBUG_TRAP
3133                    object->xferTimeout = 0;
3134 #ifdef LOG_EN
3135                     MMCSD_drv_log4(Diags_USER1,
3136                             "MMCSD:(%p) Data Transfer Failed\n", hwAttrs->baseAddr);
3137 #endif
3138                 }
3140                 /* Data transfer fail */
3141                 if (1 == object->xferComp)
3142                 {
3143                    ret = MMCSD_OK;
3144                    object->xferComp = 0;
3145 #ifdef LOG_EN
3146                     MMCSD_drv_log4(Diags_USER1,
3147                             "MMCSD:(%p) Data Transfer Successful\n", hwAttrs->baseAddr);
3148 #endif
3149                 }
3150             }
3151             
3152                         /* Release the lock for this particular MMCSD handle */
3153                         MMCSD_osalPostLock(object->transferMutex);
3155             }     
3156         else
3157         { 
3158             /* Acquire the lock for this particular MMCSD handle */
3159             MMCSD_osalPendLock(object->commandMutex, SemaphoreP_WAIT_FOREVER);
3161             /* MMCSD_osalHardwareIntrDisable(hwAttrs->intNum); */
3163             object->cmdComp = 0;
3164             object->cmdTimeout = 0;
3165             object->cmdError = 0;
3166                         object->cmdCRCError = 0;
3167                         
3168             cmdObj.cmd.cmdId = transaction->cmd;
3169             cmdObj.cmdArg = transaction->arg;
3170             cmdObj.enableDma = 0;
3172             HSMMCSDIntrStatusEnable(hwAttrs->baseAddr,
3173                 (HS_MMCSD_INTR_CMDCOMP | HS_MMCSD_INTR_ALL_ERR));
3175             if(0U != hwAttrs->enableInterrupt)
3176             {
3177                 HSMMCSDIntrEnable(hwAttrs->baseAddr,
3178                     (HS_MMCSD_INTR_CMDCOMP | HS_MMCSD_INTR_CMDTIMEOUT));
3179             }
3180             else
3181             {
3182                            HSMMCSDIntrEnable(hwAttrs->baseAddr, ~(HS_MMCSD_SIGEN_ALL));
3183                     }
3185                    /* Wait for command and data inhibit to go low before
3186                     * commands can be issued */
3187                     MMCSD_v2_waitCmdInhibit(hwAttrs);
3189             HSMMCSDCommandSend(hwAttrs->baseAddr,
3190                                HS_MMCSD_CMD(cmdObj.cmd.cmdId, cmdObj.cmd.cmdType, cmdObj.cmd.rspType, cmdObj.cmd.xferType),
3191                                cmdObj.cmdArg,
3192                                (TRUE == cmdObj.enableData)?MMC_CMD_DP_DATA:MMC_CMD_DP_NODATA,
3193                                cmdObj.numBlks,
3194                                cmdObj.enableDma,
3195                                MMC_CMD_ACEN_DISABLE);
3196 #ifdef LOG_EN
3197             MMCSD_drv_log4(Diags_USER1,
3198                        "MMCSD:(%p) Pending on commandComplete semaphore\n",
3199                        hwAttrs->baseAddr);
3200 #endif
3202             /*
3203              * Wait for the transfer to complete here.
3204              * It's OK to block from here because the MMCSD's Hwi will unblock
3205              * upon errors
3206              */
3207             if(0U != hwAttrs->enableInterrupt)
3208             {
3209                 MMCSD_osalPendLock(object->commandComplete, SemaphoreP_WAIT_FOREVER);
3210             }
3211             else
3212             {
3213                 while ((0 == object->cmdComp) && (0 == object->cmdTimeout))
3214                 {
3215                     MMCSD_v2_cmdStatusFxn((uintptr_t) handle);
3216                 }
3217             }
3219 #ifdef LOG_EN
3220             MMCSD_drv_log4(Diags_USER1,
3221                        "MMCSD:(%p) Command transaction completed\n", hwAttrs->baseAddr);
3222 #endif
3224             /* Command execution successful */
3225             if (1 == object->cmdComp)
3226             {
3227                 ret = MMCSD_OK;
3228                 object->cmdComp = 0;
3229 #ifdef LOG_EN
3230                 MMCSD_drv_log4(Diags_USER1,
3231                         "MMCSD:(%p) Command Execution successfull\n", hwAttrs->baseAddr);
3232 #endif
3233             }
3235             /* Get response for command sent to MMC device */
3236             HSMMCSDResponseGet(hwAttrs->baseAddr, transaction->response);
3238             /* Release the lock for this particular MMCSD handle */
3239             MMCSD_osalPostLock(object->commandMutex);
3240         }
3242         /* Data transfer fail or  Command execution fail */
3243         if ((1 == object->xferTimeout) || (1 == object->cmdTimeout))
3244         {
3245             if (1 == object->xferTimeout)
3246             {
3247                 ret = MMCSD_ERR;
3248                 object->xferTimeout = 0;
3249 #ifdef LOG_EN
3250                 MMCSD_drv_log4(Diags_USER1,
3251                      "MMCSD:(%p) Data Transfer Failed", hwAttrs->baseAddr);
3252 #endif
3253             }
3254             else
3255             {
3256                 ret = MMCSD_ERR;
3257                 object->cmdTimeout = 0;
3258 #ifdef LOG_EN
3259                 MMCSD_drv_log4(Diags_USER1,
3260                     "MMCSD:(%p) Command Execution Failed", hwAttrs->baseAddr);
3261 #endif
3262             }
3263             MMCSD_v2_controllerReset(object, (MMCSD_v2_HwAttrs *)hwAttrs);
3264         }
3265     }
3266     /* Return the transaction status */
3267     return (ret);
3270 /*
3271  *  ======== MMCSD_v2_control ========
3272  */
3273 /*!
3274  *  @brief      A function pointer to a driver specific implementation of
3275  *              MMCSD_control().
3276  */
3277 static MMCSD_Error MMCSD_v2_control(MMCSD_Handle handle, uint32_t cmd, const void *arg)
3279     MMCSD_Error        ret = MMCSD_ERR;
3281     /* Input parameter validation */
3282     if (handle != NULL)
3283     {
3284         switch (cmd)
3285         {
3286             case MMCSD_CMD_SETBUSWIDTH:
3287             {
3288                 ret = MMCSD_v2_setBusWidth(handle, (const uint32_t *)arg);
3289                 break;
3290             }
3292             case MMCSD_CMD_SETFREQUENCY:
3293             {
3294                 ret = MMCSD_v2_setBusFreq(handle, (const uint32_t *)arg);
3295                 break;
3296             }
3298             case MMCSD_CMD_GETBUSWIDTH:
3299             {
3300                 ret = MMCSD_v2_getBusWidth(handle, (uint32_t *)arg);
3301                 break;
3302             }
3304             case MMCSD_CMD_GETFREQUENCY:
3305             {
3306                 ret = MMCSD_v2_getBusFreq(handle, (uint32_t *)arg);
3307                 break;
3308             }
3310             case MMCSD_CMD_GETMEDIAPARAMS:
3311             {
3312                 ret = MMCSD_v2_getMediaParams(handle, (MMCSD_mediaParams *)arg);
3313                 break;
3314             }
3316             case MMCSD_CMD_ENABLEBOOTPARTITION:
3317             {
3318                 ret = MMCSD_v2_enableBootPartition(handle, (const uint8_t *)arg);
3319                 break;
3320             }
3322                         case MMCSD_CMD_GETERRORSTATUS:
3323                         {
3324                                 ret = MMCSD_v2_getErrorStatus(handle, (uint32_t *)arg);
3325                                 break;
3326                         }
3327             default:
3328             ret = MMCSD_UNDEFINEDCMD;
3329             break;
3330         }
3331     }
3332     return ret;
3335 /*
3336  *  ======== MMCSD_v2_setBusWidth ========
3337  */
3338 /*!
3339  *  @brief      A function pointer to a driver specific implementation of
3340  *              MMCSD_control().
3341  */
3342 static MMCSD_Error MMCSD_v2_setBusWidth(MMCSD_Handle handle, const uint32_t *busWidth)
3344     MMCSD_Error                 ret = MMCSD_ERR;
3345     MMCSD_v2_Object            *object = NULL;
3346     MMCSD_v2_HwAttrs const     *hwAttrs = NULL;
3347     MMCSD_v2_Transaction        transaction;
3349     /* Input parameter validation */
3350     if ((handle != NULL) && (busWidth != NULL))
3351     {
3352         /* Get the pointer to the object and hwAttrs */
3353         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3354         hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
3356         if (MMCSD_CARD_SD == object->cardType)
3357         {
3358             if ((MMCSD_BUS_WIDTH_4BIT == *busWidth) || (MMCSD_BUS_WIDTH_1BIT == *busWidth))
3359             {
3360                 ret = MMCSD_OK;
3361             }
3363             if(MMCSD_OK == ret)
3364             {
3365                 /* APP cmd should be preceeded by a CMD55 */
3366                 transaction.cmd = MMCSD_CMD(55U);
3367                 transaction.flags = 0U;
3368                 transaction.arg = object->rca << 16U;
3369                 ret = MMCSD_v2_transfer(handle, &transaction);
3370             }
3372             if(MMCSD_OK == ret)
3373             {
3374                 transaction.cmd = MMCSD_CMD(6U);
3375                 transaction.arg = MMCSD_BUS_WIDTH_1BIT;
3376                 transaction.flags = 0U;
3378                 if (hwAttrs->supportedBusWidth & MMCSD_BUS_WIDTH_4BIT)
3379                 {
3380                     if (MMCSD_BUS_WIDTH_4BIT == *busWidth)
3381                     {
3382                         transaction.arg = MMCSD_BUS_WIDTH_4BIT;
3383                     }
3384                 }
3386                 transaction.arg = transaction.arg >> 1U;
3387                 ret = MMCSD_v2_transfer(handle, &transaction);
3389                 if (MMCSD_OK == ret)
3390                 {
3391                     if (MMCSD_BUS_WIDTH_4BIT == *busWidth)
3392                     {
3393                         object->busWidth = MMCSD_BUS_WIDTH_4BIT;
3394                         HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_4BIT);
3395                     }
3396                     else
3397                     {
3398                         object->busWidth = MMCSD_BUS_WIDTH_1BIT;
3399                         HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_1BIT);
3400                     }
3401                 }
3402             }
3403         }
3404     }
3405     return(ret);
3408 /*
3409  *  ======== MMCSD_v2_setBusFreq ========
3410  */
3411 /*!
3412  *  @brief      A function pointer to a driver specific implementation of
3413  *              MMCSD_control().
3414  */
3415 static MMCSD_Error MMCSD_v2_setBusFreq(MMCSD_Handle handle, const uint32_t *busFreq)
3417     MMCSD_Error                 ret = MMCSD_ERR;
3418     MMCSD_v2_Object            *object = NULL;
3419         uint32_t cmd16_grp1_fn;
3421     /* Input parameter validation */
3422     if ((handle != NULL) && (busFreq != NULL))
3423     {
3424         /* Get the pointer to the object and hwAttrs */
3425         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3427         if (MMCSD_CARD_SD == object->cardType)
3428         {
3429             if ((MMCSD_TRANSPEED_25MBPS == *busFreq) ||
3430                 (MMCSD_TRANSPEED_50MBPS == *busFreq) ||
3431                 (MMCSD_TRANSPEED_SDR50  == *busFreq) ||
3432                 (MMCSD_TRANSPEED_DDR50  == *busFreq) ||
3433                 (MMCSD_TRANSPEED_SDR104 == *busFreq) )
3434             {
3435                 ret = MMCSD_OK;
3436             }
3438             if(object->tranSpeed == *busFreq) {
3439                  return MMCSD_OK;
3440             }
3442             switch(*busFreq)
3443             {
3444                case MMCSD_TRANSPEED_SDR104:
3445                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_SDR104;
3446                    break;
3447                case MMCSD_TRANSPEED_SDR50:
3448                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_SDR50;
3449                    break;
3450                case MMCSD_TRANSPEED_DDR50:
3451                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_DDR50;
3452                    break;
3453                case MMCSD_TRANSPEED_HS:
3454                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_HS;
3455                    break;
3456                case MMCSD_TRANSPEED_DEFAULT:
3457                default:
3458                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_DEFAULT;/*25MHz*/
3459                    break;
3460             }
3462             if(ret==MMCSD_OK){
3463               ret=MMCSD_switch_card_speed(handle,cmd16_grp1_fn);
3464             }
3465         }
3466     }
3467     return(ret);
3470 /*
3471  *  ======== MMCSD_v2_getBusWidth ========
3472  */
3473 /*!
3474  *  @brief      A function pointer to a driver specific implementation of
3475  *              MMCSD_control().
3476  */
3477 static MMCSD_Error MMCSD_v2_getBusWidth(MMCSD_Handle handle, uint32_t *busWidth)
3479     MMCSD_Error                 ret = MMCSD_ERR;
3480     MMCSD_v2_Object            *object = NULL;
3482     /* Input parameter validation */
3483     if ((handle != NULL) && (busWidth != NULL))
3484     {
3485         /* Get the pointer to the object and hwAttrs */
3486         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3488         if (MMCSD_CARD_SD == object->cardType)
3489         {
3490             *busWidth = object->busWidth;
3491             ret = MMCSD_OK;
3492         }
3493     }
3495     return(ret);
3498 /*
3499  *  ======== MMCSD_v2_getBusFreq ========
3500  */
3501 /*!
3502  *  @brief      A function pointer to a driver specific implementation of
3503  *              MMCSD_control().
3504  */
3505 static MMCSD_Error MMCSD_v2_getBusFreq(MMCSD_Handle handle, uint32_t *busFreq)
3507     MMCSD_Error                 ret = MMCSD_ERR;
3508     MMCSD_v2_Object            *object = NULL;
3510     /* Input parameter validation */
3511     if ((handle != NULL) && (busFreq != NULL))
3512     {
3513         /* Get the pointer to the object and hwAttrs */
3514         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3516         if (MMCSD_CARD_SD == object->cardType)
3517         {
3518             *busFreq = object->tranSpeed;
3519             ret = MMCSD_OK;
3520         }
3521     }
3522     return(ret);
3526 /*
3527  *  ======== MMCSD_v2_getMediaParams ========
3528  */
3529 /*!
3530  *  @brief      This function returns the media (SD/eMMC/MMC)'s parameters
3531  *              such as size, blockCount and blockSize  .
3532  */
3533 static MMCSD_Error MMCSD_v2_getMediaParams(MMCSD_Handle handle, MMCSD_mediaParams *params)
3535     MMCSD_Error                 ret = MMCSD_ERR;
3536     MMCSD_v2_Object            *object = NULL;
3538     /* Input parameter validation */
3539     if ((handle != NULL) && (params != NULL))
3540     {
3541         /* Get the pointer to the object and hwAttrs */
3542         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3544         params->blockSize = object->blockSize;
3545         params->blockCount = object->blockCount;
3546         params->size = object->size;
3548         ret = MMCSD_OK;
3549     }
3550     return(ret);
3553 /*
3554  *  ======== MMCSD_v2_getErrorStatus ========
3555  */
3556 /*!
3557  *  @brief      A function returns a error status for the command timeout
3558  *              or data transfer timeout.
3559  */
3560 static MMCSD_Error MMCSD_v2_getErrorStatus(MMCSD_Handle handle, uint32_t *errorStat)
3562     MMCSD_Error                 ret = MMCSD_ERR;
3563     MMCSD_v2_Object            *object = NULL;
3565     /* Input parameter validation */
3566     if(handle != NULL)
3567     {
3568       /* Get the pointer to the object and hwAttrs */
3569       object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3570       if(object != NULL)
3571       {
3572           if ((MMCSD_CARD_SD == object->cardType) ||
3573                     (MMCSD_CARD_MMC == object->cardType) ||
3574                         (MMCSD_CARD_EMMC == object->cardType))
3575           {
3576               *errorStat = object->intStatusErr;
3577               ret = MMCSD_OK;
3578           }
3579       }
3580     }
3581     return(ret);
3584 /*
3585  *  ======== MMCSD_v2_hwiFxn ========
3586  *  Hwi interrupt handler to service the MMCSD peripheral
3587  *
3588  *  The handler is a generic handler for a MMCSD object.
3589  */
3590 void MMCSD_v2_hwiFxn(uintptr_t arg)
3592     int32_t                 err = STW_SOK;
3593     uint32_t                errStatus;
3594     uint32_t                dataLen = 0U;
3595     uint32_t                status = 0U;
3596     volatile uint32_t       intrMask = 0U;
3597     uint32_t                temp = 0U;
3598     volatile uint32_t       cnt = 0U;
3599     MMCSD_v2_Object        *object = NULL;
3600     MMCSD_v2_HwAttrs const *hwAttrs = NULL;
3601     uint32_t                blocks_remaining,offset;
3602     uint32_t                retFlag = FALSE;
3604     /* Input parameter validation */
3605     if ((void *)arg == NULL)
3606     {
3607         retFlag = TRUE;
3608     }
3609     else
3610     {
3611         /* Get the pointer to the object and hwAttrs */
3612         object = (MMCSD_v2_Object*)(((MMCSD_Config *)arg)->object);
3613         hwAttrs = (MMCSD_v2_HwAttrs const *)(((MMCSD_Config *)arg)->hwAttrs);
3615         // status = HSMMCSDIntrStatus(hwAttrs->baseAddr);
3616         err = HSMMCSDIntrStatusGet(hwAttrs->baseAddr, HS_MMCSD_INTR_ALL, &status);
3617         if(err != STW_SOK)
3618         {
3619             retFlag = TRUE;
3620         }
3621         else
3622         {
3623             errStatus = status & 0xFFFF0000U;
3624             intrMask = HSMMCSDIntrGet(hwAttrs->baseAddr);
3625         }
3626     }
3628     /* Command execution is complete */
3629     if ((retFlag == FALSE) &&
3630         ((status & HS_MMCSD_INTR_CMDCOMP) != 0U))
3631     {
3632         HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3633                                    HS_MMCSD_INTR_CMDCOMP);
3634         object->cmdComp = 1;
3636                 /* Indicate command complete */
3637         if (intrMask & HS_MMCSD_SIGEN_CMDCOMP)
3638         {
3639                         MMCSD_osalPostLock(object->commandComplete);
3640         }
3642     }    /* Error occurred in execution of command */
3644     if ((retFlag == FALSE) && (errStatus != 0U))
3645     {
3648         if (errStatus & HS_MMCSD_INTR_CMDTIMEOUT)
3649         {
3650             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3651                                        HS_MMCSD_INTR_CMDTIMEOUT);
3652             object->cmdTimeout = 1;
3654                         /* Indicate command complete */
3655             if (intrMask & HS_MMCSD_SIGEN_CMDTIMEOUT)
3656             {
3657                 MMCSD_osalPostLock(object->commandComplete);
3658             }
3659         }
3661     }
3663     /* Read data received from card */
3664     if ((retFlag == FALSE)                           &&
3665         ((status & HS_MMCSD_INTR_BUFRDRDY) != 0U)    &&
3666         ((intrMask & HS_MMCSD_INTR_BUFRDRDY) != 0U))
3667     {
3669         HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3670                                HS_MMCSD_INTR_BUFRDRDY);
3672         if (object->dataBufIdx != NULL && object->readBlockCount)
3673         {
3674                 object->xferInProgress=1;
3675             dataLen=object->dataBlockSize;
3676                         blocks_remaining=object->readBlockCount;
3677             offset=(object->dataBlockCount-blocks_remaining)*object->dataBlockSize;
3678             for (cnt = 0U; cnt < dataLen; cnt += 4U)
3679             {
3680                             HSMMCSDDataGet(hwAttrs->baseAddr, (uint8_t *)&temp, 4U);
3681                 object->dataBufIdx[offset+cnt] = *((uint8_t*)&temp);
3682                 object->dataBufIdx[offset+cnt + 1U] = *((uint8_t*)&temp + 1U);
3683                 object->dataBufIdx[offset+cnt + 2U] = *((uint8_t*)&temp + 2U);
3684                 object->dataBufIdx[offset+cnt + 3U] = *((uint8_t*)&temp + 3U);
3685             }
3686                         object->readBlockCount--;
3687            if (object->readBlockCount==0)
3688            {
3689                       MMCSD_osalPostLock(object->dataBufferCopyComplete);
3690             }
3693         }
3694     }
3696     /* Write data received from card */
3697     if ((retFlag == FALSE)                        &&
3698         ((status & HS_MMCSD_INTR_BUFWRRDY) != 0U) &&
3699         ((intrMask & HS_MMCSD_INTR_BUFWRRDY) != 0U))
3700     {
3701         HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3702                                HS_MMCSD_INTR_BUFWRRDY);
3705                 if (object->dataBufIdx != NULL && object->writeBlockCount)
3706         {
3707             object->xferInProgress=1;
3708             dataLen=object->dataBlockSize;
3709             blocks_remaining=object->writeBlockCount;
3710                         offset=(object->dataBlockCount-blocks_remaining)*object->dataBlockSize;
3712             for (cnt = 0U; cnt < dataLen; cnt+=4U)
3713             {
3714                             *((uint8_t*)&temp) = object->dataBufIdx[offset+cnt];
3715                 *((uint8_t*)&temp + 1U) = object->dataBufIdx[offset + cnt + 1U];
3716                 *((uint8_t*)&temp + 2U) = object->dataBufIdx[offset + cnt + 2U];
3717                 *((uint8_t*)&temp + 3U) = object->dataBufIdx[offset + cnt + 3U];
3718                 // HW_WR_REG32((hwAttrs->baseAddr + CSL_MMCHS_DATA), temp);
3719                    HSMMCSDDataSet(hwAttrs->baseAddr,(uint8_t *)&temp,4);
3721             }
3722                         object->writeBlockCount--;
3723            if (object->writeBlockCount==0)
3724            {
3725                        MMCSD_osalPostLock(object->dataBufferCopyComplete);
3726            }
3728         }
3729     }
3731     /* Data transfer is complete */
3732     if ((retFlag == FALSE)                        &&
3733         ((status & HS_MMCSD_INTR_TRNFCOMP) != 0U) &&
3734         ((intrMask & HS_MMCSD_INTR_TRNFCOMP) != 0U))
3735     {
3736         if((1 == object->xferInProgress) ||  (hwAttrs->enableDma==1))
3737         {
3738             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3739                                    HS_MMCSD_INTR_TRNFCOMP);
3740             object->xferComp = 1;
3741             object->xferInProgress = 0;
3742             if (hwAttrs->enableDma==1)
3743             {
3744                 MMCSD_osalPostLock(object->dataBufferCopyComplete);
3745             }
3747             /* Indicate transfer complete */
3748             if (intrMask & HS_MMCSD_INTR_TRNFCOMP)
3749             {
3750                                 MMCSD_osalPostLock(object->transferComplete);
3751             }
3752         }
3753     }
3755     /* Error occurred in data transfer */
3756     if ((retFlag == FALSE)                           &&
3757         ((status & HS_MMCSD_INTR_DATATIMEOUT) != 0U) &&
3758         ((status & HS_MMCSD_INTR_TRNFCOMP) == 0U))
3759     {
3760         if(1 == object->xferInProgress)
3761         {
3762             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3763                                    HS_MMCSD_INTR_DATATIMEOUT);
3764             object->xferTimeout = 1;
3765             object->xferInProgress = 0;
3767             /* Indicate transfer complete */
3768             if (intrMask & HS_MMCSD_SIGEN_DATATIMEOUT)
3769             {
3770                 MMCSD_osalPostLock(object->transferComplete);
3771             }
3773         }
3774     }
3775     return;
3778 /*
3779  *  ======== MMCSD_v2_cmdStatusFxn ========
3780  *  Hwi interrupt handler to service the MMCSD peripheral
3781  *
3782  *  The handler is a generic handler for a MMCSD object.
3783  */
3784 static void MMCSD_v2_cmdStatusFxn(uintptr_t arg)
3786     int32_t err = STW_SOK;
3787     volatile uint32_t        errStatus;
3788     uint32_t        status = 0U;
3789     MMCSD_v2_Object         *object = NULL;
3790     MMCSD_v2_HwAttrs const  *hwAttrs = NULL;
3792     /* Get the pointer to the object and hwAttrs */
3793     object = (MMCSD_v2_Object*)(((MMCSD_Config *)arg)->object);
3794     hwAttrs = (MMCSD_v2_HwAttrs const *)(((MMCSD_Config *)arg)->hwAttrs);
3796     // status = HSMMCSDIntrStatus(hwAttrs->baseAddr);
3797     err = HSMMCSDIntrStatusGet(hwAttrs->baseAddr, HS_MMCSD_INTR_ALL, &status);
3798         if(err != STW_SOK)
3799         {
3800            return;
3801         }
3803     /* Command execution is complete */
3804     if (status & HS_MMCSD_INTR_CMDCOMP)
3805     {
3806         HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3807                                    HS_MMCSD_INTR_CMDCOMP);
3808         object->cmdComp = 1;
3809     }
3811     /* Error occurred in execution of command */
3812     errStatus = status & 0xFFFF0000U;
3813     if (errStatus)
3814     {
3815         
3816                 object->cmdError = 1;
3817                 object->intStatusErr = MMCSD_ISR_RET_SDSTS;
3818                 
3819                 if (errStatus & HS_MMCSD_INTR_CMDTIMEOUT)
3820         {
3821             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3822                                        HS_MMCSD_INTR_CMDTIMEOUT);
3823             object->cmdTimeout = 1;
3824         }
3825         if (errStatus & HS_MMCSD_INTR_CMDCRCERR)
3826         {
3827             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3828                                        HS_MMCSD_INTR_CMDCRCERR);
3829             object->cmdCRCError = 1;
3830         }
3832         if (errStatus & HS_MMCSD_INTR_CMDINDXERR)
3833         {
3834             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3835                                        HS_MMCSD_INTR_CMDINDXERR);
3836             object->cmdIndexError = 1;
3837         }
3839         if (errStatus & HS_MMCSD_INTR_CMDBITERR)
3840         {
3841             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3842                                        HS_MMCSD_INTR_CMDBITERR);
3843             object->cmdEBError = 1;
3844         }
3845                 
3846     }
3848     return;
3850 /*
3851  *  ======== MMCSD_v2_xferStatusFxn ========
3852  *  Hwi interrupt handler to service the MMCSD peripheral
3853  *
3854  *  The handler is a generic handler for a MMCSD object.
3855  */
3856 static void MMCSD_v2_xferStatusFxn(uintptr_t arg)
3858     int32_t err = STW_SOK;
3859     volatile uint32_t        dataLen = 0U;
3860     uint32_t                 status = 0U;
3861     uint32_t                 temp = 0U;
3862     volatile uint32_t        cnt = 0U;
3863     MMCSD_v2_Object         *object = NULL;
3864     MMCSD_v2_HwAttrs const  *hwAttrs = NULL;
3865     uint32_t blocks_remaining,offset;
3866     volatile uint32_t errStatus=0;
3868     /* Get the pointer to the object and hwAttrs */
3869     object = (MMCSD_v2_Object*)(((MMCSD_Config *)arg)->object);
3870     hwAttrs = (MMCSD_v2_HwAttrs const *)(((MMCSD_Config *)arg)->hwAttrs);
3872     // status = HSMMCSDIntrStatus(hwAttrs->baseAddr);
3873     err = HSMMCSDIntrStatusGet(hwAttrs->baseAddr, HS_MMCSD_INTR_ALL, &status);
3874         /* Error occurred in execution of command */
3875     errStatus = status & 0xFFFF0000U;
3876         if(err != STW_SOK)
3877         {
3878            return;
3879         }
3881     /* Read data received from card */
3882     if (status & HS_MMCSD_INTR_BUFRDRDY)
3883     {
3884         if(1 == object->xferInProgress)
3885         {
3886             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3887                                    HS_MMCSD_INTR_BUFRDRDY);
3889             if (object->dataBufIdx != NULL && object->readBlockCount)
3890             {
3891                 dataLen=object->dataBlockSize;
3892                                 blocks_remaining=object->readBlockCount;
3893                                 offset=(object->dataBlockCount-blocks_remaining)*object->dataBlockSize;
3895                 for (cnt = 0U; cnt < dataLen; cnt += 4U)
3896                 {
3897                     HSMMCSDDataGet(hwAttrs->baseAddr, (uint8_t *)&temp, 4U);
3898                     object->dataBufIdx[offset+cnt] = *((uint8_t*)&temp);
3899                     object->dataBufIdx[offset+cnt + 1U] = *((uint8_t*)&temp + 1U);
3900                     object->dataBufIdx[offset+cnt + 2U] = *((uint8_t*)&temp + 2U);
3901                     object->dataBufIdx[offset+cnt + 3U] = *((uint8_t*)&temp + 3U);
3902                                         }
3903                                 object->readBlockCount--;
3904             }
3905         }
3906     }
3908     /* Write data received from card */
3909     if (status & HS_MMCSD_INTR_BUFWRRDY)
3910     {
3911         if(1 == object->xferInProgress)
3912         {
3913             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3914                                    HS_MMCSD_INTR_BUFWRRDY);
3916             if (object->dataBufIdx != NULL)
3917             {
3918                                 blocks_remaining=object->writeBlockCount;
3919                                 offset=(object->dataBlockCount-blocks_remaining)*object->dataBlockSize;
3920                 dataLen = object->dataBlockSize;
3921                 for (cnt = 0U; cnt < dataLen; cnt+=4U)
3922                 {
3923                     *((uint8_t*)&temp) = object->dataBufIdx[offset+cnt];
3924                     *((uint8_t*)&temp + 1U) = object->dataBufIdx[offset+cnt + 1U];
3925                     *((uint8_t*)&temp + 2U) = object->dataBufIdx[offset+cnt + 2U];
3926                     *((uint8_t*)&temp + 3U) = object->dataBufIdx[offset+cnt + 3U];
3927                      HW_WR_REG32((hwAttrs->baseAddr + MMC_DATA), temp);
3929                      //HSMMCSDDataSet(hwAttrs->baseAddr,(uint8_t *)&temp,4);
3930                 }
3931                                 object->writeBlockCount--;
3932             }
3933         }
3934     }
3937     /* Data transfer is complete */
3938     if (status & HS_MMCSD_INTR_TRNFCOMP)
3939     {
3940         if(1 == object->xferInProgress)
3941         {
3942             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3943                                    HS_MMCSD_INTR_TRNFCOMP);
3944             object->xferComp = 1;
3945             object->xferInProgress = 0;
3946         }
3947     }
3949         
3950     /* Error occurred in execution of command */
3951     errStatus = status & 0xFFFF0000U;
3952     if (errStatus)
3953     {
3954        object->cmdError=TRUE;
3955         }
3956         
3957     if (status & HS_MMCSD_INTR_DATACRCERR)
3958     {
3959         if(1 == object->xferInProgress)
3960         {
3961             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3962                                    HS_MMCSD_INTR_DATACRCERR);
3963             object->dataCRCError = 1;
3964             object->xferInProgress = 0;
3965         }
3966     }
3968         if (status & HS_MMCSD_INTR_DATABITERR)
3969     {
3970         if(1 == object->xferInProgress)
3971         {
3972             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3973                                    HS_MMCSD_INTR_DATABITERR);
3974             object->dataEBError = 1;
3975             object->xferInProgress = 0;
3976         }
3977     }
3979         
3980         /* Error occurred in data transfer */
3981     if (status & HS_MMCSD_INTR_DATATIMEOUT && !(status & HS_MMCSD_INTR_TRNFCOMP))
3982     {
3983         if(1 == object->xferInProgress)
3984         {
3985             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3986                                    HS_MMCSD_INTR_DATATIMEOUT);
3987             object->xferTimeout = 1;
3988             object->xferInProgress = 0;
3989         }
3990     }
3992     return;
3995 /*
3996  *  ======== MMCSD_v2_xferStatusFxn ========
3997  *  Hwi interrupt handler to service the MMCSD peripheral
3998  *
3999  *  The handler is a generic handler for a MMCSD object.
4000  */
4002 static void MMCSD_v2_xferStatusFxn_CMD19(uintptr_t arg)
4004     int32_t err = STW_SOK;
4005     volatile uint32_t        dataLen = 0U;
4006     uint32_t                 status = 0U;
4007     uint32_t                 temp = 0U;
4008     volatile uint32_t        cnt = 0U;
4009     MMCSD_v2_Object         *object = NULL;
4010     MMCSD_v2_HwAttrs const  *hwAttrs = NULL;
4012     /* Get the pointer to the object and hwAttrs */
4013     object = (MMCSD_v2_Object*)(((MMCSD_Config *)arg)->object);
4014     hwAttrs = (MMCSD_v2_HwAttrs const *)(((MMCSD_Config *)arg)->hwAttrs);
4016     // status = HSMMCSDIntrStatus(hwAttrs->baseAddr);
4017     err = HSMMCSDIntrStatusGet(hwAttrs->baseAddr, HS_MMCSD_INTR_ALL, &status);
4018         if(err != STW_SOK)
4019         {
4020            return;
4021         }
4023     /* Read data received from card */
4024     if (status & HS_MMCSD_INTR_BUFRDRDY)
4025     {
4026         if(1 == object->xferInProgress)
4027         {
4028             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
4029                                    HS_MMCSD_INTR_BUFRDRDY);
4031             if (object->dataBufIdx != NULL)
4032             {
4033                 dataLen = object->dataBlockCount * object->dataBlockSize;
4035                 for (cnt = 0U; cnt < dataLen; cnt += 4U)
4036                 {
4037                     HSMMCSDDataGet(hwAttrs->baseAddr, (uint8_t *)&temp, 4U);
4038                     object->dataBufIdx[cnt] = *((uint8_t*)&temp);
4039                     object->dataBufIdx[cnt + 1U] = *((uint8_t*)&temp + 1U);
4040                     object->dataBufIdx[cnt + 2U] = *((uint8_t*)&temp + 2U);
4041                     object->dataBufIdx[cnt + 3U] = *((uint8_t*)&temp + 3U);
4042                 }
4043             }
4044                         HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
4045             HS_MMCSD_INTR_TRNFCOMP);
4046             object->xferComp = 1;
4047             object->xferInProgress = 0;
4048         }
4049     }
4050     /* Error occurred in data transfer */
4051     if (status & HS_MMCSD_INTR_DATATIMEOUT && !(status & HS_MMCSD_INTR_TRNFCOMP))
4052     {
4053         if(1 == object->xferInProgress)
4054         {
4055             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
4056                                    HS_MMCSD_INTR_DATATIMEOUT);
4057             object->xferTimeout = 1;
4058             object->xferInProgress = 0;
4059         }
4060     }
4062     /* Data transfer is complete */
4064     return;
4067 /**
4068  * \brief  This API gets the SoC level of MMCSD intial configuration
4069  *
4070  * \param  index     MMC instance index.
4071  * \param  cfg       Pointer to MMCSD SOC initial config.
4072  *
4073  * \return 0 success: -1: error
4074  *
4075  */
4076 int32_t MMCSD_socGetInitCfg(uint32_t index, MMCSD_v2_HwAttrs *cfg)
4078     int32_t ret = 0;
4080     if (index < MMCSD_CNT)
4081     {
4082         *cfg = MMCSDInitCfg[index];
4083     }
4084     else
4085     {
4086         ret = -1;
4087     }
4089     return ret;
4091 /**
4092  * \brief  This API sets the SoC level of MMCSD intial configuration
4093  *
4094  * \param  index     MMC instance index.
4095  * \param  cfg       Pointer to MMC SOC initial config.
4096  *
4097  * \return           0 success: -1: error
4098  *
4099  */
4100 int32_t MMCSD_socSetInitCfg(uint32_t index, const MMCSD_v2_HwAttrs *cfg)
4102     int32_t ret = 0;
4104     if (index < MMCSD_CNT)
4105     {
4106         MMCSDInitCfg[index] = *cfg;
4107     }
4108     else
4109     {
4110         ret = -1;
4111     }
4113     return ret;
4115 /*
4116  *  ======== Delay function ========
4117  */
4118 static void delay(uint32_t delayValue)
4120     volatile uint32_t delay1 = delayValue*10000U;
4121     while (delay1--) {}
4123 /*
4124  *  ======== MMCSD_v2_controllerReset ========
4125  */
4126 static void MMCSD_v2_controllerReset(MMCSD_v2_Object *object, MMCSD_v2_HwAttrs const *hwAttrs)
4128     volatile int32_t            status = CSL_ESYS_FAIL;
4129     MMCSD_v2_IodelayParams      iodelayParams = {MMCSD_CARD_SD, MMCSD_TRANSPEED_25MBPS, MMCSD_VOLTAGE_ANY, MMCSD_LOOPBACK_ANY};
4131     MMCSD_Error           ret = MMCSD_OK;
4133     if (MMCSD_OK == ret)
4134     {
4135         /* Lines Reset */
4136         HSMMCSDLinesReset(hwAttrs->baseAddr, HS_MMCSD_ALL_RESET);
4138         /* Set the bus width */
4139         HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_1BIT);
4141         /* Set the bus voltage */
4142                 if(hwAttrs->supportedBusVoltages & MMCSD_BUS_VOLTAGE_3_0V) {
4143            HSMMCSDBusVoltSet(hwAttrs->baseAddr, HS_MMCSD_BUS_VOLT_3P0); /* Default */
4144                 } else  if(hwAttrs->supportedBusVoltages & MMCSD_BUS_VOLTAGE_1_8V) {
4145            HSMMCSDBusVoltSet(hwAttrs->baseAddr, HS_MMCSD_BUS_VOLT_1P8);
4146         }
4147         /* Bus power on */
4148         status = ((int32_t)(HSMMCSDBusPower(hwAttrs->baseAddr, MMC_HCTL_SDBP_PWRON)));
4149                 object->switched_to_v18=FALSE;
4150         if (STW_SOK != status)
4151         {
4152             ret = MMCSD_ERR;
4153         }
4154     }
4156     if (MMCSD_OK == ret)
4157     {
4158         /* Set the initialization frequency */
4159         status = HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk,
4160             hwAttrs->outputClk, FALSE);
4161         if(NULL != hwAttrs->iodelayFxn)
4162         {
4163             iodelayParams.transferSpeed = MMCSD_TRANSPEED_25MBPS;
4164             hwAttrs->iodelayFxn(hwAttrs->instNum, &iodelayParams);
4165         }
4167         if (STW_SOK != status)
4168         {
4169             ret = MMCSD_ERR;
4170         }
4171     }