xref: /freebsd/sys/dev/ufshci/ufshci.h (revision 1349a733cf2828e0040cabef89eeadc3ff00c40b)
1*1349a733SJaeyoon Choi /*-
2*1349a733SJaeyoon Choi  * Copyright (c) 2025, Samsung Electronics Co., Ltd.
3*1349a733SJaeyoon Choi  * Written by Jaeyoon Choi
4*1349a733SJaeyoon Choi  *
5*1349a733SJaeyoon Choi  * SPDX-License-Identifier: BSD-2-Clause
6*1349a733SJaeyoon Choi  */
7*1349a733SJaeyoon Choi 
8*1349a733SJaeyoon Choi #ifndef __UFSHCI_H__
9*1349a733SJaeyoon Choi #define __UFSHCI_H__
10*1349a733SJaeyoon Choi 
11*1349a733SJaeyoon Choi #include <sys/param.h>
12*1349a733SJaeyoon Choi #include <sys/endian.h>
13*1349a733SJaeyoon Choi 
14*1349a733SJaeyoon Choi /*
15*1349a733SJaeyoon Choi  * Note: This driver currently assumes a little-endian architecture.
16*1349a733SJaeyoon Choi  * Big-endian support is not yet implemented.
17*1349a733SJaeyoon Choi  */
18*1349a733SJaeyoon Choi 
19*1349a733SJaeyoon Choi /* MIPI UniPro spec 2.0, section 5.8.1 "PHY Adapter Common Attributes" */
20*1349a733SJaeyoon Choi #define PA_AvailTxDataLanes 0x1520
21*1349a733SJaeyoon Choi #define PA_AvailRxDataLanes 0x1540
22*1349a733SJaeyoon Choi 
23*1349a733SJaeyoon Choi /*
24*1349a733SJaeyoon Choi  * MIPI UniPro spec 2.0, section 5.8.2 "PHY Adapter M-PHY-Specific
25*1349a733SJaeyoon Choi  * Attributes"
26*1349a733SJaeyoon Choi  */
27*1349a733SJaeyoon Choi #define PA_ConnectedTxDataLanes 0x1561
28*1349a733SJaeyoon Choi #define PA_ConnectedRxDataLanes 0x1581
29*1349a733SJaeyoon Choi #define PA_MaxRxHSGear		0x1587
30*1349a733SJaeyoon Choi #define PA_Granularity		0x15AA
31*1349a733SJaeyoon Choi #define PA_TActivate		0x15A8
32*1349a733SJaeyoon Choi 
33*1349a733SJaeyoon Choi #define PA_RemoteVerInfo	0x15A0
34*1349a733SJaeyoon Choi #define PA_LocalVerInfo		0x15A9
35*1349a733SJaeyoon Choi 
36*1349a733SJaeyoon Choi /* UFSHCI spec 4.1, section 7.4 "UIC Power Mode Change" */
37*1349a733SJaeyoon Choi #define PA_ActiveTxDataLanes		 0x1560
38*1349a733SJaeyoon Choi #define PA_ActiveRxDataLanes		 0x1580
39*1349a733SJaeyoon Choi #define PA_TxGear			 0x1568
40*1349a733SJaeyoon Choi #define PA_RxGear			 0x1583
41*1349a733SJaeyoon Choi #define PA_TxTermination		 0x1569
42*1349a733SJaeyoon Choi #define PA_RxTermination		 0x1584
43*1349a733SJaeyoon Choi #define PA_HSSeries			 0x156A
44*1349a733SJaeyoon Choi #define PA_PWRModeUserData0		 0x15B0
45*1349a733SJaeyoon Choi #define PA_PWRModeUserData1		 0x15B1
46*1349a733SJaeyoon Choi #define PA_PWRModeUserData2		 0x15B2
47*1349a733SJaeyoon Choi #define PA_PWRModeUserData3		 0x15B3
48*1349a733SJaeyoon Choi #define PA_PWRModeUserData4		 0x15B4
49*1349a733SJaeyoon Choi #define PA_PWRModeUserData5		 0x15B5
50*1349a733SJaeyoon Choi 
51*1349a733SJaeyoon Choi #define PA_TxHsAdaptType		 0x15D4
52*1349a733SJaeyoon Choi #define PA_PWRMode			 0x1571
53*1349a733SJaeyoon Choi 
54*1349a733SJaeyoon Choi #define DME_LocalFC0ProtectionTimeOutVal 0xD041
55*1349a733SJaeyoon Choi #define DME_LocalTC0ReplayTimeOutVal	 0xD042
56*1349a733SJaeyoon Choi #define DME_LocalAFC0ReqTimeOutVal	 0xD043
57*1349a733SJaeyoon Choi 
58*1349a733SJaeyoon Choi /* Currently, UFS uses TC0 only. */
59*1349a733SJaeyoon Choi #define DL_FC0ProtectionTimeOutVal_Default 8191
60*1349a733SJaeyoon Choi #define DL_TC0ReplayTimeOutVal_Default	   65535
61*1349a733SJaeyoon Choi #define DL_AFC0ReqTimeOutVal_Default	   32767
62*1349a733SJaeyoon Choi 
63*1349a733SJaeyoon Choi /* UFS Spec 4.1, section 6.4 "Reference Clock" */
64*1349a733SJaeyoon Choi enum ufshci_attribute_reference_clock {
65*1349a733SJaeyoon Choi 	UFSHCI_REF_CLK_19_2MHz = 0x0,
66*1349a733SJaeyoon Choi 	UFSHCI_REF_CLK_26MHz = 0x1,
67*1349a733SJaeyoon Choi 	UFSHCI_REF_CLK_38_4MHz = 0x2,
68*1349a733SJaeyoon Choi 	UFSHCI_REF_CLK_OBSOLETE = 0x3,
69*1349a733SJaeyoon Choi };
70*1349a733SJaeyoon Choi 
71*1349a733SJaeyoon Choi /* UFS spec 4.1, section 9 "UFS UIC Layer: MIPI Unipro" */
72*1349a733SJaeyoon Choi enum ufshci_uic_cmd_opcode {
73*1349a733SJaeyoon Choi 	/* Configuration */
74*1349a733SJaeyoon Choi 	UFSHCI_DME_GET = 0x01,
75*1349a733SJaeyoon Choi 	UFSHCI_DME_SET = 0x02,
76*1349a733SJaeyoon Choi 	UFSHCI_DME_PEER_GET = 0x03,
77*1349a733SJaeyoon Choi 	UFSHCI_DME_PEER_SET = 0x04,
78*1349a733SJaeyoon Choi 	/* Controll */
79*1349a733SJaeyoon Choi 	UFSHCI_DME_POWER_ON = 0x10,
80*1349a733SJaeyoon Choi 	UFSHCI_DME_POWER_OFF = 0x11,
81*1349a733SJaeyoon Choi 	UFSHCI_DME_ENABLE = 0x12,
82*1349a733SJaeyoon Choi 	UFSHCI_DME_RESET = 0x14,
83*1349a733SJaeyoon Choi 	UFSHCI_DME_ENDPOINT_RESET = 0x15,
84*1349a733SJaeyoon Choi 	UFSHCI_DME_LINK_STARTUP = 0x16,
85*1349a733SJaeyoon Choi 	UFSHCI_DME_HIBERNATE_ENTER = 0x17,
86*1349a733SJaeyoon Choi 	UFSHCI_DME_HIBERNATE_EXIT = 0x18,
87*1349a733SJaeyoon Choi 	UFSHCI_DME_TEST_MODE = 0x1a,
88*1349a733SJaeyoon Choi };
89*1349a733SJaeyoon Choi 
90*1349a733SJaeyoon Choi /* UFSHCI spec 4.1, section 5.6.3 "Offset 98h: UICCMDARG2 – UIC Command
91*1349a733SJaeyoon Choi  * Argument" */
92*1349a733SJaeyoon Choi enum ufshci_uic_cmd_attr_set_type {
93*1349a733SJaeyoon Choi 	UFSHCI_ATTR_SET_TYPE_NORMAL = 0, /* volatile value */
94*1349a733SJaeyoon Choi 	UFSHCI_ATTR_SET_TYPE_STATIC = 1, /* non-volatile reset value */
95*1349a733SJaeyoon Choi };
96*1349a733SJaeyoon Choi 
97*1349a733SJaeyoon Choi struct ufshci_uic_cmd {
98*1349a733SJaeyoon Choi 	uint8_t opcode;
99*1349a733SJaeyoon Choi 	uint32_t argument1;
100*1349a733SJaeyoon Choi 	uint32_t argument2;
101*1349a733SJaeyoon Choi 	uint32_t argument3;
102*1349a733SJaeyoon Choi };
103*1349a733SJaeyoon Choi 
104*1349a733SJaeyoon Choi /* UFS spec 4.1, section 10.5 "UPIU Transactions" */
105*1349a733SJaeyoon Choi enum transaction_code {
106*1349a733SJaeyoon Choi 	UFSHCI_UPIU_TRANSACTION_CODE_NOP_OUT = 0x00,
107*1349a733SJaeyoon Choi 	UFSHCI_UPIU_TRANSACTION_CODE_COMMAND = 0x01,
108*1349a733SJaeyoon Choi 	UFSHCI_UPIU_TRANSACTION_CODE_DATA_OUT = 0x02,
109*1349a733SJaeyoon Choi 	UFSHCI_UPIU_TRANSACTION_CODE_TASK_MANAGEMENT_REQUEST = 0x04,
110*1349a733SJaeyoon Choi 	UFSHCI_UPIU_TRANSACTION_CODE_QUERY_REQUEST = 0x16,
111*1349a733SJaeyoon Choi 	UFSHCI_UPIU_TRANSACTION_CODE_NOP_IN = 0x20,
112*1349a733SJaeyoon Choi 	UFSHCI_UPIU_TRANSACTION_CODE_RESPONSE = 0x21,
113*1349a733SJaeyoon Choi 	UFSHCI_UPIU_TRANSACTION_CODE_DATA_IN = 0x22,
114*1349a733SJaeyoon Choi 	UFSHCI_UPIU_TRANSACTION_CODE_TASK_MANAGEMENT_RESPONSE = 0x24,
115*1349a733SJaeyoon Choi 	UFSHCI_UPIU_TRANSACTION_CODE_READY_TO_TRANSFER = 0x31,
116*1349a733SJaeyoon Choi 	UFSHCI_UPIU_TRANSACTION_CODE_QUERY_RESPONSE = 0x36,
117*1349a733SJaeyoon Choi 	UFSHCI_UPIU_TRANSACTION_CODE_REJECT_UPIU = 0x3f,
118*1349a733SJaeyoon Choi };
119*1349a733SJaeyoon Choi 
120*1349a733SJaeyoon Choi enum overall_command_status {
121*1349a733SJaeyoon Choi 	UFSHCI_DESC_SUCCESS = 0x0,
122*1349a733SJaeyoon Choi 	UFSHCI_DESC_INVALID_COMMAND_TABLE_ATTRIBUTES = 0x01,
123*1349a733SJaeyoon Choi 	UFSHCI_DESC_INVALID_PRDT_ATTRIBUTES = 0x02,
124*1349a733SJaeyoon Choi 	UFSHCI_DESC_MISMATCH_DATA_BUFFER_SIZE = 0x03,
125*1349a733SJaeyoon Choi 	UFSHCI_DESC_MISMATCH_RESPONSE_UPIU_SIZE = 0x04,
126*1349a733SJaeyoon Choi 	UFSHCI_DESC_COMMUNICATION_FAILURE_WITHIN_UIC_LAYERS = 0x05,
127*1349a733SJaeyoon Choi 	UFSHCI_DESC_ABORTED = 0x06,
128*1349a733SJaeyoon Choi 	UFSHCI_DESC_HOST_CONTROLLER_FATAL_ERROR = 0x07,
129*1349a733SJaeyoon Choi 	UFSHCI_DESC_DEVICEFATALERROR = 0x08,
130*1349a733SJaeyoon Choi 	UFSHCI_DESC_INVALID_CRYPTO_CONFIGURATION = 0x09,
131*1349a733SJaeyoon Choi 	UFSHCI_DESC_GENERAL_CRYPTO_ERROR = 0x0A,
132*1349a733SJaeyoon Choi 	UFSHCI_DESC_INVALID = 0x0F,
133*1349a733SJaeyoon Choi };
134*1349a733SJaeyoon Choi 
135*1349a733SJaeyoon Choi enum response_code {
136*1349a733SJaeyoon Choi 	UFSHCI_RESPONSE_CODE_TARGET_SUCCESS = 0x00,
137*1349a733SJaeyoon Choi 	UFSHCI_RESPONSE_CODE_TARGET_FAILURE = 0x01,
138*1349a733SJaeyoon Choi 	UFSHCI_RESPONSE_CODE_PARAMETER_NOTREADABLE = 0xF6,
139*1349a733SJaeyoon Choi 	UFSHCI_RESPONSE_CODE_PARAMETER_NOTWRITEABLE = 0xF7,
140*1349a733SJaeyoon Choi 	UFSHCI_RESPONSE_CODE_PARAMETER_ALREADYWRITTEN = 0xF8,
141*1349a733SJaeyoon Choi 	UFSHCI_RESPONSE_CODE_INVALID_LENGTH = 0xF9,
142*1349a733SJaeyoon Choi 	UFSHCI_RESPONSE_CODE_INVALID_VALUE = 0xFA,
143*1349a733SJaeyoon Choi 	UFSHCI_RESPONSE_CODE_INVALID_SELECTOR = 0xFB,
144*1349a733SJaeyoon Choi 	UFSHCI_RESPONSE_CODE_INVALID_INDEX = 0xFC,
145*1349a733SJaeyoon Choi 	UFSHCI_RESPONSE_CODE_INVALID_IDN = 0xFD,
146*1349a733SJaeyoon Choi 	UFSHCI_RESPONSE_CODE_INVALID_OPCODE = 0xFE,
147*1349a733SJaeyoon Choi 	UFSHCI_RESPONSE_CODE_GENERAL_FAILURE = 0xFF,
148*1349a733SJaeyoon Choi };
149*1349a733SJaeyoon Choi 
150*1349a733SJaeyoon Choi /* UFSHCI spec 4.1, section 6.1.1 "UTP Transfer Request Descriptor" */
151*1349a733SJaeyoon Choi enum ufshci_command_type {
152*1349a733SJaeyoon Choi 	UFSHCI_COMMAND_TYPE_UFS_STORAGE = 0x01,
153*1349a733SJaeyoon Choi 	UFSHCI_COMMAND_TYPE_NULLIFIED_UTRD = 0x0F,
154*1349a733SJaeyoon Choi };
155*1349a733SJaeyoon Choi 
156*1349a733SJaeyoon Choi enum ufshci_data_direction {
157*1349a733SJaeyoon Choi 	UFSHCI_DATA_DIRECTION_NO_DATA_TRANSFER = 0x00,
158*1349a733SJaeyoon Choi 	UFSHCI_DATA_DIRECTION_FROM_SYS_TO_TGT = 0x01,
159*1349a733SJaeyoon Choi 	UFSHCI_DATA_DIRECTION_FROM_TGT_TO_SYS = 0x10,
160*1349a733SJaeyoon Choi 	UFSHCI_DATA_DIRECTION_RESERVED = 0b11,
161*1349a733SJaeyoon Choi };
162*1349a733SJaeyoon Choi 
163*1349a733SJaeyoon Choi enum ufshci_overall_command_status {
164*1349a733SJaeyoon Choi 	UFSHCI_OCS_SUCCESS = 0x0,
165*1349a733SJaeyoon Choi 	UFSHCI_OCS_INVALID_COMMAND_TABLE_ATTRIBUTES = 0x01,
166*1349a733SJaeyoon Choi 	UFSHCI_OCS_INVALID_PRDT_ATTRIBUTES = 0x02,
167*1349a733SJaeyoon Choi 	UFSHCI_OCS_MISMATCH_DATA_BUFFER_SIZE = 0x03,
168*1349a733SJaeyoon Choi 	UFSHCI_OCS_MISMATCH_RESPONSE_UPIU_SIZE = 0x04,
169*1349a733SJaeyoon Choi 	UFSHCI_OCS_COMMUNICATION_FAILURE_WITHIN_UIC_LAYERS = 0x05,
170*1349a733SJaeyoon Choi 	UFSHCI_OCS_ABORTED = 0x06,
171*1349a733SJaeyoon Choi 	UFSHCI_OCS_HOST_CONTROLLER_FATAL_ERROR = 0x07,
172*1349a733SJaeyoon Choi 	UFSHCI_OCS_DEVICE_FATAL_ERROR = 0x08,
173*1349a733SJaeyoon Choi 	UFSHCI_OCS_INVALID_CRYPTO_CONFIGURATION = 0x09,
174*1349a733SJaeyoon Choi 	UFSHCI_OCS_GENERAL_CRYPTO_ERROR = 0x0A,
175*1349a733SJaeyoon Choi 	UFSHCI_OCS_INVALID = 0xF,
176*1349a733SJaeyoon Choi };
177*1349a733SJaeyoon Choi 
178*1349a733SJaeyoon Choi struct ufshci_utp_xfer_req_desc {
179*1349a733SJaeyoon Choi 	/* dword 0 */
180*1349a733SJaeyoon Choi 	uint32_t cci : 8;	       /* [7:0] */
181*1349a733SJaeyoon Choi 	uint32_t total_ehs_length : 8; /* [15:8] */
182*1349a733SJaeyoon Choi 	uint32_t reserved0 : 7;	       /* [22:16] */
183*1349a733SJaeyoon Choi 	uint32_t ce : 1;	       /* [23] */
184*1349a733SJaeyoon Choi 	uint32_t interrupt : 1;	       /* [24] */
185*1349a733SJaeyoon Choi 	uint32_t data_direction : 2;   /* [26:25] */
186*1349a733SJaeyoon Choi 	uint32_t reserved1 : 1;	       /* [27] */
187*1349a733SJaeyoon Choi 	uint32_t command_type : 4;     /* [31:28] */
188*1349a733SJaeyoon Choi 
189*1349a733SJaeyoon Choi 	/* dword 1 */
190*1349a733SJaeyoon Choi 	uint32_t data_unit_number_lower; /* [31:0] */
191*1349a733SJaeyoon Choi 
192*1349a733SJaeyoon Choi 	/* dword 2 */
193*1349a733SJaeyoon Choi 	uint8_t overall_command_status; /* [7:0] */
194*1349a733SJaeyoon Choi 	uint8_t common_data_size;	/* [15:8] */
195*1349a733SJaeyoon Choi 	uint16_t last_data_byte_count;	/* [31:16] */
196*1349a733SJaeyoon Choi 
197*1349a733SJaeyoon Choi 	/* dword 3 */
198*1349a733SJaeyoon Choi 	uint32_t data_unit_number_upper; /* [31:0] */
199*1349a733SJaeyoon Choi 
200*1349a733SJaeyoon Choi 	/* dword 4 */
201*1349a733SJaeyoon Choi 	uint32_t utp_command_descriptor_base_address; /* [31:0] */
202*1349a733SJaeyoon Choi 
203*1349a733SJaeyoon Choi 	/* dword 5 */
204*1349a733SJaeyoon Choi 	uint32_t utp_command_descriptor_base_address_upper; /* [31:0] */
205*1349a733SJaeyoon Choi 
206*1349a733SJaeyoon Choi 	/* dword 6 */
207*1349a733SJaeyoon Choi 	uint16_t response_upiu_length; /* [15:0] */
208*1349a733SJaeyoon Choi 	uint16_t response_upiu_offset; /* [31:16] */
209*1349a733SJaeyoon Choi 
210*1349a733SJaeyoon Choi 	/* dword 7 */
211*1349a733SJaeyoon Choi 	uint16_t prdt_length; /* [15:0] */
212*1349a733SJaeyoon Choi 	uint16_t prdt_offset; /* [31:16] */
213*1349a733SJaeyoon Choi } __packed __aligned(8);
214*1349a733SJaeyoon Choi 
215*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_utp_xfer_req_desc) == 32,
216*1349a733SJaeyoon Choi     "ufshci_utp_xfer_req_desc must be 32 bytes");
217*1349a733SJaeyoon Choi 
218*1349a733SJaeyoon Choi /*
219*1349a733SJaeyoon Choi  * According to the UFSHCI specification, the size of the UTP command
220*1349a733SJaeyoon Choi  * descriptor is as follows. The size of the transfer request is not limited,
221*1349a733SJaeyoon Choi  * a transfer response can be as long as 65535 * dwords, and a PRDT can be as
222*1349a733SJaeyoon Choi  * long as 65565 * PRDT entry size(16 bytes). However, for ease of use, this
223*1349a733SJaeyoon Choi  * UFSHCI Driver imposes the following limits. The size of the transfer
224*1349a733SJaeyoon Choi  * request and the transfer response is 1024 bytes or less. The PRDT region
225*1349a733SJaeyoon Choi  * limits the number of scatter gathers to 256 + 1, using a total of 4096 +
226*1349a733SJaeyoon Choi  * 16 bytes. Therefore, only 8KB size is allocated for the UTP command
227*1349a733SJaeyoon Choi  * descriptor.
228*1349a733SJaeyoon Choi  */
229*1349a733SJaeyoon Choi #define UFSHCI_UTP_COMMAND_DESCRIPTOR_SIZE 8192
230*1349a733SJaeyoon Choi #define UFSHCI_UTP_XFER_REQ_SIZE	   512
231*1349a733SJaeyoon Choi #define UFSHCI_UTP_XFER_RESP_SIZE	   512
232*1349a733SJaeyoon Choi 
233*1349a733SJaeyoon Choi /*
234*1349a733SJaeyoon Choi  * To reduce the size of the UTP Command Descriptor(8KB), we must use only
235*1349a733SJaeyoon Choi  * 256 + 1 PRDT entries. The reason for adding the 1 is that if the data is
236*1349a733SJaeyoon Choi  * not aligned, one additional PRDT_ENTRY is used.
237*1349a733SJaeyoon Choi  */
238*1349a733SJaeyoon Choi #define UFSHCI_MAX_PRDT_ENTRY_COUNT (256 + 1)
239*1349a733SJaeyoon Choi 
240*1349a733SJaeyoon Choi /* UFSHCI spec 4.1, section 6.1.2 "UTP Command Descriptor" */
241*1349a733SJaeyoon Choi struct ufshci_prdt_entry {
242*1349a733SJaeyoon Choi 	/* dword 0 */
243*1349a733SJaeyoon Choi 	uint32_t data_base_address; /* [31:0] */
244*1349a733SJaeyoon Choi 
245*1349a733SJaeyoon Choi 	/* dword 1 */
246*1349a733SJaeyoon Choi 	uint32_t data_base_address_upper; /* [31:0] */
247*1349a733SJaeyoon Choi 
248*1349a733SJaeyoon Choi 	/* dword 2 */
249*1349a733SJaeyoon Choi 	uint32_t reserved; /* [31:0] */
250*1349a733SJaeyoon Choi 
251*1349a733SJaeyoon Choi 	/* dword 3 */
252*1349a733SJaeyoon Choi 	uint32_t data_byte_count; /* [17:0] Maximum byte
253*1349a733SJaeyoon Choi 				   * count is 256KB */
254*1349a733SJaeyoon Choi } __packed __aligned(8);
255*1349a733SJaeyoon Choi 
256*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_prdt_entry) == 16,
257*1349a733SJaeyoon Choi     "ufshci_prdt_entry must be 16 bytes");
258*1349a733SJaeyoon Choi 
259*1349a733SJaeyoon Choi struct ufshci_utp_cmd_desc {
260*1349a733SJaeyoon Choi 	uint8_t command_upiu[UFSHCI_UTP_XFER_REQ_SIZE];
261*1349a733SJaeyoon Choi 	uint8_t response_upiu[UFSHCI_UTP_XFER_RESP_SIZE];
262*1349a733SJaeyoon Choi 	uint8_t prd_table[sizeof(struct ufshci_prdt_entry) *
263*1349a733SJaeyoon Choi 	    UFSHCI_MAX_PRDT_ENTRY_COUNT];
264*1349a733SJaeyoon Choi 	uint8_t padding[3072 - sizeof(struct ufshci_prdt_entry)];
265*1349a733SJaeyoon Choi } __packed __aligned(128);
266*1349a733SJaeyoon Choi 
267*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_utp_cmd_desc) ==
268*1349a733SJaeyoon Choi 	UFSHCI_UTP_COMMAND_DESCRIPTOR_SIZE,
269*1349a733SJaeyoon Choi     "ufshci_utp_cmd_desc must be 8192 bytes");
270*1349a733SJaeyoon Choi 
271*1349a733SJaeyoon Choi #define UFSHCI_UTP_TASK_MGMT_REQ_SIZE  32
272*1349a733SJaeyoon Choi #define UFSHCI_UTP_TASK_MGMT_RESP_SIZE 32
273*1349a733SJaeyoon Choi 
274*1349a733SJaeyoon Choi /* UFSHCI spec 4.1, section 6.3.1 "UTP Task Management Request Descriptor" */
275*1349a733SJaeyoon Choi struct ufshci_utp_task_mgmt_req_desc {
276*1349a733SJaeyoon Choi 	/* dword 0 */
277*1349a733SJaeyoon Choi 	uint32_t reserved0 : 24; /* [23:0] */
278*1349a733SJaeyoon Choi 	uint32_t interrupt : 1;	 /* [24] */
279*1349a733SJaeyoon Choi 	uint32_t reserved1 : 7;	 /* [31:25] */
280*1349a733SJaeyoon Choi 
281*1349a733SJaeyoon Choi 	/* dword 1 */
282*1349a733SJaeyoon Choi 	uint32_t reserved2; /* [31:0] */
283*1349a733SJaeyoon Choi 
284*1349a733SJaeyoon Choi 	/* dword 2 */
285*1349a733SJaeyoon Choi 	uint8_t overall_command_status; /* [7:0] */
286*1349a733SJaeyoon Choi 	uint8_t reserved3;		/* [15:8] */
287*1349a733SJaeyoon Choi 	uint16_t reserved4;		/* [31:16] */
288*1349a733SJaeyoon Choi 
289*1349a733SJaeyoon Choi 	/* dword 3 */
290*1349a733SJaeyoon Choi 	uint32_t reserved5; /* [31:0] */
291*1349a733SJaeyoon Choi 
292*1349a733SJaeyoon Choi 	/* dword 4-11 */
293*1349a733SJaeyoon Choi 	uint8_t request_upiu[UFSHCI_UTP_TASK_MGMT_REQ_SIZE];
294*1349a733SJaeyoon Choi 
295*1349a733SJaeyoon Choi 	/* dword 12-19 */
296*1349a733SJaeyoon Choi 	uint8_t response_upiu[UFSHCI_UTP_TASK_MGMT_RESP_SIZE];
297*1349a733SJaeyoon Choi 
298*1349a733SJaeyoon Choi } __packed __aligned(8);
299*1349a733SJaeyoon Choi 
300*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_utp_task_mgmt_req_desc) == 80,
301*1349a733SJaeyoon Choi     "ufshci_utp_task_mgmt_req_desc must be 80 bytes");
302*1349a733SJaeyoon Choi 
303*1349a733SJaeyoon Choi /* UFS spec 4.1, section 10.6.2 "Basic Header Format" */
304*1349a733SJaeyoon Choi struct ufshci_upiu_header {
305*1349a733SJaeyoon Choi 	/* dword 0 */
306*1349a733SJaeyoon Choi 	union {
307*1349a733SJaeyoon Choi 		struct {
308*1349a733SJaeyoon Choi 			uint8_t trans_code : 6; /* [5:0] */
309*1349a733SJaeyoon Choi 			uint8_t dd : 1;		/* [6] */
310*1349a733SJaeyoon Choi 			uint8_t hd : 1;		/* [7] */
311*1349a733SJaeyoon Choi 		};
312*1349a733SJaeyoon Choi 		uint8_t trans_type;
313*1349a733SJaeyoon Choi 	};
314*1349a733SJaeyoon Choi 	union {
315*1349a733SJaeyoon Choi 		struct {
316*1349a733SJaeyoon Choi 			uint8_t task_attribute : 2;	  /* [1:0] */
317*1349a733SJaeyoon Choi 			uint8_t cp : 1;			  /* [2] */
318*1349a733SJaeyoon Choi 			uint8_t retransmit_indicator : 1; /* [3] */
319*1349a733SJaeyoon Choi #define UFSHCI_OPERATIONAL_FLAG_W 0x2
320*1349a733SJaeyoon Choi #define UFSHCI_OPERATIONAL_FLAG_R 0x4
321*1349a733SJaeyoon Choi 			uint8_t operational_flags : 4; /* [7:4] */
322*1349a733SJaeyoon Choi 		};
323*1349a733SJaeyoon Choi 		uint8_t flags;
324*1349a733SJaeyoon Choi 	};
325*1349a733SJaeyoon Choi 	uint8_t lun;
326*1349a733SJaeyoon Choi 	uint8_t task_tag;
327*1349a733SJaeyoon Choi 
328*1349a733SJaeyoon Choi 	/* dword 1 */
329*1349a733SJaeyoon Choi #define UFSHCI_COMMAND_SET_TYPE_SCSI 0
330*1349a733SJaeyoon Choi 	uint8_t cmd_set_type : 4; /* [3:0] */
331*1349a733SJaeyoon Choi 	uint8_t iid : 4;	  /* [7:4] */
332*1349a733SJaeyoon Choi 	uint8_t ext_iid_or_function;
333*1349a733SJaeyoon Choi 	uint8_t response;
334*1349a733SJaeyoon Choi 	uint8_t ext_iid_or_status;
335*1349a733SJaeyoon Choi 
336*1349a733SJaeyoon Choi 	/* dword 2 */
337*1349a733SJaeyoon Choi 	uint8_t ehs_length;
338*1349a733SJaeyoon Choi 	uint8_t device_infomation;
339*1349a733SJaeyoon Choi 	uint16_t data_segment_length; /* (Big-endian) */
340*1349a733SJaeyoon Choi } __packed __aligned(4);
341*1349a733SJaeyoon Choi 
342*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_upiu_header) == 12,
343*1349a733SJaeyoon Choi     "ufshci_upiu_header must be 12 bytes");
344*1349a733SJaeyoon Choi 
345*1349a733SJaeyoon Choi #define UFSHCI_MAX_UPIU_SIZE  512
346*1349a733SJaeyoon Choi #define UFSHCI_UPIU_ALIGNMENT 8 /* UPIU requires 64-bit alignment. */
347*1349a733SJaeyoon Choi 
348*1349a733SJaeyoon Choi struct ufshci_upiu {
349*1349a733SJaeyoon Choi 	/* dword 0-2 */
350*1349a733SJaeyoon Choi 	struct ufshci_upiu_header header;
351*1349a733SJaeyoon Choi 	/* dword 3-127 */
352*1349a733SJaeyoon Choi 	uint8_t
353*1349a733SJaeyoon Choi 	    reserved[UFSHCI_MAX_UPIU_SIZE - sizeof(struct ufshci_upiu_header)];
354*1349a733SJaeyoon Choi } __packed __aligned(8);
355*1349a733SJaeyoon Choi 
356*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_upiu) == 512,
357*1349a733SJaeyoon Choi     "ufshci_upiu must be 512 bytes");
358*1349a733SJaeyoon Choi 
359*1349a733SJaeyoon Choi struct ufshci_cmd_command_upiu {
360*1349a733SJaeyoon Choi 	/* dword 0-2 */
361*1349a733SJaeyoon Choi 	struct ufshci_upiu_header header;
362*1349a733SJaeyoon Choi 	/* dword 3 */
363*1349a733SJaeyoon Choi 	uint32_t expected_data_transfer_length; /* (Big-endian) */
364*1349a733SJaeyoon Choi 
365*1349a733SJaeyoon Choi 	/* dword 4-7 */
366*1349a733SJaeyoon Choi 	uint8_t cdb[16];
367*1349a733SJaeyoon Choi 
368*1349a733SJaeyoon Choi } __packed __aligned(4);
369*1349a733SJaeyoon Choi 
370*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_cmd_command_upiu) == 32,
371*1349a733SJaeyoon Choi     "bad size for ufshci_cmd_command_upiu");
372*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_cmd_command_upiu) <=
373*1349a733SJaeyoon Choi 	UFSHCI_UTP_XFER_REQ_SIZE,
374*1349a733SJaeyoon Choi     "bad size for ufshci_cmd_command_upiu");
375*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_cmd_command_upiu) % UFSHCI_UPIU_ALIGNMENT ==
376*1349a733SJaeyoon Choi 	0,
377*1349a733SJaeyoon Choi     "UPIU requires 64-bit alignment");
378*1349a733SJaeyoon Choi 
379*1349a733SJaeyoon Choi struct ufshci_cmd_response_upiu {
380*1349a733SJaeyoon Choi 	/* dword 0-2 */
381*1349a733SJaeyoon Choi 	struct ufshci_upiu_header header;
382*1349a733SJaeyoon Choi 	/* dword 3 */
383*1349a733SJaeyoon Choi 	uint32_t residual_transfer_count; /* (Big-endian) */
384*1349a733SJaeyoon Choi 
385*1349a733SJaeyoon Choi 	/* dword 4-7 */
386*1349a733SJaeyoon Choi 	uint8_t reserved[16];
387*1349a733SJaeyoon Choi 
388*1349a733SJaeyoon Choi 	/* Sense Data */
389*1349a733SJaeyoon Choi 	uint16_t sense_data_len; /* (Big-endian) */
390*1349a733SJaeyoon Choi 	uint8_t sense_data[18];
391*1349a733SJaeyoon Choi 
392*1349a733SJaeyoon Choi 	/* Add padding to align the kUpiuAlignment. */
393*1349a733SJaeyoon Choi 	uint8_t padding[4];
394*1349a733SJaeyoon Choi } __packed __aligned(4);
395*1349a733SJaeyoon Choi 
396*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_cmd_response_upiu) == 56,
397*1349a733SJaeyoon Choi     "bad size for ufshci_cmd_response_upiu");
398*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_cmd_response_upiu) <=
399*1349a733SJaeyoon Choi 	UFSHCI_UTP_XFER_RESP_SIZE,
400*1349a733SJaeyoon Choi     "bad size for ufshci_cmd_response_upiu");
401*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_cmd_response_upiu) %
402*1349a733SJaeyoon Choi 	    UFSHCI_UPIU_ALIGNMENT ==
403*1349a733SJaeyoon Choi 	0,
404*1349a733SJaeyoon Choi     "UPIU requires 64-bit alignment");
405*1349a733SJaeyoon Choi 
406*1349a733SJaeyoon Choi /* UFS Spec 4.1, section 10.7.8 "QUERY REQUEST UPIU" */
407*1349a733SJaeyoon Choi enum ufshci_query_function {
408*1349a733SJaeyoon Choi 	UFSHCI_QUERY_FUNC_STANDARD_READ_REQUEST = 0x01,
409*1349a733SJaeyoon Choi 	UFSHCI_QUERY_FUNC_STANDARD_WRITE_REQUEST = 0x81,
410*1349a733SJaeyoon Choi };
411*1349a733SJaeyoon Choi 
412*1349a733SJaeyoon Choi enum ufshci_query_opcode {
413*1349a733SJaeyoon Choi 	UFSHCI_QUERY_OPCODE_NOP = 0,
414*1349a733SJaeyoon Choi 	UFSHCI_QUERY_OPCODE_READ_DESCRIPTOR,
415*1349a733SJaeyoon Choi 	UFSHCI_QUERY_OPCODE_WRITE_DESCRIPTOR,
416*1349a733SJaeyoon Choi 	UFSHCI_QUERY_OPCODE_READ_ATTRIBUTE,
417*1349a733SJaeyoon Choi 	UFSHCI_QUERY_OPCODE_WRITE_ATTRIBUTE,
418*1349a733SJaeyoon Choi 	UFSHCI_QUERY_OPCODE_READ_FLAG,
419*1349a733SJaeyoon Choi 	UFSHCI_QUERY_OPCODE_SET_FLAG,
420*1349a733SJaeyoon Choi 	UFSHCI_QUERY_OPCODE_CLEAR_FLAG,
421*1349a733SJaeyoon Choi 	UFSHCI_QUERY_OPCODE_TOGGLE_FLAG,
422*1349a733SJaeyoon Choi };
423*1349a733SJaeyoon Choi 
424*1349a733SJaeyoon Choi struct ufshci_query_param {
425*1349a733SJaeyoon Choi 	enum ufshci_query_function function;
426*1349a733SJaeyoon Choi 	enum ufshci_query_opcode opcode;
427*1349a733SJaeyoon Choi 	uint8_t type;
428*1349a733SJaeyoon Choi 	uint8_t index;
429*1349a733SJaeyoon Choi 	uint8_t selector;
430*1349a733SJaeyoon Choi 	uint64_t value;
431*1349a733SJaeyoon Choi 	size_t desc_size;
432*1349a733SJaeyoon Choi };
433*1349a733SJaeyoon Choi 
434*1349a733SJaeyoon Choi struct ufshci_query_request_upiu {
435*1349a733SJaeyoon Choi 	/* dword 0-2 */
436*1349a733SJaeyoon Choi 	struct ufshci_upiu_header header;
437*1349a733SJaeyoon Choi 	/* dword 3 */
438*1349a733SJaeyoon Choi 	uint8_t opcode;
439*1349a733SJaeyoon Choi 	uint8_t idn;
440*1349a733SJaeyoon Choi 	uint8_t index;
441*1349a733SJaeyoon Choi 	uint8_t selector;
442*1349a733SJaeyoon Choi 
443*1349a733SJaeyoon Choi 	/* dword 4-5 */
444*1349a733SJaeyoon Choi 	union {
445*1349a733SJaeyoon Choi 		/* The Write Attribute opcode uses 64 - bit value. */
446*1349a733SJaeyoon Choi 		uint64_t value_64; /* (Big-endian) */
447*1349a733SJaeyoon Choi 		struct {
448*1349a733SJaeyoon Choi 			uint8_t reserved1[2];
449*1349a733SJaeyoon Choi 			uint16_t length;   /* (Big-endian) */
450*1349a733SJaeyoon Choi 			uint32_t value_32; /* (Big-endian) */
451*1349a733SJaeyoon Choi 		};
452*1349a733SJaeyoon Choi 	} __packed __aligned(4);
453*1349a733SJaeyoon Choi 
454*1349a733SJaeyoon Choi 	/* dword 6 */
455*1349a733SJaeyoon Choi 	uint32_t reserved2;
456*1349a733SJaeyoon Choi 
457*1349a733SJaeyoon Choi 	/* dword 7 */
458*1349a733SJaeyoon Choi 	uint32_t reserved3;
459*1349a733SJaeyoon Choi 
460*1349a733SJaeyoon Choi 	uint8_t command_data[256];
461*1349a733SJaeyoon Choi } __packed __aligned(4);
462*1349a733SJaeyoon Choi 
463*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_query_request_upiu) == 288,
464*1349a733SJaeyoon Choi     "bad size for ufshci_query_request_upiu");
465*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_query_request_upiu) <=
466*1349a733SJaeyoon Choi 	UFSHCI_UTP_XFER_REQ_SIZE,
467*1349a733SJaeyoon Choi     "bad size for ufshci_query_request_upiu");
468*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_query_request_upiu) %
469*1349a733SJaeyoon Choi 	    UFSHCI_UPIU_ALIGNMENT ==
470*1349a733SJaeyoon Choi 	0,
471*1349a733SJaeyoon Choi     "UPIU requires 64-bit alignment");
472*1349a733SJaeyoon Choi 
473*1349a733SJaeyoon Choi /* UFS Spec 4.1, section 10.7.9 "QUERY RESPONSE UPIU" */
474*1349a733SJaeyoon Choi enum ufshci_query_response_code {
475*1349a733SJaeyoon Choi 	UFSHCI_QUERY_RESP_CODE_SUCCESS = 0x00,
476*1349a733SJaeyoon Choi 	UFSHCI_QUERY_RESP_CODE_PARAMETER_NOT_READABLE = 0xf6,
477*1349a733SJaeyoon Choi 	UFSHCI_QUERY_RESP_CODE_PARAMETER_NOT_WRITEABLE = 0xf7,
478*1349a733SJaeyoon Choi 	UFSHCI_QUERY_RESP_CODE_PARAMETER_ALREADY_WRITTEN = 0xf8,
479*1349a733SJaeyoon Choi 	UFSHCI_QUERY_RESP_CODE_INVALID_LENGTH = 0xf9,
480*1349a733SJaeyoon Choi 	UFSHCI_QUERY_RESP_CODE_INVALID_VALUE = 0xfa,
481*1349a733SJaeyoon Choi 	UFSHCI_QUERY_RESP_CODE_INVALID_SELECTOR = 0xfb,
482*1349a733SJaeyoon Choi 	UFSHCI_QUERY_RESP_CODE_INVALID_INDEX = 0xfc,
483*1349a733SJaeyoon Choi 	UFSHCI_QUERY_RESP_CODE_INVALID_IDN = 0xfd,
484*1349a733SJaeyoon Choi 	UFSHCI_QUERY_RESP_CODE_INVALID_OPCODE = 0xfe,
485*1349a733SJaeyoon Choi 	UFSHCI_QUERY_RESP_CODE_GENERAL_FAILURE = 0xff,
486*1349a733SJaeyoon Choi };
487*1349a733SJaeyoon Choi 
488*1349a733SJaeyoon Choi struct ufshci_query_response_upiu {
489*1349a733SJaeyoon Choi 	/* dword 0-2 */
490*1349a733SJaeyoon Choi 	struct ufshci_upiu_header header;
491*1349a733SJaeyoon Choi 	/* dword 3 */
492*1349a733SJaeyoon Choi 	uint8_t opcode;
493*1349a733SJaeyoon Choi 	uint8_t idn;
494*1349a733SJaeyoon Choi 	uint8_t index;
495*1349a733SJaeyoon Choi 	uint8_t selector;
496*1349a733SJaeyoon Choi 
497*1349a733SJaeyoon Choi 	/* dword 4-5 */
498*1349a733SJaeyoon Choi 	union {
499*1349a733SJaeyoon Choi 		/* The Read / Write Attribute opcodes use 64 - bit value. */
500*1349a733SJaeyoon Choi 		uint64_t value_64; /* (Big-endian) */
501*1349a733SJaeyoon Choi 		struct {
502*1349a733SJaeyoon Choi 			uint8_t reserved1[2];
503*1349a733SJaeyoon Choi 			uint16_t length; /* (Big-endian) */
504*1349a733SJaeyoon Choi 			union {
505*1349a733SJaeyoon Choi 				uint32_t value_32; /* (Big-endian) */
506*1349a733SJaeyoon Choi 				struct {
507*1349a733SJaeyoon Choi 					uint8_t reserved2[3];
508*1349a733SJaeyoon Choi 					uint8_t flag_value;
509*1349a733SJaeyoon Choi 				};
510*1349a733SJaeyoon Choi 			};
511*1349a733SJaeyoon Choi 		};
512*1349a733SJaeyoon Choi 	} __packed __aligned(4);
513*1349a733SJaeyoon Choi 
514*1349a733SJaeyoon Choi 	/* dword 6 */
515*1349a733SJaeyoon Choi 	uint8_t reserved3[4];
516*1349a733SJaeyoon Choi 
517*1349a733SJaeyoon Choi 	/* dword 7 */
518*1349a733SJaeyoon Choi 	uint8_t reserved4[4];
519*1349a733SJaeyoon Choi 
520*1349a733SJaeyoon Choi 	uint8_t command_data[256];
521*1349a733SJaeyoon Choi } __packed __aligned(4);
522*1349a733SJaeyoon Choi 
523*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_query_response_upiu) == 288,
524*1349a733SJaeyoon Choi     "bad size for ufshci_query_response_upiu");
525*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_query_response_upiu) <=
526*1349a733SJaeyoon Choi 	UFSHCI_UTP_XFER_RESP_SIZE,
527*1349a733SJaeyoon Choi     "bad size for ufshci_query_response_upiu");
528*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_query_response_upiu) %
529*1349a733SJaeyoon Choi 	    UFSHCI_UPIU_ALIGNMENT ==
530*1349a733SJaeyoon Choi 	0,
531*1349a733SJaeyoon Choi     "UPIU requires 64-bit alignment");
532*1349a733SJaeyoon Choi 
533*1349a733SJaeyoon Choi /* UFS 4.1, section 10.7.11 "NOP OUT UPIU" */
534*1349a733SJaeyoon Choi struct ufshci_nop_out_upiu {
535*1349a733SJaeyoon Choi 	/* dword 0-2 */
536*1349a733SJaeyoon Choi 	struct ufshci_upiu_header header;
537*1349a733SJaeyoon Choi 	/* dword 3-7 */
538*1349a733SJaeyoon Choi 	uint8_t reserved[20];
539*1349a733SJaeyoon Choi } __packed __aligned(8);
540*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_nop_out_upiu) == 32,
541*1349a733SJaeyoon Choi     "ufshci_upiu_nop_out must be 32 bytes");
542*1349a733SJaeyoon Choi 
543*1349a733SJaeyoon Choi /* UFS 4.1, section 10.7.12 "NOP IN UPIU" */
544*1349a733SJaeyoon Choi struct ufshci_nop_in_upiu {
545*1349a733SJaeyoon Choi 	/* dword 0-2 */
546*1349a733SJaeyoon Choi 	struct ufshci_upiu_header header;
547*1349a733SJaeyoon Choi 	/* dword 3-7 */
548*1349a733SJaeyoon Choi 	uint8_t reserved[20];
549*1349a733SJaeyoon Choi } __packed __aligned(8);
550*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_nop_in_upiu) == 32,
551*1349a733SJaeyoon Choi     "ufshci_upiu_nop_in must be 32 bytes");
552*1349a733SJaeyoon Choi 
553*1349a733SJaeyoon Choi union ufshci_reponse_upiu {
554*1349a733SJaeyoon Choi 	struct ufshci_upiu_header header;
555*1349a733SJaeyoon Choi 	struct ufshci_cmd_response_upiu cmd_response_upiu;
556*1349a733SJaeyoon Choi 	struct ufshci_query_response_upiu query_response_upiu;
557*1349a733SJaeyoon Choi 	struct ufshci_nop_in_upiu nop_in_upiu;
558*1349a733SJaeyoon Choi };
559*1349a733SJaeyoon Choi 
560*1349a733SJaeyoon Choi struct ufshci_completion {
561*1349a733SJaeyoon Choi 	union ufshci_reponse_upiu response_upiu;
562*1349a733SJaeyoon Choi 	size_t size;
563*1349a733SJaeyoon Choi };
564*1349a733SJaeyoon Choi 
565*1349a733SJaeyoon Choi typedef void (*ufshci_cb_fn_t)(void *, const struct ufshci_completion *, bool);
566*1349a733SJaeyoon Choi 
567*1349a733SJaeyoon Choi /*
568*1349a733SJaeyoon Choi  * UFS Spec 4.1, section 14.1 "UFS Descriptors"
569*1349a733SJaeyoon Choi  * All descriptors use big-endian byte ordering.
570*1349a733SJaeyoon Choi  */
571*1349a733SJaeyoon Choi enum ufshci_descriptor_type {
572*1349a733SJaeyoon Choi 	UFSHCI_DESC_TYPE_DEVICE = 0x00,
573*1349a733SJaeyoon Choi 	UFSHCI_DESC_TYPE_CONFIGURATION = 0x01,
574*1349a733SJaeyoon Choi 	UFSHCI_DESC_TYPE_UNIT = 0x02,
575*1349a733SJaeyoon Choi 	UFSHCI_DESC_TYPE_INTERCONNECT = 0x04,
576*1349a733SJaeyoon Choi 	UFSHCI_DESC_TYPE_STRING = 0x05,
577*1349a733SJaeyoon Choi 	UFSHCI_DESC_TYPE_GEOMETRY = 0X07,
578*1349a733SJaeyoon Choi 	UFSHCI_DESC_TYPE_POWER = 0x08,
579*1349a733SJaeyoon Choi 	UFSHCI_DESC_TYPE_DEVICE_HEALTH = 0x09,
580*1349a733SJaeyoon Choi 	UFSHCI_DESC_TYPE_FBO_EXTENSION_SPECIFICATION = 0x0a,
581*1349a733SJaeyoon Choi };
582*1349a733SJaeyoon Choi 
583*1349a733SJaeyoon Choi /*
584*1349a733SJaeyoon Choi  * UFS Spec 4.1, section 14.1.5.2 "Device Descriptor"
585*1349a733SJaeyoon Choi  * DeviceDescriptor use big-endian byte ordering.
586*1349a733SJaeyoon Choi  */
587*1349a733SJaeyoon Choi struct ufshci_device_descriptor {
588*1349a733SJaeyoon Choi 	uint8_t bLength;
589*1349a733SJaeyoon Choi 	uint8_t bDescriptorIDN;
590*1349a733SJaeyoon Choi 	uint8_t bDevice;
591*1349a733SJaeyoon Choi 	uint8_t bDeviceClass;
592*1349a733SJaeyoon Choi 	uint8_t bDeviceSubClass;
593*1349a733SJaeyoon Choi 	uint8_t bProtocol;
594*1349a733SJaeyoon Choi 	uint8_t bNumberLU;
595*1349a733SJaeyoon Choi 	uint8_t bNumberWLU;
596*1349a733SJaeyoon Choi 	uint8_t bBootEnable;
597*1349a733SJaeyoon Choi 	uint8_t bDescrAccessEn;
598*1349a733SJaeyoon Choi 	uint8_t bInitPowerMode;
599*1349a733SJaeyoon Choi 	uint8_t bHighPriorityLUN;
600*1349a733SJaeyoon Choi 	uint8_t bSecureRemovalType;
601*1349a733SJaeyoon Choi 	uint8_t bSecurityLU;
602*1349a733SJaeyoon Choi 	uint8_t bBackgroundOpsTermLat;
603*1349a733SJaeyoon Choi 	uint8_t bInitActiveICCLevel;
604*1349a733SJaeyoon Choi 	/* 0x10 */
605*1349a733SJaeyoon Choi 	uint16_t wSpecVersion;
606*1349a733SJaeyoon Choi 	uint16_t wManufactureDate;
607*1349a733SJaeyoon Choi 	uint8_t iManufacturerName;
608*1349a733SJaeyoon Choi 	uint8_t iProductName;
609*1349a733SJaeyoon Choi 	uint8_t iSerialNumber;
610*1349a733SJaeyoon Choi 	uint8_t iOemID;
611*1349a733SJaeyoon Choi 	uint16_t wManufacturerID;
612*1349a733SJaeyoon Choi 	uint8_t bUD0BaseOffset;
613*1349a733SJaeyoon Choi 	uint8_t bUDConfigPLength;
614*1349a733SJaeyoon Choi 	uint8_t bDeviceRTTCap;
615*1349a733SJaeyoon Choi 	uint16_t wPeriodicRTCUpdate;
616*1349a733SJaeyoon Choi 	uint8_t bUfsFeaturesSupport;
617*1349a733SJaeyoon Choi 	/* 0x20 */
618*1349a733SJaeyoon Choi 	uint8_t bFFUTimeout;
619*1349a733SJaeyoon Choi 	uint8_t bQueueDepth;
620*1349a733SJaeyoon Choi 	uint16_t wDeviceVersion;
621*1349a733SJaeyoon Choi 	uint8_t bNumSecureWPArea;
622*1349a733SJaeyoon Choi 	uint32_t dPSAMaxDataSize;
623*1349a733SJaeyoon Choi 	uint8_t bPSAStateTimeout;
624*1349a733SJaeyoon Choi 	uint8_t iProductRevisionLevel;
625*1349a733SJaeyoon Choi 	uint8_t Reserved[5];
626*1349a733SJaeyoon Choi 	/* 0x2a */
627*1349a733SJaeyoon Choi 	/* 0x30 */
628*1349a733SJaeyoon Choi 	uint8_t ReservedUME[16];
629*1349a733SJaeyoon Choi 	/* 0x40 */
630*1349a733SJaeyoon Choi 	uint8_t ReservedHpb[3];
631*1349a733SJaeyoon Choi 	uint8_t Reserved2[12];
632*1349a733SJaeyoon Choi 	uint32_t dExtendedUfsFeaturesSupport;
633*1349a733SJaeyoon Choi 	uint8_t bWriteBoosterBufferPreserveUserSpaceEn;
634*1349a733SJaeyoon Choi 	uint8_t bWriteBoosterBufferType;
635*1349a733SJaeyoon Choi 	uint32_t dNumSharedWriteBoosterBufferAllocUnits;
636*1349a733SJaeyoon Choi } __packed;
637*1349a733SJaeyoon Choi 
638*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_device_descriptor) == 89,
639*1349a733SJaeyoon Choi     "bad size for ufshci_device_descriptor");
640*1349a733SJaeyoon Choi 
641*1349a733SJaeyoon Choi /*
642*1349a733SJaeyoon Choi  * UFS Spec 4.1, section 14.1.5.3 "Configuration Descriptor"
643*1349a733SJaeyoon Choi  * ConfigurationDescriptor use big-endian byte ordering.
644*1349a733SJaeyoon Choi  */
645*1349a733SJaeyoon Choi struct ufshci_unit_descriptor_configurable_parameters {
646*1349a733SJaeyoon Choi 	uint8_t bLUEnable;
647*1349a733SJaeyoon Choi 	uint8_t bBootLunID;
648*1349a733SJaeyoon Choi 	uint8_t bLUWriteProtect;
649*1349a733SJaeyoon Choi 	uint8_t bMemoryType;
650*1349a733SJaeyoon Choi 	uint32_t dNumAllocUnits;
651*1349a733SJaeyoon Choi 	uint8_t bDataReliability;
652*1349a733SJaeyoon Choi 	uint8_t bLogicalBlockSize;
653*1349a733SJaeyoon Choi 	uint8_t bProvisioningType;
654*1349a733SJaeyoon Choi 	uint16_t wContextCapabilities;
655*1349a733SJaeyoon Choi 	union {
656*1349a733SJaeyoon Choi 		struct {
657*1349a733SJaeyoon Choi 			uint8_t Reserved[3];
658*1349a733SJaeyoon Choi 			uint8_t ReservedHpb[6];
659*1349a733SJaeyoon Choi 		} __packed;
660*1349a733SJaeyoon Choi 		uint16_t wZoneBufferAllocUnits;
661*1349a733SJaeyoon Choi 	};
662*1349a733SJaeyoon Choi 	uint32_t dLUNumWriteBoosterBufferAllocUnits;
663*1349a733SJaeyoon Choi } __packed;
664*1349a733SJaeyoon Choi 
665*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_unit_descriptor_configurable_parameters) ==
666*1349a733SJaeyoon Choi 	27,
667*1349a733SJaeyoon Choi     "bad size for ufshci_unit_descriptor_configurable_parameters");
668*1349a733SJaeyoon Choi 
669*1349a733SJaeyoon Choi #define UFSHCI_CONFIGURATION_DESCEIPTOR_LU_NUM 8
670*1349a733SJaeyoon Choi 
671*1349a733SJaeyoon Choi struct ufshci_configuration_descriptor {
672*1349a733SJaeyoon Choi 	uint8_t bLength;
673*1349a733SJaeyoon Choi 	uint8_t bDescriptorIDN;
674*1349a733SJaeyoon Choi 	uint8_t bConfDescContinue;
675*1349a733SJaeyoon Choi 	uint8_t bBootEnable;
676*1349a733SJaeyoon Choi 	uint8_t bDescrAccessEn;
677*1349a733SJaeyoon Choi 	uint8_t bInitPowerMode;
678*1349a733SJaeyoon Choi 	uint8_t bHighPriorityLUN;
679*1349a733SJaeyoon Choi 	uint8_t bSecureRemovalType;
680*1349a733SJaeyoon Choi 	uint8_t bInitActiveICCLevel;
681*1349a733SJaeyoon Choi 	uint16_t wPeriodicRTCUpdate;
682*1349a733SJaeyoon Choi 	uint8_t Reserved;
683*1349a733SJaeyoon Choi 	uint8_t bRPMBRegionEnable;
684*1349a733SJaeyoon Choi 	uint8_t bRPMBRegion1Size;
685*1349a733SJaeyoon Choi 	uint8_t bRPMBRegion2Size;
686*1349a733SJaeyoon Choi 	uint8_t bRPMBRegion3Size;
687*1349a733SJaeyoon Choi 	uint8_t bWriteBoosterBufferPreserveUserSpaceEn;
688*1349a733SJaeyoon Choi 	uint8_t bWriteBoosterBufferType;
689*1349a733SJaeyoon Choi 	uint32_t dNumSharedWriteBoosterBufferAllocUnits;
690*1349a733SJaeyoon Choi 	/* 0x16 */
691*1349a733SJaeyoon Choi 	struct ufshci_unit_descriptor_configurable_parameters
692*1349a733SJaeyoon Choi 	    unit_config_params[UFSHCI_CONFIGURATION_DESCEIPTOR_LU_NUM];
693*1349a733SJaeyoon Choi } __packed;
694*1349a733SJaeyoon Choi 
695*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_configuration_descriptor) == (22 + 27 * 8),
696*1349a733SJaeyoon Choi     "bad size for ufshci_configuration_descriptor");
697*1349a733SJaeyoon Choi 
698*1349a733SJaeyoon Choi /*
699*1349a733SJaeyoon Choi  * UFS Spec 4.1, section 14.1.5.4 "Geometry Descriptor"
700*1349a733SJaeyoon Choi  * GeometryDescriptor use big-endian byte ordering.
701*1349a733SJaeyoon Choi  */
702*1349a733SJaeyoon Choi struct ufshci_geometry_descriptor {
703*1349a733SJaeyoon Choi 	uint8_t bLength;
704*1349a733SJaeyoon Choi 	uint8_t bDescriptorIDN;
705*1349a733SJaeyoon Choi 	uint8_t bMediaTechnology;
706*1349a733SJaeyoon Choi 	uint8_t Reserved;
707*1349a733SJaeyoon Choi 	uint64_t qTotalRawDeviceCapacity;
708*1349a733SJaeyoon Choi 	uint8_t bMaxNumberLU;
709*1349a733SJaeyoon Choi 	uint32_t dSegmentSize;
710*1349a733SJaeyoon Choi 	/* 0x11 */
711*1349a733SJaeyoon Choi 	uint8_t bAllocationUnitSize;
712*1349a733SJaeyoon Choi 	uint8_t bMinAddrBlockSize;
713*1349a733SJaeyoon Choi 	uint8_t bOptimalReadBlockSize;
714*1349a733SJaeyoon Choi 	uint8_t bOptimalWriteBlockSize;
715*1349a733SJaeyoon Choi 	uint8_t bMaxInBufferSize;
716*1349a733SJaeyoon Choi 	uint8_t bMaxOutBufferSize;
717*1349a733SJaeyoon Choi 	uint8_t bRPMB_ReadWriteSize;
718*1349a733SJaeyoon Choi 	uint8_t bDynamicCapacityResourcePolicy;
719*1349a733SJaeyoon Choi 	uint8_t bDataOrdering;
720*1349a733SJaeyoon Choi 	uint8_t bMaxContexIDNumber;
721*1349a733SJaeyoon Choi 	uint8_t bSysDataTagUnitSize;
722*1349a733SJaeyoon Choi 	uint8_t bSysDataTagResSize;
723*1349a733SJaeyoon Choi 	uint8_t bSupportedSecRTypes;
724*1349a733SJaeyoon Choi 	uint16_t wSupportedMemoryTypes;
725*1349a733SJaeyoon Choi 	/* 0x20 */
726*1349a733SJaeyoon Choi 	uint32_t dSystemCodeMaxNAllocU;
727*1349a733SJaeyoon Choi 	uint16_t wSystemCodeCapAdjFac;
728*1349a733SJaeyoon Choi 	uint32_t dNonPersistMaxNAllocU;
729*1349a733SJaeyoon Choi 	uint16_t wNonPersistCapAdjFac;
730*1349a733SJaeyoon Choi 	uint32_t dEnhanced1MaxNAllocU;
731*1349a733SJaeyoon Choi 	/* 0x30 */
732*1349a733SJaeyoon Choi 	uint16_t wEnhanced1CapAdjFac;
733*1349a733SJaeyoon Choi 	uint32_t dEnhanced2MaxNAllocU;
734*1349a733SJaeyoon Choi 	uint16_t wEnhanced2CapAdjFac;
735*1349a733SJaeyoon Choi 	uint32_t dEnhanced3MaxNAllocU;
736*1349a733SJaeyoon Choi 	uint16_t wEnhanced3CapAdjFac;
737*1349a733SJaeyoon Choi 	uint32_t dEnhanced4MaxNAllocU;
738*1349a733SJaeyoon Choi 	/* 0x42 */
739*1349a733SJaeyoon Choi 	uint16_t wEnhanced4CapAdjFac;
740*1349a733SJaeyoon Choi 	uint32_t dOptimalLogicalBlockSize;
741*1349a733SJaeyoon Choi 	uint8_t ReservedHpb[5];
742*1349a733SJaeyoon Choi 	uint8_t Reserved2[2];
743*1349a733SJaeyoon Choi 	uint32_t dWriteBoosterBufferMaxNAllocUnits;
744*1349a733SJaeyoon Choi 	uint8_t bDeviceMaxWriteBoosterLUs;
745*1349a733SJaeyoon Choi 	uint8_t bWriteBoosterBufferCapAdjFac;
746*1349a733SJaeyoon Choi 	uint8_t bSupportedWriteBoosterBufferUserSpaceReductionTypes;
747*1349a733SJaeyoon Choi 	uint8_t bSupportedWriteBoosterBufferTypes;
748*1349a733SJaeyoon Choi } __packed;
749*1349a733SJaeyoon Choi 
750*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_geometry_descriptor) == 87,
751*1349a733SJaeyoon Choi     "bad size for ufshci_geometry_descriptor");
752*1349a733SJaeyoon Choi 
753*1349a733SJaeyoon Choi /*
754*1349a733SJaeyoon Choi  * UFS Spec 4.1, section 14.1.5.5 "Unit Descriptor"
755*1349a733SJaeyoon Choi  * UnitDescriptor use big-endian byte ordering.
756*1349a733SJaeyoon Choi  */
757*1349a733SJaeyoon Choi struct ufshci_unit_descriptor {
758*1349a733SJaeyoon Choi 	uint8_t bLength;
759*1349a733SJaeyoon Choi 	uint8_t bDescriptorIDN;
760*1349a733SJaeyoon Choi 	uint8_t bUnitIndex;
761*1349a733SJaeyoon Choi 	uint8_t bLUEnable;
762*1349a733SJaeyoon Choi 	uint8_t bBootLunID;
763*1349a733SJaeyoon Choi 	uint8_t bLUWriteProtect;
764*1349a733SJaeyoon Choi 	uint8_t bLUQueueDepth;
765*1349a733SJaeyoon Choi 	uint8_t bPSASensitive;
766*1349a733SJaeyoon Choi 	uint8_t bMemoryType;
767*1349a733SJaeyoon Choi 	uint8_t bDataReliability;
768*1349a733SJaeyoon Choi 	uint8_t bLogicalBlockSize;
769*1349a733SJaeyoon Choi 	uint64_t qLogicalBlockCount;
770*1349a733SJaeyoon Choi 	/* 0x13 */
771*1349a733SJaeyoon Choi 	uint32_t dEraseBlockSize;
772*1349a733SJaeyoon Choi 	uint8_t bProvisioningType;
773*1349a733SJaeyoon Choi 	uint64_t qPhyMemResourceCount;
774*1349a733SJaeyoon Choi 	/* 0x20 */
775*1349a733SJaeyoon Choi 	uint16_t wContextCapabilities;
776*1349a733SJaeyoon Choi 	uint8_t bLargeUnitGranularity_M1;
777*1349a733SJaeyoon Choi 	uint8_t ReservedHpb[6];
778*1349a733SJaeyoon Choi 	uint32_t dLUNumWriteBoosterBufferAllocUnits;
779*1349a733SJaeyoon Choi } __packed;
780*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_unit_descriptor) == 45,
781*1349a733SJaeyoon Choi     "bad size for ufshci_unit_descriptor");
782*1349a733SJaeyoon Choi 
783*1349a733SJaeyoon Choi enum LUWriteProtect {
784*1349a733SJaeyoon Choi 	kNoWriteProtect = 0x00,
785*1349a733SJaeyoon Choi 	kPowerOnWriteProtect = 0x01,
786*1349a733SJaeyoon Choi 	kPermanentWriteProtect = 0x02,
787*1349a733SJaeyoon Choi };
788*1349a733SJaeyoon Choi 
789*1349a733SJaeyoon Choi /*
790*1349a733SJaeyoon Choi  * UFS Spec 4.1, section 14.1.5.6 "RPMB Unit Descriptor"
791*1349a733SJaeyoon Choi  * RpmbUnitDescriptor use big-endian byte ordering.
792*1349a733SJaeyoon Choi  */
793*1349a733SJaeyoon Choi struct ufshci_rpmb_unit_descriptor {
794*1349a733SJaeyoon Choi 	uint8_t bLength;
795*1349a733SJaeyoon Choi 	uint8_t bDescriptorIDN;
796*1349a733SJaeyoon Choi 	uint8_t bUnitIndex;
797*1349a733SJaeyoon Choi 	uint8_t bLUEnable;
798*1349a733SJaeyoon Choi 	uint8_t bBootLunID;
799*1349a733SJaeyoon Choi 	uint8_t bLUWriteProtect;
800*1349a733SJaeyoon Choi 	uint8_t bLUQueueDepth;
801*1349a733SJaeyoon Choi 	uint8_t bPSASensitive;
802*1349a733SJaeyoon Choi 	uint8_t bMemoryType;
803*1349a733SJaeyoon Choi 	uint8_t Reserved;
804*1349a733SJaeyoon Choi 	uint8_t bLogicalBlockSize;
805*1349a733SJaeyoon Choi 	uint64_t qLogicalBlockCount;
806*1349a733SJaeyoon Choi 	/* 0x13 */
807*1349a733SJaeyoon Choi 	uint32_t dEraseBlockSize;
808*1349a733SJaeyoon Choi 	uint8_t bProvisioningType;
809*1349a733SJaeyoon Choi 	uint64_t qPhyMemResourceCount;
810*1349a733SJaeyoon Choi 	/* 0x20 */
811*1349a733SJaeyoon Choi 	uint8_t Reserved1[3];
812*1349a733SJaeyoon Choi } __packed;
813*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_rpmb_unit_descriptor) == 35,
814*1349a733SJaeyoon Choi     "bad size for RpmbUnitDescriptor");
815*1349a733SJaeyoon Choi 
816*1349a733SJaeyoon Choi /*
817*1349a733SJaeyoon Choi  * UFS Spec 4.1, section 14.1.5.7 "Power Parameters Descriptor"
818*1349a733SJaeyoon Choi  * PowerParametersDescriptor use big-endian byte ordering.
819*1349a733SJaeyoon Choi  */
820*1349a733SJaeyoon Choi struct ufshci_power_parameters_descriptor {
821*1349a733SJaeyoon Choi 	uint8_t bLength;
822*1349a733SJaeyoon Choi 	uint8_t bDescriptorIDN;
823*1349a733SJaeyoon Choi 	uint16_t wActiveICCLevelsVCC[16];
824*1349a733SJaeyoon Choi 	uint16_t wActiveICCLevelsVCCQ[16];
825*1349a733SJaeyoon Choi 	uint16_t wActiveICCLevelsVCCQ2[16];
826*1349a733SJaeyoon Choi } __packed;
827*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_power_parameters_descriptor) == 98,
828*1349a733SJaeyoon Choi     "bad size for PowerParametersDescriptor");
829*1349a733SJaeyoon Choi 
830*1349a733SJaeyoon Choi /*
831*1349a733SJaeyoon Choi  * UFS Spec 4.1, section 14.1.5.8 "Interconnect Descriptor"
832*1349a733SJaeyoon Choi  * InterconnectDescriptor use big-endian byte ordering.
833*1349a733SJaeyoon Choi  */
834*1349a733SJaeyoon Choi struct ufshci_interconnect_descriptor {
835*1349a733SJaeyoon Choi 	uint8_t bLength;
836*1349a733SJaeyoon Choi 	uint8_t bDescriptorIDN;
837*1349a733SJaeyoon Choi 	uint16_t bcdUniproVersion;
838*1349a733SJaeyoon Choi 	uint16_t bcdMphyVersion;
839*1349a733SJaeyoon Choi } __packed;
840*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_interconnect_descriptor) == 6,
841*1349a733SJaeyoon Choi     "bad size for InterconnectDescriptor");
842*1349a733SJaeyoon Choi 
843*1349a733SJaeyoon Choi /*
844*1349a733SJaeyoon Choi  * UFS Spec 4.1, section 14.1.5.9-13 "String Descriptor"
845*1349a733SJaeyoon Choi  * StringDescriptor use big-endian byte ordering.
846*1349a733SJaeyoon Choi  */
847*1349a733SJaeyoon Choi struct ufshci_string_descriptor {
848*1349a733SJaeyoon Choi 	uint8_t bLength;
849*1349a733SJaeyoon Choi 	uint8_t bDescriptorIDN;
850*1349a733SJaeyoon Choi 	uint16_t UC[126];
851*1349a733SJaeyoon Choi } __packed;
852*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_string_descriptor) == 254,
853*1349a733SJaeyoon Choi     "bad size for StringDescriptor");
854*1349a733SJaeyoon Choi 
855*1349a733SJaeyoon Choi /*
856*1349a733SJaeyoon Choi  * UFS Spec 4.1, section 14.1.5.14 "Device Health Descriptor"
857*1349a733SJaeyoon Choi  * DeviceHealthDescriptor use big-endian byte ordering.
858*1349a733SJaeyoon Choi  */
859*1349a733SJaeyoon Choi struct ufshci_device_healthd_descriptor {
860*1349a733SJaeyoon Choi 	uint8_t bLength;
861*1349a733SJaeyoon Choi 	uint8_t bDescriptorIDN;
862*1349a733SJaeyoon Choi 	uint8_t bPreEOLInfo;
863*1349a733SJaeyoon Choi 	uint8_t bDeviceLifeTimeEstA;
864*1349a733SJaeyoon Choi 	uint8_t bDeviceLifeTimeEstB;
865*1349a733SJaeyoon Choi 	uint8_t VendorPropInfo[32];
866*1349a733SJaeyoon Choi 	uint32_t dRefreshTotalCount;
867*1349a733SJaeyoon Choi 	uint32_t dRefreshProgress;
868*1349a733SJaeyoon Choi } __packed;
869*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_device_healthd_descriptor) == 45,
870*1349a733SJaeyoon Choi     "bad size for DeviceHealthDescriptor");
871*1349a733SJaeyoon Choi 
872*1349a733SJaeyoon Choi /*
873*1349a733SJaeyoon Choi  * UFS Spec 4.1, section 14.1.5.15 "Vendor Specific Descriptor"
874*1349a733SJaeyoon Choi  * VendorSpecificDescriptor use big-endian byte ordering.
875*1349a733SJaeyoon Choi  */
876*1349a733SJaeyoon Choi struct ufshci_vendor_specific_descriptor {
877*1349a733SJaeyoon Choi 	uint8_t bLength;
878*1349a733SJaeyoon Choi 	uint8_t bDescriptorIDN;
879*1349a733SJaeyoon Choi 	uint8_t DATA[254];
880*1349a733SJaeyoon Choi } __packed;
881*1349a733SJaeyoon Choi _Static_assert(sizeof(struct ufshci_vendor_specific_descriptor) == 256,
882*1349a733SJaeyoon Choi     "bad size for VendorSpecificDescriptor");
883*1349a733SJaeyoon Choi 
884*1349a733SJaeyoon Choi /* UFS Spec 4.1, section 14.2 "Flags" */
885*1349a733SJaeyoon Choi enum ufshci_flags {
886*1349a733SJaeyoon Choi 	UFSHCI_FLAG_F_RESERVED = 0x00,
887*1349a733SJaeyoon Choi 	UFSHCI_FLAG_F_DEVICE_INIT = 0x01,
888*1349a733SJaeyoon Choi 	UFSHCI_FLAG_F_PERMANENT_WP_EN = 0x02,
889*1349a733SJaeyoon Choi 	UFSHCI_FLAS_F_POWER_ON_WP_EN = 0x03,
890*1349a733SJaeyoon Choi 	UFSHCI_FLAG_F_BACKGROUND_OPS_EN = 0x04,
891*1349a733SJaeyoon Choi 	UFSHCI_FLAG_F_DEVICE_LIFE_SPAN_MODE_EN = 0x05,
892*1349a733SJaeyoon Choi 	UFSHCI_FLAG_F_PURGE_ENABLE = 0x06,
893*1349a733SJaeyoon Choi 	UFSHCI_FLAG_F_REFRESH_ENABLE = 0x07,
894*1349a733SJaeyoon Choi 	UFSHCI_FLAG_F_PHY_RESOURCE_REMOVAL = 0x08,
895*1349a733SJaeyoon Choi 	UFSHCI_FLAG_F_BUSY_RTC = 0x09,
896*1349a733SJaeyoon Choi 	UFSHCI_FLAG_F_PERMANENTLY_DISABLE_FW_UPDATE = 0x0b,
897*1349a733SJaeyoon Choi 	UFSHCI_FLAG_F_WRITE_BOOSTER_EN = 0x0e,
898*1349a733SJaeyoon Choi 	UFSHCI_FLAG_F_WB_BUFFER_FLUSH_EN = 0x0f,
899*1349a733SJaeyoon Choi 	UFSHCI_FLAG_F_WB_BUFFER_FLUSH_DURING_HIBERNATE = 0x10,
900*1349a733SJaeyoon Choi 	UFSHCI_FLAG_F_UNPIN_EN = 0x13,
901*1349a733SJaeyoon Choi };
902*1349a733SJaeyoon Choi 
903*1349a733SJaeyoon Choi /* UFS Spec 4.1, section 14.3 "Attributes" */
904*1349a733SJaeyoon Choi enum ufshci_attributes {
905*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_BOOT_LUN_EN = 0x00,
906*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_CURRENT_POWER_MODE = 0x02,
907*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_ACTIVE_ICC_LEVEL = 0x03,
908*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_OUT_OF_ORDER_DATA_EN = 0x04,
909*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_BACKGROUND_OP_STATUS = 0x05,
910*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_PURGE_STATUS = 0x06,
911*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_MAX_DATA_IN_SIZE = 0x07,
912*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_MAX_DATA_OUT_SIZE = 0x08,
913*1349a733SJaeyoon Choi 	UFSHCI_ATTR_D_DYN_CAP_NEEDED = 0x09,
914*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_REF_CLK_FREQ = 0x0a,
915*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_CONFIG_DESCR_LOCK = 0x0b,
916*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_MAX_NUM_OF_RTT = 0x0c,
917*1349a733SJaeyoon Choi 	UFSHCI_ATTR_W_EXCEPTION_EVENT_CONTROL = 0x0d,
918*1349a733SJaeyoon Choi 	UFSHCI_ATTR_W_EXCEPTION_EVENT_STATUS = 0x0e,
919*1349a733SJaeyoon Choi 	UFSHCI_ATTR_D_SECONDS_PASSED = 0x0f,
920*1349a733SJaeyoon Choi 	UFSHCI_ATTR_W_CONTEXT_CONF = 0x10,
921*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_DEVICE_FFU_STATUS = 0x14,
922*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_PSA_STATE = 0x15,
923*1349a733SJaeyoon Choi 	UFSHCI_ATTR_D_PSA_DATA_SIZE = 0x16,
924*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_REF_CLK_GATING_WAIT_TIME = 0x17,
925*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_DEVICE_CASE_ROUGH_TEMPERAURE = 0x18,
926*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_DEVICE_TOO_HIGH_TEMP_BOUNDARY = 0x19,
927*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_DEVICE_TOO_LOW_TEMP_BOUNDARY = 0x1a,
928*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_THROTTLING_STATUS = 0x1b,
929*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_WB_BUFFER_FLUSH_STATUS = 0x1c,
930*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_AVAILABLE_WB_BUFFER_SIZE = 0x1d,
931*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_WB_BUFFER_LIFE_TIME_EST = 0x1e,
932*1349a733SJaeyoon Choi 	UFSHCI_ATTR_D_CURRENT_WB_BUFFER_SIZE = 0x1f,
933*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_REFRESH_STATUS = 0x2c,
934*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_REFRESH_FREQ = 0x2d,
935*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_REFRESH_UNIT = 0x2e,
936*1349a733SJaeyoon Choi 	UFSHCI_ATTR_B_REFRESH_METHOD = 0x2f,
937*1349a733SJaeyoon Choi };
938*1349a733SJaeyoon Choi 
939*1349a733SJaeyoon Choi #endif /* __UFSHCI_H__ */
940