• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef HPM_SDXC_DRV_H
9 #define HPM_SDXC_DRV_H
10 
11 /**
12  *
13  * @brief SDXC driver APIs
14  * @defgroup sdxc_interface SDXC driver APIs
15  *  @ingroup sdxc_interfaces
16  * @{
17  *
18  */
19 
20 #include "hpm_common.h"
21 #include "hpm_sdxc_regs.h"
22 #include "hpm_sdxc_soc_drv.h"
23 
24 /**
25  * @brief Generic Definitions
26  * @Note:
27  *  If the Host support 1.8V, it means:
28  *    1. For SD card, it supports:
29  *      - SDR12
30  *      - SDR25
31  *      - SDR50
32  *      - SDR104
33  *      - DDR50
34  *    2. For eMMC, it supports:
35  *      - DDR50
36  *      - HS200
37  *      - HS400 (if 8-bit is supported as well)
38  */
39 #define SDXC_HOST_SUPPORT_1V8       (1UL << 0)  /**< SDXC Host support 1.8v */
40 #define SDXC_HOST_SUPPORT_4BIT      (1UL << 1)  /**< SDXC Host support 4bit */
41 #define SDXC_HOST_SUPPORT_8BIT      (1UL << 2)  /**< SDXC Host support 8bit */
42 #define SDXC_HOST_SUPPORT_EMMC      (1UL << 3)  /**< SDXC Host support EMMC */
43 
44 /**
45  * @brief SDXC Pin features
46  */
47 #define SDXC_HOST_SUPPORT_CD    (1UL << 16)  /**< SDXC Host support Card detection */
48 #define SDXC_HOST_SUPPORT_VSEL  (1UL << 17)  /**< SDXC Host support Voltage Selection */
49 #define SDXC_HOST_SUPPORT_PWR   (1UL << 18) /**< SDXC Host support Power Switch */
50 #define SDXC_HOST_SUPPORT_WP    (1UL << 19) /**< SDXC Host support Write Protection */
51 #define SDXC_HOST_SUPPORT_RST   (1UL << 20) /**< SDXC Host support Reset Pin */
52 #define SDXC_HOST_SUPPORT_DS    (1UL << 21) /**< SDXC Host support Data Strobe */
53 
54 /**
55  * @brief SDXC Pin is native or from GPIO
56  */
57 #define SDXC_HOST_CD_IN_IP      (SDXC_HOST_SUPPORT_CD << 8)         /**< Card detection is controlled by IP */
58 #define SDXC_HOST_VSEL_IN_IP    (SDXC_HOST_SUPPORT_VSEL << 8)       /**< Voltage selection is controlled by IP */
59 #define SDXC_HOST_PWR_IN_IP     (SDXC_HOST_SUPPORT_PWR << 8)        /**< Power switch is controlled by IP */
60 #define SDXC_HOST_WP_IN_IP      (SDXC_HOST_SUPPORT_WP << 8)         /**< Write protection is controlled by IP */
61 #define SDXC_HOST_RST_IN_IP     (SDXC_HOST_SUPPORT_RST << 8)        /**< Reset Pin is controlled by IP */
62 
63 /**
64  * @brief SDXC GPIO pin polarity
65  *  If polarity is 0, it means:
66  *      GPIO level 0 means disabled, 1 means enabled
67  *  If polarity is 1, it meansL:
68  *      GPIO level 0 means enabled, 1 means disabled
69  */
70 #define SDXC_HOST_VSEL_PIN_POLARITY (SDXC_HOST_SUPPORT_CD << 16)
71 #define SDXC_HOST_CD_PIN_POLARITY   (SDXC_HOST_VSEL_IN_IP << 16)
72 #define SDXC_HOST_PWR_PIN_POLARITY  (SDXC_HOST_SUPPORT_PWR << 16)
73 #define SDXC_HOST_WP_PIN_POLARITY   (SDXC_HOST_SUPPORT_WP << 16)
74 #define SDXC_HOST_RST_IN_POLARITY   (SDXC_HOST_SUPPORT_DS << 16)
75 
76 /**
77  * @brief Command Response Type Selection
78  */
79 #define SDXC_CMD_RESP_TYPE_NO_RESP (0U)         /**< No Response */
80 #define SDXC_CMD_RESP_TYPE_RESP_LEN_136 (1U)    /**< Response Length 136 */
81 #define SDXC_CMD_RESP_TYPE_RESP_LEN_48 (2U)     /**< Response Length 48 */
82 #define SDXC_CMD_RESP_TYPE_RESP_LEN_48B (3U)    /**< Response Length 48; Check busy after response */
83 
84 
85 #define SDXC_STS_CMD_ERR (SDXC_INT_STAT_CMD_TOUT_ERR_MASK | SDXC_INT_STAT_CMD_CRC_ERR_MASK |\
86             SDXC_INT_STAT_CMD_END_BIT_ERR_MASK | SDXC_INT_STAT_CMD_IDX_ERR_MASK | SDXC_INT_STAT_AUTO_CMD_ERR_MASK)
87 #define SDXC_STS_DATA_ERR (SDXC_INT_STAT_DATA_TOUT_ERR_MASK | SDXC_INT_STAT_DATA_CRC_ERR_MASK | \
88             SDXC_INT_STAT_DATA_END_BIT_ERR_MASK)
89 #define SDXC_STS_CARD_ERR (SDXC_INT_STAT_CARD_REMOVAL_MASK)
90 #define SDXC_STS_ERROR (SDXC_INT_STAT_ERR_INTERRUPT_MASK | SDXC_STS_CMD_ERR | SDXC_STS_DATA_ERR | SDXC_STS_CARD_ERR)
91 #define SDXC_STS_CMD_FLAGS (SDXC_STS_CMD_ERR | SDXC_INT_STAT_CMD_COMPLETE_MASK)
92 
93 #define SDXC_STS_ALL_FLAGS (SDXC_INT_STAT_ERR_INTERRUPT_MASK | SDXC_INT_STAT_CQE_EVENT_MASK | \
94             SDXC_INT_STAT_FX_EVENT_MASK | SDXC_INT_STAT_RE_TUNE_EVENT_MASK | SDXC_INT_STAT_CARD_INTERRUPT_MASK | \
95             SDXC_INT_STAT_CARD_REMOVAL_MASK | SDXC_INT_STAT_CARD_INSERTION_MASK | SDXC_INT_STAT_BUF_RD_READY_MASK | \
96             SDXC_INT_STAT_BUF_WR_READY_MASK | SDXC_INT_STAT_DMA_INTERRUPT_MASK | SDXC_INT_STAT_BGAP_EVENT_MASK | \
97             SDXC_INT_STAT_XFER_COMPLETE_MASK | SDXC_INT_STAT_CMD_COMPLETE_MASK | SDXC_INT_STAT_BOOT_ACK_ERR_MASK |  \
98             SDXC_INT_STAT_RESP_ERR_MASK | SDXC_INT_STAT_TUNING_ERR_MASK | SDXC_INT_STAT_ADMA_ERR_MASK |   \
99             SDXC_INT_STAT_AUTO_CMD_ERR_MASK | SDXC_INT_STAT_CUR_LMT_ERR_MASK | SDXC_INT_STAT_DATA_END_BIT_ERR_MASK |\
100             SDXC_INT_STAT_DATA_CRC_ERR_MASK | SDXC_INT_STAT_DATA_TOUT_ERR_MASK | SDXC_INT_STAT_CMD_IDX_ERR_MASK |\
101             SDXC_INT_STAT_CMD_END_BIT_ERR_MASK | SDXC_INT_STAT_CMD_CRC_ERR_MASK | SDXC_INT_STAT_CMD_TOUT_ERR_MASK)
102 
103 
104 /**
105  * @brief Software reset flag definitions
106  */
107 typedef enum _sdxc_software_reset {
108     sdxc_reset_all,                 /**< Reset both command line and data line */
109     sdxc_reset_cmd_line,            /**< Reset command line */
110     sdxc_reset_data_line,           /**< Reset data line */
111 } sdxc_sw_reset_type_t;
112 
113 /**
114  * @brief SDXC Bus voltage options
115  */
116 typedef enum _sdxc_bus_voltage_option {
117     sdxc_bus_voltage_sd_1v8 = 0x01U,
118     sdxc_bus_voltage_sd_3v3 = 0x00U,
119     sdxc_bus_voltage_emmc_1v8 = 0x01U,
120     sdxc_bus_voltage_emmc_3v3 = 0x00U,
121 } sdxc_bus_voltage_option_t;
122 
123 /**
124  * @brief SDXC wakeup events
125  */
126 typedef enum _sdxc_wakeup_event {
127     sdxc_wakeup_card_removal = 0x4U,        /**< Wake-up event: Card removal */
128     sdxc_wakeup_card_insert = 0x02U,        /**< Wake-up event: Card insertion */
129     sdxc_wakeup_card_interrupt = 0x01U,     /**< Wake-up event: Card interrupt */
130 } sdxc_wakeup_event_t;
131 
132 /**
133  * @brief SDXC DMA types
134  */
135 typedef enum _sdxc_dma_type {
136     sdxc_dmasel_sdma = 0U,          /**< SDXC DMA type: SDMA */
137     sdxc_dmasel_adma2 = 2U,         /**< SDXC DMA type: ADMA2 */
138     sdxc_dmasel_adma2_or_3 = 3U,    /**< SDXC DMA type: ADMA2 or ADMA3 */
139     sdxc_dmasel_nodma = 0xFU,
140 } sdxc_dma_type_t;
141 
142 /**
143  * @brief SDXC Bus width options
144  */
145 typedef enum _sdxc_bus_width {
146     sdxc_bus_width_1bit,            /**< SDXC bus width: 1 bit */
147     sdxc_bus_width_4bit,            /**< SDXC bus width: 4 bits */
148     sdxc_bus_width_8bit,            /**< SDXC bus width: 8 bits */
149 } sdxc_bus_width_t;
150 
151 /**
152  * @brief SDXC Speed mode options
153  */
154 typedef enum _sdxc_speed_mode {
155     sdxc_sd_speed_sdr12 = 0U,                   /**< SDXC speed: SDR12 */
156     sdxc_sd_speed_sdr25 = 1U,                   /**< SDXC speed: SDR25 */
157     sdxc_sd_speed_sdr50 = 2U,                   /**< SDXC speed: SDR50 */
158     sdxc_sd_speed_sdr104 = 3U,                  /**< SDXC speed: SDR104 */
159     sdxc_sd_speed_ddr50 = 4U,                   /**< SDXC speed: DDR50 */
160     sdxc_sd_speed_normal = sdxc_sd_speed_sdr12, /**< SDXC speed: Normal Speed */
161     sdxc_sd_speed_high = sdxc_sd_speed_sdr25,   /**< SDXC speed: High Speed */
162 
163     sdxc_emmc_speed_legacy = 0U,                /**< SDXC speed: MMC legacy speed */
164     sdxc_emmc_speed_high_speed_sdr = 1U,        /**< SDXC speed: MMC High Speed */
165     sdxc_emmc_speed_hs200 = 3U,                 /**< SDXC speed: MMC HS200 speed */
166     sdxc_emmc_speed_high_speed_ddr = 4U,        /**< SDXC speed: MMC High Speed DDR */
167     sdxc_emmc_speed_hs400 = 7U,                 /**< SDXC speed: MMC HS400 */
168 
169     sdxc_sdmmc_speed_card_init = 0x10,
170 
171 } sdxc_speed_mode_t;
172 
173 /**
174  * @brief SDXC auto command types
175  */
176 typedef enum _sdxc_auto_cmd_sel {
177     sdxc_auto_cmd_disabled = 0U,         /**< Auto Command type: Disabled */
178     sdxc_auto_cmd12_enabled = 1U,        /**< Auto Command type: CMD12 enabled */
179     sdxc_auto_cmd23_enabled = 2U,        /**< Auto Command type: CMD23 enabled */
180     sdxc_auto_cmd_auto_select = 3U,      /**< Auto Command type: Auto selected */
181 } sdxc_auto_cmd_sel_t;
182 
183 /**
184  * @brief SDXC transfer direction options
185  */
186 typedef enum _sdxc_xfer_direction {
187     sdxc_xfer_dir_write = 0,
188     sdxc_xfer_dir_read = 1,
189 } sdxc_xfer_direction_t;
190 
191 /**
192  * @brief SDXC Command types
193  */
194 typedef enum _sdxc_command_type {
195     sdxc_cmd_type_normal_cmd = 0U,
196     sdxc_cmd_type_suspend_cmd = 1U,
197     sdxc_cmd_tye_resume_cmd = 2U,
198     sdxc_cmd_type_abort_cmd = 3U,
199     sdxc_cmd_type_empty = 4U,
200 } sdxc_command_type_t;
201 
202 /**
203  * @brief Command Type
204  */
205 #define SDXC_CMD_TYPE_NORMAL (0UL << SDXC_CMD_XFER_CMD_TYPE_SHIFT)
206 #define SDXC_CMD_TYPE_SUSPEND (1UL << SDXC_CMD_XFER_CMD_TYPE_SHIFT)
207 #define SDXC_CMD_TYPE_RESUME (2UL << SDXC_CMD_XFER_CMD_TYPE_SHIFT)
208 #define SDXC_CMD_TYPE_ABORT (3UL << SDXC_CMD_XFER_CMD_TYPE_SHIFT)
209 
210 /**
211  * @brief SDXC boot mode types
212  */
213 typedef enum _sdxc_boot_mode {
214     sdxc_boot_mode_normal = 0,
215     sdxc_boot_mode_alternative = 1,
216 } sdxc_boot_mode_t;
217 
218 /**
219  * @brief SDXC response types
220  */
221 typedef enum _sdxc_response_type {
222     sdxc_response_type_no_resp = 0,
223     sdxc_response_type_resp_len_136bit = 1,
224     sdxc_response_type_resp_len_48bit = 2,
225     sdxc_response_type_resp_len_48bit_check_busy = 3,
226 } sdxc_response_type_t;
227 
228 #define SDXC_CMD_RESP_NO_RESPONSE (0UL << SDXC_CMD_XFER_RESP_TYPE_SELECT_SHIFT)
229 #define SDXC_CMD_RESP_LEN_136 (1UL << SDXC_CMD_XFER_RESP_TYPE_SELECT_SHIFT)
230 #define SDXC_CMD_RESP_LEN_48 (2UL << SDXC_CMD_XFER_RESP_TYPE_SELECT_SHIFT)
231 #define SDXC_CMD_RESP_LEN_48B (3UL << SDXC_CMD_XFER_RESP_TYPE_SELECT_SHIFT)
232 
233 #define SDXC_CMD_CMD_IS_MAIN_CMD (0U)
234 #define SDXC_CMD_CMD_IS_SUB_CMD (SDXC_CMD_XFER_SUB_CMD_FLAG_MASK)
235 
236 #define SDXC_CMD_CMD_CRC_CHK_EN (SDXC_CMD_XFER_CMD_CRC_CHK_ENABLE_MASK)
237 #define SDXC_CMD_CMD_CRC_CHK_DIS (0U)
238 
239 #define SDXC_CMD_CMD_IDX_CHK_EN (SDXC_CMD_XFER_CMD_IDX_CHK_ENABLE_MASK)
240 #define SDXC_CMD_CMD_IDX_CHK_DIS (0U)
241 
242 #define SDXC_CMD_DATA_PRESENT (SDXC_CMD_XFER_DATA_PRESENT_SEL_MASK)
243 #define SDXC_CMD_DATA_NO_PRESENT (0U)
244 
245 #define SDXC_CMD_CMD_TYPE_NORMAL (0U)
246 #define SDXC_CMD_CMD_TYPE_SUSPEND (1UL << SDXC_CMD_XFER_CMD_TYPE_SHIFT)
247 #define SDXC_CMD_CMD_TYPE_RESUME (2U << SDXC_CMD_XFER_CMD_TYPE_SHIFT)
248 #define SDXC_CMD_CMD_TYPE_ABORT (3U << SDXC_CMD_XFER_CMD_TYPE_SHIFT)
249 
250 /**
251  * @brief SDXC error codes
252  */
253 enum {
254     status_sdxc_busy = MAKE_STATUS(status_group_sdxc, 0),                             /**< SDXC is busy */
255     status_sdxc_error = MAKE_STATUS(status_group_sdxc, 1),                            /**< SDXC error */
256     status_sdxc_send_cmd_failed = MAKE_STATUS(status_group_sdxc, 2),                  /**< SDXC command failed */
257     status_sdxc_cmd_timeout_error = MAKE_STATUS(status_group_sdxc, 3),                /**< SDXC command timed out */
258     status_sdxc_cmd_crc_error = MAKE_STATUS(status_group_sdxc, 4),                    /**< SDXC command CRC error */
259     status_sdxc_cmd_end_bit_error = MAKE_STATUS(status_group_sdxc, 5),                /**< SDXC command end bit error */
260     status_sdxc_cmd_index_error = MAKE_STATUS(status_group_sdxc, 6),                  /**< SDXC command index error */
261     status_sdxc_data_timeout_error = MAKE_STATUS(status_group_sdxc, 7),               /**< SDXC data timeout error */
262     status_sdxc_data_crc_error = MAKE_STATUS(status_group_sdxc, 8),                   /**< SDXC data CRC error */
263     status_sdxc_data_end_bit_error = MAKE_STATUS(status_group_sdxc, 9),               /**< SDXC data end bit error */
264     status_sdxc_auto_cmd_error = MAKE_STATUS(status_group_sdxc, 10),                  /**< SDXC auto command error */
265     status_sdxc_adma_error = MAKE_STATUS(status_group_sdxc, 11),                      /**< SDXC ADMA error */
266     status_sdxc_tuning_error = MAKE_STATUS(status_group_sdxc, 12),                    /**< SDXC tuning error */
267     status_sdxc_response_error = MAKE_STATUS(status_group_sdxc, 13),                  /**< SDXC response error */
268     status_sdxc_boot_ack_error = MAKE_STATUS(status_group_sdxc, 14),                  /**< SDXC boot ack error */
269     status_sdxc_retuning_request = MAKE_STATUS(status_group_sdxc, 15),                /**< SDXC retuning request */
270     /* SDXC Auto CMD12 command not executed */
271     status_sdxc_autocmd_cmd12_not_exec = MAKE_STATUS(status_group_sdxc, 16),
272     status_sdxc_autocmd_cmd_timeout_error = MAKE_STATUS(status_group_sdxc, 17),      /**< SDXC Auto CMD timed out */
273     status_sdxc_autocmd_cmd_crc_error = MAKE_STATUS(status_group_sdxc, 18),          /**< SDXC Auto CMD crc error */
274     status_sdxc_autocmd_end_bit_error = MAKE_STATUS(status_group_sdxc, 19),          /**< SDXC Auto CMD end bit error */
275     status_sdxc_autocmd_cmd_index_error = MAKE_STATUS(status_group_sdxc, 20),        /**< SDXC Auto CMD index error */
276     status_sdxc_autocmd_cmd_response_error = MAKE_STATUS(status_group_sdxc, 21),    /**< SDXC Auto CMD response error */
277     /* SDXC Auto CMD not issued auto CMD12 */
278     status_sdxc_autocmd_cmd_not_issued_auto_cmd12 = MAKE_STATUS(status_group_sdxc, 22),
279     /**< SDXC unsupported operation */
280     status_sdxc_unsupported = MAKE_STATUS(status_group_sdxc, 23),
281     status_sdxc_transfer_data_completed = MAKE_STATUS(status_group_sdxc, 24),       /**< SDXC transfer data completed */
282     status_sdxc_send_cmd_successful = MAKE_STATUS(status_group_sdxc, 25),           /**< SDXC send command succeeded */
283     status_sdxc_transfer_dma_completed = MAKE_STATUS(status_group_sdxc, 26),        /**< SDXC transfer DMA completed */
284     status_sdxc_transfer_data_failed = MAKE_STATUS(status_group_sdxc, 27),          /**< SDXC transfer data failed */
285     status_sdxc_dma_addr_unaligned = MAKE_STATUS(status_group_sdxc, 28),            /**< SDXC DMA address unaligned */
286     status_sdxc_tuning_failed = MAKE_STATUS(status_group_sdxc, 29),                 /**< SDXC tuning failed */
287     status_sdxc_card_removed = MAKE_STATUS(status_group_sdxc, 30),                  /**< SDXC Card removed */
288     status_sdxc_non_recoverable_error = MAKE_STATUS(status_group_sdxc, 30),         /**< SDXC non-recoverable error */
289     status_sdxc_recoverable_error = MAKE_STATUS(status_group_sdxc, 31),             /**< SDXC recoverable error */
290 };
291 
292 /**
293  * @brief SDXC Capacities
294  */
295 typedef struct {
296     union {
297         struct {
298             uint32_t tout_clk_freq: 6;                  /**< Timeout clock frequency */
299             uint32_t : 1;
300             uint32_t tout_clk_unit: 1;                  /**< Timeout clock unit */
301             uint32_t base_clk_freq: 8;                  /**< Base clock frequency */
302             uint32_t max_blk_len: 2;                    /**< Maximum Block length */
303             uint32_t embedded_8_bit_support: 1;         /**< Embedded 8-bit support */
304             uint32_t adma2_support: 1;                  /**< ADMA2 support */
305             uint32_t : 1;
306             uint32_t high_speed_support: 1;             /**< High speed support */
307             uint32_t sdma_support: 1;                   /**< SDMA support */
308             uint32_t suspend_resume_support: 1;         /**< Suspend resume support */
309             uint32_t voltage_3v3_support: 1;            /**< 3.3v support */
310             uint32_t voltage_3v0_support: 1;            /**< 3.0v support */
311             uint32_t voltage_1v8_support: 1;            /**< 1.8v support */
312             uint32_t sys_addr_64_bit_v4_support: 1;     /**< SD Host Version 4 support */
313             uint32_t sys_addr_64_bit_v3_support: 1;     /**< SD Host Version 3 support */
314             uint32_t asysnc_interrupt_support: 1;       /**< Asynchronous interrupt support */
315             uint32_t slot_type_r: 2;                    /**< Slot type */
316         };
317         uint32_t U;
318     } capabilities1;
319 
320     union {
321         struct {
322             uint32_t sdr50_support: 1;                  /**< SDR50 support */
323             uint32_t sdr104_support: 1;                 /**< SDR104 support */
324             uint32_t ddr50_support: 1;                  /**< DDR50 support */
325             uint32_t uhs2_support: 1;                   /**< UHS2 support */
326             uint32_t drv_type_a: 1;                     /**< Drive TypeA support */
327             uint32_t drv_type_c: 1;                     /**< Drive TypeC support */
328             uint32_t drv_type_d: 1;                     /**< Drive TypeD support */
329             uint32_t reserved0: 1;
330             uint32_t retune_cnt: 4;                     /**< Retune count support */
331             uint32_t : 1;
332             uint32_t use_tuning_sdr50: 1;               /**< Use tuning sdr50 support */
333             uint32_t re_tuning_modes: 2;                /**< Retune modes */
334             uint32_t clk_mul: 8;                        /**< Clock multiplier */
335             uint32_t : 3;
336             uint32_t adma3_support: 1;                  /**< ADMA3 support */
337             uint32_t vdd2_1v8_support: 1;               /**< VDD2 1v8 support */
338             uint32_t : 3;
339         };
340         uint32_t U;
341     } capabilities2;
342 
343     union {
344         struct {
345             uint32_t max_current_3v3: 8;            /**< Maximum current at 3.3V */
346             uint32_t max_current_3v0: 8;            /**< Maximum current at 3.0V */
347             uint32_t max_current_1v8: 8;            /**< Maximum current at 1.8V */
348             uint32_t reserved: 8;
349         };
350         uint32_t U;
351     } curr_capabilities1;
352 
353     union {
354         struct {
355             uint32_t max_current_vdd2_1v8: 8;      /**< Maximum current at VDD2 1.8V */
356             uint32_t reserved: 24;
357         };
358         uint32_t U;
359     } curr_capabilities2;
360 
361 } sdxc_capabilities_t;
362 
363 /**
364  * @brief SDXC Device response type
365  */
366 typedef enum _sdxc_dev_resp_type {
367     sdxc_dev_resp_none = 0,
368     sdxc_dev_resp_r1,
369     sdxc_dev_resp_r1b,
370     sdxc_dev_resp_r2,
371     sdxc_dev_resp_r3,
372     sdxc_dev_resp_r4,
373     sdxc_dev_resp_r5,
374     sdxc_dev_resp_r5b,
375     sdxc_dev_resp_r6,
376     sdxc_dev_resp_r7,
377 } sdxc_dev_resp_type_t;
378 
379 /**
380  * @brief SDXC command structure
381  */
382 typedef struct _sdxc_command {
383     uint32_t cmd_index;                     /**< Command index */
384     uint32_t cmd_argument;                  /**< Command argument */
385     uint32_t cmd_flags;                     /**< Command flags */
386     sdxc_command_type_t cmd_type;           /**< Command type */
387     sdxc_dev_resp_type_t resp_type;         /**< Command response type */
388     uint32_t resp_error_flags;              /**< Command response error flags */
389     uint32_t response[4];                   /**< Response buffer */
390     uint32_t auto_cmd_resp;                 /**< Auto command response */
391     uint32_t cmd_timeout_ms;                /**< Command Timeout in ms, 0 - means use default short timeout */
392 } sdxc_command_t;
393 
394 /**
395  * @brief SDXC data list
396  */
397 typedef struct _sdxc_data_list {
398     uint32_t *data_addr;
399     uint32_t data_size;
400     struct _sdxc_data_list *data_list;
401 } sdxc_data_list_t;
402 
403 /**
404  * @brief SDXC data structure
405  */
406 typedef struct _sdxc_data {
407     bool enable_auto_cmd12;
408     bool enable_auto_cmd23;
409     bool enable_ignore_error;
410     uint8_t data_type;
411     uint32_t block_size;
412     uint32_t block_cnt;
413     uint32_t *rx_data;
414     const uint32_t *tx_data;
415 } sdxc_data_t;
416 
417 /**
418  * @brief SDXC transfer data type
419  */
420 enum {
421     sdxc_xfer_data_normal = 0U,         /**< Transfer normal read/write data */
422     sdxc_xfer_data_boot = 1U,           /**< Transfer boot data */
423     sdxc_xfer_data_boot_continuous = 2U, /**< Transfer boot data continuously */
424 };
425 
426 /**
427  * @brief SDXC transfer context
428  */
429 typedef struct _sdxc_xfer {
430     sdxc_data_t *data;
431     sdxc_command_t *command;
432 } sdxc_xfer_t;
433 
434 /**
435  * @brief SDXC ADMA configuration
436  */
437 typedef struct _sdxc_adma_config {
438     sdxc_dma_type_t dma_type;
439     uint32_t *adma_table;
440     uint32_t adma_table_words;
441 } sdxc_adma_config_t;
442 
443 enum {
444     sdxc_adma_desc_single_flag = 0U,
445     sdxc_adma_desc_multi_flag = 1U,
446 };
447 
448 /**
449  * @brief SDXC configuration
450  */
451 typedef struct _sdxc_config {
452     uint32_t data_timeout; /**< Data timeout in milliseconds */
453 } sdxc_config_t;
454 
455 /**
456  * @brief SDXC ADMA2 descriptor
457  */
458 typedef struct _sdxc_adma2_descriptor {
459     union {
460         struct {
461             uint32_t valid: 1;          /**< Valid flag */
462             uint32_t end: 1;            /**< End flag */
463             uint32_t interrupt: 1;      /**< Interrupt flag */
464             uint32_t act: 3;            /**<Act mode */
465             uint32_t len_upper: 10;     /**< Length upper 10-bit */
466             uint32_t len_lower: 16;     /**< Length lower 16-bit */
467         };
468         uint32_t len_attr;
469     };
470     const uint32_t *addr;              /**< Data Address */
471 } sdxc_adma2_descriptor_t;
472 
473 #define SDXC_ADMA2_DESC_VALID_FLAG (1UL << 0)
474 #define SDXC_ADMA2_DESC_END_FLAG (1UL << 1)
475 #define SDXC_ADMA2_DESC_INTERRUPT_FLAG (1UL << 2)
476 #define SDXC_ADMA2_DESC_ACT0_FLAG (1UL << 3)
477 #define SDXC_ADMA2_DESC_ACT1_FLAG (1UL << 4)
478 #define SDXC_ADMA2_DESC_ACT2_FLAG (1UL << 5)
479 
480 #define SDXC_ADMA2_ADDR_LEN (4U)
481 #define SDXC_ADMA2_LEN_ALIGN (4U)
482 
483 #define SDXC_ADMA2_DESC_TYPE_NOP (0U)
484 #define SDXC_ADMA2_DESC_TYPE_TRANS (4U)
485 #define SDXC_ADMA2_DESC_TYPE_LINK (6U)
486 #define SDXC_ADMA3_DESC_TYPE_FOR_SD_MODE (0x1U)
487 #define SDXC_AMDA3_DESC_TYPE_INTEGRATED_LINKER (7U)
488 
489 #define SDXC_ADMA3_CMD_FOR_SD_DESC_ATTR (0x09U)
490 #define SDXC_ADMA3_INTEGRATED_DESC_ATTR (0x39U)
491 
492 #define SDXC_ADMA3_CMD_DESC_IDX_32BIT_BLK_CNT (0U)
493 #define SDXC_ADMA3_CMD_DESC_IDX_BLK_SIZE (1U)
494 #define SDXC_ADMA3_CMD_DESC_IDX_ARG (2U)
495 #define SDXC_ADMA3_CMD_DESC_IDX_CMD_XFER (3U)
496 
497 /**
498  * @brief ADMA3 command descriptor
499  */
500 typedef struct _sdxc_adma3_cmd_sd_desc {
501     struct {
502         uint32_t attr;
503         uint32_t data;
504     } entry[4];
505 } sdxc_adma3_cmd_sd_desc_t;
506 
507 /**
508  * @brief SDXC ADMA3 Integrated Descriptor
509  */
510 typedef struct _sdxc_adma3_integrated_desc {
511     uint32_t attr;
512     sdxc_adma3_cmd_sd_desc_t *cmd_desc_ptr;
513 } sdxc_adma3_integrated_desc_t;
514 
515 /**
516  * @brief SDXC Boot confituration
517  */
518 typedef struct _sdxc_boot_config {
519     uint32_t ack_timeout_cnt;
520     sdxc_boot_mode_t boot_mode;
521     uint32_t block_cnt;
522     uint32_t block_size;
523     bool enable_boot_ack;
524     bool enable_auto_stop_at_block_gap;
525 } sdxc_boot_config_t;
526 
527 typedef struct {
528     void (*card_inserted)(SDXC_Type  *base, void *user_data);
529     void (*card_removed)(SDXC_Type  *base, void *user_data);
530     void (*sdio_interrupt)(SDXC_Type  *base, void *user_data);
531     void (*block_gap)(SDXC_Type  *base, void *user_data);
532     void (*xfer_complete)(SDXC_Type *base, void *user_data);
533 } sdxc_xfer_callback_t;
534 
535 typedef struct {
536     sdxc_data_t *volatile data;
537     sdxc_command_t  *volatile cmd;
538     volatile uint32_t xferred_words;
539     sdxc_xfer_callback_t callback;
540     void *user_data;
541 } sdxc_handle_t;
542 
543 typedef hpm_stat_t (*sdxc_xfer_func_t)(SDXC_Type *base, sdxc_xfer_t *content);
544 
545 typedef struct {
546     SDXC_Type *base;
547     uint32_t src_clk_hz;
548     sdxc_config_t config;
549     sdxc_capabilities_t capability;
550     sdxc_xfer_func_t xfer;
551 } sdxc_host_t;
552 
553 
554 #if defined(__cplusplus)
555 extern "C" {
556 #endif
557 
558 /**
559  * @brief Get the SDXC interrupt status
560  * @param [in] base SDXC base address
561  * @retval SDXC inaterrupt status
562  */
sdxc_get_interrupt_status(SDXC_Type * base)563 static inline uint32_t sdxc_get_interrupt_status(SDXC_Type *base)
564 {
565     return base->INT_STAT;
566 }
567 
568 /**
569  * @brief Check whether SD card is inserted
570  * @retval SD Card instertion status
571  *  @arg true SD Card is inserted
572  *  @arg false SD card is not inserted
573  */
sdxc_is_card_inserted(SDXC_Type * base)574 static inline bool sdxc_is_card_inserted(SDXC_Type *base)
575 {
576     return IS_HPM_BITMASK_SET(base->PSTATE, SDXC_PSTATE_CARD_INSERTED_MASK);
577 }
578 
579 /**
580  * @brief Check whether SD card is Write Protected
581  * @retval SD Card Write Protection status
582  *  @arg true SD Card is Write protected
583  *  @arg false SD card is not Write Protected
584  */
sdxc_is_write_protected(SDXC_Type * base)585 static inline bool sdxc_is_write_protected(SDXC_Type *base)
586 {
587     return IS_HPM_BITMASK_CLR(base->PSTATE, SDXC_PSTATE_WR_PROTECT_SW_LVL_MASK);
588 }
589 
590 /**
591  * @brief Clear SDXC interrupt status
592  * @param [in] base SDXC base address
593  * @param [in] status_mask the status mask to be cleared
594  */
sdxc_clear_interrupt_status(SDXC_Type * base,uint32_t status_mask)595 static inline void sdxc_clear_interrupt_status(SDXC_Type *base, uint32_t status_mask)
596 {
597     base->INT_STAT = status_mask;
598 }
599 
600 /**
601  * @brief Enable SDXC interrupt status
602  * @param [in] base SDXC base address
603  * @param [in] mask SDXC interrupt status mask
604  * @param [in] enable Interrupt status enable flag
605  */
sdxc_enable_interrupt_status(SDXC_Type * base,uint32_t mask,bool enable)606 static inline void sdxc_enable_interrupt_status(SDXC_Type *base, uint32_t mask, bool enable)
607 {
608     if (enable) {
609         base->INT_STAT_EN |= mask;
610     } else {
611         base->INT_STAT_EN &= ~mask;
612     }
613 }
614 
615 /**
616  * @brief Enable SDXC interrupt signal
617  * @param [in] base SDXC base address
618  * @param [in] mask SDXC interrupt signal mask
619  * @param [in] enable Interrupt signal enable flag
620  */
sdxc_enable_interrupt_signal(SDXC_Type * base,uint32_t mask,bool enable)621 static inline void sdxc_enable_interrupt_signal(SDXC_Type *base, uint32_t mask, bool enable)
622 {
623     if (enable) {
624         base->INT_SIGNAL_EN |= mask;
625     } else {
626         base->INT_SIGNAL_EN &= ~mask;
627     }
628 }
629 
630 /**
631  * @brief Get SDXC capabilities
632  * @param [in] base SDXC base address
633  * @param [out] capabilities buffer
634  */
635 hpm_stat_t sdxc_get_capabilities(SDXC_Type *base, sdxc_capabilities_t *capabilities);
636 
637 
638 /**
639  * @brief Get SDXC ADMA error status
640  * @param [in] base SDXC base address
641  * @retval AMDA error status register value
642  */
sdxc_get_adma_error_status(SDXC_Type * base)643 static inline uint8_t sdxc_get_adma_error_status(SDXC_Type *base)
644 {
645     return base->ADMA_ERR_STAT;
646 }
647 
648 /**
649  * @brief Configure SDXC data timeout interal
650  * @param [in] base SDXC base address
651  * @param [in] timeout SDXC data timeout option
652  */
sdxc_configure_data_timeout(SDXC_Type * base,uint8_t timeout)653 static inline void sdxc_configure_data_timeout(SDXC_Type *base, uint8_t timeout)
654 {
655     base->SYS_CTRL = (base->SYS_CTRL & ~SDXC_SYS_CTRL_TOUT_CNT_MASK) | SDXC_SYS_CTRL_TOUT_CNT_SET(timeout);
656 }
657 
658 /**
659  * @brief Configure SDXC interrupt at block gap
660  * @param [in] base SDXC base address
661  * @param [in] enable Enable Interrupt_at_Block_Gap flag
662  */
sdxc_interrupt_at_block_gap(SDXC_Type * base,bool enable)663 static inline void sdxc_interrupt_at_block_gap(SDXC_Type *base, bool enable)
664 {
665     if (enable) {
666         base->PROT_CTRL |= SDXC_PROT_CTRL_INT_AT_BGAP_MASK;
667     } else {
668         base->PROT_CTRL &= ~SDXC_PROT_CTRL_INT_AT_BGAP_MASK;
669     }
670 }
671 
672 /**
673  * @brief Enable or Disable SDXC Read Wait
674  * @param [in] base SDXC base address
675  * @param [in] enable Enable SDXC Read Wait flag
676  */
sdxc_read_wait_control(SDXC_Type * base,bool enable)677 static inline void sdxc_read_wait_control(SDXC_Type *base, bool enable)
678 {
679     if (enable) {
680         base->PROT_CTRL |= SDXC_PROT_CTRL_RD_WAIT_CTRL_MASK;
681     } else {
682         base->PROT_CTRL &= ~SDXC_PROT_CTRL_RD_WAIT_CTRL_MASK;
683     }
684 }
685 
686 /**
687  * @brief Configure SDXC continue request
688  * @param [in] base SDXC base address
689  * @param [in] enable Flag to enable/disable SDXC continue request
690  */
sdxc_continue_request(SDXC_Type * base,bool enable)691 static inline void sdxc_continue_request(SDXC_Type *base, bool enable)
692 {
693     if (enable) {
694         base->PROT_CTRL |= SDXC_PROT_CTRL_CONTINUE_REQ_MASK;
695     } else {
696         base->PROT_CTRL &= ~SDXC_PROT_CTRL_CONTINUE_REQ_MASK;
697     }
698 }
699 
700 /**
701  * @brief Configure SDXC StopAtBlockGap request
702  * @param [in] base SDXC base address
703  * @param [in] enable Flag to enable/disable StopAtBlockGap request
704  */
sdxc_stop_at_block_gap_request(SDXC_Type * base,bool enable)705 static inline void sdxc_stop_at_block_gap_request(SDXC_Type *base, bool enable)
706 {
707     if (enable) {
708         base->PROT_CTRL |= SDXC_PROT_CTRL_STOP_BG_REQ_MASK;
709     } else {
710         base->PROT_CTRL &= ~SDXC_PROT_CTRL_STOP_BG_REQ_MASK;
711     }
712 }
713 
714 /**
715  * @brief Control the SDXC high-speed support
716  * @param [in] base SDXC base address
717  * @param [in] enable flag to Enable/disable SDXC high-speed support
718  */
sdxc_enable_high_speed(SDXC_Type * base,bool enable)719 static inline void sdxc_enable_high_speed(SDXC_Type *base, bool enable)
720 {
721     if (enable) {
722         base->PROT_CTRL |= SDXC_PROT_CTRL_HIGH_SPEED_EN_MASK;
723     } else {
724         base->PROT_CTRL &= ~SDXC_PROT_CTRL_HIGH_SPEED_EN_MASK;
725     }
726 }
727 
728 /**
729  * @brief Control the SDXC power pin
730  *
731  * @param [in] base SDXC base address
732  * @param [in] enable Flas to control the SDXC power pin
733  */
sdxc_enable_power(SDXC_Type * base,bool enable)734 static inline void sdxc_enable_power(SDXC_Type *base, bool enable)
735 {
736     if (enable) {
737         base->PROT_CTRL |= SDXC_PROT_CTRL_SD_BUS_PWR_VDD1_MASK;
738     } else {
739         base->PROT_CTRL &= ~SDXC_PROT_CTRL_SD_BUS_PWR_VDD1_MASK;
740     }
741 }
742 
743 /**
744  * @brief Enable SDXC asynchronous interrupt support
745  * @param [in] base SDXC base address
746  * @param [in] enable Flag to enable/disable SDXC asynchronous interrupt support
747  */
sdxc_enable_async_interrupt(SDXC_Type * base,bool enable)748 static inline void sdxc_enable_async_interrupt(SDXC_Type *base, bool enable)
749 {
750     if (enable) {
751         base->AC_HOST_CTRL |= SDXC_AC_HOST_CTRL_ASYNC_INT_ENABLE_MASK;
752     } else {
753         base->AC_HOST_CTRL &= ~SDXC_AC_HOST_CTRL_ASYNC_INT_ENABLE_MASK;
754     }
755 }
756 
757 /**
758  * @brief Enable SDXC Preset support
759  * @param [in] base SDXC base address
760  * @param [in] enable flag to enable/disable SDXC Preset support
761  */
sdxc_enable_preset(SDXC_Type * base,bool enable)762 static inline void sdxc_enable_preset(SDXC_Type *base, bool enable)
763 {
764     if (enable) {
765         base->AC_HOST_CTRL |= SDXC_AC_HOST_CTRL_PRESET_VAL_ENABLE_MASK;
766     } else {
767         base->AC_HOST_CTRL &= ~SDXC_AC_HOST_CTRL_PRESET_VAL_ENABLE_MASK;
768     }
769 }
770 
771 /**
772  * @brief Enable SD Host version 4
773  * @param [in] base SDXC base address
774  * @param [in] enable flag to enable/disable SD Host version 4 support
775  */
sdxc_enable_host_version4(SDXC_Type * base,bool enable)776 static inline void sdxc_enable_host_version4(SDXC_Type *base, bool enable)
777 {
778     if (enable) {
779         base->AC_HOST_CTRL |= SDXC_AC_HOST_CTRL_HOST_VER4_ENABLE_MASK;
780     } else {
781         base->AC_HOST_CTRL &= ~SDXC_AC_HOST_CTRL_HOST_VER4_ENABLE_MASK;
782     }
783 }
784 
785 /**
786  * @brief Start SDXC tuning process
787  * @param [in] base SDXC base address
788  */
sdxc_execute_tuning(SDXC_Type * base)789 static inline void sdxc_execute_tuning(SDXC_Type *base)
790 {
791     base->AC_HOST_CTRL |= SDXC_AC_HOST_CTRL_EXEC_TUNING_MASK | SDXC_AC_HOST_CTRL_SAMPLE_CLK_SEL_MASK;
792 }
793 
794 /**
795  * @brief Enable SDXC software tuning process
796  * @param [in] base SDXC base address
797  * @param [in] enable flag to enable/disable SDXC software tuning
798  */
sdxc_enable_software_tuning(SDXC_Type * base,bool enable)799 static inline void sdxc_enable_software_tuning(SDXC_Type *base, bool enable)
800 {
801     if (enable) {
802         base->AUTO_TUNING_CTRL |= SDXC_AUTO_TUNING_CTRL_SW_TUNE_EN_MASK;
803     } else {
804         base->AUTO_TUNING_CTRL &= ~SDXC_AUTO_TUNING_CTRL_SW_TUNE_EN_MASK;
805     }
806 }
807 
808 /**
809  * @brief Reset SDXC tuning engine
810  * @param [in] base SDXC base address
811  */
sdxc_reset_tuning_engine(SDXC_Type * base)812 static inline void sdxc_reset_tuning_engine(SDXC_Type *base)
813 {
814     base->AC_HOST_CTRL &= ~SDXC_AC_HOST_CTRL_SAMPLE_CLK_SEL_MASK;
815 }
816 
817 /**
818  * @brief Switch SDXC to 1.8V signaling mode
819  * @param [in] base SDXC base address
820  * @param [in] enable Flag to switch to 1.8v signaling mode/stay at 3.0v signaling mode
821  */
sdxc_switch_to_1v8_signal(SDXC_Type * base,bool enable)822 static inline void sdxc_switch_to_1v8_signal(SDXC_Type *base, bool enable)
823 {
824     if (enable) {
825         base->AC_HOST_CTRL |= SDXC_AC_HOST_CTRL_SIGNALING_EN_MASK;
826     } else {
827         base->AC_HOST_CTRL &= ~SDXC_AC_HOST_CTRL_SIGNALING_EN_MASK;
828     }
829 }
830 
831 /**
832  * @brief Enable/Disable SDXC internal clock
833  * @param[in] base SDXC base address
834  * @param [in] enable Flag to enable/disable SDXC internal clock
835  */
sdxc_enable_internal_clock(SDXC_Type * base,bool enable)836 static inline void sdxc_enable_internal_clock(SDXC_Type *base, bool enable)
837 {
838     if (enable) {
839         base->SYS_CTRL |= SDXC_SYS_CTRL_INTERNAL_CLK_EN_MASK;
840     } else {
841         base->SYS_CTRL &= ~SDXC_SYS_CTRL_INTERNAL_CLK_EN_MASK;
842     }
843 }
844 
845 /**
846  * @brief Get Present status register value
847  * @param [in] base SDXC base address
848  * @retval SDXC PRESENT register value
849  */
sdxc_get_present_status(SDXC_Type * base)850 static inline uint32_t sdxc_get_present_status(SDXC_Type *base)
851 {
852     return base->PSTATE;
853 }
854 
855 /**
856  * @brief Check whether the Data Buffer is writable or not
857  * @param [in] base SDXC base address
858  * @retval true Data buffer is writeable
859  * @retval false Data buffer write is disabled
860  */
sdxc_is_data_buf_writable(SDXC_Type * base)861 static inline bool sdxc_is_data_buf_writable(SDXC_Type *base)
862 {
863     return ((base->PSTATE & SDXC_PSTATE_BUF_WR_ENABLE_MASK) != 0U);
864 }
865 
866 /**
867  * @brief Check whether the data buffer is readable
868  * @param [in] base SDXC base address
869  * @retval true There are data available in data buffer
870  * @retval false there is no data available in data buffer, read is disabled
871  */
sdxc_is_data_buf_readable(SDXC_Type * base)872 static inline bool sdxc_is_data_buf_readable(SDXC_Type *base)
873 {
874     return ((base->PSTATE & SDXC_PSTATE_BUF_RD_ENABLE_MASK) != 0U);
875 }
876 
877 /**
878  * @brief Read data from SDXC using non-DMA mode
879  * @param [in] base SDXC base address
880  * @retval Data read from SDXC
881  */
sdxc_read_data(SDXC_Type * base)882 static inline uint32_t sdxc_read_data(SDXC_Type *base)
883 {
884     return base->BUF_DATA;
885 }
886 
887 /**
888  * @brief Write data to SDXC using non-DMA mode
889  * @param [in] base SDXC base address
890  * @param [in] data Data to be written to SDXC
891  */
sdxc_write_data(SDXC_Type * base,uint32_t data)892 static inline void sdxc_write_data(SDXC_Type *base, uint32_t data)
893 {
894     base->BUF_DATA = data;
895 }
896 
897 /**
898  * @brief Get SDXC DATA3-DATA0 IO level
899  * @param [in] base SDXC base address
900  * @retval SDXC data3-data0 IO level
901  */
sdxc_get_data3_0_level(SDXC_Type * base)902 static inline uint32_t sdxc_get_data3_0_level(SDXC_Type *base)
903 {
904     return SDXC_PSTATE_DAT_3_0_GET(base->PSTATE);
905 }
906 
907 /**
908  * @brief Enable SDXC auto tuning
909  * @param [in] base SDXC base address
910  * @param [in] enable Flag to enable/disable SDXC auto tuning
911  */
sdxc_enable_auto_tuning(SDXC_Type * base,bool enable)912 static inline void sdxc_enable_auto_tuning(SDXC_Type *base, bool enable)
913 {
914     if (enable) {
915         base->AUTO_TUNING_CTRL |= SDXC_AUTO_TUNING_CTRL_AT_EN_MASK;
916     } else {
917         base->AUTO_TUNING_CTRL &= ~SDXC_AUTO_TUNING_CTRL_AT_EN_MASK;
918     }
919 }
920 
921 /**
922  * @brief Stop Clock During Phase Code Change
923  *
924  * @param [in] base SDXC base address
925  * @param [in] enable  Flag to determine whether stopping clock during phase code change
926  */
sdxc_stop_clock_during_phase_code_change(SDXC_Type * base,bool enable)927 static inline void sdxc_stop_clock_during_phase_code_change(SDXC_Type *base, bool enable)
928 {
929     if (enable) {
930         base->AUTO_TUNING_CTRL |= SDXC_AUTO_TUNING_CTRL_TUNE_CLK_STOP_EN_MASK;
931     } else {
932         base->AUTO_TUNING_CTRL &= ~SDXC_AUTO_TUNING_CTRL_TUNE_CLK_STOP_EN_MASK;
933     }
934 }
935 
936 /**
937  * @brief Set The delay cycles during phase switching and stable clock out
938  *
939  * @param [in] base SDXC base address
940  * @param [in] delay_cnt Delay cycles
941  */
sdxc_set_post_change_delay(SDXC_Type * base,uint8_t delay_cnt)942 static inline void sdxc_set_post_change_delay(SDXC_Type *base, uint8_t delay_cnt)
943 {
944     base->AUTO_TUNING_CTRL = (base->AUTO_TUNING_CTRL & ~SDXC_AUTO_TUNING_CTRL_POST_CHANGE_DLY_MASK) \
945  | SDXC_AUTO_TUNING_CTRL_POST_CHANGE_DLY_SET(delay_cnt - 1U);
946 }
947 
948 /**
949  * @brief Enable EMMC support
950  * @param [in] base SDXC base address
951  * @param [in] enable Flag to enable/disable EMMC support
952  */
sdxc_enable_emmc_support(SDXC_Type * base,bool enable)953 static inline void sdxc_enable_emmc_support(SDXC_Type *base, bool enable)
954 {
955     if (enable) {
956         base->EMMC_BOOT_CTRL |= SDXC_EMMC_BOOT_CTRL_CARD_IS_EMMC_MASK;
957     } else {
958         base->EMMC_BOOT_CTRL &= ~SDXC_EMMC_BOOT_CTRL_CARD_IS_EMMC_MASK;
959     }
960 }
961 
962 /**
963  * @brief Enable/Disable SDXC MMC boot
964  * @param [in] base SDXC base address
965  * @param [in] enable FLag to enable/disable SDXC MMC boot
966  */
sdxc_enable_mmc_boot(SDXC_Type * base,bool enable)967 static inline void sdxc_enable_mmc_boot(SDXC_Type *base, bool enable)
968 {
969     if (enable) {
970         base->EMMC_BOOT_CTRL |= SDXC_EMMC_BOOT_CTRL_MAN_BOOT_EN_MASK;
971     } else {
972         base->EMMC_BOOT_CTRL &= ~SDXC_EMMC_BOOT_CTRL_MAN_BOOT_EN_MASK;
973     }
974 }
975 
976 /**
977  * @brief Set SDXC force event
978  * @param [in] base SDXC base address
979  * @param [in] mask SDXC event mask
980  */
sdxc_force_event(SDXC_Type * base,uint32_t mask)981 static inline void sdxc_force_event(SDXC_Type *base, uint32_t mask)
982 {
983     base->FORCE_EVENT = mask;
984 }
985 
986 /**
987  * @brief Enable/disable SDXC SD clock output
988  * @param [in] base SDXC base address
989  * @param [in] enable Flag to enable/disable SDXC SD clock output
990  */
sdxc_enable_sd_clock(SDXC_Type * base,bool enable)991 static inline void sdxc_enable_sd_clock(SDXC_Type *base, bool enable)
992 {
993     if (enable) {
994         base->SYS_CTRL |= SDXC_SYS_CTRL_SD_CLK_EN_MASK;
995         while (!IS_HPM_BITMASK_SET(base->SYS_CTRL, SDXC_SYS_CTRL_SD_CLK_EN_MASK)) {
996         }
997     } else {
998         base->SYS_CTRL &= ~SDXC_SYS_CTRL_SD_CLK_EN_MASK;
999         while (IS_HPM_BITMASK_SET(base->SYS_CTRL, SDXC_SYS_CTRL_SD_CLK_EN_MASK)) {
1000         }
1001     }
1002 }
1003 
1004 /**
1005  * @brief Set SDXC center phase code
1006  * @param [in] base SDXC base address
1007  * @param [in] value SDXC center phase value
1008  */
sdxc_set_center_phase_code(SDXC_Type * base,uint32_t value)1009 static inline void sdxc_set_center_phase_code(SDXC_Type *base, uint32_t value)
1010 {
1011     base->AUTO_TUNING_STAT = (base->AUTO_TUNING_STAT & ~SDXC_AUTO_TUNING_STAT_CENTER_PH_CODE_MASK) |
1012                              SDXC_AUTO_TUNING_STAT_CENTER_PH_CODE_SET(value);
1013 }
1014 
1015 /**
1016  * @brief Enable SDXC enhanced strobe
1017  * @param [in] base SDXC base address
1018  * @param [in] enable flag to enable/disable SSDXC enhanced strobe
1019  */
sdxc_enable_enhanced_strobe(SDXC_Type * base,bool enable)1020 static inline void sdxc_enable_enhanced_strobe(SDXC_Type *base, bool enable)
1021 {
1022     if (enable) {
1023         base->EMMC_BOOT_CTRL |= SDXC_EMMC_BOOT_CTRL_ENH_STROBE_ENABLE_MASK;
1024     } else {
1025         base->EMMC_BOOT_CTRL &= ~SDXC_EMMC_BOOT_CTRL_ENH_STROBE_ENABLE_MASK;
1026     }
1027 }
1028 
1029 /**
1030  * @brief Set MMC boot configuration
1031  * @param [in] base SDXC base address
1032  * @param [in] config MMC boot configuration
1033  */
1034 void sdxc_set_mmc_boot_config(SDXC_Type *base, const sdxc_boot_config_t *config);
1035 
1036 /**
1037  * @brief Send Command via SDXC
1038  * @param [in] base SDXC base address
1039  * @param [in] cmd Command
1040  * @retval status_timeout Sending command timed out
1041  * @retval status_success Command was sent out successfully
1042  */
1043 hpm_stat_t sdxc_send_command(SDXC_Type *base, sdxc_command_t *cmd);
1044 
1045 /**
1046  * @brief Receive command response
1047  * @param [in] base SDXC base address
1048  * @param [in/out] cmd Command
1049  * @return status_success if no error happened
1050  */
1051 hpm_stat_t sdxc_receive_cmd_response(SDXC_Type *base, sdxc_command_t *cmd);
1052 
1053 /**
1054  * @brief Parse the SDXC interrupt status to HPM encoded status
1055  * @param [in] base SDXC base status
1056  * @return status_success if no error happened
1057  */
1058 hpm_stat_t sdxc_parse_interrupt_status(SDXC_Type *base);
1059 
1060 /**
1061  * @brief Wait until SDXC command completes
1062  * @param [in] base SDXC base address
1063  * @param [in] cmd Command
1064  * @param [out] polling_cmd_done flag to determine whether to use blocking wait
1065  * @retval SDXC command execution status
1066  */
1067 hpm_stat_t sdxc_wait_cmd_done(SDXC_Type *base, sdxc_command_t *cmd, bool polling_cmd_done);
1068 
1069 /**
1070  * @brief Set Data transfer configuration
1071  * @param [in] base SDXC base address
1072  * @param [in] data_dir Data transfer direction
1073  * @param [in] block_cnt Block count for data transfer
1074  * @param [in] block_size Block size for data transfer
1075  */
1076 void sdxc_set_data_config(SDXC_Type *base, sdxc_xfer_direction_t data_dir, uint32_t block_cnt, uint32_t block_size);
1077 
1078 /**
1079  * @brief Set ADMA table configuration
1080  * @param [in] base SDXC base address
1081  * @param [in] dma_cfg DMA configuration
1082  * @param [in] data_cfg Data configuration
1083  * @param [in] flags Flags for AMDA transfer
1084  * @retval API execution status
1085  */
1086 hpm_stat_t sdxc_set_adma_table_config(SDXC_Type *base,
1087                                       sdxc_adma_config_t *dma_cfg,
1088                                       sdxc_data_t *data_cfg,
1089                                       uint32_t flags);
1090 
1091 /**
1092  * @brief Set ADMA2 descriptor
1093  * @param [in] adma_tbl ADMA2 table
1094  * @param [in] adma_table_words ADMA2 table size in words
1095  * @param [in] data_buf pointer to the Data to be trnasferred
1096  * @param [in] data_bytes Data size for transfer
1097  * @param [in] flags Flags for ADMA2 descriptor
1098  * @retval API execution status
1099  */
1100 hpm_stat_t sdxc_set_adma2_desc(uint32_t *adma_tbl,
1101                                uint32_t adma_table_words,
1102                                const uint32_t *data_buf,
1103                                uint32_t data_bytes,
1104                                uint32_t flags);
1105 
1106 /**
1107  * @brief Set DMA configuration
1108  * @param [in] base SDXC base address
1109  * @param [in] dma_cfg DMA configuration data structure
1110  * @param [in] data_addr Buffer holds incoming/outgoing data
1111  * @param [in] enable_auto_cmd23 Flag to determine whether to enable auto CMD23 or not
1112  * @retval API execution status
1113  */
1114 hpm_stat_t sdxc_set_dma_config(SDXC_Type *base,
1115                                sdxc_adma_config_t *dma_cfg,
1116                                const uint32_t *data_addr,
1117                                bool enable_auto_cmd23);
1118 
1119 /**
1120  * @brief Initialize SDXC controller
1121  * @param [in] base SDXC base address
1122  * @param [in] config SDXC configuration
1123  */
1124 void sdxc_init(SDXC_Type *base, const sdxc_config_t *config);
1125 
1126 /**
1127  * @brief Set the Data Timeout Counter value for an SD/eMMC device
1128  * @param [in] base SDXC base address
1129  * @param [in] timeout_in_ms Required timeout value in milliseconds, maximum value is 131,072ms
1130  * @param [out] actual_timeout_us Actual timeout in milliseconds, reported by this API
1131  */
1132 void sdxc_set_data_timeout(SDXC_Type *base, uint32_t timeout_in_ms, uint32_t *actual_timeout_ms);
1133 
1134 /**
1135  * @brief Set SDXC speed mode
1136  * @param [in] base SDXC base address
1137  * @param [in] mode SDXC speed mode option
1138  */
1139 void sdxc_set_speed_mode(SDXC_Type *base, sdxc_speed_mode_t mode);
1140 
1141 
1142 /**
1143  * @brief Set SDXC Data bus width
1144  * @param [in] base SDXC base address
1145  * @param [in] width SDXC bus width option
1146  */
1147 void sdxc_set_data_bus_width(SDXC_Type *base, sdxc_bus_width_t width);
1148 
1149 /**
1150  * @brief Get SDXC Data bus width
1151  * @param [in] base SDXC base address
1152  * @return Actual bus width, valid value: 1 / 4 / 8
1153  */
1154 uint32_t sdxc_get_data_bus_width(SDXC_Type *base);
1155 
1156 /**
1157  * @brief Set SDXC IO voltage
1158  * @param [in] base SDXC base address
1159  * @param [option] SDXC voltage option
1160  */
1161 void sdxc_select_voltage(SDXC_Type *base, sdxc_bus_voltage_option_t option);
1162 
1163 /**
1164  * @brief Reset SDXC
1165  * @param [in] base SDXC base address
1166  * @param [in] reset_type SDXC reset type
1167  * @param [in] timeout timeout ticks
1168  * @retval SDXC reset result
1169  */
1170 bool sdxc_reset(SDXC_Type *base, sdxc_sw_reset_type_t reset_type, uint32_t timeout);
1171 
1172 /**
1173  * @brief Enable SDXC wakeup interrupt
1174  * @param [in] base SDXC base address
1175  * @param [in] evt SDXC wakeup interrupt
1176  * @param [in] enable Flag to control whether to enable SDXC wakeup event
1177  */
1178 void sdxc_enable_wakeup_event(SDXC_Type *base, sdxc_wakeup_event_t evt, bool enable);
1179 
1180 /**
1181  * @brief Start SDXC transfer in blocking way
1182  * @param [in] base SDXC base address
1183  * @param [in] dma_config SDXC DMA configuration
1184  * @param [in] xfer SDXC transfer context
1185  * @retval SDXC transfer status
1186  */
1187 hpm_stat_t sdxc_transfer_blocking(SDXC_Type *base, sdxc_adma_config_t *dma_config, sdxc_xfer_t *xfer);
1188 
1189 /**
1190  * @brief Start SDXC transfer in nonblocking way
1191  * @param [in] base SDXC base address
1192  * @param [in] dma_config SDXC DMA configuration
1193  * @param [in] xfer SDXC transfer context
1194  * @retval SDXC transfer status
1195  */
1196 hpm_stat_t sdxc_transfer_nonblocking(SDXC_Type *base, sdxc_adma_config_t *dma_config, sdxc_xfer_t *xfer);
1197 
1198 /**
1199  * @brief SDXC Error recovery
1200  * @param [in] base SDXC base address
1201  * @retval SDXC error recovery status
1202  */
1203 hpm_stat_t sdxc_error_recovery(SDXC_Type *base);
1204 
1205 /**
1206  * @brief Perform SDXC tuning flow sequence
1207  * @param [in] base SDXC base address
1208  * @param [in] tuning_cmd Tuning command
1209  * @retval Tuning status
1210  */
1211 hpm_stat_t sdxc_perform_tuning_flow_sequence(SDXC_Type *base, uint8_t tuning_cmd);
1212 
1213 /**
1214  * @brief Perform SDXC software tuning
1215  * @param [in] base SDXC base address
1216  * @param [in] tuning_cmd Tuning command
1217  * @retval Tuning status
1218  */
1219 hpm_stat_t sdxc_perform_software_tuning(SDXC_Type *base, uint8_t tuning_cmd);
1220 
1221 /**
1222  * @brief Perform SDXC auto tuning
1223  * @param [in] base SDXC base address
1224  * @param [in] tuning_cmd tuning command
1225  * @retval Tuning status
1226  */
1227 hpm_stat_t sdxc_perform_auto_tuning(SDXC_Type *base, uint8_t tuning_cmd);
1228 
1229 #if defined(__cplusplus)
1230 }
1231 #endif
1232 
1233 /**
1234  * @}
1235  */
1236 
1237 #endif /*HPM_SDXC_DRV_H */
1238