diff options
author | Dave Airlie <airlied@redhat.com> | 2013-07-22 02:14:26 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-07-22 02:14:26 -0400 |
commit | 058ca4a22ebf22ea1cbedd6cc0340ed1e2e94ee1 (patch) | |
tree | be613740a1978abadd032a7d9782ab4b995b99d6 | |
parent | 27ddabc32d9e26eb590fb7153b588eff84a9c499 (diff) | |
parent | 181d1b9e31c668259d3798c521672afb8edd355c (diff) |
Merge tag 'drm-intel-fixes-2013-07-22' of git://people.freedesktop.org/~danvet/drm-intel into drm-fixes
- fixup panel fitter readout for gen2/3 (just quitens dmesg noise)
- fix pft computations for non-autoscaled resolutions (i.e. letter/pillar
boxing on gen2/3)
- preserve the DDI A/E lane sharing bit (Stéphane Marchesin)
- fix the "rc6 fails to work after resume" regression, big thanks to
Konstantin Khlebnikov for the patch and debug insight about what
actually might be going on here
- fix Oops in is_crtc_connector_off (Chris)
- sanitize shared dpll state - our new paranoid state checker tripped up
over dirt left behind by the BIOS
- correctly restore fences, fixes the "my screen is all messed up after
resume" regression introduced in the final 3.10 pull request
- quirk backlights harder, this time for Dell XPS13 machines to fix a
regression (patch from Kamal Mostafa)
- 90% fix for some haswell hangs when accessing registers concurrently,
the 100% solution is simply too invasive for -fixes and what we have
here seems to be good enough (Chris)
* tag 'drm-intel-fixes-2013-07-22' of git://people.freedesktop.org/~danvet/drm-intel:
drm/i915: fix up gt init sequence fallout
drm/i915: Serialize almost all register access
drm/i915: quirk no PCH_PWM_ENABLE for Dell XPS13 backlight
drm/i915: correctly restore fences with objects attached
drm/i915: Fix dereferencing invalid connectors in is_crtc_connector_off()
drm/i915: Sanitize shared dpll state
drm/i915: fix long-standing SNB regression in power consumption after resume v2
drm/i915: Preserve the DDI_A_4_LANES bit from the bios
drm/i915: fix pfit regression for non-autoscaled resolutions
drm/i915: fix up readout of the lvds dither bit on gen2/3
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 69 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_panel.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 8 |
10 files changed, 110 insertions, 49 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index cf188ab7051a..67ec54f67afe 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1495,6 +1495,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1495 | dev_priv->dev = dev; | 1495 | dev_priv->dev = dev; |
1496 | dev_priv->info = info; | 1496 | dev_priv->info = info; |
1497 | 1497 | ||
1498 | spin_lock_init(&dev_priv->irq_lock); | ||
1499 | spin_lock_init(&dev_priv->gpu_error.lock); | ||
1500 | spin_lock_init(&dev_priv->rps.lock); | ||
1501 | spin_lock_init(&dev_priv->backlight.lock); | ||
1502 | mutex_init(&dev_priv->dpio_lock); | ||
1503 | mutex_init(&dev_priv->rps.hw_lock); | ||
1504 | mutex_init(&dev_priv->modeset_restore_lock); | ||
1505 | |||
1498 | i915_dump_device_info(dev_priv); | 1506 | i915_dump_device_info(dev_priv); |
1499 | 1507 | ||
1500 | if (i915_get_bridge_dev(dev)) { | 1508 | if (i915_get_bridge_dev(dev)) { |
@@ -1585,6 +1593,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1585 | intel_detect_pch(dev); | 1593 | intel_detect_pch(dev); |
1586 | 1594 | ||
1587 | intel_irq_init(dev); | 1595 | intel_irq_init(dev); |
1596 | intel_gt_sanitize(dev); | ||
1588 | intel_gt_init(dev); | 1597 | intel_gt_init(dev); |
1589 | 1598 | ||
1590 | /* Try to make sure MCHBAR is enabled before poking at it */ | 1599 | /* Try to make sure MCHBAR is enabled before poking at it */ |
@@ -1610,15 +1619,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1610 | if (!IS_I945G(dev) && !IS_I945GM(dev)) | 1619 | if (!IS_I945G(dev) && !IS_I945GM(dev)) |
1611 | pci_enable_msi(dev->pdev); | 1620 | pci_enable_msi(dev->pdev); |
1612 | 1621 | ||
1613 | spin_lock_init(&dev_priv->irq_lock); | ||
1614 | spin_lock_init(&dev_priv->gpu_error.lock); | ||
1615 | spin_lock_init(&dev_priv->rps.lock); | ||
1616 | spin_lock_init(&dev_priv->backlight.lock); | ||
1617 | mutex_init(&dev_priv->dpio_lock); | ||
1618 | |||
1619 | mutex_init(&dev_priv->rps.hw_lock); | ||
1620 | mutex_init(&dev_priv->modeset_restore_lock); | ||
1621 | |||
1622 | dev_priv->num_plane = 1; | 1622 | dev_priv->num_plane = 1; |
1623 | if (IS_VALLEYVIEW(dev)) | 1623 | if (IS_VALLEYVIEW(dev)) |
1624 | dev_priv->num_plane = 2; | 1624 | dev_priv->num_plane = 2; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f4af1ca0fb62..45b3c030f483 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -706,7 +706,7 @@ static int i915_drm_thaw(struct drm_device *dev) | |||
706 | { | 706 | { |
707 | int error = 0; | 707 | int error = 0; |
708 | 708 | ||
709 | intel_gt_reset(dev); | 709 | intel_gt_sanitize(dev); |
710 | 710 | ||
711 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 711 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
712 | mutex_lock(&dev->struct_mutex); | 712 | mutex_lock(&dev->struct_mutex); |
@@ -732,7 +732,7 @@ int i915_resume(struct drm_device *dev) | |||
732 | 732 | ||
733 | pci_set_master(dev->pdev); | 733 | pci_set_master(dev->pdev); |
734 | 734 | ||
735 | intel_gt_reset(dev); | 735 | intel_gt_sanitize(dev); |
736 | 736 | ||
737 | /* | 737 | /* |
738 | * Platforms with opregion should have sane BIOS, older ones (gen3 and | 738 | * Platforms with opregion should have sane BIOS, older ones (gen3 and |
@@ -1253,21 +1253,21 @@ hsw_unclaimed_reg_check(struct drm_i915_private *dev_priv, u32 reg) | |||
1253 | 1253 | ||
1254 | #define __i915_read(x, y) \ | 1254 | #define __i915_read(x, y) \ |
1255 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ | 1255 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ |
1256 | unsigned long irqflags; \ | ||
1256 | u##x val = 0; \ | 1257 | u##x val = 0; \ |
1258 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \ | ||
1257 | if (IS_GEN5(dev_priv->dev)) \ | 1259 | if (IS_GEN5(dev_priv->dev)) \ |
1258 | ilk_dummy_write(dev_priv); \ | 1260 | ilk_dummy_write(dev_priv); \ |
1259 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ | 1261 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
1260 | unsigned long irqflags; \ | ||
1261 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \ | ||
1262 | if (dev_priv->forcewake_count == 0) \ | 1262 | if (dev_priv->forcewake_count == 0) \ |
1263 | dev_priv->gt.force_wake_get(dev_priv); \ | 1263 | dev_priv->gt.force_wake_get(dev_priv); \ |
1264 | val = read##y(dev_priv->regs + reg); \ | 1264 | val = read##y(dev_priv->regs + reg); \ |
1265 | if (dev_priv->forcewake_count == 0) \ | 1265 | if (dev_priv->forcewake_count == 0) \ |
1266 | dev_priv->gt.force_wake_put(dev_priv); \ | 1266 | dev_priv->gt.force_wake_put(dev_priv); \ |
1267 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \ | ||
1268 | } else { \ | 1267 | } else { \ |
1269 | val = read##y(dev_priv->regs + reg); \ | 1268 | val = read##y(dev_priv->regs + reg); \ |
1270 | } \ | 1269 | } \ |
1270 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \ | ||
1271 | trace_i915_reg_rw(false, reg, val, sizeof(val)); \ | 1271 | trace_i915_reg_rw(false, reg, val, sizeof(val)); \ |
1272 | return val; \ | 1272 | return val; \ |
1273 | } | 1273 | } |
@@ -1280,8 +1280,10 @@ __i915_read(64, q) | |||
1280 | 1280 | ||
1281 | #define __i915_write(x, y) \ | 1281 | #define __i915_write(x, y) \ |
1282 | void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ | 1282 | void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ |
1283 | unsigned long irqflags; \ | ||
1283 | u32 __fifo_ret = 0; \ | 1284 | u32 __fifo_ret = 0; \ |
1284 | trace_i915_reg_rw(true, reg, val, sizeof(val)); \ | 1285 | trace_i915_reg_rw(true, reg, val, sizeof(val)); \ |
1286 | spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \ | ||
1285 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ | 1287 | if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ |
1286 | __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ | 1288 | __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \ |
1287 | } \ | 1289 | } \ |
@@ -1293,6 +1295,7 @@ void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ | |||
1293 | gen6_gt_check_fifodbg(dev_priv); \ | 1295 | gen6_gt_check_fifodbg(dev_priv); \ |
1294 | } \ | 1296 | } \ |
1295 | hsw_unclaimed_reg_check(dev_priv, reg); \ | 1297 | hsw_unclaimed_reg_check(dev_priv, reg); \ |
1298 | spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \ | ||
1296 | } | 1299 | } |
1297 | __i915_write(8, b) | 1300 | __i915_write(8, b) |
1298 | __i915_write(16, w) | 1301 | __i915_write(16, w) |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a416645bcd23..d2ee3343c943 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -555,6 +555,7 @@ enum intel_sbi_destination { | |||
555 | #define QUIRK_PIPEA_FORCE (1<<0) | 555 | #define QUIRK_PIPEA_FORCE (1<<0) |
556 | #define QUIRK_LVDS_SSC_DISABLE (1<<1) | 556 | #define QUIRK_LVDS_SSC_DISABLE (1<<1) |
557 | #define QUIRK_INVERT_BRIGHTNESS (1<<2) | 557 | #define QUIRK_INVERT_BRIGHTNESS (1<<2) |
558 | #define QUIRK_NO_PCH_PWM_ENABLE (1<<3) | ||
558 | 559 | ||
559 | struct intel_fbdev; | 560 | struct intel_fbdev; |
560 | struct intel_fbc_work; | 561 | struct intel_fbc_work; |
@@ -1583,7 +1584,7 @@ void i915_handle_error(struct drm_device *dev, bool wedged); | |||
1583 | extern void intel_irq_init(struct drm_device *dev); | 1584 | extern void intel_irq_init(struct drm_device *dev); |
1584 | extern void intel_hpd_init(struct drm_device *dev); | 1585 | extern void intel_hpd_init(struct drm_device *dev); |
1585 | extern void intel_gt_init(struct drm_device *dev); | 1586 | extern void intel_gt_init(struct drm_device *dev); |
1586 | extern void intel_gt_reset(struct drm_device *dev); | 1587 | extern void intel_gt_sanitize(struct drm_device *dev); |
1587 | 1588 | ||
1588 | void i915_error_state_free(struct kref *error_ref); | 1589 | void i915_error_state_free(struct kref *error_ref); |
1589 | 1590 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 97afd2639fb6..d9e2208cfe98 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2258,7 +2258,17 @@ void i915_gem_restore_fences(struct drm_device *dev) | |||
2258 | 2258 | ||
2259 | for (i = 0; i < dev_priv->num_fence_regs; i++) { | 2259 | for (i = 0; i < dev_priv->num_fence_regs; i++) { |
2260 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; | 2260 | struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; |
2261 | i915_gem_write_fence(dev, i, reg->obj); | 2261 | |
2262 | /* | ||
2263 | * Commit delayed tiling changes if we have an object still | ||
2264 | * attached to the fence, otherwise just clear the fence. | ||
2265 | */ | ||
2266 | if (reg->obj) { | ||
2267 | i915_gem_object_update_fence(reg->obj, reg, | ||
2268 | reg->obj->tiling_mode); | ||
2269 | } else { | ||
2270 | i915_gem_write_fence(dev, i, NULL); | ||
2271 | } | ||
2262 | } | 2272 | } |
2263 | } | 2273 | } |
2264 | 2274 | ||
@@ -2795,6 +2805,10 @@ static void i915_gem_write_fence(struct drm_device *dev, int reg, | |||
2795 | if (i915_gem_object_needs_mb(dev_priv->fence_regs[reg].obj)) | 2805 | if (i915_gem_object_needs_mb(dev_priv->fence_regs[reg].obj)) |
2796 | mb(); | 2806 | mb(); |
2797 | 2807 | ||
2808 | WARN(obj && (!obj->stride || !obj->tiling_mode), | ||
2809 | "bogus fence setup with stride: 0x%x, tiling mode: %i\n", | ||
2810 | obj->stride, obj->tiling_mode); | ||
2811 | |||
2798 | switch (INTEL_INFO(dev)->gen) { | 2812 | switch (INTEL_INFO(dev)->gen) { |
2799 | case 7: | 2813 | case 7: |
2800 | case 6: | 2814 | case 6: |
@@ -2836,6 +2850,7 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj, | |||
2836 | fence->obj = NULL; | 2850 | fence->obj = NULL; |
2837 | list_del_init(&fence->lru_list); | 2851 | list_del_init(&fence->lru_list); |
2838 | } | 2852 | } |
2853 | obj->fence_dirty = false; | ||
2839 | } | 2854 | } |
2840 | 2855 | ||
2841 | static int | 2856 | static int |
@@ -2965,7 +2980,6 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj) | |||
2965 | return 0; | 2980 | return 0; |
2966 | 2981 | ||
2967 | i915_gem_object_update_fence(obj, reg, enable); | 2982 | i915_gem_object_update_fence(obj, reg, enable); |
2968 | obj->fence_dirty = false; | ||
2969 | 2983 | ||
2970 | return 0; | 2984 | return 0; |
2971 | } | 2985 | } |
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 324211ac9c55..b042ee5c4070 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -301,7 +301,7 @@ static void intel_ddi_mode_set(struct drm_encoder *encoder, | |||
301 | struct intel_digital_port *intel_dig_port = | 301 | struct intel_digital_port *intel_dig_port = |
302 | enc_to_dig_port(encoder); | 302 | enc_to_dig_port(encoder); |
303 | 303 | ||
304 | intel_dp->DP = intel_dig_port->port_reversal | | 304 | intel_dp->DP = intel_dig_port->saved_port_bits | |
305 | DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; | 305 | DDI_BUF_CTL_ENABLE | DDI_BUF_EMP_400MV_0DB_HSW; |
306 | intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count); | 306 | intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count); |
307 | 307 | ||
@@ -1109,7 +1109,8 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) | |||
1109 | * enabling the port. | 1109 | * enabling the port. |
1110 | */ | 1110 | */ |
1111 | I915_WRITE(DDI_BUF_CTL(port), | 1111 | I915_WRITE(DDI_BUF_CTL(port), |
1112 | intel_dig_port->port_reversal | DDI_BUF_CTL_ENABLE); | 1112 | intel_dig_port->saved_port_bits | |
1113 | DDI_BUF_CTL_ENABLE); | ||
1113 | } else if (type == INTEL_OUTPUT_EDP) { | 1114 | } else if (type == INTEL_OUTPUT_EDP) { |
1114 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1115 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1115 | 1116 | ||
@@ -1347,8 +1348,9 @@ void intel_ddi_init(struct drm_device *dev, enum port port) | |||
1347 | intel_encoder->get_config = intel_ddi_get_config; | 1348 | intel_encoder->get_config = intel_ddi_get_config; |
1348 | 1349 | ||
1349 | intel_dig_port->port = port; | 1350 | intel_dig_port->port = port; |
1350 | intel_dig_port->port_reversal = I915_READ(DDI_BUF_CTL(port)) & | 1351 | intel_dig_port->saved_port_bits = I915_READ(DDI_BUF_CTL(port)) & |
1351 | DDI_BUF_PORT_REVERSAL; | 1352 | (DDI_BUF_PORT_REVERSAL | |
1353 | DDI_A_4_LANES); | ||
1352 | intel_dig_port->dp.output_reg = DDI_BUF_CTL(port); | 1354 | intel_dig_port->dp.output_reg = DDI_BUF_CTL(port); |
1353 | 1355 | ||
1354 | intel_encoder->type = INTEL_OUTPUT_UNKNOWN; | 1356 | intel_encoder->type = INTEL_OUTPUT_UNKNOWN; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 85f3eb74d2b7..5fb305840db8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -4913,22 +4913,19 @@ static void i9xx_get_pfit_config(struct intel_crtc *crtc, | |||
4913 | uint32_t tmp; | 4913 | uint32_t tmp; |
4914 | 4914 | ||
4915 | tmp = I915_READ(PFIT_CONTROL); | 4915 | tmp = I915_READ(PFIT_CONTROL); |
4916 | if (!(tmp & PFIT_ENABLE)) | ||
4917 | return; | ||
4916 | 4918 | ||
4919 | /* Check whether the pfit is attached to our pipe. */ | ||
4917 | if (INTEL_INFO(dev)->gen < 4) { | 4920 | if (INTEL_INFO(dev)->gen < 4) { |
4918 | if (crtc->pipe != PIPE_B) | 4921 | if (crtc->pipe != PIPE_B) |
4919 | return; | 4922 | return; |
4920 | |||
4921 | /* gen2/3 store dither state in pfit control, needs to match */ | ||
4922 | pipe_config->gmch_pfit.control = tmp & PANEL_8TO6_DITHER_ENABLE; | ||
4923 | } else { | 4923 | } else { |
4924 | if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT)) | 4924 | if ((tmp & PFIT_PIPE_MASK) != (crtc->pipe << PFIT_PIPE_SHIFT)) |
4925 | return; | 4925 | return; |
4926 | } | 4926 | } |
4927 | 4927 | ||
4928 | if (!(tmp & PFIT_ENABLE)) | 4928 | pipe_config->gmch_pfit.control = tmp; |
4929 | return; | ||
4930 | |||
4931 | pipe_config->gmch_pfit.control = I915_READ(PFIT_CONTROL); | ||
4932 | pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS); | 4929 | pipe_config->gmch_pfit.pgm_ratios = I915_READ(PFIT_PGM_RATIOS); |
4933 | if (INTEL_INFO(dev)->gen < 5) | 4930 | if (INTEL_INFO(dev)->gen < 5) |
4934 | pipe_config->gmch_pfit.lvds_border_bits = | 4931 | pipe_config->gmch_pfit.lvds_border_bits = |
@@ -8317,6 +8314,8 @@ check_shared_dpll_state(struct drm_device *dev) | |||
8317 | pll->active, pll->refcount); | 8314 | pll->active, pll->refcount); |
8318 | WARN(pll->active && !pll->on, | 8315 | WARN(pll->active && !pll->on, |
8319 | "pll in active use but not on in sw tracking\n"); | 8316 | "pll in active use but not on in sw tracking\n"); |
8317 | WARN(pll->on && !pll->active, | ||
8318 | "pll in on but not on in use in sw tracking\n"); | ||
8320 | WARN(pll->on != active, | 8319 | WARN(pll->on != active, |
8321 | "pll on state mismatch (expected %i, found %i)\n", | 8320 | "pll on state mismatch (expected %i, found %i)\n", |
8322 | pll->on, active); | 8321 | pll->on, active); |
@@ -8541,15 +8540,20 @@ static void intel_set_config_restore_state(struct drm_device *dev, | |||
8541 | } | 8540 | } |
8542 | 8541 | ||
8543 | static bool | 8542 | static bool |
8544 | is_crtc_connector_off(struct drm_crtc *crtc, struct drm_connector *connectors, | 8543 | is_crtc_connector_off(struct drm_mode_set *set) |
8545 | int num_connectors) | ||
8546 | { | 8544 | { |
8547 | int i; | 8545 | int i; |
8548 | 8546 | ||
8549 | for (i = 0; i < num_connectors; i++) | 8547 | if (set->num_connectors == 0) |
8550 | if (connectors[i].encoder && | 8548 | return false; |
8551 | connectors[i].encoder->crtc == crtc && | 8549 | |
8552 | connectors[i].dpms != DRM_MODE_DPMS_ON) | 8550 | if (WARN_ON(set->connectors == NULL)) |
8551 | return false; | ||
8552 | |||
8553 | for (i = 0; i < set->num_connectors; i++) | ||
8554 | if (set->connectors[i]->encoder && | ||
8555 | set->connectors[i]->encoder->crtc == set->crtc && | ||
8556 | set->connectors[i]->dpms != DRM_MODE_DPMS_ON) | ||
8553 | return true; | 8557 | return true; |
8554 | 8558 | ||
8555 | return false; | 8559 | return false; |
@@ -8562,10 +8566,8 @@ intel_set_config_compute_mode_changes(struct drm_mode_set *set, | |||
8562 | 8566 | ||
8563 | /* We should be able to check here if the fb has the same properties | 8567 | /* We should be able to check here if the fb has the same properties |
8564 | * and then just flip_or_move it */ | 8568 | * and then just flip_or_move it */ |
8565 | if (set->connectors != NULL && | 8569 | if (is_crtc_connector_off(set)) { |
8566 | is_crtc_connector_off(set->crtc, *set->connectors, | 8570 | config->mode_changed = true; |
8567 | set->num_connectors)) { | ||
8568 | config->mode_changed = true; | ||
8569 | } else if (set->crtc->fb != set->fb) { | 8571 | } else if (set->crtc->fb != set->fb) { |
8570 | /* If we have no fb then treat it as a full mode set */ | 8572 | /* If we have no fb then treat it as a full mode set */ |
8571 | if (set->crtc->fb == NULL) { | 8573 | if (set->crtc->fb == NULL) { |
@@ -9398,6 +9400,17 @@ static void quirk_invert_brightness(struct drm_device *dev) | |||
9398 | DRM_INFO("applying inverted panel brightness quirk\n"); | 9400 | DRM_INFO("applying inverted panel brightness quirk\n"); |
9399 | } | 9401 | } |
9400 | 9402 | ||
9403 | /* | ||
9404 | * Some machines (Dell XPS13) suffer broken backlight controls if | ||
9405 | * BLM_PCH_PWM_ENABLE is set. | ||
9406 | */ | ||
9407 | static void quirk_no_pcm_pwm_enable(struct drm_device *dev) | ||
9408 | { | ||
9409 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
9410 | dev_priv->quirks |= QUIRK_NO_PCH_PWM_ENABLE; | ||
9411 | DRM_INFO("applying no-PCH_PWM_ENABLE quirk\n"); | ||
9412 | } | ||
9413 | |||
9401 | struct intel_quirk { | 9414 | struct intel_quirk { |
9402 | int device; | 9415 | int device; |
9403 | int subsystem_vendor; | 9416 | int subsystem_vendor; |
@@ -9467,6 +9480,11 @@ static struct intel_quirk intel_quirks[] = { | |||
9467 | 9480 | ||
9468 | /* Acer Aspire 4736Z */ | 9481 | /* Acer Aspire 4736Z */ |
9469 | { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness }, | 9482 | { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness }, |
9483 | |||
9484 | /* Dell XPS13 HD Sandy Bridge */ | ||
9485 | { 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable }, | ||
9486 | /* Dell XPS13 HD and XPS13 FHD Ivy Bridge */ | ||
9487 | { 0x0166, 0x1028, 0x058b, quirk_no_pcm_pwm_enable }, | ||
9470 | }; | 9488 | }; |
9471 | 9489 | ||
9472 | static void intel_init_quirks(struct drm_device *dev) | 9490 | static void intel_init_quirks(struct drm_device *dev) |
@@ -9817,8 +9835,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) | |||
9817 | } | 9835 | } |
9818 | pll->refcount = pll->active; | 9836 | pll->refcount = pll->active; |
9819 | 9837 | ||
9820 | DRM_DEBUG_KMS("%s hw state readout: refcount %i\n", | 9838 | DRM_DEBUG_KMS("%s hw state readout: refcount %i, on %i\n", |
9821 | pll->name, pll->refcount); | 9839 | pll->name, pll->refcount, pll->on); |
9822 | } | 9840 | } |
9823 | 9841 | ||
9824 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | 9842 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
@@ -9869,6 +9887,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, | |||
9869 | struct drm_plane *plane; | 9887 | struct drm_plane *plane; |
9870 | struct intel_crtc *crtc; | 9888 | struct intel_crtc *crtc; |
9871 | struct intel_encoder *encoder; | 9889 | struct intel_encoder *encoder; |
9890 | int i; | ||
9872 | 9891 | ||
9873 | intel_modeset_readout_hw_state(dev); | 9892 | intel_modeset_readout_hw_state(dev); |
9874 | 9893 | ||
@@ -9884,6 +9903,18 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, | |||
9884 | intel_dump_pipe_config(crtc, &crtc->config, "[setup_hw_state]"); | 9903 | intel_dump_pipe_config(crtc, &crtc->config, "[setup_hw_state]"); |
9885 | } | 9904 | } |
9886 | 9905 | ||
9906 | for (i = 0; i < dev_priv->num_shared_dpll; i++) { | ||
9907 | struct intel_shared_dpll *pll = &dev_priv->shared_dplls[i]; | ||
9908 | |||
9909 | if (!pll->on || pll->active) | ||
9910 | continue; | ||
9911 | |||
9912 | DRM_DEBUG_KMS("%s enabled but not in use, disabling\n", pll->name); | ||
9913 | |||
9914 | pll->disable(dev_priv, pll); | ||
9915 | pll->on = false; | ||
9916 | } | ||
9917 | |||
9887 | if (force_restore) { | 9918 | if (force_restore) { |
9888 | /* | 9919 | /* |
9889 | * We need to use raw interfaces for restoring state to avoid | 9920 | * We need to use raw interfaces for restoring state to avoid |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index c8c9b6f48230..b7d6e09456ce 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -504,7 +504,7 @@ struct intel_dp { | |||
504 | struct intel_digital_port { | 504 | struct intel_digital_port { |
505 | struct intel_encoder base; | 505 | struct intel_encoder base; |
506 | enum port port; | 506 | enum port port; |
507 | u32 port_reversal; | 507 | u32 saved_port_bits; |
508 | struct intel_dp dp; | 508 | struct intel_dp dp; |
509 | struct intel_hdmi hdmi; | 509 | struct intel_hdmi hdmi; |
510 | }; | 510 | }; |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 021e8daa022d..61348eae2f04 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -109,6 +109,13 @@ static void intel_lvds_get_config(struct intel_encoder *encoder, | |||
109 | flags |= DRM_MODE_FLAG_PVSYNC; | 109 | flags |= DRM_MODE_FLAG_PVSYNC; |
110 | 110 | ||
111 | pipe_config->adjusted_mode.flags |= flags; | 111 | pipe_config->adjusted_mode.flags |= flags; |
112 | |||
113 | /* gen2/3 store dither state in pfit control, needs to match */ | ||
114 | if (INTEL_INFO(dev)->gen < 4) { | ||
115 | tmp = I915_READ(PFIT_CONTROL); | ||
116 | |||
117 | pipe_config->gmch_pfit.control |= tmp & PANEL_8TO6_DITHER_ENABLE; | ||
118 | } | ||
112 | } | 119 | } |
113 | 120 | ||
114 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. | 121 | /* The LVDS pin pair needs to be on before the DPLLs are enabled. |
@@ -290,14 +297,11 @@ static bool intel_lvds_compute_config(struct intel_encoder *intel_encoder, | |||
290 | 297 | ||
291 | intel_pch_panel_fitting(intel_crtc, pipe_config, | 298 | intel_pch_panel_fitting(intel_crtc, pipe_config, |
292 | intel_connector->panel.fitting_mode); | 299 | intel_connector->panel.fitting_mode); |
293 | return true; | ||
294 | } else { | 300 | } else { |
295 | intel_gmch_panel_fitting(intel_crtc, pipe_config, | 301 | intel_gmch_panel_fitting(intel_crtc, pipe_config, |
296 | intel_connector->panel.fitting_mode); | 302 | intel_connector->panel.fitting_mode); |
297 | } | ||
298 | 303 | ||
299 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 304 | } |
300 | pipe_config->timings_set = true; | ||
301 | 305 | ||
302 | /* | 306 | /* |
303 | * XXX: It would be nice to support lower refresh rates on the | 307 | * XXX: It would be nice to support lower refresh rates on the |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 80bea1d3209f..67e2c1f1c9a8 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -194,6 +194,9 @@ void intel_gmch_panel_fitting(struct intel_crtc *intel_crtc, | |||
194 | adjusted_mode->vdisplay == mode->vdisplay) | 194 | adjusted_mode->vdisplay == mode->vdisplay) |
195 | goto out; | 195 | goto out; |
196 | 196 | ||
197 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
198 | pipe_config->timings_set = true; | ||
199 | |||
197 | switch (fitting_mode) { | 200 | switch (fitting_mode) { |
198 | case DRM_MODE_SCALE_CENTER: | 201 | case DRM_MODE_SCALE_CENTER: |
199 | /* | 202 | /* |
@@ -580,7 +583,8 @@ void intel_panel_enable_backlight(struct drm_device *dev, | |||
580 | POSTING_READ(reg); | 583 | POSTING_READ(reg); |
581 | I915_WRITE(reg, tmp | BLM_PWM_ENABLE); | 584 | I915_WRITE(reg, tmp | BLM_PWM_ENABLE); |
582 | 585 | ||
583 | if (HAS_PCH_SPLIT(dev)) { | 586 | if (HAS_PCH_SPLIT(dev) && |
587 | !(dev_priv->quirks & QUIRK_NO_PCH_PWM_ENABLE)) { | ||
584 | tmp = I915_READ(BLC_PWM_PCH_CTL1); | 588 | tmp = I915_READ(BLC_PWM_PCH_CTL1); |
585 | tmp |= BLM_PCH_PWM_ENABLE; | 589 | tmp |= BLM_PCH_PWM_ENABLE; |
586 | tmp &= ~BLM_PCH_OVERRIDE_ENABLE; | 590 | tmp &= ~BLM_PCH_OVERRIDE_ENABLE; |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index d10e6735771f..6a347f54d39f 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -5476,7 +5476,7 @@ static void vlv_force_wake_put(struct drm_i915_private *dev_priv) | |||
5476 | gen6_gt_check_fifodbg(dev_priv); | 5476 | gen6_gt_check_fifodbg(dev_priv); |
5477 | } | 5477 | } |
5478 | 5478 | ||
5479 | void intel_gt_reset(struct drm_device *dev) | 5479 | void intel_gt_sanitize(struct drm_device *dev) |
5480 | { | 5480 | { |
5481 | struct drm_i915_private *dev_priv = dev->dev_private; | 5481 | struct drm_i915_private *dev_priv = dev->dev_private; |
5482 | 5482 | ||
@@ -5487,6 +5487,10 @@ void intel_gt_reset(struct drm_device *dev) | |||
5487 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) | 5487 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) |
5488 | __gen6_gt_force_wake_mt_reset(dev_priv); | 5488 | __gen6_gt_force_wake_mt_reset(dev_priv); |
5489 | } | 5489 | } |
5490 | |||
5491 | /* BIOS often leaves RC6 enabled, but disable it for hw init */ | ||
5492 | if (INTEL_INFO(dev)->gen >= 6) | ||
5493 | intel_disable_gt_powersave(dev); | ||
5490 | } | 5494 | } |
5491 | 5495 | ||
5492 | void intel_gt_init(struct drm_device *dev) | 5496 | void intel_gt_init(struct drm_device *dev) |
@@ -5495,8 +5499,6 @@ void intel_gt_init(struct drm_device *dev) | |||
5495 | 5499 | ||
5496 | spin_lock_init(&dev_priv->gt_lock); | 5500 | spin_lock_init(&dev_priv->gt_lock); |
5497 | 5501 | ||
5498 | intel_gt_reset(dev); | ||
5499 | |||
5500 | if (IS_VALLEYVIEW(dev)) { | 5502 | if (IS_VALLEYVIEW(dev)) { |
5501 | dev_priv->gt.force_wake_get = vlv_force_wake_get; | 5503 | dev_priv->gt.force_wake_get = vlv_force_wake_get; |
5502 | dev_priv->gt.force_wake_put = vlv_force_wake_put; | 5504 | dev_priv->gt.force_wake_put = vlv_force_wake_put; |