6141e82af3cd69d8eca61660b39ad1afcdf9b38a
[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 SD voltage enumeration as per VHS field, after the CHECK PATTERN FIELD */
106 #define MMCSD_VOLT_2P7_3P6          (0x000100U)
107 #define MMCSD_VOLT_LOW_RANGE        (0x000200U)
109 /**
110  * SD OCR register definitions.
111  */
113 /** \brief High capacity card type. */
114 #define MMCSD_OCR_HIGH_CAPACITY     (BIT(30U))
116 #define MMCSD_OCR_S18R  (BIT(24U))
117 /**
118  * Voltage configurations.
119  */
121 /** \brief Configure for 2.7V to 2.8V VDD level. */
122 #define MMCSD_OCR_VDD_2P7_2P8       (BIT(15U))
124 /** \brief Configure for 2.8V to 2.9V VDD level. */
125 #define MMCSD_OCR_VDD_2P8_2P9       (BIT(16U))
127 /** \brief Configure for 2.9V to 3.0V VDD level. */
128 #define MMCSD_OCR_VDD_2P9_3P0       (BIT(17U))
130 /** \brief Configure for 3.0V to 3.1V VDD level. */
131 #define MMCSD_OCR_VDD_3P0_3P1       (BIT(18U))
133 /** \brief Configure for 3.1V to 3.2V VDD level. */
134 #define MMCSD_OCR_VDD_3P1_3P2       (BIT(19U))
136 /** \brief Configure for 3.2V to 3.3V VDD level. */
137 #define MMCSD_OCR_VDD_3P2_3P3       (BIT(20U))
139 /** \brief Configure for 3.3V to 3.4V VDD level. */
140 #define MMCSD_OCR_VDD_3P3_3P4       (BIT(21U))
142 /** \brief Configure for 3.4V to 3.5V VDD level. */
143 #define MMCSD_OCR_VDD_3P4_3P5       (BIT(22U))
145 /** \brief Configure for 3.5V to 3.6V VDD level. */
146 #define MMCSD_OCR_VDD_3P5_3P6       (BIT(23U))
148 /** \brief Wild card to configure for VDD level. */
149 #define MMCSD_OCR_VDD_WILDCARD      (((uint32_t)0x1FFU) << 15U)
151 /**
152  * SD CSD register definitions.
153  */
155 /** \brief Card bus frequency configuration for 25 Mbps. */
156 #define MMCSD_TRANSPEED_25MBPS      (0x32U)
158 /** \brief Card bus frequency configuration for 50 Mbps. */
159 #define MMCSD_TRANSPEED_50MBPS      (0x5AU)
160 /** \brief Gives the card version. */
161 #define MMCSD_CARD_CMMCSD_VERSION(crd) \
162     (((crd)->csd[3U] & 0xC0000000U) >> 30U)
164 /** \brief Extract the size of device for SD version 0. */
165 #define MMCSD_CSD0_DEV_SIZE(csd3, csd2, csd1, csd0) \
166     ((uint64_t)(((csd2) & 0x000003FFU) << 2U) | (((csd1) & 0xC0000000U) >> 30U))
168 /** \brief TBD for SD version 0. */
169 #define MMCSD_CSD0_MULT(csd3, csd2, csd1, csd0) \
170     (((csd1) & 0x00038000U) >> 15U)
172 /** \brief Extract the read block length for SD version 0. */
173 #define MMCSD_CSD0_RDBLKLEN(csd3, csd2, csd1, csd0) \
174     (((csd2) & 0x000F0000U) >> 16U)
176 /** \brief Extract the card transfer speed for SD version 0. */
177 #define MMCSD_CSD0_TRANSPEED(csd3, csd2, csd1, csd0) \
178     (((csd3) & 0x000000FFU) >> 0U)
180 /** \brief Extracts the size of card for SD version 0. */
181 #define MMCSD_CARD0_DEV_SIZE(crd) \
182     (MMCSD_CSD0_DEV_SIZE((crd)->csd[3U], (crd)->csd[2U], \
183     (crd)->csd[1U], (crd)->csd[0U]))
185 /** \brief TBD for SD version 0. */
186 #define MMCSD_CARD0_MULT(crd) \
187     (MMCSD_CSD0_MULT((crd)->csd[3U], (crd)->csd[2U], \
188     (crd)->csd[1U], (crd)->csd[0U]))
190 /** \brief Gives the card block length for SD version 0. */
191 #define MMCSD_CARD0_RDBLKLEN(crd) \
192     (MMCSD_CSD0_RDBLKLEN((crd)->csd[3U], (crd)->csd[2U], \
193     (crd)->csd[1U], (crd)->csd[0U]))
195 /** \brief Gives the card transfer speed for SD version 0. */
196 #define MMCSD_CARD0_TRANSPEED(crd) \
197     (MMCSD_CSD0_TRANSPEED((crd)->csd[3U], (crd)->csd[2U], \
198     (crd)->csd[1U], (crd)->csd[0U]))
200 /** \brief Gives number of blocks on card for SD version 0. */
201 #define MMCSD_CARD0_NUMBLK(crd) \
202     ((MMCSD_CARD0_DEV_SIZE((crd)) + 1U) * \
203     (((uint32_t)1U) << (MMCSD_CARD0_MULT((crd)) + 2U)))
205 /** \brief Gives the size of card for SD version 0. */
206 #define MMCSD_CARD0_SIZE(crd) ((MMCSD_CARD0_NUMBLK((crd))) * \
207     (((uint32_t)1U) << (MMCSD_CARD0_RDBLKLEN(crd))))
209 /** \brief Extracts the size of card for SD version 1. */
210 #define MMCSD_CSD1_DEV_SIZE(csd3, csd2, csd1, csd0) \
211     ((uint64_t)(((csd2) & 0x0000003FU) << 16U) | (((csd1) & 0xFFFF0000U) >> 16U))
213 /** \brief Extracts the card block length for SD version 1. */
214 #define MMCSD_CSD1_RDBLKLEN(csd3, csd2, csd1, csd0) \
215     (((csd2) & 0x000F0000U) >> 16U)
217 /** \brief Extracts the card transfer speed for SD version 1. */
218 #define MMCSD_CSD1_TRANSPEED(csd3, csd2, csd1, csd0) \
219     (((csd3) & 0x000000FFU) >> 0U)
221 /** \brief Gives the size of card for SD version 1. */
222 #define MMCSD_CARD1_DEV_SIZE(crd) \
223     (MMCSD_CSD1_DEV_SIZE((crd)->csd[3U], (crd)->csd[2U], \
224     (crd)->csd[1U], (crd)->csd[0U]))
226 /** \brief Reads the card block length for SD version 1. */
227 #define MMCSD_CARD1_RDBLKLEN(crd) \
228     (MMCSD_CSD1_RDBLKLEN((crd)->csd[3U], (crd)->csd[2U], \
229     (crd)->csd[1U], (crd)->csd[0U]))
231 /** \brief Reads the card transfer speed for SD version 1. */
232 #define MMCSD_CARD1_TRANSPEED(crd) \
233     (MMCSD_CSD1_TRANSPEED((crd)->csd[3U], (crd)->csd[2U], \
234     (crd)->csd[1U], (crd)->csd[0U]))
236 /** \brief Gives the size of card for SD version 1. */
237 #define MMCSD_CARD1_SIZE(crd) (((MMCSD_CARD1_DEV_SIZE((crd)) + 1U) * \
238     (512U * 1024U)))
240 /** \brief This is the timeout value for sending CMD13 to the card.
241  * After every write, the CMD13 is sent this many times and wait for
242  * the card to go to transfer state
243  * */
244 #define MMCSD_CARD_TRANS_STATE_THRESHOLD  (10000U)
246 /* Card status value (Bits 9-12) as defined in physical layer
247  * specification section 4.10.1.
248  */
249 #define MMCSD_CARD_STATE_TRANSFER  (4U)
250 /**
251  * Check RCA/status.
252  */
254  /** \brief Command relative address. */
255 #define MMCSD_RCA_ADDR(rca)             (((rca) & 0xFFFF0000U) >> 16U)
257 /** \brief TBD. */
258 #define MMCSD_RCA_STAT(rca)             ((rca) & 0x0xFFFFU)
260 /** \brief Check pattern that can be used for card response validation. */
261 #define MMCSD_CHECK_PATTERN             (0xAAU)
263 /**
264  * SD SCR related macros.
265  */
267 /** \brief Card version 0. */
268 #define MMCSD_VERSION_1P0               (0U)
270 /** \brief Card version 1. */
271 #define MMCSD_VERSION_1P1               (1U)
273 /** \brief Card version 2. */
274 #define MMCSD_VERSION_2P0               (2U)
276 /**
277  * Helper macros.
278  * Note card registers are big endian.
279  */
281 /** \brief Reads card version. */
282 #define MMCSD_CARD_VERSION(sdcard)      (((sdcard)->scr[0U] & 0x0F000000U) >> 24)
284 /** \brief Reads card bus width. */
285 #define MMCSD_CARD_BUSWIDTH(sdcard) (((sdcard)->scr[0U] & 0x000F0000U) >> 16)
287 /** \brief Reads if the SD Card supports CMD23. */
288 #define MMCSD_CARD_CMD23_SUPPORT(sdcard) (((sdcard)->scr[0U] & 0x00000002U) >> 1)
290 /** \brief Check for bus width. Give below values
291  *         - MMCSD_BUS_WIDTH_1BIT for 1-bit.
292  *         - MMCSD_BUS_WIDTH_4BIT for 4-bit.
293  *         - 0xFFU                    for invalid bus width.
294  */
295 #define MMCSD_GET_CARD_BUSWIDTH(sdcard) \
296     (((((sdcard).busWidth) & 0x0FU) == 0x01) ? \
297     0x1 : (((((sdcard).busWidth) & 0x04U) == 0x04U) ? 0x04U : 0xFFU))
299 /** \brief Check for bus width. Give below values
300  *         - 50U for 50 MHz.
301  *         - 25U for 25 Mhz.
302  *         - 0U  for invalid bus width.
303  */
304 #define MMCSD_GET_CARD_FRE(sdcard) ((((sdcard).tranSpeed) == 0x5AU) ? 50U : \
305     ((((sdcard).tranSpeed) == 0x32U) ? 25U : \
306     ((((sdcard).tranSpeed) == 0xBU) ? 100U : \
307     ((((sdcard).tranSpeed) == 0x2BU) ? 200U : 0U))
309 /** \brief Define cache line size for buffer alignment. */
310 #ifndef SOC_CACHELINE_SIZE
311 #define SOC_CACHELINE_SIZE                  (128U)
312 #endif
314 /** \brief Command argument to configure for switch mode. */
315 #define MMCSD_SWITCH_MODE               (0x80FFFFFFU)
316 #define MMCSD_CHECK_MODE                (0x00FFFFFFU)
317 /** \brief Command argument width to configure for transfer speed. */
318 #define MMCSD_CMD6_GRP1_SEL             (0xFFFFFFF0U)
319 #define MMCSD_CMD6_GRP4_SEL             (0xFFFF0FFFU)
321 /** \brief Command argument to configure for default/SDR12 speed. */
322 #define MMCSD_CMD6_GRP1_DEFAULT         (0x0U)
323 /** \brief Command argument to configure for high/SDR25 speed. */
324 #define MMCSD_CMD6_GRP1_HS              (0x1U)
325 /** \brief Command argument to configure for SDR50 speed. */
326 #define MMCSD_CMD6_GRP1_SDR50           (0x2U)
327 /** \brief Command argument to configure for SDR104 speed. */
328 #define MMCSD_CMD6_GRP1_SDR104          (0x3U)
329 /** \brief Command argument to configure for DDR50 speed. */
330 #define MMCSD_CMD6_GRP1_DDR50           (0x4U)
332 #define MMCSD_CMD6_GRP4_200mA           (0x0U)
333 #define MMCSD_CMD6_GRP4_400mA           (0x1U)
334 #define MMCSD_CMD6_GRP4_600mA           (0x2U)
335 #define MMCSD_CMD6_GRP4_800mA           (0x3U)
338 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_INDEX  (196)
339 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_DS       (0x0U)
340 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS_26MHZ (0x1U)
341 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS_52MHZ (0x2U)
342 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS_DDR_52MHZ_1P8V (0x4U)
343 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS_DDR_52MHZ_1P2V (0x8U)
345 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS200_200MHZ_1P8V (0x10U)
346 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS200_200MHZ_1P2V (0x20U)
347 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS400_200MHZ_1P8V (0x40U)
348 #define MMCSD_EMMC_ECSD_DEVICE_TYPE_HS400_200MHZ_1P2V (0x80U)
350 #define MMCSD_ECSD_BUS_WIDTH_INDEX (183U)
351 #define MMCSD_ECSD_BUS_WIDTH_1BIT       (0U)
352 #define MMCSD_ECSD_BUS_WIDTH_4BIT       (1U)
353 #define MMCSD_ECSD_BUS_WIDTH_8BIT       (2U)
354 #define MMCSD_ECSD_BUS_WIDTH_4BIT_DDR   (5U)
355 #define MMCSD_ECSD_BUS_WIDTH_8BIT_DDR   (6U)
357 #define MMCSD_ECSD_BUS_WIDTH_BUSWIDTH_MASK    (0x0FU)
358 #define MMCSD_ECSD_BUS_WIDTH_BUSWIDTH_SHIFT   (0U)
360 #define MMCSD_ECSD_BUS_WIDTH_ES_ENABLE    (0x80U)
362 #define MMCSD_ECSD_BUS_WIDTH_ES_MASK    (0x80U)
363 #define MMCSD_ECSD_BUS_WIDTH_ES_SHIFT   (7U)
365 #define MMCSD_ECSD_HS_TIMING_INDEX    (185U)
366 #define MMCSD_ECSD_HS_TIMING_BACKWARD_COMPATIBLE       (0U)
367 #define MMCSD_ECSD_HS_TIMING_HIGH_SPEED                (1U)
368 #define MMCSD_ECSD_HS_TIMING_HS200                     (2U)
369 #define MMCSD_ECSD_HS_TIMING_HS400                     (3U)
371 #define MMCSD_ECSD_STROBE_SUPPORT_INDEX         (184U)
372 #define MMCSD_ECSD_STROBE_SUPPORT_ENHANCED_DIS    (0U)
373 #define MMCSD_ECSD_STROBE_SUPPORT_ENHANCED_EN    (1U)
377 volatile uint32_t mmcsd_emuwait_trap=1;
380 /* Tuning pattern for SDR104 mode */
381 static const uint8_t tuning_blk_pattern_4bit[] = {
382         0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
383         0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
384         0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
385         0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
386         0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
387         0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
388         0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
389         0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
390 };
391 /* Tuning pattern for HS200 mode */
392 static const uint8_t tuning_blk_pattern_8bit[] = {
393         0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
394         0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
395         0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
396         0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
397         0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
398         0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
399         0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
400         0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
401         0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
402         0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
403         0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
404         0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
405         0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
406         0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
407         0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
408         0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
409 };
411 #define BITMASK(n)      ((1 << (n)) - 1)        //!< Creates a bit mask with bits n:0 set
414 //! \brief insert a field into a 32 bit value using the CSL mask and shift fields
415 //! \param[in] val The initial value which will have the field inserted
416 //! \param[in] field The value to insert
417 //! \param[in] mask  The mask over the input value val where field will be inserted
418 //! \param[in] shift The least significant bit in the mask field
419 //! \return          The input parameter val with the value field inserted starting a bit shift
420 static inline uint32_t Bitfield_csl_set (uint32_t val, uint32_t field, uint32_t mask, int32_t shift)
422     return ( (val & ~mask) | (field << shift) );
425 //! \brief Return the size of an integer field (number of values that a bitfield can have)
426 //! \param[in] msb The most significant bit of the field
427 //! \param[in] lsb The least significant bit of the field
428 //! \return        The number of values the bit field can have
430 /* MMC functions */
431 static MMCSD_Error MMCSD_v2_close(MMCSD_Handle handle);
432 static MMCSD_Error MMCSD_v2_init(MMCSD_Handle handle);
433 static MMCSD_Error MMCSD_v2_open(MMCSD_Handle handle, MMCSD_Params params);
434 static MMCSD_Error MMCSD_v2_write(MMCSD_Handle handle,
435                                   uint8_t *buf,
436                                   uint32_t block,
437                                   uint32_t numBlks);
438 static MMCSD_Error MMCSD_v2_read(MMCSD_Handle handle,
439                                  uint8_t *buf,
440                                  uint32_t block,
441                                  uint32_t numBlks);
442 static MMCSD_Error MMCSD_v2_transfer(MMCSD_Handle handle,
443                                      MMCSD_v2_Transaction *transaction);
444 static MMCSD_Error MMCSD_v2_control(MMCSD_Handle handle, uint32_t cmd, const void *arg);
445 static MMCSD_Error MMCSD_v2_enableBootPartition(MMCSD_Handle handle, const uint8_t *partition);
446 static MMCSD_Error MMCSD_v2_initSd(MMCSD_Handle handle);
447 static MMCSD_Error MMCSD_v2_initEmmc(MMCSD_Handle handle);
448 static MMCSD_Error MMCSD_v2_setBusWidth(MMCSD_Handle handle, const uint32_t *busWidth);
449 static MMCSD_Error MMCSD_v2_setBusFreq(MMCSD_Handle handle, const uint32_t *busFreq);
450 static MMCSD_Error MMCSD_v2_getBusWidth(MMCSD_Handle handle, uint32_t *busWidth);
451 static MMCSD_Error MMCSD_v2_getBusFreq(MMCSD_Handle handle, uint32_t *busFreq);
452 static MMCSD_Error MMCSD_v2_getMediaParams(MMCSD_Handle handle, MMCSD_mediaParams *params);
453 void MMCSD_v2_hwiFxn(uintptr_t arg);
454 static void MMCSD_v2_cmdStatusFxn(uintptr_t arg);
455 static void MMCSD_v2_xferStatusFxn(uintptr_t arg);
457 static MMCSD_Error mmcsd_tuning_procedure(MMCSD_Handle handle);
458 static void MMCSD_v2_xferStatusFxn_CMD19(uintptr_t arg);
459 static MMCSD_Error MMCSD_switch_card_speed(MMCSD_Handle handle,uint32_t cmd16_grp1_fn);
460 /* Delay function */
461 static void delay(uint32_t delayValue);
463 /* MMC function table for MMC implementation */
464 const MMCSD_FxnTable MMCSD_v2_FxnTable = {
465     &MMCSD_v2_close,
466     &MMCSD_v2_control,
467     &MMCSD_v2_init,
468     &MMCSD_v2_open,
469     &MMCSD_v2_write,
470     &MMCSD_v2_read
471 };
472 typedef struct {
473   uint32_t params;
474   uint32_t addrl;
475   uint32_t addrh;
476 } adma2_desc_t;
478 adma2_desc_t adma2_desc;
479 #if defined(__ARM_ARCH_7A__) || defined(__aarch64__) || ((__ARM_ARCH == 7) && (__ARM_ARCH_PROFILE == 'R'))
480 __attribute__((aligned(SOC_CACHELINE_SIZE))) // GCC way of aligning
481 #endif
483 void mmc_setupDescriptor(
484     adma2_desc_t *desc,  ///< pointer to descriptor head, NOT pointer to the address value within the decriptor.
485     uint32_t params,     ///< parameters for descriptor.
486     uint64_t address     ///< physical address to pack into the descriptor.
487     )
489   desc->params = params;
490   desc->addrl  = address & 0xffffffffu;
491   desc->addrh  = (address >> 32) & 0xffffu;
496 /* Wait for DAT0 to go low */
497 static int32_t MMCSD_v2_waitDat0(MMCSD_v2_HwAttrs const *hwAttrs);
498 static int32_t MMCSD_v2_waitDat0(MMCSD_v2_HwAttrs const *hwAttrs)
500   /* Check for DAT0 to go low */
501   volatile uint32_t present_state_reg;
502   do {
503      present_state_reg= HW_RD_REG32(hwAttrs->baseAddr + MMC_PSTATE);
504   } while( (present_state_reg & (1 << 20))!=(1<<20));
506   return STW_SOK;
509 /* Waits for cmd inhibit to go low */
510 static int32_t MMCSD_v2_waitCmdInhibit(MMCSD_v2_HwAttrs const *hwAttrs);
511 static int32_t MMCSD_v2_waitCmdInhibit(MMCSD_v2_HwAttrs const *hwAttrs)
513   uint32_t ready=1;
514   do {
515      ready=*((volatile uint32_t *)(hwAttrs->baseAddr + MMC_PSTATE)) & 0x1;
516    } while(ready!=0);
517    return STW_SOK;
519 /* Waits for data inhibit to go low */
520 static int32_t MMCSD_v2_waitDatInhibit(MMCSD_v2_HwAttrs const *hwAttrs);
521 static int32_t MMCSD_v2_waitDatInhibit(MMCSD_v2_HwAttrs const *hwAttrs)
523   uint32_t ready=1;
524   /* Check for  DAT inhibit */
525   do {
526     ready=*((volatile uint32_t *)(hwAttrs->baseAddr + MMC_PSTATE)) & 0x2;
527   } while(ready!=0);
528   return STW_SOK;
530 /* Waits for data inhibit to go low */
531 uint32_t MMCSD_v2_getCmdInhibit(MMCSD_v2_HwAttrs *hwAttrs)
533   uint32_t cmd_inhibit;
534   /* Check for  DAT inhibit */
535   cmd_inhibit=*((volatile uint32_t *)(hwAttrs->baseAddr + MMC_PSTATE)) & 0x1;
536   return cmd_inhibit;
538 /* Waits for data inhibit to go low */
539 uint32_t MMCSD_v2_getDatInhibit(MMCSD_v2_HwAttrs *hwAttrs)
541   uint32_t dat_inhibit;
542   /* Check for  DAT inhibit */
543   dat_inhibit=*((volatile uint32_t *)(hwAttrs->baseAddr + MMC_PSTATE)) & 0x2;
544   return dat_inhibit;
547 /* Function to check if the media is ready to accept read/write transfers */
548 static MMCSD_Error mmcsd_check_transfer_ready(MMCSD_Handle handle)
550     MMCSD_Error                 ret = MMCSD_ERR;
551     uint32_t                    cmd13_try_count = 0U;
552     uint32_t                    current_state = 0U;
553     MMCSD_v2_Object            *object = NULL;
554     MMCSD_v2_Transaction        transaction;
556     /* Get the pointer to the object and hwAttrs */
557     object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
558      /*
559       * Send CMD13 to check if the card is still in the programming state.
560       * The card needs to go to transfer state before it can send/receive data
561       */
562      cmd13_try_count=0;
563      do {
564                 memset(&transaction,0,sizeof(transaction));
565         transaction.cmd = MMCSD_CMD(13U);
566         transaction.flags = MMCSD_CMDRSP_48BITS;
567         transaction.arg = object->rca << 16U;
568         ret = MMCSD_v2_transfer(handle, &transaction);
569         cmd13_try_count++;
570         /* 'Current state' can be found from bits[9-12] of Card Status Register
571          * in the response R1 */
572         current_state=(transaction.response[0] >> (9U) & (0xFU));
574         if(current_state==MMCSD_CARD_STATE_TRANSFER) {
575                    ret = MMCSD_OK;
576                    break;
577                 }
578      } while(cmd13_try_count < MMCSD_CARD_TRANS_STATE_THRESHOLD);
580      return(ret);
582 /* Function to send the block count prior to read/write transfers. This is 
583 used for better throughput */
584 static MMCSD_Error mmcsd_send_cmd23(MMCSD_Handle handle, uint32_t numBlks)
586     MMCSD_Error                 ret = MMCSD_ERR;
587     MMCSD_v2_Transaction        transaction;
589      /*
590       * Send CMD13 to check if the card is still in the programming state.
591       * The card needs to go to transfer state before it can send/receive data
592       */
593                 memset(&transaction,0,sizeof(transaction));
594         transaction.cmd = MMCSD_CMD(23U);
595         transaction.flags = MMCSD_CMDRSP_48BITS;
596         transaction.arg = numBlks;
597         ret = MMCSD_v2_transfer(handle, &transaction);
599         return(ret);
603 /*
604  *  ======== MMCSD_v2_write ========
605  */
606 static MMCSD_Error MMCSD_v2_write(MMCSD_Handle handle,
607                            uint8_t *buf,
608                            uint32_t block,
609                            uint32_t numBlks)
611     MMCSD_Error                 ret = MMCSD_ERR;
612     uint32_t                    key;
613     uint32_t                    address = 0U;
614     MMCSD_v2_Object            *object = NULL;
615     MMCSD_v2_Transaction        transaction;
617     /* Input parameter validation */
618     if ((handle != NULL) && (buf != NULL))
619     {
620         /* Get the pointer to the object and hwAttrs */
621         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
623         object->writeBufIdx = buf;
624         object->writeBlockCount = numBlks;
626         /* Determine if the device index was already opened */
627         key = MMCSD_osalHardwareIntDisable();
628         if(0 != ((MMCSD_v2_Object *)(((MMCSD_Config *) handle)->object))->isOpen)
629         {
630             ret = MMCSD_OK;
631         }
632         MMCSD_osalHardwareIntRestore(key);
633     }
635      /*
636       * Send CMD13 to check if the card is still in the programming state.
637       * The card needs to go to transfer state before it can send/receive data
638       */
639     if(MMCSD_OK == ret)
640     {
641        ret = mmcsd_check_transfer_ready(handle);
642     }
643         
644         if((MMCSD_OK == ret) && object->cmd23Supported)
645         {
646       ret = mmcsd_send_cmd23(handle,numBlks);
647     }
648     if(MMCSD_OK == ret)
649     {
650         /*
651          * Address is in blks for high cap cards and in actual bytes
652          * for standard capacity cards
653          */
654         if (0 != object->highCap)
655         {
656             address = block;
657         }
658         else
659         {
660             address = block * object->blockSize;
661         }
663         transaction.flags = MMCSD_CMDRSP_WRITE | MMCSD_CMDRSP_DATA;
664         transaction.arg = address;
665         transaction.blockCount = numBlks;
666         transaction.blockSize = object->blockSize;
667         transaction.dataBuf = buf;
669         if (numBlks > 1U)
670         {
671             transaction.cmd = MMCSD_CMD(25U);
672             // transaction.flags |= MMCSD_CMDRSP_ABORT;
673         }
674         else
675         {
676             transaction.cmd = MMCSD_CMD(24U);
677         }
679         ret = MMCSD_v2_transfer(handle, &transaction);
680     } else {
681                 MMCSD_DEBUG_TRAP
682         }       
684     if(MMCSD_OK == ret && (!object->cmd23Supported))
685     {
686                 /* Send a STOP */
687         if (transaction.blockCount > 1U)
688         {
689                         memset(&transaction,0,sizeof(transaction));
690                         transaction.cmd  = MMCSD_CMD(12U);
691             transaction.flags = MMCSD_CMDRSP_BUSY;
692             transaction.arg = 0U;
694             ret = MMCSD_v2_transfer(handle, &transaction);
695         }
696     }
698     return (ret);
701 /*
702  *  ======== MMCSD_v2_read ========
703  */
704 static MMCSD_Error MMCSD_v2_read(MMCSD_Handle handle,
705                           uint8_t *buf,
706                           uint32_t block,
707                           uint32_t numBlks)
709     MMCSD_Error                 ret = MMCSD_ERR;
710     uint32_t                    key;
711     uint32_t                    address = 0U;
712     MMCSD_v2_Object            *object = NULL;
713     MMCSD_v2_Transaction        transaction;
715     /* Input parameter validation */
716     if ((handle != NULL) && (buf != NULL))
717     {
718         /* Get the pointer to the object and hwAttrs */
719         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
721         object->readBufIdx = buf;
722         object->readBlockCount = numBlks;
724         /* Determine if the device index was already opened */
725         key = MMCSD_osalHardwareIntDisable();
726         if(0 != ((MMCSD_v2_Object *)(((MMCSD_Config *) handle)->object))->isOpen)
727         {
728             ret = MMCSD_OK;
729         }
730         MMCSD_osalHardwareIntRestore(key);
731     }
733      /*
734       * Send CMD13 to check if the card is still in the programming state.
735       * The card needs to go to transfer state before it can send/receive data
736       */
737     if(MMCSD_OK == ret)
738     {
739        ret = mmcsd_check_transfer_ready(handle);
740     }
741         
742         if((MMCSD_OK == ret) && object->cmd23Supported)
743         {
744       ret = mmcsd_send_cmd23(handle,numBlks);
745     }
747     if(MMCSD_OK == ret)
748     {
749         /*
750          * Address is in blks for high cap cards and in actual bytes
751          * for standard capacity cards
752          */
753         if (0 != object->highCap)
754         {
755             address = block;
756         }
757         else
758         {
759             address = block * object->blockSize;
760         }
762         transaction.flags = MMCSD_CMDRSP_READ | MMCSD_CMDRSP_DATA;
763         transaction.arg = address;
764         transaction.blockCount = numBlks;
765         transaction.blockSize = object->blockSize;
766         transaction.dataBuf = buf;
768         if (numBlks > 1U)
769         {
770             transaction.cmd = MMCSD_CMD(18U);
771         }
772         else
773         {
774             transaction.cmd = MMCSD_CMD(17U);
775         }
777         ret = MMCSD_v2_transfer(handle, &transaction);
778     } else {
779                 MMCSD_DEBUG_TRAP
780         }       
782         
783     if((MMCSD_OK == ret)  && (!object->cmd23Supported))
784     {
785         /* Send a STOP */
786         if (transaction.blockCount > 1U)
787         {
788                     memset(&transaction,0,sizeof(transaction));
789                     transaction.cmd  = MMCSD_CMD(12U);
790             transaction.flags = MMCSD_CMDRSP_BUSY;
791             transaction.arg = 0U;
792             ret = MMCSD_v2_transfer(handle, &transaction);
793         }
794     }
795     return (ret);
798 /*
799  *  ======== MMCSD_v2_close ========
800  */
801 static MMCSD_Error MMCSD_v2_close(MMCSD_Handle handle)
803     MMCSD_v2_Object        *object = NULL;
804     MMCSD_v2_HwAttrs const *hwAttrs = NULL;
805     MMCSD_Error             ret = MMCSD_OK;
807     /* Input parameter validation */
808     if (handle == NULL)
809     {
810         ret = MMCSD_ERR;
811     }
812     else
813     {
814         /* Get the pointer to the object and hwAttrs */
815         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
816         hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
818         ret = MMCSD_socPhyConfigure((MMCSD_v2_HwAttrs const *)hwAttrs, MODE_DEFAULT, 0, 0);
819         if(ret != MMCSD_OK)
820         {
821             MMCSD_DEBUG_TRAP
822         }
824         if(0U != hwAttrs->enableInterrupt)
825         {
826            /* Release the interrupt path */
827            if (hwAttrs->configSocIntrPath!=NULL) {
828               ret = hwAttrs->configSocIntrPath((const void *)hwAttrs,FALSE);
829             }
831            if(ret==MMCSD_OK) {
832            /* Unregister the interrupt */
833            MMCSD_osalHardwareIntDestruct(object->hwi,hwAttrs->eventId);
834            }
835         }
837         if(object->switched_to_v18)
838         {
840           if(object->switched_to_v18 && hwAttrs->switchVoltageFxn!=NULL) {
841             MMCSD_drv_log(Diags_USER1,"Switch to 1.8V indicated. Switching back to 3.3V\n");
842               ret=hwAttrs->switchVoltageFxn(hwAttrs->instNum,MMCSD_BUS_VOLTAGE_3_3V);
843           }
845           HSMMCSDSwitchSignalVoltage (hwAttrs->baseAddr, MMC_AC12_V1V8_SIGEN_3V3);
846           /* Wait for 5 ms */
847           Osal_delay(5);
849           /* wait if the signal voltage bit is set to 1 */
850           if(HSMMCSDGetSignalVoltage (hwAttrs->baseAddr)==!MMC_AC12_V1V8_SIGEN_3V3) {
851             MMCSD_DEBUG_TRAP
852           }
853         }
854         /* Destruct the instance lock */
855         MMCSD_osalDeleteBlockingLock(object->commandMutex);
856         MMCSD_osalDeleteBlockingLock(object->transferMutex);
857         MMCSD_osalDeleteBlockingLock(object->commandComplete);
858         MMCSD_osalDeleteBlockingLock(object->dataBufferCopyComplete);
859         MMCSD_osalDeleteBlockingLock(object->transferComplete);
861         memset(object, 0, sizeof(MMCSD_v2_Object));
863     #ifdef LOG_EN
864         MMCSD_drv_log4(Diags_USER1, "MMCSD: Object closed 0x%x", hwAttrs->baseAddr);
865     #endif
866     }
867     return (ret);
870 /*
871  *  ======== MMCSD_v2_init ========
872  */
873 static MMCSD_Error MMCSD_v2_init(MMCSD_Handle handle)
875     MMCSD_Error          ret = MMCSD_ERR;
877     /* Input parameter validation */
878     if (handle != NULL)
879     {
880         if (((MMCSD_Config *) handle)->object != NULL)
881         {
882             /* Initialize all variables to 0 */
883             memset(((MMCSD_Config *) handle)->object,0,sizeof(MMCSD_v2_Object));
884             ret = MMCSD_OK;
885         }
886     }
887         
888     return (ret);
891 /*
892  *  ======== MMCSD_enableBootPartitionAccess ========
893  */
894 static MMCSD_Error MMCSD_v2_enableBootPartition(MMCSD_Handle handle, const uint8_t *partition)
896     MMCSD_v2_Transaction transaction;
897     MMCSD_Error          ret = MMCSD_OK;
898     uint32_t             argument = 0;
899     uint8_t              bootAck = 1;
900     uint8_t              bootPartition = 0;
901     uint8_t              bootBusWidth = 0;
903     if((*partition == 1) || (*partition == 2))
904     {
905         bootPartition = ((bootAck << 6) | (*partition << 3) | (*partition));
906         /* Setting x8 bus width */
907         bootBusWidth = 0x02;
908         argument = (uint32_t)((bootPartition << 8) | (0xB3 << 16) | (0x03 << 24));
910         if(MMCSD_OK == ret)
911         {
912             /* Used CMD6(Switch Command) for configuring the extended CSD register */
913             transaction.cmd = MMCSD_CMD(6U);
914             transaction.arg = argument;
915             transaction.flags = 0U;
916             ret = MMCSD_v2_transfer(handle, &transaction);
917         }
918         Osal_delay(5);
920         if(MMCSD_OK == ret)
921         {
922             argument = (uint32_t)((bootBusWidth << 8) | (0xB1 << 16) | (0x03 << 24));
923             /* Used CMD6(Switch Command) for configuring the extended CSD register */
924             transaction.cmd = MMCSD_CMD(6U);
925             transaction.arg = argument;
926             transaction.flags = 0U;
927             ret = MMCSD_v2_transfer(handle, &transaction);
928         }
929         Osal_delay(5);
930     }
931     else
932     {
933         return MMCSD_ERR;
934     }
936     return(ret);
939 /*
940  *  ======== MMCSD_v2_open ========
941  */
942 static MMCSD_Error MMCSD_v2_open(MMCSD_Handle handle, MMCSD_Params params)
944     SemaphoreP_Params           semParams;
945     MMCSD_Error                 ret = MMCSD_ERR;
946     uint32_t                    key;
947     MMCSD_v2_Object            *object = NULL;
948     MMCSD_v2_HwAttrs           *hwAttrs = NULL;
949     OsalRegisterIntrParams_t interruptRegParams;
950     OsalInterruptRetCode_e interruptRegRet;
952     /* Input parameter validation */
953     if (handle != NULL)
954     {
955         /* Get the pointer to the object and hwAttrs */
956         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
957         hwAttrs = (MMCSD_v2_HwAttrs *)((MMCSD_Config *) handle)->hwAttrs;
959         /* Determine if the device index was already opened */
960         key = MMCSD_osalHardwareIntDisable();
961         if (0 == ((MMCSD_v2_Object *)(((MMCSD_Config *) handle)->object))->isOpen)
962         {
963             ret = MMCSD_OK;
964         }
965         MMCSD_osalHardwareIntRestore(key);
966     }
968     if(MMCSD_OK == ret)
969     {
970         /* Store the MMC parameters */
971         if (params == NULL)
972         {
973             /* No params passed in, so use the defaults */
974             MMCSD_Params_init(&(object->MMCSDConfigParams));
975         }
976         else
977         {
978             /* Copy the params contents */
979             object->MMCSDConfigParams.custom = ((MMCSD_ConfigParams *) params)->custom;
980         }
981     }
983     if(MMCSD_OK == ret)
984     {
985         if(0U != hwAttrs->enableInterrupt)
986         {
988            if(MMCSD_OK == ret && (hwAttrs->configSocIntrPath!=NULL)){
989              ret = hwAttrs->configSocIntrPath(hwAttrs,TRUE);
990            }
991             /* Construct Hwi object for this MMCSD peripheral */
993                     if(ret==MMCSD_OK) {
994                     /* Initialize with defaults */
995             Osal_RegisterInterrupt_initParams(&interruptRegParams);
997             interruptRegParams.corepacConfig.isrRoutine = (&MMCSD_v2_hwiFxn);
998             interruptRegParams.corepacConfig.arg = (uintptr_t)handle;
1000                         /* Populate the interrupt parameters */
1001             interruptRegParams.corepacConfig.name=NULL;
1003             interruptRegParams.corepacConfig.corepacEventNum=hwAttrs->eventId; /* Event going in to CPU */
1004             interruptRegParams.corepacConfig.intVecNum=hwAttrs->intNum; /* Host Interrupt vector */
1006                /* Register interrupts */
1007             interruptRegRet=MMCSD_osalRegisterInterrupt(&interruptRegParams,&(object->hwi));
1008             if(interruptRegRet!=OSAL_INT_SUCCESS) {
1009               ret=MMCSD_ERR;
1010             }
1011            } else {
1012                            ret=MMCSD_ERR_SET_SOC_INTERRUPT_PATH;
1013                    }
1014         }
1016         /*
1017          * Construct thread safe handles for this MMCSD peripheral
1018          * Semaphore to provide exclusive access to the MMCSD peripheral
1019          */
1020         MMCSD_osalSemParamsInit(&semParams);
1021         semParams.mode = SemaphoreP_Mode_BINARY;
1022         object->commandMutex = MMCSD_osalCreateBlockingLock(1U, &semParams);
1023         object->transferMutex = MMCSD_osalCreateBlockingLock(1U, &semParams);
1024         object->commandComplete = MMCSD_osalCreateBlockingLock(0, &semParams);
1025                 object->dataBufferCopyComplete = MMCSD_osalCreateBlockingLock(0, &semParams);
1026         object->transferComplete = MMCSD_osalCreateBlockingLock(0, &semParams);
1028     }
1030     if ((MMCSD_OK == ret) && (hwAttrs->inputClockControl)) {
1031        /* Get the input clock value from the system*/
1032         uint32_t inputClockRet;
1033         inputClockRet=hwAttrs->inputClockControl(hwAttrs->instNum,NULL,MMCSD_INPUT_CLOCK_CTRL_GET);
1034         if(inputClockRet!=0) {
1036           if(inputClockRet!=hwAttrs->inputClk) {
1037                   MMCSD_drv_log4(Diags_USER1,"Input clock[%d] to MMC is different from what is set in hwAttrs\n",inputClockRet);
1038              hwAttrs->inputClk=inputClockRet;
1039           }
1040         } else {
1041          MMCSD_drv_log(Diags_USER1,"Something is wrong. Input clock is not enabled!!\n");
1042          ret = MMCSD_ERR;
1043        }
1044     }
1046     if(MMCSD_OK == ret)
1047     {
1048         object->cardType = hwAttrs->cardType;
1050         if (MMCSD_CARD_SD == object->cardType)
1051         {
1052             ret = MMCSD_v2_initSd(handle);
1053         }
1054         else if (MMCSD_CARD_EMMC == object->cardType)
1055         {
1056             ret = MMCSD_v2_initEmmc(handle);
1057         }
1058         else
1059         {
1060             ret = MMCSD_ERR; /*dummy statement for misra warning*/
1061         }
1062     }
1064     /* Mark the object as in use */
1065     if(MMCSD_OK == ret)
1066     {
1067         ((MMCSD_v2_Object *)(((MMCSD_Config *) handle)->object))->isOpen = 1;
1068     }
1070     return (ret);
1072 /* Data buffer for message transmission, it is not stack allocated to allow cache aligning */
1073 static uint8_t dataBuffer[512] __attribute__((aligned(256)));
1075 static uint8_t cmd6_response_buf[512] __attribute__((aligned(256)));
1077 /*
1078  *  ======== MMCSD_v2_initSd ========
1079  */
1080 static MMCSD_Error MMCSD_v2_initSd(MMCSD_Handle handle)
1082     MMCSD_Error                 ret = MMCSD_OK;
1083     uint32_t                    retry = 0xFFFFU;
1084     MMCSD_v2_Object            *object = NULL;
1085     MMCSD_v2_HwAttrs const     *hwAttrs = NULL;
1086     MMCSD_v2_Transaction        transaction;
1087     volatile int32_t            status = CSL_ESYS_FAIL;
1088     stSDMMCHCCapability         hcCap = {0U, 0U, 0U, 0U};
1089     bool support18V_host=FALSE;
1090         bool attempt_18V_switch=TRUE; /* Always be optimistic to start with, unless some cards do not work well with it */
1092     /* Get the pointer to the object and hwAttrs */
1093     object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
1094     hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
1096     if(hwAttrs->switchVoltageFxn != NULL)
1097     {
1098         support18V_host=((hwAttrs->supportedBusVoltages & MMCSD_BUS_VOLTAGE_1_8V))?TRUE:FALSE;
1099     }
1100         memset(dataBuffer,0,sizeof(dataBuffer));
1102     MMCSD_socPhyInit(hwAttrs);
1103         
1104     if(MMCSD_OK == ret)
1105     {
1106         /*
1107          * Refer to the MMC Host and Bus configuration steps in TRM
1108          * controller Reset
1109          */
1110         status = HSMMCSDSoftReset(hwAttrs->baseAddr);
1112         if (STW_SOK != status)
1113         {
1114 #ifdef LOG_EN
1115             MMCSD_drv_log4(Diags_USER1,
1116                     "MMCSD:(%p) HS MMC/SD Reset failed\n", hwAttrs->baseAddr);
1117 #endif
1118             ret = MMCSD_ERR;
1119         }
1120         else
1121         {
1122             ret = MMCSD_OK;
1123         }
1124     }
1126     if (MMCSD_OK == ret)
1127     {
1128         /* Lines Reset */
1129         status = HSMMCSDLinesReset(hwAttrs->baseAddr, HS_MMCSD_ALL_RESET);
1130         if(status!=STW_SOK) {
1131             MMCSD_DEBUG_TRAP
1132         }
1134         /* Set the bus width */
1135         status = HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_1BIT);
1136         if(status!=STW_SOK) {
1137             MMCSD_DEBUG_TRAP
1138         }
1140         /* Set the bus voltage */
1141                 if(hwAttrs->supportedBusVoltages & MMCSD_BUS_VOLTAGE_3_3V) {
1142            status=HSMMCSDBusVoltSet(hwAttrs->baseAddr, MMC_HCTL_SDVS_3V3); /* Default */
1143            if(status!=STW_SOK) {
1144                MMCSD_DEBUG_TRAP
1145            }
1147                 } else  if((hwAttrs->supportedBusVoltages & MMCSD_BUS_VOLTAGE_1_8V) &&
1148                    (hwAttrs->switchVoltageFxn != NULL)) {
1149            status = HSMMCSDBusVoltSet (hwAttrs->baseAddr, MMC_HCTL_SDVS_1V8);
1150            if(status!=STW_SOK) {
1151                MMCSD_DEBUG_TRAP
1152            }
1154         }
1156       /* Card detection */
1157    if(MMCSD_OK == ret)
1158    {
1159       uint32_t slotType,reg=0,ins=0;
1160       slotType = CSL_MMC_CTLCFG_CAPABILITIES_SLOT_TYPE_VAL_REMOVABLE;
1162       reg = *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->CTL_CFG_2_REG));
1163       reg = Bitfield_csl_set (reg, slotType,
1164                             CSL_MMC_SSCFG_CTL_CFG_2_REG_SLOTTYPE_MASK,
1165                             CSL_MMC_SSCFG_CTL_CFG_2_REG_SLOTTYPE_SHIFT);
1166        *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->CTL_CFG_2_REG))=reg;
1168       //
1169       // Enable pins by setting the IO mux field in the phy to 0.
1170       //
1171       reg = *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->PHY_CTRL_1_REG));
1172       reg = Bitfield_csl_set (reg, 0,
1173                             CSL_MMC_SSCFG_PHY_CTRL_1_REG_IOMUX_ENABLE_MASK,
1174                             CSL_MMC_SSCFG_PHY_CTRL_1_REG_IOMUX_ENABLE_SHIFT);
1175       *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->PHY_CTRL_1_REG))=reg;
1177       //
1178       // Wait for card detect.
1179       //
1180        ins=0;
1181        do {
1182           ins = HSMMCSDIsCardInserted(hwAttrs->baseAddr);
1183        } while(ins==0);
1184     }
1185         /* Bus power on */
1186         status = ((int32_t)(HSMMCSDBusPower(hwAttrs->baseAddr, MMC_HCTL_SDBP_PWRON)));
1187         if(status!=STW_SOK) {
1188             MMCSD_DEBUG_TRAP
1189         }
1191          status= HSMMCSDDataTimeoutSet(hwAttrs->baseAddr, MMC_SYSCTL_DTO_15THDTO);
1192         if(status!=STW_SOK) {
1193             MMCSD_DEBUG_TRAP
1194         }
1195         hcCap.flag1=HS_MMCSD_CAPA_ALL;
1196         hcCap.flag2=HS_MMCSD_CAPA_ALL;
1197         status = HSMMCSDHostCapabilityGet(hwAttrs->baseAddr,&hcCap);
1198         if(status!=STW_SOK) {
1199             MMCSD_DEBUG_TRAP
1200         }
1202                 object->switched_to_v18=FALSE;
1203         if (STW_SOK != status)
1204         {
1205 #ifdef LOG_EN
1206             MMCSD_drv_log4(Diags_USER1,
1207                     "MMCSD:(%p) HS MMC/SD Power on failed\n", hwAttrs->baseAddr);
1208 #endif
1209             ret = MMCSD_ERR;
1210         }
1211     }
1213     if (MMCSD_OK == ret)
1214     {
1215         /* Set the initialization frequency */
1216         status = HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk,hwAttrs->outputClk, FALSE);
1218          Osal_delay(10);
1219         if(status !=STW_SOK) {
1220                   MMCSD_DEBUG_TRAP
1221                 }
1222     }
1224     /* SD Card */
1225     if(MMCSD_OK == ret)
1226     {
1227         object->cardType = MMCSD_CARD_SD;
1229         /* CMD0 - reset card */
1230         if(MMCSD_OK == ret)
1231         {
1232             transaction.cmd = MMCSD_CMD(0U);
1233             transaction.flags = MMCSD_CMDRSP_NONE;
1234             transaction.arg = 0U;
1235             ret = MMCSD_v2_transfer(handle, &transaction);
1236         } else { MMCSD_DEBUG_TRAP}
1237         }
1239     /******************* Send Operating Voltage (CMD8) ************************/
1240 #ifndef SIMULATOR // Skip CMD8 when VLAB is used
1241         if(MMCSD_OK == ret)
1242         {
1243             uint32_t curr_bus_voltage;
1244                         /* CMD8 - send oper voltage */
1245             transaction.cmd = MMCSD_CMD(8U);
1246             transaction.flags = MMCSD_CMDRSP_48BITS;
1247             transaction.arg = MMCSD_CHECK_PATTERN ;
1250             curr_bus_voltage=HSMMCSDBusVoltGet(hwAttrs->baseAddr);
1252             if(curr_bus_voltage==MMC_HCTL_SDVS_1V8)  {
1253                transaction.arg |= MMCSD_VOLT_LOW_RANGE;
1254                         } else
1255                         {
1256                transaction.arg |= MMCSD_VOLT_2P7_3P6;
1257             }
1259             ret = MMCSD_v2_transfer(handle, &transaction);
1260         }  else { MMCSD_DEBUG_TRAP}
1261 #endif // CMD8 does not for VLAB
1262         if (MMCSD_OK != ret)
1263         {
1264             /*
1265              * If the cmd fails  , it can be due to version < 2.0, since
1266              * we are currently supporting high voltage cards only
1267              */
1268              ret=MMCSD_OK;
1269                      MMCSD_DEBUG_TRAP
1271         }
1272         /******************************* Send OCR (ACMD41) *********************/
1273         if(MMCSD_OK == ret)
1274         {
1275             /* Poll until we get the card status (BIT31 of OCR) is powered up */
1276             do
1277             {
1278                 /* APP cmd should be preceeded by a CMD55 */
1279                 transaction.cmd = MMCSD_CMD(55U);
1280                 transaction.flags = MMCSD_CMDRSP_48BITS;
1281                 transaction.arg = 0; /* object->rca is zero as the card is in the idle state */
1282                 ret = MMCSD_v2_transfer(handle, &transaction);
1284                 if(MMCSD_OK == ret)
1285                 {
1286                     transaction.cmd = MMCSD_CMD(41U);
1287                     transaction.flags = MMCSD_CMDRSP_48BITS;
1288                     transaction.arg = MMCSD_OCR_HIGH_CAPACITY | MMCSD_OCR_VDD_WILDCARD;
1289                     if(support18V_host) {
1290                         /* Host supports 1.8V and seek if the card supports it */
1291                         transaction.arg|= MMCSD_OCR_S18R;
1292                     }
1293                    ret= MMCSD_v2_transfer(handle, &transaction);
1294                 }
1295                 else
1296                 {
1297                     ret = MMCSD_ERR;
1298                   { MMCSD_DEBUG_TRAP
1299                               }
1300                        break;
1301                 }
1302                 retry--;
1303             } while (((transaction.response[0U] & ((uint32_t)BIT(31U))) == 0U) && (retry != 0));
1305             if (0U == retry)
1306             {
1307                 /* No point in continuing */
1308                 ret = MMCSD_ERR;
1309             }
1310         }
1312         object->uhsCard=FALSE;
1313         /****************************** Switch to 1.8V if needed *********************************/
1314         if(MMCSD_OK == ret)
1315         {
1316             object->ocr = transaction.response[0U];
1317             /* Card capacity status (CCS) Bit 30 */
1318             object->highCap = (object->ocr & MMCSD_OCR_HIGH_CAPACITY) ? 1U : 0U;
1320             /* Bit32 of the response R3 (S18A)*/
1321             object->support1_8V = (transaction.response[0U] & MMCSD_OCR_S18R) ? 1U : 0U;
1323                         if(HSMMCSDBusVoltGet(hwAttrs->baseAddr)==MMC_HCTL_SDVS_1V8) {
1324                            attempt_18V_switch=FALSE;
1325                            object->switched_to_v18=TRUE; /* Already in 1.8V mode */
1326                         }
1328                         /* If 1.8V is supported, configure the card accordingly to switch to SDR modes */
1329             if(object->support1_8V && support18V_host && attempt_18V_switch)
1330             {
1331                 MMCSD_drv_log(Diags_USER1, "MMCSD: S18R indicates 1.8V support\n");
1333                             bool falseloop_1p8V_switch=TRUE;
1334                             do
1335                             {
1337                               falseloop_1p8V_switch=FALSE;
1339                   MMCSD_drv_log(Diags_USER1, "MMCSD: Sending CMD11 \n");
1340                                   /* Start the voltage switching procedure */
1341                   /* Send CMD11 */
1342                   transaction.cmd = MMCSD_CMD(11U);
1343                   transaction.flags = MMCSD_CMDRSP_48BITS;
1344                   transaction.arg = 0U;
1345                   ret = MMCSD_v2_transfer(handle, &transaction);
1348                   if(MMCSD_OK == ret)
1349                                   {
1350                            uint32_t retry_count,dataSigLevel;
1351                            /* Voltage sequence acknowledge */
1352                            MMCSD_drv_log(Diags_USER1,"MMCSD DRV:  Voltage sequence acknowledged via CMD11\n");
1354                            MMCSD_drv_log(Diags_USER1,"MMCSD DRV:  Setting the SDVS and V1V8 SIGEN \n");
1356                        HSMMCSDSDClockDisable(hwAttrs->baseAddr); /* Disable clock to SD card */
1358                        /* Wait for CMD and DAT levels to go low */
1359                            retry_count=10;
1361                        do {
1362                                                  dataSigLevel=HSMMCSDGetDataSignalLevel(hwAttrs->baseAddr);
1363                        } while(dataSigLevel!=0);
1365                                            if(retry_count==0) {
1366                                               /* CMD11 failed. Switch not possible */
1367                                               ret=MMCSD_ERR_1P8V_SWITCH_CARD_CMD11_FAILURE;
1368                                               MMCSD_DEBUG_TRAP
1369                                            }
1372                         /* Switch the board voltage to 1.8V */
1373                                             if(hwAttrs->switchVoltageFxn!=NULL) {
1374                                                   ret = hwAttrs->switchVoltageFxn(hwAttrs->instNum,MMCSD_BUS_VOLTAGE_1_8V);
1375                                             }  
1376                             
1377                                                 if(ret!=MMCSD_OK) {
1378                                                   ret=MMCSD_ERR_1P8V_SWITCH_MMCIO_SWITCH_FAILURE;
1379                                                    break;
1380                                                 }
1381  
1382                        status=HSMMCSDBusVoltSet(hwAttrs->baseAddr, MMC_HCTL_SDVS_1V8);
1384                                            HSMMCSDSwitchSignalVoltage (hwAttrs->baseAddr, MMC_AC12_V1V8_SIGEN_1V8);
1386                                            /* Wait for 5 ms */
1387                                            Osal_delay(5);
1388                        /* Set the bus voltage */
1390                                            /* wait if the signal voltage bit is set to 1 */
1391                                            if(HSMMCSDGetSignalVoltage (hwAttrs->baseAddr)==!MMC_AC12_V1V8_SIGEN_1V8) {
1392                                                    MMCSD_DEBUG_TRAP
1393                                            }
1395                         HSMMCSDUhsModeSet(hwAttrs->baseAddr,MMC_AC12_UHSMS_SDR12);
1396                         HSMMCSDHSModeSet(hwAttrs->baseAddr,MMC_HCTL_HSPE_NORMALSPEED);
1398                         /* Set the initialization frequency */
1399                         status = HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk,hwAttrs->outputClk, FALSE);
1401                         Osal_delay(10);
1402                         if(status !=STW_SOK) {
1403                         MMCSD_DEBUG_TRAP
1404                         }
1406                         /* PHY configurae */
1407                         MMCSD_socPhyDisableDLL((MMCSD_v2_HwAttrs const *)hwAttrs);
1409                         Osal_delay(50);
1411                         /* Configure the Phy accordignly */
1412                         ret = MMCSD_socPhyConfigure((MMCSD_v2_HwAttrs const *)hwAttrs, MODE_SDR12, 25000000U, 0);
1413                         if(ret != MMCSD_OK)
1414                         {
1415                             MMCSD_DEBUG_TRAP
1416                         }
1418                                             /* Wait for 1 ms */
1419                                             Osal_delay(1);
1421                         /* Check if the dat[0-3] level has gone to 0x1111 */
1422                         do {
1423                                                    dataSigLevel=HSMMCSDGetDataSignalLevel(hwAttrs->baseAddr);
1424                         } while(dataSigLevel!=0xf);
1428                                             object->switched_to_v18=TRUE;
1429                                             object->uhsCard=TRUE;
1430                             MMCSD_drv_log(Diags_USER1,"1.8V switching procedure complete\n");
1432                                         }
1433                 } while(falseloop_1p8V_switch);
1435                             if(ret!=MMCSD_OK) {
1437                                 /* Reverse the voltage switch */
1438                                   if(hwAttrs->switchVoltageFxn!=NULL) {
1439                                      ret = hwAttrs->switchVoltageFxn(hwAttrs->instNum,MMCSD_BUS_VOLTAGE_3_3V);
1440                                   }
1441                                   
1442                                   HSMMCSDSwitchSignalVoltage (hwAttrs->baseAddr, MMC_AC12_V1V8_SIGEN_3V3);
1443                       /* Wait for 5 ms */
1444                       Osal_delay(5);
1445                   
1446                       /* wait if the signal voltage bit is set to 1 */
1447                       if(HSMMCSDGetSignalVoltage (hwAttrs->baseAddr)==!MMC_AC12_V1V8_SIGEN_3V3) {
1448                         MMCSD_DEBUG_TRAP
1449                       }
1450                             }
1451             }
1453                 }
1456     if(MMCSD_OK == ret)
1457         {
1458             /* Send CMD2, to get the card identification register */
1459             transaction.cmd = MMCSD_CMD(2U);
1460             transaction.flags = MMCSD_CMDRSP_136BITS;
1461             transaction.arg = 0U;
1463             ret = MMCSD_v2_transfer(handle, &transaction);
1465             object->cid[3]= (transaction.response[3] << 8)| (transaction.response[2] >> 24);
1466             object->cid[2]= (transaction.response[2] << 8)| (transaction.response[1] >> 24);
1467             object->cid[1]= (transaction.response[1] << 8)| (transaction.response[0] >> 24);
1468             object->cid[0]= (transaction.response[0] << 8);
1470      }  else {MMCSD_DEBUG_TRAP}
1472      /************************ Get RCA (CMD3) **********************************/
1473      if(MMCSD_OK == ret)
1474      {
1475             /* Send CMD3, to get the card relative address */
1476             transaction.cmd = MMCSD_CMD(3U);
1477             transaction.flags = 0U;
1478             transaction.arg = 0U;
1480             ret = MMCSD_v2_transfer(handle, &transaction);
1482             object->rca = MMCSD_RCA_ADDR(transaction.response[0U]);
1483       }  else { MMCSD_DEBUG_TRAP}
1485         /******************* Get card specific data(CSD) via CMD9 ***********************/
1486         if(MMCSD_OK == ret)
1487         {
1488             /* Send CMD9, to get the card specific data */
1489             transaction.cmd = MMCSD_CMD(9U);
1490             transaction.flags = MMCSD_CMDRSP_136BITS;
1491             transaction.arg = object->rca << 16U;
1493             ret = MMCSD_v2_transfer(handle, &transaction);
1495             object->csd[3]= (transaction.response[3] << 8)| (transaction.response[2] >> 24);
1496             object->csd[2]= (transaction.response[2] << 8)| (transaction.response[1] >> 24);
1497             object->csd[1]= (transaction.response[1] << 8)| (transaction.response[0] >> 24);
1498             object->csd[0]= (transaction.response[0] << 8);
1499         }  else { MMCSD_DEBUG_TRAP }
1502       /************ Select the card (CMD7) ****************/
1504         if(MMCSD_OK == ret)
1505         {
1506             /* Select the card */
1507             transaction.cmd = MMCSD_CMD(7U);
1508             transaction.flags = MMCSD_CMDRSP_BUSY;
1509             transaction.arg = object->rca << 16U;
1511             ret = MMCSD_v2_transfer(handle, &transaction);
1512         }  else { MMCSD_DEBUG_TRAP }
1514          /* Wait for DAT0 to go low */
1515          MMCSD_v2_waitDat0(hwAttrs);
1517     /******** Set block len (CMD16) based on the CSD register *******/
1518         if(MMCSD_OK == ret)
1519         {
1520             if (MMCSD_CARD_CMMCSD_VERSION(object))
1521             {
1522                 object->tranSpeed = MMCSD_CARD1_TRANSPEED(object);
1523                 object->blockSize = ((uint32_t)1U) << (MMCSD_CARD1_RDBLKLEN(object));
1524                 object->size = MMCSD_CARD1_SIZE(object);
1525                 object->blockCount = object->size / object->blockSize;
1526             }
1527             else
1528             {
1529                 object->tranSpeed = MMCSD_CARD0_TRANSPEED(object);
1530                 object->blockSize = ((uint32_t)1U) << (MMCSD_CARD0_RDBLKLEN(object));
1531                 object->size = MMCSD_CARD0_SIZE(object);
1532                 object->blockCount = MMCSD_CARD0_NUMBLK(object);
1533             }
1536             /* Set data block length to 512 (for byte addressing cards) */
1537             if((object->highCap) == 0U)
1538             {
1539                 transaction.cmd = MMCSD_CMD(16U);
1540                 transaction.flags = MMCSD_CMDRSP_NONE;
1541                 transaction.arg = 512U;
1542                 ret = MMCSD_v2_transfer(handle, &transaction);
1544                 if(MMCSD_OK == ret)
1545                 {
1546                     object->blockSize = 512U;
1547                 }
1548             }
1549         }  else { MMCSD_DEBUG_TRAP }
1551     /************************ Get the SCR Register (ACMD51) *****************************/
1553         if(MMCSD_OK == ret)
1554         {
1555             /*
1556              * Send ACMD51, to get the SD Configuration register details.
1557              * Note, this needs data transfer (on data lines).
1558              */
1559             transaction.cmd = MMCSD_CMD(55U);
1560             transaction.flags = 0U;
1561             transaction.arg = object->rca << 16U;
1563             ret = MMCSD_v2_transfer(handle, &transaction);
1564         }  else { MMCSD_DEBUG_TRAP }
1568         if(MMCSD_OK == ret)
1569         {
1570             transaction.cmd = MMCSD_CMD(51U);
1571             transaction.flags = MMCSD_CMDRSP_48BITS | MMCSD_CMDRSP_READ | MMCSD_CMDRSP_DATA;
1572             transaction.arg = object->rca << 16U;
1573             transaction.blockCount = 1U;
1574             transaction.blockSize = 8U;
1575             transaction.dataBuf = dataBuffer;
1577             ret = MMCSD_v2_transfer(handle, &transaction);
1578         }  else { MMCSD_DEBUG_TRAP }
1580         if(MMCSD_OK == ret)
1581         {
1582              object->scr[0] = dataBuffer[0] << 24 | dataBuffer[1] << 16 | dataBuffer[2] << 8 | dataBuffer[3];
1583              object->scr[1] = dataBuffer[4] << 24 | dataBuffer[5] << 16 | dataBuffer[6] << 8 | dataBuffer[7];
1585             object->sdVer = MMCSD_CARD_VERSION(object);
1586             object->busWidth = MMCSD_CARD_BUSWIDTH(object);
1587                         object->cmd23Supported = MMCSD_CARD_CMD23_SUPPORT(object);
1588         }  else { MMCSD_DEBUG_TRAP }
1590      /*****************  Set the bus width,1bit or 4 bit (ACMD6)   ********************/
1593         if(MMCSD_OK == ret)
1594         {
1595             /* APP cmd should be preceeded by a CMD55 */
1596             transaction.cmd = MMCSD_CMD(55U);
1597             transaction.flags = 0U;
1598             transaction.arg = object->rca << 16U;
1599             ret = MMCSD_v2_transfer(handle, &transaction);
1600         }  else { MMCSD_DEBUG_TRAP }
1602         if(MMCSD_OK == ret)
1603         {
1604             transaction.cmd = MMCSD_CMD(6U);
1605             transaction.arg = MMCSD_BUS_WIDTH_1BIT;
1606             transaction.flags = 0U;
1608             if (((MMCSD_v2_HwAttrs *)(((MMCSD_Config *) handle)->hwAttrs))->supportedBusWidth & MMCSD_BUS_WIDTH_4BIT)
1609             {
1610                 if (object->busWidth & MMCSD_BUS_WIDTH_4BIT)
1611                 {
1612                     transaction.arg = MMCSD_BUS_WIDTH_4BIT;
1613                 }
1614             }
1616             transaction.arg = transaction.arg >> 1U;
1617             ret = MMCSD_v2_transfer(handle, &transaction);
1620             if (MMCSD_OK == ret)
1621             {
1622                 if (0U == transaction.arg)
1623                 {
1624                     HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_1BIT);
1625                 }
1626                 else
1627                 {
1628                     HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_4BIT);
1629                 }
1630             }  else { MMCSD_DEBUG_TRAP }
1631          }
1635         /****************** Find out the speeds supported , to switch to high speeds **************/
1636         MMCSD_drv_log(Diags_USER1,"Checking with CMD6 to see the capabilities\n");
1638                 /* Check the CMD6 to see what function could be switched to */
1639         if(MMCSD_OK == ret)
1640         {
1641             transaction.cmd = MMCSD_CMD(6U);
1642             transaction.arg = ((MMCSD_CHECK_MODE & MMCSD_CMD6_GRP1_SEL) |
1643                 (MMCSD_CMD6_GRP1_DEFAULT));
1644             transaction.flags = MMCSD_CMDRSP_READ | MMCSD_CMDRSP_DATA;
1645             transaction.blockCount = 1U;
1646             transaction.blockSize = 64U;
1647             transaction.dataBuf = dataBuffer;
1648             ret = MMCSD_v2_transfer(handle, &transaction);
1649         }  else { MMCSD_DEBUG_TRAP }
1651          /* Wait for DAT0 to go low */
1652          MMCSD_v2_waitDat0(hwAttrs);
1654                 /* Perform the switch and see what function it switches to */
1655 #ifndef SIMULATOR // Skip CMD8 when VLAB is used
1656         if(MMCSD_OK == ret)
1657         {
1658             uint32_t cmd16_grp1_fn = MMCSD_CMD6_GRP1_DEFAULT;
1659                         int32_t i;
1660                         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};
1662             MMCSD_drv_log(Diags_USER1,"With the response from CMD6, Trying each speed starting with preferable ones..\n");
1664                         /* Go through the groups in a preferential manner and select the highest speed possible */
1665                         for(i=0;i<5;i++)
1666                         {
1668              /* Go through the capabilites register and match with the card's speed
1669                 to arrive at an agreeable speed */
1670              /* See if 104 is available in response bits 415-400,  i.e bytes[12] and bytest[13] */
1671                          /* Please refer to the status response to CMD6 in the physical specification */
1672                           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))) {
1673                 cmd16_grp1_fn=MMCSD_CMD6_GRP1_SDR104;
1674                 MMCSD_drv_log(Diags_USER1,"CMD6 Says Card Supports SDR104\n");
1675               } 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))) {
1676                 cmd16_grp1_fn=MMCSD_CMD6_GRP1_SDR50;
1677                 MMCSD_drv_log(Diags_USER1,"CMD6 Says Card Supports SDR50\n");
1678                           } else
1679                           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))) {
1680                 cmd16_grp1_fn=MMCSD_CMD6_GRP1_DDR50;
1681                 MMCSD_drv_log(Diags_USER1,"CMD6 Says Card Supports DDR50\n");
1682                           } else
1683                           if ( (hwAttrs->supportedModes & MMCSD_SUPPORT_SD_HS) &&  (cmd6_groups[i]==MMCSD_CMD6_GRP1_HS) && (dataBuffer[13] & (1<< MMCSD_CMD6_GRP1_HS))) {
1684                  cmd16_grp1_fn=MMCSD_CMD6_GRP1_HS;
1685                  MMCSD_drv_log(Diags_USER1,"CMD6 Says Card Supports HS\n");
1686                           } else if ( (hwAttrs->supportedModes & MMCSD_SUPPORT_SD_DS) && (cmd6_groups[i]==MMCSD_CMD6_GRP1_DEFAULT) && (dataBuffer[13] & (1<< MMCSD_CMD6_GRP1_DEFAULT))) {
1687                              cmd16_grp1_fn=MMCSD_CMD6_GRP1_DEFAULT;
1688                  MMCSD_drv_log(Diags_USER1,"CMD6 Says Card Supports default\n");
1689                            } else {
1690                                    continue;
1691                            }
1693                           // ret=MMCSD_switch_card_curr_limit (handle,MMCSD_CMD6_GRP4_800mA);
1694                    if(ret!=MMCSD_OK) {
1695                            MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Current switch not successful\n");
1696                            }
1697               ret=MMCSD_switch_card_speed(handle,cmd16_grp1_fn);
1698                           if(ret==MMCSD_OK) {
1699                              MMCSD_drv_log(Diags_USER1," Successfully switched to the above speed\n");
1700                              break;/* Successful switching */
1701                           }
1702                     }
1704         }  else {MMCSD_DEBUG_TRAP}
1705 #endif  //CMD6 does not work for VLAB
1707         if(MMCSD_OK != ret)
1708         {
1709                         MMCSD_DEBUG_TRAP
1710            MMCSD_v2_close(handle);
1711         }
1712         return (ret);
1714 /***********************************************************************/
1715 static MMCSD_Error MMCSD_switch_card_speed(MMCSD_Handle handle,uint32_t cmd16_grp1_fn)
1717    MMCSD_Error ret=MMCSD_ERR;
1718    MMCSD_v2_Object            *object = NULL;
1719    MMCSD_v2_HwAttrs           *hwAttrs = NULL;
1720    MMCSD_v2_Transaction        transaction;
1721    uint32_t uhsMode=0xFFFF; /* Undefined */
1722    stSDMMCHCCapability hcCapab={0,0,0,0};
1724    Bool sdr104_tuning_required=FALSE,switch_speed_approved=TRUE;
1725    uint32_t phy_mode=0,phy_driverType=0,phy_freq=0;
1726    int32_t retVal=STW_SOK;
1728    object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
1729    hwAttrs = (MMCSD_v2_HwAttrs *)((MMCSD_Config *) handle)->hwAttrs;
1731    //Reading the Capability Register
1732    hcCapab.flag1 = HS_MMCSD_CAPA_ALL;
1733    hcCapab.flag2 = HS_MMCSD_CAPA_ALL;
1735    HSMMCSDHostCapabilityGet(hwAttrs->baseAddr, &hcCapab);
1737 #ifdef  MMCSD_CONFIGURE_PHY
1738    if(hcCapab.retValue2 & MMC_CAPA2_DTA_MASK)
1739    {
1740          phy_driverType = PHY_IO_PADS_CTRL1_DR_TYPE_A;
1741    }
1742    if(hcCapab.retValue2 & MMC_CAPA2_DTD_MASK)
1743    {
1744          phy_driverType = PHY_IO_PADS_CTRL1_DR_TYPE_D;
1745    }
1746    else
1747    {
1748          phy_driverType = PHY_IO_PADS_CTRL1_DR_TYPE_C;
1749    }
1750 #endif
1752    memset(cmd6_response_buf,0,sizeof(cmd6_response_buf));
1753    /* Send CMD16 to switch to the requested group */
1754    transaction.cmd = MMCSD_CMD(6U);
1755    transaction.arg = ((MMCSD_SWITCH_MODE & MMCSD_CMD6_GRP1_SEL) | cmd16_grp1_fn);
1756    transaction.flags = MMCSD_CMDRSP_READ | MMCSD_CMDRSP_DATA;
1757    transaction.blockCount = 1U;
1758    transaction.blockSize = 64U;
1759    transaction.dataBuf = cmd6_response_buf;
1761    ret = MMCSD_v2_transfer(handle, &transaction);
1762    /* Wait for DAT0 to go low */
1763    MMCSD_v2_waitDat0(hwAttrs);
1765    if (MMCSD_OK == ret)
1766    {   /* Checking bits 379:376 of the CMD6 response  to see if the switch happened successfully */
1767         uint32_t clk_freq,tranSpeed;
1769             if ((cmd6_response_buf[16U] & 0xFU) == MMCSD_CMD6_GRP1_SDR104 && (cmd16_grp1_fn==MMCSD_CMD6_GRP1_SDR104))
1770                 {
1771                    tranSpeed = MMCSD_TRANSPEED_SDR104;
1772                    uhsMode=MMC_AC12_UHSMS_SDR104;
1773                    sdr104_tuning_required=TRUE;
1774                    clk_freq=208000000U; /* Max freq supported is 208MHz */
1775                    phy_freq=200000000U;
1776                    phy_mode=MODE_SDR104;
1777                    MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Request to switch to SDR104: 192Mhz\n");
1779         } else if  ( ((cmd6_response_buf[16U] & 0xFU) == MMCSD_CMD6_GRP1_SDR50 ) && (cmd16_grp1_fn==MMCSD_CMD6_GRP1_SDR50))
1780             {
1781                    tranSpeed = MMCSD_TRANSPEED_SDR50;
1782                    uhsMode=MMC_AC12_UHSMS_SDR50;
1783                    sdr104_tuning_required=TRUE;
1784                    clk_freq=100000000U; /* 100MHz for SDR50  */
1785                    phy_freq=100000000U;
1786                    phy_mode = MODE_SDR50;
1787                    MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Request to switch to SDR50: 100Mhz\n");
1788                 } else if  ( ((cmd6_response_buf[16U] & 0xFU) == MMCSD_CMD6_GRP1_DDR50) && (cmd16_grp1_fn==MMCSD_CMD6_GRP1_DDR50))
1789                 {
1790                    tranSpeed = MMCSD_TRANSPEED_DDR50;
1791                    uhsMode=MMC_AC12_UHSMS_DDR50;
1792                    sdr104_tuning_required=TRUE;
1793                    clk_freq=50000000U; /* 50MHz for DDR50  */
1794                    phy_freq=50000000U;
1795                    phy_mode=MODE_DDR50;
1796                    MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Request to switch to DDR50: 100Mhz\n");
1798                 }  else if (((cmd6_response_buf[16U] & 0xFU) == MMCSD_CMD6_GRP1_HS) && (cmd16_grp1_fn==MMCSD_CMD6_GRP1_HS))
1799                 {
1800             tranSpeed = MMCSD_TRANSPEED_50MBPS;
1801             if(object->uhsCard) {
1802                           uhsMode= MMC_AC12_UHSMS_SDR25;
1803                         }
1804                     clk_freq=50000000U; /* 50MHz for HS mode */
1805                     phy_freq=50000000U;
1806             phy_mode = MODE_SDR25;
1807                 MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Request to switch to HS: 50Mhz\n");
1808                 } else if (((cmd6_response_buf[16U] & 0xFU) == MMCSD_CMD6_GRP1_DEFAULT) && (cmd16_grp1_fn==MMCSD_CMD6_GRP1_DEFAULT))
1809                 {
1810            tranSpeed = MMCSD_TRANSPEED_25MBPS;
1811            if(object->uhsCard) {
1812                      uhsMode=MMC_AC12_UHSMS_SDR12;
1813                    }
1814            clk_freq=25000000U;  /* 25MHz for SDR12 */
1815            phy_mode =  MODE_SDR12;
1816                    phy_freq=25000000U;
1817                    MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Request to switch to SDR12: 25Mhz\n");
1819         } else {
1820                    /* Speed switch not approved */
1821            MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Wrong Speed requested\n");
1822                    switch_speed_approved=FALSE;
1823                 }
1825                 if(switch_speed_approved)  {
1826           /* Set input clock to make sure that the input clock is equal or higher to the clock value
1827            * requested */
1828               if(NULL != hwAttrs->inputClockControl) {
1829                   uint32_t inputClockRet = hwAttrs->inputClockControl(hwAttrs->instNum, &clk_freq, MMCSD_INPUT_CLOCK_CTRL_SET);
1830                       if (inputClockRet != 0U) {
1831                 hwAttrs->inputClk=inputClockRet;
1832                       } else {
1833                         MMCSD_drv_log4(Diags_USER1,"Unable to change input clock to %d\n",clk_freq);
1834                       }
1835               }
1837       if(!object->uhsCard) {
1838              /* For non UHS cards, it is the high speed/ Default speed mode */
1839               if(tranSpeed==MMCSD_TRANSPEED_50MBPS) {
1840                       /* For non-high speed modes the data should be on the falling edge */
1841                       HSMMCSDHSModeSet(hwAttrs->baseAddr,MMC_HCTL_HSPE_NORMALSPEED);
1842                           phy_mode = MODE_HS;
1843                }  else if(tranSpeed==MMCSD_TRANSPEED_25MBPS) {
1844                       /* For non-high speed modes the data should be on the falling edge */
1845                           HSMMCSDHSModeSet(hwAttrs->baseAddr,MMC_HCTL_HSPE_NORMALSPEED);
1846                           phy_mode = MODE_DS;
1847                } else {
1848                          /* This shouldn't happen */
1849                          ret = MMCSD_ERR;
1850                          MMCSD_DEBUG_TRAP
1851                    }
1852           } else {
1853                   /* Set the UHS mode accordingly */
1854                   if(uhsMode!=0xffff) {
1855                     HSMMCSDUhsModeSet(hwAttrs->baseAddr,uhsMode);
1856             /* SDR50 is rising edge */
1857             if( (uhsMode==MMC_AC12_UHSMS_SDR12) || 
1858                 (uhsMode==MMC_AC12_UHSMS_SDR25) )
1859             {
1860                       /* For non-high speed modes the data should be on the falling edge */
1861                           HSMMCSDHSModeSet(hwAttrs->baseAddr,MMC_HCTL_HSPE_NORMALSPEED);
1862             } else
1863             {
1864                           HSMMCSDHSModeSet(hwAttrs->baseAddr,MMC_HCTL_HSPE_HIGHSPEED);
1865             }
1866   
1867                   } else { MMCSD_DEBUG_TRAP }
1868           }
1870           
1871           MMCSD_socPhyDisableDLL((MMCSD_v2_HwAttrs const *)hwAttrs);
1873          /* Change clock only if required */
1874        if(STW_SOK == HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk, clk_freq, 0U))
1875        {
1876           ret = MMCSD_OK;
1877        } else {
1878                   MMCSD_DEBUG_TRAP
1879                   return (MMCSD_ERR);
1880            }
1881         Osal_delay(50);
1882         /* Configure the Phy accordignly */
1883         
1884         retVal = MMCSD_socPhyConfigure((MMCSD_v2_HwAttrs const *)hwAttrs,phy_mode, phy_freq, phy_driverType);
1885         
1886             if(retVal != MMCSD_OK)
1887             {
1888                   MMCSD_DEBUG_TRAP
1889             }
1891                 if(hwAttrs->tuningType == MMCSD_AUTO_HW_TUNING) {
1892                   object->manualTuning=FALSE;
1893                 } else if(hwAttrs->tuningType == MMCSD_MANUAL_SW_TUNING) {
1894                   object->manualTuning=TRUE;
1895                 }       
1896                   /* Tuning mandatory for SDR104 */
1897                   if(sdr104_tuning_required) {
1898                     MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: About to execute Tuning procedure\n");
1899                 if(object->manualTuning) {
1900               ret=mmcsd_tuning_procedure_SD_manual(handle);
1901                } else {
1902                           ret=mmcsd_tuning_procedure(handle);   
1903                    }
1905                                                 
1906                         if(ret!=MMCSD_OK) {
1907                            MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Tuning failed!\n");
1908                         } else {
1909                    MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Tuning Successfully completed\n");
1910                         }
1911           }
1913                   if(ret==MMCSD_OK) {
1914                     MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: All OK so far\n");
1915                     object->tranSpeed=tranSpeed;
1916                   }
1918                 } else {
1919                   MMCSD_drv_log(Diags_USER1,"MMCSD_switch_card_speed: Error!!\n");
1920                   ret=MMCSD_ERR;
1921                 }
1922    }
1924         return ret;
1927 uint32_t mmcsd_send_tuning(MMCSD_Handle handle) {
1929     uint8_t                     dataBuffer[64] = {0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U,
1930                                                    0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U,
1931                                                    0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U,
1932                                                    0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U};
1933     MMCSD_Error                 ret = MMCSD_OK;
1934     MMCSD_v2_Transaction        transaction;
1935     Bool tuning_fail=FALSE;
1936         uint32_t i;
1937         uint32_t enableInterrupts,enableDma;
1938         MMCSD_v2_HwAttrs *hwAttrs;
1939         hwAttrs = (MMCSD_v2_HwAttrs *)((MMCSD_Config *) handle)->hwAttrs;
1941         enableInterrupts=hwAttrs->enableInterrupt;
1942         enableDma=hwAttrs->enableDma;
1944     hwAttrs->enableInterrupt=0;
1945     hwAttrs->enableDma=0;
1947         /* Send CMD19 */
1948     transaction.cmd = MMCSD_CMD(19U);
1949     transaction.arg = 0;
1950     transaction.flags = MMCSD_CMDRSP_48BITS | MMCSD_CMDRSP_READ | MMCSD_CMDRSP_DATA;
1951     transaction.blockCount = 1U;
1952     transaction.blockSize = sizeof(tuning_blk_pattern_4bit); /* 64 bytes */
1953     transaction.dataBuf = dataBuffer;/* Tuning data from the SD card comes here */
1954     ret = MMCSD_v2_transfer(handle, &transaction);
1956     if(ret==MMCSD_OK) {
1957           /* Compare the data recieved from the card to the expected values*/
1958           for(i = 0U; i < sizeof(tuning_blk_pattern_4bit); i++) {
1959             if(dataBuffer[i]!=tuning_blk_pattern_4bit[i]) {
1960                    tuning_fail=TRUE;
1961                  break;
1962                 }
1963           }
1964         } else {
1965            tuning_fail=TRUE;
1966     }
1968     hwAttrs->enableInterrupt=enableInterrupts;
1969     hwAttrs->enableDma=enableDma;
1970     return(tuning_fail);
1973 uint32_t mmcsd_send_tuning_eMMC(MMCSD_Handle handle) {
1975     uint8_t                     dataBuffer[256U] = {0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U,
1976                                                    0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U,
1977                                                    0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U,
1978                                                    0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U, 0U,0U,0U,0U};
1980     MMCSD_Error                 ret = MMCSD_OK;
1981     MMCSD_v2_Transaction        transaction;
1982     Bool tuning_fail=FALSE;
1983         uint32_t i;
1984         uint32_t enableInterrupts,enableDma;
1985         MMCSD_v2_HwAttrs *hwAttrs;
1986         hwAttrs = (MMCSD_v2_HwAttrs *)((MMCSD_Config *) handle)->hwAttrs;
1988         enableInterrupts=hwAttrs->enableInterrupt;
1989         enableDma=hwAttrs->enableDma;
1990     hwAttrs->enableInterrupt=0;
1991     hwAttrs->enableDma=0;
1993         /* Send CMD21 */
1994     transaction.cmd = MMCSD_CMD(21U);
1995     transaction.arg = 0;
1996     transaction.flags = MMCSD_CMDRSP_48BITS | MMCSD_CMDRSP_READ | MMCSD_CMDRSP_DATA;
1997     transaction.blockCount = 1U;
1998     transaction.blockSize = sizeof(tuning_blk_pattern_8bit); /* 128 bytes */
1999     transaction.dataBuf = dataBuffer;/* Tuning data from the SD card comes here */
2000     ret = MMCSD_v2_transfer(handle, &transaction);
2002     if(ret==MMCSD_OK) {
2003           /* Compare the data recieved from the card to the expected values*/
2004           for(i = 0U;i < sizeof(tuning_blk_pattern_8bit); i++) {
2005             if(dataBuffer[i]!=tuning_blk_pattern_8bit[i]) {
2006                    tuning_fail=TRUE;
2007                  break;
2008                 }
2009           }
2010         } else {
2011            tuning_fail=TRUE;
2012     }
2014     hwAttrs->enableInterrupt=enableInterrupts;
2015     hwAttrs->enableDma=enableDma;
2017     return(tuning_fail);
2021 MMCSD_Error MMCSD_switch_eMMC_mode(MMCSD_Handle handle, MMCSD_SupportedMMCModes_e mode);
2022 MMCSD_Error MMCSD_switch_eMMC_mode(MMCSD_Handle handle, MMCSD_SupportedMMCModes_e mode)
2024     volatile int32_t            ret=MMCSD_OK;
2025     uint8_t       HS_TIMING_val=0,HS_TIMING_index=185; /* EXT_CSD[185] holds HS_TIMING byte */
2026     uint32_t     phy_clk_freq=26000000,clk_freq=26000000; /* Default 26Mhz */
2027     uint32_t uhsMode=MMC_AC12_UHSMS_SDR12;
2028     uint32_t drvStrength=0;
2029     uint32_t phyDriverType=0; /* Default 60ohms */
2030     uint32_t phyMode= MODE_DS;
2031     bool tuning_required=FALSE;
2032     bool ddrMode=FALSE;
2033     uint32_t enhancedStrobe=0;
2034     MMCSD_v2_Object *object;
2035     MMCSD_v2_HwAttrs const *hwAttrs = NULL;
2036     MMCSD_v2_Transaction    transaction;
2037     uint32_t drvStrength_controller=0;
2039     /* Get the pointer to the object and hwAttrs */
2040     object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
2041     hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
2043     drvStrength = object->ecsd[185] >> 4;/* To be obtained from the EXT_CSD */
2046    if((mode == MMCSD_SUPPORT_MMC_HS200) || (mode == MMCSD_SUPPORT_MMC_HS400))
2047    {
2048      /*
2049     * To switch to HS200, host has to perform the following steps:
2050     1) Select the device (through sending CMD7) and make sure it is unlocked (through CMD42)
2051     2) Read the DEVICE_TYPE [196] field of the Extended CSD register to validate
2052       if the device supports HS200 at the IO voltage appropriate for both host and device
2053     3) Read the DRIVER_STRENGTH [197] field of the Extended CSD register to find
2054       * the supported device Driver Strengths. Note: This step can be skipped if changes of driver strength is not needed
2055      4) Set HS200 bit and Driver Strength value in the HS_TIMING [185] field of
2056        * 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.
2057      5) At this point, the host can set the frequency to ≤ 200 MHz.
2058      6) The host may invoke the HS200 tuning sequence,
2059      * by sending CMD21 to the device (see 6.6.5).
2060      NOTE The host should switch to the required bus width before starting the tuning operation to allow the
2061       *  tuning sequence to be done using the proper bus operating conditions.
2062       */
2064       /* Select the device CMD7 */
2065       /* EXT CSD already has been read, so just check if it is supported */
2066       /* Read the driver strength */
2068       /* Send Command 6 to switch the HS_TIMING MODE */
2069       HS_TIMING_val = MMCSD_ECSD_HS_TIMING_HS200;
2070       clk_freq = 200000000;
2071       phyMode = MODE_HS200;
2072       tuning_required=TRUE;
2073       uhsMode =MMC_AC12_UHSMS_SDR104;
2074     } else if ( (mode == MMCSD_SUPPORT_MMC_HS_SDR) || (mode == MMCSD_SUPPORT_MMC_HS_DDR) )
2075     {
2076       HS_TIMING_val = MMCSD_ECSD_HS_TIMING_HIGH_SPEED;
2077       tuning_required=FALSE;
2078       clk_freq = 52000000;
2079       if (mode == MMCSD_SUPPORT_MMC_HS_DDR)
2080       {
2081                   ddrMode=TRUE;
2082                   uhsMode =MMC_AC12_UHSMS_DDR50;
2083                   phyMode=MODE_HSDDR50;
2084           } else {
2085                   uhsMode =MMC_AC12_UHSMS_SDR50;
2086           phyMode = MODE_HSSDR50;
2087           }
2089         } else {
2090       phyMode = MODE_DS;
2091       HS_TIMING_val = MMCSD_ECSD_HS_TIMING_BACKWARD_COMPATIBLE;
2092       tuning_required=FALSE;
2093       clk_freq = 26000000;
2094         }
2097       /* Send the Switch command to change the HS TIMINIG bit of the EXT_CSD[185]  */
2098      if(MMCSD_OK == ret)
2099      {
2100         transaction.cmd = MMCSD_CMD(6U);
2101         transaction.arg = 0x03000000 | (HS_TIMING_index << 16) | (( (drvStrength <<4) | HS_TIMING_val) << 8);
2102         transaction.flags = MMCSD_CMDRSP_BUSY;
2103         ret = MMCSD_v2_transfer(handle, &transaction);
2104      }
2105      Osal_delay(50);
2106      if(MMCSD_OK == ret) {
2107                 /* Wait for DAT0 to go low */
2108        MMCSD_v2_waitDat0(hwAttrs);
2109          }
2111      if(ddrMode==TRUE)
2112      {
2113        uint8_t ecsd_bus_width;
2114        if(object->busWidth==MMCSD_BUS_WIDTH_8BIT) {
2115                   ecsd_bus_width= MMCSD_ECSD_BUS_WIDTH_8BIT_DDR;
2116            } else {
2117                   ecsd_bus_width= MMCSD_ECSD_BUS_WIDTH_4BIT_DDR;
2118            }
2120        transaction.cmd = MMCSD_CMD(6U);
2121        transaction.arg = 0x03000000 | (MMCSD_ECSD_BUS_WIDTH_INDEX << 16) | (( (enhancedStrobe << MMCSD_ECSD_BUS_WIDTH_ES_SHIFT) | ecsd_bus_width) << 8);
2122        transaction.flags = MMCSD_CMDRSP_BUSY;
2123        ret = MMCSD_v2_transfer(handle, &transaction);
2125        Osal_delay(50);
2126        if(MMCSD_OK == ret) {
2127                   /* Wait for DAT0 to go low */
2128           MMCSD_v2_waitDat0(hwAttrs);
2129        }
2130        phy_clk_freq=52000000;
2132      } else {
2133           phy_clk_freq=clk_freq;
2134      }
2136     /* Configure the host controller and Phy */
2137         ret = HSMMCSDUhsModeSet(hwAttrs->baseAddr, uhsMode);
2139     MMCSD_socPhyDisableDLL(hwAttrs);
2141     ret = HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk, clk_freq, 0U);
2142     if(ret!=STW_SOK) {
2143                 return MMCSD_ERR;
2144         }
2146     /* NEW: Enable DLL */
2147     Osal_delay(50);
2148      
2150     MMCSD_socPhyConfigure(hwAttrs,phyMode, phy_clk_freq, phyDriverType);
2152         if(hwAttrs->tuningType == MMCSD_AUTO_HW_TUNING) {
2153            object->manualTuning=FALSE;
2154         } else if(hwAttrs->tuningType == MMCSD_MANUAL_SW_TUNING) {
2155            object->manualTuning=TRUE;
2156         }
2157         
2158      /* Tuning mandatory for HS200 */
2159     if(tuning_required) {
2160                 if(object->manualTuning) {
2161               ret=mmcsd_tuning_procedure_EMMC_manual(handle);
2162             } else {
2163               ret=mmcsd_tuning_procedure(handle);       
2164                 }
2165                 
2166            if(ret!=MMCSD_OK) {
2167           MMCSD_DEBUG_TRAP
2168            }
2169      }
2171      if((mode == MMCSD_SUPPORT_MMC_HS400) || (mode == MMCSD_SUPPORT_MMC_HS400_ES))
2172      {
2173                 if(mode ==MMCSD_SUPPORT_MMC_HS400_ES)
2174                 {
2175                         enhancedStrobe=1;
2176                 }
2177                 /*
2178                  Set the “Timing Interface” parameter in the HS_TIMING [185] field
2179                  * of the Extended CSD register to 0x1 to switch to High Speed mode and
2180                  * then set the clock frequency to a value not greater than 52 MHz,
2181          */
2182          HS_TIMING_val=MMCSD_ECSD_HS_TIMING_HIGH_SPEED;
2183          transaction.cmd = MMCSD_CMD(6U);
2184          transaction.arg = 0x03000000 | (MMCSD_ECSD_HS_TIMING_INDEX << 16) | (( (enhancedStrobe <<4) | HS_TIMING_val) << 8);
2185          transaction.flags = MMCSD_CMDRSP_BUSY;
2186          ret = MMCSD_v2_transfer(handle, &transaction);
2188        Osal_delay(50);
2192           MMCSD_socPhyDisableDLL(hwAttrs);
2194        ret = HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk, 52000000, 0U);
2195        if(ret!=STW_SOK) {
2196                   return MMCSD_ERR;
2197            }
2199        Osal_delay(50);
2201        phyMode = MODE_HSSDR50;
2202        
2203        MMCSD_socPhyConfigure(hwAttrs,phyMode, 50000000, phyDriverType);
2204       
2205        /*Set BUS_WIDTH[183] to 0x06 to select the dual data rate x8 bus mode */
2206        transaction.cmd = MMCSD_CMD(6U);
2207        transaction.arg = 0x03000000 | (MMCSD_ECSD_BUS_WIDTH_INDEX << 16) | (( (enhancedStrobe << MMCSD_ECSD_BUS_WIDTH_ES_SHIFT) | MMCSD_ECSD_BUS_WIDTH_8BIT_DDR) << 8);
2208        transaction.flags = MMCSD_CMDRSP_BUSY;
2209        ret = MMCSD_v2_transfer(handle, &transaction);
2211        Osal_delay(50);
2212        if(MMCSD_OK == ret) {
2213                   /* Wait for DAT0 to go low */
2214           MMCSD_v2_waitDat0(hwAttrs);
2215        }
2217          /*Set the “Timing Interface” parameter in the HS_TIMING [185] field of the
2218          * Extended CSD register to 0x3 to switch to HS400 mode.
2219          */
2220         /* Send the Switch command to change the HS TIMINIG bit of the EXT_CSD[185]  */
2221         if(MMCSD_OK == ret)
2222         {
2223           transaction.cmd = MMCSD_CMD(6U);
2224           transaction.arg = 0x03000000 | (MMCSD_ECSD_HS_TIMING_INDEX << 16) | (( (enhancedStrobe <<4) | MMCSD_ECSD_HS_TIMING_HS400) << 8);
2225           transaction.flags = MMCSD_CMDRSP_BUSY;
2226           ret = MMCSD_v2_transfer(handle, &transaction);
2227         }
2228         Osal_delay(50);
2229         if(MMCSD_OK == ret) {
2230                   /* Wait for DAT0 to go low */
2231           MMCSD_v2_waitDat0(hwAttrs);
2232             }
2234         ret = HSMMCSDUhsModeSet(hwAttrs->baseAddr, MMC_AC12_UHSMS_HS400);
2236          if(enhancedStrobe)
2237          {
2238            HSMMCSDEnhancedStrobeSet(hwAttrs->baseAddr,MMC_VREG_STROBE_ENABLE);
2239                  }
2241         ret = HSMMCSDUhsDrvStrengthSet(hwAttrs->baseAddr, drvStrength_controller);
2243              MMCSD_socPhyDisableDLL(hwAttrs);
2246          /* Host may set the clock frequency to a value not greater than 200 MHz"*/
2247         ret = HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk, 200000000, 0U);
2249          /* NEW: Enable DLL */
2250         Osal_delay(50);
2251         phyMode = MODE_HS400;
2252         
2253         MMCSD_socPhyConfigure(hwAttrs,phyMode, 200000000, phyDriverType);
2255         
2256         if(ret!=STW_SOK) {
2257                   return MMCSD_ERR;
2258             }
2259         Osal_delay(50);
2260          }
2262      return (ret);
2266 /*
2267  ***********************************************************************
2268  *  ======== Returns tuning status ========
2269  **********************************************************************/
2270 static MMCSD_Error mmcsd_tuning_procedure(MMCSD_Handle handle) {
2272      MMCSD_v2_Object        *object = NULL;
2273      MMCSD_v2_HwAttrs const *hwAttrs = NULL;
2274      bool tuning_success = FALSE;
2275      uint32_t i;
2276      uint32_t state,samplingClock;
2278      /* Get the pointer to the object and hwAttrs */
2279      object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
2280          hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
2281      
2282      HSMMCSDCardTuningSet(hwAttrs->baseAddr,HS_MMCSD_EXEC_TUNING_ENABLE, HS_MMCSD_CLCK_SELECT_DISABLE);
2283          /* Read the ET back until it is 1 */
2284          {
2285                 uint32_t state,samplingClock;
2286         do {
2287            HSMMCSDCardTuningGet(hwAttrs->baseAddr,&state, &samplingClock);
2288             } while(state!=MMC_AC12_ET_EXECUTE);
2289      }
2290       for(i=0;i<40;i++)
2291      {
2293            /* Send CMD19 for SD card, CMD21 for eMMC */
2294        if(MMCSD_CARD_EMMC == object->cardType) {
2295              mmcsd_send_tuning_eMMC(handle);
2296            } else {
2297              mmcsd_send_tuning(handle);
2298            }
2299         
2300            HSMMCSDCardTuningGet(hwAttrs->baseAddr,&state, &samplingClock);
2301            if (state==MMC_AC12_ET_COMPLETED && samplingClock == MMC_AC12_SCLK_SEL_TUNED) 
2302            {
2303                    /* Tuninig is succcessful. Return */
2304            tuning_success=TRUE;
2305            break;
2306            }
2308     }
2310         if(!tuning_success) {
2311                 MMCSD_DEBUG_TRAP
2312                 HSMMCSDCardTuningSet(hwAttrs->baseAddr,HS_MMCSD_EXEC_TUNING_DISABLE, HS_MMCSD_CLCK_SELECT_DISABLE);
2313                 return MMCSD_ERR;
2314         }
2317    HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_CMDLINE_RESET);
2318    HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_DATALINE_RESET);
2320         return MMCSD_OK;
2323 /*
2324  *  ======== MMCSD_open ========
2325  */
2326 static MMCSD_Error MMCSD_v2_initEmmc(MMCSD_Handle handle)
2328     MMCSD_Error                 ret = MMCSD_OK;
2329     uint32_t                    retry = 0xFFFFU;
2330     MMCSD_v2_Object            *object = NULL;
2331     MMCSD_v2_HwAttrs const     *hwAttrs = NULL;
2332     MMCSD_v2_Transaction        transaction;
2333     volatile int32_t            status = -1;
2334     uint32_t controller_buswidth = HS_MMCSD_BUS_WIDTH_1BIT;  /* Default */
2335     uint8_t ecsd_bus_with      = MMCSD_ECSD_BUS_WIDTH_1BIT; /* Default */
2337     /* Get the pointer to the object and hwAttrs */
2338     object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
2339     hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
2341     if(MMCSD_OK == ret)
2342     {
2343         /*
2344          * 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
2345          * controller Reset
2346          */
2347         status = HSMMCSDSoftReset(hwAttrs->baseAddr);
2349         if (STW_SOK != status)
2350         {
2351 #ifdef LOG_EN
2352             MMCSD_drv_log4(Diags_USER1,
2353                     "MMCSD:(%p) HS MMC/SD Reset failed\n", hwAttrs->baseAddr);
2354 #endif
2355             ret = MMCSD_ERR;
2356         }
2357         else
2358         {
2359             ret = MMCSD_OK;
2360         }
2361     }
2363     if (MMCSD_OK == ret)
2364     {
2365         /* Lines Reset */
2366         status=HSMMCSDLinesReset(hwAttrs->baseAddr, HS_MMCSD_ALL_RESET);
2367         if(status!=STW_SOK) {
2368            MMCSD_DEBUG_TRAP
2369          }
2371         /* Set the bus width */
2372         status=HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_1BIT);
2373         if(status!=STW_SOK) {
2374            MMCSD_DEBUG_TRAP
2375          }
2377         /* Set the bus voltage */
2378         status=HSMMCSDBusVoltSet(hwAttrs->baseAddr, MMC_HCTL_SDVS_1V8);
2380         if(status!=STW_SOK) {
2381            MMCSD_DEBUG_TRAP
2382          }
2384    if(MMCSD_OK == ret)
2385    {
2386       uint32_t slotType,reg=0;
2387       slotType = CSL_MMC_CTLCFG_CAPABILITIES_SLOT_TYPE_VAL_EMBEDDED;
2389       reg = *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->CTL_CFG_2_REG));
2390       reg = Bitfield_csl_set (reg, slotType,
2391                             CSL_MMC_SSCFG_CTL_CFG_2_REG_SLOTTYPE_MASK,
2392                             CSL_MMC_SSCFG_CTL_CFG_2_REG_SLOTTYPE_SHIFT);
2393        *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->CTL_CFG_2_REG))=reg;
2394  
2395       //
2396       // Enable pins by setting the IO mux field in the phy to 0.
2397       //
2398       reg = *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->PHY_CTRL_1_REG));
2399       reg = Bitfield_csl_set (reg, 0,
2400                             CSL_MMC_SSCFG_PHY_CTRL_1_REG_IOMUX_ENABLE_MASK,
2401                             CSL_MMC_SSCFG_PHY_CTRL_1_REG_IOMUX_ENABLE_SHIFT);
2402       *(&(((CSL_mmc_sscfgRegs *)(hwAttrs->ssBaseAddr))->PHY_CTRL_1_REG))=reg;
2404       //
2405       // Wait for card detect.
2406       //
2407        {
2408                    uint32_t ins=0;
2410                do {
2411               ins = HSMMCSDIsCardInserted(hwAttrs->baseAddr);
2412            } while(ins==0);
2413        }
2414     }
2416         MMCSD_socPhyInit(hwAttrs);
2418         /* Bus power on */
2419         status = ((int32_t)(HSMMCSDBusPower(hwAttrs->baseAddr, MMC_HCTL_SDBP_PWRON)));
2420         if(status!=STW_SOK) {
2421            MMCSD_DEBUG_TRAP
2422          }
2424         if (STW_SOK != status)
2425         {
2426 #ifdef LOG_EN
2427             MMCSD_drv_log4(Diags_USER1,
2428                     "MMCSD:(%p) HS MMC/SD Power on failed\n", hwAttrs->baseAddr);
2429 #endif
2430             ret = MMCSD_ERR;
2431         }
2432     }
2434     if (MMCSD_OK == ret)
2435     {
2436         /* Set the initialization frequency */
2437         status = HSMMCSDBusFreqSet(hwAttrs->baseAddr, hwAttrs->inputClk,400000,FALSE);
2439         if (STW_SOK != status)
2440         {
2441 #ifdef LOG_EN
2442         MMCSD_drv_log4(Diags_USER1,
2443           "MMCSD:(%p) HS MMC/SD Bus Frequency set failed\n", hwAttrs->baseAddr);
2444 #endif
2445             ret = MMCSD_ERR;
2446         }
2448     }
2452     if(MMCSD_OK == ret)
2453     {
2454         /* CMD0 - reset card */
2455         if(MMCSD_OK == ret)
2456         {
2457             transaction.cmd = MMCSD_CMD(0U);
2458             transaction.flags = MMCSD_CMDRSP_NONE;
2459             transaction.arg = 0U;
2460             ret = MMCSD_v2_transfer(handle, &transaction);
2461         }
2463         /* NOTE: Add delay */
2464         Osal_delay(50U);
2466         if(MMCSD_OK == ret)
2467         {
2468             stSDMMCHCCapability hcCapab={0,0,0,0};
2469             uint32_t hostOcr=0;
2470             #define MMC_VDD_27_33                                       0x00FF8000U
2471             #define MMC_VDD_17_19                                       0x00000080U
2472             #define SECTOR_MODE                                         0x4U
2474                 //Reading the Capability Register
2475                     hcCapab.flag1 = HS_MMCSD_VOLT_3V3_SUPPORT;
2477                HSMMCSDHostCapabilityGet(hwAttrs->baseAddr, &hcCapab);
2478                if(hcCapab.retValue1)
2479                {
2480                 hostOcr |= MMC_VDD_27_33;
2481                }
2483                    hcCapab.flag1 = HS_MMCSD_VOLT_3V0_SUPPORT;
2484                HSMMCSDHostCapabilityGet(hwAttrs->baseAddr, &hcCapab);
2486                if (hcCapab.retValue1)
2487                {
2488                 hostOcr |= MMC_VDD_27_33;
2489                }
2490                hostOcr |= MMC_VDD_17_19;
2492             /* Poll until we get the card status (BIT31 of OCR) is powered up */
2493             do
2494             {
2495                 /* APP cmd should be preceeded by a CMD55 */
2496                 transaction.cmd = MMCSD_CMD(1U);
2497                 transaction.flags = MMCSD_CMDRSP_48BITS;
2498                 // transaction.arg = 0xC0FF8080U;
2499                 transaction.arg = ( (0x80000000) |  (SECTOR_MODE << 28U) | hostOcr );
2500                 ret = MMCSD_v2_transfer(handle, &transaction);
2501                 retry--;
2502             } while (((transaction.response[0U] & ((uint32_t)BIT(31U))) == 0U) && (retry != 0));
2504             if (0U == retry)
2505             {
2506                 /* No point in continuing */
2507                 ret = MMCSD_ERR;
2508             }
2509         }
2510             object->cmd23Supported = TRUE; /* MMC should always support CMD23 */
2512         if(MMCSD_OK == ret)
2513         {
2514             object->ocr = transaction.response[0U];
2516             object->highCap = (object->ocr & MMCSD_OCR_HIGH_CAPACITY) ? 1U : 0U;
2518             /* Send CMD2, to get the card identification register */
2519             transaction.cmd = MMCSD_CMD(2U);
2520             transaction.flags = MMCSD_CMDRSP_136BITS;
2521             transaction.arg = 0U;
2523             ret = MMCSD_v2_transfer(handle, &transaction);
2525             //  memcpy(object->cid, transaction.response, 16U);
2526             object->cid[3]= (transaction.response[3] << 8)| (transaction.response[2] >> 24);
2527             object->cid[2]= (transaction.response[2] << 8)| (transaction.response[1] >> 24);
2528             object->cid[1]= (transaction.response[1] << 8)| (transaction.response[0] >> 24);
2529             object->cid[0]= (transaction.response[0] << 8);
2530         }
2532         if(MMCSD_OK == ret)
2533         {
2534             object->rca = 2U;
2536             /* Send CMD3, to get the card relative address */
2537             transaction.cmd = MMCSD_CMD(3U);
2538             transaction.flags = 0U;
2539             transaction.arg = object->rca << 16U;
2541             ret = MMCSD_v2_transfer(handle, &transaction);
2542         }
2544         if(MMCSD_OK == ret)
2545         {
2546             /* Send CMD9, to get the card specific data */
2547             transaction.cmd = MMCSD_CMD(9U);
2548             transaction.flags = MMCSD_CMDRSP_136BITS;
2549             transaction.arg = object->rca << 16U;
2551             ret = MMCSD_v2_transfer(handle, &transaction);
2553             object->csd[3]= (transaction.response[3] << 8)| (transaction.response[2] >> 24);
2554             object->csd[2]= (transaction.response[2] << 8)| (transaction.response[1] >> 24);
2555             object->csd[1]= (transaction.response[1] << 8)| (transaction.response[0] >> 24);
2556             object->csd[0]= (transaction.response[0] << 8);
2557         }
2559         if(MMCSD_OK == ret)
2560         {
2561             object->tranSpeed = ((object->csd[3] & 0x000000FFU));
2562             object->blockSize = (((uint32_t)2U)<<(((object->csd[0] & 0x03C00000U) >> 22)-1U));
2564             if (((object->csd[3] & 0x3C000000U) >> 26) != 0x04U)
2565             {
2566                 ret = MMCSD_ERR;
2567             }
2568         }
2570         if(MMCSD_OK == ret)
2571         {
2572             /* Select the card */
2573             transaction.cmd = MMCSD_CMD(7U);
2574             transaction.flags = MMCSD_CMDRSP_BUSY;
2575             transaction.arg = object->rca << 16U;
2577             ret = MMCSD_v2_transfer(handle, &transaction);
2578         }
2580         if(MMCSD_OK == ret)
2581         {
2582             transaction.cmd = MMCSD_CMD(8U);
2583             transaction.flags = MMCSD_CMDRSP_READ | MMCSD_CMDRSP_DATA;
2584             transaction.arg = object->rca << 16U;
2585             transaction.blockCount = 1U;
2586             transaction.blockSize = 512U;
2587             transaction.dataBuf = object->ecsd;
2589             ret = MMCSD_v2_transfer(handle, &transaction);
2590         }
2592         /* NOTE: Add delay */
2593          delay(100U);
2595         if(MMCSD_OK == ret)
2596         {
2597             object->blockCount = (((uint32_t)(object->ecsd[215])) << 24) +
2598                                  (((uint32_t)(object->ecsd[214])) << 16) +
2599                                  (((uint32_t)(object->ecsd[213])) << 8) +
2600                                  (((uint32_t)(object->ecsd[212])));
2601             object->size = (object->blockCount * object->blockSize);
2602             object->busWidth = MMCSD_BUS_WIDTH_8BIT;
2603             object->sdVer = object->ecsd[192];
2604         }
2606         /* NOTE: Add delay */
2607         delay(100U);
2609        /* Setting the bus width as per the allowed configuration */
2610        if(hwAttrs->supportedBusWidth & MMCSD_BUS_WIDTH_8BIT) {
2611           controller_buswidth = HS_MMCSD_BUS_WIDTH_8BIT;
2612           ecsd_bus_with = MMCSD_ECSD_BUS_WIDTH_8BIT;
2613            } else if(hwAttrs->supportedBusWidth & MMCSD_BUS_WIDTH_4BIT) {
2614           controller_buswidth = HS_MMCSD_BUS_WIDTH_4BIT;
2615           ecsd_bus_with = MMCSD_ECSD_BUS_WIDTH_4BIT;
2616            } else if(hwAttrs->supportedBusWidth & MMCSD_BUS_WIDTH_1BIT) {
2617           controller_buswidth = HS_MMCSD_BUS_WIDTH_1BIT;
2618           ecsd_bus_with = MMCSD_ECSD_BUS_WIDTH_1BIT;
2619        }
2621        if(MMCSD_OK == ret)
2622        {
2623           transaction.cmd = MMCSD_CMD(6U);
2624           transaction.arg = 0x03000000 | (MMCSD_ECSD_BUS_WIDTH_INDEX << 16) | (( (0 << MMCSD_ECSD_BUS_WIDTH_ES_SHIFT) | ecsd_bus_with) << 8);
2625           transaction.flags = MMCSD_CMDRSP_BUSY;
2626           ret = MMCSD_v2_transfer(handle, &transaction);
2627         }
2628         object->busWidth = controller_buswidth;
2630         /* NOTE: Add delay */
2631         delay(100U);
2632         if (MMCSD_OK == ret)
2633         {
2634           HSMMCSDBusWidthSet(hwAttrs->baseAddr, controller_buswidth);
2635         }
2637         /* NOTE: Add delay */
2638         delay(100U);
2640         if(MMCSD_OK == ret)
2641         {
2642             transaction.cmd = MMCSD_CMD(6U);
2643             transaction.arg = 0x03A20100;
2644             transaction.flags = MMCSD_CMDRSP_BUSY;
2645             ret = MMCSD_v2_transfer(handle, &transaction);
2646         }
2648         /* NOTE: Add delay */
2649         delay(100U);
2650     }
2651 #ifndef MMCSD_SUPPORT_MMC_HS400_DISABLED
2652     /* Read DEVICE_TYPE in the ECSD[196] to get the supported speeds */
2653     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))
2654     {
2656       if( (hwAttrs->supportedModes & MMCSD_SUPPORT_MMC_HS400_ES) && (object->ecsd[MMCSD_ECSD_STROBE_SUPPORT_INDEX] == MMCSD_ECSD_STROBE_SUPPORT_ENHANCED_EN) )
2657       {
2658          ret = MMCSD_switch_eMMC_mode(handle,MMCSD_SUPPORT_MMC_HS400_ES);
2659       }
2660       else if((hwAttrs->supportedModes & MMCSD_SUPPORT_MMC_HS400))
2661       {
2662          ret = MMCSD_switch_eMMC_mode(handle,MMCSD_SUPPORT_MMC_HS400);
2663           }
2665       if(ret==MMCSD_OK) {
2666          object->tranSpeed=MMCSD_TRANSPEED_HS400;
2667        } else {
2668                    MMCSD_DEBUG_TRAP
2669            }
2670         } /* Check for HS200 next */
2671         else
2672 #endif
2673         if( (hwAttrs->supportedModes & MMCSD_SUPPORT_MMC_HS200) && (object->ecsd[MMCSD_EMMC_ECSD_DEVICE_TYPE_INDEX] & MMCSD_EMMC_ECSD_DEVICE_TYPE_HS200_200MHZ_1P8V))
2674     {
2675          ret = MMCSD_switch_eMMC_mode(handle,MMCSD_SUPPORT_MMC_HS200);
2676          if(ret==MMCSD_OK) {
2677          object->tranSpeed=MMCSD_TRANSPEED_HS200;
2678          } else {
2679                    MMCSD_DEBUG_TRAP
2680              }
2681         } /* Check for HS-DDR next */
2682         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))
2683         {
2684          ret = MMCSD_switch_eMMC_mode(handle,MMCSD_SUPPORT_MMC_HS_DDR);
2685          if(ret==MMCSD_OK) {
2686          object->tranSpeed=MMCSD_TRANSPEED_DDR50;
2687          } else {
2688                    MMCSD_DEBUG_TRAP
2689              }
2690         }
2691         else if ( (hwAttrs->supportedModes & MMCSD_SUPPORT_MMC_HS_SDR) && (object->ecsd[MMCSD_EMMC_ECSD_DEVICE_TYPE_INDEX] & MMCSD_EMMC_ECSD_DEVICE_TYPE_HS_52MHZ))
2692         {
2693          ret = MMCSD_switch_eMMC_mode(handle,MMCSD_SUPPORT_MMC_HS_SDR);
2694          if(ret==MMCSD_OK) {
2695          object->tranSpeed=MMCSD_TRANSPEED_DDR50;
2696          } else {
2697                    MMCSD_DEBUG_TRAP
2698              }
2699         }       else if (hwAttrs->supportedModes & MMCSD_SUPPORT_MMC_DS)
2700         {
2701        ret = MMCSD_switch_eMMC_mode(handle,MMCSD_SUPPORT_MMC_DS);
2702        if(ret==MMCSD_OK) {
2703          object->tranSpeed=MMCSD_TRANSPEED_SDR25;
2704        } else {
2705                  MMCSD_DEBUG_TRAP
2706            }
2707          }
2710     if(MMCSD_OK != ret)
2711     {
2712         MMCSD_v2_close(handle);
2713     }
2715     return (ret);
2717 /*
2718  *  ======== MMCSD_v2_transfer ========
2719  */
2720 static MMCSD_Error MMCSD_v2_transfer(MMCSD_Handle handle,
2721                                      MMCSD_v2_Transaction *transaction)
2723     MMCSD_Error             ret = MMCSD_ERR;
2724     hsMmcsdCmdObj_t         cmdObj = {{0U, 0U, 0U, 0U}, 0U, 0U, 0U, 0U};
2725     MMCSD_v2_Object        *object = NULL;
2726     MMCSD_v2_HwAttrs const *hwAttrs = NULL;
2727     uint32_t params;
2729     if ((handle != NULL) && (transaction != NULL))
2730     {
2731         /* Get the pointer to the object and hwAttrs */
2732         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
2733         hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
2735         ret = MMCSD_OK;
2737         if(hwAttrs->enableInterrupt==1) {
2738           /* Check the semaphre counts */
2739           int32_t count;
2740           count = SemaphoreP_getCount(object->commandComplete);
2741           if(count != 0U) {
2742               MMCSD_osalPendLock(object->commandComplete, SemaphoreP_WAIT_FOREVER);
2743           }
2744         }
2745     }
2747     if(MMCSD_OK == ret)
2748     {
2749         /* Configure the command type to be executed from the command flags */
2750         if (transaction->flags & MMCSD_CMDRSP_STOP)
2751         {
2752             cmdObj.cmd.cmdType = HS_MMCSD_CMD_TYPE_BUS_SUSPEND;
2753         }
2754         else if (transaction->flags & MMCSD_CMDRSP_FS)
2755         {
2756             cmdObj.cmd.cmdType = HS_MMCSD_CMD_TYPE_FUNC_SEL;
2757         }
2758         else if (transaction->flags & MMCSD_CMDRSP_ABORT)
2759         {
2760             cmdObj.cmd.cmdType = HS_MMCSD_CMD_TYPE_IO_ABORT;
2761         }
2762         else
2763         {
2764             cmdObj.cmd.cmdType = 0U; /*dummy statement for misra warning*/
2765         }
2767         /* Configure the response type from the command flags */
2768         if (transaction->flags & MMCSD_CMDRSP_NONE)
2769         {
2770             cmdObj.cmd.rspType = HS_MMCSD_RSP_TYPE_NONE;
2771         }
2772         else if (transaction->flags & MMCSD_CMDRSP_136BITS)
2773         {
2774             cmdObj.cmd.rspType = HS_MMCSD_RSP_TYPE_LEN_136;
2775         }
2776         else if (transaction->flags & MMCSD_CMDRSP_BUSY)
2777         {
2778             cmdObj.cmd.rspType = HS_MMCSD_RSP_TYPE_LEN_48_BUSY;
2779         }
2780         else
2781         {
2782             cmdObj.cmd.rspType = HS_MMCSD_RSP_TYPE_LEN_48;
2783         }
2785         /* Configure the transfer type */
2786         cmdObj.enableData = (transaction->flags & MMCSD_CMDRSP_DATA) ? (uint32_t)TRUE : (uint32_t)FALSE;
2788         if(0U != hwAttrs->enableInterrupt)
2789         {
2790                         HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2791             HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2792             HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2794         } else {
2795                         HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_SIGEN_ALL);
2796                 }
2798         object->cmdComp = 0;
2799         object->cmdTimeout = 0;
2800         object->cmdCRCError = 0;
2801                 object->cmdIndexError = 0;
2802                 object->cmdEBError = 0;
2803         object->dataCRCError = 0;
2804                 object->dataEBError = 0;
2805                 object->cmdError = 0;
2806                 object->xferInProgress = 0;
2807         object->xferComp = 0;
2808         object->xferTimeout = 0;
2810                 
2811                 if (0 != cmdObj.enableData)
2812         {
2814                            /* Acquire the lock for this particular MMCSD handle */
2815             MMCSD_osalPendLock(object->transferMutex, SemaphoreP_WAIT_FOREVER);
2816             MMCSD_osalPendLock(object->commandMutex, SemaphoreP_WAIT_FOREVER);
2818             /*  MMCSD_osalHardwareIntrDisable(hwAttrs->intNum); */
2820             object->dataBufIdx = (uint8_t*)transaction->dataBuf;
2823             object->dataBlockCount = transaction->blockCount;
2824             object->dataBlockSize = transaction->blockSize;
2825                         
2827 cmdObj.cmd.xferType = (transaction->flags & MMCSD_CMDRSP_READ) ? \
2828                 HS_MMCSD_XFER_TYPE_RX : HS_MMCSD_XFER_TYPE_TX;
2829             cmdObj.numBlks = (TRUE == cmdObj.enableData) ? object->dataBlockCount : 0U;
2830             HSMMCSDIntrStatusClear(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2832             if (HS_MMCSD_XFER_TYPE_RX == cmdObj.cmd.xferType)
2833             {
2834                 /* Configure the transfer for read operation */
2835                 HSMMCSDIntrStatusClear(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2836                 HSMMCSDIntrStatusEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2837                 HSMMCSDIntrStatusDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2839                                 object->readBlockCount=object->dataBlockCount;
2840             }
2841             else
2842             {
2843                 /* Configure the transfer for write operation */
2844                 HSMMCSDIntrStatusClear(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2845                 HSMMCSDIntrStatusEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2846                 HSMMCSDIntrStatusDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2848                 if(0U != hwAttrs->enableInterrupt)
2849                 {
2850                                         HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2851                     HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2852                     HSMMCSDIntrDisable(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2854                 }
2855                                 object->writeBlockCount=object->dataBlockCount;
2856             }
2858             HSMMCSDBlkLenSet(hwAttrs->baseAddr, transaction->blockSize);
2860             HSMMCSDIntrStatusClear(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2861             HSMMCSDDataTimeoutSet(hwAttrs->baseAddr, MMC_SYSCTL_DTO_15THDTO);
2863             HSMMCSDIntrStatusEnable(hwAttrs->baseAddr,
2864                 (HS_MMCSD_INTR_CMDCOMP | HS_MMCSD_INTR_CMDTIMEOUT |
2865                  HS_MMCSD_INTR_DATATIMEOUT | HS_MMCSD_INTR_TRNFCOMP | 0x17ff0000));
2867             if(0U != hwAttrs->enableInterrupt)
2868             {
2869                            HSMMCSDIntrEnable(hwAttrs->baseAddr,
2870                     (HS_MMCSD_INTR_CMDCOMP | HS_MMCSD_INTR_CMDTIMEOUT |
2871                      HS_MMCSD_INTR_DATATIMEOUT));
2873                         }
2875             cmdObj.cmd.cmdId = transaction->cmd;
2876             cmdObj.cmdArg = transaction->arg;
2878             MMCSD_osalCache_wbInv(object->dataBufIdx,(transaction->blockSize * transaction->blockCount));
2880             if(hwAttrs->enableDma)
2881             {
2882                 /* Setup the adma descriptor */
2884                 /* Lower16 bits of the size  in bits 16-32 */
2885                 params = (transaction->blockCount * transaction->blockSize) << 16;
2886                 /* Upper bits of size is in bits 6-16, followed by the ADMA transfer flags (bits 0-5)   */
2887                 params= params | ((((transaction->blockCount * transaction->blockSize) >>16) <<6) | 0x0023);
2888                 /* VER4 is enabled for 26 bit sizes */
2889                 HSMMCSDHostVer4Select(hwAttrs->baseAddr, MMC_AC12_HOSTVER4_ENABLE);
2890                 HSMMCSDAdmaLengthSelect(hwAttrs->baseAddr, MMC_ADMA2_LENGTH_MODE_26BIT);
2893                 mmc_setupDescriptor(&adma2_desc,  ///< pointer to descriptor head, NOT pointer to the address value within the decriptor.
2894                                     params,     ///< parameters for descriptor.
2895                    (uint64_t)transaction->dataBuf); ///< physical address to pack into the descriptor.
2897                 HSMMCSDDmaSelect(hwAttrs->baseAddr, MMC_HCTL_DMAS_ADMA2_32BIT);
2900                 /* Write the descriptor address to ADMA2 address */
2901                 HSMMCSDAdmaAddressSet(hwAttrs->baseAddr,(((uint64_t)&adma2_desc)&0xffffffff),(((uint64_t)&adma2_desc) >> 32));
2903                 MMCSD_osalCache_wbInv(&adma2_desc,sizeof(adma2_desc));
2905                 cmdObj.enableDma = 1U;
2906             } else
2907             {
2908                 cmdObj.enableDma = 0U;
2909             }
2910                     /* Wait for command and data inhibit to go low before
2911                      * commands can be issued */
2912                 
2913                 MMCSD_v2_waitCmdInhibit(hwAttrs);
2914             MMCSD_v2_waitDatInhibit(hwAttrs);
2915  
2916             if(0U != hwAttrs->enableInterrupt)
2917             {
2918                if (HS_MMCSD_XFER_TYPE_RX == cmdObj.cmd.xferType)   
2919                            {
2920                    HSMMCSDIntrEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFRDRDY);
2921                } 
2922                             else 
2923                            {
2924                    HSMMCSDIntrEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_BUFWRRDY);
2925                }
2926                        HSMMCSDIntrEnable(hwAttrs->baseAddr, HS_MMCSD_INTR_TRNFCOMP);
2927             }
2929             HSMMCSDCommandSend(hwAttrs->baseAddr,
2930                                HS_MMCSD_CMD(cmdObj.cmd.cmdId, cmdObj.cmd.cmdType, cmdObj.cmd.rspType, cmdObj.cmd.xferType),
2931                                cmdObj.cmdArg,
2932                                (TRUE == cmdObj.enableData)?MMC_CMD_DP_DATA:MMC_CMD_DP_NODATA,
2933                                cmdObj.numBlks,
2934                                cmdObj.enableDma,
2935                                MMC_CMD_ACEN_DISABLE);
2936             /*  MMCSD_osalHardwareIntrEnable(hwAttrs->intNum); */
2938 #ifdef LOG_EN
2939             MMCSD_drv_log4(Diags_USER1,
2940                        "MMCSD:(%p) Pending on commandComplete semaphore\n",
2941                        hwAttrs->baseAddr);
2942 #endif
2944             /*
2945              * Wait for the transfer to complete here.
2946              * It's OK to block from here because the MMCSD's Hwi will unblock
2947              * upon errors
2948              */
2950                     if((object->manualTuning==FALSE) &&    ((cmdObj.cmd.cmdId==MMCSD_CMD(19U)) || (cmdObj.cmd.cmdId==MMCSD_CMD(21U)))    ) 
2951                     {
2952                            object->cmdComp=1;   
2953                     }     
2954                     else 
2955                     {
2956                        if(0U != hwAttrs->enableInterrupt)
2957                {
2958                               MMCSD_osalPendLock(object->commandComplete, SemaphoreP_WAIT_FOREVER);
2959                }
2960                    else
2961                {
2962                     while ( (0 == object->cmdComp) && (0==object->cmdError) )
2963                     {
2964                         MMCSD_v2_cmdStatusFxn((uintptr_t) handle);
2965                     }
2966                 }
2967             }
2968                 
2969 #ifdef LOG_EN
2970             MMCSD_drv_log4(Diags_USER1,
2971                        "MMCSD:(%p) Command transaction completed\n", hwAttrs->baseAddr);
2972 #endif
2975             if( object->manualTuning && object->cmdError && ( (cmdObj.cmd.cmdId==MMCSD_CMD(19U)) || (cmdObj.cmd.cmdId==MMCSD_CMD(21U)) ) )  
2976                     {                              
2977                HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_CMDLINE_RESET);
2978                HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_DATALINE_RESET);
2979                            ret=MMCSD_ERR_TUNING_CMD_ERROR;
2980                     }
2981             else
2982                     {   
2983                      /* Command execution fail */
2984                 if (1 == object->cmdTimeout)
2985                 {
2986                     ret = MMCSD_ERR;
2987                     object->cmdTimeout = 0;
2988                     MMCSD_DEBUG_TRAP
2989                 }
2992                /* Command execution fail */
2993                if (1 == object->cmdCRCError)
2994                {
2995                    ret = MMCSD_ERR;
2996                    object->cmdCRCError = 0;
2997                    MMCSD_DEBUG_TRAP
2998                }
2999             }
3000             
3001                         /* Command execution successful */
3002             if (1 == object->cmdComp)
3003             {
3004                 ret = MMCSD_OK;
3005                 object->cmdComp = 0;
3007                 if(0==hwAttrs->enableInterrupt) 
3008                             {
3009                    object->xferInProgress = 1;
3010                 }
3012                 if(1 == hwAttrs->enableInterrupt) 
3013                             {
3015 #ifdef SEMAPHORE_EMUWAITS
3016                                while(dataBufferCopyComplete_emuwait);
3017 #endif
3018                                MMCSD_osalPendLock(object->dataBufferCopyComplete, SemaphoreP_WAIT_FOREVER);
3020                             }
3022                 /* Git response for command sent to MMC device */
3023                 HSMMCSDResponseGet(hwAttrs->baseAddr, transaction->response);
3024 #ifdef LOG_EN
3025                 MMCSD_drv_log4(Diags_USER1,
3026                         "MMCSD:(%p) Command Execution Failed\n", hwAttrs->baseAddr);
3027 #endif
3028             }
3031                     /* Release the lock for this particular MMCSD handle */
3032             MMCSD_osalPostLock(object->commandMutex);
3034             if(MMCSD_OK == ret)
3035             {
3036 #ifdef LOG_EN
3037             MMCSD_drv_log4(Diags_USER1,
3038                            "MMCSD:(%p) Pending on transferComplete semaphore\n",
3039                            hwAttrs->baseAddr);
3040 #endif
3042                 /*
3043                  * Wait for the transfer to complete here.
3044                  * It's OK to block from here because the MMCSD's Hwi will unblock
3045                  * upon errors
3046                  */
3047                             if(0U != hwAttrs->enableInterrupt)
3048                 {
3049                                MMCSD_osalPendLock(object->transferComplete, SemaphoreP_WAIT_FOREVER);
3050                 }
3051                 else
3052                 {
3053                     if( (object->manualTuning==FALSE) && ( (cmdObj.cmd.cmdId==MMCSD_CMD(19U)) || (cmdObj.cmd.cmdId==MMCSD_CMD(21U)) ) )
3054                                 {
3055                                        while ((0 == object->xferComp) && (0 == object->xferTimeout))
3056                        {
3057                            MMCSD_v2_xferStatusFxn_CMD19((uintptr_t) handle);
3058                        }
3060                                     }
3061                                 else
3062                                     {
3064                                       while (  (0 == object->cmdError) 
3065                                                     && (0 == object->xferComp) 
3066                                                     && (0 == object->xferTimeout) 
3067                                                         && (0 == object->dataCRCError) 
3068                                                         && (0 == object->dataEBError) )
3069                       {
3070                         MMCSD_v2_xferStatusFxn((uintptr_t) handle);
3071                       }
3073                                     }
3074                             }
3076             }
3077 #ifdef LOG_EN
3078                 MMCSD_drv_log4(Diags_USER1,
3079                            "MMCSD:(%p) Data transaction completed\n", hwAttrs->baseAddr);
3080 #endif
3082             if( object->manualTuning && object->cmdError && ( (cmdObj.cmd.cmdId==MMCSD_CMD(19U)) || (cmdObj.cmd.cmdId==MMCSD_CMD(21U)) ) )  
3083                     {                              
3084                /* 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 
3085                               tuning sequence */
3086                             HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_CMDLINE_RESET);
3087                 HSMMCSDLinesReset(hwAttrs->baseAddr,HS_MMCSD_DATALINE_RESET);
3088                 ret=MMCSD_ERR_TUNING_CMD_ERROR;
3090                     }
3091                     else 
3092                     { /* Data transfer successful */
3093                 if (1 == object->xferTimeout)
3094                 {
3095                    ret = MMCSD_ERR;
3096                    MMCSD_DEBUG_TRAP
3097                    object->xferTimeout = 0;
3098 #ifdef LOG_EN
3099                     MMCSD_drv_log4(Diags_USER1,
3100                             "MMCSD:(%p) Data Transfer Failed\n", hwAttrs->baseAddr);
3101 #endif
3102                 }
3104                 /* Data transfer fail */
3105                 if (1 == object->xferComp)
3106                 {
3107                    ret = MMCSD_OK;
3108                    object->xferComp = 0;
3109 #ifdef LOG_EN
3110                     MMCSD_drv_log4(Diags_USER1,
3111                             "MMCSD:(%p) Data Transfer Successful\n", hwAttrs->baseAddr);
3112 #endif
3113                 }
3114             }
3115             
3116                         /* Release the lock for this particular MMCSD handle */
3117                         MMCSD_osalPostLock(object->transferMutex);
3119             }     
3120         else
3121         { 
3122             /* Acquire the lock for this particular MMCSD handle */
3123             MMCSD_osalPendLock(object->commandMutex, SemaphoreP_WAIT_FOREVER);
3125             /* MMCSD_osalHardwareIntrDisable(hwAttrs->intNum); */
3127             object->cmdComp = 0;
3128             object->cmdTimeout = 0;
3129             object->cmdError = 0;
3130                         object->cmdCRCError = 0;
3131                         
3132             cmdObj.cmd.cmdId = transaction->cmd;
3133             cmdObj.cmdArg = transaction->arg;
3134             cmdObj.enableDma = 0;
3136             HSMMCSDIntrStatusEnable(hwAttrs->baseAddr,
3137                 (HS_MMCSD_INTR_CMDCOMP | HS_MMCSD_INTR_CMDTIMEOUT));
3139             if(0U != hwAttrs->enableInterrupt)
3140             {
3141                 HSMMCSDIntrEnable(hwAttrs->baseAddr,
3142                     (HS_MMCSD_INTR_CMDCOMP | HS_MMCSD_INTR_CMDTIMEOUT));
3143             }
3144             else
3145             {
3146                            HSMMCSDIntrEnable(hwAttrs->baseAddr, ~(HS_MMCSD_SIGEN_ALL));
3147                     }
3149                    /* Wait for command and data inhibit to go low before
3150                     * commands can be issued */
3151                     MMCSD_v2_waitCmdInhibit(hwAttrs);
3153             HSMMCSDCommandSend(hwAttrs->baseAddr,
3154                                HS_MMCSD_CMD(cmdObj.cmd.cmdId, cmdObj.cmd.cmdType, cmdObj.cmd.rspType, cmdObj.cmd.xferType),
3155                                cmdObj.cmdArg,
3156                                (TRUE == cmdObj.enableData)?MMC_CMD_DP_DATA:MMC_CMD_DP_NODATA,
3157                                cmdObj.numBlks,
3158                                cmdObj.enableDma,
3159                                MMC_CMD_ACEN_DISABLE);
3160 #ifdef LOG_EN
3161             MMCSD_drv_log4(Diags_USER1,
3162                        "MMCSD:(%p) Pending on commandComplete semaphore\n",
3163                        hwAttrs->baseAddr);
3164 #endif
3166             /*
3167              * Wait for the transfer to complete here.
3168              * It's OK to block from here because the MMCSD's Hwi will unblock
3169              * upon errors
3170              */
3171             if(0U != hwAttrs->enableInterrupt)
3172             {
3173                 MMCSD_osalPendLock(object->commandComplete, SemaphoreP_WAIT_FOREVER);
3174             }
3175             else
3176             {
3177                 while ((0 == object->cmdComp) && (0 == object->cmdTimeout))
3178                 {
3179                     MMCSD_v2_cmdStatusFxn((uintptr_t) handle);
3180                 }
3181             }
3183 #ifdef LOG_EN
3184             MMCSD_drv_log4(Diags_USER1,
3185                        "MMCSD:(%p) Command transaction completed\n", hwAttrs->baseAddr);
3186 #endif
3188             /* Command execution successful */
3189             if (1 == object->cmdComp)
3190             {
3191                 ret = MMCSD_OK;
3192                 object->cmdComp = 0;
3193 #ifdef LOG_EN
3194                 MMCSD_drv_log4(Diags_USER1,
3195                         "MMCSD:(%p) Command Execution Failed\n", hwAttrs->baseAddr);
3196 #endif
3197             }
3199             /* Command execution fail */
3200             if (1 == object->cmdTimeout)
3201             {
3202                 ret = MMCSD_ERR;
3203                 object->cmdTimeout = 0;
3204 #ifdef LOG_EN
3205                 MMCSD_drv_log4(Diags_USER1,
3206                         "MMCSD:(%p) Command Execution Failed\n", hwAttrs->baseAddr);
3207 #endif
3208             }
3210             /* Git response for command sent to MMC device */
3211             HSMMCSDResponseGet(hwAttrs->baseAddr, transaction->response);
3213             /* Release the lock for this particular MMCSD handle */
3214             MMCSD_osalPostLock(object->commandMutex);
3215         }
3216     
3217     }
3218     /* Return the transaction status */
3219     return (ret);
3222 /*
3223  *  ======== MMCSD_v2_control ========
3224  */
3225 /*!
3226  *  @brief      A function pointer to a driver specific implementation of
3227  *              MMCSD_control().
3228  */
3229 static MMCSD_Error MMCSD_v2_control(MMCSD_Handle handle, uint32_t cmd, const void *arg)
3231     MMCSD_Error        ret = MMCSD_ERR;
3233     /* Input parameter validation */
3234     if (handle != NULL)
3235     {
3236         switch (cmd)
3237         {
3238             case MMCSD_CMD_SETBUSWIDTH:
3239             {
3240                 ret = MMCSD_v2_setBusWidth(handle, (const uint32_t *)arg);
3241                 break;
3242             }
3244             case MMCSD_CMD_SETFREQUENCY:
3245             {
3246                 ret = MMCSD_v2_setBusFreq(handle, (const uint32_t *)arg);
3247                 break;
3248             }
3250             case MMCSD_CMD_GETBUSWIDTH:
3251             {
3252                 ret = MMCSD_v2_getBusWidth(handle, (uint32_t *)arg);
3253                 break;
3254             }
3256             case MMCSD_CMD_GETFREQUENCY:
3257             {
3258                 ret = MMCSD_v2_getBusFreq(handle, (uint32_t *)arg);
3259                 break;
3260             }
3262             case MMCSD_CMD_GETMEDIAPARAMS:
3263             {
3264                 ret = MMCSD_v2_getMediaParams(handle, (MMCSD_mediaParams *)arg);
3265                 break;
3266             }
3268             case MMCSD_CMD_ENABLEBOOTPARTITION:
3269             {
3270                 ret = MMCSD_v2_enableBootPartition(handle, (const uint8_t *)arg);
3271                 break;
3272             }
3274             default:
3275             ret = MMCSD_UNDEFINEDCMD;
3276             break;
3277         }
3278     }
3279     return ret;
3282 /*
3283  *  ======== MMCSD_v2_setBusWidth ========
3284  */
3285 /*!
3286  *  @brief      A function pointer to a driver specific implementation of
3287  *              MMCSD_control().
3288  */
3289 static MMCSD_Error MMCSD_v2_setBusWidth(MMCSD_Handle handle, const uint32_t *busWidth)
3291     MMCSD_Error                 ret = MMCSD_ERR;
3292     MMCSD_v2_Object            *object = NULL;
3293     MMCSD_v2_HwAttrs const     *hwAttrs = NULL;
3294     MMCSD_v2_Transaction        transaction;
3296     /* Input parameter validation */
3297     if ((handle != NULL) && (busWidth != NULL))
3298     {
3299         /* Get the pointer to the object and hwAttrs */
3300         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3301         hwAttrs = (MMCSD_v2_HwAttrs const *)((MMCSD_Config *) handle)->hwAttrs;
3303         if (MMCSD_CARD_SD == object->cardType)
3304         {
3305             if ((MMCSD_BUS_WIDTH_4BIT == *busWidth) || (MMCSD_BUS_WIDTH_1BIT == *busWidth))
3306             {
3307                 ret = MMCSD_OK;
3308             }
3310             if(MMCSD_OK == ret)
3311             {
3312                 /* APP cmd should be preceeded by a CMD55 */
3313                 transaction.cmd = MMCSD_CMD(55U);
3314                 transaction.flags = 0U;
3315                 transaction.arg = object->rca << 16U;
3316                 ret = MMCSD_v2_transfer(handle, &transaction);
3317             }
3319             if(MMCSD_OK == ret)
3320             {
3321                 transaction.cmd = MMCSD_CMD(6U);
3322                 transaction.arg = MMCSD_BUS_WIDTH_1BIT;
3323                 transaction.flags = 0U;
3325                 if (hwAttrs->supportedBusWidth & MMCSD_BUS_WIDTH_4BIT)
3326                 {
3327                     if (MMCSD_BUS_WIDTH_4BIT == *busWidth)
3328                     {
3329                         transaction.arg = MMCSD_BUS_WIDTH_4BIT;
3330                     }
3331                 }
3333                 transaction.arg = transaction.arg >> 1U;
3334                 ret = MMCSD_v2_transfer(handle, &transaction);
3336                 if (MMCSD_OK == ret)
3337                 {
3338                     if (MMCSD_BUS_WIDTH_4BIT == *busWidth)
3339                     {
3340                         object->busWidth = MMCSD_BUS_WIDTH_4BIT;
3341                         HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_4BIT);
3342                     }
3343                     else
3344                     {
3345                         object->busWidth = MMCSD_BUS_WIDTH_1BIT;
3346                         HSMMCSDBusWidthSet(hwAttrs->baseAddr, HS_MMCSD_BUS_WIDTH_1BIT);
3347                     }
3348                 }
3349             }
3350         }
3351     }
3352     return(ret);
3355 /*
3356  *  ======== MMCSD_v2_setBusFreq ========
3357  */
3358 /*!
3359  *  @brief      A function pointer to a driver specific implementation of
3360  *              MMCSD_control().
3361  */
3362 static MMCSD_Error MMCSD_v2_setBusFreq(MMCSD_Handle handle, const uint32_t *busFreq)
3364     MMCSD_Error                 ret = MMCSD_ERR;
3365     MMCSD_v2_Object            *object = NULL;
3366         uint32_t cmd16_grp1_fn;
3368     /* Input parameter validation */
3369     if ((handle != NULL) && (busFreq != NULL))
3370     {
3371         /* Get the pointer to the object and hwAttrs */
3372         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3374         if (MMCSD_CARD_SD == object->cardType)
3375         {
3376             if ((MMCSD_TRANSPEED_25MBPS == *busFreq) ||
3377                 (MMCSD_TRANSPEED_50MBPS == *busFreq) ||
3378                 (MMCSD_TRANSPEED_SDR50  == *busFreq) ||
3379                 (MMCSD_TRANSPEED_DDR50  == *busFreq) ||
3380                 (MMCSD_TRANSPEED_SDR104 == *busFreq) )
3381             {
3382                 ret = MMCSD_OK;
3383             }
3385             if(object->tranSpeed == *busFreq) {
3386                  return MMCSD_OK;
3387             }
3389             switch(*busFreq)
3390             {
3391                case MMCSD_TRANSPEED_SDR104:
3392                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_SDR104;
3393                    break;
3394                case MMCSD_TRANSPEED_SDR50:
3395                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_SDR50;
3396                    break;
3397                case MMCSD_TRANSPEED_DDR50:
3398                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_DDR50;
3399                    break;
3400                case MMCSD_TRANSPEED_HS:
3401                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_HS;
3402                    break;
3403                case MMCSD_TRANSPEED_DEFAULT:
3404                default:
3405                    cmd16_grp1_fn=MMCSD_CMD6_GRP1_DEFAULT;/*25MHz*/
3406                    break;
3407             }
3409             if(ret==MMCSD_OK){
3410               ret=MMCSD_switch_card_speed(handle,cmd16_grp1_fn);
3411             }
3412         }
3413     }
3414     return(ret);
3417 /*
3418  *  ======== MMCSD_v2_getBusWidth ========
3419  */
3420 /*!
3421  *  @brief      A function pointer to a driver specific implementation of
3422  *              MMCSD_control().
3423  */
3424 static MMCSD_Error MMCSD_v2_getBusWidth(MMCSD_Handle handle, uint32_t *busWidth)
3426     MMCSD_Error                 ret = MMCSD_ERR;
3427     MMCSD_v2_Object            *object = NULL;
3429     /* Input parameter validation */
3430     if ((handle != NULL) && (busWidth != NULL))
3431     {
3432         /* Get the pointer to the object and hwAttrs */
3433         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3435         if (MMCSD_CARD_SD == object->cardType)
3436         {
3437             *busWidth = object->busWidth;
3438             ret = MMCSD_OK;
3439         }
3440     }
3442     return(ret);
3445 /*
3446  *  ======== MMCSD_v2_getBusFreq ========
3447  */
3448 /*!
3449  *  @brief      A function pointer to a driver specific implementation of
3450  *              MMCSD_control().
3451  */
3452 static MMCSD_Error MMCSD_v2_getBusFreq(MMCSD_Handle handle, uint32_t *busFreq)
3454     MMCSD_Error                 ret = MMCSD_ERR;
3455     MMCSD_v2_Object            *object = NULL;
3457     /* Input parameter validation */
3458     if ((handle != NULL) && (busFreq != NULL))
3459     {
3460         /* Get the pointer to the object and hwAttrs */
3461         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3463         if (MMCSD_CARD_SD == object->cardType)
3464         {
3465             *busFreq = object->tranSpeed;
3466             ret = MMCSD_OK;
3467         }
3468     }
3469     return(ret);
3473 /*
3474  *  ======== MMCSD_v2_getMediaParams ========
3475  */
3476 /*!
3477  *  @brief      This function returns the media (SD/eMMC/MMC)'s parameters
3478  *              such as size, blockCount and blockSize  .
3479  */
3480 static MMCSD_Error MMCSD_v2_getMediaParams(MMCSD_Handle handle, MMCSD_mediaParams *params)
3482     MMCSD_Error                 ret = MMCSD_ERR;
3483     MMCSD_v2_Object            *object = NULL;
3485     /* Input parameter validation */
3486     if ((handle != NULL) && (params != NULL))
3487     {
3488         /* Get the pointer to the object and hwAttrs */
3489         object = (MMCSD_v2_Object *)((MMCSD_Config *) handle)->object;
3491         params->blockSize = object->blockSize;
3492         params->blockCount = object->blockCount;
3493         params->size = object->size;
3495         ret = MMCSD_OK;
3496     }
3497     return(ret);
3500 /*
3501  *  ======== MMCSD_v2_hwiFxn ========
3502  *  Hwi interrupt handler to service the MMCSD peripheral
3503  *
3504  *  The handler is a generic handler for a MMCSD object.
3505  */
3506 void MMCSD_v2_hwiFxn(uintptr_t arg)
3508     int32_t                 err = STW_SOK;
3509     uint32_t                errStatus;
3510     uint32_t                dataLen = 0U;
3511     uint32_t                status = 0U;
3512     volatile uint32_t       intrMask = 0U;
3513     uint32_t                temp = 0U;
3514     volatile uint32_t       cnt = 0U;
3515     MMCSD_v2_Object        *object = NULL;
3516     MMCSD_v2_HwAttrs const *hwAttrs = NULL;
3517     uint32_t                blocks_remaining,offset;
3518     uint32_t                retFlag = FALSE;
3520     /* Input parameter validation */
3521     if ((void *)arg == NULL)
3522     {
3523         retFlag = TRUE;
3524     }
3525     else
3526     {
3527         /* Get the pointer to the object and hwAttrs */
3528         object = (MMCSD_v2_Object*)(((MMCSD_Config *)arg)->object);
3529         hwAttrs = (MMCSD_v2_HwAttrs const *)(((MMCSD_Config *)arg)->hwAttrs);
3531         // status = HSMMCSDIntrStatus(hwAttrs->baseAddr);
3532         err = HSMMCSDIntrStatusGet(hwAttrs->baseAddr, HS_MMCSD_INTR_ALL, &status);
3533         if(err != STW_SOK)
3534         {
3535             retFlag = TRUE;
3536         }
3537         else
3538         {
3539             errStatus = status & 0xFFFF0000U;
3540             intrMask = HSMMCSDIntrGet(hwAttrs->baseAddr);
3541         }
3542     }
3544     /* Command execution is complete */
3545     if ((retFlag == FALSE) &&
3546         ((status & HS_MMCSD_INTR_CMDCOMP) != 0U))
3547     {
3548         HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3549                                    HS_MMCSD_INTR_CMDCOMP);
3550         object->cmdComp = 1;
3552                 /* Indicate command complete */
3553         if (intrMask & HS_MMCSD_SIGEN_CMDCOMP)
3554         {
3555                         MMCSD_osalPostLock(object->commandComplete);
3556         }
3558     }    /* Error occurred in execution of command */
3560     if ((retFlag == FALSE) && (errStatus != 0U))
3561     {
3564         if (errStatus & HS_MMCSD_INTR_CMDTIMEOUT)
3565         {
3566             HSMMCSDIntrStatusClear(hwAttrs->baseAddr,
3567                                        HS_MMCSD_INTR_CMDTIMEOUT);
3568             object->cmdTimeout = 1;
3570                         /* Indicate command complete */
3571             if (intrMask & HS_MMCSD_SIGEN_CMDTIMEOUT)
3572             {
3573                 MMCSD_osalPostLock(object->commandComplete);
3574             }
3575         }
3577     }
3579     /* Read data received from card */
3580     if ((retFlag == FALSE)                           &&
3581         ((status & HS_MMCSD_INTR_BUFRDRDY) != 0U)    &&
3582         ((intrMask & HS_MMCSD_INTR_BUFRDRDY) != 0U))
3583     {