• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 #ifndef HPM_SDMMC_EMMC_H
8 #define HPM_SDMMC_EMMC_H
9 
10 #include "hpm_sdmmc_common.h"
11 #include "hpm_sdmmc_card.h"
12 #include "hpm_sdmmc_port.h"
13 
14 typedef enum {
15     emmc_switch_cmd_access_mode_command_set = 0,
16     emmc_switch_cmd_access_mode_set_bits = 1,
17     emmc_switch_cmd_access_mode_clear_bits = 2,
18     emmc_switch_cmd_access_mode_write_byte = 3,
19 } emmc_switch_cmd_access_mode_t;
20 
21 typedef union {
22     struct {
23         uint8_t cmd_set;
24         uint8_t value;
25         uint8_t index;
26         uint8_t access;
27     };
28     uint32_t argument;
29 } emmc_switch_cmd_arg_t;
30 
31 
32 #define EMMC_EXT_CSD_INDEX_CMD_SET (191)
33 #define EMMC_EXT_CSD_INDEX_POWER_CLASS (187)
34 #define EMMC_EXT_CSD_INDEX_HS_TIMING (185)
35 #define EMMC_EXT_CSD_INDEX_BUS_WDITH (183)
36 #define EMMC_EXT_CSD_INDEX_PARTITION_CONFIG (179)
37 #define EMMC_EXT_CSD_INDEX_BOOT_CONFIG_PROT (178)
38 #define EMMC_EXT_CSD_INDEX_BOOT_BUS_CONDITIONS (177)
39 #define EMMC_EXT_CSD_INDEX_ERASE_GROUP_DEF (175)
40 #define EMMC_EXT_CSD_INDEX_BOOT_WP (173)
41 #define EMMC_EXT_CSD_INDEX_USER_WP (171)
42 #define EMMC_EXT_CSD_INDEX_FW_CONFIG (169)
43 #define EMMC_EXT_CSD_INDEX_WR_REL_SET (167)
44 #define EMMC_EXT_CSD_INDEX_SANITIZE_START (165)
45 #define EMMC_EXT_CSD_INDEX_BKOPS_START (164)
46 #define EMMC_EXT_CSD_INDEX_BKOPS_EN (163)
47 #define EMMC_EXT_CSD_INDEX_RSTn_FUNCTION (162)
48 #define EMMC_EXT_CSD_INDEX_HPI_MGMT (161)
49 #define EMMC_EXT_CSD_INDEX_PARTITIONS_ATTRIBUTE (156)
50 #define EMMC_EXT_CSD_INDEX_PARTITION_SETTING_COMPLETED (155)
51 #define EMMC_EXT_CSD_INDEX_SEC_BAD_BLK_MGMNT (134)
52 #define EMMC_EXT_CSD_INDEX_PRODUCTION_STATE_AWARENESS (133)
53 #define EMMC_EXT_CSD_INDEX_PERIODIC_WAKEUP (131)
54 #define EMMC_EXT_CSD_INDEX_USE_NATIVE_SECTOR (62)
55 #define EMMC_EXT_CSD_INDEX_CLASS_6_CTRL (59)
56 
57 #define EMMC_EXT_CSD_INDEX_POWER_OFF_NOTIFICATION (34)
58 #define EMMC_EXT_CSD_INDEX_CACHE_CTRL (33)
59 #define EMMC_EXT_CSD_INDEX_FLUSH_CACHE (32)
60 #define EMMC_EXT_CSD_INDEX_BARRIER_CTRL (31)
61 #define EMMC_EXT_CSD_INDEX_MODE_CONFIG (30)
62 #define EMMC_EXT_CSD_INDEX_PRODUCT_STATE_AWARENESS_ENABLEMENT (17)
63 #define EMMC_EXT_CSD_INDEX_SECURE_REMOVAL_TYPE (16)
64 #define EMMC_EXT_CSD_INDEX_CMDQ_MODE_EN (15)
65 
66 typedef union {
67     struct {
68         uint32_t : 7;
69         uint32_t voltage_170_195: 1;
70         uint32_t voltage_200_260: 7;
71         uint32_t voltage_270_360: 9;
72         uint32_t : 5;
73         uint32_t access_mode: 2;
74         uint32_t powerup_status: 1;
75     };
76     uint32_t ocr_word;
77 } emmc_ocr_t;
78 
79 typedef union {
80     struct {
81         uint8_t reserved;
82         uint8_t mdt;        /*!< Manufacturing Date */
83         uint8_t psn[4];     /*!< Product serial number */
84         uint8_t prv;        /*!< Product revision */
85         uint8_t pnm[6];     /*!< Product name */
86         uint8_t oid;        /*!< OEM/Application ID */
87         struct {
88             uint8_t cbx: 2; /*!< Device/BGA */
89             uint8_t bin: 6; /*!< Bank Index Number */
90         };
91         uint8_t mid;       /*!< Manufacturer ID */
92     };
93     uint32_t cid_words[4];
94 } emmc_cid_t;
95 
96 typedef union {
97     struct {
98         uint32_t: 5;                             /*!< Bit[4:0] */
99         uint32_t app_cmd: 1;                     /*!< Bit[5] */
100         uint32_t exception_event: 1;             /*!< Bit[6] */
101         uint32_t switch_error: 1;                /*!< Bit[7] */
102         uint32_t ready_for_data: 1;              /*!< Bit[8] */
103         uint32_t current_state: 4;               /*!< Bit[12:9] */
104         uint32_t erase_reset: 1;                 /*!< Bit[13] */
105         uint32_t : 1;                            /*!< Bit[14] */
106         uint32_t wp_erase_skip: 1;               /*!< Bit[15] */
107         uint32_t cid_or_csd_overwrite: 1;        /*!< Bit[16] */
108         uint32_t : 2;                            /*!< Bit[18:17] */
109         uint32_t error: 1;                       /*!< Bit[19] */
110         uint32_t cc_error: 1;                    /*!< Bit[20] */
111         uint32_t device_ecc_failed: 1;           /*!< Bit[21] */
112         uint32_t illegal_command: 1;             /*!< Bit[22] */
113         uint32_t com_crc_err: 1;                 /*!< Bit[23] */
114         uint32_t lock_unlock_failed: 1;          /*!< Bit[24] */
115         uint32_t device_is_locked: 1;            /*!< Bit[25] */
116         uint32_t wp_violation: 1;                /*!< Bit[26] */
117         uint32_t erase_param: 1;                 /*!< Bit[27] */
118         uint32_t erase_seq_error: 1;             /*!< Bit[28] */
119         uint32_t block_len_error: 1;             /*!< Bit[29] */
120         uint32_t address_error: 1;               /*!< Bit[30] */
121         uint32_t out_of_range: 1;                /*!< Bit[31] */
122     };
123     uint32_t card_status;
124 } emmc_card_status_t;
125 
126 typedef enum {
127     emmc_csd_vdd_current_min_0_5ma,
128     emmc_csd_vdd_current_min_1ma,
129     emmc_csd_vdd_current_min_5ma,
130     emmc_csd_vdd_current_min_10ma,
131     emmc_csd_vdd_current_min_25ma,
132     emmc_csd_vdd_current_min_35ma,
133     emmc_csd_vdd_current_min_60ma,
134     emmc_csd_vdd_current_min_100ma,
135 } emmc_csd_vdd_current_min_t;
136 
137 typedef enum {
138     emmc_csd_vdd_current_max_1ma,
139     emmc_csd_vdd_current_max_5ma,
140     emmc_csd_vdd_current_max_10ma,
141     emmc_csd_vdd_current_max_25ma,
142     emmc_csd_vdd_current_max_35ma,
143     emmc_csd_vdd_current_max_45ma,
144     emmc_csd_vdd_current_max_80ma,
145     emmc_csd_vdd_current_max_200ma,
146 } emmc_csd_vdd_current_max_t;
147 
148 typedef enum vdd_current_min_def {
149     vdd_current_min_0_5ma,
150     vdd_current_min_1ma,
151     vdd_current_min_5ma,
152     vdd_current_min_10ma,
153     vdd_current_min_25ma,
154     vdd_current_min_35ma,
155     vdd_current_min_60ma,
156     vdd_current_min_100ma,
157 } vdd_current_min_t;
158 
159 typedef enum vdd_current_max_def {
160     vdd_current_max_1ma,
161     vdd_current_max_5ma,
162     vdd_current_max_10ma,
163     vdd_current_max_25ma,
164     vdd_current_max_35ma,
165     vdd_current_max_45ma,
166     vdd_current_max_80ma,
167     vdd_current_max_200ma,
168 } vdd_current_max_t;
169 
170 typedef enum {
171     emmc_csd_file_format_hard_disk_like_file_system_with_partition_table,
172     emmc_csd_file_format_dos_fat_with_boot_sector_only,
173     emmc_csd_file_format_universal_file_format,
174     emmc_csd_file_format_others_or_unknown
175 } emmc_csd_file_format_t;
176 
177 typedef struct {
178     uint8_t csd_structure;
179     uint8_t spec_version;
180     uint16_t nsac_cycles;
181     uint32_t taac_ns;
182     bool support_read_block_partial;
183     bool support_write_block_misalignment;
184     bool support_read_block_misalignment;
185     bool is_dsr_implemented;
186     bool support_content_protect_app;
187     bool is_write_protection_group_enabled;
188     bool support_write_block_partial;
189     bool is_predefined_file_format;
190     bool support_copy;
191     bool support_permanent_write_protect;
192     bool support_temporary_write_protect;
193     uint8_t file_format;
194 
195     uint16_t card_command_class;
196     uint8_t write_speed_factor;
197     emmc_csd_vdd_current_min_t read_current_vdd_min;
198     emmc_csd_vdd_current_max_t read_current_vdd_max;
199     emmc_csd_vdd_current_min_t write_current_vdd_min;
200     emmc_csd_vdd_current_max_t write_current_vdd_max;
201     uint8_t ecc_type;
202 
203 
204     uint32_t sector_size;
205     uint32_t erase_group_size;
206     uint32_t max_read_block_len;
207     uint32_t max_write_block_len;
208     uint32_t write_protect_group_size;
209     uint32_t max_freq;
210     uint64_t device_size_in_bytes;
211 
212 } emmc_csd_t;
213 
214 typedef union {
215     uint8_t device_type;
216     struct {
217         uint8_t support_high_speed_sdr_at_26mhz: 1;
218         uint8_t support_high_speed_sdr_at_52mhz: 1;
219         uint8_t support_high_speed_ddr_at_52mhz_1v8_or_3v: 1;
220         uint8_t support_high_speed_ddr_at_52mhz_1v2: 1;
221         uint8_t support_hs200_at_200mhz_1v8: 1;
222         uint8_t support_hs200_at_200mhz_1v2: 1;
223         uint8_t support_hs400_at_200mhz_1v8: 1;
224         uint8_t support_hs400_at_200mhz_1v2: 1;
225     };
226 } emmc_device_type_t;
227 
228 #pragma pack(1)
229 
230 typedef struct {
231     /*
232      * Mode segment
233      */
234     uint8_t reserved0[15];                              /*!< [14:0] */
235     uint8_t command_queue_mode_enable;                  /*!< [15] */
236     uint8_t secure_removal_type;                        /*!< [16] */
237     uint8_t product_state_awareness_enablement;         /*!< [17] */
238     uint8_t max_pre_loading_data_size[4];               /*!< [21:18] */
239     uint8_t pre_loading_data_size[4];                   /*!< [25:22] */
240     uint8_t ffu_status;                                 /*!< [26] */
241     uint8_t reserved1[2];                               /*!< [28:27] */
242     uint8_t mode_operation_codes;                       /*!< [29] */
243     uint8_t mode_config;                                /*!< [30] */
244     uint8_t barrier_control;                            /*!< [31] */
245     uint8_t flush_cache;                                /*!< [32] */
246     uint8_t cache_control;                              /*!< [33] */
247     uint8_t power_off_notification;                     /*!< [34] */
248     uint8_t packed_command_failure_index;               /*!< [35] */
249     uint8_t packed_command_status;                      /*!< [36] */
250     uint8_t context_config[15];                         /*!< [51:37] */
251     uint8_t extended_partitions_attribute[2];           /*!< [53:52] */
252     uint8_t exception_events_status[2];                 /*!< [55:54] */
253     uint8_t exception_events_control[2];                /*!< [57:56] */
254     uint8_t dyncap_needed;                              /*!< [58] */
255     uint8_t class6_commands_control;                    /*!< [59] */
256     uint8_t init_timeout_after_disabling_emulation;     /*!< [60] 100ms *  init_timeout_after_disabling_emulation */
257     uint8_t data_sector_size;                           /*!< [61]  0 - 512Bytes, 1 - 4KB */
258     uint8_t sector_size_emulation;                      /*!< [62] */
259     uint8_t native_sector_size;                         /*!< [63] 0 - 512Bytes, 1 - 4KB */
260     uint8_t vendor_specific_field[64];                  /*!< [127:64] */
261     uint8_t reserved02[2];                              /*!< [129:128] */
262     uint8_t program_cid_or_csd_in_ddr_mode_supported;   /*!< [130] */
263     uint8_t periodic_wakeup;                            /*!< [131] */
264     uint8_t tcase_support;                              /*!< [132] */
265     uint8_t production_state_awareness;                 /*!< [133] */
266     uint8_t bad_block_management_mode;                  /*!< [134] */
267     uint8_t reserved03;                                 /*!< [135] */
268     uint32_t enhanced_user_data_start_address;          /*!< [139:136] */
269     uint8_t enhanced_user_data_area_size[3];            /*!< [142:140] 512KB * enhanced_user_data_area_size * high_capacity_erase_unit_size */
270     uint8_t general_purpose_partition_size[4][3];       /*!< [154:143] */
271     uint8_t partitioning_setting;                       /*!< [155] */
272     uint8_t partitioning_attribute;                     /*!< [156] */
273     uint8_t max_enh_size_mult[3];                       /*!< [159:157] */
274     uint8_t partitioning_support;                       /*!< [160] */
275     uint8_t hw_reset_function;                          /*!< [161] */
276     uint8_t hpi_management;                             /*!< [162] */
277     uint8_t bkops_en;                                   /*!< [163] */
278     uint8_t bkops_start;                                /*!< [164] */
279     uint8_t sanitize_start;                             /*!< [165] */
280     uint8_t write_reliability_parameter;                /*!< [166] */
281     uint8_t write_reliability_setting;                  /*!< [167]  bit0-user area, bit[4:1] general purpose partition 4-1 */
282     uint8_t rpmb_size;                                  /*!< [168] 128KB * rpmb_size */
283     uint8_t fw_config;                                  /*!< [169] */
284     uint8_t reserved04;                                 /*!< [170] */
285     /* bit0 - US_PWR_WP_EN, bit2 - US_PERM_WP_EN, bit3 - US_PWR_WP_DIS, bit4 - US_PERM_WP_DIS
286      * bit6 - CD_PERM_WP_DIS, bit7 - PERM_PSWD_DIS
287      */
288     uint8_t user_wp;                                    /*!< [171] */
289     uint8_t reserved05;                                 /*!< [172] */
290     /* bit0 - B_PWR_WP_EN, bit1 - B_PWR_WP_SEC_SEL, bit2 - B_PERM_WP_EN, bit3 - B_PERM_WP_SEC_SEL
291      * bit4 - B_PERM_WP_DIS, bit6 - B_PWR_WP_DIS, bit7 - B_SEC_WP_SEL
292      *
293      */
294     uint8_t boot_wp;                                    /*!< [173] */
295     uint8_t boot_wp_status;                             /*!< [174] bit[1:0] B_AREA_1_WP, bit[3:2] B_AREA_2_WP */
296     uint8_t erase_group_def;                            /*!< [175] 0 - old group size, 1 - high-capacity erase unit size */
297     uint8_t reserved06;                                 /*!< [176] */
298     /* bit[1:0] BOOT_BUS_WIDTH
299      *  0 - x1 SDR or x4 DDR  in boot operation mode, 1 - X4 (SDR/DDR) bus width in boot operation mode
300      *  2 - x8 (SDR/DDR) bus width in boot operation mode
301      * bit2 RESET_BOOT_BUS_CONDITIONS
302      *  0 - Reset bus width to x1
303      *  1 - Retain BOOT_BUS_WIDTH and BOOT_MODE values after boot operation
304      * bit[4:3] BOOT_MODE
305      *  0 - SDR @ normal speed timing, 1 - SDR @ High Speed timing, 2 - DDR
306      *
307      */
308     uint8_t boot_bus_conditions;                    /*!< [177] */
309     /* bit0 - PWR_BOOT_CONFIG_PROT
310      * bit4 - PERM_BOOT_CONFIG_PROT
311      */
312     uint8_t boot_config_prot;                       /*!< [178] */
313     /* bit[2:0] PARTITION_ACCESS
314      *  0 - No access to boot partition, 1 - R/W boot partition 1, 2 - R/W boot partition 2
315      *  3 - R/W RPMB, 4 - Access to General Purpose partition 1, 5 - Access to General Purpose partition 2
316      *  6 - Access to General Purpose partition 3, 7 - Access to General partition 4
317      * bit[5:3] BOOT_PARTITION_ENABLE
318      *  0 - Device not boot enabled, 1 - Boot partition 1 enabled for boot, 2 - boot partition 2 enabled for boot
319      *  7 - User area enabled for boot
320      * bit[6] BOOT_ACK
321      */
322     uint8_t partition_config;                   /*!< [179] */
323     uint8_t reserved07;                         /*!< [180] */
324     uint8_t erased_mem_content;                 /*!< [181] 0 - Read as all 0x00s for erased region, 1 - read as all 0xffs for erased region  */
325     uint8_t reserved08;                         /*!< [182] */
326     /* bit[3:0] bus mode selection: 0-1bit data bus, 1 - 4bit data bus, 2 - 8bit data bus,
327      *                              5- 4bit data bus @DDR mode, 6 - 8bit data bus @DDR mode
328      * bit7 Enhanced Strobe
329      */
330     uint8_t bus_width;                          /*!< [183] */
331     uint8_t strobe_support;                     /*!< [184] 0 - no support for enhanced strobe mode, 1 - supports enhanced strobe mode */
332     /* bit[3:0] timing interface: 0 - normal, 1 - high speed, 2 - HS200, 3 - HS400
333      * bit[7:4] selected driver strength
334      */
335     uint8_t hs_timing;                          /*!< [185] */
336     uint8_t reserved09;                         /*!< [186] */
337     uint8_t power_class;                        /*!< [187] */
338     uint8_t reserved10;                         /*!< [188] */
339     uint8_t cmd_set_revision;                   /*!< [189] 0 - v4.0 */
340     uint8_t reserved11;                         /*!< [190] */
341     uint8_t cmd_set;                            /*!< [191] */
342     /*
343      * Properties Segment
344      */
345     uint8_t ext_csd_rev;                        /*!< [192] 0-4.0, 1-4.1, 2-4.2, 3-4.3, 5-4.41, 6-4.51, 7-5.01, 8-5.1 */
346     uint8_t reserved12;                         /*!< [193] */
347     uint8_t csd_structure;                      /*!< [194] 0 - CSD 1.0, 1 - CSD 1.1, 2 - CSD 1.2 */
348     uint8_t reserved13;                         /*!< [195] */
349     /*
350      * bit0 - HS @ 26MHz, bit1 - HS @ 52MHz, bit2 - HS DDR @52MHz, 1.8V or 3V
351      * bit3 - HS DDR @ 52Mhz, 12.V, bit4 - HS200 SDR @200MHz, 1.8V, bit5 - HS200 SDR @200MHz, 1.2V
352      * bit6 - HS400 DDR @ 1.8V, bit7 - HS400 DDR  @ 1.2V
353      */
354     uint8_t device_type;                        /*!< [196] */
355     uint8_t driver_strength;                    /*!< [197] bit0 - type 0, bit1 - type 1, bit2 - type 2, bit3 - type 3, bit4 - type 4 */
356     uint8_t out_of_interrupt_timing;            /*!< [198] 10ms * out_of_interrupt_timing */
357     uint8_t partition_switch_timing;            /*!< [199] 10ms * partition_switch_timing */
358     uint8_t pwr_cl_52_195;                      /*!< [200] */
359     uint8_t pwr_cl_26_195;                      /*!< [201] */
360     uint8_t pwr_cl_52_360;                      /*!< [202] */
361     uint8_t pwr_cl_26_360;                      /*!< [203] */
362     uint8_t reserved14;                         /*!< [204] */
363     uint8_t min_perf_r_4_26;                    /*!< [205] SDR mode : 150kB/S * value, DDR mode = 300kB/s * value * 2 */
364     uint8_t ming_perf_w_4_26;                   /*!< [206] SDR mode : 150kB/S * value, DDR mode = 300kB/s * value * 2 */
365     uint8_t min_perf_r_8_26_4_52;               /*!< [207] SDR mode : 150kB/S * value, DDR mode = 300kB/s * value * 2 */
366     uint8_t min_perf_w_8_26_4_52;               /*!< [208] SDR mode : 150kB/S * value, DDR mode = 300kB/s * value * 2 */
367     uint8_t min_perf_r_8_52;                    /*!< [209] SDR mode : 150kB/S * value, DDR mode = 300kB/s * value * 2 */
368     uint8_t min_perf_w_8_52;                    /*!< [210] SDR mode : 150kB/S * value, DDR mode = 300kB/s * value * 2 */
369     uint8_t secure_wp_info;                     /*!< [211] bit0-SECURE_WP_SUPPORT, bit1-SECURE_WP_EN_STATUS */
370     uint32_t sector_count;                      /*!< [215:212] Device density = sector_count * 512Bytes */
371     uint8_t sleep_notification_timeout;         /*!< [216] 10us * 2 ^ sleep_notification_timeout */
372     uint8_t sleep_or_awake_timeout;             /*!< [217] 100ns * 2^sleep_or_awake_timeout */
373     uint8_t production_state_awareness_timeout; /*!< [218] 100us * 2 ^ production_state_awareness_timeout */
374     uint8_t sleep_current_vccq;                 /*!< [219] 1uA * 2 ^ sleep_current_vccq */
375     uint8_t sleep_current_vcc;                  /*!< [220] 1uA * 2 ^ sleep_current_vcc */
376     /* 512KB * high_capacity_erase_unit_size * high_capacity_write_protect_group_size */
377     uint8_t high_capacity_write_protect_group_size; /*!< [221] */
378     uint8_t reliable_write_sector_count;        /* !< [222] shall be set to 1 */
379     uint8_t erase_timeout_mult;                 /*!< [223] 300ms * erase_timeout_mult */
380     uint8_t high_capacity_erase_unit_size;      /*!< [224] 512KB * high_capacity_erase_unit_size */
381     uint8_t access_size;                        /*!< [225] bit[3:0] - SUPER_PAGE_SIZE = 512 * 2 ^ (SUPER_PAGE_SIZE - 1) */
382     uint8_t boot_partition_size_mult;           /*!< [226] 128KB * boot_partition_size_mult */
383     uint8_t reserved15;                         /*!< [227] */
384     uint8_t boot_info;                          /*!< [228] bit0-ALT_BOOT_MODE, bit1-DDR_BOOT_MODE, bit2-HS_BOOT_MODE */
385     uint8_t secure_trim_mult;                   /*!< [229] 300ms * secure_trim_mult */
386     uint8_t secure_erase_mult;                  /*!< [230] 300ms * secure_erase_mult */
387     uint8_t secure_feature_support;             /*!< [231] bit0-SECURE_ER_EN, bitt2-SEC_BD_BLK_EN, bit4-SEC_GB_CL_EN, bit6-SEC_SANITIZE */
388     uint8_t trim_mult;                          /*!< [232] 300ms * trim_mult */
389     uint8_t reserved16;                         /*!< [233] */
390     uint8_t min_perf_ddr_r_8_52;                /*!< [234] */
391     uint8_t min_perf_ddr_w_8_52;                /*!< [235] */
392     uint8_t pwr_cl_200_130;                     /*!< [236] */
393     uint8_t pwr_cl_200_195;                     /*!< [237] */
394     uint8_t pwr_cl_ddr_52_195;                  /*!< [238] */
395     uint8_t pwr_cl_ddr_52_360;                  /*!< [239] */
396     uint8_t cache_flush_policy;                 /*!< [240] 0 - none, 1 - FIFO policy */
397     uint8_t init_timeout_after_partitioning;    /*!< [241] 100ms * init_timeout_after_partitioning */
398     uint32_t number_of_correctly_programmed_sectors; /*!< [245:242] */
399     uint8_t bkops_status;                       /*!< [246] bit[1:0] 0:no operations required, 1:non-critical, 2:lower performance, 3:critical */
400     uint8_t power_off_long_timeout;             /*!< [247] 10ms * power_off_long_timeout */
401     uint8_t generic_cmd6_timeout;               /*!< [248] 10ms * generic_cmd6_timeout */
402     uint32_t cache_size;                        /*!< [252:249] cache_size * 1kb */
403     uint8_t pwr_cl_ddr_200_360;                 /*!< [253] */
404     uint8_t firmware_version[8];                /*!< [261:254] */
405     uint8_t device_version[2];                  /*!< [263:262] */
406     uint8_t optimal_trim_unit_size;             /*!< [264] 4KB * 2 ^(optmial_trim_unit_size - 1) */
407     uint8_t optimal_write_size;                 /*!< [265] 4KB * optimal_write_size */
408     uint8_t optimal_read_size;                  /*!< [266] 4KB * optimal_read_size */
409     uint8_t pre_eol_info;                       /*!< [267] 1-Normal, 2-Warning, 3-Urgent */
410     uint8_t device_lifetime_estimation_type_a;  /*!< [268] */
411     uint8_t device_lifetime_estimation_type_b;  /*!< [269] */
412     uint8_t vendor_proprietary_health_report[32];/*!< [301:270] */
413     uint32_t number_of_correctly_programmed_fw_sectors; /*!< [305:302] */
414     uint8_t reserved17;                         /*!< [306] */
415     uint8_t cmdq_depth;                         /*!< [307] bit[4:0] N, depth = N+1 */
416     uint8_t cmdq_support;                       /*!< [308] 1 - supported, others - not supported */
417     uint8_t reserved18[177];                    /*!< [485:309] */
418     uint8_t barrier_support;                    /*!< [486] */
419     uint8_t ffu_arg[4];                         /*!< [490:487] */
420     uint8_t operation_code_timeout;             /*!< [491] 100us * 2 ^ operation_code_timeout */
421     uint8_t ffu_features;                       /*!< [492] 0 - device does not support mode_operation_codes */
422     uint8_t supported_modes;                    /*!< [493] bit0 - FFU, 0:not supported, 1:supported, bit1 Vendor Specific Mode, 0:not supported  */
423     uint8_t extended_partitions_attribute_support; /*!< [494] bit0 system code, bit1 non-persistent */
424     uint8_t large_unit_size;                    /*!< [495] 1MB * large_unit_size */
425     uint8_t context_capabilities;               /*!< [496] bit[3:0] max_context_id, bit[6:4] maximum large_unit_size */
426     uint8_t tag_resource_size;                  /*!< [497] [n * tag_unit_size) * 2 ^tag_resource_size] / 1024 */
427     uint8_t tag_unit_size;                      /*!< [498] 2^tag_unit_size * sector_size */
428     uint8_t data_tag_support;                   /*!< [499] */
429     uint8_t max_packed_writes;                  /*!< [500] minimum value: 3 */
430     uint8_t max_packed_reads;                   /*!< [501] minimum value:5 */
431     uint8_t bkops_support;                      /*!< [502] */
432     uint8_t hpi_features;                       /*!< [503] */
433     uint8_t supported_cmd_sets;                 /*!< [504] */
434     uint8_t extended_security_error;            /*!< [505] */
435     uint8_t reserved19[6];                      /*!< [511:506] */
436 
437 } emmc_ext_csd_t;
438 
439 #pragma pack()
440 
441 typedef enum _emmc_partition {
442     emmc_partition_boot_area_1 = 0,
443     emmc_partition_boot_area_2 = 1,
444     emmc_partition_rpmb = 2,
445     emmc_partition_user_data = 3,
446 } emmc_partition_t;
447 
448 typedef enum _emmc_hs_timing {
449     emmc_timing_legacy = 0,
450     emmc_timing_high_speed = 1,
451     emmc_timing_hs200 = 2,
452     emmc_timing_hs400 = 3,
453     emmc_timing_high_speed_ddr = 4,
454 } emmc_hs_timing_t;
455 
456 typedef enum {
457     emmc_power_3v6_max_rms_100ma_peak_200ma = 0,
458     emmc_power_3v6_max_rms_120ma_peak_220ma = 1,
459     emmc_power_3v6_max_rms_150ma_peak_250ma = 2,
460     emmc_power_3v6_max_rms_180ma_peak_280ma = 3,
461     emmc_power_3v6_max_rms_200ma_peak_300ma = 4,
462     emmc_power_3v6_max_rms_220ma_peak_320ma = 5,
463     emmc_power_3v6_max_rms_250ma_peak_350ma = 6,
464     emmc_power_3v6_max_rms_300ma_peak_400ma = 7,
465     emmc_power_3v6_max_rms_350ma_peak_450ma = 8,
466     emmc_power_3v6_max_rms_400ma_peak_500ma = 9,
467     emmc_power_3v6_max_rms_450ma_peak_550ma = 10,
468     emmc_power_3v6_max_rms_500ma_peak_600ma = 11,
469     emmc_power_3v6_max_rms_600ma_peak_700ma = 12,
470     emmc_power_3v6_max_rms_700ma_peak_800ma = 13,
471     emmc_power_3v6_max_rms_800ma_peak_900ma = 14,
472     emmc_power_3v6_max_rms_gt800ma_peak_gt900ma = 15,
473 } emmc_power_class_3v6_t;
474 
475 typedef enum {
476     emmc_power_1v95_max_rms_65ma_peak_130ma = 0,
477     emmc_power_1v95_max_rms_70ma_peak_140ma = 1,
478     emmc_power_1v95_max_rms_80ma_peak_160ma = 2,
479     emmc_power_1v95_max_rms_90ma_peak_180ma = 3,
480     emmc_power_1v95_max_rms_100ma_peak_200ma = 4,
481     emmc_power_1v95_max_rms_120ma_peak_220ma = 5,
482     emmc_power_1v95_max_rms_140ma_peak_240ma = 6,
483     emmc_power_1v95_max_rms_160ma_peak_260ma = 7,
484     emmc_power_1v95_max_rms_180ma_peak_280ma = 8,
485     emmc_power_1v95_max_rms_200ma_peak_300ma = 9,
486     emmc_power_1v95_max_rms_250ma_peak_350ma = 10,
487     emmc_power_1v95_max_rms_300ma_peak_400ma = 11,
488     emmc_power_1v95_max_rms_350ma_peak_450ma = 12,
489     emmc_power_1v95_max_rms_400ma_peak_500ma = 13,
490     emmc_power_1v95_max_rms_500ma_peak_600ma = 14,
491     emmc_power_1v95_max_rms_gt500ma_peak_gt600ma = 15,
492 } emmc_power_class_1v95_t;
493 
494 typedef union {
495     emmc_power_class_3v6_t power_class_3v6;
496     emmc_power_class_1v95_t power_class_1v95;
497 } emmc_power_class_t;
498 
499 typedef enum {
500     emmc_bus_mode_x1_sdr = 0,
501     emmc_bus_mode_x4_sdr = 1,
502     emmc_bus_mode_x8_sdr = 2,
503     emmc_bus_mode_x4_ddr = 5,
504     emmc_bus_mode_x8_ddr = 6,
505     emmc_bus_mode_x8_ddr_ds = 0x86,
506 } emmc_bus_mode_t;
507 
508 typedef enum {
509     emmc_write_protection_mode_legacy = 0,
510     emmc_write_protection_mode_secure = 1,
511 } emmc_write_protection_mode_t;
512 
513 typedef struct {
514     bool is_alt_boot_mode_supported;
515     bool is_ddr_boot_mode_supported;
516     bool is_hs_boot_mode_supported;
517     uint8_t reserved;
518 } boot_info_t;
519 
520 typedef struct {
521     bool is_secure_erase_supported;
522     bool is_secure_bad_block_management_supported;
523     bool is_secure_insecure_trim_supported;
524     bool is_secure_sanitize_supported;
525 } secure_feature_info_t;
526 
527 typedef enum {
528     emmc_boot_partition_mode_not_enabled = 0,
529     emmc_boot_partition_mode_boot_partition1 = 1,
530     emmc_boot_partition_mode_boot_partition2 = 2,
531     emmc_boot_partition_mode_user_area = 7,
532 } emmc_boot_partition_mode_t;
533 
534 typedef enum {
535     emmc_partition_access_boot_partition_disabled = 0,
536     emmc_partition_access_read_or_write_boot_partition1 = 1,
537     emmc_partition_access_read_or_write_boot_partition2 = 2,
538     emmc_partition_access_read_or_write_rpmb = 3,
539     emmc_partition_access_access_to_gp_partition1 = 4,
540     emmc_partition_access_access_to_gp_partition2 = 5,
541     emmc_partition_access_access_to_gp_partition3 = 6,
542     emmc_partition_access_access_to_gp_partition4 = 7,
543 } emmc_partition_access_t;
544 
545 typedef enum {
546     emmc_boot_mode_sdr_legacy = 0, emmc_boot_mode_sdr_high_speed_timing, emmc_boot_mode_ddr,
547 } emmc_boot_mode_t;
548 
549 typedef struct {
550     bool enable_boot_ack;
551     bool enable_boot_config_protection_until_next_power_cycle;
552     bool enable_boot_config_protection_permanently;
553     bool reset_boot_bus_conditions;
554     emmc_boot_mode_t boot_mode;
555     emmc_bus_mode_t boot_bus_mode;
556     emmc_boot_partition_mode_t emmc_boot_partition_mode;
557     emmc_partition_access_t partition_access;
558 } emmc_boot_setting_t;
559 
560 typedef struct {
561     bool is_secure_write_protection_supported;
562     emmc_device_type_t device_type;
563     emmc_write_protection_mode_t write_protection_mode;
564 
565     boot_info_t boot_info;
566     secure_feature_info_t secure_feature_info;
567 
568     uint32_t boot_partition_size;
569     uint32_t rpmb_partition_size;
570     uint32_t max_enhanced_area_size;
571 
572     uint32_t gp_partition_size[4];
573 
574     uint32_t super_page_size;
575     uint32_t write_protect_group_size;
576     uint32_t erase_group_size;
577     uint64_t device_size_in_bytes;
578     uint32_t sector_count;
579     uint32_t sector_size;
580 
581     uint32_t large_unit_size;
582     uint32_t optimal_read_size;
583     uint32_t optimal_write_size;
584     uint64_t optimal_trim_unit_size;
585 
586     uint32_t operation_codes_timeout_us;
587     uint32_t switch_cmd_timeout_ms;
588     uint32_t power_off_timeout_ms;
589     uint32_t init_timeout_after_partition_ms;
590     uint32_t trim_timeout_ms;
591     uint32_t secure_erase_timeout_ms;
592     uint32_t secure_trim_timeout_ms;
593 
594     uint32_t erase_timeout_ms;
595     uint32_t partition_switch_timeout_ms;
596     uint32_t out_of_interrupt_timeout_ms;
597     uint32_t sleep_notification_timeout_us;
598     uint32_t sleep_awake_timeout_ns;
599     uint32_t production_state_awareness_timeout_us;
600     uint32_t sleep_current_vcc_ua;
601     uint32_t sleep_current_vccq_ua;
602 
603     bool use_high_capacity_erase_unit_size;
604     bool is_all_0xffs_for_erased_region;
605     bool is_enhanced_strobe_supported;
606     bool is_cmd_queue_mode_enabled;
607 } emmc_device_attribute_t;
608 
609 typedef struct _sdmmc_emmc {
610     sdmmc_host_t *host;
611     uint16_t relative_addr;
612     emmc_cid_t cid;
613     emmc_ocr_t ocr;
614     emmc_csd_t csd;
615     emmc_ext_csd_t ext_csd;
616 
617     emmc_device_attribute_t device_attribute;
618 
619     sdmmc_operation_voltage_t operation_voltage;
620     emmc_card_status_t current_r1_status;
621     emmc_partition_t current_partition;
622     emmc_hs_timing_t current_hs_timing;
623     emmc_bus_mode_t current_bus_mode;
624     emmc_power_class_t current_power_class;
625     emmc_boot_setting_t boot_setting;
626     bool is_host_ready;
627 } emmc_card_t;
628 
629 typedef enum {
630     emmc_idle_option_go_idle_state = 0,
631     emmc_idle_option_go_pre_idle_state = 0xF0F0F0F0U,
632     emmc_idle_option_boot_initialization = 0xFFFFFFFAU,
633 } emmc_idle_option_t;
634 
635 typedef enum {
636     emmc_erase_option_erase = 0,  /*!< eMMC Erase operation */
637     emmc_erase_option_trim = 1,  /*!< eMMC Trim operation */
638     emmc_erase_option_discard = 2,  /*!< eMMC Discard operation */
639 } emmc_erase_option_t;
640 
641 typedef enum {
642     boot_partition_enable_option_not_enabled = 0,
643     boot_partition_enable_option_boot_partition1 = 1,
644     boot_partition_enable_option_boot_partition2 = 2,
645     boot_partition_enable_option_user_area = 7,
646 } emmc_boot_partition_enable_option_t;
647 
648 typedef enum {
649     partition_access_option_no_access_to_boot_partition = 0,
650     partition_access_option_read_write_boot_partition1 = 1,
651     partition_access_option_read_write_boot_partition2 = 2,
652     partition_access_option_read_write_rpmb = 3,
653     partition_access_option_access_to_gp_partition1 = 4,
654     partition_access_option_access_to_gp_partition2 = 5,
655     partition_access_option_access_to_gp_partition3 = 6,
656     partition_access_option_access_to_gp_partition4 = 7
657 } emmc_partition_access_option_t;
658 
659 typedef struct {
660     bool enable_boot_ack;
661     emmc_boot_partition_enable_option_t boot_partition_enable_option;
662     emmc_partition_access_t partition_access_option;
663 } emmc_config_partition_option_t;
664 
665 #ifdef __cplusplus
666 extern "C" {
667 #endif
668 
669 /**
670  * @brief Intialize eMMC device, include both host and the device
671  * @param card
672  * @return
673  */
674 hpm_stat_t emmc_init(emmc_card_t *card);
675 
676 void emmc_deinit(emmc_card_t *card);
677 
678 /**
679  * @brief Initialize eMMC device
680  * @param card
681  * @return
682  */
683 hpm_stat_t emmc_card_init(emmc_card_t *card);
684 
685 /**
686  * @brief Request eMMC device to send CID to Host
687  * @param card
688  * @return
689  */
690 hpm_stat_t emmc_send_cid(emmc_card_t *card);
691 
692 /**
693  * @brief Probe eMMC device
694  * @param card
695  * @return
696  */
697 hpm_stat_t emmc_probe_device(emmc_card_t *card);
698 
699 /**
700  * @brief Select eMMC device
701  * @param card
702  * @param is_selected
703  * @return
704  */
705 hpm_stat_t emmc_select_card(emmc_card_t *card, bool is_selected);
706 
707 /**
708  * @brief Go to Idle mode
709  * @param card
710  * @param option
711  * @return
712  */
713 hpm_stat_t emmc_go_idle(emmc_card_t *card, emmc_idle_option_t option);
714 
715 /**
716  * @brief Switch eMMC function
717  * @param card
718  * @param arg
719  * @param timeout_us
720  * @return
721  */
722 hpm_stat_t emmc_switch_function(emmc_card_t *card, emmc_switch_cmd_arg_t arg, uint32_t timeout_us);
723 
724 /**
725  * @brief Configure eMMC Partition
726  * @param card
727  * @param option
728  * @return
729  */
730 hpm_stat_t emmc_configure_partition(emmc_card_t *card, emmc_config_partition_option_t option);
731 
732 /**
733  * @brief Enable High Density Erase group
734  * @param card
735  * @param enable
736  * @return
737  */
738 hpm_stat_t emmc_enable_high_density_erase_group(emmc_card_t *card, bool enable);
739 
740 /**
741  * @brief Program CSD register
742  * @param card
743  * @param raw_csd
744  * @return
745  */
746 hpm_stat_t emmc_program_csd(emmc_card_t *card, const uint32_t *raw_csd);
747 
748 /**
749  * @brief Read eMMC blocks
750  * @param card
751  * @param buffer
752  * @param start_block
753  * @param block_count
754  * @return
755  */
756 hpm_stat_t emmc_read_blocks(emmc_card_t *card, uint8_t *buffer, uint32_t start_block, uint32_t block_count);
757 
758 /**
759  * @brief Write eMMC blocks
760  * @param card
761  * @param buffer
762  * @param start_block
763  * @param block_count
764  * @return
765  */
766 hpm_stat_t emmc_write_blocks(emmc_card_t *card, const uint8_t *buffer, uint32_t start_block, uint32_t block_count);
767 
768 /**
769  * @brief Erase eMMC Blocks
770  * @param [in] card
771  * @param [in] start_block
772  * @param [in] block_count
773  * @param [in] erase_option
774  * @return
775  */
776 hpm_stat_t emmc_erase_blocks(emmc_card_t *card, uint32_t start_block, uint32_t block_count, emmc_erase_option_t option);
777 
778 
779 #ifdef __cplusplus
780 }
781 #endif
782 
783 #endif /* HPM_SDMMC_EMMC_H */
784