]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - psdk_cust/pdk_k2g_1_0_1_0_eng/packages/ti/platform_org/evmk2g/platform_lib/src/evmc66x_mmchs.c
Remove SPI LLD build artifacts
[processor-sdk/performance-audio-sr.git] / psdk_cust / pdk_k2g_1_0_1_0_eng / packages / ti / platform_org / evmk2g / platform_lib / src / evmc66x_mmchs.c
1 /*
2  * Copyright (c) 2015, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
34 /**
35 *
36 *  \file  evmc66x_mmchs.c
37 *
38 *  \brief This file contains C66x mmchs specific functions.
39 *
40 ******************************************************************************/
42 #include "platform_internal.h"
44 #if (PLATFORM_MMCHS_IN)
46 /** ===========================================================================
47    *   @n@b mmchsDelay
48    *
49    *   @b Description
50    *   @n This function creates a delay of given value in usecs .
51    *
52    *   @b Arguments
53    *   @verbatim
54               usecs - usecs to give the delay
55        @endverbatim
56    *
57    *   <b> Return Value </b>
58    *   @n  None
59    *
60    *   @b Modifies
61    *   @n  None
62    *
63    *  ==========================================================================
64    */
65 void mmchsDelay (uint32_t usecs)
66 {
67     platform_delay(usecs);
68 }
70  /** ===========================================================================
71   *   @n@b mmchsGetRegBaseaddr
72   *
73   *   @b Description
74   *   @n This function is used to get the base address of given MMC Instance.
75   *
76   *   @b Arguments
77   *   @verbatim
78              mmcInstance       Instance of MMC: MMC0 - SD Card,
79              MMC1 - eMMC/SDIO Card
81      mmcInstance can take the values \n
82         CSL_MMCSD_0 - SD Card \n
83         CSL_MMCSD_1 - eMMC/WLAN \n
84       @endverbatim
85   *
86   *   <b> Return Value </b>  CSL_MmchsRegs*
87   *   @li           The base address of the mmcInstance on success
88   *  @li            NULL if type is not found
89   *
90   *   @b Modifies
91   *   @n  None
92   *
93   *  ===========================================================================
94   */
95 CSL_MmchsRegs* mmchsGetRegBaseaddr(uint8_t mmcInstance)
96 {
97     CSL_MmchsRegs    *addr;
99     switch(mmcInstance)
100     {
101         case CSL_MMCSD_0:
102             addr = (CSL_MmchsRegs *)CSL_MMCSD_0_S_REGS;
103             break;
105         case CSL_MMCSD_1:
106             addr = (CSL_MmchsRegs *)CSL_MMCSD_1_S_REGS;
107             break;
109         default :
110             addr = NULL;
111             break;
112     }
114     return addr;
117  /** ===========================================================================
118    *   @n@b mmchsEnableClock
119    *
120    *   @b Description
121    *   @n This function is used to enable the clock for the given frequency
122    *
123    *   @b Arguments
124    *   @verbatim
125               mmcHsReg - handle to the mmcReg
126               clock - Input frequency
129       clock can take the values \n
130             MMCHS_CLK_INITSEQ
131             MMCHS_CLK_400KHZ
132             MMCHS_CLK_12MHZ
133             MMCHS_CLK_24MHZ
134             MMCHS_CLK_26MHZ
135             MMCHS_CLK_48MHZ
136             MMCHS_CLK_52MHZ
137        @endverbatim
138    *
139    *   <b> Return Value </b>
140    *   @li        MMCHS_RET_INVALID_PARAM - If input parameter is invalid
141    *  @li        MMCHS_RET_OK - on Success
142    *
143    *   @b Modifies
144    *   @n  None
145    *
146    *  ==========================================================================
147    */
148 MMC_RET mmchsEnableClock(CSL_MmchsRegs *mmcHsReg, uint32_t clock)
150     uint32_t val;
151     uint32_t regVal;
153     if(mmcHsReg == NULL)
154     {
155         return MMCHS_RET_INVALID_PARAM;
156     }
158     /* disables, cen and set data timeout value */
159     CSL_FINS(mmcHsReg->SYSCTL, MMCHS_SYSCTL_CEN, DISABLE);
160     CSL_FINS(mmcHsReg->SYSCTL, MMCHS_SYSCTL_DTO, MMC_DTO_MAX);
162     switch (clock) {
163     case HSMMCSD_INIT_FREQ:
164         val = (MMCHS_SDMMC_REF_CLK * 1000 / (400));
165         CSL_FINS(mmcHsReg->SYSCTL, MMCHS_SYSCTL_DTO, 0x0);
166         break;
168     case MMCHS_CLK_12MHZ:
169         val = (MMCHS_SDMMC_REF_CLK * 1000 / (12000));
170         break;
172     case MMCHS_CLK_24MHZ:
173     case HSMMCSD_TRAN_SPEED_24M_CLK:
174         val = (MMCHS_SDMMC_REF_CLK * 1000 / (24000));
175         break;
177     case MMCHS_CLK_26MHZ:
178     case HSMMCSD_TRAN_SPEED_26M_CLK:
179             val = (MMCHS_SDMMC_REF_CLK * 1000 / (26000));
180             val = val+1;
181             break;
182     case MMCHS_CLK_48MHZ:
183     case HSMMCSD_TRAN_SPEED_48M_CLK:
184             val = (MMCHS_SDMMC_REF_CLK * 1000 / (48000));
185             val = val+1;
186         break;
188     case MMCHS_CLK_50MHZ:
189     case HSMMCSD_TRAN_SPEED_50M_CLK:
190             val = (MMCHS_SDMMC_REF_CLK * 1000 / (50000));
191             val = val+1;
192             break;
194     case MMCHS_CLK_52MHZ:
195     case HSMMCSD_TRAN_SPEED_52M_CLK:
196             val = (MMCHS_SDMMC_REF_CLK * 1000 / (52000));
197             val = val+1;
199             break;
201     default:
202             val = (MMCHS_SDMMC_REF_CLK * 1000 / (clock/1000));
203             val = 0x04;
204     }
206     IFPRINT(platform_write ("Setting Clock speed to %d\n",clock));
207     /* Select clock frequency */
209     CSL_FINS(mmcHsReg->SYSCTL, MMCHS_SYSCTL_CLKD, RESETVAL);
210     mmcHsReg->SYSCTL |= (val << 6);
212     /* enable clock */
213     CSL_FINS(mmcHsReg->SYSCTL, MMCHS_SYSCTL_ICE, OSCILLATE);
214     mmchsDelay(10);
216     /* Wait until stable? */
217     do
218     {
219         regVal = CSL_FEXT(mmcHsReg->SYSCTL, MMCHS_SYSCTL_ICS);
220     }while (regVal == 0);
222     /* Enable CEN */
223     CSL_FINS(mmcHsReg->SYSCTL, MMCHS_SYSCTL_CEN, ENABLE);
225     mmchsDelay(1000);
227     return MMCHS_RET_OK;
230 /** ===========================================================================
231    *   @n@b mmchsReset
232    *
233    *   @b Description
234    *   @n This function Resets the mmc module and the controller.
235    *
236    *   @b Arguments
237    *   @verbatim
238               mmchsCtrlInfo - handle to the Controller
239        @endverbatim
240    *
241    *   <b> Return Value </b>
242    *   @li        MMCHS_RET_INVALID_PARAM - If input parameter is invalid
243    *   @li        MMCHS_RET_IDLE_TIMEOUT - If reset fails and times out.
244    *   @li        MMCHS_RET_OK - on Success
245    *
246    *   @b Modifies
247    *   @n  None
248    *
249    *  ==========================================================================
250    */
251 MMC_RET mmchsReset(mmchsControllerInfo *mmchsCtrlInfo)
253     uint32_t    pollingStatus;
254     volatile uint32_t timeout = 0xFFFF;
255     CSL_MmchsRegs *mmcHsReg;
257     if ((mmchsCtrlInfo == NULL) || (mmchsCtrlInfo->mmcHsReg == NULL))
258     {
259         return MMCHS_RET_INVALID_PARAM;
260     }
262     mmcHsReg = mmchsCtrlInfo->mmcHsReg;
264     /* software reset */
265     mmcHsReg->SYSCONFIG |= CSL_MMCHS_SYSCONFIG_SOFTRESET_MASK;
267     /* Check if reset done */
268     do
269     {
270         pollingStatus = CSL_FEXT(mmcHsReg->SYSSTATUS, \
271                                     MMCHS_SYSSTATUS_RESETDONE);
273         if (pollingStatus == CSL_MMCHS_SYSSTATUS_RESETDONE_DONE)
274         {
275             break;
276         }
277     } while (timeout--);
279     if (0 == timeout)
280     {
281         return MMCHS_RET_IDLE_TIMEOUT;
282     }
283     else
284     {
285         /* Reset is completed; Now reset the host controller */
286         CSL_FINS(mmcHsReg->SYSCTL,MMCHS_SYSCTL_SRA, RESET);
287         do {
288             if (CSL_FEXT(mmcHsReg->SYSCTL, MMCHS_SYSCTL_SRA))
289                 break;
290         } while (timeout--);
292         if (0 == timeout)
293         {
294             return MMCHS_RET_IDLE_TIMEOUT;
295         }
296     }
297     return MMCHS_RET_OK;
300 /** ===========================================================================
301    *   @n@b mmchs_send_init_stream
302    *
303    *   @b Description
304    *   @n This function sends the INIT stream to the card
305    *
306    *   @b Arguments
307    *   @verbatim
308               mmcHsReg - handle to the mmcReg
309        @endverbatim
310    *
311    *   <b> Return Value </b>
312    *   @li        MMCHS_RET_INVALID_PARAM - If input parameter is invalid
313    *   @li         MMCHS_RET_OK - on Success
314    *
315    *   @b Modifies
316    *   @n  None
317    *
318    *  ==========================================================================
319    */
320 static MMC_RET mmchs_send_init_stream(CSL_MmchsRegs *mmcHsReg)
322     uint32_t status;
323     uint32_t retry;
325     if (mmcHsReg == NULL)
326     {
327         return MMCHS_RET_INVALID_PARAM;
328     }
330     /* Enable the command completion status to be set */
331     CSL_FINS(mmcHsReg->IE, MMCHS_IE_CC_ENABLE, ENABLE);
333     /* Initiate the INIT command */
334     CSL_FINS(mmcHsReg->CON, MMCHS_CON_INIT, 1);
335     mmcHsReg->CMD = 0;
336     mmchsDelay(1);
338     retry = 0xFFFF;
339     do {
340         status = CSL_FEXT(mmcHsReg->STAT, MMCHS_STAT_CC);
341         if ( STAT_CC == status)
342         {
343             mmcHsReg->STAT |= CSL_MMCHS_STAT_CC_MASK;
344             break;
345         }
346     } while (retry--);
348     if (retry == 0)
349     {
350         return MMCHS_RET_IDLE_TIMEOUT;
351     }
353     CSL_FINS(mmcHsReg->CON, MMCHS_CON_INIT, 0);
355     /* Clear all status */
356     mmcHsReg->STAT = 0xFFFFFFFF;
358     return MMCHS_RET_OK;
361 /** ===========================================================================
362    *   @n@b mmchs_bus_power
363    *
364    *   @b Description
365    *   @n This function turn MMC/SD bus power on / off
366    *
367    *   @b Arguments
368    *   @verbatim
369               mmcHsReg - handle to the mmcReg
370               pwr           power on / off setting
372    * pwr can take the values \n
373    *     HS_MMCSD_BUS_POWER_ON \n
374    *     HS_MMCSD_BUS_POWER_OFF \n
375        @endverbatim
376    *
377    *   <b> Return Value </b>
378    *   @li        MMCHS_RET_INVALID_PARAM - If input parameter is invalid
379    *   @li         MMCHS_RET_OK - on Success
380    *
381    *   @b Modifies
382    *   @n  None
383    *
384    */
385 static MMC_RET mmchs_bus_power(CSL_MmchsRegs *mmcHsReg, uint8_t pwr)
387     volatile uint32_t timeout = 0xFFFFF;
389     if ((mmcHsReg == NULL) && (pwr > 1))
390     {
391         return MMCHS_RET_INVALID_PARAM;
392     }
394     CSL_FINS(mmcHsReg->HCTL, MMCHS_HCTL_SDBP, pwr);
396     do {
397         if (pwr == CSL_FEXT(mmcHsReg->HCTL, MMCHS_HCTL_SDBP))
398         {
399             break;
400         }
401     } while(timeout--);
403     if (timeout == 0)
404     {
405         return MMCHS_RET_IDLE_TIMEOUT;
406     }
407     else
408     {
409         return MMCHS_RET_OK;
410     }
413 /** ===========================================================================
414    *   @n@b mmchsControllerInit
415    *
416    *   @b Description
417    *   @n This function configures the mmc module and the controller.
418    *
419    *   @b Arguments
420    *   @verbatim
421               mmchsCtrlInfo - handle to the Controller
422        @endverbatim
423    *
424    *   <b> Return Value </b>
425    *   @li        MMCHS_RET_INVALID_PARAM - If input parameter is invalid
426    *   @li         MMCHS_RET_OK - on Success
427    *
428    *   @b Modifies
429    *   @n  None
430    *
431    *  ==========================================================================
432    */
433 MMC_RET mmchsControllerInit(mmchsControllerInfo *mmchsCtrlInfo)
435     uint32_t status;
436     CSL_MmchsRegs *mmcHsReg;
438     if ((mmchsCtrlInfo == NULL) || (mmchsCtrlInfo->mmcHsReg == NULL))
439     {
440         return MMCHS_RET_INVALID_PARAM;
441     }
443     mmcHsReg = mmchsCtrlInfo->mmcHsReg;
445     /* Initially configure the host bus width with the possible bus width.
446        Then while setting the bus width, based on the card capability set
447        the bus width according to the CSR */
448     mmchsCtrlInfo->busWidth = (SD_BUS_WIDTH_1BIT | SD_BUS_WIDTH_4BIT);
449     mmchsCtrlInfo->highSpeed = 1;
450     mmchsCtrlInfo->ocr = (SD_OCR_VDD_3P0_3P1 | SD_OCR_VDD_3P1_3P2);
451     mmchsCtrlInfo->opClk = HSMMCSD_INIT_FREQ;
453     /* Set supported voltage list - 1.8V and 3.0 V*/
454     mmcHsReg->CAPA &= ~(CSL_MMCHS_CAPA_VS18_MASK | \
455                               CSL_MMCHS_CAPA_VS33_MASK | \
456                               CSL_MMCHS_CAPA_VS30_MASK);
458     mmcHsReg->CAPA |= (CSL_MMCHS_CAPA_VS18_MASK | \
459                              CSL_MMCHS_CAPA_VS30_MASK);
461     /* Set to autoidle enable */
463     mmcHsReg->SYSCONFIG &= ~(CSL_MMCHS_SYSCONFIG_CLOCKACTIVITY_MASK | \
464                                    CSL_MMCHS_SYSCONFIG_STANDBYMODE_MASK | \
465                                    CSL_MMCHS_SYSCONFIG_SIDLEMODE_MASK | \
466                                    CSL_MMCHS_SYSCONFIG_ENAWAKEUP_MASK | \
467                                    CSL_MMCHS_SYSCONFIG_AUTOIDLE_MASK);
468     mmcHsReg->SYSCONFIG |=  CSL_MMCHS_SYSCONFIG_AUTOIDLE_MASK;
470     /* 1 Bit Mode, 3V Bus Voltage (SVDS) and Bus Pwr Off */
471     CSL_FINS(mmcHsReg->CON, MMCHS_CON_DW8, BITMODE1_4);
472     CSL_FINS(mmcHsReg->HCTL, MMCHS_HCTL_DTW, BITMODE_1);
474     /* Set block len to 512 */
475     mmcHsReg->BLK = MMCHS_BLK_LEN;
477     /* Set the bus voltage to 3.0 V*/
478     CSL_FINS(mmcHsReg->HCTL, MMCHS_HCTL_SDVS, V3_0);
480     /* Switch on Bus Power */
481     status = mmchs_bus_power(mmcHsReg, HS_MMCSD_BUS_POWER_ON);
483     if (status != 0)
484         return status;
485     status = mmchsEnableClock(mmcHsReg, HSMMCSD_INIT_FREQ);
487     if (status != 0)
488             return status;
490     /* Send Initialisation Sequence for 80 clock cycles */
491     status = mmchs_send_init_stream(mmcHsReg);
492     if (status != 0)
493             return status;
494     return MMCHS_RET_OK;
497 /** ===========================================================================
498    *   @n@b mmchsBusWidthConfig
499    *
500    *   @b Description
501    *   @n This function configures the mmc bus width on the host controller
502    *
503    *   @b Arguments
504    *   @verbatim
505    *      mmcHsReg - handle to the mmcReg
506           buswidth   SD/MMC bus width.\n
507        @endverbatim
508    *
509    *   <b> Return Value </b>
510    *   @li        MMCHS_RET_INVALID_PARAM - If input parameter is invalid
511    *   @li         MMCHS_RET_OK - on Success
512    *
513    *   @b Modifies
514    *   @n  None
515    *
516    *  ==========================================================================
517    */
518 MMC_RET mmchsBusWidthConfig(CSL_MmchsRegs *mmcHsReg, uint8_t busWidth)
520     if ((mmcHsReg == NULL) || (busWidth > SD_BUS_WIDTH_8BIT))
521     {
522         return MMCHS_RET_INVALID_PARAM;
523     }
525     IFPRINT(platform_write ("Setting bus width to %d\n",busWidth));
526     switch(busWidth)
527     {
528     case SD_BUS_WIDTH_4BIT:
529         CSL_FINS(mmcHsReg->CON, MMCHS_CON_DW8, BITMODE1_4);
530         CSL_FINS(mmcHsReg->HCTL, MMCHS_HCTL_DTW, BITMODE_4);
531         break;
533     case SD_BUS_WIDTH_8BIT:
534         CSL_FINS(mmcHsReg->CON, MMCHS_CON_DW8, BITMODE_8);
535         break;
537     default:  // Default will be set to 1-bit mode
538         CSL_FINS(mmcHsReg->CON, MMCHS_CON_DW8, BITMODE1_4);
539         CSL_FINS(mmcHsReg->HCTL, MMCHS_HCTL_DTW, BITMODE_1);
540         break;
541     }
543     return MMCHS_RET_OK;
546 /** ===========================================================================
547    *   @n@b mmchsEnableIntr
548    *
549    *   @b Description
550    *   @nThis function enables the controller events to generate an interrupt
551         request
552    *
553    *   @b Arguments
554    *   @verbatim
555               mmcHsReg - handle to the mmcReg
556               flags - flag to enable the Interrupt
557        @endverbatim
558    *
559    *   <b> Return Value </b>
560    *   @li        MMCHS_RET_INVALID_PARAM - If input parameter is invalid
561    *   @li         MMCHS_RET_OK - on Success
562    *
563    *   @b Modifies
564    *   @n  None
565    *
566    *  ==========================================================================
567    */
568 MMC_RET mmchsEnableIntr(CSL_MmchsRegs *mmcHsReg, uint32_t flags)
570     if(mmcHsReg == NULL)
571     {
572         return MMCHS_RET_INVALID_PARAM;
573     }
575     mmcHsReg->ISE |= flags;
576     mmcHsReg->IE |= flags;
578     return MMCHS_RET_OK;
581 /** ===========================================================================
582    *   @n@b mmchsSetBlockCount
583    *
584    *   @b Description
585    *   @n This function sets the block count for multi block data transfer
586    *
587    *   @b Arguments
588    *   @verbatim
589               mmcHsReg - handle to the mmcReg
590               nBlks    - number of Blocks
591        @endverbatim
592    *
593    *   <b> Return Value </b>
594    *   @li        MMCHS_RET_OK - on Success
595    *
596    *   @b Modifies
597    *   @n  None
598    *
599    *  ==========================================================================
600    */
601 MMC_RET mmchsSetBlockCount(CSL_MmchsRegs *mmcHsReg, uint32_t nBlks)
603     uint32_t blkLen = 0;
604     if (nBlks == 0) return MMCHS_RET_OK;
606     blkLen |= nBlks << MMCHS_BLK_NBLK_SHIFT;
607     mmcHsReg->BLK |= blkLen;
608     return MMCHS_RET_OK;
611 /** ===========================================================================
612    *   @n@b mmchsSendCmd
613    *
614    *   @b Description
615    *   @n This function sends the command to the device over the data bus.
616    *
617    *   @b Arguments
618    *   @verbatim
619               mmcHsReg - handle to the mmcReg
620               cmd      - command to send to the controller
621               arg      - argument
622               blkSize  - block size
623               nBlks    - number of Blocks
624        @endverbatim
625    *
626    *   <b> Return Value </b>
627    *   @li        MMCHS_RET_INVALID_PARAM - If input parameter is invalid
628    *   @li        MMCHS_RET_OK - on Success
629    *
630    *   @b Modifies
631    *   @n  None
632    *
633    *  ==========================================================================
634    */
635 MMC_RET mmchsSendCmd(CSL_MmchsRegs *mmcHsReg, uint32_t cmd, uint32_t arg,
636                      uint32_t blkSize)
638     uint32_t regVal;
640     if(mmcHsReg == NULL)
641     {
642         return MMCHS_RET_INVALID_PARAM;
643     }
644     /* Software reset cmd and dat lines */
645     CSL_FINS(mmcHsReg->SYSCTL, MMCHS_SYSCTL_SRD, RESET);
646     CSL_FINS(mmcHsReg->SYSCTL, MMCHS_SYSCTL_SRC, RESET);
648     do
649     {
650         regVal = CSL_FEXTR(mmcHsReg->SYSCTL, \
651                             CSL_MMCHS_SYSCTL_SRD_SHIFT, \
652                             CSL_MMCHS_SYSCTL_SRC_SHIFT);
653         if (regVal == 0)
654             break;
655     }while (1);
657     mmchsClearIntrStatus(mmcHsReg,0xFFFFFFFF);
659     /* wait until you are allowed to send cmd */
660     do
661     {
662         regVal = CSL_FEXT(mmcHsReg->PSTATE, MMCHS_PSTATE_DATI);
663     if (regVal == CSL_MMCHS_PSTATE_DATI_CMDEN)
664             break;
665     }while(1);
667     /* Set block length to blkLen */
668     mmcHsReg->BLK = blkSize;
669     mmcHsReg->ARG = arg;
670     mmcHsReg->CMD = cmd;
671     mmchsDelay(100);
673 #ifdef DEBUG
674     IFPRINT(platform_write ("CMD: %d : ",cmd >> 24));
675     IFPRINT(platform_write ("cmd 0x%x; arg: 0x%x blklen: 0x%x  ",cmd,arg,\
676                     mmcHsReg->BLK));
677     IFPRINT(platform_write ("Status 0x%x\n",mmcHsReg->STAT));
678 #endif
679     platform_delay(100);
680     return MMCHS_RET_OK;
683 /** ===========================================================================
684    *   @n@b mmchsSendAppCmd
685    *
686    *   @b Description
687    *   @n This function sends the application command to MMCSD.
688    *
689    *   @b Arguments
690    *   @verbatim
691               mmcHsReg - Handle to the mmcReg
692               cmd - Command to be sent
693               arg - argument for the command
694               blkLen - no of bytes in a block
695        @endverbatim
696    *
697    *   <b> Return Value </b>
698    *   @li        MMCHS_RET_INVALID_PARAM
699    *   @li       MMCHS_RET_OK if successful
700    *            MMCHS_RET_CMD_TIMEOUT  if cmd timeout
701    *
702    *   @b Modifies
703    *   @n  None
704    *  =========================================================================
705    */
706 MMC_RET mmchsSendAppCmd(CSL_MmchsRegs *mmcHsReg, uint32_t cmd,
707                                     uint32_t arg, uint32_t blkLen)
709     volatile uint32_t status = 0;
710      uint32_t xferStat = 0;
712     if (mmcHsReg == NULL)
713     {
714         return MMCHS_RET_INVALID_PARAM;
715     }
717     status = mmchsSendCmd(mmcHsReg, SDMMC_CMD55, 0,0);
718     if (status == MMCHS_RET_OK)
719     {
720         status = mmchsGetStatus(mmcHsReg, &xferStat);
721         if ((status == MMCHS_RET_OK) &&
722                 (xferStat & CSL_MMCHS_STAT_CC_MASK))
723         {
724             status = mmchsSendCmd(mmcHsReg, cmd, arg, blkLen);
725             status = mmchsGetStatus(mmcHsReg, &xferStat);
726         }
727         else if (xferStat & CSL_MMCHS_STAT_CTO_MASK)
728         {
729             status = MMCHS_RET_CMD_TIMEOUT;
730         }
731     }
732     return status;
735 /** ===========================================================================
736    *   @n@b mmchsClearIntrStatus
737    *
738    *   @b Description
739    *   @n This function clears the interrupt status
740    *
741    *   @b Arguments
742    *   @verbatim
743               mmcHsReg - Handle to the mmcReg
744    *          flag     - Specific status to be cleared;
745        @endverbatim
746    *
747    *   <b> Return Value </b>
748    *   @li        MMCHS_RET_INVALID_PARAM - If input parameter is invalid
749    *   @li        MMCHS_RET_OK - on Success
750    *
751    *   @b Modifies
752    *   @n  None
753    *
754    *  ==========================================================================
755    */
756 MMC_RET mmchsClearIntrStatus(CSL_MmchsRegs *mmcHsReg, uint32_t flag)
759     if(mmcHsReg == NULL)
760     {
761         return MMCHS_RET_INVALID_PARAM;
762     }
764     mmcHsReg->STAT |= flag;
765     return MMCHS_RET_OK;
768 /** ============================================================================
769    *   @n@b mmchsGetStatus
770    *
771    *   @b Description
772    *   @nThis function gets status of the controller after sending the command.
773    *
774    *   @b Arguments
775    *   @verbatim
776               mmcHsReg - Handle to the mmcReg
777    *          flag     - Specific status to be cleared;
778        @endverbatim
779    *
780    *   <b> Return Value </b>
781    *   @li        MMCHS_RET_INVALID_PARAM - If input parameter is invalid
782    *   @li        MMCHS_RET_SEND_FAILED - If error flag is set for the command
783    *   @li        MMCHS_RET_SEND_NORSP -  If no response for the send command
784    *   @li        MMCHS_RET_OK - If send command is responded with
785                                  command/transfer complete
786    *
787    *   @b Modifies
788    *   @n  None
789    *
790    *  ==========================================================================
791    */
792 MMC_RET mmchsGetStatus(CSL_MmchsRegs *mmcHsReg, uint32_t *xferStatus)
794     uint32_t retry = 0xFFFF;
795     uint32_t status = 0;
797     if ((mmcHsReg == NULL) || (xferStatus == NULL))
798     {
799         return MMCHS_RET_INVALID_PARAM;
800     }
802     *xferStatus = 0;
803     mmcHsReg->BLK = 0;
804     do
805     {
806         status = mmcHsReg->STAT;
807     } while ((status == 0) && retry--);
809     *xferStatus = status;
810 #ifdef DEBUG
811     IFPRINT(platform_write (" stat: 0x%x  ",status));
812     IFPRINT(platform_write ("Rsp1 : 0x%x\tRsp 2: 0x%x\tRsp3: 0x%x\tRsp4: 0x%x\n",
813                     mmcHsReg->RSP10, mmcHsReg->RSP32,
814                     mmcHsReg->RSP54, mmcHsReg->RSP76));
815 #endif
816     if (status & CSL_MMCHS_STAT_CC_MASK)
817     {
818         return MMCHS_RET_OK;
819     }
820     if (status && ((status & CSL_MMCHS_STAT_ERRI_MASK) == 0))
821     {
822         return MMCHS_RET_OK;
823     }
825     if (status & CSL_MMCHS_STAT_ERRI_MASK)
826     {
827         return MMCHS_RET_SEND_FAILED;
828     }
829     else
830     {
831          return MMCHS_RET_SEND_NORSP;
832     }
835 /** ============================================================================
836    *   @n@b mmchsGetResponse
837    *
838    *   @b Description
839    *   @n This function get the command response from the controller
840    *
841    *   @b Arguments
842    *   @verbatim
843               mmcHsReg - Handle to the mmcReg
844    *          rsp        pointer to buffer to be filled with the response
845        @endverbatim
846    *
847    *   <b> Return Value </b>
848    *   @li        status flags
849    *
850    *   @b Modifies
851    *   @n  None
852    *
853    * \note: that this function shall return the values from all response
854    * registers. Hence, rsp, must be a pointer to memory which can hold max
855    * response length. It is the responsibility of the caller to use only the
856    * required/relevant parts of the response
857    *
858    *  ==========================================================================
859    */
860 MMC_RET mmchsGetResponse(CSL_MmchsRegs *mmcHsReg, uint32_t *rsp)
862     if((mmcHsReg == NULL) || (rsp == NULL))
863     {
864         return MMCHS_RET_INVALID_PARAM;
865     }
867     rsp[3] = mmcHsReg->RSP10;
868     rsp[2] = mmcHsReg->RSP32;
869     rsp[1] = mmcHsReg->RSP54;
870     rsp[0] = mmcHsReg->RSP76;
871     mmchsDelay(10000);
872     return MMCHS_RET_OK;
875 /** ============================================================================
876    *   @n@b mmchsReadData
877    *
878    *   @b Description
879    *   @n This function reads the data from the mmc device (SD card/eMMC/SDIO)
880    *
881    *   @b Arguments
882    *   @verbatim
883               mmcHsReg   - Handle to the mmcReg
884               dataBuffer - pointer to the data buffer
885               blkSize    - block size
886        @endverbatim
887    *
888    *   <b> Return Value </b>
889    *   @li        MMCHS_RET_INVALID_PARAM
890        @li        MMCHS_RET_DATA_RD_FAILED    if read fails
891    *   @li        MMCHS_RET_OK if successful
892    *
893    *   @b Modifies
894    *   @n  None
895    *  =========================================================================
896    */
897 MMC_RET mmchsReadData(CSL_MmchsRegs *mmcHsReg, uint8_t *dataBuffer,
898                       uint32_t blkSize)
900     uint32_t  retry = 0xFFFF;
901     uint32_t  status;
902     uint32_t blkCnt;
904     if((mmcHsReg == NULL) || (dataBuffer == NULL))
905     {
906         return MMCHS_RET_INVALID_PARAM;
907     }
909     IFPRINT(platform_write  ("Reading data from mmc device of size 0x%x\n",blkSize));
910     for (blkCnt = 0; blkCnt < blkSize/4; blkCnt++)
911     {
912         do
913         {
914             status = mmcHsReg->STAT;
915             if (status & CSL_MMCHS_STAT_TC_MASK)
916                 break;
917         } while (((status & STAT_BRR) == 0) && retry--); /* ready to read? */
919         if (retry == 0)
920         {
921             break;
922         }
923         mmchsDelay(50);
924         retry = 0xFFFF;
925         *(uint32_t *)dataBuffer = mmcHsReg->DATA;
926         mmchsDelay(1000);
927         IFPRINT(platform_write  ("0x%x ",*(uint32_t *)dataBuffer));
928         dataBuffer = dataBuffer + 4;
929     }
930     platform_write  ("\n");
931     if (retry == 0)
932     {
933         IFPRINT(platform_write ("MMCHS:error read failed\n"));
934         return MMCHS_RET_DATA_RD_FAILED;
935     }
936     else
937     {
938         return MMCHS_RET_OK;
939     }
942 /** ============================================================================
943    *   @n@b mmchsWriteData
944    *
945    *   @b Description
946    *   @n This function writes the data to the mmc device (SD card/eMMC/SDIO)
947    *
948    *   @b Arguments
949    *   @verbatim
950               mmcHsReg   - Handle to the mmcReg
951               dataBuffer - pointer to the data buffer
952               blkSize    - block size
953        @endverbatim
954    *
955    *   <b> Return Value </b>
956    *   @li        MMCHS_RET_INVALID_PARAM
957        @li        MMCHS_RET_DATA_WR_FAILED    if write fails
958    *   @li        MMCHS_RET_OK if successful
959    *
960    *   @b Modifies
961    *   @n  None
962    *  =========================================================================
963    */
964 MMC_RET mmchsWriteData(CSL_MmchsRegs *mmcHsReg, uint8_t *dataBuffer,
965                        uint32_t blkSize)
967     uint32_t  retry = 0xFFFF;
968     uint32_t  status;
969     uint32_t blkCnt;
971     if((mmcHsReg == NULL) || (dataBuffer == NULL))
972     {
973         return MMCHS_RET_INVALID_PARAM;
974     }
976     for (blkCnt = 0; blkCnt < blkSize/4; blkCnt++)
977     {
978         do
979         {
980             status = mmcHsReg->STAT;
981         } while (((status & STAT_BWR) == 0) && retry--); /* ready to write? */
983         if (retry == 0)
984         {
985             break;
986         }
987         mmchsDelay(5);
988         retry = 0xFFFF;
989         mmcHsReg->DATA = *(uint32_t *)dataBuffer;
990         dataBuffer = dataBuffer + 4;
991     }
992     if (retry == 0)
993     {
994         IFPRINT(platform_write ("MMCHS:error write failed\n"));
995         return MMCHS_RET_DATA_WR_FAILED;
996     }
997     else
998     {
999         return MMCHS_RET_OK;
1000     }
1003 /** ============================================================================
1004    *   @n@b mmchsIsCardInserted
1005    *
1006    *   @b Description
1007    *   @n This function checks if the card is inserted in the sdcard slot
1008    *
1009    *   @b Arguments
1010    *   @verbatim
1011               mmcHsReg - Handle to the mmcReg
1012        @endverbatim
1013    *
1014    *   <b> Return Value </b>
1015    *   @li        0  if the card is not inserted and detected
1016    *   @li        1  if the card is inserted and detected
1017    *
1018    *   @b Modifies
1019    *   @n  None
1020    * \note: that this functional may not be available for all instances of the
1021    * controller. This function, is only useful if the controller has a dedicated
1022    * card detect pin. If not, the card detection mechanism is application
1023    * implementation specific
1024    *  =========================================================================
1025    */
1026 Bool mmchsIsCardInserted(CSL_MmchsRegs *mmcHsReg)
1028     uint32_t status;
1029     if (mmcHsReg == NULL)
1030     {
1031         return MMCHS_RET_INVALID_PARAM;
1032     }
1034     status = mmcHsReg->PSTATE & CSL_MMCHS_PSTATE_CINS_MASK;
1035     if (status)
1036         return TRUE;
1037     else
1038         return FALSE;
1041 #endif  /* #if (PLATFORM_MMCHS_IN) */