diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sprite.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sprite.c | 102 |
1 files changed, 69 insertions, 33 deletions
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index e90dfb625c42..2a20fb0781d7 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -110,14 +110,18 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
110 | * when scaling is disabled. | 110 | * when scaling is disabled. |
111 | */ | 111 | */ |
112 | if (crtc_w != src_w || crtc_h != src_h) { | 112 | if (crtc_w != src_w || crtc_h != src_h) { |
113 | dev_priv->sprite_scaling_enabled = true; | 113 | if (!dev_priv->sprite_scaling_enabled) { |
114 | sandybridge_update_wm(dev); | 114 | dev_priv->sprite_scaling_enabled = true; |
115 | intel_wait_for_vblank(dev, pipe); | 115 | intel_update_watermarks(dev); |
116 | intel_wait_for_vblank(dev, pipe); | ||
117 | } | ||
116 | sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; | 118 | sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; |
117 | } else { | 119 | } else { |
118 | dev_priv->sprite_scaling_enabled = false; | 120 | if (dev_priv->sprite_scaling_enabled) { |
119 | /* potentially re-enable LP watermarks */ | 121 | dev_priv->sprite_scaling_enabled = false; |
120 | sandybridge_update_wm(dev); | 122 | /* potentially re-enable LP watermarks */ |
123 | intel_update_watermarks(dev); | ||
124 | } | ||
121 | } | 125 | } |
122 | 126 | ||
123 | I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); | 127 | I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); |
@@ -133,7 +137,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
133 | I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); | 137 | I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); |
134 | I915_WRITE(SPRSCALE(pipe), sprscale); | 138 | I915_WRITE(SPRSCALE(pipe), sprscale); |
135 | I915_WRITE(SPRCTL(pipe), sprctl); | 139 | I915_WRITE(SPRCTL(pipe), sprctl); |
136 | I915_WRITE(SPRSURF(pipe), obj->gtt_offset); | 140 | I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset); |
137 | POSTING_READ(SPRSURF(pipe)); | 141 | POSTING_READ(SPRSURF(pipe)); |
138 | } | 142 | } |
139 | 143 | ||
@@ -149,8 +153,11 @@ ivb_disable_plane(struct drm_plane *plane) | |||
149 | /* Can't leave the scaler enabled... */ | 153 | /* Can't leave the scaler enabled... */ |
150 | I915_WRITE(SPRSCALE(pipe), 0); | 154 | I915_WRITE(SPRSCALE(pipe), 0); |
151 | /* Activate double buffered register update */ | 155 | /* Activate double buffered register update */ |
152 | I915_WRITE(SPRSURF(pipe), 0); | 156 | I915_MODIFY_DISPBASE(SPRSURF(pipe), 0); |
153 | POSTING_READ(SPRSURF(pipe)); | 157 | POSTING_READ(SPRSURF(pipe)); |
158 | |||
159 | dev_priv->sprite_scaling_enabled = false; | ||
160 | intel_update_watermarks(dev); | ||
154 | } | 161 | } |
155 | 162 | ||
156 | static int | 163 | static int |
@@ -208,7 +215,7 @@ ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) | |||
208 | } | 215 | } |
209 | 216 | ||
210 | static void | 217 | static void |
211 | snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | 218 | ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, |
212 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, | 219 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
213 | unsigned int crtc_w, unsigned int crtc_h, | 220 | unsigned int crtc_w, unsigned int crtc_h, |
214 | uint32_t x, uint32_t y, | 221 | uint32_t x, uint32_t y, |
@@ -218,7 +225,7 @@ snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
218 | struct drm_i915_private *dev_priv = dev->dev_private; | 225 | struct drm_i915_private *dev_priv = dev->dev_private; |
219 | struct intel_plane *intel_plane = to_intel_plane(plane); | 226 | struct intel_plane *intel_plane = to_intel_plane(plane); |
220 | int pipe = intel_plane->pipe, pixel_size; | 227 | int pipe = intel_plane->pipe, pixel_size; |
221 | u32 dvscntr, dvsscale = 0; | 228 | u32 dvscntr, dvsscale; |
222 | 229 | ||
223 | dvscntr = I915_READ(DVSCNTR(pipe)); | 230 | dvscntr = I915_READ(DVSCNTR(pipe)); |
224 | 231 | ||
@@ -262,8 +269,8 @@ snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
262 | if (obj->tiling_mode != I915_TILING_NONE) | 269 | if (obj->tiling_mode != I915_TILING_NONE) |
263 | dvscntr |= DVS_TILED; | 270 | dvscntr |= DVS_TILED; |
264 | 271 | ||
265 | /* must disable */ | 272 | if (IS_GEN6(dev)) |
266 | dvscntr |= DVS_TRICKLE_FEED_DISABLE; | 273 | dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ |
267 | dvscntr |= DVS_ENABLE; | 274 | dvscntr |= DVS_ENABLE; |
268 | 275 | ||
269 | /* Sizes are 0 based */ | 276 | /* Sizes are 0 based */ |
@@ -274,7 +281,8 @@ snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
274 | 281 | ||
275 | intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); | 282 | intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); |
276 | 283 | ||
277 | if (crtc_w != src_w || crtc_h != src_h) | 284 | dvsscale = 0; |
285 | if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h) | ||
278 | dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; | 286 | dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; |
279 | 287 | ||
280 | I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); | 288 | I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); |
@@ -290,12 +298,12 @@ snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
290 | I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); | 298 | I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); |
291 | I915_WRITE(DVSSCALE(pipe), dvsscale); | 299 | I915_WRITE(DVSSCALE(pipe), dvsscale); |
292 | I915_WRITE(DVSCNTR(pipe), dvscntr); | 300 | I915_WRITE(DVSCNTR(pipe), dvscntr); |
293 | I915_WRITE(DVSSURF(pipe), obj->gtt_offset); | 301 | I915_MODIFY_DISPBASE(DVSSURF(pipe), obj->gtt_offset); |
294 | POSTING_READ(DVSSURF(pipe)); | 302 | POSTING_READ(DVSSURF(pipe)); |
295 | } | 303 | } |
296 | 304 | ||
297 | static void | 305 | static void |
298 | snb_disable_plane(struct drm_plane *plane) | 306 | ilk_disable_plane(struct drm_plane *plane) |
299 | { | 307 | { |
300 | struct drm_device *dev = plane->dev; | 308 | struct drm_device *dev = plane->dev; |
301 | struct drm_i915_private *dev_priv = dev->dev_private; | 309 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -306,7 +314,7 @@ snb_disable_plane(struct drm_plane *plane) | |||
306 | /* Disable the scaler */ | 314 | /* Disable the scaler */ |
307 | I915_WRITE(DVSSCALE(pipe), 0); | 315 | I915_WRITE(DVSSCALE(pipe), 0); |
308 | /* Flush double buffered register updates */ | 316 | /* Flush double buffered register updates */ |
309 | I915_WRITE(DVSSURF(pipe), 0); | 317 | I915_MODIFY_DISPBASE(DVSSURF(pipe), 0); |
310 | POSTING_READ(DVSSURF(pipe)); | 318 | POSTING_READ(DVSSURF(pipe)); |
311 | } | 319 | } |
312 | 320 | ||
@@ -333,7 +341,7 @@ intel_disable_primary(struct drm_crtc *crtc) | |||
333 | } | 341 | } |
334 | 342 | ||
335 | static int | 343 | static int |
336 | snb_update_colorkey(struct drm_plane *plane, | 344 | ilk_update_colorkey(struct drm_plane *plane, |
337 | struct drm_intel_sprite_colorkey *key) | 345 | struct drm_intel_sprite_colorkey *key) |
338 | { | 346 | { |
339 | struct drm_device *dev = plane->dev; | 347 | struct drm_device *dev = plane->dev; |
@@ -362,7 +370,7 @@ snb_update_colorkey(struct drm_plane *plane, | |||
362 | } | 370 | } |
363 | 371 | ||
364 | static void | 372 | static void |
365 | snb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) | 373 | ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) |
366 | { | 374 | { |
367 | struct drm_device *dev = plane->dev; | 375 | struct drm_device *dev = plane->dev; |
368 | struct drm_i915_private *dev_priv = dev->dev_private; | 376 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -550,14 +558,13 @@ int intel_sprite_set_colorkey(struct drm_device *dev, void *data, | |||
550 | struct drm_file *file_priv) | 558 | struct drm_file *file_priv) |
551 | { | 559 | { |
552 | struct drm_intel_sprite_colorkey *set = data; | 560 | struct drm_intel_sprite_colorkey *set = data; |
553 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
554 | struct drm_mode_object *obj; | 561 | struct drm_mode_object *obj; |
555 | struct drm_plane *plane; | 562 | struct drm_plane *plane; |
556 | struct intel_plane *intel_plane; | 563 | struct intel_plane *intel_plane; |
557 | int ret = 0; | 564 | int ret = 0; |
558 | 565 | ||
559 | if (!dev_priv) | 566 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
560 | return -EINVAL; | 567 | return -ENODEV; |
561 | 568 | ||
562 | /* Make sure we don't try to enable both src & dest simultaneously */ | 569 | /* Make sure we don't try to enable both src & dest simultaneously */ |
563 | if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) | 570 | if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) |
@@ -584,14 +591,13 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data, | |||
584 | struct drm_file *file_priv) | 591 | struct drm_file *file_priv) |
585 | { | 592 | { |
586 | struct drm_intel_sprite_colorkey *get = data; | 593 | struct drm_intel_sprite_colorkey *get = data; |
587 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
588 | struct drm_mode_object *obj; | 594 | struct drm_mode_object *obj; |
589 | struct drm_plane *plane; | 595 | struct drm_plane *plane; |
590 | struct intel_plane *intel_plane; | 596 | struct intel_plane *intel_plane; |
591 | int ret = 0; | 597 | int ret = 0; |
592 | 598 | ||
593 | if (!dev_priv) | 599 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
594 | return -EINVAL; | 600 | return -ENODEV; |
595 | 601 | ||
596 | mutex_lock(&dev->mode_config.mutex); | 602 | mutex_lock(&dev->mode_config.mutex); |
597 | 603 | ||
@@ -616,6 +622,14 @@ static const struct drm_plane_funcs intel_plane_funcs = { | |||
616 | .destroy = intel_destroy_plane, | 622 | .destroy = intel_destroy_plane, |
617 | }; | 623 | }; |
618 | 624 | ||
625 | static uint32_t ilk_plane_formats[] = { | ||
626 | DRM_FORMAT_XRGB8888, | ||
627 | DRM_FORMAT_YUYV, | ||
628 | DRM_FORMAT_YVYU, | ||
629 | DRM_FORMAT_UYVY, | ||
630 | DRM_FORMAT_VYUY, | ||
631 | }; | ||
632 | |||
619 | static uint32_t snb_plane_formats[] = { | 633 | static uint32_t snb_plane_formats[] = { |
620 | DRM_FORMAT_XBGR8888, | 634 | DRM_FORMAT_XBGR8888, |
621 | DRM_FORMAT_XRGB8888, | 635 | DRM_FORMAT_XRGB8888, |
@@ -630,34 +644,56 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) | |||
630 | { | 644 | { |
631 | struct intel_plane *intel_plane; | 645 | struct intel_plane *intel_plane; |
632 | unsigned long possible_crtcs; | 646 | unsigned long possible_crtcs; |
647 | const uint32_t *plane_formats; | ||
648 | int num_plane_formats; | ||
633 | int ret; | 649 | int ret; |
634 | 650 | ||
635 | if (!(IS_GEN6(dev) || IS_GEN7(dev))) | 651 | if (INTEL_INFO(dev)->gen < 5) |
636 | return -ENODEV; | 652 | return -ENODEV; |
637 | 653 | ||
638 | intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); | 654 | intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); |
639 | if (!intel_plane) | 655 | if (!intel_plane) |
640 | return -ENOMEM; | 656 | return -ENOMEM; |
641 | 657 | ||
642 | if (IS_GEN6(dev)) { | 658 | switch (INTEL_INFO(dev)->gen) { |
659 | case 5: | ||
660 | case 6: | ||
643 | intel_plane->max_downscale = 16; | 661 | intel_plane->max_downscale = 16; |
644 | intel_plane->update_plane = snb_update_plane; | 662 | intel_plane->update_plane = ilk_update_plane; |
645 | intel_plane->disable_plane = snb_disable_plane; | 663 | intel_plane->disable_plane = ilk_disable_plane; |
646 | intel_plane->update_colorkey = snb_update_colorkey; | 664 | intel_plane->update_colorkey = ilk_update_colorkey; |
647 | intel_plane->get_colorkey = snb_get_colorkey; | 665 | intel_plane->get_colorkey = ilk_get_colorkey; |
648 | } else if (IS_GEN7(dev)) { | 666 | |
667 | if (IS_GEN6(dev)) { | ||
668 | plane_formats = snb_plane_formats; | ||
669 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); | ||
670 | } else { | ||
671 | plane_formats = ilk_plane_formats; | ||
672 | num_plane_formats = ARRAY_SIZE(ilk_plane_formats); | ||
673 | } | ||
674 | break; | ||
675 | |||
676 | case 7: | ||
649 | intel_plane->max_downscale = 2; | 677 | intel_plane->max_downscale = 2; |
650 | intel_plane->update_plane = ivb_update_plane; | 678 | intel_plane->update_plane = ivb_update_plane; |
651 | intel_plane->disable_plane = ivb_disable_plane; | 679 | intel_plane->disable_plane = ivb_disable_plane; |
652 | intel_plane->update_colorkey = ivb_update_colorkey; | 680 | intel_plane->update_colorkey = ivb_update_colorkey; |
653 | intel_plane->get_colorkey = ivb_get_colorkey; | 681 | intel_plane->get_colorkey = ivb_get_colorkey; |
682 | |||
683 | plane_formats = snb_plane_formats; | ||
684 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); | ||
685 | break; | ||
686 | |||
687 | default: | ||
688 | return -ENODEV; | ||
654 | } | 689 | } |
655 | 690 | ||
656 | intel_plane->pipe = pipe; | 691 | intel_plane->pipe = pipe; |
657 | possible_crtcs = (1 << pipe); | 692 | possible_crtcs = (1 << pipe); |
658 | ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs, | 693 | ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs, |
659 | &intel_plane_funcs, snb_plane_formats, | 694 | &intel_plane_funcs, |
660 | ARRAY_SIZE(snb_plane_formats), false); | 695 | plane_formats, num_plane_formats, |
696 | false); | ||
661 | if (ret) | 697 | if (ret) |
662 | kfree(intel_plane); | 698 | kfree(intel_plane); |
663 | 699 | ||