xref: /aosp_15_r20/external/igt-gpu-tools/tools/intel_watermark.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1 /*
2  * Copyright © 2015 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  */
24 
25 #include <inttypes.h>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <stdbool.h>
30 #include <err.h>
31 #include <string.h>
32 #include "intel_io.h"
33 #include "intel_chipset.h"
34 #include "drmtest.h"
35 
36 static uint32_t display_base;
37 static uint32_t devid;
38 
read_reg(uint32_t addr)39 static uint32_t read_reg(uint32_t addr)
40 {
41 	return INREG(display_base + addr);
42 }
43 
44 struct gmch_wm {
45 	int wm, wm1, dl, fifo, fbc, burst;
46 	bool dl_prec, valid;
47 };
48 
49 enum plane {
50 	PRI_HPLL_SR,
51 	CUR_HPLL_SR,
52 	PRI_SR,
53 	CUR_SR,
54 	PRI_A,
55 	CUR_A,
56 	SPR_A,
57 	SPR_B,
58 	PRI_B,
59 	CUR_B,
60 	SPR_C,
61 	SPR_D,
62 	PRI_C,
63 	CUR_C,
64 	SPR_E,
65 	SPR_F,
66 	MAX_PLANE,
67 };
68 
69 #define NAME(x) [x] = #x
70 
71 static const char * const plane_name[] = {
72 	NAME(PRI_HPLL_SR),
73 	NAME(CUR_HPLL_SR),
74 	NAME(PRI_SR),
75 	NAME(CUR_SR),
76 	NAME(PRI_A),
77 	NAME(CUR_A),
78 	NAME(SPR_A),
79 	NAME(SPR_B),
80 	NAME(PRI_B),
81 	NAME(CUR_B),
82 	NAME(SPR_C),
83 	NAME(SPR_D),
84 	NAME(PRI_C),
85 	NAME(CUR_C),
86 	NAME(SPR_E),
87 	NAME(SPR_F),
88 };
89 
90 struct ilk_wm_level {
91 	int primary, sprite, cursor, latency, fbc;
92 	bool enabled, sprite_enabled;
93 	bool primary_trickle_feed_dis, sprite_trickle_feed_dis;
94 };
95 
96 struct ilk_wm {
97 	struct ilk_wm_level pipe[3];
98 	struct {
99 		int linetime, ips;
100 	} linetime[3];
101 	struct ilk_wm_level lp[3];
102 };
103 
104 #define MASK(size) ((1 << (size)) - 1)
105 
106 #define REG_DECODE1(x, shift, size) \
107 	(((x) >> (shift)) & MASK(size))
108 
109 #define REG_DECODE2(lo, shift_lo, size_lo, hi, shift_hi, size_hi) \
110 	((((lo) >> (shift_lo)) & MASK(size_lo)) | \
111 	 ((((hi) >> (shift_hi)) & MASK(size_hi)) << (size_lo)))
112 
pipe_name(int pipe)113 static char pipe_name(int pipe)
114 {
115 	return 'A' + pipe;
116 }
117 
endis(bool enabled)118 static const char *endis(bool enabled)
119 {
120 	return enabled ? "enabled" : "disabled";
121 }
122 
endis_ast(bool enabled)123 static char endis_ast(bool enabled)
124 {
125 	return enabled ? '*' : ' ';
126 }
127 
skl_num_planes(uint32_t d,int pipe)128 static int skl_num_planes(uint32_t d, int pipe)
129 {
130 	if (IS_GEN11(d))
131 		return 8;
132 	else if (IS_GEN10(d) || IS_GEMINILAKE(d))
133 		return 5;
134 	else if (IS_BROXTON(d))
135 		return pipe == 2 ? 4 : 5;
136 	else
137 		return 4;
138 }
139 
skl_max_planes(uint32_t d)140 static int skl_max_planes(uint32_t d)
141 {
142 	if (IS_GEN11(d))
143 		return 8;
144 	else if (IS_GEN10(d) || IS_GEMINILAKE(d) || IS_BROXTON(d))
145 		return 5;
146 	else
147 		return 4;
148 }
149 
skl_plane_name(int pipe,int plane)150 static const char *skl_plane_name(int pipe, int plane)
151 {
152 	static char name[32];
153 
154 	if (plane == 0)
155 		snprintf(name, sizeof(name), "CURSOR");
156 	else
157 		snprintf(name, sizeof(name), "PLANE_%1d%c",
158 			 plane, pipe_name(pipe));
159 
160 	return name;
161 }
162 
skl_wm_linetime_reg_name(int pipe)163 static const char *skl_wm_linetime_reg_name(int pipe)
164 {
165 	static char reg_name[32];
166 
167 	snprintf(reg_name, sizeof(reg_name), "WM_LINETIME_%c",
168 		 pipe_name(pipe));
169 
170 	return reg_name;
171 }
172 
skl_plane_ctl_reg_name(int pipe,int plane)173 static const char *skl_plane_ctl_reg_name(int pipe, int plane)
174 {
175 	static char reg_name[32];
176 
177 	if (plane == 0)
178 		snprintf(reg_name, sizeof(reg_name), "CUR_CTL_%c",
179 			 pipe_name(pipe));
180 	else
181 		snprintf(reg_name, sizeof(reg_name), "PLANE_CTL_%1d_%c",
182 			 plane, pipe_name(pipe));
183 
184 	return reg_name;
185 }
186 
skl_wm_reg_name(int pipe,int plane,int level)187 static const char *skl_wm_reg_name(int pipe, int plane, int level)
188 {
189 	static char reg_name[32];
190 
191 	if (plane == 0)
192 		snprintf(reg_name, sizeof(reg_name), "CUR_WM_%c_%1d",
193 			 pipe_name(pipe), level);
194 	else
195 		snprintf(reg_name, sizeof(reg_name), "PLANE_WM_%1d_%c_%1d",
196 			 plane, pipe_name(pipe), level);
197 
198 	return reg_name;
199 }
200 
skl_wm_trans_reg_name(int pipe,int plane)201 static const char *skl_wm_trans_reg_name(int pipe, int plane)
202 {
203 	static char reg_name[32];
204 
205 	if (plane == 0)
206 		snprintf(reg_name, sizeof(reg_name), "CUR_WM_TRANS_%c",
207 			 pipe_name(pipe));
208 	else
209 		snprintf(reg_name, sizeof(reg_name), "PLANE_WM_TRANS_%1d_%c",
210 			 plane, pipe_name(pipe));
211 	return reg_name;
212 }
213 
skl_buf_cfg_reg_name(int pipe,int plane)214 static const char *skl_buf_cfg_reg_name(int pipe, int plane)
215 {
216 	static char reg_name[32];
217 
218 	if (plane == 0)
219 		snprintf(reg_name, sizeof(reg_name), "CUR_BUF_CFG_%c",
220 			 pipe_name(pipe));
221 	else
222 		snprintf(reg_name, sizeof(reg_name), "PLANE_BUF_CFG_%1d_%c",
223 			 plane, pipe_name(pipe));
224 
225 	return reg_name;
226 }
227 
skl_nv12_buf_cfg_reg_name(int pipe,int plane)228 static const char *skl_nv12_buf_cfg_reg_name(int pipe, int plane)
229 {
230 	static char reg_name[32];
231 
232 	snprintf(reg_name, sizeof(reg_name), "PLANE_NV12_BUF_CFG_%1d_%c",
233 		 plane, pipe_name(pipe));
234 
235 	return reg_name;
236 }
237 
skl_wm_dump(void)238 static void skl_wm_dump(void)
239 {
240 	int pipe, plane, level;
241 	int num_pipes = 3;
242 	int max_planes = skl_max_planes(devid);
243 	int num_levels = 8;
244 	uint32_t base_addr = 0x70000, addr, wm_offset;
245 	uint32_t wm[num_levels][num_pipes][max_planes];
246 	uint32_t wm_trans[num_pipes][max_planes];
247 	uint32_t buf_cfg[num_pipes][max_planes];
248 	uint32_t nv12_buf_cfg[num_pipes][max_planes];
249 	uint32_t plane_ctl[num_pipes][max_planes];
250 	uint32_t wm_linetime[num_pipes];
251 
252 	intel_register_access_init(intel_get_pci_device(), 0, -1);
253 
254 	for (pipe = 0; pipe < num_pipes; pipe++) {
255 		int num_planes = skl_num_planes(devid, pipe);
256 
257 		wm_linetime[pipe] = read_reg(0x45270 + pipe * 0x4);
258 
259 		for (plane = 0; plane < num_planes; plane++) {
260 			addr =  base_addr +  pipe * 0x1000 + plane * 0x100;
261 
262 			plane_ctl[pipe][plane] = read_reg(addr + 0x80);
263 			wm_trans[pipe][plane] = read_reg(addr + 0x00168);
264 			buf_cfg[pipe][plane] = read_reg(addr + 0x0017C);
265 			if (plane != 0 && intel_gen(devid) < 11)
266 				nv12_buf_cfg[pipe][plane] = read_reg(addr + 0x00178);
267 			else
268 				nv12_buf_cfg[pipe][plane] = 0;
269 			for (level = 0; level < num_levels; level++) {
270 				wm_offset = addr + 0x00140 + level * 0x4;
271 				wm[level][pipe][plane] = read_reg(wm_offset);
272 			}
273 		}
274 	}
275 
276 	for (pipe = 0; pipe < num_pipes; pipe++) {
277 		printf("%18s 0x%08x\t",
278 		       skl_wm_linetime_reg_name(pipe),
279 		       wm_linetime[pipe]);
280 	}
281 	printf("\n\n");
282 
283 	for (plane = 0; plane < max_planes; plane++) {
284 		for (pipe = 0; pipe < num_pipes; pipe++) {
285 			if (plane >= skl_num_planes(devid, pipe))
286 				break;
287 
288 			printf("%18s 0x%08x\t" ,
289 			       skl_plane_ctl_reg_name(pipe, plane),
290 			       plane_ctl[pipe][plane]);
291 		}
292 		printf("\n");
293 	}
294 	printf("\n");
295 
296 	for (plane = 0; plane < max_planes; plane++) {
297 		for (level = 0; level < num_levels; level++) {
298 			for (pipe = 0; pipe < num_pipes; pipe++) {
299 				if (plane >= skl_num_planes(devid, pipe))
300 					break;
301 
302 				printf("%18s 0x%08x\t" ,
303 				       skl_wm_reg_name(pipe, plane, level),
304 				       wm[level][pipe][plane]);
305 			}
306 			printf("\n");
307 		}
308 		printf("\n");
309 	}
310 
311 	for (plane = 0; plane < max_planes; plane++) {
312 		for (pipe = 0; pipe < num_pipes; pipe++) {
313 			if (plane >= skl_num_planes(devid, pipe))
314 				break;
315 
316 			printf("%18s 0x%08x\t",
317 			       skl_wm_trans_reg_name(pipe, plane),
318 			       wm_trans[pipe][plane]);
319 		}
320 		printf("\n");
321 	}
322 	printf("\n");
323 
324 	for (plane = 0; plane < max_planes; plane++) {
325 		for (pipe = 0; pipe < num_pipes; pipe++) {
326 			if (plane >= skl_num_planes(devid, pipe))
327 				break;
328 
329 			printf("%18s 0x%08x\t",
330 			       skl_buf_cfg_reg_name(pipe, plane),
331 			       buf_cfg[pipe][plane]);
332 		}
333 		printf("\n");
334 
335 		if (intel_gen(devid) >= 11)
336 			continue;
337 
338 		if (plane == 0)
339 			continue;
340 
341 		for (pipe = 0; pipe < num_pipes; pipe++) {
342 			if (plane >= skl_num_planes(devid, pipe))
343 				break;
344 
345 			printf("%18s 0x%08x\t",
346 			       skl_nv12_buf_cfg_reg_name(pipe, plane),
347 			       nv12_buf_cfg[pipe][plane]);
348 		}
349 		printf("\n");
350 	}
351 	printf("\n");
352 
353 	for (pipe = 0; pipe < num_pipes; pipe++) {
354 		uint32_t start, end, size;
355 		uint32_t lines, blocks, enable;
356 		uint32_t linetime;
357 		int num_planes = skl_num_planes(devid, pipe);
358 
359 		printf("PIPE_%c\n", pipe_name(pipe));
360 
361 		linetime = REG_DECODE1(wm_linetime[pipe], 0, 9);
362 		printf("LINETIME: %d (%.3f usec)\n", linetime, linetime* 0.125f);
363 
364 		printf("LEVEL");
365 		for (plane = 0; plane < num_planes; plane++) {
366 			if (plane == 0)
367 				enable = REG_DECODE1(plane_ctl[pipe][plane], 0, 3) ||
368 					REG_DECODE1(plane_ctl[pipe][plane], 5, 1);
369 			else
370 				enable = REG_DECODE1(plane_ctl[pipe][plane], 31, 1);
371 			printf("%9s%c", skl_plane_name(pipe, plane),
372 			       endis_ast(enable));
373 		}
374 		printf("\n");
375 
376 		for (level = 0; level < num_levels; level++) {
377 			printf("%5d", level);
378 			for (plane = 0; plane < num_planes; plane++) {
379 				blocks = REG_DECODE1(wm[level][pipe][plane], 0, 11);
380 				lines = REG_DECODE1(wm[level][pipe][plane], 14, 5);
381 				enable = REG_DECODE1(wm[level][pipe][plane], 31, 1);
382 
383 				printf("%5d%c", blocks, endis_ast(enable));
384 				if (!REG_DECODE1(wm[level][pipe][plane], 30, 1))
385 					printf("(%2d)", lines);
386 				else
387 					printf("(--)");
388 			}
389 			printf("\n");
390 		}
391 
392 		printf("TRANS");
393 		for (plane = 0; plane < num_planes; plane++) {
394 			blocks = REG_DECODE1(wm_trans[pipe][plane], 0, 11);
395 			lines = REG_DECODE1(wm_trans[pipe][plane], 14, 5);
396 			enable = REG_DECODE1(wm_trans[pipe][plane], 31, 1);
397 
398 			printf("%5d%c", blocks, endis_ast(enable));
399 			if (!REG_DECODE1(wm_trans[pipe][plane], 30, 1))
400 				printf("(%2d)", lines);
401 			else
402 				printf("(--)");
403 		}
404 
405 		printf("\nDDB allocation:");
406 
407 		printf("\nstart");
408 		for (plane = 0; plane < num_planes; plane++) {
409 			start = REG_DECODE1(buf_cfg[pipe][plane], 0, 11);
410 			printf("%10d", start);
411 		}
412 
413 		printf("\n  end");
414 		for (plane = 0; plane < num_planes; plane++) {
415 			end = REG_DECODE1(buf_cfg[pipe][plane], 16, 11);
416 			printf("%10d", end);
417 		}
418 
419 		printf("\n size");
420 		for (plane = 0; plane < num_planes; plane++) {
421 			start = REG_DECODE1(buf_cfg[pipe][plane], 0, 11);
422 			end =  REG_DECODE1(buf_cfg[pipe][plane], 16, 11);
423 			size = end - start + 1;
424 			printf("%10d", (end == 0 && size == 1) ? 0 : size);
425 		}
426 		printf("\n");
427 
428 		if (intel_gen(devid) < 11) {
429 			printf("\nNV12 DDB allocation:");
430 
431 			printf("\nstart");
432 			for (plane = 0; plane < num_planes; plane++) {
433 				start = REG_DECODE1(nv12_buf_cfg[pipe][plane], 0, 11);
434 				printf("%10d", start);
435 			}
436 
437 			printf("\n  end");
438 			for (plane = 0; plane < num_planes; plane++) {
439 				end = REG_DECODE1(nv12_buf_cfg[pipe][plane], 16, 11);
440 				printf("%10d", end);
441 			}
442 
443 			printf("\n size");
444 			for (plane = 0; plane < num_planes; plane++) {
445 				start = REG_DECODE1(nv12_buf_cfg[pipe][plane], 0, 11);
446 				end =  REG_DECODE1(nv12_buf_cfg[pipe][plane], 16, 11);
447 				size = end - start + 1;
448 				printf("%10d", (end == 0 && size == 1) ? 0 : size);
449 			}
450 		}
451 
452 		printf("\n\n\n");
453 	}
454 
455 	printf("* plane watermark enabled\n");
456 	printf("(x) line watermark if enabled\n");
457 }
458 
ilk_wm_dump(void)459 static void ilk_wm_dump(void)
460 {
461 	int i;
462 	uint32_t dspcntr[3];
463 	uint32_t spcntr[3];
464 	uint32_t wm_pipe[3];
465 	uint32_t wm_linetime[3];
466 	uint32_t wm_lp[3];
467 	uint32_t wm_lp_spr[3];
468 	uint32_t arb_ctl, arb_ctl2, wm_misc = 0;
469 	int num_pipes = intel_gen(devid) >= 7 ? 3 : 2;
470 	struct ilk_wm wm = {};
471 
472 	intel_register_access_init(intel_get_pci_device(), 0, -1);
473 
474 	for (i = 0; i < num_pipes; i++) {
475 		dspcntr[i] = read_reg(0x70180 + i * 0x1000);
476 		if (intel_gen(devid) >= 7)
477 			spcntr[i] = read_reg(0x70280 + i * 0x1000);
478 		else
479 			spcntr[i] = read_reg(0x72180 + i * 0x1000);
480 	}
481 
482 	wm_pipe[0] = read_reg(0x45100);
483 	wm_pipe[1] = read_reg(0x45104);
484 	if (num_pipes == 3)
485 		wm_pipe[2] = read_reg(0x45200);
486 
487 	if (IS_BROADWELL(devid) || IS_HASWELL(devid)) {
488 		wm_linetime[0] = read_reg(0x45270);
489 		wm_linetime[1] = read_reg(0x45274);
490 		wm_linetime[2] = read_reg(0x45278);
491 	}
492 
493 	wm_lp[0] = read_reg(0x45108);
494 	wm_lp[1] = read_reg(0x4510c);
495 	wm_lp[2] = read_reg(0x45110);
496 
497 	wm_lp_spr[0] = read_reg(0x45120);
498 	if (intel_gen(devid) >= 7) {
499 		wm_lp_spr[1] = read_reg(0x45124);
500 		wm_lp_spr[2] = read_reg(0x45128);
501 	}
502 
503 	arb_ctl = read_reg(0x45000);
504 	arb_ctl2 = read_reg(0x45004);
505 	if (IS_BROADWELL(devid) || IS_HASWELL(devid))
506 		wm_misc = read_reg(0x45260);
507 
508 	intel_register_access_fini();
509 
510 	for (i = 0; i < num_pipes; i++)
511 		printf("    WM_PIPE_%c = 0x%08x\n", pipe_name(i), wm_pipe[i]);
512 	if (IS_BROADWELL(devid) || IS_HASWELL(devid)) {
513 		for (i = 0; i < num_pipes; i++)
514 			printf("WM_LINETIME_%c = 0x%08x\n", pipe_name(i), wm_linetime[i]);
515 	}
516 	printf("       WM_LP1 = 0x%08x\n", wm_lp[0]);
517 	printf("       WM_LP2 = 0x%08x\n", wm_lp[1]);
518 	printf("       WM_LP3 = 0x%08x\n", wm_lp[2]);
519 	printf("   WM_LP1_SPR = 0x%08x\n", wm_lp_spr[0]);
520 	if (intel_gen(devid) >= 7) {
521 		printf("   WM_LP2_SPR = 0x%08x\n", wm_lp_spr[1]);
522 		printf("   WM_LP3_SPR = 0x%08x\n", wm_lp_spr[2]);
523 	}
524 	printf("      ARB_CTL = 0x%08x\n", arb_ctl);
525 	printf("     ARB_CTL2 = 0x%08x\n", arb_ctl2);
526 	if (IS_BROADWELL(devid) || IS_HASWELL(devid))
527 		printf("      WM_MISC = 0x%08x\n", wm_misc);
528 
529 	for (i = 0 ; i < num_pipes; i++) {
530 		wm.pipe[i].primary = REG_DECODE1(wm_pipe[i], 16, 8);
531 		wm.pipe[i].sprite = REG_DECODE1(wm_pipe[i], 8, 8);
532 		wm.pipe[i].cursor = REG_DECODE1(wm_pipe[i], 0, 6);
533 
534 		if (IS_BROADWELL(devid) || IS_HASWELL(devid)) {
535 			wm.linetime[i].linetime = REG_DECODE1(wm_linetime[i], 0, 9);
536 			wm.linetime[i].ips = REG_DECODE1(wm_linetime[i], 16, 9);
537 		}
538 
539 		wm.pipe[i].primary_trickle_feed_dis =
540 			REG_DECODE1(dspcntr[i], 14, 1);
541 		if (!IS_GEN5(devid))
542 			wm.pipe[i].sprite_trickle_feed_dis =
543 				REG_DECODE1(spcntr[i], 14, 1);
544 	}
545 
546 	for (i = 0; i < 3; i++) {
547 		wm.lp[i].enabled = REG_DECODE1(wm_lp[i], 31, 1);
548 		wm.lp[i].latency = REG_DECODE1(wm_lp[i], 24, 7);
549 		if (IS_BROADWELL(devid))
550 			wm.lp[i].fbc = REG_DECODE1(wm_lp[i], 19, 5);
551 		else
552 			wm.lp[i].fbc = REG_DECODE1(wm_lp[i], 20, 4);
553 		wm.lp[i].primary = REG_DECODE1(wm_lp[i], 8, 11);
554 		wm.lp[i].cursor = REG_DECODE1(wm_lp[i], 0, 8);
555 
556 		if (i == 0 || intel_gen(devid) >= 7) {
557 			if (intel_gen(devid) < 7)
558 				wm.lp[i].sprite_enabled = REG_DECODE1(wm_lp_spr[i], 31, 1);
559 			wm.lp[i].sprite = REG_DECODE1(wm_lp_spr[i], 0, 11);
560 		}
561 	}
562 
563 	for (i = 0; i < num_pipes; i++) {
564 		printf("WM_PIPE_%c: primary=%d, cursor=%d, sprite=%d\n",
565 		       pipe_name(i), wm.pipe[i].primary, wm.pipe[i].cursor, wm.pipe[i].sprite);
566 	}
567 	if (IS_BROADWELL(devid) || IS_HASWELL(devid)) {
568 		for (i = 0; i < num_pipes; i++) {
569 			printf("WM_LINETIME_%c: line time=%d (%.3f usec), ips line time=%d (%.3f usec)\n",
570 			       pipe_name(i),
571 			       wm.linetime[i].linetime, wm.linetime[i].linetime * 0.125f,
572 			       wm.linetime[i].ips, wm.linetime[i].ips * 0.125f);
573 		}
574 	}
575 	if (intel_gen(devid) >= 7) {
576 		for (i = 0; i < 3; i++) {
577 			printf("WM_LP%d: %s, latency=%d, fbc=%d, primary=%d, cursor=%d, sprite=%d\n",
578 			       i + 1, endis(wm.lp[i].enabled), wm.lp[i].latency, wm.lp[i].fbc,
579 			       wm.lp[i].primary, wm.lp[i].cursor, wm.lp[i].sprite);
580 		}
581 	} else {
582 		i = 0;
583 		printf("WM_LP%d: %s, latency=%d, fbc=%d, primary=%d, cursor=%d, sprite=%d (%s)\n",
584 		       i + 1, endis(wm.lp[i].enabled), wm.lp[i].latency, wm.lp[i].fbc,
585 		       wm.lp[i].primary, wm.lp[i].cursor, wm.lp[i].sprite,
586 		       endis(wm.lp[i].sprite_enabled));
587 		for (i = 1; i < 3; i++) {
588 			printf("WM_LP%d: %s, latency=%d, fbc=%d, primary=%d, cursor=%d\n",
589 			       i + 1, endis(wm.lp[i].enabled), wm.lp[i].latency, wm.lp[i].fbc,
590 			       wm.lp[i].primary, wm.lp[i].cursor);
591 		}
592 	}
593 	for (i = 0; i < num_pipes; i++) {
594 		printf("Primary %c trickle feed = %s\n",
595 		       pipe_name(i), endis(!wm.pipe[i].primary_trickle_feed_dis));
596 		if (!IS_GEN5(devid))
597 			printf("Sprite %c trickle feed = %s\n",
598 			       pipe_name(i), endis(!wm.pipe[i].sprite_trickle_feed_dis));
599 	}
600 	if (IS_BROADWELL(devid) || IS_HASWELL(devid)) {
601 		printf("DDB partitioning = %s\n",
602 		       REG_DECODE1(wm_misc, 0, 1) ? "5/6" : "1/2");
603 	} else if (intel_gen(devid) >= 7) {
604 		printf("DDB partitioning = %s\n",
605 		       REG_DECODE1(arb_ctl2, 6, 1) ? "5/6" : "1/2");
606 	}
607 	printf("FBC watermark = %s\n",
608 	       endis(!REG_DECODE1(arb_ctl, 15, 1)));
609 }
610 
vlv_wm_dump(void)611 static void vlv_wm_dump(void)
612 {
613 	int i;
614 	unsigned int num_pipes = IS_CHERRYVIEW(devid) ? 3 : 2;
615 	uint32_t dsparb, dsparb2, dsparb3;
616 	uint32_t fw1, fw2, fw3, fw4, fw5, fw6, fw7, fw8, fw9, howm, howm1;
617 	uint32_t ddl1, ddl2, ddl3;
618 	uint32_t fw_blc_self, mi_arb,cbr1;
619 	uint32_t dsp_ss_pm, ddr_setup2;
620 	struct gmch_wm wms[MAX_PLANE] = {};
621 
622 	intel_register_access_init(intel_get_pci_device(), 0, -1);
623 
624 	dsparb = read_reg(0x70030);
625 	dsparb2 = read_reg(0x70060);
626 
627 	fw1 = read_reg(0x70034);
628 	fw2 = read_reg(0x70038);
629 	fw3 = read_reg(0x7003c);
630 	fw4 = read_reg(0x70070);
631 	fw5 = read_reg(0x70074);
632 	fw6 = read_reg(0x70078);
633 
634 	howm = read_reg(0x70064);
635 	howm1 = read_reg(0x70068);
636 
637 	ddl1 = read_reg(0x70050);
638 	ddl2 = read_reg(0x70054);
639 
640 	fw_blc_self = read_reg(0x6500);
641 	mi_arb = read_reg(0x6504);
642 	cbr1 = read_reg(0x70400);
643 
644 	if (IS_CHERRYVIEW(devid)) {
645 		dsparb3 = read_reg(0x7006c);
646 
647 		fw7 = read_reg(0x700b4);
648 		fw8 = read_reg(0x700b8);
649 		fw9 = read_reg(0x7007c);
650 
651 		ddl3 = read_reg(0x70058);
652 
653 		intel_punit_read(0x36, &dsp_ss_pm);
654 		intel_punit_read(0x139, &ddr_setup2);
655 	} else {
656 		fw7 = read_reg(0x7007c);
657 	}
658 
659 	intel_register_access_fini();
660 
661 	printf("        FW1 = 0x%08x\n", fw1);
662 	printf("        FW2 = 0x%08x\n", fw2);
663 	printf("        FW3 = 0x%08x\n", fw3);
664 	printf("        FW4 = 0x%08x\n", fw4);
665 	printf("        FW5 = 0x%08x\n", fw5);
666 	printf("        FW6 = 0x%08x\n", fw6);
667 	printf("        FW7 = 0x%08x\n", fw7);
668 	if (IS_CHERRYVIEW(devid)) {
669 		printf("        FW8 = 0x%08x\n", fw8);
670 		printf("        FW9 = 0x%08x\n", fw9);
671 	}
672 	printf("       HOWM = 0x%08x\n", howm);
673 	printf("      HOWM1 = 0x%08x\n", howm1);
674 	printf("       DDL1 = 0x%08x\n", ddl1);
675 	printf("       DDL2 = 0x%08x\n", ddl2);
676 	if (IS_CHERRYVIEW(devid))
677 		printf("       DDL3 = 0x%08x\n", ddl3);
678 	printf("     DSPARB = 0x%08x\n", dsparb);
679 	printf("    DSPARB2 = 0x%08x\n", dsparb2);
680 	if (IS_CHERRYVIEW(devid))
681 		printf("    DSPARB3 = 0x%08x\n", dsparb3);
682 	printf("FW_BLC_SELF = 0x%08x\n", fw_blc_self);
683 	printf("     MI_ARB = 0x%08x\n", mi_arb);
684 	printf("       CBR1 = 0x%08x\n", cbr1);
685 	if (IS_CHERRYVIEW(devid)) {
686 		printf("  DSP_SS_PM = 0x%08x\n", dsp_ss_pm);
687 		printf(" DDR_SETUP2 = 0x%08x\n", ddr_setup2);
688 	}
689 
690 	wms[PRI_A].valid = true;
691 	wms[PRI_B].valid = true;
692 	wms[CUR_A].valid = true;
693 	wms[CUR_B].valid = true;
694 	wms[SPR_A].valid = true;
695 	wms[SPR_B].valid = true;
696 	wms[SPR_C].valid = true;
697 	wms[SPR_D].valid = true;
698 	wms[PRI_SR].valid = true;
699 	wms[CUR_SR].valid = true;
700 
701 	if (IS_CHERRYVIEW(devid)) {
702 		wms[PRI_C].valid = true;
703 		wms[CUR_C].valid = true;
704 		wms[SPR_E].valid = true;
705 		wms[SPR_F].valid = true;
706 	}
707 
708 	wms[PRI_A].fifo = REG_DECODE2(dsparb, 0, 8, dsparb2, 0, 1) - 0;
709 	wms[SPR_A].fifo = REG_DECODE2(dsparb, 8, 8, dsparb2, 4, 1) - wms[PRI_A].fifo;
710 	wms[SPR_B].fifo = 512 - 1 - wms[SPR_A].fifo - wms[PRI_A].fifo;
711 	wms[CUR_A].fifo = 0x3f;
712 
713 	wms[PRI_B].fifo = REG_DECODE2(dsparb, 16, 8, dsparb2, 8, 1) - 0;
714 	wms[SPR_C].fifo = REG_DECODE2(dsparb, 24, 8, dsparb2, 12, 1) - wms[PRI_B].fifo;
715 	wms[SPR_D].fifo = 512 - 1 - wms[SPR_C].fifo - wms[PRI_B].fifo;
716 	wms[CUR_B].fifo = 0x3f;
717 
718 	if (IS_CHERRYVIEW(devid)) {
719 		wms[PRI_C].fifo = REG_DECODE2(dsparb3, 0, 8, dsparb2, 16, 1) - 0;
720 		wms[SPR_E].fifo = REG_DECODE2(dsparb3, 8, 8, dsparb2, 20, 1) - wms[PRI_C].fifo;
721 		wms[SPR_F].fifo = 512 - 1 - wms[SPR_E].fifo - wms[PRI_C].fifo;
722 		wms[CUR_C].fifo = 0x3f;
723 	}
724 
725 	wms[PRI_SR].fifo = 512 * num_pipes - 1;
726 	wms[CUR_SR].fifo = 0x3f;
727 
728 	wms[PRI_HPLL_SR].fifo = 512 * num_pipes - 1;
729 	wms[CUR_HPLL_SR].fifo = 0x3f;
730 
731 	wms[PRI_A].wm  = REG_DECODE2(fw1, 0, 8, howm, 0, 1);
732 	wms[PRI_B].wm  = REG_DECODE2(fw1, 8, 8, howm, 12, 1);
733 	wms[CUR_B].wm  = REG_DECODE1(fw1, 16, 6);
734 	wms[PRI_SR].wm = REG_DECODE2(fw1, 23, 9, howm, 24, 2);
735 
736 	wms[SPR_A].wm  = REG_DECODE2(fw2, 0, 8, howm, 4, 1);
737 	wms[CUR_A].wm  = REG_DECODE1(fw2, 8, 6);
738 	wms[SPR_B].wm  = REG_DECODE2(fw2, 16, 8, howm, 8, 1);
739 
740 	wms[CUR_SR].wm   = REG_DECODE1(fw3, 24, 6);
741 
742 	wms[SPR_A].wm1 = REG_DECODE2(fw4, 0, 8, howm1, 4, 1);
743 	wms[CUR_A].wm1 = REG_DECODE1(fw4, 8, 6);
744 	wms[SPR_B].wm1 = REG_DECODE2(fw4, 16, 8, howm1, 8, 1);
745 
746 	wms[CUR_SR].wm1 = REG_DECODE1(fw5, 0, 6);
747 	wms[CUR_B].wm1  = REG_DECODE1(fw5, 8, 6);
748 	wms[PRI_A].wm1  = REG_DECODE2(fw5, 16, 8, howm1, 0, 1);
749 	wms[PRI_B].wm1  = REG_DECODE2(fw5, 24, 8, howm1, 12, 1);
750 
751 	wms[PRI_SR].wm1 = REG_DECODE2(fw6, 0, 9, howm1, 24, 2);
752 
753 	wms[SPR_C].wm  = REG_DECODE2(fw7, 0, 8, howm, 16, 1);
754 	wms[SPR_C].wm1 = REG_DECODE2(fw7, 8, 8, howm1, 16, 1);
755 	wms[SPR_D].wm  = REG_DECODE2(fw7, 16, 8, howm, 20, 1);
756 	wms[SPR_D].wm1 = REG_DECODE2(fw7, 24, 8, howm1, 20, 1);
757 
758 	if (IS_CHERRYVIEW(devid)) {
759 		wms[SPR_E].wm  = REG_DECODE2(fw8, 0, 8, howm, 22, 1);
760 		wms[SPR_E].wm1 = REG_DECODE2(fw8, 8, 8, howm1, 22, 1);
761 		wms[SPR_F].wm  = REG_DECODE2(fw8, 16, 8, howm, 23, 1);
762 		wms[SPR_F].wm1 = REG_DECODE2(fw8, 24, 8, howm1, 23, 1);
763 
764 		wms[CUR_C].wm  = REG_DECODE1(fw9, 0, 6);
765 		wms[CUR_C].wm1 = REG_DECODE1(fw9, 8, 6);
766 		wms[PRI_C].wm  = REG_DECODE2(fw9, 16, 8, howm, 21, 1);
767 		wms[PRI_C].wm1 = REG_DECODE2(fw9, 24, 8, howm1, 21, 1);
768 	}
769 
770 	wms[PRI_A].dl = REG_DECODE1(ddl1, 0, 7);
771 	wms[SPR_A].dl = REG_DECODE1(ddl1, 8, 7);
772 	wms[SPR_B].dl = REG_DECODE1(ddl1, 16, 7);
773 	wms[CUR_A].dl = REG_DECODE1(ddl1, 24, 7);
774 
775 	wms[PRI_A].dl_prec = REG_DECODE1(ddl1, 7, 1);
776 	wms[SPR_A].dl_prec = REG_DECODE1(ddl1, 15, 1);
777 	wms[SPR_B].dl_prec = REG_DECODE1(ddl1, 23, 1);
778 	wms[CUR_A].dl_prec = REG_DECODE1(ddl1, 31, 1);
779 
780 	wms[PRI_B].dl = REG_DECODE1(ddl2, 0, 7);
781 	wms[SPR_C].dl = REG_DECODE1(ddl2, 8, 7);
782 	wms[SPR_D].dl = REG_DECODE1(ddl2, 16, 7);
783 	wms[CUR_B].dl = REG_DECODE1(ddl2, 24, 7);
784 
785 	wms[PRI_B].dl_prec = REG_DECODE1(ddl2, 7, 1);
786 	wms[SPR_C].dl_prec = REG_DECODE1(ddl2, 15, 1);
787 	wms[SPR_D].dl_prec = REG_DECODE1(ddl2, 23, 1);
788 	wms[CUR_B].dl_prec = REG_DECODE1(ddl2, 31, 1);
789 
790 	if (IS_CHERRYVIEW(devid)) {
791 		wms[PRI_C].dl = REG_DECODE1(ddl3, 0, 7);
792 		wms[SPR_E].dl = REG_DECODE1(ddl3, 8, 7);
793 		wms[SPR_F].dl = REG_DECODE1(ddl3, 16, 7);
794 		wms[CUR_C].dl = REG_DECODE1(ddl3, 24, 7);
795 
796 		wms[PRI_C].dl_prec = REG_DECODE1(ddl3, 7, 1);
797 		wms[SPR_E].dl_prec = REG_DECODE1(ddl3, 15, 1);
798 		wms[SPR_F].dl_prec = REG_DECODE1(ddl3, 23, 1);
799 		wms[CUR_C].dl_prec = REG_DECODE1(ddl3, 31, 1);
800 	}
801 
802 	for (i = 0; i < ARRAY_SIZE(wms); i++) {
803 		if (!wms[i].valid)
804 			continue;
805 		printf("%s: WM = %d, WM1 = %d, DDL = %d (prec=%d), FIFO = %d\n",
806 		       plane_name[i], wms[i].wm, wms[i].wm1, wms[i].dl, wms[i].dl_prec, wms[i].fifo);
807 	}
808 
809 	printf("CxSR = %s\n",
810 	       endis(REG_DECODE1(fw_blc_self, 15, 1)));
811 	printf("Trickle feed = %s\n",
812 	       endis(!REG_DECODE1(mi_arb, 2, 1)));
813 	printf("PND deadline = %s\n",
814 	       endis(!REG_DECODE1(cbr1, 31, 1)));
815 
816 	if (IS_CHERRYVIEW(devid)) {
817 		printf("PM5 = %s\n",
818 		       endis(REG_DECODE1(dsp_ss_pm, 6, 1)));
819 		printf("PM5 state = %s\n",
820 		       endis(REG_DECODE1(dsp_ss_pm, 22, 1)));
821 		printf("DDR force high frequency = %s\n",
822 		       endis(REG_DECODE1(ddr_setup2, 0, 1)));
823 		printf("DDR force low frequency = %s\n",
824 		       endis(REG_DECODE1(ddr_setup2, 1, 1)));
825 	}
826 }
827 
g4x_wm_dump(void)828 static void g4x_wm_dump(void)
829 {
830 	int i;
831 	uint32_t dspacntr, dspbcntr;
832 	uint32_t dsparb;
833 	uint32_t fw1, fw2, fw3;
834 	uint32_t mi_display_power_down;
835 	uint32_t mi_arb_state;
836 	struct gmch_wm wms[MAX_PLANE] = {};
837 
838 	intel_register_access_init(intel_get_pci_device(), 0, -1);
839 
840 	dspacntr = read_reg(0x70180);
841 	dspbcntr = read_reg(0x71180);
842 	dsparb = read_reg(0x70030);
843 	fw1 = read_reg(0x70034);
844 	fw2 = read_reg(0x70038);
845 	fw3 = read_reg(0x7003c);
846 	mi_display_power_down = read_reg(0x20e0);
847 	mi_arb_state = read_reg(0x20e4);
848 
849 	intel_register_access_fini();
850 
851 	printf("             DSPACNTR = 0x%08x\n", dspacntr);
852 	printf("             DSPBCNTR = 0x%08x\n", dspbcntr);
853 	printf("                  FW1 = 0x%08x\n", fw1);
854 	printf("                  FW2 = 0x%08x\n", fw2);
855 	printf("                  FW3 = 0x%08x\n", fw3);
856 	printf("               DSPARB = 0x%08x\n", dsparb);
857 	printf("MI_DISPLAY_POWER_DOWN = 0x%08x\n", mi_display_power_down);
858 	printf("         MI_ARB_STATE = 0x%08x\n", mi_arb_state);
859 
860 	wms[PRI_A].valid = true;
861 	wms[PRI_B].valid = true;
862 	wms[CUR_A].valid = true;
863 	wms[CUR_B].valid = true;
864 	wms[SPR_A].valid = true;
865 	wms[SPR_B].valid = true;
866 	wms[PRI_SR].valid = true;
867 	wms[CUR_SR].valid = true;
868 	wms[PRI_HPLL_SR].valid = true;
869 	wms[CUR_HPLL_SR].valid = true;
870 
871 	wms[PRI_A].fifo = REG_DECODE1(dsparb, 0, 7) - 0;
872 	wms[PRI_B].fifo = REG_DECODE1(dsparb, 7, 7) - wms[PRI_A].fifo;
873 
874 	wms[PRI_A].wm  = REG_DECODE1(fw1, 0, 7);
875 	wms[PRI_B].wm  = REG_DECODE1(fw1, 8, 7);
876 	wms[CUR_B].wm  = REG_DECODE1(fw1, 16, 6);
877 	wms[PRI_SR].wm = REG_DECODE1(fw1, 23, 9);
878 
879 	wms[PRI_SR].fbc      = REG_DECODE1(fw2, 0, 8);
880 	wms[PRI_HPLL_SR].fbc = REG_DECODE1(fw2, 8, 6);
881 
882 	wms[SPR_B].wm = REG_DECODE1(fw2, 16, 7);
883 	wms[CUR_A].wm = REG_DECODE1(fw2, 8, 6);
884 	wms[SPR_A].wm = REG_DECODE1(fw2, 0, 7);
885 
886 	wms[CUR_SR].wm      = REG_DECODE1(fw3, 24, 6);
887 	wms[CUR_HPLL_SR].wm = REG_DECODE1(fw3, 16, 6);
888 	wms[PRI_HPLL_SR].wm = REG_DECODE1(fw3, 0, 9);
889 
890 	for (i = 0; i < ARRAY_SIZE(wms); i++) {
891 		if (!wms[i].valid)
892 			continue;
893 		printf("%s: WM = %d, FBC = %d, FIFO = %d\n",
894 		       plane_name[i], wms[i].wm, wms[i].fbc, wms[i].fifo);
895 	}
896 	printf("CxSR = %s\n",
897 	       endis(REG_DECODE1(mi_display_power_down, 15, 1)));
898 	printf("HPLL SR = %s\n",
899 	       endis(REG_DECODE1(fw3, 31, 1)));
900 	printf("FBC SR = %s\n",
901 	       endis(REG_DECODE1(fw2, 31, 1)));
902 	printf("Display A trickle feed = %s\n",
903 	       endis(!REG_DECODE1(dspacntr, 14, 1)));
904 	printf("Display B trickle feed = %s\n",
905 	       endis(!REG_DECODE1(dspbcntr, 14, 1)));
906 	printf("Display A uses sprite data buffer = %s\n",
907 	       endis(!REG_DECODE1(dspacntr, 13, 1)));
908 	printf("Display B uses sprite data buffer = %s\n",
909 	       endis(!REG_DECODE1(dspbcntr, 13, 1)));
910 	printf("Primary display = %c\n",
911 	       REG_DECODE1(mi_arb_state, 0, 1) ? 'B' : 'A');
912 }
913 
gen4_wm_dump(void)914 static void gen4_wm_dump(void)
915 {
916 	int i;
917 	int totalsize = IS_CRESTLINE(devid) ? 128 : 96;
918 	uint32_t dsparb;
919 	uint32_t fw1, fw2, fw3;
920 	uint32_t mi_display_power_down;
921 	uint32_t mi_arb_state;
922 	struct gmch_wm wms[MAX_PLANE] = {};
923 
924 	intel_register_access_init(intel_get_pci_device(), 0, -1);
925 
926 	dsparb = read_reg(0x70030);
927 	fw1 = read_reg(0x70034);
928 	fw2 = read_reg(0x70038);
929 	fw3 = read_reg(0x7003c);
930 	mi_display_power_down = read_reg(0x20e0);
931 	mi_arb_state = read_reg(0x20e4);
932 
933 	intel_register_access_fini();
934 
935 	printf("                  FW1 = 0x%08x\n", fw1);
936 	printf("                  FW2 = 0x%08x\n", fw2);
937 	printf("                  FW3 = 0x%08x\n", fw3);
938 	printf("               DSPARB = 0x%08x\n", dsparb);
939 	printf("MI_DISPLAY_POWER_DOWN = 0x%08x\n", mi_display_power_down);
940 	printf("         MI_ARB_STATE = 0x%08x\n", mi_arb_state);
941 
942 	wms[PRI_A].valid = true;
943 	wms[PRI_B].valid = true;
944 	wms[PRI_C].valid = true;
945 	wms[CUR_A].valid = true;
946 	wms[CUR_B].valid = true;
947 	wms[PRI_SR].valid = true;
948 	wms[CUR_SR].valid = true;
949 	wms[PRI_HPLL_SR].valid = true;
950 	wms[CUR_HPLL_SR].valid = true;
951 
952 	wms[PRI_A].fifo = REG_DECODE1(dsparb, 0, 7) - 0;
953 	wms[PRI_B].fifo = REG_DECODE1(dsparb, 7, 7) - wms[PRI_A].fifo;
954 	wms[PRI_C].fifo = totalsize - wms[PRI_B].fifo - wms[PRI_A].fifo - 1;
955 
956 	wms[PRI_A].wm  = REG_DECODE1(fw1, 0, 7);
957 	wms[PRI_B].wm  = REG_DECODE1(fw1, 8, 7);
958 	wms[CUR_B].wm  = REG_DECODE1(fw1, 16, 6);
959 	wms[PRI_SR].wm = REG_DECODE1(fw1, 23, 9);
960 
961 	wms[CUR_A].wm = REG_DECODE1(fw2, 8, 6);
962 	wms[PRI_C].wm = REG_DECODE1(fw2, 0, 7);
963 
964 	wms[CUR_SR].wm      = REG_DECODE1(fw3, 24, 6);
965 	wms[CUR_HPLL_SR].wm = REG_DECODE1(fw3, 16, 6);
966 	wms[PRI_HPLL_SR].wm = REG_DECODE1(fw3, 0, 9);
967 
968 	for (i = 0; i < ARRAY_SIZE(wms); i++) {
969 		if (!wms[i].valid)
970 			continue;
971 		printf("%s: WM = %d, FIFO = %d\n",
972 		       plane_name[i], wms[i].wm, wms[i].fifo);
973 	}
974 	printf("CxSR = %s\n",
975 	       endis(REG_DECODE1(mi_display_power_down, 15, 1)));
976 	printf("HPLL SR enable = %s\n",
977 	       endis(REG_DECODE1(fw3, 31, 1)));
978 	printf("Trickle feed = %s\n",
979 	       endis(!REG_DECODE1(mi_arb_state, 2, 1)));
980 	printf("Primary display = %c\n",
981 	       REG_DECODE1(mi_arb_state, 0, 1) + 'A');
982 }
983 
pnv_wm_dump(void)984 static void pnv_wm_dump(void)
985 {
986 	int i;
987 	int totalsize = 96; /* FIXME? */
988 	uint32_t dsparb;
989 	uint32_t fw1, fw2, fw3;
990 	uint32_t mi_display_power_down;
991 	uint32_t mi_arb_state;
992 	uint32_t cbr;
993 	struct gmch_wm wms[MAX_PLANE] = {};
994 
995 	intel_register_access_init(intel_get_pci_device(), 0, -1);
996 
997 	dsparb = read_reg(0x70030);
998 	fw1 = read_reg(0x70034);
999 	fw2 = read_reg(0x70038);
1000 	fw3 = read_reg(0x7003c);
1001 	cbr = read_reg(0x70400);
1002 	mi_display_power_down = read_reg(0x20e0);
1003 	mi_arb_state = read_reg(0x20e4);
1004 
1005 	intel_register_access_fini();
1006 
1007 	printf("               DSPARB = 0x%08x\n", dsparb);
1008 	printf("                  FW1 = 0x%08x\n", fw1);
1009 	printf("                  FW2 = 0x%08x\n", fw2);
1010 	printf("                  FW3 = 0x%08x\n", fw3);
1011 	printf("                  CBR = 0x%08x\n", cbr);
1012 	printf("MI_DISPLAY_POWER_DOWN = 0x%08x\n", mi_display_power_down);
1013 	printf("         MI_ARB_STATE = 0x%08x\n", mi_arb_state);
1014 
1015 	wms[PRI_A].valid = true;
1016 	wms[PRI_B].valid = true;
1017 	wms[PRI_C].valid = true;
1018 	wms[CUR_A].valid = true;
1019 	wms[CUR_B].valid = true;
1020 	wms[PRI_SR].valid = true;
1021 	wms[CUR_SR].valid = true;
1022 	wms[PRI_HPLL_SR].valid = true;
1023 	wms[CUR_HPLL_SR].valid = true;
1024 
1025 	wms[PRI_A].fifo = REG_DECODE1(dsparb, 0, 7) - 0;
1026 	wms[PRI_B].fifo = REG_DECODE1(dsparb, 7, 7) - wms[PRI_A].fifo;
1027 	wms[PRI_C].fifo = totalsize - wms[PRI_B].fifo - wms[PRI_A].fifo - 1;
1028 
1029 	wms[PRI_A].wm  = REG_DECODE1(fw1, 0, 7);
1030 	wms[PRI_B].wm  = REG_DECODE1(fw1, 8, 7);
1031 	wms[CUR_B].wm  = REG_DECODE1(fw1, 16, 6);
1032 	wms[PRI_SR].wm = REG_DECODE1(fw1, 23, 9);
1033 
1034 	wms[CUR_A].wm = REG_DECODE1(fw2, 8, 6);
1035 	wms[PRI_C].wm = REG_DECODE1(fw2, 0, 7);
1036 
1037 	switch ((REG_DECODE1(cbr, 30, 1) << 1) | REG_DECODE1(cbr, 25, 1)) {
1038 	case 3:
1039 	case 2:
1040 		wms[PRI_SR].fifo = 8 * 1024 / 64;
1041 		break;
1042 	case 1:
1043 		wms[PRI_SR].fifo = 16 * 1024 / 64;
1044 		break;
1045 	case 0:
1046 		wms[PRI_SR].fifo = 32 * 1024 / 64;
1047 		break;
1048 	}
1049 
1050 	wms[CUR_SR].wm      = REG_DECODE1(fw3, 24, 6);
1051 	wms[CUR_HPLL_SR].wm = REG_DECODE1(fw3, 16, 6);
1052 	wms[PRI_HPLL_SR].wm = REG_DECODE1(fw3, 0, 9);
1053 
1054 	for (i = 0; i < ARRAY_SIZE(wms); i++) {
1055 		if (!wms[i].valid)
1056 			continue;
1057 		printf("%s: WM = %d, FIFO = %d\n",
1058 		       plane_name[i], wms[i].wm, wms[i].fifo);
1059 	}
1060 	printf("CxSR enable = %s\n",
1061 	       endis(REG_DECODE1(fw3, 30, 1)));
1062 	printf("HPLL SR enable = %s\n",
1063 	       endis(REG_DECODE1(fw3, 31, 1)));
1064 	printf("Trickle feed = %s\n",
1065 	       endis(!REG_DECODE1(mi_arb_state, 2, 1)));
1066 	printf("Primary display = %c\n",
1067 	       REG_DECODE1(mi_arb_state, 0, 1) + 'A');
1068 	printf("Display plane A throttling = %s\n",
1069 	       endis(!REG_DECODE1(cbr, 0, 1)));
1070 	printf("Display plane B throttling = %s\n",
1071 	       endis(!REG_DECODE1(cbr, 1, 1)));
1072 }
1073 
gen3_wm_dump(void)1074 static void gen3_wm_dump(void)
1075 {
1076 	int i;
1077 	int totalsize = IS_945GM(devid) ? 128 : 96; /* FIXME? */
1078 	uint32_t dsparb;
1079 	uint32_t instpm;
1080 	uint64_t fw_blc;
1081 	uint32_t fw_blc_self;
1082 	uint32_t mi_arb_state;
1083 	struct gmch_wm wms[MAX_PLANE] = {};
1084 
1085 	intel_register_access_init(intel_get_pci_device(), 0, -1);
1086 
1087 	dsparb = read_reg(0x70030);
1088 	instpm = read_reg(0x20c0);
1089 	fw_blc = read_reg(0x20d8) | ((uint64_t)read_reg(0x20dc) << 32);
1090 	fw_blc_self = read_reg(0x20e0);
1091 	mi_arb_state = read_reg(0x20e4);
1092 
1093 	intel_register_access_fini();
1094 
1095 	printf("      DSPARB = 0x%08x\n", dsparb);
1096 	printf("      FW_BLC = 0x%016" PRIx64 "\n", fw_blc);
1097 	printf(" FW_BLC_SELF = 0x%08x\n", fw_blc_self);
1098 	printf("MI_ARB_STATE = 0x%08x\n", mi_arb_state);
1099 
1100 	wms[PRI_A].valid = true;
1101 	wms[PRI_B].valid = true;
1102 	wms[PRI_C].valid = true;
1103 	wms[PRI_SR].valid = true;
1104 
1105 	wms[PRI_SR].wm = REG_DECODE1(fw_blc_self, 0, 8);
1106 
1107 	wms[PRI_C].burst = (REG_DECODE1(fw_blc, 40, 2) + 1) * 4;
1108 	wms[PRI_C].wm    = REG_DECODE1(fw_blc, 32, 8);
1109 
1110 	wms[PRI_B].burst = (REG_DECODE1(fw_blc, 24, 2) + 1) * 4;
1111 	wms[PRI_B].wm    = REG_DECODE1(fw_blc, 16, 8);
1112 
1113 	wms[PRI_A].burst = (REG_DECODE1(fw_blc, 8, 2) + 1) * 4;
1114 	wms[PRI_A].wm    = REG_DECODE1(fw_blc, 0, 8);
1115 
1116 	wms[PRI_A].fifo = REG_DECODE1(dsparb, 0, 7) - 0;
1117 	wms[PRI_B].fifo = REG_DECODE1(dsparb, 7, 7) - wms[PRI_A].fifo;
1118 	wms[PRI_C].fifo = totalsize - wms[PRI_B].fifo - wms[PRI_A].fifo - 1;
1119 
1120 	for (i = 0; i < ARRAY_SIZE(wms); i++) {
1121 		if (!wms[i].valid)
1122 			continue;
1123 		printf("%s: WM = %d, FIFO = %d, burst = %d\n",
1124 		       plane_name[i], wms[i].wm, wms[i].fifo, wms[i].burst);
1125 	}
1126 	/* FIXME G33 too perhaps? */
1127 	if (devid == PCI_CHIP_I945_G || devid == PCI_CHIP_I945_GM ||
1128 	    devid == PCI_CHIP_I945_GME) {
1129 		printf("CxSR = %s\n",
1130 		       endis(REG_DECODE1(fw_blc_self, 15, 1)));
1131 	} else if (devid == PCI_CHIP_I915_GM) {
1132 		printf("CxSR = %s\n",
1133 		       endis(REG_DECODE1(instpm, 12, 1)));
1134 	}
1135 	printf("Trickle feed = %s\n",
1136 	       endis(!REG_DECODE1(mi_arb_state, 2, 1)));
1137 	printf("Primary display = %c\n",
1138 	       REG_DECODE1(mi_arb_state, 0, 1) + 'A');
1139 	printf("Display plane capability = %d planes\n",
1140 	       3 - REG_DECODE1(mi_arb_state, 12, 2));
1141 }
1142 
gen2_wm_dump(void)1143 static void gen2_wm_dump(void)
1144 {
1145 	int i;
1146 	int totalsize;
1147 	uint32_t dsparb;
1148 	uint32_t mem_mode;
1149 	uint64_t fw_blc;
1150 	uint32_t fw_blc_self;
1151 	uint32_t mi_state;
1152 	struct gmch_wm wms[MAX_PLANE] = {};
1153 
1154 	intel_register_access_init(intel_get_pci_device(), 0, -1);
1155 
1156 	dsparb = read_reg(0x70030);
1157 	mem_mode = read_reg(0x20cc);
1158 	fw_blc = read_reg(0x20d8) | ((uint64_t)read_reg(0x20dc) << 32);
1159 	fw_blc_self = read_reg(0x20e0);
1160 	mi_state = read_reg(0x20e4);
1161 
1162 	intel_register_access_fini();
1163 
1164 	printf("     DSPARB = 0x%08x\n", dsparb);
1165 	printf("   MEM_MODE = 0x%08x\n", mem_mode);
1166 	printf("     FW_BLC = 0x%016" PRIx64 "\n", fw_blc);
1167 	printf("FW_BLC_SELF = 0x%08x\n", fw_blc_self);
1168 	printf("   MI_STATE = 0x%08x\n", mi_state);
1169 
1170 	wms[PRI_C].burst = (REG_DECODE1(fw_blc, 40, 2) + 1) * 4;
1171 	wms[PRI_C].wm    = REG_DECODE1(fw_blc, 32, 8);
1172 
1173 	wms[PRI_B].burst = (REG_DECODE1(fw_blc, 24, 2) + 1) * 4;
1174 	wms[PRI_B].wm    = REG_DECODE1(fw_blc, 16, 8);
1175 
1176 	wms[PRI_A].burst = (REG_DECODE1(fw_blc, 8, 2) + 1) * 4;
1177 	wms[PRI_A].wm    = REG_DECODE1(fw_blc, 0, 8);
1178 
1179 	if (devid == PCI_CHIP_845_G || devid == PCI_CHIP_I865_G) {
1180 		wms[PRI_A].valid = true;
1181 		wms[PRI_C].valid = true;
1182 
1183 		totalsize = 96; /* FIXME? */
1184 		wms[PRI_A].fifo = REG_DECODE1(dsparb, 0, 7) - 0;
1185 		wms[PRI_C].fifo = totalsize - wms[PRI_A].fifo - 1;
1186 	} else {
1187 		wms[PRI_A].valid = true;
1188 		wms[PRI_B].valid = true;
1189 		wms[PRI_C].valid = true;
1190 
1191 		if (devid == PCI_CHIP_I830_M)
1192 			totalsize = 288;
1193 		else
1194 			totalsize = 256;
1195 		totalsize = (devid == PCI_CHIP_I855_GM) ? 256 : 288;
1196 		wms[PRI_A].fifo = REG_DECODE1(dsparb, 0, 9) - 0;
1197 		wms[PRI_B].fifo = REG_DECODE1(dsparb, 9, 9) - wms[PRI_A].fifo;
1198 		wms[PRI_C].fifo = totalsize - wms[PRI_B].fifo - wms[PRI_A].fifo - 1;
1199 	}
1200 
1201 	for (i = 0; i < ARRAY_SIZE(wms); i++) {
1202 		if (!wms[i].valid)
1203 			continue;
1204 		printf("%s: WM = %d, FIFO = %d, burst = %d\n",
1205 		       plane_name[i], wms[i].wm, wms[i].fifo, wms[i].burst);
1206 	}
1207 	if (devid == PCI_CHIP_I855_GM || devid == PCI_CHIP_I854_G) {
1208 		printf("CxSR = %s (%d)\n",
1209 		       endis(REG_DECODE1(mi_state, 3, 2)),
1210 		       REG_DECODE1(mi_state, 3, 2));
1211 		printf("Trickle feed = %s\n",
1212 		       endis(!REG_DECODE1(mem_mode, 2, 1)));
1213 		printf("Display round robin = %s\n",
1214 		       endis(REG_DECODE1(mem_mode, 14, 1)));
1215 		printf("Primary display = %c\n",
1216 		       REG_DECODE1(mem_mode, 15, 1) + 'A');
1217 	} else {
1218 		printf("Display A trickle feed = %s\n",
1219 		       endis(!REG_DECODE1(mem_mode, 2, 1)));
1220 		printf("Display B trickle feed = %s\n",
1221 		       endis(!REG_DECODE1(mem_mode, 3, 1)));
1222 		printf("Water mark fix = %s\n",
1223 		       endis(!REG_DECODE1(mem_mode, 14, 1)));
1224 	}
1225 }
1226 
main(int argc,char * argv[])1227 int main(int argc, char *argv[])
1228 {
1229 	devid = intel_get_pci_device()->device_id;
1230 
1231 	if (intel_gen(devid) >= 9) {
1232 		skl_wm_dump();
1233 	} else if (IS_VALLEYVIEW(devid) || IS_CHERRYVIEW(devid)) {
1234 		display_base = 0x180000;
1235 		vlv_wm_dump();
1236 	} else if (intel_gen(devid) >= 5) {
1237 		ilk_wm_dump();
1238 	} else if (IS_G4X(devid)) {
1239 		g4x_wm_dump();
1240 	} else if (IS_GEN4(devid)) {
1241 		gen4_wm_dump();
1242 	} else if (IS_PINEVIEW(devid)) {
1243 		pnv_wm_dump();
1244 	} else if (IS_GEN3(devid)) {
1245 		gen3_wm_dump();
1246 	} else if (IS_GEN2(devid)) {
1247 		gen2_wm_dump();
1248 	} else {
1249 		printf("unknown chip 0x%x\n", devid);
1250 		return 1;
1251 	}
1252 
1253 	return 0;
1254 }
1255