Rev 3482 | Rev 4104 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 3482 | Rev 3746 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | * Copyright © 2011 Intel Corporation |
2 | * Copyright © 2011 Intel Corporation |
3 | * |
3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), |
5 | * copy of this software and associated documentation files (the "Software"), |
6 | * to deal in the Software without restriction, including without limitation |
6 | * to deal in the Software without restriction, including without limitation |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
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 |
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: |
9 | * Software is furnished to do so, subject to the following conditions: |
10 | * |
10 | * |
11 | * The above copyright notice and this permission notice (including the next |
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 |
12 | * paragraph) shall be included in all copies or substantial portions of the |
13 | * Software. |
13 | * Software. |
14 | * |
14 | * |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
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, |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
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 |
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, |
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 |
20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
21 | * SOFTWARE. |
21 | * SOFTWARE. |
22 | * |
22 | * |
23 | * Authors: |
23 | * Authors: |
24 | * Jesse Barnes |
24 | * Jesse Barnes |
25 | * |
25 | * |
26 | * New plane/sprite handling. |
26 | * New plane/sprite handling. |
27 | * |
27 | * |
28 | * The older chips had a separate interface for programming plane related |
28 | * The older chips had a separate interface for programming plane related |
29 | * registers; newer ones are much simpler and we can use the new DRM plane |
29 | * registers; newer ones are much simpler and we can use the new DRM plane |
30 | * support. |
30 | * support. |
31 | */ |
31 | */ |
32 | #include |
32 | #include |
33 | #include |
33 | #include |
34 | #include |
34 | #include |
35 | #include "intel_drv.h" |
35 | #include "intel_drv.h" |
36 | #include |
36 | #include |
37 | #include "i915_drv.h" |
37 | #include "i915_drv.h" |
38 | 38 | ||
39 | static void |
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 | ||
- | 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, |
44 | uint32_t src_w, uint32_t src_h) |
212 | uint32_t src_w, uint32_t src_h) |
45 | { |
213 | { |
46 | struct drm_device *dev = plane->dev; |
214 | struct drm_device *dev = plane->dev; |
47 | struct drm_i915_private *dev_priv = dev->dev_private; |
215 | struct drm_i915_private *dev_priv = dev->dev_private; |
48 | struct intel_plane *intel_plane = to_intel_plane(plane); |
216 | struct intel_plane *intel_plane = to_intel_plane(plane); |
49 | int pipe = intel_plane->pipe; |
217 | int pipe = intel_plane->pipe; |
50 | u32 sprctl, sprscale = 0; |
218 | u32 sprctl, sprscale = 0; |
51 | unsigned long sprsurf_offset, linear_offset; |
219 | unsigned long sprsurf_offset, linear_offset; |
52 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
220 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
53 | bool scaling_was_enabled = dev_priv->sprite_scaling_enabled; |
221 | bool scaling_was_enabled = dev_priv->sprite_scaling_enabled; |
54 | 222 | ||
55 | sprctl = I915_READ(SPRCTL(pipe)); |
223 | sprctl = I915_READ(SPRCTL(pipe)); |
56 | 224 | ||
57 | /* Mask out pixel format bits in case we change it */ |
225 | /* Mask out pixel format bits in case we change it */ |
58 | sprctl &= ~SPRITE_PIXFORMAT_MASK; |
226 | sprctl &= ~SPRITE_PIXFORMAT_MASK; |
59 | sprctl &= ~SPRITE_RGB_ORDER_RGBX; |
227 | sprctl &= ~SPRITE_RGB_ORDER_RGBX; |
60 | sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK; |
228 | sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK; |
61 | sprctl &= ~SPRITE_TILED; |
229 | sprctl &= ~SPRITE_TILED; |
62 | 230 | ||
63 | switch (fb->pixel_format) { |
231 | switch (fb->pixel_format) { |
64 | case DRM_FORMAT_XBGR8888: |
232 | case DRM_FORMAT_XBGR8888: |
65 | sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; |
233 | sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX; |
66 | break; |
234 | break; |
67 | case DRM_FORMAT_XRGB8888: |
235 | case DRM_FORMAT_XRGB8888: |
68 | sprctl |= SPRITE_FORMAT_RGBX888; |
236 | sprctl |= SPRITE_FORMAT_RGBX888; |
69 | break; |
237 | break; |
70 | case DRM_FORMAT_YUYV: |
238 | case DRM_FORMAT_YUYV: |
71 | sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; |
239 | sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV; |
72 | break; |
240 | break; |
73 | case DRM_FORMAT_YVYU: |
241 | case DRM_FORMAT_YVYU: |
74 | sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU; |
242 | sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU; |
75 | break; |
243 | break; |
76 | case DRM_FORMAT_UYVY: |
244 | case DRM_FORMAT_UYVY: |
77 | sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY; |
245 | sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY; |
78 | break; |
246 | break; |
79 | case DRM_FORMAT_VYUY: |
247 | case DRM_FORMAT_VYUY: |
80 | sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY; |
248 | sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY; |
81 | break; |
249 | break; |
82 | default: |
250 | default: |
83 | BUG(); |
251 | BUG(); |
84 | } |
252 | } |
85 | 253 | ||
86 | if (obj->tiling_mode != I915_TILING_NONE) |
254 | if (obj->tiling_mode != I915_TILING_NONE) |
87 | sprctl |= SPRITE_TILED; |
255 | sprctl |= SPRITE_TILED; |
88 | 256 | ||
89 | /* must disable */ |
257 | /* must disable */ |
90 | sprctl |= SPRITE_TRICKLE_FEED_DISABLE; |
258 | sprctl |= SPRITE_TRICKLE_FEED_DISABLE; |
91 | sprctl |= SPRITE_ENABLE; |
259 | sprctl |= SPRITE_ENABLE; |
92 | 260 | ||
93 | if (IS_HASWELL(dev)) |
261 | if (IS_HASWELL(dev)) |
94 | sprctl |= SPRITE_PIPE_CSC_ENABLE; |
262 | sprctl |= SPRITE_PIPE_CSC_ENABLE; |
95 | 263 | ||
96 | /* Sizes are 0 based */ |
264 | /* Sizes are 0 based */ |
97 | src_w--; |
265 | src_w--; |
98 | src_h--; |
266 | src_h--; |
99 | crtc_w--; |
267 | crtc_w--; |
100 | crtc_h--; |
268 | crtc_h--; |
101 | 269 | ||
102 | intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); |
270 | intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); |
103 | 271 | ||
104 | /* |
272 | /* |
105 | * IVB workaround: must disable low power watermarks for at least |
273 | * IVB workaround: must disable low power watermarks for at least |
106 | * one frame before enabling scaling. LP watermarks can be re-enabled |
274 | * one frame before enabling scaling. LP watermarks can be re-enabled |
107 | * when scaling is disabled. |
275 | * when scaling is disabled. |
108 | */ |
276 | */ |
109 | if (crtc_w != src_w || crtc_h != src_h) { |
277 | if (crtc_w != src_w || crtc_h != src_h) { |
110 | dev_priv->sprite_scaling_enabled |= 1 << pipe; |
278 | dev_priv->sprite_scaling_enabled |= 1 << pipe; |
111 | 279 | ||
112 | if (!scaling_was_enabled) { |
280 | if (!scaling_was_enabled) { |
113 | intel_update_watermarks(dev); |
281 | intel_update_watermarks(dev); |
114 | intel_wait_for_vblank(dev, pipe); |
282 | intel_wait_for_vblank(dev, pipe); |
115 | } |
283 | } |
116 | sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; |
284 | sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; |
117 | } else |
285 | } else |
118 | dev_priv->sprite_scaling_enabled &= ~(1 << pipe); |
286 | dev_priv->sprite_scaling_enabled &= ~(1 << pipe); |
119 | 287 | ||
120 | I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); |
288 | I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); |
121 | I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); |
289 | I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); |
122 | 290 | ||
123 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
291 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
124 | sprsurf_offset = |
292 | sprsurf_offset = |
125 | intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, |
293 | intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, |
126 | pixel_size, fb->pitches[0]); |
294 | pixel_size, fb->pitches[0]); |
127 | linear_offset -= sprsurf_offset; |
295 | linear_offset -= sprsurf_offset; |
128 | 296 | ||
129 | /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET |
297 | /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET |
130 | * register */ |
298 | * register */ |
131 | if (IS_HASWELL(dev)) |
299 | if (IS_HASWELL(dev)) |
132 | I915_WRITE(SPROFFSET(pipe), (y << 16) | x); |
300 | I915_WRITE(SPROFFSET(pipe), (y << 16) | x); |
133 | else if (obj->tiling_mode != I915_TILING_NONE) |
301 | else if (obj->tiling_mode != I915_TILING_NONE) |
134 | I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x); |
302 | I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x); |
135 | else |
303 | else |
136 | I915_WRITE(SPRLINOFF(pipe), linear_offset); |
304 | I915_WRITE(SPRLINOFF(pipe), linear_offset); |
137 | 305 | ||
138 | I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); |
306 | I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w); |
139 | if (intel_plane->can_scale) |
307 | if (intel_plane->can_scale) |
140 | I915_WRITE(SPRSCALE(pipe), sprscale); |
308 | I915_WRITE(SPRSCALE(pipe), sprscale); |
141 | I915_WRITE(SPRCTL(pipe), sprctl); |
309 | I915_WRITE(SPRCTL(pipe), sprctl); |
142 | I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset + sprsurf_offset); |
310 | I915_MODIFY_DISPBASE(SPRSURF(pipe), obj->gtt_offset + sprsurf_offset); |
143 | POSTING_READ(SPRSURF(pipe)); |
311 | POSTING_READ(SPRSURF(pipe)); |
144 | 312 | ||
145 | /* potentially re-enable LP watermarks */ |
313 | /* potentially re-enable LP watermarks */ |
146 | if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) |
314 | if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) |
147 | intel_update_watermarks(dev); |
315 | intel_update_watermarks(dev); |
148 | } |
316 | } |
149 | 317 | ||
150 | static void |
318 | static void |
151 | ivb_disable_plane(struct drm_plane *plane) |
319 | ivb_disable_plane(struct drm_plane *plane) |
152 | { |
320 | { |
153 | struct drm_device *dev = plane->dev; |
321 | struct drm_device *dev = plane->dev; |
154 | struct drm_i915_private *dev_priv = dev->dev_private; |
322 | struct drm_i915_private *dev_priv = dev->dev_private; |
155 | struct intel_plane *intel_plane = to_intel_plane(plane); |
323 | struct intel_plane *intel_plane = to_intel_plane(plane); |
156 | int pipe = intel_plane->pipe; |
324 | int pipe = intel_plane->pipe; |
157 | bool scaling_was_enabled = dev_priv->sprite_scaling_enabled; |
325 | bool scaling_was_enabled = dev_priv->sprite_scaling_enabled; |
158 | 326 | ||
159 | I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); |
327 | I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); |
160 | /* Can't leave the scaler enabled... */ |
328 | /* Can't leave the scaler enabled... */ |
161 | if (intel_plane->can_scale) |
329 | if (intel_plane->can_scale) |
162 | I915_WRITE(SPRSCALE(pipe), 0); |
330 | I915_WRITE(SPRSCALE(pipe), 0); |
163 | /* Activate double buffered register update */ |
331 | /* Activate double buffered register update */ |
164 | I915_MODIFY_DISPBASE(SPRSURF(pipe), 0); |
332 | I915_MODIFY_DISPBASE(SPRSURF(pipe), 0); |
165 | POSTING_READ(SPRSURF(pipe)); |
333 | POSTING_READ(SPRSURF(pipe)); |
166 | 334 | ||
167 | dev_priv->sprite_scaling_enabled &= ~(1 << pipe); |
335 | dev_priv->sprite_scaling_enabled &= ~(1 << pipe); |
168 | 336 | ||
169 | /* potentially re-enable LP watermarks */ |
337 | /* potentially re-enable LP watermarks */ |
170 | if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) |
338 | if (scaling_was_enabled && !dev_priv->sprite_scaling_enabled) |
171 | intel_update_watermarks(dev); |
339 | intel_update_watermarks(dev); |
172 | } |
340 | } |
173 | 341 | ||
174 | static int |
342 | static int |
175 | ivb_update_colorkey(struct drm_plane *plane, |
343 | ivb_update_colorkey(struct drm_plane *plane, |
176 | struct drm_intel_sprite_colorkey *key) |
344 | struct drm_intel_sprite_colorkey *key) |
177 | { |
345 | { |
178 | struct drm_device *dev = plane->dev; |
346 | struct drm_device *dev = plane->dev; |
179 | struct drm_i915_private *dev_priv = dev->dev_private; |
347 | struct drm_i915_private *dev_priv = dev->dev_private; |
180 | struct intel_plane *intel_plane; |
348 | struct intel_plane *intel_plane; |
181 | u32 sprctl; |
349 | u32 sprctl; |
182 | int ret = 0; |
350 | int ret = 0; |
183 | 351 | ||
184 | intel_plane = to_intel_plane(plane); |
352 | intel_plane = to_intel_plane(plane); |
185 | 353 | ||
186 | I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value); |
354 | I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value); |
187 | I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value); |
355 | I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value); |
188 | I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask); |
356 | I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask); |
189 | 357 | ||
190 | sprctl = I915_READ(SPRCTL(intel_plane->pipe)); |
358 | sprctl = I915_READ(SPRCTL(intel_plane->pipe)); |
191 | sprctl &= ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY); |
359 | sprctl &= ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY); |
192 | if (key->flags & I915_SET_COLORKEY_DESTINATION) |
360 | if (key->flags & I915_SET_COLORKEY_DESTINATION) |
193 | sprctl |= SPRITE_DEST_KEY; |
361 | sprctl |= SPRITE_DEST_KEY; |
194 | else if (key->flags & I915_SET_COLORKEY_SOURCE) |
362 | else if (key->flags & I915_SET_COLORKEY_SOURCE) |
195 | sprctl |= SPRITE_SOURCE_KEY; |
363 | sprctl |= SPRITE_SOURCE_KEY; |
196 | I915_WRITE(SPRCTL(intel_plane->pipe), sprctl); |
364 | I915_WRITE(SPRCTL(intel_plane->pipe), sprctl); |
197 | 365 | ||
198 | POSTING_READ(SPRKEYMSK(intel_plane->pipe)); |
366 | POSTING_READ(SPRKEYMSK(intel_plane->pipe)); |
199 | 367 | ||
200 | return ret; |
368 | return ret; |
201 | } |
369 | } |
202 | 370 | ||
203 | static void |
371 | static void |
204 | ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) |
372 | ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) |
205 | { |
373 | { |
206 | struct drm_device *dev = plane->dev; |
374 | struct drm_device *dev = plane->dev; |
207 | struct drm_i915_private *dev_priv = dev->dev_private; |
375 | struct drm_i915_private *dev_priv = dev->dev_private; |
208 | struct intel_plane *intel_plane; |
376 | struct intel_plane *intel_plane; |
209 | u32 sprctl; |
377 | u32 sprctl; |
210 | 378 | ||
211 | intel_plane = to_intel_plane(plane); |
379 | intel_plane = to_intel_plane(plane); |
212 | 380 | ||
213 | key->min_value = I915_READ(SPRKEYVAL(intel_plane->pipe)); |
381 | key->min_value = I915_READ(SPRKEYVAL(intel_plane->pipe)); |
214 | key->max_value = I915_READ(SPRKEYMAX(intel_plane->pipe)); |
382 | key->max_value = I915_READ(SPRKEYMAX(intel_plane->pipe)); |
215 | key->channel_mask = I915_READ(SPRKEYMSK(intel_plane->pipe)); |
383 | key->channel_mask = I915_READ(SPRKEYMSK(intel_plane->pipe)); |
216 | key->flags = 0; |
384 | key->flags = 0; |
217 | 385 | ||
218 | sprctl = I915_READ(SPRCTL(intel_plane->pipe)); |
386 | sprctl = I915_READ(SPRCTL(intel_plane->pipe)); |
219 | 387 | ||
220 | if (sprctl & SPRITE_DEST_KEY) |
388 | if (sprctl & SPRITE_DEST_KEY) |
221 | key->flags = I915_SET_COLORKEY_DESTINATION; |
389 | key->flags = I915_SET_COLORKEY_DESTINATION; |
222 | else if (sprctl & SPRITE_SOURCE_KEY) |
390 | else if (sprctl & SPRITE_SOURCE_KEY) |
223 | key->flags = I915_SET_COLORKEY_SOURCE; |
391 | key->flags = I915_SET_COLORKEY_SOURCE; |
224 | else |
392 | else |
225 | key->flags = I915_SET_COLORKEY_NONE; |
393 | key->flags = I915_SET_COLORKEY_NONE; |
226 | } |
394 | } |
227 | 395 | ||
228 | static void |
396 | static void |
229 | ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, |
397 | ilk_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, |
230 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
398 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
231 | unsigned int crtc_w, unsigned int crtc_h, |
399 | unsigned int crtc_w, unsigned int crtc_h, |
232 | uint32_t x, uint32_t y, |
400 | uint32_t x, uint32_t y, |
233 | uint32_t src_w, uint32_t src_h) |
401 | uint32_t src_w, uint32_t src_h) |
234 | { |
402 | { |
235 | struct drm_device *dev = plane->dev; |
403 | struct drm_device *dev = plane->dev; |
236 | struct drm_i915_private *dev_priv = dev->dev_private; |
404 | struct drm_i915_private *dev_priv = dev->dev_private; |
237 | struct intel_plane *intel_plane = to_intel_plane(plane); |
405 | struct intel_plane *intel_plane = to_intel_plane(plane); |
238 | int pipe = intel_plane->pipe; |
406 | int pipe = intel_plane->pipe; |
239 | unsigned long dvssurf_offset, linear_offset; |
407 | unsigned long dvssurf_offset, linear_offset; |
240 | u32 dvscntr, dvsscale; |
408 | u32 dvscntr, dvsscale; |
241 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
409 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
242 | 410 | ||
243 | dvscntr = I915_READ(DVSCNTR(pipe)); |
411 | dvscntr = I915_READ(DVSCNTR(pipe)); |
244 | 412 | ||
245 | /* Mask out pixel format bits in case we change it */ |
413 | /* Mask out pixel format bits in case we change it */ |
246 | dvscntr &= ~DVS_PIXFORMAT_MASK; |
414 | dvscntr &= ~DVS_PIXFORMAT_MASK; |
247 | dvscntr &= ~DVS_RGB_ORDER_XBGR; |
415 | dvscntr &= ~DVS_RGB_ORDER_XBGR; |
248 | dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; |
416 | dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; |
249 | dvscntr &= ~DVS_TILED; |
417 | dvscntr &= ~DVS_TILED; |
250 | 418 | ||
251 | switch (fb->pixel_format) { |
419 | switch (fb->pixel_format) { |
252 | case DRM_FORMAT_XBGR8888: |
420 | case DRM_FORMAT_XBGR8888: |
253 | dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; |
421 | dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; |
254 | break; |
422 | break; |
255 | case DRM_FORMAT_XRGB8888: |
423 | case DRM_FORMAT_XRGB8888: |
256 | dvscntr |= DVS_FORMAT_RGBX888; |
424 | dvscntr |= DVS_FORMAT_RGBX888; |
257 | break; |
425 | break; |
258 | case DRM_FORMAT_YUYV: |
426 | case DRM_FORMAT_YUYV: |
259 | dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV; |
427 | dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV; |
260 | break; |
428 | break; |
261 | case DRM_FORMAT_YVYU: |
429 | case DRM_FORMAT_YVYU: |
262 | dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU; |
430 | dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU; |
263 | break; |
431 | break; |
264 | case DRM_FORMAT_UYVY: |
432 | case DRM_FORMAT_UYVY: |
265 | dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY; |
433 | dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY; |
266 | break; |
434 | break; |
267 | case DRM_FORMAT_VYUY: |
435 | case DRM_FORMAT_VYUY: |
268 | dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY; |
436 | dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY; |
269 | break; |
437 | break; |
270 | default: |
438 | default: |
271 | BUG(); |
439 | BUG(); |
272 | } |
440 | } |
273 | 441 | ||
274 | if (obj->tiling_mode != I915_TILING_NONE) |
442 | if (obj->tiling_mode != I915_TILING_NONE) |
275 | dvscntr |= DVS_TILED; |
443 | dvscntr |= DVS_TILED; |
276 | 444 | ||
277 | if (IS_GEN6(dev)) |
445 | if (IS_GEN6(dev)) |
278 | dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ |
446 | dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ |
279 | dvscntr |= DVS_ENABLE; |
447 | dvscntr |= DVS_ENABLE; |
280 | 448 | ||
281 | /* Sizes are 0 based */ |
449 | /* Sizes are 0 based */ |
282 | src_w--; |
450 | src_w--; |
283 | src_h--; |
451 | src_h--; |
284 | crtc_w--; |
452 | crtc_w--; |
285 | crtc_h--; |
453 | crtc_h--; |
286 | 454 | ||
287 | intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); |
455 | intel_update_sprite_watermarks(dev, pipe, crtc_w, pixel_size); |
288 | 456 | ||
289 | dvsscale = 0; |
457 | dvsscale = 0; |
290 | if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h) |
458 | if (IS_GEN5(dev) || crtc_w != src_w || crtc_h != src_h) |
291 | dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; |
459 | dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; |
292 | 460 | ||
293 | I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); |
461 | I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); |
294 | I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x); |
462 | I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x); |
295 | 463 | ||
296 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
464 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
297 | dvssurf_offset = |
465 | dvssurf_offset = |
298 | intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, |
466 | intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, |
299 | pixel_size, fb->pitches[0]); |
467 | pixel_size, fb->pitches[0]); |
300 | linear_offset -= dvssurf_offset; |
468 | linear_offset -= dvssurf_offset; |
301 | 469 | ||
302 | if (obj->tiling_mode != I915_TILING_NONE) |
470 | if (obj->tiling_mode != I915_TILING_NONE) |
303 | I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x); |
471 | I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x); |
304 | else |
472 | else |
305 | I915_WRITE(DVSLINOFF(pipe), linear_offset); |
473 | I915_WRITE(DVSLINOFF(pipe), linear_offset); |
306 | 474 | ||
307 | I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); |
475 | I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); |
308 | I915_WRITE(DVSSCALE(pipe), dvsscale); |
476 | I915_WRITE(DVSSCALE(pipe), dvsscale); |
309 | I915_WRITE(DVSCNTR(pipe), dvscntr); |
477 | I915_WRITE(DVSCNTR(pipe), dvscntr); |
310 | I915_MODIFY_DISPBASE(DVSSURF(pipe), obj->gtt_offset + dvssurf_offset); |
478 | I915_MODIFY_DISPBASE(DVSSURF(pipe), obj->gtt_offset + dvssurf_offset); |
311 | POSTING_READ(DVSSURF(pipe)); |
479 | POSTING_READ(DVSSURF(pipe)); |
312 | } |
480 | } |
313 | 481 | ||
314 | static void |
482 | static void |
315 | ilk_disable_plane(struct drm_plane *plane) |
483 | ilk_disable_plane(struct drm_plane *plane) |
316 | { |
484 | { |
317 | struct drm_device *dev = plane->dev; |
485 | struct drm_device *dev = plane->dev; |
318 | struct drm_i915_private *dev_priv = dev->dev_private; |
486 | struct drm_i915_private *dev_priv = dev->dev_private; |
319 | struct intel_plane *intel_plane = to_intel_plane(plane); |
487 | struct intel_plane *intel_plane = to_intel_plane(plane); |
320 | int pipe = intel_plane->pipe; |
488 | int pipe = intel_plane->pipe; |
321 | 489 | ||
322 | I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE); |
490 | I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE); |
323 | /* Disable the scaler */ |
491 | /* Disable the scaler */ |
324 | I915_WRITE(DVSSCALE(pipe), 0); |
492 | I915_WRITE(DVSSCALE(pipe), 0); |
325 | /* Flush double buffered register updates */ |
493 | /* Flush double buffered register updates */ |
326 | I915_MODIFY_DISPBASE(DVSSURF(pipe), 0); |
494 | I915_MODIFY_DISPBASE(DVSSURF(pipe), 0); |
327 | POSTING_READ(DVSSURF(pipe)); |
495 | POSTING_READ(DVSSURF(pipe)); |
328 | } |
496 | } |
329 | 497 | ||
330 | static void |
498 | static void |
331 | intel_enable_primary(struct drm_crtc *crtc) |
499 | intel_enable_primary(struct drm_crtc *crtc) |
332 | { |
500 | { |
333 | struct drm_device *dev = crtc->dev; |
501 | struct drm_device *dev = crtc->dev; |
334 | struct drm_i915_private *dev_priv = dev->dev_private; |
502 | struct drm_i915_private *dev_priv = dev->dev_private; |
335 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
503 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
336 | int reg = DSPCNTR(intel_crtc->plane); |
504 | int reg = DSPCNTR(intel_crtc->plane); |
337 | 505 | ||
338 | if (!intel_crtc->primary_disabled) |
506 | if (!intel_crtc->primary_disabled) |
339 | return; |
507 | return; |
340 | 508 | ||
341 | intel_crtc->primary_disabled = false; |
509 | intel_crtc->primary_disabled = false; |
342 | intel_update_fbc(dev); |
510 | intel_update_fbc(dev); |
343 | 511 | ||
344 | I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); |
512 | I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); |
345 | } |
513 | } |
346 | 514 | ||
347 | static void |
515 | static void |
348 | intel_disable_primary(struct drm_crtc *crtc) |
516 | intel_disable_primary(struct drm_crtc *crtc) |
349 | { |
517 | { |
350 | struct drm_device *dev = crtc->dev; |
518 | struct drm_device *dev = crtc->dev; |
351 | struct drm_i915_private *dev_priv = dev->dev_private; |
519 | struct drm_i915_private *dev_priv = dev->dev_private; |
352 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
520 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
353 | int reg = DSPCNTR(intel_crtc->plane); |
521 | int reg = DSPCNTR(intel_crtc->plane); |
354 | 522 | ||
355 | if (intel_crtc->primary_disabled) |
523 | if (intel_crtc->primary_disabled) |
356 | return; |
524 | return; |
357 | 525 | ||
358 | I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); |
526 | I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); |
359 | 527 | ||
360 | intel_crtc->primary_disabled = true; |
528 | intel_crtc->primary_disabled = true; |
361 | intel_update_fbc(dev); |
529 | intel_update_fbc(dev); |
362 | } |
530 | } |
363 | 531 | ||
364 | static int |
532 | static int |
365 | ilk_update_colorkey(struct drm_plane *plane, |
533 | ilk_update_colorkey(struct drm_plane *plane, |
366 | struct drm_intel_sprite_colorkey *key) |
534 | struct drm_intel_sprite_colorkey *key) |
367 | { |
535 | { |
368 | struct drm_device *dev = plane->dev; |
536 | struct drm_device *dev = plane->dev; |
369 | struct drm_i915_private *dev_priv = dev->dev_private; |
537 | struct drm_i915_private *dev_priv = dev->dev_private; |
370 | struct intel_plane *intel_plane; |
538 | struct intel_plane *intel_plane; |
371 | u32 dvscntr; |
539 | u32 dvscntr; |
372 | int ret = 0; |
540 | int ret = 0; |
373 | 541 | ||
374 | intel_plane = to_intel_plane(plane); |
542 | intel_plane = to_intel_plane(plane); |
375 | 543 | ||
376 | I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value); |
544 | I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value); |
377 | I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value); |
545 | I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value); |
378 | I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask); |
546 | I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask); |
379 | 547 | ||
380 | dvscntr = I915_READ(DVSCNTR(intel_plane->pipe)); |
548 | dvscntr = I915_READ(DVSCNTR(intel_plane->pipe)); |
381 | dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY); |
549 | dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY); |
382 | if (key->flags & I915_SET_COLORKEY_DESTINATION) |
550 | if (key->flags & I915_SET_COLORKEY_DESTINATION) |
383 | dvscntr |= DVS_DEST_KEY; |
551 | dvscntr |= DVS_DEST_KEY; |
384 | else if (key->flags & I915_SET_COLORKEY_SOURCE) |
552 | else if (key->flags & I915_SET_COLORKEY_SOURCE) |
385 | dvscntr |= DVS_SOURCE_KEY; |
553 | dvscntr |= DVS_SOURCE_KEY; |
386 | I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr); |
554 | I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr); |
387 | 555 | ||
388 | POSTING_READ(DVSKEYMSK(intel_plane->pipe)); |
556 | POSTING_READ(DVSKEYMSK(intel_plane->pipe)); |
389 | 557 | ||
390 | return ret; |
558 | return ret; |
391 | } |
559 | } |
392 | 560 | ||
393 | static void |
561 | static void |
394 | ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) |
562 | ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) |
395 | { |
563 | { |
396 | struct drm_device *dev = plane->dev; |
564 | struct drm_device *dev = plane->dev; |
397 | struct drm_i915_private *dev_priv = dev->dev_private; |
565 | struct drm_i915_private *dev_priv = dev->dev_private; |
398 | struct intel_plane *intel_plane; |
566 | struct intel_plane *intel_plane; |
399 | u32 dvscntr; |
567 | u32 dvscntr; |
400 | 568 | ||
401 | intel_plane = to_intel_plane(plane); |
569 | intel_plane = to_intel_plane(plane); |
402 | 570 | ||
403 | key->min_value = I915_READ(DVSKEYVAL(intel_plane->pipe)); |
571 | key->min_value = I915_READ(DVSKEYVAL(intel_plane->pipe)); |
404 | key->max_value = I915_READ(DVSKEYMAX(intel_plane->pipe)); |
572 | key->max_value = I915_READ(DVSKEYMAX(intel_plane->pipe)); |
405 | key->channel_mask = I915_READ(DVSKEYMSK(intel_plane->pipe)); |
573 | key->channel_mask = I915_READ(DVSKEYMSK(intel_plane->pipe)); |
406 | key->flags = 0; |
574 | key->flags = 0; |
407 | 575 | ||
408 | dvscntr = I915_READ(DVSCNTR(intel_plane->pipe)); |
576 | dvscntr = I915_READ(DVSCNTR(intel_plane->pipe)); |
409 | 577 | ||
410 | if (dvscntr & DVS_DEST_KEY) |
578 | if (dvscntr & DVS_DEST_KEY) |
411 | key->flags = I915_SET_COLORKEY_DESTINATION; |
579 | key->flags = I915_SET_COLORKEY_DESTINATION; |
412 | else if (dvscntr & DVS_SOURCE_KEY) |
580 | else if (dvscntr & DVS_SOURCE_KEY) |
413 | key->flags = I915_SET_COLORKEY_SOURCE; |
581 | key->flags = I915_SET_COLORKEY_SOURCE; |
414 | else |
582 | else |
415 | key->flags = I915_SET_COLORKEY_NONE; |
583 | key->flags = I915_SET_COLORKEY_NONE; |
416 | } |
584 | } |
417 | 585 | ||
418 | static int |
586 | static int |
419 | intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, |
587 | intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, |
420 | struct drm_framebuffer *fb, int crtc_x, int crtc_y, |
588 | struct drm_framebuffer *fb, int crtc_x, int crtc_y, |
421 | unsigned int crtc_w, unsigned int crtc_h, |
589 | unsigned int crtc_w, unsigned int crtc_h, |
422 | uint32_t src_x, uint32_t src_y, |
590 | uint32_t src_x, uint32_t src_y, |
423 | uint32_t src_w, uint32_t src_h) |
591 | uint32_t src_w, uint32_t src_h) |
424 | { |
592 | { |
425 | struct drm_device *dev = plane->dev; |
593 | struct drm_device *dev = plane->dev; |
426 | struct drm_i915_private *dev_priv = dev->dev_private; |
594 | struct drm_i915_private *dev_priv = dev->dev_private; |
427 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
595 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
428 | struct intel_plane *intel_plane = to_intel_plane(plane); |
596 | struct intel_plane *intel_plane = to_intel_plane(plane); |
429 | struct intel_framebuffer *intel_fb; |
597 | struct intel_framebuffer *intel_fb; |
430 | struct drm_i915_gem_object *obj, *old_obj; |
598 | struct drm_i915_gem_object *obj, *old_obj; |
431 | int pipe = intel_plane->pipe; |
599 | int pipe = intel_plane->pipe; |
432 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, |
600 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, |
433 | pipe); |
601 | pipe); |
434 | int ret = 0; |
602 | int ret = 0; |
435 | int x = src_x >> 16, y = src_y >> 16; |
603 | int x = src_x >> 16, y = src_y >> 16; |
436 | int primary_w = crtc->mode.hdisplay, primary_h = crtc->mode.vdisplay; |
604 | int primary_w = crtc->mode.hdisplay, primary_h = crtc->mode.vdisplay; |
437 | bool disable_primary = false; |
605 | bool disable_primary = false; |
438 | 606 | ||
439 | intel_fb = to_intel_framebuffer(fb); |
607 | intel_fb = to_intel_framebuffer(fb); |
440 | obj = intel_fb->obj; |
608 | obj = intel_fb->obj; |
441 | 609 | ||
442 | old_obj = intel_plane->obj; |
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; |
|
- | 619 | intel_plane->src_h = src_h; |
|
443 | 620 | ||
444 | src_w = src_w >> 16; |
621 | src_w = src_w >> 16; |
445 | src_h = src_h >> 16; |
622 | src_h = src_h >> 16; |
446 | 623 | ||
447 | /* Pipe must be running... */ |
624 | /* Pipe must be running... */ |
448 | if (!(I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE)) |
625 | if (!(I915_READ(PIPECONF(cpu_transcoder)) & PIPECONF_ENABLE)) |
449 | return -EINVAL; |
626 | return -EINVAL; |
450 | 627 | ||
451 | if (crtc_x >= primary_w || crtc_y >= primary_h) |
628 | if (crtc_x >= primary_w || crtc_y >= primary_h) |
452 | return -EINVAL; |
629 | return -EINVAL; |
453 | 630 | ||
454 | /* Don't modify another pipe's plane */ |
631 | /* Don't modify another pipe's plane */ |
455 | if (intel_plane->pipe != intel_crtc->pipe) |
632 | if (intel_plane->pipe != intel_crtc->pipe) |
456 | return -EINVAL; |
633 | return -EINVAL; |
457 | 634 | ||
458 | /* Sprite planes can be linear or x-tiled surfaces */ |
635 | /* Sprite planes can be linear or x-tiled surfaces */ |
459 | switch (obj->tiling_mode) { |
636 | switch (obj->tiling_mode) { |
460 | case I915_TILING_NONE: |
637 | case I915_TILING_NONE: |
461 | case I915_TILING_X: |
638 | case I915_TILING_X: |
462 | break; |
639 | break; |
463 | default: |
640 | default: |
464 | return -EINVAL; |
641 | return -EINVAL; |
465 | } |
642 | } |
466 | 643 | ||
467 | /* |
644 | /* |
468 | * Clamp the width & height into the visible area. Note we don't |
645 | * Clamp the width & height into the visible area. Note we don't |
469 | * try to scale the source if part of the visible region is offscreen. |
646 | * try to scale the source if part of the visible region is offscreen. |
470 | * The caller must handle that by adjusting source offset and size. |
647 | * The caller must handle that by adjusting source offset and size. |
471 | */ |
648 | */ |
472 | if ((crtc_x < 0) && ((crtc_x + crtc_w) > 0)) { |
649 | if ((crtc_x < 0) && ((crtc_x + crtc_w) > 0)) { |
473 | crtc_w += crtc_x; |
650 | crtc_w += crtc_x; |
474 | crtc_x = 0; |
651 | crtc_x = 0; |
475 | } |
652 | } |
476 | if ((crtc_x + crtc_w) <= 0) /* Nothing to display */ |
653 | if ((crtc_x + crtc_w) <= 0) /* Nothing to display */ |
477 | goto out; |
654 | goto out; |
478 | if ((crtc_x + crtc_w) > primary_w) |
655 | if ((crtc_x + crtc_w) > primary_w) |
479 | crtc_w = primary_w - crtc_x; |
656 | crtc_w = primary_w - crtc_x; |
480 | 657 | ||
481 | if ((crtc_y < 0) && ((crtc_y + crtc_h) > 0)) { |
658 | if ((crtc_y < 0) && ((crtc_y + crtc_h) > 0)) { |
482 | crtc_h += crtc_y; |
659 | crtc_h += crtc_y; |
483 | crtc_y = 0; |
660 | crtc_y = 0; |
484 | } |
661 | } |
485 | if ((crtc_y + crtc_h) <= 0) /* Nothing to display */ |
662 | if ((crtc_y + crtc_h) <= 0) /* Nothing to display */ |
486 | goto out; |
663 | goto out; |
487 | if (crtc_y + crtc_h > primary_h) |
664 | if (crtc_y + crtc_h > primary_h) |
488 | crtc_h = primary_h - crtc_y; |
665 | crtc_h = primary_h - crtc_y; |
489 | 666 | ||
490 | if (!crtc_w || !crtc_h) /* Again, nothing to display */ |
667 | if (!crtc_w || !crtc_h) /* Again, nothing to display */ |
491 | goto out; |
668 | goto out; |
492 | 669 | ||
493 | /* |
670 | /* |
494 | * We may not have a scaler, eg. HSW does not have it any more |
671 | * We may not have a scaler, eg. HSW does not have it any more |
495 | */ |
672 | */ |
496 | if (!intel_plane->can_scale && (crtc_w != src_w || crtc_h != src_h)) |
673 | if (!intel_plane->can_scale && (crtc_w != src_w || crtc_h != src_h)) |
497 | return -EINVAL; |
674 | return -EINVAL; |
498 | 675 | ||
499 | /* |
676 | /* |
500 | * We can take a larger source and scale it down, but |
677 | * We can take a larger source and scale it down, but |
501 | * only so much... 16x is the max on SNB. |
678 | * only so much... 16x is the max on SNB. |
502 | */ |
679 | */ |
503 | if (((src_w * src_h) / (crtc_w * crtc_h)) > intel_plane->max_downscale) |
680 | if (((src_w * src_h) / (crtc_w * crtc_h)) > intel_plane->max_downscale) |
504 | return -EINVAL; |
681 | return -EINVAL; |
505 | 682 | ||
506 | /* |
683 | /* |
507 | * If the sprite is completely covering the primary plane, |
684 | * If the sprite is completely covering the primary plane, |
508 | * we can disable the primary and save power. |
685 | * we can disable the primary and save power. |
509 | */ |
686 | */ |
510 | if ((crtc_x == 0) && (crtc_y == 0) && |
687 | if ((crtc_x == 0) && (crtc_y == 0) && |
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; |
513 | 690 | ||
514 | mutex_lock(&dev->struct_mutex); |
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, |
|
- | 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); |
517 | if (ret) |
699 | if (ret) |
518 | goto out_unlock; |
700 | goto out_unlock; |
519 | 701 | ||
520 | intel_plane->obj = obj; |
702 | intel_plane->obj = obj; |
521 | 703 | ||
522 | /* |
704 | /* |
523 | * Be sure to re-enable the primary before the sprite is no longer |
705 | * Be sure to re-enable the primary before the sprite is no longer |
524 | * covering it fully. |
706 | * covering it fully. |
525 | */ |
707 | */ |
526 | if (!disable_primary) |
708 | if (!disable_primary) |
527 | intel_enable_primary(crtc); |
709 | intel_enable_primary(crtc); |
528 | 710 | ||
529 | intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y, |
711 | intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y, |
530 | crtc_w, crtc_h, x, y, src_w, src_h); |
712 | crtc_w, crtc_h, x, y, src_w, src_h); |
531 | 713 | ||
532 | if (disable_primary) |
714 | if (disable_primary) |
533 | intel_disable_primary(crtc); |
715 | intel_disable_primary(crtc); |
534 | 716 | ||
535 | /* Unpin old obj after new one is active to avoid ugliness */ |
717 | /* Unpin old obj after new one is active to avoid ugliness */ |
536 | if (old_obj) { |
718 | if (old_obj) { |
537 | /* |
719 | /* |
538 | * It's fairly common to simply update the position of |
720 | * It's fairly common to simply update the position of |
539 | * an existing object. In that case, we don't need to |
721 | * an existing object. In that case, we don't need to |
540 | * wait for vblank to avoid ugliness, we only need to |
722 | * wait for vblank to avoid ugliness, we only need to |
541 | * do the pin & ref bookkeeping. |
723 | * do the pin & ref bookkeeping. |
542 | */ |
724 | */ |
543 | if (old_obj != obj) { |
725 | if (old_obj != obj) { |
544 | mutex_unlock(&dev->struct_mutex); |
726 | mutex_unlock(&dev->struct_mutex); |
545 | intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); |
727 | intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); |
546 | mutex_lock(&dev->struct_mutex); |
728 | mutex_lock(&dev->struct_mutex); |
547 | } |
729 | } |
548 | intel_unpin_fb_obj(old_obj); |
730 | intel_unpin_fb_obj(old_obj); |
549 | } |
731 | } |
550 | 732 | ||
551 | out_unlock: |
733 | out_unlock: |
552 | mutex_unlock(&dev->struct_mutex); |
734 | mutex_unlock(&dev->struct_mutex); |
553 | out: |
735 | out: |
554 | return ret; |
736 | return ret; |
555 | } |
737 | } |
556 | 738 | ||
557 | static int |
739 | static int |
558 | intel_disable_plane(struct drm_plane *plane) |
740 | intel_disable_plane(struct drm_plane *plane) |
559 | { |
741 | { |
560 | struct drm_device *dev = plane->dev; |
742 | struct drm_device *dev = plane->dev; |
561 | struct intel_plane *intel_plane = to_intel_plane(plane); |
743 | struct intel_plane *intel_plane = to_intel_plane(plane); |
562 | int ret = 0; |
744 | int ret = 0; |
563 | 745 | ||
564 | if (plane->crtc) |
746 | if (plane->crtc) |
565 | intel_enable_primary(plane->crtc); |
747 | intel_enable_primary(plane->crtc); |
566 | intel_plane->disable_plane(plane); |
748 | intel_plane->disable_plane(plane); |
567 | 749 | ||
568 | if (!intel_plane->obj) |
750 | if (!intel_plane->obj) |
569 | goto out; |
751 | goto out; |
- | 752 | ||
- | 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; |
574 | mutex_unlock(&dev->struct_mutex); |
758 | mutex_unlock(&dev->struct_mutex); |
575 | out: |
759 | out: |
576 | 760 | ||
577 | return ret; |
761 | return ret; |
578 | } |
762 | } |
579 | 763 | ||
580 | static void intel_destroy_plane(struct drm_plane *plane) |
764 | static void intel_destroy_plane(struct drm_plane *plane) |
581 | { |
765 | { |
582 | struct intel_plane *intel_plane = to_intel_plane(plane); |
766 | struct intel_plane *intel_plane = to_intel_plane(plane); |
583 | intel_disable_plane(plane); |
767 | intel_disable_plane(plane); |
584 | drm_plane_cleanup(plane); |
768 | drm_plane_cleanup(plane); |
585 | kfree(intel_plane); |
769 | kfree(intel_plane); |
586 | } |
770 | } |
587 | 771 | ||
588 | int intel_sprite_set_colorkey(struct drm_device *dev, void *data, |
772 | int intel_sprite_set_colorkey(struct drm_device *dev, void *data, |
589 | struct drm_file *file_priv) |
773 | struct drm_file *file_priv) |
590 | { |
774 | { |
591 | struct drm_intel_sprite_colorkey *set = data; |
775 | struct drm_intel_sprite_colorkey *set = data; |
592 | struct drm_mode_object *obj; |
776 | struct drm_mode_object *obj; |
593 | struct drm_plane *plane; |
777 | struct drm_plane *plane; |
594 | struct intel_plane *intel_plane; |
778 | struct intel_plane *intel_plane; |
595 | int ret = 0; |
779 | int ret = 0; |
596 | 780 | ||
597 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
781 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
598 | return -ENODEV; |
782 | return -ENODEV; |
599 | 783 | ||
600 | /* Make sure we don't try to enable both src & dest simultaneously */ |
784 | /* Make sure we don't try to enable both src & dest simultaneously */ |
601 | if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) |
785 | if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) |
602 | return -EINVAL; |
786 | return -EINVAL; |
603 | 787 | ||
604 | drm_modeset_lock_all(dev); |
788 | drm_modeset_lock_all(dev); |
605 | 789 | ||
606 | obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE); |
790 | obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE); |
607 | if (!obj) { |
791 | if (!obj) { |
608 | ret = -EINVAL; |
792 | ret = -EINVAL; |
609 | goto out_unlock; |
793 | goto out_unlock; |
610 | } |
794 | } |
611 | 795 | ||
612 | plane = obj_to_plane(obj); |
796 | plane = obj_to_plane(obj); |
613 | intel_plane = to_intel_plane(plane); |
797 | intel_plane = to_intel_plane(plane); |
614 | ret = intel_plane->update_colorkey(plane, set); |
798 | ret = intel_plane->update_colorkey(plane, set); |
615 | 799 | ||
616 | out_unlock: |
800 | out_unlock: |
617 | drm_modeset_unlock_all(dev); |
801 | drm_modeset_unlock_all(dev); |
618 | return ret; |
802 | return ret; |
619 | } |
803 | } |
620 | 804 | ||
621 | int intel_sprite_get_colorkey(struct drm_device *dev, void *data, |
805 | int intel_sprite_get_colorkey(struct drm_device *dev, void *data, |
622 | struct drm_file *file_priv) |
806 | struct drm_file *file_priv) |
623 | { |
807 | { |
624 | struct drm_intel_sprite_colorkey *get = data; |
808 | struct drm_intel_sprite_colorkey *get = data; |
625 | struct drm_mode_object *obj; |
809 | struct drm_mode_object *obj; |
626 | struct drm_plane *plane; |
810 | struct drm_plane *plane; |
627 | struct intel_plane *intel_plane; |
811 | struct intel_plane *intel_plane; |
628 | int ret = 0; |
812 | int ret = 0; |
629 | 813 | ||
630 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
814 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
631 | return -ENODEV; |
815 | return -ENODEV; |
632 | 816 | ||
633 | drm_modeset_lock_all(dev); |
817 | drm_modeset_lock_all(dev); |
634 | 818 | ||
635 | obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE); |
819 | obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE); |
636 | if (!obj) { |
820 | if (!obj) { |
637 | ret = -EINVAL; |
821 | ret = -EINVAL; |
638 | goto out_unlock; |
822 | goto out_unlock; |
639 | } |
823 | } |
640 | 824 | ||
641 | plane = obj_to_plane(obj); |
825 | plane = obj_to_plane(obj); |
642 | intel_plane = to_intel_plane(plane); |
826 | intel_plane = to_intel_plane(plane); |
643 | intel_plane->get_colorkey(plane, get); |
827 | intel_plane->get_colorkey(plane, get); |
644 | 828 | ||
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 | } |
- | 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, |
654 | }; |
852 | }; |
655 | 853 | ||
656 | static uint32_t ilk_plane_formats[] = { |
854 | static uint32_t ilk_plane_formats[] = { |
657 | DRM_FORMAT_XRGB8888, |
855 | DRM_FORMAT_XRGB8888, |
658 | DRM_FORMAT_YUYV, |
856 | DRM_FORMAT_YUYV, |
659 | DRM_FORMAT_YVYU, |
857 | DRM_FORMAT_YVYU, |
660 | DRM_FORMAT_UYVY, |
858 | DRM_FORMAT_UYVY, |
661 | DRM_FORMAT_VYUY, |
859 | DRM_FORMAT_VYUY, |
662 | }; |
860 | }; |
663 | 861 | ||
664 | static uint32_t snb_plane_formats[] = { |
862 | static uint32_t snb_plane_formats[] = { |
665 | DRM_FORMAT_XBGR8888, |
863 | DRM_FORMAT_XBGR8888, |
666 | DRM_FORMAT_XRGB8888, |
864 | DRM_FORMAT_XRGB8888, |
667 | DRM_FORMAT_YUYV, |
865 | DRM_FORMAT_YUYV, |
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 | }; |
- | 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; |
679 | int num_plane_formats; |
891 | int num_plane_formats; |
680 | int ret; |
892 | int ret; |
681 | 893 | ||
682 | if (INTEL_INFO(dev)->gen < 5) |
894 | if (INTEL_INFO(dev)->gen < 5) |
683 | return -ENODEV; |
895 | return -ENODEV; |
684 | 896 | ||
685 | intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); |
897 | intel_plane = kzalloc(sizeof(struct intel_plane), GFP_KERNEL); |
686 | if (!intel_plane) |
898 | if (!intel_plane) |
687 | return -ENOMEM; |
899 | return -ENOMEM; |
688 | 900 | ||
689 | switch (INTEL_INFO(dev)->gen) { |
901 | switch (INTEL_INFO(dev)->gen) { |
690 | case 5: |
902 | case 5: |
691 | case 6: |
903 | case 6: |
692 | intel_plane->can_scale = true; |
904 | intel_plane->can_scale = true; |
693 | intel_plane->max_downscale = 16; |
905 | intel_plane->max_downscale = 16; |
694 | intel_plane->update_plane = ilk_update_plane; |
906 | intel_plane->update_plane = ilk_update_plane; |
695 | intel_plane->disable_plane = ilk_disable_plane; |
907 | intel_plane->disable_plane = ilk_disable_plane; |
696 | intel_plane->update_colorkey = ilk_update_colorkey; |
908 | intel_plane->update_colorkey = ilk_update_colorkey; |
697 | intel_plane->get_colorkey = ilk_get_colorkey; |
909 | intel_plane->get_colorkey = ilk_get_colorkey; |
698 | 910 | ||
699 | if (IS_GEN6(dev)) { |
911 | if (IS_GEN6(dev)) { |
700 | plane_formats = snb_plane_formats; |
912 | plane_formats = snb_plane_formats; |
701 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); |
913 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); |
702 | } else { |
914 | } else { |
703 | plane_formats = ilk_plane_formats; |
915 | plane_formats = ilk_plane_formats; |
704 | num_plane_formats = ARRAY_SIZE(ilk_plane_formats); |
916 | num_plane_formats = ARRAY_SIZE(ilk_plane_formats); |
705 | } |
917 | } |
706 | break; |
918 | break; |
707 | 919 | ||
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; |
718 | 941 | ||
719 | plane_formats = snb_plane_formats; |
942 | plane_formats = snb_plane_formats; |
720 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); |
943 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); |
- | 944 | } |
|
721 | break; |
945 | break; |
722 | 946 | ||
723 | default: |
947 | default: |
724 | kfree(intel_plane); |
948 | kfree(intel_plane); |
725 | return -ENODEV; |
949 | return -ENODEV; |
726 | } |
950 | } |
727 | 951 | ||
728 | intel_plane->pipe = pipe; |
952 | 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, |
731 | &intel_plane_funcs, |
956 | &intel_plane_funcs, |
732 | plane_formats, num_plane_formats, |
957 | plane_formats, num_plane_formats, |
733 | false); |
958 | false); |
734 | if (ret) |
959 | if (ret) |
735 | kfree(intel_plane); |
960 | kfree(intel_plane); |
736 | 961 | ||
737 | return ret; |
962 | return ret; |
738 | }><>>=>>=>>><>><>><>><>><>><>><>><>><>><>><>><> |
963 | }><>>=>>=>>><>><>><>><>><>><>><>><>><>><>><>><>><>><>><> |