1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_host.h"
10 #include "board.h"
11 #include "fsl_gpio.h"
12 #ifdef BOARD_USDHC_CD_PORT_BASE
13 #include "fsl_port.h"
14 #endif
15 
16 /*******************************************************************************
17 * Definitions
18 ******************************************************************************/
19 
20 /*******************************************************************************
21  * Prototypes
22  ******************************************************************************/
23 /*!
24  * @brief host controller error recovery.
25  * @param host base address.
26  */
27 static void Host_ErrorRecovery(HOST_TYPE *hostBase);
28 
29 /*******************************************************************************
30  * Variables
31  ******************************************************************************/
32 /* DMA descriptor should allocate at non-cached memory */
33 AT_NONCACHEABLE_SECTION_ALIGN(uint32_t g_usdhcAdma2Table[USDHC_ADMA_TABLE_WORDS], USDHC_ADMA2_ADDR_ALIGN);
34 extern volatile uint32_t g_timeMilliseconds;
35 static volatile bool g_sdInsertedFlag;
36 
37 /*******************************************************************************
38  * Code
39  ******************************************************************************/
40 
41 /* Card detect. */
CardInsertDetect(HOST_TYPE * hostBase)42 status_t CardInsertDetect(HOST_TYPE *hostBase)
43 {
44     return kStatus_Success;
45 }
46 
47 /* User defined transfer function. */
USDHC_TransferFunction(USDHC_Type * base,usdhc_transfer_t * content)48 static status_t USDHC_TransferFunction(USDHC_Type *base, usdhc_transfer_t *content)
49 {
50     status_t error = kStatus_Success;
51 
52     usdhc_adma_config_t dmaConfig;
53 
54     if (content != NULL && content->data != NULL)
55     {
56         memset(&dmaConfig, 0, sizeof(usdhc_adma_config_t));
57         /* config adma */
58         dmaConfig.dmaMode = USDHC_DMA_MODE;
59         dmaConfig.burstLen = kUSDHC_EnBurstLenForINCR;
60         dmaConfig.admaTable = g_usdhcAdma2Table;
61         dmaConfig.admaTableWords = USDHC_ADMA_TABLE_WORDS;
62     }
63 
64     error = USDHC_TransferBlocking(base, &dmaConfig, content);
65 
66     if (error == kStatus_Fail)
67     {
68         /* host error recovery */
69         Host_ErrorRecovery(base);
70     }
71 
72     return error;
73 }
74 
Host_ErrorRecovery(HOST_TYPE * hostBase)75 static void Host_ErrorRecovery(HOST_TYPE *hostBase)
76 {
77     uint32_t status = 0U;
78     /* get host present status */
79     status = USDHC_GetPresentStatusFlags(hostBase);
80     /* check command inhibit status flag */
81     if ((status & kUSDHC_CommandInhibitFlag) != 0U)
82     {
83         /* reset command line */
84         USDHC_Reset(hostBase, kUSDHC_ResetCommand, 100U);
85     }
86     /* check data inhibit status flag */
87     if ((status & kUSDHC_DataInhibitFlag) != 0U)
88     {
89         /* reset data line */
90         USDHC_Reset(hostBase, kUSDHC_ResetData, 100U);
91     }
92 }
93 
HOST_Init(void * host)94 status_t HOST_Init(void *host)
95 {
96     usdhc_host_t *usdhcHost = (usdhc_host_t *)host;
97 
98     /* init card power control */
99     HOST_INIT_SD_POWER();
100     HOST_INIT_MMC_POWER();
101 
102     /* Initializes USDHC. */
103     usdhcHost->config.dataTimeout = USDHC_DATA_TIMEOUT;
104     usdhcHost->config.endianMode = USDHC_ENDIAN_MODE;
105     usdhcHost->config.readWatermarkLevel = USDHC_READ_WATERMARK_LEVEL;
106     usdhcHost->config.writeWatermarkLevel = USDHC_WRITE_WATERMARK_LEVEL;
107     usdhcHost->config.readBurstLen = USDHC_READ_BURST_LEN;
108     usdhcHost->config.writeBurstLen = USDHC_WRITE_BURST_LEN;
109 
110     USDHC_Init(usdhcHost->base, &(usdhcHost->config));
111 
112     /* Define transfer function. */
113     usdhcHost->transfer = USDHC_TransferFunction;
114 
115     return kStatus_Success;
116 }
117 
HOST_Reset(HOST_TYPE * hostBase)118 void HOST_Reset(HOST_TYPE *hostBase)
119 {
120     /* voltage switch to normal but not 1.8V */
121     HOST_SWITCH_VOLTAGE180V(hostBase, false);
122     /* Disable DDR mode */
123     HOST_ENABLE_DDR_MODE(hostBase, false);
124     /* disable tuning */
125     HOST_EXECUTE_STANDARD_TUNING_ENABLE(hostBase, false);
126     /* Disable HS400 mode */
127     HOST_ENABLE_HS400_MODE(hostBase, false);
128     /* Disable DLL */
129     HOST_ENABLE_STROBE_DLL(hostBase, false);
130 }
131 
HOST_Deinit(void * host)132 void HOST_Deinit(void *host)
133 {
134     usdhc_host_t *usdhcHost = (usdhc_host_t *)host;
135     USDHC_Deinit(usdhcHost->base);
136 }
137