Rev 3482 | Rev 4104 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3482 | Rev 3746 | ||
---|---|---|---|
Line 35... | Line 35... | ||
35 | #include "intel_drv.h" |
35 | #include "intel_drv.h" |
36 | #include |
36 | #include |
37 | #include "i915_drv.h" |
37 | #include "i915_drv.h" |
Line 38... | Line 38... | ||
38 | 38 | ||
- | 39 | static void |
|
- | 40 | vlv_update_plane(struct drm_plane *dplane, struct drm_framebuffer *fb, |
|
- | 41 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
|
- | 42 | unsigned int crtc_w, unsigned int crtc_h, |
|
- | 43 | uint32_t x, uint32_t y, |
|
- | 44 | uint32_t src_w, uint32_t src_h) |
|
- | 45 | { |
|
- | 46 | struct drm_device *dev = dplane->dev; |
|
- | 47 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 48 | struct intel_plane *intel_plane = to_intel_plane(dplane); |
|
- | 49 | int pipe = intel_plane->pipe; |
|
- | 50 | int plane = intel_plane->plane; |
|
- | 51 | u32 sprctl; |
|
- | 52 | unsigned long sprsurf_offset, linear_offset; |
|
- | 53 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
|
- | 54 | ||
- | 55 | sprctl = I915_READ(SPCNTR(pipe, plane)); |
|
- | 56 | ||
- | 57 | /* Mask out pixel format bits in case we change it */ |
|
- | 58 | sprctl &= ~SP_PIXFORMAT_MASK; |
|
- | 59 | sprctl &= ~SP_YUV_BYTE_ORDER_MASK; |
|
- | 60 | sprctl &= ~SP_TILED; |
|
- | 61 | ||
- | 62 | switch (fb->pixel_format) { |
|
- | 63 | case DRM_FORMAT_YUYV: |
|
- | 64 | sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV; |
|
- | 65 | break; |
|
- | 66 | case DRM_FORMAT_YVYU: |
|
- | 67 | sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU; |
|
- | 68 | break; |
|
- | 69 | case DRM_FORMAT_UYVY: |
|
- | 70 | sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY; |
|
- | 71 | break; |
|
- | 72 | case DRM_FORMAT_VYUY: |
|
- | 73 | sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY; |
|
- | 74 | break; |
|
- | 75 | case DRM_FORMAT_RGB565: |
|
- | 76 | sprctl |= SP_FORMAT_BGR565; |
|
- | 77 | break; |
|
- | 78 | case DRM_FORMAT_XRGB8888: |
|
- | 79 | sprctl |= SP_FORMAT_BGRX8888; |
|
- | 80 | break; |
|
- | 81 | case DRM_FORMAT_ARGB8888: |
|
- | 82 | sprctl |= SP_FORMAT_BGRA8888; |
|
- | 83 | break; |
|
- | 84 | case DRM_FORMAT_XBGR2101010: |
|
- | 85 | sprctl |= SP_FORMAT_RGBX1010102; |
|
- | 86 | break; |
|
- | 87 | case DRM_FORMAT_ABGR2101010: |
|
- | 88 | sprctl |= SP_FORMAT_RGBA1010102; |
|
- | 89 | break; |
|
- | 90 | case DRM_FORMAT_XBGR8888: |
|
- | 91 | sprctl |= SP_FORMAT_RGBX8888; |
|
- | 92 | break; |
|
- | 93 | case DRM_FORMAT_ABGR8888: |
|
- | 94 | sprctl |= SP_FORMAT_RGBA8888; |
|
- | 95 | break; |
|
- | 96 | default: |
|
- | 97 | /* |
|
- | 98 | * If we get here one of the upper layers failed to filter |
|
- | 99 | * out the unsupported plane formats |
|
- | 100 | */ |
|
- | 101 | BUG(); |
|
- | 102 | break; |
|
- | 103 | } |
|
- | 104 | ||
- | 105 | if (obj->tiling_mode != I915_TILING_NONE) |
|
- | 106 | sprctl |= SP_TILED; |
|
- | 107 | ||
- | 108 | sprctl |= SP_ENABLE; |
|
- | 109 | ||
- | 110 | /* Sizes are 0 based */ |
|
- | 111 | src_w--; |
|
- | 112 | src_h--; |
|
- | 113 | crtc_w--; |
|
- | 114 | crtc_h--; |
|
- | 115 | ||
- | 116 | intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); |
|
- | 117 | ||
- | 118 | I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); |
|
- | 119 | I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); |
|
- | 120 | ||
- | 121 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
|
- | 122 | sprsurf_offset = intel_gen4_compute_page_offset(&x, &y, |
|
- | 123 | obj->tiling_mode, |
|
- | 124 | pixel_size, |
|
- | 125 | fb->pitches[0]); |
|
- | 126 | linear_offset -= sprsurf_offset; |
|
- | 127 | ||
- | 128 | if (obj->tiling_mode != I915_TILING_NONE) |
|
- | 129 | I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x); |
|
- | 130 | else |
|
- | 131 | I915_WRITE(SPLINOFF(pipe, plane), linear_offset); |
|
- | 132 | ||
- | 133 | I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); |
|
- | 134 | I915_WRITE(SPCNTR(pipe, plane), sprctl); |
|
- | 135 | I915_MODIFY_DISPBASE(SPSURF(pipe, plane), obj->gtt_offset + |
|
- | 136 | sprsurf_offset); |
|
- | 137 | POSTING_READ(SPSURF(pipe, plane)); |
|
- | 138 | } |
|
- | 139 | ||
- | 140 | static void |
|
- | 141 | vlv_disable_plane(struct drm_plane *dplane) |
|
- | 142 | { |
|
- | 143 | struct drm_device *dev = dplane->dev; |
|
- | 144 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 145 | struct intel_plane *intel_plane = to_intel_plane(dplane); |
|
- | 146 | int pipe = intel_plane->pipe; |
|
- | 147 | int plane = intel_plane->plane; |
|
- | 148 | ||
- | 149 | I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) & |
|
- | 150 | ~SP_ENABLE); |
|
- | 151 | /* Activate double buffered register update */ |
|
- | 152 | I915_MODIFY_DISPBASE(SPSURF(pipe, plane), 0); |
|
- | 153 | POSTING_READ(SPSURF(pipe, plane)); |
|
- | 154 | } |
|
- | 155 | ||
- | 156 | static int |
|
- | 157 | vlv_update_colorkey(struct drm_plane *dplane, |
|
- | 158 | struct drm_intel_sprite_colorkey *key) |
|
- | 159 | { |
|
- | 160 | struct drm_device *dev = dplane->dev; |
|
- | 161 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 162 | struct intel_plane *intel_plane = to_intel_plane(dplane); |
|
- | 163 | int pipe = intel_plane->pipe; |
|
- | 164 | int plane = intel_plane->plane; |
|
- | 165 | u32 sprctl; |
|
- | 166 | ||
- | 167 | if (key->flags & I915_SET_COLORKEY_DESTINATION) |
|
- | 168 | return -EINVAL; |
|
- | 169 | ||
- | 170 | I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value); |
|
- | 171 | I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value); |
|
- | 172 | I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask); |
|
- | 173 | ||
- | 174 | sprctl = I915_READ(SPCNTR(pipe, plane)); |
|
- | 175 | sprctl &= ~SP_SOURCE_KEY; |
|
- | 176 | if (key->flags & I915_SET_COLORKEY_SOURCE) |
|
- | 177 | sprctl |= SP_SOURCE_KEY; |
|
- | 178 | I915_WRITE(SPCNTR(pipe, plane), sprctl); |
|
- | 179 | ||
- | 180 | POSTING_READ(SPKEYMSK(pipe, plane)); |
|
- | 181 | ||
- | 182 | return 0; |
|
- | 183 | } |
|
- | 184 | ||
- | 185 | static void |
|
- | 186 | vlv_get_colorkey(struct drm_plane *dplane, |
|
- | 187 | struct drm_intel_sprite_colorkey *key) |
|
- | 188 | { |
|
- | 189 | struct drm_device *dev = dplane->dev; |
|
- | 190 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 191 | struct intel_plane *intel_plane = to_intel_plane(dplane); |
|
- | 192 | int pipe = intel_plane->pipe; |
|
- | 193 | int plane = intel_plane->plane; |
|
- | 194 | u32 sprctl; |
|
- | 195 | ||
- | 196 | key->min_value = I915_READ(SPKEYMINVAL(pipe, plane)); |
|
- | 197 | key->max_value = I915_READ(SPKEYMAXVAL(pipe, plane)); |
|
- | 198 | key->channel_mask = I915_READ(SPKEYMSK(pipe, plane)); |
|
- | 199 | ||
- | 200 | sprctl = I915_READ(SPCNTR(pipe, plane)); |
|
- | 201 | if (sprctl & SP_SOURCE_KEY) |
|
- | 202 | key->flags = I915_SET_COLORKEY_SOURCE; |
|
- | 203 | else |
|
- | 204 | key->flags = I915_SET_COLORKEY_NONE; |
|
- | 205 | } |
|
- | 206 | ||
39 | static void |
207 | static void |
40 | ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, |
208 | ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, |
41 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
209 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
42 | unsigned int crtc_w, unsigned int crtc_h, |
210 | unsigned int crtc_w, unsigned int crtc_h, |
43 | uint32_t x, uint32_t y, |
211 | uint32_t x, uint32_t y, |
Line 439... | Line 607... | ||
439 | intel_fb = to_intel_framebuffer(fb); |
607 | intel_fb = to_intel_framebuffer(fb); |
440 | obj = intel_fb->obj; |
608 | obj = intel_fb->obj; |
Line 441... | Line 609... | ||
441 | 609 | ||
Line -... | Line 610... | ||
- | 610 | old_obj = intel_plane->obj; |
|
- | 611 | ||
- | 612 | intel_plane->crtc_x = crtc_x; |
|
- | 613 | intel_plane->crtc_y = crtc_y; |
|
- | 614 | intel_plane->crtc_w = crtc_w; |
|
- | 615 | intel_plane->crtc_h = crtc_h; |
|
- | 616 | intel_plane->src_x = src_x; |
|
- | 617 | intel_plane->src_y = src_y; |
|
- | 618 | intel_plane->src_w = src_w; |
|
442 | old_obj = intel_plane->obj; |
619 | intel_plane->src_h = src_h; |
443 | 620 | ||
Line 444... | Line 621... | ||
444 | src_w = src_w >> 16; |
621 | src_w = src_w >> 16; |
445 | src_h = src_h >> 16; |
622 | src_h = src_h >> 16; |
Line 511... | Line 688... | ||
511 | (crtc_w == primary_w) && (crtc_h == primary_h)) |
688 | (crtc_w == primary_w) && (crtc_h == primary_h)) |
512 | disable_primary = true; |
689 | disable_primary = true; |
Line 513... | Line 690... | ||
513 | 690 | ||
Line -... | Line 691... | ||
- | 691 | mutex_lock(&dev->struct_mutex); |
|
- | 692 | ||
- | 693 | /* Note that this will apply the VT-d workaround for scanouts, |
|
- | 694 | * which is more restrictive than required for sprites. (The |
|
- | 695 | * primary plane requires 256KiB alignment with 64 PTE padding, |
|
514 | mutex_lock(&dev->struct_mutex); |
696 | * the sprite planes only require 128KiB alignment and 32 PTE padding. |
515 | 697 | */ |
|
516 | ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); |
698 | ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); |
Line 517... | Line 699... | ||
517 | if (ret) |
699 | if (ret) |
Line 566... | Line 748... | ||
566 | intel_plane->disable_plane(plane); |
748 | intel_plane->disable_plane(plane); |
Line 567... | Line 749... | ||
567 | 749 | ||
568 | if (!intel_plane->obj) |
750 | if (!intel_plane->obj) |
Line -... | Line 751... | ||
- | 751 | goto out; |
|
- | 752 | ||
569 | goto out; |
753 | intel_wait_for_vblank(dev, intel_plane->pipe); |
570 | 754 | ||
571 | mutex_lock(&dev->struct_mutex); |
755 | mutex_lock(&dev->struct_mutex); |
572 | intel_unpin_fb_obj(intel_plane->obj); |
756 | intel_unpin_fb_obj(intel_plane->obj); |
573 | intel_plane->obj = NULL; |
757 | intel_plane->obj = NULL; |
Line 645... | Line 829... | ||
645 | out_unlock: |
829 | out_unlock: |
646 | drm_modeset_unlock_all(dev); |
830 | drm_modeset_unlock_all(dev); |
647 | return ret; |
831 | return ret; |
648 | } |
832 | } |
Line -... | Line 833... | ||
- | 833 | ||
- | 834 | void intel_plane_restore(struct drm_plane *plane) |
|
- | 835 | { |
|
- | 836 | struct intel_plane *intel_plane = to_intel_plane(plane); |
|
- | 837 | ||
- | 838 | if (!plane->crtc || !plane->fb) |
|
- | 839 | return; |
|
- | 840 | ||
- | 841 | intel_update_plane(plane, plane->crtc, plane->fb, |
|
- | 842 | intel_plane->crtc_x, intel_plane->crtc_y, |
|
- | 843 | intel_plane->crtc_w, intel_plane->crtc_h, |
|
- | 844 | intel_plane->src_x, intel_plane->src_y, |
|
- | 845 | intel_plane->src_w, intel_plane->src_h); |
|
- | 846 | } |
|
649 | 847 | ||
650 | static const struct drm_plane_funcs intel_plane_funcs = { |
848 | static const struct drm_plane_funcs intel_plane_funcs = { |
651 | .update_plane = intel_update_plane, |
849 | .update_plane = intel_update_plane, |
652 | .disable_plane = intel_disable_plane, |
850 | .disable_plane = intel_disable_plane, |
653 | .destroy = intel_destroy_plane, |
851 | .destroy = intel_destroy_plane, |
Line 668... | Line 866... | ||
668 | DRM_FORMAT_YVYU, |
866 | DRM_FORMAT_YVYU, |
669 | DRM_FORMAT_UYVY, |
867 | DRM_FORMAT_UYVY, |
670 | DRM_FORMAT_VYUY, |
868 | DRM_FORMAT_VYUY, |
671 | }; |
869 | }; |
Line -... | Line 870... | ||
- | 870 | ||
- | 871 | static uint32_t vlv_plane_formats[] = { |
|
- | 872 | DRM_FORMAT_RGB565, |
|
- | 873 | DRM_FORMAT_ABGR8888, |
|
- | 874 | DRM_FORMAT_ARGB8888, |
|
- | 875 | DRM_FORMAT_XBGR8888, |
|
- | 876 | DRM_FORMAT_XRGB8888, |
|
- | 877 | DRM_FORMAT_XBGR2101010, |
|
- | 878 | DRM_FORMAT_ABGR2101010, |
|
- | 879 | DRM_FORMAT_YUYV, |
|
- | 880 | DRM_FORMAT_YVYU, |
|
- | 881 | DRM_FORMAT_UYVY, |
|
- | 882 | DRM_FORMAT_VYUY, |
|
- | 883 | }; |
|
672 | 884 | ||
673 | int |
885 | int |
674 | intel_plane_init(struct drm_device *dev, enum pipe pipe) |
886 | intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) |
675 | { |
887 | { |
676 | struct intel_plane *intel_plane; |
888 | struct intel_plane *intel_plane; |
677 | unsigned long possible_crtcs; |
889 | unsigned long possible_crtcs; |
678 | const uint32_t *plane_formats; |
890 | const uint32_t *plane_formats; |
Line 708... | Line 920... | ||
708 | case 7: |
920 | case 7: |
709 | if (IS_HASWELL(dev) || IS_VALLEYVIEW(dev)) |
921 | if (IS_HASWELL(dev) || IS_VALLEYVIEW(dev)) |
710 | intel_plane->can_scale = false; |
922 | intel_plane->can_scale = false; |
711 | else |
923 | else |
712 | intel_plane->can_scale = true; |
924 | intel_plane->can_scale = true; |
- | 925 | ||
- | 926 | if (IS_VALLEYVIEW(dev)) { |
|
- | 927 | intel_plane->max_downscale = 1; |
|
- | 928 | intel_plane->update_plane = vlv_update_plane; |
|
- | 929 | intel_plane->disable_plane = vlv_disable_plane; |
|
- | 930 | intel_plane->update_colorkey = vlv_update_colorkey; |
|
- | 931 | intel_plane->get_colorkey = vlv_get_colorkey; |
|
- | 932 | ||
- | 933 | plane_formats = vlv_plane_formats; |
|
- | 934 | num_plane_formats = ARRAY_SIZE(vlv_plane_formats); |
|
- | 935 | } else { |
|
713 | intel_plane->max_downscale = 2; |
936 | intel_plane->max_downscale = 2; |
714 | intel_plane->update_plane = ivb_update_plane; |
937 | intel_plane->update_plane = ivb_update_plane; |
715 | intel_plane->disable_plane = ivb_disable_plane; |
938 | intel_plane->disable_plane = ivb_disable_plane; |
716 | intel_plane->update_colorkey = ivb_update_colorkey; |
939 | intel_plane->update_colorkey = ivb_update_colorkey; |
717 | intel_plane->get_colorkey = ivb_get_colorkey; |
940 | intel_plane->get_colorkey = ivb_get_colorkey; |
Line 718... | Line 941... | ||
718 | 941 | ||
719 | plane_formats = snb_plane_formats; |
942 | plane_formats = snb_plane_formats; |
- | 943 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); |
|
720 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); |
944 | } |
Line 721... | Line 945... | ||
721 | break; |
945 | break; |
722 | 946 | ||
723 | default: |
947 | default: |
724 | kfree(intel_plane); |
948 | kfree(intel_plane); |
Line 725... | Line 949... | ||
725 | return -ENODEV; |
949 | return -ENODEV; |
- | 950 | } |
|
726 | } |
951 | |
727 | 952 | intel_plane->pipe = pipe; |
|
728 | intel_plane->pipe = pipe; |
953 | intel_plane->plane = plane; |
729 | possible_crtcs = (1 << pipe); |
954 | possible_crtcs = (1 << pipe); |
730 | ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs, |
955 | ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs, |