mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-02 13:46:43 +07:00
drm/i915: pass the crtc as an argument to intel_fbc_update()
There's no need to reevaluate the status of every single crtc when a single crtc changes its state. With this, we're cutting the case where due to a change in pipe B, intel_fbc_update() is called, then intel_fbc_find_crtc() concludes FBC should be enabled on pipe A, then it completely rechecks the state of pipe A only to conclude FBC should remain enabled on pipe A. If any change on pipe A triggers a need to recompute whether FBC is valid on pipe A, then at some point someone is going to call intel_fbc_update(PIPE_A). The addition of intel_fbc_deactivate() is necessary so we keep track of the previously selected CRTC when we do invalidate/flush. We're also going to continue the enable/disable/activate/deactivate concept in the next patches. v2: Rebase. v3: Rebase after changing the patch order. Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/
This commit is contained in:
parent
e9c5fd26ac
commit
754d113304
@ -4792,7 +4792,6 @@ static void intel_post_plane_update(struct intel_crtc *crtc)
|
|||||||
{
|
{
|
||||||
struct intel_crtc_atomic_commit *atomic = &crtc->atomic;
|
struct intel_crtc_atomic_commit *atomic = &crtc->atomic;
|
||||||
struct drm_device *dev = crtc->base.dev;
|
struct drm_device *dev = crtc->base.dev;
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
||||||
|
|
||||||
if (atomic->wait_vblank)
|
if (atomic->wait_vblank)
|
||||||
intel_wait_for_vblank(dev, crtc->pipe);
|
intel_wait_for_vblank(dev, crtc->pipe);
|
||||||
@ -4806,7 +4805,7 @@ static void intel_post_plane_update(struct intel_crtc *crtc)
|
|||||||
intel_update_watermarks(&crtc->base);
|
intel_update_watermarks(&crtc->base);
|
||||||
|
|
||||||
if (atomic->update_fbc)
|
if (atomic->update_fbc)
|
||||||
intel_fbc_update(dev_priv);
|
intel_fbc_update(crtc);
|
||||||
|
|
||||||
if (atomic->post_enable_primary)
|
if (atomic->post_enable_primary)
|
||||||
intel_post_enable_primary(&crtc->base);
|
intel_post_enable_primary(&crtc->base);
|
||||||
|
@ -1323,7 +1323,7 @@ static inline void intel_fbdev_restore_mode(struct drm_device *dev)
|
|||||||
|
|
||||||
/* intel_fbc.c */
|
/* intel_fbc.c */
|
||||||
bool intel_fbc_enabled(struct drm_i915_private *dev_priv);
|
bool intel_fbc_enabled(struct drm_i915_private *dev_priv);
|
||||||
void intel_fbc_update(struct drm_i915_private *dev_priv);
|
void intel_fbc_update(struct intel_crtc *crtc);
|
||||||
void intel_fbc_init(struct drm_i915_private *dev_priv);
|
void intel_fbc_init(struct drm_i915_private *dev_priv);
|
||||||
void intel_fbc_disable(struct drm_i915_private *dev_priv);
|
void intel_fbc_disable(struct drm_i915_private *dev_priv);
|
||||||
void intel_fbc_disable_crtc(struct intel_crtc *crtc);
|
void intel_fbc_disable_crtc(struct intel_crtc *crtc);
|
||||||
|
@ -429,7 +429,7 @@ static void intel_fbc_schedule_enable(struct intel_crtc *crtc)
|
|||||||
schedule_delayed_work(&work->work, msecs_to_jiffies(50));
|
schedule_delayed_work(&work->work, msecs_to_jiffies(50));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
|
static void intel_fbc_deactivate(struct drm_i915_private *dev_priv)
|
||||||
{
|
{
|
||||||
WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock));
|
WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock));
|
||||||
|
|
||||||
@ -437,6 +437,11 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
|
|||||||
|
|
||||||
if (dev_priv->fbc.enabled)
|
if (dev_priv->fbc.enabled)
|
||||||
dev_priv->fbc.disable_fbc(dev_priv);
|
dev_priv->fbc.disable_fbc(dev_priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
|
||||||
|
{
|
||||||
|
intel_fbc_deactivate(dev_priv);
|
||||||
dev_priv->fbc.crtc = NULL;
|
dev_priv->fbc.crtc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,24 +506,6 @@ static bool crtc_is_valid(struct intel_crtc *crtc)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct drm_crtc *intel_fbc_find_crtc(struct drm_i915_private *dev_priv)
|
|
||||||
{
|
|
||||||
struct drm_crtc *crtc = NULL, *tmp_crtc;
|
|
||||||
enum pipe pipe;
|
|
||||||
|
|
||||||
for_each_pipe(dev_priv, pipe) {
|
|
||||||
tmp_crtc = dev_priv->pipe_to_crtc_mapping[pipe];
|
|
||||||
|
|
||||||
if (crtc_is_valid(to_intel_crtc(tmp_crtc)))
|
|
||||||
crtc = tmp_crtc;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!crtc)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return crtc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool multiple_pipes_ok(struct drm_i915_private *dev_priv)
|
static bool multiple_pipes_ok(struct drm_i915_private *dev_priv)
|
||||||
{
|
{
|
||||||
enum pipe pipe;
|
enum pipe pipe;
|
||||||
@ -804,21 +791,28 @@ static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* __intel_fbc_update - enable/disable FBC as needed, unlocked
|
* __intel_fbc_update - enable/disable FBC as needed, unlocked
|
||||||
* @dev_priv: i915 device instance
|
* @crtc: the CRTC that triggered the update
|
||||||
*
|
*
|
||||||
* This function completely reevaluates the status of FBC, then enables,
|
* This function completely reevaluates the status of FBC, then enables,
|
||||||
* disables or maintains it on the same state.
|
* disables or maintains it on the same state.
|
||||||
*/
|
*/
|
||||||
static void __intel_fbc_update(struct drm_i915_private *dev_priv)
|
static void __intel_fbc_update(struct intel_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct drm_crtc *drm_crtc = NULL;
|
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
|
||||||
struct intel_crtc *crtc;
|
|
||||||
struct drm_framebuffer *fb;
|
struct drm_framebuffer *fb;
|
||||||
struct drm_i915_gem_object *obj;
|
struct drm_i915_gem_object *obj;
|
||||||
const struct drm_display_mode *adjusted_mode;
|
const struct drm_display_mode *adjusted_mode;
|
||||||
|
|
||||||
WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock));
|
WARN_ON(!mutex_is_locked(&dev_priv->fbc.lock));
|
||||||
|
|
||||||
|
if (!multiple_pipes_ok(dev_priv)) {
|
||||||
|
set_no_fbc_reason(dev_priv, "more than one pipe active");
|
||||||
|
goto out_disable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dev_priv->fbc.crtc != NULL && dev_priv->fbc.crtc != crtc)
|
||||||
|
return;
|
||||||
|
|
||||||
if (intel_vgpu_active(dev_priv->dev))
|
if (intel_vgpu_active(dev_priv->dev))
|
||||||
i915.enable_fbc = 0;
|
i915.enable_fbc = 0;
|
||||||
|
|
||||||
@ -832,18 +826,11 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
|
|||||||
goto out_disable;
|
goto out_disable;
|
||||||
}
|
}
|
||||||
|
|
||||||
drm_crtc = intel_fbc_find_crtc(dev_priv);
|
if (!crtc_is_valid(crtc)) {
|
||||||
if (!drm_crtc) {
|
|
||||||
set_no_fbc_reason(dev_priv, "no output");
|
set_no_fbc_reason(dev_priv, "no output");
|
||||||
goto out_disable;
|
goto out_disable;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!multiple_pipes_ok(dev_priv)) {
|
|
||||||
set_no_fbc_reason(dev_priv, "more than one pipe active");
|
|
||||||
goto out_disable;
|
|
||||||
}
|
|
||||||
|
|
||||||
crtc = to_intel_crtc(drm_crtc);
|
|
||||||
fb = crtc->base.primary->fb;
|
fb = crtc->base.primary->fb;
|
||||||
obj = intel_fb_obj(fb);
|
obj = intel_fb_obj(fb);
|
||||||
adjusted_mode = &crtc->config->base.adjusted_mode;
|
adjusted_mode = &crtc->config->base.adjusted_mode;
|
||||||
@ -909,7 +896,8 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
|
|||||||
*/
|
*/
|
||||||
if (dev_priv->fbc.crtc == crtc &&
|
if (dev_priv->fbc.crtc == crtc &&
|
||||||
dev_priv->fbc.fb_id == fb->base.id &&
|
dev_priv->fbc.fb_id == fb->base.id &&
|
||||||
dev_priv->fbc.y == crtc->base.y)
|
dev_priv->fbc.y == crtc->base.y &&
|
||||||
|
dev_priv->fbc.enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (intel_fbc_enabled(dev_priv)) {
|
if (intel_fbc_enabled(dev_priv)) {
|
||||||
@ -955,17 +943,19 @@ static void __intel_fbc_update(struct drm_i915_private *dev_priv)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* intel_fbc_update - enable/disable FBC as needed
|
* intel_fbc_update - enable/disable FBC as needed
|
||||||
* @dev_priv: i915 device instance
|
* @crtc: the CRTC that triggered the update
|
||||||
*
|
*
|
||||||
* This function reevaluates the overall state and enables or disables FBC.
|
* This function reevaluates the overall state and enables or disables FBC.
|
||||||
*/
|
*/
|
||||||
void intel_fbc_update(struct drm_i915_private *dev_priv)
|
void intel_fbc_update(struct intel_crtc *crtc)
|
||||||
{
|
{
|
||||||
|
struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
|
||||||
|
|
||||||
if (!fbc_supported(dev_priv))
|
if (!fbc_supported(dev_priv))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mutex_lock(&dev_priv->fbc.lock);
|
mutex_lock(&dev_priv->fbc.lock);
|
||||||
__intel_fbc_update(dev_priv);
|
__intel_fbc_update(crtc);
|
||||||
mutex_unlock(&dev_priv->fbc.lock);
|
mutex_unlock(&dev_priv->fbc.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -991,7 +981,7 @@ void intel_fbc_invalidate(struct drm_i915_private *dev_priv,
|
|||||||
dev_priv->fbc.busy_bits |= (fbc_bits & frontbuffer_bits);
|
dev_priv->fbc.busy_bits |= (fbc_bits & frontbuffer_bits);
|
||||||
|
|
||||||
if (dev_priv->fbc.busy_bits)
|
if (dev_priv->fbc.busy_bits)
|
||||||
__intel_fbc_disable(dev_priv);
|
intel_fbc_deactivate(dev_priv);
|
||||||
|
|
||||||
mutex_unlock(&dev_priv->fbc.lock);
|
mutex_unlock(&dev_priv->fbc.lock);
|
||||||
}
|
}
|
||||||
@ -1009,9 +999,9 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
|
|||||||
|
|
||||||
dev_priv->fbc.busy_bits &= ~frontbuffer_bits;
|
dev_priv->fbc.busy_bits &= ~frontbuffer_bits;
|
||||||
|
|
||||||
if (!dev_priv->fbc.busy_bits) {
|
if (!dev_priv->fbc.busy_bits && dev_priv->fbc.crtc) {
|
||||||
__intel_fbc_disable(dev_priv);
|
intel_fbc_deactivate(dev_priv);
|
||||||
__intel_fbc_update(dev_priv);
|
__intel_fbc_update(dev_priv->fbc.crtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&dev_priv->fbc.lock);
|
mutex_unlock(&dev_priv->fbc.lock);
|
||||||
|
Loading…
Reference in New Issue
Block a user