Rev 4560 | Rev 5354 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4560 | Rev 5060 | ||
---|---|---|---|
Line 35... | Line 35... | ||
35 | #include |
35 | #include |
36 | #include "intel_drv.h" |
36 | #include "intel_drv.h" |
37 | #include |
37 | #include |
38 | #include "i915_drv.h" |
38 | #include "i915_drv.h" |
Line -... | Line 39... | ||
- | 39 | ||
- | 40 | static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs) |
|
- | 41 | { |
|
- | 42 | /* paranoia */ |
|
- | 43 | if (!mode->crtc_htotal) |
|
- | 44 | return 1; |
|
- | 45 | ||
- | 46 | return DIV_ROUND_UP(usecs * mode->crtc_clock, 1000 * mode->crtc_htotal); |
|
- | 47 | } |
|
- | 48 | ||
- | 49 | static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count) |
|
- | 50 | { |
|
- | 51 | struct drm_device *dev = crtc->base.dev; |
|
- | 52 | const struct drm_display_mode *mode = &crtc->config.adjusted_mode; |
|
- | 53 | enum pipe pipe = crtc->pipe; |
|
- | 54 | long timeout = msecs_to_jiffies_timeout(1); |
|
- | 55 | int scanline, min, max, vblank_start; |
|
- | 56 | DEFINE_WAIT(wait); |
|
- | 57 | ||
- | 58 | WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex)); |
|
- | 59 | ||
- | 60 | vblank_start = mode->crtc_vblank_start; |
|
- | 61 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
|
- | 62 | vblank_start = DIV_ROUND_UP(vblank_start, 2); |
|
- | 63 | ||
- | 64 | /* FIXME needs to be calibrated sensibly */ |
|
- | 65 | min = vblank_start - usecs_to_scanlines(mode, 100); |
|
- | 66 | max = vblank_start - 1; |
|
- | 67 | ||
- | 68 | if (min <= 0 || max <= 0) |
|
- | 69 | return false; |
|
- | 70 | ||
- | 71 | // if (WARN_ON(drm_vblank_get(dev, pipe))) |
|
- | 72 | // return false; |
|
- | 73 | ||
- | 74 | // local_irq_disable(); |
|
- | 75 | ||
- | 76 | // trace_i915_pipe_update_start(crtc, min, max); |
|
- | 77 | ||
- | 78 | for (;;) { |
|
- | 79 | /* |
|
- | 80 | * prepare_to_wait() has a memory barrier, which guarantees |
|
- | 81 | * other CPUs can see the task state update by the time we |
|
- | 82 | * read the scanline. |
|
- | 83 | */ |
|
- | 84 | prepare_to_wait(&crtc->vbl_wait, &wait, TASK_UNINTERRUPTIBLE); |
|
- | 85 | ||
- | 86 | scanline = intel_get_crtc_scanline(crtc); |
|
- | 87 | if (scanline < min || scanline > max) |
|
- | 88 | break; |
|
- | 89 | ||
- | 90 | if (timeout <= 0) { |
|
- | 91 | DRM_ERROR("Potential atomic update failure on pipe %c\n", |
|
- | 92 | pipe_name(crtc->pipe)); |
|
- | 93 | break; |
|
- | 94 | } |
|
- | 95 | ||
- | 96 | // local_irq_enable(); |
|
- | 97 | ||
- | 98 | schedule_timeout(timeout); |
|
- | 99 | timeout = 0; |
|
- | 100 | // local_irq_disable(); |
|
- | 101 | } |
|
- | 102 | ||
- | 103 | finish_wait(&crtc->vbl_wait, &wait); |
|
- | 104 | ||
- | 105 | // drm_vblank_put(dev, pipe); |
|
- | 106 | ||
- | 107 | *start_vbl_count = dev->driver->get_vblank_counter(dev, pipe); |
|
- | 108 | ||
- | 109 | // trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count); |
|
- | 110 | ||
- | 111 | return true; |
|
- | 112 | } |
|
- | 113 | ||
- | 114 | static void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count) |
|
- | 115 | { |
|
- | 116 | struct drm_device *dev = crtc->base.dev; |
|
- | 117 | enum pipe pipe = crtc->pipe; |
|
- | 118 | u32 end_vbl_count = dev->driver->get_vblank_counter(dev, pipe); |
|
- | 119 | ||
- | 120 | // trace_i915_pipe_update_end(crtc, end_vbl_count); |
|
- | 121 | ||
- | 122 | // local_irq_enable(); |
|
- | 123 | ||
- | 124 | if (start_vbl_count != end_vbl_count) |
|
- | 125 | DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u)\n", |
|
- | 126 | pipe_name(pipe), start_vbl_count, end_vbl_count); |
|
- | 127 | } |
|
- | 128 | ||
- | 129 | static void intel_update_primary_plane(struct intel_crtc *crtc) |
|
- | 130 | { |
|
- | 131 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; |
|
- | 132 | int reg = DSPCNTR(crtc->plane); |
|
- | 133 | ||
- | 134 | if (crtc->primary_enabled) |
|
- | 135 | I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); |
|
- | 136 | else |
|
- | 137 | I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); |
|
- | 138 | } |
|
39 | 139 | ||
40 | static void |
140 | static void |
41 | vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, |
141 | vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, |
42 | struct drm_framebuffer *fb, |
142 | struct drm_framebuffer *fb, |
43 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
143 | struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, |
Line 46... | Line 146... | ||
46 | uint32_t src_w, uint32_t src_h) |
146 | uint32_t src_w, uint32_t src_h) |
47 | { |
147 | { |
48 | struct drm_device *dev = dplane->dev; |
148 | struct drm_device *dev = dplane->dev; |
49 | struct drm_i915_private *dev_priv = dev->dev_private; |
149 | struct drm_i915_private *dev_priv = dev->dev_private; |
50 | struct intel_plane *intel_plane = to_intel_plane(dplane); |
150 | struct intel_plane *intel_plane = to_intel_plane(dplane); |
- | 151 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
51 | int pipe = intel_plane->pipe; |
152 | int pipe = intel_plane->pipe; |
52 | int plane = intel_plane->plane; |
153 | int plane = intel_plane->plane; |
53 | u32 sprctl; |
154 | u32 sprctl; |
54 | unsigned long sprsurf_offset, linear_offset; |
155 | unsigned long sprsurf_offset, linear_offset; |
55 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
156 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
- | 157 | u32 start_vbl_count; |
|
- | 158 | bool atomic_update; |
|
Line 56... | Line 159... | ||
56 | 159 | ||
Line 57... | Line 160... | ||
57 | sprctl = I915_READ(SPCNTR(pipe, plane)); |
160 | sprctl = I915_READ(SPCNTR(pipe, plane)); |
58 | 161 | ||
Line 113... | Line 216... | ||
113 | if (obj->tiling_mode != I915_TILING_NONE) |
216 | if (obj->tiling_mode != I915_TILING_NONE) |
114 | sprctl |= SP_TILED; |
217 | sprctl |= SP_TILED; |
Line 115... | Line 218... | ||
115 | 218 | ||
Line 116... | Line 219... | ||
116 | sprctl |= SP_ENABLE; |
219 | sprctl |= SP_ENABLE; |
- | 220 | ||
117 | 221 | intel_update_sprite_watermarks(dplane, crtc, src_w, src_h, |
|
Line 118... | Line 222... | ||
118 | intel_update_sprite_watermarks(dplane, crtc, src_w, pixel_size, true, |
222 | pixel_size, true, |
119 | src_w != crtc_w || src_h != crtc_h); |
223 | src_w != crtc_w || src_h != crtc_h); |
120 | 224 | ||
121 | /* Sizes are 0 based */ |
225 | /* Sizes are 0 based */ |
122 | src_w--; |
226 | src_w--; |
Line 123... | Line -... | ||
123 | src_h--; |
- | |
124 | crtc_w--; |
- | |
125 | crtc_h--; |
- | |
126 | 227 | src_h--; |
|
127 | I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); |
228 | crtc_w--; |
128 | I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); |
229 | crtc_h--; |
129 | 230 | ||
130 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
231 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
131 | sprsurf_offset = intel_gen4_compute_page_offset(&x, &y, |
232 | sprsurf_offset = intel_gen4_compute_page_offset(&x, &y, |
Line -... | Line 233... | ||
- | 233 | obj->tiling_mode, |
|
- | 234 | pixel_size, |
|
- | 235 | fb->pitches[0]); |
|
- | 236 | linear_offset -= sprsurf_offset; |
|
- | 237 | ||
- | 238 | atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); |
|
- | 239 | ||
132 | obj->tiling_mode, |
240 | intel_update_primary_plane(intel_crtc); |
133 | pixel_size, |
241 | |
134 | fb->pitches[0]); |
242 | I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]); |
135 | linear_offset -= sprsurf_offset; |
243 | I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x); |
Line 136... | Line 244... | ||
136 | 244 | ||
137 | if (obj->tiling_mode != I915_TILING_NONE) |
245 | if (obj->tiling_mode != I915_TILING_NONE) |
138 | I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x); |
246 | I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x); |
139 | else |
247 | else |
- | 248 | I915_WRITE(SPLINOFF(pipe, plane), linear_offset); |
|
140 | I915_WRITE(SPLINOFF(pipe, plane), linear_offset); |
249 | |
- | 250 | I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); |
|
- | 251 | I915_WRITE(SPCNTR(pipe, plane), sprctl); |
|
- | 252 | I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) + |
|
141 | 253 | sprsurf_offset); |
|
Line 142... | Line 254... | ||
142 | I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w); |
254 | |
143 | I915_WRITE(SPCNTR(pipe, plane), sprctl); |
255 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
144 | I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) + |
256 | |
145 | sprsurf_offset); |
257 | if (atomic_update) |
146 | POSTING_READ(SPSURF(pipe, plane)); |
258 | intel_pipe_update_end(intel_crtc, start_vbl_count); |
147 | } |
259 | } |
- | 260 | ||
148 | 261 | static void |
|
149 | static void |
262 | vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) |
- | 263 | { |
|
- | 264 | struct drm_device *dev = dplane->dev; |
|
- | 265 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 266 | struct intel_plane *intel_plane = to_intel_plane(dplane); |
|
- | 267 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 268 | int pipe = intel_plane->pipe; |
|
Line 150... | Line 269... | ||
150 | vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc) |
269 | int plane = intel_plane->plane; |
151 | { |
270 | u32 start_vbl_count; |
152 | struct drm_device *dev = dplane->dev; |
271 | bool atomic_update; |
153 | struct drm_i915_private *dev_priv = dev->dev_private; |
272 | |
154 | struct intel_plane *intel_plane = to_intel_plane(dplane); |
- | |
Line -... | Line 273... | ||
- | 273 | atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); |
|
- | 274 | ||
- | 275 | intel_update_primary_plane(intel_crtc); |
|
- | 276 | ||
- | 277 | I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) & |
|
155 | int pipe = intel_plane->pipe; |
278 | ~SP_ENABLE); |
156 | int plane = intel_plane->plane; |
279 | /* Activate double buffered register update */ |
Line 157... | Line 280... | ||
157 | 280 | I915_WRITE(SPSURF(pipe, plane), 0); |
|
158 | I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) & |
281 | |
159 | ~SP_ENABLE); |
282 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
Line 224... | Line 347... | ||
224 | uint32_t src_w, uint32_t src_h) |
347 | uint32_t src_w, uint32_t src_h) |
225 | { |
348 | { |
226 | struct drm_device *dev = plane->dev; |
349 | struct drm_device *dev = plane->dev; |
227 | struct drm_i915_private *dev_priv = dev->dev_private; |
350 | struct drm_i915_private *dev_priv = dev->dev_private; |
228 | struct intel_plane *intel_plane = to_intel_plane(plane); |
351 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | 352 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
229 | int pipe = intel_plane->pipe; |
353 | int pipe = intel_plane->pipe; |
230 | u32 sprctl, sprscale = 0; |
354 | u32 sprctl, sprscale = 0; |
231 | unsigned long sprsurf_offset, linear_offset; |
355 | unsigned long sprsurf_offset, linear_offset; |
232 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
356 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
- | 357 | u32 start_vbl_count; |
|
- | 358 | bool atomic_update; |
|
Line 233... | Line 359... | ||
233 | 359 | ||
Line 234... | Line 360... | ||
234 | sprctl = I915_READ(SPRCTL(pipe)); |
360 | sprctl = I915_READ(SPRCTL(pipe)); |
235 | 361 | ||
Line 279... | Line 405... | ||
279 | sprctl |= SPRITE_ENABLE; |
405 | sprctl |= SPRITE_ENABLE; |
Line 280... | Line 406... | ||
280 | 406 | ||
281 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
407 | if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
Line 282... | Line 408... | ||
282 | sprctl |= SPRITE_PIPE_CSC_ENABLE; |
408 | sprctl |= SPRITE_PIPE_CSC_ENABLE; |
- | 409 | ||
283 | 410 | intel_update_sprite_watermarks(plane, crtc, src_w, src_h, pixel_size, |
|
Line 284... | Line 411... | ||
284 | intel_update_sprite_watermarks(plane, crtc, src_w, pixel_size, true, |
411 | true, |
285 | src_w != crtc_w || src_h != crtc_h); |
412 | src_w != crtc_w || src_h != crtc_h); |
286 | 413 | ||
Line 291... | Line 418... | ||
291 | crtc_h--; |
418 | crtc_h--; |
Line 292... | Line 419... | ||
292 | 419 | ||
293 | if (crtc_w != src_w || crtc_h != src_h) |
420 | if (crtc_w != src_w || crtc_h != src_h) |
Line 294... | Line -... | ||
294 | sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; |
- | |
295 | - | ||
296 | I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); |
- | |
297 | I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); |
421 | sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h; |
298 | 422 | ||
299 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
423 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
300 | sprsurf_offset = |
424 | sprsurf_offset = |
301 | intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, |
425 | intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, |
Line -... | Line 426... | ||
- | 426 | pixel_size, fb->pitches[0]); |
|
- | 427 | linear_offset -= sprsurf_offset; |
|
- | 428 | ||
- | 429 | atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); |
|
- | 430 | ||
- | 431 | intel_update_primary_plane(intel_crtc); |
|
- | 432 | ||
302 | pixel_size, fb->pitches[0]); |
433 | I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]); |
303 | linear_offset -= sprsurf_offset; |
434 | I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x); |
304 | 435 | ||
305 | /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET |
436 | /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET |
306 | * register */ |
437 | * register */ |
Line 315... | Line 446... | ||
315 | if (intel_plane->can_scale) |
446 | if (intel_plane->can_scale) |
316 | I915_WRITE(SPRSCALE(pipe), sprscale); |
447 | I915_WRITE(SPRSCALE(pipe), sprscale); |
317 | I915_WRITE(SPRCTL(pipe), sprctl); |
448 | I915_WRITE(SPRCTL(pipe), sprctl); |
318 | I915_WRITE(SPRSURF(pipe), |
449 | I915_WRITE(SPRSURF(pipe), |
319 | i915_gem_obj_ggtt_offset(obj) + sprsurf_offset); |
450 | i915_gem_obj_ggtt_offset(obj) + sprsurf_offset); |
- | 451 | ||
- | 452 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
|
- | 453 | ||
320 | POSTING_READ(SPRSURF(pipe)); |
454 | if (atomic_update) |
- | 455 | intel_pipe_update_end(intel_crtc, start_vbl_count); |
|
321 | } |
456 | } |
Line 322... | Line 457... | ||
322 | 457 | ||
323 | static void |
458 | static void |
324 | ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) |
459 | ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) |
325 | { |
460 | { |
326 | struct drm_device *dev = plane->dev; |
461 | struct drm_device *dev = plane->dev; |
327 | struct drm_i915_private *dev_priv = dev->dev_private; |
462 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | 463 | struct intel_plane *intel_plane = to_intel_plane(plane); |
|
328 | struct intel_plane *intel_plane = to_intel_plane(plane); |
464 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | 465 | int pipe = intel_plane->pipe; |
|
- | 466 | u32 start_vbl_count; |
|
- | 467 | bool atomic_update; |
|
- | 468 | ||
- | 469 | atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); |
|
- | 470 | ||
Line 329... | Line 471... | ||
329 | int pipe = intel_plane->pipe; |
471 | intel_update_primary_plane(intel_crtc); |
330 | 472 | ||
331 | I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); |
473 | I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE); |
332 | /* Can't leave the scaler enabled... */ |
474 | /* Can't leave the scaler enabled... */ |
333 | if (intel_plane->can_scale) |
475 | if (intel_plane->can_scale) |
334 | I915_WRITE(SPRSCALE(pipe), 0); |
476 | I915_WRITE(SPRSCALE(pipe), 0); |
- | 477 | /* Activate double buffered register update */ |
|
- | 478 | I915_WRITE(SPRSURF(pipe), 0); |
|
- | 479 | ||
335 | /* Activate double buffered register update */ |
480 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
- | 481 | ||
Line 336... | Line 482... | ||
336 | I915_WRITE(SPRSURF(pipe), 0); |
482 | if (atomic_update) |
337 | POSTING_READ(SPRSURF(pipe)); |
483 | intel_pipe_update_end(intel_crtc, start_vbl_count); |
338 | 484 | ||
339 | /* |
485 | /* |
340 | * Avoid underruns when disabling the sprite. |
486 | * Avoid underruns when disabling the sprite. |
Line 341... | Line 487... | ||
341 | * FIXME remove once watermark updates are done properly. |
487 | * FIXME remove once watermark updates are done properly. |
342 | */ |
488 | */ |
Line 343... | Line 489... | ||
343 | intel_wait_for_vblank(dev, pipe); |
489 | intel_wait_for_vblank(dev, pipe); |
344 | 490 | ||
345 | intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false); |
491 | intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false); |
Line 408... | Line 554... | ||
408 | uint32_t src_w, uint32_t src_h) |
554 | uint32_t src_w, uint32_t src_h) |
409 | { |
555 | { |
410 | struct drm_device *dev = plane->dev; |
556 | struct drm_device *dev = plane->dev; |
411 | struct drm_i915_private *dev_priv = dev->dev_private; |
557 | struct drm_i915_private *dev_priv = dev->dev_private; |
412 | struct intel_plane *intel_plane = to_intel_plane(plane); |
558 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | 559 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
413 | int pipe = intel_plane->pipe; |
560 | int pipe = intel_plane->pipe; |
414 | unsigned long dvssurf_offset, linear_offset; |
561 | unsigned long dvssurf_offset, linear_offset; |
415 | u32 dvscntr, dvsscale; |
562 | u32 dvscntr, dvsscale; |
416 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
563 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
- | 564 | u32 start_vbl_count; |
|
- | 565 | bool atomic_update; |
|
Line 417... | Line 566... | ||
417 | 566 | ||
Line 418... | Line 567... | ||
418 | dvscntr = I915_READ(DVSCNTR(pipe)); |
567 | dvscntr = I915_READ(DVSCNTR(pipe)); |
419 | 568 | ||
Line 457... | Line 606... | ||
457 | 606 | ||
458 | if (IS_GEN6(dev)) |
607 | if (IS_GEN6(dev)) |
459 | dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ |
608 | dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */ |
Line 460... | Line 609... | ||
460 | dvscntr |= DVS_ENABLE; |
609 | dvscntr |= DVS_ENABLE; |
- | 610 | ||
461 | 611 | intel_update_sprite_watermarks(plane, crtc, src_w, src_h, |
|
Line 462... | Line 612... | ||
462 | intel_update_sprite_watermarks(plane, crtc, src_w, pixel_size, true, |
612 | pixel_size, true, |
463 | src_w != crtc_w || src_h != crtc_h); |
613 | src_w != crtc_w || src_h != crtc_h); |
464 | 614 | ||
Line 470... | Line 620... | ||
470 | 620 | ||
471 | dvsscale = 0; |
621 | dvsscale = 0; |
472 | if (crtc_w != src_w || crtc_h != src_h) |
622 | if (crtc_w != src_w || crtc_h != src_h) |
Line 473... | Line -... | ||
473 | dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; |
- | |
474 | - | ||
475 | I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); |
- | |
476 | I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x); |
623 | dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h; |
477 | 624 | ||
478 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
625 | linear_offset = y * fb->pitches[0] + x * pixel_size; |
479 | dvssurf_offset = |
626 | dvssurf_offset = |
480 | intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, |
627 | intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode, |
Line -... | Line 628... | ||
- | 628 | pixel_size, fb->pitches[0]); |
|
- | 629 | linear_offset -= dvssurf_offset; |
|
- | 630 | ||
- | 631 | atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); |
|
- | 632 | ||
- | 633 | intel_update_primary_plane(intel_crtc); |
|
- | 634 | ||
481 | pixel_size, fb->pitches[0]); |
635 | I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]); |
482 | linear_offset -= dvssurf_offset; |
636 | I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x); |
483 | 637 | ||
484 | if (obj->tiling_mode != I915_TILING_NONE) |
638 | if (obj->tiling_mode != I915_TILING_NONE) |
Line 485... | Line 639... | ||
485 | I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x); |
639 | I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x); |
486 | else |
640 | else |
487 | I915_WRITE(DVSLINOFF(pipe), linear_offset); |
641 | I915_WRITE(DVSLINOFF(pipe), linear_offset); |
488 | 642 | ||
489 | I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); |
643 | I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w); |
- | 644 | I915_WRITE(DVSSCALE(pipe), dvsscale); |
|
- | 645 | I915_WRITE(DVSCNTR(pipe), dvscntr); |
|
- | 646 | I915_WRITE(DVSSURF(pipe), |
|
490 | I915_WRITE(DVSSCALE(pipe), dvsscale); |
647 | i915_gem_obj_ggtt_offset(obj) + dvssurf_offset); |
- | 648 | ||
491 | I915_WRITE(DVSCNTR(pipe), dvscntr); |
649 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
Line 492... | Line 650... | ||
492 | I915_WRITE(DVSSURF(pipe), |
650 | |
493 | i915_gem_obj_ggtt_offset(obj) + dvssurf_offset); |
651 | if (atomic_update) |
494 | POSTING_READ(DVSSURF(pipe)); |
652 | intel_pipe_update_end(intel_crtc, start_vbl_count); |
495 | } |
653 | } |
496 | 654 | ||
497 | static void |
655 | static void |
- | 656 | ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) |
|
498 | ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc) |
657 | { |
- | 658 | struct drm_device *dev = plane->dev; |
|
- | 659 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 660 | struct intel_plane *intel_plane = to_intel_plane(plane); |
|
- | 661 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
|
- | 662 | int pipe = intel_plane->pipe; |
|
- | 663 | u32 start_vbl_count; |
|
Line 499... | Line 664... | ||
499 | { |
664 | bool atomic_update; |
500 | struct drm_device *dev = plane->dev; |
665 | |
501 | struct drm_i915_private *dev_priv = dev->dev_private; |
666 | atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); |
502 | struct intel_plane *intel_plane = to_intel_plane(plane); |
667 | |
503 | int pipe = intel_plane->pipe; |
668 | intel_update_primary_plane(intel_crtc); |
- | 669 | ||
- | 670 | I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE); |
|
- | 671 | /* Disable the scaler */ |
|
504 | 672 | I915_WRITE(DVSSCALE(pipe), 0); |
|
- | 673 | /* Flush double buffered register updates */ |
|
Line 505... | Line 674... | ||
505 | I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE); |
674 | I915_WRITE(DVSSURF(pipe), 0); |
506 | /* Disable the scaler */ |
675 | |
507 | I915_WRITE(DVSSCALE(pipe), 0); |
676 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
508 | /* Flush double buffered register updates */ |
677 | |
509 | I915_WRITE(DVSSURF(pipe), 0); |
678 | if (atomic_update) |
Line 510... | Line 679... | ||
510 | POSTING_READ(DVSSURF(pipe)); |
679 | intel_pipe_update_end(intel_crtc, start_vbl_count); |
511 | 680 | ||
Line 512... | Line 681... | ||
512 | /* |
681 | /* |
513 | * Avoid underruns when disabling the sprite. |
682 | * Avoid underruns when disabling the sprite. |
514 | * FIXME remove once watermark updates are done properly. |
683 | * FIXME remove once watermark updates are done properly. |
515 | */ |
684 | */ |
516 | intel_wait_for_vblank(dev, pipe); |
- | |
517 | 685 | intel_wait_for_vblank(dev, pipe); |
|
518 | intel_update_sprite_watermarks(plane, crtc, 0, 0, false, false); |
- | |
519 | } |
- | |
520 | - | ||
521 | static void |
- | |
522 | intel_enable_primary(struct drm_crtc *crtc) |
- | |
523 | { |
- | |
524 | struct drm_device *dev = crtc->dev; |
- | |
525 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
526 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
- | |
Line 527... | Line 686... | ||
527 | int reg = DSPCNTR(intel_crtc->plane); |
686 | |
528 | 687 | intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false); |
|
529 | if (intel_crtc->primary_enabled) |
688 | } |
530 | return; |
689 | |
531 | 690 | static void |
|
532 | intel_crtc->primary_enabled = true; |
691 | intel_post_enable_primary(struct drm_crtc *crtc) |
533 | - | ||
534 | I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); |
- | |
535 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
692 | { |
536 | - | ||
Line 537... | Line 693... | ||
537 | /* |
693 | struct drm_device *dev = crtc->dev; |
538 | * FIXME IPS should be fine as long as one plane is |
694 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
539 | * enabled, but in practice it seems to have problems |
695 | |
540 | * when going from primary only to sprite only and vice |
696 | /* |
Line 541... | Line 697... | ||
541 | * versa. |
697 | * FIXME IPS should be fine as long as one plane is |
542 | */ |
698 | * enabled, but in practice it seems to have problems |
543 | if (intel_crtc->config.ips_enabled) { |
699 | * when going from primary only to sprite only and vice |
544 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
700 | * versa. |
545 | hsw_enable_ips(intel_crtc); |
701 | */ |
546 | } |
702 | hsw_enable_ips(intel_crtc); |
547 | - | ||
548 | mutex_lock(&dev->struct_mutex); |
- | |
549 | intel_update_fbc(dev); |
- | |
550 | mutex_unlock(&dev->struct_mutex); |
- | |
551 | } |
- | |
552 | - | ||
Line 553... | Line 703... | ||
553 | static void |
703 | |
554 | intel_disable_primary(struct drm_crtc *crtc) |
704 | mutex_lock(&dev->struct_mutex); |
555 | { |
705 | intel_update_fbc(dev); |
556 | struct drm_device *dev = crtc->dev; |
706 | mutex_unlock(&dev->struct_mutex); |
Line 573... | Line 723... | ||
573 | * enabled, but in practice it seems to have problems |
723 | * enabled, but in practice it seems to have problems |
574 | * when going from primary only to sprite only and vice |
724 | * when going from primary only to sprite only and vice |
575 | * versa. |
725 | * versa. |
576 | */ |
726 | */ |
577 | hsw_disable_ips(intel_crtc); |
727 | hsw_disable_ips(intel_crtc); |
578 | - | ||
579 | I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); |
- | |
580 | intel_flush_primary_plane(dev_priv, intel_crtc->plane); |
- | |
581 | } |
728 | } |
Line 582... | Line 729... | ||
582 | 729 | ||
583 | static int |
730 | static int |
584 | ilk_update_colorkey(struct drm_plane *plane, |
731 | ilk_update_colorkey(struct drm_plane *plane, |
Line 665... | Line 812... | ||
665 | uint32_t src_w, uint32_t src_h) |
812 | uint32_t src_w, uint32_t src_h) |
666 | { |
813 | { |
667 | struct drm_device *dev = plane->dev; |
814 | struct drm_device *dev = plane->dev; |
668 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
815 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
669 | struct intel_plane *intel_plane = to_intel_plane(plane); |
816 | struct intel_plane *intel_plane = to_intel_plane(plane); |
- | 817 | enum pipe pipe = intel_crtc->pipe; |
|
670 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
818 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
671 | struct drm_i915_gem_object *obj = intel_fb->obj; |
819 | struct drm_i915_gem_object *obj = intel_fb->obj; |
672 | struct drm_i915_gem_object *old_obj = intel_plane->obj; |
820 | struct drm_i915_gem_object *old_obj = intel_plane->obj; |
673 | int ret; |
821 | int ret; |
674 | bool disable_primary = false; |
822 | bool primary_enabled; |
675 | bool visible; |
823 | bool visible; |
676 | int hscale, vscale; |
824 | int hscale, vscale; |
677 | int max_scale, min_scale; |
825 | int max_scale, min_scale; |
678 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
826 | int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0); |
679 | struct drm_rect src = { |
827 | struct drm_rect src = { |
Line 840... | Line 988... | ||
840 | 988 | ||
841 | /* |
989 | /* |
842 | * If the sprite is completely covering the primary plane, |
990 | * If the sprite is completely covering the primary plane, |
843 | * we can disable the primary and save power. |
991 | * we can disable the primary and save power. |
844 | */ |
992 | */ |
845 | disable_primary = drm_rect_equals(&dst, &clip) && !colorkey_enabled(intel_plane); |
993 | primary_enabled = !drm_rect_equals(&dst, &clip) || colorkey_enabled(intel_plane); |
Line 846... | Line 994... | ||
846 | WARN_ON(disable_primary && !visible && intel_crtc->active); |
994 | WARN_ON(!primary_enabled && !visible && intel_crtc->active); |
Line 847... | Line 995... | ||
847 | 995 | ||
848 | mutex_lock(&dev->struct_mutex); |
996 | mutex_lock(&dev->struct_mutex); |
849 | 997 | ||
850 | /* Note that this will apply the VT-d workaround for scanouts, |
998 | /* Note that this will apply the VT-d workaround for scanouts, |
851 | * which is more restrictive than required for sprites. (The |
999 | * which is more restrictive than required for sprites. (The |
852 | * primary plane requires 256KiB alignment with 64 PTE padding, |
1000 | * primary plane requires 256KiB alignment with 64 PTE padding, |
Line -... | Line 1001... | ||
- | 1001 | * the sprite planes only require 128KiB alignment and 32 PTE padding. |
|
- | 1002 | */ |
|
853 | * the sprite planes only require 128KiB alignment and 32 PTE padding. |
1003 | ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); |
Line 854... | Line 1004... | ||
854 | */ |
1004 | |
855 | ret = intel_pin_and_fence_fb_obj(dev, obj, NULL); |
1005 | i915_gem_track_fb(old_obj, obj, |
Line 868... | Line 1018... | ||
868 | intel_plane->src_w = orig.src_w; |
1018 | intel_plane->src_w = orig.src_w; |
869 | intel_plane->src_h = orig.src_h; |
1019 | intel_plane->src_h = orig.src_h; |
870 | intel_plane->obj = obj; |
1020 | intel_plane->obj = obj; |
Line 871... | Line 1021... | ||
871 | 1021 | ||
- | 1022 | if (intel_crtc->active) { |
|
872 | if (intel_crtc->active) { |
1023 | bool primary_was_enabled = intel_crtc->primary_enabled; |
873 | /* |
1024 | |
- | 1025 | intel_crtc->primary_enabled = primary_enabled; |
|
874 | * Be sure to re-enable the primary before the sprite is no longer |
1026 | |
875 | * covering it fully. |
1027 | // if (primary_was_enabled != primary_enabled) |
876 | */ |
1028 | |
877 | if (!disable_primary) |
1029 | if (primary_was_enabled && !primary_enabled) |
Line 878... | Line 1030... | ||
878 | intel_enable_primary(crtc); |
1030 | intel_pre_disable_primary(crtc); |
879 | 1031 | ||
880 | if (visible) |
1032 | if (visible) |
881 | intel_plane->update_plane(plane, crtc, fb, obj, |
1033 | intel_plane->update_plane(plane, crtc, fb, obj, |
882 | crtc_x, crtc_y, crtc_w, crtc_h, |
1034 | crtc_x, crtc_y, crtc_w, crtc_h, |
883 | src_x, src_y, src_w, src_h); |
1035 | src_x, src_y, src_w, src_h); |
Line 884... | Line 1036... | ||
884 | else |
1036 | else |
885 | intel_plane->disable_plane(plane, crtc); |
1037 | intel_plane->disable_plane(plane, crtc); |
886 | 1038 | ||
Line 887... | Line 1039... | ||
887 | if (disable_primary) |
1039 | if (!primary_was_enabled && primary_enabled) |
888 | intel_disable_primary(crtc); |
1040 | intel_post_enable_primary(crtc); |
889 | } |
1041 | } |
Line 911... | Line 1063... | ||
911 | intel_disable_plane(struct drm_plane *plane) |
1063 | intel_disable_plane(struct drm_plane *plane) |
912 | { |
1064 | { |
913 | struct drm_device *dev = plane->dev; |
1065 | struct drm_device *dev = plane->dev; |
914 | struct intel_plane *intel_plane = to_intel_plane(plane); |
1066 | struct intel_plane *intel_plane = to_intel_plane(plane); |
915 | struct intel_crtc *intel_crtc; |
1067 | struct intel_crtc *intel_crtc; |
- | 1068 | enum pipe pipe; |
|
Line 916... | Line 1069... | ||
916 | 1069 | ||
917 | if (!plane->fb) |
1070 | if (!plane->fb) |
Line 918... | Line 1071... | ||
918 | return 0; |
1071 | return 0; |
919 | 1072 | ||
Line 920... | Line 1073... | ||
920 | if (WARN_ON(!plane->crtc)) |
1073 | if (WARN_ON(!plane->crtc)) |
- | 1074 | return -EINVAL; |
|
Line 921... | Line 1075... | ||
921 | return -EINVAL; |
1075 | |
- | 1076 | intel_crtc = to_intel_crtc(plane->crtc); |
|
- | 1077 | pipe = intel_crtc->pipe; |
|
922 | 1078 | ||
- | 1079 | if (intel_crtc->active) { |
|
923 | intel_crtc = to_intel_crtc(plane->crtc); |
1080 | bool primary_was_enabled = intel_crtc->primary_enabled; |
- | 1081 | ||
- | 1082 | intel_crtc->primary_enabled = true; |
|
- | 1083 | ||
924 | 1084 | intel_plane->disable_plane(plane, plane->crtc); |
|
Line 925... | Line 1085... | ||
925 | if (intel_crtc->active) { |
1085 | |
926 | intel_enable_primary(plane->crtc); |
1086 | if (!primary_was_enabled && intel_crtc->primary_enabled) |
927 | intel_plane->disable_plane(plane, plane->crtc); |
1087 | intel_post_enable_primary(plane->crtc); |
Line 928... | Line 1088... | ||
928 | } |
1088 | } |
929 | 1089 | ||
- | 1090 | if (intel_plane->obj) { |
|
- | 1091 | if (intel_crtc->active) |
|
930 | if (intel_plane->obj) { |
1092 | intel_wait_for_vblank(dev, intel_plane->pipe); |
Line 931... | Line 1093... | ||
931 | if (intel_crtc->active) |
1093 | |
932 | intel_wait_for_vblank(dev, intel_plane->pipe); |
1094 | mutex_lock(&dev->struct_mutex); |
Line 951... | Line 1113... | ||
951 | 1113 | ||
952 | int intel_sprite_set_colorkey(struct drm_device *dev, void *data, |
1114 | int intel_sprite_set_colorkey(struct drm_device *dev, void *data, |
953 | struct drm_file *file_priv) |
1115 | struct drm_file *file_priv) |
954 | { |
1116 | { |
955 | struct drm_intel_sprite_colorkey *set = data; |
- | |
956 | struct drm_mode_object *obj; |
1117 | struct drm_intel_sprite_colorkey *set = data; |
957 | struct drm_plane *plane; |
1118 | struct drm_plane *plane; |
958 | struct intel_plane *intel_plane; |
1119 | struct intel_plane *intel_plane; |
Line 959... | Line 1120... | ||
959 | int ret = 0; |
1120 | int ret = 0; |
Line 965... | Line 1126... | ||
965 | if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) |
1126 | if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) |
966 | return -EINVAL; |
1127 | return -EINVAL; |
Line 967... | Line 1128... | ||
967 | 1128 | ||
Line 968... | Line 1129... | ||
968 | drm_modeset_lock_all(dev); |
1129 | drm_modeset_lock_all(dev); |
969 | 1130 | ||
970 | obj = drm_mode_object_find(dev, set->plane_id, DRM_MODE_OBJECT_PLANE); |
1131 | plane = drm_plane_find(dev, set->plane_id); |
971 | if (!obj) { |
1132 | if (!plane) { |
972 | ret = -ENOENT; |
1133 | ret = -ENOENT; |
Line 973... | Line -... | ||
973 | goto out_unlock; |
- | |
974 | } |
1134 | goto out_unlock; |
975 | 1135 | } |
|
Line 976... | Line 1136... | ||
976 | plane = obj_to_plane(obj); |
1136 | |
977 | intel_plane = to_intel_plane(plane); |
1137 | intel_plane = to_intel_plane(plane); |
Line 984... | Line 1144... | ||
984 | 1144 | ||
985 | int intel_sprite_get_colorkey(struct drm_device *dev, void *data, |
1145 | int intel_sprite_get_colorkey(struct drm_device *dev, void *data, |
986 | struct drm_file *file_priv) |
1146 | struct drm_file *file_priv) |
987 | { |
1147 | { |
988 | struct drm_intel_sprite_colorkey *get = data; |
- | |
989 | struct drm_mode_object *obj; |
1148 | struct drm_intel_sprite_colorkey *get = data; |
990 | struct drm_plane *plane; |
1149 | struct drm_plane *plane; |
991 | struct intel_plane *intel_plane; |
1150 | struct intel_plane *intel_plane; |
Line 992... | Line 1151... | ||
992 | int ret = 0; |
1151 | int ret = 0; |
993 | 1152 | ||
Line 994... | Line 1153... | ||
994 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
1153 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
Line 995... | Line 1154... | ||
995 | return -ENODEV; |
1154 | return -ENODEV; |
996 | 1155 | ||
997 | drm_modeset_lock_all(dev); |
1156 | drm_modeset_lock_all(dev); |
998 | 1157 | ||
999 | obj = drm_mode_object_find(dev, get->plane_id, DRM_MODE_OBJECT_PLANE); |
1158 | plane = drm_plane_find(dev, get->plane_id); |
Line 1000... | Line -... | ||
1000 | if (!obj) { |
- | |
1001 | ret = -ENOENT; |
1159 | if (!plane) { |
1002 | goto out_unlock; |
1160 | ret = -ENOENT; |
Line 1003... | Line 1161... | ||
1003 | } |
1161 | goto out_unlock; |
1004 | 1162 | } |