/*
* Copyright ( c ) 2011 - 2016 Intel Corporation . All rights reserved .
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice ( including the next
* paragraph ) shall be included in all copies or substantial portions of the
* Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE .
*
* Authors :
* Kevin Tian < kevin . tian @ intel . com >
*
* Contributors :
* Bing Niu < bing . niu @ intel . com >
* Xu Han < xu . han @ intel . com >
* Ping Gao < ping . a . gao @ intel . com >
* Xiaoguang Chen < xiaoguang . chen @ intel . com >
* Yang Liu < yang2 . liu @ intel . com >
* Tina Zhang < tina . zhang @ intel . com >
*
*/
#include <uapi/drm/drm_fourcc.h>
#include "gvt.h"
#include "i915_drv.h"
#include "i915_pvinfo.h"
#include "i915_reg.h"
#include "display/intel_display_regs.h"
#include "display/i9xx_plane_regs.h"
#include "display/intel_cursor_regs.h"
#include "display/intel_display_core.h"
#include "display/intel_sprite_regs.h"
#include "display/skl_universal_plane_regs.h"
#define PRIMARY_FORMAT_NUM 16
struct pixel_format {
int drm_format; /* Pixel format in DRM definition */
int bpp; /* Bits per pixel, 0 indicates invalid */
const char *desc; /* The description */
};
static const struct pixel_format bdw_pixel_formats[] = {
{DRM_FORMAT_C8, 8 , "8-bit Indexed" },
{DRM_FORMAT_RGB565, 16 , "16-bit BGRX (5:6:5 MSB-R:G:B)" },
{DRM_FORMAT_XRGB8888, 32 , "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)" },
{DRM_FORMAT_XBGR2101010, 32 , "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)" },
{DRM_FORMAT_XRGB2101010, 32 , "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)" },
{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 const struct pixel_format skl_pixel_formats[] = {
{DRM_FORMAT_YUYV, 16 , "16-bit packed YUYV (8:8:8:8 MSB-V:Y2:U:Y1)" },
{DRM_FORMAT_UYVY, 16 , "16-bit packed UYVY (8:8:8:8 MSB-Y2:V:Y1:U)" },
{DRM_FORMAT_YVYU, 16 , "16-bit packed YVYU (8:8:8:8 MSB-U:Y2:V:Y1)" },
{DRM_FORMAT_VYUY, 16 , "16-bit packed VYUY (8:8:8:8 MSB-Y2:U:Y1:V)" },
{DRM_FORMAT_C8, 8 , "8-bit Indexed" },
{DRM_FORMAT_RGB565, 16 , "16-bit BGRX (5:6:5 MSB-R:G:B)" },
{DRM_FORMAT_ABGR8888, 32 , "32-bit RGBA (8:8:8:8 MSB-A:B:G:R)" },
{DRM_FORMAT_XBGR8888, 32 , "32-bit RGBX (8:8:8:8 MSB-X:B:G:R)" },
{DRM_FORMAT_ARGB8888, 32 , "32-bit BGRA (8:8:8:8 MSB-A:R:G:B)" },
{DRM_FORMAT_XRGB8888, 32 , "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)" },
{DRM_FORMAT_XBGR2101010, 32 , "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)" },
{DRM_FORMAT_XRGB2101010, 32 , "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)" },
/* non-supported format has bpp default to 0 */
{}
};
static int bdw_format_to_drm(int format)
{
int bdw_pixel_formats_index = 6 ;
switch (format) {
case DISP_FORMAT_8BPP:
bdw_pixel_formats_index = 0 ;
break ;
case DISP_FORMAT_BGRX565:
bdw_pixel_formats_index = 1 ;
break ;
case DISP_FORMAT_BGRX888:
bdw_pixel_formats_index = 2 ;
break ;
case DISP_FORMAT_RGBX101010:
bdw_pixel_formats_index = 3 ;
break ;
case DISP_FORMAT_BGRX101010:
bdw_pixel_formats_index = 4 ;
break ;
case DISP_FORMAT_RGBX888:
bdw_pixel_formats_index = 5 ;
break ;
default :
break ;
}
return bdw_pixel_formats_index;
}
static int skl_format_to_drm(int format, bool rgb_order, bool alpha,
int yuv_order)
{
int skl_pixel_formats_index = 12 ;
switch (format) {
case PLANE_CTL_FORMAT_INDEXED:
skl_pixel_formats_index = 4 ;
break ;
case PLANE_CTL_FORMAT_RGB_565:
skl_pixel_formats_index = 5 ;
break ;
case PLANE_CTL_FORMAT_XRGB_8888:
if (rgb_order)
skl_pixel_formats_index = alpha ? 6 : 7 ;
else
skl_pixel_formats_index = alpha ? 8 : 9 ;
break ;
case PLANE_CTL_FORMAT_XRGB_2101010:
skl_pixel_formats_index = rgb_order ? 10 : 11 ;
break ;
case PLANE_CTL_FORMAT_YUV422:
skl_pixel_formats_index = yuv_order >> 16 ;
if (skl_pixel_formats_index > 3 )
return -EINVAL;
break ;
default :
break ;
}
return skl_pixel_formats_index;
}
static u32 intel_vgpu_get_stride(struct intel_vgpu *vgpu, int pipe,
u32 tiled, int stride_mask, int bpp)
{
struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
struct intel_display *display = dev_priv->display;
u32 stride_reg = vgpu_vreg_t(vgpu, DSPSTRIDE(display, pipe)) & stride_mask;
u32 stride = stride_reg;
if (GRAPHICS_VER(dev_priv) >= 9 ) {
switch (tiled) {
case PLANE_CTL_TILED_LINEAR:
stride = stride_reg * 64 ;
break ;
case PLANE_CTL_TILED_X:
stride = stride_reg * 512 ;
break ;
case PLANE_CTL_TILED_Y:
stride = stride_reg * 128 ;
break ;
case PLANE_CTL_TILED_YF:
if (bpp == 8 )
stride = stride_reg * 64 ;
else if (bpp == 16 || bpp == 32 || bpp == 64 )
stride = stride_reg * 128 ;
else
gvt_dbg_core("skl: unsupported bpp:%d\n" , bpp);
break ;
default :
gvt_dbg_core("skl: unsupported tile format:%x\n" ,
tiled);
}
}
return stride;
}
static int get_active_pipe(struct intel_vgpu *vgpu)
{
int i;
for (i = 0 ; i < I915_MAX_PIPES; i++)
if (pipe_is_enabled(vgpu, i))
break ;
return i;
}
/**
* intel_vgpu_decode_primary_plane - Decode primary plane
* @ vgpu : input vgpu
* @ plane : primary plane to save decoded info
* This function is called for decoding plane
*
* Returns :
* 0 on success , non - zero if failed .
*/
int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
struct intel_vgpu_primary_plane_format *plane)
{
struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
struct intel_display *display = dev_priv->display;
u32 val, fmt;
int pipe;
pipe = get_active_pipe(vgpu);
if (pipe >= I915_MAX_PIPES)
return -ENODEV;
val = vgpu_vreg_t(vgpu, DSPCNTR(display, pipe));
plane->enabled = !!(val & DISP_ENABLE);
if (!plane->enabled)
return -ENODEV;
if (GRAPHICS_VER(dev_priv) >= 9 ) {
plane->tiled = val & PLANE_CTL_TILED_MASK;
fmt = skl_format_to_drm(
val & PLANE_CTL_FORMAT_MASK_SKL,
val & PLANE_CTL_ORDER_RGBX,
val & PLANE_CTL_ALPHA_MASK,
val & PLANE_CTL_YUV422_ORDER_MASK);
if (fmt >= ARRAY_SIZE(skl_pixel_formats)) {
gvt_vgpu_err("Out-of-bounds pixel format index\n" );
return -EINVAL;
}
plane->bpp = skl_pixel_formats[fmt].bpp;
plane->drm_format = skl_pixel_formats[fmt].drm_format;
} else {
plane->tiled = val & DISP_TILED;
fmt = bdw_format_to_drm(val & DISP_FORMAT_MASK);
plane->bpp = bdw_pixel_formats[fmt].bpp;
plane->drm_format = bdw_pixel_formats[fmt].drm_format;
}
if (!plane->bpp) {
gvt_vgpu_err("Non-supported pixel format (0x%x)\n" , fmt);
return -EINVAL;
}
plane->hw_format = fmt;
plane->base = vgpu_vreg_t(vgpu, DSPSURF(display, pipe)) & I915_GTT_PAGE_MASK;
if (!vgpu_gmadr_is_valid(vgpu, plane->base))
return -EINVAL;
plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
gvt_vgpu_err("Translate primary plane gma 0x%x to gpa fail\n" ,
plane->base);
return -EINVAL;
}
plane->stride = intel_vgpu_get_stride(vgpu, pipe, plane->tiled,
(GRAPHICS_VER(dev_priv) >= 9 ) ?
(_PRI_PLANE_STRIDE_MASK >> 6 ) :
_PRI_PLANE_STRIDE_MASK, plane->bpp);
plane->width = (vgpu_vreg_t(vgpu, PIPESRC(display, pipe)) & _PIPE_H_SRCSZ_MASK) >>
_PIPE_H_SRCSZ_SHIFT;
plane->width += 1 ;
plane->height = (vgpu_vreg_t(vgpu, PIPESRC(display, pipe)) &
_PIPE_V_SRCSZ_MASK) >> _PIPE_V_SRCSZ_SHIFT;
plane->height += 1 ; /* raw height is one minus the real value */
val = vgpu_vreg_t(vgpu, DSPTILEOFF(display, 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 ;
}
#define CURSOR_FORMAT_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 */
const char *desc; /* The description */
};
static const struct cursor_mode_format cursor_pixel_formats[] = {
{DRM_FORMAT_ARGB8888, 32 , 128 , 128 , "128x128 32bpp ARGB" },
{DRM_FORMAT_ARGB8888, 32 , 256 , 256 , "256x256 32bpp ARGB" },
{DRM_FORMAT_ARGB8888, 32 , 64 , 64 , "64x64 32bpp ARGB" },
{DRM_FORMAT_ARGB8888, 32 , 64 , 64 , "64x64 32bpp ARGB" },
/* non-supported format has bpp default to 0 */
{}
};
static int cursor_mode_to_drm(int mode)
{
int cursor_pixel_formats_index = 4 ;
switch (mode) {
case MCURSOR_MODE_128_ARGB_AX:
cursor_pixel_formats_index = 0 ;
break ;
case MCURSOR_MODE_256_ARGB_AX:
cursor_pixel_formats_index = 1 ;
break ;
case MCURSOR_MODE_64_ARGB_AX:
cursor_pixel_formats_index = 2 ;
break ;
case MCURSOR_MODE_64_32B_AX:
cursor_pixel_formats_index = 3 ;
break ;
default :
break ;
}
return cursor_pixel_formats_index;
}
/**
* intel_vgpu_decode_cursor_plane - Decode sprite plane
* @ vgpu : input vgpu
* @ plane : cursor plane to save decoded info
* This function is called for decoding plane
*
* Returns :
* 0 on success , non - zero if failed .
*/
int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
struct intel_vgpu_cursor_plane_format *plane)
{
struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
struct intel_display *display = dev_priv->display;
u32 val, mode, index;
u32 alpha_plane, alpha_force;
int pipe;
pipe = get_active_pipe(vgpu);
if (pipe >= I915_MAX_PIPES)
return -ENODEV;
val = vgpu_vreg_t(vgpu, CURCNTR(display, pipe));
mode = val & MCURSOR_MODE_MASK;
plane->enabled = (mode != MCURSOR_MODE_DISABLE);
if (!plane->enabled)
return -ENODEV;
index = cursor_mode_to_drm(mode);
if (!cursor_pixel_formats[index].bpp) {
gvt_vgpu_err("Non-supported cursor mode (0x%x)\n" , mode);
return -EINVAL;
}
plane->mode = mode;
plane->bpp = cursor_pixel_formats[index].bpp;
plane->drm_format = cursor_pixel_formats[index].drm_format;
plane->width = cursor_pixel_formats[index].width;
plane->height = cursor_pixel_formats[index].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_dbg_core("alpha_plane=0x%x, alpha_force=0x%x\n" ,
alpha_plane, alpha_force);
plane->base = vgpu_vreg_t(vgpu, CURBASE(display, pipe)) & I915_GTT_PAGE_MASK;
if (!vgpu_gmadr_is_valid(vgpu, plane->base))
return -EINVAL;
plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
gvt_vgpu_err("Translate cursor plane gma 0x%x to gpa fail\n" ,
plane->base);
return -EINVAL;
}
val = vgpu_vreg_t(vgpu, CURPOS(display, 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 = vgpu_vreg_t(vgpu, vgtif_reg(cursor_x_hot));
plane->y_hot = vgpu_vreg_t(vgpu, vgtif_reg(cursor_y_hot));
return 0 ;
}
Messung V0.5 in Prozent C=97 H=99 G=97
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-10-03)
¤
*© Formatika GbR, Deutschland