1d897a111SMichal Wajdeczko /*
2d897a111SMichal Wajdeczko  * SPDX-License-Identifier: MIT
3d897a111SMichal Wajdeczko  *
4d897a111SMichal Wajdeczko  * Copyright � 2008-2018 Intel Corporation
5d897a111SMichal Wajdeczko  */
6d897a111SMichal Wajdeczko 
7d897a111SMichal Wajdeczko #ifndef _I915_GPU_ERROR_H_
8d897a111SMichal Wajdeczko #define _I915_GPU_ERROR_H_
9d897a111SMichal Wajdeczko 
10cb823ed9SChris Wilson #include <linux/atomic.h>
11d897a111SMichal Wajdeczko #include <linux/kref.h>
12d897a111SMichal Wajdeczko #include <linux/ktime.h>
13d897a111SMichal Wajdeczko #include <linux/sched.h>
14d897a111SMichal Wajdeczko 
15d897a111SMichal Wajdeczko #include <drm/drm_mm.h>
16d897a111SMichal Wajdeczko 
17112ed2d3SChris Wilson #include "gt/intel_engine.h"
180f261b24SDaniele Ceraolo Spurio #include "gt/uc/intel_uc_fw.h"
19112ed2d3SChris Wilson 
20d897a111SMichal Wajdeczko #include "intel_device_info.h"
21d897a111SMichal Wajdeczko 
22d897a111SMichal Wajdeczko #include "i915_gem.h"
23d897a111SMichal Wajdeczko #include "i915_gem_gtt.h"
24d897a111SMichal Wajdeczko #include "i915_params.h"
25b7268c5eSChris Wilson #include "i915_scheduler.h"
26d897a111SMichal Wajdeczko 
27d897a111SMichal Wajdeczko struct drm_i915_private;
28d897a111SMichal Wajdeczko struct intel_overlay_error_state;
29d897a111SMichal Wajdeczko struct intel_display_error_state;
30d897a111SMichal Wajdeczko 
31d897a111SMichal Wajdeczko struct i915_gpu_state {
32d897a111SMichal Wajdeczko 	struct kref ref;
33d897a111SMichal Wajdeczko 	ktime_t time;
34d897a111SMichal Wajdeczko 	ktime_t boottime;
35d897a111SMichal Wajdeczko 	ktime_t uptime;
36043477b0SMika Kuoppala 	unsigned long capture;
37043477b0SMika Kuoppala 	unsigned long epoch;
38d897a111SMichal Wajdeczko 
39d897a111SMichal Wajdeczko 	struct drm_i915_private *i915;
40d897a111SMichal Wajdeczko 
41d897a111SMichal Wajdeczko 	char error_msg[128];
42d897a111SMichal Wajdeczko 	bool simulated;
43d897a111SMichal Wajdeczko 	bool awake;
44d897a111SMichal Wajdeczko 	bool wakelock;
45d897a111SMichal Wajdeczko 	bool suspended;
46d897a111SMichal Wajdeczko 	int iommu;
47d897a111SMichal Wajdeczko 	u32 reset_count;
48d897a111SMichal Wajdeczko 	u32 suspend_count;
49d897a111SMichal Wajdeczko 	struct intel_device_info device_info;
500258404fSJani Nikula 	struct intel_runtime_info runtime_info;
51d897a111SMichal Wajdeczko 	struct intel_driver_caps driver_caps;
52d897a111SMichal Wajdeczko 	struct i915_params params;
53d897a111SMichal Wajdeczko 
54d897a111SMichal Wajdeczko 	struct i915_error_uc {
55d897a111SMichal Wajdeczko 		struct intel_uc_fw guc_fw;
56d897a111SMichal Wajdeczko 		struct intel_uc_fw huc_fw;
57d897a111SMichal Wajdeczko 		struct drm_i915_error_object *guc_log;
58d897a111SMichal Wajdeczko 	} uc;
59d897a111SMichal Wajdeczko 
60d897a111SMichal Wajdeczko 	/* Generic register state */
61d897a111SMichal Wajdeczko 	u32 eir;
62d897a111SMichal Wajdeczko 	u32 pgtbl_er;
63d897a111SMichal Wajdeczko 	u32 ier;
646b7a6a7bSOscar Mateo 	u32 gtier[6], ngtier;
65d897a111SMichal Wajdeczko 	u32 ccid;
66d897a111SMichal Wajdeczko 	u32 derrmr;
67d897a111SMichal Wajdeczko 	u32 forcewake;
68d897a111SMichal Wajdeczko 	u32 error; /* gen6+ */
69d897a111SMichal Wajdeczko 	u32 err_int; /* gen7 */
70d897a111SMichal Wajdeczko 	u32 fault_data0; /* gen8, gen9 */
71d897a111SMichal Wajdeczko 	u32 fault_data1; /* gen8, gen9 */
72d897a111SMichal Wajdeczko 	u32 done_reg;
73d897a111SMichal Wajdeczko 	u32 gac_eco;
74d897a111SMichal Wajdeczko 	u32 gam_ecochk;
75d897a111SMichal Wajdeczko 	u32 gab_ctl;
76d897a111SMichal Wajdeczko 	u32 gfx_mode;
77d897a111SMichal Wajdeczko 
78d897a111SMichal Wajdeczko 	u32 nfence;
79d897a111SMichal Wajdeczko 	u64 fence[I915_MAX_NUM_FENCES];
80d897a111SMichal Wajdeczko 	struct intel_overlay_error_state *overlay;
81d897a111SMichal Wajdeczko 	struct intel_display_error_state *display;
82d897a111SMichal Wajdeczko 
83d897a111SMichal Wajdeczko 	struct drm_i915_error_engine {
84c990b4c3SChris Wilson 		const struct intel_engine_cs *engine;
85c990b4c3SChris Wilson 
86d897a111SMichal Wajdeczko 		/* Software tracked state */
87d897a111SMichal Wajdeczko 		bool idle;
88d897a111SMichal Wajdeczko 		unsigned long hangcheck_timestamp;
89d897a111SMichal Wajdeczko 		int num_requests;
90d897a111SMichal Wajdeczko 		u32 reset_count;
91d897a111SMichal Wajdeczko 
92d897a111SMichal Wajdeczko 		/* position of active request inside the ring */
93d897a111SMichal Wajdeczko 		u32 rq_head, rq_post, rq_tail;
94d897a111SMichal Wajdeczko 
95d897a111SMichal Wajdeczko 		/* our own tracking of ring head and tail */
96d897a111SMichal Wajdeczko 		u32 cpu_ring_head;
97d897a111SMichal Wajdeczko 		u32 cpu_ring_tail;
98d897a111SMichal Wajdeczko 
99d897a111SMichal Wajdeczko 		/* Register state */
100d897a111SMichal Wajdeczko 		u32 start;
101d897a111SMichal Wajdeczko 		u32 tail;
102d897a111SMichal Wajdeczko 		u32 head;
103d897a111SMichal Wajdeczko 		u32 ctl;
104d897a111SMichal Wajdeczko 		u32 mode;
105d897a111SMichal Wajdeczko 		u32 hws;
106d897a111SMichal Wajdeczko 		u32 ipeir;
107d897a111SMichal Wajdeczko 		u32 ipehr;
108d897a111SMichal Wajdeczko 		u32 bbstate;
109d897a111SMichal Wajdeczko 		u32 instpm;
110d897a111SMichal Wajdeczko 		u32 instps;
111d897a111SMichal Wajdeczko 		u64 bbaddr;
112d897a111SMichal Wajdeczko 		u64 acthd;
113d897a111SMichal Wajdeczko 		u32 fault_reg;
114d897a111SMichal Wajdeczko 		u64 faddr;
115d897a111SMichal Wajdeczko 		u32 rc_psmi; /* sleep state */
116d897a111SMichal Wajdeczko 		struct intel_instdone instdone;
117d897a111SMichal Wajdeczko 
118d897a111SMichal Wajdeczko 		struct drm_i915_error_context {
119d897a111SMichal Wajdeczko 			char comm[TASK_COMM_LEN];
120d897a111SMichal Wajdeczko 			pid_t pid;
121d897a111SMichal Wajdeczko 			u32 hw_id;
122d897a111SMichal Wajdeczko 			int active;
123d897a111SMichal Wajdeczko 			int guilty;
124b7268c5eSChris Wilson 			struct i915_sched_attr sched_attr;
125d897a111SMichal Wajdeczko 		} context;
126d897a111SMichal Wajdeczko 
127d897a111SMichal Wajdeczko 		struct drm_i915_error_object {
128d897a111SMichal Wajdeczko 			u64 gtt_offset;
129d897a111SMichal Wajdeczko 			u64 gtt_size;
13083bc0f5bSChris Wilson 			int num_pages;
131d897a111SMichal Wajdeczko 			int page_count;
132d897a111SMichal Wajdeczko 			int unused;
133d897a111SMichal Wajdeczko 			u32 *pages[0];
134d897a111SMichal Wajdeczko 		} *ringbuffer, *batchbuffer, *wa_batchbuffer, *ctx, *hws_page;
135d897a111SMichal Wajdeczko 
136d897a111SMichal Wajdeczko 		struct drm_i915_error_object **user_bo;
137d897a111SMichal Wajdeczko 		long user_bo_count;
138d897a111SMichal Wajdeczko 
139d897a111SMichal Wajdeczko 		struct drm_i915_error_object *wa_ctx;
140d897a111SMichal Wajdeczko 		struct drm_i915_error_object *default_state;
141d897a111SMichal Wajdeczko 
142d897a111SMichal Wajdeczko 		struct drm_i915_error_request {
14352c0fdb2SChris Wilson 			unsigned long flags;
144d897a111SMichal Wajdeczko 			long jiffies;
145d897a111SMichal Wajdeczko 			pid_t pid;
146d897a111SMichal Wajdeczko 			u32 context;
147d897a111SMichal Wajdeczko 			u32 seqno;
1483a068721SChris Wilson 			u32 start;
149d897a111SMichal Wajdeczko 			u32 head;
150d897a111SMichal Wajdeczko 			u32 tail;
151b7268c5eSChris Wilson 			struct i915_sched_attr sched_attr;
152d897a111SMichal Wajdeczko 		} *requests, execlist[EXECLIST_MAX_PORTS];
153d897a111SMichal Wajdeczko 		unsigned int num_ports;
154d897a111SMichal Wajdeczko 
155d897a111SMichal Wajdeczko 		struct {
156d897a111SMichal Wajdeczko 			u32 gfx_mode;
157d897a111SMichal Wajdeczko 			union {
158d897a111SMichal Wajdeczko 				u64 pdp[4];
159d897a111SMichal Wajdeczko 				u32 pp_dir_base;
160d897a111SMichal Wajdeczko 			};
161d897a111SMichal Wajdeczko 		} vm_info;
162c990b4c3SChris Wilson 
163c990b4c3SChris Wilson 		struct drm_i915_error_engine *next;
164c990b4c3SChris Wilson 	} *engine;
165d897a111SMichal Wajdeczko 
1660e39037bSChris Wilson 	struct scatterlist *sgl, *fit;
167d897a111SMichal Wajdeczko };
168d897a111SMichal Wajdeczko 
169d897a111SMichal Wajdeczko struct i915_gpu_error {
170d897a111SMichal Wajdeczko 	/* For reset and error_state handling. */
171d897a111SMichal Wajdeczko 	spinlock_t lock;
172d897a111SMichal Wajdeczko 	/* Protected by the above dev->gpu_error.lock. */
173d897a111SMichal Wajdeczko 	struct i915_gpu_state *first_error;
174d897a111SMichal Wajdeczko 
175d897a111SMichal Wajdeczko 	atomic_t pending_fb_pin;
176d897a111SMichal Wajdeczko 
1772caffbf1SChris Wilson 	/** Number of times the device has been reset (global) */
178cb823ed9SChris Wilson 	atomic_t reset_count;
1792caffbf1SChris Wilson 
180d897a111SMichal Wajdeczko 	/** Number of times an engine has been reset */
181cb823ed9SChris Wilson 	atomic_t reset_engine_count[I915_NUM_ENGINES];
182d897a111SMichal Wajdeczko };
183d897a111SMichal Wajdeczko 
184d897a111SMichal Wajdeczko struct drm_i915_error_state_buf {
185d897a111SMichal Wajdeczko 	struct drm_i915_private *i915;
1860e39037bSChris Wilson 	struct scatterlist *sgl, *cur, *end;
1870e39037bSChris Wilson 
1880e39037bSChris Wilson 	char *buf;
1890e39037bSChris Wilson 	size_t bytes;
1900e39037bSChris Wilson 	size_t size;
1910e39037bSChris Wilson 	loff_t iter;
1920e39037bSChris Wilson 
193d897a111SMichal Wajdeczko 	int err;
194d897a111SMichal Wajdeczko };
195d897a111SMichal Wajdeczko 
196d897a111SMichal Wajdeczko #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
197d897a111SMichal Wajdeczko 
198d897a111SMichal Wajdeczko __printf(2, 3)
199d897a111SMichal Wajdeczko void i915_error_printf(struct drm_i915_error_state_buf *e, const char *f, ...);
200d897a111SMichal Wajdeczko 
201d897a111SMichal Wajdeczko struct i915_gpu_state *i915_capture_gpu_state(struct drm_i915_private *i915);
202d897a111SMichal Wajdeczko void i915_capture_error_state(struct drm_i915_private *dev_priv,
2033a891a62SChris Wilson 			      intel_engine_mask_t engine_mask,
204d897a111SMichal Wajdeczko 			      const char *error_msg);
205d897a111SMichal Wajdeczko 
206d897a111SMichal Wajdeczko static inline struct i915_gpu_state *
207d897a111SMichal Wajdeczko i915_gpu_state_get(struct i915_gpu_state *gpu)
208d897a111SMichal Wajdeczko {
209d897a111SMichal Wajdeczko 	kref_get(&gpu->ref);
210d897a111SMichal Wajdeczko 	return gpu;
211d897a111SMichal Wajdeczko }
212d897a111SMichal Wajdeczko 
2130e39037bSChris Wilson ssize_t i915_gpu_state_copy_to_buffer(struct i915_gpu_state *error,
2140e39037bSChris Wilson 				      char *buf, loff_t offset, size_t count);
2150e39037bSChris Wilson 
216d897a111SMichal Wajdeczko void __i915_gpu_state_free(struct kref *kref);
217d897a111SMichal Wajdeczko static inline void i915_gpu_state_put(struct i915_gpu_state *gpu)
218d897a111SMichal Wajdeczko {
219d897a111SMichal Wajdeczko 	if (gpu)
220d897a111SMichal Wajdeczko 		kref_put(&gpu->ref, __i915_gpu_state_free);
221d897a111SMichal Wajdeczko }
222d897a111SMichal Wajdeczko 
223d897a111SMichal Wajdeczko struct i915_gpu_state *i915_first_error_state(struct drm_i915_private *i915);
224d897a111SMichal Wajdeczko void i915_reset_error_state(struct drm_i915_private *i915);
225fb6f0b64SChris Wilson void i915_disable_error_state(struct drm_i915_private *i915, int err);
226d897a111SMichal Wajdeczko 
227d897a111SMichal Wajdeczko #else
228d897a111SMichal Wajdeczko 
229d897a111SMichal Wajdeczko static inline void i915_capture_error_state(struct drm_i915_private *dev_priv,
230d897a111SMichal Wajdeczko 					    u32 engine_mask,
231d897a111SMichal Wajdeczko 					    const char *error_msg)
232d897a111SMichal Wajdeczko {
233d897a111SMichal Wajdeczko }
234d897a111SMichal Wajdeczko 
235d897a111SMichal Wajdeczko static inline struct i915_gpu_state *
236d897a111SMichal Wajdeczko i915_first_error_state(struct drm_i915_private *i915)
237d897a111SMichal Wajdeczko {
238fb6f0b64SChris Wilson 	return ERR_PTR(-ENODEV);
239d897a111SMichal Wajdeczko }
240d897a111SMichal Wajdeczko 
241d897a111SMichal Wajdeczko static inline void i915_reset_error_state(struct drm_i915_private *i915)
242d897a111SMichal Wajdeczko {
243d897a111SMichal Wajdeczko }
244d897a111SMichal Wajdeczko 
245fb6f0b64SChris Wilson static inline void i915_disable_error_state(struct drm_i915_private *i915,
246fb6f0b64SChris Wilson 					    int err)
247fb6f0b64SChris Wilson {
248fb6f0b64SChris Wilson }
249fb6f0b64SChris Wilson 
250d897a111SMichal Wajdeczko #endif /* IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) */
251d897a111SMichal Wajdeczko 
252d897a111SMichal Wajdeczko #endif /* _I915_GPU_ERROR_H_ */
253