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