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