]> 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
Implemented the changes from am57x
[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;
2755         volatile uint32_t        status = 0U;
2757     if ((handle != NULL) && (transaction != NULL))
2758     {
2759         /* Get the pointer to the object and hwAttrs */
2760         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
2761         hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
2763         ret = MMCSD_OK;
2765         if(hwAttrs->enableInterrupt==1) {
2766           /* Check the semaphre counts */
2767           int32_t count;
2768           count = SemaphoreP_getCount(object->commandComplete);
2769           if(count != 0U) {
2770               MMCSD_osalPendLock(object->commandComplete, SemaphoreP_WAIT_FOREVER);
2771           }
2772         }
2773     }
2775     if(MMCSD_OK == ret)
2776     {
2777         object->intStatusErr = MMCSD_ISR_RET_OK;
2779         /* Configure the command type to be executed from the command flags */
2780         if (transaction->flags & MMCSD_CMDRSP_STOP)
2781         {
2782             cmdObj.cmd.cmdType = HS_MMCSD_CMD_TYPE_BUS_SUSPEND;
2783         }
2784         else if (transaction->flags & MMCSD_CMDRSP_FS)
2785         {
2786             cmdObj.cmd.cmdType = HS_MMCSD_CMD_TYPE_FUNC_SEL;
2787         }
2788         else if (transaction->flags & MMCSD_CMDRSP_ABORT)
2789         {
2790             cmdObj.cmd.cmdType = HS_MMCSD_CMD_TYPE_IO_ABORT;
2791         }
2792         else
2793         {
2794             cmdObj.cmd.cmdType = 0U; /*dummy statement for misra warning*/
2795         }
2797         /* Configure the response type from the command flags */
2798         if (transaction->flags & MMCSD_CMDRSP_NONE)
2799         {
2800             cmdObj.cmd.rspType = HS_MMCSD_RSP_TYPE_NONE;
2801         }
2802         else if (transaction->flags & MMCSD_CMDRSP_136BITS)
2803         {
2804             cmdObj.cmd.rspType = HS_MMCSD_RSP_TYPE_LEN_136;
2805         }
2806         else if (transaction->flags & MMCSD_CMDRSP_BUSY)
2807         {
2808             cmdObj.cmd.rspType = HS_MMCSD_RSP_TYPE_LEN_48_BUSY;
2809         }
2810         else
2811         {
2812             cmdObj.cmd.rspType = HS_MMCSD_RSP_TYPE_LEN_48;
2813         }
2815         /* Configure the transfer type */
2816         cmdObj.enableData = (transaction->flags & MMCSD_CMDRSP_DATA) ? (uint32_t)TRUE : (uint32_t)FALSE;
2818         if(0U != hwAttrs->enableInterrupt)
2819         {
2820                         HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2821             HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2822             HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2824         } else {
2825                         HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_SIGEN_ALL);
2826                 }
2828         object->cmdComp = 0;
2829         object->cmdTimeout = 0;
2830         object->cmdCRCError = 0;
2831                 object->cmdIndexError = 0;
2832                 object->cmdEBError = 0;
2833         object->dataCRCError = 0;
2834                 object->dataEBError = 0;
2835                 object->cmdError = 0;
2836                 object->xferInProgress = 0;
2837         object->xferComp = 0;
2838         object->xferTimeout = 0;
2840                 
2841                 if (0 != cmdObj.enableData)
2842         {
2844                            /* Acquire the lock for this particular MMCSD handle */
2845             MMCSD_osalPendLock(object->transferMutex, SemaphoreP_WAIT_FOREVER);
2846             MMCSD_osalPendLock(object->commandMutex, SemaphoreP_WAIT_FOREVER);
2848             /*  MMCSD_osalHardwareIntrDisable(hwAttrs->intNum); */
2850             object->dataBufIdx = (uint8_t*)transaction->dataBuf;
2853             object->dataBlockCount = transaction->blockCount;
2854             object->dataBlockSize = transaction->blockSize;
2855                         
2857 cmdObj.cmd.xferType = (transaction->flags & MMCSD_CMDRSP_READ) ? \
2858                 HS_MMCSD_XFER_TYPE_RX : HS_MMCSD_XFER_TYPE_TX;
2859             cmdObj.numBlks = (TRUE == cmdObj.enableData) ? object->dataBlockCount : 0U;
2860             HSMMCSDIntrStatusClear(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2862             if (HS_MMCSD_XFER_TYPE_RX == cmdObj.cmd.xferType)
2863             {
2864                 /* Configure the transfer for read operation */
2865                 HSMMCSDIntrStatusClear(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2866                 HSMMCSDIntrStatusEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2867                 HSMMCSDIntrStatusDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2869                                 object->readBlockCount=object->dataBlockCount;
2870             }
2871             else
2872             {
2873                 /* Configure the transfer for write operation */
2874                 HSMMCSDIntrStatusClear(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2875                 HSMMCSDIntrStatusEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2876                 HSMMCSDIntrStatusDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2878                 if(0U != hwAttrs->enableInterrupt)
2879                 {
2880                                         HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2881                     HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2882                     HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2884                 }
2885                                 object->writeBlockCount=object->dataBlockCount;
2886             }
2888             HSMMCSDBlkLenSet(hwAttrs->baseAddr, transaction->blockSize);
2890             HSMMCSDIntrStatusClear(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2891             HSMMCSDDataTimeoutSet(hwAttrs->baseAddr, MMC_SYSCTL_DTO_15THDTO);
2893             HSMMCSDIntrStatusEnable(hwAttrs->baseAddr,
2894                 (HS_MMCSD_INTR_CMDCOMP | HS_MMCSD_INTR_CMDTIMEOUT |
2895                  HS_MMCSD_INTR_DATATIMEOUT | HS_MMCSD_INTR_TRNFCOMP | 0x17ff0000 |
2896                  HS_MMCSD_INTR_ALL_ERR));
2898             if(0U != hwAttrs->enableInterrupt)
2899             {
2900                            HSMMCSDIntrEnable(hwAttrs->baseAddr,
2901                     (HS_MMCSD_INTR_CMDCOMP | HS_MMCSD_INTR_CMDTIMEOUT |
2902                      HS_MMCSD_INTR_DATATIMEOUT));
2904                         }
2906             cmdObj.cmd.cmdId = transaction->cmd;
2907             cmdObj.cmdArg = transaction->arg;
2909             MMCSD_osalCache_wbInv(object->dataBufIdx,(transaction->blockSize * transaction->blockCount));
2911             if(hwAttrs->enableDma)
2912             {
2913                 /* Setup the adma descriptor */
2915                 /* Lower16 bits of the size  in bits 16-32 */
2916                 params = (transaction->blockCount * transaction->blockSize) << 16;
2917                 /* Upper bits of size is in bits 6-16, followed by the ADMA transfer flags (bits 0-5)   */
2918                 params= params | ((((transaction->blockCount * transaction->blockSize) >>16) <<6) | 0x0023);
2919                 /* VER4 is enabled for 26 bit sizes */
2920                 HSMMCSDHostVer4Select(hwAttrs->baseAddr, MMC_AC12_HOSTVER4_ENABLE);
2921                 HSMMCSDAdmaLengthSelect(hwAttrs->baseAddr, MMC_ADMA2_LENGTH_MODE_26BIT);
2924                 mmc_setupDescriptor(&adma2_desc,  ///< pointer to descriptor head, NOT pointer to the address value within the decriptor.
2925                                     params,     ///< parameters for descriptor.
2926                    (uint64_t)transaction->dataBuf); ///< physical address to pack into the descriptor.
2928                 HSMMCSDDmaSelect(hwAttrs->baseAddr, MMC_HCTL_DMAS_ADMA2_32BIT);
2931                 /* Write the descriptor address to ADMA2 address */
2932                 HSMMCSDAdmaAddressSet(hwAttrs->baseAddr,(((uint64_t)&adma2_desc)&0xffffffff),(((uint64_t)&adma2_desc) >> 32));
2934                 MMCSD_osalCache_wbInv(&adma2_desc,sizeof(adma2_desc));
2936                 cmdObj.enableDma = 1U;
2937             } else
2938             {
2939                 cmdObj.enableDma = 0U;
2940             }
2941                     /* Wait for command and data inhibit to go low before
2942                      * commands can be issued */
2943                 
2944                 MMCSD_v2_waitCmdInhibit(hwAttrs);
2945             MMCSD_v2_waitDatInhibit(hwAttrs);
2946  
2947             if(0U != hwAttrs->enableInterrupt)
2948             {
2949                if (HS_MMCSD_XFER_TYPE_RX == cmdObj.cmd.xferType)   
2950                            {
2951                    HSMMCSDIntrEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2952                } 
2953                             else 
2954                            {
2955                    HSMMCSDIntrEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2956                }
2957                        HSMMCSDIntrEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2958             }
2960             HSMMCSDCommandSend(hwAttrs->baseAddr,
2961                                HS_MMCSD_CMD(cmdObj.cmd.cmdId, cmdObj.cmd.cmdType, cmdObj.cmd.rspType, cmdObj.cmd.xferType),
2962                                cmdObj.cmdArg,
2963                                (TRUE == cmdObj.enableData)?MMC_CMD_DP_DATA:MMC_CMD_DP_NODATA,
2964                                cmdObj.numBlks,
2965                                cmdObj.enableDma,
2966                                MMC_CMD_ACEN_DISABLE);
2967             /*  MMCSD_osalHardwareIntrEnable(hwAttrs->intNum); */
2969 #ifdef LOG_EN
2970             MMCSD_drv_log4(Diags_USER1,
2971                        "MMCSD:(%p) Pending on commandComplete semaphore\n",
2972                        hwAttrs->baseAddr);
2973 #endif
2975             /*
2976              * Wait for the transfer to complete here.
2977              * It's OK to block from here because the MMCSD's Hwi will unblock
2978              * upon errors
2979              */
2981                     if((object->manualTuning==FALSE) &&    ((cmdObj.cmd.cmdId==MMCSD_CMD(19U)) || (cmdObj.cmd.cmdId==MMCSD_CMD(21U)))    ) 
2982                     {
2983                            object->cmdComp=1;   
2984                     }     
2985                     else 
2986                     {
2987                        if(0U != hwAttrs->enableInterrupt)
2988                {
2989                               MMCSD_osalPendLock(object->commandComplete, SemaphoreP_WAIT_FOREVER);
2990                }
2991                    else
2992                {
2993                     while ( (0 == object->cmdComp) && (0==object->cmdError) )
2994                     {
2995                         MMCSD_v2_cmdStatusFxn((uintptr_t) handle);
2996                     }
2997                 }
2998             }
2999                 
3000 #ifdef LOG_EN
3001             MMCSD_drv_log4(Diags_USER1,
3002                        "MMCSD:(%p) Command transaction completed\n", hwAttrs->baseAddr);
3003 #endif
3005             if ((transaction->flags & MMCSD_CMDREQ_WR_RD) != 0)
3006                         {
3007                  HSMMCSDIntrStatusDisable(hwAttrs->baseAddr,
3008                         (HS_MMCSD_INTR_CMDBITERR | HS_MMCSD_INTR_CMDCRCERR |
3009                          HS_MMCSD_INTR_DATABITERR | HS_MMCSD_INTR_DATACRCERR) );
3010                         }
3012             if( object->manualTuning && object->cmdError && ( (cmdObj.cmd.cmdId==MMCSD_CMD(19U)) || (cmdObj.cmd.cmdId==MMCSD_CMD(21U)) ) )  
3013                     {                              
3014                HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_CMDLINE_RESET);
3015                HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_DATALINE_RESET);
3016                            ret=MMCSD_ERR_TUNING_CMD_ERROR;
3017                     }
3018             else
3019                     {   
3020                      /* Command execution fail */
3021                 if (1 == object->cmdTimeout)
3022                 {
3023                     ret = MMCSD_ERR;
3024                     object->cmdTimeout = 0;
3025                     MMCSD_DEBUG_TRAP
3026                 }
3029                /* Command execution fail */
3030                if (1 == object->cmdCRCError)
3031                {
3032                    ret = MMCSD_ERR;
3033                    object->cmdCRCError = 0;
3034                    MMCSD_DEBUG_TRAP
3035                }
3036             }
3037             
3038                         /* Command execution successful */
3039             if (1 == object->cmdComp)
3040             {
3041                 ret = MMCSD_OK;
3042                 object->cmdComp = 0;
3044                 if(0==hwAttrs->enableInterrupt) 
3045                             {
3046                    object->xferInProgress = 1;
3047                 }
3049                 if(1 == hwAttrs->enableInterrupt) 
3050                             {
3052 #ifdef SEMAPHORE_EMUWAITS
3053                                while(dataBufferCopyComplete_emuwait);
3054 #endif
3055                                MMCSD_osalPendLock(object->dataBufferCopyComplete, SemaphoreP_WAIT_FOREVER);
3057                             }
3059                 /* Git response for command sent to MMC device */
3060                 HSMMCSDResponseGet(hwAttrs->baseAddr, transaction->response);
3061 #ifdef LOG_EN
3062                 MMCSD_drv_log4(Diags_USER1,
3063                         "MMCSD:(%p) Command Execution Failed\n", hwAttrs->baseAddr);
3064 #endif
3065             }
3068                     /* Release the lock for this particular MMCSD handle */
3069             MMCSD_osalPostLock(object->commandMutex);
3071             if(MMCSD_OK == ret)
3072             {
3073 #ifdef LOG_EN
3074             MMCSD_drv_log4(Diags_USER1,
3075                            "MMCSD:(%p) Pending on transferComplete semaphore\n",
3076                            hwAttrs->baseAddr);
3077 #endif
3079                 /*
3080                  * Wait for the transfer to complete here.
3081                  * It's OK to block from here because the MMCSD's Hwi will unblock
3082                  * upon errors
3083                  */
3084                             if(0U != hwAttrs->enableInterrupt)
3085                 {
3086                                MMCSD_osalPendLock(object->transferComplete, SemaphoreP_WAIT_FOREVER);
3087                 }
3088                 else
3089                 {
3090                     if( (object->manualTuning==FALSE) && ( (cmdObj.cmd.cmdId==MMCSD_CMD(19U)) || (cmdObj.cmd.cmdId==MMCSD_CMD(21U)) ) )
3091                                 {
3092                                        while ((0 == object->xferComp) && (0 == object->xferTimeout))
3093                        {
3094                            MMCSD_v2_xferStatusFxn_CMD19((uintptr_t) handle);
3095                        }
3097                                     }
3098                                 else
3099                                     {
3101                                       while (  (0 == object->cmdError) 
3102                                                     && (0 == object->xferComp) 
3103                                                     && (0 == object->xferTimeout) 
3104                                                         && (0 == object->dataCRCError) 
3105                                                         && (0 == object->dataEBError) )
3106                       {
3107                         MMCSD_v2_xferStatusFxn((uintptr_t) handle);
3108                       }
3110                                     }
3111                             }
3113             }
3114 #ifdef LOG_EN
3115                 MMCSD_drv_log4(Diags_USER1,
3116                            "MMCSD:(%p) Data transaction completed\n", hwAttrs->baseAddr);
3117 #endif
3119             if( object->manualTuning && object->cmdError && ( (cmdObj.cmd.cmdId==MMCSD_CMD(19U)) || (cmdObj.cmd.cmdId==MMCSD_CMD(21U)) ) )  
3120                     {                              
3121                /* In case of manual tuning, any of these errors could mean that the CMD lines & data lines are reset and move on to the next 
3122                               tuning sequence */
3123                             HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_CMDLINE_RESET);
3124                 HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_DATALINE_RESET);
3125                 ret=MMCSD_ERR_TUNING_CMD_ERROR;
3127                     }
3128                     else 
3129                     { /* Data transfer successful */
3130                 if (1 == object->xferTimeout)
3131                 {
3132                    ret = MMCSD_ERR;
3133                    MMCSD_DEBUG_TRAP
3134                    object->xferTimeout = 0;
3135 #ifdef LOG_EN
3136                     MMCSD_drv_log4(Diags_USER1,
3137                             "MMCSD:(%p) Data Transfer Failed\n", hwAttrs->baseAddr);
3138 #endif
3139                 }
3141                 /* Data transfer fail */
3142                 if (1 == object->xferComp)
3143                 {
3144                    ret = MMCSD_OK;
3145                    object->xferComp = 0;
3146 #ifdef LOG_EN
3147                     MMCSD_drv_log4(Diags_USER1,
3148                             "MMCSD:(%p) Data Transfer Successful\n", hwAttrs->baseAddr);
3149 #endif
3150                 }
3151             }
3152             
3153                         /* Release the lock for this particular MMCSD handle */
3154                         MMCSD_osalPostLock(object->transferMutex);
3156             }     
3157         else
3158         { 
3159             /* Acquire the lock for this particular MMCSD handle */
3160             MMCSD_osalPendLock(object->commandMutex, SemaphoreP_WAIT_FOREVER);
3162             /* MMCSD_osalHardwareIntrDisable(hwAttrs->intNum); */
3164             object->cmdComp = 0;
3165             object->cmdTimeout = 0;
3166             object->cmdError = 0;
3167                         object->cmdCRCError = 0;
3168                         
3169             cmdObj.cmd.cmdId = transaction->cmd;
3170             cmdObj.cmdArg = transaction->arg;
3171             cmdObj.enableDma = 0;
3173             HSMMCSDIntrStatusEnable(hwAttrs->baseAddr,
3174                 (HS_MMCSD_INTR_CMDCOMP | HS_MMCSD_INTR_ALL_ERR));
3176             if(0U != hwAttrs->enableInterrupt)
3177             {
3178                 HSMMCSDIntrEnable(hwAttrs->baseAddr,
3179                     (HS_MMCSD_INTR_CMDCOMP | HS_MMCSD_INTR_CMDTIMEOUT));
3180             }
3181             else
3182             {
3183                            HSMMCSDIntrEnable(hwAttrs->baseAddr, ~(HS_MMCSD_SIGEN_ALL));
3184                     }
3186                    /* Wait for command and data inhibit to go low before
3187                     * commands can be issued */
3188                     MMCSD_v2_waitCmdInhibit(hwAttrs);
3190             HSMMCSDCommandSend(hwAttrs->baseAddr,
3191                                HS_MMCSD_CMD(cmdObj.cmd.cmdId, cmdObj.cmd.cmdType, cmdObj.cmd.rspType, cmdObj.cmd.xferType),
3192                                cmdObj.cmdArg,
3193                                (TRUE == cmdObj.enableData)?MMC_CMD_DP_DATA:MMC_CMD_DP_NODATA,
3194                                cmdObj.numBlks,
3195                                cmdObj.enableDma,
3196                                MMC_CMD_ACEN_DISABLE);
3197 #ifdef LOG_EN
3198             MMCSD_drv_log4(Diags_USER1,
3199                        "MMCSD:(%p) Pending on commandComplete semaphore\n",
3200                        hwAttrs->baseAddr);
3201 #endif
3203             /*
3204              * Wait for the transfer to complete here.
3205              * It's OK to block from here because the MMCSD's Hwi will unblock
3206              * upon errors
3207              */
3208             if(0U != hwAttrs->enableInterrupt)
3209             {
3210                 MMCSD_osalPendLock(object->commandComplete, SemaphoreP_WAIT_FOREVER);
3211             }
3212             else
3213             {
3214                 while ((0 == object->cmdComp) && (0 == object->cmdTimeout))
3215                 {
3216                     MMCSD_v2_cmdStatusFxn((uintptr_t) handle);
3217                 }
3218             }
3220 #ifdef LOG_EN
3221             MMCSD_drv_log4(Diags_USER1,
3222                        "MMCSD:(%p) Command transaction completed\n", hwAttrs->baseAddr);
3223 #endif
3225             /* Command execution successful */
3226             if (1 == object->cmdComp)
3227             {
3228                 ret = MMCSD_OK;
3229                 object->cmdComp = 0;
3230 #ifdef LOG_EN
3231                 MMCSD_drv_log4(Diags_USER1,
3232                         "MMCSD:(%p) Command Execution successfull\n", hwAttrs->baseAddr);
3233 #endif
3234             }
3236         /* Data transfer fail or  Command execution fail */
3237         if ((1 == object->xferTimeout) || (1 == object->cmdTimeout))
3238         {
3239             if (1 == object->xferTimeout)
3240             {
3241                 ret = MMCSD_ERR;
3242                  object->xferTimeout = 0;
3243 #ifdef LOG_EN
3244                  MMCSD_drv_log4(Diags_USER1,
3245                          "MMCSD:(%p) Data Transfer Failed", hwAttrs->baseAddr);
3246 #endif
3247             }
3248             else
3249             {
3250                ret = MMCSD_ERR;
3251                 object->cmdTimeout = 0;
3252 #ifdef LOG_EN
3253                 MMCSD_drv_log4(Diags_USER1,
3254                         "MMCSD:(%p) Command Execution Failed", hwAttrs->baseAddr);
3255 #endif
3256             }
3257                 MMCSD_v2_controllerReset(object, (MMCSD_v2_HwAttrs *)hwAttrs);
3258         }
3260             /* Git response for command sent to MMC device */
3261             HSMMCSDResponseGet(hwAttrs->baseAddr, transaction->response);
3263             /* Release the lock for this particular MMCSD handle */
3264             MMCSD_osalPostLock(object->commandMutex);
3265         }
3266     
3267     }
3268     /* Return the transaction status */
3269     return (ret);
3272 /*
3273  *  ======== MMCSD_v2_control ========
3274  */
3275 /*!
3276  *  @brief      A function pointer to a driver specific implementation of
3277  *              MMCSD_control().
3278  */
3279 static MMCSD_Error MMCSD_v2_control(MMCSD_Handle handle, uint32_t cmd, const void *arg)
3281     MMCSD_Error        ret = MMCSD_ERR;
3283     /* Input parameter validation */
3284     if (handle != NULL)
3285     {
3286         switch (cmd)
3287         {
3288             case MMCSD_CMD_SETBUSWIDTH:
3289             {
3290                 ret = MMCSD_v2_setBusWidth(handle, (const uint32_t *)arg);
3291                 break;
3292             }
3294             case MMCSD_CMD_SETFREQUENCY:
3295             {
3296                 ret = MMCSD_v2_setBusFreq(handle, (const uint32_t *)arg);
3297                 break;
3298             }
3300             case MMCSD_CMD_GETBUSWIDTH:
3301             {
3302                 ret = MMCSD_v2_getBusWidth(handle, (uint32_t *)arg);
3303                 break;
3304             }
3306             case MMCSD_CMD_GETFREQUENCY:
3307             {
3308                 ret = MMCSD_v2_getBusFreq(handle, (uint32_t *)arg);
3309                 break;
3310             }
3312             case MMCSD_CMD_GETMEDIAPARAMS:
3313             {
3314                 ret = MMCSD_v2_getMediaParams(handle, (MMCSD_mediaParams *)arg);
3315                 break;
3316             }
3318             case MMCSD_CMD_ENABLEBOOTPARTITION:
3319             {
3320                 ret = MMCSD_v2_enableBootPartition(handle, (const uint8_t *)arg);
3321                 break;
3322             }
3324                         case MMCSD_CMD_GETERRORSTATUS:
3325                         {
3326                                 ret = MMCSD_v2_getErrorStatus(handle, (uint32_t *)arg);
3327                                 break;
3328                         }
3329             default:
3330             ret = MMCSD_UNDEFINEDCMD;
3331             break;
3332         }
3333     }
3334     return ret;
3337 /*
3338  *  ======== MMCSD_v2_setBusWidth ========
3339  */
3340 /*!
3341  *  @brief      A function pointer to a driver specific implementation of
3342  *              MMCSD_control().
3343  */
3344 static MMCSD_Error MMCSD_v2_setBusWidth(MMCSD_Handle handle, const uint32_t *busWidth)
3346     MMCSD_Error                 ret = MMCSD_ERR;
3347     MMCSD_v2_Object            *object = NULL;
3348     MMCSD_v2_HwAttrs const     *hwAttrs = NULL;
3349     MMCSD_v2_Transaction        transaction;
3351     /* Input parameter validation */
3352     if ((handle != NULL) && (busWidth != NULL))
3353     {
3354         /* Get the pointer to the object and hwAttrs */
3355         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3356         hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
3358         if (MMCSD_CARD_SD == object->cardType)
3359         {
3360             if ((MMCSD_BUS_WIDTH_4BIT == *busWidth) || (MMCSD_BUS_WIDTH_1BIT == *busWidth))
3361             {
3362                 ret = MMCSD_OK;
3363             }
3365             if(MMCSD_OK == ret)
3366             {
3367                 /* APP cmd should be preceeded by a CMD55 */
3368                 transaction.cmd = MMCSD_CMD(55U);
3369                 transaction.flags = 0U;
3370                 transaction.arg = object->rca << 16U;
3371                 ret = MMCSD_v2_transfer(handle, &transaction);
3372             }
3374             if(MMCSD_OK == ret)
3375             {
3376                 transaction.cmd = MMCSD_CMD(6U);
3377                 transaction.arg = MMCSD_BUS_WIDTH_1BIT;
3378                 transaction.flags = 0U;
3380                 if (hwAttrs->supportedBusWidth & MMCSD_BUS_WIDTH_4BIT)
3381                 {
3382                     if (MMCSD_BUS_WIDTH_4BIT == *busWidth)
3383                     {
3384                         transaction.arg = MMCSD_BUS_WIDTH_4BIT;
3385                     }
3386                 }
3388                 transaction.arg = transaction.arg >> 1U;
3389                 ret = MMCSD_v2_transfer(handle, &transaction);
3391                 if (MMCSD_OK == ret)
3392                 {
3393                     if (MMCSD_BUS_WIDTH_4BIT == *busWidth)
3394                     {
3395                         object->busWidth = MMCSD_BUS_WIDTH_4BIT;
3396                         HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_4BIT);
3397                     }
3398                     else
3399                     {
3400                         object->busWidth = MMCSD_BUS_WIDTH_1BIT;
3401                         HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_1BIT);
3402                     }
3403                 }
3404             }
3405         }
3406     }
3407     return(ret);
3410 /*
3411  *  ======== MMCSD_v2_setBusFreq ========
3412  */
3413 /*!
3414  *  @brief      A function pointer to a driver specific implementation of
3415  *              MMCSD_control().
3416  */
3417 static MMCSD_Error MMCSD_v2_setBusFreq(MMCSD_Handle handle, const uint32_t *busFreq)
3419     MMCSD_Error                 ret = MMCSD_ERR;
3420     MMCSD_v2_Object            *object = NULL;
3421         uint32_t cmd16_grp1_fn;
3423     /* Input parameter validation */
3424     if ((handle != NULL) && (busFreq != NULL))
3425     {
3426         /* Get the pointer to the object and hwAttrs */
3427         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3429         if (MMCSD_CARD_SD == object->cardType)
3430         {
3431             if ((MMCSD_TRANSPEED_25MBPS == *busFreq) ||
3432                 (MMCSD_TRANSPEED_50MBPS == *busFreq) ||
3433                 (MMCSD_TRANSPEED_SDR50  == *busFreq) ||
3434                 (MMCSD_TRANSPEED_DDR50  == *busFreq) ||
3435                 (MMCSD_TRANSPEED_SDR104 == *busFreq) )
3436             {
3437                 ret = MMCSD_OK;
3438             }
3440             if(object->tranSpeed == *busFreq) {
3441                  return MMCSD_OK;
3442             }
3444             switch(*busFreq)
3445             {
3446                case MMCSD_TRANSPEED_SDR104:
3447                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_SDR104;
3448                    break;
3449                case MMCSD_TRANSPEED_SDR50:
3450                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_SDR50;
3451                    break;
3452                case MMCSD_TRANSPEED_DDR50:
3453                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_DDR50;
3454                    break;
3455                case MMCSD_TRANSPEED_HS:
3456                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_HS;
3457                    break;
3458                case MMCSD_TRANSPEED_DEFAULT:
3459                default:
3460                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_DEFAULT;/*25MHz*/
3461                    break;
3462             }
3464             if(ret==MMCSD_OK){
3465               ret=MMCSD_switch_card_speed(handle,cmd16_grp1_fn);
3466             }
3467         }
3468     }
3469     return(ret);
3472 /*
3473  *  ======== MMCSD_v2_getBusWidth ========
3474  */
3475 /*!
3476  *  @brief      A function pointer to a driver specific implementation of
3477  *              MMCSD_control().
3478  */
3479 static MMCSD_Error MMCSD_v2_getBusWidth(MMCSD_Handle handle, uint32_t *busWidth)
3481     MMCSD_Error                 ret = MMCSD_ERR;
3482     MMCSD_v2_Object            *object = NULL;
3484     /* Input parameter validation */
3485     if ((handle != NULL) && (busWidth != NULL))
3486     {
3487         /* Get the pointer to the object and hwAttrs */
3488         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3490         if (MMCSD_CARD_SD == object->cardType)
3491         {
3492             *busWidth = object->busWidth;
3493             ret = MMCSD_OK;
3494         }
3495     }
3497     return(ret);
3500 /*
3501  *  ======== MMCSD_v2_getBusFreq ========
3502  */
3503 /*!
3504  *  @brief      A function pointer to a driver specific implementation of
3505  *              MMCSD_control().
3506  */
3507 static MMCSD_Error MMCSD_v2_getBusFreq(MMCSD_Handle handle, uint32_t *busFreq)
3509     MMCSD_Error                 ret = MMCSD_ERR;
3510     MMCSD_v2_Object            *object = NULL;
3512     /* Input parameter validation */
3513     if ((handle != NULL) && (busFreq != NULL))
3514     {
3515         /* Get the pointer to the object and hwAttrs */
3516         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3518         if (MMCSD_CARD_SD == object->cardType)
3519         {
3520             *busFreq = object->tranSpeed;
3521             ret = MMCSD_OK;
3522         }
3523     }
3524     return(ret);
3528 /*
3529  *  ======== MMCSD_v2_getMediaParams ========
3530  */
3531 /*!
3532  *  @brief      This function returns the media (SD/eMMC/MMC)'s parameters
3533  *              such as size, blockCount and blockSize  .
3534  */
3535 static MMCSD_Error MMCSD_v2_getMediaParams(MMCSD_Handle handle, MMCSD_mediaParams *params)
3537     MMCSD_Error                 ret = MMCSD_ERR;
3538     MMCSD_v2_Object            *object = NULL;
3540     /* Input parameter validation */
3541     if ((handle != NULL) && (params != NULL))
3542     {
3543         /* Get the pointer to the object and hwAttrs */
3544         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3546         params->blockSize = object->blockSize;
3547         params->blockCount = object->blockCount;
3548         params->size = object->size;
3550         ret = MMCSD_OK;
3551     }
3552     return(ret);
3555 /*
3556  *  ======== MMCSD_v2_getErrorStatus ========
3557  */
3558 /*!
3559  *  @brief      A function returns a error status for the command timeout
3560  *              or data transfer timeout.
3561  */
3562 static MMCSD_Error MMCSD_v2_getErrorStatus(MMCSD_Handle handle, uint32_t *errorStat)
3564     MMCSD_Error                 ret = MMCSD_ERR;
3565     MMCSD_v2_Object            *object = NULL;
3567     /* Input parameter validation */
3568     if(handle != NULL)
3569     {
3570       /* Get the pointer to the object and hwAttrs */
3571       object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3572       if(object != NULL)
3573       {
3574           if ((MMCSD_CARD_SD == object->cardType) ||
3575                     (MMCSD_CARD_MMC == object->cardType) ||
3576                         (MMCSD_CARD_EMMC == object->cardType))
3577           {
3578               *errorStat = object->intStatusErr;
3579               ret = MMCSD_OK;
3580           }
3581       }
3582     }
3583     return(ret);
3586 /*
3587  *  ======== MMCSD_v2_hwiFxn ========
3588  *  Hwi interrupt handler to service the MMCSD peripheral
3589  *
3590  *  The handler is a generic handler for a MMCSD object.
3591  */
3592 void MMCSD_v2_hwiFxn(uintptr_t arg)
3594     int32_t                 err = STW_SOK;
3595     uint32_t                errStatus;
3596     uint32_t                dataLen = 0U;
3597     uint32_t                status = 0U;
3598     volatile uint32_t       intrMask = 0U;
3599     uint32_t                temp = 0U;
3600     volatile uint32_t       cnt = 0U;
3601     MMCSD_v2_Object        *object = NULL;
3602     MMCSD_v2_HwAttrs const *hwAttrs = NULL;
3603     uint32_t                blocks_remaining,offset;
3604     uint32_t                retFlag = FALSE;
3606     /* Input parameter validation */
3607     if ((void *)arg == NULL)
3608     {
3609         retFlag = TRUE;
3610     }
3611     else
3612     {
3613         /* Get the pointer to the object and hwAttrs */
3614         object = (MMCSD_v2_Object*)(((MMCSD_Config *)arg)->object);
3615         hwAttrs = (MMCSD_v2_HwAttrs const *)(((MMCSD_Config *)arg)->hwAttrs);
3617         // status = HSMMCSDIntrStatus(hwAttrs->baseAddr);
3618         err = HSMMCSDIntrStatusGet(hwAttrs->baseAddr, HS_MMCSD_INTR_ALL, &status);
3619         if(err != STW_SOK)
3620         {
3621             retFlag = TRUE;
3622         }
3623         else
3624         {
3625             errStatus = status & 0xFFFF0000U;
3626             intrMask = HSMMCSDIntrGet(hwAttrs->baseAddr);
3627         }
3628     }
3630     /* Command execution is complete */
3631     if ((retFlag == FALSE) &&
3632         ((status & HS_MMCSD_INTR_CMDCOMP) != 0U))
3633     {
3634         HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3635                                    HS_MMCSD_INTR_CMDCOMP);
3636         object->cmdComp = 1;
3638                 /* Indicate command complete */
3639         if (intrMask & HS_MMCSD_SIGEN_CMDCOMP)
3640         {
3641                         MMCSD_osalPostLock(object->commandComplete);
3642         }
3644     }    /* Error occurred in execution of command */
3646     if ((retFlag == FALSE) && (errStatus != 0U))
3647     {
3650         if (errStatus & HS_MMCSD_INTR_CMDTIMEOUT)
3651         {
3652             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3653                                        HS_MMCSD_INTR_CMDTIMEOUT);
3654             object->cmdTimeout = 1;
3656                         /* Indicate command complete */
3657             if (intrMask & HS_MMCSD_SIGEN_CMDTIMEOUT)
3658             {
3659                 MMCSD_osalPostLock(object->commandComplete);
3660             }
3661         }
3663     }
3665     /* Read data received from card */
3666     if ((retFlag == FALSE)                           &&
3667         ((status & HS_MMCSD_INTR_BUFRDRDY) != 0U)    &&
3668         ((intrMask & HS_MMCSD_INTR_BUFRDRDY) != 0U))
3669     {
3671         HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3672                                HS_MMCSD_INTR_BUFRDRDY);
3674         if (object->dataBufIdx != NULL && object->readBlockCount)
3675         {
3676                 object->xferInProgress=1;
3677             dataLen=object->dataBlockSize;
3678                         blocks_remaining=object->readBlockCount;
3679             offset=(object->dataBlockCount-blocks_remaining)*object->dataBlockSize;
3680             for (cnt = 0U; cnt < dataLen; cnt += 4U)
3681             {
3682                             HSMMCSDDataGet(hwAttrs->baseAddr, (uint8_t *)&temp, 4U);
3683                 object->dataBufIdx[offset+cnt] = *((uint8_t*)&temp);
3684                 object->dataBufIdx[offset+cnt + 1U] = *((uint8_t*)&temp + 1U);
3685                 object->dataBufIdx[offset+cnt + 2U] = *((uint8_t*)&temp + 2U);
3686                 object->dataBufIdx[offset+cnt + 3U] = *((uint8_t*)&temp + 3U);
3687             }
3688                         object->readBlockCount--;
3689            if (object->readBlockCount==0)
3690            {
3691                       MMCSD_osalPostLock(object->dataBufferCopyComplete);
3692             }
3695         }
3696     }
3698     /* Write data received from card */
3699     if ((retFlag == FALSE)                        &&
3700         ((status & HS_MMCSD_INTR_BUFWRRDY) != 0U) &&
3701         ((intrMask & HS_MMCSD_INTR_BUFWRRDY) != 0U))
3702     {
3703         HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3704                                HS_MMCSD_INTR_BUFWRRDY);
3707                 if (object->dataBufIdx != NULL && object->writeBlockCount)
3708         {
3709             object->xferInProgress=1;
3710             dataLen=object->dataBlockSize;
3711             blocks_remaining=object->writeBlockCount;
3712                         offset=(object->dataBlockCount-blocks_remaining)*object->dataBlockSize;
3714             for (cnt = 0U; cnt < dataLen; cnt+=4U)
3715             {
3716                             *((uint8_t*)&temp) = object->dataBufIdx[offset+cnt];
3717                 *((uint8_t*)&temp + 1U) = object->dataBufIdx[offset + cnt + 1U];
3718                 *((uint8_t*)&temp + 2U) = object->dataBufIdx[offset + cnt + 2U];
3719                 *((uint8_t*)&temp + 3U) = object->dataBufIdx[offset + cnt + 3U];
3720                 // HW_WR_REG32((hwAttrs->baseAddr + CSL_MMCHS_DATA), temp);
3721                    HSMMCSDDataSet(hwAttrs->baseAddr,(uint8_t *)&temp,4);
3723             }
3724                         object->writeBlockCount--;
3725            if (object->writeBlockCount==0)
3726            {
3727                        MMCSD_osalPostLock(object->dataBufferCopyComplete);
3728            }
3730         }
3731     }
3733     /* Data transfer is complete */
3734     if ((retFlag == FALSE)                        &&
3735         ((status & HS_MMCSD_INTR_TRNFCOMP) != 0U) &&
3736         ((intrMask & HS_MMCSD_INTR_TRNFCOMP) != 0U))
3737     {
3738         if((1 == object->xferInProgress) ||  (hwAttrs->enableDma==1))
3739         {
3740             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3741                                    HS_MMCSD_INTR_TRNFCOMP);
3742             object->xferComp = 1;
3743             object->xferInProgress = 0;
3744             if (hwAttrs->enableDma==1)
3745             {
3746                 MMCSD_osalPostLock(object->dataBufferCopyComplete);
3747             }
3749             /* Indicate transfer complete */
3750             if (intrMask & HS_MMCSD_INTR_TRNFCOMP)
3751             {
3752                                 MMCSD_osalPostLock(object->transferComplete);
3753             }
3754         }
3755     }
3757     /* Error occurred in data transfer */
3758     if ((retFlag == FALSE)                           &&
3759         ((status & HS_MMCSD_INTR_DATATIMEOUT) != 0U) &&
3760         ((status & HS_MMCSD_INTR_TRNFCOMP) == 0U))
3761     {
3762         if(1 == object->xferInProgress)
3763         {
3764             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3765                                    HS_MMCSD_INTR_DATATIMEOUT);
3766             object->xferTimeout = 1;
3767             object->xferInProgress = 0;
3769             /* Indicate transfer complete */
3770             if (intrMask & HS_MMCSD_SIGEN_DATATIMEOUT)
3771             {
3772                 MMCSD_osalPostLock(object->transferComplete);
3773             }
3775         }
3776     }
3777     return;
3780 /*
3781  *  ======== MMCSD_v2_cmdStatusFxn ========
3782  *  Hwi interrupt handler to service the MMCSD peripheral
3783  *
3784  *  The handler is a generic handler for a MMCSD object.
3785  */
3786 static void MMCSD_v2_cmdStatusFxn(uintptr_t arg)
3788     int32_t err = STW_SOK;
3789     volatile uint32_t        errStatus;
3790     uint32_t        status = 0U;
3791     MMCSD_v2_Object         *object = NULL;
3792     MMCSD_v2_HwAttrs const  *hwAttrs = NULL;
3794     /* Get the pointer to the object and hwAttrs */
3795     object = (MMCSD_v2_Object*)(((MMCSD_Config *)arg)->object);
3796     hwAttrs = (MMCSD_v2_HwAttrs const *)(((MMCSD_Config *)arg)->hwAttrs);
3798     // status = HSMMCSDIntrStatus(hwAttrs->baseAddr);
3799     err = HSMMCSDIntrStatusGet(hwAttrs->baseAddr, HS_MMCSD_INTR_ALL, &status);
3800         if(err != STW_SOK)
3801         {
3802            return;
3803         }
3805     /* Command execution is complete */
3806     if (status & HS_MMCSD_INTR_CMDCOMP)
3807     {
3808         HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3809                                    HS_MMCSD_INTR_CMDCOMP);
3810         object->cmdComp = 1;
3811     }
3813     /* Error occurred in execution of command */
3814     errStatus = status & 0xFFFF0000U;
3815     if (errStatus)
3816     {
3817         
3818                 object->cmdError = 1;
3819                 object->intStatusErr = MMCSD_ISR_RET_SDSTS;
3820                 
3821                 if (errStatus & HS_MMCSD_INTR_CMDTIMEOUT)
3822         {
3823             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3824                                        HS_MMCSD_INTR_CMDTIMEOUT);
3825             object->cmdTimeout = 1;
3826         }
3827         if (errStatus & HS_MMCSD_INTR_CMDCRCERR)
3828         {
3829             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3830                                        HS_MMCSD_INTR_CMDCRCERR);
3831             object->cmdCRCError = 1;
3832         }
3834         if (errStatus & HS_MMCSD_INTR_CMDINDXERR)
3835         {
3836             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3837                                        HS_MMCSD_INTR_CMDINDXERR);
3838             object->cmdIndexError = 1;
3839         }
3841         if (errStatus & HS_MMCSD_INTR_CMDBITERR)
3842         {
3843             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3844                                        HS_MMCSD_INTR_CMDBITERR);
3845             object->cmdEBError = 1;
3846         }
3847                 
3848     }
3850     return;
3852 /*
3853  *  ======== MMCSD_v2_xferStatusFxn ========
3854  *  Hwi interrupt handler to service the MMCSD peripheral
3855  *
3856  *  The handler is a generic handler for a MMCSD object.
3857  */
3858 static void MMCSD_v2_xferStatusFxn(uintptr_t arg)
3860     int32_t err = STW_SOK;
3861     volatile uint32_t        dataLen = 0U;
3862     uint32_t                 status = 0U;
3863     uint32_t                 temp = 0U;
3864     volatile uint32_t        cnt = 0U;
3865     MMCSD_v2_Object         *object = NULL;
3866     MMCSD_v2_HwAttrs const  *hwAttrs = NULL;
3867     uint32_t blocks_remaining,offset;
3868     volatile uint32_t errStatus=0;
3870     /* Get the pointer to the object and hwAttrs */
3871     object = (MMCSD_v2_Object*)(((MMCSD_Config *)arg)->object);
3872     hwAttrs = (MMCSD_v2_HwAttrs const *)(((MMCSD_Config *)arg)->hwAttrs);
3874     // status = HSMMCSDIntrStatus(hwAttrs->baseAddr);
3875     err = HSMMCSDIntrStatusGet(hwAttrs->baseAddr, HS_MMCSD_INTR_ALL, &status);
3876         /* Error occurred in execution of command */
3877     errStatus = status & 0xFFFF0000U;
3878         if(err != STW_SOK)
3879         {
3880            return;
3881         }
3883     /* Read data received from card */
3884     if (status & HS_MMCSD_INTR_BUFRDRDY)
3885     {
3886         if(1 == object->xferInProgress)
3887         {
3888             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3889                                    HS_MMCSD_INTR_BUFRDRDY);
3891             if (object->dataBufIdx != NULL && object->readBlockCount)
3892             {
3893                 dataLen=object->dataBlockSize;
3894                                 blocks_remaining=object->readBlockCount;
3895                                 offset=(object->dataBlockCount-blocks_remaining)*object->dataBlockSize;
3897                 for (cnt = 0U; cnt < dataLen; cnt += 4U)
3898                 {
3899                     HSMMCSDDataGet(hwAttrs->baseAddr, (uint8_t *)&temp, 4U);
3900                     object->dataBufIdx[offset+cnt] = *((uint8_t*)&temp);
3901                     object->dataBufIdx[offset+cnt + 1U] = *((uint8_t*)&temp + 1U);
3902                     object->dataBufIdx[offset+cnt + 2U] = *((uint8_t*)&temp + 2U);
3903                     object->dataBufIdx[offset+cnt + 3U] = *((uint8_t*)&temp + 3U);
3904                                         }
3905                                 object->readBlockCount--;
3906             }
3907         }
3908     }
3910     /* Write data received from card */
3911     if (status & HS_MMCSD_INTR_BUFWRRDY)
3912     {
3913         if(1 == object->xferInProgress)
3914         {
3915             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3916                                    HS_MMCSD_INTR_BUFWRRDY);
3918             if (object->dataBufIdx != NULL)
3919             {
3920                                 blocks_remaining=object->writeBlockCount;
3921                                 offset=(object->dataBlockCount-blocks_remaining)*object->dataBlockSize;
3922                 dataLen = object->dataBlockSize;
3923                 for (cnt = 0U; cnt < dataLen; cnt+=4U)
3924                 {
3925                     *((uint8_t*)&temp) = object->dataBufIdx[offset+cnt];
3926                     *((uint8_t*)&temp + 1U) = object->dataBufIdx[offset+cnt + 1U];
3927                     *((uint8_t*)&temp + 2U) = object->dataBufIdx[offset+cnt + 2U];
3928                     *((uint8_t*)&temp + 3U) = object->dataBufIdx[offset+cnt + 3U];
3929                      HW_WR_REG32((hwAttrs->baseAddr + MMC_DATA), temp);
3931                      //HSMMCSDDataSet(hwAttrs->baseAddr,(uint8_t *)&temp,4);
3932                 }
3933                                 object->writeBlockCount--;
3934             }
3935         }
3936     }
3939     /* Data transfer is complete */
3940     if (status & HS_MMCSD_INTR_TRNFCOMP)
3941     {
3942         if(1 == object->xferInProgress)
3943         {
3944             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3945                                    HS_MMCSD_INTR_TRNFCOMP);
3946             object->xferComp = 1;
3947             object->xferInProgress = 0;
3948         }
3949     }
3951         
3952     /* Error occurred in execution of command */
3953     errStatus = status & 0xFFFF0000U;
3954     if (errStatus)
3955     {
3956        object->cmdError=TRUE;
3957         }
3958         
3959     if (status & HS_MMCSD_INTR_DATACRCERR)
3960     {
3961         if(1 == object->xferInProgress)
3962         {
3963             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3964                                    HS_MMCSD_INTR_DATACRCERR);
3965             object->dataCRCError = 1;
3966             object->xferInProgress = 0;
3967         }
3968     }
3970         if (status & HS_MMCSD_INTR_DATABITERR)
3971     {
3972         if(1 == object->xferInProgress)
3973         {
3974             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3975                                    HS_MMCSD_INTR_DATABITERR);
3976             object->dataEBError = 1;
3977             object->xferInProgress = 0;
3978         }
3979     }
3981         
3982         /* Error occurred in data transfer */
3983     if (status & HS_MMCSD_INTR_DATATIMEOUT && !(status & HS_MMCSD_INTR_TRNFCOMP))
3984     {
3985         if(1 == object->xferInProgress)
3986         {
3987             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3988                                    HS_MMCSD_INTR_DATATIMEOUT);
3989             object->xferTimeout = 1;
3990             object->xferInProgress = 0;
3991         }
3992     }
3994     return;
3997 /*
3998  *  ======== MMCSD_v2_xferStatusFxn ========
3999  *  Hwi interrupt handler to service the MMCSD peripheral
4000  *
4001  *  The handler is a generic handler for a MMCSD object.
4002  */
4004 static void MMCSD_v2_xferStatusFxn_CMD19(uintptr_t arg)
4006     int32_t err = STW_SOK;
4007     volatile uint32_t        dataLen = 0U;
4008     uint32_t                 status = 0U;
4009     uint32_t                 temp = 0U;
4010     volatile uint32_t        cnt = 0U;
4011     MMCSD_v2_Object         *object = NULL;
4012     MMCSD_v2_HwAttrs const  *hwAttrs = NULL;
4014     /* Get the pointer to the object and hwAttrs */
4015     object = (MMCSD_v2_Object*)(((MMCSD_Config *)arg)->object);
4016     hwAttrs = (MMCSD_v2_HwAttrs const *)(((MMCSD_Config *)arg)->hwAttrs);
4018     // status = HSMMCSDIntrStatus(hwAttrs->baseAddr);
4019     err = HSMMCSDIntrStatusGet(hwAttrs->baseAddr, HS_MMCSD_INTR_ALL, &status);
4020         if(err != STW_SOK)
4021         {
4022            return;
4023         }
4025     /* Read data received from card */
4026     if (status & HS_MMCSD_INTR_BUFRDRDY)
4027     {
4028         if(1 == object->xferInProgress)
4029         {
4030             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
4031                                    HS_MMCSD_INTR_BUFRDRDY);
4033             if (object->dataBufIdx != NULL)
4034             {
4035                 dataLen = object->dataBlockCount * object->dataBlockSize;
4037                 for (cnt = 0U; cnt < dataLen; cnt += 4U)
4038                 {
4039                     HSMMCSDDataGet(hwAttrs->baseAddr, (uint8_t *)&temp, 4U);
4040                     object->dataBufIdx[cnt] = *((uint8_t*)&temp);
4041                     object->dataBufIdx[cnt + 1U] = *((uint8_t*)&temp + 1U);
4042                     object->dataBufIdx[cnt + 2U] = *((uint8_t*)&temp + 2U);
4043                     object->dataBufIdx[cnt + 3U] = *((uint8_t*)&temp + 3U);
4044                 }
4045             }
4046                         HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
4047             HS_MMCSD_INTR_TRNFCOMP);
4048             object->xferComp = 1;
4049             object->xferInProgress = 0;
4050         }
4051     }
4052     /* Error occurred in data transfer */
4053     if (status & HS_MMCSD_INTR_DATATIMEOUT && !(status & HS_MMCSD_INTR_TRNFCOMP))
4054     {
4055         if(1 == object->xferInProgress)
4056         {
4057             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
4058                                    HS_MMCSD_INTR_DATATIMEOUT);
4059             object->xferTimeout = 1;
4060             object->xferInProgress = 0;
4061         }
4062     }
4064     /* Data transfer is complete */
4066     return;
4069 /**
4070  * \brief  This API gets the SoC level of MMCSD intial configuration
4071  *
4072  * \param  index     MMC instance index.
4073  * \param  cfg       Pointer to MMCSD SOC initial config.
4074  *
4075  * \return 0 success: -1: error
4076  *
4077  */
4078 int32_t MMCSD_socGetInitCfg(uint32_t index, MMCSD_v2_HwAttrs *cfg)
4080     int32_t ret = 0;
4082     if (index < MMCSD_CNT)
4083     {
4084         *cfg = MMCSDInitCfg[index];
4085     }
4086     else
4087     {
4088         ret = -1;
4089     }
4091     return ret;
4093 /**
4094  * \brief  This API sets the SoC level of MMCSD intial configuration
4095  *
4096  * \param  index     MMC instance index.
4097  * \param  cfg       Pointer to MMC SOC initial config.
4098  *
4099  * \return           0 success: -1: error
4100  *
4101  */
4102 int32_t MMCSD_socSetInitCfg(uint32_t index, const MMCSD_v2_HwAttrs *cfg)
4104     int32_t ret = 0;
4106     if (index < MMCSD_CNT)
4107     {
4108         MMCSDInitCfg[index] = *cfg;
4109     }
4110     else
4111     {
4112         ret = -1;
4113     }
4115     return ret;
4117 /*
4118  *  ======== Delay function ========
4119  */
4120 static void delay(uint32_t delayValue)
4122     volatile uint32_t delay1 = delayValue*10000U;
4123     while (delay1--) {}
4125 /*
4126  *  ======== MMCSD_v2_controllerReset ========
4127  */
4128 static void MMCSD_v2_controllerReset(MMCSD_v2_Object *object, MMCSD_v2_HwAttrs const *hwAttrs)
4130     volatile int32_t            status = CSL_ESYS_FAIL;
4131     MMCSD_v2_IodelayParams      iodelayParams = {MMCSD_CARD_SD, MMCSD_TRANSPEED_25MBPS, MMCSD_VOLTAGE_ANY, MMCSD_LOOPBACK_ANY};
4133     MMCSD_Error           ret = MMCSD_OK;
4135     if (MMCSD_OK == ret)
4136     {
4137         /* Lines Reset */
4138         HSMMCSDLinesReset(hwAttrs->baseAddr, HS_MMCSD_ALL_RESET);
4140         /* Set the bus width */
4141         HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_1BIT);
4143         /* Set the bus voltage */
4144                 if(hwAttrs->supportedBusVoltages & MMCSD_BUS_VOLTAGE_3_0V) {
4145            HSMMCSDBusVoltSet(hwAttrs->baseAddr, HS_MMCSD_BUS_VOLT_3P0); /* Default */
4146                 } else  if(hwAttrs->supportedBusVoltages & MMCSD_BUS_VOLTAGE_1_8V) {
4147            HSMMCSDBusVoltSet(hwAttrs->baseAddr, HS_MMCSD_BUS_VOLT_1P8);
4148         }
4149         /* Bus power on */
4150         status = ((int32_t)(HSMMCSDBusPower(hwAttrs->baseAddr, MMC_HCTL_SDBP_PWRON)));
4151                 object->switched_to_v18=FALSE;
4152         if (STW_SOK != status)
4153         {
4154             ret = MMCSD_ERR;
4155         }
4156     }
4158     if (MMCSD_OK == ret)
4159     {
4160         /* Set the initialization frequency */
4161         status = HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk,
4162             hwAttrs->outputClk, FALSE);
4163         if(NULL != hwAttrs->iodelayFxn)
4164         {
4165             iodelayParams.transferSpeed = MMCSD_TRANSPEED_25MBPS;
4166             hwAttrs->iodelayFxn(hwAttrs->instNum, &iodelayParams);
4167         }
4169         if (STW_SOK != status)
4170         {
4171             ret = MMCSD_ERR;
4172         }
4173     }