163 lines
5.1 KiB
Diff
163 lines
5.1 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Fei Jiang <fei.jiang@intel.com>
|
|
Date: Fri, 14 Sep 2018 16:10:20 +0800
|
|
Subject: [PATCH] drm/i915/gvt: pvmmio optimization for plane update
|
|
|
|
It is performance optimization to reduce plane related register trap
|
|
counter. When update plane, multiple plane related registers are updated
|
|
together, optimize it to firstly cache all register values in share page,
|
|
then only PLANE_SURF register writing is trapped. Plane pvmmio level is
|
|
PVMMIO_PLANE_UPDATE.
|
|
Patch for both SOS and UOS.
|
|
|
|
V2: add memset tmp_plane to be more safer and add more commit description
|
|
|
|
Signed-off-by: Fei Jiang <fei.jiang@intel.com>
|
|
Reviewed-by: Min He <min.he@intel.com>
|
|
Reviewed-by: Zhao Yakui <yakui.zhao@intel.com>
|
|
---
|
|
drivers/gpu/drm/i915/i915_pvinfo.h | 27 +++++++++++-
|
|
drivers/gpu/drm/i915/intel_sprite.c | 68 +++++++++++++++++++++++++++++
|
|
2 files changed, 94 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/gpu/drm/i915/i915_pvinfo.h b/drivers/gpu/drm/i915/i915_pvinfo.h
|
|
index c1089bd..740b2da 100644
|
|
--- a/drivers/gpu/drm/i915/i915_pvinfo.h
|
|
+++ b/drivers/gpu/drm/i915/i915_pvinfo.h
|
|
@@ -49,13 +49,37 @@ enum vgt_g2v_type {
|
|
VGT_G2V_MAX,
|
|
};
|
|
|
|
+#define PLANE_COLOR_CTL_BIT (1 << 0)
|
|
+#define PLANE_KEY_BIT (1 << 1)
|
|
+#define PLANE_SCALER_BIT (1 << 2)
|
|
+
|
|
+struct pv_plane_update {
|
|
+ u32 flags;
|
|
+ u32 plane_color_ctl;
|
|
+ u32 plane_key_val;
|
|
+ u32 plane_key_max;
|
|
+ u32 plane_key_msk;
|
|
+ u32 plane_offset;
|
|
+ u32 plane_stride;
|
|
+ u32 plane_size;
|
|
+ u32 plane_aux_dist;
|
|
+ u32 plane_aux_offset;
|
|
+ u32 ps_ctrl;
|
|
+ u32 ps_pwr_gate;
|
|
+ u32 ps_win_ps;
|
|
+ u32 ps_win_sz;
|
|
+ u32 plane_pos;
|
|
+ u32 plane_ctl;
|
|
+};
|
|
+
|
|
/* shared page(4KB) between gvt and VM, located at the first page next
|
|
* to MMIO region(2MB size normally).
|
|
*/
|
|
struct gvt_shared_page {
|
|
u32 elsp_data[4];
|
|
u32 reg_addr;
|
|
- u32 rsvd2[0x400 - 5];
|
|
+ struct pv_plane_update pv_plane;
|
|
+ u32 rsvd2[0x400 - 21];
|
|
};
|
|
|
|
#define VGPU_PVMMIO(vgpu) vgpu_vreg_t(vgpu, vgtif_reg(enable_pvmmio))
|
|
@@ -65,6 +89,7 @@ struct gvt_shared_page {
|
|
*/
|
|
enum pvmmio_levels {
|
|
PVMMIO_ELSP_SUBMIT = 0x1,
|
|
+ PVMMIO_PLANE_UPDATE = 0x2,
|
|
};
|
|
|
|
/*
|
|
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
|
|
index 11b7afc..4b89ba3 100644
|
|
--- a/drivers/gpu/drm/i915/intel_sprite.c
|
|
+++ b/drivers/gpu/drm/i915/intel_sprite.c
|
|
@@ -232,6 +232,68 @@ void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
|
|
#endif
|
|
}
|
|
|
|
+static void pv_update_plane_reg(struct intel_plane *plane,
|
|
+ u32 stride, uint32_t src_w, uint32_t src_h,
|
|
+ uint32_t crtc_w, uint32_t crtc_h, u32 aux_stride,
|
|
+ const struct intel_crtc_state *crtc_state,
|
|
+ const struct intel_plane_state *plane_state)
|
|
+{
|
|
+ int i;
|
|
+ struct pv_plane_update tmp_plane;
|
|
+ uint32_t x = plane_state->main.x;
|
|
+ uint32_t y = plane_state->main.y;
|
|
+ struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
|
|
+ u32 __iomem *pv_plane = (u32 *)&(dev_priv->shared_page->pv_plane);
|
|
+
|
|
+ memset(&tmp_plane, 0, sizeof(struct pv_plane_update));
|
|
+ if (IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) {
|
|
+ tmp_plane.flags |= PLANE_COLOR_CTL_BIT;
|
|
+ tmp_plane.plane_color_ctl = PLANE_COLOR_PIPE_GAMMA_ENABLE |
|
|
+ PLANE_COLOR_PIPE_CSC_ENABLE |
|
|
+ PLANE_COLOR_PLANE_GAMMA_DISABLE;
|
|
+ }
|
|
+
|
|
+ if (plane_state->ckey.flags) {
|
|
+ tmp_plane.flags |= PLANE_KEY_BIT;
|
|
+ tmp_plane.plane_key_val = plane_state->ckey.min_value;
|
|
+ tmp_plane.plane_key_max = plane_state->ckey.max_value;
|
|
+ tmp_plane.plane_key_msk = plane_state->ckey.channel_mask;
|
|
+ }
|
|
+
|
|
+ tmp_plane.plane_offset = (y << 16) | x;
|
|
+ tmp_plane.plane_stride = stride;
|
|
+ tmp_plane.plane_size = (src_h << 16) | src_w;
|
|
+ tmp_plane.plane_aux_dist =
|
|
+ (plane_state->aux.offset - plane_state->main.offset) |
|
|
+ aux_stride;
|
|
+ tmp_plane.plane_aux_offset =
|
|
+ (plane_state->aux.y << 16) | plane_state->aux.x;
|
|
+
|
|
+ /* program plane scaler */
|
|
+ if (plane_state->scaler_id >= 0) {
|
|
+ tmp_plane.flags |= PLANE_SCALER_BIT;
|
|
+ tmp_plane.ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane->id) |
|
|
+ crtc_state->scaler_state.scalers[plane_state->scaler_id].mode;
|
|
+ tmp_plane.ps_pwr_gate = 0;
|
|
+ tmp_plane.ps_win_ps =
|
|
+ (plane_state->base.dst.x1 << 16) | plane_state->base.dst.y1;
|
|
+ tmp_plane.ps_win_sz = ((crtc_w + 1) << 16) | (crtc_h + 1);
|
|
+ tmp_plane.plane_pos = 0;
|
|
+ } else {
|
|
+ tmp_plane.plane_pos =
|
|
+ (plane_state->base.dst.y1 << 16) | plane_state->base.dst.x1;
|
|
+ }
|
|
+
|
|
+ tmp_plane.plane_ctl = plane_state->ctl;
|
|
+
|
|
+ spin_lock(&dev_priv->shared_page_lock);
|
|
+ for (i = 0; i < sizeof(struct pv_plane_update) / 4; i++)
|
|
+ writel(*((u32 *)(&tmp_plane) + i), pv_plane + i);
|
|
+ I915_WRITE_FW(PLANE_SURF(plane->pipe, plane->id),
|
|
+ intel_plane_ggtt_offset(plane_state) + plane_state->main.offset);
|
|
+ spin_unlock(&dev_priv->shared_page_lock);
|
|
+}
|
|
+
|
|
void
|
|
skl_update_plane(struct intel_plane *plane,
|
|
const struct intel_crtc_state *crtc_state,
|
|
@@ -268,6 +330,12 @@ skl_update_plane(struct intel_plane *plane,
|
|
crtc_w--;
|
|
crtc_h--;
|
|
|
|
+ if (PVMMIO_LEVEL(dev_priv, PVMMIO_PLANE_UPDATE)) {
|
|
+ pv_update_plane_reg(plane, stride, src_w, src_h,
|
|
+ crtc_w, crtc_h, aux_stride, crtc_state, plane_state);
|
|
+ return;
|
|
+ }
|
|
+
|
|
spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
|
|
|
|
if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
|
|
--
|
|
https://clearlinux.org
|
|
|