Skip to content

Commit

Permalink
drm/i915: force full detect on sink count change
Browse files Browse the repository at this point in the history
This patch checks for changes in sink count between short pulse
hpds and forces full detect when there is a change.

This will allow both detection of hotplug and unplug of panels
through dongles that give only short pulse for such events.

v2: changed variable type from u8 to bool (Jani)
    return immediately if perform_full_detect is set(Siva)

v3: changed method of determining full detection from using
    pointer to return code (Siva)

v4: changed comments to indicate meaning of return value of
    intel_dp_short_pulse and explain the use of return value
    from intel_dp_get_dpcd in intel_dp_short_pulse (Ander)

Tested-by: Nathan D Ciobanu <nathan.d.ciobanu@intel.com>
Signed-off-by: Sivakumar Thulasimani <sivakumar.thulasimani@intel.com>
Signed-off-by: Shubhangi Shrivastava <shubhangi.shrivastava@intel.com>
Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com>
Signed-off-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1459341326-13142-5-git-send-email-shubhangi.shrivastava@intel.com
  • Loading branch information
Shubhangi Shrivastava authored and Ander Conselvan de Oliveira committed Apr 1, 2016
1 parent 30d9aa4 commit 39ff747
Showing 1 changed file with 27 additions and 6 deletions.
33 changes: 27 additions & 6 deletions drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4273,12 +4273,19 @@ intel_dp_check_link_status(struct intel_dp *intel_dp)
* 2. Configure link according to Receiver Capabilities
* 3. Use Link Training from 2.5.3.3 and 3.5.1.3
* 4. Check link status on receipt of hot-plug interrupt
*
* intel_dp_short_pulse - handles short pulse interrupts
* when full detection is not required.
* Returns %true if short pulse is handled and full detection
* is NOT required and %false otherwise.
*/
static void
static bool
intel_dp_short_pulse(struct intel_dp *intel_dp)
{
struct drm_device *dev = intel_dp_to_dev(intel_dp);
u8 sink_irq_vector;
u8 old_sink_count = intel_dp->sink_count;
bool ret;

/*
* Clearing compliance test variables to allow capturing
Expand All @@ -4288,9 +4295,17 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
intel_dp->compliance_test_type = 0;
intel_dp->compliance_test_data = 0;

/* Now read the DPCD to see if it's actually running */
if (!intel_dp_get_dpcd(intel_dp)) {
return;
/*
* Now read the DPCD to see if it's actually running
* If the current value of sink count doesn't match with
* the value that was stored earlier or dpcd read failed
* we need to do full detection
*/
ret = intel_dp_get_dpcd(intel_dp);

if ((old_sink_count != intel_dp->sink_count) || !ret) {
/* No need to proceed if we are going to do full detect */
return false;
}

/* Try to read the source of the interrupt */
Expand All @@ -4310,6 +4325,8 @@ intel_dp_short_pulse(struct intel_dp *intel_dp)
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
intel_dp_check_link_status(intel_dp);
drm_modeset_unlock(&dev->mode_config.connection_mutex);

return true;
}

/* XXX this is probably wrong for multiple downstream ports */
Expand Down Expand Up @@ -5043,8 +5060,12 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
}
}

if (!intel_dp->is_mst)
intel_dp_short_pulse(intel_dp);
if (!intel_dp->is_mst) {
if (!intel_dp_short_pulse(intel_dp)) {
intel_dp_long_pulse(intel_dp->attached_connector);
goto put_power;
}
}
}

ret = IRQ_HANDLED;
Expand Down

0 comments on commit 39ff747

Please sign in to comment.