Rev 4104 | Rev 5060 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4104 | Rev 4560 | ||
---|---|---|---|
Line 102... | Line 102... | ||
102 | */ |
102 | */ |
103 | BUG(); |
103 | BUG(); |
104 | break; |
104 | break; |
105 | } |
105 | } |
Line -... | Line 106... | ||
- | 106 | ||
- | 107 | /* |
|
- | 108 | * Enable gamma to match primary/cursor plane behaviour. |
|
- | 109 | * FIXME should be user controllable via propertiesa. |
|
- | 110 | */ |
|
- | 111 | sprctl |= SP_GAMMA_ENABLE; |
|
106 | 112 | ||
107 | if (obj->tiling_mode != I915_TILING_NONE) |
113 | if (obj->tiling_mode != I915_TILING_NONE) |
Line 108... | Line 114... | ||
108 | sprctl |= SP_TILED; |
114 | sprctl |= SP_TILED; |
Line 133... | Line 139... | ||
133 | else |
139 | else |
134 | I915_WRITE(SPLINOFF(pipe, plane), linear_offset); |
140 | I915_WRITE(SPLINOFF(pipe, plane), linear_offset); |
Line 135... | Line 141... | ||
135 | 141 | ||
136 | I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); |
142 | I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); |
137 | I915_WRITE(SPCNTR(pipe, plane), sprctl); |
143 | I915_WRITE(SPCNTR(pipe, plane), sprctl); |
138 | I915_MODIFY_DISPBASE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) + |
144 | I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) + |
139 | sprsurf_offset); |
145 | sprsurf_offset); |
140 | POSTING_READ(SPSURF(pipe, plane)); |
146 | POSTING_READ(SPSURF(pipe, plane)); |
Line 141... | Line 147... | ||
141 | } |
147 | } |
Line 150... | Line 156... | ||
150 | int plane = intel_plane->plane; |
156 | int plane = intel_plane->plane; |
Line 151... | Line 157... | ||
151 | 157 | ||
152 | I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) & |
158 | I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) & |
153 | ~SP_ENABLE); |
159 | ~SP_ENABLE); |
154 | /* Activate double buffered register update */ |
160 | /* Activate double buffered register update */ |
155 | I915_MODIFY_DISPBASE(SPSURF(pipe, plane), 0); |
161 | I915_WRITE(SPSURF(pipe, plane), 0); |
Line 156... | Line 162... | ||
156 | POSTING_READ(SPSURF(pipe, plane)); |
162 | POSTING_READ(SPSURF(pipe, plane)); |
157 | 163 | ||
Line 222... | Line 228... | ||
222 | struct intel_plane *intel_plane = to_intel_plane(plane); |
228 | struct intel_plane *intel_plane = to_intel_plane(plane); |
223 | int pipe = intel_plane->pipe; |
229 | int pipe = intel_plane->pipe; |
224 | u32 sprctl, sprscale = 0; |
230 | u32 sprctl, sprscale = 0; |
225 | unsigned long sprsurf_offset, linear_offset; |
231 | unsigned long sprsurf_offset, linear_offset; |
226 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
232 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
227 | bool scaling_was_enabled = dev_priv->sprite_scaling_enabled; |
- | |
Line 228... | Line 233... | ||
228 | 233 | ||
Line 229... | Line 234... | ||
229 | sprctl = I915_READ(SPRCTL(pipe)); |
234 | sprctl = I915_READ(SPRCTL(pipe)); |
230 | 235 | ||
Line 255... | Line 260... | ||
255 | break; |
260 | break; |
256 | default: |
261 | default: |
257 | BUG(); |
262 | BUG(); |
258 | } |
263 | } |
Line -... | Line 264... | ||
- | 264 | ||
- | 265 | /* |
|
- | 266 | * Enable gamma to match primary/cursor plane behaviour. |
|
- | 267 | * FIXME should be user controllable via propertiesa. |
|
- | 268 | */ |
|
- | 269 | sprctl |= SPRITE_GAMMA_ENABLE; |
|
259 | 270 | ||
260 | if (obj->tiling_mode != I915_TILING_NONE) |
271 | if (obj->tiling_mode != I915_TILING_NONE) |
Line 261... | Line 272... | ||
261 | sprctl |= SPRITE_TILED; |
272 | sprctl |= SPRITE_TILED; |
262 | 273 | ||
263 | if (IS_HASWELL(dev)) |
274 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
264 | sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE; |
275 | sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE; |
Line 265... | Line 276... | ||
265 | else |
276 | else |
Line 266... | Line 277... | ||
266 | sprctl |= SPRITE_TRICKLE_FEED_DISABLE; |
277 | sprctl |= SPRITE_TRICKLE_FEED_DISABLE; |
267 | 278 | ||
Line 268... | Line 279... | ||
268 | sprctl |= SPRITE_ENABLE; |
279 | sprctl |= SPRITE_ENABLE; |
269 | 280 | ||
Line 277... | Line 288... | ||
277 | src_w--; |
288 | src_w--; |
278 | src_h--; |
289 | src_h--; |
279 | crtc_w--; |
290 | crtc_w--; |
280 | crtc_h--; |
291 | crtc_h--; |
Line 281... | Line -... | ||
281 | - | ||
282 | /* |
- | |
283 | * IVB workaround: must disable low power watermarks for at least |
- | |
284 | * one frame before enabling scaling. LP watermarks can be re-enabled |
- | |
285 | * when scaling is disabled. |
- | |
286 | */ |
292 | |
287 | if (crtc_w != src_w || crtc_h != src_h) { |
- | |
288 | dev_priv->sprite_scaling_enabled |= 1 << pipe; |
- | |
289 | - | ||
290 | if (!scaling_was_enabled) { |
- | |
291 | intel_update_watermarks(dev); |
- | |
292 | intel_wait_for_vblank(dev, pipe); |
- | |
293 | } |
293 | if (crtc_w != src_w || crtc_h != src_h) |
294 | sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; |
- | |
295 | } else |
- | |
Line 296... | Line 294... | ||
296 | dev_priv->sprite_scaling_enabled &= ~(1 << pipe); |
294 | sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; |
297 | 295 | ||
Line 298... | Line 296... | ||
298 | I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); |
296 | I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); |
Line 304... | Line 302... | ||
304 | pixel_size, fb->pitches[0]); |
302 | pixel_size, fb->pitches[0]); |
305 | linear_offset -= sprsurf_offset; |
303 | linear_offset -= sprsurf_offset; |
Line 306... | Line 304... | ||
306 | 304 | ||
307 | /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET |
305 | /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET |
308 | * register */ |
306 | * register */ |
309 | if (IS_HASWELL(dev)) |
307 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
310 | I915_WRITE(SPROFFSET(pipe), (y << 16) | x); |
308 | I915_WRITE(SPROFFSET(pipe), (y << 16) | x); |
311 | else if (obj->tiling_mode != I915_TILING_NONE) |
309 | else if (obj->tiling_mode != I915_TILING_NONE) |
312 | I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x); |
310 | I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x); |
313 | else |
311 | else |
Line 314... | Line 312... | ||
314 | I915_WRITE(SPRLINOFF(pipe), linear_offset); |
312 | I915_WRITE(SPRLINOFF(pipe), linear_offset); |
315 | 313 | ||
316 | I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); |
314 | I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); |
317 | if (intel_plane->can_scale) |
315 | if (intel_plane->can_scale) |
318 | I915_WRITE(SPRSCALE(pipe), sprscale); |
316 | I915_WRITE(SPRSCALE(pipe), sprscale); |
319 | I915_WRITE(SPRCTL(pipe), sprctl); |
317 | I915_WRITE(SPRCTL(pipe), sprctl); |
320 | I915_MODIFY_DISPBASE(SPRSURF(pipe), |
318 | I915_WRITE(SPRSURF(pipe), |
321 | i915_gem_obj_ggtt_offset(obj) + sprsurf_offset); |
- | |
322 | POSTING_READ(SPRSURF(pipe)); |
- | |
323 | - | ||
324 | /* potentially re-enable LP watermarks */ |
- | |
325 | if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) |
319 | i915_gem_obj_ggtt_offset(obj) + sprsurf_offset); |
Line 326... | Line 320... | ||
326 | intel_update_watermarks(dev); |
320 | POSTING_READ(SPRSURF(pipe)); |
327 | } |
321 | } |
328 | 322 | ||
329 | static void |
323 | static void |
330 | ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) |
324 | ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) |
331 | { |
325 | { |
332 | struct drm_device *dev = plane->dev; |
326 | struct drm_device *dev = plane->dev; |
333 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
Line 334... | Line 327... | ||
334 | struct intel_plane *intel_plane = to_intel_plane(plane); |
327 | struct drm_i915_private *dev_priv = dev->dev_private; |
335 | int pipe = intel_plane->pipe; |
328 | struct intel_plane *intel_plane = to_intel_plane(plane); |
336 | bool scaling_was_enabled = dev_priv->sprite_scaling_enabled; |
329 | int pipe = intel_plane->pipe; |
337 | 330 | ||
338 | I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); |
331 | I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); |
339 | /* Can't leave the scaler enabled... */ |
332 | /* Can't leave the scaler enabled... */ |
340 | if (intel_plane->can_scale) |
333 | if (intel_plane->can_scale) |
Line -... | Line 334... | ||
- | 334 | I915_WRITE(SPRSCALE(pipe), 0); |
|
341 | I915_WRITE(SPRSCALE(pipe), 0); |
335 | /* Activate double buffered register update */ |
- | 336 | I915_WRITE(SPRSURF(pipe), 0); |
|
- | 337 | POSTING_READ(SPRSURF(pipe)); |
|
- | 338 | ||
Line 342... | Line 339... | ||
342 | /* Activate double buffered register update */ |
339 | /* |
343 | I915_MODIFY_DISPBASE(SPRSURF(pipe), 0); |
- | |
344 | POSTING_READ(SPRSURF(pipe)); |
- | |
345 | - | ||
346 | dev_priv->sprite_scaling_enabled &= ~(1 << pipe); |
- | |
347 | 340 | * Avoid underruns when disabling the sprite. |
|
Line 348... | Line 341... | ||
348 | intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false); |
341 | * FIXME remove once watermark updates are done properly. |
349 | 342 | */ |
|
350 | /* potentially re-enable LP watermarks */ |
343 | intel_wait_for_vblank(dev, pipe); |
Line 451... | Line 444... | ||
451 | break; |
444 | break; |
452 | default: |
445 | default: |
453 | BUG(); |
446 | BUG(); |
454 | } |
447 | } |
Line -... | Line 448... | ||
- | 448 | ||
- | 449 | /* |
|
- | 450 | * Enable gamma to match primary/cursor plane behaviour. |
|
- | 451 | * FIXME should be user controllable via propertiesa. |
|
- | 452 | */ |
|
- | 453 | dvscntr |= DVS_GAMMA_ENABLE; |
|
455 | 454 | ||
456 | if (obj->tiling_mode != I915_TILING_NONE) |
455 | if (obj->tiling_mode != I915_TILING_NONE) |
Line 457... | Line 456... | ||
457 | dvscntr |= DVS_TILED; |
456 | dvscntr |= DVS_TILED; |
458 | 457 | ||
Line 468... | Line 467... | ||
468 | src_h--; |
467 | src_h--; |
469 | crtc_w--; |
468 | crtc_w--; |
470 | crtc_h--; |
469 | crtc_h--; |
Line 471... | Line 470... | ||
471 | 470 | ||
472 | dvsscale = 0; |
471 | dvsscale = 0; |
473 | if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h) |
472 | if (crtc_w != src_w || crtc_h != src_h) |
Line 474... | Line 473... | ||
474 | dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; |
473 | dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; |
475 | 474 | ||
Line 488... | Line 487... | ||
488 | I915_WRITE(DVSLINOFF(pipe), linear_offset); |
487 | I915_WRITE(DVSLINOFF(pipe), linear_offset); |
Line 489... | Line 488... | ||
489 | 488 | ||
490 | I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); |
489 | I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); |
491 | I915_WRITE(DVSSCALE(pipe), dvsscale); |
490 | I915_WRITE(DVSSCALE(pipe), dvsscale); |
492 | I915_WRITE(DVSCNTR(pipe), dvscntr); |
491 | I915_WRITE(DVSCNTR(pipe), dvscntr); |
493 | I915_MODIFY_DISPBASE(DVSSURF(pipe), |
492 | I915_WRITE(DVSSURF(pipe), |
494 | i915_gem_obj_ggtt_offset(obj) + dvssurf_offset); |
493 | i915_gem_obj_ggtt_offset(obj) + dvssurf_offset); |
495 | POSTING_READ(DVSSURF(pipe)); |
494 | POSTING_READ(DVSSURF(pipe)); |
Line 496... | Line 495... | ||
496 | } |
495 | } |
Line 505... | Line 504... | ||
505 | 504 | ||
506 | I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE); |
505 | I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE); |
507 | /* Disable the scaler */ |
506 | /* Disable the scaler */ |
508 | I915_WRITE(DVSSCALE(pipe), 0); |
507 | I915_WRITE(DVSSCALE(pipe), 0); |
509 | /* Flush double buffered register updates */ |
508 | /* Flush double buffered register updates */ |
510 | I915_MODIFY_DISPBASE(DVSSURF(pipe), 0); |
509 | I915_WRITE(DVSSURF(pipe), 0); |
Line -... | Line 510... | ||
- | 510 | POSTING_READ(DVSSURF(pipe)); |
|
- | 511 | ||
- | 512 | /* |
|
- | 513 | * Avoid underruns when disabling the sprite. |
|
- | 514 | * FIXME remove once watermark updates are done properly. |
|
- | 515 | */ |
|
511 | POSTING_READ(DVSSURF(pipe)); |
516 | intel_wait_for_vblank(dev, pipe); |
512 | 517 | ||
Line 513... | Line 518... | ||
513 | intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false); |
518 | intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false); |
514 | } |
519 | } |
Line 519... | Line 524... | ||
519 | struct drm_device *dev = crtc->dev; |
524 | struct drm_device *dev = crtc->dev; |
520 | struct drm_i915_private *dev_priv = dev->dev_private; |
525 | struct drm_i915_private *dev_priv = dev->dev_private; |
521 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
526 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
522 | int reg = DSPCNTR(intel_crtc->plane); |
527 | int reg = DSPCNTR(intel_crtc->plane); |
Line 523... | Line 528... | ||
523 | 528 | ||
524 | if (!intel_crtc->primary_disabled) |
529 | if (intel_crtc->primary_enabled) |
Line 525... | Line 530... | ||
525 | return; |
530 | return; |
526 | - | ||
Line 527... | Line 531... | ||
527 | intel_crtc->primary_disabled = false; |
531 | |
- | 532 | intel_crtc->primary_enabled = true; |
|
- | 533 | ||
- | 534 | I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); |
|
- | 535 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
|
- | 536 | ||
- | 537 | /* |
|
- | 538 | * FIXME IPS should be fine as long as one plane is |
|
- | 539 | * enabled, but in practice it seems to have problems |
|
- | 540 | * when going from primary only to sprite only and vice |
|
- | 541 | * versa. |
|
- | 542 | */ |
|
- | 543 | if (intel_crtc->config.ips_enabled) { |
|
- | 544 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
|
- | 545 | hsw_enable_ips(intel_crtc); |
|
- | 546 | } |
|
- | 547 | ||
528 | intel_update_fbc(dev); |
548 | mutex_lock(&dev->struct_mutex); |
Line 529... | Line 549... | ||
529 | 549 | intel_update_fbc(dev); |
|
530 | I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); |
550 | mutex_unlock(&dev->struct_mutex); |
531 | } |
551 | } |
532 | 552 | ||
533 | static void |
553 | static void |
534 | intel_disable_primary(struct drm_crtc *crtc) |
554 | intel_disable_primary(struct drm_crtc *crtc) |
535 | { |
555 | { |
Line 536... | Line 556... | ||
536 | struct drm_device *dev = crtc->dev; |
556 | struct drm_device *dev = crtc->dev; |
537 | struct drm_i915_private *dev_priv = dev->dev_private; |
557 | struct drm_i915_private *dev_priv = dev->dev_private; |
Line 538... | Line 558... | ||
538 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
558 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
Line 539... | Line 559... | ||
539 | int reg = DSPCNTR(intel_crtc->plane); |
559 | int reg = DSPCNTR(intel_crtc->plane); |
- | 560 | ||
540 | 561 | if (!intel_crtc->primary_enabled) |
|
- | 562 | return; |
|
- | 563 | ||
- | 564 | intel_crtc->primary_enabled = false; |
|
- | 565 | ||
- | 566 | mutex_lock(&dev->struct_mutex); |
|
- | 567 | if (dev_priv->fbc.plane == intel_crtc->plane) |
|
- | 568 | intel_disable_fbc(dev); |
|
- | 569 | mutex_unlock(&dev->struct_mutex); |
|
- | 570 | ||
- | 571 | /* |
|
- | 572 | * FIXME IPS should be fine as long as one plane is |
|
- | 573 | * enabled, but in practice it seems to have problems |
|
541 | if (intel_crtc->primary_disabled) |
574 | * when going from primary only to sprite only and vice |
Line 542... | Line 575... | ||
542 | return; |
575 | * versa. |
543 | 576 | */ |
|
544 | I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); |
577 | hsw_disable_ips(intel_crtc); |
Line 613... | Line 646... | ||
613 | default: |
646 | default: |
614 | return false; |
647 | return false; |
615 | } |
648 | } |
616 | } |
649 | } |
Line -... | Line 650... | ||
- | 650 | ||
- | 651 | static bool colorkey_enabled(struct intel_plane *intel_plane) |
|
- | 652 | { |
|
- | 653 | struct drm_intel_sprite_colorkey key; |
|
- | 654 | ||
- | 655 | intel_plane->get_colorkey(&intel_plane->base, &key); |
|
- | 656 | ||
- | 657 | return key.flags != I915_SET_COLORKEY_NONE; |
|
- | 658 | } |
|
617 | 659 | ||
618 | static int |
660 | static int |
619 | intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, |
661 | intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, |
620 | struct drm_framebuffer *fb, int crtc_x, int crtc_y, |
662 | struct drm_framebuffer *fb, int crtc_x, int crtc_y, |
621 | unsigned int crtc_w, unsigned int crtc_h, |
663 | unsigned int crtc_w, unsigned int crtc_h, |
622 | uint32_t src_x, uint32_t src_y, |
664 | uint32_t src_x, uint32_t src_y, |
623 | uint32_t src_w, uint32_t src_h) |
665 | uint32_t src_w, uint32_t src_h) |
624 | { |
666 | { |
625 | struct drm_device *dev = plane->dev; |
- | |
626 | struct drm_i915_private *dev_priv = dev->dev_private; |
667 | struct drm_device *dev = plane->dev; |
627 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
668 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
628 | struct intel_plane *intel_plane = to_intel_plane(plane); |
669 | struct intel_plane *intel_plane = to_intel_plane(plane); |
629 | struct intel_framebuffer *intel_fb; |
670 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
630 | struct drm_i915_gem_object *obj, *old_obj; |
671 | struct drm_i915_gem_object *obj = intel_fb->obj; |
631 | int pipe = intel_plane->pipe; |
- | |
632 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, |
- | |
633 | pipe); |
672 | struct drm_i915_gem_object *old_obj = intel_plane->obj; |
634 | int ret = 0; |
673 | int ret; |
635 | bool disable_primary = false; |
674 | bool disable_primary = false; |
636 | bool visible; |
675 | bool visible; |
637 | int hscale, vscale; |
676 | int hscale, vscale; |
638 | int max_scale, min_scale; |
677 | int max_scale, min_scale; |
Line 650... | Line 689... | ||
650 | .x2 = crtc_x + crtc_w, |
689 | .x2 = crtc_x + crtc_w, |
651 | .y1 = crtc_y, |
690 | .y1 = crtc_y, |
652 | .y2 = crtc_y + crtc_h, |
691 | .y2 = crtc_y + crtc_h, |
653 | }; |
692 | }; |
654 | const struct drm_rect clip = { |
693 | const struct drm_rect clip = { |
- | 694 | .x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0, |
|
- | 695 | .y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0, |
|
- | 696 | }; |
|
- | 697 | const struct { |
|
655 | .x2 = crtc->mode.hdisplay, |
698 | int crtc_x, crtc_y; |
- | 699 | unsigned int crtc_w, crtc_h; |
|
- | 700 | uint32_t src_x, src_y, src_w, src_h; |
|
- | 701 | } orig = { |
|
- | 702 | .crtc_x = crtc_x, |
|
656 | .y2 = crtc->mode.vdisplay, |
703 | .crtc_y = crtc_y, |
- | 704 | .crtc_w = crtc_w, |
|
- | 705 | .crtc_h = crtc_h, |
|
- | 706 | .src_x = src_x, |
|
- | 707 | .src_y = src_y, |
|
- | 708 | .src_w = src_w, |
|
- | 709 | .src_h = src_h, |
|
657 | }; |
710 | }; |
658 | - | ||
659 | intel_fb = to_intel_framebuffer(fb); |
- | |
660 | obj = intel_fb->obj; |
- | |
661 | - | ||
662 | old_obj = intel_plane->obj; |
- | |
663 | - | ||
664 | intel_plane->crtc_x = crtc_x; |
- | |
665 | intel_plane->crtc_y = crtc_y; |
- | |
666 | intel_plane->crtc_w = crtc_w; |
- | |
667 | intel_plane->crtc_h = crtc_h; |
- | |
668 | intel_plane->src_x = src_x; |
- | |
669 | intel_plane->src_y = src_y; |
- | |
670 | intel_plane->src_w = src_w; |
- | |
671 | intel_plane->src_h = src_h; |
- | |
672 | - | ||
673 | /* Pipe must be running... */ |
- | |
674 | if (!(I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE)) { |
- | |
675 | DRM_DEBUG_KMS("Pipe disabled\n"); |
- | |
676 | return -EINVAL; |
- | |
677 | } |
- | |
Line 678... | Line 711... | ||
678 | 711 | ||
679 | /* Don't modify another pipe's plane */ |
712 | /* Don't modify another pipe's plane */ |
680 | if (intel_plane->pipe != intel_crtc->pipe) { |
713 | if (intel_plane->pipe != intel_crtc->pipe) { |
681 | DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n"); |
714 | DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n"); |
Line 807... | Line 840... | ||
807 | 840 | ||
808 | /* |
841 | /* |
809 | * If the sprite is completely covering the primary plane, |
842 | * If the sprite is completely covering the primary plane, |
810 | * we can disable the primary and save power. |
843 | * we can disable the primary and save power. |
811 | */ |
844 | */ |
812 | disable_primary = drm_rect_equals(&dst, &clip); |
845 | disable_primary = drm_rect_equals(&dst, &clip) && !colorkey_enabled(intel_plane); |
Line 813... | Line 846... | ||
813 | WARN_ON(disable_primary && !visible); |
846 | WARN_ON(disable_primary && !visible && intel_crtc->active); |
Line 814... | Line 847... | ||
814 | 847 | ||
815 | mutex_lock(&dev->struct_mutex); |
848 | mutex_lock(&dev->struct_mutex); |
816 | 849 | ||
817 | /* Note that this will apply the VT-d workaround for scanouts, |
850 | /* Note that this will apply the VT-d workaround for scanouts, |
818 | * which is more restrictive than required for sprites. (The |
851 | * which is more restrictive than required for sprites. (The |
819 | * primary plane requires 256KiB alignment with 64 PTE padding, |
852 | * primary plane requires 256KiB alignment with 64 PTE padding, |
- | 853 | * the sprite planes only require 128KiB alignment and 32 PTE padding. |
|
- | 854 | */ |
|
- | 855 | ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); |
|
820 | * the sprite planes only require 128KiB alignment and 32 PTE padding. |
856 | |
821 | */ |
857 | mutex_unlock(&dev->struct_mutex); |
Line -... | Line 858... | ||
- | 858 | ||
- | 859 | if (ret) |
|
- | 860 | return ret; |
|
- | 861 | ||
- | 862 | intel_plane->crtc_x = orig.crtc_x; |
|
- | 863 | intel_plane->crtc_y = orig.crtc_y; |
|
- | 864 | intel_plane->crtc_w = orig.crtc_w; |
|
- | 865 | intel_plane->crtc_h = orig.crtc_h; |
|
822 | ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); |
866 | intel_plane->src_x = orig.src_x; |
Line -... | Line 867... | ||
- | 867 | intel_plane->src_y = orig.src_y; |
|
823 | if (ret) |
868 | intel_plane->src_w = orig.src_w; |
824 | goto out_unlock; |
869 | intel_plane->src_h = orig.src_h; |
825 | 870 | intel_plane->obj = obj; |
|
826 | intel_plane->obj = obj; |
871 | |
827 | 872 | if (intel_crtc->active) { |
|
Line 839... | Line 884... | ||
839 | else |
884 | else |
840 | intel_plane->disable_plane(plane, crtc); |
885 | intel_plane->disable_plane(plane, crtc); |
Line 841... | Line 886... | ||
841 | 886 | ||
842 | if (disable_primary) |
887 | if (disable_primary) |
- | 888 | intel_disable_primary(crtc); |
|
Line 843... | Line 889... | ||
843 | intel_disable_primary(crtc); |
889 | } |
844 | 890 | ||
845 | /* Unpin old obj after new one is active to avoid ugliness */ |
891 | /* Unpin old obj after new one is active to avoid ugliness */ |
846 | if (old_obj) { |
892 | if (old_obj) { |
847 | /* |
893 | /* |
848 | * It's fairly common to simply update the position of |
894 | * It's fairly common to simply update the position of |
849 | * an existing object. In that case, we don't need to |
895 | * an existing object. In that case, we don't need to |
850 | * wait for vblank to avoid ugliness, we only need to |
896 | * wait for vblank to avoid ugliness, we only need to |
851 | * do the pin & ref bookkeeping. |
897 | * do the pin & ref bookkeeping. |
852 | */ |
- | |
853 | if (old_obj != obj) { |
898 | */ |
- | 899 | if (old_obj != obj && intel_crtc->active) |
|
854 | mutex_unlock(&dev->struct_mutex); |
900 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
855 | intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); |
- | |
856 | mutex_lock(&dev->struct_mutex); |
901 | |
- | 902 | mutex_lock(&dev->struct_mutex); |
|
857 | } |
903 | intel_unpin_fb_obj(old_obj); |
Line 858... | Line -... | ||
858 | intel_unpin_fb_obj(old_obj); |
- | |
859 | } |
- | |
860 | 904 | mutex_unlock(&dev->struct_mutex); |
|
861 | out_unlock: |
905 | } |
Line 862... | Line 906... | ||
862 | mutex_unlock(&dev->struct_mutex); |
906 | |
863 | return ret; |
907 | return 0; |
864 | } |
908 | } |
865 | 909 | ||
866 | static int |
910 | static int |
867 | intel_disable_plane(struct drm_plane *plane) |
911 | intel_disable_plane(struct drm_plane *plane) |
Line 868... | Line 912... | ||
868 | { |
912 | { |
869 | struct drm_device *dev = plane->dev; |
913 | struct drm_device *dev = plane->dev; |
Line 870... | Line 914... | ||
870 | struct intel_plane *intel_plane = to_intel_plane(plane); |
914 | struct intel_plane *intel_plane = to_intel_plane(plane); |
871 | int ret = 0; |
915 | struct intel_crtc *intel_crtc; |
Line -... | Line 916... | ||
- | 916 | ||
- | 917 | if (!plane->fb) |
|
- | 918 | return 0; |
|
872 | 919 | ||
873 | if (!plane->fb) |
920 | if (WARN_ON(!plane->crtc)) |
- | 921 | return -EINVAL; |
|
Line 874... | Line 922... | ||
874 | return 0; |
922 | |
875 | 923 | intel_crtc = to_intel_crtc(plane->crtc); |
|
876 | if (WARN_ON(!plane->crtc)) |
- | |
877 | return -EINVAL; |
924 | |
Line 878... | Line 925... | ||
878 | 925 | if (intel_crtc->active) { |
|
879 | intel_enable_primary(plane->crtc); |
926 | intel_enable_primary(plane->crtc); |
880 | intel_plane->disable_plane(plane, plane->crtc); |
- | |
881 | 927 | intel_plane->disable_plane(plane, plane->crtc); |
|
882 | if (!intel_plane->obj) |
- | |
Line -... | Line 928... | ||
- | 928 | } |
|
- | 929 | ||
- | 930 | if (intel_plane->obj) { |
|
883 | goto out; |
931 | if (intel_crtc->active) |
884 | 932 | intel_wait_for_vblank(dev, intel_plane->pipe); |
|
Line 885... | Line 933... | ||
885 | intel_wait_for_vblank(dev, intel_plane->pipe); |
933 | |
886 | 934 | mutex_lock(&dev->struct_mutex); |
|
887 | mutex_lock(&dev->struct_mutex); |
935 | intel_unpin_fb_obj(intel_plane->obj); |
Line 919... | Line 967... | ||
919 | 967 | ||
Line 920... | Line 968... | ||
920 | drm_modeset_lock_all(dev); |
968 | drm_modeset_lock_all(dev); |
921 | 969 | ||
922 | obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE); |
970 | obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE); |
923 | if (!obj) { |
971 | if (!obj) { |
924 | ret = -EINVAL; |
972 | ret = -ENOENT; |
Line 925... | Line 973... | ||
925 | goto out_unlock; |
973 | goto out_unlock; |
926 | } |
974 | } |
Line 948... | Line 996... | ||
948 | 996 | ||
Line 949... | Line 997... | ||
949 | drm_modeset_lock_all(dev); |
997 | drm_modeset_lock_all(dev); |
950 | 998 | ||
951 | obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE); |
999 | obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE); |
952 | if (!obj) { |
1000 | if (!obj) { |
953 | ret = -EINVAL; |
1001 | ret = -ENOENT; |
Line 954... | Line 1002... | ||
954 | goto out_unlock; |
1002 | goto out_unlock; |
955 | } |
1003 | } |
Line 1032... | Line 1080... | ||
1032 | int ret; |
1080 | int ret; |
Line 1033... | Line 1081... | ||
1033 | 1081 | ||
1034 | if (INTEL_INFO(dev)->gen < 5) |
1082 | if (INTEL_INFO(dev)->gen < 5) |
Line 1035... | Line 1083... | ||
1035 | return -ENODEV; |
1083 | return -ENODEV; |
1036 | 1084 | ||
1037 | intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); |
1085 | intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL); |
Line 1038... | Line 1086... | ||
1038 | if (!intel_plane) |
1086 | if (!intel_plane) |
1039 | return -ENOMEM; |
1087 | return -ENOMEM; |
Line 1056... | Line 1104... | ||
1056 | num_plane_formats = ARRAY_SIZE(ilk_plane_formats); |
1104 | num_plane_formats = ARRAY_SIZE(ilk_plane_formats); |
1057 | } |
1105 | } |
1058 | break; |
1106 | break; |
Line 1059... | Line 1107... | ||
1059 | 1107 | ||
- | 1108 | case 7: |
|
1060 | case 7: |
1109 | case 8: |
1061 | if (IS_IVYBRIDGE(dev)) { |
1110 | if (IS_IVYBRIDGE(dev)) { |
1062 | intel_plane->can_scale = true; |
1111 | intel_plane->can_scale = true; |
1063 | intel_plane->max_downscale = 2; |
1112 | intel_plane->max_downscale = 2; |
1064 | } else { |
1113 | } else { |