aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorEgbert Eich <eich@suse.de>2013-04-16 07:36:55 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-04-18 03:43:29 -0400
commit821450c6938d9228d8569d54d5c369985b1cc8dd (patch)
tree36ea50f1694ef603d63717c3008f873e1768a353 /drivers/gpu
parentb543fb0464ddf30a5b554957fd212eb7a2acac65 (diff)
drm/i915: (re)init HPD interrupt storm statistics
When an encoder is shared on several connectors there is only one hotplug line, thus this line needs to be shared among these connectors. If HPD detect only works reliably on a subset of those connectors, we want to poll the others. Thus we need to make sure that storm detection doesn't mess up the settings for those connectors. Therefore we store the settings in the intel_connector struct and restore them from there. If nothing is set but the encoder has a hpd_pin set we assume this connector is hotplug capable. On init/reset we make sure the polled state of the connectors is (re)set to the default value, the HPD interrupts are marked enabled. Signed-off-by: Egbert Eich <eich@suse.de> Reviewed-by: Jani Nikula <jani.nikula@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c14
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c6
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c1
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h4
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c1
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c5
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c2
7 files changed, 23 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 5ac1291c5853..2b4967014dc6 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -596,6 +596,7 @@ static inline void hotplug_irq_storm_detect(struct drm_device *dev,
596 spin_lock_irqsave(&dev_priv->irq_lock, irqflags); 596 spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
597 597
598 for (i = 1; i < HPD_NUM_PINS; i++) { 598 for (i = 1; i < HPD_NUM_PINS; i++) {
599
599 if (!(hpd[i] & hotplug_trigger) || 600 if (!(hpd[i] & hotplug_trigger) ||
600 dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED) 601 dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED)
601 continue; 602 continue;
@@ -3062,7 +3063,20 @@ void intel_irq_init(struct drm_device *dev)
3062void intel_hpd_init(struct drm_device *dev) 3063void intel_hpd_init(struct drm_device *dev)
3063{ 3064{
3064 struct drm_i915_private *dev_priv = dev->dev_private; 3065 struct drm_i915_private *dev_priv = dev->dev_private;
3066 struct drm_mode_config *mode_config = &dev->mode_config;
3067 struct drm_connector *connector;
3068 int i;
3065 3069
3070 for (i = 1; i < HPD_NUM_PINS; i++) {
3071 dev_priv->hpd_stats[i].hpd_cnt = 0;
3072 dev_priv->hpd_stats[i].hpd_mark = HPD_ENABLED;
3073 }
3074 list_for_each_entry(connector, &mode_config->connector_list, head) {
3075 struct intel_connector *intel_connector = to_intel_connector(connector);
3076 connector->polled = intel_connector->polled;
3077 if (!connector->polled && I915_HAS_HOTPLUG(dev) && intel_connector->encoder->hpd_pin > HPD_NONE)
3078 connector->polled = DRM_CONNECTOR_POLL_HPD;
3079 }
3066 if (dev_priv->display.hpd_irq_setup) 3080 if (dev_priv->display.hpd_irq_setup)
3067 dev_priv->display.hpd_irq_setup(dev); 3081 dev_priv->display.hpd_irq_setup(dev);
3068} 3082}
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 1ae2d7f39c6f..c063b9f0dd51 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -793,10 +793,8 @@ void intel_crt_init(struct drm_device *dev)
793 793
794 drm_sysfs_connector_add(connector); 794 drm_sysfs_connector_add(connector);
795 795
796 if (I915_HAS_HOTPLUG(dev)) 796 if (!I915_HAS_HOTPLUG(dev))
797 connector->polled = DRM_CONNECTOR_POLL_HPD; 797 intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
798 else
799 connector->polled = DRM_CONNECTOR_POLL_CONNECT;
800 798
801 /* 799 /*
802 * Configure the automatic hotplug detection stuff 800 * Configure the automatic hotplug detection stuff
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 8845e82ec9ed..89f89b727900 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2787,7 +2787,6 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
2787 drm_connector_init(dev, connector, &intel_dp_connector_funcs, type); 2787 drm_connector_init(dev, connector, &intel_dp_connector_funcs, type);
2788 drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); 2788 drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs);
2789 2789
2790 connector->polled = DRM_CONNECTOR_POLL_HPD;
2791 connector->interlace_allowed = true; 2790 connector->interlace_allowed = true;
2792 connector->doublescan_allowed = 0; 2791 connector->doublescan_allowed = 0;
2793 2792
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a124e05fb581..7b97b9a1523e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -171,6 +171,10 @@ struct intel_connector {
171 171
172 /* Cached EDID for eDP and LVDS. May hold ERR_PTR for invalid EDID. */ 172 /* Cached EDID for eDP and LVDS. May hold ERR_PTR for invalid EDID. */
173 struct edid *edid; 173 struct edid *edid;
174
175 /* since POLL and HPD connectors may use the same HPD line keep the native
176 state of connector->polled in case hotplug storm detection changes it */
177 u8 polled;
174}; 178};
175 179
176struct intel_crtc_config { 180struct intel_crtc_config {
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index ee4a8da8311e..89122011720b 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -998,7 +998,6 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
998 DRM_MODE_CONNECTOR_HDMIA); 998 DRM_MODE_CONNECTOR_HDMIA);
999 drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs); 999 drm_connector_helper_add(connector, &intel_hdmi_connector_helper_funcs);
1000 1000
1001 connector->polled = DRM_CONNECTOR_POLL_HPD;
1002 connector->interlace_allowed = 1; 1001 connector->interlace_allowed = 1;
1003 connector->doublescan_allowed = 0; 1002 connector->doublescan_allowed = 0;
1004 1003
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index f6a9f4a0d7f0..a618a6a45a77 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -2274,7 +2274,6 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
2274 connector = &intel_connector->base; 2274 connector = &intel_connector->base;
2275 if (intel_sdvo_get_hotplug_support(intel_sdvo) & 2275 if (intel_sdvo_get_hotplug_support(intel_sdvo) &
2276 intel_sdvo_connector->output_flag) { 2276 intel_sdvo_connector->output_flag) {
2277 connector->polled = DRM_CONNECTOR_POLL_HPD;
2278 intel_sdvo->hotplug_active |= intel_sdvo_connector->output_flag; 2277 intel_sdvo->hotplug_active |= intel_sdvo_connector->output_flag;
2279 /* Some SDVO devices have one-shot hotplug interrupts. 2278 /* Some SDVO devices have one-shot hotplug interrupts.
2280 * Ensure that they get re-enabled when an interrupt happens. 2279 * Ensure that they get re-enabled when an interrupt happens.
@@ -2282,7 +2281,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
2282 intel_encoder->hot_plug = intel_sdvo_enable_hotplug; 2281 intel_encoder->hot_plug = intel_sdvo_enable_hotplug;
2283 intel_sdvo_enable_hotplug(intel_encoder); 2282 intel_sdvo_enable_hotplug(intel_encoder);
2284 } else { 2283 } else {
2285 connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; 2284 intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
2286 } 2285 }
2287 encoder->encoder_type = DRM_MODE_ENCODER_TMDS; 2286 encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
2288 connector->connector_type = DRM_MODE_CONNECTOR_DVID; 2287 connector->connector_type = DRM_MODE_CONNECTOR_DVID;
@@ -2351,7 +2350,7 @@ intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device)
2351 2350
2352 intel_connector = &intel_sdvo_connector->base; 2351 intel_connector = &intel_sdvo_connector->base;
2353 connector = &intel_connector->base; 2352 connector = &intel_connector->base;
2354 connector->polled = DRM_CONNECTOR_POLL_CONNECT; 2353 intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
2355 encoder->encoder_type = DRM_MODE_ENCODER_DAC; 2354 encoder->encoder_type = DRM_MODE_ENCODER_DAC;
2356 connector->connector_type = DRM_MODE_CONNECTOR_VGA; 2355 connector->connector_type = DRM_MODE_CONNECTOR_VGA;
2357 2356
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index 66737265200f..b945bc54207a 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1613,7 +1613,7 @@ intel_tv_init(struct drm_device *dev)
1613 * 1613 *
1614 * More recent chipsets favour HDMI rather than integrated S-Video. 1614 * More recent chipsets favour HDMI rather than integrated S-Video.
1615 */ 1615 */
1616 connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1616 intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1617 1617
1618 drm_connector_init(dev, connector, &intel_tv_connector_funcs, 1618 drm_connector_init(dev, connector, &intel_tv_connector_funcs,
1619 DRM_MODE_CONNECTOR_SVIDEO); 1619 DRM_MODE_CONNECTOR_SVIDEO);