[PATCH 3/3] drm/i915/gvt: Enable async flip on plane surface mmio writes

Zhenyu Wang zhenyuw at linux.intel.com
Fri Mar 22 06:45:58 UTC 2019


On 2019.03.20 14:45:21 +0800, Colin Xu wrote:
> According to Intel GFX PRM on 01.org, plane surface address can be updated
> synchronously or asynchronously. Synchronous flip will hold plane surface
> address update to start of next vsync, which is current implementation.
> Asynchronous flip will update the address as soon as possible. Without
> async flip, some 3D application could not reach better performance and
> the maximum performance is no higher than vsync frequency.
> 
> The patch enables the async flip on plane surface address mmio update,
> and increment flip count correctly.
> 
> With async flip enabled, some 3D applications have significant performance
> improvement. i.e. 3DMark Ice Storm has a 300%~400% increment on score.
> 
> Signed-off-by: Colin Xu <colin.xu at intel.com>
> ---
>  drivers/gpu/drm/i915/gvt/display.c  |  1 -
>  drivers/gpu/drm/i915/gvt/handlers.c | 99 +++++++++++++++++++++++------
>  2 files changed, 81 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c
> index e3f9caa7839f..e1c313da6c00 100644
> --- a/drivers/gpu/drm/i915/gvt/display.c
> +++ b/drivers/gpu/drm/i915/gvt/display.c
> @@ -407,7 +407,6 @@ static void emulate_vblank_on_pipe(struct intel_vgpu *vgpu, int pipe)
>  		if (!pipe_is_enabled(vgpu, pipe))
>  			continue;
>  
> -		vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(pipe))++;
>  		intel_vgpu_trigger_virtual_event(vgpu, event);
>  	}
>  
> diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
> index 63418c81ef14..8f3a5a01ab7a 100644
> --- a/drivers/gpu/drm/i915/gvt/handlers.c
> +++ b/drivers/gpu/drm/i915/gvt/handlers.c
> @@ -750,18 +750,26 @@ static int pri_surf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
>  		void *p_data, unsigned int bytes)
>  {
>  	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
> -	unsigned int index = DSPSURF_TO_PIPE(offset);
> -	i915_reg_t surflive_reg = DSPSURFLIVE(index);
> -	int flip_event[] = {
> -		[PIPE_A] = PRIMARY_A_FLIP_DONE,
> -		[PIPE_B] = PRIMARY_B_FLIP_DONE,
> -		[PIPE_C] = PRIMARY_C_FLIP_DONE,
> -	};
> +	u32 pipe = DSPSURF_TO_PIPE(offset);
> +	int event = 0;
> +
> +	if (pipe == INVALID_PIPE || pipe > PIPE_C) {
> +		gvt_vgpu_err("Unsupported pipe-%d for PLANE_PRIMARY!\n", pipe);
> +		return 0;
> +	}
> +
> +	event = SKL_FLIP_EVENT(pipe, PLANE_PRIMARY);
>  
>  	write_vreg(vgpu, offset, p_data, bytes);
> -	vgpu_vreg_t(vgpu, surflive_reg) = vgpu_vreg(vgpu, offset);
> +	vgpu_vreg_t(vgpu, DSPSURFLIVE(pipe)) = vgpu_vreg(vgpu, offset);
> +
> +	vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(pipe))++;
> +
> +	if (vgpu_vreg_t(vgpu, DSPCNTR(pipe)) & 0x200)

Could we add flip mode bit definition instead of open code like this?

> +		intel_vgpu_trigger_virtual_event(vgpu, event);
> +	else
> +		set_bit(event, vgpu->irq.flip_done_event[pipe]);
>  
> -	set_bit(flip_event[index], vgpu->irq.flip_done_event[index]);
>  	return 0;
>  }
>  
> @@ -771,18 +779,61 @@ static int pri_surf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
>  static int spr_surf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
>  		void *p_data, unsigned int bytes)
>  {
> -	unsigned int index = SPRSURF_TO_PIPE(offset);
> -	i915_reg_t surflive_reg = SPRSURFLIVE(index);
> -	int flip_event[] = {
> -		[PIPE_A] = SPRITE_A_FLIP_DONE,
> -		[PIPE_B] = SPRITE_B_FLIP_DONE,
> -		[PIPE_C] = SPRITE_C_FLIP_DONE,
> -	};
> +	u32 pipe = SPRSURF_TO_PIPE(offset);
> +	int event = 0;
> +
> +	if (pipe == INVALID_PIPE || pipe > PIPE_C) {
> +		gvt_vgpu_err("Unsupported pipe-%d for PLANE_SPRITE0!\n", pipe);
> +		return 0;
> +	}
> +
> +	event = SKL_FLIP_EVENT(pipe, PLANE_SPRITE0);
> +
> +	write_vreg(vgpu, offset, p_data, bytes);
> +	vgpu_vreg_t(vgpu, SPRSURFLIVE(pipe)) = vgpu_vreg(vgpu, offset);
> +
> +	if (vgpu_vreg_t(vgpu, SPRCTL(pipe)) & 0x200)

ditto

> +		intel_vgpu_trigger_virtual_event(vgpu, event);
> +	else
> +		set_bit(event, vgpu->irq.flip_done_event[pipe]);
> +
> +	return 0;
> +}
> +
> +static int reg50080_mmio_write(struct intel_vgpu *vgpu,
> +			       unsigned int offset, void *p_data,
> +			       unsigned int bytes)
> +{
> +	struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
> +	enum pipe pipe = REG_50080_TO_PIPE(offset);
> +	enum plane_id plane = REG_50080_TO_PLANE(offset);
> +	int event = 0;
> +
> +	if (plane != PLANE_PRIMARY && plane != PLANE_SPRITE0) {
> +		gvt_vgpu_err("Unsupported plane-%d!\n", plane);
> +		return 0;
> +	}
> +
> +	if (pipe == INVALID_PIPE || pipe > PIPE_C) {
> +		gvt_vgpu_err("Unsupported pipe-%d for plane-%d!\n", pipe, plane);
> +		return 0;
> +	}
> +
> +	event = SKL_FLIP_EVENT(pipe, plane);
>  
>  	write_vreg(vgpu, offset, p_data, bytes);
> -	vgpu_vreg_t(vgpu, surflive_reg) = vgpu_vreg(vgpu, offset);
> +	if (plane == PLANE_PRIMARY) {
> +		vgpu_vreg_t(vgpu, DSPSURFLIVE(pipe)) = vgpu_vreg(vgpu, offset);
> +		vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(pipe))++;
> +	} else {
> +		vgpu_vreg_t(vgpu, SPRSURFLIVE(pipe)) = vgpu_vreg(vgpu, offset);
> +	}
> +
> +	if ((vgpu_vreg(vgpu, offset) & 0x3) == 1)

