xref: /rk3399_rockchip-uboot/drivers/nvme/nvme.h (revision 51341de713beb7205186c7e12b9cf7c38b5faf8a)
1982388eaSZhikang Zhang /*
2982388eaSZhikang Zhang  * Copyright (C) 2017 NXP Semiconductors
3982388eaSZhikang Zhang  * Copyright (C) 2017 Bin Meng <bmeng.cn@gmail.com>
4982388eaSZhikang Zhang  *
5982388eaSZhikang Zhang  * SPDX-License-Identifier:	GPL-2.0+
6982388eaSZhikang Zhang  */
7982388eaSZhikang Zhang 
8982388eaSZhikang Zhang #ifndef __DRIVER_NVME_H__
9982388eaSZhikang Zhang #define __DRIVER_NVME_H__
10982388eaSZhikang Zhang 
11982388eaSZhikang Zhang #include <asm/io.h>
12982388eaSZhikang Zhang 
13982388eaSZhikang Zhang struct nvme_id_power_state {
14982388eaSZhikang Zhang 	__le16			max_power;	/* centiwatts */
15982388eaSZhikang Zhang 	__u8			rsvd2;
16982388eaSZhikang Zhang 	__u8			flags;
17982388eaSZhikang Zhang 	__le32			entry_lat;	/* microseconds */
18982388eaSZhikang Zhang 	__le32			exit_lat;	/* microseconds */
19982388eaSZhikang Zhang 	__u8			read_tput;
20982388eaSZhikang Zhang 	__u8			read_lat;
21982388eaSZhikang Zhang 	__u8			write_tput;
22982388eaSZhikang Zhang 	__u8			write_lat;
23982388eaSZhikang Zhang 	__le16			idle_power;
24982388eaSZhikang Zhang 	__u8			idle_scale;
25982388eaSZhikang Zhang 	__u8			rsvd19;
26982388eaSZhikang Zhang 	__le16			active_power;
27982388eaSZhikang Zhang 	__u8			active_work_scale;
28982388eaSZhikang Zhang 	__u8			rsvd23[9];
29982388eaSZhikang Zhang };
30982388eaSZhikang Zhang 
31982388eaSZhikang Zhang enum {
32982388eaSZhikang Zhang 	NVME_PS_FLAGS_MAX_POWER_SCALE	= 1 << 0,
33982388eaSZhikang Zhang 	NVME_PS_FLAGS_NON_OP_STATE	= 1 << 1,
34982388eaSZhikang Zhang };
35982388eaSZhikang Zhang 
36982388eaSZhikang Zhang struct nvme_id_ctrl {
37982388eaSZhikang Zhang 	__le16			vid;
38982388eaSZhikang Zhang 	__le16			ssvid;
39982388eaSZhikang Zhang 	char			sn[20];
40982388eaSZhikang Zhang 	char			mn[40];
41982388eaSZhikang Zhang 	char			fr[8];
42982388eaSZhikang Zhang 	__u8			rab;
43982388eaSZhikang Zhang 	__u8			ieee[3];
44982388eaSZhikang Zhang 	__u8			mic;
45982388eaSZhikang Zhang 	__u8			mdts;
46982388eaSZhikang Zhang 	__u16			cntlid;
47982388eaSZhikang Zhang 	__u32			ver;
48982388eaSZhikang Zhang 	__u8			rsvd84[172];
49982388eaSZhikang Zhang 	__le16			oacs;
50982388eaSZhikang Zhang 	__u8			acl;
51982388eaSZhikang Zhang 	__u8			aerl;
52982388eaSZhikang Zhang 	__u8			frmw;
53982388eaSZhikang Zhang 	__u8			lpa;
54982388eaSZhikang Zhang 	__u8			elpe;
55982388eaSZhikang Zhang 	__u8			npss;
56982388eaSZhikang Zhang 	__u8			avscc;
57982388eaSZhikang Zhang 	__u8			apsta;
58982388eaSZhikang Zhang 	__le16			wctemp;
59982388eaSZhikang Zhang 	__le16			cctemp;
60982388eaSZhikang Zhang 	__u8			rsvd270[242];
61982388eaSZhikang Zhang 	__u8			sqes;
62982388eaSZhikang Zhang 	__u8			cqes;
63982388eaSZhikang Zhang 	__u8			rsvd514[2];
64982388eaSZhikang Zhang 	__le32			nn;
65982388eaSZhikang Zhang 	__le16			oncs;
66982388eaSZhikang Zhang 	__le16			fuses;
67982388eaSZhikang Zhang 	__u8			fna;
68982388eaSZhikang Zhang 	__u8			vwc;
69982388eaSZhikang Zhang 	__le16			awun;
70982388eaSZhikang Zhang 	__le16			awupf;
71982388eaSZhikang Zhang 	__u8			nvscc;
72982388eaSZhikang Zhang 	__u8			rsvd531;
73982388eaSZhikang Zhang 	__le16			acwu;
74982388eaSZhikang Zhang 	__u8			rsvd534[2];
75982388eaSZhikang Zhang 	__le32			sgls;
76982388eaSZhikang Zhang 	__u8			rsvd540[1508];
77982388eaSZhikang Zhang 	struct nvme_id_power_state	psd[32];
78982388eaSZhikang Zhang 	__u8			vs[1024];
79982388eaSZhikang Zhang };
80982388eaSZhikang Zhang 
81982388eaSZhikang Zhang enum {
82982388eaSZhikang Zhang 	NVME_CTRL_ONCS_COMPARE			= 1 << 0,
83982388eaSZhikang Zhang 	NVME_CTRL_ONCS_WRITE_UNCORRECTABLE	= 1 << 1,
84982388eaSZhikang Zhang 	NVME_CTRL_ONCS_DSM			= 1 << 2,
85982388eaSZhikang Zhang 	NVME_CTRL_VWC_PRESENT			= 1 << 0,
86982388eaSZhikang Zhang };
87982388eaSZhikang Zhang 
88982388eaSZhikang Zhang struct nvme_lbaf {
89982388eaSZhikang Zhang 	__le16			ms;
90982388eaSZhikang Zhang 	__u8			ds;
91982388eaSZhikang Zhang 	__u8			rp;
92982388eaSZhikang Zhang };
93982388eaSZhikang Zhang 
94982388eaSZhikang Zhang struct nvme_id_ns {
95982388eaSZhikang Zhang 	__le64			nsze;
96982388eaSZhikang Zhang 	__le64			ncap;
97982388eaSZhikang Zhang 	__le64			nuse;
98982388eaSZhikang Zhang 	__u8			nsfeat;
99982388eaSZhikang Zhang 	__u8			nlbaf;
100982388eaSZhikang Zhang 	__u8			flbas;
101982388eaSZhikang Zhang 	__u8			mc;
102982388eaSZhikang Zhang 	__u8			dpc;
103982388eaSZhikang Zhang 	__u8			dps;
104982388eaSZhikang Zhang 	__u8			nmic;
105982388eaSZhikang Zhang 	__u8			rescap;
106982388eaSZhikang Zhang 	__u8			fpi;
107982388eaSZhikang Zhang 	__u8			rsvd33;
108982388eaSZhikang Zhang 	__le16			nawun;
109982388eaSZhikang Zhang 	__le16			nawupf;
110982388eaSZhikang Zhang 	__le16			nacwu;
111982388eaSZhikang Zhang 	__le16			nabsn;
112982388eaSZhikang Zhang 	__le16			nabo;
113982388eaSZhikang Zhang 	__le16			nabspf;
114982388eaSZhikang Zhang 	__u16			rsvd46;
115982388eaSZhikang Zhang 	__le64			nvmcap[2];
116982388eaSZhikang Zhang 	__u8			rsvd64[40];
117982388eaSZhikang Zhang 	__u8			nguid[16];
118982388eaSZhikang Zhang 	__u8			eui64[8];
119982388eaSZhikang Zhang 	struct nvme_lbaf	lbaf[16];
120982388eaSZhikang Zhang 	__u8			rsvd192[192];
121982388eaSZhikang Zhang 	__u8			vs[3712];
122982388eaSZhikang Zhang };
123982388eaSZhikang Zhang 
124982388eaSZhikang Zhang enum {
125982388eaSZhikang Zhang 	NVME_NS_FEAT_THIN	= 1 << 0,
126982388eaSZhikang Zhang 	NVME_NS_FLBAS_LBA_MASK	= 0xf,
127982388eaSZhikang Zhang 	NVME_NS_FLBAS_META_EXT	= 0x10,
128982388eaSZhikang Zhang 	NVME_LBAF_RP_BEST	= 0,
129982388eaSZhikang Zhang 	NVME_LBAF_RP_BETTER	= 1,
130982388eaSZhikang Zhang 	NVME_LBAF_RP_GOOD	= 2,
131982388eaSZhikang Zhang 	NVME_LBAF_RP_DEGRADED	= 3,
132982388eaSZhikang Zhang 	NVME_NS_DPC_PI_LAST	= 1 << 4,
133982388eaSZhikang Zhang 	NVME_NS_DPC_PI_FIRST	= 1 << 3,
134982388eaSZhikang Zhang 	NVME_NS_DPC_PI_TYPE3	= 1 << 2,
135982388eaSZhikang Zhang 	NVME_NS_DPC_PI_TYPE2	= 1 << 1,
136982388eaSZhikang Zhang 	NVME_NS_DPC_PI_TYPE1	= 1 << 0,
137982388eaSZhikang Zhang 	NVME_NS_DPS_PI_FIRST	= 1 << 3,
138982388eaSZhikang Zhang 	NVME_NS_DPS_PI_MASK	= 0x7,
139982388eaSZhikang Zhang 	NVME_NS_DPS_PI_TYPE1	= 1,
140982388eaSZhikang Zhang 	NVME_NS_DPS_PI_TYPE2	= 2,
141982388eaSZhikang Zhang 	NVME_NS_DPS_PI_TYPE3	= 3,
142982388eaSZhikang Zhang };
143982388eaSZhikang Zhang 
144982388eaSZhikang Zhang struct nvme_smart_log {
145982388eaSZhikang Zhang 	__u8			critical_warning;
146982388eaSZhikang Zhang 	__u8			temperature[2];
147982388eaSZhikang Zhang 	__u8			avail_spare;
148982388eaSZhikang Zhang 	__u8			spare_thresh;
149982388eaSZhikang Zhang 	__u8			percent_used;
150982388eaSZhikang Zhang 	__u8			rsvd6[26];
151982388eaSZhikang Zhang 	__u8			data_units_read[16];
152982388eaSZhikang Zhang 	__u8			data_units_written[16];
153982388eaSZhikang Zhang 	__u8			host_reads[16];
154982388eaSZhikang Zhang 	__u8			host_writes[16];
155982388eaSZhikang Zhang 	__u8			ctrl_busy_time[16];
156982388eaSZhikang Zhang 	__u8			power_cycles[16];
157982388eaSZhikang Zhang 	__u8			power_on_hours[16];
158982388eaSZhikang Zhang 	__u8			unsafe_shutdowns[16];
159982388eaSZhikang Zhang 	__u8			media_errors[16];
160982388eaSZhikang Zhang 	__u8			num_err_log_entries[16];
161982388eaSZhikang Zhang 	__le32			warning_temp_time;
162982388eaSZhikang Zhang 	__le32			critical_comp_time;
163982388eaSZhikang Zhang 	__le16			temp_sensor[8];
164982388eaSZhikang Zhang 	__u8			rsvd216[296];
165982388eaSZhikang Zhang };
166982388eaSZhikang Zhang 
167982388eaSZhikang Zhang enum {
168982388eaSZhikang Zhang 	NVME_SMART_CRIT_SPARE		= 1 << 0,
169982388eaSZhikang Zhang 	NVME_SMART_CRIT_TEMPERATURE	= 1 << 1,
170982388eaSZhikang Zhang 	NVME_SMART_CRIT_RELIABILITY	= 1 << 2,
171982388eaSZhikang Zhang 	NVME_SMART_CRIT_MEDIA		= 1 << 3,
172982388eaSZhikang Zhang 	NVME_SMART_CRIT_VOLATILE_MEMORY	= 1 << 4,
173982388eaSZhikang Zhang };
174982388eaSZhikang Zhang 
175982388eaSZhikang Zhang struct nvme_lba_range_type {
176982388eaSZhikang Zhang 	__u8			type;
177982388eaSZhikang Zhang 	__u8			attributes;
178982388eaSZhikang Zhang 	__u8			rsvd2[14];
179982388eaSZhikang Zhang 	__u64			slba;
180982388eaSZhikang Zhang 	__u64			nlb;
181982388eaSZhikang Zhang 	__u8			guid[16];
182982388eaSZhikang Zhang 	__u8			rsvd48[16];
183982388eaSZhikang Zhang };
184982388eaSZhikang Zhang 
185982388eaSZhikang Zhang enum {
186982388eaSZhikang Zhang 	NVME_LBART_TYPE_FS	= 0x01,
187982388eaSZhikang Zhang 	NVME_LBART_TYPE_RAID	= 0x02,
188982388eaSZhikang Zhang 	NVME_LBART_TYPE_CACHE	= 0x03,
189982388eaSZhikang Zhang 	NVME_LBART_TYPE_SWAP	= 0x04,
190982388eaSZhikang Zhang 
191982388eaSZhikang Zhang 	NVME_LBART_ATTRIB_TEMP	= 1 << 0,
192982388eaSZhikang Zhang 	NVME_LBART_ATTRIB_HIDE	= 1 << 1,
193982388eaSZhikang Zhang };
194982388eaSZhikang Zhang 
195982388eaSZhikang Zhang struct nvme_reservation_status {
196982388eaSZhikang Zhang 	__le32	gen;
197982388eaSZhikang Zhang 	__u8	rtype;
198982388eaSZhikang Zhang 	__u8	regctl[2];
199982388eaSZhikang Zhang 	__u8	resv5[2];
200982388eaSZhikang Zhang 	__u8	ptpls;
201982388eaSZhikang Zhang 	__u8	resv10[13];
202982388eaSZhikang Zhang 	struct {
203982388eaSZhikang Zhang 		__le16	cntlid;
204982388eaSZhikang Zhang 		__u8	rcsts;
205982388eaSZhikang Zhang 		__u8	resv3[5];
206982388eaSZhikang Zhang 		__le64	hostid;
207982388eaSZhikang Zhang 		__le64	rkey;
208982388eaSZhikang Zhang 	} regctl_ds[];
209982388eaSZhikang Zhang };
210982388eaSZhikang Zhang 
211982388eaSZhikang Zhang /* I/O commands */
212982388eaSZhikang Zhang 
213982388eaSZhikang Zhang enum nvme_opcode {
214982388eaSZhikang Zhang 	nvme_cmd_flush		= 0x00,
215982388eaSZhikang Zhang 	nvme_cmd_write		= 0x01,
216982388eaSZhikang Zhang 	nvme_cmd_read		= 0x02,
217982388eaSZhikang Zhang 	nvme_cmd_write_uncor	= 0x04,
218982388eaSZhikang Zhang 	nvme_cmd_compare	= 0x05,
219982388eaSZhikang Zhang 	nvme_cmd_write_zeroes	= 0x08,
220982388eaSZhikang Zhang 	nvme_cmd_dsm		= 0x09,
221982388eaSZhikang Zhang 	nvme_cmd_resv_register	= 0x0d,
222982388eaSZhikang Zhang 	nvme_cmd_resv_report	= 0x0e,
223982388eaSZhikang Zhang 	nvme_cmd_resv_acquire	= 0x11,
224982388eaSZhikang Zhang 	nvme_cmd_resv_release	= 0x15,
225982388eaSZhikang Zhang };
226982388eaSZhikang Zhang 
227982388eaSZhikang Zhang struct nvme_common_command {
228982388eaSZhikang Zhang 	__u8			opcode;
229982388eaSZhikang Zhang 	__u8			flags;
230982388eaSZhikang Zhang 	__u16			command_id;
231982388eaSZhikang Zhang 	__le32			nsid;
232982388eaSZhikang Zhang 	__le32			cdw2[2];
233982388eaSZhikang Zhang 	__le64			metadata;
234982388eaSZhikang Zhang 	__le64			prp1;
235982388eaSZhikang Zhang 	__le64			prp2;
236982388eaSZhikang Zhang 	__le32			cdw10[6];
237982388eaSZhikang Zhang };
238982388eaSZhikang Zhang 
239982388eaSZhikang Zhang struct nvme_rw_command {
240982388eaSZhikang Zhang 	__u8			opcode;
241982388eaSZhikang Zhang 	__u8			flags;
242982388eaSZhikang Zhang 	__u16			command_id;
243982388eaSZhikang Zhang 	__le32			nsid;
244982388eaSZhikang Zhang 	__u64			rsvd2;
245982388eaSZhikang Zhang 	__le64			metadata;
246982388eaSZhikang Zhang 	__le64			prp1;
247982388eaSZhikang Zhang 	__le64			prp2;
248982388eaSZhikang Zhang 	__le64			slba;
249982388eaSZhikang Zhang 	__le16			length;
250982388eaSZhikang Zhang 	__le16			control;
251982388eaSZhikang Zhang 	__le32			dsmgmt;
252982388eaSZhikang Zhang 	__le32			reftag;
253982388eaSZhikang Zhang 	__le16			apptag;
254982388eaSZhikang Zhang 	__le16			appmask;
255982388eaSZhikang Zhang };
256982388eaSZhikang Zhang 
257982388eaSZhikang Zhang enum {
258982388eaSZhikang Zhang 	NVME_RW_LR			= 1 << 15,
259982388eaSZhikang Zhang 	NVME_RW_FUA			= 1 << 14,
260982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_UNSPEC		= 0,
261982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_TYPICAL	= 1,
262982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_RARE		= 2,
263982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_READS		= 3,
264982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_WRITES		= 4,
265982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_RW		= 5,
266982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_ONCE		= 6,
267982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_PREFETCH	= 7,
268982388eaSZhikang Zhang 	NVME_RW_DSM_FREQ_TEMP		= 8,
269982388eaSZhikang Zhang 	NVME_RW_DSM_LATENCY_NONE	= 0 << 4,
270982388eaSZhikang Zhang 	NVME_RW_DSM_LATENCY_IDLE	= 1 << 4,
271982388eaSZhikang Zhang 	NVME_RW_DSM_LATENCY_NORM	= 2 << 4,
272982388eaSZhikang Zhang 	NVME_RW_DSM_LATENCY_LOW		= 3 << 4,
273982388eaSZhikang Zhang 	NVME_RW_DSM_SEQ_REQ		= 1 << 6,
274982388eaSZhikang Zhang 	NVME_RW_DSM_COMPRESSED		= 1 << 7,
275982388eaSZhikang Zhang 	NVME_RW_PRINFO_PRCHK_REF	= 1 << 10,
276982388eaSZhikang Zhang 	NVME_RW_PRINFO_PRCHK_APP	= 1 << 11,
277982388eaSZhikang Zhang 	NVME_RW_PRINFO_PRCHK_GUARD	= 1 << 12,
278982388eaSZhikang Zhang 	NVME_RW_PRINFO_PRACT		= 1 << 13,
279982388eaSZhikang Zhang };
280982388eaSZhikang Zhang 
28132a1e554SShawn Lin #define NVME_DSM_MAX_RANGES    256
28232a1e554SShawn Lin 
283982388eaSZhikang Zhang struct nvme_dsm_cmd {
284982388eaSZhikang Zhang 	__u8			opcode;
285982388eaSZhikang Zhang 	__u8			flags;
286982388eaSZhikang Zhang 	__u16			command_id;
287982388eaSZhikang Zhang 	__le32			nsid;
288982388eaSZhikang Zhang 	__u64			rsvd2[2];
289982388eaSZhikang Zhang 	__le64			prp1;
290982388eaSZhikang Zhang 	__le64			prp2;
291982388eaSZhikang Zhang 	__le32			nr;
292982388eaSZhikang Zhang 	__le32			attributes;
293982388eaSZhikang Zhang 	__u32			rsvd12[4];
294982388eaSZhikang Zhang };
295982388eaSZhikang Zhang 
296982388eaSZhikang Zhang enum {
297982388eaSZhikang Zhang 	NVME_DSMGMT_IDR		= 1 << 0,
298982388eaSZhikang Zhang 	NVME_DSMGMT_IDW		= 1 << 1,
299982388eaSZhikang Zhang 	NVME_DSMGMT_AD		= 1 << 2,
300982388eaSZhikang Zhang };
301982388eaSZhikang Zhang 
302982388eaSZhikang Zhang struct nvme_dsm_range {
303982388eaSZhikang Zhang 	__le32			cattr;
304982388eaSZhikang Zhang 	__le32			nlb;
305982388eaSZhikang Zhang 	__le64			slba;
306982388eaSZhikang Zhang };
307982388eaSZhikang Zhang 
3089d9df2d6SShawn Lin struct nvme_write_zeroes_cmd {
3099d9df2d6SShawn Lin         __u8                    opcode;
3109d9df2d6SShawn Lin 	__u8                    flags;
3119d9df2d6SShawn Lin 	__u16                   command_id;
3129d9df2d6SShawn Lin 	__le32                  nsid;
3139d9df2d6SShawn Lin 	__u64                   rsvd2;
3149d9df2d6SShawn Lin 	__le64                  metadata;
3159d9df2d6SShawn Lin 	__le64                  prp1;
3169d9df2d6SShawn Lin 	__le64                  prp2;
3179d9df2d6SShawn Lin 	__le64                  slba;
3189d9df2d6SShawn Lin 	__le16                  length;
3199d9df2d6SShawn Lin 	__le16                  control;
3209d9df2d6SShawn Lin 	__le32                  dsmgmt;
3219d9df2d6SShawn Lin 	__le32                  reftag;
3229d9df2d6SShawn Lin 	__le16                  apptag;
3239d9df2d6SShawn Lin 	__le16                  appmask;
3249d9df2d6SShawn Lin };
3259d9df2d6SShawn Lin 
326982388eaSZhikang Zhang /* Admin commands */
327982388eaSZhikang Zhang 
328982388eaSZhikang Zhang enum nvme_admin_opcode {
329982388eaSZhikang Zhang 	nvme_admin_delete_sq		= 0x00,
330982388eaSZhikang Zhang 	nvme_admin_create_sq		= 0x01,
331982388eaSZhikang Zhang 	nvme_admin_get_log_page		= 0x02,
332982388eaSZhikang Zhang 	nvme_admin_delete_cq		= 0x04,
333982388eaSZhikang Zhang 	nvme_admin_create_cq		= 0x05,
334982388eaSZhikang Zhang 	nvme_admin_identify		= 0x06,
335982388eaSZhikang Zhang 	nvme_admin_abort_cmd		= 0x08,
336982388eaSZhikang Zhang 	nvme_admin_set_features		= 0x09,
337982388eaSZhikang Zhang 	nvme_admin_get_features		= 0x0a,
338982388eaSZhikang Zhang 	nvme_admin_async_event		= 0x0c,
339982388eaSZhikang Zhang 	nvme_admin_activate_fw		= 0x10,
340982388eaSZhikang Zhang 	nvme_admin_download_fw		= 0x11,
341982388eaSZhikang Zhang 	nvme_admin_format_nvm		= 0x80,
342982388eaSZhikang Zhang 	nvme_admin_security_send	= 0x81,
343982388eaSZhikang Zhang 	nvme_admin_security_recv	= 0x82,
344982388eaSZhikang Zhang };
345982388eaSZhikang Zhang 
346982388eaSZhikang Zhang enum {
347982388eaSZhikang Zhang 	NVME_QUEUE_PHYS_CONTIG	= (1 << 0),
348982388eaSZhikang Zhang 	NVME_CQ_IRQ_ENABLED	= (1 << 1),
349982388eaSZhikang Zhang 	NVME_SQ_PRIO_URGENT	= (0 << 1),
350982388eaSZhikang Zhang 	NVME_SQ_PRIO_HIGH	= (1 << 1),
351982388eaSZhikang Zhang 	NVME_SQ_PRIO_MEDIUM	= (2 << 1),
352982388eaSZhikang Zhang 	NVME_SQ_PRIO_LOW	= (3 << 1),
353982388eaSZhikang Zhang 	NVME_FEAT_ARBITRATION	= 0x01,
354982388eaSZhikang Zhang 	NVME_FEAT_POWER_MGMT	= 0x02,
355982388eaSZhikang Zhang 	NVME_FEAT_LBA_RANGE	= 0x03,
356982388eaSZhikang Zhang 	NVME_FEAT_TEMP_THRESH	= 0x04,
357982388eaSZhikang Zhang 	NVME_FEAT_ERR_RECOVERY	= 0x05,
358982388eaSZhikang Zhang 	NVME_FEAT_VOLATILE_WC	= 0x06,
359982388eaSZhikang Zhang 	NVME_FEAT_NUM_QUEUES	= 0x07,
360982388eaSZhikang Zhang 	NVME_FEAT_IRQ_COALESCE	= 0x08,
361982388eaSZhikang Zhang 	NVME_FEAT_IRQ_CONFIG	= 0x09,
362982388eaSZhikang Zhang 	NVME_FEAT_WRITE_ATOMIC	= 0x0a,
363982388eaSZhikang Zhang 	NVME_FEAT_ASYNC_EVENT	= 0x0b,
364982388eaSZhikang Zhang 	NVME_FEAT_AUTO_PST	= 0x0c,
365982388eaSZhikang Zhang 	NVME_FEAT_SW_PROGRESS	= 0x80,
366982388eaSZhikang Zhang 	NVME_FEAT_HOST_ID	= 0x81,
367982388eaSZhikang Zhang 	NVME_FEAT_RESV_MASK	= 0x82,
368982388eaSZhikang Zhang 	NVME_FEAT_RESV_PERSIST	= 0x83,
369982388eaSZhikang Zhang 	NVME_LOG_ERROR		= 0x01,
370982388eaSZhikang Zhang 	NVME_LOG_SMART		= 0x02,
371982388eaSZhikang Zhang 	NVME_LOG_FW_SLOT	= 0x03,
372982388eaSZhikang Zhang 	NVME_LOG_RESERVATION	= 0x80,
373982388eaSZhikang Zhang 	NVME_FWACT_REPL		= (0 << 3),
374982388eaSZhikang Zhang 	NVME_FWACT_REPL_ACTV	= (1 << 3),
375982388eaSZhikang Zhang 	NVME_FWACT_ACTV		= (2 << 3),
376982388eaSZhikang Zhang };
377982388eaSZhikang Zhang 
378982388eaSZhikang Zhang struct nvme_identify {
379982388eaSZhikang Zhang 	__u8			opcode;
380982388eaSZhikang Zhang 	__u8			flags;
381982388eaSZhikang Zhang 	__u16			command_id;
382982388eaSZhikang Zhang 	__le32			nsid;
383982388eaSZhikang Zhang 	__u64			rsvd2[2];
384982388eaSZhikang Zhang 	__le64			prp1;
385982388eaSZhikang Zhang 	__le64			prp2;
386982388eaSZhikang Zhang 	__le32			cns;
387982388eaSZhikang Zhang 	__u32			rsvd11[5];
388982388eaSZhikang Zhang };
389982388eaSZhikang Zhang 
390982388eaSZhikang Zhang struct nvme_features {
391982388eaSZhikang Zhang 	__u8			opcode;
392982388eaSZhikang Zhang 	__u8			flags;
393982388eaSZhikang Zhang 	__u16			command_id;
394982388eaSZhikang Zhang 	__le32			nsid;
395982388eaSZhikang Zhang 	__u64			rsvd2[2];
396982388eaSZhikang Zhang 	__le64			prp1;
397982388eaSZhikang Zhang 	__le64			prp2;
398982388eaSZhikang Zhang 	__le32			fid;
399982388eaSZhikang Zhang 	__le32			dword11;
400982388eaSZhikang Zhang 	__u32			rsvd12[4];
401982388eaSZhikang Zhang };
402982388eaSZhikang Zhang 
403982388eaSZhikang Zhang struct nvme_create_cq {
404982388eaSZhikang Zhang 	__u8			opcode;
405982388eaSZhikang Zhang 	__u8			flags;
406982388eaSZhikang Zhang 	__u16			command_id;
407982388eaSZhikang Zhang 	__u32			rsvd1[5];
408982388eaSZhikang Zhang 	__le64			prp1;
409982388eaSZhikang Zhang 	__u64			rsvd8;
410982388eaSZhikang Zhang 	__le16			cqid;
411982388eaSZhikang Zhang 	__le16			qsize;
412982388eaSZhikang Zhang 	__le16			cq_flags;
413982388eaSZhikang Zhang 	__le16			irq_vector;
414982388eaSZhikang Zhang 	__u32			rsvd12[4];
415982388eaSZhikang Zhang };
416982388eaSZhikang Zhang 
417982388eaSZhikang Zhang struct nvme_create_sq {
418982388eaSZhikang Zhang 	__u8			opcode;
419982388eaSZhikang Zhang 	__u8			flags;
420982388eaSZhikang Zhang 	__u16			command_id;
421982388eaSZhikang Zhang 	__u32			rsvd1[5];
422982388eaSZhikang Zhang 	__le64			prp1;
423982388eaSZhikang Zhang 	__u64			rsvd8;
424982388eaSZhikang Zhang 	__le16			sqid;
425982388eaSZhikang Zhang 	__le16			qsize;
426982388eaSZhikang Zhang 	__le16			sq_flags;
427982388eaSZhikang Zhang 	__le16			cqid;
428982388eaSZhikang Zhang 	__u32			rsvd12[4];
429982388eaSZhikang Zhang };
430982388eaSZhikang Zhang 
431982388eaSZhikang Zhang struct nvme_delete_queue {
432982388eaSZhikang Zhang 	__u8			opcode;
433982388eaSZhikang Zhang 	__u8			flags;
434982388eaSZhikang Zhang 	__u16			command_id;
435982388eaSZhikang Zhang 	__u32			rsvd1[9];
436982388eaSZhikang Zhang 	__le16			qid;
437982388eaSZhikang Zhang 	__u16			rsvd10;
438982388eaSZhikang Zhang 	__u32			rsvd11[5];
439982388eaSZhikang Zhang };
440982388eaSZhikang Zhang 
441982388eaSZhikang Zhang struct nvme_abort_cmd {
442982388eaSZhikang Zhang 	__u8			opcode;
443982388eaSZhikang Zhang 	__u8			flags;
444982388eaSZhikang Zhang 	__u16			command_id;
445982388eaSZhikang Zhang 	__u32			rsvd1[9];
446982388eaSZhikang Zhang 	__le16			sqid;
447982388eaSZhikang Zhang 	__u16			cid;
448982388eaSZhikang Zhang 	__u32			rsvd11[5];
449982388eaSZhikang Zhang };
450982388eaSZhikang Zhang 
451982388eaSZhikang Zhang struct nvme_download_firmware {
452982388eaSZhikang Zhang 	__u8			opcode;
453982388eaSZhikang Zhang 	__u8			flags;
454982388eaSZhikang Zhang 	__u16			command_id;
455982388eaSZhikang Zhang 	__u32			rsvd1[5];
456982388eaSZhikang Zhang 	__le64			prp1;
457982388eaSZhikang Zhang 	__le64			prp2;
458982388eaSZhikang Zhang 	__le32			numd;
459982388eaSZhikang Zhang 	__le32			offset;
460982388eaSZhikang Zhang 	__u32			rsvd12[4];
461982388eaSZhikang Zhang };
462982388eaSZhikang Zhang 
463982388eaSZhikang Zhang struct nvme_format_cmd {
464982388eaSZhikang Zhang 	__u8			opcode;
465982388eaSZhikang Zhang 	__u8			flags;
466982388eaSZhikang Zhang 	__u16			command_id;
467982388eaSZhikang Zhang 	__le32			nsid;
468982388eaSZhikang Zhang 	__u64			rsvd2[4];
469982388eaSZhikang Zhang 	__le32			cdw10;
470982388eaSZhikang Zhang 	__u32			rsvd11[5];
471982388eaSZhikang Zhang };
472982388eaSZhikang Zhang 
473982388eaSZhikang Zhang struct nvme_command {
474982388eaSZhikang Zhang 	union {
475982388eaSZhikang Zhang 		struct nvme_common_command common;
476982388eaSZhikang Zhang 		struct nvme_rw_command rw;
477982388eaSZhikang Zhang 		struct nvme_identify identify;
478982388eaSZhikang Zhang 		struct nvme_features features;
479982388eaSZhikang Zhang 		struct nvme_create_cq create_cq;
480982388eaSZhikang Zhang 		struct nvme_create_sq create_sq;
481982388eaSZhikang Zhang 		struct nvme_delete_queue delete_queue;
482982388eaSZhikang Zhang 		struct nvme_download_firmware dlfw;
483982388eaSZhikang Zhang 		struct nvme_format_cmd format;
484982388eaSZhikang Zhang 		struct nvme_dsm_cmd dsm;
4859d9df2d6SShawn Lin 		struct nvme_write_zeroes_cmd write_zeroes;
486982388eaSZhikang Zhang 		struct nvme_abort_cmd abort;
487982388eaSZhikang Zhang 	};
488982388eaSZhikang Zhang };
489982388eaSZhikang Zhang 
490982388eaSZhikang Zhang enum {
491982388eaSZhikang Zhang 	NVME_SC_SUCCESS			= 0x0,
492982388eaSZhikang Zhang 	NVME_SC_INVALID_OPCODE		= 0x1,
493982388eaSZhikang Zhang 	NVME_SC_INVALID_FIELD		= 0x2,
494982388eaSZhikang Zhang 	NVME_SC_CMDID_CONFLICT		= 0x3,
495982388eaSZhikang Zhang 	NVME_SC_DATA_XFER_ERROR		= 0x4,
496982388eaSZhikang Zhang 	NVME_SC_POWER_LOSS		= 0x5,
497982388eaSZhikang Zhang 	NVME_SC_INTERNAL		= 0x6,
498982388eaSZhikang Zhang 	NVME_SC_ABORT_REQ		= 0x7,
499982388eaSZhikang Zhang 	NVME_SC_ABORT_QUEUE		= 0x8,
500982388eaSZhikang Zhang 	NVME_SC_FUSED_FAIL		= 0x9,
501982388eaSZhikang Zhang 	NVME_SC_FUSED_MISSING		= 0xa,
502982388eaSZhikang Zhang 	NVME_SC_INVALID_NS		= 0xb,
503982388eaSZhikang Zhang 	NVME_SC_CMD_SEQ_ERROR		= 0xc,
504982388eaSZhikang Zhang 	NVME_SC_SGL_INVALID_LAST	= 0xd,
505982388eaSZhikang Zhang 	NVME_SC_SGL_INVALID_COUNT	= 0xe,
506982388eaSZhikang Zhang 	NVME_SC_SGL_INVALID_DATA	= 0xf,
507982388eaSZhikang Zhang 	NVME_SC_SGL_INVALID_METADATA	= 0x10,
508982388eaSZhikang Zhang 	NVME_SC_SGL_INVALID_TYPE	= 0x11,
509982388eaSZhikang Zhang 	NVME_SC_LBA_RANGE		= 0x80,
510982388eaSZhikang Zhang 	NVME_SC_CAP_EXCEEDED		= 0x81,
511982388eaSZhikang Zhang 	NVME_SC_NS_NOT_READY		= 0x82,
512982388eaSZhikang Zhang 	NVME_SC_RESERVATION_CONFLICT	= 0x83,
513982388eaSZhikang Zhang 	NVME_SC_CQ_INVALID		= 0x100,
514982388eaSZhikang Zhang 	NVME_SC_QID_INVALID		= 0x101,
515982388eaSZhikang Zhang 	NVME_SC_QUEUE_SIZE		= 0x102,
516982388eaSZhikang Zhang 	NVME_SC_ABORT_LIMIT		= 0x103,
517982388eaSZhikang Zhang 	NVME_SC_ABORT_MISSING		= 0x104,
518982388eaSZhikang Zhang 	NVME_SC_ASYNC_LIMIT		= 0x105,
519982388eaSZhikang Zhang 	NVME_SC_FIRMWARE_SLOT		= 0x106,
520982388eaSZhikang Zhang 	NVME_SC_FIRMWARE_IMAGE		= 0x107,
521982388eaSZhikang Zhang 	NVME_SC_INVALID_VECTOR		= 0x108,
522982388eaSZhikang Zhang 	NVME_SC_INVALID_LOG_PAGE	= 0x109,
523982388eaSZhikang Zhang 	NVME_SC_INVALID_FORMAT		= 0x10a,
524982388eaSZhikang Zhang 	NVME_SC_FIRMWARE_NEEDS_RESET	= 0x10b,
525982388eaSZhikang Zhang 	NVME_SC_INVALID_QUEUE		= 0x10c,
526982388eaSZhikang Zhang 	NVME_SC_FEATURE_NOT_SAVEABLE	= 0x10d,
527982388eaSZhikang Zhang 	NVME_SC_FEATURE_NOT_CHANGEABLE	= 0x10e,
528982388eaSZhikang Zhang 	NVME_SC_FEATURE_NOT_PER_NS	= 0x10f,
529982388eaSZhikang Zhang 	NVME_SC_FW_NEEDS_RESET_SUBSYS	= 0x110,
530982388eaSZhikang Zhang 	NVME_SC_BAD_ATTRIBUTES		= 0x180,
531982388eaSZhikang Zhang 	NVME_SC_INVALID_PI		= 0x181,
532982388eaSZhikang Zhang 	NVME_SC_READ_ONLY		= 0x182,
533982388eaSZhikang Zhang 	NVME_SC_WRITE_FAULT		= 0x280,
534982388eaSZhikang Zhang 	NVME_SC_READ_ERROR		= 0x281,
535982388eaSZhikang Zhang 	NVME_SC_GUARD_CHECK		= 0x282,
536982388eaSZhikang Zhang 	NVME_SC_APPTAG_CHECK		= 0x283,
537982388eaSZhikang Zhang 	NVME_SC_REFTAG_CHECK		= 0x284,
538982388eaSZhikang Zhang 	NVME_SC_COMPARE_FAILED		= 0x285,
539982388eaSZhikang Zhang 	NVME_SC_ACCESS_DENIED		= 0x286,
540982388eaSZhikang Zhang 	NVME_SC_DNR			= 0x4000,
541982388eaSZhikang Zhang };
542982388eaSZhikang Zhang 
543982388eaSZhikang Zhang struct nvme_completion {
544982388eaSZhikang Zhang 	__le32	result;		/* Used by admin commands to return data */
545982388eaSZhikang Zhang 	__u32	rsvd;
546982388eaSZhikang Zhang 	__le16	sq_head;	/* how much of this queue may be reclaimed */
547982388eaSZhikang Zhang 	__le16	sq_id;		/* submission queue that generated this entry */
548982388eaSZhikang Zhang 	__u16	command_id;	/* of the command which completed */
549982388eaSZhikang Zhang 	__le16	status;		/* did the command fail, and if so, why? */
550982388eaSZhikang Zhang };
551982388eaSZhikang Zhang 
552982388eaSZhikang Zhang /*
553982388eaSZhikang Zhang  * Registers should always be accessed with double word or quad word
554982388eaSZhikang Zhang  * accesses. Registers with 64-bit address pointers should be written
555982388eaSZhikang Zhang  * to with dword accesses by writing the low dword first (ptr[0]),
556982388eaSZhikang Zhang  * then the high dword (ptr[1]) second.
557982388eaSZhikang Zhang  */
nvme_readq(__le64 volatile * regs)558982388eaSZhikang Zhang static inline u64 nvme_readq(__le64 volatile *regs)
559982388eaSZhikang Zhang {
560982388eaSZhikang Zhang #if BITS_PER_LONG == 64
561982388eaSZhikang Zhang 	return readq(regs);
562982388eaSZhikang Zhang #else
563982388eaSZhikang Zhang 	__u32 *ptr = (__u32 *)regs;
564982388eaSZhikang Zhang 	u64 val_lo = readl(ptr);
565982388eaSZhikang Zhang 	u64 val_hi = readl(ptr + 1);
566982388eaSZhikang Zhang 
567982388eaSZhikang Zhang 	return val_lo + (val_hi << 32);
568982388eaSZhikang Zhang #endif
569982388eaSZhikang Zhang }
570982388eaSZhikang Zhang 
nvme_writeq(const u64 val,__le64 volatile * regs)571982388eaSZhikang Zhang static inline void nvme_writeq(const u64 val, __le64 volatile *regs)
572982388eaSZhikang Zhang {
573982388eaSZhikang Zhang #if BITS_PER_LONG == 64
574982388eaSZhikang Zhang 	writeq(val, regs);
575982388eaSZhikang Zhang #else
576982388eaSZhikang Zhang 	__u32 *ptr = (__u32 *)regs;
577982388eaSZhikang Zhang 	u32 val_lo = lower_32_bits(val);
578982388eaSZhikang Zhang 	u32 val_hi = upper_32_bits(val);
579982388eaSZhikang Zhang 	writel(val_lo, ptr);
580982388eaSZhikang Zhang 	writel(val_hi, ptr + 1);
581982388eaSZhikang Zhang #endif
582982388eaSZhikang Zhang }
583982388eaSZhikang Zhang 
584982388eaSZhikang Zhang struct nvme_bar {
585982388eaSZhikang Zhang 	__u64 cap;	/* Controller Capabilities */
586982388eaSZhikang Zhang 	__u32 vs;	/* Version */
587982388eaSZhikang Zhang 	__u32 intms;	/* Interrupt Mask Set */
588982388eaSZhikang Zhang 	__u32 intmc;	/* Interrupt Mask Clear */
589982388eaSZhikang Zhang 	__u32 cc;	/* Controller Configuration */
590982388eaSZhikang Zhang 	__u32 rsvd1;	/* Reserved */
591982388eaSZhikang Zhang 	__u32 csts;	/* Controller Status */
592982388eaSZhikang Zhang 	__u32 rsvd2;	/* Reserved */
593982388eaSZhikang Zhang 	__u32 aqa;	/* Admin Queue Attributes */
594982388eaSZhikang Zhang 	__u64 asq;	/* Admin SQ Base Address */
595982388eaSZhikang Zhang 	__u64 acq;	/* Admin CQ Base Address */
596982388eaSZhikang Zhang };
597982388eaSZhikang Zhang 
598982388eaSZhikang Zhang #define NVME_CAP_MQES(cap)	((cap) & 0xffff)
599982388eaSZhikang Zhang #define NVME_CAP_TIMEOUT(cap)	(((cap) >> 24) & 0xff)
600982388eaSZhikang Zhang #define NVME_CAP_STRIDE(cap)	(((cap) >> 32) & 0xf)
601982388eaSZhikang Zhang #define NVME_CAP_MPSMIN(cap)	(((cap) >> 48) & 0xf)
602982388eaSZhikang Zhang #define NVME_CAP_MPSMAX(cap)	(((cap) >> 52) & 0xf)
603982388eaSZhikang Zhang 
604982388eaSZhikang Zhang #define NVME_VS(major, minor)	(((major) << 16) | ((minor) << 8))
605982388eaSZhikang Zhang 
606982388eaSZhikang Zhang enum {
607982388eaSZhikang Zhang 	NVME_CC_ENABLE		= 1 << 0,
608982388eaSZhikang Zhang 	NVME_CC_CSS_NVM		= 0 << 4,
609982388eaSZhikang Zhang 	NVME_CC_MPS_SHIFT	= 7,
610982388eaSZhikang Zhang 	NVME_CC_ARB_RR		= 0 << 11,
611982388eaSZhikang Zhang 	NVME_CC_ARB_WRRU	= 1 << 11,
612982388eaSZhikang Zhang 	NVME_CC_ARB_VS		= 7 << 11,
613982388eaSZhikang Zhang 	NVME_CC_SHN_NONE	= 0 << 14,
614982388eaSZhikang Zhang 	NVME_CC_SHN_NORMAL	= 1 << 14,
615982388eaSZhikang Zhang 	NVME_CC_SHN_ABRUPT	= 2 << 14,
616982388eaSZhikang Zhang 	NVME_CC_SHN_MASK	= 3 << 14,
617982388eaSZhikang Zhang 	NVME_CC_IOSQES		= 6 << 16,
618982388eaSZhikang Zhang 	NVME_CC_IOCQES		= 4 << 20,
619982388eaSZhikang Zhang 	NVME_CSTS_RDY		= 1 << 0,
620982388eaSZhikang Zhang 	NVME_CSTS_CFS		= 1 << 1,
621982388eaSZhikang Zhang 	NVME_CSTS_SHST_NORMAL	= 0 << 2,
622982388eaSZhikang Zhang 	NVME_CSTS_SHST_OCCUR	= 1 << 2,
623982388eaSZhikang Zhang 	NVME_CSTS_SHST_CMPLT	= 2 << 2,
624982388eaSZhikang Zhang 	NVME_CSTS_SHST_MASK	= 3 << 2,
625982388eaSZhikang Zhang };
626982388eaSZhikang Zhang 
627*51341de7SShawn Lin #define NVME_QUIRK_DELAY_AMOUNT               2300
628*51341de7SShawn Lin 
629*51341de7SShawn Lin /*
630*51341de7SShawn Lin  * List of workarounds for devices that required behavior not specified in
631*51341de7SShawn Lin  * the standard.
632*51341de7SShawn Lin  */
633*51341de7SShawn Lin enum nvme_quirks {
634*51341de7SShawn Lin 	/*
635*51341de7SShawn Lin 	 * The controller deterministically returns O's on reads to
636*51341de7SShawn Lin 	 * logical blocks that deallocate was called on.
637*51341de7SShawn Lin 	 */
638*51341de7SShawn Lin 	NVME_QUIRK_DEALLOCATE_ZEROES            = (1 << 2),
639*51341de7SShawn Lin 
640*51341de7SShawn Lin 	/*
641*51341de7SShawn Lin 	 * The controller needs a delay before starts checking the device
642*51341de7SShawn Lin 	 * readiness, which is done by reading the NVME_CSTS_RDY bit.
643*51341de7SShawn Lin 	 */
644*51341de7SShawn Lin 	NVME_QUIRK_DELAY_BEFORE_CHK_RDY		= (1 << 3),
645*51341de7SShawn Lin 
646*51341de7SShawn Lin 	/*
647*51341de7SShawn Lin 	 * Limit io queue depth to 32
648*51341de7SShawn Lin 	 */
649*51341de7SShawn Lin 	NVME_QUIRK_LIMIT_IOQD32			= (1 << 31),
650*51341de7SShawn Lin };
651*51341de7SShawn Lin 
652982388eaSZhikang Zhang /* Represents an NVM Express device. Each nvme_dev is a PCI function. */
653982388eaSZhikang Zhang struct nvme_dev {
654982388eaSZhikang Zhang 	struct list_head node;
655982388eaSZhikang Zhang 	struct nvme_queue **queues;
656982388eaSZhikang Zhang 	u32 __iomem *dbs;
657982388eaSZhikang Zhang 	int instance;
658982388eaSZhikang Zhang 	unsigned queue_count;
659982388eaSZhikang Zhang 	unsigned online_queues;
660982388eaSZhikang Zhang 	unsigned max_qid;
661*51341de7SShawn Lin 	unsigned long quirks;
662982388eaSZhikang Zhang 	int q_depth;
663982388eaSZhikang Zhang 	u32 db_stride;
664982388eaSZhikang Zhang 	u32 ctrl_config;
665982388eaSZhikang Zhang 	struct nvme_bar __iomem *bar;
666982388eaSZhikang Zhang 	struct list_head namespaces;
667982388eaSZhikang Zhang 	char serial[20];
668982388eaSZhikang Zhang 	char model[40];
669982388eaSZhikang Zhang 	char firmware_rev[8];
670982388eaSZhikang Zhang 	u32 max_transfer_shift;
671b65c6921SBin Meng 	u64 cap;
672982388eaSZhikang Zhang 	u32 stripe_size;
673982388eaSZhikang Zhang 	u32 page_size;
674982388eaSZhikang Zhang 	u8 vwc;
675982388eaSZhikang Zhang 	u64 *prp_pool;
676982388eaSZhikang Zhang 	u32 prp_entry_num;
677982388eaSZhikang Zhang 	u32 nn;
678982388eaSZhikang Zhang };
679982388eaSZhikang Zhang 
680982388eaSZhikang Zhang /*
681982388eaSZhikang Zhang  * An NVM Express namespace is equivalent to a SCSI LUN.
682982388eaSZhikang Zhang  * Each namespace is operated as an independent "device".
683982388eaSZhikang Zhang  */
684982388eaSZhikang Zhang struct nvme_ns {
685982388eaSZhikang Zhang 	struct list_head list;
686982388eaSZhikang Zhang 	struct nvme_dev *dev;
687982388eaSZhikang Zhang 	unsigned ns_id;
688ff15e123SPatrick Wildt 	u8 eui64[8];
689982388eaSZhikang Zhang 	int devnum;
690982388eaSZhikang Zhang 	int lba_shift;
691982388eaSZhikang Zhang 	u8 flbas;
692982388eaSZhikang Zhang };
693982388eaSZhikang Zhang 
694982388eaSZhikang Zhang #endif /* __DRIVER_NVME_H__ */
695