diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 68 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 42 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dvo.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_panel.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 63 |
9 files changed, 122 insertions, 74 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d9e337feef14..f2a546ef6870 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -1390,14 +1390,11 @@ out: | |||
| 1390 | if (i915_terminally_wedged(&dev_priv->gpu_error)) | 1390 | if (i915_terminally_wedged(&dev_priv->gpu_error)) |
| 1391 | return VM_FAULT_SIGBUS; | 1391 | return VM_FAULT_SIGBUS; |
| 1392 | case -EAGAIN: | 1392 | case -EAGAIN: |
| 1393 | /* Give the error handler a chance to run and move the | 1393 | /* |
| 1394 | * objects off the GPU active list. Next time we service the | 1394 | * EAGAIN means the gpu is hung and we'll wait for the error |
| 1395 | * fault, we should be able to transition the page into the | 1395 | * handler to reset everything when re-faulting in |
| 1396 | * GTT without touching the GPU (and so avoid further | 1396 | * i915_mutex_lock_interruptible. |
| 1397 | * EIO/EGAIN). If the GPU is wedged, then there is no issue | ||
| 1398 | * with coherency, just lost writes. | ||
| 1399 | */ | 1397 | */ |
| 1400 | set_need_resched(); | ||
| 1401 | case 0: | 1398 | case 0: |
| 1402 | case -ERESTARTSYS: | 1399 | case -ERESTARTSYS: |
| 1403 | case -EINTR: | 1400 | case -EINTR: |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 83cce0cdb769..4b91228fd9bd 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -1469,6 +1469,34 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) | |||
| 1469 | return ret; | 1469 | return ret; |
| 1470 | } | 1470 | } |
| 1471 | 1471 | ||
| 1472 | static void i915_error_wake_up(struct drm_i915_private *dev_priv, | ||
| 1473 | bool reset_completed) | ||
| 1474 | { | ||
| 1475 | struct intel_ring_buffer *ring; | ||
| 1476 | int i; | ||
| 1477 | |||
| 1478 | /* | ||
| 1479 | * Notify all waiters for GPU completion events that reset state has | ||
| 1480 | * been changed, and that they need to restart their wait after | ||
| 1481 | * checking for potential errors (and bail out to drop locks if there is | ||
| 1482 | * a gpu reset pending so that i915_error_work_func can acquire them). | ||
| 1483 | */ | ||
| 1484 | |||
| 1485 | /* Wake up __wait_seqno, potentially holding dev->struct_mutex. */ | ||
| 1486 | for_each_ring(ring, dev_priv, i) | ||
| 1487 | wake_up_all(&ring->irq_queue); | ||
| 1488 | |||
| 1489 | /* Wake up intel_crtc_wait_for_pending_flips, holding crtc->mutex. */ | ||
| 1490 | wake_up_all(&dev_priv->pending_flip_queue); | ||
| 1491 | |||
| 1492 | /* | ||
| 1493 | * Signal tasks blocked in i915_gem_wait_for_error that the pending | ||
| 1494 | * reset state is cleared. | ||
| 1495 | */ | ||
| 1496 | if (reset_completed) | ||
| 1497 | wake_up_all(&dev_priv->gpu_error.reset_queue); | ||
| 1498 | } | ||
| 1499 | |||
| 1472 | /** | 1500 | /** |
| 1473 | * i915_error_work_func - do process context error handling work | 1501 | * i915_error_work_func - do process context error handling work |
| 1474 | * @work: work struct | 1502 | * @work: work struct |
| @@ -1483,11 +1511,10 @@ static void i915_error_work_func(struct work_struct *work) | |||
| 1483 | drm_i915_private_t *dev_priv = container_of(error, drm_i915_private_t, | 1511 | drm_i915_private_t *dev_priv = container_of(error, drm_i915_private_t, |
| 1484 | gpu_error); | 1512 | gpu_error); |
| 1485 | struct drm_device *dev = dev_priv->dev; | 1513 | struct drm_device *dev = dev_priv->dev; |
| 1486 | struct intel_ring_buffer *ring; | ||
| 1487 | char *error_event[] = { I915_ERROR_UEVENT "=1", NULL }; | 1514 | char *error_event[] = { I915_ERROR_UEVENT "=1", NULL }; |
| 1488 | char *reset_event[] = { I915_RESET_UEVENT "=1", NULL }; | 1515 | char *reset_event[] = { I915_RESET_UEVENT "=1", NULL }; |
| 1489 | char *reset_done_event[] = { I915_ERROR_UEVENT "=0", NULL }; | 1516 | char *reset_done_event[] = { I915_ERROR_UEVENT "=0", NULL }; |
| 1490 | int i, ret; | 1517 | int ret; |
| 1491 | 1518 | ||
| 1492 | kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event); | 1519 | kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event); |
| 1493 | 1520 | ||
| @@ -1506,8 +1533,16 @@ static void i915_error_work_func(struct work_struct *work) | |||
| 1506 | kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, | 1533 | kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, |
| 1507 | reset_event); | 1534 | reset_event); |
| 1508 | 1535 | ||
| 1536 | /* | ||
| 1537 | * All state reset _must_ be completed before we update the | ||
| 1538 | * reset counter, for otherwise waiters might miss the reset | ||
| 1539 | * pending state and not properly drop locks, resulting in | ||
| 1540 | * deadlocks with the reset work. | ||
| 1541 | */ | ||
| 1509 | ret = i915_reset(dev); | 1542 | ret = i915_reset(dev); |
| 1510 | 1543 | ||
| 1544 | intel_display_handle_reset(dev); | ||
| 1545 | |||
| 1511 | if (ret == 0) { | 1546 | if (ret == 0) { |
| 1512 | /* | 1547 | /* |
| 1513 | * After all the gem state is reset, increment the reset | 1548 | * After all the gem state is reset, increment the reset |
| @@ -1528,12 +1563,11 @@ static void i915_error_work_func(struct work_struct *work) | |||
| 1528 | atomic_set(&error->reset_counter, I915_WEDGED); | 1563 | atomic_set(&error->reset_counter, I915_WEDGED); |
| 1529 | } | 1564 | } |
| 1530 | 1565 | ||
| 1531 | for_each_ring(ring, dev_priv, i) | 1566 | /* |
| 1532 | wake_up_all(&ring->irq_queue); | 1567 | * Note: The wake_up also serves as a memory barrier so that |
| 1533 | 1568 | * waiters see the update value of the reset counter atomic_t. | |
| 1534 | intel_display_handle_reset(dev); | 1569 | */ |
| 1535 | 1570 | i915_error_wake_up(dev_priv, true); | |
| 1536 | wake_up_all(&dev_priv->gpu_error.reset_queue); | ||
| 1537 | } | 1571 | } |
| 1538 | } | 1572 | } |
| 1539 | 1573 | ||
| @@ -1642,8 +1676,6 @@ static void i915_report_and_clear_eir(struct drm_device *dev) | |||
| 1642 | void i915_handle_error(struct drm_device *dev, bool wedged) | 1676 | void i915_handle_error(struct drm_device *dev, bool wedged) |
| 1643 | { | 1677 | { |
| 1644 | struct drm_i915_private *dev_priv = dev->dev_private; | 1678 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 1645 | struct intel_ring_buffer *ring; | ||
| 1646 | int i; | ||
| 1647 | 1679 | ||
| 1648 | i915_capture_error_state(dev); | 1680 | i915_capture_error_state(dev); |
| 1649 | i915_report_and_clear_eir(dev); | 1681 | i915_report_and_clear_eir(dev); |
| @@ -1653,11 +1685,19 @@ void i915_handle_error(struct drm_device *dev, bool wedged) | |||
| 1653 | &dev_priv->gpu_error.reset_counter); | 1685 | &dev_priv->gpu_error.reset_counter); |
| 1654 | 1686 | ||
| 1655 | /* | 1687 | /* |
| 1656 | * Wakeup waiting processes so that the reset work item | 1688 | * Wakeup waiting processes so that the reset work function |
| 1657 | * doesn't deadlock trying to grab various locks. | 1689 | * i915_error_work_func doesn't deadlock trying to grab various |
| 1690 | * locks. By bumping the reset counter first, the woken | ||
| 1691 | * processes will see a reset in progress and back off, | ||
| 1692 | * releasing their locks and then wait for the reset completion. | ||
| 1693 | * We must do this for _all_ gpu waiters that might hold locks | ||
| 1694 | * that the reset work needs to acquire. | ||
| 1695 | * | ||
| 1696 | * Note: The wake_up serves as the required memory barrier to | ||
| 1697 | * ensure that the waiters see the updated value of the reset | ||
| 1698 | * counter atomic_t. | ||
| 1658 | */ | 1699 | */ |
| 1659 | for_each_ring(ring, dev_priv, i) | 1700 | i915_error_wake_up(dev_priv, false); |
| 1660 | wake_up_all(&ring->irq_queue); | ||
| 1661 | } | 1701 | } |
| 1662 | 1702 | ||
| 1663 | /* | 1703 | /* |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 63aca49d11a8..63de2701b974 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
| @@ -778,7 +778,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) | |||
| 778 | /* Can only use the always-on power well for eDP when | 778 | /* Can only use the always-on power well for eDP when |
| 779 | * not using the panel fitter, and when not using motion | 779 | * not using the panel fitter, and when not using motion |
| 780 | * blur mitigation (which we don't support). */ | 780 | * blur mitigation (which we don't support). */ |
| 781 | if (intel_crtc->config.pch_pfit.size) | 781 | if (intel_crtc->config.pch_pfit.enabled) |
| 782 | temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; | 782 | temp |= TRANS_DDI_EDP_INPUT_A_ONOFF; |
| 783 | else | 783 | else |
| 784 | temp |= TRANS_DDI_EDP_INPUT_A_ON; | 784 | temp |= TRANS_DDI_EDP_INPUT_A_ON; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2489d0b4c7d2..d8a1d98693e7 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -2249,7 +2249,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 2249 | I915_WRITE(PIPESRC(intel_crtc->pipe), | 2249 | I915_WRITE(PIPESRC(intel_crtc->pipe), |
| 2250 | ((crtc->mode.hdisplay - 1) << 16) | | 2250 | ((crtc->mode.hdisplay - 1) << 16) | |
| 2251 | (crtc->mode.vdisplay - 1)); | 2251 | (crtc->mode.vdisplay - 1)); |
| 2252 | if (!intel_crtc->config.pch_pfit.size && | 2252 | if (!intel_crtc->config.pch_pfit.enabled && |
| 2253 | (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || | 2253 | (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) || |
| 2254 | intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { | 2254 | intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) { |
| 2255 | I915_WRITE(PF_CTL(intel_crtc->pipe), 0); | 2255 | I915_WRITE(PF_CTL(intel_crtc->pipe), 0); |
| @@ -3203,7 +3203,7 @@ static void ironlake_pfit_enable(struct intel_crtc *crtc) | |||
| 3203 | struct drm_i915_private *dev_priv = dev->dev_private; | 3203 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 3204 | int pipe = crtc->pipe; | 3204 | int pipe = crtc->pipe; |
| 3205 | 3205 | ||
| 3206 | if (crtc->config.pch_pfit.size) { | 3206 | if (crtc->config.pch_pfit.enabled) { |
| 3207 | /* Force use of hard-coded filter coefficients | 3207 | /* Force use of hard-coded filter coefficients |
| 3208 | * as some pre-programmed values are broken, | 3208 | * as some pre-programmed values are broken, |
| 3209 | * e.g. x201. | 3209 | * e.g. x201. |
| @@ -3428,7 +3428,7 @@ static void ironlake_pfit_disable(struct intel_crtc *crtc) | |||
| 3428 | 3428 | ||
| 3429 | /* To avoid upsetting the power well on haswell only disable the pfit if | 3429 | /* To avoid upsetting the power well on haswell only disable the pfit if |
| 3430 | * it's in use. The hw state code will make sure we get this right. */ | 3430 | * it's in use. The hw state code will make sure we get this right. */ |
| 3431 | if (crtc->config.pch_pfit.size) { | 3431 | if (crtc->config.pch_pfit.enabled) { |
| 3432 | I915_WRITE(PF_CTL(pipe), 0); | 3432 | I915_WRITE(PF_CTL(pipe), 0); |
| 3433 | I915_WRITE(PF_WIN_POS(pipe), 0); | 3433 | I915_WRITE(PF_WIN_POS(pipe), 0); |
| 3434 | I915_WRITE(PF_WIN_SZ(pipe), 0); | 3434 | I915_WRITE(PF_WIN_SZ(pipe), 0); |
| @@ -4877,9 +4877,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
| 4877 | return -EINVAL; | 4877 | return -EINVAL; |
| 4878 | } | 4878 | } |
| 4879 | 4879 | ||
| 4880 | /* Ensure that the cursor is valid for the new mode before changing... */ | ||
| 4881 | intel_crtc_update_cursor(crtc, true); | ||
| 4882 | |||
| 4883 | if (is_lvds && dev_priv->lvds_downclock_avail) { | 4880 | if (is_lvds && dev_priv->lvds_downclock_avail) { |
| 4884 | /* | 4881 | /* |
| 4885 | * Ensure we match the reduced clock's P to the target clock. | 4882 | * Ensure we match the reduced clock's P to the target clock. |
| @@ -5768,9 +5765,6 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
| 5768 | intel_crtc->config.dpll.p2 = clock.p2; | 5765 | intel_crtc->config.dpll.p2 = clock.p2; |
| 5769 | } | 5766 | } |
| 5770 | 5767 | ||
| 5771 | /* Ensure that the cursor is valid for the new mode before changing... */ | ||
| 5772 | intel_crtc_update_cursor(crtc, true); | ||
| 5773 | |||
| 5774 | /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */ | 5768 | /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */ |
| 5775 | if (intel_crtc->config.has_pch_encoder) { | 5769 | if (intel_crtc->config.has_pch_encoder) { |
| 5776 | fp = i9xx_dpll_compute_fp(&intel_crtc->config.dpll); | 5770 | fp = i9xx_dpll_compute_fp(&intel_crtc->config.dpll); |
| @@ -5859,6 +5853,7 @@ static void ironlake_get_pfit_config(struct intel_crtc *crtc, | |||
| 5859 | tmp = I915_READ(PF_CTL(crtc->pipe)); | 5853 | tmp = I915_READ(PF_CTL(crtc->pipe)); |
| 5860 | 5854 | ||
| 5861 | if (tmp & PF_ENABLE) { | 5855 | if (tmp & PF_ENABLE) { |
| 5856 | pipe_config->pch_pfit.enabled = true; | ||
| 5862 | pipe_config->pch_pfit.pos = I915_READ(PF_WIN_POS(crtc->pipe)); | 5857 | pipe_config->pch_pfit.pos = I915_READ(PF_WIN_POS(crtc->pipe)); |
| 5863 | pipe_config->pch_pfit.size = I915_READ(PF_WIN_SZ(crtc->pipe)); | 5858 | pipe_config->pch_pfit.size = I915_READ(PF_WIN_SZ(crtc->pipe)); |
| 5864 | 5859 | ||
| @@ -6236,7 +6231,7 @@ static void haswell_modeset_global_resources(struct drm_device *dev) | |||
| 6236 | if (!crtc->base.enabled) | 6231 | if (!crtc->base.enabled) |
| 6237 | continue; | 6232 | continue; |
| 6238 | 6233 | ||
| 6239 | if (crtc->pipe != PIPE_A || crtc->config.pch_pfit.size || | 6234 | if (crtc->pipe != PIPE_A || crtc->config.pch_pfit.enabled || |
| 6240 | crtc->config.cpu_transcoder != TRANSCODER_EDP) | 6235 | crtc->config.cpu_transcoder != TRANSCODER_EDP) |
| 6241 | enable = true; | 6236 | enable = true; |
| 6242 | } | 6237 | } |
| @@ -6259,9 +6254,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, | |||
| 6259 | if (!intel_ddi_pll_mode_set(crtc)) | 6254 | if (!intel_ddi_pll_mode_set(crtc)) |
| 6260 | return -EINVAL; | 6255 | return -EINVAL; |
| 6261 | 6256 | ||
| 6262 | /* Ensure that the cursor is valid for the new mode before changing... */ | ||
| 6263 | intel_crtc_update_cursor(crtc, true); | ||
| 6264 | |||
| 6265 | if (intel_crtc->config.has_dp_encoder) | 6257 | if (intel_crtc->config.has_dp_encoder) |
| 6266 | intel_dp_set_m_n(intel_crtc); | 6258 | intel_dp_set_m_n(intel_crtc); |
| 6267 | 6259 | ||
| @@ -6494,15 +6486,15 @@ static void haswell_write_eld(struct drm_connector *connector, | |||
| 6494 | 6486 | ||
| 6495 | /* Set ELD valid state */ | 6487 | /* Set ELD valid state */ |
| 6496 | tmp = I915_READ(aud_cntrl_st2); | 6488 | tmp = I915_READ(aud_cntrl_st2); |
| 6497 | DRM_DEBUG_DRIVER("HDMI audio: pin eld vld status=0x%8x\n", tmp); | 6489 | DRM_DEBUG_DRIVER("HDMI audio: pin eld vld status=0x%08x\n", tmp); |
| 6498 | tmp |= (AUDIO_ELD_VALID_A << (pipe * 4)); | 6490 | tmp |= (AUDIO_ELD_VALID_A << (pipe * 4)); |
| 6499 | I915_WRITE(aud_cntrl_st2, tmp); | 6491 | I915_WRITE(aud_cntrl_st2, tmp); |
| 6500 | tmp = I915_READ(aud_cntrl_st2); | 6492 | tmp = I915_READ(aud_cntrl_st2); |
| 6501 | DRM_DEBUG_DRIVER("HDMI audio: eld vld status=0x%8x\n", tmp); | 6493 | DRM_DEBUG_DRIVER("HDMI audio: eld vld status=0x%08x\n", tmp); |
| 6502 | 6494 | ||
| 6503 | /* Enable HDMI mode */ | 6495 | /* Enable HDMI mode */ |
| 6504 | tmp = I915_READ(aud_config); | 6496 | tmp = I915_READ(aud_config); |
| 6505 | DRM_DEBUG_DRIVER("HDMI audio: audio conf: 0x%8x\n", tmp); | 6497 | DRM_DEBUG_DRIVER("HDMI audio: audio conf: 0x%08x\n", tmp); |
| 6506 | /* clear N_programing_enable and N_value_index */ | 6498 | /* clear N_programing_enable and N_value_index */ |
| 6507 | tmp &= ~(AUD_CONFIG_N_VALUE_INDEX | AUD_CONFIG_N_PROG_ENABLE); | 6499 | tmp &= ~(AUD_CONFIG_N_VALUE_INDEX | AUD_CONFIG_N_PROG_ENABLE); |
| 6508 | I915_WRITE(aud_config, tmp); | 6500 | I915_WRITE(aud_config, tmp); |
| @@ -6937,7 +6929,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
| 6937 | intel_crtc->cursor_width = width; | 6929 | intel_crtc->cursor_width = width; |
| 6938 | intel_crtc->cursor_height = height; | 6930 | intel_crtc->cursor_height = height; |
| 6939 | 6931 | ||
| 6940 | intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL); | 6932 | if (intel_crtc->active) |
| 6933 | intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL); | ||
| 6941 | 6934 | ||
| 6942 | return 0; | 6935 | return 0; |
| 6943 | fail_unpin: | 6936 | fail_unpin: |
| @@ -6956,7 +6949,8 @@ static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
| 6956 | intel_crtc->cursor_x = x; | 6949 | intel_crtc->cursor_x = x; |
| 6957 | intel_crtc->cursor_y = y; | 6950 | intel_crtc->cursor_y = y; |
| 6958 | 6951 | ||
| 6959 | intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL); | 6952 | if (intel_crtc->active) |
| 6953 | intel_crtc_update_cursor(crtc, intel_crtc->cursor_bo != NULL); | ||
| 6960 | 6954 | ||
| 6961 | return 0; | 6955 | return 0; |
| 6962 | } | 6956 | } |
| @@ -8205,9 +8199,10 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, | |||
| 8205 | pipe_config->gmch_pfit.control, | 8199 | pipe_config->gmch_pfit.control, |
| 8206 | pipe_config->gmch_pfit.pgm_ratios, | 8200 | pipe_config->gmch_pfit.pgm_ratios, |
| 8207 | pipe_config->gmch_pfit.lvds_border_bits); | 8201 | pipe_config->gmch_pfit.lvds_border_bits); |
| 8208 | DRM_DEBUG_KMS("pch pfit: pos: 0x%08x, size: 0x%08x\n", | 8202 | DRM_DEBUG_KMS("pch pfit: pos: 0x%08x, size: 0x%08x, %s\n", |
| 8209 | pipe_config->pch_pfit.pos, | 8203 | pipe_config->pch_pfit.pos, |
| 8210 | pipe_config->pch_pfit.size); | 8204 | pipe_config->pch_pfit.size, |
| 8205 | pipe_config->pch_pfit.enabled ? "enabled" : "disabled"); | ||
| 8211 | DRM_DEBUG_KMS("ips: %i\n", pipe_config->ips_enabled); | 8206 | DRM_DEBUG_KMS("ips: %i\n", pipe_config->ips_enabled); |
| 8212 | } | 8207 | } |
| 8213 | 8208 | ||
| @@ -8603,8 +8598,11 @@ intel_pipe_config_compare(struct drm_device *dev, | |||
| 8603 | if (INTEL_INFO(dev)->gen < 4) | 8598 | if (INTEL_INFO(dev)->gen < 4) |
| 8604 | PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios); | 8599 | PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios); |
| 8605 | PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits); | 8600 | PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits); |
| 8606 | PIPE_CONF_CHECK_I(pch_pfit.pos); | 8601 | PIPE_CONF_CHECK_I(pch_pfit.enabled); |
| 8607 | PIPE_CONF_CHECK_I(pch_pfit.size); | 8602 | if (current_config->pch_pfit.enabled) { |
| 8603 | PIPE_CONF_CHECK_I(pch_pfit.pos); | ||
| 8604 | PIPE_CONF_CHECK_I(pch_pfit.size); | ||
| 8605 | } | ||
| 8608 | 8606 | ||
| 8609 | PIPE_CONF_CHECK_I(ips_enabled); | 8607 | PIPE_CONF_CHECK_I(ips_enabled); |
| 8610 | 8608 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index a47799e832c6..28cae80495e2 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
| @@ -280,6 +280,7 @@ struct intel_crtc_config { | |||
| 280 | struct { | 280 | struct { |
| 281 | u32 pos; | 281 | u32 pos; |
| 282 | u32 size; | 282 | u32 size; |
| 283 | bool enabled; | ||
| 283 | } pch_pfit; | 284 | } pch_pfit; |
| 284 | 285 | ||
| 285 | /* FDI configuration, only valid if has_pch_encoder is set. */ | 286 | /* FDI configuration, only valid if has_pch_encoder is set. */ |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 406303b509c1..7fa7df546c1e 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
| @@ -263,6 +263,8 @@ static bool intel_dvo_compute_config(struct intel_encoder *encoder, | |||
| 263 | C(vtotal); | 263 | C(vtotal); |
| 264 | C(clock); | 264 | C(clock); |
| 265 | #undef C | 265 | #undef C |
| 266 | |||
| 267 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
| 266 | } | 268 | } |
| 267 | 269 | ||
| 268 | if (intel_dvo->dev.dev_ops->mode_fixup) | 270 | if (intel_dvo->dev.dev_ops->mode_fixup) |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 42114ecbae0e..293564a2896a 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
| @@ -112,6 +112,7 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc, | |||
| 112 | done: | 112 | done: |
| 113 | pipe_config->pch_pfit.pos = (x << 16) | y; | 113 | pipe_config->pch_pfit.pos = (x << 16) | y; |
| 114 | pipe_config->pch_pfit.size = (width << 16) | height; | 114 | pipe_config->pch_pfit.size = (width << 16) | height; |
| 115 | pipe_config->pch_pfit.enabled = pipe_config->pch_pfit.size != 0; | ||
| 115 | } | 116 | } |
| 116 | 117 | ||
| 117 | static void | 118 | static void |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0c115cc4899f..dd176b7296c1 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
| @@ -2096,16 +2096,16 @@ static uint32_t ilk_pipe_pixel_rate(struct drm_device *dev, | |||
| 2096 | struct drm_crtc *crtc) | 2096 | struct drm_crtc *crtc) |
| 2097 | { | 2097 | { |
| 2098 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 2098 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| 2099 | uint32_t pixel_rate, pfit_size; | 2099 | uint32_t pixel_rate; |
| 2100 | 2100 | ||
| 2101 | pixel_rate = intel_crtc->config.adjusted_mode.clock; | 2101 | pixel_rate = intel_crtc->config.adjusted_mode.clock; |
| 2102 | 2102 | ||
| 2103 | /* We only use IF-ID interlacing. If we ever use PF-ID we'll need to | 2103 | /* We only use IF-ID interlacing. If we ever use PF-ID we'll need to |
| 2104 | * adjust the pixel_rate here. */ | 2104 | * adjust the pixel_rate here. */ |
| 2105 | 2105 | ||
| 2106 | pfit_size = intel_crtc->config.pch_pfit.size; | 2106 | if (intel_crtc->config.pch_pfit.enabled) { |
| 2107 | if (pfit_size) { | ||
| 2108 | uint64_t pipe_w, pipe_h, pfit_w, pfit_h; | 2107 | uint64_t pipe_w, pipe_h, pfit_w, pfit_h; |
| 2108 | uint32_t pfit_size = intel_crtc->config.pch_pfit.size; | ||
| 2109 | 2109 | ||
| 2110 | pipe_w = intel_crtc->config.requested_mode.hdisplay; | 2110 | pipe_w = intel_crtc->config.requested_mode.hdisplay; |
| 2111 | pipe_h = intel_crtc->config.requested_mode.vdisplay; | 2111 | pipe_h = intel_crtc->config.requested_mode.vdisplay; |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 85037b9d4934..49482fd5b76c 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -788,6 +788,8 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | |||
| 788 | uint16_t h_sync_offset, v_sync_offset; | 788 | uint16_t h_sync_offset, v_sync_offset; |
| 789 | int mode_clock; | 789 | int mode_clock; |
| 790 | 790 | ||
| 791 | memset(dtd, 0, sizeof(*dtd)); | ||
| 792 | |||
| 791 | width = mode->hdisplay; | 793 | width = mode->hdisplay; |
| 792 | height = mode->vdisplay; | 794 | height = mode->vdisplay; |
| 793 | 795 | ||
| @@ -830,44 +832,51 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | |||
| 830 | if (mode->flags & DRM_MODE_FLAG_PVSYNC) | 832 | if (mode->flags & DRM_MODE_FLAG_PVSYNC) |
| 831 | dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE; | 833 | dtd->part2.dtd_flags |= DTD_FLAG_VSYNC_POSITIVE; |
| 832 | 834 | ||
| 833 | dtd->part2.sdvo_flags = 0; | ||
| 834 | dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; | 835 | dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; |
| 835 | dtd->part2.reserved = 0; | ||
| 836 | } | 836 | } |
| 837 | 837 | ||
| 838 | static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, | 838 | static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode *pmode, |
| 839 | const struct intel_sdvo_dtd *dtd) | 839 | const struct intel_sdvo_dtd *dtd) |
| 840 | { | 840 | { |
| 841 | mode->hdisplay = dtd->part1.h_active; | 841 | struct drm_display_mode mode = {}; |
| 842 | mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; | 842 | |
| 843 | mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off; | 843 | mode.hdisplay = dtd->part1.h_active; |
| 844 | mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2; | 844 | mode.hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; |
| 845 | mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width; | 845 | mode.hsync_start = mode.hdisplay + dtd->part2.h_sync_off; |
| 846 | mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; | 846 | mode.hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2; |
| 847 | mode->htotal = mode->hdisplay + dtd->part1.h_blank; | 847 | mode.hsync_end = mode.hsync_start + dtd->part2.h_sync_width; |
| 848 | mode->htotal += (dtd->part1.h_high & 0xf) << 8; | 848 | mode.hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; |
| 849 | 849 | mode.htotal = mode.hdisplay + dtd->part1.h_blank; | |
| 850 | mode->vdisplay = dtd->part1.v_active; | 850 | mode.htotal += (dtd->part1.h_high & 0xf) << 8; |
| 851 | mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; | 851 | |
| 852 | mode->vsync_start = mode->vdisplay; | 852 | mode.vdisplay = dtd->part1.v_active; |
| 853 | mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; | 853 | mode.vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; |
| 854 | mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2; | 854 | mode.vsync_start = mode.vdisplay; |
| 855 | mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0; | 855 | mode.vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; |
| 856 | mode->vsync_end = mode->vsync_start + | 856 | mode.vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2; |
| 857 | mode.vsync_start += dtd->part2.v_sync_off_high & 0xc0; | ||
| 858 | mode.vsync_end = mode.vsync_start + | ||
| 857 | (dtd->part2.v_sync_off_width & 0xf); | 859 | (dtd->part2.v_sync_off_width & 0xf); |
| 858 | mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; | 860 | mode.vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; |
| 859 | mode->vtotal = mode->vdisplay + dtd->part1.v_blank; | 861 | mode.vtotal = mode.vdisplay + dtd->part1.v_blank; |
| 860 | mode->vtotal += (dtd->part1.v_high & 0xf) << 8; | 862 | mode.vtotal += (dtd->part1.v_high & 0xf) << 8; |
| 861 | 863 | ||
| 862 | mode->clock = dtd->part1.clock * 10; | 864 | mode.clock = dtd->part1.clock * 10; |
| 863 | 865 | ||
| 864 | mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); | ||
| 865 | if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE) | 866 | if (dtd->part2.dtd_flags & DTD_FLAG_INTERLACE) |
| 866 | mode->flags |= DRM_MODE_FLAG_INTERLACE; | 867 | mode.flags |= DRM_MODE_FLAG_INTERLACE; |
| 867 | if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) | 868 | if (dtd->part2.dtd_flags & DTD_FLAG_HSYNC_POSITIVE) |
| 868 | mode->flags |= DRM_MODE_FLAG_PHSYNC; | 869 | mode.flags |= DRM_MODE_FLAG_PHSYNC; |
| 870 | else | ||
| 871 | mode.flags |= DRM_MODE_FLAG_NHSYNC; | ||
| 869 | if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) | 872 | if (dtd->part2.dtd_flags & DTD_FLAG_VSYNC_POSITIVE) |
| 870 | mode->flags |= DRM_MODE_FLAG_PVSYNC; | 873 | mode.flags |= DRM_MODE_FLAG_PVSYNC; |
| 874 | else | ||
| 875 | mode.flags |= DRM_MODE_FLAG_NVSYNC; | ||
| 876 | |||
| 877 | drm_mode_set_crtcinfo(&mode, 0); | ||
| 878 | |||
| 879 | drm_mode_copy(pmode, &mode); | ||
| 871 | } | 880 | } |
| 872 | 881 | ||
| 873 | static bool intel_sdvo_check_supp_encode(struct intel_sdvo *intel_sdvo) | 882 | static bool intel_sdvo_check_supp_encode(struct intel_sdvo *intel_sdvo) |
