0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <uapi/drm/drm_fourcc.h>
0037 #include "i915_drv.h"
0038 #include "gvt.h"
0039 #include "i915_pvinfo.h"
0040 #include "i915_reg.h"
0041
0042 #define PRIMARY_FORMAT_NUM 16
0043 struct pixel_format {
0044 int drm_format;
0045 int bpp;
0046 const char *desc;
0047 };
0048
0049 static const struct pixel_format bdw_pixel_formats[] = {
0050 {DRM_FORMAT_C8, 8, "8-bit Indexed"},
0051 {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
0052 {DRM_FORMAT_XRGB8888, 32, "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
0053 {DRM_FORMAT_XBGR2101010, 32, "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
0054
0055 {DRM_FORMAT_XRGB2101010, 32, "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"},
0056 {DRM_FORMAT_XBGR8888, 32, "32-bit RGBX (8:8:8:8 MSB-X:B:G:R)"},
0057
0058
0059 {0, 0, NULL},
0060 };
0061
0062 static const struct pixel_format skl_pixel_formats[] = {
0063 {DRM_FORMAT_YUYV, 16, "16-bit packed YUYV (8:8:8:8 MSB-V:Y2:U:Y1)"},
0064 {DRM_FORMAT_UYVY, 16, "16-bit packed UYVY (8:8:8:8 MSB-Y2:V:Y1:U)"},
0065 {DRM_FORMAT_YVYU, 16, "16-bit packed YVYU (8:8:8:8 MSB-U:Y2:V:Y1)"},
0066 {DRM_FORMAT_VYUY, 16, "16-bit packed VYUY (8:8:8:8 MSB-Y2:U:Y1:V)"},
0067
0068 {DRM_FORMAT_C8, 8, "8-bit Indexed"},
0069 {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"},
0070 {DRM_FORMAT_ABGR8888, 32, "32-bit RGBA (8:8:8:8 MSB-A:B:G:R)"},
0071 {DRM_FORMAT_XBGR8888, 32, "32-bit RGBX (8:8:8:8 MSB-X:B:G:R)"},
0072
0073 {DRM_FORMAT_ARGB8888, 32, "32-bit BGRA (8:8:8:8 MSB-A:R:G:B)"},
0074 {DRM_FORMAT_XRGB8888, 32, "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"},
0075 {DRM_FORMAT_XBGR2101010, 32, "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"},
0076 {DRM_FORMAT_XRGB2101010, 32, "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"},
0077
0078
0079 {0, 0, NULL},
0080 };
0081
0082 static int bdw_format_to_drm(int format)
0083 {
0084 int bdw_pixel_formats_index = 6;
0085
0086 switch (format) {
0087 case DISP_FORMAT_8BPP:
0088 bdw_pixel_formats_index = 0;
0089 break;
0090 case DISP_FORMAT_BGRX565:
0091 bdw_pixel_formats_index = 1;
0092 break;
0093 case DISP_FORMAT_BGRX888:
0094 bdw_pixel_formats_index = 2;
0095 break;
0096 case DISP_FORMAT_RGBX101010:
0097 bdw_pixel_formats_index = 3;
0098 break;
0099 case DISP_FORMAT_BGRX101010:
0100 bdw_pixel_formats_index = 4;
0101 break;
0102 case DISP_FORMAT_RGBX888:
0103 bdw_pixel_formats_index = 5;
0104 break;
0105
0106 default:
0107 break;
0108 }
0109
0110 return bdw_pixel_formats_index;
0111 }
0112
0113 static int skl_format_to_drm(int format, bool rgb_order, bool alpha,
0114 int yuv_order)
0115 {
0116 int skl_pixel_formats_index = 12;
0117
0118 switch (format) {
0119 case PLANE_CTL_FORMAT_INDEXED:
0120 skl_pixel_formats_index = 4;
0121 break;
0122 case PLANE_CTL_FORMAT_RGB_565:
0123 skl_pixel_formats_index = 5;
0124 break;
0125 case PLANE_CTL_FORMAT_XRGB_8888:
0126 if (rgb_order)
0127 skl_pixel_formats_index = alpha ? 6 : 7;
0128 else
0129 skl_pixel_formats_index = alpha ? 8 : 9;
0130 break;
0131 case PLANE_CTL_FORMAT_XRGB_2101010:
0132 skl_pixel_formats_index = rgb_order ? 10 : 11;
0133 break;
0134 case PLANE_CTL_FORMAT_YUV422:
0135 skl_pixel_formats_index = yuv_order >> 16;
0136 if (skl_pixel_formats_index > 3)
0137 return -EINVAL;
0138 break;
0139
0140 default:
0141 break;
0142 }
0143
0144 return skl_pixel_formats_index;
0145 }
0146
0147 static u32 intel_vgpu_get_stride(struct intel_vgpu *vgpu, int pipe,
0148 u32 tiled, int stride_mask, int bpp)
0149 {
0150 struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
0151
0152 u32 stride_reg = vgpu_vreg_t(vgpu, DSPSTRIDE(pipe)) & stride_mask;
0153 u32 stride = stride_reg;
0154
0155 if (GRAPHICS_VER(dev_priv) >= 9) {
0156 switch (tiled) {
0157 case PLANE_CTL_TILED_LINEAR:
0158 stride = stride_reg * 64;
0159 break;
0160 case PLANE_CTL_TILED_X:
0161 stride = stride_reg * 512;
0162 break;
0163 case PLANE_CTL_TILED_Y:
0164 stride = stride_reg * 128;
0165 break;
0166 case PLANE_CTL_TILED_YF:
0167 if (bpp == 8)
0168 stride = stride_reg * 64;
0169 else if (bpp == 16 || bpp == 32 || bpp == 64)
0170 stride = stride_reg * 128;
0171 else
0172 gvt_dbg_core("skl: unsupported bpp:%d\n", bpp);
0173 break;
0174 default:
0175 gvt_dbg_core("skl: unsupported tile format:%x\n",
0176 tiled);
0177 }
0178 }
0179
0180 return stride;
0181 }
0182
0183 static int get_active_pipe(struct intel_vgpu *vgpu)
0184 {
0185 int i;
0186
0187 for (i = 0; i < I915_MAX_PIPES; i++)
0188 if (pipe_is_enabled(vgpu, i))
0189 break;
0190
0191 return i;
0192 }
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203 int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
0204 struct intel_vgpu_primary_plane_format *plane)
0205 {
0206 struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
0207 u32 val, fmt;
0208 int pipe;
0209
0210 pipe = get_active_pipe(vgpu);
0211 if (pipe >= I915_MAX_PIPES)
0212 return -ENODEV;
0213
0214 val = vgpu_vreg_t(vgpu, DSPCNTR(pipe));
0215 plane->enabled = !!(val & DISP_ENABLE);
0216 if (!plane->enabled)
0217 return -ENODEV;
0218
0219 if (GRAPHICS_VER(dev_priv) >= 9) {
0220 plane->tiled = val & PLANE_CTL_TILED_MASK;
0221 fmt = skl_format_to_drm(
0222 val & PLANE_CTL_FORMAT_MASK_SKL,
0223 val & PLANE_CTL_ORDER_RGBX,
0224 val & PLANE_CTL_ALPHA_MASK,
0225 val & PLANE_CTL_YUV422_ORDER_MASK);
0226
0227 if (fmt >= ARRAY_SIZE(skl_pixel_formats)) {
0228 gvt_vgpu_err("Out-of-bounds pixel format index\n");
0229 return -EINVAL;
0230 }
0231
0232 plane->bpp = skl_pixel_formats[fmt].bpp;
0233 plane->drm_format = skl_pixel_formats[fmt].drm_format;
0234 } else {
0235 plane->tiled = val & DISP_TILED;
0236 fmt = bdw_format_to_drm(val & DISP_FORMAT_MASK);
0237 plane->bpp = bdw_pixel_formats[fmt].bpp;
0238 plane->drm_format = bdw_pixel_formats[fmt].drm_format;
0239 }
0240
0241 if (!plane->bpp) {
0242 gvt_vgpu_err("Non-supported pixel format (0x%x)\n", fmt);
0243 return -EINVAL;
0244 }
0245
0246 plane->hw_format = fmt;
0247
0248 plane->base = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK;
0249 if (!vgpu_gmadr_is_valid(vgpu, plane->base))
0250 return -EINVAL;
0251
0252 plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
0253 if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
0254 gvt_vgpu_err("Translate primary plane gma 0x%x to gpa fail\n",
0255 plane->base);
0256 return -EINVAL;
0257 }
0258
0259 plane->stride = intel_vgpu_get_stride(vgpu, pipe, plane->tiled,
0260 (GRAPHICS_VER(dev_priv) >= 9) ?
0261 (_PRI_PLANE_STRIDE_MASK >> 6) :
0262 _PRI_PLANE_STRIDE_MASK, plane->bpp);
0263
0264 plane->width = (vgpu_vreg_t(vgpu, PIPESRC(pipe)) & _PIPE_H_SRCSZ_MASK) >>
0265 _PIPE_H_SRCSZ_SHIFT;
0266 plane->width += 1;
0267 plane->height = (vgpu_vreg_t(vgpu, PIPESRC(pipe)) &
0268 _PIPE_V_SRCSZ_MASK) >> _PIPE_V_SRCSZ_SHIFT;
0269 plane->height += 1;
0270
0271 val = vgpu_vreg_t(vgpu, DSPTILEOFF(pipe));
0272 plane->x_offset = (val & _PRI_PLANE_X_OFF_MASK) >>
0273 _PRI_PLANE_X_OFF_SHIFT;
0274 plane->y_offset = (val & _PRI_PLANE_Y_OFF_MASK) >>
0275 _PRI_PLANE_Y_OFF_SHIFT;
0276
0277 return 0;
0278 }
0279
0280 #define CURSOR_FORMAT_NUM (1 << 6)
0281 struct cursor_mode_format {
0282 int drm_format;
0283 u8 bpp;
0284 u32 width;
0285 u32 height;
0286 const char *desc;
0287 };
0288
0289 static const struct cursor_mode_format cursor_pixel_formats[] = {
0290 {DRM_FORMAT_ARGB8888, 32, 128, 128, "128x128 32bpp ARGB"},
0291 {DRM_FORMAT_ARGB8888, 32, 256, 256, "256x256 32bpp ARGB"},
0292 {DRM_FORMAT_ARGB8888, 32, 64, 64, "64x64 32bpp ARGB"},
0293 {DRM_FORMAT_ARGB8888, 32, 64, 64, "64x64 32bpp ARGB"},
0294
0295
0296 {0, 0, 0, 0, NULL},
0297 };
0298
0299 static int cursor_mode_to_drm(int mode)
0300 {
0301 int cursor_pixel_formats_index = 4;
0302
0303 switch (mode) {
0304 case MCURSOR_MODE_128_ARGB_AX:
0305 cursor_pixel_formats_index = 0;
0306 break;
0307 case MCURSOR_MODE_256_ARGB_AX:
0308 cursor_pixel_formats_index = 1;
0309 break;
0310 case MCURSOR_MODE_64_ARGB_AX:
0311 cursor_pixel_formats_index = 2;
0312 break;
0313 case MCURSOR_MODE_64_32B_AX:
0314 cursor_pixel_formats_index = 3;
0315 break;
0316
0317 default:
0318 break;
0319 }
0320
0321 return cursor_pixel_formats_index;
0322 }
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333 int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
0334 struct intel_vgpu_cursor_plane_format *plane)
0335 {
0336 struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915;
0337 u32 val, mode, index;
0338 u32 alpha_plane, alpha_force;
0339 int pipe;
0340
0341 pipe = get_active_pipe(vgpu);
0342 if (pipe >= I915_MAX_PIPES)
0343 return -ENODEV;
0344
0345 val = vgpu_vreg_t(vgpu, CURCNTR(pipe));
0346 mode = val & MCURSOR_MODE_MASK;
0347 plane->enabled = (mode != MCURSOR_MODE_DISABLE);
0348 if (!plane->enabled)
0349 return -ENODEV;
0350
0351 index = cursor_mode_to_drm(mode);
0352
0353 if (!cursor_pixel_formats[index].bpp) {
0354 gvt_vgpu_err("Non-supported cursor mode (0x%x)\n", mode);
0355 return -EINVAL;
0356 }
0357 plane->mode = mode;
0358 plane->bpp = cursor_pixel_formats[index].bpp;
0359 plane->drm_format = cursor_pixel_formats[index].drm_format;
0360 plane->width = cursor_pixel_formats[index].width;
0361 plane->height = cursor_pixel_formats[index].height;
0362
0363 alpha_plane = (val & _CURSOR_ALPHA_PLANE_MASK) >>
0364 _CURSOR_ALPHA_PLANE_SHIFT;
0365 alpha_force = (val & _CURSOR_ALPHA_FORCE_MASK) >>
0366 _CURSOR_ALPHA_FORCE_SHIFT;
0367 if (alpha_plane || alpha_force)
0368 gvt_dbg_core("alpha_plane=0x%x, alpha_force=0x%x\n",
0369 alpha_plane, alpha_force);
0370
0371 plane->base = vgpu_vreg_t(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK;
0372 if (!vgpu_gmadr_is_valid(vgpu, plane->base))
0373 return -EINVAL;
0374
0375 plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
0376 if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
0377 gvt_vgpu_err("Translate cursor plane gma 0x%x to gpa fail\n",
0378 plane->base);
0379 return -EINVAL;
0380 }
0381
0382 val = vgpu_vreg_t(vgpu, CURPOS(pipe));
0383 plane->x_pos = (val & _CURSOR_POS_X_MASK) >> _CURSOR_POS_X_SHIFT;
0384 plane->x_sign = (val & _CURSOR_SIGN_X_MASK) >> _CURSOR_SIGN_X_SHIFT;
0385 plane->y_pos = (val & _CURSOR_POS_Y_MASK) >> _CURSOR_POS_Y_SHIFT;
0386 plane->y_sign = (val & _CURSOR_SIGN_Y_MASK) >> _CURSOR_SIGN_Y_SHIFT;
0387
0388 plane->x_hot = vgpu_vreg_t(vgpu, vgtif_reg(cursor_x_hot));
0389 plane->y_hot = vgpu_vreg_t(vgpu, vgtif_reg(cursor_y_hot));
0390 return 0;
0391 }
0392
0393 #define SPRITE_FORMAT_NUM (1 << 3)
0394
0395 static const struct pixel_format sprite_pixel_formats[SPRITE_FORMAT_NUM] = {
0396 [0x0] = {DRM_FORMAT_YUV422, 16, "YUV 16-bit 4:2:2 packed"},
0397 [0x1] = {DRM_FORMAT_XRGB2101010, 32, "RGB 32-bit 2:10:10:10"},
0398 [0x2] = {DRM_FORMAT_XRGB8888, 32, "RGB 32-bit 8:8:8:8"},
0399 [0x4] = {DRM_FORMAT_AYUV, 32,
0400 "YUV 32-bit 4:4:4 packed (8:8:8:8 MSB-X:Y:U:V)"},
0401 };
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412 int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu,
0413 struct intel_vgpu_sprite_plane_format *plane)
0414 {
0415 u32 val, fmt;
0416 u32 color_order, yuv_order;
0417 int drm_format;
0418 int pipe;
0419
0420 pipe = get_active_pipe(vgpu);
0421 if (pipe >= I915_MAX_PIPES)
0422 return -ENODEV;
0423
0424 val = vgpu_vreg_t(vgpu, SPRCTL(pipe));
0425 plane->enabled = !!(val & SPRITE_ENABLE);
0426 if (!plane->enabled)
0427 return -ENODEV;
0428
0429 plane->tiled = !!(val & SPRITE_TILED);
0430 color_order = !!(val & SPRITE_RGB_ORDER_RGBX);
0431 yuv_order = (val & SPRITE_YUV_ORDER_MASK) >>
0432 _SPRITE_YUV_ORDER_SHIFT;
0433
0434 fmt = (val & SPRITE_FORMAT_MASK) >> _SPRITE_FMT_SHIFT;
0435 if (!sprite_pixel_formats[fmt].bpp) {
0436 gvt_vgpu_err("Non-supported pixel format (0x%x)\n", fmt);
0437 return -EINVAL;
0438 }
0439 plane->hw_format = fmt;
0440 plane->bpp = sprite_pixel_formats[fmt].bpp;
0441 drm_format = sprite_pixel_formats[fmt].drm_format;
0442
0443
0444
0445
0446 if (!color_order) {
0447 if (drm_format == DRM_FORMAT_XRGB2101010)
0448 drm_format = DRM_FORMAT_XBGR2101010;
0449 else if (drm_format == DRM_FORMAT_XRGB8888)
0450 drm_format = DRM_FORMAT_XBGR8888;
0451 }
0452
0453 if (drm_format == DRM_FORMAT_YUV422) {
0454 switch (yuv_order) {
0455 case 0:
0456 drm_format = DRM_FORMAT_YUYV;
0457 break;
0458 case 1:
0459 drm_format = DRM_FORMAT_UYVY;
0460 break;
0461 case 2:
0462 drm_format = DRM_FORMAT_YVYU;
0463 break;
0464 case 3:
0465 drm_format = DRM_FORMAT_VYUY;
0466 break;
0467 default:
0468
0469 break;
0470 }
0471 }
0472
0473 plane->drm_format = drm_format;
0474
0475 plane->base = vgpu_vreg_t(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK;
0476 if (!vgpu_gmadr_is_valid(vgpu, plane->base))
0477 return -EINVAL;
0478
0479 plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
0480 if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
0481 gvt_vgpu_err("Translate sprite plane gma 0x%x to gpa fail\n",
0482 plane->base);
0483 return -EINVAL;
0484 }
0485
0486 plane->stride = vgpu_vreg_t(vgpu, SPRSTRIDE(pipe)) &
0487 _SPRITE_STRIDE_MASK;
0488
0489 val = vgpu_vreg_t(vgpu, SPRSIZE(pipe));
0490 plane->height = (val & _SPRITE_SIZE_HEIGHT_MASK) >>
0491 _SPRITE_SIZE_HEIGHT_SHIFT;
0492 plane->width = (val & _SPRITE_SIZE_WIDTH_MASK) >>
0493 _SPRITE_SIZE_WIDTH_SHIFT;
0494 plane->height += 1;
0495 plane->width += 1;
0496
0497 val = vgpu_vreg_t(vgpu, SPRPOS(pipe));
0498 plane->x_pos = (val & _SPRITE_POS_X_MASK) >> _SPRITE_POS_X_SHIFT;
0499 plane->y_pos = (val & _SPRITE_POS_Y_MASK) >> _SPRITE_POS_Y_SHIFT;
0500
0501 val = vgpu_vreg_t(vgpu, SPROFFSET(pipe));
0502 plane->x_offset = (val & _SPRITE_OFFSET_START_X_MASK) >>
0503 _SPRITE_OFFSET_START_X_SHIFT;
0504 plane->y_offset = (val & _SPRITE_OFFSET_START_Y_MASK) >>
0505 _SPRITE_OFFSET_START_Y_SHIFT;
0506
0507 return 0;
0508 }