• 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_SDMMC_HOST_H
9 #define HPM_SDMMC_HOST_H
10 
11 #include "hpm_common.h"
12 #include "hpm_sdxc_drv.h"
13 #include "hpm_gpio_drv.h"
14 
15 #define HPM_SDMMC_HOST_SUPPORT_4BIT               (1UL << 0)
16 #define HPM_SDMMC_HOST_SUPPORT_8BIT               (1UL << 1)
17 #define HPM_SDMMC_HOST_SUPPORT_3V3                (1UL << 2)
18 #define HPM_SDMMC_HOST_SUPPORT_1V8                (1UL << 3)
19 
20 #define HPM_SDMMC_HOST_SUPPORT_DDR                (1UL << 4)
21 #define HPM_SDMMC_HOST_SUPPORT_SDR50              (1UL << 5)
22 #define HPM_SDMMC_HOST_SUPPORT_SDR104             (1UL << 6)
23 #define HPM_SDMMC_HOST_SUPPORT_HS200              (1UL << 7)
24 #define HPM_SDMMC_HOST_SUPPORT_HS400              (1Ul << 8)
25 
26 #define HPM_SDMMC_HOST_SUPPORT_CARD_DETECTION     (1UL << 16)
27 #define HPM_SDMMC_HOST_SUPPORT_VOLTAGE_SWITCH     (1UL << 17)
28 #define HPM_SDMMC_HOST_SUPPORT_POWER_SWITCH       (1UL << 18)
29 #define HPM_SDMMC_HOST_SUPPORT_WRITE_PROTECTION   (1UL << 19)
30 #define HPM_SDMMC_HOST_SUPPORT_RESET_PIN          (1UL << 20)
31 #define HPM_SDMMC_HOST_SUPPORT_DATA_STROBE        (1UL << 21)
32 
33 #define HPM_SDMMC_HOST_CD_IN_IP                   (HPM_SDMMC_HOST_SUPPORT_CARD_DETECTION << 8)
34 #define HPM_SDMMC_HOST_VSEL_IN_IP                 (HPM_SDMMC_HOST_SUPPORT_VOLTAGE_SWITCH << 8)
35 #define HPM_SDMMC_HOST_PWR_IN_IP                  (HPM_SDMMC_HOST_SUPPORT_POWER_SWITCH << 8)
36 #define HPM_SDMMC_HOST_WP_IN_IP                   (HPM_SDMMC_HOST_SUPPORT_WRITE_PROTECTION << 8)
37 #define HPM_SDMMC_HOST_RST_IN_IP                  (HPM_SDMMC_HOST_SUPPORT_RESET_PIN << 8)
38 
39 
40 /**
41  * @brief SD/MMC Bus Width definitions
42  */
43 typedef enum {
44     sdmmc_bus_width_1bit = 0,   /* Bus width: 1-bit */
45     sdmmc_bus_width_4bit = 1,   /* Bus width: 4-bit */
46     sdmmc_bus_width_8bit = 2,   /* Bus width: 8-bit */
47 } sdmmc_buswidth_t;
48 
49 /**
50  * @brief SD/MMC Device Type definitions
51  */
52 typedef enum {
53     sdmmc_dev_type_emmc = 0,    /* Device type is eMMC */
54     sdmmc_dev_type_sd = 1,      /* Device type is SD */
55     sdmmc_dev_type_sdio = 2,    /* Device type is SDIO */
56 } sdmmc_dev_type_t;
57 
58 /**
59  * @brief SD/MMC Host Card Detection Modes
60  */
61 typedef enum {
62     sdmmc_host_card_detection_none = 0,     /* Card detection is not enabled */
63     sdmmc_host_card_detection_via_gpio = 1, /* Card detection is via GPIO */
64     sdmmc_host_card_detection_via_sdxc = 2, /* Card deteciton is via SDXC CDN pin */
65 } sdmmc_card_detection_mode_t;
66 
67 /**
68  * @brief SDMMC IO Voltage
69  */
70 typedef enum {
71     hpm_sdmmc_io_voltage_3v3 = 0,   /*!< IO voltage is 3.3v */
72     hpm_sdmmc_io_voltage_1v8 = 1,   /*!< IO voltage is 1.8v */
73 } hpm_sdmmc_io_volt_t;
74 
75 /**
76  * @brief SDMMC Operattion 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 /**
86  * @brief SD/MMC Speed definitions
87  */
88 typedef enum {
89     /* SD Card Speed modes */
90     sdmmc_sd_speed_normal = 0,
91     sdmmc_sd_speed_high = 1,
92     sdmmc_sd_speed_sdr12 = sdmmc_sd_speed_normal,
93     sdmmc_sd_speed_sdr25 = sdmmc_sd_speed_high,
94     sdmmc_sd_speed_sdr50 = 2,
95     sdmmc_sd_speed_sdr104 = 3,
96     sdmmc_sd_speed_ddr50 = 4,
97 
98     /* eMMC Card Speed modes */
99     sdmmc_emmc_speed_legacy = 0,
100     sdmmc_emmc_speed_high_speed_sdr = 1,
101     sdmmc_emmc_speed_hs200 = 3,
102     sdmmc_emmc_speed_high_speed_ddr = 4,
103     sdmmc_emmc_speed_hs400 = 7,
104 } sdmmc_speed_mode_t;
105 
106 /**
107  * @brief SDMMC Pin info structure
108  */
109 typedef struct {
110     bool use_gpio;
111     uint8_t polarity;
112     uint16_t gpio_pin;
113 } hpm_sdmmc_pin_info_t;
114 
115 typedef enum {
116     hpm_sdmmc_power_off = 0,    /*!< Power Off the SDMMC */
117     hpm_sdmmc_power_up = 1,     /*!< Power up the SDMMC */
118     hpm_sdmmc_power_on = 2,     /*!< Power on the SDMMC */
119 } hpm_sdmmc_power_option_t;
120 
121 /**
122  * @brief SDMMC extra Pin info
123  */
124 typedef struct {
125     hpm_sdmmc_pin_info_t cd_pin;
126     hpm_sdmmc_pin_info_t vsel_pin;
127     hpm_sdmmc_pin_info_t pwr_pin;
128     hpm_sdmmc_pin_info_t rst_pin;
129     hpm_sdmmc_pin_info_t wp_pin;
130 } hpm_sdmmc_extra_io_data_t;
131 
132 typedef sdxc_xfer_t sdmmchost_xfer_t;
133 typedef sdxc_command_t sdmmchost_cmd_t;
134 typedef sdxc_data_t sdmmchost_data_t;
135 typedef sdxc_adma2_descriptor_t sdmmc_adma2_desc_t;
136 typedef SDXC_Type SDMMCHOST_Type;
137 typedef sdxc_capabilities_t sdmmchost_capabilities_t;
138 
139 typedef uint32_t (*sdmmchost_clock_init_func_t)(SDMMCHOST_Type *base, uint32_t clk_freq, bool need_reverse);
140 
141 typedef void (*sdmmchost_power_switch_func_t)(SDMMCHOST_Type *base, bool on_off);
142 
143 typedef void (*sdmmchost_io_init_func_t)(SDMMCHOST_Type *base);
144 
145 typedef void (*sdmmchost_switch_1v8_io_func_t)(SDMMCHOST_Type *base);
146 
147 typedef void (*sdmmchost_cmd_line_init_func_t)(SDMMCHOST_Type *base, bool push_pull);
148 
149 typedef bool (*sdmmchost_card_detect_func_t)(SDMMCHOST_Type *base);
150 
151 typedef struct {
152 
153     void (*cmd_io_init)(SDMMCHOST_Type *base, bool open_drain, bool is_1v8);
154 
155     void (*clk_data_io_init)(SDMMCHOST_Type *base, uint32_t data_width, bool is_1v8);
156 
157     void (*pwr_io_init)(SDMMCHOST_Type *base, bool as_gpio);
158 
159     void (*cd_io_init)(SDMMCHOST_Type *base, bool as_gpio);
160 
161     void (*vsel_io_init)(SDMMCHOST_Type *base, bool as_gpio);
162 
163     void (*ds_io_init)(SDMMCHOST_Type *base);
164 } sdmmc_io_init_apis_t;
165 
166 
167 typedef struct {
168     uint8_t hart_id;
169     uint8_t instance_num;
170     uint32_t host_flags;
171     SDMMCHOST_Type *base;
172     hpm_sdmmc_extra_io_data_t io_data;
173     sdmmchost_clock_init_func_t clock_init_func;
174     sdmmc_io_init_apis_t io_init_apis;
175 
176     void (*delay_ms)(uint32_t ms);
177 } sdmmc_host_param_t;
178 
179 
180 typedef struct {
181     sdmmc_host_param_t host_param;
182 
183     sdmmc_dev_type_t dev_type;
184     hpm_sdmmc_operation_mode_t operation_mode;
185     sdmmc_buswidth_t bus_width;
186     hpm_sdmmc_io_volt_t io_voltage;
187     uint32_t clock_freq;
188     /* Host Transfer Fields */
189     sdmmchost_xfer_t xfer;
190     sdmmchost_cmd_t cmd;
191     sdmmchost_data_t data;
192     sdmmc_adma2_desc_t adma2_desc;
193     uint32_t buffer[128];
194 
195     /* Host run-time fields */
196     bool card_inserted;
197     bool card_init_done;
198     bool cmd_done_or_error;
199     bool transfer_complete_or_error;
200     uint32_t int_stat;
201     uint32_t auto_cmd_stat;
202     uint32_t adma_error_stat;
203 } sdmmc_host_t;
204 
205 
206 hpm_stat_t sdmmchost_init(sdmmc_host_t *host);
207 
208 void sdmmchost_set_card_bus_width(sdmmc_host_t *host, sdmmc_buswidth_t bus_width);
209 
210 uint32_t sdmmchost_set_card_clock(sdmmc_host_t *host, uint32_t freq, bool clock_inverse);
211 
212 void sdmmchost_deinit(sdmmc_host_t *host);
213 
214 void sdmmchost_reset(sdmmc_host_t *host);
215 
216 void sdmmchost_wait_card_active(sdmmc_host_t *host);
217 
218 hpm_stat_t sdmmchost_send_command(sdmmc_host_t *host, sdmmchost_cmd_t *cmd);
219 
220 hpm_stat_t sdmmchost_transfer(sdmmc_host_t *host, sdmmchost_xfer_t *content);
221 
222 bool sdmmchost_is_card_detected(sdmmc_host_t *host);
223 
224 void sdmmchost_init_io(sdmmc_host_t *host, hpm_sdmmc_operation_mode_t operation_mode);
225 
226 void sdmmchost_delay_ms(sdmmc_host_t *host, uint32_t ms);
227 
228 hpm_stat_t sdmmchost_switch_to_1v8(sdmmc_host_t *host);
229 
230 void sdmmchost_enable_emmc_support(sdmmc_host_t *host, bool enable);
231 
232 hpm_stat_t sdmmchost_set_speed_mode(sdmmc_host_t *host, sdmmc_speed_mode_t speed_mode);
233 
234 hpm_stat_t sdmmchost_error_recovery(sdmmc_host_t *host, sdmmchost_cmd_t *abort_cmd);
235 
236 bool sdmmchost_is_voltage_switch_supported(sdmmc_host_t *host);
237 
238 void sdmmchost_enable_enhanced_data_strobe(sdmmc_host_t *host, bool enable);
239 
240 void sdmmchost_set_data_strobe_delay(sdmmc_host_t *host);
241 
242 void sdmmchost_select_voltage(sdmmc_host_t *host, hpm_sdmmc_io_volt_t io_volt);
243 
244 void sdmmchost_set_cardclk_delay_chain(sdmmc_host_t *host);
245 
246 void sdmmchost_set_rxclk_delay_chain(sdmmc_host_t *host);
247 
248 
249 #endif /* HPM_SDMMC_HOST_H */
250