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 #include <rtthread.h>
11 #include "sdhci.h"
12 #include <rtdbg.h>
13 #include <mmu.h>
14 #include <drivers/core/dm.h>
15
16
rt_plat_request(struct rt_mmcsd_host * host,struct rt_mmcsd_req * req)17 static void rt_plat_request(struct rt_mmcsd_host *host, struct rt_mmcsd_req *req)
18 {
19 struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;
20 rt_uint32_t flags = req->cmd->flags;
21
22 switch (flags & RESP_MASK)
23 {
24 case RESP_NONE:
25 flags |= MMC_RSP_NONE;
26 break;
27 case RESP_R1:
28 flags |= MMC_RSP_R1;
29 break;
30 case RESP_R1B:
31 flags |= MMC_RSP_R1B;
32 break;
33 case RESP_R2:
34 flags |= MMC_RSP_R2;
35 break;
36 case RESP_R3:
37 flags |= MMC_RSP_R3;
38 break;
39 case RESP_R4:
40 flags |= MMC_RSP_R4;
41 break;
42 case RESP_R5:
43 flags |= MMC_RSP_R5;
44 break;
45 case RESP_R6:
46 flags |= MMC_RSP_R6;
47 break;
48 case RESP_R7:
49 flags |= MMC_RSP_R7;
50 break;
51 }
52 if (req->data)
53 {
54 if ((rt_uint64_t)rt_kmem_v2p(req->data->buf) > 0xffffffff)
55 {
56 void *dma_buffer = rt_malloc(req->data->blks * req->data->blksize);
57 void *req_buf = NULL;
58
59 if (req->data->flags & DATA_DIR_WRITE)
60 {
61 rt_memcpy(dma_buffer, req->data->buf, req->data->blks * req->data->blksize);
62 req_buf = req->data->buf;
63 req->data->buf = dma_buffer;
64 }
65 else if (req->data->flags & DATA_DIR_READ)
66 {
67 req_buf = req->data->buf;
68 req->data->buf = dma_buffer;
69 }
70 req->cmd->flags |= flags;
71 mmc->ops->request(mmc, req);
72
73 rt_sem_take(&host->sem_ack, RT_WAITING_FOREVER);
74
75 if (req->data->flags & DATA_DIR_READ)
76 {
77 rt_memcpy(req_buf, dma_buffer, req->data->blksize * req->data->blks);
78 req->data->buf = req_buf;
79 }else{
80 req->data->buf = req_buf;
81 }
82
83 rt_free(dma_buffer);
84 rt_sem_release(&host->sem_ack);
85 }
86 else
87 {
88 req->cmd->flags |= flags;
89 mmc->ops->request(mmc, req);
90 }
91 }
92 else
93 {
94 req->cmd->flags |= flags;
95 mmc->ops->request(mmc, req);
96 }
97 }
98
rt_plat_set_ioconfig(struct rt_mmcsd_host * host,struct rt_mmcsd_io_cfg * iocfg)99 static void rt_plat_set_ioconfig(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *iocfg)
100 {
101 struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;
102
103 LOG_D("clock:%d,width:%d,power:%d,vdd:%d,timing:%d\n",
104 iocfg->clock, iocfg->bus_width,
105 iocfg->power_mode, iocfg->vdd, iocfg->timing);
106
107 mmc->ops->set_ios(mmc, iocfg);
108 }
109
rt_plat_get_card_status(struct rt_mmcsd_host * host)110 static rt_int32_t rt_plat_get_card_status(struct rt_mmcsd_host *host)
111 {
112 struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;
113
114 return mmc->ops->get_cd(mmc);
115 }
116
rt_plat_execute_tuning(struct rt_mmcsd_host * host,rt_int32_t opcode)117 static rt_int32_t rt_plat_execute_tuning(struct rt_mmcsd_host *host, rt_int32_t opcode)
118 {
119 struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;
120
121 return mmc->ops->execute_tuning(mmc, opcode);
122 }
123
rt_plat_enable_sdio_irq(struct rt_mmcsd_host * host,rt_int32_t en)124 static void rt_plat_enable_sdio_irq(struct rt_mmcsd_host *host, rt_int32_t en)
125 {
126 struct rt_mmc_host *mmc = (struct rt_mmc_host *)host;
127
128 return mmc->ops->enable_sdio_irq(mmc, en);
129 }
130
131
132 static const struct rt_mmcsd_host_ops rt_mmcsd_ops = {
133 .request = rt_plat_request,
134 .set_iocfg = rt_plat_set_ioconfig,
135 .get_card_status = rt_plat_get_card_status,
136 .enable_sdio_irq = rt_plat_enable_sdio_irq,
137 .execute_tuning = rt_plat_execute_tuning,
138 };
139
140
rt_mmc_request_done(struct rt_mmc_host * host,struct rt_mmcsd_req * mrq)141 void rt_mmc_request_done(struct rt_mmc_host *host, struct rt_mmcsd_req *mrq)
142 {
143 mmcsd_req_complete(&host->rthost);
144 }
145
146 /*add host in rtt while sdhci complete*/
rt_mmc_add_host(struct rt_mmc_host * mmc)147 int rt_mmc_add_host(struct rt_mmc_host *mmc)
148 {
149 mmc->rthost.ops = &rt_mmcsd_ops;
150 mmc->rthost.flags = mmc->caps;
151 mmc->rthost.freq_max = mmc->f_max;
152 mmc->rthost.freq_min = 400000;
153 mmc->rthost.max_dma_segs = mmc->max_segs;
154 mmc->rthost.max_seg_size = mmc->max_seg_size;
155 mmc->rthost.max_blk_size = mmc->max_blk_size;
156 mmc->rthost.max_blk_count = mmc->max_blk_count;
157 mmc->rthost.valid_ocr = VDD_165_195|VDD_20_21|VDD_21_22|VDD_22_23|VDD_24_25|VDD_25_26|VDD_26_27|VDD_27_28|VDD_28_29|VDD_29_30|VDD_30_31|VDD_32_33|VDD_33_34|VDD_34_35|VDD_35_36;
158
159
160 mmcsd_change(&mmc->rthost);
161 return 0;
162 }
163
rt_mmc_alloc_host(int extra,struct rt_device * dev)164 struct rt_mmc_host *rt_mmc_alloc_host(int extra, struct rt_device *dev)
165 {
166 struct rt_mmc_host *mmc;
167
168 mmc = rt_malloc(sizeof(*mmc) + extra);
169 if (mmc)
170 {
171 rt_memset(mmc, 0, sizeof(*mmc) + extra);
172 mmc->parent = dev;
173 mmcsd_host_init(&mmc->rthost);
174 }
175
176 return mmc;
177 }
178
rt_mmc_remove_host(struct rt_mmc_host * host)179 void rt_mmc_remove_host(struct rt_mmc_host *host)
180 {
181 rt_free(host);
182 }
183
rt_mmc_abort_tuning(struct rt_mmc_host * host,rt_uint32_t opcode)184 int rt_mmc_abort_tuning(struct rt_mmc_host *host, rt_uint32_t opcode)
185 {
186 return 0;
187 }
188
189
rt_mmc_gpio_get_cd(struct rt_mmc_host * host)190 int rt_mmc_gpio_get_cd(struct rt_mmc_host *host)
191 {
192 return -ENOSYS;
193 }
194
rt_mmc_detect_change(struct rt_mmc_host * host,unsigned long delay)195 void rt_mmc_detect_change(struct rt_mmc_host *host, unsigned long delay)
196 {
197 }
198
199
rt_mmc_regulator_set_vqmmc(struct rt_mmc_host * mmc,struct rt_mmcsd_io_cfg * ios)200 int rt_mmc_regulator_set_vqmmc(struct rt_mmc_host *mmc, struct rt_mmcsd_io_cfg *ios)
201 {
202 return 0;
203 }
204
rt_mmc_can_gpio_ro(struct rt_mmc_host * host)205 rt_bool_t rt_mmc_can_gpio_ro(struct rt_mmc_host *host)
206 {
207 return RT_FALSE;
208 }
209
rt_mmc_gpio_get_ro(struct rt_mmc_host * host)210 int rt_mmc_gpio_get_ro(struct rt_mmc_host *host)
211 {
212 return 0;
213 }
214
rt_mmc_send_abort_tuning(struct rt_mmc_host * host,rt_uint32_t opcode)215 int rt_mmc_send_abort_tuning(struct rt_mmc_host *host, rt_uint32_t opcode)
216 {
217 return 0;
218 }
rt_mmc_of_parse(struct rt_mmc_host * host)219 int rt_mmc_of_parse(struct rt_mmc_host *host)
220 {
221 struct rt_device *dev = host->parent;
222 rt_uint32_t bus_width;
223
224 if (!dev || !dev->ofw_node)
225 return 0;
226
227 /* "bus-width" is translated to MMC_CAP_*_BIT_DATA flags */
228 if (rt_dm_dev_prop_read_u32(dev, "bus-width", &bus_width) < 0)
229 {
230 bus_width = 1;
231 }
232
233 switch (bus_width)
234 {
235 case 8:
236 host->caps |= MMC_CAP_8_BIT_DATA;
237 break; /* Hosts capable of 8-bit can also do 4 bits */
238 case 4:
239 host->caps |= MMC_CAP_4_BIT_DATA;
240 break;
241 case 1:
242 break;
243 default:
244 return -EINVAL;
245 }
246
247 /* f_max is obtained from the optional "max-frequency" property */
248 rt_dm_dev_prop_read_u32(dev, "max-frequency", &host->f_max);
249
250 if (rt_dm_dev_prop_read_bool(dev, "cap-mmc-highspeed"))
251 {
252 host->caps |= MMC_CAP_MMC_HIGHSPEED;
253 }
254
255 if (rt_dm_dev_prop_read_bool(dev, "mmc-hs200-1_8v"))
256 {
257 host->caps |= MMC_CAP2_HS200_1_8V_SDR;
258 }
259
260 if (rt_dm_dev_prop_read_bool(dev, "non-removable"))
261 {
262 host->caps |= MMC_CAP_NONREMOVABLE;
263 }
264
265 if (rt_dm_dev_prop_read_bool(dev, "no-sdio"))
266 {
267 host->caps2 |= MMC_CAP2_NO_SDIO;
268 }
269
270 if (rt_dm_dev_prop_read_bool(dev, "no-sd"))
271 {
272 host->caps2 |= MMC_CAP2_NO_SD;
273 }
274
275 if (rt_dm_dev_prop_read_bool(dev, "mmc-ddr-3_3v"))
276 {
277 host->caps |= MMC_CAP_3_3V_DDR;
278 }
279
280 if (rt_dm_dev_prop_read_bool(dev, "mmc-ddr-1_8v"))
281 {
282 host->caps |= MMC_CAP_1_8V_DDR;
283 }
284
285 if (rt_dm_dev_prop_read_bool(dev, "mmc-ddr-1_2v"))
286 {
287 host->caps |= MMC_CAP_1_2V_DDR;
288 }
289
290 return 0;
291 }
292
293
rt_mmc_free_host(struct rt_mmc_host * host)294 void rt_mmc_free_host(struct rt_mmc_host *host)
295 {
296 }
297
rt_mmc_can_gpio_cd(struct rt_mmc_host * host)298 rt_bool_t rt_mmc_can_gpio_cd(struct rt_mmc_host *host)
299 {
300 return RT_FALSE;
301 }
302
mmc_regulator_get_supply(struct rt_mmc_host * mmc)303 int mmc_regulator_get_supply(struct rt_mmc_host *mmc)
304 {
305 mmc->supply.vmmc = -RT_NULL;
306 mmc->supply.vqmmc = -RT_NULL;
307
308 return 0;
309 }
regulator_get_current_limit(struct regulator * regulator)310 int regulator_get_current_limit(struct regulator *regulator)
311 {
312 return 0;
313 }
314
regulator_is_supported_voltage(struct regulator * regulator,int min_uV,int max_uV)315 int regulator_is_supported_voltage(struct regulator *regulator,
316
317 int min_uV, int max_uV)
318 {
319 return 0;
320 }
321