Commit e0ef2daa authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

drm/i915: Skip some timing checks on BXT/GLK DSI transcoders

Apparently some BXT/GLK systems have DSI panels whose timings
don't agree with the normal cpu transcoder hblank>=32 limitation.
This is perhaps fine as there are no specific hblank/etc. limits
listed for the BXT/GLK DSI transcoders.

Move those checks out from the global intel_mode_valid() into
into connector specific .mode_valid() hooks, skipping BXT/GLK
DSI connectors. We'll leave the basic [hv]display/[hv]total
checks in intel_mode_valid() as those seem like sensible upper
limits regardless of the transcoder used.

Cc: stable@vger.kernel.org
Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/9720


Fixes: 8f4b1068 ("drm/i915: Check some transcoder timing minimum limits")
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231127145028.4899-1-ville.syrjala@linux.intel.com


Reviewed-by: default avatarJani Nikula <jani.nikula@intel.com>
parent fcebbe2f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1440,6 +1440,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);
}
+5 −0
Original line number Diff line number Diff line
@@ -348,8 +348,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;

+10 −0
Original line number Diff line number Diff line
@@ -7734,6 +7734,16 @@ enum drm_mode_status 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)
+3 −0
Original line number Diff line number Diff line
@@ -402,6 +402,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 is_trans_port_sync_master(const struct intel_crtc_state *state);
+4 −0
Original line number Diff line number Diff line
@@ -1227,6 +1227,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;

Loading