bool sink_has_audio;
 
        struct mutex mutex;             /* for state below and previous_mode */
+       enum drm_connector_force force; /* mutex-protected force state */
        bool disabled;                  /* DRM has disabled our bridge */
+       bool bridge_is_on;              /* indicates the bridge is on */
 
        spinlock_t audio_lock;
        struct mutex audio_mutex;
 
 static void dw_hdmi_poweron(struct dw_hdmi *hdmi)
 {
+       hdmi->bridge_is_on = true;
        dw_hdmi_setup(hdmi, &hdmi->previous_mode);
 }
 
 static void dw_hdmi_poweroff(struct dw_hdmi *hdmi)
 {
        dw_hdmi_phy_disable(hdmi);
+       hdmi->bridge_is_on = false;
+}
+
+static void dw_hdmi_update_power(struct dw_hdmi *hdmi)
+{
+       int force = hdmi->force;
+
+       if (hdmi->disabled) {
+               force = DRM_FORCE_OFF;
+       } else if (force == DRM_FORCE_UNSPECIFIED) {
+               if (hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD)
+                       force = DRM_FORCE_ON;
+               else
+                       force = DRM_FORCE_OFF;
+       }
+
+       if (force == DRM_FORCE_OFF) {
+               if (hdmi->bridge_is_on)
+                       dw_hdmi_poweroff(hdmi);
+       } else {
+               if (!hdmi->bridge_is_on)
+                       dw_hdmi_poweron(hdmi);
+       }
 }
 
 static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge,
 
        mutex_lock(&hdmi->mutex);
        hdmi->disabled = true;
-       dw_hdmi_poweroff(hdmi);
+       dw_hdmi_update_power(hdmi);
        mutex_unlock(&hdmi->mutex);
 }
 
        struct dw_hdmi *hdmi = bridge->driver_private;
 
        mutex_lock(&hdmi->mutex);
-       dw_hdmi_poweron(hdmi);
        hdmi->disabled = false;
+       dw_hdmi_update_power(hdmi);
        mutex_unlock(&hdmi->mutex);
 }
 
        struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
                                             connector);
 
+       mutex_lock(&hdmi->mutex);
+       hdmi->force = DRM_FORCE_UNSPECIFIED;
+       dw_hdmi_update_power(hdmi);
+       mutex_unlock(&hdmi->mutex);
+
        return hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_HPD ?
                connector_status_connected : connector_status_disconnected;
 }
        drm_connector_cleanup(connector);
 }
 
+static void dw_hdmi_connector_force(struct drm_connector *connector)
+{
+       struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
+                                            connector);
+
+       mutex_lock(&hdmi->mutex);
+       hdmi->force = connector->force;
+       dw_hdmi_update_power(hdmi);
+       mutex_unlock(&hdmi->mutex);
+}
+
 static struct drm_connector_funcs dw_hdmi_connector_funcs = {
        .dpms = drm_helper_connector_dpms,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .detect = dw_hdmi_connector_detect,
        .destroy = dw_hdmi_connector_destroy,
+       .force = dw_hdmi_connector_force,
 };
 
 static struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
                if (phy_int_pol & HDMI_PHY_HPD) {
                        dev_dbg(hdmi->dev, "EVENT=plugin\n");
 
-                       if (!hdmi->disabled)
+                       if (!hdmi->disabled && !hdmi->force)
                                dw_hdmi_poweron(hdmi);
                } else {
                        dev_dbg(hdmi->dev, "EVENT=plugout\n");
 
-                       if (!hdmi->disabled)
+                       if (!hdmi->disabled && !hdmi->force)
                                dw_hdmi_poweroff(hdmi);
                }
                mutex_unlock(&hdmi->mutex);