mirror of
https://github.com/torvalds/linux.git
synced 2024-12-26 04:42:12 +00:00
drm/i915: Calculate pipe watermarks into CRTC state (v3)
A future patch will calculate these during the atomic 'check' phase rather than at WM programming time, so let's store the watermark values we're planning to use in the CRTC state; the values actually active on the hardware remains in intel_crtc. While we're at it, do some minor restructuring to keep ILK and SKL values in a union. v2: Don't move cxsr_allowed to state (Maarten) v3: Only calculate watermarks in state. Still keep active watermarks in intel_crtc itself. (Ville) Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
de165e0bcc
commit
de4a9f8339
@ -332,6 +332,21 @@ struct intel_crtc_scaler_state {
|
|||||||
/* drm_mode->private_flags */
|
/* drm_mode->private_flags */
|
||||||
#define I915_MODE_FLAG_INHERITED 1
|
#define I915_MODE_FLAG_INHERITED 1
|
||||||
|
|
||||||
|
struct intel_pipe_wm {
|
||||||
|
struct intel_wm_level wm[5];
|
||||||
|
uint32_t linetime;
|
||||||
|
bool fbc_wm_enabled;
|
||||||
|
bool pipe_enabled;
|
||||||
|
bool sprites_enabled;
|
||||||
|
bool sprites_scaled;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct skl_pipe_wm {
|
||||||
|
struct skl_wm_level wm[8];
|
||||||
|
struct skl_wm_level trans_wm;
|
||||||
|
uint32_t linetime;
|
||||||
|
};
|
||||||
|
|
||||||
struct intel_crtc_state {
|
struct intel_crtc_state {
|
||||||
struct drm_crtc_state base;
|
struct drm_crtc_state base;
|
||||||
|
|
||||||
@ -469,6 +484,17 @@ struct intel_crtc_state {
|
|||||||
|
|
||||||
/* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */
|
/* IVB sprite scaling w/a (WaCxSRDisabledForSpriteScaling:ivb) */
|
||||||
bool disable_lp_wm;
|
bool disable_lp_wm;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
/*
|
||||||
|
* optimal watermarks, programmed post-vblank when this state
|
||||||
|
* is committed
|
||||||
|
*/
|
||||||
|
union {
|
||||||
|
struct intel_pipe_wm ilk;
|
||||||
|
struct skl_pipe_wm skl;
|
||||||
|
} optimal;
|
||||||
|
} wm;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vlv_wm_state {
|
struct vlv_wm_state {
|
||||||
@ -480,15 +506,6 @@ struct vlv_wm_state {
|
|||||||
bool cxsr;
|
bool cxsr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct intel_pipe_wm {
|
|
||||||
struct intel_wm_level wm[5];
|
|
||||||
uint32_t linetime;
|
|
||||||
bool fbc_wm_enabled;
|
|
||||||
bool pipe_enabled;
|
|
||||||
bool sprites_enabled;
|
|
||||||
bool sprites_scaled;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct intel_mmio_flip {
|
struct intel_mmio_flip {
|
||||||
struct work_struct work;
|
struct work_struct work;
|
||||||
struct drm_i915_private *i915;
|
struct drm_i915_private *i915;
|
||||||
@ -496,12 +513,6 @@ struct intel_mmio_flip {
|
|||||||
struct intel_crtc *crtc;
|
struct intel_crtc *crtc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct skl_pipe_wm {
|
|
||||||
struct skl_wm_level wm[8];
|
|
||||||
struct skl_wm_level trans_wm;
|
|
||||||
uint32_t linetime;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tracking of operations that need to be performed at the beginning/end of an
|
* Tracking of operations that need to be performed at the beginning/end of an
|
||||||
* atomic commit, outside the atomic section where interrupts are disabled.
|
* atomic commit, outside the atomic section where interrupts are disabled.
|
||||||
@ -569,9 +580,10 @@ struct intel_crtc {
|
|||||||
/* per-pipe watermark state */
|
/* per-pipe watermark state */
|
||||||
struct {
|
struct {
|
||||||
/* watermarks currently being used */
|
/* watermarks currently being used */
|
||||||
struct intel_pipe_wm active;
|
union {
|
||||||
/* SKL wm values currently in use */
|
struct intel_pipe_wm ilk;
|
||||||
struct skl_pipe_wm skl_active;
|
struct skl_pipe_wm skl;
|
||||||
|
} active;
|
||||||
/* allow CxSR on this pipe */
|
/* allow CxSR on this pipe */
|
||||||
bool cxsr_allowed;
|
bool cxsr_allowed;
|
||||||
} wm;
|
} wm;
|
||||||
|
@ -2331,7 +2331,7 @@ static void ilk_compute_wm_config(struct drm_device *dev,
|
|||||||
|
|
||||||
/* Compute the currently _active_ config */
|
/* Compute the currently _active_ config */
|
||||||
for_each_intel_crtc(dev, intel_crtc) {
|
for_each_intel_crtc(dev, intel_crtc) {
|
||||||
const struct intel_pipe_wm *wm = &intel_crtc->wm.active;
|
const struct intel_pipe_wm *wm = &intel_crtc->wm.active.ilk;
|
||||||
|
|
||||||
if (!wm->pipe_enabled)
|
if (!wm->pipe_enabled)
|
||||||
continue;
|
continue;
|
||||||
@ -2428,7 +2428,9 @@ static void ilk_merge_wm_level(struct drm_device *dev,
|
|||||||
ret_wm->enable = true;
|
ret_wm->enable = true;
|
||||||
|
|
||||||
for_each_intel_crtc(dev, intel_crtc) {
|
for_each_intel_crtc(dev, intel_crtc) {
|
||||||
const struct intel_pipe_wm *active = &intel_crtc->wm.active;
|
const struct intel_crtc_state *cstate =
|
||||||
|
to_intel_crtc_state(intel_crtc->base.state);
|
||||||
|
const struct intel_pipe_wm *active = &cstate->wm.optimal.ilk;
|
||||||
const struct intel_wm_level *wm = &active->wm[level];
|
const struct intel_wm_level *wm = &active->wm[level];
|
||||||
|
|
||||||
if (!active->pipe_enabled)
|
if (!active->pipe_enabled)
|
||||||
@ -2576,14 +2578,15 @@ static void ilk_compute_wm_results(struct drm_device *dev,
|
|||||||
|
|
||||||
/* LP0 register values */
|
/* LP0 register values */
|
||||||
for_each_intel_crtc(dev, intel_crtc) {
|
for_each_intel_crtc(dev, intel_crtc) {
|
||||||
|
const struct intel_crtc_state *cstate =
|
||||||
|
to_intel_crtc_state(intel_crtc->base.state);
|
||||||
enum pipe pipe = intel_crtc->pipe;
|
enum pipe pipe = intel_crtc->pipe;
|
||||||
const struct intel_wm_level *r =
|
const struct intel_wm_level *r = &cstate->wm.optimal.ilk.wm[0];
|
||||||
&intel_crtc->wm.active.wm[0];
|
|
||||||
|
|
||||||
if (WARN_ON(!r->enable))
|
if (WARN_ON(!r->enable))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
results->wm_linetime[pipe] = intel_crtc->wm.active.linetime;
|
results->wm_linetime[pipe] = cstate->wm.optimal.ilk.linetime;
|
||||||
|
|
||||||
results->wm_pipe[pipe] =
|
results->wm_pipe[pipe] =
|
||||||
(r->pri_val << WM0_PIPE_PLANE_SHIFT) |
|
(r->pri_val << WM0_PIPE_PLANE_SHIFT) |
|
||||||
@ -3567,10 +3570,10 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
|
|||||||
skl_allocate_pipe_ddb(cstate, config, ddb);
|
skl_allocate_pipe_ddb(cstate, config, ddb);
|
||||||
skl_compute_pipe_wm(cstate, ddb, pipe_wm);
|
skl_compute_pipe_wm(cstate, ddb, pipe_wm);
|
||||||
|
|
||||||
if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
|
if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
intel_crtc->wm.skl_active = *pipe_wm;
|
intel_crtc->wm.active.skl = *pipe_wm;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -3648,7 +3651,8 @@ static void skl_update_wm(struct drm_crtc *crtc)
|
|||||||
struct drm_device *dev = crtc->dev;
|
struct drm_device *dev = crtc->dev;
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
struct skl_wm_values *results = &dev_priv->wm.skl_results;
|
struct skl_wm_values *results = &dev_priv->wm.skl_results;
|
||||||
struct skl_pipe_wm pipe_wm = {};
|
struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
|
||||||
|
struct skl_pipe_wm *pipe_wm = &cstate->wm.optimal.skl;
|
||||||
struct intel_wm_config config = {};
|
struct intel_wm_config config = {};
|
||||||
|
|
||||||
|
|
||||||
@ -3659,10 +3663,10 @@ static void skl_update_wm(struct drm_crtc *crtc)
|
|||||||
|
|
||||||
skl_compute_wm_global_parameters(dev, &config);
|
skl_compute_wm_global_parameters(dev, &config);
|
||||||
|
|
||||||
if (!skl_update_pipe_wm(crtc, &config, &results->ddb, &pipe_wm))
|
if (!skl_update_pipe_wm(crtc, &config, &results->ddb, pipe_wm))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
skl_compute_wm_results(dev, &pipe_wm, results, intel_crtc);
|
skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);
|
||||||
results->dirty[intel_crtc->pipe] = true;
|
results->dirty[intel_crtc->pipe] = true;
|
||||||
|
|
||||||
skl_update_other_pipe_wm(dev, crtc, &config, results);
|
skl_update_other_pipe_wm(dev, crtc, &config, results);
|
||||||
@ -3711,7 +3715,6 @@ static void ilk_update_wm(struct drm_crtc *crtc)
|
|||||||
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
|
struct drm_i915_private *dev_priv = to_i915(crtc->dev);
|
||||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||||
struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
|
struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
|
||||||
struct intel_pipe_wm pipe_wm = {};
|
|
||||||
|
|
||||||
WARN_ON(cstate->base.active != intel_crtc->active);
|
WARN_ON(cstate->base.active != intel_crtc->active);
|
||||||
|
|
||||||
@ -3727,12 +3730,13 @@ static void ilk_update_wm(struct drm_crtc *crtc)
|
|||||||
intel_wait_for_vblank(crtc->dev, intel_crtc->pipe);
|
intel_wait_for_vblank(crtc->dev, intel_crtc->pipe);
|
||||||
}
|
}
|
||||||
|
|
||||||
intel_compute_pipe_wm(cstate, &pipe_wm);
|
intel_compute_pipe_wm(cstate, &cstate->wm.optimal.ilk);
|
||||||
|
|
||||||
if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
|
if (!memcmp(&intel_crtc->wm.active.ilk,
|
||||||
return;
|
&cstate->wm.optimal.ilk,
|
||||||
|
sizeof(cstate->wm.optimal.ilk)));
|
||||||
|
|
||||||
intel_crtc->wm.active = pipe_wm;
|
intel_crtc->wm.active.ilk = cstate->wm.optimal.ilk;
|
||||||
|
|
||||||
ilk_program_watermarks(dev_priv);
|
ilk_program_watermarks(dev_priv);
|
||||||
}
|
}
|
||||||
@ -3787,7 +3791,8 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
|
|||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
|
struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
|
||||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||||
struct skl_pipe_wm *active = &intel_crtc->wm.skl_active;
|
struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
|
||||||
|
struct skl_pipe_wm *active = &cstate->wm.optimal.skl;
|
||||||
enum pipe pipe = intel_crtc->pipe;
|
enum pipe pipe = intel_crtc->pipe;
|
||||||
int level, i, max_level;
|
int level, i, max_level;
|
||||||
uint32_t temp;
|
uint32_t temp;
|
||||||
@ -3831,6 +3836,8 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
|
|||||||
|
|
||||||
temp = hw->plane_trans[pipe][PLANE_CURSOR];
|
temp = hw->plane_trans[pipe][PLANE_CURSOR];
|
||||||
skl_pipe_wm_active_state(temp, active, true, true, i, 0);
|
skl_pipe_wm_active_state(temp, active, true, true, i, 0);
|
||||||
|
|
||||||
|
intel_crtc->wm.active.skl = *active;
|
||||||
}
|
}
|
||||||
|
|
||||||
void skl_wm_get_hw_state(struct drm_device *dev)
|
void skl_wm_get_hw_state(struct drm_device *dev)
|
||||||
@ -3850,7 +3857,8 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
|
|||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
struct ilk_wm_values *hw = &dev_priv->wm.hw;
|
struct ilk_wm_values *hw = &dev_priv->wm.hw;
|
||||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||||
struct intel_pipe_wm *active = &intel_crtc->wm.active;
|
struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
|
||||||
|
struct intel_pipe_wm *active = &cstate->wm.optimal.ilk;
|
||||||
enum pipe pipe = intel_crtc->pipe;
|
enum pipe pipe = intel_crtc->pipe;
|
||||||
static const unsigned int wm0_pipe_reg[] = {
|
static const unsigned int wm0_pipe_reg[] = {
|
||||||
[PIPE_A] = WM0_PIPEA_ILK,
|
[PIPE_A] = WM0_PIPEA_ILK,
|
||||||
@ -3889,6 +3897,8 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
|
|||||||
for (level = 0; level <= max_level; level++)
|
for (level = 0; level <= max_level; level++)
|
||||||
active->wm[level].enable = true;
|
active->wm[level].enable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intel_crtc->wm.active.ilk = *active;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _FW_WM(value, plane) \
|
#define _FW_WM(value, plane) \
|
||||||
|
Loading…
Reference in New Issue
Block a user