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