diff options
author | Colin Xu <colin.xu@intel.com> | 2021-02-26 07:46:30 +0300 |
---|---|---|
committer | Zhenyu Wang <zhenyuw@linux.intel.com> | 2021-03-01 08:52:46 +0300 |
commit | b01739fb865a268aec617f6bb5d2ef498da72697 (patch) | |
tree | c0f6253c305942375c6874c8650ec5b550ff9f84 /drivers/gpu/drm/i915/gvt/gvt.h | |
parent | 6a4500c7b83f9e4470dd20cf89f691abd132d090 (diff) | |
download | linux-b01739fb865a268aec617f6bb5d2ef498da72697.tar.xz |
drm/i915/gvt: Refactor GVT vblank emulator for vGPU virtual display
Current vblank emulator uses single hrtimer at 16ms period for all vGPUs,
which introduces three major issues:
- 16ms matches the refresh rate at 62.5Hz (instead of 60Hz) which
doesn't follow standard timing. This leads to some frame drop or glitch
issue during video playback. SW expects a vsync interval of 16.667ms or
higher precision for an accurate 60Hz refresh rate. However current
vblank emulator only works at 16ms.
- Doesn't respect the fact that with current virtual EDID timing set,
not all resolutions are running at 60Hz. For example, current virtual
EDID also supports refresh rate at 56Hz, 59.97Hz, 60Hz, 75Hz, etc.
- Current vblank emulator use single hrtimer for all vGPUs. Regardsless
the possibility that different guests could run in different
resolutions, all vsync interrupts are injected at 16ms interval with
same hrtimer.
Based on previous patch which decode guest expected refresh rate from
vreg, the vblank emulator refactor patch makes following changes:
- Change the vblank emulator hrtimer from gvt global to per-vGPU.
By doing this, each vGPU display can operates at different refresh
rates. Currently only one dislay is supported for each vGPU so per-vGPU
hrtimer is enough. If multiple displays are supported per-vGPU in
future, we can expand to per-PIPE further.
- Change the fixed hrtimer period from 16ms to dynamic based on vreg.
GVT is expected to emulate the HW as close as possible. So reflacting
the accurate vsync interrupt interval is more correct than fixed 16ms.
- Change the vblank timer period and start the timer on PIPECONF change.
The initial period is updated to 16666667 based on 60Hz refresh rate.
According to PRM, PIPECONF controls the timing generator of the
connected display on this pipe, so it's safe to stop hrtimer on
PIPECONF disabling, and re-start hrtimer at new period on enabling.
Other changes including:
- Move vblank_timer_fn from irq.c into display.c.
- Clean per-vGPU vblank timer at clean_display instead of clean_irq.
To run quick test, launch a web browser and goto URL: www.displayhz.com
The actual refresh rate from guest can now always match guest settings.
V2:
Rebase to 5.11.
Remove unused intel_gvt_clean_irq().
Simplify enable logic in update_vblank_emulation(). (zhenyu)
Loop all vGPU by idr when check all vblank timer. (zhenyu)
Signed-off-by: Colin Xu <colin.xu@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20210226044630.284269-1-colin.xu@intel.com
Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/gvt/gvt.h')
-rw-r--r-- | drivers/gpu/drm/i915/gvt/gvt.h | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index a0f54ff55695..62b6faeb7ec0 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -215,6 +215,7 @@ struct intel_vgpu { struct list_head dmabuf_obj_list_head; struct mutex dmabuf_lock; struct idr object_idr; + struct intel_vgpu_vblank_timer vblank_timer; u32 scan_nonprivbb; }; @@ -344,13 +345,16 @@ static inline struct intel_gvt *to_gvt(struct drm_i915_private *i915) } enum { - INTEL_GVT_REQUEST_EMULATE_VBLANK = 0, - /* Scheduling trigger by timer */ - INTEL_GVT_REQUEST_SCHED = 1, + INTEL_GVT_REQUEST_SCHED = 0, /* Scheduling trigger by event */ - INTEL_GVT_REQUEST_EVENT_SCHED = 2, + INTEL_GVT_REQUEST_EVENT_SCHED = 1, + + /* per-vGPU vblank emulation request */ + INTEL_GVT_REQUEST_EMULATE_VBLANK = 2, + INTEL_GVT_REQUEST_EMULATE_VBLANK_MAX = INTEL_GVT_REQUEST_EMULATE_VBLANK + + GVT_MAX_VGPU, }; static inline void intel_gvt_request_service(struct intel_gvt *gvt, |