Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge remote branch 'intel/drm-intel-fixes' of /ssd/git/drm-next into drm-fixes

* 'intel/drm-intel-fixes' of /ssd/git/drm-next:
drm/i915: Fix resume regression from 5d1d0cc
drm/i915/tv: Use polling rather than interrupt-based hotplug
drm/i915: Trigger modesetting if force-audio changes
drm/i915/sdvo: If we have an EDID confirm it matches the mode of the connection
drm/i915: Disable RC6 on Ironlake
drm/i915/lvds: Restore dithering on native modes for gen2/3
drm/i915: Invalidate TLB caches on SNB BLT/BSD rings

+231 -101
+4 -1
drivers/gpu/drm/i915/i915_drv.c
··· 46 46 unsigned int i915_powersave = 1; 47 47 module_param_named(powersave, i915_powersave, int, 0600); 48 48 49 + unsigned int i915_enable_rc6 = 0; 50 + module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); 51 + 49 52 unsigned int i915_lvds_downclock = 0; 50 53 module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); 51 54 ··· 363 360 /* Resume the modeset for every activated CRTC */ 364 361 drm_helper_resume_force_mode(dev); 365 362 366 - if (dev_priv->renderctx && dev_priv->pwrctx) 363 + if (IS_IRONLAKE_M(dev)) 367 364 ironlake_enable_rc6(dev); 368 365 } 369 366
+1
drivers/gpu/drm/i915/i915_drv.h
··· 958 958 extern unsigned int i915_powersave; 959 959 extern unsigned int i915_lvds_downclock; 960 960 extern unsigned int i915_panel_use_ssc; 961 + extern unsigned int i915_enable_rc6; 961 962 962 963 extern int i915_suspend(struct drm_device *dev, pm_message_t state); 963 964 extern int i915_resume(struct drm_device *dev);
+3 -1
drivers/gpu/drm/i915/i915_reg.h
··· 174 174 * address/value pairs. Don't overdue it, though, x <= 2^4 must hold! 175 175 */ 176 176 #define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*x-1) 177 - #define MI_FLUSH_DW MI_INSTR(0x26, 2) /* for GEN6 */ 177 + #define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */ 178 + #define MI_INVALIDATE_TLB (1<<18) 179 + #define MI_INVALIDATE_BSD (1<<7) 178 180 #define MI_BATCH_BUFFER MI_INSTR(0x30, 1) 179 181 #define MI_BATCH_NON_SECURE (1) 180 182 #define MI_BATCH_NON_SECURE_I965 (1<<8)
+53 -46
drivers/gpu/drm/i915/intel_display.c
··· 5558 5558 /* Reset flags back to the 'unknown' status so that they 5559 5559 * will be correctly set on the initial modeset. 5560 5560 */ 5561 - intel_crtc->cursor_addr = 0; 5562 5561 intel_crtc->dpms_mode = -1; 5563 - intel_crtc->active = true; /* force the pipe off on setup_init_config */ 5564 5562 } 5565 5563 5566 5564 static struct drm_crtc_helper_funcs intel_helper_funcs = { ··· 5664 5666 dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; 5665 5667 5666 5668 intel_crtc_reset(&intel_crtc->base); 5669 + intel_crtc->active = true; /* force the pipe off on setup_init_config */ 5667 5670 5668 5671 if (HAS_PCH_SPLIT(dev)) { 5669 5672 intel_helper_funcs.prepare = ironlake_crtc_prepare; ··· 6462 6463 } 6463 6464 } 6464 6465 6465 - void intel_disable_clock_gating(struct drm_device *dev) 6466 + static void ironlake_teardown_rc6(struct drm_device *dev) 6466 6467 { 6467 6468 struct drm_i915_private *dev_priv = dev->dev_private; 6468 6469 6469 6470 if (dev_priv->renderctx) { 6470 - struct drm_i915_gem_object *obj = dev_priv->renderctx; 6471 - 6472 - I915_WRITE(CCID, 0); 6473 - POSTING_READ(CCID); 6474 - 6475 - i915_gem_object_unpin(obj); 6476 - drm_gem_object_unreference(&obj->base); 6471 + i915_gem_object_unpin(dev_priv->renderctx); 6472 + drm_gem_object_unreference(&dev_priv->renderctx->base); 6477 6473 dev_priv->renderctx = NULL; 6478 6474 } 6479 6475 6480 6476 if (dev_priv->pwrctx) { 6481 - struct drm_i915_gem_object *obj = dev_priv->pwrctx; 6482 - 6483 - I915_WRITE(PWRCTXA, 0); 6484 - POSTING_READ(PWRCTXA); 6485 - 6486 - i915_gem_object_unpin(obj); 6487 - drm_gem_object_unreference(&obj->base); 6477 + i915_gem_object_unpin(dev_priv->pwrctx); 6478 + drm_gem_object_unreference(&dev_priv->pwrctx->base); 6488 6479 dev_priv->pwrctx = NULL; 6489 6480 } 6490 6481 } ··· 6483 6494 { 6484 6495 struct drm_i915_private *dev_priv = dev->dev_private; 6485 6496 6486 - /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */ 6487 - I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT); 6488 - wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON), 6489 - 10); 6490 - POSTING_READ(CCID); 6491 - I915_WRITE(PWRCTXA, 0); 6492 - POSTING_READ(PWRCTXA); 6493 - I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); 6494 - POSTING_READ(RSTDBYCTL); 6495 - i915_gem_object_unpin(dev_priv->renderctx); 6496 - drm_gem_object_unreference(&dev_priv->renderctx->base); 6497 - dev_priv->renderctx = NULL; 6498 - i915_gem_object_unpin(dev_priv->pwrctx); 6499 - drm_gem_object_unreference(&dev_priv->pwrctx->base); 6500 - dev_priv->pwrctx = NULL; 6497 + if (I915_READ(PWRCTXA)) { 6498 + /* Wake the GPU, prevent RC6, then restore RSTDBYCTL */ 6499 + I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) | RCX_SW_EXIT); 6500 + wait_for(((I915_READ(RSTDBYCTL) & RSX_STATUS_MASK) == RSX_STATUS_ON), 6501 + 50); 6502 + 6503 + I915_WRITE(PWRCTXA, 0); 6504 + POSTING_READ(PWRCTXA); 6505 + 6506 + I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); 6507 + POSTING_READ(RSTDBYCTL); 6508 + } 6509 + 6510 + ironlake_disable_rc6(dev); 6511 + } 6512 + 6513 + static int ironlake_setup_rc6(struct drm_device *dev) 6514 + { 6515 + struct drm_i915_private *dev_priv = dev->dev_private; 6516 + 6517 + if (dev_priv->renderctx == NULL) 6518 + dev_priv->renderctx = intel_alloc_context_page(dev); 6519 + if (!dev_priv->renderctx) 6520 + return -ENOMEM; 6521 + 6522 + if (dev_priv->pwrctx == NULL) 6523 + dev_priv->pwrctx = intel_alloc_context_page(dev); 6524 + if (!dev_priv->pwrctx) { 6525 + ironlake_teardown_rc6(dev); 6526 + return -ENOMEM; 6527 + } 6528 + 6529 + return 0; 6501 6530 } 6502 6531 6503 6532 void ironlake_enable_rc6(struct drm_device *dev) ··· 6523 6516 struct drm_i915_private *dev_priv = dev->dev_private; 6524 6517 int ret; 6525 6518 6519 + /* rc6 disabled by default due to repeated reports of hanging during 6520 + * boot and resume. 6521 + */ 6522 + if (!i915_enable_rc6) 6523 + return; 6524 + 6525 + ret = ironlake_setup_rc6(dev); 6526 + if (ret) 6527 + return; 6528 + 6526 6529 /* 6527 6530 * GPU can automatically power down the render unit if given a page 6528 6531 * to save state. 6529 6532 */ 6530 6533 ret = BEGIN_LP_RING(6); 6531 6534 if (ret) { 6532 - ironlake_disable_rc6(dev); 6535 + ironlake_teardown_rc6(dev); 6533 6536 return; 6534 6537 } 6538 + 6535 6539 OUT_RING(MI_SUSPEND_FLUSH | MI_SUSPEND_FLUSH_EN); 6536 6540 OUT_RING(MI_SET_CONTEXT); 6537 6541 OUT_RING(dev_priv->renderctx->gtt_offset | ··· 6558 6540 I915_WRITE(PWRCTXA, dev_priv->pwrctx->gtt_offset | PWRCTX_EN); 6559 6541 I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT); 6560 6542 } 6543 + 6561 6544 6562 6545 /* Set up chip specific display functions */ 6563 6546 static void intel_init_display(struct drm_device *dev) ··· 6802 6783 if (IS_GEN6(dev)) 6803 6784 gen6_enable_rps(dev_priv); 6804 6785 6805 - if (IS_IRONLAKE_M(dev)) { 6806 - dev_priv->renderctx = intel_alloc_context_page(dev); 6807 - if (!dev_priv->renderctx) 6808 - goto skip_rc6; 6809 - dev_priv->pwrctx = intel_alloc_context_page(dev); 6810 - if (!dev_priv->pwrctx) { 6811 - i915_gem_object_unpin(dev_priv->renderctx); 6812 - drm_gem_object_unreference(&dev_priv->renderctx->base); 6813 - dev_priv->renderctx = NULL; 6814 - goto skip_rc6; 6815 - } 6786 + if (IS_IRONLAKE_M(dev)) 6816 6787 ironlake_enable_rc6(dev); 6817 - } 6818 6788 6819 - skip_rc6: 6820 6789 INIT_WORK(&dev_priv->idle_work, intel_idle_update); 6821 6790 setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, 6822 6791 (unsigned long)dev);
+30 -6
drivers/gpu/drm/i915/intel_dp.c
··· 1639 1639 return 0; 1640 1640 } 1641 1641 1642 + static bool 1643 + intel_dp_detect_audio(struct drm_connector *connector) 1644 + { 1645 + struct intel_dp *intel_dp = intel_attached_dp(connector); 1646 + struct edid *edid; 1647 + bool has_audio = false; 1648 + 1649 + edid = drm_get_edid(connector, &intel_dp->adapter); 1650 + if (edid) { 1651 + has_audio = drm_detect_monitor_audio(edid); 1652 + 1653 + connector->display_info.raw_edid = NULL; 1654 + kfree(edid); 1655 + } 1656 + 1657 + return has_audio; 1658 + } 1659 + 1642 1660 static int 1643 1661 intel_dp_set_property(struct drm_connector *connector, 1644 1662 struct drm_property *property, ··· 1670 1652 return ret; 1671 1653 1672 1654 if (property == intel_dp->force_audio_property) { 1673 - if (val == intel_dp->force_audio) 1655 + int i = val; 1656 + bool has_audio; 1657 + 1658 + if (i == intel_dp->force_audio) 1674 1659 return 0; 1675 1660 1676 - intel_dp->force_audio = val; 1661 + intel_dp->force_audio = i; 1677 1662 1678 - if (val > 0 && intel_dp->has_audio) 1679 - return 0; 1680 - if (val < 0 && !intel_dp->has_audio) 1663 + if (i == 0) 1664 + has_audio = intel_dp_detect_audio(connector); 1665 + else 1666 + has_audio = i > 0; 1667 + 1668 + if (has_audio == intel_dp->has_audio) 1681 1669 return 0; 1682 1670 1683 - intel_dp->has_audio = val > 0; 1671 + intel_dp->has_audio = has_audio; 1684 1672 goto done; 1685 1673 } 1686 1674
-1
drivers/gpu/drm/i915/intel_drv.h
··· 298 298 extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, 299 299 u16 *blue, int regno); 300 300 extern void intel_enable_clock_gating(struct drm_device *dev); 301 - extern void intel_disable_clock_gating(struct drm_device *dev); 302 301 extern void ironlake_enable_drps(struct drm_device *dev); 303 302 extern void ironlake_disable_drps(struct drm_device *dev); 304 303 extern void gen6_enable_rps(struct drm_i915_private *dev_priv);
+33 -6
drivers/gpu/drm/i915/intel_hdmi.c
··· 251 251 &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); 252 252 } 253 253 254 + static bool 255 + intel_hdmi_detect_audio(struct drm_connector *connector) 256 + { 257 + struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); 258 + struct drm_i915_private *dev_priv = connector->dev->dev_private; 259 + struct edid *edid; 260 + bool has_audio = false; 261 + 262 + edid = drm_get_edid(connector, 263 + &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); 264 + if (edid) { 265 + if (edid->input & DRM_EDID_INPUT_DIGITAL) 266 + has_audio = drm_detect_monitor_audio(edid); 267 + 268 + connector->display_info.raw_edid = NULL; 269 + kfree(edid); 270 + } 271 + 272 + return has_audio; 273 + } 274 + 254 275 static int 255 276 intel_hdmi_set_property(struct drm_connector *connector, 256 277 struct drm_property *property, ··· 285 264 return ret; 286 265 287 266 if (property == intel_hdmi->force_audio_property) { 288 - if (val == intel_hdmi->force_audio) 267 + int i = val; 268 + bool has_audio; 269 + 270 + if (i == intel_hdmi->force_audio) 289 271 return 0; 290 272 291 - intel_hdmi->force_audio = val; 273 + intel_hdmi->force_audio = i; 292 274 293 - if (val > 0 && intel_hdmi->has_audio) 294 - return 0; 295 - if (val < 0 && !intel_hdmi->has_audio) 275 + if (i == 0) 276 + has_audio = intel_hdmi_detect_audio(connector); 277 + else 278 + has_audio = i > 0; 279 + 280 + if (has_audio == intel_hdmi->has_audio) 296 281 return 0; 297 282 298 - intel_hdmi->has_audio = val > 0; 283 + intel_hdmi->has_audio = has_audio; 299 284 goto done; 300 285 } 301 286
+6 -6
drivers/gpu/drm/i915/intel_lvds.c
··· 261 261 return true; 262 262 } 263 263 264 - /* Make sure pre-965s set dither correctly */ 265 - if (INTEL_INFO(dev)->gen < 4) { 266 - if (dev_priv->lvds_dither) 267 - pfit_control |= PANEL_8TO6_DITHER_ENABLE; 268 - } 269 - 270 264 /* Native modes don't need fitting */ 271 265 if (adjusted_mode->hdisplay == mode->hdisplay && 272 266 adjusted_mode->vdisplay == mode->vdisplay) ··· 368 374 } 369 375 370 376 out: 377 + /* If not enabling scaling, be consistent and always use 0. */ 371 378 if ((pfit_control & PFIT_ENABLE) == 0) { 372 379 pfit_control = 0; 373 380 pfit_pgm_ratios = 0; 374 381 } 382 + 383 + /* Make sure pre-965 set dither correctly */ 384 + if (INTEL_INFO(dev)->gen < 4 && dev_priv->lvds_dither) 385 + pfit_control |= PANEL_8TO6_DITHER_ENABLE; 386 + 375 387 if (pfit_control != intel_lvds->pfit_control || 376 388 pfit_pgm_ratios != intel_lvds->pfit_pgm_ratios) { 377 389 intel_lvds->pfit_control = pfit_control;
+16 -10
drivers/gpu/drm/i915/intel_ringbuffer.c
··· 1059 1059 } 1060 1060 1061 1061 static int gen6_ring_flush(struct intel_ring_buffer *ring, 1062 - u32 invalidate_domains, 1063 - u32 flush_domains) 1062 + u32 invalidate, u32 flush) 1064 1063 { 1064 + uint32_t cmd; 1065 1065 int ret; 1066 1066 1067 - if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) 1067 + if (((invalidate | flush) & I915_GEM_GPU_DOMAINS) == 0) 1068 1068 return 0; 1069 1069 1070 1070 ret = intel_ring_begin(ring, 4); 1071 1071 if (ret) 1072 1072 return ret; 1073 1073 1074 - intel_ring_emit(ring, MI_FLUSH_DW); 1074 + cmd = MI_FLUSH_DW; 1075 + if (invalidate & I915_GEM_GPU_DOMAINS) 1076 + cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD; 1077 + intel_ring_emit(ring, cmd); 1075 1078 intel_ring_emit(ring, 0); 1076 1079 intel_ring_emit(ring, 0); 1077 - intel_ring_emit(ring, 0); 1080 + intel_ring_emit(ring, MI_NOOP); 1078 1081 intel_ring_advance(ring); 1079 1082 return 0; 1080 1083 } ··· 1233 1230 } 1234 1231 1235 1232 static int blt_ring_flush(struct intel_ring_buffer *ring, 1236 - u32 invalidate_domains, 1237 - u32 flush_domains) 1233 + u32 invalidate, u32 flush) 1238 1234 { 1235 + uint32_t cmd; 1239 1236 int ret; 1240 1237 1241 - if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) 1238 + if (((invalidate | flush) & I915_GEM_DOMAIN_RENDER) == 0) 1242 1239 return 0; 1243 1240 1244 1241 ret = blt_ring_begin(ring, 4); 1245 1242 if (ret) 1246 1243 return ret; 1247 1244 1248 - intel_ring_emit(ring, MI_FLUSH_DW); 1245 + cmd = MI_FLUSH_DW; 1246 + if (invalidate & I915_GEM_DOMAIN_RENDER) 1247 + cmd |= MI_INVALIDATE_TLB; 1248 + intel_ring_emit(ring, cmd); 1249 1249 intel_ring_emit(ring, 0); 1250 1250 intel_ring_emit(ring, 0); 1251 - intel_ring_emit(ring, 0); 1251 + intel_ring_emit(ring, MI_NOOP); 1252 1252 intel_ring_advance(ring); 1253 1253 return 0; 1254 1254 }
+55 -11
drivers/gpu/drm/i915/intel_sdvo.c
··· 46 46 SDVO_TV_MASK) 47 47 48 48 #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) 49 + #define IS_TMDS(c) (c->output_flag & SDVO_TMDS_MASK) 49 50 #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) 50 51 #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) 51 52 ··· 1360 1359 intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); 1361 1360 intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); 1362 1361 } 1363 - } 1362 + } else 1363 + status = connector_status_disconnected; 1364 1364 connector->display_info.raw_edid = NULL; 1365 1365 kfree(edid); 1366 1366 } ··· 1409 1407 1410 1408 if ((intel_sdvo_connector->output_flag & response) == 0) 1411 1409 ret = connector_status_disconnected; 1412 - else if (response & SDVO_TMDS_MASK) 1410 + else if (IS_TMDS(intel_sdvo_connector)) 1413 1411 ret = intel_sdvo_hdmi_sink_detect(connector); 1414 - else 1415 - ret = connector_status_connected; 1412 + else { 1413 + struct edid *edid; 1414 + 1415 + /* if we have an edid check it matches the connection */ 1416 + edid = intel_sdvo_get_edid(connector); 1417 + if (edid == NULL) 1418 + edid = intel_sdvo_get_analog_edid(connector); 1419 + if (edid != NULL) { 1420 + if (edid->input & DRM_EDID_INPUT_DIGITAL) 1421 + ret = connector_status_disconnected; 1422 + else 1423 + ret = connector_status_connected; 1424 + connector->display_info.raw_edid = NULL; 1425 + kfree(edid); 1426 + } else 1427 + ret = connector_status_connected; 1428 + } 1416 1429 1417 1430 /* May update encoder flag for like clock for SDVO TV, etc.*/ 1418 1431 if (ret == connector_status_connected) { ··· 1463 1446 edid = intel_sdvo_get_analog_edid(connector); 1464 1447 1465 1448 if (edid != NULL) { 1466 - if (edid->input & DRM_EDID_INPUT_DIGITAL) { 1449 + struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); 1450 + bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); 1451 + bool connector_is_digital = !!IS_TMDS(intel_sdvo_connector); 1452 + 1453 + if (connector_is_digital == monitor_is_digital) { 1467 1454 drm_mode_connector_update_edid_property(connector, edid); 1468 1455 drm_add_edid_modes(connector, edid); 1469 1456 } 1457 + 1470 1458 connector->display_info.raw_edid = NULL; 1471 1459 kfree(edid); 1472 1460 } ··· 1690 1668 kfree(connector); 1691 1669 } 1692 1670 1671 + static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) 1672 + { 1673 + struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); 1674 + struct edid *edid; 1675 + bool has_audio = false; 1676 + 1677 + if (!intel_sdvo->is_hdmi) 1678 + return false; 1679 + 1680 + edid = intel_sdvo_get_edid(connector); 1681 + if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) 1682 + has_audio = drm_detect_monitor_audio(edid); 1683 + 1684 + return has_audio; 1685 + } 1686 + 1693 1687 static int 1694 1688 intel_sdvo_set_property(struct drm_connector *connector, 1695 1689 struct drm_property *property, ··· 1722 1684 return ret; 1723 1685 1724 1686 if (property == intel_sdvo_connector->force_audio_property) { 1725 - if (val == intel_sdvo_connector->force_audio) 1687 + int i = val; 1688 + bool has_audio; 1689 + 1690 + if (i == intel_sdvo_connector->force_audio) 1726 1691 return 0; 1727 1692 1728 - intel_sdvo_connector->force_audio = val; 1693 + intel_sdvo_connector->force_audio = i; 1729 1694 1730 - if (val > 0 && intel_sdvo->has_hdmi_audio) 1731 - return 0; 1732 - if (val < 0 && !intel_sdvo->has_hdmi_audio) 1695 + if (i == 0) 1696 + has_audio = intel_sdvo_detect_hdmi_audio(connector); 1697 + else 1698 + has_audio = i > 0; 1699 + 1700 + if (has_audio == intel_sdvo->has_hdmi_audio) 1733 1701 return 0; 1734 1702 1735 - intel_sdvo->has_hdmi_audio = val > 0; 1703 + intel_sdvo->has_hdmi_audio = has_audio; 1736 1704 goto done; 1737 1705 } 1738 1706
+30 -13
drivers/gpu/drm/i915/intel_tv.c
··· 1234 1234 * \return false if TV is disconnected. 1235 1235 */ 1236 1236 static int 1237 - intel_tv_detect_type (struct intel_tv *intel_tv) 1237 + intel_tv_detect_type (struct intel_tv *intel_tv, 1238 + struct drm_connector *connector) 1238 1239 { 1239 1240 struct drm_encoder *encoder = &intel_tv->base.base; 1240 1241 struct drm_device *dev = encoder->dev; ··· 1246 1245 int type; 1247 1246 1248 1247 /* Disable TV interrupts around load detect or we'll recurse */ 1249 - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); 1250 - i915_disable_pipestat(dev_priv, 0, 1251 - PIPE_HOTPLUG_INTERRUPT_ENABLE | 1252 - PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); 1253 - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); 1248 + if (connector->polled & DRM_CONNECTOR_POLL_HPD) { 1249 + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); 1250 + i915_disable_pipestat(dev_priv, 0, 1251 + PIPE_HOTPLUG_INTERRUPT_ENABLE | 1252 + PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); 1253 + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); 1254 + } 1254 1255 1255 1256 save_tv_dac = tv_dac = I915_READ(TV_DAC); 1256 1257 save_tv_ctl = tv_ctl = I915_READ(TV_CTL); ··· 1305 1302 I915_WRITE(TV_CTL, save_tv_ctl); 1306 1303 1307 1304 /* Restore interrupt config */ 1308 - spin_lock_irqsave(&dev_priv->irq_lock, irqflags); 1309 - i915_enable_pipestat(dev_priv, 0, 1310 - PIPE_HOTPLUG_INTERRUPT_ENABLE | 1311 - PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); 1312 - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); 1305 + if (connector->polled & DRM_CONNECTOR_POLL_HPD) { 1306 + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); 1307 + i915_enable_pipestat(dev_priv, 0, 1308 + PIPE_HOTPLUG_INTERRUPT_ENABLE | 1309 + PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); 1310 + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); 1311 + } 1313 1312 1314 1313 return type; 1315 1314 } ··· 1361 1356 drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); 1362 1357 1363 1358 if (intel_tv->base.base.crtc && intel_tv->base.base.crtc->enabled) { 1364 - type = intel_tv_detect_type(intel_tv); 1359 + type = intel_tv_detect_type(intel_tv, connector); 1365 1360 } else if (force) { 1366 1361 struct drm_crtc *crtc; 1367 1362 int dpms_mode; ··· 1369 1364 crtc = intel_get_load_detect_pipe(&intel_tv->base, connector, 1370 1365 &mode, &dpms_mode); 1371 1366 if (crtc) { 1372 - type = intel_tv_detect_type(intel_tv); 1367 + type = intel_tv_detect_type(intel_tv, connector); 1373 1368 intel_release_load_detect_pipe(&intel_tv->base, connector, 1374 1369 dpms_mode); 1375 1370 } else ··· 1662 1657 1663 1658 intel_encoder = &intel_tv->base; 1664 1659 connector = &intel_connector->base; 1660 + 1661 + /* The documentation, for the older chipsets at least, recommend 1662 + * using a polling method rather than hotplug detection for TVs. 1663 + * This is because in order to perform the hotplug detection, the PLLs 1664 + * for the TV must be kept alive increasing power drain and starving 1665 + * bandwidth from other encoders. Notably for instance, it causes 1666 + * pipe underruns on Crestline when this encoder is supposedly idle. 1667 + * 1668 + * More recent chipsets favour HDMI rather than integrated S-Video. 1669 + */ 1670 + connector->polled = 1671 + DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; 1665 1672 1666 1673 drm_connector_init(dev, connector, &intel_tv_connector_funcs, 1667 1674 DRM_MODE_CONNECTOR_SVIDEO);