diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/i9xx_plane.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/i9xx_plane.c | 111 |
1 files changed, 70 insertions, 41 deletions
diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index 013295f66d56..f291ced989dc 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -2,24 +2,28 @@ /* * Copyright © 2020 Intel Corporation */ + #include <linux/kernel.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_blend.h> #include <drm/drm_fourcc.h> +#include <drm/drm_print.h> -#include "i915_drv.h" #include "i915_reg.h" +#include "i915_utils.h" #include "i9xx_plane.h" #include "i9xx_plane_regs.h" #include "intel_atomic.h" -#include "intel_atomic_plane.h" +#include "intel_bo.h" #include "intel_de.h" #include "intel_display_irq.h" +#include "intel_display_regs.h" #include "intel_display_types.h" #include "intel_fb.h" #include "intel_fbc.h" #include "intel_frontbuffer.h" +#include "intel_plane.h" #include "intel_sprite.h" /* Primary plane formats for gen <= 3 */ @@ -333,10 +337,10 @@ i9xx_plane_check(struct intel_crtc_state *crtc_state, if (ret) return ret; - ret = intel_atomic_plane_check_clipping(plane_state, crtc_state, - DRM_PLANE_NO_SCALING, - DRM_PLANE_NO_SCALING, - i9xx_plane_has_windowing(plane)); + ret = intel_plane_check_clipping(plane_state, crtc_state, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, + i9xx_plane_has_windowing(plane)); if (ret) return ret; @@ -630,85 +634,85 @@ vlv_primary_async_flip(struct intel_dsb *dsb, static void bdw_primary_enable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; - spin_lock_irq(&i915->irq_lock); - bdw_enable_pipe_irq(i915, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); - spin_unlock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); + bdw_enable_pipe_irq(display, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); + spin_unlock_irq(&display->irq.lock); } static void bdw_primary_disable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; - spin_lock_irq(&i915->irq_lock); - bdw_disable_pipe_irq(i915, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); - spin_unlock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); + bdw_disable_pipe_irq(display, pipe, GEN8_PIPE_PRIMARY_FLIP_DONE); + spin_unlock_irq(&display->irq.lock); } static void ivb_primary_enable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); - spin_lock_irq(&i915->irq_lock); - ilk_enable_display_irq(i915, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); - spin_unlock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); + ilk_enable_display_irq(display, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); + spin_unlock_irq(&display->irq.lock); } static void ivb_primary_disable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); - spin_lock_irq(&i915->irq_lock); - ilk_disable_display_irq(i915, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); - spin_unlock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); + ilk_disable_display_irq(display, DE_PLANE_FLIP_DONE_IVB(plane->i9xx_plane)); + spin_unlock_irq(&display->irq.lock); } static void ilk_primary_enable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); - spin_lock_irq(&i915->irq_lock); - ilk_enable_display_irq(i915, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); - spin_unlock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); + ilk_enable_display_irq(display, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); + spin_unlock_irq(&display->irq.lock); } static void ilk_primary_disable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); - spin_lock_irq(&i915->irq_lock); - ilk_disable_display_irq(i915, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); - spin_unlock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); + ilk_disable_display_irq(display, DE_PLANE_FLIP_DONE(plane->i9xx_plane)); + spin_unlock_irq(&display->irq.lock); } static void vlv_primary_enable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; - spin_lock_irq(&i915->irq_lock); - i915_enable_pipestat(i915, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); - spin_unlock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); + i915_enable_pipestat(display, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); + spin_unlock_irq(&display->irq.lock); } static void vlv_primary_disable_flip_done(struct intel_plane *plane) { - struct drm_i915_private *i915 = to_i915(plane->base.dev); + struct intel_display *display = to_intel_display(plane); enum pipe pipe = plane->pipe; - spin_lock_irq(&i915->irq_lock); - i915_disable_pipestat(i915, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); - spin_unlock_irq(&i915->irq_lock); + spin_lock_irq(&display->irq.lock); + i915_disable_pipestat(display, pipe, PLANE_FLIP_DONE_INT_STATUS_VLV); + spin_unlock_irq(&display->irq.lock); } static bool i9xx_plane_can_async_flip(u64 modifier) @@ -820,7 +824,7 @@ unsigned int vlv_plane_min_alignment(struct intel_plane *plane, { struct intel_display *display = to_intel_display(plane); - if (intel_plane_can_async_flip(plane, fb->modifier)) + if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier)) return 256 * 1024; /* FIXME undocumented so not sure what's actually needed */ @@ -844,7 +848,7 @@ static unsigned int g4x_primary_min_alignment(struct intel_plane *plane, { struct intel_display *display = to_intel_display(plane); - if (intel_plane_can_async_flip(plane, fb->modifier)) + if (intel_plane_can_async_flip(plane, fb->format->format, fb->modifier)) return 256 * 1024; if (intel_scanout_needs_vtd_wa(display)) @@ -889,6 +893,7 @@ static const struct drm_plane_funcs i965_plane_funcs = { .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = i965_plane_format_mod_supported, + .format_mod_supported_async = intel_plane_format_mod_supported_async, }; static const struct drm_plane_funcs i8xx_plane_funcs = { @@ -898,8 +903,30 @@ static const struct drm_plane_funcs i8xx_plane_funcs = { .atomic_duplicate_state = intel_plane_duplicate_state, .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = i8xx_plane_format_mod_supported, + .format_mod_supported_async = intel_plane_format_mod_supported_async, }; +static void i9xx_disable_tiling(struct intel_plane *plane) +{ + struct intel_display *display = to_intel_display(plane); + enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; + u32 dspcntr; + u32 reg; + + dspcntr = intel_de_read_fw(display, DSPCNTR(display, i9xx_plane)); + dspcntr &= ~DISP_TILED; + intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr); + + if (DISPLAY_VER(display) >= 4) { + reg = intel_de_read_fw(display, DSPSURF(display, i9xx_plane)); + intel_de_write_fw(display, DSPSURF(display, i9xx_plane), reg); + + } else { + reg = intel_de_read_fw(display, DSPADDR(display, i9xx_plane)); + intel_de_write_fw(display, DSPADDR(display, i9xx_plane), reg); + } +} + struct intel_plane * intel_primary_plane_create(struct intel_display *display, enum pipe pipe) { @@ -1042,6 +1069,8 @@ intel_primary_plane_create(struct intel_display *display, enum pipe pipe) } } + plane->disable_tiling = i9xx_disable_tiling; + modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_TILING_X); if (DISPLAY_VER(display) >= 5 || display->platform.g4x) @@ -1146,7 +1175,7 @@ i9xx_get_initial_plane_config(struct intel_crtc *crtc, drm_WARN_ON(display->drm, pipe != crtc->pipe); - intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); + intel_fb = intel_bo_alloc_framebuffer(); if (!intel_fb) { drm_dbg_kms(display->drm, "failed to alloc fb\n"); return; |