1bc4e68d3SJeuk Kim /* SPDX-License-Identifier: GPL-2.0-or-later */
2bc4e68d3SJeuk Kim
3bc4e68d3SJeuk Kim #ifndef BLOCK_UFS_H
4bc4e68d3SJeuk Kim #define BLOCK_UFS_H
5bc4e68d3SJeuk Kim
6bc4e68d3SJeuk Kim #include "hw/registerfields.h"
7bc4e68d3SJeuk Kim
8bc4e68d3SJeuk Kim typedef struct QEMU_PACKED UfsReg {
9bc4e68d3SJeuk Kim uint32_t cap;
10cdba3b90SMinwoo Im uint32_t mcqcap;
11bc4e68d3SJeuk Kim uint32_t ver;
12bc4e68d3SJeuk Kim uint32_t rsvd1;
13bc4e68d3SJeuk Kim uint32_t hcpid;
14bc4e68d3SJeuk Kim uint32_t hcmid;
15bc4e68d3SJeuk Kim uint32_t ahit;
16bc4e68d3SJeuk Kim uint32_t rsvd2;
17bc4e68d3SJeuk Kim uint32_t is;
18bc4e68d3SJeuk Kim uint32_t ie;
19bc4e68d3SJeuk Kim uint32_t rsvd3[2];
20bc4e68d3SJeuk Kim uint32_t hcs;
21bc4e68d3SJeuk Kim uint32_t hce;
22bc4e68d3SJeuk Kim uint32_t uecpa;
23bc4e68d3SJeuk Kim uint32_t uecdl;
24bc4e68d3SJeuk Kim uint32_t uecn;
25bc4e68d3SJeuk Kim uint32_t uect;
26bc4e68d3SJeuk Kim uint32_t uecdme;
27bc4e68d3SJeuk Kim uint32_t utriacr;
28bc4e68d3SJeuk Kim uint32_t utrlba;
29bc4e68d3SJeuk Kim uint32_t utrlbau;
30bc4e68d3SJeuk Kim uint32_t utrldbr;
31bc4e68d3SJeuk Kim uint32_t utrlclr;
32bc4e68d3SJeuk Kim uint32_t utrlrsr;
33bc4e68d3SJeuk Kim uint32_t utrlcnr;
34bc4e68d3SJeuk Kim uint32_t rsvd4[2];
35bc4e68d3SJeuk Kim uint32_t utmrlba;
36bc4e68d3SJeuk Kim uint32_t utmrlbau;
37bc4e68d3SJeuk Kim uint32_t utmrldbr;
38bc4e68d3SJeuk Kim uint32_t utmrlclr;
39bc4e68d3SJeuk Kim uint32_t utmrlrsr;
40bc4e68d3SJeuk Kim uint32_t rsvd5[3];
41bc4e68d3SJeuk Kim uint32_t uiccmd;
42bc4e68d3SJeuk Kim uint32_t ucmdarg1;
43bc4e68d3SJeuk Kim uint32_t ucmdarg2;
44bc4e68d3SJeuk Kim uint32_t ucmdarg3;
45bc4e68d3SJeuk Kim uint32_t rsvd6[4];
46bc4e68d3SJeuk Kim uint32_t rsvd7[4];
47bc4e68d3SJeuk Kim uint32_t rsvd8[16];
48bc4e68d3SJeuk Kim uint32_t ccap;
49cdba3b90SMinwoo Im uint32_t rsvd9[127];
50cdba3b90SMinwoo Im uint32_t config;
51cdba3b90SMinwoo Im uint32_t rsvd10[3];
52cdba3b90SMinwoo Im uint32_t rsvd11[28];
53cdba3b90SMinwoo Im uint32_t mcqconfig;
54cdba3b90SMinwoo Im uint32_t esilba;
55cdba3b90SMinwoo Im uint32_t esiuba;
56bc4e68d3SJeuk Kim } UfsReg;
57bc4e68d3SJeuk Kim
58bc4e68d3SJeuk Kim REG32(CAP, offsetof(UfsReg, cap))
59bc4e68d3SJeuk Kim FIELD(CAP, NUTRS, 0, 5)
60bc4e68d3SJeuk Kim FIELD(CAP, RTT, 8, 8)
61bc4e68d3SJeuk Kim FIELD(CAP, NUTMRS, 16, 3)
62bc4e68d3SJeuk Kim FIELD(CAP, AUTOH8, 23, 1)
63bc4e68d3SJeuk Kim FIELD(CAP, 64AS, 24, 1)
64bc4e68d3SJeuk Kim FIELD(CAP, OODDS, 25, 1)
65bc4e68d3SJeuk Kim FIELD(CAP, UICDMETMS, 26, 1)
66bc4e68d3SJeuk Kim FIELD(CAP, CS, 28, 1)
67cdba3b90SMinwoo Im FIELD(CAP, LSDBS, 29, 1)
68cdba3b90SMinwoo Im FIELD(CAP, MCQS, 30, 1)
69cdba3b90SMinwoo Im REG32(MCQCAP, offsetof(UfsReg, mcqcap))
70cdba3b90SMinwoo Im FIELD(MCQCAP, MAXQ, 0, 8)
71cdba3b90SMinwoo Im FIELD(MCQCAP, SP, 8, 1)
72cdba3b90SMinwoo Im FIELD(MCQCAP, RRP, 9, 1)
73cdba3b90SMinwoo Im FIELD(MCQCAP, EIS, 10, 1)
74cdba3b90SMinwoo Im FIELD(MCQCAP, QCFGPTR, 16, 8)
75cdba3b90SMinwoo Im FIELD(MCQCAP, MIAG, 24, 8)
76bc4e68d3SJeuk Kim REG32(VER, offsetof(UfsReg, ver))
77bc4e68d3SJeuk Kim REG32(HCPID, offsetof(UfsReg, hcpid))
78bc4e68d3SJeuk Kim REG32(HCMID, offsetof(UfsReg, hcmid))
79bc4e68d3SJeuk Kim REG32(AHIT, offsetof(UfsReg, ahit))
80bc4e68d3SJeuk Kim REG32(IS, offsetof(UfsReg, is))
81bc4e68d3SJeuk Kim FIELD(IS, UTRCS, 0, 1)
82bc4e68d3SJeuk Kim FIELD(IS, UDEPRI, 1, 1)
83bc4e68d3SJeuk Kim FIELD(IS, UE, 2, 1)
84bc4e68d3SJeuk Kim FIELD(IS, UTMS, 3, 1)
85bc4e68d3SJeuk Kim FIELD(IS, UPMS, 4, 1)
86bc4e68d3SJeuk Kim FIELD(IS, UHXS, 5, 1)
87bc4e68d3SJeuk Kim FIELD(IS, UHES, 6, 1)
88bc4e68d3SJeuk Kim FIELD(IS, ULLS, 7, 1)
89bc4e68d3SJeuk Kim FIELD(IS, ULSS, 8, 1)
90bc4e68d3SJeuk Kim FIELD(IS, UTMRCS, 9, 1)
91bc4e68d3SJeuk Kim FIELD(IS, UCCS, 10, 1)
92bc4e68d3SJeuk Kim FIELD(IS, DFES, 11, 1)
93bc4e68d3SJeuk Kim FIELD(IS, UTPES, 12, 1)
94bc4e68d3SJeuk Kim FIELD(IS, HCFES, 16, 1)
95bc4e68d3SJeuk Kim FIELD(IS, SBFES, 17, 1)
96bc4e68d3SJeuk Kim FIELD(IS, CEFES, 18, 1)
97cdba3b90SMinwoo Im FIELD(IS, CQES, 20, 1)
98bc4e68d3SJeuk Kim REG32(IE, offsetof(UfsReg, ie))
99bc4e68d3SJeuk Kim FIELD(IE, UTRCE, 0, 1)
100bc4e68d3SJeuk Kim FIELD(IE, UDEPRIE, 1, 1)
101bc4e68d3SJeuk Kim FIELD(IE, UEE, 2, 1)
102bc4e68d3SJeuk Kim FIELD(IE, UTMSE, 3, 1)
103bc4e68d3SJeuk Kim FIELD(IE, UPMSE, 4, 1)
104bc4e68d3SJeuk Kim FIELD(IE, UHXSE, 5, 1)
105bc4e68d3SJeuk Kim FIELD(IE, UHESE, 6, 1)
106bc4e68d3SJeuk Kim FIELD(IE, ULLSE, 7, 1)
107bc4e68d3SJeuk Kim FIELD(IE, ULSSE, 8, 1)
108bc4e68d3SJeuk Kim FIELD(IE, UTMRCE, 9, 1)
109bc4e68d3SJeuk Kim FIELD(IE, UCCE, 10, 1)
110bc4e68d3SJeuk Kim FIELD(IE, DFEE, 11, 1)
111bc4e68d3SJeuk Kim FIELD(IE, UTPEE, 12, 1)
112bc4e68d3SJeuk Kim FIELD(IE, HCFEE, 16, 1)
113bc4e68d3SJeuk Kim FIELD(IE, SBFEE, 17, 1)
114bc4e68d3SJeuk Kim FIELD(IE, CEFEE, 18, 1)
115cdba3b90SMinwoo Im FIELD(IE, CQEE, 20, 1)
116bc4e68d3SJeuk Kim REG32(HCS, offsetof(UfsReg, hcs))
117bc4e68d3SJeuk Kim FIELD(HCS, DP, 0, 1)
118bc4e68d3SJeuk Kim FIELD(HCS, UTRLRDY, 1, 1)
119bc4e68d3SJeuk Kim FIELD(HCS, UTMRLRDY, 2, 1)
120bc4e68d3SJeuk Kim FIELD(HCS, UCRDY, 3, 1)
121bc4e68d3SJeuk Kim FIELD(HCS, UPMCRS, 8, 3)
122bc4e68d3SJeuk Kim REG32(HCE, offsetof(UfsReg, hce))
123bc4e68d3SJeuk Kim FIELD(HCE, HCE, 0, 1)
124bc4e68d3SJeuk Kim FIELD(HCE, CGE, 1, 1)
125bc4e68d3SJeuk Kim REG32(UECPA, offsetof(UfsReg, uecpa))
126bc4e68d3SJeuk Kim REG32(UECDL, offsetof(UfsReg, uecdl))
127bc4e68d3SJeuk Kim REG32(UECN, offsetof(UfsReg, uecn))
128bc4e68d3SJeuk Kim REG32(UECT, offsetof(UfsReg, uect))
129bc4e68d3SJeuk Kim REG32(UECDME, offsetof(UfsReg, uecdme))
130bc4e68d3SJeuk Kim REG32(UTRIACR, offsetof(UfsReg, utriacr))
131bc4e68d3SJeuk Kim REG32(UTRLBA, offsetof(UfsReg, utrlba))
132ebca80bbSJeuk Kim FIELD(UTRLBA, UTRLBA, 10, 22)
133bc4e68d3SJeuk Kim REG32(UTRLBAU, offsetof(UfsReg, utrlbau))
134bc4e68d3SJeuk Kim REG32(UTRLDBR, offsetof(UfsReg, utrldbr))
135bc4e68d3SJeuk Kim REG32(UTRLCLR, offsetof(UfsReg, utrlclr))
136bc4e68d3SJeuk Kim REG32(UTRLRSR, offsetof(UfsReg, utrlrsr))
137bc4e68d3SJeuk Kim REG32(UTRLCNR, offsetof(UfsReg, utrlcnr))
138bc4e68d3SJeuk Kim REG32(UTMRLBA, offsetof(UfsReg, utmrlba))
139ebca80bbSJeuk Kim FIELD(UTMRLBA, UTMRLBA, 10, 22)
140bc4e68d3SJeuk Kim REG32(UTMRLBAU, offsetof(UfsReg, utmrlbau))
141bc4e68d3SJeuk Kim REG32(UTMRLDBR, offsetof(UfsReg, utmrldbr))
142bc4e68d3SJeuk Kim REG32(UTMRLCLR, offsetof(UfsReg, utmrlclr))
143bc4e68d3SJeuk Kim REG32(UTMRLRSR, offsetof(UfsReg, utmrlrsr))
144bc4e68d3SJeuk Kim REG32(UICCMD, offsetof(UfsReg, uiccmd))
145bc4e68d3SJeuk Kim REG32(UCMDARG1, offsetof(UfsReg, ucmdarg1))
146bc4e68d3SJeuk Kim REG32(UCMDARG2, offsetof(UfsReg, ucmdarg2))
147bc4e68d3SJeuk Kim REG32(UCMDARG3, offsetof(UfsReg, ucmdarg3))
148bc4e68d3SJeuk Kim REG32(CCAP, offsetof(UfsReg, ccap))
149cdba3b90SMinwoo Im REG32(CONFIG, offsetof(UfsReg, config))
150cdba3b90SMinwoo Im FIELD(CONFIG, QT, 0, 1)
151cdba3b90SMinwoo Im REG32(MCQCONFIG, offsetof(UfsReg, mcqconfig))
152cdba3b90SMinwoo Im FIELD(MCQCONFIG, MAC, 8, 8)
153bc4e68d3SJeuk Kim
154bc4e68d3SJeuk Kim #define UFS_INTR_MASK \
1555c079578SMinwoo Im ((1 << R_IS_CQES_SHIFT) | \
1565c079578SMinwoo Im (1 << R_IS_CEFES_SHIFT) | (1 << R_IS_SBFES_SHIFT) | \
157bc4e68d3SJeuk Kim (1 << R_IS_HCFES_SHIFT) | (1 << R_IS_UTPES_SHIFT) | \
158bc4e68d3SJeuk Kim (1 << R_IS_DFES_SHIFT) | (1 << R_IS_UCCS_SHIFT) | \
159bc4e68d3SJeuk Kim (1 << R_IS_UTMRCS_SHIFT) | (1 << R_IS_ULSS_SHIFT) | \
160bc4e68d3SJeuk Kim (1 << R_IS_ULLS_SHIFT) | (1 << R_IS_UHES_SHIFT) | \
161bc4e68d3SJeuk Kim (1 << R_IS_UHXS_SHIFT) | (1 << R_IS_UPMS_SHIFT) | \
162bc4e68d3SJeuk Kim (1 << R_IS_UTMS_SHIFT) | (1 << R_IS_UE_SHIFT) | \
163bc4e68d3SJeuk Kim (1 << R_IS_UDEPRI_SHIFT) | (1 << R_IS_UTRCS_SHIFT))
164bc4e68d3SJeuk Kim
165bc4e68d3SJeuk Kim #define UFS_UPIU_HEADER_TRANSACTION_TYPE_SHIFT 24
166bc4e68d3SJeuk Kim #define UFS_UPIU_HEADER_TRANSACTION_TYPE_MASK 0xff
167bc4e68d3SJeuk Kim #define UFS_UPIU_HEADER_TRANSACTION_TYPE(dword0) \
168bc4e68d3SJeuk Kim ((be32_to_cpu(dword0) >> UFS_UPIU_HEADER_TRANSACTION_TYPE_SHIFT) & \
169bc4e68d3SJeuk Kim UFS_UPIU_HEADER_TRANSACTION_TYPE_MASK)
170bc4e68d3SJeuk Kim
171bc4e68d3SJeuk Kim #define UFS_UPIU_HEADER_QUERY_FUNC_SHIFT 16
172bc4e68d3SJeuk Kim #define UFS_UPIU_HEADER_QUERY_FUNC_MASK 0xff
173bc4e68d3SJeuk Kim #define UFS_UPIU_HEADER_QUERY_FUNC(dword1) \
174bc4e68d3SJeuk Kim ((be32_to_cpu(dword1) >> UFS_UPIU_HEADER_QUERY_FUNC_SHIFT) & \
175bc4e68d3SJeuk Kim UFS_UPIU_HEADER_QUERY_FUNC_MASK)
176bc4e68d3SJeuk Kim
177bc4e68d3SJeuk Kim #define UFS_UPIU_HEADER_DATA_SEGMENT_LENGTH_SHIFT 0
178bc4e68d3SJeuk Kim #define UFS_UPIU_HEADER_DATA_SEGMENT_LENGTH_MASK 0xffff
179bc4e68d3SJeuk Kim #define UFS_UPIU_HEADER_DATA_SEGMENT_LENGTH(dword2) \
180bc4e68d3SJeuk Kim ((be32_to_cpu(dword2) >> UFS_UPIU_HEADER_DATA_SEGMENT_LENGTH_SHIFT) & \
181bc4e68d3SJeuk Kim UFS_UPIU_HEADER_DATA_SEGMENT_LENGTH_MASK)
182bc4e68d3SJeuk Kim
183cdba3b90SMinwoo Im typedef struct QEMU_PACKED UfsMcqReg {
184cdba3b90SMinwoo Im uint32_t sqattr;
185cdba3b90SMinwoo Im uint32_t sqlba;
186cdba3b90SMinwoo Im uint32_t squba;
187cdba3b90SMinwoo Im uint32_t sqdao;
188cdba3b90SMinwoo Im uint32_t sqisao;
189cdba3b90SMinwoo Im uint32_t sqcfg;
190cdba3b90SMinwoo Im uint32_t rsvd0[2];
191cdba3b90SMinwoo Im uint32_t cqattr;
192cdba3b90SMinwoo Im uint32_t cqlba;
193cdba3b90SMinwoo Im uint32_t cquba;
194cdba3b90SMinwoo Im uint32_t cqdao;
195cdba3b90SMinwoo Im uint32_t cqisao;
196cdba3b90SMinwoo Im uint32_t cqcfg;
197cdba3b90SMinwoo Im uint32_t rsvd1[2];
198cdba3b90SMinwoo Im } UfsMcqReg;
199cdba3b90SMinwoo Im
200cdba3b90SMinwoo Im REG32(SQATTR, offsetof(UfsMcqReg, sqattr))
201cdba3b90SMinwoo Im FIELD(SQATTR, SIZE, 0, 16)
202cdba3b90SMinwoo Im FIELD(SQATTR, CQID, 16, 8)
203cdba3b90SMinwoo Im FIELD(SQATTR, SQPL, 28, 3)
204cdba3b90SMinwoo Im FIELD(SQATTR, SQEN, 31, 1)
205cdba3b90SMinwoo Im REG32(SQLBA, offsetof(UfsMcqReg, sqlba))
206cdba3b90SMinwoo Im REG32(SQUBA, offsetof(UfsMcqReg, squba))
207cdba3b90SMinwoo Im REG32(SQDAO, offsetof(UfsMcqReg, sqdao))
208cdba3b90SMinwoo Im REG32(SQISAO, offsetof(UfsMcqReg, sqisao))
209cdba3b90SMinwoo Im REG32(SQCFG, offsetof(UfsMcqReg, sqcfg))
210cdba3b90SMinwoo Im REG32(CQATTR, offsetof(UfsMcqReg, cqattr))
211cdba3b90SMinwoo Im FIELD(CQATTR, SIZE, 0, 16)
212cdba3b90SMinwoo Im FIELD(CQATTR, CQEN, 31, 1)
213cdba3b90SMinwoo Im REG32(CQLBA, offsetof(UfsMcqReg, cqlba))
214cdba3b90SMinwoo Im REG32(CQUBA, offsetof(UfsMcqReg, cquba))
215cdba3b90SMinwoo Im REG32(CQDAO, offsetof(UfsMcqReg, cqdao))
216cdba3b90SMinwoo Im REG32(CQISAO, offsetof(UfsMcqReg, cqisao))
217cdba3b90SMinwoo Im REG32(CQCFG, offsetof(UfsMcqReg, cqcfg))
218cdba3b90SMinwoo Im
219cdba3b90SMinwoo Im typedef struct QEMU_PACKED UfsMcqSqReg {
220cdba3b90SMinwoo Im uint32_t hp;
221cdba3b90SMinwoo Im uint32_t tp;
222cdba3b90SMinwoo Im uint32_t rtc;
223cdba3b90SMinwoo Im uint32_t cti;
224cdba3b90SMinwoo Im uint32_t rts;
225cdba3b90SMinwoo Im } UfsMcqSqReg;
226cdba3b90SMinwoo Im
227cdba3b90SMinwoo Im typedef struct QEMU_PACKED UfsMcqCqReg {
228cdba3b90SMinwoo Im uint32_t hp;
229cdba3b90SMinwoo Im uint32_t tp;
230cdba3b90SMinwoo Im } UfsMcqCqReg;
231cdba3b90SMinwoo Im
232cdba3b90SMinwoo Im typedef struct QEMU_PACKED UfsMcqSqIntReg {
233cdba3b90SMinwoo Im uint32_t is;
234cdba3b90SMinwoo Im uint32_t ie;
235cdba3b90SMinwoo Im } UfsMcqSqIntReg;
236cdba3b90SMinwoo Im
237cdba3b90SMinwoo Im typedef struct QEMU_PACKED UfsMcqCqIntReg {
238cdba3b90SMinwoo Im uint32_t is;
239cdba3b90SMinwoo Im uint32_t ie;
240cdba3b90SMinwoo Im uint32_t iacr;
241cdba3b90SMinwoo Im } UfsMcqCqIntReg;
242cdba3b90SMinwoo Im
243cdba3b90SMinwoo Im REG32(CQIS, offsetof(UfsMcqCqIntReg, is))
244cdba3b90SMinwoo Im FIELD(CQIS, TEPS, 0, 1)
245cdba3b90SMinwoo Im
2465c079578SMinwoo Im /*
2475c079578SMinwoo Im * Provide MCQ Operation & Runtime Registers as a contiguous addressed
2485c079578SMinwoo Im * registers for the simplicity.
2495c079578SMinwoo Im * DAO(Doorbell Address Offset) and ISAO(Interrupt Status Register Address
2505c079578SMinwoo Im * Offset) registers should be properly configured with the following
2515c079578SMinwoo Im * structure.
2525c079578SMinwoo Im */
2535c079578SMinwoo Im #define UFS_MCQ_OPR_START 0x1000
2545c079578SMinwoo Im typedef struct QEMU_PACKED UfsMcqOpReg {
2555c079578SMinwoo Im UfsMcqSqReg sq;
2565c079578SMinwoo Im UfsMcqSqIntReg sq_int;
2575c079578SMinwoo Im UfsMcqCqReg cq;
2585c079578SMinwoo Im UfsMcqCqIntReg cq_int;
2595c079578SMinwoo Im } UfsMcqOpReg;
2605c079578SMinwoo Im
261bc4e68d3SJeuk Kim typedef struct QEMU_PACKED DeviceDescriptor {
262bc4e68d3SJeuk Kim uint8_t length;
263bc4e68d3SJeuk Kim uint8_t descriptor_idn;
264bc4e68d3SJeuk Kim uint8_t device;
265bc4e68d3SJeuk Kim uint8_t device_class;
266bc4e68d3SJeuk Kim uint8_t device_sub_class;
267bc4e68d3SJeuk Kim uint8_t protocol;
268bc4e68d3SJeuk Kim uint8_t number_lu;
269bc4e68d3SJeuk Kim uint8_t number_wlu;
270bc4e68d3SJeuk Kim uint8_t boot_enable;
271bc4e68d3SJeuk Kim uint8_t descr_access_en;
272bc4e68d3SJeuk Kim uint8_t init_power_mode;
273bc4e68d3SJeuk Kim uint8_t high_priority_lun;
274bc4e68d3SJeuk Kim uint8_t secure_removal_type;
275bc4e68d3SJeuk Kim uint8_t security_lu;
276bc4e68d3SJeuk Kim uint8_t background_ops_term_lat;
277bc4e68d3SJeuk Kim uint8_t init_active_icc_level;
278bc4e68d3SJeuk Kim uint16_t spec_version;
279bc4e68d3SJeuk Kim uint16_t manufacture_date;
280bc4e68d3SJeuk Kim uint8_t manufacturer_name;
281bc4e68d3SJeuk Kim uint8_t product_name;
282bc4e68d3SJeuk Kim uint8_t serial_number;
283bc4e68d3SJeuk Kim uint8_t oem_id;
284bc4e68d3SJeuk Kim uint16_t manufacturer_id;
285bc4e68d3SJeuk Kim uint8_t ud_0_base_offset;
286bc4e68d3SJeuk Kim uint8_t ud_config_p_length;
287bc4e68d3SJeuk Kim uint8_t device_rtt_cap;
288bc4e68d3SJeuk Kim uint16_t periodic_rtc_update;
289bc4e68d3SJeuk Kim uint8_t ufs_features_support;
290bc4e68d3SJeuk Kim uint8_t ffu_timeout;
291bc4e68d3SJeuk Kim uint8_t queue_depth;
292bc4e68d3SJeuk Kim uint16_t device_version;
293bc4e68d3SJeuk Kim uint8_t num_secure_wp_area;
294bc4e68d3SJeuk Kim uint32_t psa_max_data_size;
295bc4e68d3SJeuk Kim uint8_t psa_state_timeout;
296bc4e68d3SJeuk Kim uint8_t product_revision_level;
297bc4e68d3SJeuk Kim uint8_t reserved[36];
298bc4e68d3SJeuk Kim uint32_t extended_ufs_features_support;
299bc4e68d3SJeuk Kim uint8_t write_booster_buffer_preserve_user_space_en;
300bc4e68d3SJeuk Kim uint8_t write_booster_buffer_type;
301bc4e68d3SJeuk Kim uint32_t num_shared_write_booster_buffer_alloc_units;
302bc4e68d3SJeuk Kim } DeviceDescriptor;
303bc4e68d3SJeuk Kim
304bc4e68d3SJeuk Kim typedef struct QEMU_PACKED GeometryDescriptor {
305bc4e68d3SJeuk Kim uint8_t length;
306bc4e68d3SJeuk Kim uint8_t descriptor_idn;
307bc4e68d3SJeuk Kim uint8_t media_technology;
308bc4e68d3SJeuk Kim uint8_t reserved;
309bc4e68d3SJeuk Kim uint64_t total_raw_device_capacity;
310bc4e68d3SJeuk Kim uint8_t max_number_lu;
311bc4e68d3SJeuk Kim uint32_t segment_size;
312bc4e68d3SJeuk Kim uint8_t allocation_unit_size;
313bc4e68d3SJeuk Kim uint8_t min_addr_block_size;
314bc4e68d3SJeuk Kim uint8_t optimal_read_block_size;
315bc4e68d3SJeuk Kim uint8_t optimal_write_block_size;
316bc4e68d3SJeuk Kim uint8_t max_in_buffer_size;
317bc4e68d3SJeuk Kim uint8_t max_out_buffer_size;
318bc4e68d3SJeuk Kim uint8_t rpmb_read_write_size;
319bc4e68d3SJeuk Kim uint8_t dynamic_capacity_resource_policy;
320bc4e68d3SJeuk Kim uint8_t data_ordering;
321bc4e68d3SJeuk Kim uint8_t max_context_id_number;
322bc4e68d3SJeuk Kim uint8_t sys_data_tag_unit_size;
323bc4e68d3SJeuk Kim uint8_t sys_data_tag_res_size;
324bc4e68d3SJeuk Kim uint8_t supported_sec_r_types;
325bc4e68d3SJeuk Kim uint16_t supported_memory_types;
326bc4e68d3SJeuk Kim uint32_t system_code_max_n_alloc_u;
327bc4e68d3SJeuk Kim uint16_t system_code_cap_adj_fac;
328bc4e68d3SJeuk Kim uint32_t non_persist_max_n_alloc_u;
329bc4e68d3SJeuk Kim uint16_t non_persist_cap_adj_fac;
330bc4e68d3SJeuk Kim uint32_t enhanced_1_max_n_alloc_u;
331bc4e68d3SJeuk Kim uint16_t enhanced_1_cap_adj_fac;
332bc4e68d3SJeuk Kim uint32_t enhanced_2_max_n_alloc_u;
333bc4e68d3SJeuk Kim uint16_t enhanced_2_cap_adj_fac;
334bc4e68d3SJeuk Kim uint32_t enhanced_3_max_n_alloc_u;
335bc4e68d3SJeuk Kim uint16_t enhanced_3_cap_adj_fac;
336bc4e68d3SJeuk Kim uint32_t enhanced_4_max_n_alloc_u;
337bc4e68d3SJeuk Kim uint16_t enhanced_4_cap_adj_fac;
338bc4e68d3SJeuk Kim uint32_t optimal_logical_block_size;
339bc4e68d3SJeuk Kim uint8_t reserved2[7];
340bc4e68d3SJeuk Kim uint32_t write_booster_buffer_max_n_alloc_units;
341bc4e68d3SJeuk Kim uint8_t device_max_write_booster_l_us;
342bc4e68d3SJeuk Kim uint8_t write_booster_buffer_cap_adj_fac;
343bc4e68d3SJeuk Kim uint8_t supported_write_booster_buffer_user_space_reduction_types;
344bc4e68d3SJeuk Kim uint8_t supported_write_booster_buffer_types;
345bc4e68d3SJeuk Kim } GeometryDescriptor;
346bc4e68d3SJeuk Kim
347bc4e68d3SJeuk Kim #define UFS_GEOMETRY_CAPACITY_SHIFT 9
348bc4e68d3SJeuk Kim
349bc4e68d3SJeuk Kim typedef struct QEMU_PACKED UnitDescriptor {
350bc4e68d3SJeuk Kim uint8_t length;
351bc4e68d3SJeuk Kim uint8_t descriptor_idn;
352bc4e68d3SJeuk Kim uint8_t unit_index;
353bc4e68d3SJeuk Kim uint8_t lu_enable;
354bc4e68d3SJeuk Kim uint8_t boot_lun_id;
355bc4e68d3SJeuk Kim uint8_t lu_write_protect;
356bc4e68d3SJeuk Kim uint8_t lu_queue_depth;
357bc4e68d3SJeuk Kim uint8_t psa_sensitive;
358bc4e68d3SJeuk Kim uint8_t memory_type;
359bc4e68d3SJeuk Kim uint8_t data_reliability;
360bc4e68d3SJeuk Kim uint8_t logical_block_size;
361bc4e68d3SJeuk Kim uint64_t logical_block_count;
362bc4e68d3SJeuk Kim uint32_t erase_block_size;
363bc4e68d3SJeuk Kim uint8_t provisioning_type;
364bc4e68d3SJeuk Kim uint64_t phy_mem_resource_count;
365bc4e68d3SJeuk Kim uint16_t context_capabilities;
366bc4e68d3SJeuk Kim uint8_t large_unit_granularity_m1;
367bc4e68d3SJeuk Kim uint8_t reserved[6];
368bc4e68d3SJeuk Kim uint32_t lu_num_write_booster_buffer_alloc_units;
369bc4e68d3SJeuk Kim } UnitDescriptor;
370bc4e68d3SJeuk Kim
371bc4e68d3SJeuk Kim typedef struct QEMU_PACKED RpmbUnitDescriptor {
372bc4e68d3SJeuk Kim uint8_t length;
373bc4e68d3SJeuk Kim uint8_t descriptor_idn;
374bc4e68d3SJeuk Kim uint8_t unit_index;
375bc4e68d3SJeuk Kim uint8_t lu_enable;
376bc4e68d3SJeuk Kim uint8_t boot_lun_id;
377bc4e68d3SJeuk Kim uint8_t lu_write_protect;
378bc4e68d3SJeuk Kim uint8_t lu_queue_depth;
379bc4e68d3SJeuk Kim uint8_t psa_sensitive;
380bc4e68d3SJeuk Kim uint8_t memory_type;
381bc4e68d3SJeuk Kim uint8_t reserved;
382bc4e68d3SJeuk Kim uint8_t logical_block_size;
383bc4e68d3SJeuk Kim uint64_t logical_block_count;
384bc4e68d3SJeuk Kim uint32_t erase_block_size;
385bc4e68d3SJeuk Kim uint8_t provisioning_type;
386bc4e68d3SJeuk Kim uint64_t phy_mem_resource_count;
387bc4e68d3SJeuk Kim uint8_t reserved2[3];
388bc4e68d3SJeuk Kim } RpmbUnitDescriptor;
389bc4e68d3SJeuk Kim
390bc4e68d3SJeuk Kim typedef struct QEMU_PACKED PowerParametersDescriptor {
391bc4e68d3SJeuk Kim uint8_t length;
392bc4e68d3SJeuk Kim uint8_t descriptor_idn;
393bc4e68d3SJeuk Kim uint16_t active_icc_levels_vcc[16];
394bc4e68d3SJeuk Kim uint16_t active_icc_levels_vccq[16];
395bc4e68d3SJeuk Kim uint16_t active_icc_levels_vccq_2[16];
396bc4e68d3SJeuk Kim } PowerParametersDescriptor;
397bc4e68d3SJeuk Kim
398bc4e68d3SJeuk Kim typedef struct QEMU_PACKED InterconnectDescriptor {
399bc4e68d3SJeuk Kim uint8_t length;
400bc4e68d3SJeuk Kim uint8_t descriptor_idn;
401bc4e68d3SJeuk Kim uint16_t bcd_unipro_version;
402bc4e68d3SJeuk Kim uint16_t bcd_mphy_version;
403bc4e68d3SJeuk Kim } InterconnectDescriptor;
404bc4e68d3SJeuk Kim
405bc4e68d3SJeuk Kim typedef struct QEMU_PACKED StringDescriptor {
406bc4e68d3SJeuk Kim uint8_t length;
407bc4e68d3SJeuk Kim uint8_t descriptor_idn;
408bc4e68d3SJeuk Kim uint16_t UC[126];
409bc4e68d3SJeuk Kim } StringDescriptor;
410bc4e68d3SJeuk Kim
411bc4e68d3SJeuk Kim typedef struct QEMU_PACKED DeviceHealthDescriptor {
412bc4e68d3SJeuk Kim uint8_t length;
413bc4e68d3SJeuk Kim uint8_t descriptor_idn;
414bc4e68d3SJeuk Kim uint8_t pre_eol_info;
415bc4e68d3SJeuk Kim uint8_t device_life_time_est_a;
416bc4e68d3SJeuk Kim uint8_t device_life_time_est_b;
417bc4e68d3SJeuk Kim uint8_t vendor_prop_info[32];
418bc4e68d3SJeuk Kim uint32_t refresh_total_count;
419bc4e68d3SJeuk Kim uint32_t refresh_progress;
420bc4e68d3SJeuk Kim } DeviceHealthDescriptor;
421bc4e68d3SJeuk Kim
422bc4e68d3SJeuk Kim typedef struct QEMU_PACKED Flags {
423bc4e68d3SJeuk Kim uint8_t reserved;
424bc4e68d3SJeuk Kim uint8_t device_init;
425bc4e68d3SJeuk Kim uint8_t permanent_wp_en;
426bc4e68d3SJeuk Kim uint8_t power_on_wp_en;
427bc4e68d3SJeuk Kim uint8_t background_ops_en;
428bc4e68d3SJeuk Kim uint8_t device_life_span_mode_en;
429bc4e68d3SJeuk Kim uint8_t purge_enable;
430bc4e68d3SJeuk Kim uint8_t refresh_enable;
431bc4e68d3SJeuk Kim uint8_t phy_resource_removal;
432bc4e68d3SJeuk Kim uint8_t busy_rtc;
433bc4e68d3SJeuk Kim uint8_t reserved2;
434bc4e68d3SJeuk Kim uint8_t permanently_disable_fw_update;
435bc4e68d3SJeuk Kim uint8_t reserved3[2];
436bc4e68d3SJeuk Kim uint8_t wb_en;
437bc4e68d3SJeuk Kim uint8_t wb_buffer_flush_en;
438bc4e68d3SJeuk Kim uint8_t wb_buffer_flush_during_hibernate;
439bc4e68d3SJeuk Kim uint8_t reserved4[2];
440bc4e68d3SJeuk Kim } Flags;
441bc4e68d3SJeuk Kim
442bc4e68d3SJeuk Kim typedef struct Attributes {
443bc4e68d3SJeuk Kim uint8_t boot_lun_en;
444bc4e68d3SJeuk Kim uint8_t reserved;
445bc4e68d3SJeuk Kim uint8_t current_power_mode;
446bc4e68d3SJeuk Kim uint8_t active_icc_level;
447bc4e68d3SJeuk Kim uint8_t out_of_order_data_en;
448bc4e68d3SJeuk Kim uint8_t background_op_status;
449bc4e68d3SJeuk Kim uint8_t purge_status;
450bc4e68d3SJeuk Kim uint8_t max_data_in_size;
451bc4e68d3SJeuk Kim uint8_t max_data_out_size;
452bc4e68d3SJeuk Kim uint32_t dyn_cap_needed;
453bc4e68d3SJeuk Kim uint8_t ref_clk_freq;
454bc4e68d3SJeuk Kim uint8_t config_descr_lock;
455bc4e68d3SJeuk Kim uint8_t max_num_of_rtt;
456bc4e68d3SJeuk Kim uint16_t exception_event_control;
457bc4e68d3SJeuk Kim uint16_t exception_event_status;
458bc4e68d3SJeuk Kim uint32_t seconds_passed;
459bc4e68d3SJeuk Kim uint16_t context_conf;
460bc4e68d3SJeuk Kim uint8_t device_ffu_status;
461bc4e68d3SJeuk Kim uint8_t psa_state;
462bc4e68d3SJeuk Kim uint32_t psa_data_size;
463bc4e68d3SJeuk Kim uint8_t ref_clk_gating_wait_time;
464bc4e68d3SJeuk Kim uint8_t device_case_rough_temperaure;
465bc4e68d3SJeuk Kim uint8_t device_too_high_temp_boundary;
466bc4e68d3SJeuk Kim uint8_t device_too_low_temp_boundary;
467bc4e68d3SJeuk Kim uint8_t throttling_status;
468bc4e68d3SJeuk Kim uint8_t wb_buffer_flush_status;
469bc4e68d3SJeuk Kim uint8_t available_wb_buffer_size;
470bc4e68d3SJeuk Kim uint8_t wb_buffer_life_time_est;
471bc4e68d3SJeuk Kim uint32_t current_wb_buffer_size;
472bc4e68d3SJeuk Kim uint8_t refresh_status;
473bc4e68d3SJeuk Kim uint8_t refresh_freq;
474bc4e68d3SJeuk Kim uint8_t refresh_unit;
475bc4e68d3SJeuk Kim uint8_t refresh_method;
476bc4e68d3SJeuk Kim } Attributes;
477bc4e68d3SJeuk Kim
478bc4e68d3SJeuk Kim #define UFS_TRANSACTION_SPECIFIC_FIELD_SIZE 20
479bc4e68d3SJeuk Kim #define UFS_MAX_QUERY_DATA_SIZE 256
480bc4e68d3SJeuk Kim
481bc4e68d3SJeuk Kim /* Command response result code */
482bc4e68d3SJeuk Kim typedef enum CommandRespCode {
483096434feSJeuk Kim UFS_COMMAND_RESULT_SUCCESS = 0x00,
484bc4e68d3SJeuk Kim UFS_COMMAND_RESULT_FAIL = 0x01,
485bc4e68d3SJeuk Kim } CommandRespCode;
486bc4e68d3SJeuk Kim
487bc4e68d3SJeuk Kim enum {
488bc4e68d3SJeuk Kim UFS_UPIU_FLAG_UNDERFLOW = 0x20,
489bc4e68d3SJeuk Kim UFS_UPIU_FLAG_OVERFLOW = 0x40,
490bc4e68d3SJeuk Kim };
491bc4e68d3SJeuk Kim
492bc4e68d3SJeuk Kim typedef struct QEMU_PACKED UtpUpiuHeader {
493bc4e68d3SJeuk Kim uint8_t trans_type;
494bc4e68d3SJeuk Kim uint8_t flags;
495bc4e68d3SJeuk Kim uint8_t lun;
496bc4e68d3SJeuk Kim uint8_t task_tag;
497bc4e68d3SJeuk Kim uint8_t iid_cmd_set_type;
498bc4e68d3SJeuk Kim uint8_t query_func;
499bc4e68d3SJeuk Kim uint8_t response;
500bc4e68d3SJeuk Kim uint8_t scsi_status;
501bc4e68d3SJeuk Kim uint8_t ehs_len;
502bc4e68d3SJeuk Kim uint8_t device_inf;
503bc4e68d3SJeuk Kim uint16_t data_segment_length;
504bc4e68d3SJeuk Kim } UtpUpiuHeader;
505bc4e68d3SJeuk Kim
506bc4e68d3SJeuk Kim /*
507bc4e68d3SJeuk Kim * The code below is copied from the linux kernel
508bc4e68d3SJeuk Kim * ("include/uapi/scsi/scsi_bsg_ufs.h") and modified to fit the qemu style.
509bc4e68d3SJeuk Kim */
510bc4e68d3SJeuk Kim
511bc4e68d3SJeuk Kim typedef struct QEMU_PACKED UtpUpiuQuery {
512bc4e68d3SJeuk Kim uint8_t opcode;
513bc4e68d3SJeuk Kim uint8_t idn;
514bc4e68d3SJeuk Kim uint8_t index;
515bc4e68d3SJeuk Kim uint8_t selector;
516bc4e68d3SJeuk Kim uint16_t reserved_osf;
517bc4e68d3SJeuk Kim uint16_t length;
518bc4e68d3SJeuk Kim uint32_t value;
519bc4e68d3SJeuk Kim uint32_t reserved[2];
520bc4e68d3SJeuk Kim /* EHS length should be 0. We don't have to worry about EHS area. */
521bc4e68d3SJeuk Kim uint8_t data[UFS_MAX_QUERY_DATA_SIZE];
522bc4e68d3SJeuk Kim } UtpUpiuQuery;
523bc4e68d3SJeuk Kim
524bc4e68d3SJeuk Kim #define UFS_CDB_SIZE 16
525bc4e68d3SJeuk Kim
526bc4e68d3SJeuk Kim /*
527bc4e68d3SJeuk Kim * struct UtpUpiuCmd - Command UPIU structure
528bc4e68d3SJeuk Kim * @data_transfer_len: Data Transfer Length DW-3
529bc4e68d3SJeuk Kim * @cdb: Command Descriptor Block CDB DW-4 to DW-7
530bc4e68d3SJeuk Kim */
531bc4e68d3SJeuk Kim typedef struct QEMU_PACKED UtpUpiuCmd {
532bc4e68d3SJeuk Kim uint32_t exp_data_transfer_len;
533bc4e68d3SJeuk Kim uint8_t cdb[UFS_CDB_SIZE];
534bc4e68d3SJeuk Kim } UtpUpiuCmd;
535bc4e68d3SJeuk Kim
536bc4e68d3SJeuk Kim /*
537bc4e68d3SJeuk Kim * struct UtpUpiuReq - general upiu request structure
538bc4e68d3SJeuk Kim * @header:UPIU header structure DW-0 to DW-2
539bc4e68d3SJeuk Kim * @sc: fields structure for scsi command DW-3 to DW-7
540bc4e68d3SJeuk Kim * @qr: fields structure for query request DW-3 to DW-7
541bc4e68d3SJeuk Kim * @uc: use utp_upiu_query to host the 4 dwords of uic command
542bc4e68d3SJeuk Kim */
543bc4e68d3SJeuk Kim typedef struct QEMU_PACKED UtpUpiuReq {
544bc4e68d3SJeuk Kim UtpUpiuHeader header;
545bc4e68d3SJeuk Kim union {
546bc4e68d3SJeuk Kim UtpUpiuCmd sc;
547bc4e68d3SJeuk Kim UtpUpiuQuery qr;
548bc4e68d3SJeuk Kim };
549bc4e68d3SJeuk Kim } UtpUpiuReq;
550bc4e68d3SJeuk Kim
551bc4e68d3SJeuk Kim /*
552bc4e68d3SJeuk Kim * The code below is copied from the linux kernel ("include/ufs/ufshci.h") and
553bc4e68d3SJeuk Kim * modified to fit the qemu style.
554bc4e68d3SJeuk Kim */
555bc4e68d3SJeuk Kim
556bc4e68d3SJeuk Kim enum {
557bc4e68d3SJeuk Kim UFS_PWR_OK = 0x0,
558bc4e68d3SJeuk Kim UFS_PWR_LOCAL = 0x01,
559bc4e68d3SJeuk Kim UFS_PWR_REMOTE = 0x02,
560bc4e68d3SJeuk Kim UFS_PWR_BUSY = 0x03,
561bc4e68d3SJeuk Kim UFS_PWR_ERROR_CAP = 0x04,
562bc4e68d3SJeuk Kim UFS_PWR_FATAL_ERROR = 0x05,
563bc4e68d3SJeuk Kim };
564bc4e68d3SJeuk Kim
565bc4e68d3SJeuk Kim /* UIC Commands */
566bc4e68d3SJeuk Kim enum uic_cmd_dme {
567bc4e68d3SJeuk Kim UFS_UIC_CMD_DME_GET = 0x01,
568bc4e68d3SJeuk Kim UFS_UIC_CMD_DME_SET = 0x02,
569bc4e68d3SJeuk Kim UFS_UIC_CMD_DME_PEER_GET = 0x03,
570bc4e68d3SJeuk Kim UFS_UIC_CMD_DME_PEER_SET = 0x04,
571bc4e68d3SJeuk Kim UFS_UIC_CMD_DME_POWERON = 0x10,
572bc4e68d3SJeuk Kim UFS_UIC_CMD_DME_POWEROFF = 0x11,
573bc4e68d3SJeuk Kim UFS_UIC_CMD_DME_ENABLE = 0x12,
574bc4e68d3SJeuk Kim UFS_UIC_CMD_DME_RESET = 0x14,
575bc4e68d3SJeuk Kim UFS_UIC_CMD_DME_END_PT_RST = 0x15,
576bc4e68d3SJeuk Kim UFS_UIC_CMD_DME_LINK_STARTUP = 0x16,
577bc4e68d3SJeuk Kim UFS_UIC_CMD_DME_HIBER_ENTER = 0x17,
578bc4e68d3SJeuk Kim UFS_UIC_CMD_DME_HIBER_EXIT = 0x18,
579bc4e68d3SJeuk Kim UFS_UIC_CMD_DME_TEST_MODE = 0x1A,
580bc4e68d3SJeuk Kim };
581bc4e68d3SJeuk Kim
582bc4e68d3SJeuk Kim /* UIC Config result code / Generic error code */
583bc4e68d3SJeuk Kim enum {
584bc4e68d3SJeuk Kim UFS_UIC_CMD_RESULT_SUCCESS = 0x00,
585bc4e68d3SJeuk Kim UFS_UIC_CMD_RESULT_INVALID_ATTR = 0x01,
586bc4e68d3SJeuk Kim UFS_UIC_CMD_RESULT_FAILURE = 0x01,
587bc4e68d3SJeuk Kim UFS_UIC_CMD_RESULT_INVALID_ATTR_VALUE = 0x02,
588bc4e68d3SJeuk Kim UFS_UIC_CMD_RESULT_READ_ONLY_ATTR = 0x03,
589bc4e68d3SJeuk Kim UFS_UIC_CMD_RESULT_WRITE_ONLY_ATTR = 0x04,
590bc4e68d3SJeuk Kim UFS_UIC_CMD_RESULT_BAD_INDEX = 0x05,
591bc4e68d3SJeuk Kim UFS_UIC_CMD_RESULT_LOCKED_ATTR = 0x06,
592bc4e68d3SJeuk Kim UFS_UIC_CMD_RESULT_BAD_TEST_FEATURE_INDEX = 0x07,
593bc4e68d3SJeuk Kim UFS_UIC_CMD_RESULT_PEER_COMM_FAILURE = 0x08,
594bc4e68d3SJeuk Kim UFS_UIC_CMD_RESULT_BUSY = 0x09,
595bc4e68d3SJeuk Kim UFS_UIC_CMD_RESULT_DME_FAILURE = 0x0A,
596bc4e68d3SJeuk Kim };
597bc4e68d3SJeuk Kim
598bc4e68d3SJeuk Kim #define UFS_MASK_UIC_COMMAND_RESULT 0xFF
599bc4e68d3SJeuk Kim
600bc4e68d3SJeuk Kim /*
601bc4e68d3SJeuk Kim * Request Descriptor Definitions
602bc4e68d3SJeuk Kim */
603bc4e68d3SJeuk Kim
604bc4e68d3SJeuk Kim /* Transfer request command type */
605bc4e68d3SJeuk Kim enum {
606bc4e68d3SJeuk Kim UFS_UTP_CMD_TYPE_SCSI = 0x0,
607bc4e68d3SJeuk Kim UFS_UTP_CMD_TYPE_UFS = 0x1,
608bc4e68d3SJeuk Kim UFS_UTP_CMD_TYPE_DEV_MANAGE = 0x2,
609bc4e68d3SJeuk Kim };
610bc4e68d3SJeuk Kim
611bc4e68d3SJeuk Kim /* To accommodate UFS2.0 required Command type */
612bc4e68d3SJeuk Kim enum {
613bc4e68d3SJeuk Kim UFS_UTP_CMD_TYPE_UFS_STORAGE = 0x1,
614bc4e68d3SJeuk Kim };
615bc4e68d3SJeuk Kim
616bc4e68d3SJeuk Kim enum {
617bc4e68d3SJeuk Kim UFS_UTP_SCSI_COMMAND = 0x00000000,
618bc4e68d3SJeuk Kim UFS_UTP_NATIVE_UFS_COMMAND = 0x10000000,
619bc4e68d3SJeuk Kim UFS_UTP_DEVICE_MANAGEMENT_FUNCTION = 0x20000000,
620bc4e68d3SJeuk Kim UFS_UTP_REQ_DESC_INT_CMD = 0x01000000,
621bc4e68d3SJeuk Kim UFS_UTP_REQ_DESC_CRYPTO_ENABLE_CMD = 0x00800000,
622bc4e68d3SJeuk Kim };
623bc4e68d3SJeuk Kim
624bc4e68d3SJeuk Kim /* UTP Transfer Request Data Direction (DD) */
625bc4e68d3SJeuk Kim enum {
626bc4e68d3SJeuk Kim UFS_UTP_NO_DATA_TRANSFER = 0x00000000,
627bc4e68d3SJeuk Kim UFS_UTP_HOST_TO_DEVICE = 0x02000000,
628bc4e68d3SJeuk Kim UFS_UTP_DEVICE_TO_HOST = 0x04000000,
629bc4e68d3SJeuk Kim };
630bc4e68d3SJeuk Kim
631bc4e68d3SJeuk Kim /* Overall command status values */
632bc4e68d3SJeuk Kim enum UtpOcsCodes {
633bc4e68d3SJeuk Kim UFS_OCS_SUCCESS = 0x0,
634bc4e68d3SJeuk Kim UFS_OCS_INVALID_CMD_TABLE_ATTR = 0x1,
635bc4e68d3SJeuk Kim UFS_OCS_INVALID_PRDT_ATTR = 0x2,
636bc4e68d3SJeuk Kim UFS_OCS_MISMATCH_DATA_BUF_SIZE = 0x3,
637bc4e68d3SJeuk Kim UFS_OCS_MISMATCH_RESP_UPIU_SIZE = 0x4,
638bc4e68d3SJeuk Kim UFS_OCS_PEER_COMM_FAILURE = 0x5,
639bc4e68d3SJeuk Kim UFS_OCS_ABORTED = 0x6,
640bc4e68d3SJeuk Kim UFS_OCS_FATAL_ERROR = 0x7,
641bc4e68d3SJeuk Kim UFS_OCS_DEVICE_FATAL_ERROR = 0x8,
642bc4e68d3SJeuk Kim UFS_OCS_INVALID_CRYPTO_CONFIG = 0x9,
643bc4e68d3SJeuk Kim UFS_OCS_GENERAL_CRYPTO_ERROR = 0xa,
644bc4e68d3SJeuk Kim UFS_OCS_INVALID_COMMAND_STATUS = 0xf,
645bc4e68d3SJeuk Kim };
646bc4e68d3SJeuk Kim
647bc4e68d3SJeuk Kim enum {
648bc4e68d3SJeuk Kim UFS_MASK_OCS = 0x0F,
649bc4e68d3SJeuk Kim };
650bc4e68d3SJeuk Kim
651bc4e68d3SJeuk Kim /*
652bc4e68d3SJeuk Kim * struct UfshcdSgEntry - UFSHCI PRD Entry
653bc4e68d3SJeuk Kim * @addr: Physical address; DW-0 and DW-1.
654bc4e68d3SJeuk Kim * @reserved: Reserved for future use DW-2
655bc4e68d3SJeuk Kim * @size: size of physical segment DW-3
656bc4e68d3SJeuk Kim */
657bc4e68d3SJeuk Kim typedef struct QEMU_PACKED UfshcdSgEntry {
658bc4e68d3SJeuk Kim uint64_t addr;
659bc4e68d3SJeuk Kim uint32_t reserved;
660bc4e68d3SJeuk Kim uint32_t size;
661bc4e68d3SJeuk Kim /*
662bc4e68d3SJeuk Kim * followed by variant-specific fields if
663bc4e68d3SJeuk Kim * CONFIG_SCSI_UFS_VARIABLE_SG_ENTRY_SIZE has been defined.
664bc4e68d3SJeuk Kim */
665bc4e68d3SJeuk Kim } UfshcdSgEntry;
666bc4e68d3SJeuk Kim
667bc4e68d3SJeuk Kim /*
668bc4e68d3SJeuk Kim * struct RequestDescHeader - Descriptor Header common to both UTRD and UTMRD
669bc4e68d3SJeuk Kim * @dword0: Descriptor Header DW0
670bc4e68d3SJeuk Kim * @dword1: Descriptor Header DW1
671bc4e68d3SJeuk Kim * @dword2: Descriptor Header DW2
672bc4e68d3SJeuk Kim * @dword3: Descriptor Header DW3
673bc4e68d3SJeuk Kim */
674bc4e68d3SJeuk Kim typedef struct QEMU_PACKED RequestDescHeader {
675bc4e68d3SJeuk Kim uint32_t dword_0;
676bc4e68d3SJeuk Kim uint32_t dword_1;
677bc4e68d3SJeuk Kim uint32_t dword_2;
678bc4e68d3SJeuk Kim uint32_t dword_3;
679bc4e68d3SJeuk Kim } RequestDescHeader;
680bc4e68d3SJeuk Kim
681bc4e68d3SJeuk Kim /*
682bc4e68d3SJeuk Kim * struct UtpTransferReqDesc - UTP Transfer Request Descriptor (UTRD)
683bc4e68d3SJeuk Kim * @header: UTRD header DW-0 to DW-3
684bc4e68d3SJeuk Kim * @command_desc_base_addr_lo: UCD base address low DW-4
685bc4e68d3SJeuk Kim * @command_desc_base_addr_hi: UCD base address high DW-5
686bc4e68d3SJeuk Kim * @response_upiu_length: response UPIU length DW-6
687bc4e68d3SJeuk Kim * @response_upiu_offset: response UPIU offset DW-6
688bc4e68d3SJeuk Kim * @prd_table_length: Physical region descriptor length DW-7
689bc4e68d3SJeuk Kim * @prd_table_offset: Physical region descriptor offset DW-7
690bc4e68d3SJeuk Kim */
691bc4e68d3SJeuk Kim typedef struct QEMU_PACKED UtpTransferReqDesc {
692bc4e68d3SJeuk Kim /* DW 0-3 */
693bc4e68d3SJeuk Kim RequestDescHeader header;
694bc4e68d3SJeuk Kim
695bc4e68d3SJeuk Kim /* DW 4-5*/
696bc4e68d3SJeuk Kim uint32_t command_desc_base_addr_lo;
697bc4e68d3SJeuk Kim uint32_t command_desc_base_addr_hi;
698bc4e68d3SJeuk Kim
699bc4e68d3SJeuk Kim /* DW 6 */
700bc4e68d3SJeuk Kim uint16_t response_upiu_length;
701bc4e68d3SJeuk Kim uint16_t response_upiu_offset;
702bc4e68d3SJeuk Kim
703bc4e68d3SJeuk Kim /* DW 7 */
704bc4e68d3SJeuk Kim uint16_t prd_table_length;
705bc4e68d3SJeuk Kim uint16_t prd_table_offset;
706bc4e68d3SJeuk Kim } UtpTransferReqDesc;
707bc4e68d3SJeuk Kim
708bc4e68d3SJeuk Kim /*
709bc4e68d3SJeuk Kim * UTMRD structure.
710bc4e68d3SJeuk Kim */
711bc4e68d3SJeuk Kim typedef struct QEMU_PACKED UtpTaskReqDesc {
712bc4e68d3SJeuk Kim /* DW 0-3 */
713bc4e68d3SJeuk Kim RequestDescHeader header;
714bc4e68d3SJeuk Kim
715bc4e68d3SJeuk Kim /* DW 4-11 - Task request UPIU structure */
716bc4e68d3SJeuk Kim struct {
717bc4e68d3SJeuk Kim UtpUpiuHeader req_header;
718bc4e68d3SJeuk Kim uint32_t input_param1;
719bc4e68d3SJeuk Kim uint32_t input_param2;
720bc4e68d3SJeuk Kim uint32_t input_param3;
721bc4e68d3SJeuk Kim uint32_t reserved1[2];
722bc4e68d3SJeuk Kim } upiu_req;
723bc4e68d3SJeuk Kim
724bc4e68d3SJeuk Kim /* DW 12-19 - Task Management Response UPIU structure */
725bc4e68d3SJeuk Kim struct {
726bc4e68d3SJeuk Kim UtpUpiuHeader rsp_header;
727bc4e68d3SJeuk Kim uint32_t output_param1;
728bc4e68d3SJeuk Kim uint32_t output_param2;
729bc4e68d3SJeuk Kim uint32_t reserved2[3];
730bc4e68d3SJeuk Kim } upiu_rsp;
731bc4e68d3SJeuk Kim } UtpTaskReqDesc;
732bc4e68d3SJeuk Kim
733bc4e68d3SJeuk Kim /*
734bc4e68d3SJeuk Kim * The code below is copied from the linux kernel ("include/ufs/ufs.h") and
735bc4e68d3SJeuk Kim * modified to fit the qemu style.
736bc4e68d3SJeuk Kim */
737bc4e68d3SJeuk Kim
738bc4e68d3SJeuk Kim #define UFS_GENERAL_UPIU_REQUEST_SIZE (sizeof(UtpUpiuReq))
739bc4e68d3SJeuk Kim #define UFS_QUERY_DESC_MAX_SIZE 255
740bc4e68d3SJeuk Kim #define UFS_QUERY_DESC_MIN_SIZE 2
741bc4e68d3SJeuk Kim #define UFS_QUERY_DESC_HDR_SIZE 2
742bc4e68d3SJeuk Kim #define UFS_QUERY_OSF_SIZE (GENERAL_UPIU_REQUEST_SIZE - (sizeof(UtpUpiuHeader)))
743bc4e68d3SJeuk Kim #define UFS_SENSE_SIZE 18
744bc4e68d3SJeuk Kim
745bc4e68d3SJeuk Kim /*
746bc4e68d3SJeuk Kim * UFS device may have standard LUs and LUN id could be from 0x00 to
747bc4e68d3SJeuk Kim * 0x7F. Standard LUs use "Peripheral Device Addressing Format".
748bc4e68d3SJeuk Kim * UFS device may also have the Well Known LUs (also referred as W-LU)
749bc4e68d3SJeuk Kim * which again could be from 0x00 to 0x7F. For W-LUs, device only use
750bc4e68d3SJeuk Kim * the "Extended Addressing Format" which means the W-LUNs would be
751bc4e68d3SJeuk Kim * from 0xc100 (SCSI_W_LUN_BASE) onwards.
752bc4e68d3SJeuk Kim * This means max. LUN number reported from UFS device could be 0xC17F.
753bc4e68d3SJeuk Kim */
754bc4e68d3SJeuk Kim #define UFS_UPIU_MAX_UNIT_NUM_ID 0x7F
755bc4e68d3SJeuk Kim #define UFS_UPIU_WLUN_ID (1 << 7)
756bc4e68d3SJeuk Kim
757bc4e68d3SJeuk Kim /* WriteBooster buffer is available only for the logical unit from 0 to 7 */
758bc4e68d3SJeuk Kim #define UFS_UPIU_MAX_WB_LUN_ID 8
759bc4e68d3SJeuk Kim
760bc4e68d3SJeuk Kim /*
761a4dbf3feSMichael Tokarev * WriteBooster buffer lifetime has a limit set by vendor.
762bc4e68d3SJeuk Kim * If it is over the limit, WriteBooster feature will be disabled.
763bc4e68d3SJeuk Kim */
764bc4e68d3SJeuk Kim #define UFS_WB_EXCEED_LIFETIME 0x0B
765bc4e68d3SJeuk Kim
766bc4e68d3SJeuk Kim /*
767*7c85332aSYoochan Jeong * The range of valid value of Active ICC attritbute
768*7c85332aSYoochan Jeong * is from 0x00 to 0x0F.
769*7c85332aSYoochan Jeong */
770*7c85332aSYoochan Jeong #define UFS_QUERY_ATTR_ACTIVE_ICC_MAXVALUE 0x0F
771*7c85332aSYoochan Jeong
772*7c85332aSYoochan Jeong /*
773bc4e68d3SJeuk Kim * In UFS Spec, the Extra Header Segment (EHS) starts from byte 32 in UPIU
774bc4e68d3SJeuk Kim * request/response packet
775bc4e68d3SJeuk Kim */
776bc4e68d3SJeuk Kim #define UFS_EHS_OFFSET_IN_RESPONSE 32
777bc4e68d3SJeuk Kim
778bc4e68d3SJeuk Kim /* Well known logical unit id in LUN field of UPIU */
779bc4e68d3SJeuk Kim enum {
780bc4e68d3SJeuk Kim UFS_UPIU_REPORT_LUNS_WLUN = 0x81,
781bc4e68d3SJeuk Kim UFS_UPIU_UFS_DEVICE_WLUN = 0xD0,
782bc4e68d3SJeuk Kim UFS_UPIU_BOOT_WLUN = 0xB0,
783bc4e68d3SJeuk Kim UFS_UPIU_RPMB_WLUN = 0xC4,
784bc4e68d3SJeuk Kim };
785bc4e68d3SJeuk Kim
786bc4e68d3SJeuk Kim /*
787bc4e68d3SJeuk Kim * UFS Protocol Information Unit related definitions
788bc4e68d3SJeuk Kim */
789bc4e68d3SJeuk Kim
790bc4e68d3SJeuk Kim /* Task management functions */
791bc4e68d3SJeuk Kim enum {
792bc4e68d3SJeuk Kim UFS_ABORT_TASK = 0x01,
793bc4e68d3SJeuk Kim UFS_ABORT_TASK_SET = 0x02,
794bc4e68d3SJeuk Kim UFS_CLEAR_TASK_SET = 0x04,
795bc4e68d3SJeuk Kim UFS_LOGICAL_RESET = 0x08,
796bc4e68d3SJeuk Kim UFS_QUERY_TASK = 0x80,
797bc4e68d3SJeuk Kim UFS_QUERY_TASK_SET = 0x81,
798bc4e68d3SJeuk Kim };
799bc4e68d3SJeuk Kim
800bc4e68d3SJeuk Kim /* UTP UPIU Transaction Codes Initiator to Target */
801bc4e68d3SJeuk Kim enum {
802bc4e68d3SJeuk Kim UFS_UPIU_TRANSACTION_NOP_OUT = 0x00,
803bc4e68d3SJeuk Kim UFS_UPIU_TRANSACTION_COMMAND = 0x01,
804bc4e68d3SJeuk Kim UFS_UPIU_TRANSACTION_DATA_OUT = 0x02,
805bc4e68d3SJeuk Kim UFS_UPIU_TRANSACTION_TASK_REQ = 0x04,
806bc4e68d3SJeuk Kim UFS_UPIU_TRANSACTION_QUERY_REQ = 0x16,
807bc4e68d3SJeuk Kim };
808bc4e68d3SJeuk Kim
809bc4e68d3SJeuk Kim /* UTP UPIU Transaction Codes Target to Initiator */
810bc4e68d3SJeuk Kim enum {
811bc4e68d3SJeuk Kim UFS_UPIU_TRANSACTION_NOP_IN = 0x20,
812bc4e68d3SJeuk Kim UFS_UPIU_TRANSACTION_RESPONSE = 0x21,
813bc4e68d3SJeuk Kim UFS_UPIU_TRANSACTION_DATA_IN = 0x22,
814bc4e68d3SJeuk Kim UFS_UPIU_TRANSACTION_TASK_RSP = 0x24,
815bc4e68d3SJeuk Kim UFS_UPIU_TRANSACTION_READY_XFER = 0x31,
816bc4e68d3SJeuk Kim UFS_UPIU_TRANSACTION_QUERY_RSP = 0x36,
817bc4e68d3SJeuk Kim UFS_UPIU_TRANSACTION_REJECT_UPIU = 0x3F,
818bc4e68d3SJeuk Kim };
819bc4e68d3SJeuk Kim
820bc4e68d3SJeuk Kim /* UPIU Read/Write flags */
821bc4e68d3SJeuk Kim enum {
822bc4e68d3SJeuk Kim UFS_UPIU_CMD_FLAGS_NONE = 0x00,
823bc4e68d3SJeuk Kim UFS_UPIU_CMD_FLAGS_WRITE = 0x20,
824bc4e68d3SJeuk Kim UFS_UPIU_CMD_FLAGS_READ = 0x40,
825bc4e68d3SJeuk Kim };
826bc4e68d3SJeuk Kim
827bc4e68d3SJeuk Kim /* UPIU Task Attributes */
828bc4e68d3SJeuk Kim enum {
829bc4e68d3SJeuk Kim UFS_UPIU_TASK_ATTR_SIMPLE = 0x00,
830bc4e68d3SJeuk Kim UFS_UPIU_TASK_ATTR_ORDERED = 0x01,
831bc4e68d3SJeuk Kim UFS_UPIU_TASK_ATTR_HEADQ = 0x02,
832bc4e68d3SJeuk Kim UFS_UPIU_TASK_ATTR_ACA = 0x03,
833bc4e68d3SJeuk Kim };
834bc4e68d3SJeuk Kim
835bc4e68d3SJeuk Kim /* UPIU Query request function */
836bc4e68d3SJeuk Kim enum {
837bc4e68d3SJeuk Kim UFS_UPIU_QUERY_FUNC_STANDARD_READ_REQUEST = 0x01,
838bc4e68d3SJeuk Kim UFS_UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST = 0x81,
839bc4e68d3SJeuk Kim };
840bc4e68d3SJeuk Kim
841bc4e68d3SJeuk Kim /* Flag idn for Query Requests*/
842bc4e68d3SJeuk Kim enum flag_idn {
843bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_FDEVICEINIT = 0x01,
844bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_PERMANENT_WPE = 0x02,
845bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_PWR_ON_WPE = 0x03,
846bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_BKOPS_EN = 0x04,
847bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE = 0x05,
848bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_PURGE_ENABLE = 0x06,
849bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_REFRESH_ENABLE = 0x07,
850bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_FPHYRESOURCEREMOVAL = 0x08,
851bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_BUSY_RTC = 0x09,
852bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_RESERVED3 = 0x0A,
853bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_PERMANENTLY_DISABLE_FW_UPDATE = 0x0B,
854bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_WB_EN = 0x0E,
855bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_WB_BUFF_FLUSH_EN = 0x0F,
856bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8 = 0x10,
857bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_HPB_RESET = 0x11,
858bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_HPB_EN = 0x12,
859bc4e68d3SJeuk Kim UFS_QUERY_FLAG_IDN_COUNT,
860bc4e68d3SJeuk Kim };
861bc4e68d3SJeuk Kim
862bc4e68d3SJeuk Kim /* Attribute idn for Query requests */
863bc4e68d3SJeuk Kim enum attr_idn {
864bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_BOOT_LU_EN = 0x00,
865bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD = 0x01,
866bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_POWER_MODE = 0x02,
867bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_ACTIVE_ICC_LVL = 0x03,
868bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_OOO_DATA_EN = 0x04,
869bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_BKOPS_STATUS = 0x05,
870bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_PURGE_STATUS = 0x06,
871bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_MAX_DATA_IN = 0x07,
872bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_MAX_DATA_OUT = 0x08,
873bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_DYN_CAP_NEEDED = 0x09,
874bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_REF_CLK_FREQ = 0x0A,
875bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_CONF_DESC_LOCK = 0x0B,
876bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_MAX_NUM_OF_RTT = 0x0C,
877bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_EE_CONTROL = 0x0D,
878bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_EE_STATUS = 0x0E,
879bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_SECONDS_PASSED = 0x0F,
880bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_CNTX_CONF = 0x10,
881bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_CORR_PRG_BLK_NUM = 0x11,
882bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_RESERVED2 = 0x12,
883bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_RESERVED3 = 0x13,
884bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_FFU_STATUS = 0x14,
885bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_PSA_STATE = 0x15,
886bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_PSA_DATA_SIZE = 0x16,
887bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_REF_CLK_GATING_WAIT_TIME = 0x17,
888bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_CASE_ROUGH_TEMP = 0x18,
889bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_HIGH_TEMP_BOUND = 0x19,
890bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_LOW_TEMP_BOUND = 0x1A,
891bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_THROTTLING_STATUS = 0x1B,
892bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_WB_FLUSH_STATUS = 0x1C,
893bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_AVAIL_WB_BUFF_SIZE = 0x1D,
894bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_WB_BUFF_LIFE_TIME_EST = 0x1E,
895bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_CURR_WB_BUFF_SIZE = 0x1F,
896bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_REFRESH_STATUS = 0x2C,
897bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_REFRESH_FREQ = 0x2D,
898bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_REFRESH_UNIT = 0x2E,
899bc4e68d3SJeuk Kim UFS_QUERY_ATTR_IDN_COUNT,
900bc4e68d3SJeuk Kim };
901bc4e68d3SJeuk Kim
902bc4e68d3SJeuk Kim /* Descriptor idn for Query requests */
903bc4e68d3SJeuk Kim enum desc_idn {
904bc4e68d3SJeuk Kim UFS_QUERY_DESC_IDN_DEVICE = 0x0,
905bc4e68d3SJeuk Kim UFS_QUERY_DESC_IDN_CONFIGURATION = 0x1,
906bc4e68d3SJeuk Kim UFS_QUERY_DESC_IDN_UNIT = 0x2,
907bc4e68d3SJeuk Kim UFS_QUERY_DESC_IDN_RFU_0 = 0x3,
908bc4e68d3SJeuk Kim UFS_QUERY_DESC_IDN_INTERCONNECT = 0x4,
909bc4e68d3SJeuk Kim UFS_QUERY_DESC_IDN_STRING = 0x5,
910bc4e68d3SJeuk Kim UFS_QUERY_DESC_IDN_RFU_1 = 0x6,
911bc4e68d3SJeuk Kim UFS_QUERY_DESC_IDN_GEOMETRY = 0x7,
912bc4e68d3SJeuk Kim UFS_QUERY_DESC_IDN_POWER = 0x8,
913bc4e68d3SJeuk Kim UFS_QUERY_DESC_IDN_HEALTH = 0x9,
914bc4e68d3SJeuk Kim UFS_QUERY_DESC_IDN_MAX,
915bc4e68d3SJeuk Kim };
916bc4e68d3SJeuk Kim
917bc4e68d3SJeuk Kim enum desc_header_offset {
918bc4e68d3SJeuk Kim UFS_QUERY_DESC_LENGTH_OFFSET = 0x00,
919bc4e68d3SJeuk Kim UFS_QUERY_DESC_DESC_TYPE_OFFSET = 0x01,
920bc4e68d3SJeuk Kim };
921bc4e68d3SJeuk Kim
922bc4e68d3SJeuk Kim /* Unit descriptor parameters offsets in bytes*/
923bc4e68d3SJeuk Kim enum unit_desc_param {
924bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_LEN = 0x0,
925bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_TYPE = 0x1,
926bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_UNIT_INDEX = 0x2,
927bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_LU_ENABLE = 0x3,
928bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_BOOT_LUN_ID = 0x4,
929bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_LU_WR_PROTECT = 0x5,
930bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_LU_Q_DEPTH = 0x6,
931bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_PSA_SENSITIVE = 0x7,
932bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_MEM_TYPE = 0x8,
933bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_DATA_RELIABILITY = 0x9,
934bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_LOGICAL_BLK_SIZE = 0xA,
935bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_LOGICAL_BLK_COUNT = 0xB,
936bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_ERASE_BLK_SIZE = 0x13,
937bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_PROVISIONING_TYPE = 0x17,
938bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_PHY_MEM_RSRC_CNT = 0x18,
939bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_CTX_CAPABILITIES = 0x20,
940bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_LARGE_UNIT_SIZE_M1 = 0x22,
941bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_HPB_LU_MAX_ACTIVE_RGNS = 0x23,
942bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_HPB_PIN_RGN_START_OFF = 0x25,
943bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_HPB_NUM_PIN_RGNS = 0x27,
944bc4e68d3SJeuk Kim UFS_UNIT_DESC_PARAM_WB_BUF_ALLOC_UNITS = 0x29,
945bc4e68d3SJeuk Kim };
946bc4e68d3SJeuk Kim
947bc4e68d3SJeuk Kim /* RPMB Unit descriptor parameters offsets in bytes*/
948bc4e68d3SJeuk Kim enum rpmb_unit_desc_param {
949bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_LEN = 0x0,
950bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_TYPE = 0x1,
951bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_UNIT_INDEX = 0x2,
952bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_LU_ENABLE = 0x3,
953bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_BOOT_LUN_ID = 0x4,
954bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_LU_WR_PROTECT = 0x5,
955bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_LU_Q_DEPTH = 0x6,
956bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_PSA_SENSITIVE = 0x7,
957bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_MEM_TYPE = 0x8,
958bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_REGION_EN = 0x9,
959bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_LOGICAL_BLK_SIZE = 0xA,
960bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_LOGICAL_BLK_COUNT = 0xB,
961bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_REGION0_SIZE = 0x13,
962bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_REGION1_SIZE = 0x14,
963bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_REGION2_SIZE = 0x15,
964bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_REGION3_SIZE = 0x16,
965bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_PROVISIONING_TYPE = 0x17,
966bc4e68d3SJeuk Kim UFS_RPMB_UNIT_DESC_PARAM_PHY_MEM_RSRC_CNT = 0x18,
967bc4e68d3SJeuk Kim };
968bc4e68d3SJeuk Kim
969bc4e68d3SJeuk Kim /* Device descriptor parameters offsets in bytes*/
970bc4e68d3SJeuk Kim enum device_desc_param {
971bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_LEN = 0x0,
972bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_TYPE = 0x1,
973bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_DEVICE_TYPE = 0x2,
974bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_DEVICE_CLASS = 0x3,
975bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_DEVICE_SUB_CLASS = 0x4,
976bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_PRTCL = 0x5,
977bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_NUM_LU = 0x6,
978bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_NUM_WLU = 0x7,
979bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_BOOT_ENBL = 0x8,
980bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_DESC_ACCSS_ENBL = 0x9,
981bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_INIT_PWR_MODE = 0xA,
982bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_HIGH_PR_LUN = 0xB,
983bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_SEC_RMV_TYPE = 0xC,
984bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_SEC_LU = 0xD,
985bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_BKOP_TERM_LT = 0xE,
986bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_ACTVE_ICC_LVL = 0xF,
987bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_SPEC_VER = 0x10,
988bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_MANF_DATE = 0x12,
989bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_MANF_NAME = 0x14,
990bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_PRDCT_NAME = 0x15,
991bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_SN = 0x16,
992bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_OEM_ID = 0x17,
993bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_MANF_ID = 0x18,
994bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_UD_OFFSET = 0x1A,
995bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_UD_LEN = 0x1B,
996bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_RTT_CAP = 0x1C,
997bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_FRQ_RTC = 0x1D,
998bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_UFS_FEAT = 0x1F,
999bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_FFU_TMT = 0x20,
1000bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_Q_DPTH = 0x21,
1001bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_DEV_VER = 0x22,
1002bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_NUM_SEC_WPA = 0x24,
1003bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_PSA_MAX_DATA = 0x25,
1004bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_PSA_TMT = 0x29,
1005bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_PRDCT_REV = 0x2A,
1006bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_HPB_VER = 0x40,
1007bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_HPB_CONTROL = 0x42,
1008bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP = 0x4F,
1009bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_WB_PRESRV_USRSPC_EN = 0x53,
1010bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_WB_TYPE = 0x54,
1011bc4e68d3SJeuk Kim UFS_DEVICE_DESC_PARAM_WB_SHARED_ALLOC_UNITS = 0x55,
1012bc4e68d3SJeuk Kim };
1013bc4e68d3SJeuk Kim
1014bc4e68d3SJeuk Kim /* Interconnect descriptor parameters offsets in bytes*/
1015bc4e68d3SJeuk Kim enum interconnect_desc_param {
1016bc4e68d3SJeuk Kim UFS_INTERCONNECT_DESC_PARAM_LEN = 0x0,
1017bc4e68d3SJeuk Kim UFS_INTERCONNECT_DESC_PARAM_TYPE = 0x1,
1018bc4e68d3SJeuk Kim UFS_INTERCONNECT_DESC_PARAM_UNIPRO_VER = 0x2,
1019bc4e68d3SJeuk Kim UFS_INTERCONNECT_DESC_PARAM_MPHY_VER = 0x4,
1020bc4e68d3SJeuk Kim };
1021bc4e68d3SJeuk Kim
1022bc4e68d3SJeuk Kim /* Geometry descriptor parameters offsets in bytes*/
1023bc4e68d3SJeuk Kim enum geometry_desc_param {
1024bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_LEN = 0x0,
1025bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_TYPE = 0x1,
1026bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_DEV_CAP = 0x4,
1027bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_MAX_NUM_LUN = 0xC,
1028bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_SEG_SIZE = 0xD,
1029bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_ALLOC_UNIT_SIZE = 0x11,
1030bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_MIN_BLK_SIZE = 0x12,
1031bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_OPT_RD_BLK_SIZE = 0x13,
1032bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_OPT_WR_BLK_SIZE = 0x14,
1033bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_MAX_IN_BUF_SIZE = 0x15,
1034bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_MAX_OUT_BUF_SIZE = 0x16,
1035bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_RPMB_RW_SIZE = 0x17,
1036bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_DYN_CAP_RSRC_PLC = 0x18,
1037bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_DATA_ORDER = 0x19,
1038bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_MAX_NUM_CTX = 0x1A,
1039bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_TAG_UNIT_SIZE = 0x1B,
1040bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_TAG_RSRC_SIZE = 0x1C,
1041bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_SEC_RM_TYPES = 0x1D,
1042bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_MEM_TYPES = 0x1E,
1043bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_SCM_MAX_NUM_UNITS = 0x20,
1044bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_SCM_CAP_ADJ_FCTR = 0x24,
1045bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_NPM_MAX_NUM_UNITS = 0x26,
1046bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_NPM_CAP_ADJ_FCTR = 0x2A,
1047bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_ENM1_MAX_NUM_UNITS = 0x2C,
1048bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_ENM1_CAP_ADJ_FCTR = 0x30,
1049bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_ENM2_MAX_NUM_UNITS = 0x32,
1050bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_ENM2_CAP_ADJ_FCTR = 0x36,
1051bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_ENM3_MAX_NUM_UNITS = 0x38,
1052bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_ENM3_CAP_ADJ_FCTR = 0x3C,
1053bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_ENM4_MAX_NUM_UNITS = 0x3E,
1054bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_ENM4_CAP_ADJ_FCTR = 0x42,
1055bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_OPT_LOG_BLK_SIZE = 0x44,
1056bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_HPB_REGION_SIZE = 0x48,
1057bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_HPB_NUMBER_LU = 0x49,
1058bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_HPB_SUBREGION_SIZE = 0x4A,
1059bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_HPB_MAX_ACTIVE_REGS = 0x4B,
1060bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_WB_MAX_ALLOC_UNITS = 0x4F,
1061bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_WB_MAX_WB_LUNS = 0x53,
1062bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_WB_BUFF_CAP_ADJ = 0x54,
1063bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_WB_SUP_RED_TYPE = 0x55,
1064bc4e68d3SJeuk Kim UFS_GEOMETRY_DESC_PARAM_WB_SUP_WB_TYPE = 0x56,
1065bc4e68d3SJeuk Kim };
1066bc4e68d3SJeuk Kim
1067bc4e68d3SJeuk Kim /* Health descriptor parameters offsets in bytes*/
1068bc4e68d3SJeuk Kim enum health_desc_param {
1069bc4e68d3SJeuk Kim UFS_HEALTH_DESC_PARAM_LEN = 0x0,
1070bc4e68d3SJeuk Kim UFS_HEALTH_DESC_PARAM_TYPE = 0x1,
1071bc4e68d3SJeuk Kim UFS_HEALTH_DESC_PARAM_EOL_INFO = 0x2,
1072bc4e68d3SJeuk Kim UFS_HEALTH_DESC_PARAM_LIFE_TIME_EST_A = 0x3,
1073bc4e68d3SJeuk Kim UFS_HEALTH_DESC_PARAM_LIFE_TIME_EST_B = 0x4,
1074bc4e68d3SJeuk Kim };
1075bc4e68d3SJeuk Kim
1076bc4e68d3SJeuk Kim /* WriteBooster buffer mode */
1077bc4e68d3SJeuk Kim enum {
1078bc4e68d3SJeuk Kim UFS_WB_BUF_MODE_LU_DEDICATED = 0x0,
1079bc4e68d3SJeuk Kim UFS_WB_BUF_MODE_SHARED = 0x1,
1080bc4e68d3SJeuk Kim };
1081bc4e68d3SJeuk Kim
1082bc4e68d3SJeuk Kim /*
1083bc4e68d3SJeuk Kim * Logical Unit Write Protect
1084bc4e68d3SJeuk Kim * 00h: LU not write protected
1085bc4e68d3SJeuk Kim * 01h: LU write protected when fPowerOnWPEn =1
1086bc4e68d3SJeuk Kim * 02h: LU permanently write protected when fPermanentWPEn =1
1087bc4e68d3SJeuk Kim */
1088bc4e68d3SJeuk Kim enum ufs_lu_wp_type {
1089bc4e68d3SJeuk Kim UFS_LU_NO_WP = 0x00,
1090bc4e68d3SJeuk Kim UFS_LU_POWER_ON_WP = 0x01,
1091bc4e68d3SJeuk Kim UFS_LU_PERM_WP = 0x02,
1092bc4e68d3SJeuk Kim };
1093bc4e68d3SJeuk Kim
1094bc4e68d3SJeuk Kim /* UTP QUERY Transaction Specific Fields OpCode */
1095bc4e68d3SJeuk Kim enum query_opcode {
1096bc4e68d3SJeuk Kim UFS_UPIU_QUERY_OPCODE_NOP = 0x0,
1097bc4e68d3SJeuk Kim UFS_UPIU_QUERY_OPCODE_READ_DESC = 0x1,
1098bc4e68d3SJeuk Kim UFS_UPIU_QUERY_OPCODE_WRITE_DESC = 0x2,
1099bc4e68d3SJeuk Kim UFS_UPIU_QUERY_OPCODE_READ_ATTR = 0x3,
1100bc4e68d3SJeuk Kim UFS_UPIU_QUERY_OPCODE_WRITE_ATTR = 0x4,
1101bc4e68d3SJeuk Kim UFS_UPIU_QUERY_OPCODE_READ_FLAG = 0x5,
1102bc4e68d3SJeuk Kim UFS_UPIU_QUERY_OPCODE_SET_FLAG = 0x6,
1103bc4e68d3SJeuk Kim UFS_UPIU_QUERY_OPCODE_CLEAR_FLAG = 0x7,
1104bc4e68d3SJeuk Kim UFS_UPIU_QUERY_OPCODE_TOGGLE_FLAG = 0x8,
1105bc4e68d3SJeuk Kim };
1106bc4e68d3SJeuk Kim
1107bc4e68d3SJeuk Kim /* Query response result code */
1108bc4e68d3SJeuk Kim typedef enum QueryRespCode {
1109bc4e68d3SJeuk Kim UFS_QUERY_RESULT_SUCCESS = 0x00,
1110bc4e68d3SJeuk Kim UFS_QUERY_RESULT_NOT_READABLE = 0xF6,
1111bc4e68d3SJeuk Kim UFS_QUERY_RESULT_NOT_WRITEABLE = 0xF7,
1112bc4e68d3SJeuk Kim UFS_QUERY_RESULT_ALREADY_WRITTEN = 0xF8,
1113bc4e68d3SJeuk Kim UFS_QUERY_RESULT_INVALID_LENGTH = 0xF9,
1114bc4e68d3SJeuk Kim UFS_QUERY_RESULT_INVALID_VALUE = 0xFA,
1115bc4e68d3SJeuk Kim UFS_QUERY_RESULT_INVALID_SELECTOR = 0xFB,
1116bc4e68d3SJeuk Kim UFS_QUERY_RESULT_INVALID_INDEX = 0xFC,
1117bc4e68d3SJeuk Kim UFS_QUERY_RESULT_INVALID_IDN = 0xFD,
1118bc4e68d3SJeuk Kim UFS_QUERY_RESULT_INVALID_OPCODE = 0xFE,
1119bc4e68d3SJeuk Kim UFS_QUERY_RESULT_GENERAL_FAILURE = 0xFF,
1120bc4e68d3SJeuk Kim } QueryRespCode;
1121bc4e68d3SJeuk Kim
1122bc4e68d3SJeuk Kim /* UTP Transfer Request Command Type (CT) */
1123bc4e68d3SJeuk Kim enum {
1124bc4e68d3SJeuk Kim UFS_UPIU_COMMAND_SET_TYPE_SCSI = 0x0,
1125bc4e68d3SJeuk Kim UFS_UPIU_COMMAND_SET_TYPE_UFS = 0x1,
1126bc4e68d3SJeuk Kim UFS_UPIU_COMMAND_SET_TYPE_QUERY = 0x2,
1127bc4e68d3SJeuk Kim };
1128bc4e68d3SJeuk Kim
1129bc4e68d3SJeuk Kim /* Task management service response */
1130bc4e68d3SJeuk Kim enum {
1131bc4e68d3SJeuk Kim UFS_UPIU_TASK_MANAGEMENT_FUNC_COMPL = 0x00,
1132bc4e68d3SJeuk Kim UFS_UPIU_TASK_MANAGEMENT_FUNC_NOT_SUPPORTED = 0x04,
1133bc4e68d3SJeuk Kim UFS_UPIU_TASK_MANAGEMENT_FUNC_SUCCEEDED = 0x08,
1134bc4e68d3SJeuk Kim UFS_UPIU_TASK_MANAGEMENT_FUNC_FAILED = 0x05,
1135bc4e68d3SJeuk Kim UFS_UPIU_INCORRECT_LOGICAL_UNIT_NO = 0x09,
1136bc4e68d3SJeuk Kim };
1137bc4e68d3SJeuk Kim
1138bc4e68d3SJeuk Kim /* UFS device power modes */
1139bc4e68d3SJeuk Kim enum ufs_dev_pwr_mode {
1140bc4e68d3SJeuk Kim UFS_ACTIVE_PWR_MODE = 1,
1141bc4e68d3SJeuk Kim UFS_SLEEP_PWR_MODE = 2,
1142bc4e68d3SJeuk Kim UFS_POWERDOWN_PWR_MODE = 3,
1143bc4e68d3SJeuk Kim UFS_DEEPSLEEP_PWR_MODE = 4,
1144bc4e68d3SJeuk Kim };
1145bc4e68d3SJeuk Kim
1146bc4e68d3SJeuk Kim /*
1147bc4e68d3SJeuk Kim * struct UtpCmdRsp - Response UPIU structure
1148bc4e68d3SJeuk Kim * @residual_transfer_count: Residual transfer count DW-3
1149bc4e68d3SJeuk Kim * @reserved: Reserved double words DW-4 to DW-7
1150bc4e68d3SJeuk Kim * @sense_data_len: Sense data length DW-8 U16
1151bc4e68d3SJeuk Kim * @sense_data: Sense data field DW-8 to DW-12
1152bc4e68d3SJeuk Kim */
1153bc4e68d3SJeuk Kim typedef struct QEMU_PACKED UtpCmdRsp {
1154bc4e68d3SJeuk Kim uint32_t residual_transfer_count;
1155bc4e68d3SJeuk Kim uint32_t reserved[4];
1156bc4e68d3SJeuk Kim uint16_t sense_data_len;
1157bc4e68d3SJeuk Kim uint8_t sense_data[UFS_SENSE_SIZE];
1158bc4e68d3SJeuk Kim } UtpCmdRsp;
1159bc4e68d3SJeuk Kim
1160bc4e68d3SJeuk Kim /*
1161bc4e68d3SJeuk Kim * struct UtpUpiuRsp - general upiu response structure
1162bc4e68d3SJeuk Kim * @header: UPIU header structure DW-0 to DW-2
1163bc4e68d3SJeuk Kim * @sr: fields structure for scsi command DW-3 to DW-12
1164bc4e68d3SJeuk Kim * @qr: fields structure for query request DW-3 to DW-7
1165bc4e68d3SJeuk Kim */
1166bc4e68d3SJeuk Kim typedef struct QEMU_PACKED UtpUpiuRsp {
1167bc4e68d3SJeuk Kim UtpUpiuHeader header;
1168bc4e68d3SJeuk Kim union {
1169bc4e68d3SJeuk Kim UtpCmdRsp sr;
1170bc4e68d3SJeuk Kim UtpUpiuQuery qr;
1171bc4e68d3SJeuk Kim };
1172bc4e68d3SJeuk Kim } UtpUpiuRsp;
1173bc4e68d3SJeuk Kim
1174cdba3b90SMinwoo Im /*
1175cdba3b90SMinwoo Im * MCQ Completion Queue Entry
1176cdba3b90SMinwoo Im */
1177cdba3b90SMinwoo Im typedef UtpTransferReqDesc UfsSqEntry;
1178cdba3b90SMinwoo Im typedef struct QEMU_PACKED UfsCqEntry {
1179cdba3b90SMinwoo Im uint64_t utp_addr;
1180cdba3b90SMinwoo Im uint16_t resp_len;
1181cdba3b90SMinwoo Im uint16_t resp_off;
1182cdba3b90SMinwoo Im uint16_t prdt_len;
1183cdba3b90SMinwoo Im uint16_t prdt_off;
1184cdba3b90SMinwoo Im uint8_t status;
1185cdba3b90SMinwoo Im uint8_t error;
1186cdba3b90SMinwoo Im uint16_t rsvd1;
1187cdba3b90SMinwoo Im uint32_t rsvd2[3];
1188cdba3b90SMinwoo Im } UfsCqEntry;
1189cdba3b90SMinwoo Im
_ufs_check_size(void)1190bc4e68d3SJeuk Kim static inline void _ufs_check_size(void)
1191bc4e68d3SJeuk Kim {
1192cdba3b90SMinwoo Im QEMU_BUILD_BUG_ON(sizeof(UfsReg) != 0x38C);
1193cdba3b90SMinwoo Im QEMU_BUILD_BUG_ON(sizeof(UfsMcqReg) != 64);
11945c079578SMinwoo Im QEMU_BUILD_BUG_ON(sizeof(UfsMcqSqReg) != 20);
11955c079578SMinwoo Im QEMU_BUILD_BUG_ON(sizeof(UfsMcqCqReg) != 8);
11965c079578SMinwoo Im QEMU_BUILD_BUG_ON(sizeof(UfsMcqSqIntReg) != 8);
11975c079578SMinwoo Im QEMU_BUILD_BUG_ON(sizeof(UfsMcqCqIntReg) != 12);
11985c079578SMinwoo Im QEMU_BUILD_BUG_ON(sizeof(UfsMcqOpReg) != 48);
1199bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(DeviceDescriptor) != 89);
1200bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(GeometryDescriptor) != 87);
1201bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(UnitDescriptor) != 45);
1202bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(RpmbUnitDescriptor) != 35);
1203bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(PowerParametersDescriptor) != 98);
1204bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(InterconnectDescriptor) != 6);
1205bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(StringDescriptor) != 254);
1206bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(DeviceHealthDescriptor) != 45);
1207bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(Flags) != 0x13);
1208bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(UtpUpiuHeader) != 12);
1209bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(UtpUpiuQuery) != 276);
1210bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(UtpUpiuCmd) != 20);
1211bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(UtpUpiuReq) != 288);
1212bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(UfshcdSgEntry) != 16);
1213bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(RequestDescHeader) != 16);
1214bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(UtpTransferReqDesc) != 32);
1215bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(UtpTaskReqDesc) != 80);
1216bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(UtpCmdRsp) != 40);
1217bc4e68d3SJeuk Kim QEMU_BUILD_BUG_ON(sizeof(UtpUpiuRsp) != 288);
1218cdba3b90SMinwoo Im QEMU_BUILD_BUG_ON(sizeof(UfsSqEntry) != 32);
1219cdba3b90SMinwoo Im QEMU_BUILD_BUG_ON(sizeof(UfsCqEntry) != 32);
1220bc4e68d3SJeuk Kim }
1221bc4e68d3SJeuk Kim #endif
1222