Commit 27d06077 authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Make M/N checks non-fuzzy

Now that we no longer fuzz M/N during fastset these should
match exctly.

In order to get a match with what the BIOS does we need to round
M/N down. And we do the opposite rounding when doing the readback.
That gets us pretty much the same thing back.

There can still be slight rounding differences between FDI M/N
vs. the DPLL output so we allow for tiny deviation in
intel_pipe_config_sanity_check().

v2: Tweak rounding/sanity check stuff a bit

Reviewed-by: Jani Nikula <jani.nikula@intel.com> #v1
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220907091057.11572-10-ville.syrjala@linux.intel.com
parent 0ff0e219
...@@ -4495,7 +4495,8 @@ int intel_dotclock_calculate(int link_freq, ...@@ -4495,7 +4495,8 @@ int intel_dotclock_calculate(int link_freq,
if (!m_n->link_n) if (!m_n->link_n)
return 0; return 0;
return div_u64(mul_u32_u32(m_n->link_m, link_freq), m_n->link_n); return DIV_ROUND_UP_ULL(mul_u32_u32(m_n->link_m, link_freq),
m_n->link_n);
} }
int intel_crtc_dotclock(const struct intel_crtc_state *pipe_config) int intel_crtc_dotclock(const struct intel_crtc_state *pipe_config)
...@@ -5387,47 +5388,15 @@ bool intel_fuzzy_clock_check(int clock1, int clock2) ...@@ -5387,47 +5388,15 @@ bool intel_fuzzy_clock_check(int clock1, int clock2)
return false; return false;
} }
static bool
intel_compare_m_n(unsigned int m, unsigned int n,
unsigned int m2, unsigned int n2,
bool exact)
{
if (m == m2 && n == n2)
return true;
if (exact || !m || !n || !m2 || !n2)
return false;
BUILD_BUG_ON(DATA_LINK_M_N_MASK > INT_MAX);
if (n > n2) {
while (n > n2) {
m2 <<= 1;
n2 <<= 1;
}
} else if (n < n2) {
while (n < n2) {
m <<= 1;
n <<= 1;
}
}
if (n != n2)
return false;
return intel_fuzzy_clock_check(m, m2);
}
static bool static bool
intel_compare_link_m_n(const struct intel_link_m_n *m_n, intel_compare_link_m_n(const struct intel_link_m_n *m_n,
const struct intel_link_m_n *m2_n2, const struct intel_link_m_n *m2_n2)
bool exact)
{ {
return m_n->tu == m2_n2->tu && return m_n->tu == m2_n2->tu &&
intel_compare_m_n(m_n->data_m, m_n->data_n, m_n->data_m == m2_n2->data_m &&
m2_n2->data_m, m2_n2->data_n, exact) && m_n->data_n == m2_n2->data_n &&
intel_compare_m_n(m_n->link_m, m_n->link_n, m_n->link_m == m2_n2->link_m &&
m2_n2->link_m, m2_n2->link_n, exact); m_n->link_n == m2_n2->link_n;
} }
static bool static bool
...@@ -5621,8 +5590,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, ...@@ -5621,8 +5590,7 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
#define PIPE_CONF_CHECK_M_N(name) do { \ #define PIPE_CONF_CHECK_M_N(name) do { \
if (!intel_compare_link_m_n(&current_config->name, \ if (!intel_compare_link_m_n(&current_config->name, \
&pipe_config->name,\ &pipe_config->name)) { \
!fastset)) { \
pipe_config_mismatch(fastset, crtc, __stringify(name), \ pipe_config_mismatch(fastset, crtc, __stringify(name), \
"(expected tu %i data %i/%i link %i/%i, " \ "(expected tu %i data %i/%i link %i/%i, " \
"found tu %i, data %i/%i link %i/%i)", \ "found tu %i, data %i/%i link %i/%i)", \
...@@ -5669,9 +5637,9 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config, ...@@ -5669,9 +5637,9 @@ intel_pipe_config_compare(const struct intel_crtc_state *current_config,
*/ */
#define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) do { \ #define PIPE_CONF_CHECK_M_N_ALT(name, alt_name) do { \
if (!intel_compare_link_m_n(&current_config->name, \ if (!intel_compare_link_m_n(&current_config->name, \
&pipe_config->name, !fastset) && \ &pipe_config->name) && \
!intel_compare_link_m_n(&current_config->alt_name, \ !intel_compare_link_m_n(&current_config->alt_name, \
&pipe_config->name, !fastset)) { \ &pipe_config->name)) { \
pipe_config_mismatch(fastset, crtc, __stringify(name), \ pipe_config_mismatch(fastset, crtc, __stringify(name), \
"(expected tu %i data %i/%i link %i/%i, " \ "(expected tu %i data %i/%i link %i/%i, " \
"or tu %i data %i/%i link %i/%i, " \ "or tu %i data %i/%i link %i/%i, " \
......
...@@ -94,10 +94,10 @@ static void intel_pipe_config_sanity_check(struct drm_i915_private *dev_priv, ...@@ -94,10 +94,10 @@ static void intel_pipe_config_sanity_check(struct drm_i915_private *dev_priv,
/* /*
* FDI already provided one idea for the dotclock. * FDI already provided one idea for the dotclock.
* Yell if the encoder disagrees. * Yell if the encoder disagrees. Allow for slight
* rounding differences.
*/ */
drm_WARN(&dev_priv->drm, drm_WARN(&dev_priv->drm, abs(fdi_dotclock - dotclock) > 1,
!intel_fuzzy_clock_check(fdi_dotclock, dotclock),
"FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n", "FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n",
fdi_dotclock, dotclock); fdi_dotclock, dotclock);
} }
......
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