1 /* 2 * Copyright © 2009 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 * Daniel Vetter <daniel@ffwll.ch> 25 * 26 * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c 27 * $FreeBSD: src/sys/dev/drm2/i915/intel_overlay.c,v 1.1 2012/05/22 11:07:44 kib Exp $ 28 */ 29 30 #include <drm/drmP.h> 31 #include <drm/i915_drm.h> 32 #include "i915_drv.h" 33 #include "i915_reg.h" 34 #include "intel_drv.h" 35 36 /* Limits for overlay size. According to intel doc, the real limits are: 37 * Y width: 4095, UV width (planar): 2047, Y height: 2047, 38 * UV width (planar): * 1023. But the xorg thinks 2048 for height and width. Use 39 * the mininum of both. */ 40 #define IMAGE_MAX_WIDTH 2048 41 #define IMAGE_MAX_HEIGHT 2046 /* 2 * 1023 */ 42 /* on 830 and 845 these large limits result in the card hanging */ 43 #define IMAGE_MAX_WIDTH_LEGACY 1024 44 #define IMAGE_MAX_HEIGHT_LEGACY 1088 45 46 /* overlay register definitions */ 47 /* OCMD register */ 48 #define OCMD_TILED_SURFACE (0x1<<19) 49 #define OCMD_MIRROR_MASK (0x3<<17) 50 #define OCMD_MIRROR_MODE (0x3<<17) 51 #define OCMD_MIRROR_HORIZONTAL (0x1<<17) 52 #define OCMD_MIRROR_VERTICAL (0x2<<17) 53 #define OCMD_MIRROR_BOTH (0x3<<17) 54 #define OCMD_BYTEORDER_MASK (0x3<<14) /* zero for YUYV or FOURCC YUY2 */ 55 #define OCMD_UV_SWAP (0x1<<14) /* YVYU */ 56 #define OCMD_Y_SWAP (0x2<<14) /* UYVY or FOURCC UYVY */ 57 #define OCMD_Y_AND_UV_SWAP (0x3<<14) /* VYUY */ 58 #define OCMD_SOURCE_FORMAT_MASK (0xf<<10) 59 #define OCMD_RGB_888 (0x1<<10) /* not in i965 Intel docs */ 60 #define OCMD_RGB_555 (0x2<<10) /* not in i965 Intel docs */ 61 #define OCMD_RGB_565 (0x3<<10) /* not in i965 Intel docs */ 62 #define OCMD_YUV_422_PACKED (0x8<<10) 63 #define OCMD_YUV_411_PACKED (0x9<<10) /* not in i965 Intel docs */ 64 #define OCMD_YUV_420_PLANAR (0xc<<10) 65 #define OCMD_YUV_422_PLANAR (0xd<<10) 66 #define OCMD_YUV_410_PLANAR (0xe<<10) /* also 411 */ 67 #define OCMD_TVSYNCFLIP_PARITY (0x1<<9) 68 #define OCMD_TVSYNCFLIP_ENABLE (0x1<<7) 69 #define OCMD_BUF_TYPE_MASK (0x1<<5) 70 #define OCMD_BUF_TYPE_FRAME (0x0<<5) 71 #define OCMD_BUF_TYPE_FIELD (0x1<<5) 72 #define OCMD_TEST_MODE (0x1<<4) 73 #define OCMD_BUFFER_SELECT (0x3<<2) 74 #define OCMD_BUFFER0 (0x0<<2) 75 #define OCMD_BUFFER1 (0x1<<2) 76 #define OCMD_FIELD_SELECT (0x1<<2) 77 #define OCMD_FIELD0 (0x0<<1) 78 #define OCMD_FIELD1 (0x1<<1) 79 #define OCMD_ENABLE (0x1<<0) 80 81 /* OCONFIG register */ 82 #define OCONF_PIPE_MASK (0x1<<18) 83 #define OCONF_PIPE_A (0x0<<18) 84 #define OCONF_PIPE_B (0x1<<18) 85 #define OCONF_GAMMA2_ENABLE (0x1<<16) 86 #define OCONF_CSC_MODE_BT601 (0x0<<5) 87 #define OCONF_CSC_MODE_BT709 (0x1<<5) 88 #define OCONF_CSC_BYPASS (0x1<<4) 89 #define OCONF_CC_OUT_8BIT (0x1<<3) 90 #define OCONF_TEST_MODE (0x1<<2) 91 #define OCONF_THREE_LINE_BUFFER (0x1<<0) 92 #define OCONF_TWO_LINE_BUFFER (0x0<<0) 93 94 /* DCLRKM (dst-key) register */ 95 #define DST_KEY_ENABLE (0x1<<31) 96 #define CLK_RGB24_MASK 0x0 97 #define CLK_RGB16_MASK 0x070307 98 #define CLK_RGB15_MASK 0x070707 99 #define CLK_RGB8I_MASK 0xffffff 100 101 #define RGB16_TO_COLORKEY(c) \ 102 (((c & 0xF800) << 8) | ((c & 0x07E0) << 5) | ((c & 0x001F) << 3)) 103 #define RGB15_TO_COLORKEY(c) \ 104 (((c & 0x7c00) << 9) | ((c & 0x03E0) << 6) | ((c & 0x001F) << 3)) 105 106 /* overlay flip addr flag */ 107 #define OFC_UPDATE 0x1 108 109 /* polyphase filter coefficients */ 110 #define N_HORIZ_Y_TAPS 5 111 #define N_VERT_Y_TAPS 3 112 #define N_HORIZ_UV_TAPS 3 113 #define N_VERT_UV_TAPS 3 114 #define N_PHASES 17 115 #define MAX_TAPS 5 116 117 /* memory bufferd overlay registers */ 118 struct overlay_registers { 119 u32 OBUF_0Y; 120 u32 OBUF_1Y; 121 u32 OBUF_0U; 122 u32 OBUF_0V; 123 u32 OBUF_1U; 124 u32 OBUF_1V; 125 u32 OSTRIDE; 126 u32 YRGB_VPH; 127 u32 UV_VPH; 128 u32 HORZ_PH; 129 u32 INIT_PHS; 130 u32 DWINPOS; 131 u32 DWINSZ; 132 u32 SWIDTH; 133 u32 SWIDTHSW; 134 u32 SHEIGHT; 135 u32 YRGBSCALE; 136 u32 UVSCALE; 137 u32 OCLRC0; 138 u32 OCLRC1; 139 u32 DCLRKV; 140 u32 DCLRKM; 141 u32 SCLRKVH; 142 u32 SCLRKVL; 143 u32 SCLRKEN; 144 u32 OCONFIG; 145 u32 OCMD; 146 u32 RESERVED1; /* 0x6C */ 147 u32 OSTART_0Y; 148 u32 OSTART_1Y; 149 u32 OSTART_0U; 150 u32 OSTART_0V; 151 u32 OSTART_1U; 152 u32 OSTART_1V; 153 u32 OTILEOFF_0Y; 154 u32 OTILEOFF_1Y; 155 u32 OTILEOFF_0U; 156 u32 OTILEOFF_0V; 157 u32 OTILEOFF_1U; 158 u32 OTILEOFF_1V; 159 u32 FASTHSCALE; /* 0xA0 */ 160 u32 UVSCALEV; /* 0xA4 */ 161 u32 RESERVEDC[(0x200 - 0xA8) / 4]; /* 0xA8 - 0x1FC */ 162 u16 Y_VCOEFS[N_VERT_Y_TAPS * N_PHASES]; /* 0x200 */ 163 u16 RESERVEDD[0x100 / 2 - N_VERT_Y_TAPS * N_PHASES]; 164 u16 Y_HCOEFS[N_HORIZ_Y_TAPS * N_PHASES]; /* 0x300 */ 165 u16 RESERVEDE[0x200 / 2 - N_HORIZ_Y_TAPS * N_PHASES]; 166 u16 UV_VCOEFS[N_VERT_UV_TAPS * N_PHASES]; /* 0x500 */ 167 u16 RESERVEDF[0x100 / 2 - N_VERT_UV_TAPS * N_PHASES]; 168 u16 UV_HCOEFS[N_HORIZ_UV_TAPS * N_PHASES]; /* 0x600 */ 169 u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES]; 170 }; 171 172 struct intel_overlay { 173 struct drm_device *dev; 174 struct intel_crtc *crtc; 175 struct drm_i915_gem_object *vid_bo; 176 struct drm_i915_gem_object *old_vid_bo; 177 int active; 178 int pfit_active; 179 u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */ 180 u32 color_key; 181 u32 brightness, contrast, saturation; 182 u32 old_xscale, old_yscale; 183 /* register access */ 184 u32 flip_addr; 185 struct drm_i915_gem_object *reg_bo; 186 /* flip handling */ 187 uint32_t last_flip_req; 188 void (*flip_tail)(struct intel_overlay *); 189 }; 190 191 static struct overlay_registers * 192 intel_overlay_map_regs(struct intel_overlay *overlay) 193 { 194 struct overlay_registers *regs; 195 196 if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) { 197 regs = overlay->reg_bo->phys_obj->handle->vaddr; 198 } else { 199 regs = pmap_mapdev_attr(overlay->dev->agp->base + 200 overlay->reg_bo->gtt_offset, PAGE_SIZE, 201 PAT_WRITE_COMBINING); 202 } 203 return (regs); 204 } 205 206 static void intel_overlay_unmap_regs(struct intel_overlay *overlay, 207 struct overlay_registers *regs) 208 { 209 if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev)) 210 pmap_unmapdev((vm_offset_t)regs, PAGE_SIZE); 211 } 212 213 static int intel_overlay_do_wait_request(struct intel_overlay *overlay, 214 void (*tail)(struct intel_overlay *)) 215 { 216 struct drm_device *dev = overlay->dev; 217 drm_i915_private_t *dev_priv = dev->dev_private; 218 struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; 219 int ret; 220 221 BUG_ON(overlay->last_flip_req); 222 ret = i915_add_request(ring, NULL, &overlay->last_flip_req); 223 if (ret) 224 return ret; 225 226 overlay->flip_tail = tail; 227 ret = i915_wait_seqno(ring, overlay->last_flip_req); 228 if (ret) 229 return ret; 230 i915_gem_retire_requests(dev); 231 232 overlay->last_flip_req = 0; 233 return 0; 234 } 235 236 /* overlay needs to be disable in OCMD reg */ 237 static int intel_overlay_on(struct intel_overlay *overlay) 238 { 239 struct drm_device *dev = overlay->dev; 240 struct drm_i915_private *dev_priv = dev->dev_private; 241 struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; 242 int ret; 243 244 BUG_ON(overlay->active); 245 overlay->active = 1; 246 247 WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE)); 248 249 ret = intel_ring_begin(ring, 4); 250 if (ret) 251 return ret; 252 253 intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON); 254 intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE); 255 intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 256 intel_ring_emit(ring, MI_NOOP); 257 intel_ring_advance(ring); 258 259 return intel_overlay_do_wait_request(overlay, NULL); 260 } 261 262 /* overlay needs to be enabled in OCMD reg */ 263 static int intel_overlay_continue(struct intel_overlay *overlay, 264 bool load_polyphase_filter) 265 { 266 struct drm_device *dev = overlay->dev; 267 drm_i915_private_t *dev_priv = dev->dev_private; 268 struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; 269 u32 flip_addr = overlay->flip_addr; 270 u32 tmp; 271 int ret; 272 273 BUG_ON(!overlay->active); 274 275 if (load_polyphase_filter) 276 flip_addr |= OFC_UPDATE; 277 278 /* check for underruns */ 279 tmp = I915_READ(DOVSTA); 280 if (tmp & (1 << 17)) 281 DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); 282 283 ret = intel_ring_begin(ring, 2); 284 if (ret) 285 return ret; 286 287 intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); 288 intel_ring_emit(ring, flip_addr); 289 intel_ring_advance(ring); 290 291 return i915_add_request(ring, NULL, &overlay->last_flip_req); 292 } 293 294 static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay) 295 { 296 struct drm_i915_gem_object *obj = overlay->old_vid_bo; 297 298 i915_gem_object_unpin(obj); 299 drm_gem_object_unreference(&obj->base); 300 301 overlay->old_vid_bo = NULL; 302 } 303 304 static void intel_overlay_off_tail(struct intel_overlay *overlay) 305 { 306 struct drm_i915_gem_object *obj = overlay->vid_bo; 307 308 /* never have the overlay hw on without showing a frame */ 309 KASSERT(overlay->vid_bo != NULL, ("No vid_bo")); 310 311 i915_gem_object_unpin(obj); 312 drm_gem_object_unreference(&obj->base); 313 overlay->vid_bo = NULL; 314 315 overlay->crtc->overlay = NULL; 316 overlay->crtc = NULL; 317 overlay->active = 0; 318 } 319 320 /* overlay needs to be disabled in OCMD reg */ 321 static int intel_overlay_off(struct intel_overlay *overlay) 322 { 323 struct drm_device *dev = overlay->dev; 324 struct drm_i915_private *dev_priv = dev->dev_private; 325 struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; 326 u32 flip_addr = overlay->flip_addr; 327 int ret; 328 329 BUG_ON(!overlay->active); 330 331 /* According to intel docs the overlay hw may hang (when switching 332 * off) without loading the filter coeffs. It is however unclear whether 333 * this applies to the disabling of the overlay or to the switching off 334 * of the hw. Do it in both cases */ 335 flip_addr |= OFC_UPDATE; 336 337 ret = intel_ring_begin(ring, 6); 338 if (ret) 339 return ret; 340 341 /* wait for overlay to go idle */ 342 intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); 343 intel_ring_emit(ring, flip_addr); 344 intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 345 /* turn overlay off */ 346 intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_OFF); 347 intel_ring_emit(ring, flip_addr); 348 intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 349 intel_ring_advance(ring); 350 351 return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail); 352 } 353 354 /* recover from an interruption due to a signal 355 * We have to be careful not to repeat work forever an make forward progess. */ 356 static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay) 357 { 358 struct drm_device *dev = overlay->dev; 359 drm_i915_private_t *dev_priv = dev->dev_private; 360 struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; 361 int ret; 362 363 if (overlay->last_flip_req == 0) 364 return 0; 365 366 ret = i915_wait_seqno(ring, overlay->last_flip_req); 367 if (ret) 368 return ret; 369 i915_gem_retire_requests(dev); 370 371 if (overlay->flip_tail) 372 overlay->flip_tail(overlay); 373 374 overlay->last_flip_req = 0; 375 return 0; 376 } 377 378 /* Wait for pending overlay flip and release old frame. 379 * Needs to be called before the overlay register are changed 380 * via intel_overlay_(un)map_regs 381 */ 382 static int intel_overlay_release_old_vid(struct intel_overlay *overlay) 383 { 384 struct drm_device *dev = overlay->dev; 385 drm_i915_private_t *dev_priv = dev->dev_private; 386 struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; 387 int ret; 388 389 /* Only wait if there is actually an old frame to release to 390 * guarantee forward progress. 391 */ 392 if (!overlay->old_vid_bo) 393 return 0; 394 395 if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) { 396 /* synchronous slowpath */ 397 ret = intel_ring_begin(ring, 2); 398 if (ret) 399 return ret; 400 401 intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 402 intel_ring_emit(ring, MI_NOOP); 403 intel_ring_advance(ring); 404 405 ret = intel_overlay_do_wait_request(overlay, 406 intel_overlay_release_old_vid_tail); 407 if (ret) 408 return ret; 409 } 410 411 intel_overlay_release_old_vid_tail(overlay); 412 return 0; 413 } 414 415 struct put_image_params { 416 int format; 417 short dst_x; 418 short dst_y; 419 short dst_w; 420 short dst_h; 421 short src_w; 422 short src_scan_h; 423 short src_scan_w; 424 short src_h; 425 short stride_Y; 426 short stride_UV; 427 int offset_Y; 428 int offset_U; 429 int offset_V; 430 }; 431 432 static int packed_depth_bytes(u32 format) 433 { 434 switch (format & I915_OVERLAY_DEPTH_MASK) { 435 case I915_OVERLAY_YUV422: 436 return 4; 437 case I915_OVERLAY_YUV411: 438 /* return 6; not implemented */ 439 default: 440 return -EINVAL; 441 } 442 } 443 444 static int packed_width_bytes(u32 format, short width) 445 { 446 switch (format & I915_OVERLAY_DEPTH_MASK) { 447 case I915_OVERLAY_YUV422: 448 return width << 1; 449 default: 450 return -EINVAL; 451 } 452 } 453 454 static int uv_hsubsampling(u32 format) 455 { 456 switch (format & I915_OVERLAY_DEPTH_MASK) { 457 case I915_OVERLAY_YUV422: 458 case I915_OVERLAY_YUV420: 459 return 2; 460 case I915_OVERLAY_YUV411: 461 case I915_OVERLAY_YUV410: 462 return 4; 463 default: 464 return -EINVAL; 465 } 466 } 467 468 static int uv_vsubsampling(u32 format) 469 { 470 switch (format & I915_OVERLAY_DEPTH_MASK) { 471 case I915_OVERLAY_YUV420: 472 case I915_OVERLAY_YUV410: 473 return 2; 474 case I915_OVERLAY_YUV422: 475 case I915_OVERLAY_YUV411: 476 return 1; 477 default: 478 return -EINVAL; 479 } 480 } 481 482 static u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width) 483 { 484 u32 mask, shift, ret; 485 if (IS_GEN2(dev)) { 486 mask = 0x1f; 487 shift = 5; 488 } else { 489 mask = 0x3f; 490 shift = 6; 491 } 492 ret = ((offset + width + mask) >> shift) - (offset >> shift); 493 if (!IS_GEN2(dev)) 494 ret <<= 1; 495 ret -= 1; 496 return ret << 2; 497 } 498 499 static const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = { 500 0x3000, 0xb4a0, 0x1930, 0x1920, 0xb4a0, 501 0x3000, 0xb500, 0x19d0, 0x1880, 0xb440, 502 0x3000, 0xb540, 0x1a88, 0x2f80, 0xb3e0, 503 0x3000, 0xb580, 0x1b30, 0x2e20, 0xb380, 504 0x3000, 0xb5c0, 0x1bd8, 0x2cc0, 0xb320, 505 0x3020, 0xb5e0, 0x1c60, 0x2b80, 0xb2c0, 506 0x3020, 0xb5e0, 0x1cf8, 0x2a20, 0xb260, 507 0x3020, 0xb5e0, 0x1d80, 0x28e0, 0xb200, 508 0x3020, 0xb5c0, 0x1e08, 0x3f40, 0xb1c0, 509 0x3020, 0xb580, 0x1e78, 0x3ce0, 0xb160, 510 0x3040, 0xb520, 0x1ed8, 0x3aa0, 0xb120, 511 0x3040, 0xb4a0, 0x1f30, 0x3880, 0xb0e0, 512 0x3040, 0xb400, 0x1f78, 0x3680, 0xb0a0, 513 0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060, 514 0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040, 515 0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020, 516 0xb000, 0x3000, 0x0800, 0x3000, 0xb000 517 }; 518 519 static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = { 520 0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60, 521 0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40, 522 0xb040, 0x1b20, 0x29e0, 0xb060, 0x1bd8, 0x2880, 523 0xb080, 0x1c88, 0x3e60, 0xb0a0, 0x1d28, 0x3c00, 524 0xb0c0, 0x1db8, 0x39e0, 0xb0e0, 0x1e40, 0x37e0, 525 0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0, 526 0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240, 527 0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0, 528 0x3000, 0x0800, 0x3000 529 }; 530 531 static void update_polyphase_filter(struct overlay_registers *regs) 532 { 533 memcpy(regs->Y_HCOEFS, y_static_hcoeffs, sizeof(y_static_hcoeffs)); 534 memcpy(regs->UV_HCOEFS, uv_static_hcoeffs, sizeof(uv_static_hcoeffs)); 535 } 536 537 static bool update_scaling_factors(struct intel_overlay *overlay, 538 struct overlay_registers *regs, 539 struct put_image_params *params) 540 { 541 /* fixed point with a 12 bit shift */ 542 u32 xscale, yscale, xscale_UV, yscale_UV; 543 #define FP_SHIFT 12 544 #define FRACT_MASK 0xfff 545 bool scale_changed = false; 546 int uv_hscale = uv_hsubsampling(params->format); 547 int uv_vscale = uv_vsubsampling(params->format); 548 549 if (params->dst_w > 1) 550 xscale = ((params->src_scan_w - 1) << FP_SHIFT) 551 /(params->dst_w); 552 else 553 xscale = 1 << FP_SHIFT; 554 555 if (params->dst_h > 1) 556 yscale = ((params->src_scan_h - 1) << FP_SHIFT) 557 /(params->dst_h); 558 else 559 yscale = 1 << FP_SHIFT; 560 561 /*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/ 562 xscale_UV = xscale/uv_hscale; 563 yscale_UV = yscale/uv_vscale; 564 /* make the Y scale to UV scale ratio an exact multiply */ 565 xscale = xscale_UV * uv_hscale; 566 yscale = yscale_UV * uv_vscale; 567 /*} else { 568 xscale_UV = 0; 569 yscale_UV = 0; 570 }*/ 571 572 if (xscale != overlay->old_xscale || yscale != overlay->old_yscale) 573 scale_changed = true; 574 overlay->old_xscale = xscale; 575 overlay->old_yscale = yscale; 576 577 regs->YRGBSCALE = (((yscale & FRACT_MASK) << 20) | 578 ((xscale >> FP_SHIFT) << 16) | 579 ((xscale & FRACT_MASK) << 3)); 580 581 regs->UVSCALE = (((yscale_UV & FRACT_MASK) << 20) | 582 ((xscale_UV >> FP_SHIFT) << 16) | 583 ((xscale_UV & FRACT_MASK) << 3)); 584 585 regs->UVSCALEV = ((((yscale >> FP_SHIFT) << 16) | 586 ((yscale_UV >> FP_SHIFT) << 0))); 587 588 if (scale_changed) 589 update_polyphase_filter(regs); 590 591 return scale_changed; 592 } 593 594 static void update_colorkey(struct intel_overlay *overlay, 595 struct overlay_registers *regs) 596 { 597 u32 key = overlay->color_key; 598 599 switch (overlay->crtc->base.fb->bits_per_pixel) { 600 case 8: 601 regs->DCLRKV = 0; 602 regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE; 603 break; 604 605 case 16: 606 if (overlay->crtc->base.fb->depth == 15) { 607 regs->DCLRKV = RGB15_TO_COLORKEY(key); 608 regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE; 609 } else { 610 regs->DCLRKV = RGB16_TO_COLORKEY(key); 611 regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE; 612 } 613 break; 614 615 case 24: 616 case 32: 617 regs->DCLRKV = key; 618 regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE; 619 break; 620 } 621 } 622 623 static u32 overlay_cmd_reg(struct put_image_params *params) 624 { 625 u32 cmd = OCMD_ENABLE | OCMD_BUF_TYPE_FRAME | OCMD_BUFFER0; 626 627 if (params->format & I915_OVERLAY_YUV_PLANAR) { 628 switch (params->format & I915_OVERLAY_DEPTH_MASK) { 629 case I915_OVERLAY_YUV422: 630 cmd |= OCMD_YUV_422_PLANAR; 631 break; 632 case I915_OVERLAY_YUV420: 633 cmd |= OCMD_YUV_420_PLANAR; 634 break; 635 case I915_OVERLAY_YUV411: 636 case I915_OVERLAY_YUV410: 637 cmd |= OCMD_YUV_410_PLANAR; 638 break; 639 } 640 } else { /* YUV packed */ 641 switch (params->format & I915_OVERLAY_DEPTH_MASK) { 642 case I915_OVERLAY_YUV422: 643 cmd |= OCMD_YUV_422_PACKED; 644 break; 645 case I915_OVERLAY_YUV411: 646 cmd |= OCMD_YUV_411_PACKED; 647 break; 648 } 649 650 switch (params->format & I915_OVERLAY_SWAP_MASK) { 651 case I915_OVERLAY_NO_SWAP: 652 break; 653 case I915_OVERLAY_UV_SWAP: 654 cmd |= OCMD_UV_SWAP; 655 break; 656 case I915_OVERLAY_Y_SWAP: 657 cmd |= OCMD_Y_SWAP; 658 break; 659 case I915_OVERLAY_Y_AND_UV_SWAP: 660 cmd |= OCMD_Y_AND_UV_SWAP; 661 break; 662 } 663 } 664 665 return cmd; 666 } 667 668 static u32 669 max_u32(u32 a, u32 b) 670 { 671 672 return (a > b ? a : b); 673 } 674 675 static int intel_overlay_do_put_image(struct intel_overlay *overlay, 676 struct drm_i915_gem_object *new_bo, 677 struct put_image_params *params) 678 { 679 int ret, tmp_width; 680 struct overlay_registers *regs; 681 bool scale_changed = false; 682 683 KASSERT(overlay != NULL, ("No overlay ?")); 684 DRM_LOCK_ASSERT(overlay->dev); 685 686 ret = intel_overlay_release_old_vid(overlay); 687 if (ret != 0) 688 return ret; 689 690 ret = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL); 691 if (ret != 0) 692 goto out_unpin; 693 694 ret = i915_gem_object_put_fence(new_bo); 695 if (ret) 696 goto out_unpin; 697 698 if (!overlay->active) { 699 regs = intel_overlay_map_regs(overlay); 700 if (!regs) { 701 ret = -ENOMEM; 702 goto out_unpin; 703 } 704 regs->OCONFIG = OCONF_CC_OUT_8BIT; 705 if (IS_GEN4(overlay->dev)) 706 regs->OCONFIG |= OCONF_CSC_MODE_BT709; 707 regs->OCONFIG |= overlay->crtc->pipe == 0 ? 708 OCONF_PIPE_A : OCONF_PIPE_B; 709 intel_overlay_unmap_regs(overlay, regs); 710 711 ret = intel_overlay_on(overlay); 712 if (ret != 0) 713 goto out_unpin; 714 } 715 716 regs = intel_overlay_map_regs(overlay); 717 if (!regs) { 718 ret = -ENOMEM; 719 goto out_unpin; 720 } 721 722 regs->DWINPOS = (params->dst_y << 16) | params->dst_x; 723 regs->DWINSZ = (params->dst_h << 16) | params->dst_w; 724 725 if (params->format & I915_OVERLAY_YUV_PACKED) 726 tmp_width = packed_width_bytes(params->format, params->src_w); 727 else 728 tmp_width = params->src_w; 729 730 regs->SWIDTH = params->src_w; 731 regs->SWIDTHSW = calc_swidthsw(overlay->dev, 732 params->offset_Y, tmp_width); 733 regs->SHEIGHT = params->src_h; 734 regs->OBUF_0Y = new_bo->gtt_offset + params->offset_Y; 735 regs->OSTRIDE = params->stride_Y; 736 737 if (params->format & I915_OVERLAY_YUV_PLANAR) { 738 int uv_hscale = uv_hsubsampling(params->format); 739 int uv_vscale = uv_vsubsampling(params->format); 740 u32 tmp_U, tmp_V; 741 regs->SWIDTH |= (params->src_w/uv_hscale) << 16; 742 tmp_U = calc_swidthsw(overlay->dev, params->offset_U, 743 params->src_w/uv_hscale); 744 tmp_V = calc_swidthsw(overlay->dev, params->offset_V, 745 params->src_w/uv_hscale); 746 regs->SWIDTHSW |= max_u32(tmp_U, tmp_V) << 16; 747 regs->SHEIGHT |= (params->src_h/uv_vscale) << 16; 748 regs->OBUF_0U = new_bo->gtt_offset + params->offset_U; 749 regs->OBUF_0V = new_bo->gtt_offset + params->offset_V; 750 regs->OSTRIDE |= params->stride_UV << 16; 751 } 752 753 scale_changed = update_scaling_factors(overlay, regs, params); 754 755 update_colorkey(overlay, regs); 756 757 regs->OCMD = overlay_cmd_reg(params); 758 759 intel_overlay_unmap_regs(overlay, regs); 760 761 ret = intel_overlay_continue(overlay, scale_changed); 762 if (ret) 763 goto out_unpin; 764 765 overlay->old_vid_bo = overlay->vid_bo; 766 overlay->vid_bo = new_bo; 767 768 return 0; 769 770 out_unpin: 771 i915_gem_object_unpin(new_bo); 772 return ret; 773 } 774 775 int intel_overlay_switch_off(struct intel_overlay *overlay) 776 { 777 struct overlay_registers *regs; 778 int ret; 779 780 DRM_LOCK_ASSERT(overlay->dev); 781 782 ret = intel_overlay_recover_from_interrupt(overlay); 783 if (ret != 0) 784 return ret; 785 786 if (!overlay->active) 787 return 0; 788 789 ret = intel_overlay_release_old_vid(overlay); 790 if (ret != 0) 791 return ret; 792 793 regs = intel_overlay_map_regs(overlay); 794 regs->OCMD = 0; 795 intel_overlay_unmap_regs(overlay, regs); 796 797 ret = intel_overlay_off(overlay); 798 if (ret != 0) 799 return ret; 800 801 intel_overlay_off_tail(overlay); 802 return 0; 803 } 804 805 static int check_overlay_possible_on_crtc(struct intel_overlay *overlay, 806 struct intel_crtc *crtc) 807 { 808 drm_i915_private_t *dev_priv = overlay->dev->dev_private; 809 810 if (!crtc->active) 811 return -EINVAL; 812 813 /* can't use the overlay with double wide pipe */ 814 if (INTEL_INFO(overlay->dev)->gen < 4 && 815 (I915_READ(PIPECONF(crtc->pipe)) & (PIPECONF_DOUBLE_WIDE | PIPECONF_ENABLE)) != PIPECONF_ENABLE) 816 return -EINVAL; 817 818 return 0; 819 } 820 821 static void update_pfit_vscale_ratio(struct intel_overlay *overlay) 822 { 823 struct drm_device *dev = overlay->dev; 824 drm_i915_private_t *dev_priv = dev->dev_private; 825 u32 pfit_control = I915_READ(PFIT_CONTROL); 826 u32 ratio; 827 828 /* XXX: This is not the same logic as in the xorg driver, but more in 829 * line with the intel documentation for the i965 830 */ 831 if (INTEL_INFO(dev)->gen >= 4) { 832 /* on i965 use the PGM reg to read out the autoscaler values */ 833 ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965; 834 } else { 835 if (pfit_control & VERT_AUTO_SCALE) 836 ratio = I915_READ(PFIT_AUTO_RATIOS); 837 else 838 ratio = I915_READ(PFIT_PGM_RATIOS); 839 ratio >>= PFIT_VERT_SCALE_SHIFT; 840 } 841 842 overlay->pfit_vscale_ratio = ratio; 843 } 844 845 static int check_overlay_dst(struct intel_overlay *overlay, 846 struct drm_intel_overlay_put_image *rec) 847 { 848 struct drm_display_mode *mode = &overlay->crtc->base.mode; 849 850 if (rec->dst_x < mode->hdisplay && 851 rec->dst_x + rec->dst_width <= mode->hdisplay && 852 rec->dst_y < mode->vdisplay && 853 rec->dst_y + rec->dst_height <= mode->vdisplay) 854 return 0; 855 else 856 return -EINVAL; 857 } 858 859 static int check_overlay_scaling(struct put_image_params *rec) 860 { 861 u32 tmp; 862 863 /* downscaling limit is 8.0 */ 864 tmp = ((rec->src_scan_h << 16) / rec->dst_h) >> 16; 865 if (tmp > 7) 866 return -EINVAL; 867 tmp = ((rec->src_scan_w << 16) / rec->dst_w) >> 16; 868 if (tmp > 7) 869 return -EINVAL; 870 871 return 0; 872 } 873 874 static int check_overlay_src(struct drm_device *dev, 875 struct drm_intel_overlay_put_image *rec, 876 struct drm_i915_gem_object *new_bo) 877 { 878 int uv_hscale = uv_hsubsampling(rec->flags); 879 int uv_vscale = uv_vsubsampling(rec->flags); 880 u32 stride_mask; 881 int depth; 882 u32 tmp; 883 884 /* check src dimensions */ 885 if (IS_845G(dev) || IS_I830(dev)) { 886 if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY || 887 rec->src_width > IMAGE_MAX_WIDTH_LEGACY) 888 return -EINVAL; 889 } else { 890 if (rec->src_height > IMAGE_MAX_HEIGHT || 891 rec->src_width > IMAGE_MAX_WIDTH) 892 return -EINVAL; 893 } 894 895 /* better safe than sorry, use 4 as the maximal subsampling ratio */ 896 if (rec->src_height < N_VERT_Y_TAPS*4 || 897 rec->src_width < N_HORIZ_Y_TAPS*4) 898 return -EINVAL; 899 900 /* check alignment constraints */ 901 switch (rec->flags & I915_OVERLAY_TYPE_MASK) { 902 case I915_OVERLAY_RGB: 903 /* not implemented */ 904 return -EINVAL; 905 906 case I915_OVERLAY_YUV_PACKED: 907 if (uv_vscale != 1) 908 return -EINVAL; 909 910 depth = packed_depth_bytes(rec->flags); 911 if (depth < 0) 912 return depth; 913 914 /* ignore UV planes */ 915 rec->stride_UV = 0; 916 rec->offset_U = 0; 917 rec->offset_V = 0; 918 /* check pixel alignment */ 919 if (rec->offset_Y % depth) 920 return -EINVAL; 921 break; 922 923 case I915_OVERLAY_YUV_PLANAR: 924 if (uv_vscale < 0 || uv_hscale < 0) 925 return -EINVAL; 926 /* no offset restrictions for planar formats */ 927 break; 928 929 default: 930 return -EINVAL; 931 } 932 933 if (rec->src_width % uv_hscale) 934 return -EINVAL; 935 936 /* stride checking */ 937 if (IS_I830(dev) || IS_845G(dev)) 938 stride_mask = 255; 939 else 940 stride_mask = 63; 941 942 if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask) 943 return -EINVAL; 944 if (IS_GEN4(dev) && rec->stride_Y < 512) 945 return -EINVAL; 946 947 tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ? 948 4096 : 8192; 949 if (rec->stride_Y > tmp || rec->stride_UV > 2*1024) 950 return -EINVAL; 951 952 /* check buffer dimensions */ 953 switch (rec->flags & I915_OVERLAY_TYPE_MASK) { 954 case I915_OVERLAY_RGB: 955 case I915_OVERLAY_YUV_PACKED: 956 /* always 4 Y values per depth pixels */ 957 if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y) 958 return -EINVAL; 959 960 tmp = rec->stride_Y*rec->src_height; 961 if (rec->offset_Y + tmp > new_bo->base.size) 962 return -EINVAL; 963 break; 964 965 case I915_OVERLAY_YUV_PLANAR: 966 if (rec->src_width > rec->stride_Y) 967 return -EINVAL; 968 if (rec->src_width/uv_hscale > rec->stride_UV) 969 return -EINVAL; 970 971 tmp = rec->stride_Y * rec->src_height; 972 if (rec->offset_Y + tmp > new_bo->base.size) 973 return -EINVAL; 974 975 tmp = rec->stride_UV * (rec->src_height / uv_vscale); 976 if (rec->offset_U + tmp > new_bo->base.size || 977 rec->offset_V + tmp > new_bo->base.size) 978 return -EINVAL; 979 break; 980 } 981 982 return 0; 983 } 984 985 /** 986 * Return the pipe currently connected to the panel fitter, 987 * or -1 if the panel fitter is not present or not in use 988 */ 989 static int intel_panel_fitter_pipe(struct drm_device *dev) 990 { 991 struct drm_i915_private *dev_priv = dev->dev_private; 992 u32 pfit_control; 993 994 /* i830 doesn't have a panel fitter */ 995 if (IS_I830(dev)) 996 return -1; 997 998 pfit_control = I915_READ(PFIT_CONTROL); 999 1000 /* See if the panel fitter is in use */ 1001 if ((pfit_control & PFIT_ENABLE) == 0) 1002 return -1; 1003 1004 /* 965 can place panel fitter on either pipe */ 1005 if (IS_GEN4(dev)) 1006 return (pfit_control >> 29) & 0x3; 1007 1008 /* older chips can only use pipe 1 */ 1009 return 1; 1010 } 1011 1012 int intel_overlay_put_image(struct drm_device *dev, void *data, 1013 struct drm_file *file_priv) 1014 { 1015 struct drm_intel_overlay_put_image *put_image_rec = data; 1016 drm_i915_private_t *dev_priv = dev->dev_private; 1017 struct intel_overlay *overlay; 1018 struct drm_mode_object *drmmode_obj; 1019 struct intel_crtc *crtc; 1020 struct drm_i915_gem_object *new_bo; 1021 struct put_image_params *params; 1022 int ret; 1023 1024 if (!dev_priv) { 1025 DRM_ERROR("called with no initialization\n"); 1026 return -EINVAL; 1027 } 1028 1029 overlay = dev_priv->overlay; 1030 if (!overlay) { 1031 DRM_DEBUG("userspace bug: no overlay\n"); 1032 return -ENODEV; 1033 } 1034 1035 if (!(put_image_rec->flags & I915_OVERLAY_ENABLE)) { 1036 lockmgr(&dev->mode_config.mutex, LK_EXCLUSIVE); 1037 DRM_LOCK(dev); 1038 1039 ret = intel_overlay_switch_off(overlay); 1040 1041 DRM_UNLOCK(dev); 1042 lockmgr(&dev->mode_config.mutex, LK_RELEASE); 1043 1044 return ret; 1045 } 1046 1047 params = kmalloc(sizeof(struct put_image_params), DRM_I915_GEM, 1048 M_WAITOK | M_ZERO); 1049 1050 drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id, 1051 DRM_MODE_OBJECT_CRTC); 1052 if (!drmmode_obj) { 1053 ret = -ENOENT; 1054 goto out_free; 1055 } 1056 crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); 1057 1058 new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv, 1059 put_image_rec->bo_handle)); 1060 if (&new_bo->base == NULL) { 1061 ret = -ENOENT; 1062 goto out_free; 1063 } 1064 1065 lockmgr(&dev->mode_config.mutex, LK_EXCLUSIVE); 1066 DRM_LOCK(dev); 1067 1068 if (new_bo->tiling_mode) { 1069 DRM_ERROR("buffer used for overlay image can not be tiled\n"); 1070 ret = -EINVAL; 1071 goto out_unlock; 1072 } 1073 1074 ret = intel_overlay_recover_from_interrupt(overlay); 1075 if (ret != 0) 1076 goto out_unlock; 1077 1078 if (overlay->crtc != crtc) { 1079 struct drm_display_mode *mode = &crtc->base.mode; 1080 ret = intel_overlay_switch_off(overlay); 1081 if (ret != 0) 1082 goto out_unlock; 1083 1084 ret = check_overlay_possible_on_crtc(overlay, crtc); 1085 if (ret != 0) 1086 goto out_unlock; 1087 1088 overlay->crtc = crtc; 1089 crtc->overlay = overlay; 1090 1091 /* line too wide, i.e. one-line-mode */ 1092 if (mode->hdisplay > 1024 && 1093 intel_panel_fitter_pipe(dev) == crtc->pipe) { 1094 overlay->pfit_active = 1; 1095 update_pfit_vscale_ratio(overlay); 1096 } else 1097 overlay->pfit_active = 0; 1098 } 1099 1100 ret = check_overlay_dst(overlay, put_image_rec); 1101 if (ret != 0) 1102 goto out_unlock; 1103 1104 if (overlay->pfit_active) { 1105 params->dst_y = ((((u32)put_image_rec->dst_y) << 12) / 1106 overlay->pfit_vscale_ratio); 1107 /* shifting right rounds downwards, so add 1 */ 1108 params->dst_h = ((((u32)put_image_rec->dst_height) << 12) / 1109 overlay->pfit_vscale_ratio) + 1; 1110 } else { 1111 params->dst_y = put_image_rec->dst_y; 1112 params->dst_h = put_image_rec->dst_height; 1113 } 1114 params->dst_x = put_image_rec->dst_x; 1115 params->dst_w = put_image_rec->dst_width; 1116 1117 params->src_w = put_image_rec->src_width; 1118 params->src_h = put_image_rec->src_height; 1119 params->src_scan_w = put_image_rec->src_scan_width; 1120 params->src_scan_h = put_image_rec->src_scan_height; 1121 if (params->src_scan_h > params->src_h || 1122 params->src_scan_w > params->src_w) { 1123 ret = -EINVAL; 1124 goto out_unlock; 1125 } 1126 1127 ret = check_overlay_src(dev, put_image_rec, new_bo); 1128 if (ret != 0) 1129 goto out_unlock; 1130 params->format = put_image_rec->flags & ~I915_OVERLAY_FLAGS_MASK; 1131 params->stride_Y = put_image_rec->stride_Y; 1132 params->stride_UV = put_image_rec->stride_UV; 1133 params->offset_Y = put_image_rec->offset_Y; 1134 params->offset_U = put_image_rec->offset_U; 1135 params->offset_V = put_image_rec->offset_V; 1136 1137 /* Check scaling after src size to prevent a divide-by-zero. */ 1138 ret = check_overlay_scaling(params); 1139 if (ret != 0) 1140 goto out_unlock; 1141 1142 ret = intel_overlay_do_put_image(overlay, new_bo, params); 1143 if (ret != 0) 1144 goto out_unlock; 1145 1146 DRM_UNLOCK(dev); 1147 lockmgr(&dev->mode_config.mutex, LK_RELEASE); 1148 1149 drm_free(params, DRM_I915_GEM); 1150 1151 return 0; 1152 1153 out_unlock: 1154 DRM_UNLOCK(dev); 1155 lockmgr(&dev->mode_config.mutex, LK_RELEASE); 1156 drm_gem_object_unreference_unlocked(&new_bo->base); 1157 out_free: 1158 drm_free(params, DRM_I915_GEM); 1159 1160 return ret; 1161 } 1162 1163 static void update_reg_attrs(struct intel_overlay *overlay, 1164 struct overlay_registers *regs) 1165 { 1166 regs->OCLRC0 = (overlay->contrast << 18) | (overlay->brightness & 0xff); 1167 regs->OCLRC1 = overlay->saturation; 1168 } 1169 1170 static bool check_gamma_bounds(u32 gamma1, u32 gamma2) 1171 { 1172 int i; 1173 1174 if (gamma1 & 0xff000000 || gamma2 & 0xff000000) 1175 return false; 1176 1177 for (i = 0; i < 3; i++) { 1178 if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff)) 1179 return false; 1180 } 1181 1182 return true; 1183 } 1184 1185 static bool check_gamma5_errata(u32 gamma5) 1186 { 1187 int i; 1188 1189 for (i = 0; i < 3; i++) { 1190 if (((gamma5 >> i*8) & 0xff) == 0x80) 1191 return false; 1192 } 1193 1194 return true; 1195 } 1196 1197 static int check_gamma(struct drm_intel_overlay_attrs *attrs) 1198 { 1199 if (!check_gamma_bounds(0, attrs->gamma0) || 1200 !check_gamma_bounds(attrs->gamma0, attrs->gamma1) || 1201 !check_gamma_bounds(attrs->gamma1, attrs->gamma2) || 1202 !check_gamma_bounds(attrs->gamma2, attrs->gamma3) || 1203 !check_gamma_bounds(attrs->gamma3, attrs->gamma4) || 1204 !check_gamma_bounds(attrs->gamma4, attrs->gamma5) || 1205 !check_gamma_bounds(attrs->gamma5, 0x00ffffff)) 1206 return -EINVAL; 1207 1208 if (!check_gamma5_errata(attrs->gamma5)) 1209 return -EINVAL; 1210 1211 return 0; 1212 } 1213 1214 int intel_overlay_attrs(struct drm_device *dev, void *data, 1215 struct drm_file *file_priv) 1216 { 1217 struct drm_intel_overlay_attrs *attrs = data; 1218 drm_i915_private_t *dev_priv = dev->dev_private; 1219 struct intel_overlay *overlay; 1220 struct overlay_registers *regs; 1221 int ret; 1222 1223 if (!dev_priv) { 1224 DRM_ERROR("called with no initialization\n"); 1225 return -EINVAL; 1226 } 1227 1228 overlay = dev_priv->overlay; 1229 if (!overlay) { 1230 DRM_DEBUG("userspace bug: no overlay\n"); 1231 return -ENODEV; 1232 } 1233 1234 lockmgr(&dev->mode_config.mutex, LK_EXCLUSIVE); 1235 DRM_LOCK(dev); 1236 1237 ret = -EINVAL; 1238 if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) { 1239 attrs->color_key = overlay->color_key; 1240 attrs->brightness = overlay->brightness; 1241 attrs->contrast = overlay->contrast; 1242 attrs->saturation = overlay->saturation; 1243 1244 if (!IS_GEN2(dev)) { 1245 attrs->gamma0 = I915_READ(OGAMC0); 1246 attrs->gamma1 = I915_READ(OGAMC1); 1247 attrs->gamma2 = I915_READ(OGAMC2); 1248 attrs->gamma3 = I915_READ(OGAMC3); 1249 attrs->gamma4 = I915_READ(OGAMC4); 1250 attrs->gamma5 = I915_READ(OGAMC5); 1251 } 1252 } else { 1253 if (attrs->brightness < -128 || attrs->brightness > 127) 1254 goto out_unlock; 1255 if (attrs->contrast > 255) 1256 goto out_unlock; 1257 if (attrs->saturation > 1023) 1258 goto out_unlock; 1259 1260 overlay->color_key = attrs->color_key; 1261 overlay->brightness = attrs->brightness; 1262 overlay->contrast = attrs->contrast; 1263 overlay->saturation = attrs->saturation; 1264 1265 regs = intel_overlay_map_regs(overlay); 1266 if (!regs) { 1267 ret = -ENOMEM; 1268 goto out_unlock; 1269 } 1270 1271 update_reg_attrs(overlay, regs); 1272 1273 intel_overlay_unmap_regs(overlay, regs); 1274 1275 if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) { 1276 if (IS_GEN2(dev)) 1277 goto out_unlock; 1278 1279 if (overlay->active) { 1280 ret = -EBUSY; 1281 goto out_unlock; 1282 } 1283 1284 ret = check_gamma(attrs); 1285 if (ret) 1286 goto out_unlock; 1287 1288 I915_WRITE(OGAMC0, attrs->gamma0); 1289 I915_WRITE(OGAMC1, attrs->gamma1); 1290 I915_WRITE(OGAMC2, attrs->gamma2); 1291 I915_WRITE(OGAMC3, attrs->gamma3); 1292 I915_WRITE(OGAMC4, attrs->gamma4); 1293 I915_WRITE(OGAMC5, attrs->gamma5); 1294 } 1295 } 1296 1297 ret = 0; 1298 out_unlock: 1299 DRM_UNLOCK(dev); 1300 lockmgr(&dev->mode_config.mutex, LK_RELEASE); 1301 1302 return ret; 1303 } 1304 1305 void intel_setup_overlay(struct drm_device *dev) 1306 { 1307 drm_i915_private_t *dev_priv = dev->dev_private; 1308 struct intel_overlay *overlay; 1309 struct drm_i915_gem_object *reg_bo; 1310 struct overlay_registers *regs; 1311 int ret; 1312 1313 if (!HAS_OVERLAY(dev)) 1314 return; 1315 1316 overlay = kmalloc(sizeof(struct intel_overlay), DRM_I915_GEM, 1317 M_WAITOK | M_ZERO); 1318 DRM_LOCK(dev); 1319 if (dev_priv->overlay != NULL) 1320 goto out_free; 1321 overlay->dev = dev; 1322 1323 reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); 1324 if (!reg_bo) 1325 goto out_free; 1326 overlay->reg_bo = reg_bo; 1327 1328 if (OVERLAY_NEEDS_PHYSICAL(dev)) { 1329 ret = i915_gem_attach_phys_object(dev, reg_bo, 1330 I915_GEM_PHYS_OVERLAY_REGS, 1331 PAGE_SIZE); 1332 if (ret) { 1333 DRM_ERROR("failed to attach phys overlay regs\n"); 1334 goto out_free_bo; 1335 } 1336 overlay->flip_addr = reg_bo->phys_obj->handle->busaddr; 1337 } else { 1338 ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true); 1339 if (ret) { 1340 DRM_ERROR("failed to pin overlay register bo\n"); 1341 goto out_free_bo; 1342 } 1343 overlay->flip_addr = reg_bo->gtt_offset; 1344 1345 ret = i915_gem_object_set_to_gtt_domain(reg_bo, true); 1346 if (ret) { 1347 DRM_ERROR("failed to move overlay register bo into the GTT\n"); 1348 goto out_unpin_bo; 1349 } 1350 } 1351 1352 /* init all values */ 1353 overlay->color_key = 0x0101fe; 1354 overlay->brightness = -19; 1355 overlay->contrast = 75; 1356 overlay->saturation = 146; 1357 1358 regs = intel_overlay_map_regs(overlay); 1359 if (!regs) 1360 goto out_unpin_bo; 1361 1362 memset(regs, 0, sizeof(struct overlay_registers)); 1363 update_polyphase_filter(regs); 1364 update_reg_attrs(overlay, regs); 1365 1366 intel_overlay_unmap_regs(overlay, regs); 1367 1368 dev_priv->overlay = overlay; 1369 DRM_INFO("initialized overlay support\n"); 1370 DRM_UNLOCK(dev); 1371 return; 1372 1373 out_unpin_bo: 1374 if (!OVERLAY_NEEDS_PHYSICAL(dev)) 1375 i915_gem_object_unpin(reg_bo); 1376 out_free_bo: 1377 drm_gem_object_unreference(®_bo->base); 1378 out_free: 1379 DRM_UNLOCK(dev); 1380 drm_free(overlay, DRM_I915_GEM); 1381 return; 1382 } 1383 1384 void intel_cleanup_overlay(struct drm_device *dev) 1385 { 1386 drm_i915_private_t *dev_priv = dev->dev_private; 1387 1388 if (!dev_priv->overlay) 1389 return; 1390 1391 /* The bo's should be free'd by the generic code already. 1392 * Furthermore modesetting teardown happens beforehand so the 1393 * hardware should be off already */ 1394 KASSERT(!dev_priv->overlay->active, ("Overlay still active")); 1395 1396 drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base); 1397 drm_free(dev_priv->overlay, DRM_I915_GEM); 1398 } 1399 1400 struct intel_overlay_error_state { 1401 struct overlay_registers regs; 1402 unsigned long base; 1403 u32 dovsta; 1404 u32 isr; 1405 }; 1406 1407 struct intel_overlay_error_state * 1408 intel_overlay_capture_error_state(struct drm_device *dev) 1409 { 1410 drm_i915_private_t *dev_priv = dev->dev_private; 1411 struct intel_overlay *overlay = dev_priv->overlay; 1412 struct intel_overlay_error_state *error; 1413 struct overlay_registers __iomem *regs; 1414 1415 if (!overlay || !overlay->active) 1416 return NULL; 1417 1418 error = kmalloc(sizeof(*error), DRM_I915_GEM, M_NOWAIT); 1419 if (error == NULL) 1420 return NULL; 1421 1422 error->dovsta = I915_READ(DOVSTA); 1423 error->isr = I915_READ(ISR); 1424 if (OVERLAY_NEEDS_PHYSICAL(overlay->dev)) 1425 error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr; 1426 else 1427 error->base = (long) overlay->reg_bo->gtt_offset; 1428 1429 regs = intel_overlay_map_regs(overlay); 1430 if (!regs) 1431 goto err; 1432 1433 memcpy(&error->regs, regs, sizeof(struct overlay_registers)); 1434 intel_overlay_unmap_regs(overlay, regs); 1435 1436 return (error); 1437 1438 err: 1439 drm_free(error, DRM_I915_GEM); 1440 return (NULL); 1441 } 1442 1443 void 1444 intel_overlay_print_error_state(struct sbuf *m, 1445 struct intel_overlay_error_state *error) 1446 { 1447 sbuf_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n", 1448 error->dovsta, error->isr); 1449 sbuf_printf(m, " Register file at 0x%08lx:\n", 1450 error->base); 1451 1452 #define P(x) sbuf_printf(m, " " #x ": 0x%08x\n", error->regs.x) 1453 P(OBUF_0Y); 1454 P(OBUF_1Y); 1455 P(OBUF_0U); 1456 P(OBUF_0V); 1457 P(OBUF_1U); 1458 P(OBUF_1V); 1459 P(OSTRIDE); 1460 P(YRGB_VPH); 1461 P(UV_VPH); 1462 P(HORZ_PH); 1463 P(INIT_PHS); 1464 P(DWINPOS); 1465 P(DWINSZ); 1466 P(SWIDTH); 1467 P(SWIDTHSW); 1468 P(SHEIGHT); 1469 P(YRGBSCALE); 1470 P(UVSCALE); 1471 P(OCLRC0); 1472 P(OCLRC1); 1473 P(DCLRKV); 1474 P(DCLRKM); 1475 P(SCLRKVH); 1476 P(SCLRKVL); 1477 P(SCLRKEN); 1478 P(OCONFIG); 1479 P(OCMD); 1480 P(OSTART_0Y); 1481 P(OSTART_1Y); 1482 P(OSTART_0U); 1483 P(OSTART_0V); 1484 P(OSTART_1U); 1485 P(OSTART_1V); 1486 P(OTILEOFF_0Y); 1487 P(OTILEOFF_1Y); 1488 P(OTILEOFF_0U); 1489 P(OTILEOFF_0V); 1490 P(OTILEOFF_1U); 1491 P(OTILEOFF_1V); 1492 P(FASTHSCALE); 1493 P(UVSCALEV); 1494 #undef P 1495 } 1496