From patchwork Thu Jan 28 10:21:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Zhi A" X-Patchwork-Id: 8148581 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B05839F440 for ; Thu, 28 Jan 2016 10:24:59 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9786020373 for ; Thu, 28 Jan 2016 10:24:57 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 0679E20320 for ; Thu, 28 Jan 2016 10:24:55 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id A04026E7FF; Thu, 28 Jan 2016 02:24:53 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id CC45A6E7FB for ; Thu, 28 Jan 2016 02:24:51 -0800 (PST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga101.fm.intel.com with ESMTP; 28 Jan 2016 02:24:40 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,358,1449561600"; d="scan'208";a="870588545" Received: from dev-inno.bj.intel.com ([10.238.135.69]) by orsmga001.jf.intel.com with ESMTP; 28 Jan 2016 02:24:35 -0800 From: Zhi Wang To: intel-gfx@lists.freedesktop.org, igvt-g@lists.01.org Date: Thu, 28 Jan 2016 18:21:42 +0800 Message-Id: <1453976511-27322-21-git-send-email-zhi.a.wang@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1453976511-27322-1-git-send-email-zhi.a.wang@intel.com> References: <1453976511-27322-1-git-send-email-zhi.a.wang@intel.com> Cc: daniel.vetter@ffwll.ch, david.j.cowperthwaite@intel.com Subject: [Intel-gfx] [RFC 20/29] drm/i915: gvt: vGPU framebuffer format decoder X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Niu Bing 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 --- 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