From: jsg Date: Thu, 14 Dec 2023 05:47:41 +0000 (+0000) Subject: drm/i915: Skip some timing checks on BXT/GLK DSI transcoders X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=2bd53da4f7f4210689ac0f17d219fd68b31c9a3f;p=openbsd drm/i915: Skip some timing checks on BXT/GLK DSI transcoders From Ville Syrjala f38b4e99e24cbc45084552fe50273ed847a4f511 in linux-6.1.y/6.1.68 20c2dbff342aec13bf93c2f6c951da198916a455 in mainline linux --- diff --git a/sys/dev/pci/drm/i915/display/icl_dsi.c b/sys/dev/pci/drm/i915/display/icl_dsi.c index 5767d339832..d5951688aad 100644 --- a/sys/dev/pci/drm/i915/display/icl_dsi.c +++ b/sys/dev/pci/drm/i915/display/icl_dsi.c @@ -1500,6 +1500,13 @@ static void gen11_dsi_post_disable(struct intel_atomic_state *state, static enum drm_mode_status gen11_dsi_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { + struct drm_i915_private *i915 = to_i915(connector->dev); + enum drm_mode_status status; + + status = intel_cpu_transcoder_mode_valid(i915, mode); + if (status != MODE_OK) + return status; + /* FIXME: DSC? */ return intel_dsi_mode_valid(connector, mode); } diff --git a/sys/dev/pci/drm/i915/display/intel_crt.c b/sys/dev/pci/drm/i915/display/intel_crt.c index 4a8ff2f9760..e60b2cf84b8 100644 --- a/sys/dev/pci/drm/i915/display/intel_crt.c +++ b/sys/dev/pci/drm/i915/display/intel_crt.c @@ -343,8 +343,13 @@ intel_crt_mode_valid(struct drm_connector *connector, struct drm_device *dev = connector->dev; struct drm_i915_private *dev_priv = to_i915(dev); int max_dotclk = dev_priv->max_dotclk_freq; + enum drm_mode_status status; int max_clock; + status = intel_cpu_transcoder_mode_valid(dev_priv, mode); + if (status != MODE_OK) + return status; + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; diff --git a/sys/dev/pci/drm/i915/display/intel_display.c b/sys/dev/pci/drm/i915/display/intel_display.c index 65de50781be..a6bbf26c6df 100644 --- a/sys/dev/pci/drm/i915/display/intel_display.c +++ b/sys/dev/pci/drm/i915/display/intel_display.c @@ -8229,6 +8229,16 @@ intel_mode_valid(struct drm_device *dev, mode->vtotal > vtotal_max) return MODE_V_ILLEGAL; + return MODE_OK; +} + +enum drm_mode_status intel_cpu_transcoder_mode_valid(struct drm_i915_private *dev_priv, + const struct drm_display_mode *mode) +{ + /* + * Additional transcoder timing limits, + * excluding BXT/GLK DSI transcoders. + */ if (DISPLAY_VER(dev_priv) >= 5) { if (mode->hdisplay < 64 || mode->htotal - mode->hdisplay < 32) diff --git a/sys/dev/pci/drm/i915/display/intel_display.h b/sys/dev/pci/drm/i915/display/intel_display.h index 6f98e54380a..9d3f09f4f5b 100644 --- a/sys/dev/pci/drm/i915/display/intel_display.h +++ b/sys/dev/pci/drm/i915/display/intel_display.h @@ -556,6 +556,9 @@ enum drm_mode_status intel_mode_valid_max_plane_size(struct drm_i915_private *dev_priv, const struct drm_display_mode *mode, bool bigjoiner); +enum drm_mode_status +intel_cpu_transcoder_mode_valid(struct drm_i915_private *i915, + const struct drm_display_mode *mode); enum phy intel_port_to_phy(struct drm_i915_private *i915, enum port port); bool is_trans_port_sync_mode(const struct intel_crtc_state *state); bool intel_crtc_is_bigjoiner_slave(const struct intel_crtc_state *crtc_state); diff --git a/sys/dev/pci/drm/i915/display/intel_dp.c b/sys/dev/pci/drm/i915/display/intel_dp.c index 4a2fb199ab7..767f5a99663 100644 --- a/sys/dev/pci/drm/i915/display/intel_dp.c +++ b/sys/dev/pci/drm/i915/display/intel_dp.c @@ -973,6 +973,10 @@ intel_dp_mode_valid(struct drm_connector *_connector, enum drm_mode_status status; bool dsc = false, bigjoiner = false; + status = intel_cpu_transcoder_mode_valid(dev_priv, mode); + if (status != MODE_OK) + return status; + if (mode->flags & DRM_MODE_FLAG_DBLCLK) return MODE_H_ILLEGAL; diff --git a/sys/dev/pci/drm/i915/display/intel_dp_mst.c b/sys/dev/pci/drm/i915/display/intel_dp_mst.c index 9a6822256dd..eec32f68201 100644 --- a/sys/dev/pci/drm/i915/display/intel_dp_mst.c +++ b/sys/dev/pci/drm/i915/display/intel_dp_mst.c @@ -703,6 +703,10 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, return 0; } + *status = intel_cpu_transcoder_mode_valid(dev_priv, mode); + if (*status != MODE_OK) + return 0; + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) { *status = MODE_NO_DBLESCAN; return 0; diff --git a/sys/dev/pci/drm/i915/display/intel_dvo.c b/sys/dev/pci/drm/i915/display/intel_dvo.c index 5572e43026e..511c5890700 100644 --- a/sys/dev/pci/drm/i915/display/intel_dvo.c +++ b/sys/dev/pci/drm/i915/display/intel_dvo.c @@ -225,10 +225,16 @@ intel_dvo_mode_valid(struct drm_connector *connector, { struct intel_connector *intel_connector = to_intel_connector(connector); struct intel_dvo *intel_dvo = intel_attached_dvo(intel_connector); + struct drm_i915_private *i915 = to_i915(intel_connector->base.dev); const struct drm_display_mode *fixed_mode = intel_panel_fixed_mode(intel_connector, mode); int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; int target_clock = mode->clock; + enum drm_mode_status status; + + status = intel_cpu_transcoder_mode_valid(i915, mode); + if (status != MODE_OK) + return status; if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; diff --git a/sys/dev/pci/drm/i915/display/intel_hdmi.c b/sys/dev/pci/drm/i915/display/intel_hdmi.c index 286668e86ab..0f05f731f6e 100644 --- a/sys/dev/pci/drm/i915/display/intel_hdmi.c +++ b/sys/dev/pci/drm/i915/display/intel_hdmi.c @@ -1987,6 +1987,10 @@ intel_hdmi_mode_valid(struct drm_connector *connector, bool has_hdmi_sink = intel_has_hdmi_sink(hdmi, connector->state); bool ycbcr_420_only; + status = intel_cpu_transcoder_mode_valid(dev_priv, mode); + if (status != MODE_OK) + return status; + if ((mode->flags & DRM_MODE_FLAG_3D_MASK) == DRM_MODE_FLAG_3D_FRAME_PACKING) clock *= 2; diff --git a/sys/dev/pci/drm/i915/display/intel_lvds.c b/sys/dev/pci/drm/i915/display/intel_lvds.c index e4606d9a25e..40b5d3d3c7e 100644 --- a/sys/dev/pci/drm/i915/display/intel_lvds.c +++ b/sys/dev/pci/drm/i915/display/intel_lvds.c @@ -389,11 +389,16 @@ intel_lvds_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct intel_connector *intel_connector = to_intel_connector(connector); + struct drm_i915_private *i915 = to_i915(intel_connector->base.dev); const struct drm_display_mode *fixed_mode = intel_panel_fixed_mode(intel_connector, mode); int max_pixclk = to_i915(connector->dev)->max_dotclk_freq; enum drm_mode_status status; + status = intel_cpu_transcoder_mode_valid(i915, mode); + if (status != MODE_OK) + return status; + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; diff --git a/sys/dev/pci/drm/i915/display/intel_sdvo.c b/sys/dev/pci/drm/i915/display/intel_sdvo.c index dcd456e13d8..83df7223fc8 100644 --- a/sys/dev/pci/drm/i915/display/intel_sdvo.c +++ b/sys/dev/pci/drm/i915/display/intel_sdvo.c @@ -1873,13 +1873,19 @@ static enum drm_mode_status intel_sdvo_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { + struct drm_i915_private *i915 = to_i915(connector->dev); struct intel_sdvo *intel_sdvo = intel_attached_sdvo(to_intel_connector(connector)); struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); - int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; bool has_hdmi_sink = intel_has_hdmi_sink(intel_sdvo_connector, connector->state); + int max_dotclk = i915->max_dotclk_freq; + enum drm_mode_status status; int clock = mode->clock; + status = intel_cpu_transcoder_mode_valid(i915, mode); + if (status != MODE_OK) + return status; + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; diff --git a/sys/dev/pci/drm/i915/display/intel_tv.c b/sys/dev/pci/drm/i915/display/intel_tv.c index dcf89d701f0..fb25be800e7 100644 --- a/sys/dev/pci/drm/i915/display/intel_tv.c +++ b/sys/dev/pci/drm/i915/display/intel_tv.c @@ -956,8 +956,14 @@ static enum drm_mode_status intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { + struct drm_i915_private *i915 = to_i915(connector->dev); const struct tv_mode *tv_mode = intel_tv_mode_find(connector->state); - int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; + int max_dotclk = i915->max_dotclk_freq; + enum drm_mode_status status; + + status = intel_cpu_transcoder_mode_valid(i915, mode); + if (status != MODE_OK) + return status; if (mode->flags & DRM_MODE_FLAG_DBLSCAN) return MODE_NO_DBLESCAN; diff --git a/sys/dev/pci/drm/i915/display/vlv_dsi.c b/sys/dev/pci/drm/i915/display/vlv_dsi.c index 963ab2e8fdc..cd234746bbb 100644 --- a/sys/dev/pci/drm/i915/display/vlv_dsi.c +++ b/sys/dev/pci/drm/i915/display/vlv_dsi.c @@ -1627,9 +1627,25 @@ static const struct drm_encoder_funcs intel_dsi_funcs = { .destroy = intel_dsi_encoder_destroy, }; +static enum drm_mode_status vlv_dsi_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + struct drm_i915_private *i915 = to_i915(connector->dev); + + if (IS_VALLEYVIEW(i915) || IS_CHERRYVIEW(i915)) { + enum drm_mode_status status; + + status = intel_cpu_transcoder_mode_valid(i915, mode); + if (status != MODE_OK) + return status; + } + + return intel_dsi_mode_valid(connector, mode); +} + static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs = { .get_modes = intel_dsi_get_modes, - .mode_valid = intel_dsi_mode_valid, + .mode_valid = vlv_dsi_mode_valid, .atomic_check = intel_digital_connector_atomic_check, };