1eb5073f4SHaojian Zhuang /* 2eb5073f4SHaojian Zhuang * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. 3eb5073f4SHaojian Zhuang * 4eb5073f4SHaojian Zhuang * SPDX-License-Identifier: BSD-3-Clause 5eb5073f4SHaojian Zhuang */ 6eb5073f4SHaojian Zhuang 7c3cf06f1SAntonio Nino Diaz #ifndef UFS_H 8c3cf06f1SAntonio Nino Diaz #define UFS_H 9eb5073f4SHaojian Zhuang 1009d40e0eSAntonio Nino Diaz #include <lib/utils_def.h> 115ac25de6Sfengbaopeng 12eb5073f4SHaojian Zhuang /* register map of UFSHCI */ 13eb5073f4SHaojian Zhuang /* Controller Capabilities */ 14eb5073f4SHaojian Zhuang #define CAP 0x00 15eb5073f4SHaojian Zhuang #define CAP_NUTRS_MASK 0x1F 16eb5073f4SHaojian Zhuang 17eb5073f4SHaojian Zhuang /* UFS Version */ 18eb5073f4SHaojian Zhuang #define VER 0x08 19eb5073f4SHaojian Zhuang /* Host Controller Identification - Product ID */ 20eb5073f4SHaojian Zhuang #define HCDDID 0x10 21eb5073f4SHaojian Zhuang /* Host Controller Identification Descriptor - Manufacturer ID */ 22eb5073f4SHaojian Zhuang #define HCPMID 0x14 23eb5073f4SHaojian Zhuang /* Auto-Hibernate Idle Timer */ 24eb5073f4SHaojian Zhuang #define AHIT 0x18 25eb5073f4SHaojian Zhuang /* Interrupt Status */ 26eb5073f4SHaojian Zhuang #define IS 0x20 27eb5073f4SHaojian Zhuang /* Interrupt Enable */ 28eb5073f4SHaojian Zhuang #define IE 0x24 29eb5073f4SHaojian Zhuang /* System Bus Fatal Error Status */ 30eb5073f4SHaojian Zhuang #define UFS_INT_SBFES (1 << 17) 31eb5073f4SHaojian Zhuang /* Host Controller Fatal Error Status */ 32eb5073f4SHaojian Zhuang #define UFS_INT_HCFES (1 << 16) 33eb5073f4SHaojian Zhuang /* UTP Error Status */ 34eb5073f4SHaojian Zhuang #define UFS_INT_UTPES (1 << 12) 35eb5073f4SHaojian Zhuang /* Device Fatal Error Status */ 36eb5073f4SHaojian Zhuang #define UFS_INT_DFES (1 << 11) 37eb5073f4SHaojian Zhuang /* UIC Command Completion Status */ 38eb5073f4SHaojian Zhuang #define UFS_INT_UCCS (1 << 10) 39eb5073f4SHaojian Zhuang /* UTP Task Management Request Completion Status */ 40eb5073f4SHaojian Zhuang #define UFS_INT_UTMRCS (1 << 9) 41eb5073f4SHaojian Zhuang /* UIC Link Startup Status */ 42eb5073f4SHaojian Zhuang #define UFS_INT_ULSS (1 << 8) 43eb5073f4SHaojian Zhuang /* UIC Link Lost Status */ 44eb5073f4SHaojian Zhuang #define UFS_INT_ULLS (1 << 7) 45eb5073f4SHaojian Zhuang /* UIC Hibernate Enter Status */ 46eb5073f4SHaojian Zhuang #define UFS_INT_UHES (1 << 6) 47eb5073f4SHaojian Zhuang /* UIC Hibernate Exit Status */ 48eb5073f4SHaojian Zhuang #define UFS_INT_UHXS (1 << 5) 49eb5073f4SHaojian Zhuang /* UIC Power Mode Status */ 50eb5073f4SHaojian Zhuang #define UFS_INT_UPMS (1 << 4) 51eb5073f4SHaojian Zhuang /* UIC Test Mode Status */ 52eb5073f4SHaojian Zhuang #define UFS_INT_UTMS (1 << 3) 53eb5073f4SHaojian Zhuang /* UIC Error */ 54eb5073f4SHaojian Zhuang #define UFS_INT_UE (1 << 2) 55eb5073f4SHaojian Zhuang /* UIC DME_ENDPOINTRESET Indication */ 56eb5073f4SHaojian Zhuang #define UFS_INT_UDEPRI (1 << 1) 57eb5073f4SHaojian Zhuang /* UTP Transfer Request Completion Status */ 58eb5073f4SHaojian Zhuang #define UFS_INT_UTRCS (1 << 0) 59eb5073f4SHaojian Zhuang 60eb5073f4SHaojian Zhuang /* Host Controller Status */ 61eb5073f4SHaojian Zhuang #define HCS 0x30 62eb5073f4SHaojian Zhuang #define HCS_UPMCRS_MASK (7 << 8) 63eb5073f4SHaojian Zhuang #define HCS_PWR_LOCAL (1 << 8) 64eb5073f4SHaojian Zhuang #define HCS_UCRDY (1 << 3) 65eb5073f4SHaojian Zhuang #define HCS_UTMRLRDY (1 << 2) 66eb5073f4SHaojian Zhuang #define HCS_UTRLRDY (1 << 1) 67eb5073f4SHaojian Zhuang #define HCS_DP (1 << 0) 68eb5073f4SHaojian Zhuang 69eb5073f4SHaojian Zhuang /* Host Controller Enable */ 70eb5073f4SHaojian Zhuang #define HCE 0x34 71eb5073f4SHaojian Zhuang #define HCE_ENABLE 1 72*b3f03b20Sanans #define HCE_DISABLE 0 73eb5073f4SHaojian Zhuang 74eb5073f4SHaojian Zhuang /* Host UIC Error Code PHY Adapter Layer */ 75eb5073f4SHaojian Zhuang #define UECPA 0x38 76eb5073f4SHaojian Zhuang /* Host UIC Error Code Data Link Layer */ 77eb5073f4SHaojian Zhuang #define UECDL 0x3C 78eb5073f4SHaojian Zhuang /* Host UIC Error Code Network Layer */ 79eb5073f4SHaojian Zhuang #define UECN 0x40 80eb5073f4SHaojian Zhuang /* Host UIC Error Code Transport Layer */ 81eb5073f4SHaojian Zhuang #define UECT 0x44 82eb5073f4SHaojian Zhuang /* Host UIC Error Code */ 83eb5073f4SHaojian Zhuang #define UECDME 0x48 84eb5073f4SHaojian Zhuang /* UTP Transfer Request Interrupt Aggregation Control Register */ 85eb5073f4SHaojian Zhuang #define UTRIACR 0x4C 863e43121eSJustin Chadwell #define UTRIACR_IAEN (1U << 31) 87eb5073f4SHaojian Zhuang #define UTRIACR_IAPWEN (1 << 24) 88eb5073f4SHaojian Zhuang #define UTRIACR_IASB (1 << 20) 89eb5073f4SHaojian Zhuang #define UTRIACR_CTR (1 << 16) 90eb5073f4SHaojian Zhuang #define UTRIACR_IACTH(x) (((x) & 0x1F) << 8) 91eb5073f4SHaojian Zhuang #define UTRIACR_IATOVAL(x) ((x) & 0xFF) 92eb5073f4SHaojian Zhuang 93eb5073f4SHaojian Zhuang /* UTP Transfer Request List Base Address */ 94eb5073f4SHaojian Zhuang #define UTRLBA 0x50 95eb5073f4SHaojian Zhuang /* UTP Transfer Request List Base Address Upper 32-bits */ 96eb5073f4SHaojian Zhuang #define UTRLBAU 0x54 97eb5073f4SHaojian Zhuang /* UTP Transfer Request List Door Bell Register */ 98eb5073f4SHaojian Zhuang #define UTRLDBR 0x58 99eb5073f4SHaojian Zhuang /* UTP Transfer Request List Clear Register */ 100eb5073f4SHaojian Zhuang #define UTRLCLR 0x5C 101eb5073f4SHaojian Zhuang /* UTP Transfer Request List Run Stop Register */ 102eb5073f4SHaojian Zhuang #define UTRLRSR 0x60 103eb5073f4SHaojian Zhuang #define UTMRLBA 0x70 104eb5073f4SHaojian Zhuang #define UTMRLBAU 0x74 105eb5073f4SHaojian Zhuang #define UTMRLDBR 0x78 106eb5073f4SHaojian Zhuang #define UTMRLCLR 0x7C 107eb5073f4SHaojian Zhuang #define UTMRLRSR 0x80 108eb5073f4SHaojian Zhuang /* UIC Command */ 109eb5073f4SHaojian Zhuang #define UICCMD 0x90 110eb5073f4SHaojian Zhuang /* UIC Command Argument 1 */ 111eb5073f4SHaojian Zhuang #define UCMDARG1 0x94 112eb5073f4SHaojian Zhuang /* UIC Command Argument 2 */ 113eb5073f4SHaojian Zhuang #define UCMDARG2 0x98 114eb5073f4SHaojian Zhuang /* UIC Command Argument 3 */ 115eb5073f4SHaojian Zhuang #define UCMDARG3 0x9C 116eb5073f4SHaojian Zhuang 117eb5073f4SHaojian Zhuang #define UFS_BLOCK_SHIFT 12 /* 4KB */ 118eb5073f4SHaojian Zhuang #define UFS_BLOCK_SIZE (1 << UFS_BLOCK_SHIFT) 119eb5073f4SHaojian Zhuang #define UFS_BLOCK_MASK (UFS_BLOCK_SIZE - 1) 120eb5073f4SHaojian Zhuang #define UFS_MAX_LUNS 8 121eb5073f4SHaojian Zhuang 122eb5073f4SHaojian Zhuang /* UTP Transfer Request Descriptor */ 123eb5073f4SHaojian Zhuang /* Command Type */ 124eb5073f4SHaojian Zhuang #define CT_UFS_STORAGE 1 125eb5073f4SHaojian Zhuang #define CT_SCSI 0 126eb5073f4SHaojian Zhuang 127eb5073f4SHaojian Zhuang /* Data Direction */ 128eb5073f4SHaojian Zhuang #define DD_OUT 2 /* Device --> Host */ 129eb5073f4SHaojian Zhuang #define DD_IN 1 /* Host --> Device */ 130eb5073f4SHaojian Zhuang #define DD_NO_DATA_TRANSFER 0 131eb5073f4SHaojian Zhuang 132eb5073f4SHaojian Zhuang #define UTP_TRD_SIZE 32 133eb5073f4SHaojian Zhuang 134eb5073f4SHaojian Zhuang /* Transaction Type */ 135eb5073f4SHaojian Zhuang #define TRANS_TYPE_HD (1 << 7) /* E2ECRC */ 136eb5073f4SHaojian Zhuang #define TRANS_TYPE_DD (1 << 6) 137eb5073f4SHaojian Zhuang #define TRANS_TYPE_CODE_MASK 0x3F 138eb5073f4SHaojian Zhuang #define QUERY_RESPONSE_UPIU (0x36 << 0) 139eb5073f4SHaojian Zhuang #define READY_TO_TRANSACTION_UPIU (0x31 << 0) 140eb5073f4SHaojian Zhuang #define DATA_IN_UPIU (0x22 << 0) 141eb5073f4SHaojian Zhuang #define RESPONSE_UPIU (0x21 << 0) 142eb5073f4SHaojian Zhuang #define NOP_IN_UPIU (0x20 << 0) 143eb5073f4SHaojian Zhuang #define QUERY_REQUEST_UPIU (0x16 << 0) 144eb5073f4SHaojian Zhuang #define DATA_OUT_UPIU (0x02 << 0) 145eb5073f4SHaojian Zhuang #define CMD_UPIU (0x01 << 0) 146eb5073f4SHaojian Zhuang #define NOP_OUT_UPIU (0x00 << 0) 147eb5073f4SHaojian Zhuang 148eb5073f4SHaojian Zhuang #define OCS_SUCCESS 0x0 149eb5073f4SHaojian Zhuang #define OCS_INVALID_FUNC_ATTRIBUTE 0x1 150eb5073f4SHaojian Zhuang #define OCS_MISMATCH_REQUEST_SIZE 0x2 151eb5073f4SHaojian Zhuang #define OCS_MISMATCH_RESPONSE_SIZE 0x3 152eb5073f4SHaojian Zhuang #define OCS_PEER_COMMUNICATION_FAILURE 0x4 153eb5073f4SHaojian Zhuang #define OCS_ABORTED 0x5 154eb5073f4SHaojian Zhuang #define OCS_FATAL_ERROR 0x6 155eb5073f4SHaojian Zhuang #define OCS_MASK 0xF 156eb5073f4SHaojian Zhuang 157eb5073f4SHaojian Zhuang /* UIC Command */ 158eb5073f4SHaojian Zhuang #define DME_GET 0x01 159eb5073f4SHaojian Zhuang #define DME_SET 0x02 160eb5073f4SHaojian Zhuang #define DME_PEER_GET 0x03 161eb5073f4SHaojian Zhuang #define DME_PEER_SET 0x04 162eb5073f4SHaojian Zhuang #define DME_POWERON 0x10 163eb5073f4SHaojian Zhuang #define DME_POWEROFF 0x11 164eb5073f4SHaojian Zhuang #define DME_ENABLE 0x12 165eb5073f4SHaojian Zhuang #define DME_RESET 0x14 166eb5073f4SHaojian Zhuang #define DME_ENDPOINTRESET 0x15 167eb5073f4SHaojian Zhuang #define DME_LINKSTARTUP 0x16 168eb5073f4SHaojian Zhuang #define DME_HIBERNATE_ENTER 0x17 169eb5073f4SHaojian Zhuang #define DME_HIBERNATE_EXIT 0x18 170eb5073f4SHaojian Zhuang #define DME_TEST_MODE 0x1A 171eb5073f4SHaojian Zhuang 172eb5073f4SHaojian Zhuang #define GEN_SELECTOR_IDX(x) ((x) & 0xFFFF) 173eb5073f4SHaojian Zhuang 174eb5073f4SHaojian Zhuang #define CONFIG_RESULT_CODE_MASK 0xFF 175eb5073f4SHaojian Zhuang 176eb5073f4SHaojian Zhuang #define CDBCMD_TEST_UNIT_READY 0x00 177eb5073f4SHaojian Zhuang #define CDBCMD_READ_6 0x08 178eb5073f4SHaojian Zhuang #define CDBCMD_WRITE_6 0x0A 179eb5073f4SHaojian Zhuang #define CDBCMD_START_STOP_UNIT 0x1B 180eb5073f4SHaojian Zhuang #define CDBCMD_READ_CAPACITY_10 0x25 181eb5073f4SHaojian Zhuang #define CDBCMD_READ_10 0x28 182eb5073f4SHaojian Zhuang #define CDBCMD_WRITE_10 0x2A 183eb5073f4SHaojian Zhuang #define CDBCMD_READ_16 0x88 184eb5073f4SHaojian Zhuang #define CDBCMD_WRITE_16 0x8A 185eb5073f4SHaojian Zhuang #define CDBCMD_READ_CAPACITY_16 0x9E 186eb5073f4SHaojian Zhuang #define CDBCMD_REPORT_LUNS 0xA0 187eb5073f4SHaojian Zhuang 188eb5073f4SHaojian Zhuang #define UPIU_FLAGS_R (1 << 6) 189eb5073f4SHaojian Zhuang #define UPIU_FLAGS_W (1 << 5) 190eb5073f4SHaojian Zhuang #define UPIU_FLAGS_ATTR_MASK (3 << 0) 191eb5073f4SHaojian Zhuang #define UPIU_FLAGS_ATTR_S (0 << 0) /* Simple */ 192eb5073f4SHaojian Zhuang #define UPIU_FLAGS_ATTR_O (1 << 0) /* Ordered */ 193eb5073f4SHaojian Zhuang #define UPIU_FLAGS_ATTR_HQ (2 << 0) /* Head of Queue */ 194eb5073f4SHaojian Zhuang #define UPIU_FLAGS_ATTR_ACA (3 << 0) 195eb5073f4SHaojian Zhuang #define UPIU_FLAGS_O (1 << 6) 196eb5073f4SHaojian Zhuang #define UPIU_FLAGS_U (1 << 5) 197eb5073f4SHaojian Zhuang #define UPIU_FLAGS_D (1 << 4) 198eb5073f4SHaojian Zhuang 199eb5073f4SHaojian Zhuang #define QUERY_FUNC_STD_READ 0x01 200eb5073f4SHaojian Zhuang #define QUERY_FUNC_STD_WRITE 0x81 201eb5073f4SHaojian Zhuang 202eb5073f4SHaojian Zhuang #define QUERY_NOP 0x00 203eb5073f4SHaojian Zhuang #define QUERY_READ_DESC 0x01 204eb5073f4SHaojian Zhuang #define QUERY_WRITE_DESC 0x02 205eb5073f4SHaojian Zhuang #define QUERY_READ_ATTR 0x03 206eb5073f4SHaojian Zhuang #define QUERY_WRITE_ATTR 0x04 207eb5073f4SHaojian Zhuang #define QUERY_READ_FLAG 0x05 208eb5073f4SHaojian Zhuang #define QUERY_SET_FLAG 0x06 209eb5073f4SHaojian Zhuang #define QUERY_CLEAR_FLAG 0x07 210eb5073f4SHaojian Zhuang #define QUERY_TOGGLE_FLAG 0x08 211eb5073f4SHaojian Zhuang 212eb5073f4SHaojian Zhuang #define RW_WITHOUT_CACHE 0x18 213eb5073f4SHaojian Zhuang 214eb5073f4SHaojian Zhuang #define DESC_TYPE_DEVICE 0x00 215eb5073f4SHaojian Zhuang #define DESC_TYPE_CONFIGURATION 0x01 216eb5073f4SHaojian Zhuang #define DESC_TYPE_UNIT 0x02 217eb5073f4SHaojian Zhuang #define DESC_TYPE_INTERCONNECT 0x04 218eb5073f4SHaojian Zhuang #define DESC_TYPE_STRING 0x05 219eb5073f4SHaojian Zhuang 2205ac25de6Sfengbaopeng #define DESC_DEVICE_MAX_SIZE 0x1F 2215ac25de6Sfengbaopeng #define DEVICE_DESC_PARAM_MANF_ID 0x18 2225ac25de6Sfengbaopeng 223eb5073f4SHaojian Zhuang #define ATTR_CUR_PWR_MODE 0x02 /* bCurrentPowerMode */ 224eb5073f4SHaojian Zhuang #define ATTR_ACTIVECC 0x03 /* bActiveICCLevel */ 225eb5073f4SHaojian Zhuang 226eb5073f4SHaojian Zhuang #define DEVICE_DESCRIPTOR_LEN 0x40 227eb5073f4SHaojian Zhuang #define UNIT_DESCRIPTOR_LEN 0x23 228eb5073f4SHaojian Zhuang 229eb5073f4SHaojian Zhuang #define QUERY_RESP_SUCCESS 0x00 230eb5073f4SHaojian Zhuang #define QUERY_RESP_OPCODE 0xFE 231eb5073f4SHaojian Zhuang #define QUERY_RESP_GENERAL_FAIL 0xFF 232eb5073f4SHaojian Zhuang 233eb5073f4SHaojian Zhuang #define SENSE_KEY_NO_SENSE 0x00 234eb5073f4SHaojian Zhuang #define SENSE_KEY_RECOVERED_ERROR 0x01 235eb5073f4SHaojian Zhuang #define SENSE_KEY_NOT_READY 0x02 236eb5073f4SHaojian Zhuang #define SENSE_KEY_MEDIUM_ERROR 0x03 237eb5073f4SHaojian Zhuang #define SENSE_KEY_HARDWARE_ERROR 0x04 238eb5073f4SHaojian Zhuang #define SENSE_KEY_ILLEGAL_REQUEST 0x05 239eb5073f4SHaojian Zhuang #define SENSE_KEY_UNIT_ATTENTION 0x06 240eb5073f4SHaojian Zhuang #define SENSE_KEY_DATA_PROTECT 0x07 241eb5073f4SHaojian Zhuang #define SENSE_KEY_BLANK_CHECK 0x08 242eb5073f4SHaojian Zhuang #define SENSE_KEY_VENDOR_SPECIFIC 0x09 243eb5073f4SHaojian Zhuang #define SENSE_KEY_COPY_ABORTED 0x0A 244eb5073f4SHaojian Zhuang #define SENSE_KEY_ABORTED_COMMAND 0x0B 245eb5073f4SHaojian Zhuang #define SENSE_KEY_VOLUME_OVERFLOW 0x0D 246eb5073f4SHaojian Zhuang #define SENSE_KEY_MISCOMPARE 0x0E 247eb5073f4SHaojian Zhuang 248eb5073f4SHaojian Zhuang #define SENSE_DATA_VALID 0x70 249eb5073f4SHaojian Zhuang #define SENSE_DATA_LENGTH 18 250eb5073f4SHaojian Zhuang 251eb5073f4SHaojian Zhuang #define READ_CAPACITY_LENGTH 8 252eb5073f4SHaojian Zhuang 253eb5073f4SHaojian Zhuang #define FLAG_DEVICE_INIT 0x01 254eb5073f4SHaojian Zhuang 2555ac25de6Sfengbaopeng #define UFS_VENDOR_SKHYNIX U(0x1AD) 2565ac25de6Sfengbaopeng 2575ac25de6Sfengbaopeng #define MAX_MODEL_LEN 16 258d68d163dSJorge Troncoso 259d68d163dSJorge Troncoso /* maximum number of retries for a general UIC command */ 260d68d163dSJorge Troncoso #define UFS_UIC_COMMAND_RETRIES 3 261d68d163dSJorge Troncoso 262905635d5SJorge Troncoso /* maximum number of link-startup retries */ 263905635d5SJorge Troncoso #define DME_LINKSTARTUP_RETRIES 10 264905635d5SJorge Troncoso 26599ff1a35SJorge Troncoso #define HCE_ENABLE_OUTER_RETRIES 3 26699ff1a35SJorge Troncoso #define HCE_ENABLE_INNER_RETRIES 50 26799ff1a35SJorge Troncoso #define HCE_ENABLE_TIMEOUT_US 100 268*b3f03b20Sanans #define HCE_DISABLE_TIMEOUT_US 1000 26999ff1a35SJorge Troncoso 27050593e69Sanans #define FDEVICEINIT_TIMEOUT_MS 1500 27150593e69Sanans 2725ac25de6Sfengbaopeng /** 2735ac25de6Sfengbaopeng * ufs_dev_desc - ufs device details from the device descriptor 2745ac25de6Sfengbaopeng * @wmanufacturerid: card details 2755ac25de6Sfengbaopeng * @model: card model 2765ac25de6Sfengbaopeng */ 2775ac25de6Sfengbaopeng struct ufs_dev_desc { 2785ac25de6Sfengbaopeng uint16_t wmanufacturerid; 2795ac25de6Sfengbaopeng int8_t model[MAX_MODEL_LEN + 1]; 2805ac25de6Sfengbaopeng }; 2815ac25de6Sfengbaopeng 282eb5073f4SHaojian Zhuang /* UFS Driver Flags */ 283eb5073f4SHaojian Zhuang #define UFS_FLAGS_SKIPINIT (1 << 0) 2845ac25de6Sfengbaopeng #define UFS_FLAGS_VENDOR_SKHYNIX (U(1) << 2) 285eb5073f4SHaojian Zhuang 286eb5073f4SHaojian Zhuang typedef struct sense_data { 287eb5073f4SHaojian Zhuang uint8_t resp_code : 7; 288eb5073f4SHaojian Zhuang uint8_t valid : 1; 289eb5073f4SHaojian Zhuang uint8_t reserved0; 290eb5073f4SHaojian Zhuang uint8_t sense_key : 4; 291eb5073f4SHaojian Zhuang uint8_t reserved1 : 1; 292eb5073f4SHaojian Zhuang uint8_t ili : 1; 293eb5073f4SHaojian Zhuang uint8_t eom : 1; 294eb5073f4SHaojian Zhuang uint8_t file_mark : 1; 295eb5073f4SHaojian Zhuang uint8_t info[4]; 296eb5073f4SHaojian Zhuang uint8_t asl; 297eb5073f4SHaojian Zhuang uint8_t cmd_spec_len[4]; 298eb5073f4SHaojian Zhuang uint8_t asc; 299eb5073f4SHaojian Zhuang uint8_t ascq; 300eb5073f4SHaojian Zhuang uint8_t fruc; 301eb5073f4SHaojian Zhuang uint8_t sense_key_spec0 : 7; 302eb5073f4SHaojian Zhuang uint8_t sksv : 1; 303eb5073f4SHaojian Zhuang uint8_t sense_key_spec1; 304eb5073f4SHaojian Zhuang uint8_t sense_key_spec2; 305eb5073f4SHaojian Zhuang } sense_data_t; 306eb5073f4SHaojian Zhuang 307eb5073f4SHaojian Zhuang /* UTP Transfer Request Descriptor */ 308eb5073f4SHaojian Zhuang typedef struct utrd_header { 309eb5073f4SHaojian Zhuang uint32_t reserved0 : 24; 310eb5073f4SHaojian Zhuang uint32_t i : 1; /* interrupt */ 311eb5073f4SHaojian Zhuang uint32_t dd : 2; /* data direction */ 312eb5073f4SHaojian Zhuang uint32_t reserved1 : 1; 313eb5073f4SHaojian Zhuang uint32_t ct : 4; /* command type */ 314eb5073f4SHaojian Zhuang uint32_t reserved2; 315eb5073f4SHaojian Zhuang uint32_t ocs : 8; /* Overall Command Status */ 316eb5073f4SHaojian Zhuang uint32_t reserved3 : 24; 317eb5073f4SHaojian Zhuang uint32_t reserved4; 318eb5073f4SHaojian Zhuang uint32_t ucdba; /* aligned to 128-byte */ 319eb5073f4SHaojian Zhuang uint32_t ucdbau; /* Upper 32-bits */ 320eb5073f4SHaojian Zhuang uint32_t rul : 16; /* Response UPIU Length */ 321eb5073f4SHaojian Zhuang uint32_t ruo : 16; /* Response UPIU Offset */ 322eb5073f4SHaojian Zhuang uint32_t prdtl : 16; /* PRDT Length */ 323eb5073f4SHaojian Zhuang uint32_t prdto : 16; /* PRDT Offset */ 324eb5073f4SHaojian Zhuang } utrd_header_t; /* 8 words with little endian */ 325eb5073f4SHaojian Zhuang 326eb5073f4SHaojian Zhuang /* UTP Task Management Request Descriptor */ 327eb5073f4SHaojian Zhuang typedef struct utp_utmrd { 328eb5073f4SHaojian Zhuang /* 4 words with little endian */ 329eb5073f4SHaojian Zhuang uint32_t reserved0 : 24; 330eb5073f4SHaojian Zhuang uint32_t i : 1; /* interrupt */ 331eb5073f4SHaojian Zhuang uint32_t reserved1 : 7; 332eb5073f4SHaojian Zhuang uint32_t reserved2; 333eb5073f4SHaojian Zhuang uint32_t ocs : 8; /* Overall Command Status */ 334eb5073f4SHaojian Zhuang uint32_t reserved3 : 24; 335eb5073f4SHaojian Zhuang uint32_t reserved4; 336eb5073f4SHaojian Zhuang 337eb5073f4SHaojian Zhuang /* followed by 8 words UPIU with big endian */ 338eb5073f4SHaojian Zhuang 339eb5073f4SHaojian Zhuang /* followed by 8 words Response UPIU with big endian */ 340eb5073f4SHaojian Zhuang } utp_utmrd_t; 341eb5073f4SHaojian Zhuang 342eb5073f4SHaojian Zhuang /* NOP OUT UPIU */ 343eb5073f4SHaojian Zhuang typedef struct nop_out_upiu { 344eb5073f4SHaojian Zhuang uint8_t trans_type; 345eb5073f4SHaojian Zhuang uint8_t flags; 346eb5073f4SHaojian Zhuang uint8_t reserved0; 347eb5073f4SHaojian Zhuang uint8_t task_tag; 348eb5073f4SHaojian Zhuang uint8_t reserved1; 349eb5073f4SHaojian Zhuang uint8_t reserved2; 350eb5073f4SHaojian Zhuang uint8_t reserved3; 351eb5073f4SHaojian Zhuang uint8_t reserved4; 352eb5073f4SHaojian Zhuang uint8_t total_ehs_len; 353eb5073f4SHaojian Zhuang uint8_t reserved5; 354eb5073f4SHaojian Zhuang uint16_t data_segment_len; 355eb5073f4SHaojian Zhuang uint32_t reserved6; 356eb5073f4SHaojian Zhuang uint32_t reserved7; 357eb5073f4SHaojian Zhuang uint32_t reserved8; 358eb5073f4SHaojian Zhuang uint32_t reserved9; 359eb5073f4SHaojian Zhuang uint32_t reserved10; 360eb5073f4SHaojian Zhuang uint32_t e2ecrc; 361eb5073f4SHaojian Zhuang } nop_out_upiu_t; /* 36 bytes with big endian */ 362eb5073f4SHaojian Zhuang 363eb5073f4SHaojian Zhuang /* NOP IN UPIU */ 364eb5073f4SHaojian Zhuang typedef struct nop_in_upiu { 365eb5073f4SHaojian Zhuang uint8_t trans_type; 366eb5073f4SHaojian Zhuang uint8_t flags; 367eb5073f4SHaojian Zhuang uint8_t reserved0; 368eb5073f4SHaojian Zhuang uint8_t task_tag; 369eb5073f4SHaojian Zhuang uint8_t reserved1; 370eb5073f4SHaojian Zhuang uint8_t reserved2; 371eb5073f4SHaojian Zhuang uint8_t response; 372eb5073f4SHaojian Zhuang uint8_t reserved3; 373eb5073f4SHaojian Zhuang uint8_t total_ehs_len; 374eb5073f4SHaojian Zhuang uint8_t dev_info; 375eb5073f4SHaojian Zhuang uint16_t data_segment_len; 376eb5073f4SHaojian Zhuang uint32_t reserved4; 377eb5073f4SHaojian Zhuang uint32_t reserved5; 378eb5073f4SHaojian Zhuang uint32_t reserved6; 379eb5073f4SHaojian Zhuang uint32_t reserved7; 380eb5073f4SHaojian Zhuang uint32_t reserved8; 381eb5073f4SHaojian Zhuang uint32_t e2ecrc; 382eb5073f4SHaojian Zhuang } nop_in_upiu_t; /* 36 bytes with big endian */ 383eb5073f4SHaojian Zhuang 384eb5073f4SHaojian Zhuang /* Command UPIU */ 385eb5073f4SHaojian Zhuang typedef struct cmd_upiu { 386eb5073f4SHaojian Zhuang uint8_t trans_type; 387eb5073f4SHaojian Zhuang uint8_t flags; 388eb5073f4SHaojian Zhuang uint8_t lun; 389eb5073f4SHaojian Zhuang uint8_t task_tag; 390eb5073f4SHaojian Zhuang uint8_t cmd_set_type; 391eb5073f4SHaojian Zhuang uint8_t reserved0; 392eb5073f4SHaojian Zhuang uint8_t reserved1; 393eb5073f4SHaojian Zhuang uint8_t reserved2; 394eb5073f4SHaojian Zhuang uint8_t total_ehs_len; 395eb5073f4SHaojian Zhuang uint8_t reserved3; 396eb5073f4SHaojian Zhuang uint16_t data_segment_len; 397eb5073f4SHaojian Zhuang uint32_t exp_data_trans_len; 398eb5073f4SHaojian Zhuang /* 399eb5073f4SHaojian Zhuang * A CDB has a fixed length of 16bytes or a variable length 400eb5073f4SHaojian Zhuang * of between 12 and 260 bytes 401eb5073f4SHaojian Zhuang */ 402eb5073f4SHaojian Zhuang uint8_t cdb[16]; /* little endian */ 403eb5073f4SHaojian Zhuang } cmd_upiu_t; /* 32 bytes with big endian except for cdb[] */ 404eb5073f4SHaojian Zhuang 405eb5073f4SHaojian Zhuang typedef struct query_desc { 406eb5073f4SHaojian Zhuang uint8_t opcode; 407eb5073f4SHaojian Zhuang uint8_t idn; 408eb5073f4SHaojian Zhuang uint8_t index; 409eb5073f4SHaojian Zhuang uint8_t selector; 410eb5073f4SHaojian Zhuang uint8_t reserved0[2]; 411eb5073f4SHaojian Zhuang uint16_t length; 412eb5073f4SHaojian Zhuang uint32_t reserved2[2]; 413eb5073f4SHaojian Zhuang } query_desc_t; /* 16 bytes with big endian */ 414eb5073f4SHaojian Zhuang 415eb5073f4SHaojian Zhuang typedef struct query_flag { 416eb5073f4SHaojian Zhuang uint8_t opcode; 417eb5073f4SHaojian Zhuang uint8_t idn; 418eb5073f4SHaojian Zhuang uint8_t index; 419eb5073f4SHaojian Zhuang uint8_t selector; 420eb5073f4SHaojian Zhuang uint8_t reserved0[7]; 421eb5073f4SHaojian Zhuang uint8_t value; 422eb5073f4SHaojian Zhuang uint32_t reserved8; 423eb5073f4SHaojian Zhuang } query_flag_t; /* 16 bytes with big endian */ 424eb5073f4SHaojian Zhuang 425eb5073f4SHaojian Zhuang typedef struct query_attr { 426eb5073f4SHaojian Zhuang uint8_t opcode; 427eb5073f4SHaojian Zhuang uint8_t idn; 428eb5073f4SHaojian Zhuang uint8_t index; 429eb5073f4SHaojian Zhuang uint8_t selector; 430eb5073f4SHaojian Zhuang uint8_t reserved0[4]; 431eb5073f4SHaojian Zhuang uint32_t value; /* little endian */ 432eb5073f4SHaojian Zhuang uint32_t reserved4; 433eb5073f4SHaojian Zhuang } query_attr_t; /* 16 bytes with big endian except for value */ 434eb5073f4SHaojian Zhuang 435eb5073f4SHaojian Zhuang /* Query Request UPIU */ 436eb5073f4SHaojian Zhuang typedef struct query_upiu { 437eb5073f4SHaojian Zhuang uint8_t trans_type; 438eb5073f4SHaojian Zhuang uint8_t flags; 439eb5073f4SHaojian Zhuang uint8_t reserved0; 440eb5073f4SHaojian Zhuang uint8_t task_tag; 441eb5073f4SHaojian Zhuang uint8_t reserved1; 442eb5073f4SHaojian Zhuang uint8_t query_func; 443eb5073f4SHaojian Zhuang uint8_t reserved2; 444eb5073f4SHaojian Zhuang uint8_t reserved3; 445eb5073f4SHaojian Zhuang uint8_t total_ehs_len; 446eb5073f4SHaojian Zhuang uint8_t reserved4; 447eb5073f4SHaojian Zhuang uint16_t data_segment_len; 448eb5073f4SHaojian Zhuang /* Transaction Specific Fields */ 449eb5073f4SHaojian Zhuang union { 450eb5073f4SHaojian Zhuang query_desc_t desc; 451eb5073f4SHaojian Zhuang query_flag_t flag; 452eb5073f4SHaojian Zhuang query_attr_t attr; 453eb5073f4SHaojian Zhuang } ts; 454eb5073f4SHaojian Zhuang uint32_t reserved5; 455eb5073f4SHaojian Zhuang } query_upiu_t; /* 32 bytes with big endian */ 456eb5073f4SHaojian Zhuang 457eb5073f4SHaojian Zhuang /* Query Response UPIU */ 458eb5073f4SHaojian Zhuang typedef struct query_resp_upiu { 459eb5073f4SHaojian Zhuang uint8_t trans_type; 460eb5073f4SHaojian Zhuang uint8_t flags; 461eb5073f4SHaojian Zhuang uint8_t reserved0; 462eb5073f4SHaojian Zhuang uint8_t task_tag; 463eb5073f4SHaojian Zhuang uint8_t reserved1; 464eb5073f4SHaojian Zhuang uint8_t query_func; 465eb5073f4SHaojian Zhuang uint8_t query_resp; 466eb5073f4SHaojian Zhuang uint8_t reserved2; 467eb5073f4SHaojian Zhuang uint8_t total_ehs_len; 468eb5073f4SHaojian Zhuang uint8_t dev_info; 469eb5073f4SHaojian Zhuang uint16_t data_segment_len; 470eb5073f4SHaojian Zhuang union { 471eb5073f4SHaojian Zhuang query_desc_t desc; 472eb5073f4SHaojian Zhuang query_flag_t flag; 473eb5073f4SHaojian Zhuang query_attr_t attr; 474eb5073f4SHaojian Zhuang } ts; 475eb5073f4SHaojian Zhuang uint32_t reserved3; 476eb5073f4SHaojian Zhuang } query_resp_upiu_t; /* 32 bytes with big endian */ 477eb5073f4SHaojian Zhuang 478eb5073f4SHaojian Zhuang /* Response UPIU */ 479eb5073f4SHaojian Zhuang typedef struct resp_upiu { 480eb5073f4SHaojian Zhuang uint8_t trans_type; 481eb5073f4SHaojian Zhuang uint8_t flags; 482eb5073f4SHaojian Zhuang uint8_t lun; 483eb5073f4SHaojian Zhuang uint8_t task_tag; 484eb5073f4SHaojian Zhuang uint8_t cmd_set_type; 485eb5073f4SHaojian Zhuang uint8_t reserved0; 486eb5073f4SHaojian Zhuang uint8_t reserved1; 487eb5073f4SHaojian Zhuang uint8_t status; 488eb5073f4SHaojian Zhuang uint8_t total_ehs_len; 489eb5073f4SHaojian Zhuang uint8_t dev_info; 490eb5073f4SHaojian Zhuang uint16_t data_segment_len; 491eb5073f4SHaojian Zhuang uint32_t res_trans_cnt; /* Residual Transfer Count */ 492eb5073f4SHaojian Zhuang uint32_t reserved2[4]; 493eb5073f4SHaojian Zhuang uint16_t sense_data_len; 494eb5073f4SHaojian Zhuang union { 495eb5073f4SHaojian Zhuang uint8_t sense_data[18]; 496eb5073f4SHaojian Zhuang sense_data_t sense; 497eb5073f4SHaojian Zhuang } sd; 498eb5073f4SHaojian Zhuang } resp_upiu_t; /* 52 bytes with big endian */ 499eb5073f4SHaojian Zhuang 500eb5073f4SHaojian Zhuang typedef struct cmd_info { 501eb5073f4SHaojian Zhuang uintptr_t buf; 502eb5073f4SHaojian Zhuang size_t length; 503eb5073f4SHaojian Zhuang int lba; 504eb5073f4SHaojian Zhuang uint8_t op; 505eb5073f4SHaojian Zhuang uint8_t direction; 506eb5073f4SHaojian Zhuang uint8_t lun; 507eb5073f4SHaojian Zhuang } cmd_info_t; 508eb5073f4SHaojian Zhuang 509eb5073f4SHaojian Zhuang typedef struct utp_utrd { 510eb5073f4SHaojian Zhuang uintptr_t header; /* utrd_header_t */ 511eb5073f4SHaojian Zhuang uintptr_t upiu; 512eb5073f4SHaojian Zhuang uintptr_t resp_upiu; 513eb5073f4SHaojian Zhuang uintptr_t prdt; 514eb5073f4SHaojian Zhuang size_t size_upiu; 515eb5073f4SHaojian Zhuang size_t size_resp_upiu; 516eb5073f4SHaojian Zhuang size_t size_prdt; 517eb5073f4SHaojian Zhuang int task_tag; 518eb5073f4SHaojian Zhuang } utp_utrd_t; 519eb5073f4SHaojian Zhuang 520eb5073f4SHaojian Zhuang /* Physical Region Description Table */ 521eb5073f4SHaojian Zhuang typedef struct prdt { 522eb5073f4SHaojian Zhuang uint32_t dba; /* Data Base Address */ 523eb5073f4SHaojian Zhuang uint32_t dbau; /* Data Base Address Upper 32-bits */ 524eb5073f4SHaojian Zhuang uint32_t reserved0; 525eb5073f4SHaojian Zhuang uint32_t dbc : 18; /* Data Byte Count */ 526eb5073f4SHaojian Zhuang uint32_t reserved1 : 14; 527eb5073f4SHaojian Zhuang } prdt_t; 528eb5073f4SHaojian Zhuang 529eb5073f4SHaojian Zhuang typedef struct uic_cmd { 530eb5073f4SHaojian Zhuang uint32_t op; 531eb5073f4SHaojian Zhuang uint32_t arg1; 532eb5073f4SHaojian Zhuang uint32_t arg2; 533eb5073f4SHaojian Zhuang uint32_t arg3; 534eb5073f4SHaojian Zhuang } uic_cmd_t; 535eb5073f4SHaojian Zhuang 536eb5073f4SHaojian Zhuang typedef struct ufs_params { 537eb5073f4SHaojian Zhuang uintptr_t reg_base; 538eb5073f4SHaojian Zhuang uintptr_t desc_base; 539eb5073f4SHaojian Zhuang size_t desc_size; 540eb5073f4SHaojian Zhuang unsigned long flags; 541eb5073f4SHaojian Zhuang } ufs_params_t; 542eb5073f4SHaojian Zhuang 543eb5073f4SHaojian Zhuang typedef struct ufs_ops { 544eb5073f4SHaojian Zhuang int (*phy_init)(ufs_params_t *params); 545eb5073f4SHaojian Zhuang int (*phy_set_pwr_mode)(ufs_params_t *params); 546eb5073f4SHaojian Zhuang } ufs_ops_t; 547eb5073f4SHaojian Zhuang 548eb5073f4SHaojian Zhuang int ufshc_send_uic_cmd(uintptr_t base, uic_cmd_t *cmd); 549eb5073f4SHaojian Zhuang int ufshc_dme_get(unsigned int attr, unsigned int idx, unsigned int *val); 550eb5073f4SHaojian Zhuang int ufshc_dme_set(unsigned int attr, unsigned int idx, unsigned int val); 551eb5073f4SHaojian Zhuang 552eb5073f4SHaojian Zhuang unsigned int ufs_read_attr(int idn); 553eb5073f4SHaojian Zhuang void ufs_write_attr(int idn, unsigned int value); 554eb5073f4SHaojian Zhuang unsigned int ufs_read_flag(int idn); 555eb5073f4SHaojian Zhuang void ufs_set_flag(int idn); 556eb5073f4SHaojian Zhuang void ufs_clear_flag(int idn); 557eb5073f4SHaojian Zhuang void ufs_read_desc(int idn, int index, uintptr_t buf, size_t size); 558eb5073f4SHaojian Zhuang void ufs_write_desc(int idn, int index, uintptr_t buf, size_t size); 559eb5073f4SHaojian Zhuang size_t ufs_read_blocks(int lun, int lba, uintptr_t buf, size_t size); 560eb5073f4SHaojian Zhuang size_t ufs_write_blocks(int lun, int lba, const uintptr_t buf, size_t size); 561eb5073f4SHaojian Zhuang int ufs_init(const ufs_ops_t *ops, ufs_params_t *params); 562eb5073f4SHaojian Zhuang 563c3cf06f1SAntonio Nino Diaz #endif /* UFS_H */ 564