[Intel-gfx] [RFC 20/29] drm/i915: gvt: vGPU framebuffer format decoder

Zhi Wang zhi.a.wang at intel.com
Thu Jan 28 02:21:42 PST 2016


From: Niu Bing <bing.niu at intel.com>

GVT-g supports an indirect display mode by mapping guest display framebuffer
into host graphics memory space as a GEM object, so that host windows system
/ GL can easily manipulate it like a common GEM object.

For example, use an EGL extension to wrap a guest framebuffer GEM object into
an EGL image, or just use i915 MMAP_GTT ioctl to map it into host aperture,
so that userspace application can easily use them.

To create this special GEM object, GVT-g has to know the surface format of
guest framebuffer, like RGB/NV12, stride, tiling format. vGPU framebuffer
format decoder will extract these information from guest virtual plane
registers and expose them to GVT GEM object logics.

Signed-off-by: Bing Niu <bing.niu at intel.com>
---
 drivers/gpu/drm/i915/gvt/Makefile     |   3 +-
 drivers/gpu/drm/i915/gvt/fb_decoder.c | 295 ++++++++++++++++++++++++-
 drivers/gpu/drm/i915/gvt/gvt.h        |   1 +
 drivers/gpu/drm/i915/gvt/reg.h        | 404 ++++++++++++++++++++++++++++++++++
 4 files changed, 700 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile
index 8f59bbc..b0a3a1a 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,5 +1,6 @@
 GVT_SOURCE := gvt.o params.o aperture_gm.o mmio.o handlers.o instance.o \
-		trace_points.o interrupt.o gtt.o cfg_space.o opregion.o utility.o fb_decoder.o
+		trace_points.o interrupt.o gtt.o cfg_space.o opregion.o utility.o \
+		fb_decoder.o
 
 ccflags-y			+= -I$(src) -I$(src)/.. -Wall -Werror -Wno-unused-function
 i915_gvt-y			:= $(GVT_SOURCE)
diff --git a/drivers/gpu/drm/i915/gvt/fb_decoder.c b/drivers/gpu/drm/i915/gvt/fb_decoder.c
index a219819..dfb8cb3 100644
--- a/drivers/gpu/drm/i915/gvt/fb_decoder.c
+++ b/drivers/gpu/drm/i915/gvt/fb_decoder.c
@@ -23,12 +23,303 @@
 
 #include "gvt.h"
 
