Rev 5354 | Rev 6088 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5354 | Rev 6084 | ||
---|---|---|---|
Line 31... | Line 31... | ||
31 | */ |
31 | */ |
32 | #include |
32 | #include |
33 | #include |
33 | #include |
34 | #include |
34 | #include |
35 | #include |
35 | #include |
- | 36 | #include |
|
- | 37 | #include |
|
36 | #include "intel_drv.h" |
38 | #include "intel_drv.h" |
37 | #include |
39 | #include |
38 | #include "i915_drv.h" |
40 | #include "i915_drv.h" |
Line 39... | Line 41... | ||
39 | 41 | ||
Line 49... | Line 51... | ||
49 | default: |
51 | default: |
50 | return false; |
52 | return false; |
51 | } |
53 | } |
52 | } |
54 | } |
Line 53... | Line 55... | ||
53 | 55 | ||
- | 56 | static int usecs_to_scanlines(const struct drm_display_mode *adjusted_mode, |
|
54 | static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs) |
57 | int usecs) |
55 | { |
58 | { |
56 | /* paranoia */ |
59 | /* paranoia */ |
57 | if (!mode->crtc_htotal) |
60 | if (!adjusted_mode->crtc_htotal) |
Line 58... | Line 61... | ||
58 | return 1; |
61 | return 1; |
- | 62 | ||
59 | 63 | return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock, |
|
Line 60... | Line 64... | ||
60 | return DIV_ROUND_UP(usecs * mode->crtc_clock, 1000 * mode->crtc_htotal); |
64 | 1000 * adjusted_mode->crtc_htotal); |
61 | } |
65 | } |
62 | 66 | ||
Line 71... | Line 75... | ||
71 | * |
75 | * |
72 | * After a successful call to this function, interrupts will be disabled |
76 | * After a successful call to this function, interrupts will be disabled |
73 | * until a subsequent call to intel_pipe_update_end(). That is done to |
77 | * until a subsequent call to intel_pipe_update_end(). That is done to |
74 | * avoid random delays. The value written to @start_vbl_count should be |
78 | * avoid random delays. The value written to @start_vbl_count should be |
75 | * supplied to intel_pipe_update_end() for error checking. |
79 | * supplied to intel_pipe_update_end() for error checking. |
76 | * |
- | |
77 | * Return: true if the call was successful |
- | |
78 | */ |
80 | */ |
79 | bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count) |
81 | void intel_pipe_update_start(struct intel_crtc *crtc) |
80 | { |
82 | { |
- | 83 | ENTER(); |
|
81 | struct drm_device *dev = crtc->base.dev; |
84 | struct drm_device *dev = crtc->base.dev; |
82 | const struct drm_display_mode *mode = &crtc->config.adjusted_mode; |
85 | const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; |
83 | enum pipe pipe = crtc->pipe; |
86 | enum pipe pipe = crtc->pipe; |
84 | long timeout = msecs_to_jiffies_timeout(1); |
87 | long timeout = msecs_to_jiffies_timeout(1); |
85 | int scanline, min, max, vblank_start; |
88 | int scanline, min, max, vblank_start; |
- | 89 | #if 0 |
|
86 | wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); |
90 | // wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); |
87 | DEFINE_WAIT(wait); |
91 | // DEFINE_WAIT(wait); |
Line 88... | Line 92... | ||
88 | 92 | ||
89 | vblank_start = mode->crtc_vblank_start; |
93 | vblank_start = adjusted_mode->crtc_vblank_start; |
90 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
94 | if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) |
Line 91... | Line 95... | ||
91 | vblank_start = DIV_ROUND_UP(vblank_start, 2); |
95 | vblank_start = DIV_ROUND_UP(vblank_start, 2); |
92 | 96 | ||
93 | /* FIXME needs to be calibrated sensibly */ |
97 | /* FIXME needs to be calibrated sensibly */ |
Line 94... | Line 98... | ||
94 | min = vblank_start - usecs_to_scanlines(mode, 100); |
98 | min = vblank_start - usecs_to_scanlines(adjusted_mode, 100); |
95 | max = vblank_start - 1; |
99 | max = vblank_start - 1; |
Line 96... | Line 100... | ||
96 | 100 | ||
97 | if (min <= 0 || max <= 0) |
101 | if (min <= 0 || max <= 0) |
Line 98... | Line 102... | ||
98 | return false; |
102 | return; |
99 | - | ||
- | 103 | ||
100 | // if (WARN_ON(drm_vblank_get(dev, pipe))) |
104 | // if (WARN_ON(drm_vblank_get(dev, pipe))) |
Line 101... | Line 105... | ||
101 | // return false; |
105 | // return false; |
102 | 106 | ||
103 | // local_irq_disable(); |
107 | crtc->debug.min_vbl = min; |
104 | 108 | crtc->debug.max_vbl = max; |
|
Line 128... | Line 132... | ||
128 | timeout = 0; |
132 | timeout = 0; |
129 | // local_irq_disable(); |
133 | // local_irq_disable(); |
130 | } |
134 | } |
Line 131... | Line 135... | ||
131 | 135 | ||
- | 136 | finish_wait(wq, &wait); |
|
Line -... | Line 137... | ||
- | 137 | #endif |
|
132 | finish_wait(wq, &wait); |
138 | |
133 | - | ||
134 | // drm_vblank_put(dev, pipe); |
139 | crtc->debug.scanline_start = scanline; |
135 | - | ||
136 | *start_vbl_count = dev->driver->get_vblank_counter(dev, pipe); |
140 | crtc->debug.start_vbl_time = ktime_get(); |
Line 137... | Line 141... | ||
137 | 141 | crtc->debug.start_vbl_count = |
|
138 | // trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count); |
142 | dev->driver->get_vblank_counter(dev, pipe); |
Line 139... | Line 143... | ||
139 | 143 | ||
140 | return true; |
144 | trace_i915_pipe_update_vblank_evaded(crtc); |
141 | } |
145 | } |
Line 147... | Line 151... | ||
147 | * |
151 | * |
148 | * Mark the end of an update started with intel_pipe_update_start(). This |
152 | * Mark the end of an update started with intel_pipe_update_start(). This |
149 | * re-enables interrupts and verifies the update was actually completed |
153 | * re-enables interrupts and verifies the update was actually completed |
150 | * before a vblank using the value of @start_vbl_count. |
154 | * before a vblank using the value of @start_vbl_count. |
151 | */ |
155 | */ |
152 | void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count) |
156 | void intel_pipe_update_end(struct intel_crtc *crtc) |
153 | { |
157 | { |
154 | struct drm_device *dev = crtc->base.dev; |
158 | struct drm_device *dev = crtc->base.dev; |
155 | enum pipe pipe = crtc->pipe; |
159 | enum pipe pipe = crtc->pipe; |
- | 160 | int scanline_end = intel_get_crtc_scanline(crtc); |
|
156 | u32 end_vbl_count = dev->driver->get_vblank_counter(dev, pipe); |
161 | u32 end_vbl_count = dev->driver->get_vblank_counter(dev, pipe); |
- | 162 | ktime_t end_vbl_time = ktime_get(); |
|
Line 157... | Line 163... | ||
157 | 163 | ||
Line 158... | Line 164... | ||
158 | // trace_i915_pipe_update_end(crtc, end_vbl_count); |
164 | trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end); |
Line -... | Line 165... | ||
- | 165 | ||
159 | 166 | // local_irq_enable(); |
|
160 | // local_irq_enable(); |
167 | |
161 | 168 | if (crtc->debug.start_vbl_count && |
|
- | 169 | crtc->debug.start_vbl_count != end_vbl_count) { |
|
- | 170 | DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n", |
|
- | 171 | pipe_name(pipe), crtc->debug.start_vbl_count, |
|
- | 172 | end_vbl_count, |
|
162 | if (start_vbl_count != end_vbl_count) |
173 | ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time), |
163 | DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u)\n", |
- | |
164 | pipe_name(pipe), start_vbl_count, end_vbl_count); |
- | |
165 | } |
- | |
166 | - | ||
167 | static void intel_update_primary_plane(struct intel_crtc *crtc) |
- | |
168 | { |
- | |
169 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; |
- | |
170 | int reg = DSPCNTR(crtc->plane); |
- | |
171 | - | ||
172 | if (crtc->primary_enabled) |
- | |
173 | I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); |
174 | crtc->debug.min_vbl, crtc->debug.max_vbl, |
Line 174... | Line 175... | ||
174 | else |
175 | crtc->debug.scanline_start, scanline_end); |
175 | I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); |
176 | } |
176 | } |
177 | } |
177 | 178 | ||
178 | static void |
179 | static void |
179 | skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, |
180 | skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc, |
180 | struct drm_framebuffer *fb, |
181 | struct drm_framebuffer *fb, |
181 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
182 | int crtc_x, int crtc_y, |
182 | unsigned int crtc_w, unsigned int crtc_h, |
183 | unsigned int crtc_w, unsigned int crtc_h, |
183 | uint32_t x, uint32_t y, |
184 | uint32_t x, uint32_t y, |
184 | uint32_t src_w, uint32_t src_h) |
185 | uint32_t src_w, uint32_t src_h) |
- | 186 | { |
|
185 | { |
187 | struct drm_device *dev = drm_plane->dev; |
186 | struct drm_device *dev = drm_plane->dev; |
188 | struct drm_i915_private *dev_priv = dev->dev_private; |
187 | struct drm_i915_private *dev_priv = dev->dev_private; |
189 | struct intel_plane *intel_plane = to_intel_plane(drm_plane); |
188 | struct intel_plane *intel_plane = to_intel_plane(drm_plane); |
190 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
- | 191 | const int pipe = intel_plane->pipe; |
|
- | 192 | const int plane = intel_plane->plane + 1; |
|
- | 193 | u32 plane_ctl, stride_div, stride; |
|
- | 194 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
|
- | 195 | const struct drm_intel_sprite_colorkey *key = |
|
- | 196 | &to_intel_plane_state(drm_plane->state)->ckey; |
|
- | 197 | unsigned long surf_addr; |
|
- | 198 | u32 tile_height, plane_offset, plane_size; |
|
- | 199 | unsigned int rotation; |
|
- | 200 | int x_offset, y_offset; |
|
- | 201 | struct intel_crtc_state *crtc_state = to_intel_crtc(crtc)->config; |
|
- | 202 | int scaler_id; |
|
Line 189... | Line 203... | ||
189 | const int pipe = intel_plane->pipe; |
203 | |
190 | const int plane = intel_plane->plane + 1; |
- | |
191 | u32 plane_ctl, stride; |
- | |
192 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
- | |
193 | - | ||
194 | plane_ctl = I915_READ(PLANE_CTL(pipe, plane)); |
- | |
195 | - | ||
196 | /* Mask out pixel format bits in case we change it */ |
- | |
197 | plane_ctl &= ~PLANE_CTL_FORMAT_MASK; |
- | |
198 | plane_ctl &= ~PLANE_CTL_ORDER_RGBX; |
- | |
199 | plane_ctl &= ~PLANE_CTL_YUV422_ORDER_MASK; |
- | |
200 | plane_ctl &= ~PLANE_CTL_TILED_MASK; |
204 | plane_ctl = PLANE_CTL_ENABLE | |
201 | plane_ctl &= ~PLANE_CTL_ALPHA_MASK; |
- | |
202 | plane_ctl &= ~PLANE_CTL_ROTATE_MASK; |
- | |
203 | - | ||
204 | /* Trickle feed has to be enabled */ |
- | |
205 | plane_ctl &= ~PLANE_CTL_TRICKLE_FEED_DISABLE; |
- | |
206 | - | ||
207 | switch (fb->pixel_format) { |
- | |
208 | case DRM_FORMAT_RGB565: |
- | |
209 | plane_ctl |= PLANE_CTL_FORMAT_RGB_565; |
- | |
210 | break; |
- | |
211 | case DRM_FORMAT_XBGR8888: |
- | |
212 | plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX; |
- | |
213 | break; |
- | |
214 | case DRM_FORMAT_XRGB8888: |
- | |
215 | plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888; |
- | |
216 | break; |
- | |
217 | /* |
- | |
218 | * XXX: For ARBG/ABGR formats we default to expecting scanout buffers |
- | |
219 | * to be already pre-multiplied. We need to add a knob (or a different |
- | |
220 | * DRM_FORMAT) for user-space to configure that. |
- | |
221 | */ |
- | |
222 | case DRM_FORMAT_ABGR8888: |
- | |
223 | plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | |
- | |
224 | PLANE_CTL_ORDER_RGBX | |
- | |
225 | PLANE_CTL_ALPHA_SW_PREMULTIPLY; |
- | |
226 | break; |
- | |
227 | case DRM_FORMAT_ARGB8888: |
- | |
228 | plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | |
- | |
229 | PLANE_CTL_ALPHA_SW_PREMULTIPLY; |
- | |
230 | break; |
- | |
231 | case DRM_FORMAT_YUYV: |
- | |
232 | plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV; |
- | |
233 | break; |
- | |
234 | case DRM_FORMAT_YVYU: |
- | |
235 | plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU; |
- | |
236 | break; |
- | |
237 | case DRM_FORMAT_UYVY: |
- | |
238 | plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY; |
- | |
239 | break; |
- | |
240 | case DRM_FORMAT_VYUY: |
- | |
241 | plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY; |
- | |
242 | break; |
- | |
243 | default: |
- | |
244 | BUG(); |
- | |
245 | } |
- | |
246 | - | ||
247 | switch (obj->tiling_mode) { |
- | |
248 | case I915_TILING_NONE: |
- | |
249 | stride = fb->pitches[0] >> 6; |
- | |
250 | break; |
- | |
251 | case I915_TILING_X: |
- | |
252 | plane_ctl |= PLANE_CTL_TILED_X; |
- | |
253 | stride = fb->pitches[0] >> 9; |
- | |
254 | break; |
- | |
Line 255... | Line 205... | ||
255 | default: |
205 | PLANE_CTL_PIPE_GAMMA_ENABLE | |
256 | BUG(); |
206 | PLANE_CTL_PIPE_CSC_ENABLE; |
Line 257... | Line 207... | ||
257 | } |
207 | |
258 | if (intel_plane->rotation == BIT(DRM_ROTATE_180)) |
208 | plane_ctl |= skl_plane_ctl_format(fb->pixel_format); |
259 | plane_ctl |= PLANE_CTL_ROTATE_180; |
209 | plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]); |
Line -... | Line 210... | ||
- | 210 | ||
- | 211 | rotation = drm_plane->state->rotation; |
|
- | 212 | plane_ctl |= skl_plane_ctl_rotation(rotation); |
|
- | 213 | ||
- | 214 | intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h, |
|
260 | 215 | pixel_size, true, |
|
261 | plane_ctl |= PLANE_CTL_ENABLE; |
216 | src_w != crtc_w || src_h != crtc_h); |
262 | plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE; |
217 | |
263 | 218 | stride_div = intel_fb_stride_alignment(dev, fb->modifier[0], |
|
264 | intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h, |
219 | fb->pixel_format); |
Line 265... | Line -... | ||
265 | pixel_size, true, |
- | |
266 | src_w != crtc_w || src_h != crtc_h); |
- | |
267 | - | ||
268 | /* Sizes are 0 based */ |
- | |
269 | src_w--; |
- | |
270 | src_h--; |
- | |
271 | crtc_w--; |
- | |
272 | crtc_h--; |
- | |
273 | - | ||
274 | I915_WRITE(PLANE_OFFSET(pipe, plane), (y << 16) | x); |
- | |
275 | I915_WRITE(PLANE_STRIDE(pipe, plane), stride); |
- | |
276 | I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x); |
- | |
277 | I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w); |
- | |
278 | I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl); |
- | |
279 | I915_WRITE(PLANE_SURF(pipe, plane), i915_gem_obj_ggtt_offset(obj)); |
- | |
280 | POSTING_READ(PLANE_SURF(pipe, plane)); |
- | |
281 | } |
- | |
282 | - | ||
283 | static void |
- | |
284 | skl_disable_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc) |
- | |
285 | { |
- | |
286 | struct drm_device *dev = drm_plane->dev; |
- | |
287 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
288 | struct intel_plane *intel_plane = to_intel_plane(drm_plane); |
- | |
289 | const int pipe = intel_plane->pipe; |
- | |
290 | const int plane = intel_plane->plane + 1; |
- | |
291 | - | ||
292 | I915_WRITE(PLANE_CTL(pipe, plane), |
- | |
293 | I915_READ(PLANE_CTL(pipe, plane)) & ~PLANE_CTL_ENABLE); |
- | |
294 | - | ||
295 | /* Activate double buffered register update */ |
- | |
296 | I915_WRITE(PLANE_CTL(pipe, plane), 0); |
- | |
297 | POSTING_READ(PLANE_CTL(pipe, plane)); |
- | |
298 | - | ||
299 | intel_update_sprite_watermarks(drm_plane, crtc, 0, 0, 0, false, false); |
- | |
300 | } |
- | |
301 | - | ||
302 | static int |
220 | |
303 | skl_update_colorkey(struct drm_plane *drm_plane, |
- | |
304 | struct drm_intel_sprite_colorkey *key) |
221 | scaler_id = to_intel_plane_state(drm_plane->state)->scaler_id; |
305 | { |
222 | |
306 | struct drm_device *dev = drm_plane->dev; |
223 | /* Sizes are 0 based */ |
- | 224 | src_w--; |
|
Line 307... | Line -... | ||
307 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
308 | struct intel_plane *intel_plane = to_intel_plane(drm_plane); |
- | |
309 | const int pipe = intel_plane->pipe; |
225 | src_h--; |
310 | const int plane = intel_plane->plane; |
226 | crtc_w--; |
311 | u32 plane_ctl; |
227 | crtc_h--; |
312 | 228 | ||
313 | I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value); |
- | |
Line 314... | Line 229... | ||
314 | I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value); |
229 | if (key->flags) { |
Line -... | Line 230... | ||
- | 230 | I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value); |
|
- | 231 | I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value); |
|
- | 232 | I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask); |
|
- | 233 | } |
|
- | 234 | ||
- | 235 | if (key->flags & I915_SET_COLORKEY_DESTINATION) |
|
- | 236 | plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION; |
|
- | 237 | else if (key->flags & I915_SET_COLORKEY_SOURCE) |
|
315 | I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask); |
238 | plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE; |
- | 239 | ||
- | 240 | surf_addr = intel_plane_obj_offset(intel_plane, obj, 0); |
|
- | 241 | ||
- | 242 | if (intel_rotation_90_or_270(rotation)) { |
|
- | 243 | /* stride: Surface height in tiles */ |
|
- | 244 | tile_height = intel_tile_height(dev, fb->pixel_format, |
|
- | 245 | fb->modifier[0], 0); |
|
- | 246 | stride = DIV_ROUND_UP(fb->height, tile_height); |
|
- | 247 | plane_size = (src_w << 16) | src_h; |
|
- | 248 | x_offset = stride * tile_height - y - (src_h + 1); |
|
- | 249 | y_offset = x; |
|
- | 250 | } else { |
|
- | 251 | stride = fb->pitches[0] / stride_div; |
|
- | 252 | plane_size = (src_h << 16) | src_w; |
|
- | 253 | x_offset = x; |
|
- | 254 | y_offset = y; |
|
- | 255 | } |
|
- | 256 | plane_offset = y_offset << 16 | x_offset; |
|
- | 257 | ||
- | 258 | I915_WRITE(PLANE_OFFSET(pipe, plane), plane_offset); |
|
- | 259 | I915_WRITE(PLANE_STRIDE(pipe, plane), stride); |
|
- | 260 | I915_WRITE(PLANE_SIZE(pipe, plane), plane_size); |
|
- | 261 | ||
- | 262 | /* program plane scaler */ |
|
- | 263 | if (scaler_id >= 0) { |
|
- | 264 | uint32_t ps_ctrl = 0; |
|
- | 265 | ||
- | 266 | DRM_DEBUG_KMS("plane = %d PS_PLANE_SEL(plane) = 0x%x\n", plane, |
|
- | 267 | PS_PLANE_SEL(plane)); |
|
- | 268 | ps_ctrl = PS_SCALER_EN | PS_PLANE_SEL(plane) | |
|
- | 269 | crtc_state->scaler_state.scalers[scaler_id].mode; |
|
- | 270 | I915_WRITE(SKL_PS_CTRL(pipe, scaler_id), ps_ctrl); |
|
- | 271 | I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0); |
|
316 | 272 | I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y); |
|
Line 317... | Line 273... | ||
317 | plane_ctl = I915_READ(PLANE_CTL(pipe, plane)); |
273 | I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id), |
318 | plane_ctl &= ~PLANE_CTL_KEY_ENABLE_MASK; |
274 | ((crtc_w + 1) << 16)|(crtc_h + 1)); |
319 | if (key->flags & I915_SET_COLORKEY_DESTINATION) |
- | |
320 | plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION; |
275 | |
321 | else if (key->flags & I915_SET_COLORKEY_SOURCE) |
276 | I915_WRITE(PLANE_POS(pipe, plane), 0); |
322 | plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE; |
277 | } else { |
323 | I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl); |
278 | I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x); |
324 | 279 | } |
|
325 | POSTING_READ(PLANE_CTL(pipe, plane)); |
280 | |
326 | - | ||
Line 327... | Line 281... | ||
327 | return 0; |
281 | I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl); |
328 | } |
- | |
329 | - | ||
Line -... | Line 282... | ||
- | 282 | I915_WRITE(PLANE_SURF(pipe, plane), surf_addr); |
|
330 | static void |
283 | POSTING_READ(PLANE_SURF(pipe, plane)); |
Line 331... | Line 284... | ||
331 | skl_get_colorkey(struct drm_plane *drm_plane, |
284 | } |
332 | struct drm_intel_sprite_colorkey *key) |
- | |
333 | { |
- | |
334 | struct drm_device *dev = drm_plane->dev; |
- | |
335 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
336 | struct intel_plane *intel_plane = to_intel_plane(drm_plane); |
- | |
337 | const int pipe = intel_plane->pipe; |
- | |
338 | const int plane = intel_plane->plane; |
- | |
339 | u32 plane_ctl; |
- | |
340 | - | ||
341 | key->min_value = I915_READ(PLANE_KEYVAL(pipe, plane)); |
285 | |
Line 342... | Line 286... | ||
342 | key->max_value = I915_READ(PLANE_KEYMAX(pipe, plane)); |
286 | static void |
343 | key->channel_mask = I915_READ(PLANE_KEYMSK(pipe, plane)); |
287 | skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) |
344 | 288 | { |
|
Line 396... | Line 340... | ||
396 | } |
340 | } |
Line 397... | Line 341... | ||
397 | 341 | ||
398 | static void |
342 | static void |
399 | vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, |
343 | vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, |
400 | struct drm_framebuffer *fb, |
344 | struct drm_framebuffer *fb, |
401 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
345 | int crtc_x, int crtc_y, |
402 | unsigned int crtc_w, unsigned int crtc_h, |
346 | unsigned int crtc_w, unsigned int crtc_h, |
403 | uint32_t x, uint32_t y, |
347 | uint32_t x, uint32_t y, |
404 | uint32_t src_w, uint32_t src_h) |
348 | uint32_t src_w, uint32_t src_h) |
405 | { |
349 | { |
406 | struct drm_device *dev = dplane->dev; |
350 | struct drm_device *dev = dplane->dev; |
407 | struct drm_i915_private *dev_priv = dev->dev_private; |
351 | struct drm_i915_private *dev_priv = dev->dev_private; |
408 | struct intel_plane *intel_plane = to_intel_plane(dplane); |
352 | struct intel_plane *intel_plane = to_intel_plane(dplane); |
409 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
353 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
410 | int pipe = intel_plane->pipe; |
354 | int pipe = intel_plane->pipe; |
411 | int plane = intel_plane->plane; |
355 | int plane = intel_plane->plane; |
412 | u32 sprctl; |
356 | u32 sprctl; |
413 | unsigned long sprsurf_offset, linear_offset; |
357 | unsigned long sprsurf_offset, linear_offset; |
414 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
358 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
415 | u32 start_vbl_count; |
359 | const struct drm_intel_sprite_colorkey *key = |
Line 416... | Line -... | ||
416 | bool atomic_update; |
- | |
417 | - | ||
418 | sprctl = I915_READ(SPCNTR(pipe, plane)); |
- | |
419 | - | ||
420 | /* Mask out pixel format bits in case we change it */ |
- | |
421 | sprctl &= ~SP_PIXFORMAT_MASK; |
360 | &to_intel_plane_state(dplane->state)->ckey; |
422 | sprctl &= ~SP_YUV_BYTE_ORDER_MASK; |
- | |
Line 423... | Line 361... | ||
423 | sprctl &= ~SP_TILED; |
361 | |
424 | sprctl &= ~SP_ROTATE_180; |
362 | sprctl = SP_ENABLE; |
425 | 363 | ||
426 | switch (fb->pixel_format) { |
364 | switch (fb->pixel_format) { |
Line 473... | Line 411... | ||
473 | sprctl |= SP_GAMMA_ENABLE; |
411 | sprctl |= SP_GAMMA_ENABLE; |
Line 474... | Line 412... | ||
474 | 412 | ||
475 | if (obj->tiling_mode != I915_TILING_NONE) |
413 | if (obj->tiling_mode != I915_TILING_NONE) |
Line 476... | Line -... | ||
476 | sprctl |= SP_TILED; |
- | |
477 | - | ||
478 | sprctl |= SP_ENABLE; |
- | |
479 | - | ||
480 | intel_update_sprite_watermarks(dplane, crtc, src_w, src_h, |
- | |
481 | pixel_size, true, |
- | |
482 | src_w != crtc_w || src_h != crtc_h); |
414 | sprctl |= SP_TILED; |
483 | 415 | ||
484 | /* Sizes are 0 based */ |
416 | /* Sizes are 0 based */ |
485 | src_w--; |
417 | src_w--; |
486 | src_h--; |
418 | src_h--; |
Line 487... | Line 419... | ||
487 | crtc_w--; |
419 | crtc_w--; |
488 | crtc_h--; |
420 | crtc_h--; |
- | 421 | ||
489 | 422 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
|
490 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
423 | sprsurf_offset = intel_gen4_compute_page_offset(dev_priv, |
491 | sprsurf_offset = intel_gen4_compute_page_offset(&x, &y, |
424 | &x, &y, |
492 | obj->tiling_mode, |
425 | obj->tiling_mode, |
Line 493... | Line 426... | ||
493 | pixel_size, |
426 | pixel_size, |
494 | fb->pitches[0]); |
427 | fb->pitches[0]); |
Line 495... | Line 428... | ||
495 | linear_offset -= sprsurf_offset; |
428 | linear_offset -= sprsurf_offset; |
496 | 429 | ||
497 | if (intel_plane->rotation == BIT(DRM_ROTATE_180)) { |
430 | if (dplane->state->rotation == BIT(DRM_ROTATE_180)) { |
498 | sprctl |= SP_ROTATE_180; |
431 | sprctl |= SP_ROTATE_180; |
Line -... | Line 432... | ||
- | 432 | ||
- | 433 | x += src_w; |
|
- | 434 | y += src_h; |
|
499 | 435 | linear_offset += src_h * fb->pitches[0] + src_w * pixel_size; |
|
- | 436 | } |
|
Line 500... | Line 437... | ||
500 | x += src_w; |
437 | |
- | 438 | if (key->flags) { |
|
Line 501... | Line 439... | ||
501 | y += src_h; |
439 | I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value); |
502 | linear_offset += src_h * fb->pitches[0] + src_w * pixel_size; |
440 | I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value); |
Line 503... | Line 441... | ||
503 | } |
441 | I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask); |
Line 521... | Line 459... | ||
521 | 459 | ||
522 | I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); |
460 | I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); |
523 | I915_WRITE(SPCNTR(pipe, plane), sprctl); |
461 | I915_WRITE(SPCNTR(pipe, plane), sprctl); |
524 | I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) + |
462 | I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) + |
525 | sprsurf_offset); |
- | |
526 | 463 | sprsurf_offset); |
|
527 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
- | |
528 | - | ||
529 | if (atomic_update) |
- | |
530 | intel_pipe_update_end(intel_crtc, start_vbl_count); |
464 | POSTING_READ(SPSURF(pipe, plane)); |
Line 531... | Line 465... | ||
531 | } |
465 | } |
532 | 466 | ||
533 | static void |
467 | static void |
534 | vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) |
468 | vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) |
535 | { |
469 | { |
536 | struct drm_device *dev = dplane->dev; |
470 | struct drm_device *dev = dplane->dev; |
537 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
538 | struct intel_plane *intel_plane = to_intel_plane(dplane); |
471 | struct drm_i915_private *dev_priv = dev->dev_private; |
539 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
472 | struct intel_plane *intel_plane = to_intel_plane(dplane); |
540 | int pipe = intel_plane->pipe; |
- | |
541 | int plane = intel_plane->plane; |
- | |
542 | u32 start_vbl_count; |
- | |
543 | bool atomic_update; |
- | |
Line 544... | Line 473... | ||
544 | 473 | int pipe = intel_plane->pipe; |
|
Line 545... | Line -... | ||
545 | atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); |
- | |
546 | - | ||
547 | intel_update_primary_plane(intel_crtc); |
- | |
548 | 474 | int plane = intel_plane->plane; |
|
549 | I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) & |
- | |
550 | ~SP_ENABLE); |
- | |
551 | /* Activate double buffered register update */ |
- | |
552 | I915_WRITE(SPSURF(pipe, plane), 0); |
- | |
553 | - | ||
554 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
- | |
555 | - | ||
556 | if (atomic_update) |
- | |
557 | intel_pipe_update_end(intel_crtc, start_vbl_count); |
- | |
558 | - | ||
559 | intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false); |
- | |
560 | } |
- | |
561 | - | ||
562 | static int |
- | |
563 | vlv_update_colorkey(struct drm_plane *dplane, |
- | |
564 | struct drm_intel_sprite_colorkey *key) |
- | |
565 | { |
- | |
566 | struct drm_device *dev = dplane->dev; |
- | |
567 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
568 | struct intel_plane *intel_plane = to_intel_plane(dplane); |
- | |
569 | int pipe = intel_plane->pipe; |
- | |
570 | int plane = intel_plane->plane; |
- | |
571 | u32 sprctl; |
- | |
572 | - | ||
573 | if (key->flags & I915_SET_COLORKEY_DESTINATION) |
- | |
574 | return -EINVAL; |
- | |
575 | - | ||
576 | I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value); |
- | |
577 | I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value); |
- | |
578 | I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask); |
- | |
579 | - | ||
580 | sprctl = I915_READ(SPCNTR(pipe, plane)); |
- | |
581 | sprctl &= ~SP_SOURCE_KEY; |
- | |
582 | if (key->flags & I915_SET_COLORKEY_SOURCE) |
475 | |
583 | sprctl |= SP_SOURCE_KEY; |
- | |
584 | I915_WRITE(SPCNTR(pipe, plane), sprctl); |
- | |
585 | - | ||
586 | POSTING_READ(SPKEYMSK(pipe, plane)); |
- | |
587 | - | ||
588 | return 0; |
- | |
589 | } |
- | |
590 | - | ||
591 | static void |
- | |
592 | vlv_get_colorkey(struct drm_plane *dplane, |
- | |
593 | struct drm_intel_sprite_colorkey *key) |
- | |
594 | { |
- | |
595 | struct drm_device *dev = dplane->dev; |
- | |
596 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
597 | struct intel_plane *intel_plane = to_intel_plane(dplane); |
- | |
598 | int pipe = intel_plane->pipe; |
- | |
599 | int plane = intel_plane->plane; |
- | |
600 | u32 sprctl; |
- | |
601 | - | ||
602 | key->min_value = I915_READ(SPKEYMINVAL(pipe, plane)); |
- | |
603 | key->max_value = I915_READ(SPKEYMAXVAL(pipe, plane)); |
- | |
604 | key->channel_mask = I915_READ(SPKEYMSK(pipe, plane)); |
- | |
605 | - | ||
606 | sprctl = I915_READ(SPCNTR(pipe, plane)); |
- | |
607 | if (sprctl & SP_SOURCE_KEY) |
476 | I915_WRITE(SPCNTR(pipe, plane), 0); |
Line 608... | Line 477... | ||
608 | key->flags = I915_SET_COLORKEY_SOURCE; |
477 | |
609 | else |
478 | I915_WRITE(SPSURF(pipe, plane), 0); |
610 | key->flags = I915_SET_COLORKEY_NONE; |
479 | POSTING_READ(SPSURF(pipe, plane)); |
611 | } |
480 | } |
612 | 481 | ||
613 | static void |
482 | static void |
614 | ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, |
483 | ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, |
615 | struct drm_framebuffer *fb, |
484 | struct drm_framebuffer *fb, |
616 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
485 | int crtc_x, int crtc_y, |
617 | unsigned int crtc_w, unsigned int crtc_h, |
486 | unsigned int crtc_w, unsigned int crtc_h, |
618 | uint32_t x, uint32_t y, |
487 | uint32_t x, uint32_t y, |
619 | uint32_t src_w, uint32_t src_h) |
488 | uint32_t src_w, uint32_t src_h) |
620 | { |
489 | { |
621 | struct drm_device *dev = plane->dev; |
490 | struct drm_device *dev = plane->dev; |
622 | struct drm_i915_private *dev_priv = dev->dev_private; |
491 | struct drm_i915_private *dev_priv = dev->dev_private; |
623 | struct intel_plane *intel_plane = to_intel_plane(plane); |
492 | struct intel_plane *intel_plane = to_intel_plane(plane); |
624 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
493 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
625 | int pipe = intel_plane->pipe; |
494 | enum pipe pipe = intel_plane->pipe; |
Line 626... | Line -... | ||
626 | u32 sprctl, sprscale = 0; |
- | |
627 | unsigned long sprsurf_offset, linear_offset; |
- | |
628 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
- | |
629 | u32 start_vbl_count; |
- | |
630 | bool atomic_update; |
- | |
631 | - | ||
632 | sprctl = I915_READ(SPRCTL(pipe)); |
495 | u32 sprctl, sprscale = 0; |
633 | - | ||
Line 634... | Line 496... | ||
634 | /* Mask out pixel format bits in case we change it */ |
496 | unsigned long sprsurf_offset, linear_offset; |
635 | sprctl &= ~SPRITE_PIXFORMAT_MASK; |
497 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
636 | sprctl &= ~SPRITE_RGB_ORDER_RGBX; |
498 | const struct drm_intel_sprite_colorkey *key = |
637 | sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK; |
499 | &to_intel_plane_state(plane->state)->ckey; |
Line 673... | Line 535... | ||
673 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
535 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
674 | sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE; |
536 | sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE; |
675 | else |
537 | else |
676 | sprctl |= SPRITE_TRICKLE_FEED_DISABLE; |
538 | sprctl |= SPRITE_TRICKLE_FEED_DISABLE; |
Line 677... | Line -... | ||
677 | - | ||
678 | sprctl |= SPRITE_ENABLE; |
- | |
679 | 539 | ||
680 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
540 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
Line 681... | Line 541... | ||
681 | sprctl |= SPRITE_PIPE_CSC_ENABLE; |
541 | sprctl |= SPRITE_PIPE_CSC_ENABLE; |
682 | 542 | ||
Line 693... | Line 553... | ||
693 | if (crtc_w != src_w || crtc_h != src_h) |
553 | if (crtc_w != src_w || crtc_h != src_h) |
694 | sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; |
554 | sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; |
Line 695... | Line 555... | ||
695 | 555 | ||
696 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
556 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
697 | sprsurf_offset = |
557 | sprsurf_offset = |
- | 558 | intel_gen4_compute_page_offset(dev_priv, |
|
698 | intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, |
559 | &x, &y, obj->tiling_mode, |
699 | pixel_size, fb->pitches[0]); |
560 | pixel_size, fb->pitches[0]); |
Line 700... | Line 561... | ||
700 | linear_offset -= sprsurf_offset; |
561 | linear_offset -= sprsurf_offset; |
701 | 562 | ||
Line 702... | Line 563... | ||
702 | if (intel_plane->rotation == BIT(DRM_ROTATE_180)) { |
563 | if (plane->state->rotation == BIT(DRM_ROTATE_180)) { |
703 | sprctl |= SPRITE_ROTATE_180; |
564 | sprctl |= SPRITE_ROTATE_180; |
704 | 565 | ||
Line 709... | Line 570... | ||
709 | linear_offset += src_h * fb->pitches[0] + |
570 | linear_offset += src_h * fb->pitches[0] + |
710 | src_w * pixel_size; |
571 | src_w * pixel_size; |
711 | } |
572 | } |
712 | } |
573 | } |
Line -... | Line 574... | ||
- | 574 | ||
- | 575 | if (key->flags) { |
|
- | 576 | I915_WRITE(SPRKEYVAL(pipe), key->min_value); |
|
713 | 577 | I915_WRITE(SPRKEYMAX(pipe), key->max_value); |
|
- | 578 | I915_WRITE(SPRKEYMSK(pipe), key->channel_mask); |
|
Line -... | Line 579... | ||
- | 579 | } |
|
- | 580 | ||
714 | atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); |
581 | if (key->flags & I915_SET_COLORKEY_DESTINATION) |
- | 582 | sprctl |= SPRITE_DEST_KEY; |
|
Line 715... | Line 583... | ||
715 | 583 | else if (key->flags & I915_SET_COLORKEY_SOURCE) |
|
716 | intel_update_primary_plane(intel_crtc); |
584 | sprctl |= SPRITE_SOURCE_KEY; |
Line 717... | Line 585... | ||
717 | 585 | ||
Line 731... | Line 599... | ||
731 | if (intel_plane->can_scale) |
599 | if (intel_plane->can_scale) |
732 | I915_WRITE(SPRSCALE(pipe), sprscale); |
600 | I915_WRITE(SPRSCALE(pipe), sprscale); |
733 | I915_WRITE(SPRCTL(pipe), sprctl); |
601 | I915_WRITE(SPRCTL(pipe), sprctl); |
734 | I915_WRITE(SPRSURF(pipe), |
602 | I915_WRITE(SPRSURF(pipe), |
735 | i915_gem_obj_ggtt_offset(obj) + sprsurf_offset); |
603 | i915_gem_obj_ggtt_offset(obj) + sprsurf_offset); |
736 | - | ||
737 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
- | |
738 | - | ||
739 | if (atomic_update) |
604 | POSTING_READ(SPRSURF(pipe)); |
740 | intel_pipe_update_end(intel_crtc, start_vbl_count); |
- | |
741 | } |
605 | } |
Line 742... | Line 606... | ||
742 | 606 | ||
743 | static void |
607 | static void |
744 | ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) |
608 | ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) |
745 | { |
609 | { |
746 | struct drm_device *dev = plane->dev; |
610 | struct drm_device *dev = plane->dev; |
747 | struct drm_i915_private *dev_priv = dev->dev_private; |
611 | struct drm_i915_private *dev_priv = dev->dev_private; |
748 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | |
749 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
612 | struct intel_plane *intel_plane = to_intel_plane(plane); |
750 | int pipe = intel_plane->pipe; |
- | |
751 | u32 start_vbl_count; |
- | |
752 | bool atomic_update; |
- | |
753 | - | ||
Line 754... | Line -... | ||
754 | atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); |
- | |
755 | - | ||
756 | intel_update_primary_plane(intel_crtc); |
613 | int pipe = intel_plane->pipe; |
757 | 614 | ||
758 | I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); |
615 | I915_WRITE(SPRCTL(pipe), 0); |
759 | /* Can't leave the scaler enabled... */ |
616 | /* Can't leave the scaler enabled... */ |
760 | if (intel_plane->can_scale) |
- | |
761 | I915_WRITE(SPRSCALE(pipe), 0); |
- | |
762 | /* Activate double buffered register update */ |
- | |
763 | I915_WRITE(SPRSURF(pipe), 0); |
- | |
764 | - | ||
765 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
- | |
766 | - | ||
767 | if (atomic_update) |
- | |
768 | intel_pipe_update_end(intel_crtc, start_vbl_count); |
- | |
769 | - | ||
770 | /* |
- | |
771 | * Avoid underruns when disabling the sprite. |
- | |
772 | * FIXME remove once watermark updates are done properly. |
- | |
773 | */ |
- | |
774 | intel_wait_for_vblank(dev, pipe); |
- | |
775 | - | ||
776 | intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false); |
- | |
777 | } |
- | |
778 | - | ||
779 | static int |
- | |
780 | ivb_update_colorkey(struct drm_plane *plane, |
- | |
781 | struct drm_intel_sprite_colorkey *key) |
- | |
782 | { |
- | |
783 | struct drm_device *dev = plane->dev; |
- | |
784 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
785 | struct intel_plane *intel_plane; |
- | |
786 | u32 sprctl; |
- | |
787 | int ret = 0; |
- | |
788 | - | ||
789 | intel_plane = to_intel_plane(plane); |
- | |
790 | - | ||
791 | I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value); |
- | |
792 | I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value); |
- | |
793 | I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask); |
- | |
794 | - | ||
795 | sprctl = I915_READ(SPRCTL(intel_plane->pipe)); |
- | |
796 | sprctl &= ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY); |
- | |
797 | if (key->flags & I915_SET_COLORKEY_DESTINATION) |
- | |
798 | sprctl |= SPRITE_DEST_KEY; |
- | |
799 | else if (key->flags & I915_SET_COLORKEY_SOURCE) |
- | |
Line 800... | Line 617... | ||
800 | sprctl |= SPRITE_SOURCE_KEY; |
617 | if (intel_plane->can_scale) |
801 | I915_WRITE(SPRCTL(intel_plane->pipe), sprctl); |
- | |
802 | - | ||
803 | POSTING_READ(SPRKEYMSK(intel_plane->pipe)); |
- | |
804 | - | ||
805 | return ret; |
- | |
806 | } |
- | |
807 | - | ||
808 | static void |
- | |
809 | ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) |
- | |
810 | { |
- | |
811 | struct drm_device *dev = plane->dev; |
- | |
812 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
813 | struct intel_plane *intel_plane; |
- | |
814 | u32 sprctl; |
- | |
815 | - | ||
816 | intel_plane = to_intel_plane(plane); |
- | |
817 | - | ||
818 | key->min_value = I915_READ(SPRKEYVAL(intel_plane->pipe)); |
- | |
819 | key->max_value = I915_READ(SPRKEYMAX(intel_plane->pipe)); |
- | |
820 | key->channel_mask = I915_READ(SPRKEYMSK(intel_plane->pipe)); |
618 | I915_WRITE(SPRSCALE(pipe), 0); |
821 | key->flags = 0; |
- | |
822 | - | ||
823 | sprctl = I915_READ(SPRCTL(intel_plane->pipe)); |
- | |
824 | - | ||
825 | if (sprctl & SPRITE_DEST_KEY) |
- | |
826 | key->flags = I915_SET_COLORKEY_DESTINATION; |
- | |
827 | else if (sprctl & SPRITE_SOURCE_KEY) |
- | |
828 | key->flags = I915_SET_COLORKEY_SOURCE; |
619 | |
Line 829... | Line 620... | ||
829 | else |
620 | I915_WRITE(SPRSURF(pipe), 0); |
830 | key->flags = I915_SET_COLORKEY_NONE; |
621 | POSTING_READ(SPRSURF(pipe)); |
831 | } |
622 | } |
832 | 623 | ||
833 | static void |
624 | static void |
834 | ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, |
625 | ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, |
835 | struct drm_framebuffer *fb, |
626 | struct drm_framebuffer *fb, |
836 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
627 | int crtc_x, int crtc_y, |
837 | unsigned int crtc_w, unsigned int crtc_h, |
628 | unsigned int crtc_w, unsigned int crtc_h, |
838 | uint32_t x, uint32_t y, |
629 | uint32_t x, uint32_t y, |
839 | uint32_t src_w, uint32_t src_h) |
630 | uint32_t src_w, uint32_t src_h) |
840 | { |
631 | { |
841 | struct drm_device *dev = plane->dev; |
632 | struct drm_device *dev = plane->dev; |
842 | struct drm_i915_private *dev_priv = dev->dev_private; |
633 | struct drm_i915_private *dev_priv = dev->dev_private; |
843 | struct intel_plane *intel_plane = to_intel_plane(plane); |
634 | struct intel_plane *intel_plane = to_intel_plane(plane); |
844 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
635 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
845 | int pipe = intel_plane->pipe; |
636 | int pipe = intel_plane->pipe; |
846 | unsigned long dvssurf_offset, linear_offset; |
637 | unsigned long dvssurf_offset, linear_offset; |
Line 847... | Line -... | ||
847 | u32 dvscntr, dvsscale; |
- | |
848 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
- | |
849 | u32 start_vbl_count; |
- | |
850 | bool atomic_update; |
- | |
851 | - | ||
852 | dvscntr = I915_READ(DVSCNTR(pipe)); |
- | |
853 | 638 | u32 dvscntr, dvsscale; |
|
854 | /* Mask out pixel format bits in case we change it */ |
- | |
Line 855... | Line 639... | ||
855 | dvscntr &= ~DVS_PIXFORMAT_MASK; |
639 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
856 | dvscntr &= ~DVS_RGB_ORDER_XBGR; |
640 | const struct drm_intel_sprite_colorkey *key = |
857 | dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; |
641 | &to_intel_plane_state(plane->state)->ckey; |
858 | dvscntr &= ~DVS_TILED; |
642 | |
Line 890... | Line 674... | ||
890 | if (obj->tiling_mode != I915_TILING_NONE) |
674 | if (obj->tiling_mode != I915_TILING_NONE) |
891 | dvscntr |= DVS_TILED; |
675 | dvscntr |= DVS_TILED; |
Line 892... | Line 676... | ||
892 | 676 | ||
893 | if (IS_GEN6(dev)) |
677 | if (IS_GEN6(dev)) |
894 | dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ |
- | |
Line 895... | Line 678... | ||
895 | dvscntr |= DVS_ENABLE; |
678 | dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ |
896 | 679 | ||
897 | intel_update_sprite_watermarks(plane, crtc, src_w, src_h, |
680 | intel_update_sprite_watermarks(plane, crtc, src_w, src_h, |
Line 908... | Line 691... | ||
908 | if (crtc_w != src_w || crtc_h != src_h) |
691 | if (crtc_w != src_w || crtc_h != src_h) |
909 | dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; |
692 | dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; |
Line 910... | Line 693... | ||
910 | 693 | ||
911 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
694 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
912 | dvssurf_offset = |
695 | dvssurf_offset = |
- | 696 | intel_gen4_compute_page_offset(dev_priv, |
|
913 | intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, |
697 | &x, &y, obj->tiling_mode, |
914 | pixel_size, fb->pitches[0]); |
698 | pixel_size, fb->pitches[0]); |
Line 915... | Line 699... | ||
915 | linear_offset -= dvssurf_offset; |
699 | linear_offset -= dvssurf_offset; |
916 | 700 | ||
Line 917... | Line 701... | ||
917 | if (intel_plane->rotation == BIT(DRM_ROTATE_180)) { |
701 | if (plane->state->rotation == BIT(DRM_ROTATE_180)) { |
918 | dvscntr |= DVS_ROTATE_180; |
702 | dvscntr |= DVS_ROTATE_180; |
919 | 703 | ||
920 | x += src_w; |
704 | x += src_w; |
Line -... | Line 705... | ||
- | 705 | y += src_h; |
|
- | 706 | linear_offset += src_h * fb->pitches[0] + src_w * pixel_size; |
|
- | 707 | } |
|
921 | y += src_h; |
708 | |
- | 709 | if (key->flags) { |
|
Line -... | Line 710... | ||
- | 710 | I915_WRITE(DVSKEYVAL(pipe), key->min_value); |
|
- | 711 | I915_WRITE(DVSKEYMAX(pipe), key->max_value); |
|
922 | linear_offset += src_h * fb->pitches[0] + src_w * pixel_size; |
712 | I915_WRITE(DVSKEYMSK(pipe), key->channel_mask); |
- | 713 | } |
|
Line 923... | Line 714... | ||
923 | } |
714 | |
924 | 715 | if (key->flags & I915_SET_COLORKEY_DESTINATION) |
|
Line 925... | Line 716... | ||
925 | atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); |
716 | dvscntr |= DVS_DEST_KEY; |
Line 937... | Line 728... | ||
937 | I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); |
728 | I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); |
938 | I915_WRITE(DVSSCALE(pipe), dvsscale); |
729 | I915_WRITE(DVSSCALE(pipe), dvsscale); |
939 | I915_WRITE(DVSCNTR(pipe), dvscntr); |
730 | I915_WRITE(DVSCNTR(pipe), dvscntr); |
940 | I915_WRITE(DVSSURF(pipe), |
731 | I915_WRITE(DVSSURF(pipe), |
941 | i915_gem_obj_ggtt_offset(obj) + dvssurf_offset); |
732 | i915_gem_obj_ggtt_offset(obj) + dvssurf_offset); |
942 | - | ||
943 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
- | |
944 | - | ||
945 | if (atomic_update) |
733 | POSTING_READ(DVSSURF(pipe)); |
946 | intel_pipe_update_end(intel_crtc, start_vbl_count); |
- | |
947 | } |
734 | } |
Line 948... | Line 735... | ||
948 | 735 | ||
949 | static void |
736 | static void |
950 | ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) |
737 | ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) |
951 | { |
738 | { |
952 | struct drm_device *dev = plane->dev; |
739 | struct drm_device *dev = plane->dev; |
953 | struct drm_i915_private *dev_priv = dev->dev_private; |
740 | struct drm_i915_private *dev_priv = dev->dev_private; |
954 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | |
955 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
741 | struct intel_plane *intel_plane = to_intel_plane(plane); |
956 | int pipe = intel_plane->pipe; |
- | |
957 | u32 start_vbl_count; |
- | |
958 | bool atomic_update; |
- | |
959 | - | ||
960 | atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); |
- | |
961 | - | ||
Line 962... | Line 742... | ||
962 | intel_update_primary_plane(intel_crtc); |
742 | int pipe = intel_plane->pipe; |
963 | 743 | ||
964 | I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE); |
744 | I915_WRITE(DVSCNTR(pipe), 0); |
965 | /* Disable the scaler */ |
- | |
966 | I915_WRITE(DVSSCALE(pipe), 0); |
- | |
967 | /* Flush double buffered register updates */ |
- | |
968 | I915_WRITE(DVSSURF(pipe), 0); |
- | |
969 | - | ||
970 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
- | |
971 | - | ||
972 | if (atomic_update) |
- | |
973 | intel_pipe_update_end(intel_crtc, start_vbl_count); |
- | |
974 | - | ||
975 | /* |
- | |
976 | * Avoid underruns when disabling the sprite. |
- | |
977 | * FIXME remove once watermark updates are done properly. |
- | |
978 | */ |
- | |
979 | intel_wait_for_vblank(dev, pipe); |
- | |
980 | - | ||
981 | intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false); |
- | |
982 | } |
- | |
983 | - | ||
984 | static void |
- | |
985 | intel_post_enable_primary(struct drm_crtc *crtc) |
- | |
986 | { |
- | |
987 | struct drm_device *dev = crtc->dev; |
- | |
988 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
989 | - | ||
990 | /* |
- | |
991 | * BDW signals flip done immediately if the plane |
- | |
992 | * is disabled, even if the plane enable is already |
- | |
993 | * armed to occur at the next vblank :( |
- | |
994 | */ |
- | |
995 | if (IS_BROADWELL(dev)) |
- | |
996 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
- | |
997 | - | ||
998 | /* |
- | |
999 | * FIXME IPS should be fine as long as one plane is |
- | |
1000 | * enabled, but in practice it seems to have problems |
- | |
1001 | * when going from primary only to sprite only and vice |
- | |
1002 | * versa. |
- | |
1003 | */ |
- | |
1004 | hsw_enable_ips(intel_crtc); |
- | |
1005 | - | ||
1006 | mutex_lock(&dev->struct_mutex); |
- | |
1007 | intel_update_fbc(dev); |
- | |
1008 | mutex_unlock(&dev->struct_mutex); |
- | |
1009 | } |
- | |
1010 | - | ||
1011 | static void |
- | |
1012 | intel_pre_disable_primary(struct drm_crtc *crtc) |
- | |
1013 | { |
- | |
1014 | struct drm_device *dev = crtc->dev; |
- | |
1015 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1016 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
1017 | - | ||
1018 | mutex_lock(&dev->struct_mutex); |
- | |
1019 | if (dev_priv->fbc.plane == intel_crtc->plane) |
- | |
1020 | intel_disable_fbc(dev); |
- | |
1021 | mutex_unlock(&dev->struct_mutex); |
- | |
1022 | - | ||
1023 | /* |
- | |
1024 | * FIXME IPS should be fine as long as one plane is |
- | |
1025 | * enabled, but in practice it seems to have problems |
- | |
1026 | * when going from primary only to sprite only and vice |
- | |
1027 | * versa. |
- | |
1028 | */ |
- | |
1029 | hsw_disable_ips(intel_crtc); |
- | |
1030 | } |
- | |
1031 | - | ||
1032 | static int |
- | |
1033 | ilk_update_colorkey(struct drm_plane *plane, |
- | |
1034 | struct drm_intel_sprite_colorkey *key) |
- | |
1035 | { |
- | |
1036 | struct drm_device *dev = plane->dev; |
- | |
1037 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1038 | struct intel_plane *intel_plane; |
- | |
1039 | u32 dvscntr; |
- | |
1040 | int ret = 0; |
- | |
1041 | - | ||
1042 | intel_plane = to_intel_plane(plane); |
- | |
1043 | - | ||
1044 | I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value); |
- | |
1045 | I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value); |
- | |
1046 | I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask); |
- | |
1047 | - | ||
1048 | dvscntr = I915_READ(DVSCNTR(intel_plane->pipe)); |
- | |
1049 | dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY); |
- | |
1050 | if (key->flags & I915_SET_COLORKEY_DESTINATION) |
- | |
1051 | dvscntr |= DVS_DEST_KEY; |
- | |
1052 | else if (key->flags & I915_SET_COLORKEY_SOURCE) |
- | |
1053 | dvscntr |= DVS_SOURCE_KEY; |
- | |
1054 | I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr); |
- | |
1055 | - | ||
1056 | POSTING_READ(DVSKEYMSK(intel_plane->pipe)); |
- | |
1057 | - | ||
1058 | return ret; |
- | |
1059 | } |
- | |
1060 | - | ||
1061 | static void |
- | |
1062 | ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key) |
- | |
1063 | { |
- | |
1064 | struct drm_device *dev = plane->dev; |
- | |
1065 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
1066 | struct intel_plane *intel_plane; |
- | |
1067 | u32 dvscntr; |
- | |
1068 | - | ||
1069 | intel_plane = to_intel_plane(plane); |
- | |
1070 | - | ||
1071 | key->min_value = I915_READ(DVSKEYVAL(intel_plane->pipe)); |
- | |
1072 | key->max_value = I915_READ(DVSKEYMAX(intel_plane->pipe)); |
- | |
Line 1073... | Line 745... | ||
1073 | key->channel_mask = I915_READ(DVSKEYMSK(intel_plane->pipe)); |
745 | /* Disable the scaler */ |
1074 | key->flags = 0; |
- | |
1075 | 746 | I915_WRITE(DVSSCALE(pipe), 0); |
|
1076 | dvscntr = I915_READ(DVSCNTR(intel_plane->pipe)); |
- | |
1077 | - | ||
1078 | if (dvscntr & DVS_DEST_KEY) |
- | |
1079 | key->flags = I915_SET_COLORKEY_DESTINATION; |
- | |
1080 | else if (dvscntr & DVS_SOURCE_KEY) |
- | |
1081 | key->flags = I915_SET_COLORKEY_SOURCE; |
- | |
1082 | else |
- | |
1083 | key->flags = I915_SET_COLORKEY_NONE; |
- | |
1084 | } |
- | |
1085 | - | ||
1086 | static bool colorkey_enabled(struct intel_plane *intel_plane) |
- | |
1087 | { |
- | |
1088 | struct drm_intel_sprite_colorkey key; |
- | |
1089 | - | ||
1090 | intel_plane->get_colorkey(&intel_plane->base, &key); |
747 | |
Line 1091... | Line 748... | ||
1091 | 748 | I915_WRITE(DVSSURF(pipe), 0); |
|
1092 | return key.flags != I915_SET_COLORKEY_NONE; |
749 | POSTING_READ(DVSSURF(pipe)); |
- | 750 | } |
|
1093 | } |
751 | |
1094 | 752 | static int |
|
- | 753 | intel_check_sprite_plane(struct drm_plane *plane, |
|
- | 754 | struct intel_crtc_state *crtc_state, |
|
1095 | static int |
755 | struct intel_plane_state *state) |
1096 | intel_check_sprite_plane(struct drm_plane *plane, |
756 | { |
1097 | struct intel_plane_state *state) |
757 | struct drm_device *dev = plane->dev; |
1098 | { |
- | |
1099 | struct intel_crtc *intel_crtc = to_intel_crtc(state->crtc); |
758 | struct drm_crtc *crtc = state->base.crtc; |
1100 | struct intel_plane *intel_plane = to_intel_plane(plane); |
759 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1101 | struct drm_framebuffer *fb = state->fb; |
760 | struct intel_plane *intel_plane = to_intel_plane(plane); |
1102 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
761 | struct drm_framebuffer *fb = state->base.fb; |
1103 | int crtc_x, crtc_y; |
762 | int crtc_x, crtc_y; |
1104 | unsigned int crtc_w, crtc_h; |
- | |
1105 | uint32_t src_x, src_y, src_w, src_h; |
763 | unsigned int crtc_w, crtc_h; |
1106 | struct drm_rect *src = &state->src; |
764 | uint32_t src_x, src_y, src_w, src_h; |
1107 | struct drm_rect *dst = &state->dst; |
765 | struct drm_rect *src = &state->src; |
- | 766 | struct drm_rect *dst = &state->dst; |
|
- | 767 | const struct drm_rect *clip = &state->clip; |
|
- | 768 | int hscale, vscale; |
|
- | 769 | int max_scale, min_scale; |
|
1108 | struct drm_rect *orig_src = &state->orig_src; |
770 | bool can_scale; |
- | 771 | int pixel_size; |
|
- | 772 | ||
Line 1109... | Line 773... | ||
1109 | const struct drm_rect *clip = &state->clip; |
773 | if (!fb) { |
1110 | int hscale, vscale; |
774 | state->visible = false; |
1111 | int max_scale, min_scale; |
775 | return 0; |
1112 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
776 | } |
Line 1121... | Line 785... | ||
1121 | if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) { |
785 | if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) { |
1122 | DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n"); |
786 | DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n"); |
1123 | return -EINVAL; |
787 | return -EINVAL; |
1124 | } |
788 | } |
Line 1125... | Line 789... | ||
1125 | 789 | ||
1126 | /* Sprite planes can be linear or x-tiled surfaces */ |
790 | /* setup can_scale, min_scale, max_scale */ |
- | 791 | if (INTEL_INFO(dev)->gen >= 9) { |
|
1127 | switch (obj->tiling_mode) { |
792 | /* use scaler when colorkey is not required */ |
1128 | case I915_TILING_NONE: |
793 | if (state->ckey.flags == I915_SET_COLORKEY_NONE) { |
1129 | case I915_TILING_X: |
794 | can_scale = 1; |
- | 795 | min_scale = 1; |
|
1130 | break; |
796 | max_scale = skl_max_scale(intel_crtc, crtc_state); |
- | 797 | } else { |
|
- | 798 | can_scale = 0; |
|
1131 | default: |
799 | min_scale = DRM_PLANE_HELPER_NO_SCALING; |
- | 800 | max_scale = DRM_PLANE_HELPER_NO_SCALING; |
|
1132 | DRM_DEBUG_KMS("Unsupported tiling mode\n"); |
801 | } |
- | 802 | } else { |
|
- | 803 | can_scale = intel_plane->can_scale; |
|
- | 804 | max_scale = intel_plane->max_downscale << 16; |
|
1133 | return -EINVAL; |
805 | min_scale = intel_plane->can_scale ? 1 : (1 << 16); |
Line 1134... | Line 806... | ||
1134 | } |
806 | } |
1135 | 807 | ||
1136 | /* |
808 | /* |
1137 | * FIXME the following code does a bunch of fuzzy adjustments to the |
809 | * FIXME the following code does a bunch of fuzzy adjustments to the |
1138 | * coordinates and sizes. We probably need some way to decide whether |
810 | * coordinates and sizes. We probably need some way to decide whether |
1139 | * more strict checking should be done instead. |
- | |
1140 | */ |
- | |
1141 | max_scale = intel_plane->max_downscale << 16; |
- | |
1142 | min_scale = intel_plane->can_scale ? 1 : (1 << 16); |
811 | * more strict checking should be done instead. |
1143 | 812 | */ |
|
Line 1144... | Line 813... | ||
1144 | drm_rect_rotate(src, fb->width << 16, fb->height << 16, |
813 | drm_rect_rotate(src, fb->width << 16, fb->height << 16, |
1145 | intel_plane->rotation); |
814 | state->base.rotation); |
Line 1146... | Line 815... | ||
1146 | 815 | ||
Line 1181... | Line 850... | ||
1181 | drm_rect_adjust_size(src, |
850 | drm_rect_adjust_size(src, |
1182 | drm_rect_width(dst) * hscale - drm_rect_width(src), |
851 | drm_rect_width(dst) * hscale - drm_rect_width(src), |
1183 | drm_rect_height(dst) * vscale - drm_rect_height(src)); |
852 | drm_rect_height(dst) * vscale - drm_rect_height(src)); |
Line 1184... | Line 853... | ||
1184 | 853 | ||
1185 | drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, |
854 | drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, |
Line 1186... | Line 855... | ||
1186 | intel_plane->rotation); |
855 | state->base.rotation); |
1187 | 856 | ||
1188 | /* sanity check to make sure the src viewport wasn't enlarged */ |
857 | /* sanity check to make sure the src viewport wasn't enlarged */ |
1189 | WARN_ON(src->x1 < (int) orig_src->x1 || |
858 | WARN_ON(src->x1 < (int) state->base.src_x || |
1190 | src->y1 < (int) orig_src->y1 || |
859 | src->y1 < (int) state->base.src_y || |
Line 1191... | Line 860... | ||
1191 | src->x2 > (int) orig_src->x2 || |
860 | src->x2 > (int) state->base.src_x + state->base.src_w || |
1192 | src->y2 > (int) orig_src->y2); |
861 | src->y2 > (int) state->base.src_y + state->base.src_h); |
1193 | 862 | ||
1194 | /* |
863 | /* |
Line 1208... | Line 877... | ||
1208 | 877 | ||
1209 | /* |
878 | /* |
1210 | * Must keep src and dst the |
879 | * Must keep src and dst the |
1211 | * same if we can't scale. |
880 | * same if we can't scale. |
1212 | */ |
881 | */ |
1213 | if (!intel_plane->can_scale) |
882 | if (!can_scale) |
Line 1214... | Line 883... | ||
1214 | crtc_w &= ~1; |
883 | crtc_w &= ~1; |
1215 | 884 | ||
1216 | if (crtc_w == 0) |
885 | if (crtc_w == 0) |
Line 1220... | Line 889... | ||
1220 | 889 | ||
1221 | /* Check size restrictions when scaling */ |
890 | /* Check size restrictions when scaling */ |
1222 | if (state->visible && (src_w != crtc_w || src_h != crtc_h)) { |
891 | if (state->visible && (src_w != crtc_w || src_h != crtc_h)) { |
Line 1223... | Line 892... | ||
1223 | unsigned int width_bytes; |
892 | unsigned int width_bytes; |
Line 1224... | Line 893... | ||
1224 | 893 | ||
Line 1225... | Line 894... | ||
1225 | WARN_ON(!intel_plane->can_scale); |
894 | WARN_ON(!can_scale); |
1226 | 895 | ||
Line 1227... | Line 896... | ||
1227 | /* FIXME interlacing min height is 6 */ |
896 | /* FIXME interlacing min height is 6 */ |
1228 | 897 | ||
Line -... | Line 898... | ||
- | 898 | if (crtc_w < 3 || crtc_h < 3) |
|
1229 | if (crtc_w < 3 || crtc_h < 3) |
899 | state->visible = false; |
1230 | state->visible = false; |
900 | |
Line 1231... | Line 901... | ||
1231 | 901 | if (src_w < 3 || src_h < 3) |
|
1232 | if (src_w < 3 || src_h < 3) |
902 | state->visible = false; |
1233 | state->visible = false; |
903 | |
1234 | 904 | pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
|
1235 | width_bytes = ((src_x * pixel_size) & 63) + |
905 | width_bytes = ((src_x * pixel_size) & 63) + |
1236 | src_w * pixel_size; |
906 | src_w * pixel_size; |
Line 1237... | Line 907... | ||
1237 | 907 | ||
1238 | if (src_w > 2048 || src_h > 2048 || |
908 | if (INTEL_INFO(dev)->gen < 9 && (src_w > 2048 || src_h > 2048 || |
1239 | width_bytes > 4096 || fb->pitches[0] > 4096) { |
909 | width_bytes > 4096 || fb->pitches[0] > 4096)) { |
1240 | DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n"); |
910 | DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n"); |
1241 | return -EINVAL; |
911 | return -EINVAL; |
1242 | } |
912 | } |
Line 1243... | Line 913... | ||
1243 | } |
913 | } |
1244 | 914 | ||
1245 | if (state->visible) { |
915 | if (state->visible) { |
1246 | src->x1 = src_x; |
916 | src->x1 = src_x << 16; |
Line 1247... | Line 917... | ||
1247 | src->x2 = src_x + src_w; |
917 | src->x2 = (src_x + src_w) << 16; |
1248 | src->y1 = src_y; |
918 | src->y1 = src_y << 16; |
Line 1249... | Line -... | ||
1249 | src->y2 = src_y + src_h; |
- | |
1250 | } |
- | |
1251 | - | ||
1252 | dst->x1 = crtc_x; |
- | |
1253 | dst->x2 = crtc_x + crtc_w; |
- | |
1254 | dst->y1 = crtc_y; |
- | |
1255 | dst->y2 = crtc_y + crtc_h; |
- | |
1256 | - | ||
1257 | return 0; |
- | |
1258 | } |
- | |
1259 | - | ||
1260 | static int |
- | |
1261 | intel_prepare_sprite_plane(struct drm_plane *plane, |
- | |
1262 | struct intel_plane_state *state) |
- | |
1263 | { |
- | |
1264 | struct drm_device *dev = plane->dev; |
- | |
1265 | struct drm_crtc *crtc = state->crtc; |
- | |
1266 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
1267 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | |
1268 | enum pipe pipe = intel_crtc->pipe; |
- | |
1269 | struct drm_framebuffer *fb = state->fb; |
- | |
1270 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
- | |
1271 | struct drm_i915_gem_object *old_obj = intel_plane->obj; |
- | |
1272 | int ret; |
- | |
1273 | - | ||
1274 | if (old_obj != obj) { |
- | |
1275 | mutex_lock(&dev->struct_mutex); |
- | |
1276 | - | ||
1277 | /* Note that this will apply the VT-d workaround for scanouts, |
- | |
1278 | * which is more restrictive than required for sprites. (The |
- | |
1279 | * primary plane requires 256KiB alignment with 64 PTE padding, |
- | |
1280 | * the sprite planes only require 128KiB alignment and 32 PTE |
- | |
1281 | * padding. |
- | |
1282 | */ |
- | |
1283 | ret = intel_pin_and_fence_fb_obj(plane, fb, NULL); |
- | |
1284 | if (ret == 0) |
919 | src->y2 = (src_y + src_h) << 16; |
1285 | i915_gem_track_fb(old_obj, obj, |
920 | } |
1286 | INTEL_FRONTBUFFER_SPRITE(pipe)); |
921 | |
1287 | mutex_unlock(&dev->struct_mutex); |
922 | dst->x1 = crtc_x; |
1288 | if (ret) |
- | |
1289 | return ret; |
923 | dst->x2 = crtc_x + crtc_w; |
1290 | } |
- | |
1291 | 924 | dst->y1 = crtc_y; |
|
1292 | return 0; |
- | |
1293 | } |
925 | dst->y2 = crtc_y + crtc_h; |
1294 | - | ||
1295 | static void |
- | |
1296 | intel_commit_sprite_plane(struct drm_plane *plane, |
- | |
1297 | struct intel_plane_state *state) |
- | |
1298 | { |
- | |
1299 | struct drm_device *dev = plane->dev; |
- | |
1300 | struct drm_crtc *crtc = state->crtc; |
- | |
1301 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
1302 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | |
1303 | enum pipe pipe = intel_crtc->pipe; |
- | |
1304 | struct drm_framebuffer *fb = state->fb; |
- | |
1305 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
- | |
1306 | struct drm_i915_gem_object *old_obj = intel_plane->obj; |
- | |
1307 | int crtc_x, crtc_y; |
- | |
1308 | unsigned int crtc_w, crtc_h; |
- | |
1309 | uint32_t src_x, src_y, src_w, src_h; |
- | |
1310 | struct drm_rect *dst = &state->dst; |
- | |
1311 | const struct drm_rect *clip = &state->clip; |
- | |
1312 | bool primary_enabled; |
- | |
1313 | - | ||
1314 | /* |
- | |
1315 | * If the sprite is completely covering the primary plane, |
- | |
1316 | * we can disable the primary and save power. |
- | |
1317 | */ |
- | |
1318 | primary_enabled = !drm_rect_equals(dst, clip) || colorkey_enabled(intel_plane); |
- | |
1319 | WARN_ON(!primary_enabled && !state->visible && intel_crtc->active); |
- | |
1320 | - | ||
1321 | intel_plane->crtc_x = state->orig_dst.x1; |
- | |
Line 1322... | Line 926... | ||
1322 | intel_plane->crtc_y = state->orig_dst.y1; |
926 | |
Line 1323... | Line -... | ||
1323 | intel_plane->crtc_w = drm_rect_width(&state->orig_dst); |
- | |
1324 | intel_plane->crtc_h = drm_rect_height(&state->orig_dst); |
- | |
1325 | intel_plane->src_x = state->orig_src.x1; |
- | |
1326 | intel_plane->src_y = state->orig_src.y1; |
927 | return 0; |
1327 | intel_plane->src_w = drm_rect_width(&state->orig_src); |
928 | } |
Line 1328... | Line 929... | ||
1328 | intel_plane->src_h = drm_rect_height(&state->orig_src); |
929 | |
1329 | intel_plane->obj = obj; |
930 | static void |
1330 | 931 | intel_commit_sprite_plane(struct drm_plane *plane, |
|
1331 | if (intel_crtc->active) { |
932 | struct intel_plane_state *state) |
1332 | bool primary_was_enabled = intel_crtc->primary_enabled; |
933 | { |
1333 | 934 | struct drm_crtc *crtc = state->base.crtc; |
|
1334 | intel_crtc->primary_enabled = primary_enabled; |
935 | struct intel_plane *intel_plane = to_intel_plane(plane); |
1335 | 936 | struct drm_framebuffer *fb = state->base.fb; |
|
1336 | // if (primary_was_enabled != primary_enabled) |
937 | |
1337 | // intel_crtc_wait_for_pending_flips(crtc); |
- | |
1338 | - | ||
1339 | if (primary_was_enabled && !primary_enabled) |
- | |
1340 | intel_pre_disable_primary(crtc); |
938 | crtc = crtc ? crtc : plane->crtc; |
1341 | 939 | ||
1342 | if (state->visible) { |
940 | if (!crtc->state->active) |
1343 | crtc_x = state->dst.x1; |
- | |
1344 | crtc_y = state->dst.y1; |
- | |
1345 | crtc_w = drm_rect_width(&state->dst); |
- | |
1346 | crtc_h = drm_rect_height(&state->dst); |
- | |
1347 | src_x = state->src.x1; |
- | |
1348 | src_y = state->src.y1; |
- | |
1349 | src_w = drm_rect_width(&state->src); |
- | |
1350 | src_h = drm_rect_height(&state->src); |
- | |
1351 | intel_plane->update_plane(plane, crtc, fb, obj, |
- | |
1352 | crtc_x, crtc_y, crtc_w, crtc_h, |
- | |
1353 | src_x, src_y, src_w, src_h); |
- | |
1354 | } else { |
- | |
1355 | intel_plane->disable_plane(plane, crtc); |
- | |
1356 | } |
- | |
1357 | - | ||
1358 | - | ||
1359 | intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_SPRITE(pipe)); |
- | |
1360 | - | ||
1361 | if (!primary_was_enabled && primary_enabled) |
- | |
1362 | intel_post_enable_primary(crtc); |
- | |
1363 | } |
- | |
1364 | - | ||
1365 | /* Unpin old obj after new one is active to avoid ugliness */ |
- | |
1366 | if (old_obj && old_obj != obj) { |
- | |
1367 | - | ||
1368 | /* |
- | |
1369 | * It's fairly common to simply update the position of |
- | |
1370 | * an existing object. In that case, we don't need to |
- | |
1371 | * wait for vblank to avoid ugliness, we only need to |
- | |
1372 | * do the pin & ref bookkeeping. |
- | |
1373 | */ |
- | |
1374 | if (intel_crtc->active) |
- | |
1375 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
- | |
1376 | - | ||
1377 | mutex_lock(&dev->struct_mutex); |
- | |
1378 | intel_unpin_fb_obj(old_obj); |
- | |
1379 | mutex_unlock(&dev->struct_mutex); |
- | |
1380 | } |
- | |
1381 | } |
- | |
1382 | - | ||
1383 | static int |
- | |
1384 | intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, |
- | |
1385 | struct drm_framebuffer *fb, int crtc_x, int crtc_y, |
- | |
1386 | unsigned int crtc_w, unsigned int crtc_h, |
- | |
1387 | uint32_t src_x, uint32_t src_y, |
- | |
1388 | uint32_t src_w, uint32_t src_h) |
- | |
1389 | { |
- | |
1390 | struct intel_plane_state state; |
- | |
1391 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
1392 | int ret; |
- | |
1393 | - | ||
1394 | state.crtc = crtc; |
- | |
1395 | state.fb = fb; |
- | |
1396 | - | ||
1397 | /* sample coordinates in 16.16 fixed point */ |
- | |
1398 | state.src.x1 = src_x; |
- | |
1399 | state.src.x2 = src_x + src_w; |
- | |
1400 | state.src.y1 = src_y; |
- | |
1401 | state.src.y2 = src_y + src_h; |
- | |
1402 | - | ||
1403 | /* integer pixels */ |
- | |
1404 | state.dst.x1 = crtc_x; |
- | |
1405 | state.dst.x2 = crtc_x + crtc_w; |
- | |
1406 | state.dst.y1 = crtc_y; |
- | |
1407 | state.dst.y2 = crtc_y + crtc_h; |
- | |
1408 | - | ||
1409 | state.clip.x1 = 0; |
- | |
1410 | state.clip.y1 = 0; |
- | |
1411 | state.clip.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0; |
- | |
1412 | state.clip.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0; |
- | |
1413 | state.orig_src = state.src; |
- | |
1414 | state.orig_dst = state.dst; |
- | |
1415 | - | ||
1416 | ret = intel_check_sprite_plane(plane, &state); |
- | |
1417 | if (ret) |
- | |
1418 | return ret; |
- | |
1419 | - | ||
1420 | ret = intel_prepare_sprite_plane(plane, &state); |
- | |
1421 | if (ret) |
- | |
1422 | return ret; |
- | |
1423 | - | ||
1424 | intel_commit_sprite_plane(plane, &state); |
- | |
1425 | return 0; |
- | |
1426 | } |
- | |
1427 | - | ||
1428 | static int |
- | |
1429 | intel_disable_plane(struct drm_plane *plane) |
- | |
1430 | { |
- | |
1431 | struct drm_device *dev = plane->dev; |
- | |
1432 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | |
1433 | struct intel_crtc *intel_crtc; |
- | |
1434 | enum pipe pipe; |
- | |
1435 | - | ||
1436 | if (!plane->fb) |
- | |
1437 | return 0; |
- | |
1438 | - | ||
1439 | if (WARN_ON(!plane->crtc)) |
- | |
1440 | return -EINVAL; |
- | |
1441 | - | ||
1442 | intel_crtc = to_intel_crtc(plane->crtc); |
- | |
1443 | pipe = intel_crtc->pipe; |
- | |
1444 | - | ||
1445 | if (intel_crtc->active) { |
- | |
1446 | bool primary_was_enabled = intel_crtc->primary_enabled; |
- | |
1447 | - | ||
1448 | intel_crtc->primary_enabled = true; |
- | |
1449 | - | ||
1450 | intel_plane->disable_plane(plane, plane->crtc); |
- | |
1451 | - | ||
1452 | if (!primary_was_enabled && intel_crtc->primary_enabled) |
- | |
1453 | intel_post_enable_primary(plane->crtc); |
- | |
1454 | } |
- | |
1455 | - | ||
1456 | if (intel_plane->obj) { |
- | |
1457 | if (intel_crtc->active) |
- | |
1458 | intel_wait_for_vblank(dev, intel_plane->pipe); |
- | |
1459 | - | ||
1460 | mutex_lock(&dev->struct_mutex); |
- | |
1461 | intel_unpin_fb_obj(intel_plane->obj); |
- | |
1462 | i915_gem_track_fb(intel_plane->obj, NULL, |
- | |
1463 | INTEL_FRONTBUFFER_SPRITE(pipe)); |
- | |
1464 | mutex_unlock(&dev->struct_mutex); |
941 | return; |
Line 1465... | Line 942... | ||
1465 | 942 | ||
1466 | intel_plane->obj = NULL; |
943 | if (state->visible) { |
1467 | } |
944 | intel_plane->update_plane(plane, crtc, fb, |
1468 | 945 | state->dst.x1, state->dst.y1, |
|
1469 | return 0; |
946 | drm_rect_width(&state->dst), |
1470 | } |
947 | drm_rect_height(&state->dst), |
- | 948 | state->src.x1 >> 16, |
|
- | 949 | state->src.y1 >> 16, |
|
1471 | 950 | drm_rect_width(&state->src) >> 16, |
|
Line 1472... | Line -... | ||
1472 | static void intel_destroy_plane(struct drm_plane *plane) |
- | |
1473 | { |
- | |
1474 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | |
1475 | intel_disable_plane(plane); |
951 | drm_rect_height(&state->src) >> 16); |
1476 | drm_plane_cleanup(plane); |
952 | } else { |
1477 | kfree(intel_plane); |
953 | intel_plane->disable_plane(plane, crtc); |
Line 1478... | Line 954... | ||
1478 | } |
954 | } |
- | 955 | } |
|
- | 956 | ||
Line 1479... | Line 957... | ||
1479 | 957 | int intel_sprite_set_colorkey(struct drm_device *dev, void *data, |
|
1480 | int intel_sprite_set_colorkey(struct drm_device *dev, void *data, |
958 | struct drm_file *file_priv) |
1481 | struct drm_file *file_priv) |
959 | { |
1482 | { |
- | |
1483 | struct drm_intel_sprite_colorkey *set = data; |
- | |
Line 1484... | Line 960... | ||
1484 | struct drm_plane *plane; |
960 | struct drm_intel_sprite_colorkey *set = data; |
1485 | struct intel_plane *intel_plane; |
- | |
Line -... | Line 961... | ||
- | 961 | struct drm_plane *plane; |
|
1486 | int ret = 0; |
962 | struct drm_plane_state *plane_state; |
1487 | 963 | struct drm_atomic_state *state; |
|
1488 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
964 | struct drm_modeset_acquire_ctx ctx; |
1489 | return -ENODEV; |
965 | int ret = 0; |
- | 966 | ||
Line 1490... | Line -... | ||
1490 | - | ||
1491 | /* Make sure we don't try to enable both src & dest simultaneously */ |
967 | /* Make sure we don't try to enable both src & dest simultaneously */ |
1492 | if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) |
- | |
1493 | return -EINVAL; |
968 | if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) |
1494 | - | ||
1495 | drm_modeset_lock_all(dev); |
969 | return -EINVAL; |
1496 | 970 | ||
1497 | plane = drm_plane_find(dev, set->plane_id); |
- | |
1498 | if (!plane) { |
971 | if (IS_VALLEYVIEW(dev) && |
1499 | ret = -ENOENT; |
- | |
1500 | goto out_unlock; |
- | |
1501 | } |
- | |
1502 | - | ||
1503 | intel_plane = to_intel_plane(plane); |
972 | set->flags & I915_SET_COLORKEY_DESTINATION) |
1504 | ret = intel_plane->update_colorkey(plane, set); |
- | |
1505 | - | ||
1506 | out_unlock: |
- | |
1507 | drm_modeset_unlock_all(dev); |
973 | return -EINVAL; |
Line 1508... | Line 974... | ||
1508 | return ret; |
974 | |
1509 | } |
975 | plane = drm_plane_find(dev, set->plane_id); |
Line 1510... | Line 976... | ||
1510 | 976 | if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY) |
|
1511 | int intel_sprite_get_colorkey(struct drm_device *dev, void *data, |
977 | return -ENOENT; |
1512 | struct drm_file *file_priv) |
- | |
1513 | { |
978 | |
Line 1514... | Line -... | ||
1514 | struct drm_intel_sprite_colorkey *get = data; |
- | |
1515 | struct drm_plane *plane; |
- | |
1516 | struct intel_plane *intel_plane; |
- | |
1517 | int ret = 0; |
- | |
1518 | - | ||
1519 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
- | |
1520 | return -ENODEV; |
- | |
1521 | - | ||
1522 | drm_modeset_lock_all(dev); |
- | |
1523 | - | ||
1524 | plane = drm_plane_find(dev, get->plane_id); |
- | |
1525 | if (!plane) { |
- | |
1526 | ret = -ENOENT; |
- | |
1527 | goto out_unlock; |
- | |
1528 | } |
- | |
1529 | - | ||
1530 | intel_plane = to_intel_plane(plane); |
- | |
1531 | intel_plane->get_colorkey(plane, get); |
- | |
1532 | - | ||
1533 | out_unlock: |
- | |
1534 | drm_modeset_unlock_all(dev); |
979 | drm_modeset_acquire_init(&ctx, 0); |
1535 | return ret; |
980 | |
1536 | } |
- | |
Line -... | Line 981... | ||
- | 981 | state = drm_atomic_state_alloc(plane->dev); |
|
- | 982 | if (!state) { |
|
- | 983 | ret = -ENOMEM; |
|
1537 | 984 | goto out; |
|
1538 | int intel_plane_set_property(struct drm_plane *plane, |
985 | } |
Line 1539... | Line -... | ||
1539 | struct drm_property *prop, |
- | |
1540 | uint64_t val) |
- | |
1541 | { |
- | |
1542 | struct drm_device *dev = plane->dev; |
- | |
1543 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | |
1544 | uint64_t old_val; |
- | |
1545 | int ret = -ENOENT; |
- | |
1546 | - | ||
1547 | if (prop == dev->mode_config.rotation_property) { |
- | |
1548 | /* exactly one rotation angle please */ |
- | |
1549 | if (hweight32(val & 0xf) != 1) |
- | |
1550 | return -EINVAL; |
- | |
1551 | - | ||
1552 | if (intel_plane->rotation == val) |
- | |
1553 | return 0; |
- | |
1554 | - | ||
1555 | old_val = intel_plane->rotation; |
- | |
1556 | intel_plane->rotation = val; |
- | |
1557 | ret = intel_plane_restore(plane); |
- | |
1558 | if (ret) |
- | |
1559 | intel_plane->rotation = old_val; |
- | |
1560 | } |
- | |
1561 | - | ||
1562 | return ret; |
- | |
1563 | } |
- | |
1564 | - | ||
1565 | int intel_plane_restore(struct drm_plane *plane) |
- | |
1566 | { |
- | |
1567 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | |
1568 | 986 | state->acquire_ctx = &ctx; |
|
1569 | if (!plane->crtc || !plane->fb) |
987 | |
1570 | return 0; |
988 | while (1) { |
1571 | 989 | plane_state = drm_atomic_get_plane_state(state, plane); |
|
1572 | return plane->funcs->update_plane(plane, plane->crtc, plane->fb, |
990 | ret = PTR_ERR_OR_ZERO(plane_state); |
1573 | intel_plane->crtc_x, intel_plane->crtc_y, |
991 | if (!ret) { |
1574 | intel_plane->crtc_w, intel_plane->crtc_h, |
992 | to_intel_plane_state(plane_state)->ckey = *set; |
Line 1575... | Line 993... | ||
1575 | intel_plane->src_x, intel_plane->src_y, |
993 | ret = drm_atomic_commit(state); |
1576 | intel_plane->src_w, intel_plane->src_h); |
994 | } |
1577 | } |
995 | |
1578 | 996 | if (ret != -EDEADLK) |
|
1579 | void intel_plane_disable(struct drm_plane *plane) |
997 | break; |
1580 | { |
998 | |
1581 | if (!plane->crtc || !plane->fb) |
999 | drm_atomic_state_clear(state); |
1582 | return; |
1000 | drm_modeset_backoff(&ctx); |
Line 1583... | Line 1001... | ||
1583 | 1001 | } |
|
1584 | intel_disable_plane(plane); |
1002 | |
1585 | } |
1003 | if (ret) |
1586 | 1004 | drm_atomic_state_free(state); |
|
1587 | static const struct drm_plane_funcs intel_plane_funcs = { |
1005 | |
1588 | .update_plane = intel_update_plane, |
1006 | out: |
Line 1636... | Line 1054... | ||
1636 | 1054 | ||
1637 | int |
1055 | int |
1638 | intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) |
1056 | intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) |
1639 | { |
1057 | { |
- | 1058 | struct intel_plane *intel_plane; |
|
1640 | struct intel_plane *intel_plane; |
1059 | struct intel_plane_state *state; |
1641 | unsigned long possible_crtcs; |
1060 | unsigned long possible_crtcs; |
1642 | const uint32_t *plane_formats; |
1061 | const uint32_t *plane_formats; |
1643 | int num_plane_formats; |
1062 | int num_plane_formats; |
Line 1648... | Line 1067... | ||
1648 | 1067 | ||
1649 | intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL); |
1068 | intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL); |
1650 | if (!intel_plane) |
1069 | if (!intel_plane) |
Line -... | Line 1070... | ||
- | 1070 | return -ENOMEM; |
|
- | 1071 | ||
- | 1072 | state = intel_create_plane_state(&intel_plane->base); |
|
- | 1073 | if (!state) { |
|
- | 1074 | kfree(intel_plane); |
|
- | 1075 | return -ENOMEM; |
|
- | 1076 | } |
|
1651 | return -ENOMEM; |
1077 | intel_plane->base.state = &state->base; |
1652 | 1078 | ||
1653 | switch (INTEL_INFO(dev)->gen) { |
1079 | switch (INTEL_INFO(dev)->gen) { |
1654 | case 5: |
1080 | case 5: |
1655 | case 6: |
1081 | case 6: |
1656 | intel_plane->can_scale = true; |
1082 | intel_plane->can_scale = true; |
1657 | intel_plane->max_downscale = 16; |
1083 | intel_plane->max_downscale = 16; |
1658 | intel_plane->update_plane = ilk_update_plane; |
- | |
1659 | intel_plane->disable_plane = ilk_disable_plane; |
- | |
Line 1660... | Line 1084... | ||
1660 | intel_plane->update_colorkey = ilk_update_colorkey; |
1084 | intel_plane->update_plane = ilk_update_plane; |
1661 | intel_plane->get_colorkey = ilk_get_colorkey; |
1085 | intel_plane->disable_plane = ilk_disable_plane; |
1662 | 1086 | ||
1663 | if (IS_GEN6(dev)) { |
1087 | if (IS_GEN6(dev)) { |
Line 1680... | Line 1104... | ||
1680 | } |
1104 | } |
Line 1681... | Line 1105... | ||
1681 | 1105 | ||
1682 | if (IS_VALLEYVIEW(dev)) { |
1106 | if (IS_VALLEYVIEW(dev)) { |
1683 | intel_plane->update_plane = vlv_update_plane; |
1107 | intel_plane->update_plane = vlv_update_plane; |
1684 | intel_plane->disable_plane = vlv_disable_plane; |
- | |
1685 | intel_plane->update_colorkey = vlv_update_colorkey; |
- | |
Line 1686... | Line 1108... | ||
1686 | intel_plane->get_colorkey = vlv_get_colorkey; |
1108 | intel_plane->disable_plane = vlv_disable_plane; |
1687 | 1109 | ||
1688 | plane_formats = vlv_plane_formats; |
1110 | plane_formats = vlv_plane_formats; |
1689 | num_plane_formats = ARRAY_SIZE(vlv_plane_formats); |
1111 | num_plane_formats = ARRAY_SIZE(vlv_plane_formats); |
1690 | } else { |
1112 | } else { |
1691 | intel_plane->update_plane = ivb_update_plane; |
- | |
1692 | intel_plane->disable_plane = ivb_disable_plane; |
- | |
Line 1693... | Line 1113... | ||
1693 | intel_plane->update_colorkey = ivb_update_colorkey; |
1113 | intel_plane->update_plane = ivb_update_plane; |
1694 | intel_plane->get_colorkey = ivb_get_colorkey; |
1114 | intel_plane->disable_plane = ivb_disable_plane; |
1695 | 1115 | ||
1696 | plane_formats = snb_plane_formats; |
1116 | plane_formats = snb_plane_formats; |
1697 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); |
1117 | num_plane_formats = ARRAY_SIZE(snb_plane_formats); |
1698 | } |
- | |
1699 | break; |
- | |
1700 | case 9: |
- | |
1701 | /* |
- | |
1702 | * FIXME: Skylake planes can be scaled (with some restrictions), |
1118 | } |
1703 | * but this is for another time. |
- | |
1704 | */ |
1119 | break; |
1705 | intel_plane->can_scale = false; |
1120 | case 9: |
1706 | intel_plane->max_downscale = 1; |
- | |
1707 | intel_plane->update_plane = skl_update_plane; |
1121 | intel_plane->can_scale = true; |
Line 1708... | Line 1122... | ||
1708 | intel_plane->disable_plane = skl_disable_plane; |
1122 | intel_plane->update_plane = skl_update_plane; |
1709 | intel_plane->update_colorkey = skl_update_colorkey; |
1123 | intel_plane->disable_plane = skl_disable_plane; |
1710 | intel_plane->get_colorkey = skl_get_colorkey; |
1124 | state->scaler_id = -1; |
1711 | 1125 | ||
Line 1717... | Line 1131... | ||
1717 | return -ENODEV; |
1131 | return -ENODEV; |
1718 | } |
1132 | } |
Line 1719... | Line 1133... | ||
1719 | 1133 | ||
1720 | intel_plane->pipe = pipe; |
1134 | intel_plane->pipe = pipe; |
- | 1135 | intel_plane->plane = plane; |
|
- | 1136 | intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER_SPRITE(pipe, plane); |
|
1721 | intel_plane->plane = plane; |
1137 | intel_plane->check_plane = intel_check_sprite_plane; |
1722 | intel_plane->rotation = BIT(DRM_ROTATE_0); |
1138 | intel_plane->commit_plane = intel_commit_sprite_plane; |
1723 | possible_crtcs = (1 << pipe); |
1139 | possible_crtcs = (1 << pipe); |
1724 | ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs, |
1140 | ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs, |
1725 | &intel_plane_funcs, |
1141 | &intel_plane_funcs, |
1726 | plane_formats, num_plane_formats, |
1142 | plane_formats, num_plane_formats, |
1727 | DRM_PLANE_TYPE_OVERLAY); |
1143 | DRM_PLANE_TYPE_OVERLAY); |
1728 | if (ret) { |
1144 | if (ret) { |
1729 | kfree(intel_plane); |
1145 | kfree(intel_plane); |
1730 | goto out; |
1146 | goto out; |
Line 1731... | Line -... | ||
1731 | } |
- | |
1732 | - | ||
1733 | if (!dev->mode_config.rotation_property) |
1147 | } |
1734 | dev->mode_config.rotation_property = |
- | |
1735 | drm_mode_create_rotation_property(dev, |
- | |
1736 | BIT(DRM_ROTATE_0) | |
1148 | |
1737 | BIT(DRM_ROTATE_180)); |
- | |
1738 | 1149 | intel_create_rotation_property(dev, intel_plane); |
|
1739 | if (dev->mode_config.rotation_property) |
- | |
1740 | drm_object_attach_property(&intel_plane->base.base, |
- | |
Line 1741... | Line 1150... | ||
1741 | dev->mode_config.rotation_property, |
1150 | |
1742 | intel_plane->rotation); |
1151 | drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); |
1743 | 1152 |