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