aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-06-18 20:25:49 -0400
committerDave Airlie <airlied@redhat.com>2014-06-18 20:25:49 -0400
commit937a0c79870ccd7034640f72560653b269cc11c5 (patch)
tree0aedda35e7ad5c9a92dacb8a6ed8a1a2062428de
parent571366284b50c93ba4ba5f13fad3f2430024c613 (diff)
parent46889d9568b90ae9032a4e84a7b404bb5f96f9a3 (diff)
Merge branch 'drm-fixes-3.16' of git://people.freedesktop.org/~agd5f/linux into drm-next
mode validation, deep color and pageflipping fixes. * 'drm-fixes-3.16' of git://people.freedesktop.org/~agd5f/linux: drm/radeon: Fix radeon_irq_kms_pflip_irq_get/put() imbalance Revert "drm/radeon: remove drm_vblank_get|put from pflip handling" drm/radeon: improve dvi_mode_valid drm/radeon: update mode_valid testing for DP drm/radeon: Use dce5/6 hdmi deep color clock setup also on dce8+
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c35
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c19
3 files changed, 41 insertions, 15 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index 9758f9170fce..a03c73411a56 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -1052,7 +1052,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
1052 int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder); 1052 int encoder_mode = atombios_get_encoder_mode(radeon_crtc->encoder);
1053 1053
1054 /* pass the actual clock to atombios_crtc_program_pll for DCE5,6 for HDMI */ 1054 /* pass the actual clock to atombios_crtc_program_pll for DCE5,6 for HDMI */
1055 if (ASIC_IS_DCE5(rdev) && !ASIC_IS_DCE8(rdev) && 1055 if (ASIC_IS_DCE5(rdev) &&
1056 (encoder_mode == ATOM_ENCODER_MODE_HDMI) && 1056 (encoder_mode == ATOM_ENCODER_MODE_HDMI) &&
1057 (radeon_crtc->bpc > 8)) 1057 (radeon_crtc->bpc > 8))
1058 clock = radeon_crtc->adjusted_clock; 1058 clock = radeon_crtc->adjusted_clock;
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 933c5c39654d..1b9177ed181f 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1288,17 +1288,15 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector,
1288 (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) || 1288 (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D) ||
1289 (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) 1289 (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B))
1290 return MODE_OK; 1290 return MODE_OK;
1291 else if (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_A) { 1291 else if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
1292 if (ASIC_IS_DCE6(rdev)) { 1292 /* HDMI 1.3+ supports max clock of 340 Mhz */
1293 /* HDMI 1.3+ supports max clock of 340 Mhz */ 1293 if (mode->clock > 340000)
1294 if (mode->clock > 340000)
1295 return MODE_CLOCK_HIGH;
1296 else
1297 return MODE_OK;
1298 } else
1299 return MODE_CLOCK_HIGH; 1294 return MODE_CLOCK_HIGH;
1300 } else 1295 else
1296 return MODE_OK;
1297 } else {
1301 return MODE_CLOCK_HIGH; 1298 return MODE_CLOCK_HIGH;
1299 }
1302 } 1300 }
1303 1301
1304 /* check against the max pixel clock */ 1302 /* check against the max pixel clock */
@@ -1549,6 +1547,8 @@ out:
1549static int radeon_dp_mode_valid(struct drm_connector *connector, 1547static int radeon_dp_mode_valid(struct drm_connector *connector,
1550 struct drm_display_mode *mode) 1548 struct drm_display_mode *mode)
1551{ 1549{
1550 struct drm_device *dev = connector->dev;
1551 struct radeon_device *rdev = dev->dev_private;
1552 struct radeon_connector *radeon_connector = to_radeon_connector(connector); 1552 struct radeon_connector *radeon_connector = to_radeon_connector(connector);
1553 struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; 1553 struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
1554 1554
@@ -1579,14 +1579,23 @@ static int radeon_dp_mode_valid(struct drm_connector *connector,
1579 return MODE_PANEL; 1579 return MODE_PANEL;
1580 } 1580 }
1581 } 1581 }
1582 return MODE_OK;
1583 } else { 1582 } else {
1584 if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || 1583 if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
1585 (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) 1584 (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
1586 return radeon_dp_mode_valid_helper(connector, mode); 1585 return radeon_dp_mode_valid_helper(connector, mode);
1587 else 1586 } else {
1588 return MODE_OK; 1587 if (ASIC_IS_DCE6(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) {
1588 /* HDMI 1.3+ supports max clock of 340 Mhz */
1589 if (mode->clock > 340000)
1590 return MODE_CLOCK_HIGH;
1591 } else {
1592 if (mode->clock > 165000)
1593 return MODE_CLOCK_HIGH;
1594 }
1595 }
1589 } 1596 }
1597
1598 return MODE_OK;
1590} 1599}
1591 1600
1592static const struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = { 1601static const struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = {
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 4db26420f38a..8fc362aa6a1a 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -358,8 +358,9 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
358 358
359 spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); 359 spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
360 360
361 drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id);
361 radeon_fence_unref(&work->fence); 362 radeon_fence_unref(&work->fence);
362 radeon_irq_kms_pflip_irq_get(rdev, work->crtc_id); 363 radeon_irq_kms_pflip_irq_put(rdev, work->crtc_id);
363 queue_work(radeon_crtc->flip_queue, &work->unpin_work); 364 queue_work(radeon_crtc->flip_queue, &work->unpin_work);
364} 365}
365 366
@@ -460,6 +461,12 @@ static void radeon_flip_work_func(struct work_struct *__work)
460 base &= ~7; 461 base &= ~7;
461 } 462 }
462 463
464 r = drm_vblank_get(crtc->dev, radeon_crtc->crtc_id);
465 if (r) {
466 DRM_ERROR("failed to get vblank before flip\n");
467 goto pflip_cleanup;
468 }
469
463 /* We borrow the event spin lock for protecting flip_work */ 470 /* We borrow the event spin lock for protecting flip_work */
464 spin_lock_irqsave(&crtc->dev->event_lock, flags); 471 spin_lock_irqsave(&crtc->dev->event_lock, flags);
465 472
@@ -474,6 +481,16 @@ static void radeon_flip_work_func(struct work_struct *__work)
474 481
475 return; 482 return;
476 483
484pflip_cleanup:
485 if (unlikely(radeon_bo_reserve(work->new_rbo, false) != 0)) {
486 DRM_ERROR("failed to reserve new rbo in error path\n");
487 goto cleanup;
488 }
489 if (unlikely(radeon_bo_unpin(work->new_rbo) != 0)) {
490 DRM_ERROR("failed to unpin new rbo in error path\n");
491 }
492 radeon_bo_unreserve(work->new_rbo);
493
477cleanup: 494cleanup:
478 drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); 495 drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
479 radeon_fence_unref(&work->fence); 496 radeon_fence_unref(&work->fence);