1 /* Copyright © 2011 Intel Corporation
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a
4  * copy of this software and associated documentation files (the "Software"),
5  * to deal in the Software without restriction, including without limitation
6  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7  * and/or sell copies of the Software, and to permit persons to whom the
8  * Software is furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice (including the next
11  * paragraph) shall be included in all copies or substantial portions of the
12  * Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <err.h>
27 #include <string.h>
28 #include <stdbool.h>
29 #include "intel_io.h"
30 #include "intel_chipset.h"
31 
32 static uint32_t devid;
33 static int gen;
34 
35 static uint32_t
read_and_print_reg(const char * name,uint32_t reg)36 read_and_print_reg(const char *name, uint32_t reg)
37 {
38 	uint32_t val = INREG(reg);
39 
40 	printf("%s (0x%x): 0x%08x\n", name, reg, val);
41 
42 	return val;
43 }
44 
45 static void
check_chicken_unset(const char * name,uint32_t reg)46 check_chicken_unset(const char *name, uint32_t reg)
47 {
48 	uint32_t val = read_and_print_reg(name, reg);
49 
50 
51 	if (val != 0) {
52 		fprintf(stderr, "           WARN: chicken bits set\n");
53 	} else {
54 		printf("           OK:   chicken bits unset\n");
55 	}
56 }
57 
58 static void
check_bit(uint32_t val,int bit,const char * bitname,bool set)59 check_bit(uint32_t val, int bit, const char *bitname, bool set)
60 {
61 	if (!!(val & (1 << bit)) != set) {
62 		fprintf(stderr, "  (bit %2d) FAIL: %s must be %s\n",
63 			bit, bitname, set ? "set" : "unset");
64 	} else {
65 		printf("  (bit %2d) OK:   %s\n", bit, bitname);
66 	}
67 }
68 
69 static void
check_perf_bit(uint32_t val,int bit,const char * bitname,bool set)70 check_perf_bit(uint32_t val, int bit, const char *bitname, bool set)
71 {
72 	if (!!(val & (1 << bit)) != set) {
73 		printf("  (bit %2d) PERF: %s should be %s\n",
74 			bit, bitname, set ? "set" : "unset");
75 	} else {
76 		printf("  (bit %2d) OK:   %s\n", bit, bitname);
77 	}
78 }
79 
80 static void
check_mi_mode(void)81 check_mi_mode(void)
82 {
83 	/* Described in page 14-16 of the IHD_OS_Vol1_Part3.pdf
84 	 * specification.
85 	 */
86 
87 	uint32_t mi_mode = read_and_print_reg("MI_MODE", 0x209c);
88 
89 	/* From page 14:
90 	 *
91 	 * Async Flip Performance mode
92 	 * Project: All
93 	 * Default Value: 0h
94 	 * Format: U1
95 	 * [DevSNB] This bit must be set to ‘1’
96 	 */
97 	if (gen == 6)
98 		check_bit(mi_mode, 14, "Async Flip Performance mode", true);
99 	else
100 		check_perf_bit(mi_mode, 14, "Async Flip Performance mode",
101 			       false);
102 
103 	check_perf_bit(mi_mode, 13, "Flush Performance Mode", false);
104 
105 	/* Our driver relies on MI_FLUSH, unfortunately. */
106 	if (gen >= 6)
107 		check_bit(mi_mode, 12, "MI_FLUSH enable", true);
108 
109 	/* From page 15:
110 	 *
111 	 *     "1h: LRA mode of allocation. Used for validation purposes"
112 	 */
113 	if (gen < 7)
114 		check_bit(mi_mode, 7, "Vertex Shader Cache Mode", false);
115 
116 	/* From page 16:
117 	 *
118 	 *     "To avoid deadlock conditions in hardware this bit
119 	 *      needs to be set for normal operation.
120 	 */
121 	check_bit(mi_mode, 6, "Vertex Shader Timer Dispatch Enable", true);
122 }
123 
124 static void
check_gfx_mode(void)125 check_gfx_mode(void)
126 {
127 	/* Described in page 17-19 of the IHD_OS_Vol1_Part3.pdf
128 	 * specification.
129 	 */
130 	uint32_t gfx_mode;
131 
132 	if (gen < 6)
133 		return;
134 
135 	if (gen == 6)
136 		gfx_mode = read_and_print_reg("GFX_MODE", 0x2520);
137 	else
138 		gfx_mode = read_and_print_reg("GFX_MODE", 0x229c);
139 
140 	/* Our driver only updates page tables at batchbuffer
141 	 * boundaries, so we don't need TLB flushes at other times.
142 	 */
143 	check_perf_bit(gfx_mode, 13, "Flush TLB Invalidation Mode", true);
144 }
145 
146 static void
check_gt_mode(void)147 check_gt_mode(void)
148 {
149 	/* Described in page 20-22 of the IHD_OS_Vol1_Part3.pdf
150 	 * specification.
151 	 */
152 	uint32_t gt_mode;
153 
154 	if (gen < 6)
155 		return;
156 
157 	if (gen == 6)
158 		gt_mode = read_and_print_reg("GT_MODE", 0x20d0);
159 	else
160 		gt_mode = read_and_print_reg("GT_MODE", 0x7008);
161 
162 	if (gen == 6)
163 		check_perf_bit(gt_mode, 8, "Full Rate Sampler Disable", false);
164 
165 	if (gen == 6) {
166 		/* For DevSmallGT, this bit must be set, which means disable
167 		 * hashing.
168 		 */
169 		if (intel_gt(devid) == 0)
170 			check_bit(gt_mode, 6,
171 				  "WIZ Hashing disable", true);
172 		else
173 			check_perf_bit(gt_mode, 6,
174 				       "WIZ Hashing disable", false);
175 
176 		check_perf_bit(gt_mode, 5, "TD Four Row Dispatch Disable",
177 			       false);
178 		check_perf_bit(gt_mode, 4, "Full Size URB Disable", false);
179 		check_perf_bit(gt_mode, 3, "Full Size SF FIFO Disable", false);
180 		check_perf_bit(gt_mode, 1, "VS Quad Thread Dispatch Disable",
181 			       false);
182 	}
183 }
184 
185 static void
check_cache_mode_0(void)186 check_cache_mode_0(void)
187 {
188 	/* Described in page 23-25 of the IHD_OS_Vol1_Part3.pdf
189 	 * specification.
190 	 */
191 	uint32_t cache_mode_0;
192 
193 	if (gen >= 7)
194 		cache_mode_0 = read_and_print_reg("CACHE_MODE_0", 0x7000);
195 	else
196 		cache_mode_0 = read_and_print_reg("CACHE_MODE_0", 0x2120);
197 
198 	check_perf_bit(cache_mode_0, 15, "Sampler L2 Disable", false);
199 	check_perf_bit(cache_mode_0, 9, "Sampler L2 TLB Prefetch Enable", true);
200 	check_perf_bit(cache_mode_0, 8,
201 		       "Depth Related Cache Pipelined Flush Disable", false);
202 
203 	/* From page 24:
204 	 *
205 	 *     "If this bit is set, RCCunit will have LRA as
206 	 *      replacement policy. The default value i.e. ( when this
207 	 *      bit is reset ) indicates that non-LRA eviction
208 	 *      policy. This bit must be reset. LRA replacement policy
209 	 *      is not supported."
210 	 *
211 	 * And the same for STC Eviction Policy.
212 	 */
213 	check_bit(cache_mode_0, 5, "STC LRA Eviction Policy", false);
214 	if (gen >= 6)
215 		check_bit(cache_mode_0, 4, "RCC LRA Eviction Policy", false);
216 
217 	check_perf_bit(cache_mode_0, 3, "Hierarchical Z Disable", false);
218 
219 	if (gen == 6) {
220 		check_perf_bit(cache_mode_0, 2,
221 			       "Hierarchical Z RAW Stall Optimization "
222 			       "Disable", false);
223 	}
224 
225 	/* From page 25:
226 	 *
227 	 *     "This bit must be 0. Operational Flushes [DevSNB] are
228 	 *      not supported in [DevSNB].  SW must flush the render
229 	 *      target after front buffer rendering."
230 	 */
231 	check_bit(cache_mode_0, 0, "Render Cache Operational Flush", false);
232 }
233 
234 
235 static void
check_cache_mode_1(void)236 check_cache_mode_1(void)
237 {
238 	/* Described in page 23-25 of the IHD_OS_Vol1_Part3.pdf
239 	 * specification.
240 	 */
241 	uint32_t cache_mode_1;
242 
243 	if (gen >= 7)
244 		cache_mode_1 = read_and_print_reg("CACHE_MODE_1", 0x7004);
245 	else
246 		cache_mode_1 = read_and_print_reg("CACHE_MODE_1", 0x2124);
247 
248 	if (gen >= 7) {
249 		check_perf_bit(cache_mode_1, 13,
250 			       "STC Address Lookup Optimization Disable",
251 			       false);
252 	}
253 
254 	/* From page 24:
255 	 *
256 	 *     "If this bit is set, Hizunit will have LRA as
257 	 *      replacement policy. The default value i.e.  (when this
258 	 *      bit is reset) indicates the non-LRA eviction
259 	 *      policy. For performance reasons, this bit must be
260 	 *      reset."
261 	 */
262 	check_bit(cache_mode_1, 12, "HIZ LRA Eviction Policy", false);
263 
264 	/* Page 26 describes these bits as reserved (debug only). */
265 	check_bit(cache_mode_1, 11,
266 		  "DAP Instruction and State Cache Invalidate", false);
267 	check_bit(cache_mode_1, 10,
268 		  "Instruction L1 Cache and In-Flight Queue Disable",
269 		  false);
270 	check_bit(cache_mode_1, 9, "Instruction L2 Cache Fill Buffers Disable",
271 		  false);
272 
273 
274 	if (gen >= 7) {
275 		check_perf_bit(cache_mode_1, 6,
276 			       "Pixel Backend sub-span collection "
277 			       "Optimization Disable",
278 			       false);
279 		check_perf_bit(cache_mode_1, 5, "MCS Cache Disable", false);
280 	}
281 	check_perf_bit(cache_mode_1, 4, "Data Disable", false);
282 
283 	if (gen == 6) {
284 		/* In a later update of the documentation, it says:
285 		 *
286 		 *     "[DevSNB:A0{WKA1}] [DevSNB]: This bit must be
287 		 *      set for depth buffer format
288 		 *      D24_UNORM_S8_UINT."
289 		 *
290 		 * XXX: Does that mean A0 only, or all DevSNB?
291 		 */
292 		check_perf_bit(cache_mode_1, 3,
293 			       "Depth Read Hit Write-Only Optimization "
294 			       "Disable", false);
295 
296 		check_perf_bit(cache_mode_1, 2,
297 			       "Depth Cache LRA Hunt Feature Disable",
298 			       false);
299 	}
300 
301 	check_bit(cache_mode_1, 1, "Instruction and State L2 Cache Disable",
302 		  false);
303 	check_bit(cache_mode_1, 0, "Instruction and State L1 Cache Disable",
304 		  false);
305 }
306 
307 
308 static void
check_3d_chicken4(void)309 check_3d_chicken4(void)
310 {
311 	/* Described in page 23-25 of the IHD_OS_Vol1_Part3.pdf
312 	 * specification.
313 	 */
314 	uint32_t _3d_chicken4 = read_and_print_reg("3D_CHICKEN4", 0x20d4);
315 
316 	check_perf_bit(_3d_chicken4, 6, "3D Scoreboard Hashing Enable", true);
317 
318 	if (_3d_chicken4 & 0x0fbf) {
319 		fprintf(stderr,
320 			"         WARN:   other non-thread deps bits set\n");
321 	} else {
322 		printf("           OK:   other non-thread deps bits unset\n");
323 	}
324 }
325 
326 static void
check_dpfc_control_sa(void)327 check_dpfc_control_sa(void)
328 {
329 	uint32_t dpfc_control_sa;
330 
331 	if (gen != 6)
332 		return;
333 
334 	dpfc_control_sa = read_and_print_reg("DPFC_CONTROL_SA", 0x100100);
335 
336 	/* This is needed for framebuffer compression for us to be
337 	 * able to access the framebuffer by the CPU through the GTT.
338 	 */
339 	check_bit(dpfc_control_sa, 29, "CPU Fence Enable", true);
340 }
341 
main(int argc,char ** argv)342 int main(int argc, char** argv)
343 {
344 	struct pci_device *dev;
345 
346 	dev = intel_get_pci_device();
347 	devid = dev->device_id;
348 	intel_mmio_use_pci_bar(dev);
349 
350 	if (IS_GEN7(devid))
351 		gen = 7;
352 	else if (IS_GEN6(devid))
353 		gen = 6;
354 	else if (IS_GEN5(devid))
355 		gen = 5;
356 	else
357 		gen = 4;
358 
359 	check_mi_mode();
360 	check_gfx_mode();
361 	check_gt_mode();
362 	check_cache_mode_0();
363 	check_cache_mode_1();
364 
365 	if (gen < 7) {
366  		check_chicken_unset("3D_CHICKEN", 0x2084);
367  		check_chicken_unset("3D_CHICKEN2", 0x208c);
368 	} else {
369 		check_chicken_unset("FF_SLICE_CHICKEN", 0x2088);
370 	}
371 	if (gen >= 6)
372 		check_chicken_unset("3D_CHICKEN3", 0x2090);
373 	if (gen == 6)
374 		check_3d_chicken4();
375 
376 	if (gen >= 7) {
377 		check_chicken_unset("FF_SLICE_CS_CHICKEN1", 0x20e0);
378 		check_chicken_unset("FF_SLICE_CS_CHICKEN2", 0x20e4);
379 		check_chicken_unset("FF_SLICE_CS_CHICKEN3", 0x20e8);
380 		check_chicken_unset("COMMON_SLICE_CHICKEN1", 0x7010);
381 		check_chicken_unset("COMMON_SLICE_CHICKEN2", 0x7014);
382 		check_chicken_unset("WM_CHICKEN", 0x5580);
383 		check_chicken_unset("HALF_SLICE_CHICKEN", 0xe100);
384 		check_chicken_unset("HALF_SLICE_CHICKEN2", 0xe180);
385 		check_chicken_unset("ROW_CHICKEN", 0xe4f0);
386 		check_chicken_unset("ROW_CHICKEN2", 0xe4f4);
387 	}
388 
389 	check_chicken_unset("ECOSKPD", 0x21d0);
390 
391 	check_dpfc_control_sa();
392 
393 	return 0;
394 }
395 
396