From: Damien Lespiau Date: Thu, 13 Nov 2014 17:51:46 +0000 (+0000) Subject: drm/i915/skl: Implement queue_flip X-Git-Tag: v3.19-rc1~73^2~14^2~71 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=830c81db2dc9dccc505adc7d4651324ea5332add;p=karo-tx-linux.git drm/i915/skl: Implement queue_flip A few bits have changed in MI_DISPLAY_FLIP to accomodate the new planes. DE_RRMR seems to have kept its plane flip bits backward compatible. v2: Rebase on top of nightly v3: Rebase on top of nightly (minor conflict in i915_reg.h) v4: Remove code that is now part of intel_crtc_page_flip() Don't use BUG() in default: Use intel_crtc->unpin_work->gtt_offset (Paulo) Reviewed-by: Paulo Zanoni Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c443008e99d8..2bdfe0810684 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -248,6 +248,16 @@ #define MI_DISPLAY_FLIP_IVB_SPRITE_B (3 << 19) #define MI_DISPLAY_FLIP_IVB_PLANE_C (4 << 19) #define MI_DISPLAY_FLIP_IVB_SPRITE_C (5 << 19) +/* SKL ones */ +#define MI_DISPLAY_FLIP_SKL_PLANE_1_A (0 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_1_B (1 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_1_C (2 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_2_A (4 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_2_B (5 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_2_C (6 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_3_A (7 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_3_B (8 << 8) +#define MI_DISPLAY_FLIP_SKL_PLANE_3_C (9 << 8) #define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6, gen7 */ #define MI_SEMAPHORE_GLOBAL_GTT (1<<22) #define MI_SEMAPHORE_UPDATE (1<<21) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c60bfbd9b5f4..8f47b988a233 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9480,6 +9480,69 @@ static int intel_queue_mmio_flip(struct drm_device *dev, return 0; } +static int intel_gen9_queue_flip(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_i915_gem_object *obj, + struct intel_engine_cs *ring, + uint32_t flags) +{ + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + uint32_t plane = 0, stride; + int ret; + + switch(intel_crtc->pipe) { + case PIPE_A: + plane = MI_DISPLAY_FLIP_SKL_PLANE_1_A; + break; + case PIPE_B: + plane = MI_DISPLAY_FLIP_SKL_PLANE_1_B; + break; + case PIPE_C: + plane = MI_DISPLAY_FLIP_SKL_PLANE_1_C; + break; + default: + WARN_ONCE(1, "unknown plane in flip command\n"); + return -ENODEV; + } + + switch (obj->tiling_mode) { + case I915_TILING_NONE: + stride = fb->pitches[0] >> 6; + break; + case I915_TILING_X: + stride = fb->pitches[0] >> 9; + break; + default: + WARN_ONCE(1, "unknown tiling in flip command\n"); + return -ENODEV; + } + + ret = intel_ring_begin(ring, 10); + if (ret) + return ret; + + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(ring, DERRMR); + intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE | + DERRMR_PIPEB_PRI_FLIP_DONE | + DERRMR_PIPEC_PRI_FLIP_DONE)); + intel_ring_emit(ring, MI_STORE_REGISTER_MEM_GEN8(1) | + MI_SRM_LRM_GLOBAL_GTT); + intel_ring_emit(ring, DERRMR); + intel_ring_emit(ring, ring->scratch.gtt_offset + 256); + intel_ring_emit(ring, 0); + + intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane); + intel_ring_emit(ring, stride << 6 | obj->tiling_mode); + intel_ring_emit(ring, intel_crtc->unpin_work->gtt_offset); + + intel_mark_page_flip_active(intel_crtc); + __intel_ring_advance(ring); + + return 0; +} + static int intel_default_queue_flip(struct drm_device *dev, struct drm_crtc *crtc, struct drm_framebuffer *fb, @@ -12648,6 +12711,9 @@ static void intel_init_display(struct drm_device *dev) case 8: /* FIXME(BDW): Check that the gen8 RCS flip works. */ dev_priv->display.queue_flip = intel_gen7_queue_flip; break; + case 9: + dev_priv->display.queue_flip = intel_gen9_queue_flip; + break; } intel_panel_init_backlight_funcs(dev);