Let's add a copy of the active_pipes bitmask into the cdclk_state.
While this is duplicating a bit of information we may already
have elsewhere, I think it's worth it to decopule the cdclk stuff
from whatever else wants to use that bitmask. Also we want to get
rid of all the old ad-hoc global state which is what the current
bitmask is, so this removes one obstacle.
The one extra thing we have to remember is write locking the cdclk
state whenever the bitmask changes.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200120174728.21095-19-ville.syrjala@linux.intel.com
Reviewed-by: Imre Deak <imre.deak@intel.com>
Our current global state handling is pretty ad-hoc. Let's try to
make it better by imitating the standard drm core private object
approach.
The reason why we don't want to directly use the private objects
is locking; Each private object has its own lock so if we
introduce any global private objects we get serialized by that
single lock across all pipes. The global state apporoach instead
uses a read/write lock type of approach where each individual
crtc lock counts as a read lock, and grabbing all the crtc locks
allows one write access.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200120174728.21095-15-ville.syrjala@linux.intel.com
Reviewed-by: Imre Deak <imre.deak@intel.com>
There seems to be some undocumented bandwidth
bottleneck/dependency which scales with CDCLK,
causing FIFO underruns when CDCLK is too low,
even when it's correct from BSpec point of view.
Currently for TGL platforms we calculate
min_cdclk initially based on pixel_rate divided
by 2, accounting for also plane requirements,
however in some cases the lowest possible CDCLK
doesn't work and causing the underruns.
We've found experimentally that raising cdclk to
at least pixel_rate (rather than pixel_rate/2)
eliminates these underruns, so let's use this as a
temporary workaround until the hardware team
can suggest a more precise remedy.
Explicitly stating here that this seems to be currently
rather a Hack, than final solution.
v2: Use clamp operation instead of min(Matt Roper)
v3: - Fixed commit message(Matt Roper)
- Now using pixel_rate instead of max_cdclk(Jani Nikula)
- Switched to max from clamp(Ville Syrjälä)
Hopefully this hybrid satisfies everyone :)
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Closes: https://gitlab.freedesktop.org/drm/intel/issues/402
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200109220547.23817-1-stanislav.lisovskiy@intel.com
Various pixel formats and plane scaling impose additional constraints
on the cdclk frequency. Provide a new plane->min_cdclk() hook that
will be used to compute the minimum acceptable cdclk frequency for
each plane.
Annoyingly on some platforms the numer of active planes affects
this calculation so we must also toss in more planes into the
state when the number of active planes changes.
The sequence of state computation must also be changed:
1. check_plane() (updates plane's visibility etc.)
2. figure out if more planes now require update min_cdclk
computaion
3. calculate the new min cdclk for each plane in the state
4. if the minimum of any plane now exceeds the current
logical cdclk we recompute the cdclk
4. during cdclk computation take the planes' min_cdclk into
accoutn
5. follow the normal cdclk programming to change the
cdclk frequency. This may now require a modeset (except
on bxt/glk in some cases), which either succeeds or
fails depending on whether userspace has given
us permission to perform a modeset or not.
v2: Fix plane id check in intel_crtc_add_planes_to_state()
Only print the debug message when cdclk needs bumping
Use dev_priv->cdclk... as the old state explicitly
Reviewed-by: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191015193035.25982-5-ville.syrjala@linux.intel.com
So far we've sort of protected the global state under dev_priv with
the connection_mutex. I wan to change that so that we can change the
cdclk even for pure plane updates. To that end let's formalize the
protection of the global state to follow what I started with the cdclk
code already (though not entirely properly) such that any crtc mutex
will suffice as a read lock, and all crtcs mutexes act as the write
lock.
We'll also pimp intel_atomic_state_clear() to clear the entire global
state, so that we don't accidentally leak stale information between
the locking retries.
As a slight optimization we'll only lock the crtc mutexes to protect
the global state, however if and when we actually have to poke the
hw (eg. if the actual cdclk changes) we must serialize commits
across all crtcs so that a parallel nonblocking commit can't get
ahead of the cdclk reprogamming. We do that by adding all crtcs to
the state.
TODO: the old global state examined during commit may still
be a problem since it always looks at the _latest_ swapped state
in dev_priv. Need to add proper old/new state for that too I think.
v2: Remeber to serialize the commits if necessary
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20191015193035.25982-3-ville.syrjala@linux.intel.com
Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
The bspec lays out legal cdclk frequencies, PLL ratios, and CD2X
dividers in an easy-to-read table for most recent platforms. We've been
translating the data from that table into platform-specific code logic,
but it's easy to overlook an area we need to update when adding new
cdclk values or enabling new platforms. Let's just add a form of the
bspec table to the code and then adjust our functions to pull what they
need directly out of the table.
v2: Fix comparison when finding best cdclk.
v3: Another logic fix for calc_cdclk.
v4:
- Use named initializers for cdclk tables. (Ville)
- Include refclk as a field in the table instead of adding all three
ratios for each entry. (Ville)
- Terminate tables with an empty entry to avoid needing to store the
table size. (Ville)
- Don't try so hard to return reasonable values from our lookup
functions if we get impossible inputs; just WARN and return 0.
(Ville)
- Keep a bxt_ prefix on the lookup functions since they're still only
used on bxt+ for now. We can rename them later if we extend this
table-based approach back to older platforms. (Ville)
v5:
- Fix cnl table's ratios for 24mhz refclk. (Ville)
- Don't miss the named initializers on the cnl table. (Ville)
- Represent refclk in table as u16 rather than u32. (Ville)
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190910161506.7158-1-matthew.d.roper@intel.com
Aside from a few minor register changes and some different clock values,
cdclk design hasn't changed much since gen9lp. Let's consolidate the
handlers for bxt, cnl, and icl to keep the codeflow consistent.
Also, while we're at it, s/bxt_de_pll_update/bxt_de_pll_readout/ since
"update" makes me think we should be writing to hardware rather than
reading from it.
v2:
- Fix icl_calc_voltage_level() limits. (Ville)
- Use CNL_CDCLK_PLL_RATIO_MASK rather than BXT_DE_PLL_RATIO_MASK on
gen10+ to avoid confusion. (Ville)
v3:
- Also fix ehl_calc_voltage_level() limits. (Ville)
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Suggested-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190910160520.6587-1-matthew.d.roper@intel.com
The bspec has just recently been updated with new cdclk values that
require the use of a /2 CD2X divider rather than a /1 divider. Once we
add the divider selection logic to ICL+ cdclk programming, we have
pretty much the same logic we were already using on CNL, so it's simpler
to drop icl_set_cdclk() completely and reuse cnl_set_cdclk() on gen11+
platforms as well.
v2:
- Using ICL_CDCLK_CD2X_PIPE_NONE + BXT_CDCLK_CD2X_PIPE(pipe) for TGL is
correct, but looks really confusing. Add some TGL_ macros that alias
these to avoid confusion. (Ville)
- Use DIV_ROUND_CLOSEST rather than / when applying the divider. (Ville)
Cc: José Roberto de Souza <jose.souza@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190830004828.19359-1-matthew.d.roper@intel.com
On VLV/CHV there is some kind of linkage between the cdclk frequency
and the DP link frequency. The spec says:
"For DP audio configuration, cdclk frequency shall be set to
meet the following requirements:
DP Link Frequency(MHz) | Cdclk frequency(MHz)
270 | 320 or higher
162 | 200 or higher"
I suspect that would more accurately be expressed as
"cdclk >= DP link clock", and in any case we can express it like
that in the code because of the limited set of cdclk (200, 266,
320, 400 MHz) and link frequencies (162 and 270 MHz) we support.
Without this we can end up in a situation where the cdclk
is too low and enabling DP audio will kill the pipe. Happens
eg. with 2560x1440 modes where the 266MHz cdclk is sufficient
to pump the pixels (241.5 MHz dotclock) but is too low for
the DP audio due to the link frequency being 270 MHz.
v2: Spell out the cdclk and link frequencies we actually support
Cc: stable@vger.kernel.org
Tested-by: Stefan Gottwald <gottwald@igel.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=111149
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190717114536.22937-1-ville.syrjala@linux.intel.com
Acked-by: Chris Wilson <chris@chris-wilson.co.uk>