aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_overlay.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-26 21:57:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-26 21:57:59 -0400
commitc48c43e422c1404fd72c57d1d21a6f6d01e18900 (patch)
tree48e5d3828b4f5479361986535f71a1ae44e4f3c1 /drivers/gpu/drm/i915/intel_overlay.c
parent520045db940a381d2bee1c1b2179f7921b40fb10 (diff)
parent135cba0dc399fdd47bd3ae305c1db75fcd77243f (diff)
Merge branch 'drm-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (476 commits) vmwgfx: Implement a proper GMR eviction mechanism drm/radeon/kms: fix r6xx/7xx 1D tiling CS checker v2 drm/radeon/kms: properly compute group_size on 6xx/7xx drm/radeon/kms: fix 2D tile height alignment in the r600 CS checker drm/radeon/kms/evergreen: set the clear state to the blit state drm/radeon/kms: don't poll dac load detect. gpu: Add Intel GMA500(Poulsbo) Stub Driver drm/radeon/kms: MC vram map needs to be >= pci aperture size drm/radeon/kms: implement display watermark support for evergreen drm/radeon/kms/evergreen: add some additional safe regs v2 drm/radeon/r600: fix tiling issues in CS checker. drm/i915: Move gpu_write_list to per-ring drm/i915: Invalidate the to-ring, flush the old-ring when updating domains drm/i915/ringbuffer: Write the value passed in to the tail register agp/intel: Restore valid PTE bit for Sandybridge after bdd3072 drm/i915: Fix flushing regression from 9af90d19f drm/i915/sdvo: Remove unused encoding member i915: enable AVI infoframe for intel_hdmi.c [v4] drm/i915: Fix current fb blocking for page flip drm/i915: IS_IRONLAKE is synonymous with gen == 5 ... Fix up conflicts in - drivers/gpu/drm/i915/{i915_gem.c, i915/intel_overlay.c}: due to the new simplified stack-based kmap_atomic() interface - drivers/gpu/drm/vmwgfx/vmwgfx_drv.c: added .llseek entry due to BKL removal cleanups.
Diffstat (limited to 'drivers/gpu/drm/i915/intel_overlay.c')
-rw-r--r--drivers/gpu/drm/i915/intel_overlay.c1000
1 files changed, 531 insertions, 469 deletions
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
index 3264bbd47e65..afb96d25219a 100644
--- a/drivers/gpu/drm/i915/intel_overlay.c
+++ b/drivers/gpu/drm/i915/intel_overlay.c
@@ -170,56 +170,143 @@ struct overlay_registers {
170 u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES]; 170 u16 RESERVEDG[0x100 / 2 - N_HORIZ_UV_TAPS * N_PHASES];
171}; 171};
172 172
173/* overlay flip addr flag */ 173struct intel_overlay {
174#define OFC_UPDATE 0x1 174 struct drm_device *dev;
175 175 struct intel_crtc *crtc;
176#define OVERLAY_NONPHYSICAL(dev) (IS_G33(dev) || IS_I965G(dev)) 176 struct drm_i915_gem_object *vid_bo;
177#define OVERLAY_EXISTS(dev) (!IS_G4X(dev) && !IS_IRONLAKE(dev) && !IS_GEN6(dev)) 177 struct drm_i915_gem_object *old_vid_bo;
178 178 int active;
179 int pfit_active;
180 u32 pfit_vscale_ratio; /* shifted-point number, (1<<12) == 1.0 */
181 u32 color_key;
182 u32 brightness, contrast, saturation;
183 u32 old_xscale, old_yscale;
184 /* register access */
185 u32 flip_addr;
186 struct drm_i915_gem_object *reg_bo;
187 /* flip handling */
188 uint32_t last_flip_req;
189 void (*flip_tail)(struct intel_overlay *);
190};
179 191
180static struct overlay_registers *intel_overlay_map_regs_atomic(struct intel_overlay *overlay) 192static struct overlay_registers *
193intel_overlay_map_regs(struct intel_overlay *overlay)
181{ 194{
182 drm_i915_private_t *dev_priv = overlay->dev->dev_private; 195 drm_i915_private_t *dev_priv = overlay->dev->dev_private;
183 struct overlay_registers *regs; 196 struct overlay_registers *regs;
184 197
185 /* no recursive mappings */ 198 if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
186 BUG_ON(overlay->virt_addr); 199 regs = overlay->reg_bo->phys_obj->handle->vaddr;
200 else
201 regs = io_mapping_map_wc(dev_priv->mm.gtt_mapping,
202 overlay->reg_bo->gtt_offset);
187 203
188 if (OVERLAY_NONPHYSICAL(overlay->dev)) { 204 return regs;
189 regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, 205}
190 overlay->reg_bo->gtt_offset);
191 206
192 if (!regs) { 207static void intel_overlay_unmap_regs(struct intel_overlay *overlay,
193 DRM_ERROR("failed to map overlay regs in GTT\n"); 208 struct overlay_registers *regs)
194 return NULL; 209{
195 } 210 if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
196 } else 211 io_mapping_unmap(regs);
197 regs = overlay->reg_bo->phys_obj->handle->vaddr; 212}
213
214static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
215 struct drm_i915_gem_request *request,
216 bool interruptible,
217 void (*tail)(struct intel_overlay *))
218{
219 struct drm_device *dev = overlay->dev;
220 drm_i915_private_t *dev_priv = dev->dev_private;
221 int ret;
222
223 BUG_ON(overlay->last_flip_req);
224 overlay->last_flip_req =
225 i915_add_request(dev, NULL, request, &dev_priv->render_ring);
226 if (overlay->last_flip_req == 0)
227 return -ENOMEM;
198 228
199 return overlay->virt_addr = regs; 229 overlay->flip_tail = tail;
230 ret = i915_do_wait_request(dev,
231 overlay->last_flip_req, true,
232 &dev_priv->render_ring);
233 if (ret)
234 return ret;
235
236 overlay->last_flip_req = 0;
237 return 0;
200} 238}
201 239
202static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay) 240/* Workaround for i830 bug where pipe a must be enable to change control regs */
241static int
242i830_activate_pipe_a(struct drm_device *dev)
203{ 243{
204 if (OVERLAY_NONPHYSICAL(overlay->dev)) 244 drm_i915_private_t *dev_priv = dev->dev_private;
205 io_mapping_unmap_atomic(overlay->virt_addr); 245 struct intel_crtc *crtc;
246 struct drm_crtc_helper_funcs *crtc_funcs;
247 struct drm_display_mode vesa_640x480 = {
248 DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
249 752, 800, 0, 480, 489, 492, 525, 0,
250 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC)
251 }, *mode;
252
253 crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[0]);
254 if (crtc->dpms_mode == DRM_MODE_DPMS_ON)
255 return 0;
206 256
207 overlay->virt_addr = NULL; 257 /* most i8xx have pipe a forced on, so don't trust dpms mode */
258 if (I915_READ(PIPEACONF) & PIPECONF_ENABLE)
259 return 0;
208 260
209 return; 261 crtc_funcs = crtc->base.helper_private;
262 if (crtc_funcs->dpms == NULL)
263 return 0;
264
265 DRM_DEBUG_DRIVER("Enabling pipe A in order to enable overlay\n");
266
267 mode = drm_mode_duplicate(dev, &vesa_640x480);
268 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
269 if(!drm_crtc_helper_set_mode(&crtc->base, mode,
270 crtc->base.x, crtc->base.y,
271 crtc->base.fb))
272 return 0;
273
274 crtc_funcs->dpms(&crtc->base, DRM_MODE_DPMS_ON);
275 return 1;
276}
277
278static void
279i830_deactivate_pipe_a(struct drm_device *dev)
280{
281 drm_i915_private_t *dev_priv = dev->dev_private;
282 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[0];
283 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
284
285 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
210} 286}
211 287
212/* overlay needs to be disable in OCMD reg */ 288/* overlay needs to be disable in OCMD reg */
213static int intel_overlay_on(struct intel_overlay *overlay) 289static int intel_overlay_on(struct intel_overlay *overlay)
214{ 290{
215 struct drm_device *dev = overlay->dev; 291 struct drm_device *dev = overlay->dev;
292 struct drm_i915_gem_request *request;
293 int pipe_a_quirk = 0;
216 int ret; 294 int ret;
217 drm_i915_private_t *dev_priv = dev->dev_private;
218 295
219 BUG_ON(overlay->active); 296 BUG_ON(overlay->active);
220
221 overlay->active = 1; 297 overlay->active = 1;
222 overlay->hw_wedged = NEEDS_WAIT_FOR_FLIP; 298
299 if (IS_I830(dev)) {
300 pipe_a_quirk = i830_activate_pipe_a(dev);
301 if (pipe_a_quirk < 0)
302 return pipe_a_quirk;
303 }
304
305 request = kzalloc(sizeof(*request), GFP_KERNEL);
306 if (request == NULL) {
307 ret = -ENOMEM;
308 goto out;
309 }
223 310
224 BEGIN_LP_RING(4); 311 BEGIN_LP_RING(4);
225 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON); 312 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON);
@@ -228,32 +315,30 @@ static int intel_overlay_on(struct intel_overlay *overlay)
228 OUT_RING(MI_NOOP); 315 OUT_RING(MI_NOOP);
229 ADVANCE_LP_RING(); 316 ADVANCE_LP_RING();
230 317
231 overlay->last_flip_req = 318 ret = intel_overlay_do_wait_request(overlay, request, true, NULL);
232 i915_add_request(dev, NULL, 0, &dev_priv->render_ring); 319out:
233 if (overlay->last_flip_req == 0) 320 if (pipe_a_quirk)
234 return -ENOMEM; 321 i830_deactivate_pipe_a(dev);
235
236 ret = i915_do_wait_request(dev,
237 overlay->last_flip_req, 1, &dev_priv->render_ring);
238 if (ret != 0)
239 return ret;
240 322
241 overlay->hw_wedged = 0; 323 return ret;
242 overlay->last_flip_req = 0;
243 return 0;
244} 324}
245 325
246/* overlay needs to be enabled in OCMD reg */ 326/* overlay needs to be enabled in OCMD reg */
247static void intel_overlay_continue(struct intel_overlay *overlay, 327static int intel_overlay_continue(struct intel_overlay *overlay,
248 bool load_polyphase_filter) 328 bool load_polyphase_filter)
249{ 329{
250 struct drm_device *dev = overlay->dev; 330 struct drm_device *dev = overlay->dev;
251 drm_i915_private_t *dev_priv = dev->dev_private; 331 drm_i915_private_t *dev_priv = dev->dev_private;
332 struct drm_i915_gem_request *request;
252 u32 flip_addr = overlay->flip_addr; 333 u32 flip_addr = overlay->flip_addr;
253 u32 tmp; 334 u32 tmp;
254 335
255 BUG_ON(!overlay->active); 336 BUG_ON(!overlay->active);
256 337
338 request = kzalloc(sizeof(*request), GFP_KERNEL);
339 if (request == NULL)
340 return -ENOMEM;
341
257 if (load_polyphase_filter) 342 if (load_polyphase_filter)
258 flip_addr |= OFC_UPDATE; 343 flip_addr |= OFC_UPDATE;
259 344
@@ -268,220 +353,132 @@ static void intel_overlay_continue(struct intel_overlay *overlay,
268 ADVANCE_LP_RING(); 353 ADVANCE_LP_RING();
269 354
270 overlay->last_flip_req = 355 overlay->last_flip_req =
271 i915_add_request(dev, NULL, 0, &dev_priv->render_ring); 356 i915_add_request(dev, NULL, request, &dev_priv->render_ring);
357 return 0;
272} 358}
273 359
274static int intel_overlay_wait_flip(struct intel_overlay *overlay) 360static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
275{ 361{
276 struct drm_device *dev = overlay->dev; 362 struct drm_gem_object *obj = &overlay->old_vid_bo->base;
277 drm_i915_private_t *dev_priv = dev->dev_private;
278 int ret;
279 u32 tmp;
280
281 if (overlay->last_flip_req != 0) {
282 ret = i915_do_wait_request(dev, overlay->last_flip_req,
283 1, &dev_priv->render_ring);
284 if (ret == 0) {
285 overlay->last_flip_req = 0;
286
287 tmp = I915_READ(ISR);
288 363
289 if (!(tmp & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT)) 364 i915_gem_object_unpin(obj);
290 return 0; 365 drm_gem_object_unreference(obj);
291 }
292 }
293 366
294 /* synchronous slowpath */ 367 overlay->old_vid_bo = NULL;
295 overlay->hw_wedged = RELEASE_OLD_VID; 368}
296 369
297 BEGIN_LP_RING(2); 370static void intel_overlay_off_tail(struct intel_overlay *overlay)
298 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 371{
299 OUT_RING(MI_NOOP); 372 struct drm_gem_object *obj;
300 ADVANCE_LP_RING();
301 373
302 overlay->last_flip_req = 374 /* never have the overlay hw on without showing a frame */
303 i915_add_request(dev, NULL, 0, &dev_priv->render_ring); 375 BUG_ON(!overlay->vid_bo);
304 if (overlay->last_flip_req == 0) 376 obj = &overlay->vid_bo->base;
305 return -ENOMEM;
306 377
307 ret = i915_do_wait_request(dev, overlay->last_flip_req, 378 i915_gem_object_unpin(obj);
308 1, &dev_priv->render_ring); 379 drm_gem_object_unreference(obj);
309 if (ret != 0) 380 overlay->vid_bo = NULL;
310 return ret;
311 381
312 overlay->hw_wedged = 0; 382 overlay->crtc->overlay = NULL;
313 overlay->last_flip_req = 0; 383 overlay->crtc = NULL;
314 return 0; 384 overlay->active = 0;
315} 385}
316 386
317/* overlay needs to be disabled in OCMD reg */ 387/* overlay needs to be disabled in OCMD reg */
318static int intel_overlay_off(struct intel_overlay *overlay) 388static int intel_overlay_off(struct intel_overlay *overlay,
389 bool interruptible)
319{ 390{
320 u32 flip_addr = overlay->flip_addr;
321 struct drm_device *dev = overlay->dev; 391 struct drm_device *dev = overlay->dev;
322 drm_i915_private_t *dev_priv = dev->dev_private; 392 u32 flip_addr = overlay->flip_addr;
323 int ret; 393 struct drm_i915_gem_request *request;
324 394
325 BUG_ON(!overlay->active); 395 BUG_ON(!overlay->active);
326 396
397 request = kzalloc(sizeof(*request), GFP_KERNEL);
398 if (request == NULL)
399 return -ENOMEM;
400
327 /* According to intel docs the overlay hw may hang (when switching 401 /* According to intel docs the overlay hw may hang (when switching
328 * off) without loading the filter coeffs. It is however unclear whether 402 * off) without loading the filter coeffs. It is however unclear whether
329 * this applies to the disabling of the overlay or to the switching off 403 * this applies to the disabling of the overlay or to the switching off
330 * of the hw. Do it in both cases */ 404 * of the hw. Do it in both cases */
331 flip_addr |= OFC_UPDATE; 405 flip_addr |= OFC_UPDATE;
332 406
407 BEGIN_LP_RING(6);
333 /* wait for overlay to go idle */ 408 /* wait for overlay to go idle */
334 overlay->hw_wedged = SWITCH_OFF_STAGE_1;
335
336 BEGIN_LP_RING(4);
337 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); 409 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
338 OUT_RING(flip_addr); 410 OUT_RING(flip_addr);
339 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 411 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
340 OUT_RING(MI_NOOP);
341 ADVANCE_LP_RING();
342
343 overlay->last_flip_req =
344 i915_add_request(dev, NULL, 0, &dev_priv->render_ring);
345 if (overlay->last_flip_req == 0)
346 return -ENOMEM;
347
348 ret = i915_do_wait_request(dev, overlay->last_flip_req,
349 1, &dev_priv->render_ring);
350 if (ret != 0)
351 return ret;
352
353 /* turn overlay off */ 412 /* turn overlay off */
354 overlay->hw_wedged = SWITCH_OFF_STAGE_2; 413 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
355
356 BEGIN_LP_RING(4);
357 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
358 OUT_RING(flip_addr); 414 OUT_RING(flip_addr);
359 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); 415 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
360 OUT_RING(MI_NOOP);
361 ADVANCE_LP_RING(); 416 ADVANCE_LP_RING();
362 417
363 overlay->last_flip_req = 418 return intel_overlay_do_wait_request(overlay, request, interruptible,
364 i915_add_request(dev, NULL, 0, &dev_priv->render_ring); 419 intel_overlay_off_tail);
365 if (overlay->last_flip_req == 0)
366 return -ENOMEM;
367
368 ret = i915_do_wait_request(dev, overlay->last_flip_req,
369 1, &dev_priv->render_ring);
370 if (ret != 0)
371 return ret;
372
373 overlay->hw_wedged = 0;
374 overlay->last_flip_req = 0;
375 return ret;
376}
377
378static void intel_overlay_off_tail(struct intel_overlay *overlay)
379{
380 struct drm_gem_object *obj;
381
382 /* never have the overlay hw on without showing a frame */
383 BUG_ON(!overlay->vid_bo);
384 obj = &overlay->vid_bo->base;
385
386 i915_gem_object_unpin(obj);
387 drm_gem_object_unreference(obj);
388 overlay->vid_bo = NULL;
389
390 overlay->crtc->overlay = NULL;
391 overlay->crtc = NULL;
392 overlay->active = 0;
393} 420}
394 421
395/* recover from an interruption due to a signal 422/* recover from an interruption due to a signal
396 * We have to be careful not to repeat work forever an make forward progess. */ 423 * We have to be careful not to repeat work forever an make forward progess. */
397int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, 424static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay,
398 int interruptible) 425 bool interruptible)
399{ 426{
400 struct drm_device *dev = overlay->dev; 427 struct drm_device *dev = overlay->dev;
401 struct drm_gem_object *obj;
402 drm_i915_private_t *dev_priv = dev->dev_private; 428 drm_i915_private_t *dev_priv = dev->dev_private;
403 u32 flip_addr;
404 int ret; 429 int ret;
405 430
406 if (overlay->hw_wedged == HW_WEDGED) 431 if (overlay->last_flip_req == 0)
407 return -EIO; 432 return 0;
408
409 if (overlay->last_flip_req == 0) {
410 overlay->last_flip_req =
411 i915_add_request(dev, NULL, 0, &dev_priv->render_ring);
412 if (overlay->last_flip_req == 0)
413 return -ENOMEM;
414 }
415 433
416 ret = i915_do_wait_request(dev, overlay->last_flip_req, 434 ret = i915_do_wait_request(dev, overlay->last_flip_req,
417 interruptible, &dev_priv->render_ring); 435 interruptible, &dev_priv->render_ring);
418 if (ret != 0) 436 if (ret)
419 return ret; 437 return ret;
420 438
421 switch (overlay->hw_wedged) { 439 if (overlay->flip_tail)
422 case RELEASE_OLD_VID: 440 overlay->flip_tail(overlay);
423 obj = &overlay->old_vid_bo->base;
424 i915_gem_object_unpin(obj);
425 drm_gem_object_unreference(obj);
426 overlay->old_vid_bo = NULL;
427 break;
428 case SWITCH_OFF_STAGE_1:
429 flip_addr = overlay->flip_addr;
430 flip_addr |= OFC_UPDATE;
431
432 overlay->hw_wedged = SWITCH_OFF_STAGE_2;
433
434 BEGIN_LP_RING(4);
435 OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_OFF);
436 OUT_RING(flip_addr);
437 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
438 OUT_RING(MI_NOOP);
439 ADVANCE_LP_RING();
440
441 overlay->last_flip_req = i915_add_request(dev, NULL,
442 0, &dev_priv->render_ring);
443 if (overlay->last_flip_req == 0)
444 return -ENOMEM;
445
446 ret = i915_do_wait_request(dev, overlay->last_flip_req,
447 interruptible, &dev_priv->render_ring);
448 if (ret != 0)
449 return ret;
450
451 case SWITCH_OFF_STAGE_2:
452 intel_overlay_off_tail(overlay);
453 break;
454 default:
455 BUG_ON(overlay->hw_wedged != NEEDS_WAIT_FOR_FLIP);
456 }
457 441
458 overlay->hw_wedged = 0;
459 overlay->last_flip_req = 0; 442 overlay->last_flip_req = 0;
460 return 0; 443 return 0;
461} 444}
462 445
463/* Wait for pending overlay flip and release old frame. 446/* Wait for pending overlay flip and release old frame.
464 * Needs to be called before the overlay register are changed 447 * Needs to be called before the overlay register are changed
465 * via intel_overlay_(un)map_regs_atomic */ 448 * via intel_overlay_(un)map_regs
449 */
466static int intel_overlay_release_old_vid(struct intel_overlay *overlay) 450static int intel_overlay_release_old_vid(struct intel_overlay *overlay)
467{ 451{
452 struct drm_device *dev = overlay->dev;
453 drm_i915_private_t *dev_priv = dev->dev_private;
468 int ret; 454 int ret;
469 struct drm_gem_object *obj;
470 455
471 /* only wait if there is actually an old frame to release to 456 /* Only wait if there is actually an old frame to release to
472 * guarantee forward progress */ 457 * guarantee forward progress.
458 */
473 if (!overlay->old_vid_bo) 459 if (!overlay->old_vid_bo)
474 return 0; 460 return 0;
475 461
476 ret = intel_overlay_wait_flip(overlay); 462 if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
477 if (ret != 0) 463 struct drm_i915_gem_request *request;
478 return ret;
479 464
480 obj = &overlay->old_vid_bo->base; 465 /* synchronous slowpath */
481 i915_gem_object_unpin(obj); 466 request = kzalloc(sizeof(*request), GFP_KERNEL);
482 drm_gem_object_unreference(obj); 467 if (request == NULL)
483 overlay->old_vid_bo = NULL; 468 return -ENOMEM;
484 469
470 BEGIN_LP_RING(2);
471 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
472 OUT_RING(MI_NOOP);
473 ADVANCE_LP_RING();
474
475 ret = intel_overlay_do_wait_request(overlay, request, true,
476 intel_overlay_release_old_vid_tail);
477 if (ret)
478 return ret;
479 }
480
481 intel_overlay_release_old_vid_tail(overlay);
485 return 0; 482 return 0;
486} 483}
487 484
@@ -505,65 +502,65 @@ struct put_image_params {
505static int packed_depth_bytes(u32 format) 502static int packed_depth_bytes(u32 format)
506{ 503{
507 switch (format & I915_OVERLAY_DEPTH_MASK) { 504 switch (format & I915_OVERLAY_DEPTH_MASK) {
508 case I915_OVERLAY_YUV422: 505 case I915_OVERLAY_YUV422:
509 return 4; 506 return 4;
510 case I915_OVERLAY_YUV411: 507 case I915_OVERLAY_YUV411:
511 /* return 6; not implemented */ 508 /* return 6; not implemented */
512 default: 509 default:
513 return -EINVAL; 510 return -EINVAL;
514 } 511 }
515} 512}
516 513
517static int packed_width_bytes(u32 format, short width) 514static int packed_width_bytes(u32 format, short width)
518{ 515{
519 switch (format & I915_OVERLAY_DEPTH_MASK) { 516 switch (format & I915_OVERLAY_DEPTH_MASK) {
520 case I915_OVERLAY_YUV422: 517 case I915_OVERLAY_YUV422:
521 return width << 1; 518 return width << 1;
522 default: 519 default:
523 return -EINVAL; 520 return -EINVAL;
524 } 521 }
525} 522}
526 523
527static int uv_hsubsampling(u32 format) 524static int uv_hsubsampling(u32 format)
528{ 525{
529 switch (format & I915_OVERLAY_DEPTH_MASK) { 526 switch (format & I915_OVERLAY_DEPTH_MASK) {
530 case I915_OVERLAY_YUV422: 527 case I915_OVERLAY_YUV422:
531 case I915_OVERLAY_YUV420: 528 case I915_OVERLAY_YUV420:
532 return 2; 529 return 2;
533 case I915_OVERLAY_YUV411: 530 case I915_OVERLAY_YUV411:
534 case I915_OVERLAY_YUV410: 531 case I915_OVERLAY_YUV410:
535 return 4; 532 return 4;
536 default: 533 default:
537 return -EINVAL; 534 return -EINVAL;
538 } 535 }
539} 536}
540 537
541static int uv_vsubsampling(u32 format) 538static int uv_vsubsampling(u32 format)
542{ 539{
543 switch (format & I915_OVERLAY_DEPTH_MASK) { 540 switch (format & I915_OVERLAY_DEPTH_MASK) {
544 case I915_OVERLAY_YUV420: 541 case I915_OVERLAY_YUV420:
545 case I915_OVERLAY_YUV410: 542 case I915_OVERLAY_YUV410:
546 return 2; 543 return 2;
547 case I915_OVERLAY_YUV422: 544 case I915_OVERLAY_YUV422:
548 case I915_OVERLAY_YUV411: 545 case I915_OVERLAY_YUV411:
549 return 1; 546 return 1;
550 default: 547 default:
551 return -EINVAL; 548 return -EINVAL;
552 } 549 }
553} 550}
554 551
555static u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width) 552static u32 calc_swidthsw(struct drm_device *dev, u32 offset, u32 width)
556{ 553{
557 u32 mask, shift, ret; 554 u32 mask, shift, ret;
558 if (IS_I9XX(dev)) { 555 if (IS_GEN2(dev)) {
559 mask = 0x3f;
560 shift = 6;
561 } else {
562 mask = 0x1f; 556 mask = 0x1f;
563 shift = 5; 557 shift = 5;
558 } else {
559 mask = 0x3f;
560 shift = 6;
564 } 561 }
565 ret = ((offset + width + mask) >> shift) - (offset >> shift); 562 ret = ((offset + width + mask) >> shift) - (offset >> shift);
566 if (IS_I9XX(dev)) 563 if (!IS_GEN2(dev))
567 ret <<= 1; 564 ret <<= 1;
568 ret -=1; 565 ret -=1;
569 return ret << 2; 566 return ret << 2;
@@ -586,7 +583,9 @@ static const u16 y_static_hcoeffs[N_HORIZ_Y_TAPS * N_PHASES] = {
586 0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060, 583 0x3020, 0xb340, 0x1fb8, 0x34a0, 0xb060,
587 0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040, 584 0x3020, 0xb240, 0x1fe0, 0x32e0, 0xb040,
588 0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020, 585 0x3020, 0xb140, 0x1ff8, 0x3160, 0xb020,
589 0xb000, 0x3000, 0x0800, 0x3000, 0xb000}; 586 0xb000, 0x3000, 0x0800, 0x3000, 0xb000
587};
588
590static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = { 589static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
591 0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60, 590 0x3000, 0x1800, 0x1800, 0xb000, 0x18d0, 0x2e60,
592 0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40, 591 0xb000, 0x1990, 0x2ce0, 0xb020, 0x1a68, 0x2b40,
@@ -596,7 +595,8 @@ static const u16 uv_static_hcoeffs[N_HORIZ_UV_TAPS * N_PHASES] = {
596 0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0, 595 0xb100, 0x1eb8, 0x3620, 0xb100, 0x1f18, 0x34a0,
597 0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240, 596 0xb100, 0x1f68, 0x3360, 0xb0e0, 0x1fa8, 0x3240,
598 0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0, 597 0xb0c0, 0x1fe0, 0x3140, 0xb060, 0x1ff0, 0x30a0,
599 0x3000, 0x0800, 0x3000}; 598 0x3000, 0x0800, 0x3000
599};
600 600
601static void update_polyphase_filter(struct overlay_registers *regs) 601static void update_polyphase_filter(struct overlay_registers *regs)
602{ 602{
@@ -629,29 +629,31 @@ static bool update_scaling_factors(struct intel_overlay *overlay,
629 yscale = 1 << FP_SHIFT; 629 yscale = 1 << FP_SHIFT;
630 630
631 /*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/ 631 /*if (params->format & I915_OVERLAY_YUV_PLANAR) {*/
632 xscale_UV = xscale/uv_hscale; 632 xscale_UV = xscale/uv_hscale;
633 yscale_UV = yscale/uv_vscale; 633 yscale_UV = yscale/uv_vscale;
634 /* make the Y scale to UV scale ratio an exact multiply */ 634 /* make the Y scale to UV scale ratio an exact multiply */
635 xscale = xscale_UV * uv_hscale; 635 xscale = xscale_UV * uv_hscale;
636 yscale = yscale_UV * uv_vscale; 636 yscale = yscale_UV * uv_vscale;
637 /*} else { 637 /*} else {
638 xscale_UV = 0; 638 xscale_UV = 0;
639 yscale_UV = 0; 639 yscale_UV = 0;
640 }*/ 640 }*/
641 641
642 if (xscale != overlay->old_xscale || yscale != overlay->old_yscale) 642 if (xscale != overlay->old_xscale || yscale != overlay->old_yscale)
643 scale_changed = true; 643 scale_changed = true;
644 overlay->old_xscale = xscale; 644 overlay->old_xscale = xscale;
645 overlay->old_yscale = yscale; 645 overlay->old_yscale = yscale;
646 646
647 regs->YRGBSCALE = ((yscale & FRACT_MASK) << 20) 647 regs->YRGBSCALE = (((yscale & FRACT_MASK) << 20) |
648 | ((xscale >> FP_SHIFT) << 16) 648 ((xscale >> FP_SHIFT) << 16) |
649 | ((xscale & FRACT_MASK) << 3); 649 ((xscale & FRACT_MASK) << 3));
650 regs->UVSCALE = ((yscale_UV & FRACT_MASK) << 20) 650
651 | ((xscale_UV >> FP_SHIFT) << 16) 651 regs->UVSCALE = (((yscale_UV & FRACT_MASK) << 20) |
652 | ((xscale_UV & FRACT_MASK) << 3); 652 ((xscale_UV >> FP_SHIFT) << 16) |
653 regs->UVSCALEV = ((yscale >> FP_SHIFT) << 16) 653 ((xscale_UV & FRACT_MASK) << 3));
654 | ((yscale_UV >> FP_SHIFT) << 0); 654
655 regs->UVSCALEV = ((((yscale >> FP_SHIFT) << 16) |
656 ((yscale_UV >> FP_SHIFT) << 0)));
655 657
656 if (scale_changed) 658 if (scale_changed)
657 update_polyphase_filter(regs); 659 update_polyphase_filter(regs);
@@ -663,22 +665,28 @@ static void update_colorkey(struct intel_overlay *overlay,
663 struct overlay_registers *regs) 665 struct overlay_registers *regs)
664{ 666{
665 u32 key = overlay->color_key; 667 u32 key = overlay->color_key;
668
666 switch (overlay->crtc->base.fb->bits_per_pixel) { 669 switch (overlay->crtc->base.fb->bits_per_pixel) {
667 case 8: 670 case 8:
668 regs->DCLRKV = 0; 671 regs->DCLRKV = 0;
669 regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE; 672 regs->DCLRKM = CLK_RGB8I_MASK | DST_KEY_ENABLE;
670 case 16: 673 break;
671 if (overlay->crtc->base.fb->depth == 15) { 674
672 regs->DCLRKV = RGB15_TO_COLORKEY(key); 675 case 16:
673 regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE; 676 if (overlay->crtc->base.fb->depth == 15) {
674 } else { 677 regs->DCLRKV = RGB15_TO_COLORKEY(key);
675 regs->DCLRKV = RGB16_TO_COLORKEY(key); 678 regs->DCLRKM = CLK_RGB15_MASK | DST_KEY_ENABLE;
676 regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE; 679 } else {
677 } 680 regs->DCLRKV = RGB16_TO_COLORKEY(key);
678 case 24: 681 regs->DCLRKM = CLK_RGB16_MASK | DST_KEY_ENABLE;
679 case 32: 682 }
680 regs->DCLRKV = key; 683 break;
681 regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE; 684
685 case 24:
686 case 32:
687 regs->DCLRKV = key;
688 regs->DCLRKM = CLK_RGB24_MASK | DST_KEY_ENABLE;
689 break;
682 } 690 }
683} 691}
684 692
@@ -688,48 +696,48 @@ static u32 overlay_cmd_reg(struct put_image_params *params)
688 696
689 if (params->format & I915_OVERLAY_YUV_PLANAR) { 697 if (params->format & I915_OVERLAY_YUV_PLANAR) {
690 switch (params->format & I915_OVERLAY_DEPTH_MASK) { 698 switch (params->format & I915_OVERLAY_DEPTH_MASK) {
691 case I915_OVERLAY_YUV422: 699 case I915_OVERLAY_YUV422:
692 cmd |= OCMD_YUV_422_PLANAR; 700 cmd |= OCMD_YUV_422_PLANAR;
693 break; 701 break;
694 case I915_OVERLAY_YUV420: 702 case I915_OVERLAY_YUV420:
695 cmd |= OCMD_YUV_420_PLANAR; 703 cmd |= OCMD_YUV_420_PLANAR;
696 break; 704 break;
697 case I915_OVERLAY_YUV411: 705 case I915_OVERLAY_YUV411:
698 case I915_OVERLAY_YUV410: 706 case I915_OVERLAY_YUV410:
699 cmd |= OCMD_YUV_410_PLANAR; 707 cmd |= OCMD_YUV_410_PLANAR;
700 break; 708 break;
701 } 709 }
702 } else { /* YUV packed */ 710 } else { /* YUV packed */
703 switch (params->format & I915_OVERLAY_DEPTH_MASK) { 711 switch (params->format & I915_OVERLAY_DEPTH_MASK) {
704 case I915_OVERLAY_YUV422: 712 case I915_OVERLAY_YUV422:
705 cmd |= OCMD_YUV_422_PACKED; 713 cmd |= OCMD_YUV_422_PACKED;
706 break; 714 break;
707 case I915_OVERLAY_YUV411: 715 case I915_OVERLAY_YUV411:
708 cmd |= OCMD_YUV_411_PACKED; 716 cmd |= OCMD_YUV_411_PACKED;
709 break; 717 break;
710 } 718 }
711 719
712 switch (params->format & I915_OVERLAY_SWAP_MASK) { 720 switch (params->format & I915_OVERLAY_SWAP_MASK) {
713 case I915_OVERLAY_NO_SWAP: 721 case I915_OVERLAY_NO_SWAP:
714 break; 722 break;
715 case I915_OVERLAY_UV_SWAP: 723 case I915_OVERLAY_UV_SWAP:
716 cmd |= OCMD_UV_SWAP; 724 cmd |= OCMD_UV_SWAP;
717 break; 725 break;
718 case I915_OVERLAY_Y_SWAP: 726 case I915_OVERLAY_Y_SWAP:
719 cmd |= OCMD_Y_SWAP; 727 cmd |= OCMD_Y_SWAP;
720 break; 728 break;
721 case I915_OVERLAY_Y_AND_UV_SWAP: 729 case I915_OVERLAY_Y_AND_UV_SWAP:
722 cmd |= OCMD_Y_AND_UV_SWAP; 730 cmd |= OCMD_Y_AND_UV_SWAP;
723 break; 731 break;
724 } 732 }
725 } 733 }
726 734
727 return cmd; 735 return cmd;
728} 736}
729 737
730int intel_overlay_do_put_image(struct intel_overlay *overlay, 738static int intel_overlay_do_put_image(struct intel_overlay *overlay,
731 struct drm_gem_object *new_bo, 739 struct drm_gem_object *new_bo,
732 struct put_image_params *params) 740 struct put_image_params *params)
733{ 741{
734 int ret, tmp_width; 742 int ret, tmp_width;
735 struct overlay_registers *regs; 743 struct overlay_registers *regs;
@@ -754,24 +762,24 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
754 goto out_unpin; 762 goto out_unpin;
755 763
756 if (!overlay->active) { 764 if (!overlay->active) {
757 regs = intel_overlay_map_regs_atomic(overlay); 765 regs = intel_overlay_map_regs(overlay);
758 if (!regs) { 766 if (!regs) {
759 ret = -ENOMEM; 767 ret = -ENOMEM;
760 goto out_unpin; 768 goto out_unpin;
761 } 769 }
762 regs->OCONFIG = OCONF_CC_OUT_8BIT; 770 regs->OCONFIG = OCONF_CC_OUT_8BIT;
763 if (IS_I965GM(overlay->dev)) 771 if (IS_GEN4(overlay->dev))
764 regs->OCONFIG |= OCONF_CSC_MODE_BT709; 772 regs->OCONFIG |= OCONF_CSC_MODE_BT709;
765 regs->OCONFIG |= overlay->crtc->pipe == 0 ? 773 regs->OCONFIG |= overlay->crtc->pipe == 0 ?
766 OCONF_PIPE_A : OCONF_PIPE_B; 774 OCONF_PIPE_A : OCONF_PIPE_B;
767 intel_overlay_unmap_regs_atomic(overlay); 775 intel_overlay_unmap_regs(overlay, regs);
768 776
769 ret = intel_overlay_on(overlay); 777 ret = intel_overlay_on(overlay);
770 if (ret != 0) 778 if (ret != 0)
771 goto out_unpin; 779 goto out_unpin;
772 } 780 }
773 781
774 regs = intel_overlay_map_regs_atomic(overlay); 782 regs = intel_overlay_map_regs(overlay);
775 if (!regs) { 783 if (!regs) {
776 ret = -ENOMEM; 784 ret = -ENOMEM;
777 goto out_unpin; 785 goto out_unpin;
@@ -787,7 +795,7 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
787 795
788 regs->SWIDTH = params->src_w; 796 regs->SWIDTH = params->src_w;
789 regs->SWIDTHSW = calc_swidthsw(overlay->dev, 797 regs->SWIDTHSW = calc_swidthsw(overlay->dev,
790 params->offset_Y, tmp_width); 798 params->offset_Y, tmp_width);
791 regs->SHEIGHT = params->src_h; 799 regs->SHEIGHT = params->src_h;
792 regs->OBUF_0Y = bo_priv->gtt_offset + params-> offset_Y; 800 regs->OBUF_0Y = bo_priv->gtt_offset + params-> offset_Y;
793 regs->OSTRIDE = params->stride_Y; 801 regs->OSTRIDE = params->stride_Y;
@@ -798,9 +806,9 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
798 u32 tmp_U, tmp_V; 806 u32 tmp_U, tmp_V;
799 regs->SWIDTH |= (params->src_w/uv_hscale) << 16; 807 regs->SWIDTH |= (params->src_w/uv_hscale) << 16;
800 tmp_U = calc_swidthsw(overlay->dev, params->offset_U, 808 tmp_U = calc_swidthsw(overlay->dev, params->offset_U,
801 params->src_w/uv_hscale); 809 params->src_w/uv_hscale);
802 tmp_V = calc_swidthsw(overlay->dev, params->offset_V, 810 tmp_V = calc_swidthsw(overlay->dev, params->offset_V,
803 params->src_w/uv_hscale); 811 params->src_w/uv_hscale);
804 regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16; 812 regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16;
805 regs->SHEIGHT |= (params->src_h/uv_vscale) << 16; 813 regs->SHEIGHT |= (params->src_h/uv_vscale) << 16;
806 regs->OBUF_0U = bo_priv->gtt_offset + params->offset_U; 814 regs->OBUF_0U = bo_priv->gtt_offset + params->offset_U;
@@ -814,9 +822,11 @@ int intel_overlay_do_put_image(struct intel_overlay *overlay,
814 822
815 regs->OCMD = overlay_cmd_reg(params); 823 regs->OCMD = overlay_cmd_reg(params);
816 824
817 intel_overlay_unmap_regs_atomic(overlay); 825 intel_overlay_unmap_regs(overlay, regs);
818 826
819 intel_overlay_continue(overlay, scale_changed); 827 ret = intel_overlay_continue(overlay, scale_changed);
828 if (ret)
829 goto out_unpin;
820 830
821 overlay->old_vid_bo = overlay->vid_bo; 831 overlay->old_vid_bo = overlay->vid_bo;
822 overlay->vid_bo = to_intel_bo(new_bo); 832 overlay->vid_bo = to_intel_bo(new_bo);
@@ -828,20 +838,19 @@ out_unpin:
828 return ret; 838 return ret;
829} 839}
830 840
831int intel_overlay_switch_off(struct intel_overlay *overlay) 841int intel_overlay_switch_off(struct intel_overlay *overlay,
842 bool interruptible)
832{ 843{
833 int ret;
834 struct overlay_registers *regs; 844 struct overlay_registers *regs;
835 struct drm_device *dev = overlay->dev; 845 struct drm_device *dev = overlay->dev;
846 int ret;
836 847
837 BUG_ON(!mutex_is_locked(&dev->struct_mutex)); 848 BUG_ON(!mutex_is_locked(&dev->struct_mutex));
838 BUG_ON(!mutex_is_locked(&dev->mode_config.mutex)); 849 BUG_ON(!mutex_is_locked(&dev->mode_config.mutex));
839 850
840 if (overlay->hw_wedged) { 851 ret = intel_overlay_recover_from_interrupt(overlay, interruptible);
841 ret = intel_overlay_recover_from_interrupt(overlay, 1); 852 if (ret != 0)
842 if (ret != 0) 853 return ret;
843 return ret;
844 }
845 854
846 if (!overlay->active) 855 if (!overlay->active)
847 return 0; 856 return 0;
@@ -850,33 +859,29 @@ int intel_overlay_switch_off(struct intel_overlay *overlay)
850 if (ret != 0) 859 if (ret != 0)
851 return ret; 860 return ret;
852 861
853 regs = intel_overlay_map_regs_atomic(overlay); 862 regs = intel_overlay_map_regs(overlay);
854 regs->OCMD = 0; 863 regs->OCMD = 0;
855 intel_overlay_unmap_regs_atomic(overlay); 864 intel_overlay_unmap_regs(overlay, regs);
856 865
857 ret = intel_overlay_off(overlay); 866 ret = intel_overlay_off(overlay, interruptible);
858 if (ret != 0) 867 if (ret != 0)
859 return ret; 868 return ret;
860 869
861 intel_overlay_off_tail(overlay); 870 intel_overlay_off_tail(overlay);
862
863 return 0; 871 return 0;
864} 872}
865 873
866static int check_overlay_possible_on_crtc(struct intel_overlay *overlay, 874static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
867 struct intel_crtc *crtc) 875 struct intel_crtc *crtc)
868{ 876{
869 drm_i915_private_t *dev_priv = overlay->dev->dev_private; 877 drm_i915_private_t *dev_priv = overlay->dev->dev_private;
870 u32 pipeconf;
871 int pipeconf_reg = (crtc->pipe == 0) ? PIPEACONF : PIPEBCONF;
872 878
873 if (!crtc->base.enabled || crtc->dpms_mode != DRM_MODE_DPMS_ON) 879 if (!crtc->active)
874 return -EINVAL; 880 return -EINVAL;
875 881
876 pipeconf = I915_READ(pipeconf_reg);
877
878 /* can't use the overlay with double wide pipe */ 882 /* can't use the overlay with double wide pipe */
879 if (!IS_I965G(overlay->dev) && pipeconf & PIPEACONF_DOUBLE_WIDE) 883 if (INTEL_INFO(overlay->dev)->gen < 4 &&
884 (I915_READ(PIPECONF(crtc->pipe)) & (PIPECONF_DOUBLE_WIDE | PIPECONF_ENABLE)) != PIPECONF_ENABLE)
880 return -EINVAL; 885 return -EINVAL;
881 886
882 return 0; 887 return 0;
@@ -885,20 +890,22 @@ static int check_overlay_possible_on_crtc(struct intel_overlay *overlay,
885static void update_pfit_vscale_ratio(struct intel_overlay *overlay) 890static void update_pfit_vscale_ratio(struct intel_overlay *overlay)
886{ 891{
887 struct drm_device *dev = overlay->dev; 892 struct drm_device *dev = overlay->dev;
888 drm_i915_private_t *dev_priv = dev->dev_private; 893 drm_i915_private_t *dev_priv = dev->dev_private;
889 u32 ratio;
890 u32 pfit_control = I915_READ(PFIT_CONTROL); 894 u32 pfit_control = I915_READ(PFIT_CONTROL);
895 u32 ratio;
891 896
892 /* XXX: This is not the same logic as in the xorg driver, but more in 897 /* XXX: This is not the same logic as in the xorg driver, but more in
893 * line with the intel documentation for the i965 */ 898 * line with the intel documentation for the i965
894 if (!IS_I965G(dev) && (pfit_control & VERT_AUTO_SCALE)) { 899 */
895 ratio = I915_READ(PFIT_AUTO_RATIOS) >> PFIT_VERT_SCALE_SHIFT; 900 if (INTEL_INFO(dev)->gen >= 4) {
896 } else { /* on i965 use the PGM reg to read out the autoscaler values */ 901 /* on i965 use the PGM reg to read out the autoscaler values */
897 ratio = I915_READ(PFIT_PGM_RATIOS); 902 ratio = I915_READ(PFIT_PGM_RATIOS) >> PFIT_VERT_SCALE_SHIFT_965;
898 if (IS_I965G(dev)) 903 } else {
899 ratio >>= PFIT_VERT_SCALE_SHIFT_965; 904 if (pfit_control & VERT_AUTO_SCALE)
905 ratio = I915_READ(PFIT_AUTO_RATIOS);
900 else 906 else
901 ratio >>= PFIT_VERT_SCALE_SHIFT; 907 ratio = I915_READ(PFIT_PGM_RATIOS);
908 ratio >>= PFIT_VERT_SCALE_SHIFT;
902 } 909 }
903 910
904 overlay->pfit_vscale_ratio = ratio; 911 overlay->pfit_vscale_ratio = ratio;
@@ -909,12 +916,10 @@ static int check_overlay_dst(struct intel_overlay *overlay,
909{ 916{
910 struct drm_display_mode *mode = &overlay->crtc->base.mode; 917 struct drm_display_mode *mode = &overlay->crtc->base.mode;
911 918
912 if ((rec->dst_x < mode->crtc_hdisplay) 919 if (rec->dst_x < mode->crtc_hdisplay &&
913 && (rec->dst_x + rec->dst_width 920 rec->dst_x + rec->dst_width <= mode->crtc_hdisplay &&
914 <= mode->crtc_hdisplay) 921 rec->dst_y < mode->crtc_vdisplay &&
915 && (rec->dst_y < mode->crtc_vdisplay) 922 rec->dst_y + rec->dst_height <= mode->crtc_vdisplay)
916 && (rec->dst_y + rec->dst_height
917 <= mode->crtc_vdisplay))
918 return 0; 923 return 0;
919 else 924 else
920 return -EINVAL; 925 return -EINVAL;
@@ -939,53 +944,57 @@ static int check_overlay_src(struct drm_device *dev,
939 struct drm_intel_overlay_put_image *rec, 944 struct drm_intel_overlay_put_image *rec,
940 struct drm_gem_object *new_bo) 945 struct drm_gem_object *new_bo)
941{ 946{
942 u32 stride_mask;
943 int depth;
944 int uv_hscale = uv_hsubsampling(rec->flags); 947 int uv_hscale = uv_hsubsampling(rec->flags);
945 int uv_vscale = uv_vsubsampling(rec->flags); 948 int uv_vscale = uv_vsubsampling(rec->flags);
946 size_t tmp; 949 u32 stride_mask, depth, tmp;
947 950
948 /* check src dimensions */ 951 /* check src dimensions */
949 if (IS_845G(dev) || IS_I830(dev)) { 952 if (IS_845G(dev) || IS_I830(dev)) {
950 if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY 953 if (rec->src_height > IMAGE_MAX_HEIGHT_LEGACY ||
951 || rec->src_width > IMAGE_MAX_WIDTH_LEGACY) 954 rec->src_width > IMAGE_MAX_WIDTH_LEGACY)
952 return -EINVAL; 955 return -EINVAL;
953 } else { 956 } else {
954 if (rec->src_height > IMAGE_MAX_HEIGHT 957 if (rec->src_height > IMAGE_MAX_HEIGHT ||
955 || rec->src_width > IMAGE_MAX_WIDTH) 958 rec->src_width > IMAGE_MAX_WIDTH)
956 return -EINVAL; 959 return -EINVAL;
957 } 960 }
961
958 /* better safe than sorry, use 4 as the maximal subsampling ratio */ 962 /* better safe than sorry, use 4 as the maximal subsampling ratio */
959 if (rec->src_height < N_VERT_Y_TAPS*4 963 if (rec->src_height < N_VERT_Y_TAPS*4 ||
960 || rec->src_width < N_HORIZ_Y_TAPS*4) 964 rec->src_width < N_HORIZ_Y_TAPS*4)
961 return -EINVAL; 965 return -EINVAL;
962 966
963 /* check alignment constraints */ 967 /* check alignment constraints */
964 switch (rec->flags & I915_OVERLAY_TYPE_MASK) { 968 switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
965 case I915_OVERLAY_RGB: 969 case I915_OVERLAY_RGB:
966 /* not implemented */ 970 /* not implemented */
971 return -EINVAL;
972
973 case I915_OVERLAY_YUV_PACKED:
974 if (uv_vscale != 1)
967 return -EINVAL; 975 return -EINVAL;
968 case I915_OVERLAY_YUV_PACKED: 976
969 depth = packed_depth_bytes(rec->flags); 977 depth = packed_depth_bytes(rec->flags);
970 if (uv_vscale != 1) 978 if (depth < 0)
971 return -EINVAL; 979 return depth;
972 if (depth < 0) 980
973 return depth; 981 /* ignore UV planes */
974 /* ignore UV planes */ 982 rec->stride_UV = 0;
975 rec->stride_UV = 0; 983 rec->offset_U = 0;
976 rec->offset_U = 0; 984 rec->offset_V = 0;
977 rec->offset_V = 0; 985 /* check pixel alignment */
978 /* check pixel alignment */ 986 if (rec->offset_Y % depth)
979 if (rec->offset_Y % depth) 987 return -EINVAL;
980 return -EINVAL; 988 break;
981 break; 989
982 case I915_OVERLAY_YUV_PLANAR: 990 case I915_OVERLAY_YUV_PLANAR:
983 if (uv_vscale < 0 || uv_hscale < 0) 991 if (uv_vscale < 0 || uv_hscale < 0)
984 return -EINVAL;
985 /* no offset restrictions for planar formats */
986 break;
987 default:
988 return -EINVAL; 992 return -EINVAL;
993 /* no offset restrictions for planar formats */
994 break;
995
996 default:
997 return -EINVAL;
989 } 998 }
990 999
991 if (rec->src_width % uv_hscale) 1000 if (rec->src_width % uv_hscale)
@@ -999,47 +1008,74 @@ static int check_overlay_src(struct drm_device *dev,
999 1008
1000 if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask) 1009 if (rec->stride_Y & stride_mask || rec->stride_UV & stride_mask)
1001 return -EINVAL; 1010 return -EINVAL;
1002 if (IS_I965G(dev) && rec->stride_Y < 512) 1011 if (IS_GEN4(dev) && rec->stride_Y < 512)
1003 return -EINVAL; 1012 return -EINVAL;
1004 1013
1005 tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ? 1014 tmp = (rec->flags & I915_OVERLAY_TYPE_MASK) == I915_OVERLAY_YUV_PLANAR ?
1006 4 : 8; 1015 4096 : 8192;
1007 if (rec->stride_Y > tmp*1024 || rec->stride_UV > 2*1024) 1016 if (rec->stride_Y > tmp || rec->stride_UV > 2*1024)
1008 return -EINVAL; 1017 return -EINVAL;
1009 1018
1010 /* check buffer dimensions */ 1019 /* check buffer dimensions */
1011 switch (rec->flags & I915_OVERLAY_TYPE_MASK) { 1020 switch (rec->flags & I915_OVERLAY_TYPE_MASK) {
1012 case I915_OVERLAY_RGB: 1021 case I915_OVERLAY_RGB:
1013 case I915_OVERLAY_YUV_PACKED: 1022 case I915_OVERLAY_YUV_PACKED:
1014 /* always 4 Y values per depth pixels */ 1023 /* always 4 Y values per depth pixels */
1015 if (packed_width_bytes(rec->flags, rec->src_width) 1024 if (packed_width_bytes(rec->flags, rec->src_width) > rec->stride_Y)
1016 > rec->stride_Y) 1025 return -EINVAL;
1017 return -EINVAL; 1026
1018 1027 tmp = rec->stride_Y*rec->src_height;
1019 tmp = rec->stride_Y*rec->src_height; 1028 if (rec->offset_Y + tmp > new_bo->size)
1020 if (rec->offset_Y + tmp > new_bo->size) 1029 return -EINVAL;
1021 return -EINVAL; 1030 break;
1022 break; 1031
1023 case I915_OVERLAY_YUV_PLANAR: 1032 case I915_OVERLAY_YUV_PLANAR:
1024 if (rec->src_width > rec->stride_Y) 1033 if (rec->src_width > rec->stride_Y)
1025 return -EINVAL; 1034 return -EINVAL;
1026 if (rec->src_width/uv_hscale > rec->stride_UV) 1035 if (rec->src_width/uv_hscale > rec->stride_UV)
1027 return -EINVAL; 1036 return -EINVAL;
1028 1037
1029 tmp = rec->stride_Y*rec->src_height; 1038 tmp = rec->stride_Y * rec->src_height;
1030 if (rec->offset_Y + tmp > new_bo->size) 1039 if (rec->offset_Y + tmp > new_bo->size)
1031 return -EINVAL; 1040 return -EINVAL;
1032 tmp = rec->stride_UV*rec->src_height; 1041
1033 tmp /= uv_vscale; 1042 tmp = rec->stride_UV * (rec->src_height / uv_vscale);
1034 if (rec->offset_U + tmp > new_bo->size 1043 if (rec->offset_U + tmp > new_bo->size ||
1035 || rec->offset_V + tmp > new_bo->size) 1044 rec->offset_V + tmp > new_bo->size)
1036 return -EINVAL; 1045 return -EINVAL;
1037 break; 1046 break;
1038 } 1047 }
1039 1048
1040 return 0; 1049 return 0;
1041} 1050}
1042 1051
1052/**
1053 * Return the pipe currently connected to the panel fitter,
1054 * or -1 if the panel fitter is not present or not in use
1055 */
1056static int intel_panel_fitter_pipe(struct drm_device *dev)
1057{
1058 struct drm_i915_private *dev_priv = dev->dev_private;
1059 u32 pfit_control;
1060
1061 /* i830 doesn't have a panel fitter */
1062 if (IS_I830(dev))
1063 return -1;
1064
1065 pfit_control = I915_READ(PFIT_CONTROL);
1066
1067 /* See if the panel fitter is in use */
1068 if ((pfit_control & PFIT_ENABLE) == 0)
1069 return -1;
1070
1071 /* 965 can place panel fitter on either pipe */
1072 if (IS_GEN4(dev))
1073 return (pfit_control >> 29) & 0x3;
1074
1075 /* older chips can only use pipe 1 */
1076 return 1;
1077}
1078
1043int intel_overlay_put_image(struct drm_device *dev, void *data, 1079int intel_overlay_put_image(struct drm_device *dev, void *data,
1044 struct drm_file *file_priv) 1080 struct drm_file *file_priv)
1045{ 1081{
@@ -1067,7 +1103,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
1067 mutex_lock(&dev->mode_config.mutex); 1103 mutex_lock(&dev->mode_config.mutex);
1068 mutex_lock(&dev->struct_mutex); 1104 mutex_lock(&dev->struct_mutex);
1069 1105
1070 ret = intel_overlay_switch_off(overlay); 1106 ret = intel_overlay_switch_off(overlay, true);
1071 1107
1072 mutex_unlock(&dev->struct_mutex); 1108 mutex_unlock(&dev->struct_mutex);
1073 mutex_unlock(&dev->mode_config.mutex); 1109 mutex_unlock(&dev->mode_config.mutex);
@@ -1080,7 +1116,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
1080 return -ENOMEM; 1116 return -ENOMEM;
1081 1117
1082 drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id, 1118 drmmode_obj = drm_mode_object_find(dev, put_image_rec->crtc_id,
1083 DRM_MODE_OBJECT_CRTC); 1119 DRM_MODE_OBJECT_CRTC);
1084 if (!drmmode_obj) { 1120 if (!drmmode_obj) {
1085 ret = -ENOENT; 1121 ret = -ENOENT;
1086 goto out_free; 1122 goto out_free;
@@ -1088,7 +1124,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
1088 crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); 1124 crtc = to_intel_crtc(obj_to_crtc(drmmode_obj));
1089 1125
1090 new_bo = drm_gem_object_lookup(dev, file_priv, 1126 new_bo = drm_gem_object_lookup(dev, file_priv,
1091 put_image_rec->bo_handle); 1127 put_image_rec->bo_handle);
1092 if (!new_bo) { 1128 if (!new_bo) {
1093 ret = -ENOENT; 1129 ret = -ENOENT;
1094 goto out_free; 1130 goto out_free;
@@ -1097,15 +1133,13 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
1097 mutex_lock(&dev->mode_config.mutex); 1133 mutex_lock(&dev->mode_config.mutex);
1098 mutex_lock(&dev->struct_mutex); 1134 mutex_lock(&dev->struct_mutex);
1099 1135
1100 if (overlay->hw_wedged) { 1136 ret = intel_overlay_recover_from_interrupt(overlay, true);
1101 ret = intel_overlay_recover_from_interrupt(overlay, 1); 1137 if (ret != 0)
1102 if (ret != 0) 1138 goto out_unlock;
1103 goto out_unlock;
1104 }
1105 1139
1106 if (overlay->crtc != crtc) { 1140 if (overlay->crtc != crtc) {
1107 struct drm_display_mode *mode = &crtc->base.mode; 1141 struct drm_display_mode *mode = &crtc->base.mode;
1108 ret = intel_overlay_switch_off(overlay); 1142 ret = intel_overlay_switch_off(overlay, true);
1109 if (ret != 0) 1143 if (ret != 0)
1110 goto out_unlock; 1144 goto out_unlock;
1111 1145
@@ -1116,9 +1150,9 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
1116 overlay->crtc = crtc; 1150 overlay->crtc = crtc;
1117 crtc->overlay = overlay; 1151 crtc->overlay = overlay;
1118 1152
1119 if (intel_panel_fitter_pipe(dev) == crtc->pipe 1153 /* line too wide, i.e. one-line-mode */
1120 /* and line to wide, i.e. one-line-mode */ 1154 if (mode->hdisplay > 1024 &&
1121 && mode->hdisplay > 1024) { 1155 intel_panel_fitter_pipe(dev) == crtc->pipe) {
1122 overlay->pfit_active = 1; 1156 overlay->pfit_active = 1;
1123 update_pfit_vscale_ratio(overlay); 1157 update_pfit_vscale_ratio(overlay);
1124 } else 1158 } else
@@ -1131,10 +1165,10 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
1131 1165
1132 if (overlay->pfit_active) { 1166 if (overlay->pfit_active) {
1133 params->dst_y = ((((u32)put_image_rec->dst_y) << 12) / 1167 params->dst_y = ((((u32)put_image_rec->dst_y) << 12) /
1134 overlay->pfit_vscale_ratio); 1168 overlay->pfit_vscale_ratio);
1135 /* shifting right rounds downwards, so add 1 */ 1169 /* shifting right rounds downwards, so add 1 */
1136 params->dst_h = ((((u32)put_image_rec->dst_height) << 12) / 1170 params->dst_h = ((((u32)put_image_rec->dst_height) << 12) /
1137 overlay->pfit_vscale_ratio) + 1; 1171 overlay->pfit_vscale_ratio) + 1;
1138 } else { 1172 } else {
1139 params->dst_y = put_image_rec->dst_y; 1173 params->dst_y = put_image_rec->dst_y;
1140 params->dst_h = put_image_rec->dst_height; 1174 params->dst_h = put_image_rec->dst_height;
@@ -1146,8 +1180,8 @@ int intel_overlay_put_image(struct drm_device *dev, void *data,
1146 params->src_h = put_image_rec->src_height; 1180 params->src_h = put_image_rec->src_height;
1147 params->src_scan_w = put_image_rec->src_scan_width; 1181 params->src_scan_w = put_image_rec->src_scan_width;
1148 params->src_scan_h = put_image_rec->src_scan_height; 1182 params->src_scan_h = put_image_rec->src_scan_height;
1149 if (params->src_scan_h > params->src_h 1183 if (params->src_scan_h > params->src_h ||
1150 || params->src_scan_w > params->src_w) { 1184 params->src_scan_w > params->src_w) {
1151 ret = -EINVAL; 1185 ret = -EINVAL;
1152 goto out_unlock; 1186 goto out_unlock;
1153 } 1187 }
@@ -1203,7 +1237,7 @@ static bool check_gamma_bounds(u32 gamma1, u32 gamma2)
1203 return false; 1237 return false;
1204 1238
1205 for (i = 0; i < 3; i++) { 1239 for (i = 0; i < 3; i++) {
1206 if (((gamma1 >> i * 8) & 0xff) >= ((gamma2 >> i*8) & 0xff)) 1240 if (((gamma1 >> i*8) & 0xff) >= ((gamma2 >> i*8) & 0xff))
1207 return false; 1241 return false;
1208 } 1242 }
1209 1243
@@ -1224,16 +1258,18 @@ static bool check_gamma5_errata(u32 gamma5)
1224 1258
1225static int check_gamma(struct drm_intel_overlay_attrs *attrs) 1259static int check_gamma(struct drm_intel_overlay_attrs *attrs)
1226{ 1260{
1227 if (!check_gamma_bounds(0, attrs->gamma0) 1261 if (!check_gamma_bounds(0, attrs->gamma0) ||
1228 || !check_gamma_bounds(attrs->gamma0, attrs->gamma1) 1262 !check_gamma_bounds(attrs->gamma0, attrs->gamma1) ||
1229 || !check_gamma_bounds(attrs->gamma1, attrs->gamma2) 1263 !check_gamma_bounds(attrs->gamma1, attrs->gamma2) ||
1230 || !check_gamma_bounds(attrs->gamma2, attrs->gamma3) 1264 !check_gamma_bounds(attrs->gamma2, attrs->gamma3) ||
1231 || !check_gamma_bounds(attrs->gamma3, attrs->gamma4) 1265 !check_gamma_bounds(attrs->gamma3, attrs->gamma4) ||
1232 || !check_gamma_bounds(attrs->gamma4, attrs->gamma5) 1266 !check_gamma_bounds(attrs->gamma4, attrs->gamma5) ||
1233 || !check_gamma_bounds(attrs->gamma5, 0x00ffffff)) 1267 !check_gamma_bounds(attrs->gamma5, 0x00ffffff))
1234 return -EINVAL; 1268 return -EINVAL;
1269
1235 if (!check_gamma5_errata(attrs->gamma5)) 1270 if (!check_gamma5_errata(attrs->gamma5))
1236 return -EINVAL; 1271 return -EINVAL;
1272
1237 return 0; 1273 return 0;
1238} 1274}
1239 1275
@@ -1260,13 +1296,14 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
1260 mutex_lock(&dev->mode_config.mutex); 1296 mutex_lock(&dev->mode_config.mutex);
1261 mutex_lock(&dev->struct_mutex); 1297 mutex_lock(&dev->struct_mutex);
1262 1298
1299 ret = -EINVAL;
1263 if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) { 1300 if (!(attrs->flags & I915_OVERLAY_UPDATE_ATTRS)) {
1264 attrs->color_key = overlay->color_key; 1301 attrs->color_key = overlay->color_key;
1265 attrs->brightness = overlay->brightness; 1302 attrs->brightness = overlay->brightness;
1266 attrs->contrast = overlay->contrast; 1303 attrs->contrast = overlay->contrast;
1267 attrs->saturation = overlay->saturation; 1304 attrs->saturation = overlay->saturation;
1268 1305
1269 if (IS_I9XX(dev)) { 1306 if (!IS_GEN2(dev)) {
1270 attrs->gamma0 = I915_READ(OGAMC0); 1307 attrs->gamma0 = I915_READ(OGAMC0);
1271 attrs->gamma1 = I915_READ(OGAMC1); 1308 attrs->gamma1 = I915_READ(OGAMC1);
1272 attrs->gamma2 = I915_READ(OGAMC2); 1309 attrs->gamma2 = I915_READ(OGAMC2);
@@ -1274,29 +1311,20 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
1274 attrs->gamma4 = I915_READ(OGAMC4); 1311 attrs->gamma4 = I915_READ(OGAMC4);
1275 attrs->gamma5 = I915_READ(OGAMC5); 1312 attrs->gamma5 = I915_READ(OGAMC5);
1276 } 1313 }
1277 ret = 0;
1278 } else { 1314 } else {
1279 overlay->color_key = attrs->color_key; 1315 if (attrs->brightness < -128 || attrs->brightness > 127)
1280 if (attrs->brightness >= -128 && attrs->brightness <= 127) {
1281 overlay->brightness = attrs->brightness;
1282 } else {
1283 ret = -EINVAL;
1284 goto out_unlock; 1316 goto out_unlock;
1285 } 1317 if (attrs->contrast > 255)
1286 if (attrs->contrast <= 255) {
1287 overlay->contrast = attrs->contrast;
1288 } else {
1289 ret = -EINVAL;
1290 goto out_unlock; 1318 goto out_unlock;
1291 } 1319 if (attrs->saturation > 1023)
1292 if (attrs->saturation <= 1023) {
1293 overlay->saturation = attrs->saturation;
1294 } else {
1295 ret = -EINVAL;
1296 goto out_unlock; 1320 goto out_unlock;
1297 }
1298 1321
1299 regs = intel_overlay_map_regs_atomic(overlay); 1322 overlay->color_key = attrs->color_key;
1323 overlay->brightness = attrs->brightness;
1324 overlay->contrast = attrs->contrast;
1325 overlay->saturation = attrs->saturation;
1326
1327 regs = intel_overlay_map_regs(overlay);
1300 if (!regs) { 1328 if (!regs) {
1301 ret = -ENOMEM; 1329 ret = -ENOMEM;
1302 goto out_unlock; 1330 goto out_unlock;
@@ -1304,13 +1332,11 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
1304 1332
1305 update_reg_attrs(overlay, regs); 1333 update_reg_attrs(overlay, regs);
1306 1334
1307 intel_overlay_unmap_regs_atomic(overlay); 1335 intel_overlay_unmap_regs(overlay, regs);
1308 1336
1309 if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) { 1337 if (attrs->flags & I915_OVERLAY_UPDATE_GAMMA) {
1310 if (!IS_I9XX(dev)) { 1338 if (IS_GEN2(dev))
1311 ret = -EINVAL;
1312 goto out_unlock; 1339 goto out_unlock;
1313 }
1314 1340
1315 if (overlay->active) { 1341 if (overlay->active) {
1316 ret = -EBUSY; 1342 ret = -EBUSY;
@@ -1318,7 +1344,7 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
1318 } 1344 }
1319 1345
1320 ret = check_gamma(attrs); 1346 ret = check_gamma(attrs);
1321 if (ret != 0) 1347 if (ret)
1322 goto out_unlock; 1348 goto out_unlock;
1323 1349
1324 I915_WRITE(OGAMC0, attrs->gamma0); 1350 I915_WRITE(OGAMC0, attrs->gamma0);
@@ -1328,9 +1354,9 @@ int intel_overlay_attrs(struct drm_device *dev, void *data,
1328 I915_WRITE(OGAMC4, attrs->gamma4); 1354 I915_WRITE(OGAMC4, attrs->gamma4);
1329 I915_WRITE(OGAMC5, attrs->gamma5); 1355 I915_WRITE(OGAMC5, attrs->gamma5);
1330 } 1356 }
1331 ret = 0;
1332 } 1357 }
1333 1358
1359 ret = 0;
1334out_unlock: 1360out_unlock:
1335 mutex_unlock(&dev->struct_mutex); 1361 mutex_unlock(&dev->struct_mutex);
1336 mutex_unlock(&dev->mode_config.mutex); 1362 mutex_unlock(&dev->mode_config.mutex);
@@ -1346,7 +1372,7 @@ void intel_setup_overlay(struct drm_device *dev)
1346 struct overlay_registers *regs; 1372 struct overlay_registers *regs;
1347 int ret; 1373 int ret;
1348 1374
1349 if (!OVERLAY_EXISTS(dev)) 1375 if (!HAS_OVERLAY(dev))
1350 return; 1376 return;
1351 1377
1352 overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL); 1378 overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
@@ -1359,22 +1385,28 @@ void intel_setup_overlay(struct drm_device *dev)
1359 goto out_free; 1385 goto out_free;
1360 overlay->reg_bo = to_intel_bo(reg_bo); 1386 overlay->reg_bo = to_intel_bo(reg_bo);
1361 1387
1362 if (OVERLAY_NONPHYSICAL(dev)) { 1388 if (OVERLAY_NEEDS_PHYSICAL(dev)) {
1363 ret = i915_gem_object_pin(reg_bo, PAGE_SIZE);
1364 if (ret) {
1365 DRM_ERROR("failed to pin overlay register bo\n");
1366 goto out_free_bo;
1367 }
1368 overlay->flip_addr = overlay->reg_bo->gtt_offset;
1369 } else {
1370 ret = i915_gem_attach_phys_object(dev, reg_bo, 1389 ret = i915_gem_attach_phys_object(dev, reg_bo,
1371 I915_GEM_PHYS_OVERLAY_REGS, 1390 I915_GEM_PHYS_OVERLAY_REGS,
1372 0); 1391 PAGE_SIZE);
1373 if (ret) { 1392 if (ret) {
1374 DRM_ERROR("failed to attach phys overlay regs\n"); 1393 DRM_ERROR("failed to attach phys overlay regs\n");
1375 goto out_free_bo; 1394 goto out_free_bo;
1376 } 1395 }
1377 overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr; 1396 overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr;
1397 } else {
1398 ret = i915_gem_object_pin(reg_bo, PAGE_SIZE);
1399 if (ret) {
1400 DRM_ERROR("failed to pin overlay register bo\n");
1401 goto out_free_bo;
1402 }
1403 overlay->flip_addr = overlay->reg_bo->gtt_offset;
1404
1405 ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
1406 if (ret) {
1407 DRM_ERROR("failed to move overlay register bo into the GTT\n");
1408 goto out_unpin_bo;
1409 }
1378 } 1410 }
1379 1411
1380 /* init all values */ 1412 /* init all values */
@@ -1383,21 +1415,22 @@ void intel_setup_overlay(struct drm_device *dev)
1383 overlay->contrast = 75; 1415 overlay->contrast = 75;
1384 overlay->saturation = 146; 1416 overlay->saturation = 146;
1385 1417
1386 regs = intel_overlay_map_regs_atomic(overlay); 1418 regs = intel_overlay_map_regs(overlay);
1387 if (!regs) 1419 if (!regs)
1388 goto out_free_bo; 1420 goto out_free_bo;
1389 1421
1390 memset(regs, 0, sizeof(struct overlay_registers)); 1422 memset(regs, 0, sizeof(struct overlay_registers));
1391 update_polyphase_filter(regs); 1423 update_polyphase_filter(regs);
1392
1393 update_reg_attrs(overlay, regs); 1424 update_reg_attrs(overlay, regs);
1394 1425
1395 intel_overlay_unmap_regs_atomic(overlay); 1426 intel_overlay_unmap_regs(overlay, regs);
1396 1427
1397 dev_priv->overlay = overlay; 1428 dev_priv->overlay = overlay;
1398 DRM_INFO("initialized overlay support\n"); 1429 DRM_INFO("initialized overlay support\n");
1399 return; 1430 return;
1400 1431
1432out_unpin_bo:
1433 i915_gem_object_unpin(reg_bo);
1401out_free_bo: 1434out_free_bo:
1402 drm_gem_object_unreference(reg_bo); 1435 drm_gem_object_unreference(reg_bo);
1403out_free: 1436out_free:
@@ -1407,18 +1440,23 @@ out_free:
1407 1440
1408void intel_cleanup_overlay(struct drm_device *dev) 1441void intel_cleanup_overlay(struct drm_device *dev)
1409{ 1442{
1410 drm_i915_private_t *dev_priv = dev->dev_private; 1443 drm_i915_private_t *dev_priv = dev->dev_private;
1411 1444
1412 if (dev_priv->overlay) { 1445 if (!dev_priv->overlay)
1413 /* The bo's should be free'd by the generic code already. 1446 return;
1414 * Furthermore modesetting teardown happens beforehand so the
1415 * hardware should be off already */
1416 BUG_ON(dev_priv->overlay->active);
1417 1447
1418 kfree(dev_priv->overlay); 1448 /* The bo's should be free'd by the generic code already.
1419 } 1449 * Furthermore modesetting teardown happens beforehand so the
1450 * hardware should be off already */
1451 BUG_ON(dev_priv->overlay->active);
1452
1453 drm_gem_object_unreference_unlocked(&dev_priv->overlay->reg_bo->base);
1454 kfree(dev_priv->overlay);
1420} 1455}
1421 1456
1457#ifdef CONFIG_DEBUG_FS
1458#include <linux/seq_file.h>
1459
1422struct intel_overlay_error_state { 1460struct intel_overlay_error_state {
1423 struct overlay_registers regs; 1461 struct overlay_registers regs;
1424 unsigned long base; 1462 unsigned long base;
@@ -1426,6 +1464,29 @@ struct intel_overlay_error_state {
1426 u32 isr; 1464 u32 isr;
1427}; 1465};
1428 1466
1467static struct overlay_registers *
1468intel_overlay_map_regs_atomic(struct intel_overlay *overlay)
1469{
1470 drm_i915_private_t *dev_priv = overlay->dev->dev_private;
1471 struct overlay_registers *regs;
1472
1473 if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1474 regs = overlay->reg_bo->phys_obj->handle->vaddr;
1475 else
1476 regs = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping,
1477 overlay->reg_bo->gtt_offset);
1478
1479 return regs;
1480}
1481
1482static void intel_overlay_unmap_regs_atomic(struct intel_overlay *overlay,
1483 struct overlay_registers *regs)
1484{
1485 if (!OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1486 io_mapping_unmap_atomic(regs);
1487}
1488
1489
1429struct intel_overlay_error_state * 1490struct intel_overlay_error_state *
1430intel_overlay_capture_error_state(struct drm_device *dev) 1491intel_overlay_capture_error_state(struct drm_device *dev)
1431{ 1492{
@@ -1443,17 +1504,17 @@ intel_overlay_capture_error_state(struct drm_device *dev)
1443 1504
1444 error->dovsta = I915_READ(DOVSTA); 1505 error->dovsta = I915_READ(DOVSTA);
1445 error->isr = I915_READ(ISR); 1506 error->isr = I915_READ(ISR);
1446 if (OVERLAY_NONPHYSICAL(overlay->dev)) 1507 if (OVERLAY_NEEDS_PHYSICAL(overlay->dev))
1447 error->base = (long) overlay->reg_bo->gtt_offset;
1448 else
1449 error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr; 1508 error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr;
1509 else
1510 error->base = (long) overlay->reg_bo->gtt_offset;
1450 1511
1451 regs = intel_overlay_map_regs_atomic(overlay); 1512 regs = intel_overlay_map_regs_atomic(overlay);
1452 if (!regs) 1513 if (!regs)
1453 goto err; 1514 goto err;
1454 1515
1455 memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers)); 1516 memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers));
1456 intel_overlay_unmap_regs_atomic(overlay); 1517 intel_overlay_unmap_regs_atomic(overlay, regs);
1457 1518
1458 return error; 1519 return error;
1459 1520
@@ -1514,3 +1575,4 @@ intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_s
1514 P(UVSCALEV); 1575 P(UVSCALEV);
1515#undef P 1576#undef P
1516} 1577}
1578#endif