Skip to content

Commit 9eb0463

Browse files
vsyrjalarodrigovivi
authored andcommitted
drm/i915/fbc: Fix fence_y_offset handling
The current fence_y_offset calculation is broken. I think it more or less used to do the right thing, but then I changed the plane code to put the final x/y source offsets back into the src rectangle so now it's just subtraacting the same value from itself. The code would never have worked if we allowed the framebuffer to have a non-zero offset. Let's do this in a better way by just calculating the fence_y_offset from the final plane surface offset. Note that we don't align the plane surface address to fence rows so with horizontal panning there's often a horizontal offset from the fence start to the surface address as well. We have no way to tell the hardware about that so we just ignore it. Based on some quick tests the invlidation still happens correctly. I presume due to the invalidation nuking at least the full line (or a segment of multiple lines). Fixes: 54d4d71 ("drm/i915: Overcome display engine stride limits via GTT remapping") Signed-off-by: Ville Syrjälä <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Matt Roper <[email protected]> (cherry picked from commit 5331889) Signed-off-by: Rodrigo Vivi <[email protected]>
1 parent 7dfbf8a commit 9eb0463

File tree

4 files changed

+25
-25
lines changed

4 files changed

+25
-25
lines changed

drivers/gpu/drm/i915/display/intel_display.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3822,6 +3822,17 @@ skl_check_main_ccs_coordinates(struct intel_plane_state *plane_state,
38223822
return true;
38233823
}
38243824

3825+
unsigned int
3826+
intel_plane_fence_y_offset(const struct intel_plane_state *plane_state)
3827+
{
3828+
int x = 0, y = 0;
3829+
3830+
intel_plane_adjust_aligned_offset(&x, &y, plane_state, 0,
3831+
plane_state->color_plane[0].offset, 0);
3832+
3833+
return y;
3834+
}
3835+
38253836
static int skl_check_main_surface(struct intel_plane_state *plane_state)
38263837
{
38273838
struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);

drivers/gpu/drm/i915/display/intel_display.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,7 @@ unsigned int i9xx_plane_max_stride(struct intel_plane *plane,
608608
u32 pixel_format, u64 modifier,
609609
unsigned int rotation);
610610
int bdw_get_pipemisc_bpp(struct intel_crtc *crtc);
611+
unsigned int intel_plane_fence_y_offset(const struct intel_plane_state *plane_state);
611612

612613
struct intel_display_error_state *
613614
intel_display_capture_error_state(struct drm_i915_private *dev_priv);

drivers/gpu/drm/i915/display/intel_fbc.c

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,6 @@
4747
#include "intel_fbc.h"
4848
#include "intel_frontbuffer.h"
4949

50-
/*
51-
* In some platforms where the CRTC's x:0/y:0 coordinates doesn't match the
52-
* frontbuffer's x:0/y:0 coordinates we lie to the hardware about the plane's
53-
* origin so the x and y offsets can actually fit the registers. As a
54-
* consequence, the fence doesn't really start exactly at the display plane
55-
* address we program because it starts at the real start of the buffer, so we
56-
* have to take this into consideration here.
57-
*/
58-
static unsigned int get_crtc_fence_y_offset(struct intel_fbc *fbc)
59-
{
60-
return fbc->state_cache.plane.y - fbc->state_cache.plane.adjusted_y;
61-
}
62-
6350
/*
6451
* For SKL+, the plane source size used by the hardware is based on the value we
6552
* write to the PLANE_SIZE register. For BDW-, the hardware looks at the value
@@ -141,7 +128,7 @@ static void i8xx_fbc_activate(struct drm_i915_private *dev_priv)
141128
fbc_ctl2 |= FBC_CTL_CPU_FENCE;
142129
intel_de_write(dev_priv, FBC_CONTROL2, fbc_ctl2);
143130
intel_de_write(dev_priv, FBC_FENCE_OFF,
144-
params->crtc.fence_y_offset);
131+
params->fence_y_offset);
145132
}
146133

147134
/* enable it... */
@@ -175,7 +162,7 @@ static void g4x_fbc_activate(struct drm_i915_private *dev_priv)
175162
if (params->fence_id >= 0) {
176163
dpfc_ctl |= DPFC_CTL_FENCE_EN | params->fence_id;
177164
intel_de_write(dev_priv, DPFC_FENCE_YOFF,
178-
params->crtc.fence_y_offset);
165+
params->fence_y_offset);
179166
} else {
180167
intel_de_write(dev_priv, DPFC_FENCE_YOFF, 0);
181168
}
@@ -243,7 +230,7 @@ static void ilk_fbc_activate(struct drm_i915_private *dev_priv)
243230
intel_de_write(dev_priv, SNB_DPFC_CTL_SA,
244231
SNB_CPU_FENCE_ENABLE | params->fence_id);
245232
intel_de_write(dev_priv, DPFC_CPU_FENCE_OFFSET,
246-
params->crtc.fence_y_offset);
233+
params->fence_y_offset);
247234
}
248235
} else {
249236
if (IS_GEN(dev_priv, 6)) {
@@ -253,7 +240,7 @@ static void ilk_fbc_activate(struct drm_i915_private *dev_priv)
253240
}
254241

255242
intel_de_write(dev_priv, ILK_DPFC_FENCE_YOFF,
256-
params->crtc.fence_y_offset);
243+
params->fence_y_offset);
257244
/* enable it... */
258245
intel_de_write(dev_priv, ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN);
259246

