1 /*
2 * Copyright (c) 2019 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT nxp_imx_usdhc
8
9 #include <sys/__assert.h>
10 #include <drivers/disk.h>
11 #include <drivers/gpio.h>
12 #include <sys/byteorder.h>
13 #include <soc.h>
14 #include <drivers/clock_control.h>
15
16 #include "sdmmc_sdhc.h"
17
18 #include <logging/log.h>
19 LOG_MODULE_REGISTER(usdhc, CONFIG_SDMMC_LOG_LEVEL);
20
21 enum usdhc_cmd_type {
22 USDHC_CMD_TYPE_NORMAL = 0U,
23 /*!< Normal command */
24 USDHC_CMD_TYPE_SUSPEND = 1U,
25 /*!< Suspend command */
26 USDHC_CMD_TYPE_RESUME = 2U,
27 /*!< Resume command */
28 USDHC_CMD_TYPE_ABORT = 3U,
29 /*!< Abort command */
30 USDHC_CMD_TYPE_EMPTY = 4U,
31 /*!< Empty command */
32 };
33
34 enum usdhc_status_flag {
35 USDHC_CMD_INHIBIT_FLAG =
36 USDHC_PRES_STATE_CIHB_MASK,
37 /*!< Command inhibit */
38 USDHC_DATA_INHIBIT_FLAG =
39 USDHC_PRES_STATE_CDIHB_MASK,
40 /*!< Data inhibit */
41 USDHC_DATA_LINE_ACTIVE_FLAG =
42 USDHC_PRES_STATE_DLA_MASK,
43 /*!< Data line active */
44 USDHC_SD_CLK_STATUS_FLAG =
45 USDHC_PRES_STATE_SDSTB_MASK,
46 /*!< SD bus clock stable */
47 USDHC_WRITE_ACTIVE_FLAG =
48 USDHC_PRES_STATE_WTA_MASK,
49 /*!< Write transfer active */
50 USDHC_READ_ACTIVE_FLAG =
51 USDHC_PRES_STATE_RTA_MASK,
52 /*!< Read transfer active */
53 USDHC_BUF_WRITE_ENABLE_FLAG =
54 USDHC_PRES_STATE_BWEN_MASK,
55 /*!< Buffer write enable */
56 USDHC_BUF_READ_ENABLE_FLAG =
57 USDHC_PRES_STATE_BREN_MASK,
58 /*!< Buffer read enable */
59 USDHC_RETUNING_REQ_FLAG =
60 USDHC_PRES_STATE_RTR_MASK,
61 /*!< re-tuning request flag ,only used for SDR104 mode */
62 USDHC_DELAY_SETTING_DONE_FLAG =
63 USDHC_PRES_STATE_TSCD_MASK,
64 /*!< delay setting finished flag */
65 USDHC_CARD_INSERTED_FLAG =
66 USDHC_PRES_STATE_CINST_MASK,
67 /*!< Card inserted */
68 USDHC_CMD_LINE_LEVEL_FLAG =
69 USDHC_PRES_STATE_CLSL_MASK,
70 /*!< Command line signal level */
71 USDHC_DATA0_LINE_LEVEL_FLAG =
72 1U << USDHC_PRES_STATE_DLSL_SHIFT,
73 /*!< Data0 line signal level */
74 USDHC_DATA1_LINE_LEVEL_FLAG =
75 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 1U),
76 /*!< Data1 line signal level */
77 USDHC_DATA2_LINE_LEVEL_FLAG =
78 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 2U),
79 /*!< Data2 line signal level */
80 USDHC_DATA3_LINE_LEVEL_FLAG =
81 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 3U),
82 /*!< Data3 line signal level */
83 USDHC_DATA4_LINE_LEVEL_FLAG =
84 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 4U),
85 /*!< Data4 line signal level */
86 USDHC_DATA5_LINE_LEVEL_FLAG =
87 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 5U),
88 /*!< Data5 line signal level */
89 USDHC_DATA6_LINE_LEVEL_FLAG =
90 1U << (USDHC_PRES_STATE_DLSL_SHIFT + 6U),
91 /*!< Data6 line signal level */
92 USDHC_DATA7_LINE_LEVEL_FLAG =
93 (int)(1U << (USDHC_PRES_STATE_DLSL_SHIFT + 7U)),
94 /*!< Data7 line signal level */
95 };
96
97 enum usdhc_transfer_flag {
98 USDHC_ENABLE_DMA_FLAG =
99 USDHC_MIX_CTRL_DMAEN_MASK,
100 /*!< Enable DMA */
101
102 USDHC_CMD_TYPE_SUSPEND_FLAG =
103 (USDHC_CMD_XFR_TYP_CMDTYP(1U)),
104 /*!< Suspend command */
105 USDHC_CMD_TYPE_RESUME_FLAG =
106 (USDHC_CMD_XFR_TYP_CMDTYP(2U)),
107 /*!< Resume command */
108 USDHC_CMD_TYPE_ABORT_FLAG =
109 (USDHC_CMD_XFR_TYP_CMDTYP(3U)),
110 /*!< Abort command */
111
112 USDHC_BLOCK_COUNT_FLAG =
113 USDHC_MIX_CTRL_BCEN_MASK,
114 /*!< Enable block count */
115 USDHC_AUTO_CMD12_FLAG =
116 USDHC_MIX_CTRL_AC12EN_MASK,
117 /*!< Enable auto CMD12 */
118 USDHC_DATA_READ_FLAG =
119 USDHC_MIX_CTRL_DTDSEL_MASK,
120 /*!< Enable data read */
121 USDHC_MULTIPLE_BLOCK_FLAG =
122 USDHC_MIX_CTRL_MSBSEL_MASK,
123 /*!< Multiple block data read/write */
124 USDHC_AUTO_CMD23FLAG =
125 USDHC_MIX_CTRL_AC23EN_MASK,
126 /*!< Enable auto CMD23 */
127 USDHC_RSP_LEN_136_FLAG =
128 USDHC_CMD_XFR_TYP_RSPTYP(1U),
129 /*!< 136 bit response length */
130 USDHC_RSP_LEN_48_FLAG =
131 USDHC_CMD_XFR_TYP_RSPTYP(2U),
132 /*!< 48 bit response length */
133 USDHC_RSP_LEN_48_BUSY_FLAG =
134 USDHC_CMD_XFR_TYP_RSPTYP(3U),
135 /*!< 48 bit response length with busy status */
136
137 USDHC_CRC_CHECK_FLAG =
138 USDHC_CMD_XFR_TYP_CCCEN_MASK,
139 /*!< Enable CRC check */
140 USDHC_IDX_CHECK_FLAG =
141 USDHC_CMD_XFR_TYP_CICEN_MASK,
142 /*!< Enable index check */
143 USDHC_DATA_PRESENT_FLAG =
144 USDHC_CMD_XFR_TYP_DPSEL_MASK,
145 /*!< Data present flag */
146 };
147
148 enum usdhc_int_status_flag {
149 USDHC_INT_CMD_DONE_FLAG =
150 USDHC_INT_STATUS_CC_MASK,
151 /*!< Command complete */
152 USDHC_INT_DATA_DONE_FLAG =
153 USDHC_INT_STATUS_TC_MASK,
154 /*!< Data complete */
155 USDHC_INT_BLK_GAP_EVENT_FLAG =
156 USDHC_INT_STATUS_BGE_MASK,
157 /*!< Block gap event */
158 USDHC_INT_DMA_DONE_FLAG =
159 USDHC_INT_STATUS_DINT_MASK,
160 /*!< DMA interrupt */
161 USDHC_INT_BUF_WRITE_READY_FLAG =
162 USDHC_INT_STATUS_BWR_MASK,
163 /*!< Buffer write ready */
164 USDHC_INT_BUF_READ_READY_FLAG =
165 USDHC_INT_STATUS_BRR_MASK,
166 /*!< Buffer read ready */
167 USDHC_INT_CARD_INSERTED_FLAG =
168 USDHC_INT_STATUS_CINS_MASK,
169 /*!< Card inserted */
170 USDHC_INT_CARD_REMOVED_FLAG =
171 USDHC_INT_STATUS_CRM_MASK,
172 /*!< Card removed */
173 USDHC_INT_CARD_INTERRUPT_FLAG =
174 USDHC_INT_STATUS_CINT_MASK,
175 /*!< Card interrupt */
176
177 USDHC_INT_RE_TUNING_EVENT_FLAG =
178 USDHC_INT_STATUS_RTE_MASK,
179 /*!< Re-Tuning event,only for SD3.0 SDR104 mode */
180 USDHC_INT_TUNING_PASS_FLAG =
181 USDHC_INT_STATUS_TP_MASK,
182 /*!< SDR104 mode tuning pass flag */
183 USDHC_INT_TUNING_ERR_FLAG =
184 USDHC_INT_STATUS_TNE_MASK,
185 /*!< SDR104 tuning error flag */
186
187 USDHC_INT_CMD_TIMEOUT_FLAG =
188 USDHC_INT_STATUS_CTOE_MASK,
189 /*!< Command timeout error */
190 USDHC_INT_CMD_CRC_ERR_FLAG =
191 USDHC_INT_STATUS_CCE_MASK,
192 /*!< Command CRC error */
193 USDHC_INT_CMD_ENDBIT_ERR_FLAG =
194 USDHC_INT_STATUS_CEBE_MASK,
195 /*!< Command end bit error */
196 USDHC_INT_CMD_IDX_ERR_FLAG =
197 USDHC_INT_STATUS_CIE_MASK,
198 /*!< Command index error */
199 USDHC_INT_DATA_TIMEOUT_FLAG =
200 USDHC_INT_STATUS_DTOE_MASK,
201 /*!< Data timeout error */
202 USDHC_INT_DATA_CRC_ERR_FLAG =
203 USDHC_INT_STATUS_DCE_MASK,
204 /*!< Data CRC error */
205 USDHC_INT_DATA_ENDBIT_ERR_FLAG =
206 USDHC_INT_STATUS_DEBE_MASK,
207 /*!< Data end bit error */
208 USDHC_INT_AUTO_CMD12_ERR_FLAG =
209 USDHC_INT_STATUS_AC12E_MASK,
210 /*!< Auto CMD12 error */
211 USDHC_INT_DMA_ERR_FLAG =
212 USDHC_INT_STATUS_DMAE_MASK,
213 /*!< DMA error */
214
215 USDHC_INT_CMD_ERR_FLAG =
216 (USDHC_INT_CMD_TIMEOUT_FLAG |
217 USDHC_INT_CMD_CRC_ERR_FLAG |
218 USDHC_INT_CMD_ENDBIT_ERR_FLAG |
219 USDHC_INT_CMD_IDX_ERR_FLAG),
220 /*!< Command error */
221 USDHC_INT_DATA_ERR_FLAG =
222 (USDHC_INT_DATA_TIMEOUT_FLAG |
223 USDHC_INT_DATA_CRC_ERR_FLAG |
224 USDHC_INT_DATA_ENDBIT_ERR_FLAG |
225 USDHC_INT_AUTO_CMD12_ERR_FLAG),
226 /*!< Data error */
227 USDHC_INT_ERR_FLAG =
228 (USDHC_INT_CMD_ERR_FLAG |
229 USDHC_INT_DATA_ERR_FLAG |
230 USDHC_INT_DMA_ERR_FLAG),
231 /*!< All error */
232 USDHC_INT_DATA_FLAG =
233 (USDHC_INT_DATA_DONE_FLAG |
234 USDHC_INT_DMA_DONE_FLAG |
235 USDHC_INT_BUF_WRITE_READY_FLAG |
236 USDHC_INT_BUF_READ_READY_FLAG |
237 USDHC_INT_DATA_ERR_FLAG |
238 USDHC_INT_DMA_ERR_FLAG),
239 /*!< Data interrupts */
240 USDHC_INT_CMD_FLAG =
241 (USDHC_INT_CMD_DONE_FLAG |
242 USDHC_INT_CMD_ERR_FLAG),
243 /*!< Command interrupts */
244 USDHC_INT_CARD_DETECT_FLAG =
245 (USDHC_INT_CARD_INSERTED_FLAG |
246 USDHC_INT_CARD_REMOVED_FLAG),
247 /*!< Card detection interrupts */
248 USDHC_INT_SDR104_TUNING_FLAG =
249 (USDHC_INT_RE_TUNING_EVENT_FLAG |
250 USDHC_INT_TUNING_PASS_FLAG |
251 USDHC_INT_TUNING_ERR_FLAG),
252
253 USDHC_INT_ALL_FLAGS =
254 (USDHC_INT_BLK_GAP_EVENT_FLAG |
255 USDHC_INT_CARD_INTERRUPT_FLAG |
256 USDHC_INT_CMD_FLAG |
257 USDHC_INT_DATA_FLAG |
258 USDHC_INT_ERR_FLAG |
259 USDHC_INT_SDR104_TUNING_FLAG),
260 /*!< All flags mask */
261 };
262
263 enum usdhc_data_bus_width {
264 USDHC_DATA_BUS_WIDTH_1BIT = 0U,
265 /*!< 1-bit mode */
266 USDHC_DATA_BUS_WIDTH_4BIT = 1U,
267 /*!< 4-bit mode */
268 USDHC_DATA_BUS_WIDTH_8BIT = 2U,
269 /*!< 8-bit mode */
270 };
271
272 #define USDHC_MAX_BLOCK_COUNT \
273 (USDHC_BLK_ATT_BLKCNT_MASK >> \
274 USDHC_BLK_ATT_BLKCNT_SHIFT)
275
276 struct usdhc_cmd {
277 uint32_t index; /*cmd idx*/
278 uint32_t argument; /*cmd arg*/
279 enum usdhc_cmd_type cmd_type;
280 enum sdhc_rsp_type rsp_type;
281 uint32_t response[4U];
282 uint32_t rsp_err_flags;
283 uint32_t flags;
284 };
285
286 struct usdhc_data {
287 bool cmd12;
288 /* Enable auto CMD12 */
289 bool cmd23;
290 /* Enable auto CMD23 */
291 bool ignore_err;
292 /* Enable to ignore error event
293 * to read/write all the data
294 */
295 bool data_enable;
296 uint8_t data_type;
297 /* this is used to distinguish
298 * the normal/tuning/boot data
299 */
300 uint32_t block_size;
301 /* Block size
302 */
303 uint32_t block_count;
304 /* Block count
305 */
306 uint32_t *rx_data;
307 /* Buffer to save data read
308 */
309 const uint32_t *tx_data;
310 /* Data buffer to write
311 */
312 };
313
314 enum usdhc_dma_mode {
315 USDHC_DMA_SIMPLE = 0U,
316 /* external DMA
317 */
318 USDHC_DMA_ADMA1 = 1U,
319 /* ADMA1 is selected
320 */
321 USDHC_DMA_ADMA2 = 2U,
322 /* ADMA2 is selected
323 */
324 USDHC_EXT_DMA = 3U,
325 /* external dma mode select
326 */
327 };
328
329 enum usdhc_burst_len {
330 USDHC_INCR_BURST_LEN = 0x01U,
331 /* enable burst len for INCR
332 */
333 USDHC_INCR4816_BURST_LEN = 0x02U,
334 /* enable burst len for INCR4/INCR8/INCR16
335 */
336 USDHC_INCR4816_BURST_LEN_WRAP = 0x04U,
337 /* enable burst len for INCR4/8/16 WRAP
338 */
339 };
340
341 struct usdhc_adma_config {
342 enum usdhc_dma_mode dma_mode;
343 /* DMA mode
344 */
345 enum usdhc_burst_len burst_len;
346 /* burst len config
347 */
348 uint32_t *adma_table;
349 /* ADMA table address,
350 * can't be null if transfer way is ADMA1/ADMA2
351 */
352 uint32_t adma_table_words;
353 /* ADMA table length united as words,
354 * can't be 0 if transfer way is ADMA1/ADMA2
355 */
356 };
357
358 struct usdhc_context {
359 bool cmd_only;
360 struct usdhc_cmd cmd;
361 struct usdhc_data data;
362 struct usdhc_adma_config dma_cfg;
363 };
364
365 enum usdhc_endian_mode {
366 USDHC_BIG_ENDIAN = 0U,
367 /* Big endian mode
368 */
369 USDHC_HALF_WORD_BIG_ENDIAN = 1U,
370 /* Half word big endian mode
371 */
372 USDHC_LITTLE_ENDIAN = 2U,
373 /* Little endian mode
374 */
375 };
376
377 struct usdhc_config {
378 USDHC_Type *base;
379 const struct device *clock_dev;
380 clock_control_subsys_t clock_subsys;
381 uint8_t nusdhc;
382
383 char *pwr_name;
384 uint8_t pwr_pin;
385 gpio_dt_flags_t pwr_flags;
386
387 char *detect_name;
388 uint8_t detect_pin;
389 gpio_dt_flags_t detect_flags;
390
391 bool no_1_8_v;
392
393 uint32_t data_timeout;
394 /* Data timeout value
395 */
396 enum usdhc_endian_mode endian;
397 /* Endian mode
398 */
399 uint8_t read_watermark;
400 /* Watermark level for DMA read operation.
401 * Available range is 1 ~ 128.
402 */
403 uint8_t write_watermark;
404 /* Watermark level for DMA write operation.
405 * Available range is 1 ~ 128.
406 */
407 uint8_t read_burst_len;
408 /* Read burst len
409 */
410 uint8_t write_burst_len;
411 /* Write burst len
412 */
413 };
414
415 struct usdhc_capability {
416 uint32_t max_blk_len;
417 uint32_t max_blk_cnt;
418 uint32_t host_flags;
419 };
420
421 enum host_detect_type {
422 SD_DETECT_GPIO_CD,
423 /* sd card detect by CD pin through GPIO
424 */
425 SD_DETECT_HOST_CD,
426 /* sd card detect by CD pin through host
427 */
428 SD_DETECT_HOST_DATA3,
429 /* sd card detect by DAT3 pin through host
430 */
431 };
432
433 struct usdhc_client_info {
434 uint32_t busclk_hz;
435 uint32_t relative_addr;
436 uint32_t version;
437 uint32_t card_flags;
438 uint32_t raw_cid[4U];
439 uint32_t raw_csd[4U];
440 uint32_t raw_scr[2U];
441 uint32_t raw_ocr;
442 struct sd_cid cid;
443 struct sd_csd csd;
444 struct sd_scr scr;
445 uint32_t sd_block_count;
446 uint32_t sd_block_size;
447 enum sd_timing_mode sd_timing;
448 enum sd_driver_strength driver_strength;
449 enum sd_max_current max_current;
450 enum sd_voltage voltage;
451 };
452
453 struct usdhc_priv {
454 bool host_ready;
455 uint8_t status;
456
457 const struct device *pwr_gpio;
458 const struct device *detect_gpio;
459 struct gpio_callback detect_cb;
460
461 enum host_detect_type detect_type;
462 bool inserted;
463
464 uint32_t src_clk_hz;
465
466 const struct usdhc_config *config;
467 struct usdhc_capability host_capability;
468
469 struct usdhc_client_info card_info;
470
471 struct usdhc_context op_context;
472 };
473
474 enum usdhc_xfer_data_type {
475 USDHC_XFER_NORMAL = 0U,
476 /* transfer normal read/write data
477 */
478 USDHC_XFER_TUNING = 1U,
479 /* transfer tuning data
480 */
481 USDHC_XFER_BOOT = 2U,
482 /* transfer boot data
483 */
484 USDHC_XFER_BOOT_CONTINUOUS = 3U,
485 /* transfer boot data continuous
486 */
487 };
488
489 #define USDHC_ADMA1_ADDRESS_ALIGN (4096U)
490 #define USDHC_ADMA1_LENGTH_ALIGN (4096U)
491 #define USDHC_ADMA2_ADDRESS_ALIGN (4U)
492 #define USDHC_ADMA2_LENGTH_ALIGN (4U)
493
494 #define USDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT (16U)
495 #define USDHC_ADMA2_DESCRIPTOR_LENGTH_MASK (0xFFFFU)
496 #define USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY \
497 (USDHC_ADMA2_DESCRIPTOR_LENGTH_MASK - 3U)
498
499 #define SWAP_WORD_BYTE_SEQUENCE(x) (__REV(x))
500 #define SWAP_HALF_WROD_BYTE_SEQUENCE(x) (__REV16(x))
501
502 #define SDMMCHOST_NOT_SUPPORT 0U
503
504 #define CARD_BUS_FREQ_50MHZ (0U)
505 #define CARD_BUS_FREQ_100MHZ0 (1U)
506 #define CARD_BUS_FREQ_100MHZ1 (2U)
507 #define CARD_BUS_FREQ_200MHZ (3U)
508
509 #define CARD_BUS_STRENGTH_0 (0U)
510 #define CARD_BUS_STRENGTH_1 (1U)
511 #define CARD_BUS_STRENGTH_2 (2U)
512 #define CARD_BUS_STRENGTH_3 (3U)
513 #define CARD_BUS_STRENGTH_4 (4U)
514 #define CARD_BUS_STRENGTH_5 (5U)
515 #define CARD_BUS_STRENGTH_6 (6U)
516 #define CARD_BUS_STRENGTH_7 (7U)
517
518 enum usdhc_adma_flag {
519 USDHC_ADMA_SINGLE_FLAG = 0U,
520 USDHC_ADMA_MUTI_FLAG = 1U,
521 };
522
523 enum usdhc_adma2_descriptor_flag {
524 USDHC_ADMA2_VALID_FLAG = (1U << 0U),
525 /* Valid flag
526 */
527 USDHC_ADMA2_END_FLAG = (1U << 1U),
528 /* End flag
529 */
530 USDHC_ADMA2_INT_FLAG = (1U << 2U),
531 /* Interrupt flag
532 */
533 USDHC_ADMA2_ACTIVITY1_FLAG = (1U << 4U),
534 /* Activity 1 mask
535 */
536 USDHC_ADMA2_ACTIVITY2_FLAG = (1U << 5U),
537 /* Activity 2 mask
538 */
539
540 USDHC_ADMA2_NOP_FLAG =
541 (USDHC_ADMA2_VALID_FLAG),
542 /* No operation
543 */
544 USDHC_ADMA2_RESERVED_FLAG =
545 (USDHC_ADMA2_ACTIVITY1_FLAG |
546 USDHC_ADMA2_VALID_FLAG),
547 /* Reserved
548 */
549 USDHC_ADMA2_XFER_FLAG =
550 (USDHC_ADMA2_ACTIVITY2_FLAG |
551 USDHC_ADMA2_VALID_FLAG),
552 /* Transfer type
553 */
554 USDHC_ADMA2_LINK_FLAG =
555 (USDHC_ADMA2_ACTIVITY1_FLAG |
556 USDHC_ADMA2_ACTIVITY2_FLAG |
557 USDHC_ADMA2_VALID_FLAG),
558 /* Link type
559 */
560 };
561
562 struct usdhc_adma2_descriptor {
563 uint32_t attribute;
564 /*!< The control and status field */
565 const uint32_t *address;
566 /*!< The address field */
567 };
568
569 enum usdhc_card_flag {
570 USDHC_HIGH_CAPACITY_FLAG =
571 (1U << 1U),
572 /* Support high capacity
573 */
574 USDHC_4BIT_WIDTH_FLAG =
575 (1U << 2U),
576 /* Support 4-bit data width
577 */
578 USDHC_SDHC_FLAG =
579 (1U << 3U),
580 /* Card is SDHC
581 */
582 USDHC_SDXC_FLAG =
583 (1U << 4U),
584 /* Card is SDXC
585 */
586 USDHC_VOL_1_8V_FLAG =
587 (1U << 5U),
588 /* card support 1.8v voltage
589 */
590 USDHC_SET_BLK_CNT_CMD23_FLAG =
591 (1U << 6U),
592 /* card support cmd23 flag
593 */
594 USDHC_SPEED_CLASS_CONTROL_CMD_FLAG =
595 (1U << 7U),
596 /* card support speed class control flag
597 */
598 };
599
600 enum usdhc_capability_flag {
601 USDHC_SUPPORT_ADMA_FLAG =
602 USDHC_HOST_CTRL_CAP_ADMAS_MASK,
603 /*!< Support ADMA */
604 USDHC_SUPPORT_HIGHSPEED_FLAG =
605 USDHC_HOST_CTRL_CAP_HSS_MASK,
606 /*!< Support high-speed */
607 USDHC_SUPPORT_DMA_FLAG =
608 USDHC_HOST_CTRL_CAP_DMAS_MASK,
609 /*!< Support DMA */
610 USDHC_SUPPORT_SUSPEND_RESUME_FLAG =
611 USDHC_HOST_CTRL_CAP_SRS_MASK,
612 /*!< Support suspend/resume */
613 USDHC_SUPPORT_V330_FLAG =
614 USDHC_HOST_CTRL_CAP_VS33_MASK,
615 /*!< Support voltage 3.3V */
616 USDHC_SUPPORT_V300_FLAG =
617 USDHC_HOST_CTRL_CAP_VS30_MASK,
618 /*!< Support voltage 3.0V */
619 USDHC_SUPPORT_V180_FLAG =
620 USDHC_HOST_CTRL_CAP_VS18_MASK,
621 /*!< Support voltage 1.8V */
622 /* Put additional two flags in
623 * HTCAPBLT_MBL's position.
624 */
625 USDHC_SUPPORT_4BIT_FLAG =
626 (USDHC_HOST_CTRL_CAP_MBL_SHIFT << 0U),
627 /*!< Support 4 bit mode */
628 USDHC_SUPPORT_8BIT_FLAG =
629 (USDHC_HOST_CTRL_CAP_MBL_SHIFT << 1U),
630 /*!< Support 8 bit mode */
631 /* sd version 3.0 new feature */
632 USDHC_SUPPORT_DDR50_FLAG =
633 USDHC_HOST_CTRL_CAP_DDR50_SUPPORT_MASK,
634 /*!< support DDR50 mode */
635
636 #if defined(FSL_FEATURE_USDHC_HAS_SDR104_MODE) &&\
637 (!FSL_FEATURE_USDHC_HAS_SDR104_MODE)
638 USDHC_SUPPORT_SDR104_FLAG = 0,
639 /*!< not support SDR104 mode */
640 #else
641 USDHC_SUPPORT_SDR104_FLAG =
642 USDHC_HOST_CTRL_CAP_SDR104_SUPPORT_MASK,
643 /*!< support SDR104 mode */
644 #endif
645 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) &&\
646 (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
647 USDHC_SUPPORT_SDR50_FLAG = 0U,
648 /*!< not support SDR50 mode */
649 #else
650 USDHC_SUPPORT_SDR50_FLAG =
651 USDHC_HOST_CTRL_CAP_SDR50_SUPPORT_MASK,
652 /*!< support SDR50 mode */
653 #endif
654 };
655
656 #define NXP_SDMMC_MAX_VOLTAGE_RETRIES (1000U)
657
658 #define CARD_DATA0_STATUS_MASK USDHC_DATA0_LINE_LEVEL_FLAG
659 #define CARD_DATA1_STATUS_MASK USDHC_DATA1_LINE_LEVEL_FLAG
660 #define CARD_DATA2_STATUS_MASK USDHC_DATA2_LINE_LEVEL_FLAG
661 #define CARD_DATA3_STATUS_MASK USDHC_DATA3_LINE_LEVEL_FLAG
662 #define CARD_DATA0_NOT_BUSY USDHC_DATA0_LINE_LEVEL_FLAG
663
664 #define SDHC_STANDARD_TUNING_START (10U)
665 /*!< standard tuning start point */
666 #define SDHC_TUINIG_STEP (2U)
667 /*!< standard tuning step */
668 #define SDHC_RETUNING_TIMER_COUNT (0U)
669 /*!< Re-tuning timer */
670
671 #define USDHC_MAX_DVS \
672 ((USDHC_SYS_CTRL_DVS_MASK >> \
673 USDHC_SYS_CTRL_DVS_SHIFT) + 1U)
674 #define USDHC_MAX_CLKFS \
675 ((USDHC_SYS_CTRL_SDCLKFS_MASK >> \
676 USDHC_SYS_CTRL_SDCLKFS_SHIFT) + 1U)
677 #define USDHC_PREV_DVS(x) ((x) -= 1U)
678 #define USDHC_PREV_CLKFS(x, y) ((x) >>= (y))
679
680 #define SDMMCHOST_SUPPORT_SDR104_FREQ SD_CLOCK_208MHZ
681
682 #define USDHC_ADMA_TABLE_WORDS (8U)
683 #define USDHC_ADMA2_ADDR_ALIGN (4U)
684 #define USDHC_READ_BURST_LEN (8U)
685 #define USDHC_WRITE_BURST_LEN (8U)
686 #define USDHC_DATA_TIMEOUT (0xFU)
687
688 #define USDHC_READ_WATERMARK_LEVEL (0x80U)
689 #define USDHC_WRITE_WATERMARK_LEVEL (0x80U)
690
691 enum usdhc_reset {
692 USDHC_RESET_ALL =
693 USDHC_SYS_CTRL_RSTA_MASK,
694 /*!< Reset all except card detection */
695 USDHC_RESET_CMD =
696 USDHC_SYS_CTRL_RSTC_MASK,
697 /*!< Reset command line */
698 USDHC_RESET_DATA =
699 USDHC_SYS_CTRL_RSTD_MASK,
700 /*!< Reset data line */
701
702 #if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) &&\
703 (!FSL_FEATURE_USDHC_HAS_SDR50_MODE)
704 USDHC_RESET_TUNING = 0U,
705 /*!< no reset tuning circuit bit */
706 #else
707 USDHC_RESET_TUNING = USDHC_SYS_CTRL_RSTT_MASK,
708 /*!< reset tuning circuit */
709 #endif
710
711 USDHC_RESETS_All =
712 (USDHC_RESET_ALL |
713 USDHC_RESET_CMD |
714 USDHC_RESET_DATA |
715 USDHC_RESET_TUNING),
716 /*!< All reset types */
717 };
718
usdhc_millsec_delay(unsigned int cycles_to_wait)719 static void usdhc_millsec_delay(unsigned int cycles_to_wait)
720 {
721 unsigned int start = sys_clock_cycle_get_32();
722
723 while (sys_clock_cycle_get_32() - start < (cycles_to_wait * 1000))
724 ;
725 }
726
727 uint32_t g_usdhc_boot_dummy __aligned(64);
728 uint32_t g_usdhc_rx_dummy[2048] __aligned(64);
729
usdhc_adma2_descriptor_cfg(uint32_t * adma_table,uint32_t adma_table_words,const uint32_t * data_addr,uint32_t data_size,uint32_t flags)730 static int usdhc_adma2_descriptor_cfg(
731 uint32_t *adma_table, uint32_t adma_table_words,
732 const uint32_t *data_addr, uint32_t data_size, uint32_t flags)
733 {
734 uint32_t min_entries, start_entry = 0U;
735 uint32_t max_entries = (adma_table_words * sizeof(uint32_t)) /
736 sizeof(struct usdhc_adma2_descriptor);
737 struct usdhc_adma2_descriptor *adma2_addr =
738 (struct usdhc_adma2_descriptor *)(adma_table);
739 uint32_t i, dma_buf_len = 0U;
740
741 if ((uint32_t)data_addr % USDHC_ADMA2_ADDRESS_ALIGN) {
742 return -EIO;
743 }
744 /* Add non aligned access support.
745 */
746 if (data_size % sizeof(uint32_t)) {
747 /* make the data length as word-aligned */
748 data_size += sizeof(uint32_t) - (data_size % sizeof(uint32_t));
749 }
750
751 /* Check if ADMA descriptor's number is enough. */
752 if (!(data_size % USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY)) {
753 min_entries = data_size /
754 USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY;
755 } else {
756 min_entries = ((data_size /
757 USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U);
758 }
759 /* calcucate the start entry for multiple descriptor mode,
760 * ADMA engine is not stop, so update the descriptor
761 * data address and data size is enough
762 */
763 if (flags == USDHC_ADMA_MUTI_FLAG) {
764 for (i = 0U; i < max_entries; i++) {
765 if (!(adma2_addr[i].attribute & USDHC_ADMA2_VALID_FLAG))
766 break;
767 }
768 start_entry = i;
769 /* add one entry for dummy entry */
770 min_entries += 1U;
771 }
772
773 if ((min_entries + start_entry) > max_entries) {
774 return -EIO;
775 }
776
777 for (i = start_entry; i < (min_entries + start_entry); i++) {
778 if (data_size > USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) {
779 dma_buf_len =
780 USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY;
781 } else {
782 dma_buf_len = (data_size == 0U ? sizeof(uint32_t) :
783 data_size);
784 /* adma don't support 0 data length transfer
785 * descriptor
786 */
787 }
788
789 /* Each descriptor for ADMA2 is 64-bit in length */
790 adma2_addr[i].address = (data_size == 0U) ?
791 &g_usdhc_boot_dummy : data_addr;
792 adma2_addr[i].attribute = (dma_buf_len <<
793 USDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT);
794 adma2_addr[i].attribute |=
795 (data_size == 0U) ? 0U :
796 (USDHC_ADMA2_XFER_FLAG | USDHC_ADMA2_INT_FLAG);
797 data_addr += (dma_buf_len / sizeof(uint32_t));
798
799 if (data_size != 0U)
800 data_size -= dma_buf_len;
801 }
802
803 /* add a dummy valid ADMA descriptor for multiple descriptor mode,
804 * this is useful when transfer boot data, the ADMA
805 * engine will not stop at block gap
806 */
807 if (flags == USDHC_ADMA_MUTI_FLAG) {
808 adma2_addr[start_entry + 1U].attribute |= USDHC_ADMA2_XFER_FLAG;
809 } else {
810 adma2_addr[i - 1U].attribute |= USDHC_ADMA2_END_FLAG;
811 /* set the end bit */
812 }
813
814 return 0;
815 }
816
usdhc_Internal_dma_cfg(struct usdhc_priv * priv,struct usdhc_adma_config * dma_cfg,const uint32_t * data_addr)817 static int usdhc_Internal_dma_cfg(struct usdhc_priv *priv,
818 struct usdhc_adma_config *dma_cfg,
819 const uint32_t *data_addr)
820 {
821 USDHC_Type *base = priv->config->base;
822 bool cmd23 = priv->op_context.data.cmd23;
823
824 if (dma_cfg->dma_mode == USDHC_DMA_SIMPLE) {
825 /* check DMA data buffer address align or not */
826 if (((uint32_t)data_addr % USDHC_ADMA2_ADDRESS_ALIGN) != 0U) {
827 return -EIO;
828 }
829 /* in simple DMA mode if use auto CMD23,
830 * address should load to ADMA addr,
831 * and block count should load to DS_ADDR
832 */
833 if (cmd23)
834 base->ADMA_SYS_ADDR = (uint32_t)data_addr;
835 else
836 base->DS_ADDR = (uint32_t)data_addr;
837 } else {
838 /* When use ADMA, disable simple DMA */
839 base->DS_ADDR = 0U;
840 base->ADMA_SYS_ADDR = (uint32_t)(dma_cfg->adma_table);
841 }
842
843 /* select DMA mode and config the burst length */
844 base->PROT_CTRL &= ~(USDHC_PROT_CTRL_DMASEL_MASK |
845 USDHC_PROT_CTRL_BURST_LEN_EN_MASK);
846 base->PROT_CTRL |= USDHC_PROT_CTRL_DMASEL(dma_cfg->dma_mode) |
847 USDHC_PROT_CTRL_BURST_LEN_EN(dma_cfg->burst_len);
848 /* enable DMA */
849 base->MIX_CTRL |= USDHC_MIX_CTRL_DMAEN_MASK;
850
851 return 0;
852 }
853
854
usdhc_adma_table_cfg(struct usdhc_priv * priv,uint32_t flags)855 static int usdhc_adma_table_cfg(struct usdhc_priv *priv, uint32_t flags)
856 {
857 int error = -EIO;
858 struct usdhc_data *data = &priv->op_context.data;
859 struct usdhc_adma_config *dma_cfg = &priv->op_context.dma_cfg;
860 uint32_t boot_dummy_off = data->data_type == USDHC_XFER_BOOT_CONTINUOUS ?
861 sizeof(uint32_t) : 0U;
862 const uint32_t *data_addr = (const uint32_t *)((uint32_t)((!data->rx_data) ?
863 data->tx_data : data->rx_data) + boot_dummy_off);
864 uint32_t data_size = data->block_size * data->block_count - boot_dummy_off;
865
866 switch (dma_cfg->dma_mode) {
867 case USDHC_DMA_SIMPLE:
868 error = 0;
869 break;
870
871 case USDHC_DMA_ADMA1:
872 error = -EINVAL;
873 break;
874
875 case USDHC_DMA_ADMA2:
876 error = usdhc_adma2_descriptor_cfg(dma_cfg->adma_table,
877 dma_cfg->adma_table_words, data_addr, data_size, flags);
878 break;
879 default:
880 return -EINVAL;
881 }
882
883 /* for internal dma, internal DMA configurations should not update
884 * the configurations when continuous transfer the
885 * boot data, only the DMA descriptor need update
886 */
887 if ((!error) && (data->data_type != USDHC_XFER_BOOT_CONTINUOUS)) {
888 error = usdhc_Internal_dma_cfg(priv, dma_cfg, data_addr);
889 }
890
891 return error;
892 }
893
usdhc_data_xfer_cfg(struct usdhc_priv * priv,bool en_dma)894 static int usdhc_data_xfer_cfg(struct usdhc_priv *priv,
895 bool en_dma)
896 {
897 USDHC_Type *base = priv->config->base;
898 uint32_t mix_ctrl = base->MIX_CTRL;
899 struct usdhc_data *data = NULL;
900 uint32_t *flag = &priv->op_context.cmd.flags;
901
902 if (!priv->op_context.cmd_only)
903 data = &priv->op_context.data;
904
905 if (data != NULL) {
906 if (data->data_type == USDHC_XFER_BOOT_CONTINUOUS) {
907 /* clear stop at block gap request */
908 base->PROT_CTRL &= ~USDHC_PROT_CTRL_SABGREQ_MASK;
909 /* continuous transfer data */
910 base->PROT_CTRL |= USDHC_PROT_CTRL_CREQ_MASK;
911 return 0;
912 }
913
914 /* check data inhibit flag */
915 if (base->PRES_STATE & USDHC_DATA_INHIBIT_FLAG)
916 return -EBUSY;
917 /* check transfer block count */
918 if ((data->block_count > USDHC_MAX_BLOCK_COUNT) ||
919 (!data->tx_data && !data->rx_data))
920 return -EINVAL;
921
922 /* config mix parameter */
923 mix_ctrl &= ~(USDHC_MIX_CTRL_MSBSEL_MASK |
924 USDHC_MIX_CTRL_BCEN_MASK |
925 USDHC_MIX_CTRL_DTDSEL_MASK |
926 USDHC_MIX_CTRL_AC12EN_MASK);
927
928 if (data->rx_data) {
929 mix_ctrl |= USDHC_MIX_CTRL_DTDSEL_MASK;
930 }
931
932 if (data->block_count > 1U) {
933 mix_ctrl |= USDHC_MIX_CTRL_MSBSEL_MASK |
934 USDHC_MIX_CTRL_BCEN_MASK;
935 /* auto command 12 */
936 if (data->cmd12) {
937 mix_ctrl |= USDHC_MIX_CTRL_AC12EN_MASK;
938 }
939 }
940
941 /* auto command 23, auto send set block count cmd before
942 * multiple read/write
943 */
944 if ((data->cmd23)) {
945 mix_ctrl |= USDHC_MIX_CTRL_AC23EN_MASK;
946 base->VEND_SPEC2 |=
947 USDHC_VEND_SPEC2_ACMD23_ARGU2_EN_MASK;
948 /* config the block count to DS_ADDR */
949 base->DS_ADDR = data->block_count;
950 } else {
951 mix_ctrl &= ~USDHC_MIX_CTRL_AC23EN_MASK;
952 base->VEND_SPEC2 &=
953 (~USDHC_VEND_SPEC2_ACMD23_ARGU2_EN_MASK);
954 }
955
956 if (data->data_type != USDHC_XFER_BOOT) {
957 /* config data block size/block count */
958 base->BLK_ATT =
959 ((base->BLK_ATT & ~(USDHC_BLK_ATT_BLKSIZE_MASK |
960 USDHC_BLK_ATT_BLKCNT_MASK)) |
961 (USDHC_BLK_ATT_BLKSIZE(data->block_size) |
962 USDHC_BLK_ATT_BLKCNT(data->block_count)));
963 } else {
964 mix_ctrl |= USDHC_MIX_CTRL_MSBSEL_MASK |
965 USDHC_MIX_CTRL_BCEN_MASK;
966 base->PROT_CTRL |=
967 USDHC_PROT_CTRL_RD_DONE_NO_8CLK_MASK;
968 }
969
970 /* data present flag */
971 *flag |= USDHC_DATA_PRESENT_FLAG;
972 /* Disable useless interrupt */
973 if (en_dma) {
974 base->INT_SIGNAL_EN &=
975 ~(USDHC_INT_BUF_WRITE_READY_FLAG |
976 USDHC_INT_BUF_READ_READY_FLAG |
977 USDHC_INT_DMA_DONE_FLAG);
978 base->INT_STATUS_EN &=
979 ~(USDHC_INT_BUF_WRITE_READY_FLAG |
980 USDHC_INT_BUF_READ_READY_FLAG |
981 USDHC_INT_DMA_DONE_FLAG);
982 } else {
983 base->INT_SIGNAL_EN |=
984 USDHC_INT_BUF_WRITE_READY_FLAG |
985 USDHC_INT_BUF_READ_READY_FLAG;
986 base->INT_STATUS_EN |=
987 USDHC_INT_BUF_WRITE_READY_FLAG |
988 USDHC_INT_BUF_READ_READY_FLAG;
989 }
990 } else {
991 /* clear data flags */
992 mix_ctrl &= ~(USDHC_MIX_CTRL_MSBSEL_MASK |
993 USDHC_MIX_CTRL_BCEN_MASK |
994 USDHC_MIX_CTRL_DTDSEL_MASK |
995 USDHC_MIX_CTRL_AC12EN_MASK |
996 USDHC_MIX_CTRL_AC23EN_MASK);
997
998 if (base->PRES_STATE & USDHC_CMD_INHIBIT_FLAG)
999 return -EBUSY;
1000 }
1001
1002 /* config the mix parameter */
1003 base->MIX_CTRL = mix_ctrl;
1004
1005 return 0;
1006 }
1007
usdhc_send_cmd(USDHC_Type * base,struct usdhc_cmd * command)1008 static void usdhc_send_cmd(USDHC_Type *base, struct usdhc_cmd *command)
1009 {
1010 uint32_t xfer_type = base->CMD_XFR_TYP;
1011 uint32_t flags = command->flags;
1012
1013 if (!(base->PRES_STATE & USDHC_CMD_INHIBIT_FLAG)
1014 && (command->cmd_type != USDHC_CMD_TYPE_EMPTY)) {
1015 /* Define the flag corresponding to each response type. */
1016 switch (command->rsp_type) {
1017 case SDHC_RSP_TYPE_NONE:
1018 break;
1019 case SDHC_RSP_TYPE_R1: /* Response 1 */
1020 case SDHC_RSP_TYPE_R5: /* Response 5 */
1021 case SDHC_RSP_TYPE_R6: /* Response 6 */
1022 case SDHC_RSP_TYPE_R7: /* Response 7 */
1023 flags |= (USDHC_RSP_LEN_48_FLAG |
1024 USDHC_CRC_CHECK_FLAG |
1025 USDHC_IDX_CHECK_FLAG);
1026 break;
1027
1028 case SDHC_RSP_TYPE_R1b: /* Response 1 with busy */
1029 case SDHC_RSP_TYPE_R5b: /* Response 5 with busy */
1030 flags |= (USDHC_RSP_LEN_48_BUSY_FLAG |
1031 USDHC_CRC_CHECK_FLAG |
1032 USDHC_IDX_CHECK_FLAG);
1033 break;
1034
1035 case SDHC_RSP_TYPE_R2: /* Response 2 */
1036 flags |= (USDHC_RSP_LEN_136_FLAG |
1037 USDHC_CRC_CHECK_FLAG);
1038 break;
1039
1040 case SDHC_RSP_TYPE_R3: /* Response 3 */
1041 case SDHC_RSP_TYPE_R4: /* Response 4 */
1042 flags |= (USDHC_RSP_LEN_48_FLAG);
1043 break;
1044
1045 default:
1046 break;
1047 }
1048
1049 if (command->cmd_type == USDHC_CMD_TYPE_ABORT)
1050 flags |= USDHC_CMD_TYPE_ABORT_FLAG;
1051
1052 /* config cmd index */
1053 xfer_type &= ~(USDHC_CMD_XFR_TYP_CMDINX_MASK |
1054 USDHC_CMD_XFR_TYP_CMDTYP_MASK |
1055 USDHC_CMD_XFR_TYP_CICEN_MASK |
1056 USDHC_CMD_XFR_TYP_CCCEN_MASK |
1057 USDHC_CMD_XFR_TYP_RSPTYP_MASK |
1058 USDHC_CMD_XFR_TYP_DPSEL_MASK);
1059
1060 xfer_type |=
1061 (((command->index << USDHC_CMD_XFR_TYP_CMDINX_SHIFT) &
1062 USDHC_CMD_XFR_TYP_CMDINX_MASK) |
1063 ((flags) & (USDHC_CMD_XFR_TYP_CMDTYP_MASK |
1064 USDHC_CMD_XFR_TYP_CICEN_MASK |
1065 USDHC_CMD_XFR_TYP_CCCEN_MASK |
1066 USDHC_CMD_XFR_TYP_RSPTYP_MASK |
1067 USDHC_CMD_XFR_TYP_DPSEL_MASK)));
1068
1069 /* config the command xfertype and argument */
1070 base->CMD_ARG = command->argument;
1071 base->CMD_XFR_TYP = xfer_type;
1072 }
1073
1074 if (command->cmd_type == USDHC_CMD_TYPE_EMPTY) {
1075 /* disable CMD done interrupt for empty command */
1076 base->INT_SIGNAL_EN &= ~USDHC_INT_SIGNAL_EN_CCIEN_MASK;
1077 }
1078 }
1079
usdhc_cmd_rsp(struct usdhc_priv * priv)1080 static int usdhc_cmd_rsp(struct usdhc_priv *priv)
1081 {
1082 uint32_t i;
1083 USDHC_Type *base = priv->config->base;
1084 struct usdhc_cmd *cmd = &priv->op_context.cmd;
1085
1086 if (cmd->rsp_type != SDHC_RSP_TYPE_NONE) {
1087 cmd->response[0U] = base->CMD_RSP0;
1088 if (cmd->rsp_type == SDHC_RSP_TYPE_R2) {
1089 cmd->response[1U] = base->CMD_RSP1;
1090 cmd->response[2U] = base->CMD_RSP2;
1091 cmd->response[3U] = base->CMD_RSP3;
1092
1093 i = 4U;
1094 /* R3-R2-R1-R0(lowest 8 bit is invalid bit)
1095 * has the same format
1096 * as R2 format in SD specification document
1097 * after removed internal CRC7 and end bit.
1098 */
1099 do {
1100 cmd->response[i - 1U] <<= 8U;
1101 if (i > 1U) {
1102 cmd->response[i - 1U] |=
1103 ((cmd->response[i - 2U] &
1104 0xFF000000U) >> 24U);
1105 }
1106 i--;
1107 } while (i);
1108 }
1109 }
1110 /* check response error flag */
1111 if ((cmd->rsp_err_flags) &&
1112 ((cmd->rsp_type == SDHC_RSP_TYPE_R1) ||
1113 (cmd->rsp_type == SDHC_RSP_TYPE_R1b) ||
1114 (cmd->rsp_type == SDHC_RSP_TYPE_R6) ||
1115 (cmd->rsp_type == SDHC_RSP_TYPE_R5))) {
1116 if (((cmd->rsp_err_flags) & (cmd->response[0U])))
1117 return -EIO;
1118 }
1119
1120 return 0;
1121 }
1122
usdhc_wait_cmd_done(struct usdhc_priv * priv,bool poll_cmd)1123 static int usdhc_wait_cmd_done(struct usdhc_priv *priv,
1124 bool poll_cmd)
1125 {
1126 int error = 0;
1127 uint32_t int_status = 0U;
1128 USDHC_Type *base = priv->config->base;
1129
1130 /* check if need polling command done or not */
1131 if (poll_cmd) {
1132 /* Wait command complete or USDHC encounters error. */
1133 while (!(int_status & (USDHC_INT_CMD_DONE_FLAG |
1134 USDHC_INT_CMD_ERR_FLAG))) {
1135 int_status = base->INT_STATUS;
1136 }
1137
1138 if ((int_status & USDHC_INT_TUNING_ERR_FLAG) ||
1139 (int_status & USDHC_INT_CMD_ERR_FLAG)) {
1140 error = -EIO;
1141 }
1142 /* Receive response when command completes successfully. */
1143 if (!error) {
1144 error = usdhc_cmd_rsp(priv);
1145 } else {
1146 LOG_ERR("CMD%d Polling ERROR",
1147 priv->op_context.cmd.index);
1148 }
1149
1150 base->INT_STATUS = (USDHC_INT_CMD_DONE_FLAG |
1151 USDHC_INT_CMD_ERR_FLAG |
1152 USDHC_INT_TUNING_ERR_FLAG);
1153 }
1154
1155 return error;
1156 }
1157
usdhc_write_data(USDHC_Type * base,uint32_t data)1158 static inline void usdhc_write_data(USDHC_Type *base, uint32_t data)
1159 {
1160 base->DATA_BUFF_ACC_PORT = data;
1161 }
1162
usdhc_read_data(USDHC_Type * base)1163 static inline uint32_t usdhc_read_data(USDHC_Type *base)
1164 {
1165 return base->DATA_BUFF_ACC_PORT;
1166 }
1167
usdhc_read_data_port(struct usdhc_priv * priv,uint32_t xfered_words)1168 static uint32_t usdhc_read_data_port(struct usdhc_priv *priv,
1169 uint32_t xfered_words)
1170 {
1171 USDHC_Type *base = priv->config->base;
1172 struct usdhc_data *data = &priv->op_context.data;
1173 uint32_t i, total_words, remaing_words;
1174 /* The words can be read at this time. */
1175 uint32_t watermark = ((base->WTMK_LVL & USDHC_WTMK_LVL_RD_WML_MASK) >>
1176 USDHC_WTMK_LVL_RD_WML_SHIFT);
1177
1178 /* If DMA is enable, do not need to polling data port */
1179 if (!(base->MIX_CTRL & USDHC_MIX_CTRL_DMAEN_MASK)) {
1180 /*Add non aligned access support.*/
1181 if (data->block_size % sizeof(uint32_t)) {
1182 data->block_size +=
1183 sizeof(uint32_t) -
1184 (data->block_size % sizeof(uint32_t));
1185 /* make the block size as word-aligned */
1186 }
1187
1188 total_words = ((data->block_count * data->block_size) /
1189 sizeof(uint32_t));
1190
1191 if (watermark >= total_words) {
1192 remaing_words = total_words;
1193 } else if ((watermark < total_words) &&
1194 ((total_words - xfered_words) >= watermark)) {
1195 remaing_words = watermark;
1196 } else {
1197 remaing_words = (total_words - xfered_words);
1198 }
1199
1200 i = 0U;
1201 while (i < remaing_words) {
1202 data->rx_data[xfered_words++] = usdhc_read_data(base);
1203 i++;
1204 }
1205 }
1206
1207 return xfered_words;
1208 }
1209
usdhc_read_data_port_sync(struct usdhc_priv * priv)1210 static int usdhc_read_data_port_sync(struct usdhc_priv *priv)
1211 {
1212 USDHC_Type *base = priv->config->base;
1213 struct usdhc_data *data = &priv->op_context.data;
1214 uint32_t total_words;
1215 uint32_t xfered_words = 0U, int_status = 0U;
1216 int error = 0;
1217
1218 if (data->block_size % sizeof(uint32_t)) {
1219 data->block_size +=
1220 sizeof(uint32_t) -
1221 (data->block_size % sizeof(uint32_t));
1222 }
1223
1224 total_words =
1225 ((data->block_count * data->block_size) /
1226 sizeof(uint32_t));
1227
1228 while ((!error) && (xfered_words < total_words)) {
1229 while (!(int_status & (USDHC_INT_BUF_READ_READY_FLAG |
1230 USDHC_INT_DATA_ERR_FLAG |
1231 USDHC_INT_TUNING_ERR_FLAG)))
1232 int_status = base->INT_STATUS;
1233
1234 /* during std tuning process, software do not need to read data,
1235 * but wait BRR is enough
1236 */
1237 if ((data->data_type == USDHC_XFER_TUNING) &&
1238 (int_status & USDHC_INT_BUF_READ_READY_FLAG)) {
1239 base->INT_STATUS = USDHC_INT_BUF_READ_READY_FLAG |
1240 USDHC_INT_TUNING_PASS_FLAG;
1241
1242 return 0;
1243 } else if ((int_status & USDHC_INT_TUNING_ERR_FLAG)) {
1244 base->INT_STATUS = USDHC_INT_TUNING_ERR_FLAG;
1245 /* if tuning error occur ,return directly */
1246 error = -EIO;
1247 } else if ((int_status & USDHC_INT_DATA_ERR_FLAG)) {
1248 if (!(data->ignore_err))
1249 error = -EIO;
1250 /* clear data error flag */
1251 base->INT_STATUS = USDHC_INT_DATA_ERR_FLAG;
1252 }
1253
1254 if (!error) {
1255 xfered_words = usdhc_read_data_port(priv, xfered_words);
1256 /* clear buffer read ready */
1257 base->INT_STATUS = USDHC_INT_BUF_READ_READY_FLAG;
1258 int_status = 0U;
1259 }
1260 }
1261
1262 /* Clear data complete flag after the last read operation. */
1263 base->INT_STATUS = USDHC_INT_DATA_DONE_FLAG;
1264
1265 return error;
1266 }
1267
usdhc_write_data_port(struct usdhc_priv * priv,uint32_t xfered_words)1268 static uint32_t usdhc_write_data_port(struct usdhc_priv *priv,
1269 uint32_t xfered_words)
1270 {
1271 USDHC_Type *base = priv->config->base;
1272 struct usdhc_data *data = &priv->op_context.data;
1273 uint32_t i, total_words, remaing_words;
1274 /* Words can be wrote at this time. */
1275 uint32_t watermark = ((base->WTMK_LVL & USDHC_WTMK_LVL_WR_WML_MASK) >>
1276 USDHC_WTMK_LVL_WR_WML_SHIFT);
1277
1278 /* If DMA is enable, do not need to polling data port */
1279 if (!(base->MIX_CTRL & USDHC_MIX_CTRL_DMAEN_MASK)) {
1280 if (data->block_size % sizeof(uint32_t)) {
1281 data->block_size +=
1282 sizeof(uint32_t) -
1283 (data->block_size % sizeof(uint32_t));
1284 }
1285
1286 total_words =
1287 ((data->block_count * data->block_size) /
1288 sizeof(uint32_t));
1289
1290 if (watermark >= total_words) {
1291 remaing_words = total_words;
1292 } else if ((watermark < total_words) &&
1293 ((total_words - xfered_words) >= watermark)) {
1294 remaing_words = watermark;
1295 } else {
1296 remaing_words = (total_words - xfered_words);
1297 }
1298
1299 i = 0U;
1300 while (i < remaing_words) {
1301 usdhc_write_data(base, data->tx_data[xfered_words++]);
1302 i++;
1303 }
1304 }
1305
1306 return xfered_words;
1307 }
1308
usdhc_write_data_port_sync(struct usdhc_priv * priv)1309 static status_t usdhc_write_data_port_sync(struct usdhc_priv *priv)
1310 {
1311 USDHC_Type *base = priv->config->base;
1312 struct usdhc_data *data = &priv->op_context.data;
1313 uint32_t total_words;
1314 uint32_t xfered_words = 0U, int_status = 0U;
1315 int error = 0;
1316
1317 if (data->block_size % sizeof(uint32_t)) {
1318 data->block_size +=
1319 sizeof(uint32_t) - (data->block_size % sizeof(uint32_t));
1320 }
1321
1322 total_words = (data->block_count * data->block_size) / sizeof(uint32_t);
1323
1324 while ((!error) && (xfered_words < total_words)) {
1325 while (!(int_status & (USDHC_INT_BUF_WRITE_READY_FLAG |
1326 USDHC_INT_DATA_ERR_FLAG |
1327 USDHC_INT_TUNING_ERR_FLAG))) {
1328 int_status = base->INT_STATUS;
1329 }
1330
1331 if (int_status & USDHC_INT_TUNING_ERR_FLAG) {
1332 base->INT_STATUS = USDHC_INT_TUNING_ERR_FLAG;
1333 /* if tuning error occur ,return directly */
1334 return -EIO;
1335 } else if (int_status & USDHC_INT_DATA_ERR_FLAG) {
1336 if (!(data->ignore_err))
1337 error = -EIO;
1338 /* clear data error flag */
1339 base->INT_STATUS = USDHC_INT_DATA_ERR_FLAG;
1340 }
1341
1342 if (!error) {
1343 xfered_words = usdhc_write_data_port(priv,
1344 xfered_words);
1345 /* clear buffer write ready */
1346 base->INT_STATUS = USDHC_INT_BUF_WRITE_READY_FLAG;
1347 int_status = 0U;
1348 }
1349 }
1350
1351 /* Wait write data complete or data transfer error
1352 * after the last writing operation.
1353 */
1354 while (!(int_status & (USDHC_INT_DATA_DONE_FLAG |
1355 USDHC_INT_DATA_ERR_FLAG))) {
1356 int_status = base->INT_STATUS;
1357 }
1358
1359 if (int_status & USDHC_INT_DATA_ERR_FLAG) {
1360 if (!(data->ignore_err))
1361 error = -EIO;
1362 }
1363 base->INT_STATUS = USDHC_INT_DATA_DONE_FLAG |
1364 USDHC_INT_DATA_ERR_FLAG;
1365
1366 return error;
1367 }
1368
usdhc_data_sync_xfer(struct usdhc_priv * priv,bool en_dma)1369 static int usdhc_data_sync_xfer(struct usdhc_priv *priv, bool en_dma)
1370 {
1371 int error = 0;
1372 uint32_t int_status = 0U;
1373 USDHC_Type *base = priv->config->base;
1374 struct usdhc_data *data = &priv->op_context.data;
1375
1376 if (en_dma) {
1377 /* Wait data complete or USDHC encounters error. */
1378 while (!((int_status &
1379 (USDHC_INT_DATA_DONE_FLAG | USDHC_INT_DATA_ERR_FLAG |
1380 USDHC_INT_CMD_ERR_FLAG | USDHC_INT_TUNING_ERR_FLAG)))) {
1381 int_status = base->INT_STATUS;
1382 }
1383
1384 if (int_status & USDHC_INT_TUNING_ERR_FLAG) {
1385 error = -EIO;
1386 } else if ((int_status & (USDHC_INT_DATA_ERR_FLAG |
1387 USDHC_INT_DMA_ERR_FLAG))) {
1388 if ((!(data->ignore_err)) ||
1389 (int_status &
1390 USDHC_INT_DATA_TIMEOUT_FLAG)) {
1391 error = -EIO;
1392 }
1393 }
1394 /* load dummy data */
1395 if ((data->data_type == USDHC_XFER_BOOT_CONTINUOUS) && (!error))
1396 *(data->rx_data) = g_usdhc_boot_dummy;
1397
1398 base->INT_STATUS = (USDHC_INT_DATA_DONE_FLAG |
1399 USDHC_INT_DATA_ERR_FLAG |
1400 USDHC_INT_DMA_ERR_FLAG |
1401 USDHC_INT_TUNING_PASS_FLAG |
1402 USDHC_INT_TUNING_ERR_FLAG);
1403 } else {
1404 if (data->rx_data) {
1405 error = usdhc_read_data_port_sync(priv);
1406 } else {
1407 error = usdhc_write_data_port_sync(priv);
1408 }
1409 }
1410 return error;
1411 }
1412
usdhc_xfer(struct usdhc_priv * priv)1413 static int usdhc_xfer(struct usdhc_priv *priv)
1414 {
1415 int error = -EIO;
1416 struct usdhc_data *data = NULL;
1417 bool en_dma = true, execute_tuning;
1418 USDHC_Type *base = priv->config->base;
1419
1420 if (!priv->op_context.cmd_only) {
1421 data = &priv->op_context.data;
1422 if (data->data_type == USDHC_XFER_TUNING)
1423 execute_tuning = true;
1424 else
1425 execute_tuning = false;
1426 } else {
1427 execute_tuning = false;
1428 }
1429
1430 /*check re-tuning request*/
1431 if ((base->INT_STATUS & USDHC_INT_RE_TUNING_EVENT_FLAG)) {
1432 base->INT_STATUS = USDHC_INT_RE_TUNING_EVENT_FLAG;
1433 return -EAGAIN;
1434 }
1435
1436 /* Update ADMA descriptor table according to different DMA mode
1437 * (no DMA, ADMA1, ADMA2).
1438 */
1439
1440 if (data && (!execute_tuning) && priv->op_context.dma_cfg.adma_table)
1441 error = usdhc_adma_table_cfg(priv,
1442 (data->data_type & USDHC_XFER_BOOT) ?
1443 USDHC_ADMA_MUTI_FLAG : USDHC_ADMA_SINGLE_FLAG);
1444
1445 /* if the DMA descriptor configure fail or not needed , disable it */
1446 if (error) {
1447 en_dma = false;
1448 /* disable DMA, using polling mode in this situation */
1449 base->MIX_CTRL &= ~USDHC_MIX_CTRL_DMAEN_MASK;
1450 base->PROT_CTRL &= ~USDHC_PROT_CTRL_DMASEL_MASK;
1451 }
1452
1453 /* config the data transfer parameter */
1454 error = usdhc_data_xfer_cfg(priv, en_dma);
1455 if (error)
1456 return error;
1457 /* send command first */
1458 usdhc_send_cmd(base, &priv->op_context.cmd);
1459 /* wait command done */
1460 error = usdhc_wait_cmd_done(priv, (data == NULL) ||
1461 (data->data_type == USDHC_XFER_NORMAL));
1462 /* wait transfer data finish */
1463 if (data && (!error)) {
1464 return usdhc_data_sync_xfer(priv, en_dma);
1465 }
1466
1467 return error;
1468 }
1469
usdhc_select_1_8_vol(USDHC_Type * base,bool en_1_8_v)1470 static inline void usdhc_select_1_8_vol(USDHC_Type *base, bool en_1_8_v)
1471 {
1472 if (en_1_8_v)
1473 base->VEND_SPEC |= USDHC_VEND_SPEC_VSELECT_MASK;
1474 else
1475 base->VEND_SPEC &= ~USDHC_VEND_SPEC_VSELECT_MASK;
1476 }
1477
usdhc_force_clk_on(USDHC_Type * base,bool on)1478 static inline void usdhc_force_clk_on(USDHC_Type *base, bool on)
1479 {
1480 if (on)
1481 base->VEND_SPEC |= USDHC_VEND_SPEC_FRC_SDCLK_ON_MASK;
1482 else
1483 base->VEND_SPEC &= ~USDHC_VEND_SPEC_FRC_SDCLK_ON_MASK;
1484 }
1485
usdhc_tuning(USDHC_Type * base,uint32_t start,uint32_t step,bool enable)1486 static void usdhc_tuning(USDHC_Type *base, uint32_t start, uint32_t step, bool enable)
1487 {
1488 uint32_t tuning_ctrl = 0U;
1489
1490 if (enable) {
1491 /* feedback clock */
1492 base->MIX_CTRL |= USDHC_MIX_CTRL_FBCLK_SEL_MASK;
1493 /* config tuning start and step */
1494 tuning_ctrl = base->TUNING_CTRL;
1495 tuning_ctrl &= ~(USDHC_TUNING_CTRL_TUNING_START_TAP_MASK |
1496 USDHC_TUNING_CTRL_TUNING_STEP_MASK);
1497 tuning_ctrl |= (USDHC_TUNING_CTRL_TUNING_START_TAP(start) |
1498 USDHC_TUNING_CTRL_TUNING_STEP(step) |
1499 USDHC_TUNING_CTRL_STD_TUNING_EN_MASK);
1500 base->TUNING_CTRL = tuning_ctrl;
1501
1502 /* excute tuning */
1503 base->AUTOCMD12_ERR_STATUS |=
1504 (USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK |
1505 USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK);
1506 } else {
1507 /* disable the standard tuning */
1508 base->TUNING_CTRL &= ~USDHC_TUNING_CTRL_STD_TUNING_EN_MASK;
1509 /* clear excute tuning */
1510 base->AUTOCMD12_ERR_STATUS &=
1511 ~(USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK |
1512 USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK);
1513 }
1514 }
1515
usdhc_adjust_tuning_timing(USDHC_Type * base,uint32_t delay)1516 int usdhc_adjust_tuning_timing(USDHC_Type *base, uint32_t delay)
1517 {
1518 uint32_t clk_tune_ctrl = 0U;
1519
1520 clk_tune_ctrl = base->CLK_TUNE_CTRL_STATUS;
1521
1522 clk_tune_ctrl &= ~USDHC_CLK_TUNE_CTRL_STATUS_DLY_CELL_SET_PRE_MASK;
1523
1524 clk_tune_ctrl |= USDHC_CLK_TUNE_CTRL_STATUS_DLY_CELL_SET_PRE(delay);
1525
1526 /* load the delay setting */
1527 base->CLK_TUNE_CTRL_STATUS = clk_tune_ctrl;
1528 /* check delat setting error */
1529 if (base->CLK_TUNE_CTRL_STATUS &
1530 (USDHC_CLK_TUNE_CTRL_STATUS_PRE_ERR_MASK |
1531 USDHC_CLK_TUNE_CTRL_STATUS_NXT_ERR_MASK))
1532 return -EIO;
1533
1534 return 0;
1535 }
1536
usdhc_set_retuning_timer(USDHC_Type * base,uint32_t counter)1537 static inline void usdhc_set_retuning_timer(USDHC_Type *base, uint32_t counter)
1538 {
1539 base->HOST_CTRL_CAP &= ~USDHC_HOST_CTRL_CAP_TIME_COUNT_RETUNING_MASK;
1540 base->HOST_CTRL_CAP |= USDHC_HOST_CTRL_CAP_TIME_COUNT_RETUNING(counter);
1541 }
1542
usdhc_set_bus_width(USDHC_Type * base,enum usdhc_data_bus_width width)1543 static inline void usdhc_set_bus_width(USDHC_Type *base,
1544 enum usdhc_data_bus_width width)
1545 {
1546 base->PROT_CTRL = ((base->PROT_CTRL & ~USDHC_PROT_CTRL_DTW_MASK) |
1547 USDHC_PROT_CTRL_DTW(width));
1548 }
1549
usdhc_execute_tuning(struct usdhc_priv * priv)1550 static int usdhc_execute_tuning(struct usdhc_priv *priv)
1551 {
1552 bool tuning_err = true;
1553 int ret;
1554 USDHC_Type *base = priv->config->base;
1555
1556 /* enable the standard tuning */
1557 usdhc_tuning(base, SDHC_STANDARD_TUNING_START, SDHC_TUINIG_STEP, true);
1558
1559 while (true) {
1560 /* send tuning block */
1561 ret = usdhc_xfer(priv);
1562 if (ret) {
1563 return ret;
1564 }
1565 usdhc_millsec_delay(10);
1566
1567 /*wait excute tuning bit clear*/
1568 if ((base->AUTOCMD12_ERR_STATUS &
1569 USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK)) {
1570 continue;
1571 }
1572
1573 /* if tuning error , re-tuning again */
1574 if ((base->CLK_TUNE_CTRL_STATUS &
1575 (USDHC_CLK_TUNE_CTRL_STATUS_NXT_ERR_MASK |
1576 USDHC_CLK_TUNE_CTRL_STATUS_PRE_ERR_MASK)) &&
1577 tuning_err) {
1578 tuning_err = false;
1579 /* enable the standard tuning */
1580 usdhc_tuning(base, SDHC_STANDARD_TUNING_START,
1581 SDHC_TUINIG_STEP, true);
1582 usdhc_adjust_tuning_timing(base,
1583 SDHC_STANDARD_TUNING_START);
1584 } else {
1585 break;
1586 }
1587 }
1588
1589 /* delay to wait the host controller stable */
1590 usdhc_millsec_delay(1000);
1591
1592 /* check tuning result*/
1593 if (!(base->AUTOCMD12_ERR_STATUS &
1594 USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK)) {
1595 return -EIO;
1596 }
1597
1598 usdhc_set_retuning_timer(base, SDHC_RETUNING_TIMER_COUNT);
1599
1600 return 0;
1601 }
1602
usdhc_vol_switch(struct usdhc_priv * priv)1603 static int usdhc_vol_switch(struct usdhc_priv *priv)
1604 {
1605 USDHC_Type *base = priv->config->base;
1606 int retry = 0xffff;
1607
1608 while (base->PRES_STATE &
1609 (CARD_DATA1_STATUS_MASK | CARD_DATA2_STATUS_MASK |
1610 CARD_DATA3_STATUS_MASK | CARD_DATA0_NOT_BUSY)) {
1611 retry--;
1612 if (retry <= 0) {
1613 return -EACCES;
1614 }
1615 }
1616
1617 /* host switch to 1.8V */
1618 usdhc_select_1_8_vol(base, true);
1619
1620 usdhc_millsec_delay(20000U);
1621
1622 /*enable force clock on*/
1623 usdhc_force_clk_on(base, true);
1624 /* dealy 1ms,not exactly correct when use while */
1625 usdhc_millsec_delay(20000U);
1626 /*disable force clock on*/
1627 usdhc_force_clk_on(base, false);
1628
1629 /* check data line and cmd line status */
1630 retry = 0xffff;
1631 while (!(base->PRES_STATE &
1632 (CARD_DATA1_STATUS_MASK | CARD_DATA2_STATUS_MASK |
1633 CARD_DATA3_STATUS_MASK | CARD_DATA0_NOT_BUSY))) {
1634 retry--;
1635 if (retry <= 0) {
1636 return -EBUSY;
1637 }
1638 }
1639
1640 return 0;
1641 }
1642
usdhc_op_ctx_init(struct usdhc_priv * priv,bool cmd_only,uint8_t cmd_idx,uint32_t arg,enum sdhc_rsp_type rsp_type)1643 static inline void usdhc_op_ctx_init(struct usdhc_priv *priv,
1644 bool cmd_only, uint8_t cmd_idx, uint32_t arg, enum sdhc_rsp_type rsp_type)
1645 {
1646 struct usdhc_cmd *cmd = &priv->op_context.cmd;
1647 struct usdhc_data *data = &priv->op_context.data;
1648
1649 priv->op_context.cmd_only = cmd_only;
1650
1651 memset((char *)cmd, 0, sizeof(struct usdhc_cmd));
1652 memset((char *)data, 0, sizeof(struct usdhc_data));
1653
1654 cmd->index = cmd_idx;
1655 cmd->argument = arg;
1656 cmd->rsp_type = rsp_type;
1657 }
1658
usdhc_select_fun(struct usdhc_priv * priv,uint32_t group,uint32_t function)1659 static int usdhc_select_fun(struct usdhc_priv *priv,
1660 uint32_t group, uint32_t function)
1661 {
1662 const struct usdhc_config *config = priv->config;
1663 uint32_t *fun_status;
1664 uint16_t fun_grp_info[6U] = {0};
1665 uint32_t current_fun_status = 0U, arg;
1666 struct usdhc_cmd *cmd = &priv->op_context.cmd;
1667 struct usdhc_data *data = &priv->op_context.data;
1668 int ret;
1669
1670 /* check if card support CMD6 */
1671 if ((priv->card_info.version <= SD_SPEC_VER1_0) ||
1672 (!(priv->card_info.csd.cmd_class & SD_CMD_CLASS_SWITCH))) {
1673 return -EINVAL;
1674 }
1675
1676 /* Check if card support high speed mode. */
1677 arg = (SD_SWITCH_CHECK << 31U | 0x00FFFFFFU);
1678 arg &= ~((uint32_t)(0xFU) << (group * 4U));
1679 arg |= (function << (group * 4U));
1680 usdhc_op_ctx_init(priv, 0, SDHC_SWITCH, arg, SDHC_RSP_TYPE_R1);
1681
1682 data->block_size = 64U;
1683 data->block_count = 1U;
1684 data->rx_data = &g_usdhc_rx_dummy[0];
1685 ret = usdhc_xfer(priv);
1686 if (ret || (cmd->response[0U] & SDHC_R1ERR_All_FLAG))
1687 return -EIO;
1688
1689 fun_status = data->rx_data;
1690
1691 /* Switch function status byte sequence
1692 * from card is big endian(MSB first).
1693 */
1694 switch (config->endian) {
1695 case USDHC_LITTLE_ENDIAN:
1696 fun_status[0U] = SWAP_WORD_BYTE_SEQUENCE(fun_status[0U]);
1697 fun_status[1U] = SWAP_WORD_BYTE_SEQUENCE(fun_status[1U]);
1698 fun_status[2U] = SWAP_WORD_BYTE_SEQUENCE(fun_status[2U]);
1699 fun_status[3U] = SWAP_WORD_BYTE_SEQUENCE(fun_status[3U]);
1700 fun_status[4U] = SWAP_WORD_BYTE_SEQUENCE(fun_status[4U]);
1701 break;
1702 case USDHC_BIG_ENDIAN:
1703 break;
1704 case USDHC_HALF_WORD_BIG_ENDIAN:
1705 fun_status[0U] = SWAP_HALF_WROD_BYTE_SEQUENCE(fun_status[0U]);
1706 fun_status[1U] = SWAP_HALF_WROD_BYTE_SEQUENCE(fun_status[1U]);
1707 fun_status[2U] = SWAP_HALF_WROD_BYTE_SEQUENCE(fun_status[2U]);
1708 fun_status[3U] = SWAP_HALF_WROD_BYTE_SEQUENCE(fun_status[3U]);
1709 fun_status[4U] = SWAP_HALF_WROD_BYTE_SEQUENCE(fun_status[4U]);
1710 break;
1711 default:
1712 return -ENOTSUP;
1713 }
1714
1715 fun_grp_info[5U] = (uint16_t)fun_status[0U];
1716 fun_grp_info[4U] = (uint16_t)(fun_status[1U] >> 16U);
1717 fun_grp_info[3U] = (uint16_t)(fun_status[1U]);
1718 fun_grp_info[2U] = (uint16_t)(fun_status[2U] >> 16U);
1719 fun_grp_info[1U] = (uint16_t)(fun_status[2U]);
1720 fun_grp_info[0U] = (uint16_t)(fun_status[3U] >> 16U);
1721 current_fun_status = ((fun_status[3U] & 0xFFU) << 8U) |
1722 (fun_status[4U] >> 24U);
1723
1724 /* check if function is support */
1725 if (((fun_grp_info[group] & (1 << function)) == 0U) ||
1726 ((current_fun_status >>
1727 (group * 4U)) & 0xFU) != function) {
1728 return -ENOTSUP;
1729 }
1730
1731 /* Switch to high speed mode. */
1732 usdhc_op_ctx_init(priv, 0, SDHC_SWITCH, arg, SDHC_RSP_TYPE_R1);
1733
1734 data->block_size = 64U;
1735 data->block_count = 1U;
1736 data->rx_data = &g_usdhc_rx_dummy[0];
1737
1738 cmd->argument = (SD_SWITCH_SET << 31U | 0x00FFFFFFU);
1739 cmd->argument &= ~((uint32_t)(0xFU) << (group * 4U));
1740 cmd->argument |= (function << (group * 4U));
1741
1742 ret = usdhc_xfer(priv);
1743 if (ret || (cmd->response[0U] & SDHC_R1ERR_All_FLAG))
1744 return -EIO;
1745 /* Switch function status byte sequence
1746 * from card is big endian(MSB first).
1747 */
1748 switch (config->endian) {
1749 case USDHC_LITTLE_ENDIAN:
1750 fun_status[3U] = SWAP_WORD_BYTE_SEQUENCE(fun_status[3U]);
1751 fun_status[4U] = SWAP_WORD_BYTE_SEQUENCE(fun_status[4U]);
1752 break;
1753 case USDHC_BIG_ENDIAN:
1754 break;
1755 case USDHC_HALF_WORD_BIG_ENDIAN:
1756 fun_status[3U] = SWAP_HALF_WROD_BYTE_SEQUENCE(fun_status[3U]);
1757 fun_status[4U] = SWAP_HALF_WROD_BYTE_SEQUENCE(fun_status[4U]);
1758 break;
1759 default:
1760 return -ENOTSUP;
1761 }
1762 /* According to the "switch function status[bits 511~0]" return
1763 * by switch command in mode "set function":
1764 * -check if group 1 is successfully changed to function 1 by checking
1765 * if bits 379~376 equal value 1;
1766 */
1767 current_fun_status = ((fun_status[3U] & 0xFFU) << 8U) |
1768 (fun_status[4U] >> 24U);
1769
1770 if (((current_fun_status >>
1771 (group * 4U)) & 0xFU) != function) {
1772 return -EINVAL;
1773 }
1774
1775 return 0;
1776 }
1777
usdhc_set_sd_clk(USDHC_Type * base,uint32_t src_clk_hz,uint32_t sd_clk_hz)1778 uint32_t usdhc_set_sd_clk(USDHC_Type *base, uint32_t src_clk_hz, uint32_t sd_clk_hz)
1779 {
1780 uint32_t total_div = 0U;
1781 uint32_t divisor = 0U;
1782 uint32_t prescaler = 0U;
1783 uint32_t sysctl = 0U;
1784 uint32_t nearest_freq = 0U;
1785
1786 __ASSERT_NO_MSG(src_clk_hz != 0U);
1787 __ASSERT_NO_MSG((sd_clk_hz != 0U) && (sd_clk_hz <= src_clk_hz));
1788
1789 /* calculate total divisor first */
1790 total_div = src_clk_hz / sd_clk_hz;
1791 if (total_div > (USDHC_MAX_CLKFS * USDHC_MAX_DVS)) {
1792 return 0U;
1793 }
1794
1795 if (total_div) {
1796 /* calculate the divisor (src_clk_hz / divisor) <= sd_clk_hz */
1797 if ((src_clk_hz / total_div) > sd_clk_hz)
1798 total_div++;
1799
1800 /* divide the total divisor to div and prescaler */
1801 if (total_div > USDHC_MAX_DVS) {
1802 prescaler = total_div / USDHC_MAX_DVS;
1803 /* prescaler must be a value which equal 2^n and
1804 * smaller than SDHC_MAX_CLKFS
1805 */
1806 while (((USDHC_MAX_CLKFS % prescaler) != 0U) ||
1807 (prescaler == 1U))
1808 prescaler++;
1809 /* calculate the divisor */
1810 divisor = total_div / prescaler;
1811 /* fine tuning the divisor until
1812 * divisor * prescaler >= total_div
1813 */
1814 while ((divisor * prescaler) < total_div) {
1815 divisor++;
1816 if (divisor > USDHC_MAX_DVS) {
1817 if ((prescaler <<= 1U) >
1818 USDHC_MAX_CLKFS) {
1819 return 0;
1820 }
1821 divisor = total_div / prescaler;
1822 }
1823 }
1824 } else {
1825 /* in this situation , divsior and SDCLKFS
1826 * can generate same clock
1827 * use SDCLKFS
1828 */
1829 if (((total_div % 2U) != 0U) & (total_div != 1U)) {
1830 divisor = total_div;
1831 prescaler = 1U;
1832 } else {
1833 divisor = 1U;
1834 prescaler = total_div;
1835 }
1836 }
1837 nearest_freq = src_clk_hz / (divisor == 0U ? 1U : divisor) /
1838 prescaler;
1839 } else {
1840 /* in this condition , src_clk_hz = busClock_Hz, */
1841 /* in DDR mode , set SDCLKFS to 0, divisor = 0, actually the
1842 * totoal divider = 2U
1843 */
1844 divisor = 0U;
1845 prescaler = 0U;
1846 nearest_freq = src_clk_hz;
1847 }
1848
1849 /* calculate the value write to register */
1850 if (divisor != 0U) {
1851 USDHC_PREV_DVS(divisor);
1852 }
1853 /* calculate the value write to register */
1854 if (prescaler != 0U) {
1855 USDHC_PREV_CLKFS(prescaler, 1U);
1856 }
1857
1858 /* Set the SD clock frequency divisor, SD clock frequency select,
1859 * data timeout counter value.
1860 */
1861 sysctl = base->SYS_CTRL;
1862 sysctl &= ~(USDHC_SYS_CTRL_DVS_MASK |
1863 USDHC_SYS_CTRL_SDCLKFS_MASK);
1864 sysctl |= (USDHC_SYS_CTRL_DVS(divisor) |
1865 USDHC_SYS_CTRL_SDCLKFS(prescaler));
1866 base->SYS_CTRL = sysctl;
1867
1868 /* Wait until the SD clock is stable. */
1869 while (!(base->PRES_STATE & USDHC_PRES_STATE_SDSTB_MASK)) {
1870 ;
1871 }
1872
1873 return nearest_freq;
1874 }
1875
usdhc_enable_ddr_mode(USDHC_Type * base,bool enable,uint32_t nibble_pos)1876 static void usdhc_enable_ddr_mode(USDHC_Type *base,
1877 bool enable, uint32_t nibble_pos)
1878 {
1879 uint32_t prescaler = (base->SYS_CTRL & USDHC_SYS_CTRL_SDCLKFS_MASK) >>
1880 USDHC_SYS_CTRL_SDCLKFS_SHIFT;
1881
1882 if (enable) {
1883 base->MIX_CTRL &= ~USDHC_MIX_CTRL_NIBBLE_POS_MASK;
1884 base->MIX_CTRL |= (USDHC_MIX_CTRL_DDR_EN_MASK |
1885 USDHC_MIX_CTRL_NIBBLE_POS(nibble_pos));
1886 prescaler >>= 1U;
1887 } else {
1888 base->MIX_CTRL &= ~USDHC_MIX_CTRL_DDR_EN_MASK;
1889
1890 if (prescaler == 0U) {
1891 prescaler += 1U;
1892 } else {
1893 prescaler <<= 1U;
1894 }
1895 }
1896
1897 base->SYS_CTRL = (base->SYS_CTRL & (~USDHC_SYS_CTRL_SDCLKFS_MASK)) |
1898 USDHC_SYS_CTRL_SDCLKFS(prescaler);
1899 }
1900
usdhc_select_bus_timing(struct usdhc_priv * priv)1901 static int usdhc_select_bus_timing(struct usdhc_priv *priv)
1902 {
1903 const struct usdhc_config *config = priv->config;
1904 int error = -EIO;
1905
1906 if (priv->card_info.voltage != SD_VOL_1_8_V) {
1907 /* Switch the card to high speed mode */
1908 if (priv->host_capability.host_flags &
1909 USDHC_SUPPORT_HIGHSPEED_FLAG) {
1910 /* group 1, function 1 ->high speed mode*/
1911 error = usdhc_select_fun(priv, SD_GRP_TIMING_MODE,
1912 SD_TIMING_SDR25_HIGH_SPEED_MODE);
1913 /* If the result isn't "switching to
1914 * high speed mode(50MHZ)
1915 * successfully or card doesn't support
1916 * high speed
1917 * mode". Return failed status.
1918 */
1919 if (!error) {
1920 priv->card_info.sd_timing =
1921 SD_TIMING_SDR25_HIGH_SPEED_MODE;
1922 priv->card_info.busclk_hz =
1923 usdhc_set_sd_clk(config->base,
1924 priv->src_clk_hz,
1925 SD_CLOCK_50MHZ);
1926 } else if (error == -ENOTSUP) {
1927 /* if not support high speed,
1928 * keep the card work at default mode
1929 */
1930 return 0;
1931 }
1932 } else {
1933 /* if not support high speed,
1934 * keep the card work at default mode
1935 */
1936 return 0;
1937 }
1938 } else if ((USDHC_SUPPORT_SDR104_FLAG !=
1939 SDMMCHOST_NOT_SUPPORT) ||
1940 (USDHC_SUPPORT_SDR50_FLAG != SDMMCHOST_NOT_SUPPORT) ||
1941 (USDHC_SUPPORT_DDR50_FLAG != SDMMCHOST_NOT_SUPPORT)) {
1942 /* card is in UHS_I mode */
1943 switch (priv->card_info.sd_timing) {
1944 /* if not select timing mode,
1945 * sdmmc will handle it automatically
1946 */
1947 case SD_TIMING_SDR12_DFT_MODE:
1948 case SD_TIMING_SDR104_MODE:
1949 error = usdhc_select_fun(priv, SD_GRP_TIMING_MODE,
1950 SD_TIMING_SDR104_MODE);
1951 if (!error) {
1952 priv->card_info.sd_timing =
1953 SD_TIMING_SDR104_MODE;
1954 priv->card_info.busclk_hz =
1955 usdhc_set_sd_clk(config->base,
1956 priv->src_clk_hz,
1957 SDMMCHOST_SUPPORT_SDR104_FREQ);
1958 break;
1959 }
1960 case SD_TIMING_DDR50_MODE:
1961 error = usdhc_select_fun(priv, SD_GRP_TIMING_MODE,
1962 SD_TIMING_DDR50_MODE);
1963 if (!error) {
1964 priv->card_info.sd_timing =
1965 SD_TIMING_DDR50_MODE;
1966 priv->card_info.busclk_hz =
1967 usdhc_set_sd_clk(
1968 config->base,
1969 priv->src_clk_hz,
1970 SD_CLOCK_50MHZ);
1971 usdhc_enable_ddr_mode(config->base, true, 0U);
1972 }
1973 break;
1974 case SD_TIMING_SDR50_MODE:
1975 error = usdhc_select_fun(priv,
1976 SD_GRP_TIMING_MODE,
1977 SD_TIMING_SDR50_MODE);
1978 if (!error) {
1979 priv->card_info.sd_timing =
1980 SD_TIMING_SDR50_MODE;
1981 priv->card_info.busclk_hz =
1982 usdhc_set_sd_clk(
1983 config->base,
1984 priv->src_clk_hz,
1985 SD_CLOCK_100MHZ);
1986 }
1987 break;
1988 case SD_TIMING_SDR25_HIGH_SPEED_MODE:
1989 error = usdhc_select_fun(priv, SD_GRP_TIMING_MODE,
1990 SD_TIMING_SDR25_HIGH_SPEED_MODE);
1991 if (!error) {
1992 priv->card_info.sd_timing =
1993 SD_TIMING_SDR25_HIGH_SPEED_MODE;
1994 priv->card_info.busclk_hz =
1995 usdhc_set_sd_clk(
1996 config->base,
1997 priv->src_clk_hz,
1998 SD_CLOCK_50MHZ);
1999 }
2000 break;
2001
2002 default:
2003 break;
2004 }
2005 }
2006
2007 /* SDR50 and SDR104 mode need tuning */
2008 if ((priv->card_info.sd_timing == SD_TIMING_SDR50_MODE) ||
2009 (priv->card_info.sd_timing == SD_TIMING_SDR104_MODE)) {
2010 struct usdhc_cmd *cmd = &priv->op_context.cmd;
2011 struct usdhc_data *data = &priv->op_context.data;
2012
2013 /* config IO strength in IOMUX*/
2014 if (priv->card_info.sd_timing == SD_TIMING_SDR50_MODE) {
2015 imxrt_usdhc_pinmux(config->nusdhc, false,
2016 CARD_BUS_FREQ_100MHZ1,
2017 CARD_BUS_STRENGTH_7);
2018 } else {
2019 imxrt_usdhc_pinmux(config->nusdhc, false,
2020 CARD_BUS_FREQ_200MHZ,
2021 CARD_BUS_STRENGTH_7);
2022 }
2023 /* execute tuning */
2024 priv->op_context.cmd_only = 0;
2025
2026 memset((char *)cmd, 0, sizeof(struct usdhc_cmd));
2027 memset((char *)data, 0, sizeof(struct usdhc_data));
2028
2029 cmd->index = SDHC_SEND_TUNING_BLOCK;
2030 cmd->rsp_type = SDHC_RSP_TYPE_R1;
2031
2032 data->block_size = 64;
2033 data->block_count = 1U;
2034 data->rx_data = &g_usdhc_rx_dummy[0];
2035 data->data_type = USDHC_XFER_TUNING;
2036 error = usdhc_execute_tuning(priv);
2037 if (error)
2038 return error;
2039 } else {
2040 /* set default IO strength to 4 to cover card adapter driver
2041 * strength difference
2042 */
2043 imxrt_usdhc_pinmux(config->nusdhc, false,
2044 CARD_BUS_FREQ_100MHZ1,
2045 CARD_BUS_STRENGTH_4);
2046 }
2047
2048 return error;
2049 }
2050
usdhc_write_sector(void * bus_data,const uint8_t * buf,uint32_t sector,uint32_t count)2051 static int usdhc_write_sector(void *bus_data, const uint8_t *buf, uint32_t sector,
2052 uint32_t count)
2053 {
2054 struct usdhc_priv *priv = bus_data;
2055 struct usdhc_cmd *cmd = &priv->op_context.cmd;
2056 struct usdhc_data *data = &priv->op_context.data;
2057
2058 memset((char *)cmd, 0, sizeof(struct usdhc_cmd));
2059 memset((char *)data, 0, sizeof(struct usdhc_data));
2060
2061 priv->op_context.cmd_only = 0;
2062 cmd->index = SDHC_WRITE_MULTIPLE_BLOCK;
2063 data->block_size = priv->card_info.sd_block_size;
2064 data->block_count = count;
2065 data->tx_data = (const uint32_t *)buf;
2066 data->cmd12 = true;
2067 if (data->block_count == 1U) {
2068 cmd->index = SDHC_WRITE_BLOCK;
2069 }
2070 cmd->argument = sector;
2071 if (!(priv->card_info.card_flags & SDHC_HIGH_CAPACITY_FLAG)) {
2072 cmd->argument *= priv->card_info.sd_block_size;
2073 }
2074 cmd->rsp_type = SDHC_RSP_TYPE_R1;
2075 cmd->rsp_err_flags = SDHC_R1ERR_All_FLAG;
2076
2077 return usdhc_xfer(priv);
2078 }
2079
usdhc_read_sector(void * bus_data,uint8_t * buf,uint32_t sector,uint32_t count)2080 static int usdhc_read_sector(void *bus_data, uint8_t *buf, uint32_t sector,
2081 uint32_t count)
2082 {
2083 struct usdhc_priv *priv = bus_data;
2084 struct usdhc_cmd *cmd = &priv->op_context.cmd;
2085 struct usdhc_data *data = &priv->op_context.data;
2086
2087 memset((char *)cmd, 0, sizeof(struct usdhc_cmd));
2088 memset((char *)data, 0, sizeof(struct usdhc_data));
2089
2090 priv->op_context.cmd_only = 0;
2091 cmd->index = SDHC_READ_MULTIPLE_BLOCK;
2092 data->block_size = priv->card_info.sd_block_size;
2093 data->block_count = count;
2094 data->rx_data = (uint32_t *)buf;
2095 data->cmd12 = true;
2096
2097 if (data->block_count == 1U) {
2098 cmd->index = SDHC_READ_SINGLE_BLOCK;
2099 }
2100
2101 cmd->argument = sector;
2102 if (!(priv->card_info.card_flags & SDHC_HIGH_CAPACITY_FLAG)) {
2103 cmd->argument *= priv->card_info.sd_block_size;
2104 }
2105
2106 cmd->rsp_type = SDHC_RSP_TYPE_R1;
2107 cmd->rsp_err_flags = SDHC_R1ERR_All_FLAG;
2108
2109 return usdhc_xfer(priv);
2110 }
2111
usdhc_set_sd_active(USDHC_Type * base)2112 static bool usdhc_set_sd_active(USDHC_Type *base)
2113 {
2114 uint32_t timeout = 0xffff;
2115
2116 base->SYS_CTRL |= USDHC_SYS_CTRL_INITA_MASK;
2117 /* Delay some time to wait card become active state. */
2118 while ((base->SYS_CTRL & USDHC_SYS_CTRL_INITA_MASK) ==
2119 USDHC_SYS_CTRL_INITA_MASK) {
2120 if (!timeout) {
2121 break;
2122 }
2123 timeout--;
2124 }
2125
2126 return ((!timeout) ? false : true);
2127 }
2128
usdhc_get_host_capability(USDHC_Type * base,struct usdhc_capability * capability)2129 static void usdhc_get_host_capability(USDHC_Type *base,
2130 struct usdhc_capability *capability)
2131 {
2132 uint32_t host_cap;
2133 uint32_t max_blk_len;
2134
2135 host_cap = base->HOST_CTRL_CAP;
2136
2137 /* Get the capability of USDHC. */
2138 max_blk_len = ((host_cap & USDHC_HOST_CTRL_CAP_MBL_MASK) >>
2139 USDHC_HOST_CTRL_CAP_MBL_SHIFT);
2140 capability->max_blk_len = (512U << max_blk_len);
2141 /* Other attributes not in HTCAPBLT register. */
2142 capability->max_blk_cnt = USDHC_MAX_BLOCK_COUNT;
2143 capability->host_flags = (host_cap & (USDHC_SUPPORT_ADMA_FLAG |
2144 USDHC_SUPPORT_HIGHSPEED_FLAG | USDHC_SUPPORT_DMA_FLAG |
2145 USDHC_SUPPORT_SUSPEND_RESUME_FLAG | USDHC_SUPPORT_V330_FLAG));
2146 capability->host_flags |= (host_cap & USDHC_SUPPORT_V300_FLAG);
2147 capability->host_flags |= (host_cap & USDHC_SUPPORT_V180_FLAG);
2148 capability->host_flags |=
2149 (host_cap & (USDHC_SUPPORT_DDR50_FLAG |
2150 USDHC_SUPPORT_SDR104_FLAG |
2151 USDHC_SUPPORT_SDR50_FLAG));
2152 /* USDHC support 4/8 bit data bus width. */
2153 capability->host_flags |= (USDHC_SUPPORT_4BIT_FLAG |
2154 USDHC_SUPPORT_8BIT_FLAG);
2155 }
2156
usdhc_hw_reset(USDHC_Type * base,uint32_t mask,uint32_t timeout)2157 static bool usdhc_hw_reset(USDHC_Type *base, uint32_t mask, uint32_t timeout)
2158 {
2159 base->SYS_CTRL |= (mask & (USDHC_SYS_CTRL_RSTA_MASK |
2160 USDHC_SYS_CTRL_RSTC_MASK | USDHC_SYS_CTRL_RSTD_MASK));
2161 /* Delay some time to wait reset success. */
2162 while ((base->SYS_CTRL & mask)) {
2163 if (!timeout) {
2164 break;
2165 }
2166 timeout--;
2167 }
2168
2169 return ((!timeout) ? false : true);
2170 }
2171
usdhc_host_hw_init(USDHC_Type * base,const struct usdhc_config * config)2172 static void usdhc_host_hw_init(USDHC_Type *base,
2173 const struct usdhc_config *config)
2174 {
2175 uint32_t proctl, sysctl, wml;
2176 uint32_t int_mask;
2177
2178 __ASSERT_NO_MSG(config);
2179 __ASSERT_NO_MSG((config->write_watermark >= 1U) &&
2180 (config->write_watermark <= 128U));
2181 __ASSERT_NO_MSG((config->read_watermark >= 1U) &&
2182 (config->read_watermark <= 128U));
2183 __ASSERT_NO_MSG(config->write_burst_len <= 16U);
2184
2185 /* Reset USDHC. */
2186 usdhc_hw_reset(base, USDHC_RESET_ALL, 100U);
2187
2188 proctl = base->PROT_CTRL;
2189 wml = base->WTMK_LVL;
2190 sysctl = base->SYS_CTRL;
2191
2192 proctl &= ~(USDHC_PROT_CTRL_EMODE_MASK | USDHC_PROT_CTRL_DMASEL_MASK);
2193 /* Endian mode*/
2194 proctl |= USDHC_PROT_CTRL_EMODE(config->endian);
2195
2196 /* Watermark level */
2197 wml &= ~(USDHC_WTMK_LVL_RD_WML_MASK |
2198 USDHC_WTMK_LVL_WR_WML_MASK |
2199 USDHC_WTMK_LVL_RD_BRST_LEN_MASK |
2200 USDHC_WTMK_LVL_WR_BRST_LEN_MASK);
2201 wml |= (USDHC_WTMK_LVL_RD_WML(config->read_watermark) |
2202 USDHC_WTMK_LVL_WR_WML(config->write_watermark) |
2203 USDHC_WTMK_LVL_RD_BRST_LEN(config->read_burst_len) |
2204 USDHC_WTMK_LVL_WR_BRST_LEN(config->write_burst_len));
2205
2206 /* config the data timeout value */
2207 sysctl &= ~USDHC_SYS_CTRL_DTOCV_MASK;
2208 sysctl |= USDHC_SYS_CTRL_DTOCV(config->data_timeout);
2209
2210 base->SYS_CTRL = sysctl;
2211 base->WTMK_LVL = wml;
2212 base->PROT_CTRL = proctl;
2213
2214 /* disable internal DMA and DDR mode */
2215 base->MIX_CTRL &= ~(USDHC_MIX_CTRL_DMAEN_MASK |
2216 USDHC_MIX_CTRL_DDR_EN_MASK);
2217
2218 int_mask = (USDHC_INT_CMD_FLAG | USDHC_INT_CARD_DETECT_FLAG |
2219 USDHC_INT_DATA_FLAG | USDHC_INT_SDR104_TUNING_FLAG |
2220 USDHC_INT_BLK_GAP_EVENT_FLAG);
2221
2222 base->INT_STATUS_EN |= int_mask;
2223
2224 }
2225
usdhc_cd_gpio_cb(const struct device * dev,struct gpio_callback * cb,uint32_t pins)2226 static void usdhc_cd_gpio_cb(const struct device *dev,
2227 struct gpio_callback *cb, uint32_t pins)
2228 {
2229 struct usdhc_priv *priv =
2230 CONTAINER_OF(cb, struct usdhc_priv, detect_cb);
2231 const struct usdhc_config *config = priv->config;
2232
2233 gpio_pin_interrupt_configure(dev, config->detect_pin, GPIO_INT_DISABLE);
2234 }
2235
usdhc_cd_gpio_init(const struct device * detect_gpio,uint32_t pin,gpio_dt_flags_t flags,struct gpio_callback * callback)2236 static int usdhc_cd_gpio_init(const struct device *detect_gpio,
2237 uint32_t pin, gpio_dt_flags_t flags,
2238 struct gpio_callback *callback)
2239 {
2240 int ret;
2241
2242 ret = gpio_pin_configure(detect_gpio, pin, GPIO_INPUT | flags);
2243 if (ret)
2244 return ret;
2245
2246 gpio_init_callback(callback, usdhc_cd_gpio_cb, BIT(pin));
2247
2248 return gpio_add_callback(detect_gpio, callback);
2249 }
2250
usdhc_host_reset(struct usdhc_priv * priv)2251 static void usdhc_host_reset(struct usdhc_priv *priv)
2252 {
2253 USDHC_Type *base = priv->config->base;
2254
2255 usdhc_select_1_8_vol(base, false);
2256 usdhc_enable_ddr_mode(base, false, 0);
2257 usdhc_tuning(base, SDHC_STANDARD_TUNING_START, SDHC_TUINIG_STEP, false);
2258 #if FSL_FEATURE_USDHC_HAS_HS400_MODE
2259 /* Disable HS400 mode */
2260 /* Disable DLL */
2261 #endif
2262 }
2263
usdhc_app_host_cmd(struct usdhc_priv * priv,int retry,uint32_t arg,uint8_t app_cmd,uint32_t app_arg,enum sdhc_rsp_type rsp_type,enum sdhc_rsp_type app_rsp_type,bool app_cmd_only)2264 static int usdhc_app_host_cmd(struct usdhc_priv *priv, int retry,
2265 uint32_t arg, uint8_t app_cmd, uint32_t app_arg, enum sdhc_rsp_type rsp_type,
2266 enum sdhc_rsp_type app_rsp_type, bool app_cmd_only)
2267 {
2268 struct usdhc_cmd *cmd = &priv->op_context.cmd;
2269 int ret;
2270
2271 APP_CMD_XFER_AGAIN:
2272 priv->op_context.cmd_only = 1;
2273 cmd->index = SDHC_APP_CMD;
2274 cmd->argument = arg;
2275 cmd->rsp_type = rsp_type;
2276 ret = usdhc_xfer(priv);
2277 retry--;
2278 if (ret && retry > 0) {
2279 goto APP_CMD_XFER_AGAIN;
2280 }
2281
2282 priv->op_context.cmd_only = app_cmd_only;
2283 cmd->index = app_cmd;
2284 cmd->argument = app_arg;
2285 cmd->rsp_type = app_rsp_type;
2286 ret = usdhc_xfer(priv);
2287 if (ret && retry > 0) {
2288 goto APP_CMD_XFER_AGAIN;
2289 }
2290
2291 return ret;
2292 }
2293
usdhc_sd_init(struct usdhc_priv * priv)2294 static int usdhc_sd_init(struct usdhc_priv *priv)
2295 {
2296 const struct usdhc_config *config = priv->config;
2297 USDHC_Type *base = config->base;
2298 uint32_t app_cmd_41_arg = 0U;
2299 int ret, retry;
2300 struct usdhc_cmd *cmd = &priv->op_context.cmd;
2301 struct usdhc_data *data = &priv->op_context.data;
2302
2303 if (!priv->host_ready) {
2304 return -ENODEV;
2305 }
2306
2307 /* reset variables */
2308 priv->card_info.card_flags = 0U;
2309 /* set DATA bus width 1bit at beginning*/
2310 usdhc_set_bus_width(base, USDHC_DATA_BUS_WIDTH_1BIT);
2311 /*set card freq to 400KHZ at begging*/
2312 priv->card_info.busclk_hz =
2313 usdhc_set_sd_clk(base, priv->src_clk_hz,
2314 SDMMC_CLOCK_400KHZ);
2315 /* send card active */
2316 ret = usdhc_set_sd_active(base);
2317 if (ret == false) {
2318 return -EIO;
2319 }
2320
2321 /* Get host capability. */
2322 usdhc_get_host_capability(base, &priv->host_capability);
2323
2324 /* card go idle */
2325 usdhc_op_ctx_init(priv, 1, SDHC_GO_IDLE_STATE, 0, SDHC_RSP_TYPE_NONE);
2326
2327 ret = usdhc_xfer(priv);
2328 if (ret) {
2329 return ret;
2330 }
2331
2332 if (USDHC_SUPPORT_V330_FLAG != SDMMCHOST_NOT_SUPPORT) {
2333 app_cmd_41_arg |= (SD_OCR_VDD32_33FLAG | SD_OCR_VDD33_34FLAG);
2334 priv->card_info.voltage = SD_VOL_3_3_V;
2335 } else if (USDHC_SUPPORT_V300_FLAG != SDMMCHOST_NOT_SUPPORT) {
2336 app_cmd_41_arg |= SD_OCR_VDD29_30FLAG;
2337 priv->card_info.voltage = SD_VOL_3_3_V;
2338 }
2339
2340 /* allow user select the work voltage, if not select,
2341 * sdmmc will handle it automatically
2342 */
2343 if (priv->config->no_1_8_v == false) {
2344 if (USDHC_SUPPORT_V180_FLAG != SDMMCHOST_NOT_SUPPORT) {
2345 app_cmd_41_arg |= SD_OCR_SWITCH_18_REQ_FLAG;
2346 }
2347 }
2348
2349 /* Check card's supported interface condition. */
2350 usdhc_op_ctx_init(priv, 1, SDHC_SEND_IF_COND,
2351 SDHC_VHS_3V3 | SDHC_CHECK, SDHC_RSP_TYPE_R7);
2352
2353 retry = 10;
2354 while (retry) {
2355 ret = usdhc_xfer(priv);
2356 if (!ret) {
2357 if ((cmd->response[0U] & 0xFFU) != SDHC_CHECK) {
2358 ret = -ENOTSUP;
2359 } else {
2360 break;
2361 }
2362 }
2363 retry--;
2364 }
2365
2366 if (!ret) {
2367 /* SDHC or SDXC card */
2368 app_cmd_41_arg |= SD_OCR_HOST_CAP_FLAG;
2369 priv->card_info.card_flags |= USDHC_SDHC_FLAG;
2370 } else {
2371 /* SDSC card */
2372 LOG_ERR("USDHC SDSC not implemented yet!");
2373 return -ENOTSUP;
2374 }
2375
2376 /* Set card interface condition according to SDHC capability and
2377 * card's supported interface condition.
2378 */
2379 APP_SEND_OP_COND_AGAIN:
2380 usdhc_op_ctx_init(priv, 1, 0, 0, SDHC_RSP_TYPE_NONE);
2381 ret = usdhc_app_host_cmd(priv, NXP_SDMMC_MAX_VOLTAGE_RETRIES, 0,
2382 SDHC_APP_SEND_OP_COND, app_cmd_41_arg,
2383 SDHC_RSP_TYPE_R1, SDHC_RSP_TYPE_R3, 1);
2384 if (ret) {
2385 LOG_ERR("APP Condition CMD failed:%d", ret);
2386 return ret;
2387 }
2388 if (cmd->response[0U] & SD_OCR_PWR_BUSY_FLAG) {
2389 /* high capacity check */
2390 if (cmd->response[0U] & SD_OCR_CARD_CAP_FLAG) {
2391 priv->card_info.card_flags |= SDHC_HIGH_CAPACITY_FLAG;
2392 }
2393
2394 if (priv->config->no_1_8_v == false) {
2395 /* 1.8V support */
2396 if (cmd->response[0U] & SD_OCR_SWITCH_18_ACCEPT_FLAG) {
2397 priv->card_info.card_flags |= SDHC_1800MV_FLAG;
2398 }
2399 }
2400 priv->card_info.raw_ocr = cmd->response[0U];
2401 } else {
2402 goto APP_SEND_OP_COND_AGAIN;
2403 }
2404
2405 /* check if card support 1.8V */
2406 if ((priv->card_info.card_flags & USDHC_VOL_1_8V_FLAG)) {
2407 usdhc_op_ctx_init(priv, 1, SDHC_VOL_SWITCH,
2408 0, SDHC_RSP_TYPE_R1);
2409
2410 ret = usdhc_xfer(priv);
2411 if (!ret) {
2412 ret = usdhc_vol_switch(priv);
2413 }
2414 if (ret) {
2415 LOG_ERR("Voltage switch failed: %d", ret);
2416 return ret;
2417 }
2418 priv->card_info.voltage = SD_VOL_1_8_V;
2419 }
2420
2421 /* Initialize card if the card is SD card. */
2422 usdhc_op_ctx_init(priv, 1, SDHC_ALL_SEND_CID, 0, SDHC_RSP_TYPE_R2);
2423
2424 ret = usdhc_xfer(priv);
2425 if (!ret) {
2426 memcpy(priv->card_info.raw_cid, cmd->response,
2427 sizeof(priv->card_info.raw_cid));
2428 sdhc_decode_cid(&priv->card_info.cid,
2429 priv->card_info.raw_cid);
2430 } else {
2431 LOG_ERR("All send CID CMD failed: %d", ret);
2432 return ret;
2433 }
2434
2435 usdhc_op_ctx_init(priv, 1, SDHC_SEND_RELATIVE_ADDR,
2436 0, SDHC_RSP_TYPE_R6);
2437
2438 ret = usdhc_xfer(priv);
2439 if (!ret) {
2440 priv->card_info.relative_addr = (cmd->response[0U] >> 16U);
2441 } else {
2442 LOG_ERR("Send relative address CMD failed: %d", ret);
2443 return ret;
2444 }
2445
2446 usdhc_op_ctx_init(priv, 1, SDHC_SEND_CSD,
2447 (priv->card_info.relative_addr << 16U), SDHC_RSP_TYPE_R2);
2448
2449 ret = usdhc_xfer(priv);
2450 if (!ret) {
2451 memcpy(priv->card_info.raw_csd, cmd->response,
2452 sizeof(priv->card_info.raw_csd));
2453 sdhc_decode_csd(&priv->card_info.csd, priv->card_info.raw_csd,
2454 &priv->card_info.sd_block_count,
2455 &priv->card_info.sd_block_size);
2456 } else {
2457 LOG_ERR("Send CSD CMD failed: %d", ret);
2458 return ret;
2459 }
2460
2461 usdhc_op_ctx_init(priv, 1, SDHC_SELECT_CARD,
2462 priv->card_info.relative_addr << 16U,
2463 SDHC_RSP_TYPE_R1);
2464
2465 ret = usdhc_xfer(priv);
2466 if (ret || (cmd->response[0U] & SDHC_R1ERR_All_FLAG)) {
2467 LOG_ERR("Select card CMD failed: %d", ret);
2468 return -EIO;
2469 }
2470
2471 usdhc_op_ctx_init(priv, 0, 0, 0, SDHC_RSP_TYPE_NONE);
2472 data->block_size = 8;
2473 data->block_count = 1;
2474 data->rx_data = &priv->card_info.raw_scr[0];
2475 ret = usdhc_app_host_cmd(priv, 1, (priv->card_info.relative_addr << 16),
2476 SDHC_APP_SEND_SCR, 0,
2477 SDHC_RSP_TYPE_R1, SDHC_RSP_TYPE_R1, 0);
2478
2479 if (ret) {
2480 LOG_ERR("Send SCR following APP CMD failed: %d", ret);
2481 return ret;
2482 }
2483
2484 switch (config->endian) {
2485 case USDHC_LITTLE_ENDIAN:
2486 priv->card_info.raw_scr[0] =
2487 SWAP_WORD_BYTE_SEQUENCE(priv->card_info.raw_scr[0]);
2488 priv->card_info.raw_scr[1] =
2489 SWAP_WORD_BYTE_SEQUENCE(priv->card_info.raw_scr[1]);
2490 break;
2491 case USDHC_BIG_ENDIAN:
2492 break;
2493 case USDHC_HALF_WORD_BIG_ENDIAN:
2494 priv->card_info.raw_scr[0U] =
2495 SWAP_HALF_WROD_BYTE_SEQUENCE(
2496 priv->card_info.raw_scr[0U]);
2497 priv->card_info.raw_scr[1U] =
2498 SWAP_HALF_WROD_BYTE_SEQUENCE(
2499 priv->card_info.raw_scr[1U]);
2500 break;
2501 default:
2502 return -EINVAL;
2503 }
2504
2505 sdhc_decode_scr(&priv->card_info.scr, priv->card_info.raw_scr,
2506 &priv->card_info.version);
2507 if (priv->card_info.scr.sd_width & 0x4U) {
2508 priv->card_info.card_flags |=
2509 USDHC_4BIT_WIDTH_FLAG;
2510 }
2511 /* speed class control cmd */
2512 if (priv->card_info.scr.cmd_support & 0x01U) {
2513 priv->card_info.card_flags |=
2514 USDHC_SPEED_CLASS_CONTROL_CMD_FLAG;
2515 }
2516 /* set block count cmd */
2517 if (priv->card_info.scr.cmd_support & 0x02U) {
2518 priv->card_info.card_flags |=
2519 USDHC_SET_BLK_CNT_CMD23_FLAG;
2520 }
2521
2522 /* Set to max frequency in non-high speed mode. */
2523 priv->card_info.busclk_hz = usdhc_set_sd_clk(base,
2524 priv->src_clk_hz, SD_CLOCK_25MHZ);
2525
2526 /* Set to 4-bit data bus mode. */
2527 if ((priv->host_capability.host_flags & USDHC_SUPPORT_4BIT_FLAG) &&
2528 (priv->card_info.card_flags & USDHC_4BIT_WIDTH_FLAG)) {
2529 usdhc_op_ctx_init(priv, 1, 0, 0, SDHC_RSP_TYPE_NONE);
2530
2531 ret = usdhc_app_host_cmd(priv, 1,
2532 (priv->card_info.relative_addr << 16),
2533 SDHC_APP_SET_BUS_WIDTH, 2,
2534 SDHC_RSP_TYPE_R1, SDHC_RSP_TYPE_R1, 1);
2535
2536 if (ret) {
2537 LOG_ERR("Set bus width failed: %d", ret);
2538 return ret;
2539 }
2540 usdhc_set_bus_width(base, USDHC_DATA_BUS_WIDTH_4BIT);
2541 }
2542
2543 if (priv->card_info.version >= SD_SPEC_VER3_0) {
2544 /* set sd card driver strength */
2545 ret = usdhc_select_fun(priv, SD_GRP_DRIVER_STRENGTH_MODE,
2546 priv->card_info.driver_strength);
2547 if (ret) {
2548 LOG_ERR("Set SD driver strength failed: %d", ret);
2549 return ret;
2550 }
2551
2552 /* set sd card current limit */
2553 ret = usdhc_select_fun(priv, SD_GRP_CURRENT_LIMIT_MODE,
2554 priv->card_info.max_current);
2555 if (ret) {
2556 LOG_ERR("Set SD current limit failed: %d", ret);
2557 return ret;
2558 }
2559 }
2560
2561 /* set block size */
2562 usdhc_op_ctx_init(priv, 1, SDHC_SET_BLOCK_SIZE,
2563 priv->card_info.sd_block_size, SDHC_RSP_TYPE_R1);
2564
2565 ret = usdhc_xfer(priv);
2566 if (ret || cmd->response[0U] & SDHC_R1ERR_All_FLAG) {
2567 LOG_ERR("Set block size failed: %d", ret);
2568 return -EIO;
2569 }
2570
2571 if (priv->card_info.version > SD_SPEC_VER1_0) {
2572 /* select bus timing */
2573 ret = usdhc_select_bus_timing(priv);
2574 if (ret) {
2575 LOG_ERR("Select bus timing failed: %d", ret);
2576 return ret;
2577 }
2578 }
2579
2580 retry = 10;
2581 ret = -EIO;
2582 while (ret && retry >= 0) {
2583 ret = usdhc_read_sector(priv, (uint8_t *)g_usdhc_rx_dummy, 0, 1);
2584 if (!ret) {
2585 break;
2586 }
2587 retry--;
2588 }
2589
2590 if (ret) {
2591 LOG_ERR("USDHC bus device initalization failed!");
2592 }
2593
2594 return ret;
2595 }
2596
2597 static K_MUTEX_DEFINE(z_usdhc_init_lock);
2598
usdhc_board_access_init(struct usdhc_priv * priv)2599 static int usdhc_board_access_init(struct usdhc_priv *priv)
2600 {
2601 const struct usdhc_config *config = priv->config;
2602 int ret = 0;
2603 uint32_t gpio_level;
2604 USDHC_Type *base = config->base;
2605
2606 if (config->pwr_name) {
2607 priv->pwr_gpio = device_get_binding(config->pwr_name);
2608 if (!priv->pwr_gpio) {
2609 return -ENODEV;
2610 }
2611 }
2612
2613 if (config->detect_name) {
2614 priv->detect_type = SD_DETECT_GPIO_CD;
2615 priv->detect_gpio = device_get_binding(config->detect_name);
2616 if (!priv->detect_gpio) {
2617 return -ENODEV;
2618 }
2619 }
2620
2621 if (priv->pwr_gpio) {
2622 ret = gpio_pin_configure(priv->pwr_gpio,
2623 config->pwr_pin,
2624 GPIO_OUTPUT_ACTIVE |
2625 config->pwr_flags);
2626 if (ret) {
2627 return ret;
2628 }
2629
2630 /* 100ms delay to make sure SD card is stable,
2631 * maybe could be shorter
2632 */
2633 k_busy_wait(100000);
2634 }
2635
2636 if (!priv->detect_gpio) {
2637 LOG_INF("USDHC detection other than GPIO");
2638 /* DATA3 does not monitor card insertion */
2639 base->PROT_CTRL &= ~USDHC_PROT_CTRL_D3CD_MASK;
2640 if ((base->PRES_STATE & USDHC_PRES_STATE_CINST_MASK) != 0) {
2641 priv->inserted = true;
2642 } else {
2643 priv->inserted = false;
2644 return -ENODEV;
2645 }
2646 } else {
2647 ret = usdhc_cd_gpio_init(priv->detect_gpio,
2648 config->detect_pin,
2649 config->detect_flags,
2650 &priv->detect_cb);
2651 if (ret) {
2652 return ret;
2653 }
2654 ret = gpio_pin_get(priv->detect_gpio, config->detect_pin);
2655 if (ret < 0) {
2656 return ret;
2657 }
2658
2659 gpio_level = ret;
2660
2661 if (gpio_level == 0) {
2662 priv->inserted = false;
2663 LOG_ERR("NO SD inserted!");
2664
2665 return -ENODEV;
2666 }
2667
2668 priv->inserted = true;
2669 LOG_INF("SD inserted!");
2670 }
2671 return 0;
2672 }
2673
usdhc_access_init(const struct device * dev)2674 static int usdhc_access_init(const struct device *dev)
2675 {
2676 const struct usdhc_config *config = dev->config;
2677 struct usdhc_priv *priv = dev->data;
2678 int ret;
2679
2680 (void)k_mutex_lock(&z_usdhc_init_lock, K_FOREVER);
2681
2682 memset((char *)priv, 0, sizeof(struct usdhc_priv));
2683 priv->config = config;
2684
2685 if (!config->base) {
2686 k_mutex_unlock(&z_usdhc_init_lock);
2687
2688 return -ENODEV;
2689 }
2690
2691 if (clock_control_get_rate(config->clock_dev,
2692 config->clock_subsys,
2693 &priv->src_clk_hz)) {
2694 return -EINVAL;
2695 }
2696
2697 ret = usdhc_board_access_init(priv);
2698 if (ret) {
2699 k_mutex_unlock(&z_usdhc_init_lock);
2700
2701 return ret;
2702 }
2703
2704 priv->op_context.dma_cfg.dma_mode = USDHC_DMA_ADMA2;
2705 priv->op_context.dma_cfg.burst_len = USDHC_INCR_BURST_LEN;
2706 /*No DMA used for this Version*/
2707 priv->op_context.dma_cfg.adma_table = 0;
2708 priv->op_context.dma_cfg.adma_table_words = USDHC_ADMA_TABLE_WORDS;
2709 usdhc_host_hw_init(config->base, config);
2710 priv->host_ready = 1;
2711
2712 usdhc_host_reset(priv);
2713 ret = usdhc_sd_init(priv);
2714 k_mutex_unlock(&z_usdhc_init_lock);
2715
2716 return ret;
2717 }
2718
disk_usdhc_access_status(struct disk_info * disk)2719 static int disk_usdhc_access_status(struct disk_info *disk)
2720 {
2721 const struct device *dev = disk->dev;
2722 struct usdhc_priv *priv = dev->data;
2723
2724 return priv->status;
2725 }
2726
disk_usdhc_access_read(struct disk_info * disk,uint8_t * buf,uint32_t sector,uint32_t count)2727 static int disk_usdhc_access_read(struct disk_info *disk, uint8_t *buf,
2728 uint32_t sector, uint32_t count)
2729 {
2730 const struct device *dev = disk->dev;
2731 struct usdhc_priv *priv = dev->data;
2732
2733 LOG_DBG("sector=%u count=%u", sector, count);
2734
2735 return usdhc_read_sector(priv, buf, sector, count);
2736 }
2737
disk_usdhc_access_write(struct disk_info * disk,const uint8_t * buf,uint32_t sector,uint32_t count)2738 static int disk_usdhc_access_write(struct disk_info *disk, const uint8_t *buf,
2739 uint32_t sector, uint32_t count)
2740 {
2741 const struct device *dev = disk->dev;
2742 struct usdhc_priv *priv = dev->data;
2743
2744 LOG_DBG("sector=%u count=%u", sector, count);
2745
2746 return usdhc_write_sector(priv, buf, sector, count);
2747 }
2748
disk_usdhc_access_ioctl(struct disk_info * disk,uint8_t cmd,void * buf)2749 static int disk_usdhc_access_ioctl(struct disk_info *disk, uint8_t cmd, void *buf)
2750 {
2751 const struct device *dev = disk->dev;
2752 struct usdhc_priv *priv = dev->data;
2753 int err;
2754
2755 err = sdhc_map_disk_status(priv->status);
2756 if (err != 0) {
2757 return err;
2758 }
2759
2760 switch (cmd) {
2761 case DISK_IOCTL_CTRL_SYNC:
2762 break;
2763 case DISK_IOCTL_GET_SECTOR_COUNT:
2764 *(uint32_t *)buf = priv->card_info.sd_block_count;
2765 break;
2766 case DISK_IOCTL_GET_SECTOR_SIZE:
2767 *(uint32_t *)buf = priv->card_info.sd_block_size;
2768 break;
2769 case DISK_IOCTL_GET_ERASE_BLOCK_SZ:
2770 *(uint32_t *)buf = priv->card_info.sd_block_size;
2771 break;
2772 default:
2773 return -EINVAL;
2774 }
2775
2776 return 0;
2777 }
2778
disk_usdhc_access_init(struct disk_info * disk)2779 static int disk_usdhc_access_init(struct disk_info *disk)
2780 {
2781 const struct device *dev = disk->dev;
2782 struct usdhc_priv *priv = dev->data;
2783
2784 if (priv->status == DISK_STATUS_OK) {
2785 /* Called twice, don't re-init. */
2786 return 0;
2787 }
2788
2789 return usdhc_access_init(dev);
2790 }
2791
2792 static const struct disk_operations usdhc_disk_ops = {
2793 .init = disk_usdhc_access_init,
2794 .status = disk_usdhc_access_status,
2795 .read = disk_usdhc_access_read,
2796 .write = disk_usdhc_access_write,
2797 .ioctl = disk_usdhc_access_ioctl,
2798 };
2799
2800 static struct disk_info usdhc_disk = {
2801 .name = CONFIG_SDMMC_VOLUME_NAME,
2802 .ops = &usdhc_disk_ops,
2803 };
2804
disk_usdhc_init(const struct device * dev)2805 static int disk_usdhc_init(const struct device *dev)
2806 {
2807 struct usdhc_priv *priv = dev->data;
2808
2809 priv->status = DISK_STATUS_UNINIT;
2810
2811 usdhc_disk.dev = dev;
2812
2813 return disk_access_register(&usdhc_disk);
2814 }
2815
2816 #define DISK_ACCESS_USDHC_INIT_NONE(n)
2817
2818 #define DISK_ACCESS_USDHC_INIT_PWR_PROPS(n) \
2819 .pwr_name = DT_INST_GPIO_LABEL(n, pwr_gpios), \
2820 .pwr_pin = DT_INST_GPIO_PIN(n, pwr_gpios), \
2821 .pwr_flags = DT_INST_GPIO_FLAGS(n, pwr_gpios),
2822
2823 #define DISK_ACCESS_USDHC_INIT_CD_PROPS(n) \
2824 .detect_name = DT_INST_GPIO_LABEL(n, cd_gpios), \
2825 .detect_pin = DT_INST_GPIO_PIN(n, cd_gpios), \
2826 .detect_flags = DT_INST_GPIO_FLAGS(n, cd_gpios),
2827
2828 #define DISK_ACCESS_USDHC_INIT_PWR(n) \
2829 COND_CODE_1(DT_INST_NODE_HAS_PROP(n, pwr_gpios), \
2830 (DISK_ACCESS_USDHC_INIT_PWR_PROPS(n)), \
2831 (DISK_ACCESS_USDHC_INIT_NONE(n)))
2832
2833 #define DISK_ACCESS_USDHC_INIT_CD(n) \
2834 COND_CODE_1(DT_INST_NODE_HAS_PROP(n, cd_gpios), \
2835 (DISK_ACCESS_USDHC_INIT_CD_PROPS(n)), \
2836 (DISK_ACCESS_USDHC_INIT_NONE(n)))
2837
2838 #define DISK_ACCESS_USDHC_INIT(n) \
2839 static const struct usdhc_config usdhc_config_##n = { \
2840 .base = (USDHC_Type *) DT_INST_REG_ADDR(n), \
2841 .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \
2842 .clock_subsys = \
2843 (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \
2844 .nusdhc = n, \
2845 DISK_ACCESS_USDHC_INIT_PWR(n) \
2846 DISK_ACCESS_USDHC_INIT_CD(n) \
2847 .no_1_8_v = DT_INST_PROP(n, no_1_8_v), \
2848 .data_timeout = USDHC_DATA_TIMEOUT, \
2849 .endian = USDHC_LITTLE_ENDIAN, \
2850 .read_watermark = USDHC_READ_WATERMARK_LEVEL, \
2851 .write_watermark = USDHC_WRITE_WATERMARK_LEVEL, \
2852 .read_burst_len = USDHC_READ_BURST_LEN, \
2853 .write_burst_len = USDHC_WRITE_BURST_LEN, \
2854 }; \
2855 \
2856 static struct usdhc_priv usdhc_priv_##n; \
2857 \
2858 DEVICE_DT_INST_DEFINE(n, \
2859 &disk_usdhc_init, \
2860 NULL, \
2861 &usdhc_priv_##n, \
2862 &usdhc_config_##n, \
2863 POST_KERNEL, \
2864 CONFIG_SDMMC_INIT_PRIORITY, \
2865 NULL);
2866
2867 DT_INST_FOREACH_STATUS_OKAY(DISK_ACCESS_USDHC_INIT)
2868