-int gvt_decode_fb_format(struct pgt_device *pdev, int vmid, struct gvt_fb_format *fb)
+#define FORMAT_NUM	16
+struct pixel_format {
+	int	drm_format;	/* Pixel format in DRM definition */
+	int	bpp;		/* Bits per pixel, 0 indicates invalid */
+	char	*desc;		/* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format primary_pixel_formats[FORMAT_NUM] = {
+	[0b0010]  = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+	[0b0101]  = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+	[0b0110]  = {DRM_FORMAT_XRGB8888, 32, "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
+	[0b1000]  = {DRM_FORMAT_XBGR2101010, 32, "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
+	[0b1010] = {DRM_FORMAT_XRGB2101010, 32, "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"},
+	[0b1110] = {DRM_FORMAT_XBGR8888, 32, "32-bit RGBX (8:8:8:8 MSB-X:B:G:R)"},
+};
+
+/* non-supported format has bpp default to 0 */
+static struct pixel_format skl_pixel_formats[FORMAT_NUM] = {
+	[0b1100]  = {DRM_FORMAT_C8, 8, "8-bit Indexed"},
+	[0b1110]  = {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
+	[0b0100]  = {DRM_FORMAT_XRGB8888, 32, "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
+	[0b1010]  = {DRM_FORMAT_XRGB2101010, 32, "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"},
+};
+
+static ATOMIC_NOTIFIER_HEAD(gvt_fb_notifier_list);
+
+int gvt_decode_primary_plane_format(struct vgt_device *vgt,
+	int pipe, struct gvt_primary_plane_format *plane)
 {
+	u32	val, fmt;
+	struct drm_device *dev = vgt->pdev->dev_priv->dev;
+
+	val = __vreg(vgt, GVT_DSPCNTR(pipe));
+	plane->enabled = !!(val & DISPLAY_PLANE_ENABLE);
+	if (!plane->enabled)
+		return 0;
+
+	if (IS_SKYLAKE(dev)) {
+		plane->tiled = !!(val & PLANE_CTL_TILED_MASK);
+		fmt = (val & PLANE_CTL_FORMAT_MASK) >> 24;
+	} else {
+		plane->tiled = !!(val & DISPPLANE_TILED);
+		fmt = (val & DISPPLANE_PIXFORMAT_MASK) >> _PRI_PLANE_FMT_SHIFT;
+	}
+
+	if ((IS_SKYLAKE(dev) && !skl_pixel_formats[fmt].bpp)
+			|| (!IS_SKYLAKE(dev) && !primary_pixel_formats[fmt].bpp)) {
+		gvt_err("Non-supported pixel format (0x%x)\n", fmt);
+		return -EINVAL;
+	}
+
+	plane->hw_format = fmt;
+	plane->bpp = primary_pixel_formats[fmt].bpp;
+	plane->drm_format = primary_pixel_formats[fmt].drm_format;
+
+	plane->base = __vreg(vgt, GVT_DSPSURF(pipe)) & GTT_PAGE_MASK;
+	plane->stride = __vreg(vgt, GVT_DSPSTRIDE(pipe)) &
+		_PRI_PLANE_STRIDE_MASK;
+	plane->width = (__vreg(vgt, GVT_PIPESRC(pipe)) & _PIPE_H_SRCSZ_MASK) >>
+		_PIPE_H_SRCSZ_SHIFT;
+	plane->width += 1;
+	plane->height = (__vreg(vgt, GVT_PIPESRC(pipe)) &
+			_PIPE_V_SRCSZ_MASK) >> _PIPE_V_SRCSZ_SHIFT;
+	plane->height += 1;	/* raw height is one minus the real value */
+
+	val = __vreg(vgt, GVT_DSPTILEOFF(pipe));
+	plane->x_offset = (val & _PRI_PLANE_X_OFF_MASK) >>
+		_PRI_PLANE_X_OFF_SHIFT;
+	plane->y_offset = (val & _PRI_PLANE_Y_OFF_MASK) >>
+		_PRI_PLANE_Y_OFF_SHIFT;
+
 	return 0;
 }
 
-int gvt_fb_notifier_call_chain(unsigned long val, void *data)
+#define CURSOR_MODE_NUM	(1 << 6)
+struct cursor_mode_format {
+	int	drm_format;	/* Pixel format in DRM definition */
+	u8	bpp;		/* Bits per pixel; 0 indicates invalid */
+	u32	width;		/* In pixel */
+	u32	height;		/* In lines */
+	char	*desc;		/* The description */
+};
+
+/* non-supported format has bpp default to 0 */
+static struct cursor_mode_format cursor_pixel_formats[CURSOR_MODE_NUM] = {
+	[0b100010]  = {DRM_FORMAT_ARGB8888, 32, 128, 128,"128x128 32bpp ARGB"},
+	[0b100011]  = {DRM_FORMAT_ARGB8888, 32, 256, 256, "256x256 32bpp ARGB"},
+	[0b100111]  = {DRM_FORMAT_ARGB8888, 32, 64, 64, "64x64 32bpp ARGB"},
+	[0b000111]  = {DRM_FORMAT_ARGB8888, 32, 64, 64, "64x64 32bpp ARGB"},//actually inverted... figure this out later
+};
+
+int gvt_decode_cursor_plane_format(struct vgt_device *vgt,
+	int pipe, struct gvt_cursor_plane_format *plane)
 {
+	u32 val, mode;
+	u32 alpha_plane, alpha_force;
+
+	val = __vreg(vgt, GVT_CURCNTR(pipe));
+	mode = val & _CURSOR_MODE;
+	plane->enabled = (mode != _CURSOR_MODE_DISABLE);
+	if (!plane->enabled)
+		return 0;
+
+	if (!cursor_pixel_formats[mode].bpp) {
+		gvt_err("Non-supported cursor mode (0x%x)\n", mode);
+		return -EINVAL;
+	}
+	plane->mode = mode;
+	plane->bpp = cursor_pixel_formats[mode].bpp;
+	plane->drm_format = cursor_pixel_formats[mode].drm_format;
+	plane->width = cursor_pixel_formats[mode].width;
+	plane->height = cursor_pixel_formats[mode].height;
+
+	alpha_plane = (val & _CURSOR_ALPHA_PLANE_MASK) >>
+				_CURSOR_ALPHA_PLANE_SHIFT;
+	alpha_force = (val & _CURSOR_ALPHA_FORCE_MASK) >>
+				_CURSOR_ALPHA_FORCE_SHIFT;
+	if (alpha_plane || alpha_force)
+		gvt_warn("alpha_plane=0x%x, alpha_force=0x%x\n",
+			alpha_plane, alpha_force);
+
+	plane->base = __vreg(vgt, GVT_CURBASE(pipe)) & GTT_PAGE_MASK;
+
+	val = __vreg(vgt, GVT_CURPOS(pipe));
+	plane->x_pos = (val & _CURSOR_POS_X_MASK) >> _CURSOR_POS_X_SHIFT;
+	plane->x_sign = (val & _CURSOR_SIGN_X_MASK) >> _CURSOR_SIGN_X_SHIFT;
+	plane->y_pos = (val & _CURSOR_POS_Y_MASK) >> _CURSOR_POS_Y_SHIFT;
+	plane->y_sign = (val & _CURSOR_SIGN_Y_MASK) >> _CURSOR_SIGN_Y_SHIFT;
+	plane->x_hot = __vreg(vgt, _vgtif_reg(xhot));
+	plane->y_hot = __vreg(vgt, _vgtif_reg(xhot));
+
+	return 0;
+}
+
+#define FORMAT_NUM_SRRITE	(1 << 3)
+
+static struct pixel_format sprite_pixel_formats[FORMAT_NUM_SRRITE] = {
+	[0b000]  = {DRM_FORMAT_YUV422, 16, "YUV 16-bit 4:2:2 packed"},
+	[0b001]  = {DRM_FORMAT_XRGB2101010, 32, "RGB 32-bit 2:10:10:10"},
+	[0b010]  = {DRM_FORMAT_XRGB8888, 32, "RGB 32-bit 8:8:8:8"},
+	[0b100] = {DRM_FORMAT_AYUV, 32, "YUV 32-bit 4:4:4 packed (8:8:8:8 MSB-X:Y:U:V)"},
+};
+
+int gvt_decode_sprite_plane_format(struct vgt_device *vgt,
+	int pipe, struct gvt_sprite_plane_format *plane)
+{
+	u32 val, fmt;
+	u32 width;
+	u32 color_order, yuv_order;
+	int drm_format;
+
+	val = __vreg(vgt, GVT_SPRCTL(pipe));
+	plane->enabled = !!(val & SPRITE_ENABLE);
+	if (!plane->enabled)
+		return 0;
+
+	plane->tiled = !!(val & SPRITE_TILED);
+	color_order = !!(val & SPRITE_RGB_ORDER_RGBX);
+	yuv_order = (val & SPRITE_YUV_BYTE_ORDER_MASK) >>
+				_SPRITE_YUV_ORDER_SHIFT;
+
+	fmt = (val & SPRITE_PIXFORMAT_MASK) >> _SPRITE_FMT_SHIFT;
+	if (!sprite_pixel_formats[fmt].bpp) {
+		gvt_err("Non-supported pixel format (0x%x)\n", fmt);
+		return -EINVAL;
+	}
+	plane->hw_format = fmt;
+	plane->bpp = sprite_pixel_formats[fmt].bpp;
+	drm_format = sprite_pixel_formats[fmt].drm_format;
+
+	/* Order of RGB values in an RGBxxx buffer may be ordered RGB or
+	 * BGR depending on the state of the color_order field
+	 */
+	if (!color_order) {
+		if (drm_format == DRM_FORMAT_XRGB2101010)
+			drm_format = DRM_FORMAT_XBGR2101010;
+		else if (drm_format == DRM_FORMAT_XRGB8888)
+			drm_format = DRM_FORMAT_XBGR8888;
+	}
+
+	if (drm_format == DRM_FORMAT_YUV422) {
+		switch (yuv_order){
+		case	0:
+			drm_format = DRM_FORMAT_YUYV;
+			break;
+		case	1:
+			drm_format = DRM_FORMAT_UYVY;
+			break;
+		case	2:
+			drm_format = DRM_FORMAT_YVYU;
+			break;
+		case	3:
+			drm_format = DRM_FORMAT_VYUY;
+			break;
+		default:
+			/* yuv_order has only 2 bits */
+			BUG();
+			break;
+		}
+	}
+
+	plane->drm_format = drm_format;
+
+	plane->base = __vreg(vgt, GVT_SPRSURF(pipe)) & GTT_PAGE_MASK;
+	plane->width = __vreg(vgt, GVT_SPRSTRIDE(pipe)) &
+				_SPRITE_STRIDE_MASK;
+	plane->width /= plane->bpp / 8;	/* raw width in bytes */
+
+	val = __vreg(vgt, GVT_SPRSIZE(pipe));
+	plane->height = (val & _SPRITE_SIZE_HEIGHT_MASK) >>
+		_SPRITE_SIZE_HEIGHT_SHIFT;
+	width = (val & _SPRITE_SIZE_WIDTH_MASK) >> _SPRITE_SIZE_WIDTH_SHIFT;
+	plane->height += 1;	/* raw height is one minus the real value */
+	width += 1;		/* raw width is one minus the real value */
+	if (plane->width != width)
+		gvt_warn("sprite_plane: plane->width=%d, width=%d\n",
+			plane->width, width);
+
+	val = __vreg(vgt, GVT_SPRPOS(pipe));
+	plane->x_pos = (val & _SPRITE_POS_X_MASK) >> _SPRITE_POS_X_SHIFT;
+	plane->y_pos = (val & _SPRITE_POS_Y_MASK) >> _SPRITE_POS_Y_SHIFT;
+
+	val = __vreg(vgt, GVT_SPROFFSET(pipe));
+	plane->x_offset = (val & _SPRITE_OFFSET_START_X_MASK) >>
+			   _SPRITE_OFFSET_START_X_SHIFT;
+	plane->y_offset = (val & _SPRITE_OFFSET_START_Y_MASK) >>
+			   _SPRITE_OFFSET_START_Y_SHIFT;
 	return 0;
 }
+
+/*
+ * Decode framebuffer information from raw vMMIO
+ *
+ * INPUT:
+ *   [domid] - specify the VM
+ * OUTPUT:
+ *   [format] - contain the decoded format info
+ *
+ * NOTE: The caller is expected to poll this interface, and reconstruct
+ * previous reference to the new format information
+ */
+
+int gvt_decode_fb_format(struct pgt_device *pdev, int vmid, struct gvt_fb_format *fb)
+{
+	int i;
+	struct vgt_device *vgt = NULL;
+	int ret = 0;
+
+	if (!fb)
+		return -EINVAL;
+
+	/* TODO: use fine-grained refcnt later */
+	mutex_lock(&pdev->lock);
+
+	for_each_online_instance(pdev, vgt, i)
+		if (vgt->vm_id == vmid)
+			break;
+
+	if (!vgt) {
+		gvt_err("Invalid domain ID (%d)\n", vmid);
+		mutex_unlock(&pdev->lock);
+		return -ENODEV;
+	}
+
+	for (i = 0; i < I915_MAX_PIPES; i++) {
+		struct gvt_pipe_format *pipe = &fb->pipes[i];
+		u32 ddi_func_ctl = __vreg(vgt, _GVT_TRANS_DDI_FUNC_CTL(i));
+
+		if (!(ddi_func_ctl & TRANS_DDI_FUNC_ENABLE)) {
+			pipe->ddi_port = DDI_PORT_NONE;
+		} else {
+			u32 port = (ddi_func_ctl & TRANS_DDI_PORT_MASK) >>
+						TRANS_DDI_PORT_SHIFT;
+			if (port <= DDI_PORT_E)
+				pipe->ddi_port = port;
+			else
+				pipe->ddi_port = DDI_PORT_NONE;
+		}
+
+		ret |= gvt_decode_primary_plane_format(vgt, i, &pipe->primary);
+		ret |= gvt_decode_sprite_plane_format(vgt, i, &pipe->sprite);
+		ret |= gvt_decode_cursor_plane_format(vgt, i, &pipe->cursor);
+
+		if (ret) {
+			gvt_err("Decode format error for pipe(%d)\n", i);
+			ret = -EINVAL;
+			break;
+		}
+	}
+
+	mutex_unlock(&pdev->lock);
+
+	return ret;
+}
+
+int gvt_fb_notifier_call_chain(unsigned long val, void *data)
+{
+	return atomic_notifier_call_chain(&gvt_fb_notifier_list, val, data);
+}
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index cf88bd6..456b332 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -38,6 +38,7 @@
 #include "gtt.h"
 #include "cfg_space.h"
 #include "opregion.h"
+#include "fb_decoder.h"
 
 #define GVT_MAX_VGPU 8
 
diff --git a/drivers/gpu/drm/i915/gvt/reg.h b/drivers/gpu/drm/i915/gvt/reg.h
index 3fb4495..c66a2dc 100644
--- a/drivers/gpu/drm/i915/gvt/reg.h
+++ b/drivers/gpu/drm/i915/gvt/reg.h
@@ -68,6 +68,407 @@
 #define    _REGBIT_BDW_GMCH_GMS_SHIFT   8
 #define    _REGBIT_BDW_GMCH_GMS_MASK    0xff
 
+#define	_PRI_PLANE_FMT_SHIFT	26
+#define	_PRI_PLANE_TILE_SHIFT	10
+
+#define	_PRI_PLANE_STRIDE_SHIFT	6
+#define	_PRI_PLANE_STRIDE_MASK	(0x3ff << _PRI_PLANE_STRIDE_SHIFT)
+
+#define	_PRI_PLANE_X_OFF_SHIFT	0
+#define	_PRI_PLANE_X_OFF_MASK	(0x1fff << _PRI_PLANE_X_OFF_SHIFT)
+#define	_PRI_PLANE_Y_OFF_SHIFT	16
+#define	_PRI_PLANE_Y_OFF_MASK	(0xfff << _PRI_PLANE_Y_OFF_SHIFT)
+
+#define     _PIPE_V_SRCSZ_SHIFT	0
+#define     _PIPE_V_SRCSZ_MASK	(0xfff << _PIPE_V_SRCSZ_SHIFT)
+#define     _PIPE_H_SRCSZ_SHIFT	16
+#define     _PIPE_H_SRCSZ_MASK	(0x1fff << _PIPE_H_SRCSZ_SHIFT)
+
+#define _CURSOR_MODE	0x3f
+#define _CURSOR_MODE_DISABLE	0x00
+#define _CURSOR_ALPHA_FORCE_SHIFT	8
+#define _CURSOR_ALPHA_FORCE_MASK	(0x3 << _CURSOR_ALPHA_FORCE_SHIFT)
+#define _CURSOR_ALPHA_PLANE_SHIFT	10
+#define _CURSOR_ALPHA_PLANE_MASK	(0x3 << _CURSOR_ALPHA_PLANE_SHIFT)
+#define _CURSOR_POS_X_SHIFT	0
+#define _CURSOR_POS_X_MASK	(0x1fff << _CURSOR_POS_X_SHIFT)
+#define _CURSOR_SIGN_X_SHIFT	15
+#define _CURSOR_SIGN_X_MASK	(1 << _CURSOR_SIGN_X_SHIFT)
+#define _CURSOR_POS_Y_SHIFT		16
+#define _CURSOR_POS_Y_MASK	(0xfff << _CURSOR_POS_Y_SHIFT)
+#define _CURSOR_SIGN_Y_SHIFT	31
+#define _CURSOR_SIGN_Y_MASK	(1 << _CURSOR_SIGN_Y_SHIFT)
+
+#define GVT_CURCNTR(pipe)	_PIPE(pipe, _CURACNTR, _CURBCNTR_IVB)
+#define GVT_CURBASE(pipe)	_PIPE(pipe, _CURABASE, _CURBBASE_IVB)
+#define GVT_CURPOS(pipe)	_PIPE(pipe, _CURAPOS, _CURBPOS_IVB)
+
+#define	_SPRITE_FMT_SHIFT	25
+#define	_SPRITE_COLOR_ORDER_SHIFT	20
+#define	_SPRITE_YUV_ORDER_SHIFT	16
+
+#define	_SPRITE_STRIDE_SHIFT	6
+#define	_SPRITE_STRIDE_MASK	(0x1ff << _SPRITE_STRIDE_SHIFT)
+
+#define	_SPRITE_POS_X_SHIFT	0
+#define	_SPRITE_POS_Y_SHIFT	16
+#define	_SPRITE_POS_X_MASK	(0x1fff << _SPRITE_POS_X_SHIFT)
+#define	_SPRITE_POS_Y_MASK	(0xfff << _SPRITE_POS_Y_SHIFT)
+
+#define	_SPRITE_SIZE_WIDTH_SHIFT	0
+#define	_SPRITE_SIZE_HEIGHT_SHIFT	16
+#define	_SPRITE_SIZE_WIDTH_MASK	(0x1fff << _SPRITE_SIZE_WIDTH_SHIFT)
+#define	_SPRITE_SIZE_HEIGHT_MASK	(0xfff << _SPRITE_SIZE_HEIGHT_SHIFT)
+
+#define	_SPRITE_OFFSET_START_X_SHIFT	0
+#define	_SPRITE_OFFSET_START_Y_SHIFT	16
+#define	_SPRITE_OFFSET_START_X_MASK	(0x1fff << _SPRITE_OFFSET_START_X_SHIFT)
+#define	_SPRITE_OFFSET_START_Y_MASK	(0xfff << _SPRITE_OFFSET_START_Y_SHIFT)
+
+#define GVT_SPRCTL(pipe)	_PIPE(pipe, _SPRA_CTL, _PLANE_CTL_2_B)
+#define GVT_SPRSTRIDE(pipe)	_PIPE(pipe, _SPRA_STRIDE, _PLANE_STRIDE_2_B)
+#define GVT_SPRPOS(pipe)	_PIPE(pipe, _PLANE_POS_2_A, _PLANE_POS_2_B)
+#define GVT_SPRSIZE(pipe)	_PIPE(pipe, _PLANE_SIZE_2_A, _PLANE_SIZE_2_B)
+#define GVT_SPROFFSET(pipe)	_PIPE(pipe, _PLANE_OFFSET_2_A, _PLANE_OFFSET_2_B)
+
+#define GVT_DSPCNTR(pipe) _PIPE(pipe, _DSPACNTR, 0x71180)
+#define GVT_DSPCNTRPIPE(dspcntr) _GVT_GET_PIPE(dspcntr, _DSPACNTR, 0x71180)
+
+#define GVT_DSPLINOFF(pipe) _PIPE(pipe, _DSPAADDR, 0x71184)
+#define GVT_DSPSTRIDE(pipe) _PIPE(pipe, _DSPASTRIDE, 0x71188)
+#define GVT_DSPTILEOFF(pipe) _PIPE(pipe, _DSPATILEOFF, 0x711A4)
+
+#define GVT_DSPSURF(pipe) _PIPE(pipe, _DSPASURF, 0x7119C)
+#define GVT_DSPSURFPIPE(dspsurf) _GVT_GET_PIPE(dspsurf, _DSPASURF, 0x7119C)
+
+#define GVT_DSPSURFLIVE(pipe) _PIPE(pipe, _DSPASURFLIVE, 0x711AC)
+#define GVT_DSPSURFLIVEPIPE(dspsurf) _GVT_GET_PIPE(dspsurf, _DSPASURFLIVE, 0x711AC)
+
+#define GVT_DSPPOS(pipe) _PIPE(pipe, _DSPAPOS, 0x7118C)
+#define GVT_DSPSIZE(pipe) _PIPE(pipe, _DSPASIZE, 0x71190)
+
+#define GVT_CURSURF(pipe) _PIPE(pipe, _CURABASE, _CURBBASE_IVB)
+#define GVT_CURCNTR(pipe) _PIPE(pipe, _CURACNTR, _CURBCNTR_IVB)
+#define GVT_CURPOS(pipe)	_PIPE(pipe, _CURAPOS, _CURBPOS_IVB)
+#define GVT_CURSURFLIVE(pipe) _PIPE(pipe, 0x700AC, 0x710AC)
+
+#define GVT_CURSURFPIPE(cursurf) _GVT_GET_PIPE(cursurf, _CURABASE, _CURBBASE_IVB)
+#define GVT_CURCNTRPIPE(curcntr) _GVT_GET_PIPE(curcntr, _CURACNTR,_CURBCNTR_IVB)
+
+#define GVT_SPRSURF(pipe) _PIPE(pipe, _SPRA_SURF, _SPRB_SURF)
+#define GVT_SPRSURFLIVE(pipe) _PIPE(pipe, _SPRA_SURFLIVE, _SPRB_SURFLIVE)
+#define GVT_SPRSURFPIPE(sprsurf) _GVT_GET_PIPE(sprsurf, _SPRA_SURF, _SPRB_SURF)
+
+#define GVT_SPRCNTR(pipe) _PIPE(pipe, _SPRA_CTL, _SPRB_CTL)
+#define GVT_SPRCNTRPIPE(sprcntr) _GVT_GET_PIPE(sprcntr, _SPRA_CTL, _SPRB_CTL)
+
+/*
+ * We use _IMM instead of _INDEX, to avoid switching hardware
+ * status page
+ */
+#define MI_STORE_DATA_IMM		((0x20<<23) | 2)
+#define MI_STORE_DATA_IMM_QWORD		((0x20<<23) | 3)
+#define   MI_SDI_USE_GTT		(1<<22)
+#define MI_LRI_CMD			(0x22<<23 | 1)
+#define   MI_LRI_BYTE0_DISABLE		(1<<8)
+#define   MI_LRI_BYTE1_DISABLE		(1<<9)
+#define   MI_LRI_BYTE2_DISABLE		(1<<10)
+#define   MI_LRI_BYTE3_DISABLE		(1<<11)
+
+#define   MI_WAIT_FOR_PLANE_C_FLIP_PENDING      (1<<15)
+#define   MI_WAIT_FOR_PLANE_B_FLIP_PENDING      (1<<9)
+#define   MI_WAIT_FOR_PLANE_A_FLIP_PENDING      (1<<1)
+
+#define   MI_WAIT_FOR_SPRITE_C_FLIP_PENDING      (1<<20)
+#define   MI_WAIT_FOR_SPRITE_B_FLIP_PENDING      (1<<10)
+#define   MI_WAIT_FOR_SPRITE_A_FLIP_PENDING      (1<<2)
+
+#define	PIPE_CONTROL_DC_FLUSH_ENABLE			(1<<5)
+#define DUMMY_3D		(0x6d800005)
+#define PRIM_TRILIST		(0x4)
+
+/*
+ * Display engine regs
+ */
+
+#define _REG_SWF		0x4f000
+#define _REG_PIPE_MISC_C	0x72030
+
+/* CPU panel fitter */
+#define _REG_PF_CTL_2			0x69080
+#define _REG_PF_WIN_SZ_2		0x69074
+#define _REG_PF_WIN_POS_2		0x69070
+
+#define GVT_HTOTAL(pipe)	_PIPE(pipe, _HTOTAL_A, _HTOTAL_B)
+#define GVT_HBLANK(pipe)	_PIPE(pipe, _HBLANK_A, _HBLANK_B)
+#define GVT_HSYNC(pipe)		_PIPE(pipe, _HSYNC_A, _HSYNC_B)
+#define GVT_VTOTAL(pipe)	_PIPE(pipe, _VTOTAL_A, _VTOTAL_B)
+#define GVT_VBLANK(pipe)	_PIPE(pipe, _VBLANK_A, _VBLANK_B)
+#define GVT_VSYNC(pipe)		_PIPE(pipe, _VSYNC_A, _VSYNC_B)
+#define GVT_BCLRPAT(pipe)	_PIPE(pipe, _BCLRPAT_A, _BCLRPAT_B)
+#define GVT_VSYNCSHIFT(pipe)	_PIPE(pipe, _VSYNCSHIFT_A, _VSYNCSHIFT_B)
+#define GVT_PIPESRC(pipe)	_PIPE(pipe, _PIPEASRC, _PIPEBSRC)
+
+#define GVT_PCH_DPLL(pipe)	_PIPE(pipe, _REG_PCH_DPLL_A, _REG_PCH_DPLL_B)
+
+#define GVT_PCH_FP0(pipe)	_PIPE(pipe, _REG_PCH_FPA0, _REG_PCH_FPB0)
+#define GVT_PCH_FP1(pipe)	_PIPE(pipe, _REG_PCH_FPA1, _REG_PCH_FPB1)
+
+/* PIPE C timing regs are same start from 0x61000 */
+#define _REG_PIPEC_DATA_M1		0x62030
+#define _REG_PIPEC_DATA_N1		0x62034
+#define _REG_PIPEC_LINK_M1		0x62040
+#define _REG_PIPEC_LINK_N1		0x62044
+
+#define _REG_PIPEC_DATA_M2		0x62038
+#define _REG_PIPEC_DATA_N2		0x6203c
+#define _REG_PIPEC_LINK_M2		0x62048
+#define _REG_PIPEC_LINK_N2		0x6204c
+
+#define GVT_PIPE_DATA_M1(pipe) _PIPE(pipe, _REG_PIPEA_DATA_M1, _REG_PIPEB_DATA_M1)
+#define GVT_PIPE_DATA_N1(pipe) _PIPE(pipe, _REG_PIPEA_DATA_N1, _REG_PIPEB_DATA_N1)
+#define GVT_PIPE_DATA_M2(pipe) _PIPE(pipe, _REG_PIPEA_DATA_M2, _REG_PIPEB_DATA_M2)
+#define GVT_PIPE_DATA_N2(pipe) _PIPE(pipe, _REG_PIPEA_DATA_N2, _REG_PIPEB_DATA_N2)
+#define GVT_PIPE_LINK_M1(pipe) _PIPE(pipe, _REG_PIPEA_LINK_M1, _REG_PIPEB_LINK_M1)
+#define GVT_PIPE_LINK_N1(pipe) _PIPE(pipe, _REG_PIPEA_LINK_N1, _REG_PIPEB_LINK_N1)
+#define GVT_PIPE_LINK_M2(pipe) _PIPE(pipe, _REG_PIPEA_LINK_M2, _REG_PIPEB_LINK_M2)
+#define GVT_PIPE_LINK_N2(pipe) _PIPE(pipe, _REG_PIPEA_LINK_N2, _REG_PIPEB_LINK_N2)
+
+/* FDI_RX, FDI_X is hard-wired to Transcoder_X */
+
+#define _REG_FDI_RXC_CTL			0xf200c
+#define _REGBIT_FDI_RX_PORT_WIDTH_MASK		(0x7 << 19)
+#define _REGBIT_FDI_RX_FDI_AUTO_TRAIN_ENABLE	(0x1 << 10)
+
+#define _REG_FDI_RXC_IIR			0xf2014
+#define _REG_FDI_RXC_IMR			0xf2018
+
+#define GVT_FDI_RX_IIR(pipe) _PIPE(pipe, _FDI_RXA_IIR, _FDI_RXB_IIR)
+#define GVT_FDI_RX_IMR(pipe) _PIPE(pipe, _FDI_RXA_IMR, _FDI_RXB_IMR)
+
+#define _REGBIT_FDI_RX_INTER_LANE_ALIGN		(1<<10)
+#define _REGBIT_FDI_RX_SYMBOL_LOCK		(1 << 9) /* train 2*/
+#define _REGBIT_FDI_RX_BIT_LOCK			(1 << 8) /* train 1*/
+#define _REGBIT_FDI_RX_TRAIN_PATTERN_2_FAIL	(1<<7)
+#define _REGBIT_FDI_RX_FS_CODE_ERR		(1<<6)
+#define _REGBIT_FDI_RX_FE_CODE_ERR		(1<<5)
+#define _REGBIT_FDI_RX_SYMBOL_ERR_RATE_ABOVE	(1<<4)
+#define _REGBIT_FDI_RX_HDCP_LINK_FAIL		(1<<3)
+#define _REGBIT_FDI_RX_PIXEL_FIFO_OVERFLOW	(1<<2)
+#define _REGBIT_FDI_RX_CROSS_CLOCK_OVERFLOW	(1<<1)
+#define _REGBIT_FDI_RX_SYMBOL_QUEUE_OVERFLOW	(1<<0)
+
+
+#define GVT_FDI_RX_CTL_BPC_MASK		(0x7 << 16)
+#define GVT_FDI_RX_CTL(pipe) _PIPE(pipe, _FDI_RXA_CTL, _FDI_RXB_CTL)
+
+#define GVT_FDI_RX_TUSIZE1(pipe) _PIPE(pipe, _REG_FDI_RXA_TUSIZE1,_REG_FDI_RXB_TUSIZE1)
+
+/* CPU: FDI_TX */
+#define _REG_FDI_TXC_CTL		0x62100
+
+#define _REGBIT_FDI_TX_ENABLE				(1 << 31)
+#define _REGBIT_FDI_TX_PLL_ENABLE			(1 << 14)
+#define _REGBIT_FDI_TX_ENHANCE_FRAME_ENABLE		(1<<18)
+
+#define GVT_FDI_TX_CTL(pipe) _PIPE(pipe, _FDI_TXA_CTL, _FDI_TXB_CTL)
+
+/* CRT */
+#define _REGBIT_ADPA_DAC_ENABLE			(1 << 31)
+#define PORT_TRANS_SEL_SHIFT			29
+#define GVT_PORT_TRANS_SEL_CPT(pipe)		((pipe) << PORT_TRANS_SEL_SHIFT)
+#define _REGBIT_ADPA_VSYNC_ACTIVE_HIGH		(1 << 4)
+#define _REGBIT_ADPA_HSYNC_ACTIVE_HIGH		(1 << 3)
+
+/*Intermediate Pixel Storage*/
+union _PCH_PP_CTL
+{
+	uint32_t data;
+	struct
+	{
+		uint32_t power_state_target	: 1; // bit 0
+		uint32_t power_down_on_reset	: 1; // bit 1
+		uint32_t backlight_enable	: 1; // bit 2
+		uint32_t edp_vdd_override_for_aux : 1; // bit 3
+		uint32_t reserve : 12;			// bits 15:4
+		uint32_t write_protect_key :16; // bits 31:16 0xABCD to disable protected)
+	};
+};
+
+union _PCH_PP_STAUTS
+{
+	uint32_t data;
+	struct
+	{
+		uint32_t reserv1	: 4;	// bit 3:0
+		uint32_t reserv2	: 23;	// bit 26:4
+		uint32_t power_cycle_delay_active	:1;	// bit 27
+		uint32_t power_sequence_progress	:2;	// bits 29:28
+		uint32_t require_asset_status		:1;	// bit 30
+		uint32_t panel_powere_on_statue		:1;	// bit 31 (0 - Disable, 1 - Enable)
+	};
+};
+
+/* Per-transcoder DIP controls */
+
+#define GVT_TRANSCONF(plane)	_PIPE(plane, _PCH_TRANSACONF, _PCH_TRANSBCONF)
+
+union _TRANS_CONFIG
+{
+	uint32_t data;
+	struct
+	{
+		uint32_t reserve1 : 10;			// bit 9:0
+		uint32_t xvycc_color_range_limit : 1;	// bit 10
+		uint32_t reserve2 : 10;			// bit 20:11
+		uint32_t interlaced_mode: 3;		// bit 23:21
+		uint32_t reserve3 : 6;			// bit 29:24
+		uint32_t transcoder_state : 1;		// bit 30
+		uint32_t transcoder_enable : 1;		// bit 31
+	};
+};
+
+#define _REG_TRANSC_VIDEO_DIP_CTL	0xE2200
+#define _REG_TRANSC_VIDEO_DIP_DATA	0xE2208
+#define _REG_TRANSC_VIDEO_DIP_GCP	0xE2210
+
+/* eDP */
+#define _REG_PIPE_EDP_CONF	0x7f008
+
+/* bit fields of pipestat */
+#define GVT_PIPEDSL(pipe)	_PIPE(pipe, _PIPEADSL, 0x71000)
+#define GVT_PIPECONF(pipe)	_PIPE(pipe, _PIPEACONF, 0x71008)
+#define GVT_PIPESTAT(pipe)	_PIPE(pipe, _PIPEASTAT, 0x71024)
+#define GVT_PIPE_FRMCOUNT(pipe)	_PIPE(pipe, _PIPEA_FRMCOUNT_G4X, 0x71040)
+#define GVT_PIPE_FLIPCOUNT(pipe) _PIPE(pipe, _PIPEA_FLIPCOUNT_G4X, 0x71044)
+
+#define GVT_PIPECONFPIPE(pipeconf) _GVT_GET_PIPE(pipeconf, _PIPEACONF, 0x71008)
+#define GVT_FRMCOUNTPIPE(frmcount) _GVT_GET_PIPE(frmcount, _PIPEA_FRMCOUNT_G4X, 0x71040)
+
+#define GVT_PALETTE(pipe) _PIPE(pipe, _PALETTE_A_OFFSET, _PALETTE_B_OFFSET)
+
+/* legacy palette */
+#define _REG_LGC_PALETTE_C		0x4b000
+
+/* Display Port */
+#define _REG_DP_TP_CTL_C		0x64240
+#define _REG_DP_TP_CTL_D		0x64340
+#define _REG_DP_TP_CTL_E		0x64440
+#define  _REGBIT_DP_TP_FDI_AUTO_TRAIN_ENABLE	(1 << 15)
+#define  _DDI_BUFCTL_DETECT_MASK	0x1
+#define  _REGBIT_DDI_BUF_ENABLE		(1 << 31)
+#define  _REGBIT_DDI_BUF_IS_IDLE	(1<<7)
+#define _REG_DDI_BUF_CTL_C		0x64200
+#define _REG_DDI_BUF_CTL_D		0x64300
+#define _REG_DDI_BUF_CTL_E		0x64400
+#define _REG_DP_TP_STATUS_C			0x64244
+#define _REG_DP_TP_STATUS_D			0x64344
+#define _REG_DP_TP_STATUS_E			0x64444
+#define GVT_DP_TP_CTL(port)		_PORT(port, _DP_TP_CTL_A, \
+		_DP_TP_CTL_B)
+
+#define DP_TP_PORT(reg)		_GVT_GET_PORT(reg, _DP_TP_CTL_A, \
+		_DP_TP_CTL_B)
+
+#define DRM_MODE_DPMS_ON		0
+
+#define _PCH_DPA_AUX_CH_CTL	0x64010
+#define _PCH_DPB_AUX_CH_CTL	0xe4110
+#define _PCH_DPC_AUX_CH_CTL	0xe4210
+#define _PCH_DPD_AUX_CH_CTL	0xe4310
+
+/* DPCD */
+#define DP_SET_POWER		0x600
+#define DP_SET_POWER_D0		0x1
+#define AUX_NATIVE_WRITE	0x8
+#define AUX_NATIVE_READ		0x9
+
+#define AUX_NATIVE_REPLY_MASK	(0x3 << 4)
+#define AUX_NATIVE_REPLY_ACK	(0x0 << 4)
+#define AUX_NATIVE_REPLY_NAK	(0x1 << 4)
+#define AUX_NATIVE_REPLY_DEFER	(0x2 << 4)
+
+#define AUX_BURST_SIZE		16
+
+/* DPCD 0x106 */
+
+#define DP_TRAINING_PATTERN_SET			0x102
+#define DP_TRAINING_PATTERN_DISABLE		0
+#define DP_TRAINING_PATTERN_1			1
+#define DP_TRAINING_PATTERN_2			2
+#define DP_LINK_SCRAMBLING_DISABLE		(1 << 5)
+
+#define DP_LINK_CONFIGURATION_SIZE		9
+#define    DP_LINK_BW_SET			0x100
+# define DP_SET_ANSI_8B10B			(1 << 0)
+
+#define DP_LINK_STATUS_SIZE			6
+#define DP_TRAIN_MAX_SWING_REACHED		(1 << 2)
+
+#define DP_TRAINING_LANE0_SET			0x103
+
+#define DP_TRAIN_VOLTAGE_SWING_MASK		0x3
+#define DP_TRAIN_VOLTAGE_SWING_SHIFT		0
+#define DP_TRAIN_VOLTAGE_SWING_400		(0 << 0)
+#define DP_TRAIN_VOLTAGE_SWING_600		(1 << 0)
+#define DP_TRAIN_VOLTAGE_SWING_800		(2 << 0)
+#define DP_TRAIN_VOLTAGE_SWING_1200		(3 << 0)
+
+#define DP_TRAIN_PRE_EMPHASIS_MASK		(3 << 3)
+#define DP_TRAIN_PRE_EMPHASIS_0			(0 << 3)
+#define DP_TRAIN_PRE_EMPHASIS_3_5		(1 << 3)
+#define DP_TRAIN_PRE_EMPHASIS_6			(2 << 3)
+#define DP_TRAIN_PRE_EMPHASIS_9_5		(3 << 3)
+
+#define DP_TRAIN_PRE_EMPHASIS_SHIFT		3
+#define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED	(1 << 5)
+
+#define DP_LANE0_1_STATUS			0x202
+#define DP_LANE_CR_DONE				(1 << 0)
+
+#define DP_LANE_ALIGN_STATUS_UPDATED		0x204
+#define DP_INTERLANE_ALIGN_DONE			(1 << 0)
+#define DP_LANE_CHANNEL_EQ_DONE			(1 << 1)
+#define DP_LANE_SYMBOL_LOCKED			(1 << 2)
+
+#define DP_ADJUST_REQUEST_LANE0_1		0x206
+
+#define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0
+#define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4
+#define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT  2
+#define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT  6
+/* Ironlake */
+#define	_REG_CPU_VGACNTRL	CPU_VGACNTRL
+#define _REGBIT_VGA_DISPLAY_DISABLE	(1UL << 31)
+#define _REG_DPFC_CB_BASE		0x43200
+#define _REG_DPFC_CONTROL		0x43208
+#define _REG_DPFC_RECOMP_CTL		0x4320c
+#define _REG_DPFC_CPU_FENCE_OFFSET	0x43218
+#define _REG_DPFC_CONTROL_SA		0x100100
+#define _REG_DPFC_CPU_FENCE_OFFSET_SA	0x100104
+
+#define _REG_CSC_A_COEFFICIENTS		0x49010
+#define _REG_CSC_A_MODE			0x49028
+#define _REG_PRECSC_A_HIGH_COLOR_CHANNEL_OFFSET		0x49030
+#define _REG_PRECSC_A_MEDIUM_COLOR_CHANNEL_OFFSET	0x49034
+#define _REG_PRECSC_A_LOW_COLOR_CHANNEL_OFFSET		0x49038
+
+#define _REG_CSC_B_COEFFICIENTS		0x49110
+#define _REG_CSC_B_MODE			0x49128
+#define _REG_PRECSC_B_HIGH_COLOR_CHANNEL_OFFSET		0x49130
+#define _REG_PRECSC_B_MEDIUM_COLOR_CHANNEL_OFFSET	0x49134
+#define _REG_PRECSC_B_LOW_COLOR_CHANNEL_OFFSET		0x49138
+
+#define _REG_CSC_C_COEFFICIENTS		0x49210
+#define _REG_CSC_C_MODE			0x49228
+#define _REG_PRECSC_C_HIGH_COLOR_CHANNEL_OFFSET		0x49230
+#define _REG_PRECSC_C_MEDIUM_COLOR_CHANNEL_OFFSET	0x49234
+#define _REG_PRECSC_C_LOW_COLOR_CHANNEL_OFFSET		0x49238
+
+#define _REG_DP_BUFTRANS		0xe4f00
+
+#define _PCH_GMBUS0			0xc5100
+#define _PCH_GMBUS1			0xc5104
 #define _PCH_GMBUS2			0xc5108
 
 #define _GEN6_GDRST			0x941c
@@ -105,4 +506,7 @@
 #define _GEN8_DE_PIPE_IIR(pipe) (0x44408 + (0x10 * (pipe)))
 #define _GEN8_DE_PIPE_IER(pipe) (0x4440c + (0x10 * (pipe)))
 
+#define _GVT_TRANS_DDI_FUNC_CTL(tran)   _TRANS(tran, _TRANS_DDI_FUNC_CTL_A, \
+		_TRANS_DDI_FUNC_CTL_B)
+
 #endif
-- 
1.9.1



More information about the Intel-gfx mailing list