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