1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
|
/* $OpenBSD: ufshcireg.h,v 1.7 2024/05/09 08:20:22 mglocker Exp $ */
/*
* Copyright (c) 2022 Marcus Glocker <mglocker@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* Generic parameters.
*/
#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 0x64 /* 4ms */
#define UFSHCI_MAX_UNITS 32
/*
* Controller Capabilities Registers
*/
/* Controller Capabilities */
#define UFSHCI_REG_CAP 0x00
#define UFSHCI_REG_CAP_CS (1 << 28) /* RO */
#define UFSHCI_REG_CAP_UICDMETMS (1 << 26) /* RO */
#define UFSHCI_REG_CAP_OODDS (1 << 25) /* RO */
#define UFSHCI_REG_CAP_64AS (1 << 24) /* RO */
#define UFSHCI_REG_AUTOH8 (1 << 23) /* RO */
#define UFSHCI_REG_CAP_NUTMRS(x) ((x >> 16) & 0x00000007) /* RO */
#define UFSHCI_REG_CAP_RTT(x) ((x >> 8) & 0x000000ff) /* RO */
#define UFSHCI_REG_CAP_NUTRS(x) ((x >> 0) & 0x0000001f) /* RO */
/* UFS Version in BCD format */
#define UFSHCI_REG_VER 0x08
#define UFSHCI_REG_VER_MAJOR(x) ((x >> 8) & 0x0000000f) /* RO */
#define UFSHCI_REG_VER_MINOR(x) ((x >> 4) & 0x0000000f) /* RO */
#define UFSHCI_REG_VER_SUFFIX(x) ((x >> 0) & 0x0000000f) /* RO */
/* Product ID */
#define UFSHCI_REG_HCPID 0x10
/* Manufacturer ID */
#define UFSHCI_REG_HCMID 0x14
#define UFSHCI_REG_HCMID_BI(x) ((x >> 8) & 0x000000ff) /* RO */
#define UFSHCI_REG_HCMID_MIC(x) ((x >> 0) & 0x000000ff) /* RO */
/* Auto-Hibernate Idle Timer */
#define UFSHCI_REG_AHIT 0x18
/*
* Operation and Runtime Registers
*/
/* Interrupt Status */
#define UFSHCI_REG_IS 0x20
#define UFSHCI_REG_IS_CEFES (1 << 18) /* RWC */
#define UFSHCI_REG_IS_SBFES (1 << 17) /* RWC */
#define UFSHCI_REG_IS_HCFES (1 << 16) /* RWC */
#define UFSHCI_REG_IS_UTPES (1 << 12) /* RWC */
#define UFSHCI_REG_IS_DFES (1 << 11) /* RWC */
#define UFSHCI_REG_IS_UCCS (1 << 10) /* RWC */
#define UFSHCI_REG_IS_UTMRCS (1 << 9) /* RWC */
#define UFSHCI_REG_IS_ULSS (1 << 8) /* RWC */
#define UFSHCI_REG_IS_ULLS (1 << 7) /* RWC */
#define UFSHCI_REG_IS_UHES (1 << 6) /* RWC */
#define UFSHCI_REG_IS_UHXS (1 << 5) /* RWC */
#define UFSHCI_REG_IS_UPMS (1 << 4) /* RWC */
#define UFSHCI_REG_IS_UTMS (1 << 3) /* RWC */
#define UFSHCI_REG_IS_UE (1 << 2) /* RWC */
#define UFSHCI_REG_IS_UDEPRI (1 << 1) /* RWC */
#define UFSHCI_REG_IS_UTRCS (1 << 0) /* RWC */
/* Interrupt Enable */
#define UFSHCI_REG_IE 0x24
#define UFSHCI_REG_IE_CEFFE (1 << 18) /* RW */
#define UFSHCI_REG_IE_SBFEE (1 << 17) /* RW */
#define UFSHCI_REG_IE_HCFEE (1 << 16) /* RW */
#define UFSHCI_REG_IE_UTPEE (1 << 12) /* RW */
#define UFSHCI_REG_IE_DFEE (1 << 11) /* RW */
#define UFSHCI_REG_IE_UCCE (1 << 10) /* RW */
#define UFSHCI_REG_IE_UTMRCE (1 << 9) /* RW */
#define UFSHCI_REG_IE_ULSSE (1 << 8) /* RW */
#define UFSHCI_REG_IE_ULLSE (1 << 7) /* RW */
#define UFSHCI_REG_IE_UHESE (1 << 6) /* RW */
#define UFSHCI_REG_IE_UHXSE (1 << 5) /* RW */
#define UFSHCI_REG_IE_UPMSE (1 << 4) /* RW */
#define UFSHCI_REG_IE_UTMSE (1 << 3) /* RW */
#define UFSHCI_REG_IE_UEE (1 << 2) /* RW */
#define UFSHCI_REG_IE_UDEPRIE (1 << 1) /* RW */
#define UFSHCI_REG_IE_UTRCE (1 << 0) /* RW */
/* Host Controller Status */
#define UFSHCI_REG_HCS 0x30
#define UFSHCI_REG_HCS_TLUNUTPE(x) ((x << 24) & 0xff000000) /* RO */
#define UFSHCI_REG_HCS_TTAGUTPE(x) ((x << 16) & 0x00ff0000) /* RO */
#define UFSHCI_REG_HCS_UTPEC(x) ((x << 12) & 0x0000f000) /* RO */
#define UFSHCI_REG_HCS_UPMCRS(x) ((x << 8) & 0x00000700) /* RO */
#define UFSHCI_REG_HCS_UCRDY (1 << 3) /* RO */
#define UFSHCI_REG_HCS_UTMRLRDY (1 << 2) /* RO */
#define UFSHCI_REG_HCS_UTRLRDY (1 << 1) /* RO */
#define UFSHCI_REG_HCS_DP (1 << 0) /* RO */
/* Host Controller Enable */
#define UFSHCI_REG_HCE 0x34
#define UFSHCI_REG_HCE_CGE (1 << 1) /* RW */
#define UFSHCI_REG_HCE_HCE (1 << 0) /* RW */
/* Host UIC Error Code PHY Adapter Layer */
#define UFSHCI_REG_UECPA 0x38
/* Host UIC Error Code Data Link Layer */
#define UFSHCI_REG_UECDL 0x3C
/* Host UIC Error Code Network Layer */
#define UFSHCI_REG_UECN 0x40
/* Host UIC Error Code Transport Layer */
#define UFSHCI_REG_UECT 0x44
/* Host UIC Error Code */
#define UFSHCI_REG_UECDME 0x48
/* UTP Transfer Request Interrupt Aggregation Control Register */
#define UFSHCI_REG_UTRIACR 0x4C
#define UFSHCI_REG_UTRIACR_IAEN (1U << 31) /* RW */
#define UFSHCI_REG_UTRIACR_IAPWEN (1 << 24) /* WO */
#define UFSHCI_REG_UTRIACR_IASB (1 << 20) /* RO */
#define UFSHCI_REG_UTRIACR_CTR (1 << 16) /* WO */
#define UFSHCI_REG_UTRIACR_IACTH(x) (x << 8) /* RW, max. val = 31 */
#define UFSHCI_REG_UTRIACR_IATOVAL(x) (x << 0) /* RW, 40us units (1=40us) */
/*
* UTP Transfer Request List Registers
*/
/* Base Address */
#define UFSHCI_REG_UTRLBA 0x50 /* RW */
/* Base Address Upper 32-bits */
#define UFSHCI_REG_UTRLBAU 0x54 /* RW */
/* Door Bell Register */
#define UFSHCI_REG_UTRLDBR 0x58 /* RWS */
/* Clear Register */
#define UFSHCI_REG_UTRLCLR 0x5C /* WO */
/* Run-Stop Register */
#define UFSHCI_REG_UTRLRSR 0x60 /* RW */
#define UFSHCI_REG_UTRLRSR_STOP 0x00
#define UFSHCI_REG_UTRLRSR_START 0x01
/* Completion Notification Register */
#define UFSHCI_REG_UTRLCNR 0x64 /* RWC */
/*
* UTP Task Management Request List Registers
*/
/* Base Address */
#define UFSHCI_REG_UTMRLBA 0x70 /* RW */
/* Base Address Upper 32-bits */
#define UFSHCI_REG_UTMRLBAU 0x74 /* RW */
/* Door Bell Register */
#define UFSHCI_REG_UTMRLDBR 0x78 /* RWS */
/* Clear Register */
#define UFSHCI_REG_UTMRLCLR 0x7C /* WO */
/* Run-Stop Register */
#define UFSHCI_REG_UTMRLRSR 0x80 /* RW */
#define UFSHCI_REG_UTMRLRSR_STOP 0x00
#define UFSHCI_REG_UTMRLRSR_START 0x01
/*
* UIC Command Registers
*/
/* UIC Command Register */
#define UFSHCI_REG_UICCMD 0x90
#define UFSHCI_REG_UICCMD_CMDOP_DME_GET 0x01 /* RW */
#define UFSHCI_REG_UICCMD_CMDOP_DME_SET 0x02 /* RW */
#define UFSHCI_REG_UICCMD_CMDOP_DME_PEER_GET 0x03 /* RW */
#define UFSHCI_REG_UICCMD_CMDOP_DME_PEER_SET 0x04 /* RW */
#define UFSHCI_REG_UICCMD_CMDOP_DME_POWERON 0x10 /* RW */
#define UFSHCI_REG_UICCMD_CMDOP_DME_POWEROFF 0x11 /* RW */
#define UFSHCI_REG_UICCMD_CMDOP_DME_ENABLE 0x12 /* RW */
#define UFSHCI_REG_UICCMD_CMDOP_DME_RESET 0x14 /* RW */
#define UFSHCI_REG_UICCMD_CMDOP_DME_ENDPOINTRESET 0x15 /* RW */
#define UFSHCI_REG_UICCMD_CMDOP_DME_LINKSTARTUP 0x16 /* RW */
#define UFSHCI_REG_UICCMD_CMDOP_DME_HIBERNATE_ENTER 0x17 /* RW */
#define UFSHCI_REG_UICCMD_CMDOP_DME_HIBERNATE_EXIT 0x18 /* RW */
#define UFSHCI_REG_UICCMD_CMDOP_DME_TEST_MODE 0x1A /* RW */
/* UIC Command Argument 1 */
#define UFSHCI_REG_UICCMDARG1 0x94
/* UIC Command Argument 2 */
#define UFSHCI_REG_UICCMDARG2 0x98
/* UIC Command Argument 3 */
#define UFSHCI_REG_UICCMDARG3 0x9C
/*
* Vendor Specific Registers (0xC0 - 0xFF)
*/
/*
* UTP Transfer Request Descriptor Structure
*/
/* Command Type (CT) */
#define UFSHCI_UTRD_DW0_CT_UFS (1 << 28) /* UFS Storage */
/* Data Direction (DD) */
#define UFSHCI_UTRD_DW0_DD_NO (0 << 25) /* No transfer */
#define UFSHCI_UTRD_DW0_DD_I2T (1 << 25) /* From Initiator to Target */
#define UFSHCI_UTRD_DW0_DD_T2I (2 << 25) /* From Target to Initiator */
/* Interrupt (I) */
#define UFSHCI_UTRD_DW0_I_REG (0 << 24) /* Regular Command */
#define UFSHCI_UTRD_DW0_I_INT (1 << 24) /* Interrupt Command */
/* Crypto Enable (CE) */
#define UFSHCI_UTRD_DW0_CE_DISABLE (0 << 23) /* Disable Crypto */
#define UFSHCI_UTRD_DW0_CE_ENABLE (1 << 23) /* Enable Crypto */
/* Crypto Configuration Index (CCI) */
#define UFSHCI_UTRD_DW0_CCI(x) (x & 0x000000ff)
/* Data Unit Number Upper 32-bits (DUNL) */
#define UFSHCI_UTRD_DW1_DUNL(x) (x << 0)
/* Overall Command Status (OCS) */
#define UFSHCI_UTRD_DW2_OCS(x) (x & 0x000000ff)
#define UFSHCI_UTRD_DW2_OCS_SUCCESS 0x00 /* Success */
#define UFSHCI_UTRD_DW2_OCS_ICTA 0x01 /* Invalid Command Table Attr. */
#define UFSHCI_UTRD_DW2_OCS_IPA 0x02 /* Invalid PRDT Attr. */
#define UFSHCI_UTRD_DW2_OCS_MDBS 0x03 /* Mismatch Data Buffer Size */
#define UFSHCI_UTRD_DW2_OCS_MRUS 0x04 /* Mismatch Response UPIU Size */
#define UFSHCI_UTRD_DW2_OCS_CF 0x05 /* Communication Failure */
#define UFSHCI_UTRD_DW2_OCS_ABRT 0x06 /* Aborted */
#define UFSHCI_UTRD_DW2_OCS_FE 0x07 /* Fatal Error */
#define UFSHCI_UTRD_DW2_OCS_DFE 0x08 /* Device Fatal Error */
#define UFSHCI_UTRD_DW2_OCS_ICC 0x09 /* Invalid Crypto Configuration */
#define UFSHCI_UTRD_DW2_OCS_GCE 0x0A /* General Crypto Error */
#define UFSHCI_UTRD_DW2_OCS_IOV 0x0F /* Invalid OCS Value */
/* Data Unit Number Upper 32-bits Upper 32-bits (DUNU) */
#define UFSHCI_UTRD_DW3_DUNU(x) (x << 0)
/* UTP Command Descriptor Base Address (UCDBA) */
#define UFSHCI_UTRD_DW4_UCDBA(x) (x << 7)
/* UTP Command Descriptor Base Address Upper 32-bits (UCDBAU) */
#define UFSHCI_UTRD_DW5_UCDBAU(x) (x << 0)
/* Response UPIU Offset (RUO) */
#define UFSHCI_UTRD_DW6_RUO(x) (x << 16)
/* Response UPIU Length (RUL) */
#define UFSHCI_UTRD_DW6_RUL(x) (x & 0x0000ffff)
/* PRDT Offset (PRDTO) */
#define UFSHCI_UTRD_DW7_PRDTO(x) (x << 16)
/* PRDT Length (PRDTL) */
#define UFSHCI_UTRD_DW7_PRDTL(x) (x & 0x0000ffff)
struct ufshci_utrd {
uint32_t dw0; /* CT, DD, I, CE, CCI */
uint32_t dw1; /* Data Unit Number Lower 32-bits (DUNL) */
uint32_t dw2; /* OCS */
uint32_t dw3; /* Data Unit Number Upper 32-bits (DUNU) */
uint32_t dw4; /* UTP Cmd. Desc. Base Addr. Lower 32-bits (UCDBA) */
uint32_t dw5; /* UTP Cmd. Desc. Base Addr. Upper 32-bits (UCDBAU) */
uint32_t dw6; /* RUO, RUL */
uint32_t dw7; /* PRDTO, PRDTL */
} __packed;
/*
* UTP Command Descriptor, PRDT (Physical Region Description Table) Structure
*/
/* Data Base Address (DBA) */
#define UFSHCI_UCD_DW0_DBA(x) (x & 0xfffffffc)
/* Data Byte Count (DBC) */
#define UFSHCI_UCD_DW3_DBC(x) (x & 0x0003ffff)
struct ufshci_ucd_prdt {
uint32_t dw0; /* Data base Address Lower 32-bits (DBA) */
uint32_t dw1; /* Data base Address Upper 32-bits (DBAU) */
uint32_t dw2; /* Reserved */
uint32_t dw3; /* Data Byte Count (DBC) */
} __packed;
/*
* UTP Task Management Request Descriptor Structure
*/
/* Interrupt (I) */
#define UFSHCI_UTMRD_DW0_I_DISABLE (0 << 24)
#define UFSHCI_UTMRD_DW0_I_ENABLE (1 << 24)
/* Overall Command Status (OCS) */
#define UFSHCI_UTMRD_DW2_OCS(x) (x & 0x000000ff)
#define UFSHCI_UTMRD_DW2_OCS_SUCCESS 0x00 /* Success */
#define UFSHCI_UTMRD_DW2_OCS_ICTA 0x01 /* Invalid Command Table Attr. */
#define UFSHCI_UTMRD_DW2_OCS_IPA 0x02 /* Invalid PRDT Attr. */
#define UFSHCI_UTMRD_DW2_OCS_MDBS 0x03 /* Mismatch Data Buffer Size */
#define UFSHCI_UTMRD_DW2_OCS_MRUS 0x04 /* Mismatch Response UPIU Size */
#define UFSHCI_UTMRD_DW2_OCS_CF 0x05 /* Communication Failure */
#define UFSHCI_UTMRD_DW2_OCS_ABRT 0x06 /* Aborted */
#define UFSHCI_UTMRD_DW2_OCS_FE 0x07 /* Fatal Error */
#define UFSHCI_UTMRD_DW2_OCS_DFE 0x08 /* Device Fatal Error */
#define UFSHCI_UTMRD_DW2_OCS_ICC 0x09 /* Invalid Crypto Configuration */
#define UFSHCI_UTMRD_DW2_OCS_GCE 0x0A /* General Crypto Error */
#define UFSHCI_UTMRD_DW2_OCS_IOV 0x0F /* Invalid OCS Value */
struct ufshci_utmrd {
uint32_t dw0; /* I */
uint32_t dw1; /* Reserved */
uint32_t dw2; /* OCS */
uint32_t dw3; /* Reserved */
uint8_t dw4_w11[32]; /* Task Management Request UPIU */
uint8_t dw12_dw19[32]; /* Task Management Response UPIU */
} __packed;
/*
* ****************************************************************************
* Universal Flash Storage (UFS) Version 2.1 Specs from JESD220C
* ****************************************************************************
*/
/* UPIU structures are in Big Endian! */
#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; /* Transaction Code */
uint8_t flags;
uint8_t lun;
uint8_t taskid;
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; /* Data Segment Length */
} __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);
|