From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Jani Nikula <jani.nikula@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [Intel-gfx] [PATCH] drm/i915: split out display debugfs to a separate file
Date: Tue, 4 Feb 2020 17:29:27 +0200 [thread overview]
Message-ID: <20200204152927.GA13686@intel.com> (raw)
In-Reply-To: <20200204151810.8189-1-jani.nikula@intel.com>
On Tue, Feb 04, 2020 at 05:18:10PM +0200, Jani Nikula wrote:
> The i915_debugfs.c has grown more than a little unwieldy. Split out the
> display related debugfs code to a file of its own under display/,
> initialized with a separate call. No functional changes.
>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
> drivers/gpu/drm/i915/Makefile | 1 +
> .../drm/i915/display/intel_display_debugfs.c | 1921 ++++++++++++++++
> .../drm/i915/display/intel_display_debugfs.h | 20 +
> drivers/gpu/drm/i915/display/intel_dp.c | 3 +-
> drivers/gpu/drm/i915/display/intel_hdmi.c | 3 +-
> drivers/gpu/drm/i915/i915_debugfs.c | 2032 +----------------
> drivers/gpu/drm/i915/i915_debugfs.h | 2 -
> drivers/gpu/drm/i915/i915_drv.c | 2 +
> 8 files changed, 2028 insertions(+), 1956 deletions(-)
> create mode 100644 drivers/gpu/drm/i915/display/intel_display_debugfs.c
> create mode 100644 drivers/gpu/drm/i915/display/intel_display_debugfs.h
>
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 787ffe669810..ed91f6be19c6 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -69,6 +69,7 @@ i915-$(CONFIG_COMPAT) += i915_ioc32.o
> i915-$(CONFIG_DEBUG_FS) += \
> i915_debugfs.o \
> i915_debugfs_params.o \
> + display/intel_display_debugfs.o \
> display/intel_pipe_crc.o
> i915-$(CONFIG_PERF_EVENTS) += i915_pmu.o
>
> diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.c b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> new file mode 100644
> index 000000000000..9e252b508479
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.c
> @@ -0,0 +1,1921 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2020 Intel Corporation
> + */
> +
> +#include <drm/drm_debugfs.h>
> +#include <drm/drm_fourcc.h>
> +
> +#include "intel_display_debugfs.h"
> +#include "intel_display_types.h"
> +#include "intel_dp.h"
> +#include "intel_fbc.h"
> +#include "intel_hdcp.h"
> +#include "intel_hdmi.h"
> +#include "intel_pm.h"
> +#include "intel_psr.h"
> +#include "intel_sideband.h"
> +
> +static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node)
> +{
> + return to_i915(node->minor->dev);
> +}
> +
> +static int i915_fbc_status(struct seq_file *m, void *unused)
> +{
> + struct drm_i915_private *dev_priv = node_to_i915(m->private);
> + struct intel_fbc *fbc = &dev_priv->fbc;
> + intel_wakeref_t wakeref;
> +
> + if (!HAS_FBC(dev_priv))
> + return -ENODEV;
> +
> + wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> + mutex_lock(&fbc->lock);
> +
> + if (intel_fbc_is_active(dev_priv))
> + seq_puts(m, "FBC enabled\n");
> + else
> + seq_printf(m, "FBC disabled: %s\n", fbc->no_fbc_reason);
> +
> + if (intel_fbc_is_active(dev_priv)) {
> + u32 mask;
> +
> + if (INTEL_GEN(dev_priv) >= 8)
> + mask = I915_READ(IVB_FBC_STATUS2) & BDW_FBC_COMP_SEG_MASK;
> + else if (INTEL_GEN(dev_priv) >= 7)
> + mask = I915_READ(IVB_FBC_STATUS2) & IVB_FBC_COMP_SEG_MASK;
> + else if (INTEL_GEN(dev_priv) >= 5)
> + mask = I915_READ(ILK_DPFC_STATUS) & ILK_DPFC_COMP_SEG_MASK;
> + else if (IS_G4X(dev_priv))
> + mask = I915_READ(DPFC_STATUS) & DPFC_COMP_SEG_MASK;
> + else
> + mask = I915_READ(FBC_STATUS) & (FBC_STAT_COMPRESSING |
> + FBC_STAT_COMPRESSED);
> +
> + seq_printf(m, "Compressing: %s\n", yesno(mask));
> + }
> +
> + mutex_unlock(&fbc->lock);
> + intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
> +
> + return 0;
> +}
> +
> +static int i915_fbc_false_color_get(void *data, u64 *val)
> +{
> + struct drm_i915_private *dev_priv = data;
> +
> + if (INTEL_GEN(dev_priv) < 7 || !HAS_FBC(dev_priv))
> + return -ENODEV;
> +
> + *val = dev_priv->fbc.false_color;
> +
> + return 0;
> +}
> +
> +static int i915_fbc_false_color_set(void *data, u64 val)
> +{
> + struct drm_i915_private *dev_priv = data;
> + u32 reg;
> +
> + if (INTEL_GEN(dev_priv) < 7 || !HAS_FBC(dev_priv))
> + return -ENODEV;
> +
> + mutex_lock(&dev_priv->fbc.lock);
> +
> + reg = I915_READ(ILK_DPFC_CONTROL);
> + dev_priv->fbc.false_color = val;
> +
> + I915_WRITE(ILK_DPFC_CONTROL, val ?
> + (reg | FBC_CTL_FALSE_COLOR) :
> + (reg & ~FBC_CTL_FALSE_COLOR));
> +
> + mutex_unlock(&dev_priv->fbc.lock);
> + return 0;
> +}
> +
> +DEFINE_SIMPLE_ATTRIBUTE(i915_fbc_false_color_fops,
> + i915_fbc_false_color_get, i915_fbc_false_color_set,
> + "%llu\n");
> +
> +static int i915_ips_status(struct seq_file *m, void *unused)
> +{
> + struct drm_i915_private *dev_priv = node_to_i915(m->private);
> + intel_wakeref_t wakeref;
> +
> + if (!HAS_IPS(dev_priv))
> + return -ENODEV;
> +
> + wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> +
> + seq_printf(m, "Enabled by kernel parameter: %s\n",
> + yesno(i915_modparams.enable_ips));
> +
> + if (INTEL_GEN(dev_priv) >= 8) {
> + seq_puts(m, "Currently: unknown\n");
> + } else {
> + if (I915_READ(IPS_CTL) & IPS_ENABLE)
> + seq_puts(m, "Currently: enabled\n");
> + else
> + seq_puts(m, "Currently: disabled\n");
> + }
> +
> + intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
> +
> + return 0;
> +}
> +
> +static int i915_sr_status(struct seq_file *m, void *unused)
> +{
> + struct drm_i915_private *dev_priv = node_to_i915(m->private);
> + intel_wakeref_t wakeref;
> + bool sr_enabled = false;
> +
> + wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
> +
> + if (INTEL_GEN(dev_priv) >= 9)
> + /* no global SR status; inspect per-plane WM */;
> + else if (HAS_PCH_SPLIT(dev_priv))
> + sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN;
> + else if (IS_I965GM(dev_priv) || IS_G4X(dev_priv) ||
> + IS_I945G(dev_priv) || IS_I945GM(dev_priv))
> + sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN;
> + else if (IS_I915GM(dev_priv))
> + sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN;
> + else if (IS_PINEVIEW(dev_priv))
> + sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN;
> + else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> + sr_enabled = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN;
> +
> + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref);
> +
> + seq_printf(m, "self-refresh: %s\n", enableddisabled(sr_enabled));
> +
> + return 0;
> +}
> +
> +static int i915_opregion(struct seq_file *m, void *unused)
> +{
> + struct intel_opregion *opregion = &node_to_i915(m->private)->opregion;
> +
> + if (opregion->header)
> + seq_write(m, opregion->header, OPREGION_SIZE);
> +
> + return 0;
> +}
> +
> +static int i915_vbt(struct seq_file *m, void *unused)
> +{
> + struct intel_opregion *opregion = &node_to_i915(m->private)->opregion;
> +
> + if (opregion->vbt)
> + seq_write(m, opregion->vbt, opregion->vbt_size);
> +
> + return 0;
> +}
> +
> +static int i915_psr_sink_status_show(struct seq_file *m, void *data)
> +{
> + u8 val;
> + static const char * const sink_status[] = {
> + "inactive",
> + "transition to active, capture and display",
> + "active, display from RFB",
> + "active, capture and display on sink device timings",
> + "transition to inactive, capture and display, timing re-sync",
> + "reserved",
> + "reserved",
> + "sink internal error",
> + };
> + struct drm_connector *connector = m->private;
> + struct drm_i915_private *dev_priv = to_i915(connector->dev);
> + struct intel_dp *intel_dp =
> + intel_attached_dp(to_intel_connector(connector));
> + int ret;
> +
> + if (!CAN_PSR(dev_priv)) {
> + seq_puts(m, "PSR Unsupported\n");
> + return -ENODEV;
> + }
> +
> + if (connector->status != connector_status_connected)
> + return -ENODEV;
> +
> + ret = drm_dp_dpcd_readb(&intel_dp->aux, DP_PSR_STATUS, &val);
> +
> + if (ret == 1) {
> + const char *str = "unknown";
> +
> + val &= DP_PSR_SINK_STATE_MASK;
> + if (val < ARRAY_SIZE(sink_status))
> + str = sink_status[val];
> + seq_printf(m, "Sink PSR status: 0x%x [%s]\n", val, str);
> + } else {
> + return ret;
> + }
> +
> + return 0;
> +}
> +DEFINE_SHOW_ATTRIBUTE(i915_psr_sink_status);
> +
> +static void
> +psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m)
> +{
> + u32 val, status_val;
> + const char *status = "unknown";
> +
> + if (dev_priv->psr.psr2_enabled) {
> + static const char * const live_status[] = {
> + "IDLE",
> + "CAPTURE",
> + "CAPTURE_FS",
> + "SLEEP",
> + "BUFON_FW",
> + "ML_UP",
> + "SU_STANDBY",
> + "FAST_SLEEP",
> + "DEEP_SLEEP",
> + "BUF_ON",
> + "TG_ON"
> + };
> + val = I915_READ(EDP_PSR2_STATUS(dev_priv->psr.transcoder));
> + status_val = (val & EDP_PSR2_STATUS_STATE_MASK) >>
> + EDP_PSR2_STATUS_STATE_SHIFT;
> + if (status_val < ARRAY_SIZE(live_status))
> + status = live_status[status_val];
> + } else {
> + static const char * const live_status[] = {
> + "IDLE",
> + "SRDONACK",
> + "SRDENT",
> + "BUFOFF",
> + "BUFON",
> + "AUXACK",
> + "SRDOFFACK",
> + "SRDENT_ON",
> + };
> + val = I915_READ(EDP_PSR_STATUS(dev_priv->psr.transcoder));
> + status_val = (val & EDP_PSR_STATUS_STATE_MASK) >>
> + EDP_PSR_STATUS_STATE_SHIFT;
> + if (status_val < ARRAY_SIZE(live_status))
> + status = live_status[status_val];
> + }
> +
> + seq_printf(m, "Source PSR status: %s [0x%08x]\n", status, val);
> +}
> +
> +static int i915_edp_psr_status(struct seq_file *m, void *data)
> +{
> + struct drm_i915_private *dev_priv = node_to_i915(m->private);
> + struct i915_psr *psr = &dev_priv->psr;
> + intel_wakeref_t wakeref;
> + const char *status;
> + bool enabled;
> + u32 val;
> +
> + if (!HAS_PSR(dev_priv))
> + return -ENODEV;
> +
> + seq_printf(m, "Sink support: %s", yesno(psr->sink_support));
> + if (psr->dp)
> + seq_printf(m, " [0x%02x]", psr->dp->psr_dpcd[0]);
> + seq_puts(m, "\n");
> +
> + if (!psr->sink_support)
> + return 0;
> +
> + wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> + mutex_lock(&psr->lock);
> +
> + if (psr->enabled)
> + status = psr->psr2_enabled ? "PSR2 enabled" : "PSR1 enabled";
> + else
> + status = "disabled";
> + seq_printf(m, "PSR mode: %s\n", status);
> +
> + if (!psr->enabled) {
> + seq_printf(m, "PSR sink not reliable: %s\n",
> + yesno(psr->sink_not_reliable));
> +
> + goto unlock;
> + }
> +
> + if (psr->psr2_enabled) {
> + val = I915_READ(EDP_PSR2_CTL(dev_priv->psr.transcoder));
> + enabled = val & EDP_PSR2_ENABLE;
> + } else {
> + val = I915_READ(EDP_PSR_CTL(dev_priv->psr.transcoder));
> + enabled = val & EDP_PSR_ENABLE;
> + }
> + seq_printf(m, "Source PSR ctl: %s [0x%08x]\n",
> + enableddisabled(enabled), val);
> + psr_source_status(dev_priv, m);
> + seq_printf(m, "Busy frontbuffer bits: 0x%08x\n",
> + psr->busy_frontbuffer_bits);
> +
> + /*
> + * SKL+ Perf counter is reset to 0 everytime DC state is entered
> + */
> + if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> + val = I915_READ(EDP_PSR_PERF_CNT(dev_priv->psr.transcoder));
> + val &= EDP_PSR_PERF_CNT_MASK;
> + seq_printf(m, "Performance counter: %u\n", val);
> + }
> +
> + if (psr->debug & I915_PSR_DEBUG_IRQ) {
> + seq_printf(m, "Last attempted entry at: %lld\n",
> + psr->last_entry_attempt);
> + seq_printf(m, "Last exit at: %lld\n", psr->last_exit);
> + }
> +
> + if (psr->psr2_enabled) {
> + u32 su_frames_val[3];
> + int frame;
> +
> + /*
> + * Reading all 3 registers before hand to minimize crossing a
> + * frame boundary between register reads
> + */
> + for (frame = 0; frame < PSR2_SU_STATUS_FRAMES; frame += 3) {
> + val = I915_READ(PSR2_SU_STATUS(dev_priv->psr.transcoder,
> + frame));
> + su_frames_val[frame / 3] = val;
> + }
> +
> + seq_puts(m, "Frame:\tPSR2 SU blocks:\n");
> +
> + for (frame = 0; frame < PSR2_SU_STATUS_FRAMES; frame++) {
> + u32 su_blocks;
> +
> + su_blocks = su_frames_val[frame / 3] &
> + PSR2_SU_STATUS_MASK(frame);
> + su_blocks = su_blocks >> PSR2_SU_STATUS_SHIFT(frame);
> + seq_printf(m, "%d\t%d\n", frame, su_blocks);
> + }
> + }
> +
> +unlock:
> + mutex_unlock(&psr->lock);
> + intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
> +
> + return 0;
> +}
> +
> +static int
> +i915_edp_psr_debug_set(void *data, u64 val)
> +{
> + struct drm_i915_private *dev_priv = data;
> + intel_wakeref_t wakeref;
> + int ret;
> +
> + if (!CAN_PSR(dev_priv))
> + return -ENODEV;
> +
> + drm_dbg_kms(&dev_priv->drm, "Setting PSR debug to %llx\n", val);
> +
> + wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> +
> + ret = intel_psr_debug_set(dev_priv, val);
> +
> + intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
> +
> + return ret;
> +}
> +
> +static int
> +i915_edp_psr_debug_get(void *data, u64 *val)
> +{
> + struct drm_i915_private *dev_priv = data;
> +
> + if (!CAN_PSR(dev_priv))
> + return -ENODEV;
> +
> + *val = READ_ONCE(dev_priv->psr.debug);
> + return 0;
> +}
> +
> +DEFINE_SIMPLE_ATTRIBUTE(i915_edp_psr_debug_fops,
> + i915_edp_psr_debug_get, i915_edp_psr_debug_set,
> + "%llu\n");
> +
> +static void intel_seq_print_mode(struct seq_file *m, int tabs,
> + const struct drm_display_mode *mode)
> +{
> + int i;
> +
> + for (i = 0; i < tabs; i++)
> + seq_putc(m, '\t');
> +
> + seq_printf(m, DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
> +}
> +
> +static void intel_encoder_info(struct seq_file *m,
> + struct intel_crtc *crtc,
> + struct intel_encoder *encoder)
> +{
> + struct drm_i915_private *dev_priv = node_to_i915(m->private);
> + struct drm_connector_list_iter conn_iter;
> + struct drm_connector *connector;
> +
> + seq_printf(m, "\t[ENCODER:%d:%s]: connectors:\n",
> + encoder->base.base.id, encoder->base.name);
> +
> + drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
> + drm_for_each_connector_iter(connector, &conn_iter) {
> + const struct drm_connector_state *conn_state =
> + connector->state;
> +
> + if (conn_state->best_encoder != &encoder->base)
> + continue;
> +
> + seq_printf(m, "\t\t[CONNECTOR:%d:%s]\n",
> + connector->base.id, connector->name);
> + }
> + drm_connector_list_iter_end(&conn_iter);
> +}
> +
> +static void intel_panel_info(struct seq_file *m, struct intel_panel *panel)
> +{
> + const struct drm_display_mode *mode = panel->fixed_mode;
> +
> + seq_printf(m, "\tfixed mode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
> +}
> +
> +static void intel_hdcp_info(struct seq_file *m,
> + struct intel_connector *intel_connector)
> +{
> + bool hdcp_cap, hdcp2_cap;
> +
> + hdcp_cap = intel_hdcp_capable(intel_connector);
> + hdcp2_cap = intel_hdcp2_capable(intel_connector);
> +
> + if (hdcp_cap)
> + seq_puts(m, "HDCP1.4 ");
> + if (hdcp2_cap)
> + seq_puts(m, "HDCP2.2 ");
> +
> + if (!hdcp_cap && !hdcp2_cap)
> + seq_puts(m, "None");
> +
> + seq_puts(m, "\n");
> +}
> +
> +static void intel_dp_info(struct seq_file *m,
> + struct intel_connector *intel_connector)
> +{
> + struct intel_encoder *intel_encoder = intel_attached_encoder(intel_connector);
> + struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder);
> +
> + seq_printf(m, "\tDPCD rev: %x\n", intel_dp->dpcd[DP_DPCD_REV]);
> + seq_printf(m, "\taudio support: %s\n", yesno(intel_dp->has_audio));
> + if (intel_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
> + intel_panel_info(m, &intel_connector->panel);
> +
> + drm_dp_downstream_debug(m, intel_dp->dpcd, intel_dp->downstream_ports,
> + &intel_dp->aux);
> + if (intel_connector->hdcp.shim) {
> + seq_puts(m, "\tHDCP version: ");
> + intel_hdcp_info(m, intel_connector);
> + }
> +}
> +
> +static void intel_dp_mst_info(struct seq_file *m,
> + struct intel_connector *intel_connector)
> +{
> + struct intel_encoder *intel_encoder = intel_attached_encoder(intel_connector);
> + struct intel_dp_mst_encoder *intel_mst =
> + enc_to_mst(intel_encoder);
> + struct intel_digital_port *intel_dig_port = intel_mst->primary;
> + struct intel_dp *intel_dp = &intel_dig_port->dp;
> + bool has_audio = drm_dp_mst_port_has_audio(&intel_dp->mst_mgr,
> + intel_connector->port);
> +
> + seq_printf(m, "\taudio support: %s\n", yesno(has_audio));
> +}
> +
> +static void intel_hdmi_info(struct seq_file *m,
> + struct intel_connector *intel_connector)
> +{
> + struct intel_encoder *intel_encoder = intel_attached_encoder(intel_connector);
> + struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(intel_encoder);
> +
> + seq_printf(m, "\taudio support: %s\n", yesno(intel_hdmi->has_audio));
> + if (intel_connector->hdcp.shim) {
> + seq_puts(m, "\tHDCP version: ");
> + intel_hdcp_info(m, intel_connector);
> + }
> +}
> +
> +static void intel_lvds_info(struct seq_file *m,
> + struct intel_connector *intel_connector)
> +{
> + intel_panel_info(m, &intel_connector->panel);
> +}
> +
> +static void intel_connector_info(struct seq_file *m,
> + struct drm_connector *connector)
> +{
> + struct intel_connector *intel_connector = to_intel_connector(connector);
> + const struct drm_connector_state *conn_state = connector->state;
> + struct intel_encoder *encoder =
> + to_intel_encoder(conn_state->best_encoder);
> + const struct drm_display_mode *mode;
> +
> + seq_printf(m, "[CONNECTOR:%d:%s]: status: %s\n",
> + connector->base.id, connector->name,
> + drm_get_connector_status_name(connector->status));
> +
> + if (connector->status == connector_status_disconnected)
> + return;
> +
> + seq_printf(m, "\tphysical dimensions: %dx%dmm\n",
> + connector->display_info.width_mm,
> + connector->display_info.height_mm);
> + seq_printf(m, "\tsubpixel order: %s\n",
> + drm_get_subpixel_order_name(connector->display_info.subpixel_order));
> + seq_printf(m, "\tCEA rev: %d\n", connector->display_info.cea_rev);
> +
> + if (!encoder)
> + return;
> +
> + switch (connector->connector_type) {
> + case DRM_MODE_CONNECTOR_DisplayPort:
> + case DRM_MODE_CONNECTOR_eDP:
> + if (encoder->type == INTEL_OUTPUT_DP_MST)
> + intel_dp_mst_info(m, intel_connector);
> + else
> + intel_dp_info(m, intel_connector);
> + break;
> + case DRM_MODE_CONNECTOR_LVDS:
> + if (encoder->type == INTEL_OUTPUT_LVDS)
> + intel_lvds_info(m, intel_connector);
> + break;
> + case DRM_MODE_CONNECTOR_HDMIA:
> + if (encoder->type == INTEL_OUTPUT_HDMI ||
> + encoder->type == INTEL_OUTPUT_DDI)
> + intel_hdmi_info(m, intel_connector);
> + break;
> + default:
> + break;
> + }
> +
> + seq_printf(m, "\tmodes:\n");
> + list_for_each_entry(mode, &connector->modes, head)
> + intel_seq_print_mode(m, 2, mode);
> +}
> +
> +static const char *plane_type(enum drm_plane_type type)
> +{
> + switch (type) {
> + case DRM_PLANE_TYPE_OVERLAY:
> + return "OVL";
> + case DRM_PLANE_TYPE_PRIMARY:
> + return "PRI";
> + case DRM_PLANE_TYPE_CURSOR:
> + return "CUR";
> + /*
> + * Deliberately omitting default: to generate compiler warnings
> + * when a new drm_plane_type gets added.
> + */
> + }
> +
> + return "unknown";
> +}
> +
> +static void plane_rotation(char *buf, size_t bufsize, unsigned int rotation)
> +{
> + /*
> + * According to doc only one DRM_MODE_ROTATE_ is allowed but this
> + * will print them all to visualize if the values are misused
> + */
> + snprintf(buf, bufsize,
> + "%s%s%s%s%s%s(0x%08x)",
> + (rotation & DRM_MODE_ROTATE_0) ? "0 " : "",
> + (rotation & DRM_MODE_ROTATE_90) ? "90 " : "",
> + (rotation & DRM_MODE_ROTATE_180) ? "180 " : "",
> + (rotation & DRM_MODE_ROTATE_270) ? "270 " : "",
> + (rotation & DRM_MODE_REFLECT_X) ? "FLIPX " : "",
> + (rotation & DRM_MODE_REFLECT_Y) ? "FLIPY " : "",
> + rotation);
> +}
> +
> +static void intel_plane_uapi_info(struct seq_file *m, struct intel_plane *plane)
> +{
> + const struct intel_plane_state *plane_state =
> + to_intel_plane_state(plane->base.state);
> + const struct drm_framebuffer *fb = plane_state->uapi.fb;
> + struct drm_format_name_buf format_name;
> + struct drm_rect src, dst;
> + char rot_str[48];
> +
> + src = drm_plane_state_src(&plane_state->uapi);
> + dst = drm_plane_state_dest(&plane_state->uapi);
> +
> + if (fb)
> + drm_get_format_name(fb->format->format, &format_name);
> +
> + plane_rotation(rot_str, sizeof(rot_str),
> + plane_state->uapi.rotation);
> +
> + seq_printf(m, "\t\tuapi: fb=%d,%s,%dx%d, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",
> + fb ? fb->base.id : 0, fb ? format_name.str : "n/a",
> + fb ? fb->width : 0, fb ? fb->height : 0,
> + DRM_RECT_FP_ARG(&src),
> + DRM_RECT_ARG(&dst),
> + rot_str);
> +}
> +
> +static void intel_plane_hw_info(struct seq_file *m, struct intel_plane *plane)
> +{
> + const struct intel_plane_state *plane_state =
> + to_intel_plane_state(plane->base.state);
> + const struct drm_framebuffer *fb = plane_state->hw.fb;
> + struct drm_format_name_buf format_name;
> + char rot_str[48];
> +
> + if (!fb)
> + return;
> +
> + drm_get_format_name(fb->format->format, &format_name);
> +
> + plane_rotation(rot_str, sizeof(rot_str),
> + plane_state->hw.rotation);
> +
> + seq_printf(m, "\t\thw: fb=%d,%s,%dx%d, visible=%s, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",
> + fb->base.id, format_name.str,
> + fb->width, fb->height,
> + yesno(plane_state->uapi.visible),
> + DRM_RECT_FP_ARG(&plane_state->uapi.src),
> + DRM_RECT_ARG(&plane_state->uapi.dst),
> + rot_str);
> +}
> +
> +static void intel_plane_info(struct seq_file *m, struct intel_crtc *crtc)
> +{
> + struct drm_i915_private *dev_priv = node_to_i915(m->private);
> + struct intel_plane *plane;
> +
> + for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
> + seq_printf(m, "\t[PLANE:%d:%s]: type=%s\n",
> + plane->base.base.id, plane->base.name,
> + plane_type(plane->base.type));
> + intel_plane_uapi_info(m, plane);
> + intel_plane_hw_info(m, plane);
> + }
> +}
> +
> +static void intel_scaler_info(struct seq_file *m, struct intel_crtc *crtc)
> +{
> + const struct intel_crtc_state *crtc_state =
> + to_intel_crtc_state(crtc->base.state);
> + int num_scalers = crtc->num_scalers;
> + int i;
> +
> + /* Not all platformas have a scaler */
> + if (num_scalers) {
> + seq_printf(m, "\tnum_scalers=%d, scaler_users=%x scaler_id=%d",
> + num_scalers,
> + crtc_state->scaler_state.scaler_users,
> + crtc_state->scaler_state.scaler_id);
> +
> + for (i = 0; i < num_scalers; i++) {
> + const struct intel_scaler *sc =
> + &crtc_state->scaler_state.scalers[i];
> +
> + seq_printf(m, ", scalers[%d]: use=%s, mode=%x",
> + i, yesno(sc->in_use), sc->mode);
> + }
> + seq_puts(m, "\n");
> + } else {
> + seq_puts(m, "\tNo scalers available on this platform\n");
> + }
> +}
> +
> +static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
> +{
> + struct drm_i915_private *dev_priv = node_to_i915(m->private);
> + const struct intel_crtc_state *crtc_state =
> + to_intel_crtc_state(crtc->base.state);
> + struct intel_encoder *encoder;
> +
> + seq_printf(m, "[CRTC:%d:%s]:\n",
> + crtc->base.base.id, crtc->base.name);
> +
> + seq_printf(m, "\tuapi: enable=%s, active=%s, mode=" DRM_MODE_FMT "\n",
> + yesno(crtc_state->uapi.enable),
> + yesno(crtc_state->uapi.active),
> + DRM_MODE_ARG(&crtc_state->uapi.mode));
> +
> + if (crtc_state->hw.enable) {
> + seq_printf(m, "\thw: active=%s, adjusted_mode=" DRM_MODE_FMT "\n",
> + yesno(crtc_state->hw.active),
> + DRM_MODE_ARG(&crtc_state->hw.adjusted_mode));
> +
> + seq_printf(m, "\tpipe src size=%dx%d, dither=%s, bpp=%d\n",
> + crtc_state->pipe_src_w, crtc_state->pipe_src_h,
> + yesno(crtc_state->dither), crtc_state->pipe_bpp);
> +
> + intel_scaler_info(m, crtc);
> + }
> +
> + for_each_intel_encoder_mask(&dev_priv->drm, encoder,
> + crtc_state->uapi.encoder_mask)
> + intel_encoder_info(m, crtc, encoder);
> +
> + intel_plane_info(m, crtc);
> +
> + seq_printf(m, "\tunderrun reporting: cpu=%s pch=%s\n",
> + yesno(!crtc->cpu_fifo_underrun_disabled),
> + yesno(!crtc->pch_fifo_underrun_disabled));
> +}
> +
> +static int i915_display_info(struct seq_file *m, void *unused)
> +{
> + struct drm_i915_private *dev_priv = node_to_i915(m->private);
> + struct drm_device *dev = &dev_priv->drm;
> + struct intel_crtc *crtc;
> + struct drm_connector *connector;
> + struct drm_connector_list_iter conn_iter;
> + intel_wakeref_t wakeref;
> +
> + wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> +
> + drm_modeset_lock_all(dev);
> +
> + seq_printf(m, "CRTC info\n");
> + seq_printf(m, "---------\n");
> + for_each_intel_crtc(dev, crtc)
> + intel_crtc_info(m, crtc);
> +
> + seq_printf(m, "\n");
> + seq_printf(m, "Connector info\n");
> + seq_printf(m, "--------------\n");
> + drm_connector_list_iter_begin(dev, &conn_iter);
> + drm_for_each_connector_iter(connector, &conn_iter)
> + intel_connector_info(m, connector);
> + drm_connector_list_iter_end(&conn_iter);
> +
> + drm_modeset_unlock_all(dev);
> +
> + intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
> +
> + return 0;
> +}
> +
> +static int i915_shared_dplls_info(struct seq_file *m, void *unused)
> +{
> + struct drm_i915_private *dev_priv = node_to_i915(m->private);
> + struct drm_device *dev = &dev_priv->drm;
> + int i;
> +
> + drm_modeset_lock_all(dev);
> + for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> + struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
> +
> + seq_printf(m, "DPLL%i: %s, id: %i\n", i, pll->info->name,
> + pll->info->id);
> + seq_printf(m, " crtc_mask: 0x%08x, active: 0x%x, on: %s\n",
> + pll->state.crtc_mask, pll->active_mask, yesno(pll->on));
> + seq_printf(m, " tracked hardware state:\n");
> + seq_printf(m, " dpll: 0x%08x\n", pll->state.hw_state.dpll);
> + seq_printf(m, " dpll_md: 0x%08x\n",
> + pll->state.hw_state.dpll_md);
> + seq_printf(m, " fp0: 0x%08x\n", pll->state.hw_state.fp0);
> + seq_printf(m, " fp1: 0x%08x\n", pll->state.hw_state.fp1);
> + seq_printf(m, " wrpll: 0x%08x\n", pll->state.hw_state.wrpll);
> + seq_printf(m, " cfgcr0: 0x%08x\n", pll->state.hw_state.cfgcr0);
> + seq_printf(m, " cfgcr1: 0x%08x\n", pll->state.hw_state.cfgcr1);
> + seq_printf(m, " mg_refclkin_ctl: 0x%08x\n",
> + pll->state.hw_state.mg_refclkin_ctl);
> + seq_printf(m, " mg_clktop2_coreclkctl1: 0x%08x\n",
> + pll->state.hw_state.mg_clktop2_coreclkctl1);
> + seq_printf(m, " mg_clktop2_hsclkctl: 0x%08x\n",
> + pll->state.hw_state.mg_clktop2_hsclkctl);
> + seq_printf(m, " mg_pll_div0: 0x%08x\n",
> + pll->state.hw_state.mg_pll_div0);
> + seq_printf(m, " mg_pll_div1: 0x%08x\n",
> + pll->state.hw_state.mg_pll_div1);
> + seq_printf(m, " mg_pll_lf: 0x%08x\n",
> + pll->state.hw_state.mg_pll_lf);
> + seq_printf(m, " mg_pll_frac_lock: 0x%08x\n",
> + pll->state.hw_state.mg_pll_frac_lock);
> + seq_printf(m, " mg_pll_ssc: 0x%08x\n",
> + pll->state.hw_state.mg_pll_ssc);
> + seq_printf(m, " mg_pll_bias: 0x%08x\n",
> + pll->state.hw_state.mg_pll_bias);
> + seq_printf(m, " mg_pll_tdc_coldst_bias: 0x%08x\n",
> + pll->state.hw_state.mg_pll_tdc_coldst_bias);
> + }
> + drm_modeset_unlock_all(dev);
> +
> + return 0;
> +}
> +
> +static int i915_ddb_info(struct seq_file *m, void *unused)
> +{
> + struct drm_i915_private *dev_priv = node_to_i915(m->private);
> + struct drm_device *dev = &dev_priv->drm;
> + struct skl_ddb_entry *entry;
> + struct intel_crtc *crtc;
> +
> + if (INTEL_GEN(dev_priv) < 9)
> + return -ENODEV;
> +
> + drm_modeset_lock_all(dev);
> +
> + seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
> +
> + for_each_intel_crtc(&dev_priv->drm, crtc) {
> + struct intel_crtc_state *crtc_state =
> + to_intel_crtc_state(crtc->base.state);
> + enum pipe pipe = crtc->pipe;
> + enum plane_id plane_id;
> +
> + seq_printf(m, "Pipe %c\n", pipe_name(pipe));
> +
> + for_each_plane_id_on_crtc(crtc, plane_id) {
> + entry = &crtc_state->wm.skl.plane_ddb_y[plane_id];
> + seq_printf(m, " Plane%-8d%8u%8u%8u\n", plane_id + 1,
> + entry->start, entry->end,
> + skl_ddb_entry_size(entry));
> + }
> +
> + entry = &crtc_state->wm.skl.plane_ddb_y[PLANE_CURSOR];
> + seq_printf(m, " %-13s%8u%8u%8u\n", "Cursor", entry->start,
> + entry->end, skl_ddb_entry_size(entry));
> + }
> +
> + drm_modeset_unlock_all(dev);
> +
> + return 0;
> +}
> +
> +static void drrs_status_per_crtc(struct seq_file *m,
> + struct drm_device *dev,
> + struct intel_crtc *intel_crtc)
> +{
> + struct drm_i915_private *dev_priv = to_i915(dev);
> + struct i915_drrs *drrs = &dev_priv->drrs;
> + int vrefresh = 0;
> + struct drm_connector *connector;
> + struct drm_connector_list_iter conn_iter;
> +
> + drm_connector_list_iter_begin(dev, &conn_iter);
> + drm_for_each_connector_iter(connector, &conn_iter) {
> + if (connector->state->crtc != &intel_crtc->base)
> + continue;
> +
> + seq_printf(m, "%s:\n", connector->name);
> + }
> + drm_connector_list_iter_end(&conn_iter);
> +
> + seq_puts(m, "\n");
> +
> + if (to_intel_crtc_state(intel_crtc->base.state)->has_drrs) {
> + struct intel_panel *panel;
> +
> + mutex_lock(&drrs->mutex);
> + /* DRRS Supported */
> + seq_puts(m, "\tDRRS Supported: Yes\n");
> +
> + /* disable_drrs() will make drrs->dp NULL */
> + if (!drrs->dp) {
> + seq_puts(m, "Idleness DRRS: Disabled\n");
> + if (dev_priv->psr.enabled)
> + seq_puts(m,
> + "\tAs PSR is enabled, DRRS is not enabled\n");
> + mutex_unlock(&drrs->mutex);
> + return;
> + }
> +
> + panel = &drrs->dp->attached_connector->panel;
> + seq_printf(m, "\t\tBusy_frontbuffer_bits: 0x%X",
> + drrs->busy_frontbuffer_bits);
> +
> + seq_puts(m, "\n\t\t");
> + if (drrs->refresh_rate_type == DRRS_HIGH_RR) {
> + seq_puts(m, "DRRS_State: DRRS_HIGH_RR\n");
> + vrefresh = panel->fixed_mode->vrefresh;
> + } else if (drrs->refresh_rate_type == DRRS_LOW_RR) {
> + seq_puts(m, "DRRS_State: DRRS_LOW_RR\n");
> + vrefresh = panel->downclock_mode->vrefresh;
> + } else {
> + seq_printf(m, "DRRS_State: Unknown(%d)\n",
> + drrs->refresh_rate_type);
> + mutex_unlock(&drrs->mutex);
> + return;
> + }
> + seq_printf(m, "\t\tVrefresh: %d", vrefresh);
> +
> + seq_puts(m, "\n\t\t");
> + mutex_unlock(&drrs->mutex);
> + } else {
> + /* DRRS not supported. Print the VBT parameter*/
> + seq_puts(m, "\tDRRS Supported : No");
> + }
> + seq_puts(m, "\n");
> +}
> +
> +static int i915_drrs_status(struct seq_file *m, void *unused)
> +{
> + struct drm_i915_private *dev_priv = node_to_i915(m->private);
> + struct drm_device *dev = &dev_priv->drm;
> + struct intel_crtc *intel_crtc;
> + int active_crtc_cnt = 0;
> +
> + drm_modeset_lock_all(dev);
> + for_each_intel_crtc(dev, intel_crtc) {
> + if (intel_crtc->base.state->active) {
> + active_crtc_cnt++;
> + seq_printf(m, "\nCRTC %d: ", active_crtc_cnt);
> +
> + drrs_status_per_crtc(m, dev, intel_crtc);
> + }
> + }
> + drm_modeset_unlock_all(dev);
> +
> + if (!active_crtc_cnt)
> + seq_puts(m, "No active crtc found\n");
> +
> + return 0;
> +}
> +
> +static int i915_dp_mst_info(struct seq_file *m, void *unused)
> +{
> + struct drm_i915_private *dev_priv = node_to_i915(m->private);
> + struct drm_device *dev = &dev_priv->drm;
> + struct intel_encoder *intel_encoder;
> + struct intel_digital_port *intel_dig_port;
> + struct drm_connector *connector;
> + struct drm_connector_list_iter conn_iter;
> +
> + drm_connector_list_iter_begin(dev, &conn_iter);
> + drm_for_each_connector_iter(connector, &conn_iter) {
> + if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
> + continue;
> +
> + intel_encoder = intel_attached_encoder(to_intel_connector(connector));
> + if (!intel_encoder || intel_encoder->type == INTEL_OUTPUT_DP_MST)
> + continue;
> +
> + intel_dig_port = enc_to_dig_port(intel_encoder);
> + if (!intel_dig_port->dp.can_mst)
> + continue;
> +
> + seq_printf(m, "MST Source Port [ENCODER:%d:%s]\n",
> + intel_dig_port->base.base.base.id,
> + intel_dig_port->base.base.name);
> + drm_dp_mst_dump_topology(m, &intel_dig_port->dp.mst_mgr);
> + }
> + drm_connector_list_iter_end(&conn_iter);
> +
> + return 0;
> +}
> +
> +static ssize_t i915_displayport_test_active_write(struct file *file,
> + const char __user *ubuf,
> + size_t len, loff_t *offp)
> +{
> + char *input_buffer;
> + int status = 0;
> + struct drm_device *dev;
> + struct drm_connector *connector;
> + struct drm_connector_list_iter conn_iter;
> + struct intel_dp *intel_dp;
> + int val = 0;
> +
> + dev = ((struct seq_file *)file->private_data)->private;
> +
> + if (len == 0)
> + return 0;
> +
> + input_buffer = memdup_user_nul(ubuf, len);
> + if (IS_ERR(input_buffer))
> + return PTR_ERR(input_buffer);
> +
> + drm_dbg(&to_i915(dev)->drm,
> + "Copied %d bytes from user\n", (unsigned int)len);
> +
> + drm_connector_list_iter_begin(dev, &conn_iter);
> + drm_for_each_connector_iter(connector, &conn_iter) {
> + struct intel_encoder *encoder;
> +
> + if (connector->connector_type !=
> + DRM_MODE_CONNECTOR_DisplayPort)
> + continue;
> +
> + encoder = to_intel_encoder(connector->encoder);
> + if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
> + continue;
> +
> + if (encoder && connector->status == connector_status_connected) {
> + intel_dp = enc_to_intel_dp(encoder);
> + status = kstrtoint(input_buffer, 10, &val);
> + if (status < 0)
> + break;
> + drm_dbg(&to_i915(dev)->drm,
> + "Got %d for test active\n", val);
> + /* To prevent erroneous activation of the compliance
> + * testing code, only accept an actual value of 1 here
> + */
> + if (val == 1)
> + intel_dp->compliance.test_active = true;
> + else
> + intel_dp->compliance.test_active = false;
> + }
> + }
> + drm_connector_list_iter_end(&conn_iter);
> + kfree(input_buffer);
> + if (status < 0)
> + return status;
> +
> + *offp += len;
> + return len;
> +}
> +
> +static int i915_displayport_test_active_show(struct seq_file *m, void *data)
> +{
> + struct drm_i915_private *dev_priv = m->private;
> + struct drm_device *dev = &dev_priv->drm;
> + struct drm_connector *connector;
> + struct drm_connector_list_iter conn_iter;
> + struct intel_dp *intel_dp;
> +
> + drm_connector_list_iter_begin(dev, &conn_iter);
> + drm_for_each_connector_iter(connector, &conn_iter) {
> + struct intel_encoder *encoder;
> +
> + if (connector->connector_type !=
> + DRM_MODE_CONNECTOR_DisplayPort)
> + continue;
> +
> + encoder = to_intel_encoder(connector->encoder);
> + if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
> + continue;
> +
> + if (encoder && connector->status == connector_status_connected) {
> + intel_dp = enc_to_intel_dp(encoder);
> + if (intel_dp->compliance.test_active)
> + seq_puts(m, "1");
> + else
> + seq_puts(m, "0");
> + } else
> + seq_puts(m, "0");
> + }
> + drm_connector_list_iter_end(&conn_iter);
> +
> + return 0;
> +}
> +
> +static int i915_displayport_test_active_open(struct inode *inode,
> + struct file *file)
> +{
> + return single_open(file, i915_displayport_test_active_show,
> + inode->i_private);
> +}
> +
> +static const struct file_operations i915_displayport_test_active_fops = {
> + .owner = THIS_MODULE,
> + .open = i915_displayport_test_active_open,
> + .read = seq_read,
> + .llseek = seq_lseek,
> + .release = single_release,
> + .write = i915_displayport_test_active_write
> +};
> +
> +static int i915_displayport_test_data_show(struct seq_file *m, void *data)
> +{
> + struct drm_i915_private *dev_priv = m->private;
> + struct drm_device *dev = &dev_priv->drm;
> + struct drm_connector *connector;
> + struct drm_connector_list_iter conn_iter;
> + struct intel_dp *intel_dp;
> +
> + drm_connector_list_iter_begin(dev, &conn_iter);
> + drm_for_each_connector_iter(connector, &conn_iter) {
> + struct intel_encoder *encoder;
> +
> + if (connector->connector_type !=
> + DRM_MODE_CONNECTOR_DisplayPort)
> + continue;
> +
> + encoder = to_intel_encoder(connector->encoder);
> + if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
> + continue;
> +
> + if (encoder && connector->status == connector_status_connected) {
> + intel_dp = enc_to_intel_dp(encoder);
> + if (intel_dp->compliance.test_type ==
> + DP_TEST_LINK_EDID_READ)
> + seq_printf(m, "%lx",
> + intel_dp->compliance.test_data.edid);
> + else if (intel_dp->compliance.test_type ==
> + DP_TEST_LINK_VIDEO_PATTERN) {
> + seq_printf(m, "hdisplay: %d\n",
> + intel_dp->compliance.test_data.hdisplay);
> + seq_printf(m, "vdisplay: %d\n",
> + intel_dp->compliance.test_data.vdisplay);
> + seq_printf(m, "bpc: %u\n",
> + intel_dp->compliance.test_data.bpc);
> + }
> + } else
> + seq_puts(m, "0");
> + }
> + drm_connector_list_iter_end(&conn_iter);
> +
> + return 0;
> +}
> +DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_data);
> +
> +static int i915_displayport_test_type_show(struct seq_file *m, void *data)
> +{
> + struct drm_i915_private *dev_priv = m->private;
> + struct drm_device *dev = &dev_priv->drm;
> + struct drm_connector *connector;
> + struct drm_connector_list_iter conn_iter;
> + struct intel_dp *intel_dp;
> +
> + drm_connector_list_iter_begin(dev, &conn_iter);
> + drm_for_each_connector_iter(connector, &conn_iter) {
> + struct intel_encoder *encoder;
> +
> + if (connector->connector_type !=
> + DRM_MODE_CONNECTOR_DisplayPort)
> + continue;
> +
> + encoder = to_intel_encoder(connector->encoder);
> + if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
> + continue;
> +
> + if (encoder && connector->status == connector_status_connected) {
> + intel_dp = enc_to_intel_dp(encoder);
> + seq_printf(m, "%02lx", intel_dp->compliance.test_type);
> + } else
> + seq_puts(m, "0");
> + }
> + drm_connector_list_iter_end(&conn_iter);
> +
> + return 0;
> +}
> +DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_type);
> +
> +static void wm_latency_show(struct seq_file *m, const u16 wm[8])
> +{
> + struct drm_i915_private *dev_priv = m->private;
> + struct drm_device *dev = &dev_priv->drm;
> + int level;
> + int num_levels;
> +
> + if (IS_CHERRYVIEW(dev_priv))
> + num_levels = 3;
> + else if (IS_VALLEYVIEW(dev_priv))
> + num_levels = 1;
> + else if (IS_G4X(dev_priv))
> + num_levels = 3;
> + else
> + num_levels = ilk_wm_max_level(dev_priv) + 1;
> +
> + drm_modeset_lock_all(dev);
> +
> + for (level = 0; level < num_levels; level++) {
> + unsigned int latency = wm[level];
> +
> + /*
> + * - WM1+ latency values in 0.5us units
> + * - latencies are in us on gen9/vlv/chv
> + */
> + if (INTEL_GEN(dev_priv) >= 9 ||
> + IS_VALLEYVIEW(dev_priv) ||
> + IS_CHERRYVIEW(dev_priv) ||
> + IS_G4X(dev_priv))
> + latency *= 10;
> + else if (level > 0)
> + latency *= 5;
> +
> + seq_printf(m, "WM%d %u (%u.%u usec)\n",
> + level, wm[level], latency / 10, latency % 10);
> + }
> +
> + drm_modeset_unlock_all(dev);
> +}
> +
> +static int pri_wm_latency_show(struct seq_file *m, void *data)
> +{
> + struct drm_i915_private *dev_priv = m->private;
> + const u16 *latencies;
> +
> + if (INTEL_GEN(dev_priv) >= 9)
> + latencies = dev_priv->wm.skl_latency;
> + else
> + latencies = dev_priv->wm.pri_latency;
> +
> + wm_latency_show(m, latencies);
> +
> + return 0;
> +}
> +
> +static int spr_wm_latency_show(struct seq_file *m, void *data)
> +{
> + struct drm_i915_private *dev_priv = m->private;
> + const u16 *latencies;
> +
> + if (INTEL_GEN(dev_priv) >= 9)
> + latencies = dev_priv->wm.skl_latency;
> + else
> + latencies = dev_priv->wm.spr_latency;
> +
> + wm_latency_show(m, latencies);
> +
> + return 0;
> +}
> +
> +static int cur_wm_latency_show(struct seq_file *m, void *data)
> +{
> + struct drm_i915_private *dev_priv = m->private;
> + const u16 *latencies;
> +
> + if (INTEL_GEN(dev_priv) >= 9)
> + latencies = dev_priv->wm.skl_latency;
> + else
> + latencies = dev_priv->wm.cur_latency;
> +
> + wm_latency_show(m, latencies);
> +
> + return 0;
> +}
> +
> +static int pri_wm_latency_open(struct inode *inode, struct file *file)
> +{
> + struct drm_i915_private *dev_priv = inode->i_private;
> +
> + if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv))
> + return -ENODEV;
> +
> + return single_open(file, pri_wm_latency_show, dev_priv);
> +}
> +
> +static int spr_wm_latency_open(struct inode *inode, struct file *file)
> +{
> + struct drm_i915_private *dev_priv = inode->i_private;
> +
> + if (HAS_GMCH(dev_priv))
> + return -ENODEV;
> +
> + return single_open(file, spr_wm_latency_show, dev_priv);
> +}
> +
> +static int cur_wm_latency_open(struct inode *inode, struct file *file)
> +{
> + struct drm_i915_private *dev_priv = inode->i_private;
> +
> + if (HAS_GMCH(dev_priv))
> + return -ENODEV;
> +
> + return single_open(file, cur_wm_latency_show, dev_priv);
> +}
> +
> +static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
> + size_t len, loff_t *offp, u16 wm[8])
> +{
> + struct seq_file *m = file->private_data;
> + struct drm_i915_private *dev_priv = m->private;
> + struct drm_device *dev = &dev_priv->drm;
> + u16 new[8] = { 0 };
> + int num_levels;
> + int level;
> + int ret;
> + char tmp[32];
> +
> + if (IS_CHERRYVIEW(dev_priv))
> + num_levels = 3;
> + else if (IS_VALLEYVIEW(dev_priv))
> + num_levels = 1;
> + else if (IS_G4X(dev_priv))
> + num_levels = 3;
> + else
> + num_levels = ilk_wm_max_level(dev_priv) + 1;
> +
> + if (len >= sizeof(tmp))
> + return -EINVAL;
> +
> + if (copy_from_user(tmp, ubuf, len))
> + return -EFAULT;
> +
> + tmp[len] = '\0';
> +
> + ret = sscanf(tmp, "%hu %hu %hu %hu %hu %hu %hu %hu",
> + &new[0], &new[1], &new[2], &new[3],
> + &new[4], &new[5], &new[6], &new[7]);
> + if (ret != num_levels)
> + return -EINVAL;
> +
> + drm_modeset_lock_all(dev);
> +
> + for (level = 0; level < num_levels; level++)
> + wm[level] = new[level];
> +
> + drm_modeset_unlock_all(dev);
> +
> + return len;
> +}
> +
> +
> +static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf,
> + size_t len, loff_t *offp)
> +{
> + struct seq_file *m = file->private_data;
> + struct drm_i915_private *dev_priv = m->private;
> + u16 *latencies;
> +
> + if (INTEL_GEN(dev_priv) >= 9)
> + latencies = dev_priv->wm.skl_latency;
> + else
> + latencies = dev_priv->wm.pri_latency;
> +
> + return wm_latency_write(file, ubuf, len, offp, latencies);
> +}
> +
> +static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
> + size_t len, loff_t *offp)
> +{
> + struct seq_file *m = file->private_data;
> + struct drm_i915_private *dev_priv = m->private;
> + u16 *latencies;
> +
> + if (INTEL_GEN(dev_priv) >= 9)
> + latencies = dev_priv->wm.skl_latency;
> + else
> + latencies = dev_priv->wm.spr_latency;
> +
> + return wm_latency_write(file, ubuf, len, offp, latencies);
> +}
> +
> +static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
> + size_t len, loff_t *offp)
> +{
> + struct seq_file *m = file->private_data;
> + struct drm_i915_private *dev_priv = m->private;
> + u16 *latencies;
> +
> + if (INTEL_GEN(dev_priv) >= 9)
> + latencies = dev_priv->wm.skl_latency;
> + else
> + latencies = dev_priv->wm.cur_latency;
> +
> + return wm_latency_write(file, ubuf, len, offp, latencies);
> +}
> +
> +static const struct file_operations i915_pri_wm_latency_fops = {
> + .owner = THIS_MODULE,
> + .open = pri_wm_latency_open,
> + .read = seq_read,
> + .llseek = seq_lseek,
> + .release = single_release,
> + .write = pri_wm_latency_write
> +};
> +
> +static const struct file_operations i915_spr_wm_latency_fops = {
> + .owner = THIS_MODULE,
> + .open = spr_wm_latency_open,
> + .read = seq_read,
> + .llseek = seq_lseek,
> + .release = single_release,
> + .write = spr_wm_latency_write
> +};
> +
> +static const struct file_operations i915_cur_wm_latency_fops = {
> + .owner = THIS_MODULE,
> + .open = cur_wm_latency_open,
> + .read = seq_read,
> + .llseek = seq_lseek,
> + .release = single_release,
> + .write = cur_wm_latency_write
> +};
> +
> +static int i915_hpd_storm_ctl_show(struct seq_file *m, void *data)
> +{
> + struct drm_i915_private *dev_priv = m->private;
> + struct i915_hotplug *hotplug = &dev_priv->hotplug;
> +
> + /* Synchronize with everything first in case there's been an HPD
> + * storm, but we haven't finished handling it in the kernel yet
> + */
> + intel_synchronize_irq(dev_priv);
> + flush_work(&dev_priv->hotplug.dig_port_work);
> + flush_delayed_work(&dev_priv->hotplug.hotplug_work);
> +
> + seq_printf(m, "Threshold: %d\n", hotplug->hpd_storm_threshold);
> + seq_printf(m, "Detected: %s\n",
> + yesno(delayed_work_pending(&hotplug->reenable_work)));
> +
> + return 0;
> +}
> +
> +static ssize_t i915_hpd_storm_ctl_write(struct file *file,
> + const char __user *ubuf, size_t len,
> + loff_t *offp)
> +{
> + struct seq_file *m = file->private_data;
> + struct drm_i915_private *dev_priv = m->private;
> + struct i915_hotplug *hotplug = &dev_priv->hotplug;
> + unsigned int new_threshold;
> + int i;
> + char *newline;
> + char tmp[16];
> +
> + if (len >= sizeof(tmp))
> + return -EINVAL;
> +
> + if (copy_from_user(tmp, ubuf, len))
> + return -EFAULT;
> +
> + tmp[len] = '\0';
> +
> + /* Strip newline, if any */
> + newline = strchr(tmp, '\n');
> + if (newline)
> + *newline = '\0';
> +
> + if (strcmp(tmp, "reset") == 0)
> + new_threshold = HPD_STORM_DEFAULT_THRESHOLD;
> + else if (kstrtouint(tmp, 10, &new_threshold) != 0)
> + return -EINVAL;
> +
> + if (new_threshold > 0)
> + drm_dbg_kms(&dev_priv->drm,
> + "Setting HPD storm detection threshold to %d\n",
> + new_threshold);
> + else
> + drm_dbg_kms(&dev_priv->drm, "Disabling HPD storm detection\n");
> +
> + spin_lock_irq(&dev_priv->irq_lock);
> + hotplug->hpd_storm_threshold = new_threshold;
> + /* Reset the HPD storm stats so we don't accidentally trigger a storm */
> + for_each_hpd_pin(i)
> + hotplug->stats[i].count = 0;
> + spin_unlock_irq(&dev_priv->irq_lock);
> +
> + /* Re-enable hpd immediately if we were in an irq storm */
> + flush_delayed_work(&dev_priv->hotplug.reenable_work);
> +
> + return len;
> +}
> +
> +static int i915_hpd_storm_ctl_open(struct inode *inode, struct file *file)
> +{
> + return single_open(file, i915_hpd_storm_ctl_show, inode->i_private);
> +}
> +
> +static const struct file_operations i915_hpd_storm_ctl_fops = {
> + .owner = THIS_MODULE,
> + .open = i915_hpd_storm_ctl_open,
> + .read = seq_read,
> + .llseek = seq_lseek,
> + .release = single_release,
> + .write = i915_hpd_storm_ctl_write
> +};
> +
> +static int i915_hpd_short_storm_ctl_show(struct seq_file *m, void *data)
> +{
> + struct drm_i915_private *dev_priv = m->private;
> +
> + seq_printf(m, "Enabled: %s\n",
> + yesno(dev_priv->hotplug.hpd_short_storm_enabled));
> +
> + return 0;
> +}
> +
> +static int
> +i915_hpd_short_storm_ctl_open(struct inode *inode, struct file *file)
> +{
> + return single_open(file, i915_hpd_short_storm_ctl_show,
> + inode->i_private);
> +}
> +
> +static ssize_t i915_hpd_short_storm_ctl_write(struct file *file,
> + const char __user *ubuf,
> + size_t len, loff_t *offp)
> +{
> + struct seq_file *m = file->private_data;
> + struct drm_i915_private *dev_priv = m->private;
> + struct i915_hotplug *hotplug = &dev_priv->hotplug;
> + char *newline;
> + char tmp[16];
> + int i;
> + bool new_state;
> +
> + if (len >= sizeof(tmp))
> + return -EINVAL;
> +
> + if (copy_from_user(tmp, ubuf, len))
> + return -EFAULT;
> +
> + tmp[len] = '\0';
> +
> + /* Strip newline, if any */
> + newline = strchr(tmp, '\n');
> + if (newline)
> + *newline = '\0';
> +
> + /* Reset to the "default" state for this system */
> + if (strcmp(tmp, "reset") == 0)
> + new_state = !HAS_DP_MST(dev_priv);
> + else if (kstrtobool(tmp, &new_state) != 0)
> + return -EINVAL;
> +
> + drm_dbg_kms(&dev_priv->drm, "%sabling HPD short storm detection\n",
> + new_state ? "En" : "Dis");
> +
> + spin_lock_irq(&dev_priv->irq_lock);
> + hotplug->hpd_short_storm_enabled = new_state;
> + /* Reset the HPD storm stats so we don't accidentally trigger a storm */
> + for_each_hpd_pin(i)
> + hotplug->stats[i].count = 0;
> + spin_unlock_irq(&dev_priv->irq_lock);
> +
> + /* Re-enable hpd immediately if we were in an irq storm */
> + flush_delayed_work(&dev_priv->hotplug.reenable_work);
> +
> + return len;
> +}
> +
> +static const struct file_operations i915_hpd_short_storm_ctl_fops = {
> + .owner = THIS_MODULE,
> + .open = i915_hpd_short_storm_ctl_open,
> + .read = seq_read,
> + .llseek = seq_lseek,
> + .release = single_release,
> + .write = i915_hpd_short_storm_ctl_write,
> +};
> +
> +static int i915_drrs_ctl_set(void *data, u64 val)
> +{
> + struct drm_i915_private *dev_priv = data;
> + struct drm_device *dev = &dev_priv->drm;
> + struct intel_crtc *crtc;
> +
> + if (INTEL_GEN(dev_priv) < 7)
> + return -ENODEV;
> +
> + for_each_intel_crtc(dev, crtc) {
> + struct drm_connector_list_iter conn_iter;
> + struct intel_crtc_state *crtc_state;
> + struct drm_connector *connector;
> + struct drm_crtc_commit *commit;
> + int ret;
> +
> + ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
> + if (ret)
> + return ret;
> +
> + crtc_state = to_intel_crtc_state(crtc->base.state);
> +
> + if (!crtc_state->hw.active ||
> + !crtc_state->has_drrs)
> + goto out;
> +
> + commit = crtc_state->uapi.commit;
> + if (commit) {
> + ret = wait_for_completion_interruptible(&commit->hw_done);
> + if (ret)
> + goto out;
> + }
> +
> + drm_connector_list_iter_begin(dev, &conn_iter);
> + drm_for_each_connector_iter(connector, &conn_iter) {
> + struct intel_encoder *encoder;
> + struct intel_dp *intel_dp;
> +
> + if (!(crtc_state->uapi.connector_mask &
> + drm_connector_mask(connector)))
> + continue;
> +
> + encoder = intel_attached_encoder(to_intel_connector(connector));
> + if (encoder->type != INTEL_OUTPUT_EDP)
> + continue;
> +
> + drm_dbg(&dev_priv->drm,
> + "Manually %sabling DRRS. %llu\n",
> + val ? "en" : "dis", val);
> +
> + intel_dp = enc_to_intel_dp(encoder);
> + if (val)
> + intel_edp_drrs_enable(intel_dp,
> + crtc_state);
> + else
> + intel_edp_drrs_disable(intel_dp,
> + crtc_state);
> + }
> + drm_connector_list_iter_end(&conn_iter);
> +
> +out:
> + drm_modeset_unlock(&crtc->base.mutex);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +DEFINE_SIMPLE_ATTRIBUTE(i915_drrs_ctl_fops, NULL, i915_drrs_ctl_set, "%llu\n");
> +
> +static ssize_t
> +i915_fifo_underrun_reset_write(struct file *filp,
> + const char __user *ubuf,
> + size_t cnt, loff_t *ppos)
> +{
> + struct drm_i915_private *dev_priv = filp->private_data;
> + struct intel_crtc *intel_crtc;
> + struct drm_device *dev = &dev_priv->drm;
> + int ret;
> + bool reset;
> +
> + ret = kstrtobool_from_user(ubuf, cnt, &reset);
> + if (ret)
> + return ret;
> +
> + if (!reset)
> + return cnt;
> +
> + for_each_intel_crtc(dev, intel_crtc) {
> + struct drm_crtc_commit *commit;
> + struct intel_crtc_state *crtc_state;
> +
> + ret = drm_modeset_lock_single_interruptible(&intel_crtc->base.mutex);
> + if (ret)
> + return ret;
> +
> + crtc_state = to_intel_crtc_state(intel_crtc->base.state);
> + commit = crtc_state->uapi.commit;
> + if (commit) {
> + ret = wait_for_completion_interruptible(&commit->hw_done);
> + if (!ret)
> + ret = wait_for_completion_interruptible(&commit->flip_done);
> + }
> +
> + if (!ret && crtc_state->hw.active) {
> + drm_dbg_kms(&dev_priv->drm,
> + "Re-arming FIFO underruns on pipe %c\n",
> + pipe_name(intel_crtc->pipe));
> +
> + intel_crtc_arm_fifo_underrun(intel_crtc, crtc_state);
> + }
> +
> + drm_modeset_unlock(&intel_crtc->base.mutex);
> +
> + if (ret)
> + return ret;
> + }
> +
> + ret = intel_fbc_reset_underrun(dev_priv);
> + if (ret)
> + return ret;
> +
> + return cnt;
> +}
> +
> +static const struct file_operations i915_fifo_underrun_reset_ops = {
> + .owner = THIS_MODULE,
> + .open = simple_open,
> + .write = i915_fifo_underrun_reset_write,
> + .llseek = default_llseek,
> +};
> +
> +static const struct drm_info_list intel_display_debugfs_list[] = {
> + {"i915_ddb_info", i915_ddb_info, 0},
> + {"i915_display_info", i915_display_info, 0},
> + {"i915_dp_mst_info", i915_dp_mst_info, 0},
> + {"i915_drrs_status", i915_drrs_status, 0},
> + {"i915_edp_psr_status", i915_edp_psr_status, 0},
> + {"i915_fbc_status", i915_fbc_status, 0},
> + {"i915_ips_status", i915_ips_status, 0},
> + {"i915_opregion", i915_opregion, 0},
> + {"i915_shared_dplls_info", i915_shared_dplls_info, 0},
> + {"i915_sr_status", i915_sr_status, 0},
> + {"i915_vbt", i915_vbt, 0},
> +};
> +
> +static const struct {
> + const char *name;
> + const struct file_operations *fops;
> +} intel_display_debugfs_files[] = {
> + {"i915_cur_wm_latency", &i915_cur_wm_latency_fops},
> + {"i915_dp_test_active", &i915_displayport_test_active_fops},
> + {"i915_dp_test_data", &i915_displayport_test_data_fops},
> + {"i915_dp_test_type", &i915_displayport_test_type_fops},
> + {"i915_drrs_ctl", &i915_drrs_ctl_fops},
> + {"i915_edp_psr_debug", &i915_edp_psr_debug_fops},
> + {"i915_fbc_false_color", &i915_fbc_false_color_fops},
> + {"i915_fifo_underrun_reset", &i915_fifo_underrun_reset_ops},
> + {"i915_hpd_short_storm_ctl", &i915_hpd_short_storm_ctl_fops},
> + {"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops},
> + {"i915_pri_wm_latency", &i915_pri_wm_latency_fops},
> + {"i915_spr_wm_latency", &i915_spr_wm_latency_fops},
> +};
> +
> +int intel_display_debugfs_register(struct drm_i915_private *i915)
> +{
> + struct drm_minor *minor = i915->drm.primary;
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(intel_display_debugfs_files); i++) {
> + debugfs_create_file(intel_display_debugfs_files[i].name,
> + S_IRUGO | S_IWUSR,
> + minor->debugfs_root,
> + to_i915(minor->dev),
> + intel_display_debugfs_files[i].fops);
> + }
> +
> + return drm_debugfs_create_files(intel_display_debugfs_list,
> + ARRAY_SIZE(intel_display_debugfs_list),
> + minor->debugfs_root, minor);
> +}
> +
> +static int i915_panel_show(struct seq_file *m, void *data)
> +{
> + struct drm_connector *connector = m->private;
> + struct intel_dp *intel_dp =
> + intel_attached_dp(to_intel_connector(connector));
> +
> + if (connector->status != connector_status_connected)
> + return -ENODEV;
> +
> + seq_printf(m, "Panel power up delay: %d\n",
> + intel_dp->panel_power_up_delay);
> + seq_printf(m, "Panel power down delay: %d\n",
> + intel_dp->panel_power_down_delay);
> + seq_printf(m, "Backlight on delay: %d\n",
> + intel_dp->backlight_on_delay);
> + seq_printf(m, "Backlight off delay: %d\n",
> + intel_dp->backlight_off_delay);
> +
> + return 0;
> +}
> +DEFINE_SHOW_ATTRIBUTE(i915_panel);
> +
> +static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data)
> +{
> + struct drm_connector *connector = m->private;
> + struct intel_connector *intel_connector = to_intel_connector(connector);
> +
> + if (connector->status != connector_status_connected)
> + return -ENODEV;
> +
> + /* HDCP is supported by connector */
> + if (!intel_connector->hdcp.shim)
> + return -EINVAL;
> +
> + seq_printf(m, "%s:%d HDCP version: ", connector->name,
> + connector->base.id);
> + intel_hdcp_info(m, intel_connector);
> +
> + return 0;
> +}
> +DEFINE_SHOW_ATTRIBUTE(i915_hdcp_sink_capability);
> +
> +static int i915_dsc_fec_support_show(struct seq_file *m, void *data)
> +{
> + struct drm_connector *connector = m->private;
> + struct drm_device *dev = connector->dev;
> + struct drm_crtc *crtc;
> + struct intel_dp *intel_dp;
> + struct drm_modeset_acquire_ctx ctx;
> + struct intel_crtc_state *crtc_state = NULL;
> + int ret = 0;
> + bool try_again = false;
> +
> + drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
> +
> + do {
> + try_again = false;
> + ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
> + &ctx);
> + if (ret) {
> + if (ret == -EDEADLK && !drm_modeset_backoff(&ctx)) {
> + try_again = true;
> + continue;
> + }
> + break;
> + }
> + crtc = connector->state->crtc;
> + if (connector->status != connector_status_connected || !crtc) {
> + ret = -ENODEV;
> + break;
> + }
> + ret = drm_modeset_lock(&crtc->mutex, &ctx);
> + if (ret == -EDEADLK) {
> + ret = drm_modeset_backoff(&ctx);
> + if (!ret) {
> + try_again = true;
> + continue;
> + }
> + break;
> + } else if (ret) {
> + break;
> + }
> + intel_dp = intel_attached_dp(to_intel_connector(connector));
> + crtc_state = to_intel_crtc_state(crtc->state);
> + seq_printf(m, "DSC_Enabled: %s\n",
> + yesno(crtc_state->dsc.compression_enable));
> + seq_printf(m, "DSC_Sink_Support: %s\n",
> + yesno(drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)));
> + seq_printf(m, "Force_DSC_Enable: %s\n",
> + yesno(intel_dp->force_dsc_en));
> + if (!intel_dp_is_edp(intel_dp))
> + seq_printf(m, "FEC_Sink_Support: %s\n",
> + yesno(drm_dp_sink_supports_fec(intel_dp->fec_capable)));
> + } while (try_again);
> +
> + drm_modeset_drop_locks(&ctx);
> + drm_modeset_acquire_fini(&ctx);
> +
> + return ret;
> +}
> +
> +static ssize_t i915_dsc_fec_support_write(struct file *file,
> + const char __user *ubuf,
> + size_t len, loff_t *offp)
> +{
> + bool dsc_enable = false;
> + int ret;
> + struct drm_connector *connector =
> + ((struct seq_file *)file->private_data)->private;
> + struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
> + struct drm_i915_private *i915 = to_i915(encoder->base.dev);
> + struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> +
> + if (len == 0)
> + return 0;
> +
> + drm_dbg(&i915->drm,
> + "Copied %zu bytes from user to force DSC\n", len);
> +
> + ret = kstrtobool_from_user(ubuf, len, &dsc_enable);
> + if (ret < 0)
> + return ret;
> +
> + drm_dbg(&i915->drm, "Got %s for DSC Enable\n",
> + (dsc_enable) ? "true" : "false");
> + intel_dp->force_dsc_en = dsc_enable;
> +
> + *offp += len;
> + return len;
> +}
> +
> +static int i915_dsc_fec_support_open(struct inode *inode,
> + struct file *file)
> +{
> + return single_open(file, i915_dsc_fec_support_show,
> + inode->i_private);
> +}
> +
> +static const struct file_operations i915_dsc_fec_support_fops = {
> + .owner = THIS_MODULE,
> + .open = i915_dsc_fec_support_open,
> + .read = seq_read,
> + .llseek = seq_lseek,
> + .release = single_release,
> + .write = i915_dsc_fec_support_write
> +};
> +
> +/**
> + * intel_connector_debugfs_add - add i915 specific connector debugfs files
> + * @connector: pointer to a registered drm_connector
> + *
> + * Cleanup will be done by drm_connector_unregister() through a call to
> + * drm_debugfs_connector_remove().
> + *
> + * Returns 0 on success, negative error codes on error.
> + */
> +int intel_connector_debugfs_add(struct drm_connector *connector)
> +{
> + struct dentry *root = connector->debugfs_entry;
> + struct drm_i915_private *dev_priv = to_i915(connector->dev);
> +
> + /* The connector must have been registered beforehands. */
> + if (!root)
> + return -ENODEV;
> +
> + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
> + debugfs_create_file("i915_panel_timings", S_IRUGO, root,
> + connector, &i915_panel_fops);
> + debugfs_create_file("i915_psr_sink_status", S_IRUGO, root,
> + connector, &i915_psr_sink_status_fops);
> + }
> +
> + if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
> + connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
> + connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
> + debugfs_create_file("i915_hdcp_sink_capability", S_IRUGO, root,
> + connector, &i915_hdcp_sink_capability_fops);
> + }
> +
> + if (INTEL_GEN(dev_priv) >= 10 &&
> + (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
> + connector->connector_type == DRM_MODE_CONNECTOR_eDP))
> + debugfs_create_file("i915_dsc_fec_support", S_IRUGO, root,
> + connector, &i915_dsc_fec_support_fops);
> +
> + return 0;
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_display_debugfs.h b/drivers/gpu/drm/i915/display/intel_display_debugfs.h
> new file mode 100644
> index 000000000000..a3bea1ce04c2
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/intel_display_debugfs.h
> @@ -0,0 +1,20 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2020 Intel Corporation
> + */
> +
> +#ifndef __INTEL_DISPLAY_DEBUGFS_H__
> +#define __INTEL_DISPLAY_DEBUGFS_H__
> +
> +struct drm_connector;
> +struct drm_i915_private;
> +
> +#ifdef CONFIG_DEBUG_FS
> +int intel_display_debugfs_register(struct drm_i915_private *i915);
> +int intel_connector_debugfs_add(struct drm_connector *connector);
> +#else
> +static inline int intel_display_debugfs_register(struct drm_i915_private *i915) { return 0; }
> +static inline int intel_connector_debugfs_add(struct drm_connector *connector) { return 0; }
> +#endif
> +
> +#endif /* __INTEL_DISPLAY_DEBUGFS_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
> index f4dede6253f8..9541ab11624d 100644
> --- a/drivers/gpu/drm/i915/display/intel_dp.c
> +++ b/drivers/gpu/drm/i915/display/intel_dp.c
> @@ -49,6 +49,7 @@
> #include "intel_audio.h"
> #include "intel_connector.h"
> #include "intel_ddi.h"
> +#include "intel_display_debugfs.h"
> #include "intel_display_types.h"
> #include "intel_dp.h"
> #include "intel_dp_link_training.h"
> @@ -5851,7 +5852,7 @@ intel_dp_connector_register(struct drm_connector *connector)
> if (ret)
> return ret;
>
> - i915_debugfs_connector_add(connector);
> + intel_connector_debugfs_add(connector);
>
> DRM_DEBUG_KMS("registering %s bus for %s\n",
> intel_dp->aux.name, connector->kdev->kobj.name);
> diff --git a/drivers/gpu/drm/i915/display/intel_hdmi.c b/drivers/gpu/drm/i915/display/intel_hdmi.c
> index e68bafb76cb1..a3a5cfe49aba 100644
> --- a/drivers/gpu/drm/i915/display/intel_hdmi.c
> +++ b/drivers/gpu/drm/i915/display/intel_hdmi.c
> @@ -45,6 +45,7 @@
> #include "intel_audio.h"
> #include "intel_connector.h"
> #include "intel_ddi.h"
> +#include "intel_display_debugfs.h"
> #include "intel_display_types.h"
> #include "intel_dp.h"
> #include "intel_dpio_phy.h"
> @@ -2823,7 +2824,7 @@ intel_hdmi_connector_register(struct drm_connector *connector)
> if (ret)
> return ret;
>
> - i915_debugfs_connector_add(connector);
> + intel_connector_debugfs_add(connector);
>
> intel_hdmi_create_i2c_symlink(connector);
>
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
> index c313c90405cb..7d1d3d16c09e 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.c
> +++ b/drivers/gpu/drm/i915/i915_debugfs.c
> @@ -1232,140 +1232,6 @@ static int i915_frontbuffer_tracking(struct seq_file *m, void *unused)
> return 0;
> }
>
> -static int i915_fbc_status(struct seq_file *m, void *unused)
> -{
> - struct drm_i915_private *dev_priv = node_to_i915(m->private);
> - struct intel_fbc *fbc = &dev_priv->fbc;
> - intel_wakeref_t wakeref;
> -
> - if (!HAS_FBC(dev_priv))
> - return -ENODEV;
> -
> - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> - mutex_lock(&fbc->lock);
> -
> - if (intel_fbc_is_active(dev_priv))
> - seq_puts(m, "FBC enabled\n");
> - else
> - seq_printf(m, "FBC disabled: %s\n", fbc->no_fbc_reason);
> -
> - if (intel_fbc_is_active(dev_priv)) {
> - u32 mask;
> -
> - if (INTEL_GEN(dev_priv) >= 8)
> - mask = I915_READ(IVB_FBC_STATUS2) & BDW_FBC_COMP_SEG_MASK;
> - else if (INTEL_GEN(dev_priv) >= 7)
> - mask = I915_READ(IVB_FBC_STATUS2) & IVB_FBC_COMP_SEG_MASK;
> - else if (INTEL_GEN(dev_priv) >= 5)
> - mask = I915_READ(ILK_DPFC_STATUS) & ILK_DPFC_COMP_SEG_MASK;
> - else if (IS_G4X(dev_priv))
> - mask = I915_READ(DPFC_STATUS) & DPFC_COMP_SEG_MASK;
> - else
> - mask = I915_READ(FBC_STATUS) & (FBC_STAT_COMPRESSING |
> - FBC_STAT_COMPRESSED);
> -
> - seq_printf(m, "Compressing: %s\n", yesno(mask));
> - }
> -
> - mutex_unlock(&fbc->lock);
> - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
> -
> - return 0;
> -}
> -
> -static int i915_fbc_false_color_get(void *data, u64 *val)
> -{
> - struct drm_i915_private *dev_priv = data;
> -
> - if (INTEL_GEN(dev_priv) < 7 || !HAS_FBC(dev_priv))
> - return -ENODEV;
> -
> - *val = dev_priv->fbc.false_color;
> -
> - return 0;
> -}
> -
> -static int i915_fbc_false_color_set(void *data, u64 val)
> -{
> - struct drm_i915_private *dev_priv = data;
> - u32 reg;
> -
> - if (INTEL_GEN(dev_priv) < 7 || !HAS_FBC(dev_priv))
> - return -ENODEV;
> -
> - mutex_lock(&dev_priv->fbc.lock);
> -
> - reg = I915_READ(ILK_DPFC_CONTROL);
> - dev_priv->fbc.false_color = val;
> -
> - I915_WRITE(ILK_DPFC_CONTROL, val ?
> - (reg | FBC_CTL_FALSE_COLOR) :
> - (reg & ~FBC_CTL_FALSE_COLOR));
> -
> - mutex_unlock(&dev_priv->fbc.lock);
> - return 0;
> -}
> -
> -DEFINE_SIMPLE_ATTRIBUTE(i915_fbc_false_color_fops,
> - i915_fbc_false_color_get, i915_fbc_false_color_set,
> - "%llu\n");
> -
> -static int i915_ips_status(struct seq_file *m, void *unused)
> -{
> - struct drm_i915_private *dev_priv = node_to_i915(m->private);
> - intel_wakeref_t wakeref;
> -
> - if (!HAS_IPS(dev_priv))
> - return -ENODEV;
> -
> - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> -
> - seq_printf(m, "Enabled by kernel parameter: %s\n",
> - yesno(i915_modparams.enable_ips));
> -
> - if (INTEL_GEN(dev_priv) >= 8) {
> - seq_puts(m, "Currently: unknown\n");
> - } else {
> - if (I915_READ(IPS_CTL) & IPS_ENABLE)
> - seq_puts(m, "Currently: enabled\n");
> - else
> - seq_puts(m, "Currently: disabled\n");
> - }
> -
> - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
> -
> - return 0;
> -}
> -
> -static int i915_sr_status(struct seq_file *m, void *unused)
> -{
> - struct drm_i915_private *dev_priv = node_to_i915(m->private);
> - intel_wakeref_t wakeref;
> - bool sr_enabled = false;
> -
> - wakeref = intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
> -
> - if (INTEL_GEN(dev_priv) >= 9)
> - /* no global SR status; inspect per-plane WM */;
> - else if (HAS_PCH_SPLIT(dev_priv))
> - sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN;
> - else if (IS_I965GM(dev_priv) || IS_G4X(dev_priv) ||
> - IS_I945G(dev_priv) || IS_I945GM(dev_priv))
> - sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN;
> - else if (IS_I915GM(dev_priv))
> - sr_enabled = I915_READ(INSTPM) & INSTPM_SELF_EN;
> - else if (IS_PINEVIEW(dev_priv))
> - sr_enabled = I915_READ(DSPFW3) & PINEVIEW_SELF_REFRESH_EN;
> - else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> - sr_enabled = I915_READ(FW_BLC_SELF_VLV) & FW_CSPWRDWNEN;
> -
> - intel_display_power_put(dev_priv, POWER_DOMAIN_INIT, wakeref);
> -
> - seq_printf(m, "self-refresh: %s\n", enableddisabled(sr_enabled));
> -
> - return 0;
> -}
> -
> static int i915_ring_freq_table(struct seq_file *m, void *unused)
> {
> struct drm_i915_private *dev_priv = node_to_i915(m->private);
> @@ -1407,26 +1273,6 @@ static int i915_ring_freq_table(struct seq_file *m, void *unused)
> return 0;
> }
>
> -static int i915_opregion(struct seq_file *m, void *unused)
> -{
> - struct intel_opregion *opregion = &node_to_i915(m->private)->opregion;
> -
> - if (opregion->header)
> - seq_write(m, opregion->header, OPREGION_SIZE);
> -
> - return 0;
> -}
> -
> -static int i915_vbt(struct seq_file *m, void *unused)
> -{
> - struct intel_opregion *opregion = &node_to_i915(m->private)->opregion;
> -
> - if (opregion->vbt)
> - seq_write(m, opregion->vbt, opregion->vbt_size);
> -
> - return 0;
> -}
> -
> static int i915_gem_framebuffer_info(struct seq_file *m, void *data)
> {
> struct drm_i915_private *dev_priv = node_to_i915(m->private);
> @@ -1964,230 +1810,6 @@ static const struct file_operations i915_guc_log_relay_fops = {
> .release = i915_guc_log_relay_release,
> };
>
> -static int i915_psr_sink_status_show(struct seq_file *m, void *data)
> -{
> - u8 val;
> - static const char * const sink_status[] = {
> - "inactive",
> - "transition to active, capture and display",
> - "active, display from RFB",
> - "active, capture and display on sink device timings",
> - "transition to inactive, capture and display, timing re-sync",
> - "reserved",
> - "reserved",
> - "sink internal error",
> - };
> - struct drm_connector *connector = m->private;
> - struct drm_i915_private *dev_priv = to_i915(connector->dev);
> - struct intel_dp *intel_dp =
> - intel_attached_dp(to_intel_connector(connector));
> - int ret;
> -
> - if (!CAN_PSR(dev_priv)) {
> - seq_puts(m, "PSR Unsupported\n");
> - return -ENODEV;
> - }
> -
> - if (connector->status != connector_status_connected)
> - return -ENODEV;
> -
> - ret = drm_dp_dpcd_readb(&intel_dp->aux, DP_PSR_STATUS, &val);
> -
> - if (ret == 1) {
> - const char *str = "unknown";
> -
> - val &= DP_PSR_SINK_STATE_MASK;
> - if (val < ARRAY_SIZE(sink_status))
> - str = sink_status[val];
> - seq_printf(m, "Sink PSR status: 0x%x [%s]\n", val, str);
> - } else {
> - return ret;
> - }
> -
> - return 0;
> -}
> -DEFINE_SHOW_ATTRIBUTE(i915_psr_sink_status);
> -
> -static void
> -psr_source_status(struct drm_i915_private *dev_priv, struct seq_file *m)
> -{
> - u32 val, status_val;
> - const char *status = "unknown";
> -
> - if (dev_priv->psr.psr2_enabled) {
> - static const char * const live_status[] = {
> - "IDLE",
> - "CAPTURE",
> - "CAPTURE_FS",
> - "SLEEP",
> - "BUFON_FW",
> - "ML_UP",
> - "SU_STANDBY",
> - "FAST_SLEEP",
> - "DEEP_SLEEP",
> - "BUF_ON",
> - "TG_ON"
> - };
> - val = I915_READ(EDP_PSR2_STATUS(dev_priv->psr.transcoder));
> - status_val = (val & EDP_PSR2_STATUS_STATE_MASK) >>
> - EDP_PSR2_STATUS_STATE_SHIFT;
> - if (status_val < ARRAY_SIZE(live_status))
> - status = live_status[status_val];
> - } else {
> - static const char * const live_status[] = {
> - "IDLE",
> - "SRDONACK",
> - "SRDENT",
> - "BUFOFF",
> - "BUFON",
> - "AUXACK",
> - "SRDOFFACK",
> - "SRDENT_ON",
> - };
> - val = I915_READ(EDP_PSR_STATUS(dev_priv->psr.transcoder));
> - status_val = (val & EDP_PSR_STATUS_STATE_MASK) >>
> - EDP_PSR_STATUS_STATE_SHIFT;
> - if (status_val < ARRAY_SIZE(live_status))
> - status = live_status[status_val];
> - }
> -
> - seq_printf(m, "Source PSR status: %s [0x%08x]\n", status, val);
> -}
> -
> -static int i915_edp_psr_status(struct seq_file *m, void *data)
> -{
> - struct drm_i915_private *dev_priv = node_to_i915(m->private);
> - struct i915_psr *psr = &dev_priv->psr;
> - intel_wakeref_t wakeref;
> - const char *status;
> - bool enabled;
> - u32 val;
> -
> - if (!HAS_PSR(dev_priv))
> - return -ENODEV;
> -
> - seq_printf(m, "Sink support: %s", yesno(psr->sink_support));
> - if (psr->dp)
> - seq_printf(m, " [0x%02x]", psr->dp->psr_dpcd[0]);
> - seq_puts(m, "\n");
> -
> - if (!psr->sink_support)
> - return 0;
> -
> - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> - mutex_lock(&psr->lock);
> -
> - if (psr->enabled)
> - status = psr->psr2_enabled ? "PSR2 enabled" : "PSR1 enabled";
> - else
> - status = "disabled";
> - seq_printf(m, "PSR mode: %s\n", status);
> -
> - if (!psr->enabled) {
> - seq_printf(m, "PSR sink not reliable: %s\n",
> - yesno(psr->sink_not_reliable));
> -
> - goto unlock;
> - }
> -
> - if (psr->psr2_enabled) {
> - val = I915_READ(EDP_PSR2_CTL(dev_priv->psr.transcoder));
> - enabled = val & EDP_PSR2_ENABLE;
> - } else {
> - val = I915_READ(EDP_PSR_CTL(dev_priv->psr.transcoder));
> - enabled = val & EDP_PSR_ENABLE;
> - }
> - seq_printf(m, "Source PSR ctl: %s [0x%08x]\n",
> - enableddisabled(enabled), val);
> - psr_source_status(dev_priv, m);
> - seq_printf(m, "Busy frontbuffer bits: 0x%08x\n",
> - psr->busy_frontbuffer_bits);
> -
> - /*
> - * SKL+ Perf counter is reset to 0 everytime DC state is entered
> - */
> - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> - val = I915_READ(EDP_PSR_PERF_CNT(dev_priv->psr.transcoder));
> - val &= EDP_PSR_PERF_CNT_MASK;
> - seq_printf(m, "Performance counter: %u\n", val);
> - }
> -
> - if (psr->debug & I915_PSR_DEBUG_IRQ) {
> - seq_printf(m, "Last attempted entry at: %lld\n",
> - psr->last_entry_attempt);
> - seq_printf(m, "Last exit at: %lld\n", psr->last_exit);
> - }
> -
> - if (psr->psr2_enabled) {
> - u32 su_frames_val[3];
> - int frame;
> -
> - /*
> - * Reading all 3 registers before hand to minimize crossing a
> - * frame boundary between register reads
> - */
> - for (frame = 0; frame < PSR2_SU_STATUS_FRAMES; frame += 3) {
> - val = I915_READ(PSR2_SU_STATUS(dev_priv->psr.transcoder,
> - frame));
> - su_frames_val[frame / 3] = val;
> - }
> -
> - seq_puts(m, "Frame:\tPSR2 SU blocks:\n");
> -
> - for (frame = 0; frame < PSR2_SU_STATUS_FRAMES; frame++) {
> - u32 su_blocks;
> -
> - su_blocks = su_frames_val[frame / 3] &
> - PSR2_SU_STATUS_MASK(frame);
> - su_blocks = su_blocks >> PSR2_SU_STATUS_SHIFT(frame);
> - seq_printf(m, "%d\t%d\n", frame, su_blocks);
> - }
> - }
> -
> -unlock:
> - mutex_unlock(&psr->lock);
> - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
> -
> - return 0;
> -}
> -
> -static int
> -i915_edp_psr_debug_set(void *data, u64 val)
> -{
> - struct drm_i915_private *dev_priv = data;
> - intel_wakeref_t wakeref;
> - int ret;
> -
> - if (!CAN_PSR(dev_priv))
> - return -ENODEV;
> -
> - drm_dbg_kms(&dev_priv->drm, "Setting PSR debug to %llx\n", val);
> -
> - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> -
> - ret = intel_psr_debug_set(dev_priv, val);
> -
> - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
> -
> - return ret;
> -}
> -
> -static int
> -i915_edp_psr_debug_get(void *data, u64 *val)
> -{
> - struct drm_i915_private *dev_priv = data;
> -
> - if (!CAN_PSR(dev_priv))
> - return -ENODEV;
> -
> - *val = READ_ONCE(dev_priv->psr.debug);
> - return 0;
> -}
> -
> -DEFINE_SIMPLE_ATTRIBUTE(i915_edp_psr_debug_fops,
> - i915_edp_psr_debug_get, i915_edp_psr_debug_set,
> - "%llu\n");
> -
> static int i915_energy_uJ(struct seq_file *m, void *data)
> {
> struct drm_i915_private *dev_priv = node_to_i915(m->private);
> @@ -2326,1123 +1948,129 @@ static int i915_dmc_info(struct seq_file *m, void *unused)
> return 0;
> }
>
> -static void intel_seq_print_mode(struct seq_file *m, int tabs,
> - const struct drm_display_mode *mode)
> +static int i915_engine_info(struct seq_file *m, void *unused)
> {
> - int i;
> + struct drm_i915_private *dev_priv = node_to_i915(m->private);
> + struct intel_engine_cs *engine;
> + intel_wakeref_t wakeref;
> + struct drm_printer p;
> +
> + wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> +
> + seq_printf(m, "GT awake? %s [%d]\n",
> + yesno(dev_priv->gt.awake),
> + atomic_read(&dev_priv->gt.wakeref.count));
> + seq_printf(m, "CS timestamp frequency: %u kHz\n",
> + RUNTIME_INFO(dev_priv)->cs_timestamp_frequency_khz);
> +
> + p = drm_seq_file_printer(m);
> + for_each_uabi_engine(engine, dev_priv)
> + intel_engine_dump(engine, &p, "%s\n", engine->name);
>
> - for (i = 0; i < tabs; i++)
> - seq_putc(m, '\t');
> + intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
>
> - seq_printf(m, DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
> + return 0;
> }
>
> -static void intel_encoder_info(struct seq_file *m,
> - struct intel_crtc *crtc,
> - struct intel_encoder *encoder)
> +static int i915_rcs_topology(struct seq_file *m, void *unused)
> {
> struct drm_i915_private *dev_priv = node_to_i915(m->private);
> - struct drm_connector_list_iter conn_iter;
> - struct drm_connector *connector;
> -
> - seq_printf(m, "\t[ENCODER:%d:%s]: connectors:\n",
> - encoder->base.base.id, encoder->base.name);
> -
> - drm_connector_list_iter_begin(&dev_priv->drm, &conn_iter);
> - drm_for_each_connector_iter(connector, &conn_iter) {
> - const struct drm_connector_state *conn_state =
> - connector->state;
> + struct drm_printer p = drm_seq_file_printer(m);
>
> - if (conn_state->best_encoder != &encoder->base)
> - continue;
> + intel_device_info_print_topology(&RUNTIME_INFO(dev_priv)->sseu, &p);
>
> - seq_printf(m, "\t\t[CONNECTOR:%d:%s]\n",
> - connector->base.id, connector->name);
> - }
> - drm_connector_list_iter_end(&conn_iter);
> + return 0;
> }
>
> -static void intel_panel_info(struct seq_file *m, struct intel_panel *panel)
> +static int i915_shrinker_info(struct seq_file *m, void *unused)
> {
> - const struct drm_display_mode *mode = panel->fixed_mode;
> + struct drm_i915_private *i915 = node_to_i915(m->private);
> +
> + seq_printf(m, "seeks = %d\n", i915->mm.shrinker.seeks);
> + seq_printf(m, "batch = %lu\n", i915->mm.shrinker.batch);
>
> - seq_printf(m, "\tfixed mode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
> + return 0;
> }
>
> -static void intel_hdcp_info(struct seq_file *m,
> - struct intel_connector *intel_connector)
> +static int i915_wa_registers(struct seq_file *m, void *unused)
> {
> - bool hdcp_cap, hdcp2_cap;
> + struct drm_i915_private *i915 = node_to_i915(m->private);
> + struct intel_engine_cs *engine;
>
> - hdcp_cap = intel_hdcp_capable(intel_connector);
> - hdcp2_cap = intel_hdcp2_capable(intel_connector);
> + for_each_uabi_engine(engine, i915) {
> + const struct i915_wa_list *wal = &engine->ctx_wa_list;
> + const struct i915_wa *wa;
> + unsigned int count;
>
> - if (hdcp_cap)
> - seq_puts(m, "HDCP1.4 ");
> - if (hdcp2_cap)
> - seq_puts(m, "HDCP2.2 ");
> + count = wal->count;
> + if (!count)
> + continue;
>
> - if (!hdcp_cap && !hdcp2_cap)
> - seq_puts(m, "None");
> + seq_printf(m, "%s: Workarounds applied: %u\n",
> + engine->name, count);
>
> - seq_puts(m, "\n");
> -}
> + for (wa = wal->list; count--; wa++)
> + seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X\n",
> + i915_mmio_reg_offset(wa->reg),
> + wa->set, wa->clr);
>
> -static void intel_dp_info(struct seq_file *m,
> - struct intel_connector *intel_connector)
> -{
> - struct intel_encoder *intel_encoder = intel_attached_encoder(intel_connector);
> - struct intel_dp *intel_dp = enc_to_intel_dp(intel_encoder);
> -
> - seq_printf(m, "\tDPCD rev: %x\n", intel_dp->dpcd[DP_DPCD_REV]);
> - seq_printf(m, "\taudio support: %s\n", yesno(intel_dp->has_audio));
> - if (intel_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)
> - intel_panel_info(m, &intel_connector->panel);
> -
> - drm_dp_downstream_debug(m, intel_dp->dpcd, intel_dp->downstream_ports,
> - &intel_dp->aux);
> - if (intel_connector->hdcp.shim) {
> - seq_puts(m, "\tHDCP version: ");
> - intel_hdcp_info(m, intel_connector);
> + seq_printf(m, "\n");
> }
> -}
>
> -static void intel_dp_mst_info(struct seq_file *m,
> - struct intel_connector *intel_connector)
> -{
> - struct intel_encoder *intel_encoder = intel_attached_encoder(intel_connector);
> - struct intel_dp_mst_encoder *intel_mst =
> - enc_to_mst(intel_encoder);
> - struct intel_digital_port *intel_dig_port = intel_mst->primary;
> - struct intel_dp *intel_dp = &intel_dig_port->dp;
> - bool has_audio = drm_dp_mst_port_has_audio(&intel_dp->mst_mgr,
> - intel_connector->port);
> -
> - seq_printf(m, "\taudio support: %s\n", yesno(has_audio));
> + return 0;
> }
>
> -static void intel_hdmi_info(struct seq_file *m,
> - struct intel_connector *intel_connector)
> +static int i915_ipc_status_show(struct seq_file *m, void *data)
> {
> - struct intel_encoder *intel_encoder = intel_attached_encoder(intel_connector);
> - struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(intel_encoder);
> + struct drm_i915_private *dev_priv = m->private;
>
> - seq_printf(m, "\taudio support: %s\n", yesno(intel_hdmi->has_audio));
> - if (intel_connector->hdcp.shim) {
> - seq_puts(m, "\tHDCP version: ");
> - intel_hdcp_info(m, intel_connector);
> - }
> + seq_printf(m, "Isochronous Priority Control: %s\n",
> + yesno(dev_priv->ipc_enabled));
> + return 0;
> }
>
> -static void intel_lvds_info(struct seq_file *m,
> - struct intel_connector *intel_connector)
> +static int i915_ipc_status_open(struct inode *inode, struct file *file)
> {
> - intel_panel_info(m, &intel_connector->panel);
> + struct drm_i915_private *dev_priv = inode->i_private;
> +
> + if (!HAS_IPC(dev_priv))
> + return -ENODEV;
> +
> + return single_open(file, i915_ipc_status_show, dev_priv);
> }
>
> -static void intel_connector_info(struct seq_file *m,
> - struct drm_connector *connector)
> +static ssize_t i915_ipc_status_write(struct file *file, const char __user *ubuf,
> + size_t len, loff_t *offp)
> {
> - struct intel_connector *intel_connector = to_intel_connector(connector);
> - const struct drm_connector_state *conn_state = connector->state;
> - struct intel_encoder *encoder =
> - to_intel_encoder(conn_state->best_encoder);
> - const struct drm_display_mode *mode;
> + struct seq_file *m = file->private_data;
> + struct drm_i915_private *dev_priv = m->private;
> + intel_wakeref_t wakeref;
> + bool enable;
> + int ret;
>
> - seq_printf(m, "[CONNECTOR:%d:%s]: status: %s\n",
> - connector->base.id, connector->name,
> - drm_get_connector_status_name(connector->status));
> + ret = kstrtobool_from_user(ubuf, len, &enable);
> + if (ret < 0)
> + return ret;
>
> - if (connector->status == connector_status_disconnected)
> - return;
> -
> - seq_printf(m, "\tphysical dimensions: %dx%dmm\n",
> - connector->display_info.width_mm,
> - connector->display_info.height_mm);
> - seq_printf(m, "\tsubpixel order: %s\n",
> - drm_get_subpixel_order_name(connector->display_info.subpixel_order));
> - seq_printf(m, "\tCEA rev: %d\n", connector->display_info.cea_rev);
> -
> - if (!encoder)
> - return;
> -
> - switch (connector->connector_type) {
> - case DRM_MODE_CONNECTOR_DisplayPort:
> - case DRM_MODE_CONNECTOR_eDP:
> - if (encoder->type == INTEL_OUTPUT_DP_MST)
> - intel_dp_mst_info(m, intel_connector);
> - else
> - intel_dp_info(m, intel_connector);
> - break;
> - case DRM_MODE_CONNECTOR_LVDS:
> - if (encoder->type == INTEL_OUTPUT_LVDS)
> - intel_lvds_info(m, intel_connector);
> - break;
> - case DRM_MODE_CONNECTOR_HDMIA:
> - if (encoder->type == INTEL_OUTPUT_HDMI ||
> - encoder->type == INTEL_OUTPUT_DDI)
> - intel_hdmi_info(m, intel_connector);
> - break;
> - default:
> - break;
> - }
> -
> - seq_printf(m, "\tmodes:\n");
> - list_for_each_entry(mode, &connector->modes, head)
> - intel_seq_print_mode(m, 2, mode);
> -}
> -
> -static const char *plane_type(enum drm_plane_type type)
> -{
> - switch (type) {
> - case DRM_PLANE_TYPE_OVERLAY:
> - return "OVL";
> - case DRM_PLANE_TYPE_PRIMARY:
> - return "PRI";
> - case DRM_PLANE_TYPE_CURSOR:
> - return "CUR";
> - /*
> - * Deliberately omitting default: to generate compiler warnings
> - * when a new drm_plane_type gets added.
> - */
> - }
> -
> - return "unknown";
> -}
> -
> -static void plane_rotation(char *buf, size_t bufsize, unsigned int rotation)
> -{
> - /*
> - * According to doc only one DRM_MODE_ROTATE_ is allowed but this
> - * will print them all to visualize if the values are misused
> - */
> - snprintf(buf, bufsize,
> - "%s%s%s%s%s%s(0x%08x)",
> - (rotation & DRM_MODE_ROTATE_0) ? "0 " : "",
> - (rotation & DRM_MODE_ROTATE_90) ? "90 " : "",
> - (rotation & DRM_MODE_ROTATE_180) ? "180 " : "",
> - (rotation & DRM_MODE_ROTATE_270) ? "270 " : "",
> - (rotation & DRM_MODE_REFLECT_X) ? "FLIPX " : "",
> - (rotation & DRM_MODE_REFLECT_Y) ? "FLIPY " : "",
> - rotation);
> -}
> -
> -static void intel_plane_uapi_info(struct seq_file *m, struct intel_plane *plane)
> -{
> - const struct intel_plane_state *plane_state =
> - to_intel_plane_state(plane->base.state);
> - const struct drm_framebuffer *fb = plane_state->uapi.fb;
> - struct drm_format_name_buf format_name;
> - struct drm_rect src, dst;
> - char rot_str[48];
> -
> - src = drm_plane_state_src(&plane_state->uapi);
> - dst = drm_plane_state_dest(&plane_state->uapi);
> -
> - if (fb)
> - drm_get_format_name(fb->format->format, &format_name);
> -
> - plane_rotation(rot_str, sizeof(rot_str),
> - plane_state->uapi.rotation);
> -
> - seq_printf(m, "\t\tuapi: fb=%d,%s,%dx%d, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",
> - fb ? fb->base.id : 0, fb ? format_name.str : "n/a",
> - fb ? fb->width : 0, fb ? fb->height : 0,
> - DRM_RECT_FP_ARG(&src),
> - DRM_RECT_ARG(&dst),
> - rot_str);
> -}
> -
> -static void intel_plane_hw_info(struct seq_file *m, struct intel_plane *plane)
> -{
> - const struct intel_plane_state *plane_state =
> - to_intel_plane_state(plane->base.state);
> - const struct drm_framebuffer *fb = plane_state->hw.fb;
> - struct drm_format_name_buf format_name;
> - char rot_str[48];
> -
> - if (!fb)
> - return;
> -
> - drm_get_format_name(fb->format->format, &format_name);
> -
> - plane_rotation(rot_str, sizeof(rot_str),
> - plane_state->hw.rotation);
> -
> - seq_printf(m, "\t\thw: fb=%d,%s,%dx%d, visible=%s, src=" DRM_RECT_FP_FMT ", dst=" DRM_RECT_FMT ", rotation=%s\n",
> - fb->base.id, format_name.str,
> - fb->width, fb->height,
> - yesno(plane_state->uapi.visible),
> - DRM_RECT_FP_ARG(&plane_state->uapi.src),
> - DRM_RECT_ARG(&plane_state->uapi.dst),
> - rot_str);
> -}
> -
> -static void intel_plane_info(struct seq_file *m, struct intel_crtc *crtc)
> -{
> - struct drm_i915_private *dev_priv = node_to_i915(m->private);
> - struct intel_plane *plane;
> -
> - for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
> - seq_printf(m, "\t[PLANE:%d:%s]: type=%s\n",
> - plane->base.base.id, plane->base.name,
> - plane_type(plane->base.type));
> - intel_plane_uapi_info(m, plane);
> - intel_plane_hw_info(m, plane);
> - }
> -}
> -
> -static void intel_scaler_info(struct seq_file *m, struct intel_crtc *crtc)
> -{
> - const struct intel_crtc_state *crtc_state =
> - to_intel_crtc_state(crtc->base.state);
> - int num_scalers = crtc->num_scalers;
> - int i;
> -
> - /* Not all platformas have a scaler */
> - if (num_scalers) {
> - seq_printf(m, "\tnum_scalers=%d, scaler_users=%x scaler_id=%d",
> - num_scalers,
> - crtc_state->scaler_state.scaler_users,
> - crtc_state->scaler_state.scaler_id);
> -
> - for (i = 0; i < num_scalers; i++) {
> - const struct intel_scaler *sc =
> - &crtc_state->scaler_state.scalers[i];
> -
> - seq_printf(m, ", scalers[%d]: use=%s, mode=%x",
> - i, yesno(sc->in_use), sc->mode);
> - }
> - seq_puts(m, "\n");
> - } else {
> - seq_puts(m, "\tNo scalers available on this platform\n");
> - }
> -}
> -
> -static void intel_crtc_info(struct seq_file *m, struct intel_crtc *crtc)
> -{
> - struct drm_i915_private *dev_priv = node_to_i915(m->private);
> - const struct intel_crtc_state *crtc_state =
> - to_intel_crtc_state(crtc->base.state);
> - struct intel_encoder *encoder;
> -
> - seq_printf(m, "[CRTC:%d:%s]:\n",
> - crtc->base.base.id, crtc->base.name);
> -
> - seq_printf(m, "\tuapi: enable=%s, active=%s, mode=" DRM_MODE_FMT "\n",
> - yesno(crtc_state->uapi.enable),
> - yesno(crtc_state->uapi.active),
> - DRM_MODE_ARG(&crtc_state->uapi.mode));
> -
> - if (crtc_state->hw.enable) {
> - seq_printf(m, "\thw: active=%s, adjusted_mode=" DRM_MODE_FMT "\n",
> - yesno(crtc_state->hw.active),
> - DRM_MODE_ARG(&crtc_state->hw.adjusted_mode));
> -
> - seq_printf(m, "\tpipe src size=%dx%d, dither=%s, bpp=%d\n",
> - crtc_state->pipe_src_w, crtc_state->pipe_src_h,
> - yesno(crtc_state->dither), crtc_state->pipe_bpp);
> -
> - intel_scaler_info(m, crtc);
> - }
> -
> - for_each_intel_encoder_mask(&dev_priv->drm, encoder,
> - crtc_state->uapi.encoder_mask)
> - intel_encoder_info(m, crtc, encoder);
> -
> - intel_plane_info(m, crtc);
> -
> - seq_printf(m, "\tunderrun reporting: cpu=%s pch=%s\n",
> - yesno(!crtc->cpu_fifo_underrun_disabled),
> - yesno(!crtc->pch_fifo_underrun_disabled));
> -}
> -
> -static int i915_display_info(struct seq_file *m, void *unused)
> -{
> - struct drm_i915_private *dev_priv = node_to_i915(m->private);
> - struct drm_device *dev = &dev_priv->drm;
> - struct intel_crtc *crtc;
> - struct drm_connector *connector;
> - struct drm_connector_list_iter conn_iter;
> - intel_wakeref_t wakeref;
> -
> - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> -
> - drm_modeset_lock_all(dev);
> -
> - seq_printf(m, "CRTC info\n");
> - seq_printf(m, "---------\n");
> - for_each_intel_crtc(dev, crtc)
> - intel_crtc_info(m, crtc);
> -
> - seq_printf(m, "\n");
> - seq_printf(m, "Connector info\n");
> - seq_printf(m, "--------------\n");
> - drm_connector_list_iter_begin(dev, &conn_iter);
> - drm_for_each_connector_iter(connector, &conn_iter)
> - intel_connector_info(m, connector);
> - drm_connector_list_iter_end(&conn_iter);
> -
> - drm_modeset_unlock_all(dev);
> -
> - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
> -
> - return 0;
> -}
> -
> -static int i915_engine_info(struct seq_file *m, void *unused)
> -{
> - struct drm_i915_private *dev_priv = node_to_i915(m->private);
> - struct intel_engine_cs *engine;
> - intel_wakeref_t wakeref;
> - struct drm_printer p;
> -
> - wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
> -
> - seq_printf(m, "GT awake? %s [%d]\n",
> - yesno(dev_priv->gt.awake),
> - atomic_read(&dev_priv->gt.wakeref.count));
> - seq_printf(m, "CS timestamp frequency: %u kHz\n",
> - RUNTIME_INFO(dev_priv)->cs_timestamp_frequency_khz);
> -
> - p = drm_seq_file_printer(m);
> - for_each_uabi_engine(engine, dev_priv)
> - intel_engine_dump(engine, &p, "%s\n", engine->name);
> -
> - intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
> -
> - return 0;
> -}
> -
> -static int i915_rcs_topology(struct seq_file *m, void *unused)
> -{
> - struct drm_i915_private *dev_priv = node_to_i915(m->private);
> - struct drm_printer p = drm_seq_file_printer(m);
> -
> - intel_device_info_print_topology(&RUNTIME_INFO(dev_priv)->sseu, &p);
> -
> - return 0;
> -}
> -
> -static int i915_shrinker_info(struct seq_file *m, void *unused)
> -{
> - struct drm_i915_private *i915 = node_to_i915(m->private);
> -
> - seq_printf(m, "seeks = %d\n", i915->mm.shrinker.seeks);
> - seq_printf(m, "batch = %lu\n", i915->mm.shrinker.batch);
> -
> - return 0;
> -}
> -
> -static int i915_shared_dplls_info(struct seq_file *m, void *unused)
> -{
> - struct drm_i915_private *dev_priv = node_to_i915(m->private);
> - struct drm_device *dev = &dev_priv->drm;
> - int i;
> -
> - drm_modeset_lock_all(dev);
> - for (i = 0; i < dev_priv->num_shared_dpll; i++) {
> - struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i];
> -
> - seq_printf(m, "DPLL%i: %s, id: %i\n", i, pll->info->name,
> - pll->info->id);
> - seq_printf(m, " crtc_mask: 0x%08x, active: 0x%x, on: %s\n",
> - pll->state.crtc_mask, pll->active_mask, yesno(pll->on));
> - seq_printf(m, " tracked hardware state:\n");
> - seq_printf(m, " dpll: 0x%08x\n", pll->state.hw_state.dpll);
> - seq_printf(m, " dpll_md: 0x%08x\n",
> - pll->state.hw_state.dpll_md);
> - seq_printf(m, " fp0: 0x%08x\n", pll->state.hw_state.fp0);
> - seq_printf(m, " fp1: 0x%08x\n", pll->state.hw_state.fp1);
> - seq_printf(m, " wrpll: 0x%08x\n", pll->state.hw_state.wrpll);
> - seq_printf(m, " cfgcr0: 0x%08x\n", pll->state.hw_state.cfgcr0);
> - seq_printf(m, " cfgcr1: 0x%08x\n", pll->state.hw_state.cfgcr1);
> - seq_printf(m, " mg_refclkin_ctl: 0x%08x\n",
> - pll->state.hw_state.mg_refclkin_ctl);
> - seq_printf(m, " mg_clktop2_coreclkctl1: 0x%08x\n",
> - pll->state.hw_state.mg_clktop2_coreclkctl1);
> - seq_printf(m, " mg_clktop2_hsclkctl: 0x%08x\n",
> - pll->state.hw_state.mg_clktop2_hsclkctl);
> - seq_printf(m, " mg_pll_div0: 0x%08x\n",
> - pll->state.hw_state.mg_pll_div0);
> - seq_printf(m, " mg_pll_div1: 0x%08x\n",
> - pll->state.hw_state.mg_pll_div1);
> - seq_printf(m, " mg_pll_lf: 0x%08x\n",
> - pll->state.hw_state.mg_pll_lf);
> - seq_printf(m, " mg_pll_frac_lock: 0x%08x\n",
> - pll->state.hw_state.mg_pll_frac_lock);
> - seq_printf(m, " mg_pll_ssc: 0x%08x\n",
> - pll->state.hw_state.mg_pll_ssc);
> - seq_printf(m, " mg_pll_bias: 0x%08x\n",
> - pll->state.hw_state.mg_pll_bias);
> - seq_printf(m, " mg_pll_tdc_coldst_bias: 0x%08x\n",
> - pll->state.hw_state.mg_pll_tdc_coldst_bias);
> - }
> - drm_modeset_unlock_all(dev);
> -
> - return 0;
> -}
> -
> -static int i915_wa_registers(struct seq_file *m, void *unused)
> -{
> - struct drm_i915_private *i915 = node_to_i915(m->private);
> - struct intel_engine_cs *engine;
> -
> - for_each_uabi_engine(engine, i915) {
> - const struct i915_wa_list *wal = &engine->ctx_wa_list;
> - const struct i915_wa *wa;
> - unsigned int count;
> -
> - count = wal->count;
> - if (!count)
> - continue;
> -
> - seq_printf(m, "%s: Workarounds applied: %u\n",
> - engine->name, count);
> -
> - for (wa = wal->list; count--; wa++)
> - seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X\n",
> - i915_mmio_reg_offset(wa->reg),
> - wa->set, wa->clr);
> -
> - seq_printf(m, "\n");
> - }
> -
> - return 0;
> -}
> -
> -static int i915_ipc_status_show(struct seq_file *m, void *data)
> -{
> - struct drm_i915_private *dev_priv = m->private;
> -
> - seq_printf(m, "Isochronous Priority Control: %s\n",
> - yesno(dev_priv->ipc_enabled));
> - return 0;
> -}
> -
> -static int i915_ipc_status_open(struct inode *inode, struct file *file)
> -{
> - struct drm_i915_private *dev_priv = inode->i_private;
> -
> - if (!HAS_IPC(dev_priv))
> - return -ENODEV;
> -
> - return single_open(file, i915_ipc_status_show, dev_priv);
> -}
> -
> -static ssize_t i915_ipc_status_write(struct file *file, const char __user *ubuf,
> - size_t len, loff_t *offp)
> -{
> - struct seq_file *m = file->private_data;
> - struct drm_i915_private *dev_priv = m->private;
> - intel_wakeref_t wakeref;
> - bool enable;
> - int ret;
> -
> - ret = kstrtobool_from_user(ubuf, len, &enable);
> - if (ret < 0)
> - return ret;
> -
> - with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) {
> - if (!dev_priv->ipc_enabled && enable)
> - drm_info(&dev_priv->drm,
> - "Enabling IPC: WM will be proper only after next commit\n");
> - dev_priv->wm.distrust_bios_wm = true;
> - dev_priv->ipc_enabled = enable;
> - intel_enable_ipc(dev_priv);
> - }
> -
> - return len;
> -}
> -
> -static const struct file_operations i915_ipc_status_fops = {
> - .owner = THIS_MODULE,
> - .open = i915_ipc_status_open,
> - .read = seq_read,
> - .llseek = seq_lseek,
> - .release = single_release,
> - .write = i915_ipc_status_write
> -};
> -
> -static int i915_ddb_info(struct seq_file *m, void *unused)
> -{
> - struct drm_i915_private *dev_priv = node_to_i915(m->private);
> - struct drm_device *dev = &dev_priv->drm;
> - struct skl_ddb_entry *entry;
> - struct intel_crtc *crtc;
> -
> - if (INTEL_GEN(dev_priv) < 9)
> - return -ENODEV;
> -
> - drm_modeset_lock_all(dev);
> -
> - seq_printf(m, "%-15s%8s%8s%8s\n", "", "Start", "End", "Size");
> -
> - for_each_intel_crtc(&dev_priv->drm, crtc) {
> - struct intel_crtc_state *crtc_state =
> - to_intel_crtc_state(crtc->base.state);
> - enum pipe pipe = crtc->pipe;
> - enum plane_id plane_id;
> -
> - seq_printf(m, "Pipe %c\n", pipe_name(pipe));
> -
> - for_each_plane_id_on_crtc(crtc, plane_id) {
> - entry = &crtc_state->wm.skl.plane_ddb_y[plane_id];
> - seq_printf(m, " Plane%-8d%8u%8u%8u\n", plane_id + 1,
> - entry->start, entry->end,
> - skl_ddb_entry_size(entry));
> - }
> -
> - entry = &crtc_state->wm.skl.plane_ddb_y[PLANE_CURSOR];
> - seq_printf(m, " %-13s%8u%8u%8u\n", "Cursor", entry->start,
> - entry->end, skl_ddb_entry_size(entry));
> - }
> -
> - drm_modeset_unlock_all(dev);
> -
> - return 0;
> -}
> -
> -static void drrs_status_per_crtc(struct seq_file *m,
> - struct drm_device *dev,
> - struct intel_crtc *intel_crtc)
> -{
> - struct drm_i915_private *dev_priv = to_i915(dev);
> - struct i915_drrs *drrs = &dev_priv->drrs;
> - int vrefresh = 0;
> - struct drm_connector *connector;
> - struct drm_connector_list_iter conn_iter;
> -
> - drm_connector_list_iter_begin(dev, &conn_iter);
> - drm_for_each_connector_iter(connector, &conn_iter) {
> - if (connector->state->crtc != &intel_crtc->base)
> - continue;
> -
> - seq_printf(m, "%s:\n", connector->name);
> - }
> - drm_connector_list_iter_end(&conn_iter);
> -
> - seq_puts(m, "\n");
> -
> - if (to_intel_crtc_state(intel_crtc->base.state)->has_drrs) {
> - struct intel_panel *panel;
> -
> - mutex_lock(&drrs->mutex);
> - /* DRRS Supported */
> - seq_puts(m, "\tDRRS Supported: Yes\n");
> -
> - /* disable_drrs() will make drrs->dp NULL */
> - if (!drrs->dp) {
> - seq_puts(m, "Idleness DRRS: Disabled\n");
> - if (dev_priv->psr.enabled)
> - seq_puts(m,
> - "\tAs PSR is enabled, DRRS is not enabled\n");
> - mutex_unlock(&drrs->mutex);
> - return;
> - }
> -
> - panel = &drrs->dp->attached_connector->panel;
> - seq_printf(m, "\t\tBusy_frontbuffer_bits: 0x%X",
> - drrs->busy_frontbuffer_bits);
> -
> - seq_puts(m, "\n\t\t");
> - if (drrs->refresh_rate_type == DRRS_HIGH_RR) {
> - seq_puts(m, "DRRS_State: DRRS_HIGH_RR\n");
> - vrefresh = panel->fixed_mode->vrefresh;
> - } else if (drrs->refresh_rate_type == DRRS_LOW_RR) {
> - seq_puts(m, "DRRS_State: DRRS_LOW_RR\n");
> - vrefresh = panel->downclock_mode->vrefresh;
> - } else {
> - seq_printf(m, "DRRS_State: Unknown(%d)\n",
> - drrs->refresh_rate_type);
> - mutex_unlock(&drrs->mutex);
> - return;
> - }
> - seq_printf(m, "\t\tVrefresh: %d", vrefresh);
> -
> - seq_puts(m, "\n\t\t");
> - mutex_unlock(&drrs->mutex);
> - } else {
> - /* DRRS not supported. Print the VBT parameter*/
> - seq_puts(m, "\tDRRS Supported : No");
> - }
> - seq_puts(m, "\n");
> -}
> -
> -static int i915_drrs_status(struct seq_file *m, void *unused)
> -{
> - struct drm_i915_private *dev_priv = node_to_i915(m->private);
> - struct drm_device *dev = &dev_priv->drm;
> - struct intel_crtc *intel_crtc;
> - int active_crtc_cnt = 0;
> -
> - drm_modeset_lock_all(dev);
> - for_each_intel_crtc(dev, intel_crtc) {
> - if (intel_crtc->base.state->active) {
> - active_crtc_cnt++;
> - seq_printf(m, "\nCRTC %d: ", active_crtc_cnt);
> -
> - drrs_status_per_crtc(m, dev, intel_crtc);
> - }
> - }
> - drm_modeset_unlock_all(dev);
> -
> - if (!active_crtc_cnt)
> - seq_puts(m, "No active crtc found\n");
> -
> - return 0;
> -}
> -
> -static int i915_dp_mst_info(struct seq_file *m, void *unused)
> -{
> - struct drm_i915_private *dev_priv = node_to_i915(m->private);
> - struct drm_device *dev = &dev_priv->drm;
> - struct intel_encoder *intel_encoder;
> - struct intel_digital_port *intel_dig_port;
> - struct drm_connector *connector;
> - struct drm_connector_list_iter conn_iter;
> -
> - drm_connector_list_iter_begin(dev, &conn_iter);
> - drm_for_each_connector_iter(connector, &conn_iter) {
> - if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
> - continue;
> -
> - intel_encoder = intel_attached_encoder(to_intel_connector(connector));
> - if (!intel_encoder || intel_encoder->type == INTEL_OUTPUT_DP_MST)
> - continue;
> -
> - intel_dig_port = enc_to_dig_port(intel_encoder);
> - if (!intel_dig_port->dp.can_mst)
> - continue;
> -
> - seq_printf(m, "MST Source Port [ENCODER:%d:%s]\n",
> - intel_dig_port->base.base.base.id,
> - intel_dig_port->base.base.name);
> - drm_dp_mst_dump_topology(m, &intel_dig_port->dp.mst_mgr);
> - }
> - drm_connector_list_iter_end(&conn_iter);
> -
> - return 0;
> -}
> -
> -static ssize_t i915_displayport_test_active_write(struct file *file,
> - const char __user *ubuf,
> - size_t len, loff_t *offp)
> -{
> - char *input_buffer;
> - int status = 0;
> - struct drm_device *dev;
> - struct drm_connector *connector;
> - struct drm_connector_list_iter conn_iter;
> - struct intel_dp *intel_dp;
> - int val = 0;
> -
> - dev = ((struct seq_file *)file->private_data)->private;
> -
> - if (len == 0)
> - return 0;
> -
> - input_buffer = memdup_user_nul(ubuf, len);
> - if (IS_ERR(input_buffer))
> - return PTR_ERR(input_buffer);
> -
> - drm_dbg(&to_i915(dev)->drm,
> - "Copied %d bytes from user\n", (unsigned int)len);
> -
> - drm_connector_list_iter_begin(dev, &conn_iter);
> - drm_for_each_connector_iter(connector, &conn_iter) {
> - struct intel_encoder *encoder;
> -
> - if (connector->connector_type !=
> - DRM_MODE_CONNECTOR_DisplayPort)
> - continue;
> -
> - encoder = to_intel_encoder(connector->encoder);
> - if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
> - continue;
> -
> - if (encoder && connector->status == connector_status_connected) {
> - intel_dp = enc_to_intel_dp(encoder);
> - status = kstrtoint(input_buffer, 10, &val);
> - if (status < 0)
> - break;
> - drm_dbg(&to_i915(dev)->drm,
> - "Got %d for test active\n", val);
> - /* To prevent erroneous activation of the compliance
> - * testing code, only accept an actual value of 1 here
> - */
> - if (val == 1)
> - intel_dp->compliance.test_active = true;
> - else
> - intel_dp->compliance.test_active = false;
> - }
> - }
> - drm_connector_list_iter_end(&conn_iter);
> - kfree(input_buffer);
> - if (status < 0)
> - return status;
> -
> - *offp += len;
> - return len;
> -}
> -
> -static int i915_displayport_test_active_show(struct seq_file *m, void *data)
> -{
> - struct drm_i915_private *dev_priv = m->private;
> - struct drm_device *dev = &dev_priv->drm;
> - struct drm_connector *connector;
> - struct drm_connector_list_iter conn_iter;
> - struct intel_dp *intel_dp;
> -
> - drm_connector_list_iter_begin(dev, &conn_iter);
> - drm_for_each_connector_iter(connector, &conn_iter) {
> - struct intel_encoder *encoder;
> -
> - if (connector->connector_type !=
> - DRM_MODE_CONNECTOR_DisplayPort)
> - continue;
> -
> - encoder = to_intel_encoder(connector->encoder);
> - if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
> - continue;
> -
> - if (encoder && connector->status == connector_status_connected) {
> - intel_dp = enc_to_intel_dp(encoder);
> - if (intel_dp->compliance.test_active)
> - seq_puts(m, "1");
> - else
> - seq_puts(m, "0");
> - } else
> - seq_puts(m, "0");
> - }
> - drm_connector_list_iter_end(&conn_iter);
> -
> - return 0;
> -}
> -
> -static int i915_displayport_test_active_open(struct inode *inode,
> - struct file *file)
> -{
> - return single_open(file, i915_displayport_test_active_show,
> - inode->i_private);
> -}
> -
> -static const struct file_operations i915_displayport_test_active_fops = {
> - .owner = THIS_MODULE,
> - .open = i915_displayport_test_active_open,
> - .read = seq_read,
> - .llseek = seq_lseek,
> - .release = single_release,
> - .write = i915_displayport_test_active_write
> -};
> -
> -static int i915_displayport_test_data_show(struct seq_file *m, void *data)
> -{
> - struct drm_i915_private *dev_priv = m->private;
> - struct drm_device *dev = &dev_priv->drm;
> - struct drm_connector *connector;
> - struct drm_connector_list_iter conn_iter;
> - struct intel_dp *intel_dp;
> -
> - drm_connector_list_iter_begin(dev, &conn_iter);
> - drm_for_each_connector_iter(connector, &conn_iter) {
> - struct intel_encoder *encoder;
> -
> - if (connector->connector_type !=
> - DRM_MODE_CONNECTOR_DisplayPort)
> - continue;
> -
> - encoder = to_intel_encoder(connector->encoder);
> - if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
> - continue;
> -
> - if (encoder && connector->status == connector_status_connected) {
> - intel_dp = enc_to_intel_dp(encoder);
> - if (intel_dp->compliance.test_type ==
> - DP_TEST_LINK_EDID_READ)
> - seq_printf(m, "%lx",
> - intel_dp->compliance.test_data.edid);
> - else if (intel_dp->compliance.test_type ==
> - DP_TEST_LINK_VIDEO_PATTERN) {
> - seq_printf(m, "hdisplay: %d\n",
> - intel_dp->compliance.test_data.hdisplay);
> - seq_printf(m, "vdisplay: %d\n",
> - intel_dp->compliance.test_data.vdisplay);
> - seq_printf(m, "bpc: %u\n",
> - intel_dp->compliance.test_data.bpc);
> - }
> - } else
> - seq_puts(m, "0");
> - }
> - drm_connector_list_iter_end(&conn_iter);
> -
> - return 0;
> -}
> -DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_data);
> -
> -static int i915_displayport_test_type_show(struct seq_file *m, void *data)
> -{
> - struct drm_i915_private *dev_priv = m->private;
> - struct drm_device *dev = &dev_priv->drm;
> - struct drm_connector *connector;
> - struct drm_connector_list_iter conn_iter;
> - struct intel_dp *intel_dp;
> -
> - drm_connector_list_iter_begin(dev, &conn_iter);
> - drm_for_each_connector_iter(connector, &conn_iter) {
> - struct intel_encoder *encoder;
> -
> - if (connector->connector_type !=
> - DRM_MODE_CONNECTOR_DisplayPort)
> - continue;
> -
> - encoder = to_intel_encoder(connector->encoder);
> - if (encoder && encoder->type == INTEL_OUTPUT_DP_MST)
> - continue;
> -
> - if (encoder && connector->status == connector_status_connected) {
> - intel_dp = enc_to_intel_dp(encoder);
> - seq_printf(m, "%02lx", intel_dp->compliance.test_type);
> - } else
> - seq_puts(m, "0");
> - }
> - drm_connector_list_iter_end(&conn_iter);
> -
> - return 0;
> -}
> -DEFINE_SHOW_ATTRIBUTE(i915_displayport_test_type);
> -
> -static void wm_latency_show(struct seq_file *m, const u16 wm[8])
> -{
> - struct drm_i915_private *dev_priv = m->private;
> - struct drm_device *dev = &dev_priv->drm;
> - int level;
> - int num_levels;
> -
> - if (IS_CHERRYVIEW(dev_priv))
> - num_levels = 3;
> - else if (IS_VALLEYVIEW(dev_priv))
> - num_levels = 1;
> - else if (IS_G4X(dev_priv))
> - num_levels = 3;
> - else
> - num_levels = ilk_wm_max_level(dev_priv) + 1;
> -
> - drm_modeset_lock_all(dev);
> -
> - for (level = 0; level < num_levels; level++) {
> - unsigned int latency = wm[level];
> -
> - /*
> - * - WM1+ latency values in 0.5us units
> - * - latencies are in us on gen9/vlv/chv
> - */
> - if (INTEL_GEN(dev_priv) >= 9 ||
> - IS_VALLEYVIEW(dev_priv) ||
> - IS_CHERRYVIEW(dev_priv) ||
> - IS_G4X(dev_priv))
> - latency *= 10;
> - else if (level > 0)
> - latency *= 5;
> -
> - seq_printf(m, "WM%d %u (%u.%u usec)\n",
> - level, wm[level], latency / 10, latency % 10);
> - }
> -
> - drm_modeset_unlock_all(dev);
> -}
> -
> -static int pri_wm_latency_show(struct seq_file *m, void *data)
> -{
> - struct drm_i915_private *dev_priv = m->private;
> - const u16 *latencies;
> -
> - if (INTEL_GEN(dev_priv) >= 9)
> - latencies = dev_priv->wm.skl_latency;
> - else
> - latencies = dev_priv->wm.pri_latency;
> -
> - wm_latency_show(m, latencies);
> -
> - return 0;
> -}
> -
> -static int spr_wm_latency_show(struct seq_file *m, void *data)
> -{
> - struct drm_i915_private *dev_priv = m->private;
> - const u16 *latencies;
> -
> - if (INTEL_GEN(dev_priv) >= 9)
> - latencies = dev_priv->wm.skl_latency;
> - else
> - latencies = dev_priv->wm.spr_latency;
> -
> - wm_latency_show(m, latencies);
> -
> - return 0;
> -}
> -
> -static int cur_wm_latency_show(struct seq_file *m, void *data)
> -{
> - struct drm_i915_private *dev_priv = m->private;
> - const u16 *latencies;
> -
> - if (INTEL_GEN(dev_priv) >= 9)
> - latencies = dev_priv->wm.skl_latency;
> - else
> - latencies = dev_priv->wm.cur_latency;
> -
> - wm_latency_show(m, latencies);
> -
> - return 0;
> -}
> -
> -static int pri_wm_latency_open(struct inode *inode, struct file *file)
> -{
> - struct drm_i915_private *dev_priv = inode->i_private;
> -
> - if (INTEL_GEN(dev_priv) < 5 && !IS_G4X(dev_priv))
> - return -ENODEV;
> -
> - return single_open(file, pri_wm_latency_show, dev_priv);
> -}
> -
> -static int spr_wm_latency_open(struct inode *inode, struct file *file)
> -{
> - struct drm_i915_private *dev_priv = inode->i_private;
> -
> - if (HAS_GMCH(dev_priv))
> - return -ENODEV;
> -
> - return single_open(file, spr_wm_latency_show, dev_priv);
> -}
> -
> -static int cur_wm_latency_open(struct inode *inode, struct file *file)
> -{
> - struct drm_i915_private *dev_priv = inode->i_private;
> -
> - if (HAS_GMCH(dev_priv))
> - return -ENODEV;
> -
> - return single_open(file, cur_wm_latency_show, dev_priv);
> -}
> -
> -static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
> - size_t len, loff_t *offp, u16 wm[8])
> -{
> - struct seq_file *m = file->private_data;
> - struct drm_i915_private *dev_priv = m->private;
> - struct drm_device *dev = &dev_priv->drm;
> - u16 new[8] = { 0 };
> - int num_levels;
> - int level;
> - int ret;
> - char tmp[32];
> -
> - if (IS_CHERRYVIEW(dev_priv))
> - num_levels = 3;
> - else if (IS_VALLEYVIEW(dev_priv))
> - num_levels = 1;
> - else if (IS_G4X(dev_priv))
> - num_levels = 3;
> - else
> - num_levels = ilk_wm_max_level(dev_priv) + 1;
> -
> - if (len >= sizeof(tmp))
> - return -EINVAL;
> -
> - if (copy_from_user(tmp, ubuf, len))
> - return -EFAULT;
> -
> - tmp[len] = '\0';
> -
> - ret = sscanf(tmp, "%hu %hu %hu %hu %hu %hu %hu %hu",
> - &new[0], &new[1], &new[2], &new[3],
> - &new[4], &new[5], &new[6], &new[7]);
> - if (ret != num_levels)
> - return -EINVAL;
> -
> - drm_modeset_lock_all(dev);
> -
> - for (level = 0; level < num_levels; level++)
> - wm[level] = new[level];
> -
> - drm_modeset_unlock_all(dev);
> + with_intel_runtime_pm(&dev_priv->runtime_pm, wakeref) {
> + if (!dev_priv->ipc_enabled && enable)
> + drm_info(&dev_priv->drm,
> + "Enabling IPC: WM will be proper only after next commit\n");
> + dev_priv->wm.distrust_bios_wm = true;
> + dev_priv->ipc_enabled = enable;
> + intel_enable_ipc(dev_priv);
> + }
>
> return len;
> }
>
> -
> -static ssize_t pri_wm_latency_write(struct file *file, const char __user *ubuf,
> - size_t len, loff_t *offp)
> -{
> - struct seq_file *m = file->private_data;
> - struct drm_i915_private *dev_priv = m->private;
> - u16 *latencies;
> -
> - if (INTEL_GEN(dev_priv) >= 9)
> - latencies = dev_priv->wm.skl_latency;
> - else
> - latencies = dev_priv->wm.pri_latency;
> -
> - return wm_latency_write(file, ubuf, len, offp, latencies);
> -}
> -
> -static ssize_t spr_wm_latency_write(struct file *file, const char __user *ubuf,
> - size_t len, loff_t *offp)
> -{
> - struct seq_file *m = file->private_data;
> - struct drm_i915_private *dev_priv = m->private;
> - u16 *latencies;
> -
> - if (INTEL_GEN(dev_priv) >= 9)
> - latencies = dev_priv->wm.skl_latency;
> - else
> - latencies = dev_priv->wm.spr_latency;
> -
> - return wm_latency_write(file, ubuf, len, offp, latencies);
> -}
> -
> -static ssize_t cur_wm_latency_write(struct file *file, const char __user *ubuf,
> - size_t len, loff_t *offp)
> -{
> - struct seq_file *m = file->private_data;
> - struct drm_i915_private *dev_priv = m->private;
> - u16 *latencies;
> -
> - if (INTEL_GEN(dev_priv) >= 9)
> - latencies = dev_priv->wm.skl_latency;
> - else
> - latencies = dev_priv->wm.cur_latency;
> -
> - return wm_latency_write(file, ubuf, len, offp, latencies);
> -}
> -
> -static const struct file_operations i915_pri_wm_latency_fops = {
> - .owner = THIS_MODULE,
> - .open = pri_wm_latency_open,
> - .read = seq_read,
> - .llseek = seq_lseek,
> - .release = single_release,
> - .write = pri_wm_latency_write
> -};
> -
> -static const struct file_operations i915_spr_wm_latency_fops = {
> - .owner = THIS_MODULE,
> - .open = spr_wm_latency_open,
> - .read = seq_read,
> - .llseek = seq_lseek,
> - .release = single_release,
> - .write = spr_wm_latency_write
> -};
> -
> -static const struct file_operations i915_cur_wm_latency_fops = {
> +static const struct file_operations i915_ipc_status_fops = {
> .owner = THIS_MODULE,
> - .open = cur_wm_latency_open,
> + .open = i915_ipc_status_open,
> .read = seq_read,
> .llseek = seq_lseek,
> .release = single_release,
> - .write = cur_wm_latency_write
> + .write = i915_ipc_status_write
> };
>
> static int
> @@ -3943,295 +2571,6 @@ static const struct file_operations i915_forcewake_fops = {
> .release = i915_forcewake_release,
> };
>
> -static int i915_hpd_storm_ctl_show(struct seq_file *m, void *data)
> -{
> - struct drm_i915_private *dev_priv = m->private;
> - struct i915_hotplug *hotplug = &dev_priv->hotplug;
> -
> - /* Synchronize with everything first in case there's been an HPD
> - * storm, but we haven't finished handling it in the kernel yet
> - */
> - intel_synchronize_irq(dev_priv);
> - flush_work(&dev_priv->hotplug.dig_port_work);
> - flush_delayed_work(&dev_priv->hotplug.hotplug_work);
> -
> - seq_printf(m, "Threshold: %d\n", hotplug->hpd_storm_threshold);
> - seq_printf(m, "Detected: %s\n",
> - yesno(delayed_work_pending(&hotplug->reenable_work)));
> -
> - return 0;
> -}
> -
> -static ssize_t i915_hpd_storm_ctl_write(struct file *file,
> - const char __user *ubuf, size_t len,
> - loff_t *offp)
> -{
> - struct seq_file *m = file->private_data;
> - struct drm_i915_private *dev_priv = m->private;
> - struct i915_hotplug *hotplug = &dev_priv->hotplug;
> - unsigned int new_threshold;
> - int i;
> - char *newline;
> - char tmp[16];
> -
> - if (len >= sizeof(tmp))
> - return -EINVAL;
> -
> - if (copy_from_user(tmp, ubuf, len))
> - return -EFAULT;
> -
> - tmp[len] = '\0';
> -
> - /* Strip newline, if any */
> - newline = strchr(tmp, '\n');
> - if (newline)
> - *newline = '\0';
> -
> - if (strcmp(tmp, "reset") == 0)
> - new_threshold = HPD_STORM_DEFAULT_THRESHOLD;
> - else if (kstrtouint(tmp, 10, &new_threshold) != 0)
> - return -EINVAL;
> -
> - if (new_threshold > 0)
> - drm_dbg_kms(&dev_priv->drm,
> - "Setting HPD storm detection threshold to %d\n",
> - new_threshold);
> - else
> - drm_dbg_kms(&dev_priv->drm, "Disabling HPD storm detection\n");
> -
> - spin_lock_irq(&dev_priv->irq_lock);
> - hotplug->hpd_storm_threshold = new_threshold;
> - /* Reset the HPD storm stats so we don't accidentally trigger a storm */
> - for_each_hpd_pin(i)
> - hotplug->stats[i].count = 0;
> - spin_unlock_irq(&dev_priv->irq_lock);
> -
> - /* Re-enable hpd immediately if we were in an irq storm */
> - flush_delayed_work(&dev_priv->hotplug.reenable_work);
> -
> - return len;
> -}
> -
> -static int i915_hpd_storm_ctl_open(struct inode *inode, struct file *file)
> -{
> - return single_open(file, i915_hpd_storm_ctl_show, inode->i_private);
> -}
> -
> -static const struct file_operations i915_hpd_storm_ctl_fops = {
> - .owner = THIS_MODULE,
> - .open = i915_hpd_storm_ctl_open,
> - .read = seq_read,
> - .llseek = seq_lseek,
> - .release = single_release,
> - .write = i915_hpd_storm_ctl_write
> -};
> -
> -static int i915_hpd_short_storm_ctl_show(struct seq_file *m, void *data)
> -{
> - struct drm_i915_private *dev_priv = m->private;
> -
> - seq_printf(m, "Enabled: %s\n",
> - yesno(dev_priv->hotplug.hpd_short_storm_enabled));
> -
> - return 0;
> -}
> -
> -static int
> -i915_hpd_short_storm_ctl_open(struct inode *inode, struct file *file)
> -{
> - return single_open(file, i915_hpd_short_storm_ctl_show,
> - inode->i_private);
> -}
> -
> -static ssize_t i915_hpd_short_storm_ctl_write(struct file *file,
> - const char __user *ubuf,
> - size_t len, loff_t *offp)
> -{
> - struct seq_file *m = file->private_data;
> - struct drm_i915_private *dev_priv = m->private;
> - struct i915_hotplug *hotplug = &dev_priv->hotplug;
> - char *newline;
> - char tmp[16];
> - int i;
> - bool new_state;
> -
> - if (len >= sizeof(tmp))
> - return -EINVAL;
> -
> - if (copy_from_user(tmp, ubuf, len))
> - return -EFAULT;
> -
> - tmp[len] = '\0';
> -
> - /* Strip newline, if any */
> - newline = strchr(tmp, '\n');
> - if (newline)
> - *newline = '\0';
> -
> - /* Reset to the "default" state for this system */
> - if (strcmp(tmp, "reset") == 0)
> - new_state = !HAS_DP_MST(dev_priv);
> - else if (kstrtobool(tmp, &new_state) != 0)
> - return -EINVAL;
> -
> - drm_dbg_kms(&dev_priv->drm, "%sabling HPD short storm detection\n",
> - new_state ? "En" : "Dis");
> -
> - spin_lock_irq(&dev_priv->irq_lock);
> - hotplug->hpd_short_storm_enabled = new_state;
> - /* Reset the HPD storm stats so we don't accidentally trigger a storm */
> - for_each_hpd_pin(i)
> - hotplug->stats[i].count = 0;
> - spin_unlock_irq(&dev_priv->irq_lock);
> -
> - /* Re-enable hpd immediately if we were in an irq storm */
> - flush_delayed_work(&dev_priv->hotplug.reenable_work);
> -
> - return len;
> -}
> -
> -static const struct file_operations i915_hpd_short_storm_ctl_fops = {
> - .owner = THIS_MODULE,
> - .open = i915_hpd_short_storm_ctl_open,
> - .read = seq_read,
> - .llseek = seq_lseek,
> - .release = single_release,
> - .write = i915_hpd_short_storm_ctl_write,
> -};
> -
> -static int i915_drrs_ctl_set(void *data, u64 val)
> -{
> - struct drm_i915_private *dev_priv = data;
> - struct drm_device *dev = &dev_priv->drm;
> - struct intel_crtc *crtc;
> -
> - if (INTEL_GEN(dev_priv) < 7)
> - return -ENODEV;
> -
> - for_each_intel_crtc(dev, crtc) {
> - struct drm_connector_list_iter conn_iter;
> - struct intel_crtc_state *crtc_state;
> - struct drm_connector *connector;
> - struct drm_crtc_commit *commit;
> - int ret;
> -
> - ret = drm_modeset_lock_single_interruptible(&crtc->base.mutex);
> - if (ret)
> - return ret;
> -
> - crtc_state = to_intel_crtc_state(crtc->base.state);
> -
> - if (!crtc_state->hw.active ||
> - !crtc_state->has_drrs)
> - goto out;
> -
> - commit = crtc_state->uapi.commit;
> - if (commit) {
> - ret = wait_for_completion_interruptible(&commit->hw_done);
> - if (ret)
> - goto out;
> - }
> -
> - drm_connector_list_iter_begin(dev, &conn_iter);
> - drm_for_each_connector_iter(connector, &conn_iter) {
> - struct intel_encoder *encoder;
> - struct intel_dp *intel_dp;
> -
> - if (!(crtc_state->uapi.connector_mask &
> - drm_connector_mask(connector)))
> - continue;
> -
> - encoder = intel_attached_encoder(to_intel_connector(connector));
> - if (encoder->type != INTEL_OUTPUT_EDP)
> - continue;
> -
> - drm_dbg(&dev_priv->drm,
> - "Manually %sabling DRRS. %llu\n",
> - val ? "en" : "dis", val);
> -
> - intel_dp = enc_to_intel_dp(encoder);
> - if (val)
> - intel_edp_drrs_enable(intel_dp,
> - crtc_state);
> - else
> - intel_edp_drrs_disable(intel_dp,
> - crtc_state);
> - }
> - drm_connector_list_iter_end(&conn_iter);
> -
> -out:
> - drm_modeset_unlock(&crtc->base.mutex);
> - if (ret)
> - return ret;
> - }
> -
> - return 0;
> -}
> -
> -DEFINE_SIMPLE_ATTRIBUTE(i915_drrs_ctl_fops, NULL, i915_drrs_ctl_set, "%llu\n");
> -
> -static ssize_t
> -i915_fifo_underrun_reset_write(struct file *filp,
> - const char __user *ubuf,
> - size_t cnt, loff_t *ppos)
> -{
> - struct drm_i915_private *dev_priv = filp->private_data;
> - struct intel_crtc *intel_crtc;
> - struct drm_device *dev = &dev_priv->drm;
> - int ret;
> - bool reset;
> -
> - ret = kstrtobool_from_user(ubuf, cnt, &reset);
> - if (ret)
> - return ret;
> -
> - if (!reset)
> - return cnt;
> -
> - for_each_intel_crtc(dev, intel_crtc) {
> - struct drm_crtc_commit *commit;
> - struct intel_crtc_state *crtc_state;
> -
> - ret = drm_modeset_lock_single_interruptible(&intel_crtc->base.mutex);
> - if (ret)
> - return ret;
> -
> - crtc_state = to_intel_crtc_state(intel_crtc->base.state);
> - commit = crtc_state->uapi.commit;
> - if (commit) {
> - ret = wait_for_completion_interruptible(&commit->hw_done);
> - if (!ret)
> - ret = wait_for_completion_interruptible(&commit->flip_done);
> - }
> -
> - if (!ret && crtc_state->hw.active) {
> - drm_dbg_kms(&dev_priv->drm,
> - "Re-arming FIFO underruns on pipe %c\n",
> - pipe_name(intel_crtc->pipe));
> -
> - intel_crtc_arm_fifo_underrun(intel_crtc, crtc_state);
> - }
> -
> - drm_modeset_unlock(&intel_crtc->base.mutex);
> -
> - if (ret)
> - return ret;
> - }
> -
> - ret = intel_fbc_reset_underrun(dev_priv);
> - if (ret)
> - return ret;
> -
> - return cnt;
> -}
> -
> -static const struct file_operations i915_fifo_underrun_reset_ops = {
> - .owner = THIS_MODULE,
> - .open = simple_open,
> - .write = i915_fifo_underrun_reset_write,
> - .llseek = default_llseek,
> -};
> -
> static const struct drm_info_list i915_debugfs_list[] = {
> {"i915_capabilities", i915_capabilities, 0},
> {"i915_gem_objects", i915_gem_object_info, 0},
> @@ -4247,31 +2586,20 @@ static const struct drm_info_list i915_debugfs_list[] = {
> {"i915_drpc_info", i915_drpc_info, 0},
> {"i915_ring_freq_table", i915_ring_freq_table, 0},
> {"i915_frontbuffer_tracking", i915_frontbuffer_tracking, 0},
^ should probably be under display
> - {"i915_fbc_status", i915_fbc_status, 0},
> - {"i915_ips_status", i915_ips_status, 0},
> - {"i915_sr_status", i915_sr_status, 0},
> - {"i915_opregion", i915_opregion, 0},
> - {"i915_vbt", i915_vbt, 0},
> {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0},
^ that too maybe?
> {"i915_context_status", i915_context_status, 0},
> {"i915_forcewake_domains", i915_forcewake_domains, 0},
> {"i915_swizzle_info", i915_swizzle_info, 0},
> {"i915_llc", i915_llc, 0},
> - {"i915_edp_psr_status", i915_edp_psr_status, 0},
> {"i915_energy_uJ", i915_energy_uJ, 0},
> {"i915_runtime_pm_status", i915_runtime_pm_status, 0},
> {"i915_power_domain_info", i915_power_domain_info, 0},
> {"i915_dmc_info", i915_dmc_info, 0},
power domains and dmc too maybe?
> - {"i915_display_info", i915_display_info, 0},
> {"i915_engine_info", i915_engine_info, 0},
> {"i915_rcs_topology", i915_rcs_topology, 0},
> {"i915_shrinker_info", i915_shrinker_info, 0},
> - {"i915_shared_dplls_info", i915_shared_dplls_info, 0},
> - {"i915_dp_mst_info", i915_dp_mst_info, 0},
> {"i915_wa_registers", i915_wa_registers, 0},
> - {"i915_ddb_info", i915_ddb_info, 0},
> {"i915_sseu_status", i915_sseu_status, 0},
> - {"i915_drrs_status", i915_drrs_status, 0},
> {"i915_rps_boost_info", i915_rps_boost_info, 0},
> };
> #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
> @@ -4288,21 +2616,9 @@ static const struct i915_debugfs_files {
> {"i915_error_state", &i915_error_state_fops},
> {"i915_gpu_info", &i915_gpu_info_fops},
> #endif
> - {"i915_fifo_underrun_reset", &i915_fifo_underrun_reset_ops},
> - {"i915_pri_wm_latency", &i915_pri_wm_latency_fops},
> - {"i915_spr_wm_latency", &i915_spr_wm_latency_fops},
> - {"i915_cur_wm_latency", &i915_cur_wm_latency_fops},
> - {"i915_fbc_false_color", &i915_fbc_false_color_fops},
> - {"i915_dp_test_data", &i915_displayport_test_data_fops},
> - {"i915_dp_test_type", &i915_displayport_test_type_fops},
> - {"i915_dp_test_active", &i915_displayport_test_active_fops},
> {"i915_guc_log_level", &i915_guc_log_level_fops},
> {"i915_guc_log_relay", &i915_guc_log_relay_fops},
> - {"i915_hpd_storm_ctl", &i915_hpd_storm_ctl_fops},
> - {"i915_hpd_short_storm_ctl", &i915_hpd_short_storm_ctl_fops},
> {"i915_ipc_status", &i915_ipc_status_fops},
^ that should be under display, or just nuked from orbit.
> - {"i915_drrs_ctl", &i915_drrs_ctl_fops},
> - {"i915_edp_psr_debug", &i915_edp_psr_debug_fops}
> };
>
> int i915_debugfs_register(struct drm_i915_private *dev_priv)
> @@ -4326,191 +2642,3 @@ int i915_debugfs_register(struct drm_i915_private *dev_priv)
> I915_DEBUGFS_ENTRIES,
> minor->debugfs_root, minor);
> }
> -
> -static int i915_panel_show(struct seq_file *m, void *data)
> -{
> - struct drm_connector *connector = m->private;
> - struct intel_dp *intel_dp =
> - intel_attached_dp(to_intel_connector(connector));
> -
> - if (connector->status != connector_status_connected)
> - return -ENODEV;
> -
> - seq_printf(m, "Panel power up delay: %d\n",
> - intel_dp->panel_power_up_delay);
> - seq_printf(m, "Panel power down delay: %d\n",
> - intel_dp->panel_power_down_delay);
> - seq_printf(m, "Backlight on delay: %d\n",
> - intel_dp->backlight_on_delay);
> - seq_printf(m, "Backlight off delay: %d\n",
> - intel_dp->backlight_off_delay);
> -
> - return 0;
> -}
> -DEFINE_SHOW_ATTRIBUTE(i915_panel);
> -
> -static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data)
> -{
> - struct drm_connector *connector = m->private;
> - struct intel_connector *intel_connector = to_intel_connector(connector);
> -
> - if (connector->status != connector_status_connected)
> - return -ENODEV;
> -
> - /* HDCP is supported by connector */
> - if (!intel_connector->hdcp.shim)
> - return -EINVAL;
> -
> - seq_printf(m, "%s:%d HDCP version: ", connector->name,
> - connector->base.id);
> - intel_hdcp_info(m, intel_connector);
> -
> - return 0;
> -}
> -DEFINE_SHOW_ATTRIBUTE(i915_hdcp_sink_capability);
> -
> -static int i915_dsc_fec_support_show(struct seq_file *m, void *data)
> -{
> - struct drm_connector *connector = m->private;
> - struct drm_device *dev = connector->dev;
> - struct drm_crtc *crtc;
> - struct intel_dp *intel_dp;
> - struct drm_modeset_acquire_ctx ctx;
> - struct intel_crtc_state *crtc_state = NULL;
> - int ret = 0;
> - bool try_again = false;
> -
> - drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
> -
> - do {
> - try_again = false;
> - ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
> - &ctx);
> - if (ret) {
> - if (ret == -EDEADLK && !drm_modeset_backoff(&ctx)) {
> - try_again = true;
> - continue;
> - }
> - break;
> - }
> - crtc = connector->state->crtc;
> - if (connector->status != connector_status_connected || !crtc) {
> - ret = -ENODEV;
> - break;
> - }
> - ret = drm_modeset_lock(&crtc->mutex, &ctx);
> - if (ret == -EDEADLK) {
> - ret = drm_modeset_backoff(&ctx);
> - if (!ret) {
> - try_again = true;
> - continue;
> - }
> - break;
> - } else if (ret) {
> - break;
> - }
> - intel_dp = intel_attached_dp(to_intel_connector(connector));
> - crtc_state = to_intel_crtc_state(crtc->state);
> - seq_printf(m, "DSC_Enabled: %s\n",
> - yesno(crtc_state->dsc.compression_enable));
> - seq_printf(m, "DSC_Sink_Support: %s\n",
> - yesno(drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)));
> - seq_printf(m, "Force_DSC_Enable: %s\n",
> - yesno(intel_dp->force_dsc_en));
> - if (!intel_dp_is_edp(intel_dp))
> - seq_printf(m, "FEC_Sink_Support: %s\n",
> - yesno(drm_dp_sink_supports_fec(intel_dp->fec_capable)));
> - } while (try_again);
> -
> - drm_modeset_drop_locks(&ctx);
> - drm_modeset_acquire_fini(&ctx);
> -
> - return ret;
> -}
> -
> -static ssize_t i915_dsc_fec_support_write(struct file *file,
> - const char __user *ubuf,
> - size_t len, loff_t *offp)
> -{
> - bool dsc_enable = false;
> - int ret;
> - struct drm_connector *connector =
> - ((struct seq_file *)file->private_data)->private;
> - struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
> - struct drm_i915_private *i915 = to_i915(encoder->base.dev);
> - struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
> -
> - if (len == 0)
> - return 0;
> -
> - drm_dbg(&i915->drm,
> - "Copied %zu bytes from user to force DSC\n", len);
> -
> - ret = kstrtobool_from_user(ubuf, len, &dsc_enable);
> - if (ret < 0)
> - return ret;
> -
> - drm_dbg(&i915->drm, "Got %s for DSC Enable\n",
> - (dsc_enable) ? "true" : "false");
> - intel_dp->force_dsc_en = dsc_enable;
> -
> - *offp += len;
> - return len;
> -}
> -
> -static int i915_dsc_fec_support_open(struct inode *inode,
> - struct file *file)
> -{
> - return single_open(file, i915_dsc_fec_support_show,
> - inode->i_private);
> -}
> -
> -static const struct file_operations i915_dsc_fec_support_fops = {
> - .owner = THIS_MODULE,
> - .open = i915_dsc_fec_support_open,
> - .read = seq_read,
> - .llseek = seq_lseek,
> - .release = single_release,
> - .write = i915_dsc_fec_support_write
> -};
> -
> -/**
> - * i915_debugfs_connector_add - add i915 specific connector debugfs files
> - * @connector: pointer to a registered drm_connector
> - *
> - * Cleanup will be done by drm_connector_unregister() through a call to
> - * drm_debugfs_connector_remove().
> - *
> - * Returns 0 on success, negative error codes on error.
> - */
> -int i915_debugfs_connector_add(struct drm_connector *connector)
> -{
> - struct dentry *root = connector->debugfs_entry;
> - struct drm_i915_private *dev_priv = to_i915(connector->dev);
> -
> - /* The connector must have been registered beforehands. */
> - if (!root)
> - return -ENODEV;
> -
> - if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
> - debugfs_create_file("i915_panel_timings", S_IRUGO, root,
> - connector, &i915_panel_fops);
> - debugfs_create_file("i915_psr_sink_status", S_IRUGO, root,
> - connector, &i915_psr_sink_status_fops);
> - }
> -
> - if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
> - connector->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
> - connector->connector_type == DRM_MODE_CONNECTOR_HDMIB) {
> - debugfs_create_file("i915_hdcp_sink_capability", S_IRUGO, root,
> - connector, &i915_hdcp_sink_capability_fops);
> - }
> -
> - if (INTEL_GEN(dev_priv) >= 10 &&
> - (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
> - connector->connector_type == DRM_MODE_CONNECTOR_eDP))
> - debugfs_create_file("i915_dsc_fec_support", S_IRUGO, root,
> - connector, &i915_dsc_fec_support_fops);
> -
> - return 0;
> -}
> diff --git a/drivers/gpu/drm/i915/i915_debugfs.h b/drivers/gpu/drm/i915/i915_debugfs.h
> index c0cd22eb916d..f0309219ed4c 100644
> --- a/drivers/gpu/drm/i915/i915_debugfs.h
> +++ b/drivers/gpu/drm/i915/i915_debugfs.h
> @@ -11,10 +11,8 @@ struct drm_connector;
>
> #ifdef CONFIG_DEBUG_FS
> int i915_debugfs_register(struct drm_i915_private *dev_priv);
> -int i915_debugfs_connector_add(struct drm_connector *connector);
> #else
> static inline int i915_debugfs_register(struct drm_i915_private *dev_priv) { return 0; }
> -static inline int i915_debugfs_connector_add(struct drm_connector *connector) { return 0; }
> #endif
>
> #endif /* __I915_DEBUGFS_H__ */
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 516536234e97..4ab3689420e6 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -50,6 +50,7 @@
> #include "display/intel_audio.h"
> #include "display/intel_bw.h"
> #include "display/intel_cdclk.h"
> +#include "display/intel_display_debugfs.h"
> #include "display/intel_display_types.h"
> #include "display/intel_dp.h"
> #include "display/intel_fbdev.h"
> @@ -1330,6 +1331,7 @@ static void i915_driver_register(struct drm_i915_private *dev_priv)
> /* Reveal our presence to userspace */
> if (drm_dev_register(dev, 0) == 0) {
> i915_debugfs_register(dev_priv);
> + intel_display_debugfs_register(dev_priv);
> i915_setup_sysfs(dev_priv);
>
> /* Depends on sysfs having been initialized */
> --
> 2.20.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Ville Syrjälä
Intel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2020-02-04 15:29 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-04 15:18 [Intel-gfx] [PATCH] drm/i915: split out display debugfs to a separate file Jani Nikula
2020-02-04 15:29 ` Ville Syrjälä [this message]
2020-02-05 3:23 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for " Patchwork
2020-02-05 3:42 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2020-02-07 8:08 ` [Intel-gfx] ✓ Fi.CI.IGT: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200204152927.GA13686@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=jani.nikula@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.