1 /* 2 * Copyright(c) 2011-2016 Intel Corporation. All rights reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Kevin Tian <kevin.tian@intel.com> 25 * 26 * Contributors: 27 * Bing Niu <bing.niu@intel.com> 28 * Xu Han <xu.han@intel.com> 29 * Ping Gao <ping.a.gao@intel.com> 30 * Xiaoguang Chen <xiaoguang.chen@intel.com> 31 * Yang Liu <yang2.liu@intel.com> 32 * Tina Zhang <tina.zhang@intel.com> 33 * 34 */ 35 36 #include <uapi/drm/drm_fourcc.h> 37 38 #include "gvt.h" 39 #include "i915_drv.h" 40 #include "i915_pvinfo.h" 41 #include "i915_reg.h" 42 43 #include "display/i9xx_plane_regs.h" 44 #include "display/intel_cursor_regs.h" 45 #include "display/intel_sprite_regs.h" 46 #include "display/skl_universal_plane_regs.h" 47 48 #define PRIMARY_FORMAT_NUM 16 49 struct pixel_format { 50 int drm_format; /* Pixel format in DRM definition */ 51 int bpp; /* Bits per pixel, 0 indicates invalid */ 52 const char *desc; /* The description */ 53 }; 54 55 static const struct pixel_format bdw_pixel_formats[] = { 56 {DRM_FORMAT_C8, 8, "8-bit Indexed"}, 57 {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"}, 58 {DRM_FORMAT_XRGB8888, 32, "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"}, 59 {DRM_FORMAT_XBGR2101010, 32, "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"}, 60 61 {DRM_FORMAT_XRGB2101010, 32, "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"}, 62 {DRM_FORMAT_XBGR8888, 32, "32-bit RGBX (8:8:8:8 MSB-X:B:G:R)"}, 63 64 /* non-supported format has bpp default to 0 */ 65 {} 66 }; 67 68 static const struct pixel_format skl_pixel_formats[] = { 69 {DRM_FORMAT_YUYV, 16, "16-bit packed YUYV (8:8:8:8 MSB-V:Y2:U:Y1)"}, 70 {DRM_FORMAT_UYVY, 16, "16-bit packed UYVY (8:8:8:8 MSB-Y2:V:Y1:U)"}, 71 {DRM_FORMAT_YVYU, 16, "16-bit packed YVYU (8:8:8:8 MSB-U:Y2:V:Y1)"}, 72 {DRM_FORMAT_VYUY, 16, "16-bit packed VYUY (8:8:8:8 MSB-Y2:U:Y1:V)"}, 73 74 {DRM_FORMAT_C8, 8, "8-bit Indexed"}, 75 {DRM_FORMAT_RGB565, 16, "16-bit BGRX (5:6:5 MSB-R:G:B)"}, 76 {DRM_FORMAT_ABGR8888, 32, "32-bit RGBA (8:8:8:8 MSB-A:B:G:R)"}, 77 {DRM_FORMAT_XBGR8888, 32, "32-bit RGBX (8:8:8:8 MSB-X:B:G:R)"}, 78 79 {DRM_FORMAT_ARGB8888, 32, "32-bit BGRA (8:8:8:8 MSB-A:R:G:B)"}, 80 {DRM_FORMAT_XRGB8888, 32, "32-bit BGRX (8:8:8:8 MSB-X:R:G:B)"}, 81 {DRM_FORMAT_XBGR2101010, 32, "32-bit RGBX (2:10:10:10 MSB-X:B:G:R)"}, 82 {DRM_FORMAT_XRGB2101010, 32, "32-bit BGRX (2:10:10:10 MSB-X:R:G:B)"}, 83 84 /* non-supported format has bpp default to 0 */ 85 {} 86 }; 87 88 static int bdw_format_to_drm(int format) 89 { 90 int bdw_pixel_formats_index = 6; 91 92 switch (format) { 93 case DISP_FORMAT_8BPP: 94 bdw_pixel_formats_index = 0; 95 break; 96 case DISP_FORMAT_BGRX565: 97 bdw_pixel_formats_index = 1; 98 break; 99 case DISP_FORMAT_BGRX888: 100 bdw_pixel_formats_index = 2; 101 break; 102 case DISP_FORMAT_RGBX101010: 103 bdw_pixel_formats_index = 3; 104 break; 105 case DISP_FORMAT_BGRX101010: 106 bdw_pixel_formats_index = 4; 107 break; 108 case DISP_FORMAT_RGBX888: 109 bdw_pixel_formats_index = 5; 110 break; 111 112 default: 113 break; 114 } 115 116 return bdw_pixel_formats_index; 117 } 118 119 static int skl_format_to_drm(int format, bool rgb_order, bool alpha, 120 int yuv_order) 121 { 122 int skl_pixel_formats_index = 12; 123 124 switch (format) { 125 case PLANE_CTL_FORMAT_INDEXED: 126 skl_pixel_formats_index = 4; 127 break; 128 case PLANE_CTL_FORMAT_RGB_565: 129 skl_pixel_formats_index = 5; 130 break; 131 case PLANE_CTL_FORMAT_XRGB_8888: 132 if (rgb_order) 133 skl_pixel_formats_index = alpha ? 6 : 7; 134 else 135 skl_pixel_formats_index = alpha ? 8 : 9; 136 break; 137 case PLANE_CTL_FORMAT_XRGB_2101010: 138 skl_pixel_formats_index = rgb_order ? 10 : 11; 139 break; 140 case PLANE_CTL_FORMAT_YUV422: 141 skl_pixel_formats_index = yuv_order >> 16; 142 if (skl_pixel_formats_index > 3) 143 return -EINVAL; 144 break; 145 146 default: 147 break; 148 } 149 150 return skl_pixel_formats_index; 151 } 152 153 static u32 intel_vgpu_get_stride(struct intel_vgpu *vgpu, int pipe, 154 u32 tiled, int stride_mask, int bpp) 155 { 156 struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915; 157 struct intel_display *display = &dev_priv->display; 158 159 u32 stride_reg = vgpu_vreg_t(vgpu, DSPSTRIDE(display, pipe)) & stride_mask; 160 u32 stride = stride_reg; 161 162 if (GRAPHICS_VER(dev_priv) >= 9) { 163 switch (tiled) { 164 case PLANE_CTL_TILED_LINEAR: 165 stride = stride_reg * 64; 166 break; 167 case PLANE_CTL_TILED_X: 168 stride = stride_reg * 512; 169 break; 170 case PLANE_CTL_TILED_Y: 171 stride = stride_reg * 128; 172 break; 173 case PLANE_CTL_TILED_YF: 174 if (bpp == 8) 175 stride = stride_reg * 64; 176 else if (bpp == 16 || bpp == 32 || bpp == 64) 177 stride = stride_reg * 128; 178 else 179 gvt_dbg_core("skl: unsupported bpp:%d\n", bpp); 180 break; 181 default: 182 gvt_dbg_core("skl: unsupported tile format:%x\n", 183 tiled); 184 } 185 } 186 187 return stride; 188 } 189 190 static int get_active_pipe(struct intel_vgpu *vgpu) 191 { 192 int i; 193 194 for (i = 0; i < I915_MAX_PIPES; i++) 195 if (pipe_is_enabled(vgpu, i)) 196 break; 197 198 return i; 199 } 200 201 /** 202 * intel_vgpu_decode_primary_plane - Decode primary plane 203 * @vgpu: input vgpu 204 * @plane: primary plane to save decoded info 205 * This function is called for decoding plane 206 * 207 * Returns: 208 * 0 on success, non-zero if failed. 209 */ 210 int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu, 211 struct intel_vgpu_primary_plane_format *plane) 212 { 213 struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915; 214 struct intel_display *display = &dev_priv->display; 215 u32 val, fmt; 216 int pipe; 217 218 pipe = get_active_pipe(vgpu); 219 if (pipe >= I915_MAX_PIPES) 220 return -ENODEV; 221 222 val = vgpu_vreg_t(vgpu, DSPCNTR(display, pipe)); 223 plane->enabled = !!(val & DISP_ENABLE); 224 if (!plane->enabled) 225 return -ENODEV; 226 227 if (GRAPHICS_VER(dev_priv) >= 9) { 228 plane->tiled = val & PLANE_CTL_TILED_MASK; 229 fmt = skl_format_to_drm( 230 val & PLANE_CTL_FORMAT_MASK_SKL, 231 val & PLANE_CTL_ORDER_RGBX, 232 val & PLANE_CTL_ALPHA_MASK, 233 val & PLANE_CTL_YUV422_ORDER_MASK); 234 235 if (fmt >= ARRAY_SIZE(skl_pixel_formats)) { 236 gvt_vgpu_err("Out-of-bounds pixel format index\n"); 237 return -EINVAL; 238 } 239 240 plane->bpp = skl_pixel_formats[fmt].bpp; 241 plane->drm_format = skl_pixel_formats[fmt].drm_format; 242 } else { 243 plane->tiled = val & DISP_TILED; 244 fmt = bdw_format_to_drm(val & DISP_FORMAT_MASK); 245 plane->bpp = bdw_pixel_formats[fmt].bpp; 246 plane->drm_format = bdw_pixel_formats[fmt].drm_format; 247 } 248 249 if (!plane->bpp) { 250 gvt_vgpu_err("Non-supported pixel format (0x%x)\n", fmt); 251 return -EINVAL; 252 } 253 254 plane->hw_format = fmt; 255 256 plane->base = vgpu_vreg_t(vgpu, DSPSURF(display, pipe)) & I915_GTT_PAGE_MASK; 257 if (!vgpu_gmadr_is_valid(vgpu, plane->base)) 258 return -EINVAL; 259 260 plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base); 261 if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) { 262 gvt_vgpu_err("Translate primary plane gma 0x%x to gpa fail\n", 263 plane->base); 264 return -EINVAL; 265 } 266 267 plane->stride = intel_vgpu_get_stride(vgpu, pipe, plane->tiled, 268 (GRAPHICS_VER(dev_priv) >= 9) ? 269 (_PRI_PLANE_STRIDE_MASK >> 6) : 270 _PRI_PLANE_STRIDE_MASK, plane->bpp); 271 272 plane->width = (vgpu_vreg_t(vgpu, PIPESRC(display, pipe)) & _PIPE_H_SRCSZ_MASK) >> 273 _PIPE_H_SRCSZ_SHIFT; 274 plane->width += 1; 275 plane->height = (vgpu_vreg_t(vgpu, PIPESRC(display, pipe)) & 276 _PIPE_V_SRCSZ_MASK) >> _PIPE_V_SRCSZ_SHIFT; 277 plane->height += 1; /* raw height is one minus the real value */ 278 279 val = vgpu_vreg_t(vgpu, DSPTILEOFF(display, pipe)); 280 plane->x_offset = (val & _PRI_PLANE_X_OFF_MASK) >> 281 _PRI_PLANE_X_OFF_SHIFT; 282 plane->y_offset = (val & _PRI_PLANE_Y_OFF_MASK) >> 283 _PRI_PLANE_Y_OFF_SHIFT; 284 285 return 0; 286 } 287 288 #define CURSOR_FORMAT_NUM (1 << 6) 289 struct cursor_mode_format { 290 int drm_format; /* Pixel format in DRM definition */ 291 u8 bpp; /* Bits per pixel; 0 indicates invalid */ 292 u32 width; /* In pixel */ 293 u32 height; /* In lines */ 294 const char *desc; /* The description */ 295 }; 296 297 static const struct cursor_mode_format cursor_pixel_formats[] = { 298 {DRM_FORMAT_ARGB8888, 32, 128, 128, "128x128 32bpp ARGB"}, 299 {DRM_FORMAT_ARGB8888, 32, 256, 256, "256x256 32bpp ARGB"}, 300 {DRM_FORMAT_ARGB8888, 32, 64, 64, "64x64 32bpp ARGB"}, 301 {DRM_FORMAT_ARGB8888, 32, 64, 64, "64x64 32bpp ARGB"}, 302 303 /* non-supported format has bpp default to 0 */ 304 {} 305 }; 306 307 static int cursor_mode_to_drm(int mode) 308 { 309 int cursor_pixel_formats_index = 4; 310 311 switch (mode) { 312 case MCURSOR_MODE_128_ARGB_AX: 313 cursor_pixel_formats_index = 0; 314 break; 315 case MCURSOR_MODE_256_ARGB_AX: 316 cursor_pixel_formats_index = 1; 317 break; 318 case MCURSOR_MODE_64_ARGB_AX: 319 cursor_pixel_formats_index = 2; 320 break; 321 case MCURSOR_MODE_64_32B_AX: 322 cursor_pixel_formats_index = 3; 323 break; 324 325 default: 326 break; 327 } 328 329 return cursor_pixel_formats_index; 330 } 331 332 /** 333 * intel_vgpu_decode_cursor_plane - Decode sprite plane 334 * @vgpu: input vgpu 335 * @plane: cursor plane to save decoded info 336 * This function is called for decoding plane 337 * 338 * Returns: 339 * 0 on success, non-zero if failed. 340 */ 341 int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu, 342 struct intel_vgpu_cursor_plane_format *plane) 343 { 344 struct drm_i915_private *dev_priv = vgpu->gvt->gt->i915; 345 struct intel_display *display = &dev_priv->display; 346 u32 val, mode, index; 347 u32 alpha_plane, alpha_force; 348 int pipe; 349 350 pipe = get_active_pipe(vgpu); 351 if (pipe >= I915_MAX_PIPES) 352 return -ENODEV; 353 354 val = vgpu_vreg_t(vgpu, CURCNTR(display, pipe)); 355 mode = val & MCURSOR_MODE_MASK; 356 plane->enabled = (mode != MCURSOR_MODE_DISABLE); 357 if (!plane->enabled) 358 return -ENODEV; 359 360 index = cursor_mode_to_drm(mode); 361 362 if (!cursor_pixel_formats[index].bpp) { 363 gvt_vgpu_err("Non-supported cursor mode (0x%x)\n", mode); 364 return -EINVAL; 365 } 366 plane->mode = mode; 367 plane->bpp = cursor_pixel_formats[index].bpp; 368 plane->drm_format = cursor_pixel_formats[index].drm_format; 369 plane->width = cursor_pixel_formats[index].width; 370 plane->height = cursor_pixel_formats[index].height; 371 372 alpha_plane = (val & _CURSOR_ALPHA_PLANE_MASK) >> 373 _CURSOR_ALPHA_PLANE_SHIFT; 374 alpha_force = (val & _CURSOR_ALPHA_FORCE_MASK) >> 375 _CURSOR_ALPHA_FORCE_SHIFT; 376 if (alpha_plane || alpha_force) 377 gvt_dbg_core("alpha_plane=0x%x, alpha_force=0x%x\n", 378 alpha_plane, alpha_force); 379 380 plane->base = vgpu_vreg_t(vgpu, CURBASE(display, pipe)) & I915_GTT_PAGE_MASK; 381 if (!vgpu_gmadr_is_valid(vgpu, plane->base)) 382 return -EINVAL; 383 384 plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base); 385 if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) { 386 gvt_vgpu_err("Translate cursor plane gma 0x%x to gpa fail\n", 387 plane->base); 388 return -EINVAL; 389 } 390 391 val = vgpu_vreg_t(vgpu, CURPOS(display, pipe)); 392 plane->x_pos = (val & _CURSOR_POS_X_MASK) >> _CURSOR_POS_X_SHIFT; 393 plane->x_sign = (val & _CURSOR_SIGN_X_MASK) >> _CURSOR_SIGN_X_SHIFT; 394 plane->y_pos = (val & _CURSOR_POS_Y_MASK) >> _CURSOR_POS_Y_SHIFT; 395 plane->y_sign = (val & _CURSOR_SIGN_Y_MASK) >> _CURSOR_SIGN_Y_SHIFT; 396 397 plane->x_hot = vgpu_vreg_t(vgpu, vgtif_reg(cursor_x_hot)); 398 plane->y_hot = vgpu_vreg_t(vgpu, vgtif_reg(cursor_y_hot)); 399 return 0; 400 } 401