Skip to content

Commit b8b1191

Browse files
committed
[dm][sdhci] Cleanup the SDHCI
Signed-off-by: GuEe-GUI <[email protected]>
1 parent d2ee5a3 commit b8b1191

File tree

11 files changed

+2264
-1749
lines changed

11 files changed

+2264
-1749
lines changed

components/drivers/include/drivers/dev_sdhci.h

Lines changed: 668 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
/*
2+
* Copyright (c) 2006-2024 RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2024-08-16 zhujiale first version
9+
*/
10+
11+
#ifndef __DEV_SDHCI_HOST_H__
12+
#define __DEV_SDHCI_HOST_H__
13+
14+
#include <rtthread.h>
15+
16+
#include <drivers/dma.h>
17+
#include <drivers/mmcsd_cmd.h>
18+
#include <drivers/mmcsd_host.h>
19+
#include <drivers/dev_mmcsd_core.h>
20+
21+
#define rt_mmc_dev(x) ((x)->parent)
22+
23+
#define MMC_SEND_TUNING_BLOCK_HS200 SEND_TUNING_BLOCK_HS200
24+
#define MMC_SEND_TUNING_BLOCK SEND_TUNING_BLOCK
25+
#define MMC_STOP_TRANSMISSION STOP_TRANSMISSION
26+
#define MMC_BUS_TEST_R 14 /* adtc R1 */
27+
#define MMC_WRITE_MULTIPLE_BLOCK WRITE_MULTIPLE_BLOCK
28+
#define MMC_READ_MULTIPLE_BLOCK READ_MULTIPLE_BLOCK
29+
30+
#define MMC_TIMING_UHS_DDR50 MMCSD_TIMING_UHS_DDR50
31+
#define MMC_TIMING_UHS_SDR50 MMCSD_TIMING_UHS_SDR50
32+
#define MMC_TIMING_MMC_HS200 MMCSD_TIMING_MMC_HS200
33+
#define MMC_TIMING_MMC_HS400 MMCSD_TIMING_MMC_HS400
34+
#define MMC_TIMING_UHS_SDR104 MMCSD_TIMING_UHS_SDR104
35+
#define MMC_TIMING_UHS_SDR25 MMCSD_TIMING_UHS_SDR25
36+
#define MMC_TIMING_MMC_DDR52 MMCSD_TIMING_MMC_DDR52
37+
#define MMC_TIMING_UHS_SDR12 MMCSD_TIMING_UHS_SDR12
38+
#define MMC_TIMING_SD_HS MMCSD_TIMING_SD_HS
39+
#define MMC_TIMING_MMC_HS MMCSD_TIMING_MMC_HS
40+
41+
#define MMC_POWER_OFF MMCSD_POWER_OFF
42+
#define MMC_POWER_UP MMCSD_POWER_UP
43+
#define MMC_POWER_ON MMCSD_POWER_ON
44+
#define MMC_POWER_UNDEFINED 3
45+
46+
#define MMC_SET_DRIVER_TYPE_B 0
47+
#define MMC_SET_DRIVER_TYPE_A 1
48+
#define MMC_SET_DRIVER_TYPE_C 2
49+
#define MMC_SET_DRIVER_TYPE_D 3
50+
51+
#define MMC_SIGNAL_VOLTAGE_330 0
52+
#define MMC_SIGNAL_VOLTAGE_180 1
53+
#define MMC_SIGNAL_VOLTAGE_120 2
54+
55+
#define MMC_RSP_PRESENT (1 << 16)
56+
#define MMC_RSP_136 (1 << 17) /* 136 bit response */
57+
#define MMC_RSP_CRC (1 << 18) /* expect valid crc */
58+
#define MMC_RSP_BUSY (1 << 19) /* card may send busy */
59+
#define MMC_RSP_OPCODE (1 << 20) /* response contains opcode */
60+
61+
#define MMC_RSP_NONE (0)
62+
#define MMC_RSP_R1 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
63+
#define MMC_RSP_R1B (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE | MMC_RSP_BUSY)
64+
#define MMC_RSP_R2 (MMC_RSP_PRESENT | MMC_RSP_136 | MMC_RSP_CRC)
65+
#define MMC_RSP_R3 (MMC_RSP_PRESENT)
66+
#define MMC_RSP_R4 (MMC_RSP_PRESENT)
67+
#define MMC_RSP_R5 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
68+
#define MMC_RSP_R6 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
69+
#define MMC_RSP_R7 (MMC_RSP_PRESENT | MMC_RSP_CRC | MMC_RSP_OPCODE)
70+
71+
#define MMC_CMD_ADTC CMD_ADTC
72+
73+
#define MMC_BUS_WIDTH_8 MMCSD_BUS_WIDTH_8
74+
#define MMC_BUS_WIDTH_4 MMCSD_BUS_WIDTH_4
75+
#define MMC_BUS_WIDTH_1 MMCSD_BUS_WIDTH_1
76+
77+
#define MMC_PM_KEEP_POWER (1 << 0) /* preserve card power during suspend */
78+
#define MMC_PM_WAKE_SDIO_IRQ (1 << 1) /* wake up host system on SDIO IRQ assertion */
79+
80+
enum mmc_blk_status
81+
{
82+
MMC_BLK_SUCCESS = 0,
83+
MMC_BLK_PARTIAL,
84+
MMC_BLK_CMD_ERR,
85+
MMC_BLK_RETRY,
86+
MMC_BLK_ABORT,
87+
MMC_BLK_DATA_ERR,
88+
MMC_BLK_ECC_ERR,
89+
MMC_BLK_NOMEDIUM,
90+
MMC_BLK_NEW_REQUEST,
91+
};
92+
93+
#define MMC_NUM_CLK_PHASES (MMC_TIMING_MMC_HS400 + 1)
94+
95+
struct rt_mmc_host;
96+
97+
struct rt_mmc_host_ops
98+
{
99+
void (*request)(struct rt_mmc_host *host, struct rt_mmcsd_req *req);
100+
void (*set_ios)(struct rt_mmc_host *host, struct rt_mmcsd_io_cfg *ios);
101+
int (*get_ro)(struct rt_mmc_host *host);
102+
int (*get_cd)(struct rt_mmc_host *host);
103+
void (*enable_sdio_irq)(struct rt_mmc_host *host, int enable);
104+
void (*ack_sdio_irq)(struct rt_mmc_host *host);
105+
int (*start_signal_voltage_switch)(struct rt_mmc_host *host, struct rt_mmcsd_io_cfg *ios);
106+
int (*card_busy)(struct rt_mmc_host *host);
107+
int (*execute_tuning)(struct rt_mmc_host *host, unsigned opcode);
108+
int (*prepare_hs400_tuning)(struct rt_mmc_host *host, struct rt_mmcsd_io_cfg *ios);
109+
int (*hs400_prepare_ddr)(struct rt_mmc_host *host);
110+
void (*hs400_downgrade)(struct rt_mmc_host *host);
111+
void (*hs400_complete)(struct rt_mmc_host *host);
112+
void (*hs400_enhanced_strobe)(struct rt_mmc_host *host, struct rt_mmcsd_io_cfg *ios);
113+
void (*hw_reset)(struct rt_mmc_host *host);
114+
void (*card_event)(struct rt_mmc_host *host);
115+
};
116+
117+
/* VDD voltage 3.3 ~ 3.4 */
118+
#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */
119+
#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */
120+
121+
#define MMC_CAP2_HS200_1_8V_SDR MMCSD_SUP_HS200_1V8
122+
#define MMC_CAP2_HS200_1_2V_SDR MMCSD_SUP_HS200_1V2
123+
#define MMC_CAP_4_BIT_DATA MMCSD_BUSWIDTH_4
124+
#define MMC_CAP_8_BIT_DATA MMCSD_BUSWIDTH_8
125+
#define MMC_CAP2_HS200 MMCSD_SUP_HS200
126+
#define MMC_CAP_MMC_HIGHSPEED MMCSD_SUP_HIGHSPEED
127+
#define MMC_CAP_SD_HIGHSPEED MMCSD_SUP_HIGHSPEED
128+
#define MMC_CAP_1_8V_DDR MMCSD_SUP_DDR_1V8
129+
#define MMC_CAP_3_3V_DDR MMCSD_SUP_DDR_3V3
130+
#define MMC_CAP_1_2V_DDR MMCSD_SUP_DDR_1V2
131+
#define MMC_CAP_NONREMOVABLE MMCSD_SUP_NONREMOVABLE
132+
133+
#define MMC_CAP_UHS_DDR50 0
134+
#define MMC_CAP2_HS400 0
135+
#define MMC_CAP_UHS_SDR50 0
136+
#define MMC_CAP_UHS_SDR25 0
137+
#define MMC_CAP_UHS_SDR12 0
138+
#define MMC_CAP_UHS_SDR104 0
139+
#define MMC_CAP_UHS 0
140+
#define MMC_CAP2_HSX00_1_8V 0
141+
#define MMC_CAP2_HS400_ES 0
142+
#define MMC_CAP_NEEDS_POLL 0
143+
#define MMC_CAP2_HSX00_1_2V 0
144+
#define MMC_CAP2_HS400_1_2V 0
145+
#define MMC_CAP2_HS400_1_8V 0
146+
#define MMC_CAP_DRIVER_TYPE_D 0
147+
#define MMC_CAP_DRIVER_TYPE_C 0
148+
#define MMC_SET_DRIVER_TYPE_B 0
149+
#define MMC_CAP_DRIVER_TYPE_A 0
150+
#define MMC_CAP2_SDIO_IRQ_NOTHREAD 0
151+
#define MMC_CAP_CMD23 0
152+
#define MMC_CAP_SDIO_IRQ 0
153+
154+
#define MMC_CAP2_NO_SDIO (1 << 19)
155+
#define MMC_CAP2_NO_SD (1 << 21)
156+
#define MMC_CAP2_NO_MMC (1 << 22)
157+
#define MMC_CAP2_CQE (1 << 23)
158+
159+
#define MMC_VDD_165_195 VDD_165_195
160+
#define MMC_VDD_20_21 VDD_20_21
161+
#define MMC_VDD_29_30 VDD_29_30
162+
#define MMC_VDD_30_31 VDD_30_31
163+
#define MMC_VDD_32_33 VDD_32_33
164+
#define MMC_VDD_33_34 VDD_33_34
165+
166+
struct rt_mmc_host
167+
{
168+
struct rt_mmcsd_host rthost;
169+
struct rt_device *parent;
170+
int index;
171+
const struct rt_mmc_host_ops *ops;
172+
unsigned int f_min;
173+
unsigned int f_max;
174+
unsigned int f_init;
175+
rt_uint32_t ocr_avail;
176+
rt_uint32_t ocr_avail_sdio; /* SDIO-specific OCR */
177+
rt_uint32_t ocr_avail_sd; /* SD-specific OCR */
178+
rt_uint32_t ocr_avail_mmc; /* MMC-specific OCR */
179+
struct wakeup_source *ws; /* Enable consume of uevents */
180+
rt_uint32_t max_current_330;
181+
rt_uint32_t max_current_300;
182+
rt_uint32_t max_current_180;
183+
rt_uint32_t caps; /* Host capabilities */
184+
rt_uint32_t caps2; /* More host capabilities */
185+
186+
187+
/* host specific block data */
188+
unsigned int max_seg_size; /* see blk_queue_max_segment_size */
189+
unsigned short max_segs; /* see blk_queue_max_segments */
190+
unsigned short unused;
191+
unsigned int max_req_size; /* maximum number of bytes in one req */
192+
unsigned int max_blk_size; /* maximum size of one mmc block */
193+
unsigned int max_blk_count; /* maximum number of blocks in one req */
194+
unsigned int max_busy_timeout; /* max busy timeout in ms */
195+
struct rt_mmcsd_io_cfg ios; /* current io bus settings */
196+
unsigned int retune_period;
197+
/* group bitfields together to minimize padding */
198+
unsigned int use_spi_crc : 1;
199+
unsigned int claimed : 1; /* host exclusively claimed */
200+
unsigned int doing_init_tune : 1; /* initial tuning in progress */
201+
unsigned int can_retune : 1; /* re-tuning can be used */
202+
unsigned int doing_retune : 1; /* re-tuning in progress */
203+
unsigned int retune_now : 1; /* do re-tuning at next req */
204+
unsigned int retune_paused : 1; /* re-tuning is temporarily disabled */
205+
unsigned int retune_crc_disable : 1; /* don't trigger retune upon crc */
206+
unsigned int can_dma_map_merge : 1; /* merging can be used */
207+
unsigned int vqmmc_enabled : 1; /* vqmmc regulator is enabled */
208+
209+
int need_retune; /* re-tuning is needed */
210+
int hold_retune; /* hold off re-tuning */
211+
rt_bool_t trigger_card_event; /* card_event necessary */
212+
unsigned int sdio_irqs;
213+
rt_bool_t sdio_irq_pending;
214+
215+
/* Ongoing data transfer that allows commands during transfer */
216+
struct rt_mmcsd_req *ongoing_mrq;
217+
218+
rt_uint32_t actual_clock; /* Actual HC clock rate */
219+
rt_uint32_t pm_caps;
220+
rt_ubase_t private[];
221+
};
222+
223+
rt_inline int mmc_card_is_removable(struct rt_mmc_host *host)
224+
{
225+
return !(host->caps & MMC_CAP_NONREMOVABLE);
226+
}
227+
228+
struct rt_mmc_host *rt_mmc_alloc_host(int extra, struct rt_device *);
229+
rt_err_t rt_mmc_add_host(struct rt_mmc_host *);
230+
void rt_mmc_remove_host(struct rt_mmc_host *);
231+
void rt_mmc_free_host(struct rt_mmc_host *);
232+
rt_err_t rt_mmc_of_parse(struct rt_mmc_host *host);
233+
234+
rt_inline void *rt_mmc_priv(struct rt_mmc_host *host)
235+
{
236+
return (void *)host->private;
237+
}
238+
239+
#define mmc_host_is_spi(host) ((host)->caps & MMC_CAP_SPI)
240+
241+
#define mmc_dev(x) ((x)->parent)
242+
#define mmc_classdev(x) (&(x)->class_dev)
243+
#define mmc_hostname(x) (x->parent->parent.name)
244+
245+
void rt_mmc_detect_change(struct rt_mmc_host *host, rt_ubase_t delay);
246+
void rt_mmc_request_done(struct rt_mmc_host *host, struct rt_mmcsd_req *req);
247+
248+
rt_inline rt_bool_t sdio_irq_claimed(struct rt_mmc_host *host)
249+
{
250+
return host->sdio_irqs > 0;
251+
}
252+
253+
void mmc_retune_timer_stop(struct rt_mmc_host* host);
254+
255+
enum dma_data_direction
256+
{
257+
DMA_BIDIRECTIONAL = 0,
258+
DMA_TO_DEVICE = 1,
259+
DMA_FROM_DEVICE = 2,
260+
DMA_NONE = 3,
261+
};
262+
263+
rt_inline void mmc_retune_needed(struct rt_mmc_host *host)
264+
{
265+
if (host->can_retune)
266+
{
267+
host->need_retune = 1;
268+
}
269+
}
270+
271+
rt_inline rt_bool_t mmc_can_retune(struct rt_mmc_host *host)
272+
{
273+
return host->can_retune == 1;
274+
}
275+
276+
rt_inline rt_bool_t mmc_doing_retune(struct rt_mmc_host *host)
277+
{
278+
return host->doing_retune == 1;
279+
}
280+
281+
rt_inline rt_bool_t mmc_doing_tune(struct rt_mmc_host *host)
282+
{
283+
return host->doing_retune == 1 || host->doing_init_tune == 1;
284+
}
285+
286+
rt_inline int mmc_get_dma_dir(struct rt_mmcsd_data *data)
287+
{
288+
return data->flags & DATA_DIR_WRITE ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
289+
}
290+
291+
rt_inline rt_bool_t mmc_op_multi(rt_uint32_t opcode)
292+
{
293+
return opcode == MMC_WRITE_MULTIPLE_BLOCK ||
294+
opcode == MMC_READ_MULTIPLE_BLOCK;
295+
}
296+
297+
rt_inline rt_bool_t mmc_op_tuning(rt_uint32_t opcode)
298+
{
299+
return opcode == MMC_SEND_TUNING_BLOCK ||
300+
opcode == MMC_SEND_TUNING_BLOCK_HS200;
301+
}
302+
303+
rt_err_t rt_mmc_gpio_get_cd(struct rt_mmc_host *host);
304+
void rt_mmc_detect_change(struct rt_mmc_host *host, rt_ubase_t delay);
305+
rt_bool_t rt_mmc_can_gpio_ro(struct rt_mmc_host *host);
306+
rt_err_t rt_mmc_gpio_get_ro(struct rt_mmc_host *host);
307+
308+
rt_err_t rt_mmc_send_abort_tuning(struct rt_mmc_host *host, rt_uint32_t opcode);
309+
310+
#endif /* __DEV_SDHCI_HOST_H__ */

components/drivers/include/rtdevice.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,10 @@ extern "C" {
215215
#include "drivers/dev_mmcsd_core.h"
216216
#include "drivers/dev_sd.h"
217217
#include "drivers/dev_sdio.h"
218+
#if defined(RT_USING_DM) && defined(RT_USING_SDHCI)
219+
#include "drivers/dev_sdhci.h"
220+
#include "drivers/dev_sdhci_host.h"
221+
#endif /* RT_USING_DM && RT_USING_SDHCI */
218222
#endif /* RT_USING_SDIO */
219223

220224

0 commit comments

Comments
 (0)