fh_mmc.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * This file is part of FH8620 BSP for RT-Thread distribution.
  3. *
  4. * Copyright (c) 2016 Shanghai Fullhan Microelectronics Co., Ltd.
  5. * All rights reserved
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along
  18. * with this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. *
  21. * Visit http://www.fullhan.com to get contact with Fullhan.
  22. *
  23. * Change Logs:
  24. * Date Author Notes
  25. */
  26. #ifndef FH_MMC_H_
  27. #define FH_MMC_H_
  28. #include "fh_def.h"
  29. #define OFFSET_SDC_CTRL (0x0000)
  30. #define OFFSET_SDC_PWREN (0x0004)
  31. #define OFFSET_SDC_CLKDIV (0x0008)
  32. #define OFFSET_SDC_CLKSRC (0x000C)
  33. #define OFFSET_SDC_CLKENA (0x0010)
  34. #define OFFSET_SDC_TMOUT (0x0014)
  35. #define OFFSET_SDC_CTYPE (0x0018)
  36. #define OFFSET_SDC_BLKSIZ (0x001C)
  37. #define OFFSET_SDC_BYTCNT (0x0020)
  38. #define OFFSET_SDC_INTMASK (0x0024)
  39. #define OFFSET_SDC_CMDARG (0x0028)
  40. #define OFFSET_SDC_CMD (0x002C)
  41. #define OFFSET_SDC_RESP0 (0x0030)
  42. #define OFFSET_SDC_RESP1 (0x0034)
  43. #define OFFSET_SDC_RESP2 (0x0038)
  44. #define OFFSET_SDC_RESP3 (0x003C)
  45. #define OFFSET_SDC_MINTSTS (0x0040)
  46. #define OFFSET_SDC_RINTSTS (0x0044)
  47. #define OFFSET_SDC_STATUS (0x0048)
  48. #define OFFSET_SDC_FIFOTH (0x004C)
  49. #define OFFSET_SDC_CDETECT (0x0050)
  50. #define OFFSET_SDC_WRTPRT (0x0054)
  51. #define OFFSET_SDC_GPIO (0x0058)
  52. #define OFFSET_SDC_TCBCNT (0x005C)
  53. #define OFFSET_SDC_TBBCNT (0x0060)
  54. #define OFFSET_SDC_DEBNCE (0x0064)
  55. #define OFFSET_SDC_USRID (0x0068)
  56. #define OFFSET_SDC_VERID (0x006C)
  57. #define OFFSET_SDC_HCON (0x0070)
  58. #define OFFSET_SDC_UHS_REG (0x0074)
  59. #define OFFSET_SDC_RST_N (0x0078)
  60. #define OFFSET_SDC_BMOD (0x0080)
  61. #define OFFSET_SDC_PLDMND (0x0084)
  62. #define OFFSET_SDC_DBADDR (0x0088)
  63. #define OFFSET_SDC_IDSTS (0x008C)
  64. #define OFFSET_SDC_IDINTEN (0x0090)
  65. #define OFFSET_SDC_DSCADDR (0x0094)
  66. #define OFFSET_SDC_BUFADDR (0x0098)
  67. #define OFFSET_SDC_CARDTHRCTL (0x0100)
  68. #define OFFSET_SDC_BACK_END_POWER (0x0104)
  69. #define OFFSET_SDC_FIFO (0x0200)
  70. #define MMC_FIFO_DEPTH (16)
  71. #define MMC_CMD_FLAG_RESPONSE_EXPECTED BIT(6)
  72. #define MMC_CMD_FLAG_LONG_RESPONSE BIT(7)
  73. #define MMC_CMD_FLAG_CHECK_RESP_CRC BIT(8)
  74. #define MMC_CMD_FLAG_DATA_EXPECTED BIT(9)
  75. #define MMC_CMD_FLAG_WRITE_TO_CARD BIT(10)
  76. #define MMC_CMD_FLAG_DATA_STREAM BIT(11)
  77. #define MMC_CMD_FLAG_AUTO_STOP BIT(12)
  78. #define MMC_CMD_FLAG_WAIT_PREV_DATA BIT(13)
  79. #define MMC_CMD_FLAG_STOP_TRANSFER BIT(14)
  80. #define MMC_CMD_FLAG_SEND_INIT BIT(15)
  81. #define MMC_CMD_FLAG_SWITCH_VOLTAGE BIT(28)
  82. #define MMC_STATUS_DATA_BUSY BIT(9)
  83. #define MMC_CTRL_CONTROLLER_RESET BIT(0)
  84. #define MMC_CTRL_FIFO_RESET BIT(1)
  85. #define MMC_CTRL_DMA_RESET BIT(2)
  86. #define MMC_CTRL_INT_ENABLE BIT(4)
  87. #define MMC_CTRL_USE_DMA BIT(25)
  88. #define MMC_CMD_START_CMD BIT(31)
  89. #define MMC_BMOD_RESET BIT(0)
  90. #define MMC_CLOCK_IN (50000000)
  91. #define MMC_CARD_WIDTH_1BIT (0)
  92. #define MMC_CARD_WIDTH_4BIT (1)
  93. #define MMC_INT_STATUS_CARD_DETECT BIT(0)
  94. #define MMC_INT_STATUS_RESPONSE_ERROR BIT(1)
  95. #define MMC_INT_STATUS_CMD_DONE BIT(2)
  96. #define MMC_INT_STATUS_TRANSFER_OVER BIT(3)
  97. #define MMC_INT_STATUS_TX_REQUEST BIT(4)
  98. #define MMC_INT_STATUS_RX_REQUEST BIT(5)
  99. #define MMC_INT_STATUS_RESP_CRC_ERROR BIT(6)
  100. #define MMC_INT_STATUS_DATA_CRC_ERROR BIT(7)
  101. #define MMC_INT_STATUS_RESPONSE_TIMEOUT BIT(8)
  102. #define MMC_INT_STATUS_READ_TIMEOUT BIT(9)
  103. #define MMC_INT_STATUS_STARVATION_TIMEOUT BIT(10)
  104. #define MMC_INT_STATUS_OVERRUN_UNDERRUN BIT(11)
  105. #define MMC_INT_STATUS_HARDWARE_LOCKED BIT(12)
  106. #define MMC_INT_STATUS_START_BIT_ERROR BIT(13)
  107. #define MMC_INT_STATUS_AUTO_CMD_DONE BIT(14)
  108. #define MMC_INT_STATUS_END_BIT_ERROR BIT(15)
  109. #define MMC_INT_STATUS_SDIO BIT(16)
  110. #define MMC_INT_STATUS_ALL (~0)
  111. #define MMC_INIT_STATUS_DATA_ERROR (MMC_INT_STATUS_DATA_CRC_ERROR \
  112. | MMC_INT_STATUS_START_BIT_ERROR | MMC_INT_STATUS_END_BIT_ERROR)
  113. #define MMC_USE_DMA
  114. #ifdef MMC_USE_DMA
  115. #define MMC_INT_STATUS_DATA (MMC_INT_STATUS_TRANSFER_OVER | MMC_INIT_STATUS_DATA_ERROR)
  116. #else
  117. #define MMC_INT_STATUS_DATA (MMC_INT_STATUS_TRANSFER_OVER | MMC_INIT_STATUS_DATA_ERROR \
  118. | MMC_INT_STATUS_TX_REQUEST | MMC_INT_STATUS_RX_REQUEST)
  119. #endif
  120. #define MMC_DMA_DESC_BUFF_SIZE (0x1f00)
  121. typedef union
  122. {
  123. struct
  124. {
  125. UINT32 reserved :1; //0~15
  126. UINT32 disable_interrupt_on_completion :1; //16~31
  127. UINT32 last_descriptor :1; //0~15
  128. UINT32 first_descriptor :1; //16~31
  129. UINT32 sencond_address_chained :1; //0~15
  130. UINT32 end_of_ring :1; //16~31
  131. UINT32 reserved_29_6 :24; //0~15
  132. UINT32 card_error_summary :1; //16~31
  133. UINT32 own :1; //16~31
  134. }bit;
  135. UINT32 dw;
  136. }MMC_DMA_Descriptor0;
  137. typedef union
  138. {
  139. struct
  140. {
  141. UINT32 buffer1_size :13; //0~15
  142. UINT32 buffer2_size :13; //16~31
  143. UINT32 reserved_26_31 :6; //0~15
  144. }bit;
  145. UINT32 dw;
  146. }MMC_DMA_Descriptor1;
  147. typedef union
  148. {
  149. struct
  150. {
  151. UINT32 buffer_addr0 :32; //0~15
  152. }bit;
  153. UINT32 dw;
  154. }MMC_DMA_Descriptor2;
  155. typedef union
  156. {
  157. struct
  158. {
  159. UINT32 buffer_addr1 :32; //0~15
  160. }bit;
  161. UINT32 dw;
  162. }MMC_DMA_Descriptor3;
  163. typedef struct
  164. {
  165. MMC_DMA_Descriptor0 desc0; /* control and status information of descriptor */
  166. MMC_DMA_Descriptor1 desc1; /* buffer sizes */
  167. MMC_DMA_Descriptor2 desc2; /* physical address of the buffer 1 */
  168. MMC_DMA_Descriptor3 desc3; /* physical address of the buffer 2 */
  169. }MMC_DMA_Descriptors;
  170. struct fh_mmc_obj
  171. {
  172. rt_uint32_t id;
  173. rt_uint32_t irq;
  174. rt_uint32_t base;
  175. rt_uint32_t power_pin_gpio;
  176. MMC_DMA_Descriptors *descriptors;
  177. void (*mmc_reset)(struct fh_mmc_obj *);
  178. };
  179. rt_inline rt_uint32_t MMC_GetCardStatus(struct fh_mmc_obj *mmc_obj)
  180. {
  181. rt_uint32_t card_status = GET_REG(mmc_obj->base + OFFSET_SDC_CDETECT);
  182. return card_status & 0x1;
  183. }
  184. rt_inline void MMC_StartDma(struct fh_mmc_obj *mmc_obj)
  185. {
  186. rt_uint32_t reg;
  187. SET_REG(mmc_obj->base + OFFSET_SDC_DBADDR, (rt_uint32_t)mmc_obj->descriptors);
  188. reg = GET_REG(mmc_obj->base + OFFSET_SDC_BMOD);
  189. reg |= 1 << 7;
  190. SET_REG(mmc_obj->base + OFFSET_SDC_BMOD, reg);
  191. }
  192. rt_inline void MMC_StopDma(struct fh_mmc_obj *mmc_obj)
  193. {
  194. rt_uint32_t reg;
  195. reg = GET_REG(mmc_obj->base + OFFSET_SDC_BMOD);
  196. reg &= ~(1 << 7);
  197. SET_REG(mmc_obj->base + OFFSET_SDC_BMOD, reg);
  198. }
  199. rt_inline rt_uint32_t MMC_GetWaterlevel(struct fh_mmc_obj *mmc_obj)
  200. {
  201. return (GET_REG(mmc_obj->base + OFFSET_SDC_STATUS) >> 17) & 0x1fff;
  202. }
  203. rt_inline rt_uint32_t MMC_GetStatus(struct fh_mmc_obj *mmc_obj)
  204. {
  205. return GET_REG(mmc_obj->base + OFFSET_SDC_STATUS);
  206. }
  207. rt_inline rt_uint32_t MMC_GetRawInterrupt(struct fh_mmc_obj *mmc_obj)
  208. {
  209. return GET_REG(mmc_obj->base + OFFSET_SDC_RINTSTS);
  210. }
  211. rt_inline rt_uint32_t MMC_GetUnmaskedInterrupt(struct fh_mmc_obj *mmc_obj)
  212. {
  213. return GET_REG(mmc_obj->base + OFFSET_SDC_MINTSTS);
  214. }
  215. rt_inline rt_uint32_t MMC_ClearRawInterrupt(struct fh_mmc_obj *mmc_obj, rt_uint32_t interrupts)
  216. {
  217. return SET_REG(mmc_obj->base + OFFSET_SDC_RINTSTS, interrupts);
  218. }
  219. rt_inline rt_uint32_t MMC_GetInterruptMask(struct fh_mmc_obj *mmc_obj)
  220. {
  221. return GET_REG(mmc_obj->base + OFFSET_SDC_INTMASK);
  222. }
  223. rt_inline rt_uint32_t MMC_SetInterruptMask(struct fh_mmc_obj *mmc_obj, rt_uint32_t mask)
  224. {
  225. return SET_REG(mmc_obj->base + OFFSET_SDC_INTMASK, mask);
  226. }
  227. rt_inline void MMC_SetByteCount(struct fh_mmc_obj *mmc_obj, rt_uint32_t bytes)
  228. {
  229. SET_REG(mmc_obj->base + OFFSET_SDC_BYTCNT, bytes);
  230. }
  231. rt_inline void MMC_SetBlockSize(struct fh_mmc_obj *mmc_obj, rt_uint32_t size)
  232. {
  233. SET_REG(mmc_obj->base + OFFSET_SDC_BLKSIZ, size);
  234. }
  235. rt_inline rt_uint32_t MMC_GetResponse(struct fh_mmc_obj *mmc_obj, int resp_num)
  236. {
  237. return GET_REG(mmc_obj->base + OFFSET_SDC_RESP0 + resp_num * 4);
  238. }
  239. rt_inline rt_uint32_t MMC_IsFifoEmpty(struct fh_mmc_obj *mmc_obj)
  240. {
  241. return (GET_REG(mmc_obj->base + OFFSET_SDC_STATUS) >> 2) & 0x1;
  242. }
  243. rt_inline rt_uint32_t MMC_IsDataStateBusy(struct fh_mmc_obj *mmc_obj)
  244. {
  245. return (GET_REG(mmc_obj->base + OFFSET_SDC_STATUS) >> 10) & 0x1;
  246. }
  247. void MMC_Init(struct fh_mmc_obj *mmc_obj);
  248. int MMC_ResetFifo(struct fh_mmc_obj *mmc_obj);
  249. int MMC_SetCardWidth(struct fh_mmc_obj *mmc_obj, int width);
  250. int MMC_UpdateClockRegister(struct fh_mmc_obj *mmc_obj, int div);
  251. int MMC_SendCommand(struct fh_mmc_obj *mmc_obj, rt_uint32_t cmd, rt_uint32_t arg, rt_uint32_t flags);
  252. int MMC_WriteData(struct fh_mmc_obj *mmc_obj, rt_uint32_t *buf, rt_uint32_t size);
  253. int MMC_ReadData(struct fh_mmc_obj *mmc_obj, rt_uint32_t *buf, rt_uint32_t size);
  254. inline void MMC_StartDma(struct fh_mmc_obj *mmc_obj);
  255. inline void MMC_StopDma(struct fh_mmc_obj *mmc_obj);
  256. void MMC_InitDescriptors(struct fh_mmc_obj *mmc_obj, rt_uint32_t *buf, rt_uint32_t size);
  257. #endif /* FH_MMC_H_ */