[PATCH v6 5/6] drm/i915/gvt: Deliver async primary plane page flip events at vblank

From: Tina Zhang
Date: Tue Sep 24 2019 - 02:43:32 EST


From: Kechen Lu <kechen.lu@xxxxxxxxx>

Only sync primary plane page flip events are checked and delivered
as the display refresh events before, this patch tries to deliver async
primary page flip events bounded by vblanks.

To deliver correct async page flip, the new async flip bitmap is
introduced and in vblank emulation handler to check bitset.

Signed-off-by: Kechen Lu <kechen.lu@xxxxxxxxx>
Signed-off-by: Tina Zhang <tina.zhang@xxxxxxxxx>
---
drivers/gpu/drm/i915/gvt/cmd_parser.c | 6 ++++--
drivers/gpu/drm/i915/gvt/display.c | 10 ++++++++++
drivers/gpu/drm/i915/gvt/gvt.h | 2 ++
drivers/gpu/drm/i915/gvt/handlers.c | 5 +++--
4 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index e753b1e706e2..1abb05431177 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -1365,9 +1365,11 @@ static int gen8_update_plane_mmio_from_mi_display_flip(
if (info->plane == PLANE_PRIMARY)
vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(info->pipe))++;

- if (info->async_flip)
+ if (info->async_flip) {
intel_vgpu_trigger_virtual_event(vgpu, info->event);
- else
+ set_bit(info->plane,
+ vgpu->display.async_flip_event[info->pipe]);
+ } else
set_bit(info->event, vgpu->irq.flip_done_event[info->pipe]);

return 0;
diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c
index 9f2c2cd10369..9acde0bdd5f4 100644
--- a/drivers/gpu/drm/i915/gvt/display.c
+++ b/drivers/gpu/drm/i915/gvt/display.c
@@ -419,6 +419,16 @@ static void emulate_vblank_on_pipe(struct intel_vgpu *vgpu, int pipe)
intel_vgpu_trigger_virtual_event(vgpu, event);
}

+ for_each_set_bit(event, vgpu->display.async_flip_event[pipe],
+ I915_MAX_PLANES) {
+ clear_bit(event, vgpu->display.async_flip_event[pipe]);
+ if (!pipe_is_enabled(vgpu, pipe))
+ continue;
+
+ if (event == PLANE_PRIMARY)
+ eventfd_signal_val |= DISPLAY_PRI_REFRESH_EVENT_VAL;
+ }
+
if (eventfd_signal_val)
vgpu->no_pageflip_count = 0;
else if (!eventfd_signal_val && vgpu->no_pageflip_count > PAGEFLIP_DELAY_THR)
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index cc39b449b061..73769a87b407 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -128,6 +128,8 @@ struct intel_vgpu_display {
struct intel_vgpu_i2c_edid i2c_edid;
struct intel_vgpu_port ports[I915_MAX_PORTS];
struct intel_vgpu_sbi sbi;
+ DECLARE_BITMAP(async_flip_event[I915_MAX_PIPES],
+ I915_MAX_PLANES);
};

struct vgpu_sched_ctl {
diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
index 45a9124e53b6..e5a022c2e7bb 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -760,9 +760,10 @@ static int pri_surf_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,

vgpu_vreg_t(vgpu, PIPE_FLIPCOUNT_G4X(pipe))++;

- if (vgpu_vreg_t(vgpu, DSPCNTR(pipe)) & PLANE_CTL_ASYNC_FLIP)
+ if (vgpu_vreg_t(vgpu, DSPCNTR(pipe)) & PLANE_CTL_ASYNC_FLIP) {
intel_vgpu_trigger_virtual_event(vgpu, event);
- else
+ set_bit(PLANE_PRIMARY, vgpu->display.async_flip_event[pipe]);
+ } else
set_bit(event, vgpu->irq.flip_done_event[pipe]);

return 0;
--
2.17.1