1 /*
2 * Copyright 2022 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7
8 #define DT_DRV_COMPAT nxp_imx_usdhc
9
10 #include <zephyr/kernel.h>
11 #include <zephyr/devicetree.h>
12 #include <zephyr/drivers/sdhc.h>
13 #include <zephyr/sd/sd_spec.h>
14 #include <zephyr/drivers/clock_control.h>
15 #include <zephyr/drivers/gpio.h>
16 #include <zephyr/logging/log.h>
17 #include <soc.h>
18 #include <zephyr/drivers/pinctrl.h>
19 #define PINCTRL_STATE_SLOW PINCTRL_STATE_PRIV_START
20 #define PINCTRL_STATE_MED (PINCTRL_STATE_PRIV_START + 1U)
21 #define PINCTRL_STATE_FAST (PINCTRL_STATE_PRIV_START + 2U)
22 #define PINCTRL_STATE_NOPULL (PINCTRL_STATE_PRIV_START + 3U)
23
24 LOG_MODULE_REGISTER(usdhc, CONFIG_SDHC_LOG_LEVEL);
25
26 #include <fsl_usdhc.h>
27 #include <fsl_cache.h>
28 #include <zephyr/irq.h>
29
30 enum transfer_callback_status {
31 TRANSFER_CMD_COMPLETE = BIT(0),
32 TRANSFER_CMD_FAILED = BIT(1),
33 TRANSFER_DATA_COMPLETE = BIT(2),
34 TRANSFER_DATA_FAILED = BIT(3),
35 };
36
37 #define TRANSFER_CMD_FLAGS (TRANSFER_CMD_COMPLETE | TRANSFER_CMD_FAILED)
38 #define TRANSFER_DATA_FLAGS (TRANSFER_DATA_COMPLETE | TRANSFER_DATA_FAILED)
39
40 /* USDHC tuning constants */
41 #define IMX_USDHC_STANDARD_TUNING_START (10U)
42 #define IMX_USDHC_TUNING_STEP (2U)
43 #define IMX_USDHC_STANDARD_TUNING_COUNTER (60U)
44 /* Default transfer timeout in ms for tuning */
45 #define IMX_USDHC_DEFAULT_TIMEOUT (5000U)
46
47 struct usdhc_host_transfer {
48 usdhc_transfer_t *transfer;
49 k_timeout_t command_timeout;
50 k_timeout_t data_timeout;
51 };
52
53 struct usdhc_config {
54 USDHC_Type *base;
55 const struct device *clock_dev;
56 clock_control_subsys_t clock_subsys;
57 uint8_t nusdhc;
58 const struct gpio_dt_spec pwr_gpio;
59 const struct gpio_dt_spec detect_gpio;
60 bool detect_dat3;
61 bool no_180_vol;
62 uint32_t data_timeout;
63 uint32_t read_watermark;
64 uint32_t write_watermark;
65 uint32_t max_current_330;
66 uint32_t max_current_300;
67 uint32_t max_current_180;
68 uint32_t power_delay_ms;
69 uint32_t min_bus_freq;
70 uint32_t max_bus_freq;
71 bool mmc_hs200_1_8v;
72 bool mmc_hs400_1_8v;
73 const struct pinctrl_dev_config *pincfg;
74 void (*irq_config_func)(const struct device *dev);
75 };
76
77 struct usdhc_data {
78 const struct device *dev;
79 struct sdhc_host_props props;
80 bool card_present;
81 struct k_sem transfer_sem;
82 volatile uint32_t transfer_status;
83 usdhc_handle_t transfer_handle;
84 struct sdhc_io host_io;
85 struct k_mutex access_mutex;
86 sdhc_interrupt_cb_t sdhc_cb;
87 struct gpio_callback cd_callback;
88 void *sdhc_cb_user_data;
89 uint8_t usdhc_rx_dummy[128] __aligned(32);
90 #ifdef CONFIG_IMX_USDHC_DMA_SUPPORT
91 uint32_t *usdhc_dma_descriptor; /* ADMA descriptor table (noncachable) */
92 uint32_t dma_descriptor_len; /* DMA descriptor table length in words */
93 #endif
94 };
95
transfer_complete_cb(USDHC_Type * usdhc,usdhc_handle_t * handle,status_t status,void * user_data)96 static void transfer_complete_cb(USDHC_Type *usdhc, usdhc_handle_t *handle,
97 status_t status, void *user_data)
98 {
99 const struct device *dev = (const struct device *)user_data;
100 struct usdhc_data *data = dev->data;
101
102 if (status == kStatus_USDHC_TransferDataFailed) {
103 data->transfer_status |= TRANSFER_DATA_FAILED;
104 } else if (status == kStatus_USDHC_TransferDataComplete) {
105 data->transfer_status |= TRANSFER_DATA_COMPLETE;
106 } else if (status == kStatus_USDHC_SendCommandFailed) {
107 data->transfer_status |= TRANSFER_CMD_FAILED;
108 } else if (status == kStatus_USDHC_SendCommandSuccess) {
109 data->transfer_status |= TRANSFER_CMD_COMPLETE;
110 }
111 k_sem_give(&data->transfer_sem);
112 }
113
114
sdio_interrupt_cb(USDHC_Type * usdhc,void * user_data)115 static void sdio_interrupt_cb(USDHC_Type *usdhc, void *user_data)
116 {
117 const struct device *dev = user_data;
118 struct usdhc_data *data = dev->data;
119
120 if (data->sdhc_cb) {
121 data->sdhc_cb(dev, SDHC_INT_SDIO, data->sdhc_cb_user_data);
122 }
123 }
124
card_inserted_cb(USDHC_Type * usdhc,void * user_data)125 static void card_inserted_cb(USDHC_Type *usdhc, void *user_data)
126 {
127 const struct device *dev = user_data;
128 struct usdhc_data *data = dev->data;
129
130 if (data->sdhc_cb) {
131 data->sdhc_cb(dev, SDHC_INT_INSERTED, data->sdhc_cb_user_data);
132 }
133 }
134
card_removed_cb(USDHC_Type * usdhc,void * user_data)135 static void card_removed_cb(USDHC_Type *usdhc, void *user_data)
136 {
137 const struct device *dev = user_data;
138 struct usdhc_data *data = dev->data;
139
140 if (data->sdhc_cb) {
141 data->sdhc_cb(dev, SDHC_INT_REMOVED, data->sdhc_cb_user_data);
142 }
143 }
144
card_detect_gpio_cb(const struct device * port,struct gpio_callback * cb,gpio_port_pins_t pins)145 static void card_detect_gpio_cb(const struct device *port,
146 struct gpio_callback *cb,
147 gpio_port_pins_t pins)
148 {
149 struct usdhc_data *data = CONTAINER_OF(cb, struct usdhc_data, cd_callback);
150 const struct device *dev = data->dev;
151 const struct usdhc_config *cfg = dev->config;
152
153 if (data->sdhc_cb) {
154 if (gpio_pin_get_dt(&cfg->detect_gpio)) {
155 data->sdhc_cb(dev, SDHC_INT_INSERTED, data->sdhc_cb_user_data);
156 } else {
157 data->sdhc_cb(dev, SDHC_INT_REMOVED, data->sdhc_cb_user_data);
158 }
159 }
160 }
161
imx_usdhc_select_1_8v(USDHC_Type * base,bool enable_1_8v)162 static void imx_usdhc_select_1_8v(USDHC_Type *base, bool enable_1_8v)
163 {
164 #if !(defined(FSL_FEATURE_USDHC_HAS_NO_VOLTAGE_SELECT) && \
165 (FSL_FEATURE_USDHC_HAS_NO_VOLTAGE_SELECT))
166 UDSHC_SelectVoltage(base, enable_1_8v);
167 #endif
168 }
169
170
imx_usdhc_dat3_pull(const struct usdhc_config * cfg,bool pullup)171 static int imx_usdhc_dat3_pull(const struct usdhc_config *cfg, bool pullup)
172 {
173 int ret = 0U;
174
175 ret = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_NOPULL);
176 if (ret) {
177 LOG_ERR("No DAT3 floating state defined, but dat3 detect selected");
178 return ret;
179 }
180 #ifdef CONFIG_IMX_USDHC_DAT3_PWR_TOGGLE
181 if (!pullup) {
182 /* Power off the card to clear DAT3 legacy status */
183 if (cfg->pwr_gpio.port) {
184 ret = gpio_pin_set_dt(&cfg->pwr_gpio, 0);
185 if (ret) {
186 return ret;
187 }
188 /* Delay for card power off to complete */
189 k_busy_wait(1000);
190 ret = gpio_pin_set_dt(&cfg->pwr_gpio, 1);
191 /* Delay for power on */
192 k_busy_wait(1000);
193 if (ret) {
194 return ret;
195 }
196 }
197 }
198 #endif
199 return ret;
200 }
201
202 /*
203 * Reset SDHC after command error
204 */
imx_usdhc_error_recovery(const struct device * dev)205 static void imx_usdhc_error_recovery(const struct device *dev)
206 {
207 const struct usdhc_config *cfg = dev->config;
208 uint32_t status = USDHC_GetPresentStatusFlags(cfg->base);
209
210 if (status & kUSDHC_CommandInhibitFlag) {
211 /* Reset command line */
212 USDHC_Reset(cfg->base, kUSDHC_ResetCommand, 100U);
213 }
214 if (((status & (uint32_t)kUSDHC_DataInhibitFlag) != 0U) ||
215 (USDHC_GetAdmaErrorStatusFlags(cfg->base) != 0U)) {
216 /* Reset data line */
217 USDHC_Reset(cfg->base, kUSDHC_DataInhibitFlag, 100U);
218 }
219 }
220
221 /*
222 * Initialize SDHC host properties for use in get_host_props api call
223 */
imx_usdhc_init_host_props(const struct device * dev)224 static void imx_usdhc_init_host_props(const struct device *dev)
225 {
226 const struct usdhc_config *cfg = dev->config;
227 struct usdhc_data *data = dev->data;
228 usdhc_capability_t caps;
229 struct sdhc_host_props *props = &data->props;
230
231 memset(props, 0, sizeof(struct sdhc_host_props));
232 props->f_max = cfg->max_bus_freq;
233 props->f_min = cfg->min_bus_freq;
234 props->max_current_330 = cfg->max_current_330;
235 props->max_current_180 = cfg->max_current_180;
236 props->power_delay = cfg->power_delay_ms;
237 /* Read host capabilities */
238 USDHC_GetCapability(cfg->base, &caps);
239 if (cfg->no_180_vol) {
240 props->host_caps.vol_180_support = false;
241 } else {
242 props->host_caps.vol_180_support = (bool)(caps.flags & kUSDHC_SupportV180Flag);
243 }
244 props->host_caps.vol_300_support = (bool)(caps.flags & kUSDHC_SupportV300Flag);
245 props->host_caps.vol_330_support = (bool)(caps.flags & kUSDHC_SupportV330Flag);
246 props->host_caps.suspend_res_support = (bool)(caps.flags & kUSDHC_SupportSuspendResumeFlag);
247 props->host_caps.sdma_support = (bool)(caps.flags & kUSDHC_SupportDmaFlag);
248 props->host_caps.high_spd_support = (bool)(caps.flags & kUSDHC_SupportHighSpeedFlag);
249 props->host_caps.adma_2_support = (bool)(caps.flags & kUSDHC_SupportAdmaFlag);
250 props->host_caps.max_blk_len = (bool)(caps.maxBlockLength);
251 props->host_caps.ddr50_support = (bool)(caps.flags & kUSDHC_SupportDDR50Flag);
252 props->host_caps.sdr104_support = (bool)(caps.flags & kUSDHC_SupportSDR104Flag);
253 props->host_caps.sdr50_support = (bool)(caps.flags & kUSDHC_SupportSDR50Flag);
254 props->host_caps.bus_8_bit_support = (bool)(caps.flags & kUSDHC_Support8BitFlag);
255 props->host_caps.bus_4_bit_support = (bool)(caps.flags & kUSDHC_Support4BitFlag);
256 props->host_caps.hs200_support = (bool)(cfg->mmc_hs200_1_8v);
257 props->host_caps.hs400_support = (bool)(cfg->mmc_hs400_1_8v);
258 }
259
260 /*
261 * Reset USDHC controller
262 */
imx_usdhc_reset(const struct device * dev)263 static int imx_usdhc_reset(const struct device *dev)
264 {
265 const struct usdhc_config *cfg = dev->config;
266 /* Switch to default I/O voltage of 3.3V */
267 imx_usdhc_select_1_8v(cfg->base, false);
268 USDHC_EnableDDRMode(cfg->base, false, 0U);
269 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE)
270 USDHC_EnableStandardTuning(cfg->base, 0, 0, false);
271 USDHC_EnableAutoTuning(cfg->base, false);
272 #endif
273
274 #if FSL_FEATURE_USDHC_HAS_HS400_MODE
275 /* Disable HS400 mode */
276 USDHC_EnableHS400Mode(cfg->base, false);
277 /* Disable DLL */
278 USDHC_EnableStrobeDLL(cfg->base, false);
279 #endif
280
281 /* Reset data/command/tuning circuit */
282 return USDHC_Reset(cfg->base, kUSDHC_ResetAll, 1000U) == true ? 0 : -ETIMEDOUT;
283 }
284
285 /*
286 * Set SDHC io properties
287 */
imx_usdhc_set_io(const struct device * dev,struct sdhc_io * ios)288 static int imx_usdhc_set_io(const struct device *dev, struct sdhc_io *ios)
289 {
290 const struct usdhc_config *cfg = dev->config;
291 struct usdhc_data *data = dev->data;
292 uint32_t src_clk_hz, bus_clk;
293 struct sdhc_io *host_io = &data->host_io;
294
295 LOG_DBG("SDHC I/O: bus width %d, clock %dHz, card power %s, voltage %s",
296 ios->bus_width,
297 ios->clock,
298 ios->power_mode == SDHC_POWER_ON ? "ON" : "OFF",
299 ios->signal_voltage == SD_VOL_1_8_V ? "1.8V" : "3.3V"
300 );
301
302 if (clock_control_get_rate(cfg->clock_dev,
303 cfg->clock_subsys,
304 &src_clk_hz)) {
305 return -EINVAL;
306 }
307
308 if (ios->clock && (ios->clock > data->props.f_max || ios->clock < data->props.f_min)) {
309 return -EINVAL;
310 }
311
312 /* Set host clock */
313 if (host_io->clock != ios->clock) {
314 if (ios->clock != 0) {
315 /* Enable the clock output */
316 bus_clk = USDHC_SetSdClock(cfg->base, src_clk_hz, ios->clock);
317 LOG_DBG("BUS CLOCK: %d", bus_clk);
318 if (bus_clk == 0) {
319 return -ENOTSUP;
320 }
321 }
322 host_io->clock = ios->clock;
323 }
324
325
326 /* Set bus width */
327 if (host_io->bus_width != ios->bus_width) {
328 switch (ios->bus_width) {
329 case SDHC_BUS_WIDTH1BIT:
330 USDHC_SetDataBusWidth(cfg->base, kUSDHC_DataBusWidth1Bit);
331 break;
332 case SDHC_BUS_WIDTH4BIT:
333 USDHC_SetDataBusWidth(cfg->base, kUSDHC_DataBusWidth4Bit);
334 break;
335 case SDHC_BUS_WIDTH8BIT:
336 USDHC_SetDataBusWidth(cfg->base, kUSDHC_DataBusWidth8Bit);
337 break;
338 default:
339 return -ENOTSUP;
340 }
341 host_io->bus_width = ios->bus_width;
342 }
343
344 /* Set host signal voltage */
345 if (ios->signal_voltage != host_io->signal_voltage) {
346 switch (ios->signal_voltage) {
347 case SD_VOL_3_3_V:
348 case SD_VOL_3_0_V:
349 imx_usdhc_select_1_8v(cfg->base, false);
350 break;
351 case SD_VOL_1_8_V:
352 /**
353 * USDHC peripheral deviates from SD spec here.
354 * The host controller specification claims
355 * the "SD clock enable" bit can be used to gate the SD
356 * clock by clearing it. The USDHC controller does not
357 * provide this bit, only a way to force the SD clock
358 * on. We will instead delay 10 ms to allow the clock
359 * to be gated for enough time, then force it on for
360 * 10 ms, then allow it to be gated again.
361 */
362 /* Switch to 1.8V */
363 imx_usdhc_select_1_8v(cfg->base, true);
364 /* Wait 10 ms- clock will be gated during this period */
365 k_msleep(10);
366 /* Force the clock on */
367 USDHC_ForceClockOn(cfg->base, true);
368 /* Keep the clock on for a moment, so SD will recognize it */
369 k_msleep(10);
370 /* Stop forcing clock on */
371 USDHC_ForceClockOn(cfg->base, false);
372 break;
373 default:
374 return -ENOTSUP;
375 }
376 /* Save new host voltage */
377 host_io->signal_voltage = ios->signal_voltage;
378 }
379
380 /* Set card power */
381 if ((host_io->power_mode != ios->power_mode) && (cfg->pwr_gpio.port)) {
382 if (ios->power_mode == SDHC_POWER_OFF) {
383 gpio_pin_set_dt(&cfg->pwr_gpio, 0);
384 } else if (ios->power_mode == SDHC_POWER_ON) {
385 gpio_pin_set_dt(&cfg->pwr_gpio, 1);
386 }
387 host_io->power_mode = ios->power_mode;
388 }
389
390 /* Set I/O timing */
391 if (host_io->timing != ios->timing) {
392 switch (ios->timing) {
393 case SDHC_TIMING_LEGACY:
394 case SDHC_TIMING_HS:
395 break;
396 case SDHC_TIMING_DDR50:
397 case SDHC_TIMING_DDR52:
398 /* Enable DDR mode */
399 USDHC_EnableDDRMode(cfg->base, true, 0);
400 __fallthrough;
401 case SDHC_TIMING_SDR12:
402 case SDHC_TIMING_SDR25:
403 pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_SLOW);
404 break;
405 case SDHC_TIMING_SDR50:
406 pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_MED);
407 break;
408 case SDHC_TIMING_HS400:
409 #if FSL_FEATURE_USDHC_HAS_HS400_MODE
410 USDHC_EnableHS400Mode(cfg->base, true);
411 USDHC_EnableDDRMode(cfg->base, true, 0U);
412 USDHC_ConfigStrobeDLL(cfg->base, 7U, 4U);
413 USDHC_EnableStrobeDLL(cfg->base, true);
414 #else
415 LOG_ERR("HS400 not supported for this device");
416 return -ENOTSUP;
417 #endif
418 case SDHC_TIMING_SDR104:
419 case SDHC_TIMING_HS200:
420 pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_FAST);
421 break;
422 default:
423 return -ENOTSUP;
424 }
425 host_io->timing = ios->timing;
426 }
427
428 return 0;
429 }
430
431 /*
432 * Internal transfer function, used by tuning and request apis
433 */
imx_usdhc_transfer(const struct device * dev,struct usdhc_host_transfer * request)434 static int imx_usdhc_transfer(const struct device *dev,
435 struct usdhc_host_transfer *request)
436 {
437 const struct usdhc_config *cfg = dev->config;
438 struct usdhc_data *dev_data = dev->data;
439 status_t error;
440 #ifdef CONFIG_IMX_USDHC_DMA_SUPPORT
441 usdhc_adma_config_t dma_config = {0};
442
443 /* Configure DMA */
444 dma_config.admaTable = dev_data->usdhc_dma_descriptor;
445 dma_config.admaTableWords = dev_data->dma_descriptor_len;
446 #if !(defined(FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN) && FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN)
447 dma_config.burstLen = kUSDHC_EnBurstLenForINCR;
448 #endif
449 dma_config.dmaMode = kUSDHC_DmaModeAdma2;
450 #endif /* CONFIG_IMX_USDHC_DMA_SUPPORT */
451
452 /* Reset transfer status */
453 dev_data->transfer_status = 0U;
454 /* Reset semaphore */
455 k_sem_reset(&dev_data->transfer_sem);
456 #ifdef CONFIG_IMX_USDHC_DMA_SUPPORT
457 error = USDHC_TransferNonBlocking(cfg->base, &dev_data->transfer_handle,
458 &dma_config, request->transfer);
459 #else
460 error = USDHC_TransferNonBlocking(cfg->base, &dev_data->transfer_handle,
461 NULL, request->transfer);
462 #endif
463 if (error == kStatus_USDHC_ReTuningRequest) {
464 return -EAGAIN;
465 } else if (error != kStatus_Success) {
466 return -EIO;
467 }
468 /* Wait for event to occur */
469 while ((dev_data->transfer_status & (TRANSFER_CMD_FLAGS | TRANSFER_DATA_FLAGS)) == 0) {
470 if (k_sem_take(&dev_data->transfer_sem, request->command_timeout)) {
471 return -ETIMEDOUT;
472 }
473 }
474 if (dev_data->transfer_status & TRANSFER_CMD_FAILED) {
475 return -EIO;
476 }
477 /* If data was sent, wait for that to complete */
478 if (request->transfer->data) {
479 while ((dev_data->transfer_status & TRANSFER_DATA_FLAGS) == 0) {
480 if (k_sem_take(&dev_data->transfer_sem, request->data_timeout)) {
481 return -ETIMEDOUT;
482 }
483 }
484 if (dev_data->transfer_status & TRANSFER_DATA_FAILED) {
485 return -EIO;
486 }
487 }
488 return 0;
489 }
490
491 /* Stops transmission after failed command with CMD12 */
imx_usdhc_stop_transmission(const struct device * dev)492 static void imx_usdhc_stop_transmission(const struct device *dev)
493 {
494 usdhc_command_t stop_cmd = {0};
495 struct usdhc_host_transfer request;
496 usdhc_transfer_t transfer;
497
498 /* Send CMD12 to stop transmission */
499 stop_cmd.index = SD_STOP_TRANSMISSION;
500 stop_cmd.argument = 0U;
501 stop_cmd.type = kCARD_CommandTypeAbort;
502 stop_cmd.responseType = SD_RSP_TYPE_R1b;
503 transfer.command = &stop_cmd;
504 transfer.data = NULL;
505
506 request.transfer = &transfer;
507 request.command_timeout = K_MSEC(IMX_USDHC_DEFAULT_TIMEOUT);
508 request.data_timeout = K_MSEC(IMX_USDHC_DEFAULT_TIMEOUT);
509
510 imx_usdhc_transfer(dev, &request);
511 }
512
513 /*
514 * Return 0 if card is not busy, 1 if it is
515 */
imx_usdhc_card_busy(const struct device * dev)516 static int imx_usdhc_card_busy(const struct device *dev)
517 {
518 const struct usdhc_config *cfg = dev->config;
519
520 return (USDHC_GetPresentStatusFlags(cfg->base)
521 & (kUSDHC_Data0LineLevelFlag |
522 kUSDHC_Data1LineLevelFlag |
523 kUSDHC_Data2LineLevelFlag |
524 kUSDHC_Data3LineLevelFlag))
525 ? 0 : 1;
526 }
527
528 /*
529 * Execute card tuning
530 */
imx_usdhc_execute_tuning(const struct device * dev)531 static int imx_usdhc_execute_tuning(const struct device *dev)
532 {
533 const struct usdhc_config *cfg = dev->config;
534 struct usdhc_data *dev_data = dev->data;
535 usdhc_command_t cmd = {0};
536 usdhc_data_t data = {0};
537 struct usdhc_host_transfer request;
538 usdhc_transfer_t transfer;
539 int ret;
540 bool retry_tuning = true;
541
542 if ((dev_data->host_io.timing == SDHC_TIMING_HS200) ||
543 (dev_data->host_io.timing == SDHC_TIMING_HS400)) {
544 /*Currently only reaches here when MMC */
545 cmd.index = MMC_SEND_TUNING_BLOCK;
546 } else {
547 cmd.index = SD_SEND_TUNING_BLOCK;
548 }
549 cmd.argument = 0;
550 cmd.responseType = SD_RSP_TYPE_R1;
551
552 if (dev_data->host_io.bus_width == SDHC_BUS_WIDTH8BIT) {
553 data.blockSize = sizeof(dev_data->usdhc_rx_dummy);
554 } else {
555 data.blockSize = sizeof(dev_data->usdhc_rx_dummy) / 2;
556 }
557 data.blockCount = 1;
558 data.rxData = (uint32_t *)dev_data->usdhc_rx_dummy;
559 data.dataType = kUSDHC_TransferDataTuning;
560
561 transfer.command = &cmd;
562 transfer.data = &data;
563
564 /* Reset tuning circuit */
565 USDHC_Reset(cfg->base, kUSDHC_ResetTuning, 100U);
566 /* Disable standard tuning */
567 USDHC_EnableStandardTuning(cfg->base, IMX_USDHC_STANDARD_TUNING_START,
568 IMX_USDHC_TUNING_STEP, false);
569 USDHC_ForceClockOn(cfg->base, true);
570 /*
571 * Tuning fail found on some SOCs is caused by the different of delay
572 * cell, so we need to increase the tuning counter to cover the
573 * adjustable tuning window
574 */
575 USDHC_SetStandardTuningCounter(cfg->base, IMX_USDHC_STANDARD_TUNING_COUNTER);
576 /* Reenable standard tuning */
577 USDHC_EnableStandardTuning(cfg->base, IMX_USDHC_STANDARD_TUNING_START,
578 IMX_USDHC_TUNING_STEP, true);
579
580 request.command_timeout = K_MSEC(IMX_USDHC_DEFAULT_TIMEOUT);
581 request.data_timeout = K_MSEC(IMX_USDHC_DEFAULT_TIMEOUT);
582 request.transfer = &transfer;
583
584 while (true) {
585 ret = imx_usdhc_transfer(dev, &request);
586 if (ret) {
587 return ret;
588 }
589 /* Delay 1ms */
590 k_busy_wait(1000);
591
592 /* Wait for execute tuning bit to clear */
593 if (USDHC_GetExecuteStdTuningStatus(cfg->base) != 0) {
594 continue;
595 }
596 /* If tuning had error, retry tuning */
597 if ((USDHC_CheckTuningError(cfg->base) != 0U) && retry_tuning) {
598 retry_tuning = false;
599 /* Enable standard tuning */
600 USDHC_EnableStandardTuning(cfg->base,
601 IMX_USDHC_STANDARD_TUNING_START,
602 IMX_USDHC_TUNING_STEP, true);
603 USDHC_SetTuningDelay(cfg->base,
604 IMX_USDHC_STANDARD_TUNING_START, 0U, 0U);
605 } else {
606 break;
607 }
608 }
609
610 /* Check tuning result */
611 if (USDHC_CheckStdTuningResult(cfg->base) == 0) {
612 return -EIO;
613 }
614 USDHC_ForceClockOn(cfg->base, false);
615
616 /* Enable auto tuning */
617 USDHC_EnableAutoTuning(cfg->base, true);
618 return 0;
619 }
620
621 /*
622 * Send CMD or CMD/DATA via SDHC
623 */
imx_usdhc_request(const struct device * dev,struct sdhc_command * cmd,struct sdhc_data * data)624 static int imx_usdhc_request(const struct device *dev, struct sdhc_command *cmd,
625 struct sdhc_data *data)
626 {
627 const struct usdhc_config *cfg = dev->config;
628 struct usdhc_data *dev_data = dev->data;
629 usdhc_command_t host_cmd = {0};
630 usdhc_data_t host_data = {0};
631 struct usdhc_host_transfer request;
632 usdhc_transfer_t transfer;
633 int busy_timeout = IMX_USDHC_DEFAULT_TIMEOUT;
634 int ret = 0;
635 int retries = (int)cmd->retries;
636
637 if (cmd->opcode == SD_GO_IDLE_STATE) {
638 USDHC_SetCardActive(cfg->base, 0xFFFF);
639 }
640
641 host_cmd.index = cmd->opcode;
642 host_cmd.argument = cmd->arg;
643 /* Mask out part of response type field used for SPI commands */
644 host_cmd.responseType = (cmd->response_type & SDHC_NATIVE_RESPONSE_MASK);
645 transfer.command = &host_cmd;
646 if (cmd->timeout_ms == SDHC_TIMEOUT_FOREVER) {
647 request.command_timeout = K_FOREVER;
648 } else {
649 request.command_timeout = K_MSEC(cmd->timeout_ms);
650 }
651
652 if (data) {
653 host_data.blockSize = data->block_size;
654 host_data.blockCount = data->blocks;
655 /*
656 * Determine type of command. Note that driver is expected to
657 * handle CMD12 and CMD23 for reading and writing blocks
658 */
659 switch (cmd->opcode) {
660 case SD_WRITE_SINGLE_BLOCK:
661 host_data.enableAutoCommand12 = true;
662 host_data.txData = data->data;
663 break;
664 case SD_WRITE_MULTIPLE_BLOCK:
665 if (dev_data->host_io.timing == SDHC_TIMING_SDR104) {
666 /* Card uses UHS104, so it must support CMD23 */
667 host_data.enableAutoCommand23 = true;
668 } else {
669 /* No CMD23 support */
670 host_data.enableAutoCommand12 = true;
671 }
672 host_data.txData = data->data;
673 break;
674 case SD_READ_SINGLE_BLOCK:
675 host_data.enableAutoCommand12 = true;
676 host_data.rxData = data->data;
677 break;
678 case SD_READ_MULTIPLE_BLOCK:
679 if (dev_data->host_io.timing == SDHC_TIMING_SDR104) {
680 /* Card uses UHS104, so it must support CMD23 */
681 host_data.enableAutoCommand23 = true;
682 } else {
683 /* No CMD23 support */
684 host_data.enableAutoCommand12 = true;
685 }
686 host_data.rxData = data->data;
687 break;
688 case MMC_CHECK_BUS_TEST:
689 case MMC_SEND_EXT_CSD:
690 case SD_APP_SEND_SCR:
691 case SD_SWITCH:
692 case SD_APP_SEND_NUM_WRITTEN_BLK:
693 host_data.rxData = data->data;
694 break;
695 case SDIO_RW_EXTENDED:
696 /* Use R/W bit to determine data direction */
697 if (host_cmd.argument & BIT(SDIO_CMD_ARG_RW_SHIFT)) {
698 host_data.txData = data->data;
699 } else {
700 host_data.rxData = data->data;
701 }
702 break;
703 default:
704 return -ENOTSUP;
705
706 }
707 transfer.data = &host_data;
708 if (data->timeout_ms == SDHC_TIMEOUT_FOREVER) {
709 request.data_timeout = K_FOREVER;
710 } else {
711 request.data_timeout = K_MSEC(data->timeout_ms);
712 }
713 } else {
714 transfer.data = NULL;
715 request.data_timeout = K_NO_WAIT;
716 }
717 request.transfer = &transfer;
718
719 /* Ensure we have exclusive access to SD card before sending request */
720 if (k_mutex_lock(&dev_data->access_mutex, request.command_timeout) != 0) {
721 return -EBUSY;
722 }
723 while (retries >= 0) {
724 ret = imx_usdhc_transfer(dev, &request);
725 if (ret && data) {
726 /*
727 * Disable and clear interrupts. If the data transmission
728 * completes later, we will encounter issues because
729 * the USDHC driver expects data to be present in the
730 * current transmission, but CMD12 does not contain data
731 */
732 USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CommandFlag |
733 kUSDHC_DataFlag | kUSDHC_DataDMAFlag);
734 USDHC_ClearInterruptStatusFlags(cfg->base, kUSDHC_CommandFlag |
735 kUSDHC_DataFlag | kUSDHC_DataDMAFlag);
736 /* Stop transmission with CMD12 in case of data error */
737 imx_usdhc_stop_transmission(dev);
738 /* Wait for card to go idle */
739 while (busy_timeout > 0) {
740 if (!imx_usdhc_card_busy(dev)) {
741 break;
742 }
743 /* Wait 125us before polling again */
744 k_busy_wait(125);
745 busy_timeout -= 125;
746 }
747 if (busy_timeout <= 0) {
748 LOG_DBG("Card did not idle after CMD12");
749 k_mutex_unlock(&dev_data->access_mutex);
750 return -ETIMEDOUT;
751 }
752 }
753 if (ret == -EAGAIN) {
754 /* Retry, card made a tuning request */
755 if (dev_data->host_io.timing == SDHC_TIMING_SDR50 ||
756 dev_data->host_io.timing == SDHC_TIMING_SDR104 ||
757 dev_data->host_io.timing == SDHC_TIMING_HS200 ||
758 dev_data->host_io.timing == SDHC_TIMING_HS400) {
759 /* Retune card */
760 LOG_DBG("Card made tuning request, retune");
761 ret = imx_usdhc_execute_tuning(dev);
762 if (ret) {
763 LOG_DBG("Card failed to tune");
764 k_mutex_unlock(&dev_data->access_mutex);
765 return ret;
766 }
767 }
768 }
769 if (ret) {
770 imx_usdhc_error_recovery(dev);
771 retries--;
772 } else {
773 break;
774 }
775 }
776
777 /* Release access on card */
778 k_mutex_unlock(&dev_data->access_mutex);
779 /* Record command response */
780 memcpy(cmd->response, host_cmd.response, sizeof(cmd->response));
781 if (data) {
782 /* Record number of bytes xfered */
783 data->bytes_xfered = dev_data->transfer_handle.transferredWords;
784 }
785 return ret;
786 }
787
788 /*
789 * Get card presence
790 */
imx_usdhc_get_card_present(const struct device * dev)791 static int imx_usdhc_get_card_present(const struct device *dev)
792 {
793 const struct usdhc_config *cfg = dev->config;
794 struct usdhc_data *data = dev->data;
795
796 if (cfg->detect_dat3) {
797 /*
798 * If card is already present, do not retry detection.
799 * Power line toggling would reset SD card
800 */
801 if (!data->card_present) {
802 /* Detect card presence with DAT3 line pull */
803 imx_usdhc_dat3_pull(cfg, false);
804 USDHC_CardDetectByData3(cfg->base, true);
805 /* Delay to ensure host has time to detect card */
806 k_busy_wait(1000);
807 data->card_present = USDHC_DetectCardInsert(cfg->base);
808 /* Clear card detection and pull */
809 imx_usdhc_dat3_pull(cfg, true);
810 USDHC_CardDetectByData3(cfg->base, false);
811 }
812 } else if (cfg->detect_gpio.port) {
813 data->card_present = gpio_pin_get_dt(&cfg->detect_gpio) > 0;
814 } else {
815 data->card_present = USDHC_DetectCardInsert(cfg->base);
816 }
817 return ((int)data->card_present);
818 }
819
820 /*
821 * Get host properties
822 */
imx_usdhc_get_host_props(const struct device * dev,struct sdhc_host_props * props)823 static int imx_usdhc_get_host_props(const struct device *dev,
824 struct sdhc_host_props *props)
825 {
826 struct usdhc_data *data = dev->data;
827
828 memcpy(props, &data->props, sizeof(struct sdhc_host_props));
829 return 0;
830 }
831
832 /*
833 * Enable SDHC card interrupt
834 */
imx_usdhc_enable_interrupt(const struct device * dev,sdhc_interrupt_cb_t callback,int sources,void * user_data)835 static int imx_usdhc_enable_interrupt(const struct device *dev,
836 sdhc_interrupt_cb_t callback,
837 int sources, void *user_data)
838 {
839 const struct usdhc_config *cfg = dev->config;
840 struct usdhc_data *data = dev->data;
841 int ret;
842
843 /* Record SDIO callback parameters */
844 data->sdhc_cb = callback;
845 data->sdhc_cb_user_data = user_data;
846
847 /* Disable interrupts, then enable what the user requested */
848 USDHC_DisableInterruptStatus(cfg->base, kUSDHC_CardInterruptFlag);
849 USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CardInterruptFlag);
850 if (cfg->detect_gpio.port) {
851 ret = gpio_pin_interrupt_configure_dt(&cfg->detect_gpio,
852 GPIO_INT_DISABLE);
853 if (ret) {
854 return ret;
855 }
856 } else {
857 USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CardInsertionFlag);
858 USDHC_DisableInterruptStatus(cfg->base, kUSDHC_CardInsertionFlag);
859 USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CardRemovalFlag);
860 USDHC_DisableInterruptStatus(cfg->base, kUSDHC_CardRemovalFlag);
861 }
862
863 if (sources & SDHC_INT_SDIO) {
864 /* Enable SDIO card interrupt */
865 USDHC_EnableInterruptStatus(cfg->base, kUSDHC_CardInterruptFlag);
866 USDHC_EnableInterruptSignal(cfg->base, kUSDHC_CardInterruptFlag);
867 }
868 if (sources & SDHC_INT_INSERTED) {
869 if (cfg->detect_gpio.port) {
870 /* Use GPIO interrupt */
871 ret = gpio_pin_interrupt_configure_dt(&cfg->detect_gpio,
872 GPIO_INT_EDGE_TO_ACTIVE);
873 if (ret) {
874 return ret;
875 }
876 } else {
877 /* Enable card insertion interrupt */
878 USDHC_EnableInterruptStatus(cfg->base,
879 kUSDHC_CardInsertionFlag);
880 USDHC_EnableInterruptSignal(cfg->base,
881 kUSDHC_CardInsertionFlag);
882 }
883 }
884 if (sources & SDHC_INT_REMOVED) {
885 if (cfg->detect_gpio.port) {
886 /* Use GPIO interrupt */
887 ret = gpio_pin_interrupt_configure_dt(&cfg->detect_gpio,
888 GPIO_INT_EDGE_TO_INACTIVE);
889 if (ret) {
890 return ret;
891 }
892 } else {
893 /* Enable card removal interrupt */
894 USDHC_EnableInterruptStatus(cfg->base,
895 kUSDHC_CardRemovalFlag);
896 USDHC_EnableInterruptSignal(cfg->base,
897 kUSDHC_CardRemovalFlag);
898 }
899 }
900
901 return 0;
902 }
903
imx_usdhc_disable_interrupt(const struct device * dev,int sources)904 static int imx_usdhc_disable_interrupt(const struct device *dev, int sources)
905 {
906 const struct usdhc_config *cfg = dev->config;
907 struct usdhc_data *data = dev->data;
908 int ret;
909
910
911 if (sources & SDHC_INT_SDIO) {
912 /* Disable SDIO card interrupt */
913 USDHC_DisableInterruptStatus(cfg->base, kUSDHC_CardInterruptFlag);
914 USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CardInterruptFlag);
915 }
916 if (sources & SDHC_INT_INSERTED) {
917 if (cfg->detect_gpio.port) {
918 ret = gpio_pin_interrupt_configure_dt(&cfg->detect_gpio,
919 GPIO_INT_DISABLE);
920 if (ret) {
921 return ret;
922 }
923 } else {
924 /* Disable card insertion interrupt */
925 USDHC_DisableInterruptStatus(cfg->base,
926 kUSDHC_CardInsertionFlag);
927 USDHC_DisableInterruptSignal(cfg->base,
928 kUSDHC_CardInsertionFlag);
929 }
930 }
931 if (sources & SDHC_INT_REMOVED) {
932 if (cfg->detect_gpio.port) {
933 ret = gpio_pin_interrupt_configure_dt(&cfg->detect_gpio,
934 GPIO_INT_DISABLE);
935 if (ret) {
936 return ret;
937 }
938 } else {
939 /* Disable card removal interrupt */
940 USDHC_DisableInterruptStatus(cfg->base,
941 kUSDHC_CardRemovalFlag);
942 USDHC_DisableInterruptSignal(cfg->base,
943 kUSDHC_CardRemovalFlag);
944 }
945 }
946
947 /* If all interrupt flags are disabled, remove callback */
948 if ((USDHC_GetEnabledInterruptStatusFlags(cfg->base) &
949 (kUSDHC_CardInterruptFlag | kUSDHC_CardInsertionFlag |
950 kUSDHC_CardRemovalFlag)) == 0) {
951 data->sdhc_cb = NULL;
952 data->sdhc_cb_user_data = NULL;
953 }
954
955 return 0;
956 }
957
imx_usdhc_isr(const struct device * dev)958 static int imx_usdhc_isr(const struct device *dev)
959 {
960 const struct usdhc_config *cfg = dev->config;
961 struct usdhc_data *data = dev->data;
962
963 USDHC_TransferHandleIRQ(cfg->base, &data->transfer_handle);
964 return 0;
965 }
966
967 /*
968 * Perform early system init for SDHC
969 */
imx_usdhc_init(const struct device * dev)970 static int imx_usdhc_init(const struct device *dev)
971 {
972 const struct usdhc_config *cfg = dev->config;
973 struct usdhc_data *data = dev->data;
974 usdhc_config_t host_config = {0};
975 int ret;
976 const usdhc_transfer_callback_t callbacks = {
977 .TransferComplete = transfer_complete_cb,
978 .SdioInterrupt = sdio_interrupt_cb,
979 .CardInserted = card_inserted_cb,
980 .CardRemoved = card_removed_cb,
981 };
982
983 if (!device_is_ready(cfg->clock_dev)) {
984 LOG_ERR("clock control device not ready");
985 return -ENODEV;
986 }
987
988 ret = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT);
989 if (ret) {
990 return ret;
991 }
992 USDHC_TransferCreateHandle(cfg->base, &data->transfer_handle,
993 &callbacks, (void *)dev);
994 cfg->irq_config_func(dev);
995
996
997 host_config.dataTimeout = cfg->data_timeout;
998 host_config.endianMode = kUSDHC_EndianModeLittle;
999 host_config.readWatermarkLevel = cfg->read_watermark;
1000 host_config.writeWatermarkLevel = cfg->write_watermark;
1001 USDHC_Init(cfg->base, &host_config);
1002 /* Read host controller properties */
1003 imx_usdhc_init_host_props(dev);
1004 /* Set power GPIO low, so card starts powered off */
1005 if (cfg->pwr_gpio.port) {
1006 ret = gpio_pin_configure_dt(&cfg->pwr_gpio, GPIO_OUTPUT_INACTIVE);
1007 if (ret) {
1008 return ret;
1009 }
1010 } else {
1011 LOG_WRN("No power control GPIO defined. Without power control,\n"
1012 "the SD card may fail to communicate with the host");
1013 }
1014 if (cfg->detect_gpio.port) {
1015 ret = gpio_pin_configure_dt(&cfg->detect_gpio, GPIO_INPUT);
1016 if (ret) {
1017 return ret;
1018 }
1019 gpio_init_callback(&data->cd_callback, card_detect_gpio_cb,
1020 BIT(cfg->detect_gpio.pin));
1021 ret = gpio_add_callback_dt(&cfg->detect_gpio, &data->cd_callback);
1022 if (ret) {
1023 return ret;
1024 }
1025 }
1026 data->dev = dev;
1027 k_mutex_init(&data->access_mutex);
1028 /* Setup initial host IO values */
1029 data->host_io.clock = 0;
1030 data->host_io.bus_mode = SDHC_BUSMODE_PUSHPULL;
1031 data->host_io.power_mode = SDHC_POWER_OFF;
1032 data->host_io.bus_width = SDHC_BUS_WIDTH1BIT;
1033 data->host_io.timing = SDHC_TIMING_LEGACY;
1034 data->host_io.driver_type = SD_DRIVER_TYPE_B;
1035 data->host_io.signal_voltage = SD_VOL_3_3_V;
1036
1037 return k_sem_init(&data->transfer_sem, 0, 1);
1038 }
1039
1040 static const struct sdhc_driver_api usdhc_api = {
1041 .reset = imx_usdhc_reset,
1042 .request = imx_usdhc_request,
1043 .set_io = imx_usdhc_set_io,
1044 .get_card_present = imx_usdhc_get_card_present,
1045 .execute_tuning = imx_usdhc_execute_tuning,
1046 .card_busy = imx_usdhc_card_busy,
1047 .get_host_props = imx_usdhc_get_host_props,
1048 .enable_interrupt = imx_usdhc_enable_interrupt,
1049 .disable_interrupt = imx_usdhc_disable_interrupt,
1050 };
1051
1052 #ifdef CONFIG_NOCACHE_MEMORY
1053 #define IMX_USDHC_NOCACHE_TAG __attribute__((__section__(".nocache")));
1054 #else
1055 #define IMX_USDHC_NOCACHE_TAG
1056 #endif
1057
1058 #ifdef CONFIG_IMX_USDHC_DMA_SUPPORT
1059 #define IMX_USDHC_DMA_BUFFER_DEFINE(n) \
1060 static uint32_t __aligned(32) \
1061 usdhc_##n##_dma_descriptor[CONFIG_IMX_USDHC_DMA_BUFFER_SIZE / 4]\
1062 IMX_USDHC_NOCACHE_TAG;
1063 #define IMX_USDHC_DMA_BUFFER_INIT(n) \
1064 .usdhc_dma_descriptor = usdhc_##n##_dma_descriptor, \
1065 .dma_descriptor_len = CONFIG_IMX_USDHC_DMA_BUFFER_SIZE / 4,
1066 #else
1067 #define IMX_USDHC_DMA_BUFFER_DEFINE(n)
1068 #define IMX_USDHC_DMA_BUFFER_INIT(n)
1069 #endif /* CONFIG_IMX_USDHC_DMA_SUPPORT */
1070
1071
1072
1073 #define IMX_USDHC_INIT(n) \
1074 static void usdhc_##n##_irq_config_func(const struct device *dev) \
1075 { \
1076 IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \
1077 imx_usdhc_isr, DEVICE_DT_INST_GET(n), 0); \
1078 irq_enable(DT_INST_IRQN(n)); \
1079 } \
1080 \
1081 PINCTRL_DT_INST_DEFINE(n); \
1082 \
1083 static const struct usdhc_config usdhc_##n##_config = { \
1084 .base = (USDHC_Type *) DT_INST_REG_ADDR(n), \
1085 .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \
1086 .clock_subsys = \
1087 (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \
1088 .nusdhc = n, \
1089 .pwr_gpio = GPIO_DT_SPEC_INST_GET_OR(n, pwr_gpios, {0}), \
1090 .detect_gpio = GPIO_DT_SPEC_INST_GET_OR(n, cd_gpios, {0}), \
1091 .data_timeout = DT_INST_PROP(n, data_timeout), \
1092 .detect_dat3 = DT_INST_PROP(n, detect_dat3), \
1093 .no_180_vol = DT_INST_PROP(n, no_1_8_v), \
1094 .read_watermark = DT_INST_PROP(n, read_watermark), \
1095 .write_watermark = DT_INST_PROP(n, write_watermark), \
1096 .max_current_330 = DT_INST_PROP(n, max_current_330), \
1097 .max_current_180 = DT_INST_PROP(n, max_current_180), \
1098 .min_bus_freq = DT_INST_PROP(n, min_bus_freq), \
1099 .max_bus_freq = DT_INST_PROP(n, max_bus_freq), \
1100 .power_delay_ms = DT_INST_PROP(n, power_delay_ms), \
1101 .mmc_hs200_1_8v = DT_INST_PROP(n, mmc_hs200_1_8v), \
1102 .mmc_hs400_1_8v = DT_INST_PROP(n, mmc_hs400_1_8v), \
1103 .irq_config_func = usdhc_##n##_irq_config_func, \
1104 .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
1105 }; \
1106 \
1107 \
1108 IMX_USDHC_DMA_BUFFER_DEFINE(n) \
1109 \
1110 static struct usdhc_data usdhc_##n##_data = { \
1111 .card_present = false, \
1112 IMX_USDHC_DMA_BUFFER_INIT(n) \
1113 }; \
1114 \
1115 DEVICE_DT_INST_DEFINE(n, \
1116 &imx_usdhc_init, \
1117 NULL, \
1118 &usdhc_##n##_data, \
1119 &usdhc_##n##_config, \
1120 POST_KERNEL, \
1121 CONFIG_SDHC_INIT_PRIORITY, \
1122 &usdhc_api);
1123
1124 DT_INST_FOREACH_STATUS_OKAY(IMX_USDHC_INIT)
1125