[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