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