clear-pkgs-linux-iot-lts2018/0605-drm-i915-gvt-pvmmio-op...

163 lines
5.2 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 c1089bdedd2e..740b2da14186 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 11b7afc0a0d3..4b89ba3e021c 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