提交 9c61de4c 编写于 作者: V Ville Syrjälä

drm/i915: Consolidate max_cdclk_freq check in intel_crtc_compute_min_cdclk()

Currently the .modeset_calc_cdclk() hooks check the final cdclk value
against the max allowed. That's not really sufficient since the low
level calc_cdclk() functions effectively clamp the minimum required
cdclk to the max supported by the platform. Hence if the minimum
required exceeds the platforms capabilities we'd keep going anyway
using the max cdclk frequency.

To fix that let's move the check earlier into
intel_crtc_compute_min_cdclk() and we'll check the minimum required
cdclk of the pipe against the maximum supported by the platform.

Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: NVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170710193347.8734-2-ville.syrjala@linux.intel.comReviewed-by: NDhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
上级 d305e061
...@@ -1789,6 +1789,12 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state) ...@@ -1789,6 +1789,12 @@ int intel_crtc_compute_min_cdclk(const struct intel_crtc_state *crtc_state)
if (crtc_state->has_audio && INTEL_GEN(dev_priv) >= 9) if (crtc_state->has_audio && INTEL_GEN(dev_priv) >= 9)
min_cdclk = max(2 * 96000, min_cdclk); min_cdclk = max(2 * 96000, min_cdclk);
if (min_cdclk > dev_priv->max_cdclk_freq) {
DRM_DEBUG_KMS("required cdclk (%d kHz) exceeds max (%d kHz)\n",
min_cdclk, dev_priv->max_cdclk_freq);
return -EINVAL;
}
return min_cdclk; return min_cdclk;
} }
...@@ -1798,16 +1804,21 @@ static int intel_compute_min_cdclk(struct drm_atomic_state *state) ...@@ -1798,16 +1804,21 @@ static int intel_compute_min_cdclk(struct drm_atomic_state *state)
struct drm_i915_private *dev_priv = to_i915(state->dev); struct drm_i915_private *dev_priv = to_i915(state->dev);
struct intel_crtc *crtc; struct intel_crtc *crtc;
struct intel_crtc_state *crtc_state; struct intel_crtc_state *crtc_state;
int min_cdclk = 0, i; int min_cdclk, i;
enum pipe pipe; enum pipe pipe;
memcpy(intel_state->min_cdclk, dev_priv->min_cdclk, memcpy(intel_state->min_cdclk, dev_priv->min_cdclk,
sizeof(intel_state->min_cdclk)); sizeof(intel_state->min_cdclk));
for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) for_each_new_intel_crtc_in_state(intel_state, crtc, crtc_state, i) {
intel_state->min_cdclk[i] = min_cdclk = intel_crtc_compute_min_cdclk(crtc_state);
intel_crtc_compute_min_cdclk(crtc_state); if (min_cdclk < 0)
return min_cdclk;
intel_state->min_cdclk[i] = min_cdclk;
}
min_cdclk = 0;
for_each_pipe(dev_priv, pipe) for_each_pipe(dev_priv, pipe)
min_cdclk = max(intel_state->min_cdclk[pipe], min_cdclk); min_cdclk = max(intel_state->min_cdclk[pipe], min_cdclk);
...@@ -1817,18 +1828,14 @@ static int intel_compute_min_cdclk(struct drm_atomic_state *state) ...@@ -1817,18 +1828,14 @@ static int intel_compute_min_cdclk(struct drm_atomic_state *state)
static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state) static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
{ {
struct drm_i915_private *dev_priv = to_i915(state->dev); struct drm_i915_private *dev_priv = to_i915(state->dev);
int min_cdclk = intel_compute_min_cdclk(state); struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
struct intel_atomic_state *intel_state = int min_cdclk, cdclk;
to_intel_atomic_state(state);
int cdclk;
cdclk = vlv_calc_cdclk(dev_priv, min_cdclk); min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
if (cdclk > dev_priv->max_cdclk_freq) { cdclk = vlv_calc_cdclk(dev_priv, min_cdclk);
DRM_DEBUG_KMS("requested cdclk (%d kHz) exceeds max (%d kHz)\n",
cdclk, dev_priv->max_cdclk_freq);
return -EINVAL;
}
intel_state->cdclk.logical.cdclk = cdclk; intel_state->cdclk.logical.cdclk = cdclk;
...@@ -1846,10 +1853,12 @@ static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state) ...@@ -1846,10 +1853,12 @@ static int vlv_modeset_calc_cdclk(struct drm_atomic_state *state)
static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state) static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state)
{ {
struct drm_i915_private *dev_priv = to_i915(state->dev);
struct intel_atomic_state *intel_state = to_intel_atomic_state(state); struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
int min_cdclk = intel_compute_min_cdclk(state); int min_cdclk, cdclk;
int cdclk;
min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
/* /*
* FIXME should also account for plane ratio * FIXME should also account for plane ratio
...@@ -1857,12 +1866,6 @@ static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state) ...@@ -1857,12 +1866,6 @@ static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state)
*/ */
cdclk = bdw_calc_cdclk(min_cdclk); cdclk = bdw_calc_cdclk(min_cdclk);
if (cdclk > dev_priv->max_cdclk_freq) {
DRM_DEBUG_KMS("requested cdclk (%d kHz) exceeds max (%d kHz)\n",
cdclk, dev_priv->max_cdclk_freq);
return -EINVAL;
}
intel_state->cdclk.logical.cdclk = cdclk; intel_state->cdclk.logical.cdclk = cdclk;
if (!intel_state->active_crtcs) { if (!intel_state->active_crtcs) {
...@@ -1879,10 +1882,13 @@ static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state) ...@@ -1879,10 +1882,13 @@ static int bdw_modeset_calc_cdclk(struct drm_atomic_state *state)
static int skl_modeset_calc_cdclk(struct drm_atomic_state *state) static int skl_modeset_calc_cdclk(struct drm_atomic_state *state)
{ {
struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
struct drm_i915_private *dev_priv = to_i915(state->dev); struct drm_i915_private *dev_priv = to_i915(state->dev);
int min_cdclk = intel_compute_min_cdclk(state); struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
int cdclk, vco; int min_cdclk, cdclk, vco;
min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
vco = intel_state->cdclk.logical.vco; vco = intel_state->cdclk.logical.vco;
if (!vco) if (!vco)
...@@ -1894,12 +1900,6 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state) ...@@ -1894,12 +1900,6 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state)
*/ */
cdclk = skl_calc_cdclk(min_cdclk, vco); cdclk = skl_calc_cdclk(min_cdclk, vco);
if (cdclk > dev_priv->max_cdclk_freq) {
DRM_DEBUG_KMS("requested cdclk (%d kHz) exceeds max (%d kHz)\n",
cdclk, dev_priv->max_cdclk_freq);
return -EINVAL;
}
intel_state->cdclk.logical.vco = vco; intel_state->cdclk.logical.vco = vco;
intel_state->cdclk.logical.cdclk = cdclk; intel_state->cdclk.logical.cdclk = cdclk;
...@@ -1919,10 +1919,12 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state) ...@@ -1919,10 +1919,12 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state)
static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state) static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state)
{ {
struct drm_i915_private *dev_priv = to_i915(state->dev); struct drm_i915_private *dev_priv = to_i915(state->dev);
int min_cdclk = intel_compute_min_cdclk(state); struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
struct intel_atomic_state *intel_state = int min_cdclk, cdclk, vco;
to_intel_atomic_state(state);
int cdclk, vco; min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
if (IS_GEMINILAKE(dev_priv)) { if (IS_GEMINILAKE(dev_priv)) {
cdclk = glk_calc_cdclk(min_cdclk); cdclk = glk_calc_cdclk(min_cdclk);
...@@ -1932,12 +1934,6 @@ static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state) ...@@ -1932,12 +1934,6 @@ static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state)
vco = bxt_de_pll_vco(dev_priv, cdclk); vco = bxt_de_pll_vco(dev_priv, cdclk);
} }
if (cdclk > dev_priv->max_cdclk_freq) {
DRM_DEBUG_KMS("requested cdclk (%d kHz) exceeds max (%d kHz)\n",
cdclk, dev_priv->max_cdclk_freq);
return -EINVAL;
}
intel_state->cdclk.logical.vco = vco; intel_state->cdclk.logical.vco = vco;
intel_state->cdclk.logical.cdclk = cdclk; intel_state->cdclk.logical.cdclk = cdclk;
...@@ -1963,20 +1959,16 @@ static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state) ...@@ -1963,20 +1959,16 @@ static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state)
static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state) static int cnl_modeset_calc_cdclk(struct drm_atomic_state *state)
{ {
struct drm_i915_private *dev_priv = to_i915(state->dev); struct drm_i915_private *dev_priv = to_i915(state->dev);
struct intel_atomic_state *intel_state = struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
to_intel_atomic_state(state); int min_cdclk, cdclk, vco;
int min_cdclk = intel_compute_min_cdclk(state);
int cdclk, vco; min_cdclk = intel_compute_min_cdclk(state);
if (min_cdclk < 0)
return min_cdclk;
cdclk = cnl_calc_cdclk(min_cdclk); cdclk = cnl_calc_cdclk(min_cdclk);
vco = cnl_cdclk_pll_vco(dev_priv, cdclk); vco = cnl_cdclk_pll_vco(dev_priv, cdclk);
if (cdclk > dev_priv->max_cdclk_freq) {
DRM_DEBUG_KMS("requested cdclk (%d kHz) exceeds max (%d kHz)\n",
cdclk, dev_priv->max_cdclk_freq);
return -EINVAL;
}
intel_state->cdclk.logical.vco = vco; intel_state->cdclk.logical.vco = vco;
intel_state->cdclk.logical.cdclk = cdclk; intel_state->cdclk.logical.cdclk = cdclk;
......
...@@ -15118,8 +15118,11 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) ...@@ -15118,8 +15118,11 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev)
intel_crtc_compute_pixel_rate(crtc_state); intel_crtc_compute_pixel_rate(crtc_state);
if (dev_priv->display.modeset_calc_cdclk) if (dev_priv->display.modeset_calc_cdclk) {
min_cdclk = intel_crtc_compute_min_cdclk(crtc_state); min_cdclk = intel_crtc_compute_min_cdclk(crtc_state);
if (WARN_ON(min_cdclk < 0))
min_cdclk = 0;
}
drm_calc_timestamping_constants(&crtc->base, drm_calc_timestamping_constants(&crtc->base,
&crtc_state->base.adjusted_mode); &crtc_state->base.adjusted_mode);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册