• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 #ifndef __UFS_H
3 #define __UFS_H
4 
5 #include <asm/io.h>
6 #include <dm.h>
7 
8 #include "unipro.h"
9 
10 #define UFS_CDB_SIZE	16
11 #define UPIU_TRANSACTION_UIC_CMD 0x1F
12 #define UIC_CMD_SIZE (sizeof(u32) * 4)
13 #define RESPONSE_UPIU_SENSE_DATA_LENGTH	18
14 #define UFS_MAX_LUNS		0x7F
15 
16 enum {
17 	TASK_REQ_UPIU_SIZE_DWORDS	= 8,
18 	TASK_RSP_UPIU_SIZE_DWORDS	= 8,
19 	ALIGNED_UPIU_SIZE		= 512,
20 };
21 
22 /* UFS device power modes */
23 enum ufs_dev_pwr_mode {
24 	UFS_ACTIVE_PWR_MODE	= 1,
25 	UFS_SLEEP_PWR_MODE	= 2,
26 	UFS_POWERDOWN_PWR_MODE	= 3,
27 };
28 
29 enum ufs_notify_change_status {
30 	PRE_CHANGE,
31 	POST_CHANGE,
32 };
33 
34 struct ufs_pa_layer_attr {
35 	u32 gear_rx;
36 	u32 gear_tx;
37 	u32 lane_rx;
38 	u32 lane_tx;
39 	u32 pwr_rx;
40 	u32 pwr_tx;
41 	u32 hs_rate;
42 };
43 
44 struct ufs_pwr_mode_info {
45 	bool is_valid;
46 	struct ufs_pa_layer_attr info;
47 };
48 
49 enum ufs_desc_def_size {
50 	QUERY_DESC_DEVICE_DEF_SIZE		= 0x40,
51 	QUERY_DESC_CONFIGURATION_DEF_SIZE	= 0x90,
52 	QUERY_DESC_UNIT_DEF_SIZE		= 0x23,
53 	QUERY_DESC_INTERCONNECT_DEF_SIZE	= 0x06,
54 	QUERY_DESC_GEOMETRY_DEF_SIZE		= 0x48,
55 	QUERY_DESC_POWER_DEF_SIZE		= 0x62,
56 	QUERY_DESC_HEALTH_DEF_SIZE		= 0x25,
57 };
58 
59 struct ufs_desc_size {
60 	int dev_desc;
61 	int pwr_desc;
62 	int geom_desc;
63 	int interc_desc;
64 	int unit_desc;
65 	int conf_desc;
66 	int hlth_desc;
67 };
68 
69 /*
70  * Request Descriptor Definitions
71  */
72 
73 /* Transfer request command type */
74 enum {
75 	UTP_CMD_TYPE_SCSI		= 0x0,
76 	UTP_CMD_TYPE_UFS		= 0x1,
77 	UTP_CMD_TYPE_DEV_MANAGE		= 0x2,
78 };
79 
80 /* UTP Transfer Request Command Offset */
81 #define UPIU_COMMAND_TYPE_OFFSET	28
82 
83 /* Offset of the response code in the UPIU header */
84 #define UPIU_RSP_CODE_OFFSET		8
85 
86 /* To accommodate UFS2.0 required Command type */
87 enum {
88 	UTP_CMD_TYPE_UFS_STORAGE	= 0x1,
89 };
90 
91 enum {
92 	UTP_SCSI_COMMAND		= 0x00000000,
93 	UTP_NATIVE_UFS_COMMAND		= 0x10000000,
94 	UTP_DEVICE_MANAGEMENT_FUNCTION	= 0x20000000,
95 	UTP_REQ_DESC_INT_CMD		= 0x01000000,
96 };
97 
98 /* UTP Transfer Request Data Direction (DD) */
99 enum {
100 	UTP_NO_DATA_TRANSFER	= 0x00000000,
101 	UTP_HOST_TO_DEVICE	= 0x02000000,
102 	UTP_DEVICE_TO_HOST	= 0x04000000,
103 };
104 
105 /* Overall command status values */
106 enum {
107 	OCS_SUCCESS			= 0x0,
108 	OCS_INVALID_CMD_TABLE_ATTR	= 0x1,
109 	OCS_INVALID_PRDT_ATTR		= 0x2,
110 	OCS_MISMATCH_DATA_BUF_SIZE	= 0x3,
111 	OCS_MISMATCH_RESP_UPIU_SIZE	= 0x4,
112 	OCS_PEER_COMM_FAILURE		= 0x5,
113 	OCS_ABORTED			= 0x6,
114 	OCS_FATAL_ERROR			= 0x7,
115 	OCS_INVALID_COMMAND_STATUS	= 0x0F,
116 	MASK_OCS			= 0x0F,
117 };
118 
119 /* The maximum length of the data byte count field in the PRDT is 256KB */
120 #define PRDT_DATA_BYTE_COUNT_MAX	(256 * 1024)
121 /* The granularity of the data byte count field in the PRDT is 32-bit */
122 #define PRDT_DATA_BYTE_COUNT_PAD	4
123 
124 #define GENERAL_UPIU_REQUEST_SIZE (sizeof(struct utp_upiu_req))
125 #define QUERY_DESC_MAX_SIZE       255
126 #define QUERY_DESC_MIN_SIZE       2
127 #define QUERY_DESC_HDR_SIZE       2
128 #define QUERY_OSF_SIZE            (GENERAL_UPIU_REQUEST_SIZE - \
129 					(sizeof(struct utp_upiu_header)))
130 #define RESPONSE_UPIU_SENSE_DATA_LENGTH	18
131 #define UPIU_HEADER_DWORD(byte3, byte2, byte1, byte0)\
132 			cpu_to_be32((byte3 << 24) | (byte2 << 16) |\
133 			 (byte1 << 8) | (byte0))
134 /*
135  * UFS Protocol Information Unit related definitions
136  */
137 
138 /* Task management functions */
139 enum {
140 	UFS_ABORT_TASK		= 0x01,
141 	UFS_ABORT_TASK_SET	= 0x02,
142 	UFS_CLEAR_TASK_SET	= 0x04,
143 	UFS_LOGICAL_RESET	= 0x08,
144 	UFS_QUERY_TASK		= 0x80,
145 	UFS_QUERY_TASK_SET	= 0x81,
146 };
147 
148 /* UTP UPIU Transaction Codes Initiator to Target */
149 enum {
150 	UPIU_TRANSACTION_NOP_OUT	= 0x00,
151 	UPIU_TRANSACTION_COMMAND	= 0x01,
152 	UPIU_TRANSACTION_DATA_OUT	= 0x02,
153 	UPIU_TRANSACTION_TASK_REQ	= 0x04,
154 	UPIU_TRANSACTION_QUERY_REQ	= 0x16,
155 };
156 
157 /* UTP UPIU Transaction Codes Target to Initiator */
158 enum {
159 	UPIU_TRANSACTION_NOP_IN		= 0x20,
160 	UPIU_TRANSACTION_RESPONSE	= 0x21,
161 	UPIU_TRANSACTION_DATA_IN	= 0x22,
162 	UPIU_TRANSACTION_TASK_RSP	= 0x24,
163 	UPIU_TRANSACTION_READY_XFER	= 0x31,
164 	UPIU_TRANSACTION_QUERY_RSP	= 0x36,
165 	UPIU_TRANSACTION_REJECT_UPIU	= 0x3F,
166 };
167 
168 /* UPIU Read/Write flags */
169 enum {
170 	UPIU_CMD_FLAGS_NONE	= 0x00,
171 	UPIU_CMD_FLAGS_WRITE	= 0x20,
172 	UPIU_CMD_FLAGS_READ	= 0x40,
173 };
174 
175 /* UPIU Task Attributes */
176 enum {
177 	UPIU_TASK_ATTR_SIMPLE	= 0x00,
178 	UPIU_TASK_ATTR_ORDERED	= 0x01,
179 	UPIU_TASK_ATTR_HEADQ	= 0x02,
180 	UPIU_TASK_ATTR_ACA	= 0x03,
181 };
182 
183 /* UPIU Query request function */
184 enum {
185 	UPIU_QUERY_FUNC_STANDARD_READ_REQUEST           = 0x01,
186 	UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST          = 0x81,
187 };
188 
189 /* Offset of the response code in the UPIU header */
190 #define UPIU_RSP_CODE_OFFSET		8
191 
192 enum {
193 	MASK_SCSI_STATUS		= 0xFF,
194 	MASK_TASK_RESPONSE              = 0xFF00,
195 	MASK_RSP_UPIU_RESULT            = 0xFFFF,
196 	MASK_QUERY_DATA_SEG_LEN         = 0xFFFF,
197 	MASK_RSP_UPIU_DATA_SEG_LEN	= 0xFFFF,
198 	MASK_RSP_EXCEPTION_EVENT        = 0x10000,
199 	MASK_TM_SERVICE_RESP		= 0xFF,
200 	MASK_TM_FUNC			= 0xFF,
201 };
202 
203 /* UTP QUERY Transaction Specific Fields OpCode */
204 enum query_opcode {
205 	UPIU_QUERY_OPCODE_NOP		= 0x0,
206 	UPIU_QUERY_OPCODE_READ_DESC	= 0x1,
207 	UPIU_QUERY_OPCODE_WRITE_DESC	= 0x2,
208 	UPIU_QUERY_OPCODE_READ_ATTR	= 0x3,
209 	UPIU_QUERY_OPCODE_WRITE_ATTR	= 0x4,
210 	UPIU_QUERY_OPCODE_READ_FLAG	= 0x5,
211 	UPIU_QUERY_OPCODE_SET_FLAG	= 0x6,
212 	UPIU_QUERY_OPCODE_CLEAR_FLAG	= 0x7,
213 	UPIU_QUERY_OPCODE_TOGGLE_FLAG	= 0x8,
214 };
215 
216 /* Query response result code */
217 enum {
218 	QUERY_RESULT_SUCCESS                    = 0x00,
219 	QUERY_RESULT_NOT_READABLE               = 0xF6,
220 	QUERY_RESULT_NOT_WRITEABLE              = 0xF7,
221 	QUERY_RESULT_ALREADY_WRITTEN            = 0xF8,
222 	QUERY_RESULT_INVALID_LENGTH             = 0xF9,
223 	QUERY_RESULT_INVALID_VALUE              = 0xFA,
224 	QUERY_RESULT_INVALID_SELECTOR           = 0xFB,
225 	QUERY_RESULT_INVALID_INDEX              = 0xFC,
226 	QUERY_RESULT_INVALID_IDN                = 0xFD,
227 	QUERY_RESULT_INVALID_OPCODE             = 0xFE,
228 	QUERY_RESULT_GENERAL_FAILURE            = 0xFF,
229 };
230 
231 enum {
232 	UPIU_COMMAND_SET_TYPE_SCSI	= 0x0,
233 	UPIU_COMMAND_SET_TYPE_UFS	= 0x1,
234 	UPIU_COMMAND_SET_TYPE_QUERY	= 0x2,
235 };
236 
237 /* Flag idn for Query Requests*/
238 enum flag_idn {
239 	QUERY_FLAG_IDN_FDEVICEINIT			= 0x01,
240 	QUERY_FLAG_IDN_PERMANENT_WPE			= 0x02,
241 	QUERY_FLAG_IDN_PWR_ON_WPE			= 0x03,
242 	QUERY_FLAG_IDN_BKOPS_EN				= 0x04,
243 	QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE		= 0x05,
244 	QUERY_FLAG_IDN_PURGE_ENABLE			= 0x06,
245 	QUERY_FLAG_IDN_RESERVED2			= 0x07,
246 	QUERY_FLAG_IDN_FPHYRESOURCEREMOVAL		= 0x08,
247 	QUERY_FLAG_IDN_BUSY_RTC				= 0x09,
248 	QUERY_FLAG_IDN_RESERVED3			= 0x0A,
249 	QUERY_FLAG_IDN_PERMANENTLY_DISABLE_FW_UPDATE	= 0x0B,
250 };
251 
252 /* Attribute idn for Query requests */
253 enum attr_idn {
254 	QUERY_ATTR_IDN_BOOT_LU_EN		= 0x00,
255 	QUERY_ATTR_IDN_RESERVED			= 0x01,
256 	QUERY_ATTR_IDN_POWER_MODE		= 0x02,
257 	QUERY_ATTR_IDN_ACTIVE_ICC_LVL		= 0x03,
258 	QUERY_ATTR_IDN_OOO_DATA_EN		= 0x04,
259 	QUERY_ATTR_IDN_BKOPS_STATUS		= 0x05,
260 	QUERY_ATTR_IDN_PURGE_STATUS		= 0x06,
261 	QUERY_ATTR_IDN_MAX_DATA_IN		= 0x07,
262 	QUERY_ATTR_IDN_MAX_DATA_OUT		= 0x08,
263 	QUERY_ATTR_IDN_DYN_CAP_NEEDED		= 0x09,
264 	QUERY_ATTR_IDN_REF_CLK_FREQ		= 0x0A,
265 	QUERY_ATTR_IDN_CONF_DESC_LOCK		= 0x0B,
266 	QUERY_ATTR_IDN_MAX_NUM_OF_RTT		= 0x0C,
267 	QUERY_ATTR_IDN_EE_CONTROL		= 0x0D,
268 	QUERY_ATTR_IDN_EE_STATUS		= 0x0E,
269 	QUERY_ATTR_IDN_SECONDS_PASSED		= 0x0F,
270 	QUERY_ATTR_IDN_CNTX_CONF		= 0x10,
271 	QUERY_ATTR_IDN_CORR_PRG_BLK_NUM		= 0x11,
272 	QUERY_ATTR_IDN_RESERVED2		= 0x12,
273 	QUERY_ATTR_IDN_RESERVED3		= 0x13,
274 	QUERY_ATTR_IDN_FFU_STATUS		= 0x14,
275 	QUERY_ATTR_IDN_PSA_STATE		= 0x15,
276 	QUERY_ATTR_IDN_PSA_DATA_SIZE		= 0x16,
277 };
278 
279 /* Descriptor idn for Query requests */
280 enum desc_idn {
281 	QUERY_DESC_IDN_DEVICE		= 0x0,
282 	QUERY_DESC_IDN_CONFIGURATION	= 0x1,
283 	QUERY_DESC_IDN_UNIT		= 0x2,
284 	QUERY_DESC_IDN_RFU_0		= 0x3,
285 	QUERY_DESC_IDN_INTERCONNECT	= 0x4,
286 	QUERY_DESC_IDN_STRING		= 0x5,
287 	QUERY_DESC_IDN_RFU_1		= 0x6,
288 	QUERY_DESC_IDN_GEOMETRY		= 0x7,
289 	QUERY_DESC_IDN_POWER		= 0x8,
290 	QUERY_DESC_IDN_HEALTH           = 0x9,
291 	QUERY_DESC_IDN_MAX,
292 };
293 
294 enum desc_header_offset {
295 	QUERY_DESC_LENGTH_OFFSET	= 0x00,
296 	QUERY_DESC_DESC_TYPE_OFFSET	= 0x01,
297 };
298 
299 struct ufshcd_sg_entry {
300 	__le32    base_addr;
301 	__le32    upper_addr;
302 	__le32    reserved;
303 	__le32    size;
304 };
305 
306 #define MAX_BUFF	128
307 /**
308  * struct utp_transfer_cmd_desc - UFS Command Descriptor structure
309  * @command_upiu: Command UPIU Frame address
310  * @response_upiu: Response UPIU Frame address
311  * @prd_table: Physical Region Descriptor
312  */
313 struct utp_transfer_cmd_desc {
314 	u8 command_upiu[ALIGNED_UPIU_SIZE];
315 	u8 response_upiu[ALIGNED_UPIU_SIZE];
316 	struct ufshcd_sg_entry    prd_table[MAX_BUFF];
317 };
318 
319 /**
320  * struct request_desc_header - Descriptor Header common to both UTRD and UTMRD
321  * @dword0: Descriptor Header DW0
322  * @dword1: Descriptor Header DW1
323  * @dword2: Descriptor Header DW2
324  * @dword3: Descriptor Header DW3
325  */
326 struct request_desc_header {
327 	__le32 dword_0;
328 	__le32 dword_1;
329 	__le32 dword_2;
330 	__le32 dword_3;
331 };
332 
333 /**
334  * struct utp_transfer_req_desc - UTRD structure
335  * @header: UTRD header DW-0 to DW-3
336  * @command_desc_base_addr_lo: UCD base address low DW-4
337  * @command_desc_base_addr_hi: UCD base address high DW-5
338  * @response_upiu_length: response UPIU length DW-6
339  * @response_upiu_offset: response UPIU offset DW-6
340  * @prd_table_length: Physical region descriptor length DW-7
341  * @prd_table_offset: Physical region descriptor offset DW-7
342  */
343 struct utp_transfer_req_desc {
344 	/* DW 0-3 */
345 	struct request_desc_header header;
346 
347 	/* DW 4-5*/
348 	__le32  command_desc_base_addr_lo;
349 	__le32  command_desc_base_addr_hi;
350 
351 	/* DW 6 */
352 	__le16  response_upiu_length;
353 	__le16  response_upiu_offset;
354 
355 	/* DW 7 */
356 	__le16  prd_table_length;
357 	__le16  prd_table_offset;
358 };
359 
360 /**
361  * struct utp_upiu_header - UPIU header structure
362  * @dword_0: UPIU header DW-0
363  * @dword_1: UPIU header DW-1
364  * @dword_2: UPIU header DW-2
365  */
366 struct utp_upiu_header {
367 	__be32 dword_0;
368 	__be32 dword_1;
369 	__be32 dword_2;
370 };
371 
372 /**
373  * struct utp_upiu_query - upiu request buffer structure for
374  * query request.
375  * @opcode: command to perform B-0
376  * @idn: a value that indicates the particular type of data B-1
377  * @index: Index to further identify data B-2
378  * @selector: Index to further identify data B-3
379  * @reserved_osf: spec reserved field B-4,5
380  * @length: number of descriptor bytes to read/write B-6,7
381  * @value: Attribute value to be written DW-5
382  * @reserved: spec reserved DW-6,7
383  */
384 struct utp_upiu_query {
385 	__u8 opcode;
386 	__u8 idn;
387 	__u8 index;
388 	__u8 selector;
389 	__be16 reserved_osf;
390 	__be16 length;
391 	__be32 value;
392 	__be32 reserved[2];
393 };
394 
395 /**
396  * struct utp_upiu_cmd - Command UPIU structure
397  * @data_transfer_len: Data Transfer Length DW-3
398  * @cdb: Command Descriptor Block CDB DW-4 to DW-7
399  */
400 struct utp_upiu_cmd {
401 	__be32 exp_data_transfer_len;
402 	u8 cdb[UFS_CDB_SIZE];
403 };
404 
405 /*
406  * UTMRD structure.
407  */
408 struct utp_task_req_desc {
409 	/* DW 0-3 */
410 	struct request_desc_header header;
411 
412 	/* DW 4-11 - Task request UPIU structure */
413 	struct utp_upiu_header	req_header;
414 	__be32			input_param1;
415 	__be32			input_param2;
416 	__be32			input_param3;
417 	__be32			__reserved1[2];
418 
419 	/* DW 12-19 - Task Management Response UPIU structure */
420 	struct utp_upiu_header	rsp_header;
421 	__be32			output_param1;
422 	__be32			output_param2;
423 	__be32			__reserved2[3];
424 };
425 
426 /**
427  * struct utp_upiu_req - general upiu request structure
428  * @header:UPIU header structure DW-0 to DW-2
429  * @sc: fields structure for scsi command DW-3 to DW-7
430  * @qr: fields structure for query request DW-3 to DW-7
431  */
432 struct utp_upiu_req {
433 	struct utp_upiu_header header;
434 	union {
435 		struct utp_upiu_cmd		sc;
436 		struct utp_upiu_query		qr;
437 		struct utp_upiu_query		tr;
438 		/* use utp_upiu_query to host the 4 dwords of uic command */
439 		struct utp_upiu_query		uc;
440 	};
441 };
442 
443 /**
444  * struct utp_cmd_rsp - Response UPIU structure
445  * @residual_transfer_count: Residual transfer count DW-3
446  * @reserved: Reserved double words DW-4 to DW-7
447  * @sense_data_len: Sense data length DW-8 U16
448  * @sense_data: Sense data field DW-8 to DW-12
449  */
450 struct utp_cmd_rsp {
451 	__be32 residual_transfer_count;
452 	__be32 reserved[4];
453 	__be16 sense_data_len;
454 	u8 sense_data[RESPONSE_UPIU_SENSE_DATA_LENGTH];
455 };
456 
457 /**
458  * struct utp_upiu_rsp - general upiu response structure
459  * @header: UPIU header structure DW-0 to DW-2
460  * @sr: fields structure for scsi command DW-3 to DW-12
461  * @qr: fields structure for query request DW-3 to DW-7
462  */
463 struct utp_upiu_rsp {
464 	struct utp_upiu_header header;
465 	union {
466 		struct utp_cmd_rsp sr;
467 		struct utp_upiu_query qr;
468 	};
469 };
470 
471 #define MAX_MODEL_LEN 16
472 /**
473  * ufs_dev_desc - ufs device details from the device descriptor
474  *
475  * @wmanufacturerid: card details
476  * @model: card model
477  */
478 struct ufs_dev_desc {
479 	u16 wmanufacturerid;
480 	char model[MAX_MODEL_LEN + 1];
481 };
482 
483 /* Device descriptor parameters offsets in bytes*/
484 enum device_desc_param {
485 	DEVICE_DESC_PARAM_LEN			= 0x0,
486 	DEVICE_DESC_PARAM_TYPE			= 0x1,
487 	DEVICE_DESC_PARAM_DEVICE_TYPE		= 0x2,
488 	DEVICE_DESC_PARAM_DEVICE_CLASS		= 0x3,
489 	DEVICE_DESC_PARAM_DEVICE_SUB_CLASS	= 0x4,
490 	DEVICE_DESC_PARAM_PRTCL			= 0x5,
491 	DEVICE_DESC_PARAM_NUM_LU		= 0x6,
492 	DEVICE_DESC_PARAM_NUM_WLU		= 0x7,
493 	DEVICE_DESC_PARAM_BOOT_ENBL		= 0x8,
494 	DEVICE_DESC_PARAM_DESC_ACCSS_ENBL	= 0x9,
495 	DEVICE_DESC_PARAM_INIT_PWR_MODE		= 0xA,
496 	DEVICE_DESC_PARAM_HIGH_PR_LUN		= 0xB,
497 	DEVICE_DESC_PARAM_SEC_RMV_TYPE		= 0xC,
498 	DEVICE_DESC_PARAM_SEC_LU		= 0xD,
499 	DEVICE_DESC_PARAM_BKOP_TERM_LT		= 0xE,
500 	DEVICE_DESC_PARAM_ACTVE_ICC_LVL		= 0xF,
501 	DEVICE_DESC_PARAM_SPEC_VER		= 0x10,
502 	DEVICE_DESC_PARAM_MANF_DATE		= 0x12,
503 	DEVICE_DESC_PARAM_MANF_NAME		= 0x14,
504 	DEVICE_DESC_PARAM_PRDCT_NAME		= 0x15,
505 	DEVICE_DESC_PARAM_SN			= 0x16,
506 	DEVICE_DESC_PARAM_OEM_ID		= 0x17,
507 	DEVICE_DESC_PARAM_MANF_ID		= 0x18,
508 	DEVICE_DESC_PARAM_UD_OFFSET		= 0x1A,
509 	DEVICE_DESC_PARAM_UD_LEN		= 0x1B,
510 	DEVICE_DESC_PARAM_RTT_CAP		= 0x1C,
511 	DEVICE_DESC_PARAM_FRQ_RTC		= 0x1D,
512 	DEVICE_DESC_PARAM_UFS_FEAT		= 0x1F,
513 	DEVICE_DESC_PARAM_FFU_TMT		= 0x20,
514 	DEVICE_DESC_PARAM_Q_DPTH		= 0x21,
515 	DEVICE_DESC_PARAM_DEV_VER		= 0x22,
516 	DEVICE_DESC_PARAM_NUM_SEC_WPA		= 0x24,
517 	DEVICE_DESC_PARAM_PSA_MAX_DATA		= 0x25,
518 	DEVICE_DESC_PARAM_PSA_TMT		= 0x29,
519 	DEVICE_DESC_PARAM_PRDCT_REV		= 0x2A,
520 };
521 
522 struct ufs_hba;
523 
524 enum {
525 	UFSHCD_MAX_CHANNEL	= 0,
526 	UFSHCD_MAX_ID		= 1,
527 };
528 
529 enum dev_cmd_type {
530 	DEV_CMD_TYPE_NOP		= 0x0,
531 	DEV_CMD_TYPE_QUERY		= 0x1,
532 };
533 
534 /**
535  * struct uic_command - UIC command structure
536  * @command: UIC command
537  * @argument1: UIC command argument 1
538  * @argument2: UIC command argument 2
539  * @argument3: UIC command argument 3
540  * @cmd_active: Indicate if UIC command is outstanding
541  * @result: UIC command result
542  * @done: UIC command completion
543  */
544 struct uic_command {
545 	u32 command;
546 	u32 argument1;
547 	u32 argument2;
548 	u32 argument3;
549 	int cmd_active;
550 	int result;
551 };
552 
553 /* GenSelectorIndex calculation macros for M-PHY attributes */
554 #define UIC_ARG_MPHY_TX_GEN_SEL_INDEX(lane) (lane)
555 #define UIC_ARG_MPHY_RX_GEN_SEL_INDEX(lane) (PA_MAXDATALANES + (lane))
556 
557 #define UIC_ARG_MIB_SEL(attr, sel)	((((attr) & 0xFFFF) << 16) |\
558 					 ((sel) & 0xFFFF))
559 #define UIC_ARG_MIB(attr)		UIC_ARG_MIB_SEL(attr, 0)
560 #define UIC_ARG_ATTR_TYPE(t)		(((t) & 0xFF) << 16)
561 #define UIC_GET_ATTR_ID(v)		(((v) >> 16) & 0xFFFF)
562 
563 /* Link Status*/
564 enum link_status {
565 	UFSHCD_LINK_IS_DOWN	= 1,
566 	UFSHCD_LINK_IS_UP	= 2,
567 };
568 
569 #define UIC_ARG_MIB_SEL(attr, sel)	((((attr) & 0xFFFF) << 16) |\
570 					 ((sel) & 0xFFFF))
571 #define UIC_ARG_MIB(attr)		UIC_ARG_MIB_SEL(attr, 0)
572 #define UIC_ARG_ATTR_TYPE(t)		(((t) & 0xFF) << 16)
573 #define UIC_GET_ATTR_ID(v)		(((v) >> 16) & 0xFFFF)
574 
575 /* UIC Commands */
576 enum uic_cmd_dme {
577 	UIC_CMD_DME_GET			= 0x01,
578 	UIC_CMD_DME_SET			= 0x02,
579 	UIC_CMD_DME_PEER_GET		= 0x03,
580 	UIC_CMD_DME_PEER_SET		= 0x04,
581 	UIC_CMD_DME_POWERON		= 0x10,
582 	UIC_CMD_DME_POWEROFF		= 0x11,
583 	UIC_CMD_DME_ENABLE		= 0x12,
584 	UIC_CMD_DME_RESET		= 0x14,
585 	UIC_CMD_DME_END_PT_RST		= 0x15,
586 	UIC_CMD_DME_LINK_STARTUP	= 0x16,
587 	UIC_CMD_DME_HIBER_ENTER		= 0x17,
588 	UIC_CMD_DME_HIBER_EXIT		= 0x18,
589 	UIC_CMD_DME_TEST_MODE		= 0x1A,
590 };
591 
592 /* UIC Config result code / Generic error code */
593 enum {
594 	UIC_CMD_RESULT_SUCCESS			= 0x00,
595 	UIC_CMD_RESULT_INVALID_ATTR		= 0x01,
596 	UIC_CMD_RESULT_FAILURE			= 0x01,
597 	UIC_CMD_RESULT_INVALID_ATTR_VALUE	= 0x02,
598 	UIC_CMD_RESULT_READ_ONLY_ATTR		= 0x03,
599 	UIC_CMD_RESULT_WRITE_ONLY_ATTR		= 0x04,
600 	UIC_CMD_RESULT_BAD_INDEX		= 0x05,
601 	UIC_CMD_RESULT_LOCKED_ATTR		= 0x06,
602 	UIC_CMD_RESULT_BAD_TEST_FEATURE_INDEX	= 0x07,
603 	UIC_CMD_RESULT_PEER_COMM_FAILURE	= 0x08,
604 	UIC_CMD_RESULT_BUSY			= 0x09,
605 	UIC_CMD_RESULT_DME_FAILURE		= 0x0A,
606 };
607 
608 #define MASK_UIC_COMMAND_RESULT			0xFF
609 
610 /* Host <-> Device UniPro Link state */
611 enum uic_link_state {
612 	UIC_LINK_OFF_STATE	= 0, /* Link powered down or disabled */
613 	UIC_LINK_ACTIVE_STATE	= 1, /* Link is in Fast/Slow/Sleep state */
614 	UIC_LINK_HIBERN8_STATE	= 2, /* Link is in Hibernate state */
615 };
616 
617 /* UIC command interfaces for DME primitives */
618 #define DME_LOCAL	0
619 #define DME_PEER	1
620 #define ATTR_SET_NOR	0	/* NORMAL */
621 #define ATTR_SET_ST	1	/* STATIC */
622 
623 int ufshcd_dme_set_attr(struct ufs_hba *hba, u32 attr_sel,
624 			u8 attr_set, u32 mib_val, u8 peer);
625 int ufshcd_dme_get_attr(struct ufs_hba *hba, u32 attr_sel,
626 			u32 *mib_val, u8 peer);
627 
ufshcd_dme_set(struct ufs_hba * hba,u32 attr_sel,u32 mib_val)628 static inline int ufshcd_dme_set(struct ufs_hba *hba, u32 attr_sel,
629 				 u32 mib_val)
630 {
631 	return ufshcd_dme_set_attr(hba, attr_sel, ATTR_SET_NOR,
632 				   mib_val, DME_LOCAL);
633 }
634 
ufshcd_dme_get(struct ufs_hba * hba,u32 attr_sel,u32 * mib_val)635 static inline int ufshcd_dme_get(struct ufs_hba *hba,
636 				 u32 attr_sel, u32 *mib_val)
637 {
638 	return ufshcd_dme_get_attr(hba, attr_sel, mib_val, DME_LOCAL);
639 }
640 
ufshcd_dme_peer_get(struct ufs_hba * hba,u32 attr_sel,u32 * mib_val)641 static inline int ufshcd_dme_peer_get(struct ufs_hba *hba,
642 				      u32 attr_sel, u32 *mib_val)
643 {
644 	return ufshcd_dme_get_attr(hba, attr_sel, mib_val, DME_PEER);
645 }
646 
ufshcd_dme_peer_set(struct ufs_hba * hba,u32 attr_sel,u32 mib_val)647 static inline int ufshcd_dme_peer_set(struct ufs_hba *hba, u32 attr_sel,
648 				      u32 mib_val)
649 {
650 	return ufshcd_dme_set_attr(hba, attr_sel, ATTR_SET_NOR,
651 				   mib_val, DME_PEER);
652 }
653 
654 /**
655  * struct ufs_query_req - parameters for building a query request
656  * @query_func: UPIU header query function
657  * @upiu_req: the query request data
658  */
659 struct ufs_query_req {
660 	u8 query_func;
661 	struct utp_upiu_query upiu_req;
662 };
663 
664 /**
665  * struct ufs_query_resp - UPIU QUERY
666  * @response: device response code
667  * @upiu_res: query response data
668  */
669 struct ufs_query_res {
670 	u8 response;
671 	struct utp_upiu_query upiu_res;
672 };
673 
674 /**
675  * struct ufs_query - holds relevant data structures for query request
676  * @request: request upiu and function
677  * @descriptor: buffer for sending/receiving descriptor
678  * @response: response upiu and response
679  */
680 struct ufs_query {
681 	struct ufs_query_req request;
682 	u8 *descriptor;
683 	struct ufs_query_res response;
684 };
685 
686 /**
687  * struct ufs_dev_cmd - all assosiated fields with device management commands
688  * @type: device management command type - Query, NOP OUT
689  * @tag_wq: wait queue until free command slot is available
690  */
691 struct ufs_dev_cmd {
692 	enum dev_cmd_type type;
693 	struct ufs_query query;
694 };
695 
696 struct ufs_hba_ops {
697 	int (*init)(struct ufs_hba *hba);
698 	int (*hce_enable_notify)(struct ufs_hba *hba,
699 				 enum ufs_notify_change_status);
700 	int (*link_startup_notify)(struct ufs_hba *hba,
701 				   enum ufs_notify_change_status);
702 	int (*phy_initialization)(struct ufs_hba *hba);
703 };
704 
705 struct ufs_hba {
706 	struct			udevice *dev;
707 	void __iomem		*mmio_base;
708 	struct ufs_hba_ops	*ops;
709 	struct ufs_desc_size	desc_size;
710 	u32			capabilities;
711 	u32			version;
712 	u32			intr_mask;
713 	u32			quirks;
714 /*
715  * If UFS host controller is having issue in processing LCC (Line
716  * Control Command) coming from device then enable this quirk.
717  * When this quirk is enabled, host controller driver should disable
718  * the LCC transmission on UFS device (by clearing TX_LCC_ENABLE
719  * attribute of device to 0).
720  */
721 #define UFSHCD_QUIRK_BROKEN_LCC				0x1
722 
723 	/* Virtual memory reference */
724 	struct utp_transfer_cmd_desc *ucdl;
725 	struct utp_transfer_req_desc *utrdl;
726 	/* TODO: Add Task Manegement Support */
727 	struct utp_task_req_desc *utmrdl;
728 
729 	struct utp_upiu_req *ucd_req_ptr;
730 	struct utp_upiu_rsp *ucd_rsp_ptr;
731 	struct ufshcd_sg_entry *ucd_prdt_ptr;
732 
733 	/* Power Mode information */
734 	enum ufs_dev_pwr_mode curr_dev_pwr_mode;
735 	struct ufs_pa_layer_attr pwr_info;
736 	struct ufs_pwr_mode_info max_pwr_info;
737 
738 	struct ufs_dev_cmd dev_cmd;
739 };
740 
ufshcd_ops_init(struct ufs_hba * hba)741 static inline int ufshcd_ops_init(struct ufs_hba *hba)
742 {
743 	if (hba->ops && hba->ops->init)
744 		return hba->ops->init(hba);
745 
746 	return 0;
747 }
748 
ufshcd_ops_hce_enable_notify(struct ufs_hba * hba,bool status)749 static inline int ufshcd_ops_hce_enable_notify(struct ufs_hba *hba,
750 						bool status)
751 {
752 	if (hba->ops && hba->ops->hce_enable_notify)
753 		return hba->ops->hce_enable_notify(hba, status);
754 
755 	return 0;
756 }
757 
ufshcd_ops_link_startup_notify(struct ufs_hba * hba,bool status)758 static inline int ufshcd_ops_link_startup_notify(struct ufs_hba *hba,
759 						 bool status)
760 {
761 	if (hba->ops && hba->ops->link_startup_notify)
762 		return hba->ops->link_startup_notify(hba, status);
763 
764 	return 0;
765 }
766 
767 /* Controller UFSHCI version */
768 enum {
769 	UFSHCI_VERSION_10 = 0x00010000, /* 1.0 */
770 	UFSHCI_VERSION_11 = 0x00010100, /* 1.1 */
771 	UFSHCI_VERSION_20 = 0x00000200, /* 2.0 */
772 	UFSHCI_VERSION_21 = 0x00000210, /* 2.1 */
773 };
774 
775 /* Interrupt disable masks */
776 enum {
777 	/* Interrupt disable mask for UFSHCI v1.0 */
778 	INTERRUPT_MASK_ALL_VER_10	= 0x30FFF,
779 	INTERRUPT_MASK_RW_VER_10	= 0x30000,
780 
781 	/* Interrupt disable mask for UFSHCI v1.1 */
782 	INTERRUPT_MASK_ALL_VER_11	= 0x31FFF,
783 
784 	/* Interrupt disable mask for UFSHCI v2.1 */
785 	INTERRUPT_MASK_ALL_VER_21	= 0x71FFF,
786 };
787 
788 /* UFSHCI Registers */
789 enum {
790 	REG_CONTROLLER_CAPABILITIES		= 0x00,
791 	REG_UFS_VERSION				= 0x08,
792 	REG_CONTROLLER_DEV_ID			= 0x10,
793 	REG_CONTROLLER_PROD_ID			= 0x14,
794 	REG_AUTO_HIBERNATE_IDLE_TIMER		= 0x18,
795 	REG_INTERRUPT_STATUS			= 0x20,
796 	REG_INTERRUPT_ENABLE			= 0x24,
797 	REG_CONTROLLER_STATUS			= 0x30,
798 	REG_CONTROLLER_ENABLE			= 0x34,
799 	REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER	= 0x38,
800 	REG_UIC_ERROR_CODE_DATA_LINK_LAYER	= 0x3C,
801 	REG_UIC_ERROR_CODE_NETWORK_LAYER	= 0x40,
802 	REG_UIC_ERROR_CODE_TRANSPORT_LAYER	= 0x44,
803 	REG_UIC_ERROR_CODE_DME			= 0x48,
804 	REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL	= 0x4C,
805 	REG_UTP_TRANSFER_REQ_LIST_BASE_L	= 0x50,
806 	REG_UTP_TRANSFER_REQ_LIST_BASE_H	= 0x54,
807 	REG_UTP_TRANSFER_REQ_DOOR_BELL		= 0x58,
808 	REG_UTP_TRANSFER_REQ_LIST_CLEAR		= 0x5C,
809 	REG_UTP_TRANSFER_REQ_LIST_RUN_STOP	= 0x60,
810 	REG_UTP_TASK_REQ_LIST_BASE_L		= 0x70,
811 	REG_UTP_TASK_REQ_LIST_BASE_H		= 0x74,
812 	REG_UTP_TASK_REQ_DOOR_BELL		= 0x78,
813 	REG_UTP_TASK_REQ_LIST_CLEAR		= 0x7C,
814 	REG_UTP_TASK_REQ_LIST_RUN_STOP		= 0x80,
815 	REG_UIC_COMMAND				= 0x90,
816 	REG_UIC_COMMAND_ARG_1			= 0x94,
817 	REG_UIC_COMMAND_ARG_2			= 0x98,
818 	REG_UIC_COMMAND_ARG_3			= 0x9C,
819 
820 	UFSHCI_REG_SPACE_SIZE			= 0xA0,
821 
822 	REG_UFS_CCAP				= 0x100,
823 	REG_UFS_CRYPTOCAP			= 0x104,
824 
825 	UFSHCI_CRYPTO_REG_SPACE_SIZE		= 0x400,
826 };
827 
828 /* Controller capability masks */
829 enum {
830 	MASK_TRANSFER_REQUESTS_SLOTS		= 0x0000001F,
831 	MASK_TASK_MANAGEMENT_REQUEST_SLOTS	= 0x00070000,
832 	MASK_AUTO_HIBERN8_SUPPORT		= 0x00800000,
833 	MASK_64_ADDRESSING_SUPPORT		= 0x01000000,
834 	MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT	= 0x02000000,
835 	MASK_UIC_DME_TEST_MODE_SUPPORT		= 0x04000000,
836 };
837 
838 /* Interrupt Status 20h */
839 #define UTP_TRANSFER_REQ_COMPL			0x1
840 #define UIC_DME_END_PT_RESET			0x2
841 #define UIC_ERROR				0x4
842 #define UIC_TEST_MODE				0x8
843 #define UIC_POWER_MODE				0x10
844 #define UIC_HIBERNATE_EXIT			0x20
845 #define UIC_HIBERNATE_ENTER			0x40
846 #define UIC_LINK_LOST				0x80
847 #define UIC_LINK_STARTUP			0x100
848 #define UTP_TASK_REQ_COMPL			0x200
849 #define UIC_COMMAND_COMPL			0x400
850 #define DEVICE_FATAL_ERROR			0x800
851 #define CONTROLLER_FATAL_ERROR			0x10000
852 #define SYSTEM_BUS_FATAL_ERROR			0x20000
853 
854 #define UFSHCD_UIC_PWR_MASK	(UIC_HIBERNATE_ENTER |\
855 				UIC_HIBERNATE_EXIT |\
856 				UIC_POWER_MODE)
857 
858 #define UFSHCD_UIC_MASK		(UIC_COMMAND_COMPL | UIC_POWER_MODE)
859 
860 #define UFSHCD_ERROR_MASK	(UIC_ERROR |\
861 				DEVICE_FATAL_ERROR |\
862 				CONTROLLER_FATAL_ERROR |\
863 				SYSTEM_BUS_FATAL_ERROR)
864 
865 #define INT_FATAL_ERRORS	(DEVICE_FATAL_ERROR |\
866 				CONTROLLER_FATAL_ERROR |\
867 				SYSTEM_BUS_FATAL_ERROR)
868 
869 /* Host Controller Enable 0x34h */
870 #define CONTROLLER_ENABLE	0x1
871 #define CONTROLLER_DISABLE	0x0
872 /* HCS - Host Controller Status 30h */
873 #define DEVICE_PRESENT				0x1
874 #define UTP_TRANSFER_REQ_LIST_READY		0x2
875 #define UTP_TASK_REQ_LIST_READY			0x4
876 #define UIC_COMMAND_READY			0x8
877 #define HOST_ERROR_INDICATOR			0x10
878 #define DEVICE_ERROR_INDICATOR			0x20
879 #define UIC_POWER_MODE_CHANGE_REQ_STATUS_MASK	UFS_MASK(0x7, 8)
880 
881 #define UFSHCD_STATUS_READY	(UTP_TRANSFER_REQ_LIST_READY |\
882 				UTP_TASK_REQ_LIST_READY |\
883 				UIC_COMMAND_READY)
884 
885 enum {
886 	PWR_OK		= 0x0,
887 	PWR_LOCAL	= 0x01,
888 	PWR_REMOTE	= 0x02,
889 	PWR_BUSY	= 0x03,
890 	PWR_ERROR_CAP	= 0x04,
891 	PWR_FATAL_ERROR	= 0x05,
892 };
893 
894 /* UICCMD - UIC Command */
895 #define COMMAND_OPCODE_MASK		0xFF
896 #define GEN_SELECTOR_INDEX_MASK		0xFFFF
897 
898 #define MIB_ATTRIBUTE_MASK		UFS_MASK(0xFFFF, 16)
899 #define RESET_LEVEL			0xFF
900 
901 #define ATTR_SET_TYPE_MASK		UFS_MASK(0xFF, 16)
902 #define CONFIG_RESULT_CODE_MASK		0xFF
903 #define GENERIC_ERROR_CODE_MASK		0xFF
904 
905 #define ufshcd_writel(hba, val, reg)   \
906 	writel((val), (hba)->mmio_base + (reg))
907 #define ufshcd_readl(hba, reg) \
908 	readl((hba)->mmio_base + (reg))
909 
910 /* UTRLRSR - UTP Transfer Request Run-Stop Register 60h */
911 #define UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT	0x1
912 
913 /* UTMRLRSR - UTP Task Management Request Run-Stop Register 80h */
914 #define UTP_TASK_REQ_LIST_RUN_STOP_BIT		0x1
915 
916 int ufshcd_probe(struct udevice *dev, struct ufs_hba_ops *hba_ops);
917 
918 #endif
919