Commit 9a86cda0 authored by Jani Nikula's avatar Jani Nikula

drm/i915/dp: reduce link M/N parameters

Several major vendor USB-C->HDMI converters, in particular the DA200,
fail to recover a 5.4 GHz 1 lane signal if the link N is greater than
0x80000.

The link M and N depend on the pixel clock and link clock ratio. With
current code link N exceeds 0x80000 only when link clock >= 540000
kHz. Except for the eDP intermediate link clocks, at least the four
least significant bits are always zero. Just one bit shift right would
be enough to bring even the DP 1.4 810000 kHz link clock under 0x80000
link N. The pixel clock for modes that require a link clock >= 540000
kHz would also have several least significant bits zero. Unless the user
provides a mode with an odd pixel clock value, we can reduce the numbers
to reach the goal, with no loss in precision.

The DP spec even mentions sources making choices that "allow for static
and relatively small Mvid and Nvid values", thus reducing the link M/N
regardless of the sink in question seems justified.

Everything here is based on the work and information gathered by Clint
Taylor <clinton.a.taylor@intel.com>. This is just an iteration to reduce
the parameters regardless of lane count, link rate, or sink.

Reference: http://patchwork.freedesktop.org/patch/msgid/1490225256-11667-1-git-send-email-clinton.a.taylor@intel.com
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93578Tested-by: default avatarMads <mads@ab3.no>
Tested-by: default avatarPJ <foobar@pjmodos.net>
Tested-by: default avatarFrançois Guerraz <kubrick@fgv6.net>
Tested-by: default avatarLev Popov <leo@nabam.net>
Tested-by: default avatarIgor Krivenko <igor.s.krivenko@gmail.com>
Tested-by: default avatarClint Taylor <clinton.a.taylor@intel.com>
Reviewed-by: default avatarClint Taylor <clinton.a.taylor@intel.com>
Reviewed-by: default avatarDhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Acked-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Cc: Clint Taylor <clinton.a.taylor@intel.com>
Cc: Anusha Srivatsa <anusha.srivatsa@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1490614405-23337-1-git-send-email-jani.nikula@intel.com
parent 090e5fe3
...@@ -6290,6 +6290,17 @@ intel_reduce_m_n_ratio(uint32_t *num, uint32_t *den) ...@@ -6290,6 +6290,17 @@ intel_reduce_m_n_ratio(uint32_t *num, uint32_t *den)
static void compute_m_n(unsigned int m, unsigned int n, static void compute_m_n(unsigned int m, unsigned int n,
uint32_t *ret_m, uint32_t *ret_n) uint32_t *ret_m, uint32_t *ret_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.
*/
while ((m & 1) == 0 && (n & 1) == 0) {
m >>= 1;
n >>= 1;
}
*ret_n = min_t(unsigned int, roundup_pow_of_two(n), DATA_LINK_N_MAX); *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); *ret_m = div_u64((uint64_t) m * *ret_n, n);
intel_reduce_m_n_ratio(ret_m, ret_n); intel_reduce_m_n_ratio(ret_m, ret_n);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment