[Intel-gfx] [PATCH] drm/i915: Fix offset page-flips on i965+

Jesse Barnes jbarnes at virtuousgeek.org
Tue Aug 10 23:37:53 CEST 2010


On Sun,  8 Aug 2010 10:20:25 +0100
Chris Wilson <chris at chris-wilson.co.uk> wrote:

> i965 uses the Display Registers to compute the offset from the display
> base so the new base does not need adjusting when flipping. The older
> chipsets use a fence to access the display and so do perceive the
> surface as linear and have a single base register which is reprogrammed
> using the flip.

Mostly correct, we should get this in quickly to fix
https://bugs.freedesktop.org/show_bug.cgi?id=28518 (which is my fault;
I tested on 945 and assumed the fix applied to all future generations.
Of course I should have realized the hw guys like to keep us on our
toes so they keep changing register and command layouts on us).

Comments below.

> -	if (intel_crtc->plane)
> -		flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
> -	else
> -		flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
> -
>  	if (IS_GEN3(dev) || IS_GEN2(dev)) {
> +		u32 flip_mask;
> +
> +		if (intel_crtc->plane)
> +			flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
> +		else
> +			flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
> +
>  		BEGIN_LP_RING(2);
>  		OUT_RING(MI_WAIT_FOR_EVENT | flip_mask);
>  		OUT_RING(0);
> @@ -5092,28 +5092,36 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
>  	}

Nice cleanup.

>  
>  	/* Offset into the new buffer for cases of shared fbs between CRTCs */
> -	offset = obj_priv->gtt_offset;
> -	offset += (crtc->y * fb->pitch) + (crtc->x * (fb->bits_per_pixel) / 8);
> +	offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8;

Yep.

>  
>  	BEGIN_LP_RING(4);
>  	if (IS_I965G(dev)) {
> +		int pipe = intel_crtc->pipe;
> +		u32 pf, pipesrc;
> +
>  		OUT_RING(MI_DISPLAY_FLIP |
>  			 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
> -		OUT_RING(fb->pitch);
> -		OUT_RING(offset | obj_priv->tiling_mode);
> -		pipesrc = I915_READ(pipesrc_reg); 
> -		OUT_RING(pipesrc & 0x0fff0fff);
> +		OUT_RING(fb->pitch | obj_priv->tiling_mode);
> +		/* i965+ uses the linear or tiled offsets from the
> +		 * Display Registers (which do not change across a page-flip)
> +		 * so we need only reprogram the base address.
> +		 */
> +		OUT_RING(obj_priv->gtt_offset);
> +
> +		pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE;
> +		pipesrc = I915_READ(pipe == 0 ? PIPEASRC : PIPEBSRC) & 0x0fff0fff;
> +		OUT_RING(pf | pipesrc);

Should be
	OUT_RING(fb->pitch);
	OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
(as discussed on IRC the fields are documented incorrectly in some
places and the tiling param is required). Also I'm worried about the
panel fitting bits; I know ILK has more flexible panel fitting, but I'd
like to see this tested on 965 and GM45 with a non-native mode to be
sure these bits also work there.

>  	} else if (IS_GEN3(dev)) {
>  		OUT_RING(MI_DISPLAY_FLIP_I915 |
>  			 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
>  		OUT_RING(fb->pitch);
> -		OUT_RING(offset);
> +		OUT_RING(obj_priv->gtt_offset + offset);
>  		OUT_RING(MI_NOOP);
>  	} else {
>  		OUT_RING(MI_DISPLAY_FLIP |
>  			 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
>  		OUT_RING(fb->pitch);
> -		OUT_RING(offset);
> +		OUT_RING(obj_priv->gtt_offset + offset);
>  		OUT_RING(MI_NOOP);
>  	}
>  	ADVANCE_LP_RING();

These bits look good.

Thanks,
-- 
Jesse Barnes, Intel Open Source Technology Center



More information about the Intel-gfx mailing list