blob: e71c3d9cff6da1b90c56ea864b3878f5666633ba [file] [log] [blame]
Ville Syrjälä4d2577e2014-12-10 21:17:36 +02001/*
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
Mike Frysinger030977e2018-01-10 17:12:15 -050025#include <inttypes.h>
Ville Syrjälä4d2577e2014-12-10 21:17:36 +020026#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"
Chris Wilson83884e92017-03-21 17:16:03 +000034#include "drmtest.h"
Ville Syrjälä4d2577e2014-12-10 21:17:36 +020035
36static uint32_t display_base;
37static uint32_t devid;
Ville Syrjälä4d2577e2014-12-10 21:17:36 +020038
39static uint32_t read_reg(uint32_t addr)
40{
Jani Nikulafb1515c2015-04-15 15:50:19 +030041 return INREG(display_base + addr);
Ville Syrjälä4d2577e2014-12-10 21:17:36 +020042}
43
44struct gmch_wm {
45 int wm, wm1, dl, fifo, fbc, burst;
46 bool dl_prec, valid;
47};
48
49enum 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
71static 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
90struct 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
96struct ilk_wm {
97 struct ilk_wm_level pipe[3];
Ville Syrjälä92a95882016-04-25 23:21:34 +030098 struct {
99 int linetime, ips;
100 } linetime[3];
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200101 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
Eric Anholteac4baf2017-09-02 21:38:52 -0700113static char pipe_name(int pipe)
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200114{
115 return 'A' + pipe;
116}
117
118static const char *endis(bool enabled)
119{
120 return enabled ? "enabled" : "disabled";
121}
122
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700123static char endis_ast(bool enabled)
124{
125 return enabled ? '*' : ' ';
126}
127
Dhinakaran Pandiyanf8f6db92016-10-18 17:05:19 -0700128static int skl_num_planes(uint32_t d, int pipe)
129{
Ville Syrjäläf46cb242018-12-18 16:22:32 +0200130 if (IS_GEN11(d))
131 return 8;
132 else if (IS_GEN10(d) || IS_GEMINILAKE(d))
Dhinakaran Pandiyanf8f6db92016-10-18 17:05:19 -0700133 return 5;
134 else if (IS_BROXTON(d))
135 return pipe == 2 ? 4 : 5;
136 else
137 return 4;
138}
139
140static int skl_max_planes(uint32_t d)
141{
Ville Syrjäläf46cb242018-12-18 16:22:32 +0200142 if (IS_GEN11(d))
143 return 8;
144 else if (IS_GEN10(d) || IS_GEMINILAKE(d) || IS_BROXTON(d))
Dhinakaran Pandiyanf8f6db92016-10-18 17:05:19 -0700145 return 5;
146 else
147 return 4;
148}
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700149
Ville Syrjälä4aebd4a2017-11-21 20:18:54 +0200150static 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
Ville Syrjälä4a1e8392017-11-21 20:07:34 +0200163static 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
Ville Syrjälä9343ae52018-12-18 17:25:18 +0200173static 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
Ville Syrjälä4a1e8392017-11-21 20:07:34 +0200187static 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
201static 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
214static 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
Ville Syrjälä09f50672018-12-20 08:30:13 +0200228static 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
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700238static void skl_wm_dump(void)
239{
240 int pipe, plane, level;
241 int num_pipes = 3;
Dhinakaran Pandiyanf8f6db92016-10-18 17:05:19 -0700242 int max_planes = skl_max_planes(devid);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700243 int num_levels = 8;
244 uint32_t base_addr = 0x70000, addr, wm_offset;
Dhinakaran Pandiyanf8f6db92016-10-18 17:05:19 -0700245 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];
Ville Syrjälä09f50672018-12-20 08:30:13 +0200248 uint32_t nv12_buf_cfg[num_pipes][max_planes];
Ville Syrjälä9343ae52018-12-18 17:25:18 +0200249 uint32_t plane_ctl[num_pipes][max_planes];
Ville Syrjäläaadde842017-09-15 20:46:23 +0300250 uint32_t wm_linetime[num_pipes];
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700251
Ville Syrjäläe408d562019-03-27 20:52:52 +0200252 intel_register_access_init(intel_get_pci_device(), 0, -1);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700253
254 for (pipe = 0; pipe < num_pipes; pipe++) {
Dhinakaran Pandiyanf8f6db92016-10-18 17:05:19 -0700255 int num_planes = skl_num_planes(devid, pipe);
256
Ville Syrjäläaadde842017-09-15 20:46:23 +0300257 wm_linetime[pipe] = read_reg(0x45270 + pipe * 0x4);
258
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700259 for (plane = 0; plane < num_planes; plane++) {
260 addr = base_addr + pipe * 0x1000 + plane * 0x100;
261
Ville Syrjälä9343ae52018-12-18 17:25:18 +0200262 plane_ctl[pipe][plane] = read_reg(addr + 0x80);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700263 wm_trans[pipe][plane] = read_reg(addr + 0x00168);
264 buf_cfg[pipe][plane] = read_reg(addr + 0x0017C);
Ville Syrjälä09f50672018-12-20 08:30:13 +0200265 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;
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700269 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
Ville Syrjäläaadde842017-09-15 20:46:23 +0300276 for (pipe = 0; pipe < num_pipes; pipe++) {
Ville Syrjälä62b77232017-11-21 20:44:50 +0200277 printf("%18s 0x%08x\t",
Ville Syrjälä4a1e8392017-11-21 20:07:34 +0200278 skl_wm_linetime_reg_name(pipe),
279 wm_linetime[pipe]);
Ville Syrjäläaadde842017-09-15 20:46:23 +0300280 }
281 printf("\n\n");
282
Dhinakaran Pandiyanf8f6db92016-10-18 17:05:19 -0700283 for (plane = 0; plane < max_planes; plane++) {
Ville Syrjälä9343ae52018-12-18 17:25:18 +0200284 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++) {
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700297 for (level = 0; level < num_levels; level++) {
298 for (pipe = 0; pipe < num_pipes; pipe++) {
Dhinakaran Pandiyanf8f6db92016-10-18 17:05:19 -0700299 if (plane >= skl_num_planes(devid, pipe))
300 break;
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700301
Ville Syrjälä62b77232017-11-21 20:44:50 +0200302 printf("%18s 0x%08x\t" ,
Ville Syrjälä4a1e8392017-11-21 20:07:34 +0200303 skl_wm_reg_name(pipe, plane, level),
304 wm[level][pipe][plane]);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700305 }
306 printf("\n");
307 }
308 printf("\n");
309 }
310
Dhinakaran Pandiyanf8f6db92016-10-18 17:05:19 -0700311 for (plane = 0; plane < max_planes; plane++) {
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700312 for (pipe = 0; pipe < num_pipes; pipe++) {
Dhinakaran Pandiyanf8f6db92016-10-18 17:05:19 -0700313 if (plane >= skl_num_planes(devid, pipe))
314 break;
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700315
Ville Syrjälä62b77232017-11-21 20:44:50 +0200316 printf("%18s 0x%08x\t",
Ville Syrjälä4a1e8392017-11-21 20:07:34 +0200317 skl_wm_trans_reg_name(pipe, plane),
318 wm_trans[pipe][plane]);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700319 }
320 printf("\n");
321 }
322 printf("\n");
323
Dhinakaran Pandiyanf8f6db92016-10-18 17:05:19 -0700324 for (plane = 0; plane < max_planes; plane++) {
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700325 for (pipe = 0; pipe < num_pipes; pipe++) {
Dhinakaran Pandiyanf8f6db92016-10-18 17:05:19 -0700326 if (plane >= skl_num_planes(devid, pipe))
327 break;
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700328
Ville Syrjälä62b77232017-11-21 20:44:50 +0200329 printf("%18s 0x%08x\t",
Ville Syrjälä4a1e8392017-11-21 20:07:34 +0200330 skl_buf_cfg_reg_name(pipe, plane),
331 buf_cfg[pipe][plane]);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700332 }
333 printf("\n");
Ville Syrjälä09f50672018-12-20 08:30:13 +0200334
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");
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700350 }
351 printf("\n");
352
353 for (pipe = 0; pipe < num_pipes; pipe++) {
354 uint32_t start, end, size;
355 uint32_t lines, blocks, enable;
Ville Syrjäläaadde842017-09-15 20:46:23 +0300356 uint32_t linetime;
Dhinakaran Pandiyanf8f6db92016-10-18 17:05:19 -0700357 int num_planes = skl_num_planes(devid, pipe);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700358
359 printf("PIPE_%c\n", pipe_name(pipe));
Ville Syrjäläaadde842017-09-15 20:46:23 +0300360
361 linetime = REG_DECODE1(wm_linetime[pipe], 0, 9);
362 printf("LINETIME: %d (%.3f usec)\n", linetime, linetime* 0.125f);
363
Ville Syrjälä4aebd4a2017-11-21 20:18:54 +0200364 printf("LEVEL");
Ville Syrjälä9343ae52018-12-18 17:25:18 +0200365 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 }
Ville Syrjälä4aebd4a2017-11-21 20:18:54 +0200374 printf("\n");
375
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700376 for (level = 0; level < num_levels; level++) {
Ville Syrjälä0c4eb792017-11-21 20:32:42 +0200377 printf("%5d", level);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700378 for (plane = 0; plane < num_planes; plane++) {
Ville Syrjälä0657f312018-12-18 16:28:59 +0200379 blocks = REG_DECODE1(wm[level][pipe][plane], 0, 11);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700380 lines = REG_DECODE1(wm[level][pipe][plane], 14, 5);
381 enable = REG_DECODE1(wm[level][pipe][plane], 31, 1);
382
Ville Syrjälä0c4eb792017-11-21 20:32:42 +0200383 printf("%5d%c", blocks, endis_ast(enable));
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700384 if (!REG_DECODE1(wm[level][pipe][plane], 30, 1))
Ville Syrjälä0c4eb792017-11-21 20:32:42 +0200385 printf("(%2d)", lines);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700386 else
Ville Syrjälä0c4eb792017-11-21 20:32:42 +0200387 printf("(--)");
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700388 }
389 printf("\n");
390 }
391
Ville Syrjälä0c4eb792017-11-21 20:32:42 +0200392 printf("TRANS");
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700393 for (plane = 0; plane < num_planes; plane++) {
Ville Syrjälä0657f312018-12-18 16:28:59 +0200394 blocks = REG_DECODE1(wm_trans[pipe][plane], 0, 11);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700395 lines = REG_DECODE1(wm_trans[pipe][plane], 14, 5);
396 enable = REG_DECODE1(wm_trans[pipe][plane], 31, 1);
397
Ville Syrjälä0c4eb792017-11-21 20:32:42 +0200398 printf("%5d%c", blocks, endis_ast(enable));
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700399 if (!REG_DECODE1(wm_trans[pipe][plane], 30, 1))
Ville Syrjälä0c4eb792017-11-21 20:32:42 +0200400 printf("(%2d)", lines);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700401 else
Ville Syrjälä0c4eb792017-11-21 20:32:42 +0200402 printf("(--)");
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700403 }
404
405 printf("\nDDB allocation:");
406
Ville Syrjälä0c4eb792017-11-21 20:32:42 +0200407 printf("\nstart");
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700408 for (plane = 0; plane < num_planes; plane++) {
Ville Syrjälä672acd72018-12-18 16:23:59 +0200409 start = REG_DECODE1(buf_cfg[pipe][plane], 0, 11);
Ville Syrjälä0c4eb792017-11-21 20:32:42 +0200410 printf("%10d", start);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700411 }
412
Ville Syrjälä0c4eb792017-11-21 20:32:42 +0200413 printf("\n end");
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700414 for (plane = 0; plane < num_planes; plane++) {
Ville Syrjälä672acd72018-12-18 16:23:59 +0200415 end = REG_DECODE1(buf_cfg[pipe][plane], 16, 11);
Ville Syrjälä0c4eb792017-11-21 20:32:42 +0200416 printf("%10d", end);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700417 }
418
Ville Syrjälä0c4eb792017-11-21 20:32:42 +0200419 printf("\n size");
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700420 for (plane = 0; plane < num_planes; plane++) {
Ville Syrjälä672acd72018-12-18 16:23:59 +0200421 start = REG_DECODE1(buf_cfg[pipe][plane], 0, 11);
422 end = REG_DECODE1(buf_cfg[pipe][plane], 16, 11);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700423 size = end - start + 1;
Ville Syrjälä0c4eb792017-11-21 20:32:42 +0200424 printf("%10d", (end == 0 && size == 1) ? 0 : size);
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700425 }
Ville Syrjälä09f50672018-12-20 08:30:13 +0200426 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 }
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -0700451
452 printf("\n\n\n");
453 }
454
455 printf("* plane watermark enabled\n");
456 printf("(x) line watermark if enabled\n");
457}
458
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200459static 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];
Ville Syrjälä92a95882016-04-25 23:21:34 +0300465 uint32_t wm_linetime[3];
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200466 uint32_t wm_lp[3];
467 uint32_t wm_lp_spr[3];
468 uint32_t arb_ctl, arb_ctl2, wm_misc = 0;
Ville Syrjälä592b8542018-12-20 08:30:06 +0200469 int num_pipes = intel_gen(devid) >= 7 ? 3 : 2;
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200470 struct ilk_wm wm = {};
471
Ville Syrjäläe408d562019-03-27 20:52:52 +0200472 intel_register_access_init(intel_get_pci_device(), 0, -1);
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200473
474 for (i = 0; i < num_pipes; i++) {
475 dspcntr[i] = read_reg(0x70180 + i * 0x1000);
Ville Syrjälä592b8542018-12-20 08:30:06 +0200476 if (intel_gen(devid) >= 7)
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200477 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);
Ville Syrjälä92a95882016-04-25 23:21:34 +0300486
Ville Syrjälä592b8542018-12-20 08:30:06 +0200487 if (IS_BROADWELL(devid) || IS_HASWELL(devid)) {
Ville Syrjälä92a95882016-04-25 23:21:34 +0300488 wm_linetime[0] = read_reg(0x45270);
489 wm_linetime[1] = read_reg(0x45274);
490 wm_linetime[2] = read_reg(0x45278);
491 }
492
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200493 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);
Ville Syrjälä592b8542018-12-20 08:30:06 +0200498 if (intel_gen(devid) >= 7) {
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200499 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);
Ville Syrjälä592b8542018-12-20 08:30:06 +0200505 if (IS_BROADWELL(devid) || IS_HASWELL(devid))
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200506 wm_misc = read_reg(0x45260);
507
508 intel_register_access_fini();
509
510 for (i = 0; i < num_pipes; i++)
Ville Syrjälä92a95882016-04-25 23:21:34 +0300511 printf(" WM_PIPE_%c = 0x%08x\n", pipe_name(i), wm_pipe[i]);
Ville Syrjälä592b8542018-12-20 08:30:06 +0200512 if (IS_BROADWELL(devid) || IS_HASWELL(devid)) {
Ville Syrjälä92a95882016-04-25 23:21:34 +0300513 for (i = 0; i < num_pipes; i++)
514 printf("WM_LINETIME_%c = 0x%08x\n", pipe_name(i), wm_linetime[i]);
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200515 }
Ville Syrjälä92a95882016-04-25 23:21:34 +0300516 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]);
Ville Syrjälä592b8542018-12-20 08:30:06 +0200520 if (intel_gen(devid) >= 7) {
Ville Syrjälä92a95882016-04-25 23:21:34 +0300521 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);
Ville Syrjälä592b8542018-12-20 08:30:06 +0200526 if (IS_BROADWELL(devid) || IS_HASWELL(devid))
Ville Syrjälä92a95882016-04-25 23:21:34 +0300527 printf(" WM_MISC = 0x%08x\n", wm_misc);
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200528
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
Ville Syrjälä592b8542018-12-20 08:30:06 +0200534 if (IS_BROADWELL(devid) || IS_HASWELL(devid)) {
Ville Syrjälä92a95882016-04-25 23:21:34 +0300535 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
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200539 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);
Ville Syrjälä592b8542018-12-20 08:30:06 +0200549 if (IS_BROADWELL(devid))
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200550 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
Ville Syrjälä592b8542018-12-20 08:30:06 +0200556 if (i == 0 || intel_gen(devid) >= 7) {
557 if (intel_gen(devid) < 7)
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200558 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 }
Ville Syrjälä592b8542018-12-20 08:30:06 +0200567 if (IS_BROADWELL(devid) || IS_HASWELL(devid)) {
Ville Syrjälä92a95882016-04-25 23:21:34 +0300568 for (i = 0; i < num_pipes; i++) {
Ville Syrjälä1f5814e2017-09-15 20:26:33 +0300569 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);
Ville Syrjälä92a95882016-04-25 23:21:34 +0300573 }
574 }
Ville Syrjälä592b8542018-12-20 08:30:06 +0200575 if (intel_gen(devid) >= 7) {
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200576 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 }
Ville Syrjälä592b8542018-12-20 08:30:06 +0200600 if (IS_BROADWELL(devid) || IS_HASWELL(devid)) {
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200601 printf("DDB partitioning = %s\n",
602 REG_DECODE1(wm_misc, 0, 1) ? "5/6" : "1/2");
Ville Syrjälä592b8542018-12-20 08:30:06 +0200603 } else if (intel_gen(devid) >= 7) {
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200604 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
611static 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
Ville Syrjäläe408d562019-03-27 20:52:52 +0200622 intel_register_access_init(intel_get_pci_device(), 0, -1);
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200623
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
828static 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
Ville Syrjäläe408d562019-03-27 20:52:52 +0200838 intel_register_access_init(intel_get_pci_device(), 0, -1);
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200839
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
914static 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
Ville Syrjäläe408d562019-03-27 20:52:52 +0200924 intel_register_access_init(intel_get_pci_device(), 0, -1);
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200925
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
984static 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
Ville Syrjäläe408d562019-03-27 20:52:52 +0200995 intel_register_access_init(intel_get_pci_device(), 0, -1);
Ville Syrjälä4d2577e2014-12-10 21:17:36 +0200996
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
1074static 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
Ville Syrjäläe408d562019-03-27 20:52:52 +02001085 intel_register_access_init(intel_get_pci_device(), 0, -1);
Ville Syrjälä4d2577e2014-12-10 21:17:36 +02001086
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
1143static 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
Ville Syrjäläe408d562019-03-27 20:52:52 +02001154 intel_register_access_init(intel_get_pci_device(), 0, -1);
Ville Syrjälä4d2577e2014-12-10 21:17:36 +02001155
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
1227int main(int argc, char *argv[])
1228{
Ville Syrjäläe408d562019-03-27 20:52:52 +02001229 devid = intel_get_pci_device()->device_id;
Ville Syrjälä4d2577e2014-12-10 21:17:36 +02001230
Ville Syrjäläff8d1152018-10-24 19:24:55 +03001231 if (intel_gen(devid) >= 9) {
Dhinakaran Pandiyan6d9f4842016-10-18 17:05:19 -07001232 skl_wm_dump();
1233 } else if (IS_VALLEYVIEW(devid) || IS_CHERRYVIEW(devid)) {
Ville Syrjälä4d2577e2014-12-10 21:17:36 +02001234 display_base = 0x180000;
1235 vlv_wm_dump();
Ville Syrjäläff8d1152018-10-24 19:24:55 +03001236 } else if (intel_gen(devid) >= 5) {
Chris Wilson8b0dd382016-07-25 12:47:19 +01001237 ilk_wm_dump();
Ville Syrjälä4d2577e2014-12-10 21:17:36 +02001238 } else if (IS_G4X(devid)) {
1239 g4x_wm_dump();
1240 } else if (IS_GEN4(devid)) {
1241 gen4_wm_dump();
Chris Wilson37eec6d2016-06-29 11:06:09 +01001242 } else if (IS_PINEVIEW(devid)) {
Ville Syrjälä4d2577e2014-12-10 21:17:36 +02001243 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
Ville Syrjälä4d2577e2014-12-10 21:17:36 +02001253 return 0;
1254}