#define UFSHCI_UCD_PRDT_MAX_SEGS 64
#define UFSHCI_UCD_PRDT_MAX_XFER (UFSHCI_UCD_PRDT_MAX_SEGS * PAGE_SIZE)
#define UFSHCI_INTR_AGGR_TIMEOUT 0x08
#define UFSHCI_INTR_AGGR_COUNT_MAX 31
#define UFSHCI_SLOTS_MIN 1
#define UFSHCI_SLOTS_MAX 32
#define UFSHCI_TARGETS_MAX 1
#define UFSHCI_LBS 4096
#define UFSHCI_REG_CAP 0x00
#define UFSHCI_REG_CAP_CS (1 << 28)
#define UFSHCI_REG_CAP_UICDMETMS (1 << 26)
#define UFSHCI_REG_CAP_OODDS (1 << 25)
#define UFSHCI_REG_CAP_64AS (1 << 24)
#define UFSHCI_REG_AUTOH8 (1 << 23)
#define UFSHCI_REG_CAP_NUTMRS(x) ((x >> 16) & 0x00000007)
#define UFSHCI_REG_CAP_RTT(x) ((x >> 8) & 0x000000ff)
#define UFSHCI_REG_CAP_NUTRS(x) ((x >> 0) & 0x0000001f)
#define UFSHCI_REG_VER 0x08
#define UFSHCI_REG_VER_MAJOR(x) ((x >> 8) & 0x0000000f)
#define UFSHCI_REG_VER_MINOR(x) ((x >> 4) & 0x0000000f)
#define UFSHCI_REG_VER_SUFFIX(x) ((x >> 0) & 0x0000000f)
#define UFSHCI_REG_HCPID 0x10
#define UFSHCI_REG_HCMID 0x14
#define UFSHCI_REG_HCMID_BI(x) ((x >> 8) & 0x000000ff)
#define UFSHCI_REG_HCMID_MIC(x) ((x >> 0) & 0x000000ff)
#define UFSHCI_REG_AHIT 0x18
#define UFSHCI_REG_AHIT_TS(x) (x << 10)
#define UFSHCI_REG_AHIT_TS_1US 0x00
#define UFSHCI_REG_AHIT_TS_10US 0x01
#define UFSHCI_REG_AHIT_TS_100US 0x02
#define UFSHCI_REG_AHIT_TS_1MS 0x03
#define UFSHCI_REG_AHIT_TS_10MS 0x04
#define UFSHCI_REG_AHIT_TS_100MS 0x05
#define UFSHCI_REG_IS 0x20
#define UFSHCI_REG_IS_CEFES (1 << 18)
#define UFSHCI_REG_IS_SBFES (1 << 17)
#define UFSHCI_REG_IS_HCFES (1 << 16)
#define UFSHCI_REG_IS_UTPES (1 << 12)
#define UFSHCI_REG_IS_DFES (1 << 11)
#define UFSHCI_REG_IS_UCCS (1 << 10)
#define UFSHCI_REG_IS_UTMRCS (1 << 9)
#define UFSHCI_REG_IS_ULSS (1 << 8)
#define UFSHCI_REG_IS_ULLS (1 << 7)
#define UFSHCI_REG_IS_UHES (1 << 6)
#define UFSHCI_REG_IS_UHXS (1 << 5)
#define UFSHCI_REG_IS_UPMS (1 << 4)
#define UFSHCI_REG_IS_UTMS (1 << 3)
#define UFSHCI_REG_IS_UE (1 << 2)
#define UFSHCI_REG_IS_UDEPRI (1 << 1)
#define UFSHCI_REG_IS_UTRCS (1 << 0)
#define UFSHCI_REG_IE 0x24
#define UFSHCI_REG_IE_CEFFE (1 << 18)
#define UFSHCI_REG_IE_SBFEE (1 << 17)
#define UFSHCI_REG_IE_HCFEE (1 << 16)
#define UFSHCI_REG_IE_UTPEE (1 << 12)
#define UFSHCI_REG_IE_DFEE (1 << 11)
#define UFSHCI_REG_IE_UCCE (1 << 10)
#define UFSHCI_REG_IE_UTMRCE (1 << 9)
#define UFSHCI_REG_IE_ULSSE (1 << 8)
#define UFSHCI_REG_IE_ULLSE (1 << 7)
#define UFSHCI_REG_IE_UHESE (1 << 6)
#define UFSHCI_REG_IE_UHXSE (1 << 5)
#define UFSHCI_REG_IE_UPMSE (1 << 4)
#define UFSHCI_REG_IE_UTMSE (1 << 3)
#define UFSHCI_REG_IE_UEE (1 << 2)
#define UFSHCI_REG_IE_UDEPRIE (1 << 1)
#define UFSHCI_REG_IE_UTRCE (1 << 0)
#define UFSHCI_REG_HCS 0x30
#define UFSHCI_REG_HCS_TLUNUTPE(x) ((x >> 24) & 0x000000ff)
#define UFSHCI_REG_HCS_TTAGUTPE(x) ((x >> 16) & 0x000000ff)
#define UFSHCI_REG_HCS_UTPEC(x) ((x >> 12) & 0x0000000f)
#define UFSHCI_REG_HCS_UPMCRS(x) ((x >> 8) & 0x00000007)
#define UFSHCI_REG_HCS_UPMCRS_PWR_OK 0x00
#define UFSHCI_REG_HCS_UPMCRS_PWR_LOCAL 0x01
#define UFSHCI_REG_HCS_UPMCRS_PWR_REMTOTE 0x02
#define UFSHCI_REG_HCS_UMPCRS_PWR_BUSY 0x03
#define UFSHCI_REG_HCS_UMPCRS_PWR_ERROR_CAP 0x04
#define UFSHCI_REG_HCS_UMPCRS_PWR_FATAL_ERROR 0x05
#define UFSHCI_REG_HCS_UCRDY (1 << 3)
#define UFSHCI_REG_HCS_UTMRLRDY (1 << 2)
#define UFSHCI_REG_HCS_UTRLRDY (1 << 1)
#define UFSHCI_REG_HCS_DP (1 << 0)
#define UFSHCI_REG_HCE 0x34
#define UFSHCI_REG_HCE_CGE (1 << 1)
#define UFSHCI_REG_HCE_HCE (1 << 0)
#define UFSHCI_REG_UECPA 0x38
#define UFSHCI_REG_UECDL 0x3C
#define UFSHCI_REG_UECN 0x40
#define UFSHCI_REG_UECT 0x44
#define UFSHCI_REG_UECDME 0x48
#define UFSHCI_REG_UTRIACR 0x4C
#define UFSHCI_REG_UTRIACR_IAEN (1U << 31)
#define UFSHCI_REG_UTRIACR_IAPWEN (1 << 24)
#define UFSHCI_REG_UTRIACR_IASB (1 << 20)
#define UFSHCI_REG_UTRIACR_CTR (1 << 16)
#define UFSHCI_REG_UTRIACR_IACTH(x) (x << 8)
#define UFSHCI_REG_UTRIACR_IATOVAL(x) (x << 0)
#define UFSHCI_REG_UTRLBA 0x50
#define UFSHCI_REG_UTRLBAU 0x54
#define UFSHCI_REG_UTRLDBR 0x58
#define UFSHCI_REG_UTRLCLR 0x5C
#define UFSHCI_REG_UTRLRSR 0x60
#define UFSHCI_REG_UTRLRSR_STOP 0x00
#define UFSHCI_REG_UTRLRSR_START 0x01
#define UFSHCI_REG_UTRLCNR 0x64
#define UFSHCI_REG_UTMRLBA 0x70
#define UFSHCI_REG_UTMRLBAU 0x74
#define UFSHCI_REG_UTMRLDBR 0x78
#define UFSHCI_REG_UTMRLCLR 0x7C
#define UFSHCI_REG_UTMRLRSR 0x80
#define UFSHCI_REG_UTMRLRSR_STOP 0x00
#define UFSHCI_REG_UTMRLRSR_START 0x01
#define UFSHCI_REG_UICCMD 0x90
#define UFSHCI_REG_UICCMD_CMDOP_DME_GET 0x01
#define UFSHCI_REG_UICCMD_CMDOP_DME_SET 0x02
#define UFSHCI_REG_UICCMD_CMDOP_DME_PEER_GET 0x03
#define UFSHCI_REG_UICCMD_CMDOP_DME_PEER_SET 0x04
#define UFSHCI_REG_UICCMD_CMDOP_DME_POWERON 0x10
#define UFSHCI_REG_UICCMD_CMDOP_DME_POWEROFF 0x11
#define UFSHCI_REG_UICCMD_CMDOP_DME_ENABLE 0x12
#define UFSHCI_REG_UICCMD_CMDOP_DME_RESET 0x14
#define UFSHCI_REG_UICCMD_CMDOP_DME_ENDPOINTRESET 0x15
#define UFSHCI_REG_UICCMD_CMDOP_DME_LINKSTARTUP 0x16
#define UFSHCI_REG_UICCMD_CMDOP_DME_HIBERNATE_ENTER 0x17
#define UFSHCI_REG_UICCMD_CMDOP_DME_HIBERNATE_EXIT 0x18
#define UFSHCI_REG_UICCMD_CMDOP_DME_TEST_MODE 0x1A
#define UFSHCI_REG_UICCMDARG1 0x94
#define UFSHCI_REG_UICCMDARG2 0x98
#define UFSHCI_REG_UICCMDARG3 0x9C
#define UFSHCI_UTRD_DW0_CT_UFS (1 << 28)
#define UFSHCI_UTRD_DW0_DD_NO (0 << 25)
#define UFSHCI_UTRD_DW0_DD_I2T (1 << 25)
#define UFSHCI_UTRD_DW0_DD_T2I (2 << 25)
#define UFSHCI_UTRD_DW0_I_REG (0 << 24)
#define UFSHCI_UTRD_DW0_I_INT (1 << 24)
#define UFSHCI_UTRD_DW0_CE_DISABLE (0 << 23)
#define UFSHCI_UTRD_DW0_CE_ENABLE (1 << 23)
#define UFSHCI_UTRD_DW0_CCI(x) (x & 0x000000ff)
#define UFSHCI_UTRD_DW1_DUNL(x) (x << 0)
#define UFSHCI_UTRD_DW2_OCS(x) (x & 0x000000ff)
#define UFSHCI_UTRD_DW2_OCS_SUCCESS 0x00
#define UFSHCI_UTRD_DW2_OCS_ICTA 0x01
#define UFSHCI_UTRD_DW2_OCS_IPA 0x02
#define UFSHCI_UTRD_DW2_OCS_MDBS 0x03
#define UFSHCI_UTRD_DW2_OCS_MRUS 0x04
#define UFSHCI_UTRD_DW2_OCS_CF 0x05
#define UFSHCI_UTRD_DW2_OCS_ABRT 0x06
#define UFSHCI_UTRD_DW2_OCS_FE 0x07
#define UFSHCI_UTRD_DW2_OCS_DFE 0x08
#define UFSHCI_UTRD_DW2_OCS_ICC 0x09
#define UFSHCI_UTRD_DW2_OCS_GCE 0x0A
#define UFSHCI_UTRD_DW2_OCS_IOV 0x0F
#define UFSHCI_UTRD_DW3_DUNU(x) (x << 0)
#define UFSHCI_UTRD_DW4_UCDBA(x) (x << 7)
#define UFSHCI_UTRD_DW5_UCDBAU(x) (x << 0)
#define UFSHCI_UTRD_DW6_RUO(x) (x << 16)
#define UFSHCI_UTRD_DW6_RUL(x) (x & 0x0000ffff)
#define UFSHCI_UTRD_DW7_PRDTO(x) (x << 16)
#define UFSHCI_UTRD_DW7_PRDTL(x) (x & 0x0000ffff)
struct ufshci_utrd {
uint32_t dw0;
uint32_t dw1;
uint32_t dw2;
uint32_t dw3;
uint32_t dw4;
uint32_t dw5;
uint32_t dw6;
uint32_t dw7;
} __packed;
#define UFSHCI_UCD_DW0_DBA(x) (x & 0xfffffffc)
#define UFSHCI_UCD_DW3_DBC(x) (x & 0x0003ffff)
struct ufshci_ucd_prdt {
uint32_t dw0;
uint32_t dw1;
uint32_t dw2;
uint32_t dw3;
} __packed;
#define UFSHCI_UTMRD_DW0_I_DISABLE (0 << 24)
#define UFSHCI_UTMRD_DW0_I_ENABLE (1 << 24)
#define UFSHCI_UTMRD_DW2_OCS(x) (x & 0x000000ff)
#define UFSHCI_UTMRD_DW2_OCS_SUCCESS 0x00
#define UFSHCI_UTMRD_DW2_OCS_ICTA 0x01
#define UFSHCI_UTMRD_DW2_OCS_IPA 0x02
#define UFSHCI_UTMRD_DW2_OCS_MDBS 0x03
#define UFSHCI_UTMRD_DW2_OCS_MRUS 0x04
#define UFSHCI_UTMRD_DW2_OCS_CF 0x05
#define UFSHCI_UTMRD_DW2_OCS_ABRT 0x06
#define UFSHCI_UTMRD_DW2_OCS_FE 0x07
#define UFSHCI_UTMRD_DW2_OCS_DFE 0x08
#define UFSHCI_UTMRD_DW2_OCS_ICC 0x09
#define UFSHCI_UTMRD_DW2_OCS_GCE 0x0A
#define UFSHCI_UTMRD_DW2_OCS_IOV 0x0F
struct ufshci_utmrd {
uint32_t dw0;
uint32_t dw1;
uint32_t dw2;
uint32_t dw3;
uint8_t dw4_w11[32];
uint8_t dw12_dw19[32];
} __packed;
#define UPIU_TC_I2T_NOP_OUT 0x00
#define UPIU_TC_I2T_COMMAND 0x01
#define UPIU_TC_I2T_DATA_OUT 0x02
#define UPIU_TC_I2T_TMR 0x04
#define UPIU_TC_I2T_QUERY_REQUEST 0x16
#define UPIU_TC_T2I_NOP_IN 0x20
#define UPIU_TC_T2I_RESPONSE 0x21
#define UPIU_TC_T2I_DATA_IN 0x22
#define UPIU_TC_T2I_TMR 0x24
#define UPIU_TC_T2I_QUERY_RESPONSE 0x36
#define UPIU_TC_T2I_REJECT 0x3f
#define UPIU_SCSI_RSP_INQUIRY_SIZE 36
#define UPIU_SCSI_RSP_CAPACITY16_SIZE 32
#define UPIU_SCSI_RSP_CAPACITY_SIZE 8
struct upiu_hdr {
uint8_t tc;
uint8_t flags;
uint8_t lun;
uint8_t task_tag;
uint8_t cmd_set_type;
uint8_t query;
uint8_t response;
uint8_t status;
uint8_t ehs_len;
uint8_t device_info;
uint16_t ds_len;
} __packed;
struct upiu_command {
struct upiu_hdr hdr;
uint32_t expected_xfer_len;
uint8_t cdb[16];
} __packed;
struct upiu_response {
struct upiu_hdr hdr;
uint32_t residual_xfer_len;
uint8_t cdb[16];
} __packed;
struct ufshci_ucd {
struct upiu_command cmd;
struct upiu_response rsp;
struct ufshci_ucd_prdt prdt[UFSHCI_UCD_PRDT_MAX_SEGS];
} __packed __aligned(128);