194b49d53SJani Nikula // SPDX-License-Identifier: MIT
294b49d53SJani Nikula /*
394b49d53SJani Nikula * Copyright © 2023 Intel Corporation
494b49d53SJani Nikula */
594b49d53SJani Nikula
694b49d53SJani Nikula #include "i915_drv.h"
794b49d53SJani Nikula #include "i9xx_wm.h"
894b49d53SJani Nikula #include "intel_display_types.h"
994b49d53SJani Nikula #include "intel_wm.h"
1094b49d53SJani Nikula #include "skl_watermark.h"
1194b49d53SJani Nikula
12284c5baaSJani Nikula /**
13284c5baaSJani Nikula * intel_update_watermarks - update FIFO watermark values based on current modes
1475a252beSLee Jones * @i915: i915 device
15284c5baaSJani Nikula *
16284c5baaSJani Nikula * Calculate watermark values for the various WM regs based on current mode
17284c5baaSJani Nikula * and plane configuration.
18284c5baaSJani Nikula *
19284c5baaSJani Nikula * There are several cases to deal with here:
20284c5baaSJani Nikula * - normal (i.e. non-self-refresh)
21284c5baaSJani Nikula * - self-refresh (SR) mode
22284c5baaSJani Nikula * - lines are large relative to FIFO size (buffer can hold up to 2)
23284c5baaSJani Nikula * - lines are small relative to FIFO size (buffer can hold more than 2
24284c5baaSJani Nikula * lines), so need to account for TLB latency
25284c5baaSJani Nikula *
26284c5baaSJani Nikula * The normal calculation is:
27284c5baaSJani Nikula * watermark = dotclock * bytes per pixel * latency
28284c5baaSJani Nikula * where latency is platform & configuration dependent (we assume pessimal
29284c5baaSJani Nikula * values here).
30284c5baaSJani Nikula *
31284c5baaSJani Nikula * The SR calculation is:
32284c5baaSJani Nikula * watermark = (trunc(latency/line time)+1) * surface width *
33284c5baaSJani Nikula * bytes per pixel
34284c5baaSJani Nikula * where
35284c5baaSJani Nikula * line time = htotal / dotclock
36284c5baaSJani Nikula * surface width = hdisplay for normal plane and 64 for cursor
37284c5baaSJani Nikula * and latency is assumed to be high, as above.
38284c5baaSJani Nikula *
39284c5baaSJani Nikula * The final value programmed to the register should always be rounded up,
40284c5baaSJani Nikula * and include an extra 2 entries to account for clock crossings.
41284c5baaSJani Nikula *
42284c5baaSJani Nikula * We don't use the sprite, so we can ignore that. And on Crestline we have
43284c5baaSJani Nikula * to set the non-SR watermarks to 8.
44284c5baaSJani Nikula */
intel_update_watermarks(struct drm_i915_private * i915)45284c5baaSJani Nikula void intel_update_watermarks(struct drm_i915_private *i915)
46284c5baaSJani Nikula {
47284c5baaSJani Nikula if (i915->display.funcs.wm->update_wm)
48284c5baaSJani Nikula i915->display.funcs.wm->update_wm(i915);
49284c5baaSJani Nikula }
50284c5baaSJani Nikula
intel_compute_pipe_wm(struct intel_atomic_state * state,struct intel_crtc * crtc)51284c5baaSJani Nikula int intel_compute_pipe_wm(struct intel_atomic_state *state,
52284c5baaSJani Nikula struct intel_crtc *crtc)
53284c5baaSJani Nikula {
54284c5baaSJani Nikula struct drm_i915_private *i915 = to_i915(state->base.dev);
55284c5baaSJani Nikula
56284c5baaSJani Nikula if (i915->display.funcs.wm->compute_pipe_wm)
57284c5baaSJani Nikula return i915->display.funcs.wm->compute_pipe_wm(state, crtc);
58284c5baaSJani Nikula
59284c5baaSJani Nikula return 0;
60284c5baaSJani Nikula }
61284c5baaSJani Nikula
intel_compute_intermediate_wm(struct intel_atomic_state * state,struct intel_crtc * crtc)62284c5baaSJani Nikula int intel_compute_intermediate_wm(struct intel_atomic_state *state,
63284c5baaSJani Nikula struct intel_crtc *crtc)
64284c5baaSJani Nikula {
65284c5baaSJani Nikula struct drm_i915_private *i915 = to_i915(state->base.dev);
66284c5baaSJani Nikula
67284c5baaSJani Nikula if (!i915->display.funcs.wm->compute_intermediate_wm)
68284c5baaSJani Nikula return 0;
69284c5baaSJani Nikula
70284c5baaSJani Nikula if (drm_WARN_ON(&i915->drm, !i915->display.funcs.wm->compute_pipe_wm))
71284c5baaSJani Nikula return 0;
72284c5baaSJani Nikula
73284c5baaSJani Nikula return i915->display.funcs.wm->compute_intermediate_wm(state, crtc);
74284c5baaSJani Nikula }
75284c5baaSJani Nikula
intel_initial_watermarks(struct intel_atomic_state * state,struct intel_crtc * crtc)76284c5baaSJani Nikula bool intel_initial_watermarks(struct intel_atomic_state *state,
77284c5baaSJani Nikula struct intel_crtc *crtc)
78284c5baaSJani Nikula {
79284c5baaSJani Nikula struct drm_i915_private *i915 = to_i915(state->base.dev);
80284c5baaSJani Nikula
81284c5baaSJani Nikula if (i915->display.funcs.wm->initial_watermarks) {
82284c5baaSJani Nikula i915->display.funcs.wm->initial_watermarks(state, crtc);
83284c5baaSJani Nikula return true;
84284c5baaSJani Nikula }
85284c5baaSJani Nikula
86284c5baaSJani Nikula return false;
87284c5baaSJani Nikula }
88284c5baaSJani Nikula
intel_atomic_update_watermarks(struct intel_atomic_state * state,struct intel_crtc * crtc)89284c5baaSJani Nikula void intel_atomic_update_watermarks(struct intel_atomic_state *state,
90284c5baaSJani Nikula struct intel_crtc *crtc)
91284c5baaSJani Nikula {
92284c5baaSJani Nikula struct drm_i915_private *i915 = to_i915(state->base.dev);
93284c5baaSJani Nikula
94284c5baaSJani Nikula if (i915->display.funcs.wm->atomic_update_watermarks)
95284c5baaSJani Nikula i915->display.funcs.wm->atomic_update_watermarks(state, crtc);
96284c5baaSJani Nikula }
97284c5baaSJani Nikula
intel_optimize_watermarks(struct intel_atomic_state * state,struct intel_crtc * crtc)98284c5baaSJani Nikula void intel_optimize_watermarks(struct intel_atomic_state *state,
99284c5baaSJani Nikula struct intel_crtc *crtc)
100284c5baaSJani Nikula {
101284c5baaSJani Nikula struct drm_i915_private *i915 = to_i915(state->base.dev);
102284c5baaSJani Nikula
103284c5baaSJani Nikula if (i915->display.funcs.wm->optimize_watermarks)
104284c5baaSJani Nikula i915->display.funcs.wm->optimize_watermarks(state, crtc);
105284c5baaSJani Nikula }
106284c5baaSJani Nikula
intel_compute_global_watermarks(struct intel_atomic_state * state)107284c5baaSJani Nikula int intel_compute_global_watermarks(struct intel_atomic_state *state)
108284c5baaSJani Nikula {
109284c5baaSJani Nikula struct drm_i915_private *i915 = to_i915(state->base.dev);
110284c5baaSJani Nikula
111284c5baaSJani Nikula if (i915->display.funcs.wm->compute_global_watermarks)
112284c5baaSJani Nikula return i915->display.funcs.wm->compute_global_watermarks(state);
113284c5baaSJani Nikula
114284c5baaSJani Nikula return 0;
115284c5baaSJani Nikula }
116284c5baaSJani Nikula
intel_wm_get_hw_state(struct drm_i915_private * i915)1170e7a16f9SJani Nikula void intel_wm_get_hw_state(struct drm_i915_private *i915)
1180e7a16f9SJani Nikula {
1190e7a16f9SJani Nikula if (i915->display.funcs.wm->get_hw_state)
1200e7a16f9SJani Nikula return i915->display.funcs.wm->get_hw_state(i915);
1210e7a16f9SJani Nikula }
1220e7a16f9SJani Nikula
intel_wm_plane_visible(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)12394b49d53SJani Nikula bool intel_wm_plane_visible(const struct intel_crtc_state *crtc_state,
12494b49d53SJani Nikula const struct intel_plane_state *plane_state)
12594b49d53SJani Nikula {
12694b49d53SJani Nikula struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
12794b49d53SJani Nikula
12894b49d53SJani Nikula /* FIXME check the 'enable' instead */
12994b49d53SJani Nikula if (!crtc_state->hw.active)
13094b49d53SJani Nikula return false;
13194b49d53SJani Nikula
13294b49d53SJani Nikula /*
13394b49d53SJani Nikula * Treat cursor with fb as always visible since cursor updates
13494b49d53SJani Nikula * can happen faster than the vrefresh rate, and the current
13594b49d53SJani Nikula * watermark code doesn't handle that correctly. Cursor updates
13694b49d53SJani Nikula * which set/clear the fb or change the cursor size are going
13794b49d53SJani Nikula * to get throttled by intel_legacy_cursor_update() to work
13894b49d53SJani Nikula * around this problem with the watermark code.
13994b49d53SJani Nikula */
14094b49d53SJani Nikula if (plane->id == PLANE_CURSOR)
14194b49d53SJani Nikula return plane_state->hw.fb != NULL;
14294b49d53SJani Nikula else
14394b49d53SJani Nikula return plane_state->uapi.visible;
14494b49d53SJani Nikula }
14594b49d53SJani Nikula
intel_print_wm_latency(struct drm_i915_private * dev_priv,const char * name,const u16 wm[])14694b49d53SJani Nikula void intel_print_wm_latency(struct drm_i915_private *dev_priv,
14794b49d53SJani Nikula const char *name, const u16 wm[])
14894b49d53SJani Nikula {
14994b49d53SJani Nikula int level;
15094b49d53SJani Nikula
15194b49d53SJani Nikula for (level = 0; level < dev_priv->display.wm.num_levels; level++) {
15294b49d53SJani Nikula unsigned int latency = wm[level];
15394b49d53SJani Nikula
15494b49d53SJani Nikula if (latency == 0) {
15594b49d53SJani Nikula drm_dbg_kms(&dev_priv->drm,
15694b49d53SJani Nikula "%s WM%d latency not provided\n",
15794b49d53SJani Nikula name, level);
15894b49d53SJani Nikula continue;
15994b49d53SJani Nikula }
16094b49d53SJani Nikula
16194b49d53SJani Nikula /*
16294b49d53SJani Nikula * - latencies are in us on gen9.
16394b49d53SJani Nikula * - before then, WM1+ latency values are in 0.5us units
16494b49d53SJani Nikula */
16594b49d53SJani Nikula if (DISPLAY_VER(dev_priv) >= 9)
16694b49d53SJani Nikula latency *= 10;
16794b49d53SJani Nikula else if (level > 0)
16894b49d53SJani Nikula latency *= 5;
16994b49d53SJani Nikula
17094b49d53SJani Nikula drm_dbg_kms(&dev_priv->drm,
17194b49d53SJani Nikula "%s WM%d latency %u (%u.%u usec)\n", name, level,
17294b49d53SJani Nikula wm[level], latency / 10, latency % 10);
17394b49d53SJani Nikula }
17494b49d53SJani Nikula }
17594b49d53SJani Nikula
intel_wm_init(struct drm_i915_private * i915)17694b49d53SJani Nikula void intel_wm_init(struct drm_i915_private *i915)
17794b49d53SJani Nikula {
17894b49d53SJani Nikula if (DISPLAY_VER(i915) >= 9)
17994b49d53SJani Nikula skl_wm_init(i915);
18094b49d53SJani Nikula else
18194b49d53SJani Nikula i9xx_wm_init(i915);
18294b49d53SJani Nikula }
183f22c982eSJani Nikula
wm_latency_show(struct seq_file * m,const u16 wm[8])184f22c982eSJani Nikula static void wm_latency_show(struct seq_file *m, const u16 wm[8])
185f22c982eSJani Nikula {
186f22c982eSJani Nikula struct drm_i915_private *dev_priv = m->private;
187f22c982eSJani Nikula int level;
188f22c982eSJani Nikula
189f22c982eSJani Nikula drm_modeset_lock_all(&dev_priv->drm);
190f22c982eSJani Nikula
191f22c982eSJani Nikula for (level = 0; level < dev_priv->display.wm.num_levels; level++) {
192f22c982eSJani Nikula unsigned int latency = wm[level];
193f22c982eSJani Nikula
194f22c982eSJani Nikula /*
195f22c982eSJani Nikula * - WM1+ latency values in 0.5us units
196f22c982eSJani Nikula * - latencies are in us on gen9/vlv/chv
197f22c982eSJani Nikula */
198f22c982eSJani Nikula if (DISPLAY_VER(dev_priv) >= 9 ||
199f22c982eSJani Nikula IS_VALLEYVIEW(dev_priv) ||
200f22c982eSJani Nikula IS_CHERRYVIEW(dev_priv) ||
201f22c982eSJani Nikula IS_G4X(dev_priv))
202f22c982eSJani Nikula latency *= 10;
203f22c982eSJani Nikula else if (level > 0)
204f22c982eSJani Nikula latency *= 5;
205f22c982eSJani Nikula
206f22c982eSJani Nikula seq_printf(m, "WM%d %u (%u.%u usec)\n",
207f22c982eSJani Nikula level, wm[level], latency / 10, latency % 10);
208f22c982eSJani Nikula }
209f22c982eSJani Nikula
210f22c982eSJani Nikula drm_modeset_unlock_all(&dev_priv->drm);
211f22c982eSJani Nikula }
212f22c982eSJani Nikula
pri_wm_latency_show(struct seq_file * m,void * data)213f22c982eSJani Nikula static int pri_wm_latency_show(struct seq_file *m, void *data)
214f22c982eSJani Nikula {
215f22c982eSJani Nikula struct drm_i915_private *dev_priv = m->private;
216f22c982eSJani Nikula const u16 *latencies;
217f22c982eSJani Nikula
218f22c982eSJani Nikula if (DISPLAY_VER(dev_priv) >= 9)
219f22c982eSJani Nikula latencies = dev_priv->display.wm.skl_latency;
220f22c982eSJani Nikula else
221f22c982eSJani Nikula latencies = dev_priv->display.wm.pri_latency;
222f22c982eSJani Nikula
223f22c982eSJani Nikula wm_latency_show(m, latencies);
224f22c982eSJani Nikula
225f22c982eSJani Nikula return 0;
226f22c982eSJani Nikula }
227f22c982eSJani Nikula
spr_wm_latency_show(struct seq_file * m,void * data)228f22c982eSJani Nikula static int spr_wm_latency_show(struct seq_file *m, void *data)
229f22c982eSJani Nikula {
230f22c982eSJani Nikula struct drm_i915_private *dev_priv = m->private;
231f22c982eSJani Nikula const u16 *latencies;
232f22c982eSJani Nikula
233f22c982eSJani Nikula if (DISPLAY_VER(dev_priv) >= 9)
234f22c982eSJani Nikula latencies = dev_priv->display.wm.skl_latency;
235f22c982eSJani Nikula else
236f22c982eSJani Nikula latencies = dev_priv->display.wm.spr_latency;
237f22c982eSJani Nikula
238f22c982eSJani Nikula wm_latency_show(m, latencies);
239f22c982eSJani Nikula
240f22c982eSJani Nikula return 0;
241f22c982eSJani Nikula }
242f22c982eSJani Nikula
cur_wm_latency_show(struct seq_file * m,void * data)243f22c982eSJani Nikula static int cur_wm_latency_show(struct seq_file *m, void *data)
244f22c982eSJani Nikula {
245f22c982eSJani Nikula struct drm_i915_private *dev_priv = m->private;
246f22c982eSJani Nikula const u16 *latencies;
247f22c982eSJani Nikula
248f22c982eSJani Nikula if (DISPLAY_VER(dev_priv) >= 9)
249f22c982eSJani Nikula latencies = dev_priv->display.wm.skl_latency;
250f22c982eSJani Nikula else
251f22c982eSJani Nikula latencies = dev_priv->display.wm.cur_latency;
252f22c982eSJani Nikula
253f22c982eSJani Nikula wm_latency_show(m, latencies);
254f22c982eSJani Nikula
255f22c982eSJani Nikula return 0;
256f22c982eSJani Nikula }
257f22c982eSJani Nikula
pri_wm_latency_open(struct inode * inode,struct file * file)258f22c982eSJani Nikula static int pri_wm_latency_open(struct inode *inode, struct file *file)
259f22c982eSJani Nikula {
260f22c982eSJani Nikula struct drm_i915_private *dev_priv = inode->i_private;
261f22c982eSJani Nikula
262f22c982eSJani Nikula if (DISPLAY_VER(dev_priv) < 5 && !IS_G4X(dev_priv))
263f22c982eSJani Nikula return -ENODEV;
264f22c982eSJani Nikula
265f22c982eSJani Nikula return single_open(file, pri_wm_latency_show, dev_priv);
266f22c982eSJani Nikula }
267f22c982eSJani Nikula
spr_wm_latency_open(struct inode * inode,struct file * file)268f22c982eSJani Nikula static int spr_wm_latency_open(struct inode *inode, struct file *file)
269f22c982eSJani Nikula {
270f22c982eSJani Nikula struct drm_i915_private *dev_priv = inode->i_private;
271f22c982eSJani Nikula
272f22c982eSJani Nikula if (HAS_GMCH(dev_priv))
273f22c982eSJani Nikula return -ENODEV;
274f22c982eSJani Nikula
275f22c982eSJani Nikula return single_open(file, spr_wm_latency_show, dev_priv);
276f22c982eSJani Nikula }
277f22c982eSJani Nikula
cur_wm_latency_open(struct inode * inode,struct file * file)278f22c982eSJani Nikula static int cur_wm_latency_open(struct inode *inode, struct file *file)
279f22c982eSJani Nikula {
280f22c982eSJani Nikula struct drm_i915_private *dev_priv = inode->i_private;
281f22c982eSJani Nikula
282f22c982eSJani Nikula if (HAS_GMCH(dev_priv))
283f22c982eSJani Nikula return -ENODEV;
284f22c982eSJani Nikula
285f22c982eSJani Nikula return single_open(file, cur_wm_latency_show, dev_priv);
286f22c982eSJani Nikula }
287f22c982eSJani Nikula
wm_latency_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp,u16 wm[8])288f22c982eSJani Nikula static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
289f22c982eSJani Nikula size_t len, loff_t *offp, u16 wm[8])
290f22c982eSJani Nikula {
291f22c982eSJani Nikula struct seq_file *m = file->private_data;
292f22c982eSJani Nikula struct drm_i915_private *dev_priv = m->private;
293*eebc1525SVille Syrjälä u16 new[8] = {};
294f22c982eSJani Nikula int level;
295f22c982eSJani Nikula int ret;
296f22c982eSJani Nikula char tmp[32];
297f22c982eSJani Nikula
298f22c982eSJani Nikula if (len >= sizeof(tmp))
299f22c982eSJani Nikula return -EINVAL;
300f22c982eSJani Nikula
301f22c982eSJani Nikula if (copy_from_user(tmp, ubuf, len))
302f22c982eSJani Nikula return -EFAULT;
303f22c982eSJani Nikula
304f22c982eSJani Nikula tmp[len] = '\0';
305f22c982eSJani Nikula
306f22c982eSJani Nikula ret = sscanf(tmp, "%hu %hu %hu %hu %hu %hu %hu %hu",
307f22c982eSJani Nikula &new[0], &new[1], &new[2], &new[3],
308f22c982eSJani Nikula &new[4], &new[5], &new[6], &new[7]);
309f22c982eSJani Nikula if (ret != dev_priv->display.wm.num_levels)
310f22c982eSJani Nikula return -EINVAL;
311f22c982eSJani Nikula
312f22c982eSJani Nikula drm_modeset_lock_all(&dev_priv->drm);
313f22c982eSJani Nikula
314f22c982eSJani Nikula for (level = 0; level < dev_priv->display.wm.num_levels; level++)
315f22c982eSJani Nikula wm[level] = new[level];
316f22c982eSJani Nikula
317f22c982eSJani Nikula drm_modeset_unlock_all(&dev_priv->drm);
318f22c982eSJani Nikula
319f22c982eSJani Nikula return len;
320f22c982eSJani Nikula }
321f22c982eSJani Nikula
pri_wm_latency_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)322f22c982eSJani Nikula static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf,
323f22c982eSJani Nikula size_t len, loff_t *offp)
324f22c982eSJani Nikula {
325f22c982eSJani Nikula struct seq_file *m = file->private_data;
326f22c982eSJani Nikula struct drm_i915_private *dev_priv = m->private;
327f22c982eSJani Nikula u16 *latencies;
328f22c982eSJani Nikula
329f22c982eSJani Nikula if (DISPLAY_VER(dev_priv) >= 9)
330f22c982eSJani Nikula latencies = dev_priv->display.wm.skl_latency;
331f22c982eSJani Nikula else
332f22c982eSJani Nikula latencies = dev_priv->display.wm.pri_latency;
333f22c982eSJani Nikula
334f22c982eSJani Nikula return wm_latency_write(file, ubuf, len, offp, latencies);
335f22c982eSJani Nikula }
336f22c982eSJani Nikula
spr_wm_latency_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)337f22c982eSJani Nikula static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
338f22c982eSJani Nikula size_t len, loff_t *offp)
339f22c982eSJani Nikula {
340f22c982eSJani Nikula struct seq_file *m = file->private_data;
341f22c982eSJani Nikula struct drm_i915_private *dev_priv = m->private;
342f22c982eSJani Nikula u16 *latencies;
343f22c982eSJani Nikula
344f22c982eSJani Nikula if (DISPLAY_VER(dev_priv) >= 9)
345f22c982eSJani Nikula latencies = dev_priv->display.wm.skl_latency;
346f22c982eSJani Nikula else
347f22c982eSJani Nikula latencies = dev_priv->display.wm.spr_latency;
348f22c982eSJani Nikula
349f22c982eSJani Nikula return wm_latency_write(file, ubuf, len, offp, latencies);
350f22c982eSJani Nikula }
351f22c982eSJani Nikula
cur_wm_latency_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)352f22c982eSJani Nikula static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
353f22c982eSJani Nikula size_t len, loff_t *offp)
354f22c982eSJani Nikula {
355f22c982eSJani Nikula struct seq_file *m = file->private_data;
356f22c982eSJani Nikula struct drm_i915_private *dev_priv = m->private;
357f22c982eSJani Nikula u16 *latencies;
358f22c982eSJani Nikula
359f22c982eSJani Nikula if (DISPLAY_VER(dev_priv) >= 9)
360f22c982eSJani Nikula latencies = dev_priv->display.wm.skl_latency;
361f22c982eSJani Nikula else
362f22c982eSJani Nikula latencies = dev_priv->display.wm.cur_latency;
363f22c982eSJani Nikula
364f22c982eSJani Nikula return wm_latency_write(file, ubuf, len, offp, latencies);
365f22c982eSJani Nikula }
366f22c982eSJani Nikula
367f22c982eSJani Nikula static const struct file_operations i915_pri_wm_latency_fops = {
368f22c982eSJani Nikula .owner = THIS_MODULE,
369f22c982eSJani Nikula .open = pri_wm_latency_open,
370f22c982eSJani Nikula .read = seq_read,
371f22c982eSJani Nikula .llseek = seq_lseek,
372f22c982eSJani Nikula .release = single_release,
373f22c982eSJani Nikula .write = pri_wm_latency_write
374f22c982eSJani Nikula };
375f22c982eSJani Nikula
376f22c982eSJani Nikula static const struct file_operations i915_spr_wm_latency_fops = {
377f22c982eSJani Nikula .owner = THIS_MODULE,
378f22c982eSJani Nikula .open = spr_wm_latency_open,
379f22c982eSJani Nikula .read = seq_read,
380f22c982eSJani Nikula .llseek = seq_lseek,
381f22c982eSJani Nikula .release = single_release,
382f22c982eSJani Nikula .write = spr_wm_latency_write
383f22c982eSJani Nikula };
384f22c982eSJani Nikula
385f22c982eSJani Nikula static const struct file_operations i915_cur_wm_latency_fops = {
386f22c982eSJani Nikula .owner = THIS_MODULE,
387f22c982eSJani Nikula .open = cur_wm_latency_open,
388f22c982eSJani Nikula .read = seq_read,
389f22c982eSJani Nikula .llseek = seq_lseek,
390f22c982eSJani Nikula .release = single_release,
391f22c982eSJani Nikula .write = cur_wm_latency_write
392f22c982eSJani Nikula };
393f22c982eSJani Nikula
intel_wm_debugfs_register(struct drm_i915_private * i915)394f22c982eSJani Nikula void intel_wm_debugfs_register(struct drm_i915_private *i915)
395f22c982eSJani Nikula {
396f22c982eSJani Nikula struct drm_minor *minor = i915->drm.primary;
397f22c982eSJani Nikula
398f22c982eSJani Nikula debugfs_create_file("i915_pri_wm_latency", 0644, minor->debugfs_root,
399f22c982eSJani Nikula i915, &i915_pri_wm_latency_fops);
400f22c982eSJani Nikula
401f22c982eSJani Nikula debugfs_create_file("i915_spr_wm_latency", 0644, minor->debugfs_root,
402f22c982eSJani Nikula i915, &i915_spr_wm_latency_fops);
403f22c982eSJani Nikula
404f22c982eSJani Nikula debugfs_create_file("i915_cur_wm_latency", 0644, minor->debugfs_root,
405f22c982eSJani Nikula i915, &i915_cur_wm_latency_fops);
406f22c982eSJani Nikula
407f22c982eSJani Nikula skl_watermark_debugfs_register(i915);
408f22c982eSJani Nikula }
409