diff options
| author | Lee, Shawn C <shawn.c.lee@intel.com> | 2018-09-12 02:22:50 -0400 |
|---|---|---|
| committer | Jani Nikula <jani.nikula@intel.com> | 2018-09-19 09:44:12 -0400 |
| commit | 53ca2edcf033f3368b2dc0ef3cbcc2f47d556d13 (patch) | |
| tree | c7a8b6e2c93bb03c8cd5b4d3eb5b68e2154a3fe0 /drivers/gpu | |
| parent | 0b49bbbd9f10dd5bcce126aa99041a44320767f7 (diff) | |
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: Clint Taylor <clinton.a.taylor@intel.com>
Signed-off-by: Lee, Shawn C <shawn.c.lee@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1536733371-25004-3-git-send-email-shawn.c.lee@intel.com
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/drm_dp_helper.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 28 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp_mst.c | 6 |
5 files changed, 22 insertions, 24 deletions
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 07167604e8cc..c1fe1713eaef 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c | |||
| @@ -1270,7 +1270,7 @@ struct dpcd_quirk { | |||
| 1270 | 1270 | ||
| 1271 | static const struct dpcd_quirk dpcd_quirk_list[] = { | 1271 | static const struct dpcd_quirk dpcd_quirk_list[] = { |
| 1272 | /* Analogix 7737 needs reduced M and N at HBR2 link rates */ | 1272 | /* Analogix 7737 needs reduced M and N at HBR2 link rates */ |
| 1273 | { OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true, BIT(DP_DPCD_QUIRK_LIMITED_M_N) }, | 1273 | { OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true, BIT(DP_DPCD_QUIRK_CONSTANT_N) }, |
| 1274 | }; | 1274 | }; |
| 1275 | 1275 | ||
| 1276 | #undef OUI | 1276 | #undef OUI |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c24bc848ac6c..611b425b50f1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -6677,22 +6677,20 @@ intel_reduce_m_n_ratio(uint32_t *num, uint32_t *den) | |||
| 6677 | 6677 | ||
| 6678 | static void compute_m_n(unsigned int m, unsigned int n, | 6678 | static void compute_m_n(unsigned int m, unsigned int n, |
| 6679 | uint32_t *ret_m, uint32_t *ret_n, | 6679 | uint32_t *ret_m, uint32_t *ret_n, |
| 6680 | bool reduce_m_n) | 6680 | bool constant_n) |
| 6681 | { | 6681 | { |
| 6682 | /* | 6682 | /* |
| 6683 | * Reduce M/N as much as possible without loss in precision. Several DP | 6683 | * Several DP dongles in particular seem to be fussy about |
| 6684 | * dongles in particular seem to be fussy about too large *link* M/N | 6684 | * too large link M/N values. Give N value as 0x8000 that |
| 6685 | * values. The passed in values are more likely to have the least | 6685 | * should be acceptable by specific devices. 0x8000 is the |
| 6686 | * significant bits zero than M after rounding below, so do this first. | 6686 | * specified fixed N value for asynchronous clock mode, |
| 6687 | * which the devices expect also in synchronous clock mode. | ||
| 6687 | */ | 6688 | */ |
| 6688 | if (reduce_m_n) { | 6689 | if (constant_n) |
| 6689 | while ((m & 1) == 0 && (n & 1) == 0) { | 6690 | *ret_n = 0x8000; |
| 6690 | m >>= 1; | 6691 | else |
| 6691 | n >>= 1; | 6692 | *ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX); |
| 6692 | } | ||
| 6693 | } | ||
| 6694 | 6693 | ||
| 6695 | *ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX); | ||
| 6696 | *ret_m = div_u64((uint64_t) m * *ret_n, n); | 6694 | *ret_m = div_u64((uint64_t) m * *ret_n, n); |
| 6697 | intel_reduce_m_n_ratio(ret_m, ret_n); | 6695 | intel_reduce_m_n_ratio(ret_m, ret_n); |
| 6698 | } | 6696 | } |
| @@ -6701,18 +6699,18 @@ void | |||
| 6701 | intel_link_compute_m_n(int bits_per_pixel, int nlanes, | 6699 | intel_link_compute_m_n(int bits_per_pixel, int nlanes, |
| 6702 | int pixel_clock, int link_clock, | 6700 | int pixel_clock, int link_clock, |
| 6703 | struct intel_link_m_n *m_n, | 6701 | struct intel_link_m_n *m_n, |
| 6704 | bool reduce_m_n) | 6702 | bool constant_n) |
| 6705 | { | 6703 | { |
| 6706 | m_n->tu = 64; | 6704 | m_n->tu = 64; |
| 6707 | 6705 | ||
| 6708 | compute_m_n(bits_per_pixel * pixel_clock, | 6706 | compute_m_n(bits_per_pixel * pixel_clock, |
| 6709 | link_clock * nlanes * 8, | 6707 | link_clock * nlanes * 8, |
| 6710 | &m_n->gmch_m, &m_n->gmch_n, | 6708 | &m_n->gmch_m, &m_n->gmch_n, |
| 6711 | reduce_m_n); | 6709 | constant_n); |
| 6712 | 6710 | ||
| 6713 | compute_m_n(pixel_clock, link_clock, | 6711 | compute_m_n(pixel_clock, link_clock, |
| 6714 | &m_n->link_m, &m_n->link_n, | 6712 | &m_n->link_m, &m_n->link_n, |
| 6715 | reduce_m_n); | 6713 | constant_n); |
| 6716 | } | 6714 | } |
| 6717 | 6715 | ||
| 6718 | static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) | 6716 | static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) |
diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h index 809c06ae4c07..58ba614862e5 100644 --- a/drivers/gpu/drm/i915/intel_display.h +++ b/drivers/gpu/drm/i915/intel_display.h | |||
| @@ -382,6 +382,6 @@ struct intel_link_m_n { | |||
| 382 | void intel_link_compute_m_n(int bpp, int nlanes, | 382 | void intel_link_compute_m_n(int bpp, int nlanes, |
| 383 | int pixel_clock, int link_clock, | 383 | int pixel_clock, int link_clock, |
| 384 | struct intel_link_m_n *m_n, | 384 | struct intel_link_m_n *m_n, |
| 385 | bool reduce_m_n); | 385 | bool constant_n); |
| 386 | 386 | ||
| 387 | #endif | 387 | #endif |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cd0f649b57a5..29212d317f58 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -1834,8 +1834,8 @@ intel_dp_compute_config(struct intel_encoder *encoder, | |||
| 1834 | struct intel_connector *intel_connector = intel_dp->attached_connector; | 1834 | struct intel_connector *intel_connector = intel_dp->attached_connector; |
| 1835 | struct intel_digital_connector_state *intel_conn_state = | 1835 | struct intel_digital_connector_state *intel_conn_state = |
| 1836 | to_intel_digital_connector_state(conn_state); | 1836 | to_intel_digital_connector_state(conn_state); |
| 1837 | bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc, | 1837 | bool constant_n = drm_dp_has_quirk(&intel_dp->desc, |
| 1838 | DP_DPCD_QUIRK_LIMITED_M_N); | 1838 | DP_DPCD_QUIRK_CONSTANT_N); |
| 1839 | 1839 | ||
| 1840 | if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A) | 1840 | if (HAS_PCH_SPLIT(dev_priv) && !HAS_DDI(dev_priv) && port != PORT_A) |
| 1841 | pipe_config->has_pch_encoder = true; | 1841 | pipe_config->has_pch_encoder = true; |
| @@ -1900,7 +1900,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, | |||
| 1900 | adjusted_mode->crtc_clock, | 1900 | adjusted_mode->crtc_clock, |
| 1901 | pipe_config->port_clock, | 1901 | pipe_config->port_clock, |
| 1902 | &pipe_config->dp_m_n, | 1902 | &pipe_config->dp_m_n, |
| 1903 | reduce_m_n); | 1903 | constant_n); |
| 1904 | 1904 | ||
| 1905 | if (intel_connector->panel.downclock_mode != NULL && | 1905 | if (intel_connector->panel.downclock_mode != NULL && |
| 1906 | dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) { | 1906 | dev_priv->drrs.type == SEAMLESS_DRRS_SUPPORT) { |
| @@ -1910,7 +1910,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, | |||
| 1910 | intel_connector->panel.downclock_mode->clock, | 1910 | intel_connector->panel.downclock_mode->clock, |
| 1911 | pipe_config->port_clock, | 1911 | pipe_config->port_clock, |
| 1912 | &pipe_config->dp_m2_n2, | 1912 | &pipe_config->dp_m2_n2, |
| 1913 | reduce_m_n); | 1913 | constant_n); |
| 1914 | } | 1914 | } |
| 1915 | 1915 | ||
| 1916 | if (!HAS_DDI(dev_priv)) | 1916 | if (!HAS_DDI(dev_priv)) |
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 7e3e01607643..b7505879b1f7 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c | |||
| @@ -45,8 +45,8 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, | |||
| 45 | int lane_count, slots; | 45 | int lane_count, slots; |
| 46 | const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; | 46 | const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode; |
| 47 | int mst_pbn; | 47 | int mst_pbn; |
| 48 | bool reduce_m_n = drm_dp_has_quirk(&intel_dp->desc, | 48 | bool constant_n = drm_dp_has_quirk(&intel_dp->desc, |
| 49 | DP_DPCD_QUIRK_LIMITED_M_N); | 49 | DP_DPCD_QUIRK_CONSTANT_N); |
| 50 | 50 | ||
| 51 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) | 51 | if (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN) |
| 52 | return false; | 52 | return false; |
| @@ -87,7 +87,7 @@ static bool intel_dp_mst_compute_config(struct intel_encoder *encoder, | |||
| 87 | adjusted_mode->crtc_clock, | 87 | adjusted_mode->crtc_clock, |
| 88 | pipe_config->port_clock, | 88 | pipe_config->port_clock, |
| 89 | &pipe_config->dp_m_n, | 89 | &pipe_config->dp_m_n, |
| 90 | reduce_m_n); | 90 | constant_n); |
| 91 | 91 | ||
| 92 | pipe_config->dp_m_n.tu = slots; | 92 | pipe_config->dp_m_n.tu = slots; |
| 93 | 93 | ||
