xref: /openbsd-src/sys/dev/pci/drm/i915/display/intel_display_debugfs.c (revision f005ef32267c16bdb134f0e9fa4477dbe07c263a)
1c349dbc7Sjsg // SPDX-License-Identifier: MIT
2c349dbc7Sjsg /*
3c349dbc7Sjsg  * Copyright © 2020 Intel Corporation
4c349dbc7Sjsg  */
5c349dbc7Sjsg 
61bb76ff1Sjsg #include <linux/string_helpers.h>
71bb76ff1Sjsg 
8c349dbc7Sjsg #include <drm/drm_debugfs.h>
9*f005ef32Sjsg #include <drm/drm_edid.h>
10c349dbc7Sjsg #include <drm/drm_fourcc.h>
11c349dbc7Sjsg 
12*f005ef32Sjsg #include "hsw_ips.h"
13c349dbc7Sjsg #include "i915_debugfs.h"
14*f005ef32Sjsg #include "i915_irq.h"
15*f005ef32Sjsg #include "i915_reg.h"
16*f005ef32Sjsg #include "intel_crtc.h"
171bb76ff1Sjsg #include "intel_de.h"
18*f005ef32Sjsg #include "intel_crtc_state_dump.h"
19c349dbc7Sjsg #include "intel_display_debugfs.h"
20ad8b1aafSjsg #include "intel_display_power.h"
211bb76ff1Sjsg #include "intel_display_power_well.h"
22c349dbc7Sjsg #include "intel_display_types.h"
235ca02815Sjsg #include "intel_dmc.h"
24c349dbc7Sjsg #include "intel_dp.h"
251bb76ff1Sjsg #include "intel_dp_mst.h"
26469cac2cSjsg #include "intel_drrs.h"
27c349dbc7Sjsg #include "intel_fbc.h"
281bb76ff1Sjsg #include "intel_fbdev.h"
29c349dbc7Sjsg #include "intel_hdcp.h"
30c349dbc7Sjsg #include "intel_hdmi.h"
31*f005ef32Sjsg #include "intel_hotplug.h"
321bb76ff1Sjsg #include "intel_panel.h"
33c349dbc7Sjsg #include "intel_psr.h"
34*f005ef32Sjsg #include "intel_psr_regs.h"
35*f005ef32Sjsg #include "intel_wm.h"
36c349dbc7Sjsg 
node_to_i915(struct drm_info_node * node)37c349dbc7Sjsg static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node)
38c349dbc7Sjsg {
39c349dbc7Sjsg 	return to_i915(node->minor->dev);
40c349dbc7Sjsg }
41c349dbc7Sjsg 
i915_frontbuffer_tracking(struct seq_file * m,void * unused)42c349dbc7Sjsg static int i915_frontbuffer_tracking(struct seq_file *m, void *unused)
43c349dbc7Sjsg {
44c349dbc7Sjsg 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
45c349dbc7Sjsg 
46c349dbc7Sjsg 	seq_printf(m, "FB tracking busy bits: 0x%08x\n",
471bb76ff1Sjsg 		   dev_priv->display.fb_tracking.busy_bits);
48c349dbc7Sjsg 
49c349dbc7Sjsg 	seq_printf(m, "FB tracking flip bits: 0x%08x\n",
501bb76ff1Sjsg 		   dev_priv->display.fb_tracking.flip_bits);
51c349dbc7Sjsg 
52c349dbc7Sjsg 	return 0;
53c349dbc7Sjsg }
54c349dbc7Sjsg 
i915_sr_status(struct seq_file * m,void * unused)55c349dbc7Sjsg static int i915_sr_status(struct seq_file *m, void *unused)
56c349dbc7Sjsg {
57c349dbc7Sjsg 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
58c349dbc7Sjsg 	intel_wakeref_t wakeref;
59c349dbc7Sjsg 	bool sr_enabled = false;
60c349dbc7Sjsg 
61c349dbc7Sjsg 	wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
62c349dbc7Sjsg 
635ca02815Sjsg 	if (DISPLAY_VER(dev_priv) >= 9)
64c349dbc7Sjsg 		/* no global SR status; inspect per-plane WM */;
65c349dbc7Sjsg 	else if (HAS_PCH_SPLIT(dev_priv))
661bb76ff1Sjsg 		sr_enabled = intel_de_read(dev_priv, WM1_LP_ILK) & WM_LP_ENABLE;
67c349dbc7Sjsg 	else if (IS_I965GM(dev_priv) || IS_G4X(dev_priv) ||
68c349dbc7Sjsg 		 IS_I945G(dev_priv) || IS_I945GM(dev_priv))
69c349dbc7Sjsg 		sr_enabled = intel_de_read(dev_priv, FW_BLC_SELF) & FW_BLC_SELF_EN;
70c349dbc7Sjsg 	else if (IS_I915GM(dev_priv))
71c349dbc7Sjsg 		sr_enabled = intel_de_read(dev_priv, INSTPM) & INSTPM_SELF_EN;
72c349dbc7Sjsg 	else if (IS_PINEVIEW(dev_priv))
73c349dbc7Sjsg 		sr_enabled = intel_de_read(dev_priv, DSPFW3) & PINEVIEW_SELF_REFRESH_EN;
74c349dbc7Sjsg 	else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
75c349dbc7Sjsg 		sr_enabled = intel_de_read(dev_priv, FW_BLC_SELF_VLV) & FW_CSPWRDWNEN;
76c349dbc7Sjsg 
77c349dbc7Sjsg 	intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref);
78c349dbc7Sjsg 
791bb76ff1Sjsg 	seq_printf(m, "self-refresh: %s\n", str_enabled_disabled(sr_enabled));
80c349dbc7Sjsg 
81c349dbc7Sjsg 	return 0;
82c349dbc7Sjsg }
83c349dbc7Sjsg 
i915_opregion(struct seq_file * m,void * unused)84c349dbc7Sjsg static int i915_opregion(struct seq_file *m, void *unused)
85c349dbc7Sjsg {
861bb76ff1Sjsg 	struct drm_i915_private *i915 = node_to_i915(m->private);
871bb76ff1Sjsg 	struct intel_opregion *opregion = &i915->display.opregion;
88c349dbc7Sjsg 
89c349dbc7Sjsg 	if (opregion->header)
90c349dbc7Sjsg 		seq_write(m, opregion->header, OPREGION_SIZE);
91c349dbc7Sjsg 
92c349dbc7Sjsg 	return 0;
93c349dbc7Sjsg }
94c349dbc7Sjsg 
i915_vbt(struct seq_file * m,void * unused)95c349dbc7Sjsg static int i915_vbt(struct seq_file *m, void *unused)
96c349dbc7Sjsg {
971bb76ff1Sjsg 	struct drm_i915_private *i915 = node_to_i915(m->private);
981bb76ff1Sjsg 	struct intel_opregion *opregion = &i915->display.opregion;
99c349dbc7Sjsg 
100c349dbc7Sjsg 	if (opregion->vbt)
101c349dbc7Sjsg 		seq_write(m, opregion->vbt, opregion->vbt_size);
102c349dbc7Sjsg 
103c349dbc7Sjsg 	return 0;
104c349dbc7Sjsg }
105c349dbc7Sjsg 
i915_gem_framebuffer_info(struct seq_file * m,void * data)106c349dbc7Sjsg static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
107c349dbc7Sjsg {
108c349dbc7Sjsg 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
109c349dbc7Sjsg 	struct intel_framebuffer *fbdev_fb = NULL;
110c349dbc7Sjsg 	struct drm_framebuffer *drm_fb;
111c349dbc7Sjsg 
112c349dbc7Sjsg #ifdef CONFIG_DRM_FBDEV_EMULATION
1131bb76ff1Sjsg 	fbdev_fb = intel_fbdev_framebuffer(dev_priv->display.fbdev.fbdev);
1141bb76ff1Sjsg 	if (fbdev_fb) {
115c349dbc7Sjsg 		seq_printf(m, "fbcon size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ",
116c349dbc7Sjsg 			   fbdev_fb->base.width,
117c349dbc7Sjsg 			   fbdev_fb->base.height,
118c349dbc7Sjsg 			   fbdev_fb->base.format->depth,
119c349dbc7Sjsg 			   fbdev_fb->base.format->cpp[0] * 8,
120c349dbc7Sjsg 			   fbdev_fb->base.modifier,
121c349dbc7Sjsg 			   drm_framebuffer_read_refcount(&fbdev_fb->base));
122c349dbc7Sjsg 		i915_debugfs_describe_obj(m, intel_fb_obj(&fbdev_fb->base));
123c349dbc7Sjsg 		seq_putc(m, '\n');
124c349dbc7Sjsg 	}
125c349dbc7Sjsg #endif
126c349dbc7Sjsg 
127*f005ef32Sjsg 	mutex_lock(&dev_priv->drm.mode_config.fb_lock);
128*f005ef32Sjsg 	drm_for_each_fb(drm_fb, &dev_priv->drm) {
129c349dbc7Sjsg 		struct intel_framebuffer *fb = to_intel_framebuffer(drm_fb);
130c349dbc7Sjsg 		if (fb == fbdev_fb)
131c349dbc7Sjsg 			continue;
132c349dbc7Sjsg 
133c349dbc7Sjsg 		seq_printf(m, "user size: %d x %d, depth %d, %d bpp, modifier 0x%llx, refcount %d, obj ",
134c349dbc7Sjsg 			   fb->base.width,
135c349dbc7Sjsg 			   fb->base.height,
136c349dbc7Sjsg 			   fb->base.format->depth,
137c349dbc7Sjsg 			   fb->base.format->cpp[0] * 8,
138c349dbc7Sjsg 			   fb->base.modifier,
139c349dbc7Sjsg 			   drm_framebuffer_read_refcount(&fb->base));
140c349dbc7Sjsg 		i915_debugfs_describe_obj(m, intel_fb_obj(&fb->base));
141c349dbc7Sjsg 		seq_putc(m, '\n');
142c349dbc7Sjsg 	}
143*f005ef32Sjsg 	mutex_unlock(&dev_priv->drm.mode_config.fb_lock);
144c349dbc7Sjsg 
145c349dbc7Sjsg 	return 0;
146c349dbc7Sjsg }
147c349dbc7Sjsg 
i915_power_domain_info(struct seq_file * m,void * unused)148c349dbc7Sjsg static int i915_power_domain_info(struct seq_file *m, void *unused)
149c349dbc7Sjsg {
1501bb76ff1Sjsg 	struct drm_i915_private *i915 = node_to_i915(m->private);
151c349dbc7Sjsg 
1521bb76ff1Sjsg 	intel_display_power_debug(i915, m);
153c349dbc7Sjsg 
154c349dbc7Sjsg 	return 0;
155c349dbc7Sjsg }
156c349dbc7Sjsg 
intel_seq_print_mode(struct seq_file * m,int tabs,const struct drm_display_mode * mode)157c349dbc7Sjsg static void intel_seq_print_mode(struct seq_file *m, int tabs,
158c349dbc7Sjsg 				 const struct drm_display_mode *mode)
159c349dbc7Sjsg {
160c349dbc7Sjsg 	int i;
161c349dbc7Sjsg 
162c349dbc7Sjsg 	for (i = 0; i < tabs; i++)
163c349dbc7Sjsg 		seq_putc(m, '\t');
164c349dbc7Sjsg 
165c349dbc7Sjsg 	seq_printf(m, DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
166c349dbc7Sjsg }
167c349dbc7Sjsg 
intel_encoder_info(struct seq_file * m,struct intel_crtc * crtc,struct intel_encoder * encoder)168c349dbc7Sjsg static void intel_encoder_info(struct seq_file *m,
169c349dbc7Sjsg 			       struct intel_crtc *crtc,
170c349dbc7Sjsg 			       struct intel_encoder *encoder)
171c349dbc7Sjsg {
172c349dbc7Sjsg 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
173c349dbc7Sjsg 	struct drm_connector_list_iter conn_iter;
174c349dbc7Sjsg 	struct drm_connector *connector;
175c349dbc7Sjsg 
176c349dbc7Sjsg 	seq_printf(m, "\t[ENCODER:%d:%s]: connectors:\n",
177c349dbc7Sjsg 		   encoder->base.base.id, encoder->base.name);
178c349dbc7Sjsg 
179c349dbc7Sjsg 	drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
180c349dbc7Sjsg 	drm_for_each_connector_iter(connector, &conn_iter) {
181c349dbc7Sjsg 		const struct drm_connector_state *conn_state =
182c349dbc7Sjsg 			connector->state;
183c349dbc7Sjsg 
184c349dbc7Sjsg 		if (conn_state->best_encoder != &encoder->base)
185c349dbc7Sjsg 			continue;
186c349dbc7Sjsg 
187c349dbc7Sjsg 		seq_printf(m, "\t\t[CONNECTOR:%d:%s]\n",
188c349dbc7Sjsg 			   connector->base.id, connector->name);
189c349dbc7Sjsg 	}
190c349dbc7Sjsg 	drm_connector_list_iter_end(&conn_iter);
191c349dbc7Sjsg }
192c349dbc7Sjsg 
intel_panel_info(struct seq_file * m,struct intel_connector * connector)1931bb76ff1Sjsg static void intel_panel_info(struct seq_file *m,
1941bb76ff1Sjsg 			     struct intel_connector *connector)
195c349dbc7Sjsg {
1961bb76ff1Sjsg 	const struct drm_display_mode *fixed_mode;
197c349dbc7Sjsg 
1981bb76ff1Sjsg 	if (list_empty(&connector->panel.fixed_modes))
1991bb76ff1Sjsg 		return;
2001bb76ff1Sjsg 
2011bb76ff1Sjsg 	seq_puts(m, "\tfixed modes:\n");
2021bb76ff1Sjsg 
2031bb76ff1Sjsg 	list_for_each_entry(fixed_mode, &connector->panel.fixed_modes, head)
2041bb76ff1Sjsg 		intel_seq_print_mode(m, 2, fixed_mode);
205c349dbc7Sjsg }
206c349dbc7Sjsg 
intel_hdcp_info(struct seq_file * m,struct intel_connector * intel_connector)207c349dbc7Sjsg static void intel_hdcp_info(struct seq_file *m,
208c349dbc7Sjsg 			    struct intel_connector *intel_connector)
209c349dbc7Sjsg {
210c349dbc7Sjsg 	bool hdcp_cap, hdcp2_cap;
211c349dbc7Sjsg 
212ad8b1aafSjsg 	if (!intel_connector->hdcp.shim) {
213ad8b1aafSjsg 		seq_puts(m, "No Connector Support");
214ad8b1aafSjsg 		goto out;
215ad8b1aafSjsg 	}
216ad8b1aafSjsg 
217c349dbc7Sjsg 	hdcp_cap = intel_hdcp_capable(intel_connector);
218c349dbc7Sjsg 	hdcp2_cap = intel_hdcp2_capable(intel_connector);
219c349dbc7Sjsg 
220c349dbc7Sjsg 	if (hdcp_cap)
221c349dbc7Sjsg 		seq_puts(m, "HDCP1.4 ");
222c349dbc7Sjsg 	if (hdcp2_cap)
223c349dbc7Sjsg 		seq_puts(m, "HDCP2.2 ");
224c349dbc7Sjsg 
225c349dbc7Sjsg 	if (!hdcp_cap && !hdcp2_cap)
226c349dbc7Sjsg 		seq_puts(m, "None");
227c349dbc7Sjsg 
228ad8b1aafSjsg out:
229c349dbc7Sjsg 	seq_puts(m, "\n");
230c349dbc7Sjsg }
231c349dbc7Sjsg 
intel_dp_info(struct seq_file * m,struct intel_connector * connector)232*f005ef32Sjsg static void intel_dp_info(struct seq_file *m, struct intel_connector *connector)
233c349dbc7Sjsg {
234*f005ef32Sjsg 	struct intel_encoder *intel_encoder = intel_attached_encoder(connector);
235c349dbc7Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder);
236*f005ef32Sjsg 	const struct edid *edid = drm_edid_raw(connector->detect_edid);
237c349dbc7Sjsg 
238c349dbc7Sjsg 	seq_printf(m, "\tDPCD rev: %x\n", intel_dp->dpcd[DP_DPCD_REV]);
2391bb76ff1Sjsg 	seq_printf(m, "\taudio support: %s\n",
240*f005ef32Sjsg 		   str_yes_no(connector->base.display_info.has_audio));
241c349dbc7Sjsg 
242c349dbc7Sjsg 	drm_dp_downstream_debug(m, intel_dp->dpcd, intel_dp->downstream_ports,
243*f005ef32Sjsg 				edid, &intel_dp->aux);
244c349dbc7Sjsg }
245c349dbc7Sjsg 
intel_dp_mst_info(struct seq_file * m,struct intel_connector * connector)246c349dbc7Sjsg static void intel_dp_mst_info(struct seq_file *m,
247*f005ef32Sjsg 			      struct intel_connector *connector)
248c349dbc7Sjsg {
249*f005ef32Sjsg 	bool has_audio = connector->base.display_info.has_audio;
250c349dbc7Sjsg 
2511bb76ff1Sjsg 	seq_printf(m, "\taudio support: %s\n", str_yes_no(has_audio));
252c349dbc7Sjsg }
253c349dbc7Sjsg 
intel_hdmi_info(struct seq_file * m,struct intel_connector * connector)254c349dbc7Sjsg static void intel_hdmi_info(struct seq_file *m,
255*f005ef32Sjsg 			    struct intel_connector *connector)
256c349dbc7Sjsg {
257*f005ef32Sjsg 	bool has_audio = connector->base.display_info.has_audio;
258c349dbc7Sjsg 
259*f005ef32Sjsg 	seq_printf(m, "\taudio support: %s\n", str_yes_no(has_audio));
260c349dbc7Sjsg }
261c349dbc7Sjsg 
intel_connector_info(struct seq_file * m,struct drm_connector * connector)262c349dbc7Sjsg static void intel_connector_info(struct seq_file *m,
263c349dbc7Sjsg 				 struct drm_connector *connector)
264c349dbc7Sjsg {
265c349dbc7Sjsg 	struct intel_connector *intel_connector = to_intel_connector(connector);
266c349dbc7Sjsg 	const struct drm_connector_state *conn_state = connector->state;
267c349dbc7Sjsg 	struct intel_encoder *encoder =
268c349dbc7Sjsg 		to_intel_encoder(conn_state->best_encoder);
269c349dbc7Sjsg 	const struct drm_display_mode *mode;
270c349dbc7Sjsg 
271c349dbc7Sjsg 	seq_printf(m, "[CONNECTOR:%d:%s]: status: %s\n",
272c349dbc7Sjsg 		   connector->base.id, connector->name,
273c349dbc7Sjsg 		   drm_get_connector_status_name(connector->status));
274c349dbc7Sjsg 
275c349dbc7Sjsg 	if (connector->status == connector_status_disconnected)
276c349dbc7Sjsg 		return;
277c349dbc7Sjsg 
278c349dbc7Sjsg 	seq_printf(m, "\tphysical dimensions: %dx%dmm\n",
279c349dbc7Sjsg 		   connector->display_info.width_mm,
280c349dbc7Sjsg 		   connector->display_info.height_mm);
281c349dbc7Sjsg 	seq_printf(m, "\tsubpixel order: %s\n",
282c349dbc7Sjsg 		   drm_get_subpixel_order_name(connector->display_info.subpixel_order));
283c349dbc7Sjsg 	seq_printf(m, "\tCEA rev: %d\n", connector->display_info.cea_rev);
284c349dbc7Sjsg 
285c349dbc7Sjsg 	if (!encoder)
286c349dbc7Sjsg 		return;
287c349dbc7Sjsg 
288c349dbc7Sjsg 	switch (connector->connector_type) {
289c349dbc7Sjsg 	case DRM_MODE_CONNECTOR_DisplayPort:
290c349dbc7Sjsg 	case DRM_MODE_CONNECTOR_eDP:
291c349dbc7Sjsg 		if (encoder->type == INTEL_OUTPUT_DP_MST)
292c349dbc7Sjsg 			intel_dp_mst_info(m, intel_connector);
293c349dbc7Sjsg 		else
294c349dbc7Sjsg 			intel_dp_info(m, intel_connector);
295c349dbc7Sjsg 		break;
296c349dbc7Sjsg 	case DRM_MODE_CONNECTOR_HDMIA:
297c349dbc7Sjsg 		if (encoder->type == INTEL_OUTPUT_HDMI ||
298c349dbc7Sjsg 		    encoder->type == INTEL_OUTPUT_DDI)
299c349dbc7Sjsg 			intel_hdmi_info(m, intel_connector);
300c349dbc7Sjsg 		break;
301c349dbc7Sjsg 	default:
302c349dbc7Sjsg 		break;
303c349dbc7Sjsg 	}
304c349dbc7Sjsg 
305ad8b1aafSjsg 	seq_puts(m, "\tHDCP version: ");
306ad8b1aafSjsg 	intel_hdcp_info(m, intel_connector);
307ad8b1aafSjsg 
3081bb76ff1Sjsg 	seq_printf(m, "\tmax bpc: %u\n", connector->display_info.bpc);
3091bb76ff1Sjsg 
3101bb76ff1Sjsg 	intel_panel_info(m, intel_connector);
3111bb76ff1Sjsg 
312c349dbc7Sjsg 	seq_printf(m, "\tmodes:\n");
313c349dbc7Sjsg 	list_for_each_entry(mode, &connector->modes, head)
314c349dbc7Sjsg 		intel_seq_print_mode(m, 2, mode);
315c349dbc7Sjsg }
316c349dbc7Sjsg 
plane_type(enum drm_plane_type type)317c349dbc7Sjsg static const char *plane_type(enum drm_plane_type type)
318c349dbc7Sjsg {
319c349dbc7Sjsg 	switch (type) {
320c349dbc7Sjsg 	case DRM_PLANE_TYPE_OVERLAY:
321c349dbc7Sjsg 		return "OVL";
322c349dbc7Sjsg 	case DRM_PLANE_TYPE_PRIMARY:
323c349dbc7Sjsg 		return "PRI";
324c349dbc7Sjsg 	case DRM_PLANE_TYPE_CURSOR:
325c349dbc7Sjsg 		return "CUR";
326c349dbc7Sjsg 	/*
327c349dbc7Sjsg 	 * Deliberately omitting default: to generate compiler warnings
328c349dbc7Sjsg 	 * when a new drm_plane_type gets added.
329c349dbc7Sjsg 	 */
330c349dbc7Sjsg 	}
331c349dbc7Sjsg 
332c349dbc7Sjsg 	return "unknown";
333c349dbc7Sjsg }
334c349dbc7Sjsg 
plane_rotation(char * buf,size_t bufsize,unsigned int rotation)335c349dbc7Sjsg static void plane_rotation(char *buf, size_t bufsize, unsigned int rotation)
336c349dbc7Sjsg {
337c349dbc7Sjsg 	/*
338c349dbc7Sjsg 	 * According to doc only one DRM_MODE_ROTATE_ is allowed but this
339c349dbc7Sjsg 	 * will print them all to visualize if the values are misused
340c349dbc7Sjsg 	 */
341c349dbc7Sjsg 	snprintf(buf, bufsize,
342c349dbc7Sjsg 		 "%s%s%s%s%s%s(0x%08x)",
343c349dbc7Sjsg 		 (rotation & DRM_MODE_ROTATE_0) ? "0 " : "",
344c349dbc7Sjsg 		 (rotation & DRM_MODE_ROTATE_90) ? "90 " : "",
345c349dbc7Sjsg 		 (rotation & DRM_MODE_ROTATE_180) ? "180 " : "",
346c349dbc7Sjsg 		 (rotation & DRM_MODE_ROTATE_270) ? "270 " : "",
347c349dbc7Sjsg 		 (rotation & DRM_MODE_REFLECT_X) ? "FLIPX " : "",
348c349dbc7Sjsg 		 (rotation & DRM_MODE_REFLECT_Y) ? "FLIPY " : "",
349c349dbc7Sjsg 		 rotation);
350c349dbc7Sjsg }
351c349dbc7Sjsg 
plane_visibility(const struct intel_plane_state * plane_state)3525ca02815Sjsg static const char *plane_visibility(const struct intel_plane_state *plane_state)
3535ca02815Sjsg {
3545ca02815Sjsg 	if (plane_state->uapi.visible)
3555ca02815Sjsg 		return "visible";
3565ca02815Sjsg 
3575ca02815Sjsg 	if (plane_state->planar_slave)
3585ca02815Sjsg 		return "planar-slave";
3595ca02815Sjsg 
3605ca02815Sjsg 	return "hidden";
3615ca02815Sjsg }
3625ca02815Sjsg 
intel_plane_uapi_info(struct seq_file * m,struct intel_plane * plane)363c349dbc7Sjsg static void intel_plane_uapi_info(struct seq_file *m, struct intel_plane *plane)
364c349dbc7Sjsg {
365c349dbc7Sjsg 	const struct intel_plane_state *plane_state =
366c349dbc7Sjsg 		to_intel_plane_state(plane->base.state);
367c349dbc7Sjsg 	const struct drm_framebuffer *fb = plane_state->uapi.fb;
368c349dbc7Sjsg 	struct drm_rect src, dst;
369c349dbc7Sjsg 	char rot_str[48];
370c349dbc7Sjsg 
371c349dbc7Sjsg 	src = drm_plane_state_src(&plane_state->uapi);
372c349dbc7Sjsg 	dst = drm_plane_state_dest(&plane_state->uapi);
373c349dbc7Sjsg 
374c349dbc7Sjsg 	plane_rotation(rot_str, sizeof(rot_str),
375c349dbc7Sjsg 		       plane_state->uapi.rotation);
376c349dbc7Sjsg 
3775ca02815Sjsg 	seq_puts(m, "\t\tuapi: [FB:");
3785ca02815Sjsg 	if (fb)
3795ca02815Sjsg 		seq_printf(m, "%d] %p4cc,0x%llx,%dx%d", fb->base.id,
3805ca02815Sjsg 			   &fb->format->format, fb->modifier, fb->width,
3815ca02815Sjsg 			   fb->height);
3825ca02815Sjsg 	else
3835ca02815Sjsg 		seq_puts(m, "0] n/a,0x0,0x0,");
3845ca02815Sjsg 	seq_printf(m, ", visible=%s, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT
3855ca02815Sjsg 		   ", rotation=%s\n", plane_visibility(plane_state),
3865ca02815Sjsg 		   DRM_RECT_FP_ARG(&src), DRM_RECT_ARG(&dst), rot_str);
3875ca02815Sjsg 
3885ca02815Sjsg 	if (plane_state->planar_linked_plane)
3895ca02815Sjsg 		seq_printf(m, "\t\tplanar: Linked to [PLANE:%d:%s] as a %s\n",
3905ca02815Sjsg 			   plane_state->planar_linked_plane->base.base.id, plane_state->planar_linked_plane->base.name,
3915ca02815Sjsg 			   plane_state->planar_slave ? "slave" : "master");
392c349dbc7Sjsg }
393c349dbc7Sjsg 
intel_plane_hw_info(struct seq_file * m,struct intel_plane * plane)394c349dbc7Sjsg static void intel_plane_hw_info(struct seq_file *m, struct intel_plane *plane)
395c349dbc7Sjsg {
396c349dbc7Sjsg 	const struct intel_plane_state *plane_state =
397c349dbc7Sjsg 		to_intel_plane_state(plane->base.state);
398c349dbc7Sjsg 	const struct drm_framebuffer *fb = plane_state->hw.fb;
399c349dbc7Sjsg 	char rot_str[48];
400c349dbc7Sjsg 
401c349dbc7Sjsg 	if (!fb)
402c349dbc7Sjsg 		return;
403c349dbc7Sjsg 
404c349dbc7Sjsg 	plane_rotation(rot_str, sizeof(rot_str),
405c349dbc7Sjsg 		       plane_state->hw.rotation);
406c349dbc7Sjsg 
4075ca02815Sjsg 	seq_printf(m, "\t\thw: [FB:%d] %p4cc,0x%llx,%dx%d, visible=%s, src="
4085ca02815Sjsg 		   DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",
4095ca02815Sjsg 		   fb->base.id, &fb->format->format,
4105ca02815Sjsg 		   fb->modifier, fb->width, fb->height,
4111bb76ff1Sjsg 		   str_yes_no(plane_state->uapi.visible),
412c349dbc7Sjsg 		   DRM_RECT_FP_ARG(&plane_state->uapi.src),
413c349dbc7Sjsg 		   DRM_RECT_ARG(&plane_state->uapi.dst),
414c349dbc7Sjsg 		   rot_str);
415c349dbc7Sjsg }
416c349dbc7Sjsg 
intel_plane_info(struct seq_file * m,struct intel_crtc * crtc)417c349dbc7Sjsg static void intel_plane_info(struct seq_file *m, struct intel_crtc *crtc)
418c349dbc7Sjsg {
419c349dbc7Sjsg 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
420c349dbc7Sjsg 	struct intel_plane *plane;
421c349dbc7Sjsg 
422c349dbc7Sjsg 	for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
423c349dbc7Sjsg 		seq_printf(m, "\t[PLANE:%d:%s]: type=%s\n",
424c349dbc7Sjsg 			   plane->base.base.id, plane->base.name,
425c349dbc7Sjsg 			   plane_type(plane->base.type));
426c349dbc7Sjsg 		intel_plane_uapi_info(m, plane);
427c349dbc7Sjsg 		intel_plane_hw_info(m, plane);
428c349dbc7Sjsg 	}
429c349dbc7Sjsg }
430c349dbc7Sjsg 
intel_scaler_info(struct seq_file * m,struct intel_crtc * crtc)431c349dbc7Sjsg static void intel_scaler_info(struct seq_file *m, struct intel_crtc *crtc)
432c349dbc7Sjsg {
433c349dbc7Sjsg 	const struct intel_crtc_state *crtc_state =
434c349dbc7Sjsg 		to_intel_crtc_state(crtc->base.state);
435c349dbc7Sjsg 	int num_scalers = crtc->num_scalers;
436c349dbc7Sjsg 	int i;
437c349dbc7Sjsg 
438c349dbc7Sjsg 	/* Not all platformas have a scaler */
439c349dbc7Sjsg 	if (num_scalers) {
4401bb76ff1Sjsg 		seq_printf(m, "\tnum_scalers=%d, scaler_users=%x scaler_id=%d scaling_filter=%d",
441c349dbc7Sjsg 			   num_scalers,
442c349dbc7Sjsg 			   crtc_state->scaler_state.scaler_users,
4431bb76ff1Sjsg 			   crtc_state->scaler_state.scaler_id,
4441bb76ff1Sjsg 			   crtc_state->hw.scaling_filter);
445c349dbc7Sjsg 
446c349dbc7Sjsg 		for (i = 0; i < num_scalers; i++) {
447c349dbc7Sjsg 			const struct intel_scaler *sc =
448c349dbc7Sjsg 				&crtc_state->scaler_state.scalers[i];
449c349dbc7Sjsg 
450c349dbc7Sjsg 			seq_printf(m, ", scalers[%d]: use=%s, mode=%x",
4511bb76ff1Sjsg 				   i, str_yes_no(sc->in_use), sc->mode);
452c349dbc7Sjsg 		}
453c349dbc7Sjsg 		seq_puts(m, "\n");
454c349dbc7Sjsg 	} else {
455c349dbc7Sjsg 		seq_puts(m, "\tNo scalers available on this platform\n");
456c349dbc7Sjsg 	}
457c349dbc7Sjsg }
458c349dbc7Sjsg 
4595ca02815Sjsg #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_VBLANK_EVADE)
crtc_updates_info(struct seq_file * m,struct intel_crtc * crtc,const char * hdr)4605ca02815Sjsg static void crtc_updates_info(struct seq_file *m,
4615ca02815Sjsg 			      struct intel_crtc *crtc,
4625ca02815Sjsg 			      const char *hdr)
4635ca02815Sjsg {
4645ca02815Sjsg 	u64 count;
4655ca02815Sjsg 	int row;
4665ca02815Sjsg 
4675ca02815Sjsg 	count = 0;
4685ca02815Sjsg 	for (row = 0; row < ARRAY_SIZE(crtc->debug.vbl.times); row++)
4695ca02815Sjsg 		count += crtc->debug.vbl.times[row];
4705ca02815Sjsg 	seq_printf(m, "%sUpdates: %llu\n", hdr, count);
4715ca02815Sjsg 	if (!count)
4725ca02815Sjsg 		return;
4735ca02815Sjsg 
4745ca02815Sjsg 	for (row = 0; row < ARRAY_SIZE(crtc->debug.vbl.times); row++) {
4755ca02815Sjsg 		char columns[80] = "       |";
4765ca02815Sjsg 		unsigned int x;
4775ca02815Sjsg 
4785ca02815Sjsg 		if (row & 1) {
4795ca02815Sjsg 			const char *units;
4805ca02815Sjsg 
4815ca02815Sjsg 			if (row > 10) {
4825ca02815Sjsg 				x = 1000000;
4835ca02815Sjsg 				units = "ms";
4845ca02815Sjsg 			} else {
4855ca02815Sjsg 				x = 1000;
4865ca02815Sjsg 				units = "us";
4875ca02815Sjsg 			}
4885ca02815Sjsg 
4895ca02815Sjsg 			snprintf(columns, sizeof(columns), "%4ld%s |",
4905ca02815Sjsg 				 DIV_ROUND_CLOSEST(BIT(row + 9), x), units);
4915ca02815Sjsg 		}
4925ca02815Sjsg 
4935ca02815Sjsg 		if (crtc->debug.vbl.times[row]) {
4945ca02815Sjsg 			x = ilog2(crtc->debug.vbl.times[row]);
4955ca02815Sjsg 			memset(columns + 8, '*', x);
4965ca02815Sjsg 			columns[8 + x] = '\0';
4975ca02815Sjsg 		}
4985ca02815Sjsg 
4995ca02815Sjsg 		seq_printf(m, "%s%s\n", hdr, columns);
5005ca02815Sjsg 	}
5015ca02815Sjsg 
5025ca02815Sjsg 	seq_printf(m, "%sMin update: %lluns\n",
5035ca02815Sjsg 		   hdr, crtc->debug.vbl.min);
5045ca02815Sjsg 	seq_printf(m, "%sMax update: %lluns\n",
5055ca02815Sjsg 		   hdr, crtc->debug.vbl.max);
5065ca02815Sjsg 	seq_printf(m, "%sAverage update: %lluns\n",
5075ca02815Sjsg 		   hdr, div64_u64(crtc->debug.vbl.sum,  count));
5085ca02815Sjsg 	seq_printf(m, "%sOverruns > %uus: %u\n",
5095ca02815Sjsg 		   hdr, VBLANK_EVASION_TIME_US, crtc->debug.vbl.over);
5105ca02815Sjsg }
5115ca02815Sjsg 
crtc_updates_show(struct seq_file * m,void * data)5125ca02815Sjsg static int crtc_updates_show(struct seq_file *m, void *data)
5135ca02815Sjsg {
5145ca02815Sjsg 	crtc_updates_info(m, m->private, "");
5155ca02815Sjsg 	return 0;
5165ca02815Sjsg }
5175ca02815Sjsg 
crtc_updates_open(struct inode * inode,struct file * file)5185ca02815Sjsg static int crtc_updates_open(struct inode *inode, struct file *file)
5195ca02815Sjsg {
5205ca02815Sjsg 	return single_open(file, crtc_updates_show, inode->i_private);
5215ca02815Sjsg }
5225ca02815Sjsg 
crtc_updates_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)5235ca02815Sjsg static ssize_t crtc_updates_write(struct file *file,
5245ca02815Sjsg 				  const char __user *ubuf,
5255ca02815Sjsg 				  size_t len, loff_t *offp)
5265ca02815Sjsg {
5275ca02815Sjsg 	struct seq_file *m = file->private_data;
5285ca02815Sjsg 	struct intel_crtc *crtc = m->private;
5295ca02815Sjsg 
5305ca02815Sjsg 	/* May race with an update. Meh. */
5315ca02815Sjsg 	memset(&crtc->debug.vbl, 0, sizeof(crtc->debug.vbl));
5325ca02815Sjsg 
5335ca02815Sjsg 	return len;
5345ca02815Sjsg }
5355ca02815Sjsg 
5365ca02815Sjsg static const struct file_operations crtc_updates_fops = {
5375ca02815Sjsg 	.owner = THIS_MODULE,
5385ca02815Sjsg 	.open = crtc_updates_open,
5395ca02815Sjsg 	.read = seq_read,
5405ca02815Sjsg 	.llseek = seq_lseek,
5415ca02815Sjsg 	.release = single_release,
5425ca02815Sjsg 	.write = crtc_updates_write
5435ca02815Sjsg };
5445ca02815Sjsg 
crtc_updates_add(struct intel_crtc * crtc)545*f005ef32Sjsg static void crtc_updates_add(struct intel_crtc *crtc)
5465ca02815Sjsg {
547*f005ef32Sjsg 	debugfs_create_file("i915_update_info", 0644, crtc->base.debugfs_entry,
548*f005ef32Sjsg 			    crtc, &crtc_updates_fops);
5495ca02815Sjsg }
5505ca02815Sjsg 
5515ca02815Sjsg #else
crtc_updates_info(struct seq_file * m,struct intel_crtc * crtc,const char * hdr)5525ca02815Sjsg static void crtc_updates_info(struct seq_file *m,
5535ca02815Sjsg 			      struct intel_crtc *crtc,
5545ca02815Sjsg 			      const char *hdr)
5555ca02815Sjsg {
5565ca02815Sjsg }
5575ca02815Sjsg 
crtc_updates_add(struct intel_crtc * crtc)558*f005ef32Sjsg static void crtc_updates_add(struct intel_crtc *crtc)
5595ca02815Sjsg {
5605ca02815Sjsg }
5615ca02815Sjsg #endif
5625ca02815Sjsg 
intel_crtc_info(struct seq_file * m,struct intel_crtc * crtc)563c349dbc7Sjsg static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
564c349dbc7Sjsg {
565c349dbc7Sjsg 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
566c349dbc7Sjsg 	const struct intel_crtc_state *crtc_state =
567c349dbc7Sjsg 		to_intel_crtc_state(crtc->base.state);
568c349dbc7Sjsg 	struct intel_encoder *encoder;
569c349dbc7Sjsg 
570c349dbc7Sjsg 	seq_printf(m, "[CRTC:%d:%s]:\n",
571c349dbc7Sjsg 		   crtc->base.base.id, crtc->base.name);
572c349dbc7Sjsg 
573c349dbc7Sjsg 	seq_printf(m, "\tuapi: enable=%s, active=%s, mode=" DRM_MODE_FMT "\n",
5741bb76ff1Sjsg 		   str_yes_no(crtc_state->uapi.enable),
5751bb76ff1Sjsg 		   str_yes_no(crtc_state->uapi.active),
576c349dbc7Sjsg 		   DRM_MODE_ARG(&crtc_state->uapi.mode));
577c349dbc7Sjsg 
5781bb76ff1Sjsg 	seq_printf(m, "\thw: enable=%s, active=%s\n",
5791bb76ff1Sjsg 		   str_yes_no(crtc_state->hw.enable), str_yes_no(crtc_state->hw.active));
5801bb76ff1Sjsg 	seq_printf(m, "\tadjusted_mode=" DRM_MODE_FMT "\n",
581c349dbc7Sjsg 		   DRM_MODE_ARG(&crtc_state->hw.adjusted_mode));
5821bb76ff1Sjsg 	seq_printf(m, "\tpipe__mode=" DRM_MODE_FMT "\n",
5831bb76ff1Sjsg 		   DRM_MODE_ARG(&crtc_state->hw.pipe_mode));
584c349dbc7Sjsg 
5851bb76ff1Sjsg 	seq_printf(m, "\tpipe src=" DRM_RECT_FMT ", dither=%s, bpp=%d\n",
5861bb76ff1Sjsg 		   DRM_RECT_ARG(&crtc_state->pipe_src),
5871bb76ff1Sjsg 		   str_yes_no(crtc_state->dither), crtc_state->pipe_bpp);
588c349dbc7Sjsg 
589c349dbc7Sjsg 	intel_scaler_info(m, crtc);
590c349dbc7Sjsg 
5911bb76ff1Sjsg 	if (crtc_state->bigjoiner_pipes)
5921bb76ff1Sjsg 		seq_printf(m, "\tLinked to 0x%x pipes as a %s\n",
5931bb76ff1Sjsg 			   crtc_state->bigjoiner_pipes,
5941bb76ff1Sjsg 			   intel_crtc_is_bigjoiner_slave(crtc_state) ? "slave" : "master");
5955ca02815Sjsg 
596c349dbc7Sjsg 	for_each_intel_encoder_mask(&dev_priv->drm, encoder,
597c349dbc7Sjsg 				    crtc_state->uapi.encoder_mask)
598c349dbc7Sjsg 		intel_encoder_info(m, crtc, encoder);
599c349dbc7Sjsg 
600c349dbc7Sjsg 	intel_plane_info(m, crtc);
601c349dbc7Sjsg 
602c349dbc7Sjsg 	seq_printf(m, "\tunderrun reporting: cpu=%s pch=%s\n",
6031bb76ff1Sjsg 		   str_yes_no(!crtc->cpu_fifo_underrun_disabled),
6041bb76ff1Sjsg 		   str_yes_no(!crtc->pch_fifo_underrun_disabled));
6055ca02815Sjsg 
6065ca02815Sjsg 	crtc_updates_info(m, crtc, "\t");
607c349dbc7Sjsg }
608c349dbc7Sjsg 
i915_display_info(struct seq_file * m,void * unused)609c349dbc7Sjsg static int i915_display_info(struct seq_file *m, void *unused)
610c349dbc7Sjsg {
611c349dbc7Sjsg 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
612c349dbc7Sjsg 	struct intel_crtc *crtc;
613c349dbc7Sjsg 	struct drm_connector *connector;
614c349dbc7Sjsg 	struct drm_connector_list_iter conn_iter;
615c349dbc7Sjsg 	intel_wakeref_t wakeref;
616c349dbc7Sjsg 
617c349dbc7Sjsg 	wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
618c349dbc7Sjsg 
619*f005ef32Sjsg 	drm_modeset_lock_all(&dev_priv->drm);
620c349dbc7Sjsg 
621c349dbc7Sjsg 	seq_printf(m, "CRTC info\n");
622c349dbc7Sjsg 	seq_printf(m, "---------\n");
623*f005ef32Sjsg 	for_each_intel_crtc(&dev_priv->drm, crtc)
624c349dbc7Sjsg 		intel_crtc_info(m, crtc);
625c349dbc7Sjsg 
626c349dbc7Sjsg 	seq_printf(m, "\n");
627c349dbc7Sjsg 	seq_printf(m, "Connector info\n");
628c349dbc7Sjsg 	seq_printf(m, "--------------\n");
629*f005ef32Sjsg 	drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
630c349dbc7Sjsg 	drm_for_each_connector_iter(connector, &conn_iter)
631c349dbc7Sjsg 		intel_connector_info(m, connector);
632c349dbc7Sjsg 	drm_connector_list_iter_end(&conn_iter);
633c349dbc7Sjsg 
634*f005ef32Sjsg 	drm_modeset_unlock_all(&dev_priv->drm);
635c349dbc7Sjsg 
636c349dbc7Sjsg 	intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
637c349dbc7Sjsg 
638c349dbc7Sjsg 	return 0;
639c349dbc7Sjsg }
640c349dbc7Sjsg 
i915_shared_dplls_info(struct seq_file * m,void * unused)641c349dbc7Sjsg static int i915_shared_dplls_info(struct seq_file *m, void *unused)
642c349dbc7Sjsg {
643c349dbc7Sjsg 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
644c349dbc7Sjsg 	int i;
645c349dbc7Sjsg 
646*f005ef32Sjsg 	drm_modeset_lock_all(&dev_priv->drm);
647c349dbc7Sjsg 
648c349dbc7Sjsg 	seq_printf(m, "PLL refclks: non-SSC: %d kHz, SSC: %d kHz\n",
6491bb76ff1Sjsg 		   dev_priv->display.dpll.ref_clks.nssc,
6501bb76ff1Sjsg 		   dev_priv->display.dpll.ref_clks.ssc);
651c349dbc7Sjsg 
6521bb76ff1Sjsg 	for (i = 0; i < dev_priv->display.dpll.num_shared_dpll; i++) {
6531bb76ff1Sjsg 		struct intel_shared_dpll *pll = &dev_priv->display.dpll.shared_dplls[i];
654c349dbc7Sjsg 
655c349dbc7Sjsg 		seq_printf(m, "DPLL%i: %s, id: %i\n", i, pll->info->name,
656c349dbc7Sjsg 			   pll->info->id);
6575ca02815Sjsg 		seq_printf(m, " pipe_mask: 0x%x, active: 0x%x, on: %s\n",
6581bb76ff1Sjsg 			   pll->state.pipe_mask, pll->active_mask,
6591bb76ff1Sjsg 			   str_yes_no(pll->on));
660c349dbc7Sjsg 		seq_printf(m, " tracked hardware state:\n");
661c349dbc7Sjsg 		seq_printf(m, " dpll:    0x%08x\n", pll->state.hw_state.dpll);
662c349dbc7Sjsg 		seq_printf(m, " dpll_md: 0x%08x\n",
663c349dbc7Sjsg 			   pll->state.hw_state.dpll_md);
664c349dbc7Sjsg 		seq_printf(m, " fp0:     0x%08x\n", pll->state.hw_state.fp0);
665c349dbc7Sjsg 		seq_printf(m, " fp1:     0x%08x\n", pll->state.hw_state.fp1);
666c349dbc7Sjsg 		seq_printf(m, " wrpll:   0x%08x\n", pll->state.hw_state.wrpll);
667c349dbc7Sjsg 		seq_printf(m, " cfgcr0:  0x%08x\n", pll->state.hw_state.cfgcr0);
668c349dbc7Sjsg 		seq_printf(m, " cfgcr1:  0x%08x\n", pll->state.hw_state.cfgcr1);
6691bb76ff1Sjsg 		seq_printf(m, " div0:    0x%08x\n", pll->state.hw_state.div0);
670c349dbc7Sjsg 		seq_printf(m, " mg_refclkin_ctl:        0x%08x\n",
671c349dbc7Sjsg 			   pll->state.hw_state.mg_refclkin_ctl);
672c349dbc7Sjsg 		seq_printf(m, " mg_clktop2_coreclkctl1: 0x%08x\n",
673c349dbc7Sjsg 			   pll->state.hw_state.mg_clktop2_coreclkctl1);
674c349dbc7Sjsg 		seq_printf(m, " mg_clktop2_hsclkctl:    0x%08x\n",
675c349dbc7Sjsg 			   pll->state.hw_state.mg_clktop2_hsclkctl);
676c349dbc7Sjsg 		seq_printf(m, " mg_pll_div0:  0x%08x\n",
677c349dbc7Sjsg 			   pll->state.hw_state.mg_pll_div0);
678c349dbc7Sjsg 		seq_printf(m, " mg_pll_div1:  0x%08x\n",
679c349dbc7Sjsg 			   pll->state.hw_state.mg_pll_div1);
680c349dbc7Sjsg 		seq_printf(m, " mg_pll_lf:    0x%08x\n",
681c349dbc7Sjsg 			   pll->state.hw_state.mg_pll_lf);
682c349dbc7Sjsg 		seq_printf(m, " mg_pll_frac_lock: 0x%08x\n",
683c349dbc7Sjsg 			   pll->state.hw_state.mg_pll_frac_lock);
684c349dbc7Sjsg 		seq_printf(m, " mg_pll_ssc:   0x%08x\n",
685c349dbc7Sjsg 			   pll->state.hw_state.mg_pll_ssc);
686c349dbc7Sjsg 		seq_printf(m, " mg_pll_bias:  0x%08x\n",
687c349dbc7Sjsg 			   pll->state.hw_state.mg_pll_bias);
688c349dbc7Sjsg 		seq_printf(m, " mg_pll_tdc_coldst_bias: 0x%08x\n",
689c349dbc7Sjsg 			   pll->state.hw_state.mg_pll_tdc_coldst_bias);
690c349dbc7Sjsg 	}
691*f005ef32Sjsg 	drm_modeset_unlock_all(&dev_priv->drm);
692c349dbc7Sjsg 
693c349dbc7Sjsg 	return 0;
694c349dbc7Sjsg }
695c349dbc7Sjsg 
i915_ddb_info(struct seq_file * m,void * unused)696c349dbc7Sjsg static int i915_ddb_info(struct seq_file *m, void *unused)
697c349dbc7Sjsg {
698c349dbc7Sjsg 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
699c349dbc7Sjsg 	struct skl_ddb_entry *entry;
700c349dbc7Sjsg 	struct intel_crtc *crtc;
701c349dbc7Sjsg 
7025ca02815Sjsg 	if (DISPLAY_VER(dev_priv) < 9)
703c349dbc7Sjsg 		return -ENODEV;
704c349dbc7Sjsg 
705*f005ef32Sjsg 	drm_modeset_lock_all(&dev_priv->drm);
706c349dbc7Sjsg 
707c349dbc7Sjsg 	seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
708c349dbc7Sjsg 
709c349dbc7Sjsg 	for_each_intel_crtc(&dev_priv->drm, crtc) {
710c349dbc7Sjsg 		struct intel_crtc_state *crtc_state =
711c349dbc7Sjsg 			to_intel_crtc_state(crtc->base.state);
712c349dbc7Sjsg 		enum pipe pipe = crtc->pipe;
713c349dbc7Sjsg 		enum plane_id plane_id;
714c349dbc7Sjsg 
715c349dbc7Sjsg 		seq_printf(m, "Pipe %c\n", pipe_name(pipe));
716c349dbc7Sjsg 
717c349dbc7Sjsg 		for_each_plane_id_on_crtc(crtc, plane_id) {
7181bb76ff1Sjsg 			entry = &crtc_state->wm.skl.plane_ddb[plane_id];
719c349dbc7Sjsg 			seq_printf(m, "  Plane%-8d%8u%8u%8u\n", plane_id + 1,
720c349dbc7Sjsg 				   entry->start, entry->end,
721c349dbc7Sjsg 				   skl_ddb_entry_size(entry));
722c349dbc7Sjsg 		}
723c349dbc7Sjsg 
7241bb76ff1Sjsg 		entry = &crtc_state->wm.skl.plane_ddb[PLANE_CURSOR];
725c349dbc7Sjsg 		seq_printf(m, "  %-13s%8u%8u%8u\n", "Cursor", entry->start,
726c349dbc7Sjsg 			   entry->end, skl_ddb_entry_size(entry));
727c349dbc7Sjsg 	}
728c349dbc7Sjsg 
729*f005ef32Sjsg 	drm_modeset_unlock_all(&dev_priv->drm);
730c349dbc7Sjsg 
731c349dbc7Sjsg 	return 0;
732c349dbc7Sjsg }
733c349dbc7Sjsg 
734ad8b1aafSjsg static bool
intel_lpsp_power_well_enabled(struct drm_i915_private * i915,enum i915_power_well_id power_well_id)735ad8b1aafSjsg intel_lpsp_power_well_enabled(struct drm_i915_private *i915,
736ad8b1aafSjsg 			      enum i915_power_well_id power_well_id)
737ad8b1aafSjsg {
738ad8b1aafSjsg 	intel_wakeref_t wakeref;
739ad8b1aafSjsg 	bool is_enabled;
740ad8b1aafSjsg 
741ad8b1aafSjsg 	wakeref = intel_runtime_pm_get(&i915->runtime_pm);
742ad8b1aafSjsg 	is_enabled = intel_display_power_well_is_enabled(i915,
743ad8b1aafSjsg 							 power_well_id);
744ad8b1aafSjsg 	intel_runtime_pm_put(&i915->runtime_pm, wakeref);
745ad8b1aafSjsg 
746ad8b1aafSjsg 	return is_enabled;
747ad8b1aafSjsg }
748ad8b1aafSjsg 
i915_lpsp_status(struct seq_file * m,void * unused)749ad8b1aafSjsg static int i915_lpsp_status(struct seq_file *m, void *unused)
750ad8b1aafSjsg {
751ad8b1aafSjsg 	struct drm_i915_private *i915 = node_to_i915(m->private);
7521bb76ff1Sjsg 	bool lpsp_enabled = false;
753ad8b1aafSjsg 
7541bb76ff1Sjsg 	if (DISPLAY_VER(i915) >= 13 || IS_DISPLAY_VER(i915, 9, 10)) {
7551bb76ff1Sjsg 		lpsp_enabled = !intel_lpsp_power_well_enabled(i915, SKL_DISP_PW_2);
7561bb76ff1Sjsg 	} else if (IS_DISPLAY_VER(i915, 11, 12)) {
7571bb76ff1Sjsg 		lpsp_enabled = !intel_lpsp_power_well_enabled(i915, ICL_DISP_PW_3);
7581bb76ff1Sjsg 	} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
7591bb76ff1Sjsg 		lpsp_enabled = !intel_lpsp_power_well_enabled(i915, HSW_DISP_PW_GLOBAL);
7601bb76ff1Sjsg 	} else {
7611bb76ff1Sjsg 		seq_puts(m, "LPSP: not supported\n");
7625ca02815Sjsg 		return 0;
7635ca02815Sjsg 	}
7645ca02815Sjsg 
7651bb76ff1Sjsg 	seq_printf(m, "LPSP: %s\n", str_enabled_disabled(lpsp_enabled));
766ad8b1aafSjsg 
767ad8b1aafSjsg 	return 0;
768ad8b1aafSjsg }
769ad8b1aafSjsg 
i915_dp_mst_info(struct seq_file * m,void * unused)770c349dbc7Sjsg static int i915_dp_mst_info(struct seq_file *m, void *unused)
771c349dbc7Sjsg {
772c349dbc7Sjsg 	struct drm_i915_private *dev_priv = node_to_i915(m->private);
773c349dbc7Sjsg 	struct intel_encoder *intel_encoder;
774ad8b1aafSjsg 	struct intel_digital_port *dig_port;
775c349dbc7Sjsg 	struct drm_connector *connector;
776c349dbc7Sjsg 	struct drm_connector_list_iter conn_iter;
777c349dbc7Sjsg 
778*f005ef32Sjsg 	drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
779c349dbc7Sjsg 	drm_for_each_connector_iter(connector, &conn_iter) {
780c349dbc7Sjsg 		if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
781c349dbc7Sjsg 			continue;
782c349dbc7Sjsg 
783c349dbc7Sjsg 		intel_encoder = intel_attached_encoder(to_intel_connector(connector));
784c349dbc7Sjsg 		if (!intel_encoder || intel_encoder->type == INTEL_OUTPUT_DP_MST)
785c349dbc7Sjsg 			continue;
786c349dbc7Sjsg 
787ad8b1aafSjsg 		dig_port = enc_to_dig_port(intel_encoder);
7881bb76ff1Sjsg 		if (!intel_dp_mst_source_support(&dig_port->dp))
789c349dbc7Sjsg 			continue;
790c349dbc7Sjsg 
791c349dbc7Sjsg 		seq_printf(m, "MST Source Port [ENCODER:%d:%s]\n",
792ad8b1aafSjsg 			   dig_port->base.base.base.id,
793ad8b1aafSjsg 			   dig_port->base.base.name);
794ad8b1aafSjsg 		drm_dp_mst_dump_topology(m, &dig_port->dp.mst_mgr);
795c349dbc7Sjsg 	}
796c349dbc7Sjsg 	drm_connector_list_iter_end(&conn_iter);
797c349dbc7Sjsg 
798c349dbc7Sjsg 	return 0;
799c349dbc7Sjsg }
800c349dbc7Sjsg 
i915_displayport_test_active_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)801c349dbc7Sjsg static ssize_t i915_displayport_test_active_write(struct file *file,
802c349dbc7Sjsg 						  const char __user *ubuf,
803c349dbc7Sjsg 						  size_t len, loff_t *offp)
804c349dbc7Sjsg {
805c349dbc7Sjsg 	char *input_buffer;
806c349dbc7Sjsg 	int status = 0;
807c349dbc7Sjsg 	struct drm_device *dev;
808c349dbc7Sjsg 	struct drm_connector *connector;
809c349dbc7Sjsg 	struct drm_connector_list_iter conn_iter;
810c349dbc7Sjsg 	struct intel_dp *intel_dp;
811c349dbc7Sjsg 	int val = 0;
812c349dbc7Sjsg 
813c349dbc7Sjsg 	dev = ((struct seq_file *)file->private_data)->private;
814c349dbc7Sjsg 
815c349dbc7Sjsg 	if (len == 0)
816c349dbc7Sjsg 		return 0;
817c349dbc7Sjsg 
818c349dbc7Sjsg 	input_buffer = memdup_user_nul(ubuf, len);
819c349dbc7Sjsg 	if (IS_ERR(input_buffer))
820c349dbc7Sjsg 		return PTR_ERR(input_buffer);
821c349dbc7Sjsg 
822*f005ef32Sjsg 	drm_dbg(dev, "Copied %d bytes from user\n", (unsigned int)len);
823c349dbc7Sjsg 
824c349dbc7Sjsg 	drm_connector_list_iter_begin(dev, &conn_iter);
825c349dbc7Sjsg 	drm_for_each_connector_iter(connector, &conn_iter) {
826c349dbc7Sjsg 		struct intel_encoder *encoder;
827c349dbc7Sjsg 
828c349dbc7Sjsg 		if (connector->connector_type !=
829c349dbc7Sjsg 		    DRM_MODE_CONNECTOR_DisplayPort)
830c349dbc7Sjsg 			continue;
831c349dbc7Sjsg 
832c349dbc7Sjsg 		encoder = to_intel_encoder(connector->encoder);
833c349dbc7Sjsg 		if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
834c349dbc7Sjsg 			continue;
835c349dbc7Sjsg 
836c349dbc7Sjsg 		if (encoder && connector->status == connector_status_connected) {
837c349dbc7Sjsg 			intel_dp = enc_to_intel_dp(encoder);
838c349dbc7Sjsg 			status = kstrtoint(input_buffer, 10, &val);
839c349dbc7Sjsg 			if (status < 0)
840c349dbc7Sjsg 				break;
841*f005ef32Sjsg 			drm_dbg(dev, "Got %d for test active\n", val);
842c349dbc7Sjsg 			/* To prevent erroneous activation of the compliance
843c349dbc7Sjsg 			 * testing code, only accept an actual value of 1 here
844c349dbc7Sjsg 			 */
845c349dbc7Sjsg 			if (val == 1)
846c349dbc7Sjsg 				intel_dp->compliance.test_active = true;
847c349dbc7Sjsg 			else
848c349dbc7Sjsg 				intel_dp->compliance.test_active = false;
849c349dbc7Sjsg 		}
850c349dbc7Sjsg 	}
851c349dbc7Sjsg 	drm_connector_list_iter_end(&conn_iter);
852c349dbc7Sjsg 	kfree(input_buffer);
853c349dbc7Sjsg 	if (status < 0)
854c349dbc7Sjsg 		return status;
855c349dbc7Sjsg 
856c349dbc7Sjsg 	*offp += len;
857c349dbc7Sjsg 	return len;
858c349dbc7Sjsg }
859c349dbc7Sjsg 
i915_displayport_test_active_show(struct seq_file * m,void * data)860c349dbc7Sjsg static int i915_displayport_test_active_show(struct seq_file *m, void *data)
861c349dbc7Sjsg {
862c349dbc7Sjsg 	struct drm_i915_private *dev_priv = m->private;
863c349dbc7Sjsg 	struct drm_connector *connector;
864c349dbc7Sjsg 	struct drm_connector_list_iter conn_iter;
865c349dbc7Sjsg 	struct intel_dp *intel_dp;
866c349dbc7Sjsg 
867*f005ef32Sjsg 	drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
868c349dbc7Sjsg 	drm_for_each_connector_iter(connector, &conn_iter) {
869c349dbc7Sjsg 		struct intel_encoder *encoder;
870c349dbc7Sjsg 
871c349dbc7Sjsg 		if (connector->connector_type !=
872c349dbc7Sjsg 		    DRM_MODE_CONNECTOR_DisplayPort)
873c349dbc7Sjsg 			continue;
874c349dbc7Sjsg 
875c349dbc7Sjsg 		encoder = to_intel_encoder(connector->encoder);
876c349dbc7Sjsg 		if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
877c349dbc7Sjsg 			continue;
878c349dbc7Sjsg 
879c349dbc7Sjsg 		if (encoder && connector->status == connector_status_connected) {
880c349dbc7Sjsg 			intel_dp = enc_to_intel_dp(encoder);
881c349dbc7Sjsg 			if (intel_dp->compliance.test_active)
882c349dbc7Sjsg 				seq_puts(m, "1");
883c349dbc7Sjsg 			else
884c349dbc7Sjsg 				seq_puts(m, "0");
885c349dbc7Sjsg 		} else
886c349dbc7Sjsg 			seq_puts(m, "0");
887c349dbc7Sjsg 	}
888c349dbc7Sjsg 	drm_connector_list_iter_end(&conn_iter);
889c349dbc7Sjsg 
890c349dbc7Sjsg 	return 0;
891c349dbc7Sjsg }
892c349dbc7Sjsg 
i915_displayport_test_active_open(struct inode * inode,struct file * file)893c349dbc7Sjsg static int i915_displayport_test_active_open(struct inode *inode,
894c349dbc7Sjsg 					     struct file *file)
895c349dbc7Sjsg {
896c349dbc7Sjsg 	return single_open(file, i915_displayport_test_active_show,
897c349dbc7Sjsg 			   inode->i_private);
898c349dbc7Sjsg }
899c349dbc7Sjsg 
900c349dbc7Sjsg static const struct file_operations i915_displayport_test_active_fops = {
901c349dbc7Sjsg 	.owner = THIS_MODULE,
902c349dbc7Sjsg 	.open = i915_displayport_test_active_open,
903c349dbc7Sjsg 	.read = seq_read,
904c349dbc7Sjsg 	.llseek = seq_lseek,
905c349dbc7Sjsg 	.release = single_release,
906c349dbc7Sjsg 	.write = i915_displayport_test_active_write
907c349dbc7Sjsg };
908c349dbc7Sjsg 
i915_displayport_test_data_show(struct seq_file * m,void * data)909c349dbc7Sjsg static int i915_displayport_test_data_show(struct seq_file *m, void *data)
910c349dbc7Sjsg {
911c349dbc7Sjsg 	struct drm_i915_private *dev_priv = m->private;
912c349dbc7Sjsg 	struct drm_connector *connector;
913c349dbc7Sjsg 	struct drm_connector_list_iter conn_iter;
914c349dbc7Sjsg 	struct intel_dp *intel_dp;
915c349dbc7Sjsg 
916*f005ef32Sjsg 	drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
917c349dbc7Sjsg 	drm_for_each_connector_iter(connector, &conn_iter) {
918c349dbc7Sjsg 		struct intel_encoder *encoder;
919c349dbc7Sjsg 
920c349dbc7Sjsg 		if (connector->connector_type !=
921c349dbc7Sjsg 		    DRM_MODE_CONNECTOR_DisplayPort)
922c349dbc7Sjsg 			continue;
923c349dbc7Sjsg 
924c349dbc7Sjsg 		encoder = to_intel_encoder(connector->encoder);
925c349dbc7Sjsg 		if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
926c349dbc7Sjsg 			continue;
927c349dbc7Sjsg 
928c349dbc7Sjsg 		if (encoder && connector->status == connector_status_connected) {
929c349dbc7Sjsg 			intel_dp = enc_to_intel_dp(encoder);
930c349dbc7Sjsg 			if (intel_dp->compliance.test_type ==
931c349dbc7Sjsg 			    DP_TEST_LINK_EDID_READ)
932c349dbc7Sjsg 				seq_printf(m, "%lx",
933c349dbc7Sjsg 					   intel_dp->compliance.test_data.edid);
934c349dbc7Sjsg 			else if (intel_dp->compliance.test_type ==
935c349dbc7Sjsg 				 DP_TEST_LINK_VIDEO_PATTERN) {
936c349dbc7Sjsg 				seq_printf(m, "hdisplay: %d\n",
937c349dbc7Sjsg 					   intel_dp->compliance.test_data.hdisplay);
938c349dbc7Sjsg 				seq_printf(m, "vdisplay: %d\n",
939c349dbc7Sjsg 					   intel_dp->compliance.test_data.vdisplay);
940c349dbc7Sjsg 				seq_printf(m, "bpc: %u\n",
941c349dbc7Sjsg 					   intel_dp->compliance.test_data.bpc);
942ad8b1aafSjsg 			} else if (intel_dp->compliance.test_type ==
943ad8b1aafSjsg 				   DP_TEST_LINK_PHY_TEST_PATTERN) {
944ad8b1aafSjsg 				seq_printf(m, "pattern: %d\n",
945ad8b1aafSjsg 					   intel_dp->compliance.test_data.phytest.phy_pattern);
946ad8b1aafSjsg 				seq_printf(m, "Number of lanes: %d\n",
947ad8b1aafSjsg 					   intel_dp->compliance.test_data.phytest.num_lanes);
948ad8b1aafSjsg 				seq_printf(m, "Link Rate: %d\n",
949ad8b1aafSjsg 					   intel_dp->compliance.test_data.phytest.link_rate);
950ad8b1aafSjsg 				seq_printf(m, "level: %02x\n",
951ad8b1aafSjsg 					   intel_dp->train_set[0]);
952c349dbc7Sjsg 			}
953c349dbc7Sjsg 		} else
954c349dbc7Sjsg 			seq_puts(m, "0");
955c349dbc7Sjsg 	}
956c349dbc7Sjsg 	drm_connector_list_iter_end(&conn_iter);
957c349dbc7Sjsg 
958c349dbc7Sjsg 	return 0;
959c349dbc7Sjsg }
960c349dbc7Sjsg DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_data);
961c349dbc7Sjsg 
i915_displayport_test_type_show(struct seq_file * m,void * data)962c349dbc7Sjsg static int i915_displayport_test_type_show(struct seq_file *m, void *data)
963c349dbc7Sjsg {
964c349dbc7Sjsg 	struct drm_i915_private *dev_priv = m->private;
965c349dbc7Sjsg 	struct drm_connector *connector;
966c349dbc7Sjsg 	struct drm_connector_list_iter conn_iter;
967c349dbc7Sjsg 	struct intel_dp *intel_dp;
968c349dbc7Sjsg 
969*f005ef32Sjsg 	drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
970c349dbc7Sjsg 	drm_for_each_connector_iter(connector, &conn_iter) {
971c349dbc7Sjsg 		struct intel_encoder *encoder;
972c349dbc7Sjsg 
973c349dbc7Sjsg 		if (connector->connector_type !=
974c349dbc7Sjsg 		    DRM_MODE_CONNECTOR_DisplayPort)
975c349dbc7Sjsg 			continue;
976c349dbc7Sjsg 
977c349dbc7Sjsg 		encoder = to_intel_encoder(connector->encoder);
978c349dbc7Sjsg 		if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
979c349dbc7Sjsg 			continue;
980c349dbc7Sjsg 
981c349dbc7Sjsg 		if (encoder && connector->status == connector_status_connected) {
982c349dbc7Sjsg 			intel_dp = enc_to_intel_dp(encoder);
983ad8b1aafSjsg 			seq_printf(m, "%02lx\n", intel_dp->compliance.test_type);
984c349dbc7Sjsg 		} else
985c349dbc7Sjsg 			seq_puts(m, "0");
986c349dbc7Sjsg 	}
987c349dbc7Sjsg 	drm_connector_list_iter_end(&conn_iter);
988c349dbc7Sjsg 
989c349dbc7Sjsg 	return 0;
990c349dbc7Sjsg }
991c349dbc7Sjsg DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_type);
992c349dbc7Sjsg 
993c349dbc7Sjsg static ssize_t
i915_fifo_underrun_reset_write(struct file * filp,const char __user * ubuf,size_t cnt,loff_t * ppos)994c349dbc7Sjsg i915_fifo_underrun_reset_write(struct file *filp,
995c349dbc7Sjsg 			       const char __user *ubuf,
996c349dbc7Sjsg 			       size_t cnt, loff_t *ppos)
997c349dbc7Sjsg {
998c349dbc7Sjsg 	struct drm_i915_private *dev_priv = filp->private_data;
9995ca02815Sjsg 	struct intel_crtc *crtc;
1000c349dbc7Sjsg 	int ret;
1001c349dbc7Sjsg 	bool reset;
1002c349dbc7Sjsg 
1003c349dbc7Sjsg 	ret = kstrtobool_from_user(ubuf, cnt, &reset);
1004c349dbc7Sjsg 	if (ret)
1005c349dbc7Sjsg 		return ret;
1006c349dbc7Sjsg 
1007c349dbc7Sjsg 	if (!reset)
1008c349dbc7Sjsg 		return cnt;
1009c349dbc7Sjsg 
1010*f005ef32Sjsg 	for_each_intel_crtc(&dev_priv->drm, crtc) {
1011c349dbc7Sjsg 		struct drm_crtc_commit *commit;
1012c349dbc7Sjsg 		struct intel_crtc_state *crtc_state;
1013c349dbc7Sjsg 
10145ca02815Sjsg 		ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
1015c349dbc7Sjsg 		if (ret)
1016c349dbc7Sjsg 			return ret;
1017c349dbc7Sjsg 
10185ca02815Sjsg 		crtc_state = to_intel_crtc_state(crtc->base.state);
1019c349dbc7Sjsg 		commit = crtc_state->uapi.commit;
1020c349dbc7Sjsg 		if (commit) {
1021c349dbc7Sjsg 			ret = wait_for_completion_interruptible(&commit->hw_done);
1022c349dbc7Sjsg 			if (!ret)
1023c349dbc7Sjsg 				ret = wait_for_completion_interruptible(&commit->flip_done);
1024c349dbc7Sjsg 		}
1025c349dbc7Sjsg 
1026c349dbc7Sjsg 		if (!ret && crtc_state->hw.active) {
1027c349dbc7Sjsg 			drm_dbg_kms(&dev_priv->drm,
1028c349dbc7Sjsg 				    "Re-arming FIFO underruns on pipe %c\n",
10295ca02815Sjsg 				    pipe_name(crtc->pipe));
1030c349dbc7Sjsg 
10315ca02815Sjsg 			intel_crtc_arm_fifo_underrun(crtc, crtc_state);
1032c349dbc7Sjsg 		}
1033c349dbc7Sjsg 
10345ca02815Sjsg 		drm_modeset_unlock(&crtc->base.mutex);
1035c349dbc7Sjsg 
1036c349dbc7Sjsg 		if (ret)
1037c349dbc7Sjsg 			return ret;
1038c349dbc7Sjsg 	}
1039c349dbc7Sjsg 
10401bb76ff1Sjsg 	intel_fbc_reset_underrun(dev_priv);
1041c349dbc7Sjsg 
1042c349dbc7Sjsg 	return cnt;
1043c349dbc7Sjsg }
1044c349dbc7Sjsg 
1045c349dbc7Sjsg static const struct file_operations i915_fifo_underrun_reset_ops = {
1046c349dbc7Sjsg 	.owner = THIS_MODULE,
1047c349dbc7Sjsg 	.open = simple_open,
1048c349dbc7Sjsg 	.write = i915_fifo_underrun_reset_write,
1049c349dbc7Sjsg 	.llseek = default_llseek,
1050c349dbc7Sjsg };
1051c349dbc7Sjsg 
1052c349dbc7Sjsg static const struct drm_info_list intel_display_debugfs_list[] = {
1053c349dbc7Sjsg 	{"i915_frontbuffer_tracking", i915_frontbuffer_tracking, 0},
1054c349dbc7Sjsg 	{"i915_sr_status", i915_sr_status, 0},
1055c349dbc7Sjsg 	{"i915_opregion", i915_opregion, 0},
1056c349dbc7Sjsg 	{"i915_vbt", i915_vbt, 0},
1057c349dbc7Sjsg 	{"i915_gem_framebuffer", i915_gem_framebuffer_info, 0},
1058c349dbc7Sjsg 	{"i915_power_domain_info", i915_power_domain_info, 0},
1059c349dbc7Sjsg 	{"i915_display_info", i915_display_info, 0},
1060c349dbc7Sjsg 	{"i915_shared_dplls_info", i915_shared_dplls_info, 0},
1061c349dbc7Sjsg 	{"i915_dp_mst_info", i915_dp_mst_info, 0},
1062c349dbc7Sjsg 	{"i915_ddb_info", i915_ddb_info, 0},
1063ad8b1aafSjsg 	{"i915_lpsp_status", i915_lpsp_status, 0},
1064c349dbc7Sjsg };
1065c349dbc7Sjsg 
1066c349dbc7Sjsg static const struct {
1067c349dbc7Sjsg 	const char *name;
1068c349dbc7Sjsg 	const struct file_operations *fops;
1069c349dbc7Sjsg } intel_display_debugfs_files[] = {
1070c349dbc7Sjsg 	{"i915_fifo_underrun_reset", &i915_fifo_underrun_reset_ops},
1071c349dbc7Sjsg 	{"i915_dp_test_data", &i915_displayport_test_data_fops},
1072c349dbc7Sjsg 	{"i915_dp_test_type", &i915_displayport_test_type_fops},
1073c349dbc7Sjsg 	{"i915_dp_test_active", &i915_displayport_test_active_fops},
1074c349dbc7Sjsg };
1075c349dbc7Sjsg 
intel_display_debugfs_register(struct drm_i915_private * i915)1076ad8b1aafSjsg void intel_display_debugfs_register(struct drm_i915_private *i915)
1077c349dbc7Sjsg {
1078c349dbc7Sjsg 	struct drm_minor *minor = i915->drm.primary;
1079c349dbc7Sjsg 	int i;
1080c349dbc7Sjsg 
1081c349dbc7Sjsg 	for (i = 0; i < ARRAY_SIZE(intel_display_debugfs_files); i++) {
1082c349dbc7Sjsg 		debugfs_create_file(intel_display_debugfs_files[i].name,
1083c349dbc7Sjsg 				    S_IRUGO | S_IWUSR,
1084c349dbc7Sjsg 				    minor->debugfs_root,
1085c349dbc7Sjsg 				    to_i915(minor->dev),
1086c349dbc7Sjsg 				    intel_display_debugfs_files[i].fops);
1087c349dbc7Sjsg 	}
1088c349dbc7Sjsg 
1089ad8b1aafSjsg 	drm_debugfs_create_files(intel_display_debugfs_list,
1090c349dbc7Sjsg 				 ARRAY_SIZE(intel_display_debugfs_list),
1091c349dbc7Sjsg 				 minor->debugfs_root, minor);
10921bb76ff1Sjsg 
1093*f005ef32Sjsg 	intel_cdclk_debugfs_register(i915);
10941bb76ff1Sjsg 	intel_dmc_debugfs_register(i915);
10951bb76ff1Sjsg 	intel_fbc_debugfs_register(i915);
1096*f005ef32Sjsg 	intel_hpd_debugfs_register(i915);
1097*f005ef32Sjsg 	intel_psr_debugfs_register(i915);
1098*f005ef32Sjsg 	intel_wm_debugfs_register(i915);
1099c349dbc7Sjsg }
1100c349dbc7Sjsg 
i915_panel_show(struct seq_file * m,void * data)1101c349dbc7Sjsg static int i915_panel_show(struct seq_file *m, void *data)
1102c349dbc7Sjsg {
1103c349dbc7Sjsg 	struct drm_connector *connector = m->private;
1104c349dbc7Sjsg 	struct intel_dp *intel_dp =
1105c349dbc7Sjsg 		intel_attached_dp(to_intel_connector(connector));
1106c349dbc7Sjsg 
1107c349dbc7Sjsg 	if (connector->status != connector_status_connected)
1108c349dbc7Sjsg 		return -ENODEV;
1109c349dbc7Sjsg 
1110c349dbc7Sjsg 	seq_printf(m, "Panel power up delay: %d\n",
11115ca02815Sjsg 		   intel_dp->pps.panel_power_up_delay);
1112c349dbc7Sjsg 	seq_printf(m, "Panel power down delay: %d\n",
11135ca02815Sjsg 		   intel_dp->pps.panel_power_down_delay);
1114c349dbc7Sjsg 	seq_printf(m, "Backlight on delay: %d\n",
11155ca02815Sjsg 		   intel_dp->pps.backlight_on_delay);
1116c349dbc7Sjsg 	seq_printf(m, "Backlight off delay: %d\n",
11175ca02815Sjsg 		   intel_dp->pps.backlight_off_delay);
1118c349dbc7Sjsg 
1119c349dbc7Sjsg 	return 0;
1120c349dbc7Sjsg }
1121c349dbc7Sjsg DEFINE_SHOW_ATTRIBUTE(i915_panel);
1122c349dbc7Sjsg 
i915_hdcp_sink_capability_show(struct seq_file * m,void * data)1123c349dbc7Sjsg static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data)
1124c349dbc7Sjsg {
1125c349dbc7Sjsg 	struct drm_connector *connector = m->private;
11265ca02815Sjsg 	struct drm_i915_private *i915 = to_i915(connector->dev);
1127c349dbc7Sjsg 	struct intel_connector *intel_connector = to_intel_connector(connector);
11285ca02815Sjsg 	int ret;
1129c349dbc7Sjsg 
11305ca02815Sjsg 	ret = drm_modeset_lock_single_interruptible(&i915->drm.mode_config.connection_mutex);
11315ca02815Sjsg 	if (ret)
11325ca02815Sjsg 		return ret;
11335ca02815Sjsg 
11345ca02815Sjsg 	if (!connector->encoder || connector->status != connector_status_connected) {
11355ca02815Sjsg 		ret = -ENODEV;
11365ca02815Sjsg 		goto out;
11375ca02815Sjsg 	}
1138c349dbc7Sjsg 
1139c349dbc7Sjsg 	seq_printf(m, "%s:%d HDCP version: ", connector->name,
1140c349dbc7Sjsg 		   connector->base.id);
1141c349dbc7Sjsg 	intel_hdcp_info(m, intel_connector);
1142c349dbc7Sjsg 
11435ca02815Sjsg out:
11445ca02815Sjsg 	drm_modeset_unlock(&i915->drm.mode_config.connection_mutex);
11455ca02815Sjsg 
11465ca02815Sjsg 	return ret;
1147c349dbc7Sjsg }
1148c349dbc7Sjsg DEFINE_SHOW_ATTRIBUTE(i915_hdcp_sink_capability);
1149c349dbc7Sjsg 
i915_lpsp_capability_show(struct seq_file * m,void * data)1150ad8b1aafSjsg static int i915_lpsp_capability_show(struct seq_file *m, void *data)
1151ad8b1aafSjsg {
1152ad8b1aafSjsg 	struct drm_connector *connector = m->private;
1153ad8b1aafSjsg 	struct drm_i915_private *i915 = to_i915(connector->dev);
1154ad8b1aafSjsg 	struct intel_encoder *encoder;
11551bb76ff1Sjsg 	bool lpsp_capable = false;
1156ad8b1aafSjsg 
1157ad8b1aafSjsg 	encoder = intel_attached_encoder(to_intel_connector(connector));
1158ad8b1aafSjsg 	if (!encoder)
1159ad8b1aafSjsg 		return -ENODEV;
1160ad8b1aafSjsg 
1161ad8b1aafSjsg 	if (connector->status != connector_status_connected)
1162ad8b1aafSjsg 		return -ENODEV;
1163ad8b1aafSjsg 
11641bb76ff1Sjsg 	if (DISPLAY_VER(i915) >= 13)
11651bb76ff1Sjsg 		lpsp_capable = encoder->port <= PORT_B;
11661bb76ff1Sjsg 	else if (DISPLAY_VER(i915) >= 12)
1167ad8b1aafSjsg 		/*
1168ad8b1aafSjsg 		 * Actually TGL can drive LPSP on port till DDI_C
1169ad8b1aafSjsg 		 * but there is no physical connected DDI_C on TGL sku's,
1170ad8b1aafSjsg 		 * even driver is not initilizing DDI_C port for gen12.
1171ad8b1aafSjsg 		 */
11721bb76ff1Sjsg 		lpsp_capable = encoder->port <= PORT_B;
11731bb76ff1Sjsg 	else if (DISPLAY_VER(i915) == 11)
11741bb76ff1Sjsg 		lpsp_capable = (connector->connector_type == DRM_MODE_CONNECTOR_DSI ||
1175ad8b1aafSjsg 				connector->connector_type == DRM_MODE_CONNECTOR_eDP);
11761bb76ff1Sjsg 	else if (IS_DISPLAY_VER(i915, 9, 10))
11771bb76ff1Sjsg 		lpsp_capable = (encoder->port == PORT_A &&
1178ad8b1aafSjsg 				(connector->connector_type == DRM_MODE_CONNECTOR_DSI ||
1179ad8b1aafSjsg 				 connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
1180ad8b1aafSjsg 				 connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort));
11811bb76ff1Sjsg 	else if (IS_HASWELL(i915) || IS_BROADWELL(i915))
11821bb76ff1Sjsg 		lpsp_capable = connector->connector_type == DRM_MODE_CONNECTOR_eDP;
11831bb76ff1Sjsg 
11841bb76ff1Sjsg 	seq_printf(m, "LPSP: %s\n", lpsp_capable ? "capable" : "incapable");
1185ad8b1aafSjsg 
1186ad8b1aafSjsg 	return 0;
1187ad8b1aafSjsg }
1188ad8b1aafSjsg DEFINE_SHOW_ATTRIBUTE(i915_lpsp_capability);
1189ad8b1aafSjsg 
i915_dsc_fec_support_show(struct seq_file * m,void * data)1190c349dbc7Sjsg static int i915_dsc_fec_support_show(struct seq_file *m, void *data)
1191c349dbc7Sjsg {
1192c349dbc7Sjsg 	struct drm_connector *connector = m->private;
1193c349dbc7Sjsg 	struct drm_device *dev = connector->dev;
1194c349dbc7Sjsg 	struct drm_crtc *crtc;
1195c349dbc7Sjsg 	struct intel_dp *intel_dp;
1196c349dbc7Sjsg 	struct drm_modeset_acquire_ctx ctx;
1197c349dbc7Sjsg 	struct intel_crtc_state *crtc_state = NULL;
1198c349dbc7Sjsg 	int ret = 0;
1199c349dbc7Sjsg 	bool try_again = false;
1200c349dbc7Sjsg 
1201c349dbc7Sjsg 	drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
1202c349dbc7Sjsg 
1203c349dbc7Sjsg 	do {
1204c349dbc7Sjsg 		try_again = false;
1205c349dbc7Sjsg 		ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
1206c349dbc7Sjsg 				       &ctx);
1207c349dbc7Sjsg 		if (ret) {
1208c349dbc7Sjsg 			if (ret == -EDEADLK && !drm_modeset_backoff(&ctx)) {
1209c349dbc7Sjsg 				try_again = true;
1210c349dbc7Sjsg 				continue;
1211c349dbc7Sjsg 			}
1212c349dbc7Sjsg 			break;
1213c349dbc7Sjsg 		}
1214c349dbc7Sjsg 		crtc = connector->state->crtc;
1215c349dbc7Sjsg 		if (connector->status != connector_status_connected || !crtc) {
1216c349dbc7Sjsg 			ret = -ENODEV;
1217c349dbc7Sjsg 			break;
1218c349dbc7Sjsg 		}
1219c349dbc7Sjsg 		ret = drm_modeset_lock(&crtc->mutex, &ctx);
1220c349dbc7Sjsg 		if (ret == -EDEADLK) {
1221c349dbc7Sjsg 			ret = drm_modeset_backoff(&ctx);
1222c349dbc7Sjsg 			if (!ret) {
1223c349dbc7Sjsg 				try_again = true;
1224c349dbc7Sjsg 				continue;
1225c349dbc7Sjsg 			}
1226c349dbc7Sjsg 			break;
1227c349dbc7Sjsg 		} else if (ret) {
1228c349dbc7Sjsg 			break;
1229c349dbc7Sjsg 		}
1230c349dbc7Sjsg 		intel_dp = intel_attached_dp(to_intel_connector(connector));
1231c349dbc7Sjsg 		crtc_state = to_intel_crtc_state(crtc->state);
1232c349dbc7Sjsg 		seq_printf(m, "DSC_Enabled: %s\n",
12331bb76ff1Sjsg 			   str_yes_no(crtc_state->dsc.compression_enable));
1234c349dbc7Sjsg 		seq_printf(m, "DSC_Sink_Support: %s\n",
12351bb76ff1Sjsg 			   str_yes_no(drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)));
1236*f005ef32Sjsg 		seq_printf(m, "DSC_Output_Format_Sink_Support: RGB: %s YCBCR420: %s YCBCR444: %s\n",
1237*f005ef32Sjsg 			   str_yes_no(drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd,
1238*f005ef32Sjsg 								      DP_DSC_RGB)),
1239*f005ef32Sjsg 			   str_yes_no(drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd,
1240*f005ef32Sjsg 								      DP_DSC_YCbCr420_Native)),
1241*f005ef32Sjsg 			   str_yes_no(drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd,
1242*f005ef32Sjsg 								      DP_DSC_YCbCr444)));
1243c349dbc7Sjsg 		seq_printf(m, "Force_DSC_Enable: %s\n",
12441bb76ff1Sjsg 			   str_yes_no(intel_dp->force_dsc_en));
1245c349dbc7Sjsg 		if (!intel_dp_is_edp(intel_dp))
1246c349dbc7Sjsg 			seq_printf(m, "FEC_Sink_Support: %s\n",
12471bb76ff1Sjsg 				   str_yes_no(drm_dp_sink_supports_fec(intel_dp->fec_capable)));
1248c349dbc7Sjsg 	} while (try_again);
1249c349dbc7Sjsg 
1250c349dbc7Sjsg 	drm_modeset_drop_locks(&ctx);
1251c349dbc7Sjsg 	drm_modeset_acquire_fini(&ctx);
1252c349dbc7Sjsg 
1253c349dbc7Sjsg 	return ret;
1254c349dbc7Sjsg }
1255c349dbc7Sjsg 
i915_dsc_fec_support_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)1256c349dbc7Sjsg static ssize_t i915_dsc_fec_support_write(struct file *file,
1257c349dbc7Sjsg 					  const char __user *ubuf,
1258c349dbc7Sjsg 					  size_t len, loff_t *offp)
1259c349dbc7Sjsg {
1260c349dbc7Sjsg 	bool dsc_enable = false;
1261c349dbc7Sjsg 	int ret;
1262c349dbc7Sjsg 	struct drm_connector *connector =
1263c349dbc7Sjsg 		((struct seq_file *)file->private_data)->private;
1264c349dbc7Sjsg 	struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
1265c349dbc7Sjsg 	struct drm_i915_private *i915 = to_i915(encoder->base.dev);
1266c349dbc7Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1267c349dbc7Sjsg 
1268c349dbc7Sjsg 	if (len == 0)
1269c349dbc7Sjsg 		return 0;
1270c349dbc7Sjsg 
1271c349dbc7Sjsg 	drm_dbg(&i915->drm,
1272c349dbc7Sjsg 		"Copied %zu bytes from user to force DSC\n", len);
1273c349dbc7Sjsg 
1274c349dbc7Sjsg 	ret = kstrtobool_from_user(ubuf, len, &dsc_enable);
1275c349dbc7Sjsg 	if (ret < 0)
1276c349dbc7Sjsg 		return ret;
1277c349dbc7Sjsg 
1278c349dbc7Sjsg 	drm_dbg(&i915->drm, "Got %s for DSC Enable\n",
1279c349dbc7Sjsg 		(dsc_enable) ? "true" : "false");
1280c349dbc7Sjsg 	intel_dp->force_dsc_en = dsc_enable;
1281c349dbc7Sjsg 
1282c349dbc7Sjsg 	*offp += len;
1283c349dbc7Sjsg 	return len;
1284c349dbc7Sjsg }
1285c349dbc7Sjsg 
i915_dsc_fec_support_open(struct inode * inode,struct file * file)1286c349dbc7Sjsg static int i915_dsc_fec_support_open(struct inode *inode,
1287c349dbc7Sjsg 				     struct file *file)
1288c349dbc7Sjsg {
1289c349dbc7Sjsg 	return single_open(file, i915_dsc_fec_support_show,
1290c349dbc7Sjsg 			   inode->i_private);
1291c349dbc7Sjsg }
1292c349dbc7Sjsg 
1293c349dbc7Sjsg static const struct file_operations i915_dsc_fec_support_fops = {
1294c349dbc7Sjsg 	.owner = THIS_MODULE,
1295c349dbc7Sjsg 	.open = i915_dsc_fec_support_open,
1296c349dbc7Sjsg 	.read = seq_read,
1297c349dbc7Sjsg 	.llseek = seq_lseek,
1298c349dbc7Sjsg 	.release = single_release,
1299c349dbc7Sjsg 	.write = i915_dsc_fec_support_write
1300c349dbc7Sjsg };
1301c349dbc7Sjsg 
i915_dsc_bpc_show(struct seq_file * m,void * data)13021bb76ff1Sjsg static int i915_dsc_bpc_show(struct seq_file *m, void *data)
13035ca02815Sjsg {
13045ca02815Sjsg 	struct drm_connector *connector = m->private;
13055ca02815Sjsg 	struct drm_device *dev = connector->dev;
13065ca02815Sjsg 	struct drm_crtc *crtc;
13075ca02815Sjsg 	struct intel_crtc_state *crtc_state;
13085ca02815Sjsg 	struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
13095ca02815Sjsg 	int ret;
13105ca02815Sjsg 
13115ca02815Sjsg 	if (!encoder)
13125ca02815Sjsg 		return -ENODEV;
13135ca02815Sjsg 
13145ca02815Sjsg 	ret = drm_modeset_lock_single_interruptible(&dev->mode_config.connection_mutex);
13155ca02815Sjsg 	if (ret)
13165ca02815Sjsg 		return ret;
13175ca02815Sjsg 
13185ca02815Sjsg 	crtc = connector->state->crtc;
13195ca02815Sjsg 	if (connector->status != connector_status_connected || !crtc) {
13205ca02815Sjsg 		ret = -ENODEV;
13215ca02815Sjsg 		goto out;
13225ca02815Sjsg 	}
13235ca02815Sjsg 
13245ca02815Sjsg 	crtc_state = to_intel_crtc_state(crtc->state);
13251bb76ff1Sjsg 	seq_printf(m, "Input_BPC: %d\n", crtc_state->dsc.config.bits_per_component);
13265ca02815Sjsg 
13275ca02815Sjsg out:	drm_modeset_unlock(&dev->mode_config.connection_mutex);
13285ca02815Sjsg 
13295ca02815Sjsg 	return ret;
13305ca02815Sjsg }
13315ca02815Sjsg 
i915_dsc_bpc_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)13321bb76ff1Sjsg static ssize_t i915_dsc_bpc_write(struct file *file,
13335ca02815Sjsg 				  const char __user *ubuf,
13345ca02815Sjsg 				  size_t len, loff_t *offp)
13355ca02815Sjsg {
13365ca02815Sjsg 	struct drm_connector *connector =
13375ca02815Sjsg 		((struct seq_file *)file->private_data)->private;
13385ca02815Sjsg 	struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
13395ca02815Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
13401bb76ff1Sjsg 	int dsc_bpc = 0;
13415ca02815Sjsg 	int ret;
13425ca02815Sjsg 
13431bb76ff1Sjsg 	ret = kstrtoint_from_user(ubuf, len, 0, &dsc_bpc);
13445ca02815Sjsg 	if (ret < 0)
13455ca02815Sjsg 		return ret;
13465ca02815Sjsg 
13471bb76ff1Sjsg 	intel_dp->force_dsc_bpc = dsc_bpc;
13485ca02815Sjsg 	*offp += len;
13495ca02815Sjsg 
13505ca02815Sjsg 	return len;
13515ca02815Sjsg }
13525ca02815Sjsg 
i915_dsc_bpc_open(struct inode * inode,struct file * file)13531bb76ff1Sjsg static int i915_dsc_bpc_open(struct inode *inode,
13545ca02815Sjsg 			     struct file *file)
13555ca02815Sjsg {
13561bb76ff1Sjsg 	return single_open(file, i915_dsc_bpc_show, inode->i_private);
13575ca02815Sjsg }
13585ca02815Sjsg 
13591bb76ff1Sjsg static const struct file_operations i915_dsc_bpc_fops = {
13605ca02815Sjsg 	.owner = THIS_MODULE,
13611bb76ff1Sjsg 	.open = i915_dsc_bpc_open,
13625ca02815Sjsg 	.read = seq_read,
13635ca02815Sjsg 	.llseek = seq_lseek,
13645ca02815Sjsg 	.release = single_release,
13651bb76ff1Sjsg 	.write = i915_dsc_bpc_write
13665ca02815Sjsg };
13675ca02815Sjsg 
i915_dsc_output_format_show(struct seq_file * m,void * data)1368*f005ef32Sjsg static int i915_dsc_output_format_show(struct seq_file *m, void *data)
1369*f005ef32Sjsg {
1370*f005ef32Sjsg 	struct drm_connector *connector = m->private;
1371*f005ef32Sjsg 	struct drm_device *dev = connector->dev;
1372*f005ef32Sjsg 	struct drm_crtc *crtc;
1373*f005ef32Sjsg 	struct intel_crtc_state *crtc_state;
1374*f005ef32Sjsg 	struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
1375*f005ef32Sjsg 	int ret;
1376*f005ef32Sjsg 
1377*f005ef32Sjsg 	if (!encoder)
1378*f005ef32Sjsg 		return -ENODEV;
1379*f005ef32Sjsg 
1380*f005ef32Sjsg 	ret = drm_modeset_lock_single_interruptible(&dev->mode_config.connection_mutex);
1381*f005ef32Sjsg 	if (ret)
1382*f005ef32Sjsg 		return ret;
1383*f005ef32Sjsg 
1384*f005ef32Sjsg 	crtc = connector->state->crtc;
1385*f005ef32Sjsg 	if (connector->status != connector_status_connected || !crtc) {
1386*f005ef32Sjsg 		ret = -ENODEV;
1387*f005ef32Sjsg 		goto out;
1388*f005ef32Sjsg 	}
1389*f005ef32Sjsg 
1390*f005ef32Sjsg 	crtc_state = to_intel_crtc_state(crtc->state);
1391*f005ef32Sjsg 	seq_printf(m, "DSC_Output_Format: %s\n",
1392*f005ef32Sjsg 		   intel_output_format_name(crtc_state->output_format));
1393*f005ef32Sjsg 
1394*f005ef32Sjsg out:	drm_modeset_unlock(&dev->mode_config.connection_mutex);
1395*f005ef32Sjsg 
1396*f005ef32Sjsg 	return ret;
1397*f005ef32Sjsg }
1398*f005ef32Sjsg 
i915_dsc_output_format_write(struct file * file,const char __user * ubuf,size_t len,loff_t * offp)1399*f005ef32Sjsg static ssize_t i915_dsc_output_format_write(struct file *file,
1400*f005ef32Sjsg 					    const char __user *ubuf,
1401*f005ef32Sjsg 					    size_t len, loff_t *offp)
1402*f005ef32Sjsg {
1403*f005ef32Sjsg 	struct drm_connector *connector =
1404*f005ef32Sjsg 		((struct seq_file *)file->private_data)->private;
1405*f005ef32Sjsg 	struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
1406*f005ef32Sjsg 	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
1407*f005ef32Sjsg 	int dsc_output_format = 0;
1408*f005ef32Sjsg 	int ret;
1409*f005ef32Sjsg 
1410*f005ef32Sjsg 	ret = kstrtoint_from_user(ubuf, len, 0, &dsc_output_format);
1411*f005ef32Sjsg 	if (ret < 0)
1412*f005ef32Sjsg 		return ret;
1413*f005ef32Sjsg 
1414*f005ef32Sjsg 	intel_dp->force_dsc_output_format = dsc_output_format;
1415*f005ef32Sjsg 	*offp += len;
1416*f005ef32Sjsg 
1417*f005ef32Sjsg 	return len;
1418*f005ef32Sjsg }
1419*f005ef32Sjsg 
i915_dsc_output_format_open(struct inode * inode,struct file * file)1420*f005ef32Sjsg static int i915_dsc_output_format_open(struct inode *inode,
1421*f005ef32Sjsg 				       struct file *file)
1422*f005ef32Sjsg {
1423*f005ef32Sjsg 	return single_open(file, i915_dsc_output_format_show, inode->i_private);
1424*f005ef32Sjsg }
1425*f005ef32Sjsg 
1426*f005ef32Sjsg static const struct file_operations i915_dsc_output_format_fops = {
1427*f005ef32Sjsg 	.owner = THIS_MODULE,
1428*f005ef32Sjsg 	.open = i915_dsc_output_format_open,
1429*f005ef32Sjsg 	.read = seq_read,
1430*f005ef32Sjsg 	.llseek = seq_lseek,
1431*f005ef32Sjsg 	.release = single_release,
1432*f005ef32Sjsg 	.write = i915_dsc_output_format_write
1433*f005ef32Sjsg };
1434*f005ef32Sjsg 
14351bb76ff1Sjsg /*
14361bb76ff1Sjsg  * Returns the Current CRTC's bpc.
14371bb76ff1Sjsg  * Example usage: cat /sys/kernel/debug/dri/0/crtc-0/i915_current_bpc
14381bb76ff1Sjsg  */
i915_current_bpc_show(struct seq_file * m,void * data)14391bb76ff1Sjsg static int i915_current_bpc_show(struct seq_file *m, void *data)
14401bb76ff1Sjsg {
1441*f005ef32Sjsg 	struct intel_crtc *crtc = m->private;
14421bb76ff1Sjsg 	struct intel_crtc_state *crtc_state;
14431bb76ff1Sjsg 	int ret;
14441bb76ff1Sjsg 
14451bb76ff1Sjsg 	ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
14461bb76ff1Sjsg 	if (ret)
14471bb76ff1Sjsg 		return ret;
14481bb76ff1Sjsg 
14491bb76ff1Sjsg 	crtc_state = to_intel_crtc_state(crtc->base.state);
14501bb76ff1Sjsg 	seq_printf(m, "Current: %u\n", crtc_state->pipe_bpp / 3);
14511bb76ff1Sjsg 
14521bb76ff1Sjsg 	drm_modeset_unlock(&crtc->base.mutex);
14531bb76ff1Sjsg 
14541bb76ff1Sjsg 	return ret;
14551bb76ff1Sjsg }
14561bb76ff1Sjsg DEFINE_SHOW_ATTRIBUTE(i915_current_bpc);
14571bb76ff1Sjsg 
1458*f005ef32Sjsg /* Pipe may differ from crtc index if pipes are fused off */
intel_crtc_pipe_show(struct seq_file * m,void * unused)1459*f005ef32Sjsg static int intel_crtc_pipe_show(struct seq_file *m, void *unused)
1460*f005ef32Sjsg {
1461*f005ef32Sjsg 	struct intel_crtc *crtc = m->private;
1462*f005ef32Sjsg 
1463*f005ef32Sjsg 	seq_printf(m, "%c\n", pipe_name(crtc->pipe));
1464*f005ef32Sjsg 
1465*f005ef32Sjsg 	return 0;
1466*f005ef32Sjsg }
1467*f005ef32Sjsg DEFINE_SHOW_ATTRIBUTE(intel_crtc_pipe);
1468*f005ef32Sjsg 
1469c349dbc7Sjsg /**
1470c349dbc7Sjsg  * intel_connector_debugfs_add - add i915 specific connector debugfs files
1471*f005ef32Sjsg  * @intel_connector: pointer to a registered drm_connector
1472c349dbc7Sjsg  *
1473c349dbc7Sjsg  * Cleanup will be done by drm_connector_unregister() through a call to
1474c349dbc7Sjsg  * drm_debugfs_connector_remove().
1475c349dbc7Sjsg  */
intel_connector_debugfs_add(struct intel_connector * intel_connector)14761bb76ff1Sjsg void intel_connector_debugfs_add(struct intel_connector *intel_connector)
1477c349dbc7Sjsg {
14781bb76ff1Sjsg 	struct drm_connector *connector = &intel_connector->base;
1479c349dbc7Sjsg 	struct dentry *root = connector->debugfs_entry;
1480c349dbc7Sjsg 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
1481c349dbc7Sjsg 
1482c349dbc7Sjsg 	/* The connector must have been registered beforehands. */
1483c349dbc7Sjsg 	if (!root)
14841bb76ff1Sjsg 		return;
1485c349dbc7Sjsg 
1486*f005ef32Sjsg 	intel_drrs_connector_debugfs_add(intel_connector);
1487*f005ef32Sjsg 	intel_psr_connector_debugfs_add(intel_connector);
1488*f005ef32Sjsg 
1489*f005ef32Sjsg 	if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
1490c349dbc7Sjsg 		debugfs_create_file("i915_panel_timings", S_IRUGO, root,
1491c349dbc7Sjsg 				    connector, &i915_panel_fops);
14925ca02815Sjsg 
1493c349dbc7Sjsg 	if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
1494c349dbc7Sjsg 	    connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
1495c349dbc7Sjsg 	    connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
1496c349dbc7Sjsg 		debugfs_create_file("i915_hdcp_sink_capability", S_IRUGO, root,
1497c349dbc7Sjsg 				    connector, &i915_hdcp_sink_capability_fops);
1498c349dbc7Sjsg 	}
1499c349dbc7Sjsg 
15005ca02815Sjsg 	if (DISPLAY_VER(dev_priv) >= 11 &&
1501ad8b1aafSjsg 	    ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort &&
1502ad8b1aafSjsg 	    !to_intel_connector(connector)->mst_port) ||
15035ca02815Sjsg 	    connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
15045ca02815Sjsg 		debugfs_create_file("i915_dsc_fec_support", 0644, root,
1505c349dbc7Sjsg 				    connector, &i915_dsc_fec_support_fops);
1506c349dbc7Sjsg 
15071bb76ff1Sjsg 		debugfs_create_file("i915_dsc_bpc", 0644, root,
15081bb76ff1Sjsg 				    connector, &i915_dsc_bpc_fops);
1509*f005ef32Sjsg 
1510*f005ef32Sjsg 		debugfs_create_file("i915_dsc_output_format", 0644, root,
1511*f005ef32Sjsg 				    connector, &i915_dsc_output_format_fops);
15125ca02815Sjsg 	}
15135ca02815Sjsg 
15141bb76ff1Sjsg 	if (connector->connector_type == DRM_MODE_CONNECTOR_DSI ||
1515ad8b1aafSjsg 	    connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
1516ad8b1aafSjsg 	    connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
1517ad8b1aafSjsg 	    connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
15181bb76ff1Sjsg 	    connector->connector_type == DRM_MODE_CONNECTOR_HDMIB)
1519ad8b1aafSjsg 		debugfs_create_file("i915_lpsp_capability", 0444, root,
1520ad8b1aafSjsg 				    connector, &i915_lpsp_capability_fops);
1521c349dbc7Sjsg }
15225ca02815Sjsg 
15235ca02815Sjsg /**
15245ca02815Sjsg  * intel_crtc_debugfs_add - add i915 specific crtc debugfs files
15255ca02815Sjsg  * @crtc: pointer to a drm_crtc
15265ca02815Sjsg  *
15275ca02815Sjsg  * Failure to add debugfs entries should generally be ignored.
15285ca02815Sjsg  */
intel_crtc_debugfs_add(struct intel_crtc * crtc)1529*f005ef32Sjsg void intel_crtc_debugfs_add(struct intel_crtc *crtc)
15305ca02815Sjsg {
1531*f005ef32Sjsg 	struct dentry *root = crtc->base.debugfs_entry;
1532*f005ef32Sjsg 
1533*f005ef32Sjsg 	if (!root)
15341bb76ff1Sjsg 		return;
15355ca02815Sjsg 
15365ca02815Sjsg 	crtc_updates_add(crtc);
1537*f005ef32Sjsg 	intel_drrs_crtc_debugfs_add(crtc);
1538*f005ef32Sjsg 	intel_fbc_crtc_debugfs_add(crtc);
1539*f005ef32Sjsg 	hsw_ips_crtc_debugfs_add(crtc);
15401bb76ff1Sjsg 
1541*f005ef32Sjsg 	debugfs_create_file("i915_current_bpc", 0444, root, crtc,
15421bb76ff1Sjsg 			    &i915_current_bpc_fops);
1543*f005ef32Sjsg 	debugfs_create_file("i915_pipe", 0444, root, crtc,
1544*f005ef32Sjsg 			    &intel_crtc_pipe_fops);
15455ca02815Sjsg }
1546