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