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