hpm_sdmmc_host.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /*
  2. * Copyright (c) 2021-2024 HPMicro
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. */
  7. #ifndef HPM_SDMMC_HOST_H
  8. #define HPM_SDMMC_HOST_H
  9. #include "hpm_common.h"
  10. #include "hpm_sdmmc_osal.h"
  11. #include "hpm_sdxc_drv.h"
  12. /**
  13. *
  14. * @brief HPM SDMMC Host APIs
  15. * @defgroup hpm_sdmmc HPM SDMMC stack
  16. * @ingroup hpm_sdmmc_interfaces
  17. * @{
  18. *
  19. */
  20. #ifdef __cplusplus
  21. extern "C" {
  22. #endif
  23. #define HPM_SDMMC_HOST_SUPPORT_4BIT (1UL << 0)
  24. #define HPM_SDMMC_HOST_SUPPORT_8BIT (1UL << 1)
  25. #define HPM_SDMMC_HOST_SUPPORT_3V3 (1UL << 2)
  26. #define HPM_SDMMC_HOST_SUPPORT_1V8 (1UL << 3)
  27. #define HPM_SDMMC_HOST_SUPPORT_DDR (1UL << 4)
  28. #define HPM_SDMMC_HOST_SUPPORT_SDR50 (1UL << 5)
  29. #define HPM_SDMMC_HOST_SUPPORT_SDR104 (1UL << 6)
  30. #define HPM_SDMMC_HOST_SUPPORT_HS200 (1UL << 7)
  31. #define HPM_SDMMC_HOST_SUPPORT_HS400 (1Ul << 8)
  32. #define HPM_SDMMC_HOST_SUPPORT_CARD_DETECTION (1UL << 16)
  33. #define HPM_SDMMC_HOST_SUPPORT_VOLTAGE_SWITCH (1UL << 17)
  34. #define HPM_SDMMC_HOST_SUPPORT_POWER_SWITCH (1UL << 18)
  35. #define HPM_SDMMC_HOST_SUPPORT_WRITE_PROTECTION (1UL << 19)
  36. #define HPM_SDMMC_HOST_SUPPORT_RESET_PIN (1UL << 20)
  37. #define HPM_SDMMC_HOST_SUPPORT_DATA_STROBE (1UL << 21)
  38. #define HPM_SDMMC_HOST_CD_IN_IP (HPM_SDMMC_HOST_SUPPORT_CARD_DETECTION << 8)
  39. #define HPM_SDMMC_HOST_VSEL_IN_IP (HPM_SDMMC_HOST_SUPPORT_VOLTAGE_SWITCH << 8)
  40. #define HPM_SDMMC_HOST_PWR_IN_IP (HPM_SDMMC_HOST_SUPPORT_POWER_SWITCH << 8)
  41. #define HPM_SDMMC_HOST_WP_IN_IP (HPM_SDMMC_HOST_SUPPORT_WRITE_PROTECTION << 8)
  42. #define HPM_SDMMC_HOST_RST_IN_IP (HPM_SDMMC_HOST_SUPPORT_RESET_PIN << 8)
  43. #define HPM_SDMMC_HOST_ADMA3_ALIGN_SIZE (8U)
  44. /**
  45. * @brief SD/MMC Bus Width definitions
  46. */
  47. typedef enum {
  48. sdmmc_bus_width_1bit = 0, /* Bus width: 1-bit */
  49. sdmmc_bus_width_4bit = 1, /* Bus width: 4-bit */
  50. sdmmc_bus_width_8bit = 2, /* Bus width: 8-bit */
  51. } sdmmc_buswidth_t;
  52. /**
  53. * @brief SD/MMC Device Type definitions
  54. */
  55. typedef enum {
  56. sdmmc_dev_type_emmc = 0, /* Device type is eMMC */
  57. sdmmc_dev_type_sd = 1, /* Device type is SD */
  58. sdmmc_dev_type_sdio = 2, /* Device type is SDIO */
  59. } sdmmc_dev_type_t;
  60. /**
  61. * @brief SD/MMC Host Card Detection Modes
  62. */
  63. typedef enum {
  64. sdmmc_host_card_detection_none = 0, /* Card detection is not enabled */
  65. sdmmc_host_card_detection_via_gpio = 1, /* Card detection is via GPIO */
  66. sdmmc_host_card_detection_via_sdxc = 2, /* Card detection is via SDXC CDN pin */
  67. } sdmmc_card_detection_mode_t;
  68. /**
  69. * @brief SDMMC IO Voltage
  70. */
  71. typedef enum {
  72. hpm_sdmmc_io_voltage_3v3 = 0, /*!< IO voltage is 3.3v */
  73. hpm_sdmmc_io_voltage_1v8 = 1, /*!< IO voltage is 1.8v */
  74. } hpm_sdmmc_io_volt_t;
  75. /**
  76. * @brief SDMMC Operation mode
  77. */
  78. typedef enum {
  79. hpm_sdmmc_operation_mode_inactive = 0,
  80. hpm_sdmmc_operation_mode_identification = 1,
  81. hpm_sdmmc_operation_mode_transfer = 2,
  82. hpm_sdmmc_operation_mode_interrupt = 3,
  83. } hpm_sdmmc_operation_mode_t;
  84. /**
  85. * @brief SD/MMC Speed definitions
  86. */
  87. typedef enum {
  88. /* SD Card Speed modes */
  89. sdmmc_sd_speed_normal = 0,
  90. sdmmc_sd_speed_high = 1,
  91. sdmmc_sd_speed_sdr12 = sdmmc_sd_speed_normal,
  92. sdmmc_sd_speed_sdr25 = sdmmc_sd_speed_high,
  93. sdmmc_sd_speed_sdr50 = 2,
  94. sdmmc_sd_speed_sdr104 = 3,
  95. sdmmc_sd_speed_ddr50 = 4,
  96. /* eMMC Card Speed modes */
  97. sdmmc_emmc_speed_legacy = 0,
  98. sdmmc_emmc_speed_high_speed_sdr = 1,
  99. sdmmc_emmc_speed_hs200 = 3,
  100. sdmmc_emmc_speed_high_speed_ddr = 4,
  101. sdmmc_emmc_speed_hs400 = 7,
  102. } sdmmc_speed_mode_t;
  103. /**
  104. * @brief SDMMC Pin info structure
  105. */
  106. typedef struct {
  107. bool use_gpio;
  108. uint8_t polarity;
  109. uint16_t gpio_pin;
  110. } hpm_sdmmc_pin_info_t;
  111. typedef enum {
  112. hpm_sdmmc_power_off = 0, /*!< Power Off the SDMMC */
  113. hpm_sdmmc_power_up = 1, /*!< Power up the SDMMC */
  114. hpm_sdmmc_power_on = 2, /*!< Power on the SDMMC */
  115. } hpm_sdmmc_power_option_t;
  116. /**
  117. * @brief SDMMC extra Pin info
  118. */
  119. typedef struct {
  120. hpm_sdmmc_pin_info_t cd_pin;
  121. hpm_sdmmc_pin_info_t vsel_pin;
  122. hpm_sdmmc_pin_info_t pwr_pin;
  123. hpm_sdmmc_pin_info_t rst_pin;
  124. hpm_sdmmc_pin_info_t wp_pin;
  125. } hpm_sdmmc_extra_io_data_t;
  126. #ifndef HPM_SDMMC_HOST_ADMA_TBL_SIZE
  127. #if defined(HPM_SDMMC_USE_ADMA2) && (HPM_SDMMC_USE_ADMA2 == 1)
  128. #define HPM_SDMMC_HOST_ADMA_TBL_SIZE (SDXC_ADMA2_DESC_WORDS * 2UL)
  129. #else
  130. #define HPM_SDMMC_HOST_ADMA_TBL_SIZE (SDXC_AMDA3_DESC_MIN_WORDS * 2UL)
  131. #endif
  132. #endif
  133. typedef sdxc_xfer_t sdmmchost_xfer_t;
  134. typedef sdxc_command_t sdmmchost_cmd_t;
  135. typedef sdxc_data_t sdmmchost_data_t;
  136. typedef sdxc_adma2_descriptor_t sdmmc_adma2_desc_t;
  137. typedef SDXC_Type SDMMCHOST_Type;
  138. typedef sdxc_capabilities_t sdmmchost_capabilities_t;
  139. typedef uint32_t (*sdmmchost_clock_init_func_t)(SDMMCHOST_Type *base, uint32_t clk_freq, bool need_reverse);
  140. typedef void (*sdmmchost_power_switch_func_t)(SDMMCHOST_Type *base, bool on_off);
  141. typedef void (*sdmmchost_io_init_func_t)(SDMMCHOST_Type *base);
  142. typedef void (*sdmmchost_switch_1v8_io_func_t)(SDMMCHOST_Type *base);
  143. typedef void (*sdmmchost_cmd_line_init_func_t)(SDMMCHOST_Type *base, bool push_pull);
  144. typedef bool (*sdmmchost_card_detect_func_t)(SDMMCHOST_Type *base);
  145. typedef struct {
  146. void (*cmd_io_init)(SDMMCHOST_Type *base, bool open_drain, bool is_1v8);
  147. void (*clk_data_io_init)(SDMMCHOST_Type *base, uint32_t data_width, bool is_1v8);
  148. void (*pwr_io_init)(SDMMCHOST_Type *base, bool as_gpio);
  149. void (*cd_io_init)(SDMMCHOST_Type *base, bool as_gpio);
  150. void (*vsel_io_init)(SDMMCHOST_Type *base, bool as_gpio);
  151. void (*ds_io_init)(SDMMCHOST_Type *base);
  152. } sdmmc_io_init_apis_t;
  153. typedef struct {
  154. uint8_t hart_id;
  155. uint8_t instance_num;
  156. uint32_t host_flags;
  157. SDMMCHOST_Type *base;
  158. hpm_sdmmc_extra_io_data_t io_data;
  159. sdmmchost_clock_init_func_t clock_init_func;
  160. sdmmc_io_init_apis_t io_init_apis;
  161. void (*delay_ms)(uint32_t ms);
  162. } sdmmc_host_param_t;
  163. typedef struct {
  164. sdmmc_host_param_t host_param; /* Host Parameters */
  165. sdmmc_dev_type_t dev_type; /* Device Type */
  166. hpm_sdmmc_operation_mode_t operation_mode; /* Operation mode */
  167. sdmmc_buswidth_t bus_width; /* Bus width */
  168. hpm_sdmmc_io_volt_t io_voltage; /* IO voltage */
  169. uint32_t clock_freq; /* Clock Frequency */
  170. /* Host Transfer Fields */
  171. sdmmchost_xfer_t xfer; /* xfer context */
  172. sdmmchost_cmd_t cmd; /* Command Context */
  173. sdmmchost_data_t data; /* Data Context */
  174. uint32_t adma_table[HPM_SDMMC_HOST_ADMA_TBL_SIZE + 1]; /* ADMA table buffer, allocate one extra word in case that the adma_table is not 8-byte aligned */
  175. uint32_t buffer[128]; /* Host buffer */
  176. /* Host run-time fields */
  177. bool card_inserted;
  178. bool card_init_done;
  179. void (*sdio_irq_handler)(void *param);
  180. void *sdio_irq_param;
  181. #if defined(HPM_SDMMC_HOST_ENABLE_IRQ) && (HPM_SDMMC_HOST_ENABLE_IRQ == 1)
  182. hpm_sdmmc_osal_event_t xfer_done_or_error_event;
  183. #endif
  184. } sdmmc_host_t;
  185. /**
  186. * @brief SDMMC Host Initialization
  187. * @param [in] host Host context
  188. *
  189. * @return Host initialization status
  190. */
  191. hpm_stat_t sdmmchost_init(sdmmc_host_t *host);
  192. /**
  193. * @brief Set the card bus width
  194. * @param [in,out] host Host context
  195. * @param [in] bus_width Bus width
  196. */
  197. void sdmmchost_set_card_bus_width(sdmmc_host_t *host, sdmmc_buswidth_t bus_width);
  198. /**
  199. * @brief Set the Card clock
  200. * @param [in,out] host Host context
  201. * @param [in] freq Frequency in Hz
  202. * @param [in] clock_inverse Clock Inverse flag
  203. *
  204. * @return Actual clock frequency in Hz
  205. */
  206. uint32_t sdmmchost_set_card_clock(sdmmc_host_t *host, uint32_t freq, bool clock_inverse);
  207. /**
  208. * @brief Deinitialize the host
  209. * @param [in] host Host context
  210. */
  211. void sdmmchost_deinit(sdmmc_host_t *host);
  212. /**
  213. * @brief Reset the host
  214. * @param [in] host Host context
  215. */
  216. void sdmmchost_reset(const sdmmc_host_t *host);
  217. /**
  218. * @brief Wait until the card is active
  219. * @param [in] host Host context
  220. */
  221. void sdmmchost_wait_card_active(const sdmmc_host_t *host);
  222. /**
  223. * @brief Send command via the host
  224. * @param [in] host Host context
  225. * @param [in] cmd Command context
  226. *
  227. * @return Command execution status
  228. */
  229. hpm_stat_t sdmmchost_send_command(sdmmc_host_t *host, const sdmmchost_cmd_t *cmd);
  230. /**
  231. * @brief Transfer data via the host
  232. * @param [in] host Host context
  233. * @param [in] content Transfer context
  234. *
  235. * @return Transfer execution status
  236. */
  237. hpm_stat_t sdmmchost_transfer(sdmmc_host_t *host, const sdmmchost_xfer_t *content);
  238. /**
  239. * @brief Check whether the card is detected or not
  240. * @param [in] host Host context
  241. *
  242. * @return The card detection state
  243. */
  244. bool sdmmchost_is_card_detected(const sdmmc_host_t *host);
  245. /**
  246. * @brief Initialize the Host IO according to the operation mode
  247. * @param [in] host Host context
  248. * @param [in] operation_mode Operation mode
  249. */
  250. void sdmmchost_init_io(sdmmc_host_t *host, hpm_sdmmc_operation_mode_t operation_mode);
  251. /**
  252. * @brief Host delay
  253. * @param [in] host Host context
  254. * @param [in] ms Delay in milliseconds
  255. */
  256. void sdmmchost_delay_ms(const sdmmc_host_t *host, uint32_t ms);
  257. /**
  258. * @brief Switch the Host to 1.8V IO voltage
  259. * @param [in,out] host Host context
  260. *
  261. * @return Host switch voltage status
  262. */
  263. hpm_stat_t sdmmchost_switch_to_1v8(sdmmc_host_t *host);
  264. /**
  265. * @brief Control the Voltage selection pin
  266. * @param [in] host Host context
  267. * @param [in] io_volt IO voltage
  268. */
  269. void sdmmchost_vsel_pin_control(const sdmmc_host_t *host, hpm_sdmmc_io_volt_t io_volt);
  270. /**
  271. * @brief Enable the eMMC support on the host
  272. * @param [in] host Host context
  273. * @param [in] enable Enable or disable the eMMC support
  274. * @note This function should be called after the host is initialized
  275. */
  276. void sdmmchost_enable_emmc_support(const sdmmc_host_t *host, bool enable);
  277. /**
  278. * @brief Set the speed mode via the Host
  279. * @param [in] host Host context
  280. * @param [in] speed_mode Speed mode
  281. *
  282. * @return Operation status
  283. */
  284. hpm_stat_t sdmmchost_set_speed_mode(const sdmmc_host_t *host, sdmmc_speed_mode_t speed_mode);
  285. /**
  286. * @brief Trigger the Error recovery via the Host
  287. * @param [in] host Host context
  288. * @param [in] cmd abort command context
  289. *
  290. * @return Operation status
  291. */
  292. hpm_stat_t sdmmchost_error_recovery(sdmmc_host_t *host, sdmmchost_cmd_t *cmd);
  293. /**
  294. * @brief Check whether the host support voltage switch
  295. * @param [in] host Host context
  296. *
  297. * @return Voltage switch support state
  298. */
  299. bool sdmmchost_is_voltage_switch_supported(const sdmmc_host_t *host);
  300. /**
  301. * @brief Enable the enhanced data strboe
  302. * @param [in] host Host context
  303. * @param [in] enable Enable or disable the enhanced data strobe
  304. */
  305. void sdmmchost_enable_enhanced_data_strobe(const sdmmc_host_t *host, bool enable);
  306. /**
  307. * @brief Set the Data strobe delay for Host
  308. * @param [in] host Host context
  309. */
  310. void sdmmchost_set_data_strobe_delay(const sdmmc_host_t *host);
  311. /**
  312. * @brief Select the IO voltage
  313. * @param [in] host Host context
  314. * @param [in] io_volt IO voltage
  315. */
  316. void sdmmchost_select_voltage(sdmmc_host_t *host, hpm_sdmmc_io_volt_t io_volt);
  317. /**
  318. * @brief Set the Card clock delay chain for the host
  319. * @param [in] host Host context
  320. */
  321. void sdmmchost_set_cardclk_delay_chain(const sdmmc_host_t *host);
  322. /**
  323. * @brief Set the Card Rx Clock delay chain for the host
  324. * @param [in] host Host context
  325. */
  326. void sdmmchost_set_rxclk_delay_chain(sdmmc_host_t *host);
  327. /**
  328. * @brief THe Host IRQ Handler
  329. *
  330. * @param [in,out] host Host context
  331. */
  332. void sdmmchost_irq_handler(sdmmc_host_t *host);
  333. /**
  334. * @brief Registers an SDIO interrupt callback function for the SDMMC host controller.
  335. *
  336. * This function allows the user to register a callback that will be invoked upon
  337. * SDIO interrupts. It is useful for handling SDIO-specific events in addition to
  338. * standard SDMMC transactions.
  339. *
  340. * @param [in,out] host Pointer to the SDMMC host controller structure.
  341. * @param [in] sdio_irq_callback Pointer to the callback function that will be called when an SDIO interrupt occurs.
  342. * The function should accept a single parameter of type `void*`.
  343. * @param [in] param A pointer to a user-defined data that will be passed to the callback function each time it is invoked.
  344. */
  345. void sdmmchost_register_sdio_callback(sdmmc_host_t *host, void (*sdio_irq_callback)(void *param), void *param);
  346. /**
  347. * @brief Enable or disable SDIO interrupt on the SDMMC host controller.
  348. *
  349. * This function allows controlling the SDIO interrupt signal and status based on the provided flag.
  350. * When enabled, it sets the interrupt signal and status masks to detect card interrupts.
  351. * When disabled, it clears the interrupt status mask to stop interrupt generation from card interrupts.
  352. *
  353. * @param [in] host Pointer to the SDMMC host controller structure.
  354. * @param [in] enable Flag to enable (true) or disable (false) the SDIO interrupt.
  355. */
  356. void sdmmchost_enable_sdio_interrupt(sdmmc_host_t *host, bool enable);
  357. /**
  358. * @brief Return the data pin level
  359. * @param [in] host Pointer to the SDMMC host controller structure.
  360. *
  361. * @return value for data pin level
  362. */
  363. uint32_t sdmmchost_get_data_pin_level(sdmmc_host_t *host);
  364. #ifdef __cplusplus
  365. }
  366. #endif
  367. /**
  368. * @}
  369. */
  370. #endif /* HPM_SDMMC_HOST_H */