@@ -1322,6 +1322,10 @@ extern void intel_irq_init(struct drm_device *dev);
extern void intel_gt_init(struct drm_device *dev);
extern void intel_gt_reset(struct drm_device *dev);
+extern u32 intel_crt_hotplug_int_status(struct drm_device *dev);
+extern u32 intel_sdvo_hotplug_int_status(struct drm_device *dev, bool is_sdvo_b);
+extern u32 intel_hotplug_int_status(struct drm_device *dev, enum port port);
+
void i915_error_state_free(struct kref *error_ref);
void
@@ -2765,3 +2765,74 @@ void intel_irq_init(struct drm_device *dev)
dev->driver->disable_vblank = i915_disable_vblank;
}
}
+
+u32 intel_hotplug_int_status(struct drm_device *dev, enum port port)
+{
+ /* SDVO is treated separately */
+ if (IS_IVYBRIDGE(dev) ||
+ IS_HASWELL(dev) ||
+ (HAS_PCH_SPLIT(dev) && HAS_PCH_CPT(dev))) {
+ switch (port) {
+ case PORT_B:
+ return SDE_PORTB_HOTPLUG_CPT;
+ case PORT_C:
+ return SDE_PORTC_HOTPLUG_CPT;
+ case PORT_D:
+ return SDE_PORTD_HOTPLUG_CPT;
+ default:
+ BUG();
+ }
+ } else if (HAS_PCH_SPLIT(dev)) { /* ! HAS_PCH_CPT(dev) */
+ switch (port) {
+ case PORT_B:
+ return SDE_PORTB_HOTPLUG;
+ case PORT_C:
+ return SDE_PORTC_HOTPLUG;
+ case PORT_D:
+ return SDE_PORTD_HOTPLUG;
+ default:
+ BUG();
+ }
+ } else {
+ switch (port) {
+ case PORT_B:
+ return HDMIB_HOTPLUG_INT_STATUS; /* same as PDB_HOTPLUG_INT_STATUS */
+ case PORT_C:
+ return HDMIC_HOTPLUG_INT_STATUS; /* same as PDB_HOTPLUG_INT_STATUS */
+ case PORT_D:
+ return HDMID_HOTPLUG_INT_STATUS; /* same as PDB_HOTPLUG_INT_STATUS */
+ default:
+ BUG();
+ }
+ }
+ return 0;
+}
+
+u32 intel_crt_hotplug_int_status(struct drm_device *dev)
+{
+ if (IS_IVYBRIDGE(dev) ||
+ IS_HASWELL(dev) ||
+ (HAS_PCH_SPLIT(dev) && HAS_PCH_CPT(dev))) {
+ return SDE_CRT_HOTPLUG_CPT;
+ } else if (HAS_PCH_SPLIT(dev)) { /* ! HAS_PCH_CPT(dev) */
+ return SDE_CRT_HOTPLUG;
+ } else {
+ return CRT_HOTPLUG_INT_STATUS;
+ }
+ return 0;
+}
+
+u32 intel_sdvo_hotplug_int_status(struct drm_device *dev, bool is_sdvo_b)
+{
+ if (IS_G4X(dev)) {
+ return is_sdvo_b ?
+ SDVOB_HOTPLUG_INT_STATUS_G4X : SDVOC_HOTPLUG_INT_STATUS_G4X;
+ } else if (IS_GEN4(dev)) {
+ return is_sdvo_b ?
+ SDVOB_HOTPLUG_INT_STATUS_I965 : SDVOC_HOTPLUG_INT_STATUS_I965;
+ } else {
+ return is_sdvo_b ?
+ SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915;
+ }
+ return 0;
+}
@@ -797,7 +797,7 @@ void intel_crt_init(struct drm_device *dev)
*/
crt->force_hotplug_required = 0;
- dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS;
+ dev_priv->hotplug_supported_mask |= intel_crt_hotplug_int_status(dev);
/*
* TODO: find a proper way to discover whether we need to set the
@@ -2754,21 +2754,19 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
name = "DPDDC-A";
break;
case PORT_B:
- dev_priv->hotplug_supported_mask |= DPB_HOTPLUG_INT_STATUS;
name = "DPDDC-B";
break;
case PORT_C:
- dev_priv->hotplug_supported_mask |= DPC_HOTPLUG_INT_STATUS;
name = "DPDDC-C";
break;
case PORT_D:
- dev_priv->hotplug_supported_mask |= DPD_HOTPLUG_INT_STATUS;
name = "DPDDC-D";
break;
default:
WARN(1, "Invalid port %c\n", port_name(port));
break;
}
+ dev_priv->hotplug_supported_mask |= intel_hotplug_int_status(dev, port);
if (is_edp(intel_dp))
intel_dp_init_panel_power_sequencer(dev, intel_dp);
@@ -980,21 +980,19 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
switch (port) {
case PORT_B:
intel_hdmi->ddc_bus = GMBUS_PORT_DPB;
- dev_priv->hotplug_supported_mask |= HDMIB_HOTPLUG_INT_STATUS;
break;
case PORT_C:
intel_hdmi->ddc_bus = GMBUS_PORT_DPC;
- dev_priv->hotplug_supported_mask |= HDMIC_HOTPLUG_INT_STATUS;
break;
case PORT_D:
intel_hdmi->ddc_bus = GMBUS_PORT_DPD;
- dev_priv->hotplug_supported_mask |= HDMID_HOTPLUG_INT_STATUS;
break;
case PORT_A:
/* Internal port only for eDP. */
default:
BUG();
}
+ dev_priv->hotplug_supported_mask |= intel_hotplug_int_status(dev, port);
if (!HAS_PCH_SPLIT(dev)) {
intel_hdmi->write_infoframe = g4x_write_infoframe;
@@ -2727,17 +2727,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
}
}
- hotplug_mask = 0;
- if (IS_G4X(dev)) {
- hotplug_mask = intel_sdvo->is_sdvob ?
- SDVOB_HOTPLUG_INT_STATUS_G4X : SDVOC_HOTPLUG_INT_STATUS_G4X;
- } else if (IS_GEN4(dev)) {
- hotplug_mask = intel_sdvo->is_sdvob ?
- SDVOB_HOTPLUG_INT_STATUS_I965 : SDVOC_HOTPLUG_INT_STATUS_I965;
- } else {
- hotplug_mask = intel_sdvo->is_sdvob ?
- SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915;
- }
+ hotplug_mask = intel_sdvo_hotplug_int_status(dev, intel_sdvo->is_sdvob);
drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs);
So far the hotplug_supported_mask in the struct drm_i915_private is only used for pre-Ironlake chipsets. This patch sets up the correct value for all generations. Signed-off-by: Egbert Eich <eich@suse.de> --- drivers/gpu/drm/i915/i915_drv.h | 4 ++ drivers/gpu/drm/i915/i915_irq.c | 71 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_crt.c | 2 +- drivers/gpu/drm/i915/intel_dp.c | 4 +-- drivers/gpu/drm/i915/intel_hdmi.c | 4 +-- drivers/gpu/drm/i915/intel_sdvo.c | 12 +------ 6 files changed, 79 insertions(+), 18 deletions(-)