aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_crtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
-rw-r--r--drivers/gpu/drm/drm_crtc.c54
1 files changed, 39 insertions, 15 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 03583887cfec..98a36e6c69ad 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -402,6 +402,7 @@ int drm_mode_getcrtc(struct drm_device *dev,
402{ 402{
403 struct drm_mode_crtc *crtc_resp = data; 403 struct drm_mode_crtc *crtc_resp = data;
404 struct drm_crtc *crtc; 404 struct drm_crtc *crtc;
405 struct drm_plane *plane;
405 406
406 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 407 if (!drm_core_check_feature(dev, DRIVER_MODESET))
407 return -EINVAL; 408 return -EINVAL;
@@ -410,34 +411,36 @@ int drm_mode_getcrtc(struct drm_device *dev,
410 if (!crtc) 411 if (!crtc)
411 return -ENOENT; 412 return -ENOENT;
412 413
414 plane = crtc->primary;
415
413 crtc_resp->gamma_size = crtc->gamma_size; 416 crtc_resp->gamma_size = crtc->gamma_size;
414 417
415 drm_modeset_lock(&crtc->primary->mutex, NULL); 418 drm_modeset_lock(&plane->mutex, NULL);
416 if (crtc->primary->state && crtc->primary->state->fb) 419 if (plane->state && plane->state->fb)
417 crtc_resp->fb_id = crtc->primary->state->fb->base.id; 420 crtc_resp->fb_id = plane->state->fb->base.id;
418 else if (!crtc->primary->state && crtc->primary->fb) 421 else if (!plane->state && plane->fb)
419 crtc_resp->fb_id = crtc->primary->fb->base.id; 422 crtc_resp->fb_id = plane->fb->base.id;
420 else 423 else
421 crtc_resp->fb_id = 0; 424 crtc_resp->fb_id = 0;
422 425
423 if (crtc->primary->state) { 426 if (plane->state) {
424 crtc_resp->x = crtc->primary->state->src_x >> 16; 427 crtc_resp->x = plane->state->src_x >> 16;
425 crtc_resp->y = crtc->primary->state->src_y >> 16; 428 crtc_resp->y = plane->state->src_y >> 16;
426 } 429 }
427 drm_modeset_unlock(&crtc->primary->mutex); 430 drm_modeset_unlock(&plane->mutex);
428 431
429 drm_modeset_lock(&crtc->mutex, NULL); 432 drm_modeset_lock(&crtc->mutex, NULL);
430 if (crtc->state) { 433 if (crtc->state) {
431 if (crtc->state->enable) { 434 if (crtc->state->enable) {
432 drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode); 435 drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->state->mode);
433 crtc_resp->mode_valid = 1; 436 crtc_resp->mode_valid = 1;
434
435 } else { 437 } else {
436 crtc_resp->mode_valid = 0; 438 crtc_resp->mode_valid = 0;
437 } 439 }
438 } else { 440 } else {
439 crtc_resp->x = crtc->x; 441 crtc_resp->x = crtc->x;
440 crtc_resp->y = crtc->y; 442 crtc_resp->y = crtc->y;
443
441 if (crtc->enabled) { 444 if (crtc->enabled) {
442 drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode); 445 drm_mode_convert_to_umode(&crtc_resp->mode, &crtc->mode);
443 crtc_resp->mode_valid = 1; 446 crtc_resp->mode_valid = 1;
@@ -446,6 +449,8 @@ int drm_mode_getcrtc(struct drm_device *dev,
446 crtc_resp->mode_valid = 0; 449 crtc_resp->mode_valid = 0;
447 } 450 }
448 } 451 }
452 if (!file_priv->aspect_ratio_allowed)
453 crtc_resp->mode.flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;
449 drm_modeset_unlock(&crtc->mutex); 454 drm_modeset_unlock(&crtc->mutex);
450 455
451 return 0; 456 return 0;
@@ -471,7 +476,7 @@ static int __drm_mode_set_config_internal(struct drm_mode_set *set,
471 476
472 ret = crtc->funcs->set_config(set, ctx); 477 ret = crtc->funcs->set_config(set, ctx);
473 if (ret == 0) { 478 if (ret == 0) {
474 crtc->primary->crtc = crtc; 479 crtc->primary->crtc = fb ? crtc : NULL;
475 crtc->primary->fb = fb; 480 crtc->primary->fb = fb;
476 } 481 }
477 482
@@ -554,6 +559,7 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
554 struct drm_mode_config *config = &dev->mode_config; 559 struct drm_mode_config *config = &dev->mode_config;
555 struct drm_mode_crtc *crtc_req = data; 560 struct drm_mode_crtc *crtc_req = data;
556 struct drm_crtc *crtc; 561 struct drm_crtc *crtc;
562 struct drm_plane *plane;
557 struct drm_connector **connector_set = NULL, *connector; 563 struct drm_connector **connector_set = NULL, *connector;
558 struct drm_framebuffer *fb = NULL; 564 struct drm_framebuffer *fb = NULL;
559 struct drm_display_mode *mode = NULL; 565 struct drm_display_mode *mode = NULL;
@@ -580,22 +586,33 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
580 } 586 }
581 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name); 587 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
582 588
589 plane = crtc->primary;
590
583 mutex_lock(&crtc->dev->mode_config.mutex); 591 mutex_lock(&crtc->dev->mode_config.mutex);
584 drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE); 592 drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
585retry: 593retry:
586 ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx); 594 ret = drm_modeset_lock_all_ctx(crtc->dev, &ctx);
587 if (ret) 595 if (ret)
588 goto out; 596 goto out;
597
589 if (crtc_req->mode_valid) { 598 if (crtc_req->mode_valid) {
590 /* If we have a mode we need a framebuffer. */ 599 /* If we have a mode we need a framebuffer. */
591 /* If we pass -1, set the mode with the currently bound fb */ 600 /* If we pass -1, set the mode with the currently bound fb */
592 if (crtc_req->fb_id == -1) { 601 if (crtc_req->fb_id == -1) {
593 if (!crtc->primary->fb) { 602 struct drm_framebuffer *old_fb;
603
604 if (plane->state)
605 old_fb = plane->state->fb;
606 else
607 old_fb = plane->fb;
608
609 if (!old_fb) {
594 DRM_DEBUG_KMS("CRTC doesn't have current FB\n"); 610 DRM_DEBUG_KMS("CRTC doesn't have current FB\n");
595 ret = -EINVAL; 611 ret = -EINVAL;
596 goto out; 612 goto out;
597 } 613 }
598 fb = crtc->primary->fb; 614
615 fb = old_fb;
599 /* Make refcounting symmetric with the lookup path. */ 616 /* Make refcounting symmetric with the lookup path. */
600 drm_framebuffer_get(fb); 617 drm_framebuffer_get(fb);
601 } else { 618 } else {
@@ -613,6 +630,13 @@ retry:
613 ret = -ENOMEM; 630 ret = -ENOMEM;
614 goto out; 631 goto out;
615 } 632 }
633 if (!file_priv->aspect_ratio_allowed &&
634 (crtc_req->mode.flags & DRM_MODE_FLAG_PIC_AR_MASK) != DRM_MODE_FLAG_PIC_AR_NONE) {
635 DRM_DEBUG_KMS("Unexpected aspect-ratio flag bits\n");
636 ret = -EINVAL;
637 goto out;
638 }
639
616 640
617 ret = drm_mode_convert_umode(dev, mode, &crtc_req->mode); 641 ret = drm_mode_convert_umode(dev, mode, &crtc_req->mode);
618 if (ret) { 642 if (ret) {
@@ -627,8 +651,8 @@ retry:
627 * match real hardware capabilities. Skip the check in that 651 * match real hardware capabilities. Skip the check in that
628 * case. 652 * case.
629 */ 653 */
630 if (!crtc->primary->format_default) { 654 if (!plane->format_default) {
631 ret = drm_plane_check_pixel_format(crtc->primary, 655 ret = drm_plane_check_pixel_format(plane,
632 fb->format->format, 656 fb->format->format,
633 fb->modifier); 657 fb->modifier);
634 if (ret) { 658 if (ret) {