fit-mmc.c 7.5 KB

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