Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 53ca2edc authored by Lee, Shawn C's avatar Lee, Shawn C Committed by Jani Nikula
Browse files

drm: Change limited M/N quirk to constant N quirk.



Some DP dongles in particular seem to be fussy about too large
link M/N values. Set specific value for N divider can resolve
this issue per dongle vendor's comment. So configure N as
constant value (0x8000) to instead of reduce M/N formula when
specific DP dongle connected.

v2: add more comments for issue description and fix typo.
v3: add lost commit messages back for version 2
v4: send patch to both intel-gfx and dri-devel

Cc: Jani Nikula <jani.nikula@intel.com>
Cc: Cooper Chiou <cooper.chiou@intel.com>
Cc: Matt Atwood <matthew.s.atwood@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Cc: Clint Taylor <clinton.a.taylor@intel.com>
Tested-by: default avatarClint Taylor <clinton.a.taylor@intel.com>
Signed-off-by: default avatarLee, Shawn C <shawn.c.lee@intel.com>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1536733371-25004-3-git-send-email-shawn.c.lee@intel.com
parent 0b49bbbd
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1270,7 +1270,7 @@ struct dpcd_quirk {

static const struct dpcd_quirk dpcd_quirk_list[] = {
	/* Analogix 7737 needs reduced M and N at HBR2 link rates */
	{ OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true, BIT(DP_DPCD_QUIRK_LIMITED_M_N) },
	{ OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true, BIT(DP_DPCD_QUIRK_CONSTANT_N) },
};

#undef OUI
+13 −15
Original line number Diff line number Diff line
@@ -6677,22 +6677,20 @@ intel_reduce_m_n_ratio(uint32_t *num, uint32_t *den)

static void compute_m_n(unsigned int m, unsigned int n,
			uint32_t *ret_m, uint32_t *ret_n,
			bool reduce_m_n)
			bool constant_n)
{
	/*
	 * Reduce M/N as much as possible without loss in precision. Several DP
	 * dongles in particular seem to be fussy about too large *link* M/N
	 * values. The passed in values are more likely to have the least
	 * significant bits zero than M after rounding below, so do this first.
	 * Several DP dongles in particular seem to be fussy about
	 * too large link M/N values. Give N value as 0x8000 that
	 * should be acceptable by specific devices. 0x8000 is the
	 * specified fixed N value for asynchronous clock mode,
	 * which the devices expect also in synchronous clock mode.
	 */
	if (reduce_m_n) {
		while ((m & 1) == 0 && (n & 1) == 0) {
			m >>= 1;
			n >>= 1;
		}
	}

	if (constant_n)
		*ret_n = 0x8000;
	else
		*ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX);

	*ret_m = div_u64((uint64_t) m * *ret_n, n);
	intel_reduce_m_n_ratio(ret_m, ret_n);
}
@@ -6701,18 +6699,18 @@ void
intel_link_compute_m_n(int bits_per_pixel, int nlanes,
		       int pixel_clock, int link_clock,
		       struct intel_link_m_n *m_n,
		       bool reduce_m_n)
		       bool constant_n)
{
	m_n->tu = 64;

	compute_m_n(bits_per_pixel * pixel_clock,
		    link_clock * nlanes * 8,
		    &m_n->gmch_m, &m_n->gmch_n,
		    reduce_m_n);
		    constant_n);

	compute_m_n(pixel_clock, link_clock,
		    &m_n->link_m, &m_n->link_n,
		    reduce_m_n);
		    constant_n);
}

static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
+1 −1
Original line number Diff line number Diff line
@@ -382,6 +382,6 @@ struct intel_link_m_n {
void intel_link_compute_m_n(int bpp, int nlanes,
			    int pixel_clock, int link_clock,
			    struct intel_link_m_n *m_n,
			    bool reduce_m_n);
			    bool constant_n);

#endif
+4 −4
Original line number Diff line number Diff line
@@ -1834,8 +1834,8 @@ intel_dp_compute_config(struct intel_encoder *encoder,
	struct intel_connector *intel_connector = intel_dp->attached_connector;
	struct intel_digital_connector_state *intel_conn_state =
		to_intel_digital_connector_state(conn_state);
	bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc,
					   DP_DPCD_QUIRK_LIMITED_M_N);
	bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
					   DP_DPCD_QUIRK_CONSTANT_N);

	if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A)
		pipe_config->has_pch_encoder = true;
@@ -1900,7 +1900,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
			       adjusted_mode->crtc_clock,
			       pipe_config->port_clock,
			       &pipe_config->dp_m_n,
			       reduce_m_n);
			       constant_n);

	if (intel_connector->panel.downclock_mode != NULL &&
		dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) {
@@ -1910,7 +1910,7 @@ intel_dp_compute_config(struct intel_encoder *encoder,
					       intel_connector->panel.downclock_mode->clock,
					       pipe_config->port_clock,
					       &pipe_config->dp_m2_n2,
					       reduce_m_n);
					       constant_n);
	}

	if (!HAS_DDI(dev_priv))
+3 −3
Original line number Diff line number Diff line
@@ -45,8 +45,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
	int lane_count, slots;
	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
	int mst_pbn;
	bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc,
					   DP_DPCD_QUIRK_LIMITED_M_N);
	bool constant_n = drm_dp_has_quirk(&intel_dp->desc,
					   DP_DPCD_QUIRK_CONSTANT_N);

	if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)
		return false;
@@ -87,7 +87,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder,
			       adjusted_mode->crtc_clock,
			       pipe_config->port_clock,
			       &pipe_config->dp_m_n,
			       reduce_m_n);
			       constant_n);

	pipe_config->dp_m_n.tu = slots;

Loading