@@ -320,7 +307,7 @@ static void gen7_fbc_activate(struct drm_i915_private *dev_priv)
320307
intel_de_write(dev_priv, SNB_DPFC_CTL_SA,
321308
SNB_CPU_FENCE_ENABLE | params->fence_id);
322309
intel_de_write(dev_priv, DPFC_CPU_FENCE_OFFSET,
323-
params->crtc.fence_y_offset);
310+
params->fence_y_offset);
324311
} else if (dev_priv->ggtt.num_fences) {
325312
intel_de_write(dev_priv, SNB_DPFC_CTL_SA, 0);
326313
intel_de_write(dev_priv, DPFC_CPU_FENCE_OFFSET, 0);
@@ -631,8 +618,8 @@ static bool rotation_is_valid(struct drm_i915_private *dev_priv,
631618
/*
632619
* For some reason, the hardware tracking starts looking at whatever we
633620
* programmed as the display plane base address register. It does not look at
634-
* the X and Y offset registers. That's why we look at the crtc->adjusted{x,y}
635-
* variables instead of just looking at the pipe/plane size.
621+
* the X and Y offset registers. That's why we include the src x/y offsets
622+
* instead of just looking at the plane size.
636623
*/
637624
static bool intel_fbc_hw_tracking_covers_screen(struct intel_crtc *crtc)
638625
{
@@ -705,14 +692,15 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
705692
cache->plane.src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
706693
cache->plane.adjusted_x = plane_state->color_plane[0].x;
707694
cache->plane.adjusted_y = plane_state->color_plane[0].y;
708-
cache->plane.y = plane_state->uapi.src.y1 >> 16;
709695

710696
cache->plane.pixel_blend_mode = plane_state->hw.pixel_blend_mode;
711697

712698
cache->fb.format = fb->format;
713699
cache->fb.stride = fb->pitches[0];
714700
cache->fb.modifier = fb->modifier;
715701

702+
cache->fence_y_offset = intel_plane_fence_y_offset(plane_state);
703+
716704
drm_WARN_ON(&dev_priv->drm, plane_state->flags & PLANE_HAS_FENCE &&
717705
!plane_state->vma->fence);
718706

@@ -883,10 +871,10 @@ static void intel_fbc_get_reg_params(struct intel_crtc *crtc,
883871
memset(params, 0, sizeof(*params));
884872

885873
params->fence_id = cache->fence_id;
874+
params->fence_y_offset = cache->fence_y_offset;
886875

887876
params->crtc.pipe = crtc->pipe;
888877
params->crtc.i9xx_plane = to_intel_plane(crtc->base.primary)->i9xx_plane;
889-
params->crtc.fence_y_offset = get_crtc_fence_y_offset(fbc);
890878

891879
params->fb.format = cache->fb.format;
892880
params->fb.stride = cache->fb.stride;

drivers/gpu/drm/i915/i915_drv.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,6 @@ struct intel_fbc {
410410
int adjusted_x;
411411
int adjusted_y;
412412

413-
int y;
414-
415413
u16 pixel_blend_mode;
416414
} plane;
417415

@@ -420,6 +418,8 @@ struct intel_fbc {
420418
unsigned int stride;
421419
u64 modifier;
422420
} fb;
421+
422+
unsigned int fence_y_offset;
423423
u16 gen9_wa_cfb_stride;
424424
s8 fence_id;
425425
} state_cache;
@@ -435,7 +435,6 @@ struct intel_fbc {
435435
struct {
436436
enum pipe pipe;
437437
enum i9xx_plane_id i9xx_plane;
438-
unsigned int fence_y_offset;
439438
} crtc;
440439

441440
struct {
@@ -444,6 +443,7 @@ struct intel_fbc {
444443
} fb;
445444

446445
int cfb_size;
446+
unsigned int fence_y_offset;
447447
u16 gen9_wa_cfb_stride;
448448
s8 fence_id;
449449
bool plane_visible;

0 commit comments

Comments
 (0)