1 /*
2 * Copyright 2020-2022 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "sdmmc_config.h"
9 #include "fsl_power.h"
10 #include "fsl_iopctl.h"
11
12 /*******************************************************************************
13 * Definitions
14 ******************************************************************************/
15
16 /*******************************************************************************
17 * Prototypes
18 ******************************************************************************/
19 #if defined(SDIO_ENABLED) || defined(SD_ENABLED)
20 void BOARD_SDCardIoVoltageControl(sdmmc_operation_voltage_t voltage);
21 #endif
22 void BOARD_SDCardPowerControl(bool enable);
23
24 /*******************************************************************************
25 * Variables
26 ******************************************************************************/
27 /*!brief sdmmc dma buffer */
28 AT_NONCACHEABLE_SECTION_ALIGN(static uint32_t s_sdmmcHostDmaBuffer[BOARD_SDMMC_HOST_DMA_DESCRIPTOR_BUFFER_SIZE],
29 SDMMCHOST_DMA_DESCRIPTOR_BUFFER_ALIGN_SIZE);
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 = BOARD_SDCardIoVoltageControl,
35 };
36 #endif
37 static sdmmchost_t s_host;
38 GPIO_HANDLE_DEFINE(s_PowerResetGpioHandle);
39
40 #ifdef SDIO_ENABLED
41 static sdio_card_int_t s_sdioInt;
42 #endif
43 /*******************************************************************************
44 * Code
45 ******************************************************************************/
BOARD_USDHC0ClockConfiguration(void)46 uint32_t BOARD_USDHC0ClockConfiguration(void)
47 {
48 /*Make sure USDHC ram buffer has power up*/
49 POWER_DisablePD(kPDRUNCFG_APD_USDHC0_SRAM);
50 POWER_DisablePD(kPDRUNCFG_PPD_USDHC0_SRAM);
51 POWER_DisablePD(kPDRUNCFG_PD_LPOSC);
52 POWER_ApplyPD();
53
54 /* SDIO0 */
55 /* usdhc depend on 32K clock also */
56 CLOCK_AttachClk(kLPOSC_DIV32_to_32KHZWAKE_CLK);
57 CLOCK_AttachClk(kAUX0_PLL_to_SDIO0_CLK);
58 CLOCK_SetClkDiv(kCLOCK_DivSdio0Clk, 1);
59
60 return CLOCK_GetSdioClkFreq(0);
61 }
62 #if defined(SDIO_ENABLED) || defined(SD_ENABLED)
BOARD_SDCardDAT3PullFunction(uint32_t status)63 void BOARD_SDCardDAT3PullFunction(uint32_t status)
64 {
65 if (status == kSD_DAT3PullDown)
66 {
67 IOPCTL_PinMuxSet(IOPCTL, 2U, 3U, 0x41); /* PULL UP/PULL DOWN disable */
68 }
69 else
70 {
71 IOPCTL_PinMuxSet(IOPCTL, 2U, 3U, 0x71);
72 }
73 }
74
BOARD_SDCardDetectInit(sd_cd_t cd,void * userData)75 void BOARD_SDCardDetectInit(sd_cd_t cd, void *userData)
76 {
77 /* install card detect callback */
78 s_cd.cdDebounce_ms = BOARD_SDMMC_SD_CARD_DETECT_DEBOUNCE_DELAY_MS;
79 s_cd.type = BOARD_SDMMC_SD_CD_TYPE;
80 s_cd.callback = cd;
81 s_cd.userData = userData;
82
83 /* register DAT3 pull function switch function pointer */
84 if (BOARD_SDMMC_SD_CD_TYPE == kSD_DetectCardByHostDATA3)
85 {
86 s_cd.dat3PullFunc = BOARD_SDCardDAT3PullFunction;
87 /* make sure the card is power on for DAT3 pull up */
88 BOARD_SDCardPowerControl(true);
89 }
90 }
91 #endif
BOARD_SDCardIoVoltageControlInit(void)92 void BOARD_SDCardIoVoltageControlInit(void)
93 {
94 /* Intentional empty, since the default SD signal voltage is 1.8V already which is againist with SD3.0 spec, so
95 leave the voltage switch function as empty to workaround the limitation, then some SD3.0 card may works, but SD2.0
96 card cannot works on this board */
97 }
98
BOARD_SDCardIoVoltageControl(sdmmc_operation_voltage_t voltage)99 void BOARD_SDCardIoVoltageControl(sdmmc_operation_voltage_t voltage)
100 {
101 /* Intentional empty, since the default SD signal voltage is 1.8V already which is againist with SD3.0 spec, so
102 leave the voltage switch function as empty to workaround the limitation, then some SD3.0 card may works, but SD2.0
103 card cannot works on this board */
104 }
105
BOARD_SDCardPowerResetInit(void)106 void BOARD_SDCardPowerResetInit(void)
107 {
108 hal_gpio_pin_config_t sw_config = {
109 kHAL_GpioDirectionOut,
110 0,
111 BOARD_SDMMC_SD_POWER_RESET_GPIO_PORT,
112 BOARD_SDMMC_SD_POWER_RESET_GPIO_PIN,
113 };
114 HAL_GpioInit(s_PowerResetGpioHandle, &sw_config);
115 }
116
BOARD_SDCardPowerControl(bool enable)117 void BOARD_SDCardPowerControl(bool enable)
118 {
119 if (enable)
120 {
121 HAL_GpioSetOutput(s_PowerResetGpioHandle, 1);
122 }
123 else
124 {
125 HAL_GpioSetOutput(s_PowerResetGpioHandle, 0);
126 }
127 }
128
129 #ifdef SD_ENABLED
BOARD_SD_Config(void * card,sd_cd_t cd,uint32_t hostIRQPriority,void * userData)130 void BOARD_SD_Config(void *card, sd_cd_t cd, uint32_t hostIRQPriority, void *userData)
131 {
132 assert(card);
133
134 s_host.dmaDesBuffer = s_sdmmcHostDmaBuffer;
135 s_host.dmaDesBufferWordsNum = BOARD_SDMMC_HOST_DMA_DESCRIPTOR_BUFFER_SIZE;
136 ((sd_card_t *)card)->host = &s_host;
137 ((sd_card_t *)card)->host->hostController.base = BOARD_SDMMC_SD_HOST_BASEADDR;
138 ((sd_card_t *)card)->host->hostController.sourceClock_Hz = BOARD_USDHC0ClockConfiguration();
139
140 ((sd_card_t *)card)->host->tuningType = BOARD_SDMMC_SD_TUNING_TYPE;
141
142 ((sd_card_t *)card)->usrParam.cd = &s_cd;
143 ((sd_card_t *)card)->usrParam.pwr = BOARD_SDCardPowerControl;
144 ((sd_card_t *)card)->usrParam.ioVoltage = &s_ioVoltage;
145
146 BOARD_SDCardPowerResetInit();
147
148 BOARD_SDCardIoVoltageControlInit();
149
150 BOARD_SDCardDetectInit(cd, userData);
151
152 NVIC_SetPriority(BOARD_SDMMC_SD_HOST_IRQ, hostIRQPriority);
153 }
154 #endif
155
156 #ifdef SDIO_ENABLED
BOARD_SDIO_Config(void * card,sd_cd_t cd,uint32_t hostIRQPriority,sdio_int_t cardInt)157 void BOARD_SDIO_Config(void *card, sd_cd_t cd, uint32_t hostIRQPriority, sdio_int_t cardInt)
158 {
159 assert(card);
160
161 s_host.dmaDesBuffer = s_sdmmcHostDmaBuffer;
162 s_host.dmaDesBufferWordsNum = BOARD_SDMMC_HOST_DMA_DESCRIPTOR_BUFFER_SIZE;
163 ((sdio_card_t *)card)->host = &s_host;
164 ((sdio_card_t *)card)->host->hostController.base = BOARD_SDMMC_SDIO_HOST_BASEADDR;
165 ((sdio_card_t *)card)->host->hostController.sourceClock_Hz = BOARD_USDHC0ClockConfiguration();
166 ((sdio_card_t *)card)->host->tuningType = BOARD_SDMMC_SD_TUNING_TYPE;
167
168 ((sdio_card_t *)card)->usrParam.cd = &s_cd;
169 ((sdio_card_t *)card)->usrParam.pwr = BOARD_SDCardPowerControl;
170 ((sdio_card_t *)card)->usrParam.ioVoltage = &s_ioVoltage;
171 if (cardInt != NULL)
172 {
173 s_sdioInt.cardInterrupt = cardInt;
174 ((sdio_card_t *)card)->usrParam.sdioInt = &s_sdioInt;
175 }
176 BOARD_SDCardPowerResetInit();
177
178 BOARD_SDCardIoVoltageControlInit();
179
180 BOARD_SDCardDetectInit(cd, NULL);
181
182 NVIC_SetPriority(BOARD_SDMMC_SDIO_HOST_IRQ, hostIRQPriority);
183 }
184 #endif
185
186 #ifdef MMC_ENABLED
BOARD_MMC_Config(void * card,uint32_t hostIRQPriority)187 void BOARD_MMC_Config(void *card, uint32_t hostIRQPriority)
188 {
189 assert(card);
190
191 s_host.dmaDesBuffer = s_sdmmcHostDmaBuffer;
192 s_host.dmaDesBufferWordsNum = BOARD_SDMMC_HOST_DMA_DESCRIPTOR_BUFFER_SIZE;
193 ((mmc_card_t *)card)->host = &s_host;
194 ((mmc_card_t *)card)->host->hostController.base = BOARD_SDMMC_MMC_HOST_BASEADDR;
195 ((mmc_card_t *)card)->host->hostController.sourceClock_Hz = BOARD_USDHC0ClockConfiguration();
196 ((mmc_card_t *)card)->host->tuningType = BOARD_SDMMC_MMC_TUNING_TYPE;
197 ((mmc_card_t *)card)->hostVoltageWindowVCC = BOARD_SDMMC_MMC_VCC_SUPPLY;
198 ((mmc_card_t *)card)->hostVoltageWindowVCCQ = BOARD_SDMMC_MMC_VCCQ_SUPPLY;
199
200 ((mmc_card_t *)card)->usrParam.capability |= BOARD_SDMMC_MMC_SUPPORT_8_BIT_DATA_WIDTH;
201
202 BOARD_SDCardIoVoltageControlInit();
203 BOARD_SDCardIoVoltageControl(kSDMMC_OperationVoltage180V);
204
205 NVIC_SetPriority(BOARD_SDMMC_MMC_HOST_IRQ, hostIRQPriority);
206 }
207 #endif
208