6141e82af3cd69d8eca61660b39ad1afcdf9b38a
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)
421 {
422 return ( (val & ~mask) | (field << shift) );
423 }
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 )
488 {
489 desc->params = params;
490 desc->addrl = address & 0xffffffffu;
491 desc->addrh = (address >> 32) & 0xffffu;
492 }
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)
499 {
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;
507 }
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)
512 {
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;
518 }
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)
522 {
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;
529 }
530 /* Waits for data inhibit to go low */
531 uint32_t MMCSD_v2_getCmdInhibit(MMCSD_v2_HwAttrs *hwAttrs)
532 {
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;
537 }
538 /* Waits for data inhibit to go low */
539 uint32_t MMCSD_v2_getDatInhibit(MMCSD_v2_HwAttrs *hwAttrs)
540 {
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;
545 }
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)
549 {
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);
581 }
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)
585 {
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);
600 }
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)
610 {
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 }
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);
699 }
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)
708 {
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 }
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 }
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);
796 }
798 /*
799 * ======== MMCSD_v2_close ========
800 */
801 static MMCSD_Error MMCSD_v2_close(MMCSD_Handle handle)
802 {
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);
868 }
870 /*
871 * ======== MMCSD_v2_init ========
872 */
873 static MMCSD_Error MMCSD_v2_init(MMCSD_Handle handle)
874 {
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 }
888 return (ret);
889 }
891 /*
892 * ======== MMCSD_enableBootPartitionAccess ========
893 */
894 static MMCSD_Error MMCSD_v2_enableBootPartition(MMCSD_Handle handle, const uint8_t *partition)
895 {
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);
937 }
939 /*
940 * ======== MMCSD_v2_open ========
941 */
942 static MMCSD_Error MMCSD_v2_open(MMCSD_Handle handle, MMCSD_Params params)
943 {
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);
1071 }
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)
1081 {
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);
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 }
1377 if(ret!=MMCSD_OK) {
1378 ret=MMCSD_ERR_1P8V_SWITCH_MMCIO_SWITCH_FAILURE;
1379 break;
1380 }
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 }
1442 HSMMCSDSwitchSignalVoltage (hwAttrs->baseAddr, MMC_AC12_V1V8_SIGEN_3V3);
1443 /* Wait for 5 ms */
1444 Osal_delay(5);
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);
1713 }
1714 /***********************************************************************/
1715 static MMCSD_Error MMCSD_switch_card_speed(MMCSD_Handle handle,uint32_t cmd16_grp1_fn)
1716 {
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 }
1867 } else { MMCSD_DEBUG_TRAP }
1868 }
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 */
1884 retVal = MMCSD_socPhyConfigure((MMCSD_v2_HwAttrs const *)hwAttrs,phy_mode, phy_freq, phy_driverType);
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 }
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;
1925 }
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);
1971 }
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);
2018 }
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)
2023 {
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);
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 }
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 }
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;
2203 MMCSD_socPhyConfigure(hwAttrs,phyMode, 50000000, phyDriverType);
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;
2253 MMCSD_socPhyConfigure(hwAttrs,phyMode, 200000000, phyDriverType);
2256 if(ret!=STW_SOK) {
2257 return MMCSD_ERR;
2258 }
2259 Osal_delay(50);
2260 }
2262 return (ret);
2264 }
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;
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 }
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;
2321 }
2323 /*
2324 * ======== MMCSD_open ========
2325 */
2326 static MMCSD_Error MMCSD_v2_initEmmc(MMCSD_Handle handle)
2327 {
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;
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);
2716 }
2717 /*
2718 * ======== MMCSD_v2_transfer ========
2719 */
2720 static MMCSD_Error MMCSD_v2_transfer(MMCSD_Handle handle,
2721 MMCSD_v2_Transaction *transaction)
2722 {
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;
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;
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 */
2913 MMCSD_v2_waitCmdInhibit(hwAttrs);
2914 MMCSD_v2_waitDatInhibit(hwAttrs);
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 }
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 }
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 }
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;
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 }
3217 }
3218 /* Return the transaction status */
3219 return (ret);
3220 }
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)
3230 {
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;
3280 }
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)
3290 {
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);
3353 }
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)
3363 {
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);
3415 }
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)
3425 {
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);
3443 }
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)
3453 {
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);
3470 }
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)
3481 {
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);
3498 }
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)
3507 {
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 {