and this

> +		intel_vgpu_trigger_virtual_event(vgpu, event);
> +	else
> +		set_bit(event, vgpu->irq.flip_done_event[pipe]);
>  
> -	set_bit(flip_event[index], vgpu->irq.flip_done_event[index]);
>  	return 0;
>  }
>  
> @@ -1969,6 +2020,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
>  	MMIO_DH(DSPSURF(PIPE_A), D_ALL, NULL, pri_surf_mmio_write);
>  	MMIO_D(DSPOFFSET(PIPE_A), D_ALL);
>  	MMIO_D(DSPSURFLIVE(PIPE_A), D_ALL);
> +	MMIO_DH(REG_50080(PIPE_A, PLANE_PRIMARY), D_ALL, NULL,
> +		reg50080_mmio_write);
>  
>  	MMIO_D(DSPCNTR(PIPE_B), D_ALL);
>  	MMIO_D(DSPADDR(PIPE_B), D_ALL);
> @@ -1978,6 +2031,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
>  	MMIO_DH(DSPSURF(PIPE_B), D_ALL, NULL, pri_surf_mmio_write);
>  	MMIO_D(DSPOFFSET(PIPE_B), D_ALL);
>  	MMIO_D(DSPSURFLIVE(PIPE_B), D_ALL);
> +	MMIO_DH(REG_50080(PIPE_B, PLANE_PRIMARY), D_ALL, NULL,
> +		reg50080_mmio_write);
>  
>  	MMIO_D(DSPCNTR(PIPE_C), D_ALL);
>  	MMIO_D(DSPADDR(PIPE_C), D_ALL);
> @@ -1987,6 +2042,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
>  	MMIO_DH(DSPSURF(PIPE_C), D_ALL, NULL, pri_surf_mmio_write);
>  	MMIO_D(DSPOFFSET(PIPE_C), D_ALL);
>  	MMIO_D(DSPSURFLIVE(PIPE_C), D_ALL);
> +	MMIO_DH(REG_50080(PIPE_C, PLANE_PRIMARY), D_ALL, NULL,
> +		reg50080_mmio_write);
>  
>  	MMIO_D(SPRCTL(PIPE_A), D_ALL);
>  	MMIO_D(SPRLINOFF(PIPE_A), D_ALL);
> @@ -2000,6 +2057,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
>  	MMIO_D(SPROFFSET(PIPE_A), D_ALL);
>  	MMIO_D(SPRSCALE(PIPE_A), D_ALL);
>  	MMIO_D(SPRSURFLIVE(PIPE_A), D_ALL);
> +	MMIO_DH(REG_50080(PIPE_A, PLANE_SPRITE0), D_ALL, NULL,
> +		reg50080_mmio_write);
>  
>  	MMIO_D(SPRCTL(PIPE_B), D_ALL);
>  	MMIO_D(SPRLINOFF(PIPE_B), D_ALL);
> @@ -2013,6 +2072,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
>  	MMIO_D(SPROFFSET(PIPE_B), D_ALL);
>  	MMIO_D(SPRSCALE(PIPE_B), D_ALL);
>  	MMIO_D(SPRSURFLIVE(PIPE_B), D_ALL);
> +	MMIO_DH(REG_50080(PIPE_B, PLANE_SPRITE0), D_ALL, NULL,
> +		reg50080_mmio_write);
>  
>  	MMIO_D(SPRCTL(PIPE_C), D_ALL);
>  	MMIO_D(SPRLINOFF(PIPE_C), D_ALL);
> @@ -2026,6 +2087,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
>  	MMIO_D(SPROFFSET(PIPE_C), D_ALL);
>  	MMIO_D(SPRSCALE(PIPE_C), D_ALL);
>  	MMIO_D(SPRSURFLIVE(PIPE_C), D_ALL);
> +	MMIO_DH(REG_50080(PIPE_C, PLANE_SPRITE0), D_ALL, NULL,
> +		reg50080_mmio_write);
>  
>  	MMIO_D(HTOTAL(TRANSCODER_A), D_ALL);
>  	MMIO_D(HBLANK(TRANSCODER_A), D_ALL);
> -- 
> 2.21.0
> 
> _______________________________________________
> intel-gvt-dev mailing list
> intel-gvt-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gvt-dev

-- 
Open Source Technology Center, Intel ltd.

$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/intel-gvt-dev/attachments/20190322/770d178d/attachment.sig>


More information about the intel-gvt-dev mailing list