On some (well, maybe just one) HDMI monitor I get a spurious disconnect in the process of lighting up the display. A low-pass filter on HPD events, in the form of leaving the HPD irq disabled for 100ms after the previous HPD irq, seems to do a good job of working around the issue. A somewhat simpler solution is just msleep(100) in the hotplug worker. But AFAIU that will interfere with the pending HDCP support, if HDCP requires guarantees about detecting disconnect in a timely fashion. Signed-off-by: Rob Clark <robdclark@xxxxxxxxx> --- drivers/gpu/drm/msm/hdmi/hdmi_connector.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c index bc20e9b..f481f54 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c @@ -24,6 +24,7 @@ struct hdmi_connector { struct drm_connector base; struct hdmi *hdmi; struct work_struct hpd_work; + struct timer_list hotplug_timer; }; #define to_hdmi_connector(x) container_of(x, struct hdmi_connector, base) @@ -228,11 +229,25 @@ static void hdp_disable(struct hdmi_connector *hdmi_connector) } static void +hotplug_timer(unsigned long data) +{ + struct hdmi *hdmi = (struct hdmi *)data; + uint32_t hpd_int_ctrl; + + /* re-enable HPD irq: */ + hpd_int_ctrl = hdmi_read(hdmi, REG_HDMI_HPD_INT_CTRL); + hpd_int_ctrl |= HDMI_HPD_INT_CTRL_INT_EN; + hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, hpd_int_ctrl); +} + +static void hotplug_work(struct work_struct *work) { struct hdmi_connector *hdmi_connector = container_of(work, struct hdmi_connector, hpd_work); struct drm_connector *connector = &hdmi_connector->base; + mod_timer(&hdmi_connector->hotplug_timer, + round_jiffies_up(jiffies + msecs_to_jiffies(100))); drm_helper_hpd_irq_event(connector->dev); } @@ -258,7 +273,7 @@ void hdmi_connector_irq(struct drm_connector *connector) DBG("status=%04x, ctrl=%04x", hpd_int_status, hpd_int_ctrl); /* detect disconnect if we are connected or visa versa: */ - hpd_int_ctrl = HDMI_HPD_INT_CTRL_INT_EN; + hpd_int_ctrl = 0; if (!detected) hpd_int_ctrl |= HDMI_HPD_INT_CTRL_INT_CONNECT; hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, hpd_int_ctrl); @@ -416,6 +431,8 @@ struct drm_connector *hdmi_connector_init(struct hdmi *hdmi) hdmi_connector->hdmi = hdmi; INIT_WORK(&hdmi_connector->hpd_work, hotplug_work); + setup_timer(&hdmi_connector->hotplug_timer, hotplug_timer, + (unsigned long)hdmi); connector = &hdmi_connector->base; -- 2.1.0 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel