diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_sprite.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_sprite.c | 74 |
1 files changed, 65 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_sprite.c b/drivers/gpu/drm/i915/display/intel_sprite.c index 63040cb0d4e1..b6deeb338477 100644 --- a/drivers/gpu/drm/i915/display/intel_sprite.c +++ b/drivers/gpu/drm/i915/display/intel_sprite.c @@ -47,6 +47,7 @@ #include "intel_frontbuffer.h" #include "intel_pm.h" #include "intel_psr.h" +#include "intel_dsi.h" #include "intel_sprite.h" int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, @@ -93,6 +94,9 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state) DEFINE_WAIT(wait); u32 psr_status; + if (new_crtc_state->uapi.async_flip) + return; + vblank_start = adjusted_mode->crtc_vblank_start; if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) vblank_start = DIV_ROUND_UP(vblank_start, 2); @@ -200,8 +204,19 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state) ktime_t end_vbl_time = ktime_get(); struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + if (new_crtc_state->uapi.async_flip) + return; + trace_intel_pipe_update_end(crtc, end_vbl_count, scanline_end); + /* + * Incase of mipi dsi command mode, we need to set frame update + * request for every commit. + */ + if (INTEL_GEN(dev_priv) >= 11 && + intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI)) + icl_dsi_frame_update(new_crtc_state); + /* We're still in the vblank-evade critical section, this can't race. * Would be slightly nice to just grab the vblank count and arm the * event outside of the critical section - the spinlock might spin for a @@ -429,6 +444,7 @@ skl_program_scaler(struct intel_plane *plane, u16 y_hphase, uv_rgb_hphase; u16 y_vphase, uv_rgb_vphase; int hscale, vscale; + u32 ps_ctrl; hscale = drm_rect_calc_hscale(&plane_state->uapi.src, &plane_state->uapi.dst, @@ -455,8 +471,13 @@ skl_program_scaler(struct intel_plane *plane, uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false); } - intel_de_write_fw(dev_priv, SKL_PS_CTRL(pipe, scaler_id), - PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode); + ps_ctrl = skl_scaler_get_filter_select(plane_state->hw.scaling_filter, 0); + ps_ctrl |= PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode; + + skl_scaler_setup_filter(dev_priv, pipe, scaler_id, 0, + plane_state->hw.scaling_filter); + + intel_de_write_fw(dev_priv, SKL_PS_CTRL(pipe, scaler_id), ps_ctrl); intel_de_write_fw(dev_priv, SKL_PS_VPHASE(pipe, scaler_id), PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase)); intel_de_write_fw(dev_priv, SKL_PS_HPHASE(pipe, scaler_id), @@ -604,6 +625,29 @@ icl_program_input_csc(struct intel_plane *plane, } static void +skl_plane_async_flip(struct intel_plane *plane, + const struct intel_crtc_state *crtc_state, + const struct intel_plane_state *plane_state) +{ + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); + unsigned long irqflags; + enum plane_id plane_id = plane->id; + enum pipe pipe = plane->pipe; + u32 surf_addr = plane_state->color_plane[0].offset; + u32 plane_ctl = plane_state->ctl; + + plane_ctl |= skl_plane_ctl_crtc(crtc_state); + + spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); + + intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl); + intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), + intel_plane_ggtt_offset(plane_state) + surf_addr); + + spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags); +} + +static void skl_program_plane(struct intel_plane *plane, const struct intel_crtc_state *crtc_state, const struct intel_plane_state *plane_state, @@ -617,8 +661,6 @@ skl_program_plane(struct intel_plane *plane, u32 stride = skl_plane_stride(plane_state, color_plane); const struct drm_framebuffer *fb = plane_state->hw.fb; int aux_plane = intel_main_to_aux_plane(fb, color_plane); - u32 aux_dist = plane_state->color_plane[aux_plane].offset - surf_addr; - u32 aux_stride = skl_plane_stride(plane_state, aux_plane); int crtc_x = plane_state->uapi.dst.x1; int crtc_y = plane_state->uapi.dst.y1; u32 x = plane_state->color_plane[color_plane].x; @@ -626,7 +668,7 @@ skl_program_plane(struct intel_plane *plane, u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16; u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16; u8 alpha = plane_state->hw.alpha >> 8; - u32 plane_color_ctl = 0; + u32 plane_color_ctl = 0, aux_dist = 0; unsigned long irqflags; u32 keymsk, keymax; u32 plane_ctl = plane_state->ctl; @@ -653,6 +695,13 @@ skl_program_plane(struct intel_plane *plane, crtc_y = 0; } + if (aux_plane) { + aux_dist = plane_state->color_plane[aux_plane].offset - surf_addr; + + if (INTEL_GEN(dev_priv) < 12) + aux_dist |= skl_plane_stride(plane_state, aux_plane); + } + spin_lock_irqsave(&dev_priv->uncore.lock, irqflags); intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id), stride); @@ -661,8 +710,6 @@ skl_program_plane(struct intel_plane *plane, intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w); - if (INTEL_GEN(dev_priv) < 12) - aux_dist |= aux_stride; intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id), aux_dist); if (icl_is_hdr_plane(dev_priv, plane_id)) @@ -690,6 +737,9 @@ skl_program_plane(struct intel_plane *plane, intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id), (plane_state->color_plane[1].y << 16) | plane_state->color_plane[1].x); + if (!drm_atomic_crtc_needs_modeset(&crtc_state->uapi)) + intel_psr2_program_plane_sel_fetch(plane, crtc_state, plane_state, color_plane); + /* * The control register self-arms if the plane was previously * disabled. Try to make the plane enable atomic by writing @@ -2842,8 +2892,8 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane, static bool gen12_plane_supports_mc_ccs(struct drm_i915_private *dev_priv, enum plane_id plane_id) { - /* Wa_14010477008:tgl[a0..c0],rkl[all] */ - if (IS_ROCKETLAKE(dev_priv) || + /* Wa_14010477008:tgl[a0..c0],rkl[all],dg1[all] */ + if (IS_DG1(dev_priv) || IS_ROCKETLAKE(dev_priv) || IS_TGL_DISP_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_C0)) return false; @@ -3089,6 +3139,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, plane->get_hw_state = skl_plane_get_hw_state; plane->check_plane = skl_plane_check; plane->min_cdclk = skl_plane_min_cdclk; + plane->async_flip = skl_plane_async_flip; if (INTEL_GEN(dev_priv) >= 11) formats = icl_get_plane_formats(dev_priv, pipe, @@ -3160,6 +3211,11 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, if (INTEL_GEN(dev_priv) >= 12) drm_plane_enable_fb_damage_clips(&plane->base); + if (INTEL_GEN(dev_priv) >= 10) + drm_plane_create_scaling_filter_property(&plane->base, + BIT(DRM_SCALING_FILTER_DEFAULT) | + BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR)); + drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); return plane; |