1 /*
2 * Copyright 2021 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "sdmmc_config.h"
9 #include "fsl_iomuxc.h"
10 /*******************************************************************************
11 * Definitions
12 ******************************************************************************/
13
14 /*******************************************************************************
15 * Prototypes
16 ******************************************************************************/
17 void BOARD_SDCardPowerControl(bool enable);
18
19 /*******************************************************************************
20 * Variables
21 ******************************************************************************/
22 /*!brief sdmmc dma buffer */
23 AT_NONCACHEABLE_SECTION_ALIGN(static uint32_t s_sdmmcHostDmaBuffer[BOARD_SDMMC_HOST_DMA_DESCRIPTOR_BUFFER_SIZE],
24 SDMMCHOST_DMA_DESCRIPTOR_BUFFER_ALIGN_SIZE);
25 #if defined SDMMCHOST_ENABLE_CACHE_LINE_ALIGN_TRANSFER && SDMMCHOST_ENABLE_CACHE_LINE_ALIGN_TRANSFER
26 /* two cache line length for sdmmc host driver maintain unalign transfer */
27 SDK_ALIGN(static uint8_t s_sdmmcCacheLineAlignBuffer[BOARD_SDMMC_DATA_BUFFER_ALIGN_SIZE * 2U],
28 BOARD_SDMMC_DATA_BUFFER_ALIGN_SIZE);
29 #endif
30 #if defined(SDIO_ENABLED) || defined(SD_ENABLED)
31 static sd_detect_card_t s_cd;
32 static sd_io_voltage_t s_ioVoltage = {
33 .type = BOARD_SDMMC_SD_IO_VOLTAGE_CONTROL_TYPE,
34 .func = NULL,
35 };
36 #endif
37 static sdmmchost_t s_host;
38
39 #ifdef SDIO_ENABLED
40 static sdio_card_int_t s_sdioInt;
41 #endif
42
43 GPIO_HANDLE_DEFINE(s_CardDetectGpioHandle);
44 GPIO_HANDLE_DEFINE(s_PowerResetGpioHandle);
45
46 /*******************************************************************************
47 * Code
48 ******************************************************************************/
BOARD_USDHC1ClockConfiguration(void)49 uint32_t BOARD_USDHC1ClockConfiguration(void)
50 {
51 CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN);
52 /*configure system pll PFD0 fractional divider to 24, output clock is 528MHZ * 18 / 24 = 396 MHZ*/
53 CLOCK_InitSysPfd(kCLOCK_Pfd0, 24U);
54 /* Configure USDHC clock source and divider */
55 CLOCK_SetDiv(kCLOCK_Usdhc1Div, 1U); /* USDHC clock root frequency maximum: 198MHZ */
56 CLOCK_SetMux(kCLOCK_Usdhc1Mux, 1U);
57
58 return 396000000U / 2U;
59 }
60
61 #if defined(SDIO_ENABLED) || defined(SD_ENABLED)
BOARD_SDCardGetDetectStatus(void)62 bool BOARD_SDCardGetDetectStatus(void)
63 {
64 uint8_t pinState;
65
66 if (HAL_GpioGetInput(s_CardDetectGpioHandle, &pinState) == kStatus_HAL_GpioSuccess)
67 {
68 if (pinState == BOARD_SDMMC_SD_CD_INSERT_LEVEL)
69 {
70 return true;
71 }
72 }
73
74 return false;
75 }
76
SDMMC_SD_CD_Callback(void * param)77 void SDMMC_SD_CD_Callback(void *param)
78 {
79 if (s_cd.callback != NULL)
80 {
81 s_cd.callback(BOARD_SDCardGetDetectStatus(), s_cd.userData);
82 }
83 }
84
BOARD_SDCardDAT3PullFunction(uint32_t status)85 void BOARD_SDCardDAT3PullFunction(uint32_t status)
86 {
87 if (status == kSD_DAT3PullDown)
88 {
89 IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3,
90 IOMUXC_SW_PAD_CTL_PAD_SPEED(1) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
91 IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
92 IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
93 IOMUXC_SW_PAD_CTL_PAD_DSE(1));
94 }
95 else
96 {
97 IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3,
98 IOMUXC_SW_PAD_CTL_PAD_SPEED(1) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
99 IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
100 IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
101 IOMUXC_SW_PAD_CTL_PAD_DSE(1));
102 }
103 }
104
BOARD_SDCardDetectInit(sd_cd_t cd,void * userData)105 void BOARD_SDCardDetectInit(sd_cd_t cd, void *userData)
106 {
107 uint8_t pinState;
108
109 /* install card detect callback */
110 s_cd.cdDebounce_ms = BOARD_SDMMC_SD_CARD_DETECT_DEBOUNCE_DELAY_MS;
111 s_cd.type = BOARD_SDMMC_SD_CD_TYPE;
112 s_cd.cardDetected = BOARD_SDCardGetDetectStatus;
113 s_cd.callback = cd;
114 s_cd.userData = userData;
115
116 if (BOARD_SDMMC_SD_CD_TYPE == kSD_DetectCardByGpioCD)
117 {
118 hal_gpio_pin_config_t sw_config = {
119 kHAL_GpioDirectionIn,
120 0,
121 BOARD_SDMMC_SD_CD_GPIO_PORT,
122 BOARD_SDMMC_SD_CD_GPIO_PIN,
123 };
124 HAL_GpioInit(s_CardDetectGpioHandle, &sw_config);
125 HAL_GpioSetTriggerMode(s_CardDetectGpioHandle, BOARD_SDMMC_SD_CD_INTTERUPT_TYPE);
126 HAL_GpioInstallCallback(s_CardDetectGpioHandle, SDMMC_SD_CD_Callback, NULL);
127
128 if (HAL_GpioGetInput(s_CardDetectGpioHandle, &pinState) == kStatus_HAL_GpioSuccess)
129 {
130 if (pinState == BOARD_SDMMC_SD_CD_INSERT_LEVEL)
131 {
132 if (cd != NULL)
133 {
134 cd(true, userData);
135 }
136 }
137 }
138 }
139
140 /* register DAT3 pull function switch function pointer */
141 if (BOARD_SDMMC_SD_CD_TYPE == kSD_DetectCardByHostDATA3)
142 {
143 s_cd.dat3PullFunc = BOARD_SDCardDAT3PullFunction;
144 /* make sure the card is power on for DAT3 pull up */
145 BOARD_SDCardPowerControl(true);
146 }
147 }
148
BOARD_SDCardPowerResetInit(void)149 void BOARD_SDCardPowerResetInit(void)
150 {
151 hal_gpio_pin_config_t sw_config = {
152 kHAL_GpioDirectionOut,
153 1,
154 BOARD_SDMMC_SD_POWER_RESET_GPIO_PORT,
155 BOARD_SDMMC_SD_POWER_RESET_GPIO_PIN,
156 };
157 HAL_GpioInit(s_PowerResetGpioHandle, &sw_config);
158 }
159
BOARD_SDCardPowerControl(bool enable)160 void BOARD_SDCardPowerControl(bool enable)
161 {
162 if (enable)
163 {
164 HAL_GpioSetOutput(s_PowerResetGpioHandle, 0);
165 }
166 else
167 {
168 HAL_GpioSetOutput(s_PowerResetGpioHandle, 1);
169 }
170 }
171
BOARD_SD_Pin_Config(uint32_t freq)172 void BOARD_SD_Pin_Config(uint32_t freq)
173 {
174 uint32_t speed = 0U, strength = 0U;
175
176 if (freq <= 50000000)
177 {
178 speed = 0U;
179 strength = 7U;
180 }
181 else if (freq <= 100000000)
182 {
183 speed = 2U;
184 strength = 7U;
185 }
186 else
187 {
188 speed = 3U;
189 strength = 7U;
190 }
191
192 IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD,
193 IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
194 IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
195 IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
196 IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
197 IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_01_USDHC1_CLK,
198 IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
199 IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(0) |
200 IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
201 IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0,
202 IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
203 IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
204 IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
205 IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
206 IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1,
207 IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
208 IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
209 IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
210 IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
211 IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2,
212 IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
213 IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
214 IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
215 IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
216 IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3,
217 IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |
218 IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |
219 IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(1) |
220 IOMUXC_SW_PAD_CTL_PAD_DSE(strength));
221 }
222 #endif
223
224 #ifdef SD_ENABLED
BOARD_SD_Config(void * card,sd_cd_t cd,uint32_t hostIRQPriority,void * userData)225 void BOARD_SD_Config(void *card, sd_cd_t cd, uint32_t hostIRQPriority, void *userData)
226 {
227 assert(card);
228
229 s_host.dmaDesBuffer = s_sdmmcHostDmaBuffer;
230 s_host.dmaDesBufferWordsNum = BOARD_SDMMC_HOST_DMA_DESCRIPTOR_BUFFER_SIZE;
231 s_host.enableCacheControl = BOARD_SDMMC_HOST_CACHE_CONTROL;
232 #if defined SDMMCHOST_ENABLE_CACHE_LINE_ALIGN_TRANSFER && SDMMCHOST_ENABLE_CACHE_LINE_ALIGN_TRANSFER
233 s_host.cacheAlignBuffer = s_sdmmcCacheLineAlignBuffer;
234 s_host.cacheAlignBufferSize = BOARD_SDMMC_DATA_BUFFER_ALIGN_SIZE * 2U;
235 #endif
236
237 ((sd_card_t *)card)->host = &s_host;
238 ((sd_card_t *)card)->host->hostController.base = BOARD_SDMMC_SD_HOST_BASEADDR;
239 ((sd_card_t *)card)->host->hostController.sourceClock_Hz = BOARD_USDHC1ClockConfiguration();
240
241 ((sd_card_t *)card)->usrParam.cd = &s_cd;
242 ((sd_card_t *)card)->usrParam.pwr = BOARD_SDCardPowerControl;
243 ((sd_card_t *)card)->usrParam.ioStrength = BOARD_SD_Pin_Config;
244 ((sd_card_t *)card)->usrParam.ioVoltage = &s_ioVoltage;
245 ((sd_card_t *)card)->usrParam.maxFreq = BOARD_SDMMC_SD_HOST_SUPPORT_SDR104_FREQ;
246
247 BOARD_SDCardPowerResetInit();
248 BOARD_SDCardDetectInit(cd, userData);
249
250 NVIC_SetPriority(BOARD_SDMMC_SD_HOST_IRQ, hostIRQPriority);
251 }
252 #endif
253
254 #ifdef SDIO_ENABLED
BOARD_SDIO_Config(void * card,sd_cd_t cd,uint32_t hostIRQPriority,sdio_int_t cardInt)255 void BOARD_SDIO_Config(void *card, sd_cd_t cd, uint32_t hostIRQPriority, sdio_int_t cardInt)
256 {
257 assert(card);
258
259 s_host.dmaDesBuffer = s_sdmmcHostDmaBuffer;
260 s_host.dmaDesBufferWordsNum = BOARD_SDMMC_HOST_DMA_DESCRIPTOR_BUFFER_SIZE;
261 s_host.enableCacheControl = BOARD_SDMMC_HOST_CACHE_CONTROL;
262 #if defined SDMMCHOST_ENABLE_CACHE_LINE_ALIGN_TRANSFER && SDMMCHOST_ENABLE_CACHE_LINE_ALIGN_TRANSFER
263 s_host.cacheAlignBuffer = s_sdmmcCacheLineAlignBuffer;
264 s_host.cacheAlignBufferSize = BOARD_SDMMC_DATA_BUFFER_ALIGN_SIZE * 2U;
265 #endif
266
267 ((sdio_card_t *)card)->host = &s_host;
268 ((sdio_card_t *)card)->host->hostController.base = BOARD_SDMMC_SDIO_HOST_BASEADDR;
269 ((sdio_card_t *)card)->host->hostController.sourceClock_Hz = BOARD_USDHC1ClockConfiguration();
270
271 ((sdio_card_t *)card)->usrParam.cd = &s_cd;
272 ((sdio_card_t *)card)->usrParam.pwr = BOARD_SDCardPowerControl;
273 ((sdio_card_t *)card)->usrParam.ioStrength = BOARD_SD_Pin_Config;
274 ((sdio_card_t *)card)->usrParam.ioVoltage = &s_ioVoltage;
275 ((sdio_card_t *)card)->usrParam.maxFreq = BOARD_SDMMC_SD_HOST_SUPPORT_SDR104_FREQ;
276 if (cardInt != NULL)
277 {
278 s_sdioInt.cardInterrupt = cardInt;
279 ((sdio_card_t *)card)->usrParam.sdioInt = &s_sdioInt;
280 }
281
282 BOARD_SDCardPowerResetInit();
283 BOARD_SDCardDetectInit(cd, NULL);
284
285 NVIC_SetPriority(BOARD_SDMMC_SDIO_HOST_IRQ, hostIRQPriority);
286 }
287 #endif
288
289 #ifdef MMC_ENABLED
BOARD_MMC_Config(void * card,uint32_t hostIRQPriority)290 void BOARD_MMC_Config(void *card, uint32_t hostIRQPriority)
291
292 {
293 assert(card);
294
295 s_host.dmaDesBuffer = s_sdmmcHostDmaBuffer;
296 s_host.dmaDesBufferWordsNum = BOARD_SDMMC_HOST_DMA_DESCRIPTOR_BUFFER_SIZE;
297 s_host.enableCacheControl = BOARD_SDMMC_HOST_CACHE_CONTROL;
298 #if defined SDMMCHOST_ENABLE_CACHE_LINE_ALIGN_TRANSFER && SDMMCHOST_ENABLE_CACHE_LINE_ALIGN_TRANSFER
299 s_host.cacheAlignBuffer = s_sdmmcCacheLineAlignBuffer;
300 s_host.cacheAlignBufferSize = BOARD_SDMMC_DATA_BUFFER_ALIGN_SIZE * 2U;
301 #endif
302
303 ((mmc_card_t *)card)->host = &s_host;
304 ((mmc_card_t *)card)->host->hostController.base = BOARD_SDMMC_MMC_HOST_BASEADDR;
305 ((mmc_card_t *)card)->host->hostController.sourceClock_Hz = BOARD_USDHC1ClockConfiguration();
306 ((mmc_card_t *)card)->usrParam.ioStrength = NULL;
307 ((mmc_card_t *)card)->usrParam.maxFreq = BOARD_SDMMC_MMC_HOST_SUPPORT_HS200_FREQ;
308
309 ((mmc_card_t *)card)->hostVoltageWindowVCC = BOARD_SDMMC_MMC_VCC_SUPPLY;
310 ((mmc_card_t *)card)->hostVoltageWindowVCCQ = BOARD_SDMMC_MMC_VCCQ_SUPPLY;
311
312 NVIC_SetPriority(BOARD_SDMMC_MMC_HOST_IRQ, hostIRQPriority);
313 }
314 #endif
315