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