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