]> 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                           &nbs