summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_fbc.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-07-15 13:50:58 +1000
committerDave Airlie <airlied@redhat.com>2016-07-15 13:50:58 +1000
commitff37c05a996bb96eccc21f4fb1b32ba0e24f3443 (patch)
treec09b09b37521f2f8f3f7a9bb3b0a33a2b3bde1a1 /drivers/gpu/drm/i915/intel_fbc.c
parent6c181c82106e12dced317e93a7a396cbb8c64f75 (diff)
parent0b2c0582f1570bfc95aa9ac1cd340a215d8e8335 (diff)
Merge tag 'drm-intel-next-2016-07-11' of git://anongit.freedesktop.org/drm-intel into drm-next
- select igt testing depencies for CONFIG_DRM_I915_DEBUG (Chris) - track outputs in crtc state and clean up all our ad-hoc connector/encoder walking in modest code (Ville) - demidlayer drm_device/drm_i915_private (Chris Wilson) - thundering herd fix from Chris Wilson, with lots of help from Tvrtko Ursulin - piles of assorted clean and fallout from the thundering herd fix - documentation and more tuning for waitboosting (Chris) - pooled EU support on bxt (Arun Siluvery) - bxt support is no longer considered prelimary! - ring/engine vfunc cleanup from Tvrtko - introduce intel_wait_for_register helper (Chris) - opregion updates (Jani Nukla) - tuning and fixes for wait_for macros (Tvrkto&Imre) - more kabylake pci ids (Rodrigo) - pps cleanup and fixes for bxt (Imre) - move sink crc support over to atomic state (Maarten) - fix up async fbdev init ordering (Chris) - fbc fixes from Paulo and Chris * tag 'drm-intel-next-2016-07-11' of git://anongit.freedesktop.org/drm-intel: (223 commits) drm/i915: Update DRIVER_DATE to 20160711 drm/i915: Select DRM_VGEM for igt drm/i915: Select X86_MSR for igt drm/i915: Fill unused GGTT with scratch pages for VT-d drm/i915: Introduce Kabypoint PCH for Kabylake H/DT. drm/i915:gen9: implement WaMediaPoolStateCmdInWABB drm/i915: Check for invalid cloning earlier during modeset drm/i915: Simplify hdmi_12bpc_possible() drm/i915: Kill has_dsi_encoder drm/i915: s/INTEL_OUTPUT_DISPLAYPORT/INTEL_OUTPUT_DP/ drm/i915: Replace some open coded intel_crtc_has_dp_encoder()s drm/i915: Kill has_dp_encoder from pipe_config drm/i915: Replace manual lvds and sdvo/hdmi counting with intel_crtc_has_type() drm/i915: Unify intel_pipe_has_type() and intel_pipe_will_have_type() drm/i915: Add output_types bitmask into the crtc state drm/i915: Remove encoder type checks from MST suspend/resume drm/i915: Don't mark eDP encoders as MST capable drm/i915: avoid wait_for_atomic() in non-atomic host2guc_action() drm/i915: Group the irq breadcrumb variables into the same cacheline drm/i915: Wake up the bottom-half if we steal their interrupt ...
Diffstat (limited to 'drivers/gpu/drm/i915/intel_fbc.c')
-rw-r--r--drivers/gpu/drm/i915/intel_fbc.c70
1 files changed, 45 insertions, 25 deletions
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index a19944b6dc25..6a7ad3ed1463 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -124,7 +124,9 @@ static void i8xx_fbc_deactivate(struct drm_i915_private *dev_priv)
I915_WRITE(FBC_CONTROL, fbc_ctl);
/* Wait for compressing bit to clear */
- if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10)) {
+ if (intel_wait_for_register(dev_priv,
+ FBC_STATUS, FBC_STAT_COMPRESSING, 0,
+ 10)) {
DRM_DEBUG_KMS("FBC idle timed out\n");
return;
}
@@ -390,7 +392,7 @@ static void intel_fbc_work_fn(struct work_struct *__work)
struct intel_fbc *fbc = &dev_priv->fbc;
struct intel_fbc_work *work = &fbc->work;
struct intel_crtc *crtc = fbc->crtc;
- struct drm_vblank_crtc *vblank = &dev_priv->dev->vblank[crtc->pipe];
+ struct drm_vblank_crtc *vblank = &dev_priv->drm.vblank[crtc->pipe];
if (drm_crtc_vblank_get(&crtc->base)) {
DRM_ERROR("vblank not available for FBC on pipe %c\n",
@@ -443,7 +445,7 @@ out:
static void intel_fbc_schedule_activation(struct intel_crtc *crtc)
{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_fbc *fbc = &dev_priv->fbc;
struct intel_fbc_work *work = &fbc->work;
@@ -553,7 +555,7 @@ again:
static int intel_fbc_alloc_cfb(struct intel_crtc *crtc)
{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_fbc *fbc = &dev_priv->fbc;
struct drm_mm_node *uninitialized_var(compressed_llb);
int size, fb_cpp, ret;
@@ -684,7 +686,7 @@ static bool pixel_format_is_valid(struct drm_i915_private *dev_priv,
*/
static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_fbc *fbc = &dev_priv->fbc;
unsigned int effective_w, effective_h, max_w, max_h;
@@ -711,7 +713,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state)
{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_fbc *fbc = &dev_priv->fbc;
struct intel_fbc_state_cache *cache = &fbc->state_cache;
struct drm_framebuffer *fb = plane_state->base.fb;
@@ -744,7 +746,7 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
static bool intel_fbc_can_activate(struct intel_crtc *crtc)
{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_fbc *fbc = &dev_priv->fbc;
struct intel_fbc_state_cache *cache = &fbc->state_cache;
@@ -816,22 +818,16 @@ static bool intel_fbc_can_activate(struct intel_crtc *crtc)
static bool intel_fbc_can_choose(struct intel_crtc *crtc)
{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_fbc *fbc = &dev_priv->fbc;
- bool enable_by_default = IS_BROADWELL(dev_priv);
if (intel_vgpu_active(dev_priv)) {
fbc->no_fbc_reason = "VGPU is active";
return false;
}
- if (i915.enable_fbc < 0 && !enable_by_default) {
- fbc->no_fbc_reason = "disabled per chip default";
- return false;
- }
-
if (!i915.enable_fbc) {
- fbc->no_fbc_reason = "disabled per module param";
+ fbc->no_fbc_reason = "disabled per module param or by default";
return false;
}
@@ -851,7 +847,7 @@ static bool intel_fbc_can_choose(struct intel_crtc *crtc)
static void intel_fbc_get_reg_params(struct intel_crtc *crtc,
struct intel_fbc_reg_params *params)
{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_fbc *fbc = &dev_priv->fbc;
struct intel_fbc_state_cache *cache = &fbc->state_cache;
@@ -884,7 +880,7 @@ void intel_fbc_pre_update(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state)
{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_fbc *fbc = &dev_priv->fbc;
if (!fbc_supported(dev_priv))
@@ -910,7 +906,7 @@ unlock:
static void __intel_fbc_post_update(struct intel_crtc *crtc)
{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_fbc *fbc = &dev_priv->fbc;
struct intel_fbc_reg_params old_params;
@@ -943,7 +939,7 @@ static void __intel_fbc_post_update(struct intel_crtc *crtc)
void intel_fbc_post_update(struct intel_crtc *crtc)
{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_fbc *fbc = &dev_priv->fbc;
if (!fbc_supported(dev_priv))
@@ -992,13 +988,13 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
if (!fbc_supported(dev_priv))
return;
- if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP)
- return;
-
mutex_lock(&fbc->lock);
fbc->busy_bits &= ~frontbuffer_bits;
+ if (origin == ORIGIN_GTT || origin == ORIGIN_FLIP)
+ goto out;
+
if (!fbc->busy_bits && fbc->enabled &&
(frontbuffer_bits & intel_fbc_get_frontbuffer_bit(fbc))) {
if (fbc->active)
@@ -1007,6 +1003,7 @@ void intel_fbc_flush(struct drm_i915_private *dev_priv,
__intel_fbc_post_update(fbc->crtc);
}
+out:
mutex_unlock(&fbc->lock);
}
@@ -1088,7 +1085,7 @@ void intel_fbc_enable(struct intel_crtc *crtc,
struct intel_crtc_state *crtc_state,
struct intel_plane_state *plane_state)
{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_fbc *fbc = &dev_priv->fbc;
if (!fbc_supported(dev_priv))
@@ -1159,7 +1156,7 @@ static void __intel_fbc_disable(struct drm_i915_private *dev_priv)
*/
void intel_fbc_disable(struct intel_crtc *crtc)
{
- struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct intel_fbc *fbc = &dev_priv->fbc;
if (!fbc_supported(dev_priv))
@@ -1213,12 +1210,32 @@ void intel_fbc_init_pipe_state(struct drm_i915_private *dev_priv)
if (!no_fbc_on_multiple_pipes(dev_priv))
return;
- for_each_intel_crtc(dev_priv->dev, crtc)
+ for_each_intel_crtc(&dev_priv->drm, crtc)
if (intel_crtc_active(&crtc->base) &&
to_intel_plane_state(crtc->base.primary->state)->visible)
dev_priv->fbc.visible_pipes_mask |= (1 << crtc->pipe);
}
+/*
+ * The DDX driver changes its behavior depending on the value it reads from
+ * i915.enable_fbc, so sanitize it by translating the default value into either
+ * 0 or 1 in order to allow it to know what's going on.
+ *
+ * Notice that this is done at driver initialization and we still allow user
+ * space to change the value during runtime without sanitizing it again. IGT
+ * relies on being able to change i915.enable_fbc at runtime.
+ */
+static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv)
+{
+ if (i915.enable_fbc >= 0)
+ return !!i915.enable_fbc;
+
+ if (IS_BROADWELL(dev_priv))
+ return 1;
+
+ return 0;
+}
+
/**
* intel_fbc_init - Initialize FBC
* @dev_priv: the i915 device
@@ -1236,6 +1253,9 @@ void intel_fbc_init(struct drm_i915_private *dev_priv)
fbc->active = false;
fbc->work.scheduled = false;
+ i915.enable_fbc = intel_sanitize_fbc_option(dev_priv);
+ DRM_DEBUG_KMS("Sanitized enable_fbc value: %d\n", i915.enable_fbc);
+
if (!HAS_FBC(dev_priv)) {
fbc->no_fbc_reason = "unsupported by this chipset";
return;