Merge drm/drm-next into drm-misc-next
[sfrench/cifs-2.6.git] / drivers / gpu / drm / msm / dp / dp_display.c
index 766c8d01e6b3e0fac7f76da5f13e469a7e2aa6ef..c8e1bbebdffe24934c1feaf4bdd3473cd278479e 100644 (file)
@@ -50,13 +50,11 @@ enum {
        ST_CONNECTED,
        ST_DISCONNECT_PENDING,
        ST_DISPLAY_OFF,
-       ST_SUSPENDED,
 };
 
 enum {
        EV_NO_EVENT,
        /* hpd events */
-       EV_HPD_INIT_SETUP,
        EV_HPD_PLUG_INT,
        EV_IRQ_HPD_INT,
        EV_HPD_UNPLUG_INT,
@@ -171,6 +169,11 @@ static const struct msm_dp_desc sm8350_dp_descs[] = {
        {}
 };
 
+static const struct msm_dp_desc sm8650_dp_descs[] = {
+       { .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort },
+       {}
+};
+
 static const struct of_device_id dp_dt_match[] = {
        { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },
        { .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },
@@ -181,6 +184,7 @@ static const struct of_device_id dp_dt_match[] = {
        { .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_edp_descs },
        { .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs },
        { .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_descs },
+       { .compatible = "qcom,sm8650-dp", .data = &sm8650_dp_descs },
        {}
 };
 
@@ -276,11 +280,6 @@ static int dp_display_bind(struct device *dev, struct device *master,
        dp->dp_display.drm_dev = drm;
        priv->dp[dp->id] = &dp->dp_display;
 
-       rc = dp->parser->parse(dp->parser);
-       if (rc) {
-               DRM_ERROR("device tree parsing failed\n");
-               goto end;
-       }
 
 
        dp->drm_dev = drm;
@@ -291,11 +290,6 @@ static int dp_display_bind(struct device *dev, struct device *master,
                goto end;
        }
 
-       rc = dp_power_client_init(dp->power);
-       if (rc) {
-               DRM_ERROR("Power client create failed\n");
-               goto end;
-       }
 
        rc = dp_register_audio_driver(dev, dp->audio);
        if (rc) {
@@ -320,15 +314,10 @@ static void dp_display_unbind(struct device *dev, struct device *master,
        struct dp_display_private *dp = dev_get_dp_display_private(dev);
        struct msm_drm_private *priv = dev_get_drvdata(master);
 
-       /* disable all HPD interrupts */
-       if (dp->core_initialized)
-               dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);
-
        kthread_stop(dp->ev_tsk);
 
        of_dp_aux_depopulate_bus(dp->aux);
 
-       dp_power_client_deinit(dp->power);
        dp_unregister_audio_driver(dev, dp->audio);
        dp_aux_unregister(dp->aux);
        dp->drm_dev = NULL;
@@ -341,27 +330,10 @@ static const struct component_ops dp_display_comp_ops = {
        .unbind = dp_display_unbind,
 };
 
-static void dp_display_send_hpd_event(struct msm_dp *dp_display)
-{
-       struct dp_display_private *dp;
-       struct drm_connector *connector;
-
-       dp = container_of(dp_display, struct dp_display_private, dp_display);
-
-       connector = dp->dp_display.connector;
-       drm_helper_hpd_irq_event(connector->dev);
-}
-
-
 static int dp_display_send_hpd_notification(struct dp_display_private *dp,
                                            bool hpd)
 {
-       if ((hpd && dp->dp_display.is_connected) ||
-                       (!hpd && !dp->dp_display.is_connected)) {
-               drm_dbg_dp(dp->drm_dev, "HPD already %s\n",
-                               (hpd ? "on" : "off"));
-               return 0;
-       }
+       struct drm_bridge *bridge = dp->dp_display.bridge;
 
        /* reset video pattern flag on disconnect */
        if (!hpd) {
@@ -373,11 +345,11 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp,
                                                         dp->panel->downstream_ports);
        }
 
-       dp->dp_display.is_connected = hpd;
+       dp->dp_display.link_ready = hpd;
 
        drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n",
                        dp->dp_display.connector_type, hpd);
-       dp_display_send_hpd_event(&dp->dp_display);
+       drm_bridge_hpd_notify(bridge, dp->dp_display.link_ready);
 
        return 0;
 }
@@ -576,6 +548,7 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)
 {
        u32 state;
        int ret;
+       struct platform_device *pdev = dp->dp_display.pdev;
 
        mutex_lock(&dp->event_mutex);
 
@@ -583,7 +556,7 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)
        drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
                        dp->dp_display.connector_type, state);
 
-       if (state == ST_DISPLAY_OFF || state == ST_SUSPENDED) {
+       if (state == ST_DISPLAY_OFF) {
                mutex_unlock(&dp->event_mutex);
                return 0;
        }
@@ -600,7 +573,14 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)
                return 0;
        }
 
-       ret = dp_display_usbpd_configure_cb(&dp->dp_display.pdev->dev);
+       ret = pm_runtime_resume_and_get(&pdev->dev);
+       if (ret) {
+               DRM_ERROR("failed to pm_runtime_resume\n");
+               mutex_unlock(&dp->event_mutex);
+               return ret;
+       }
+
+       ret = dp_display_usbpd_configure_cb(&pdev->dev);
        if (ret) {      /* link train failed */
                dp->hpd_state = ST_DISCONNECTED;
        } else {
@@ -632,6 +612,7 @@ static void dp_display_handle_plugged_change(struct msm_dp *dp_display,
 static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
 {
        u32 state;
+       struct platform_device *pdev = dp->dp_display.pdev;
 
        mutex_lock(&dp->event_mutex);
 
@@ -682,6 +663,7 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
                        dp->dp_display.connector_type, state);
 
        /* uevent will complete disconnection part */
+       pm_runtime_put_sync(&pdev->dev);
        mutex_unlock(&dp->event_mutex);
        return 0;
 }
@@ -697,7 +679,7 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data)
        drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",
                        dp->dp_display.connector_type, state);
 
-       if (state == ST_DISPLAY_OFF || state == ST_SUSPENDED) {
+       if (state == ST_DISPLAY_OFF) {
                mutex_unlock(&dp->event_mutex);
                return 0;
        }
@@ -721,7 +703,6 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data)
 
 static void dp_display_deinit_sub_modules(struct dp_display_private *dp)
 {
-       dp_debug_put(dp->debug);
        dp_audio_put(dp->audio);
        dp_panel_put(dp->panel);
        dp_aux_put(dp->aux);
@@ -919,7 +900,7 @@ int dp_display_set_plugged_cb(struct msm_dp *dp_display,
 
        dp_display->plugged_cb = fn;
        dp_display->codec_dev = codec_dev;
-       plugged = dp_display->is_connected;
+       plugged = dp_display->link_ready;
        dp_display_handle_plugged_change(dp_display, plugged);
 
        return 0;
@@ -1109,9 +1090,6 @@ static int hpd_event_thread(void *data)
                spin_unlock_irqrestore(&dp_priv->event_lock, flag);
 
                switch (todo->event_id) {
-               case EV_HPD_INIT_SETUP:
-                       dp_display_host_init(dp_priv);
-                       break;
                case EV_HPD_PLUG_INT:
                        dp_hpd_plug_handle(dp_priv, todo->data);
                        break;
@@ -1190,27 +1168,21 @@ static irqreturn_t dp_display_irq_handler(int irq, void *dev_id)
        return ret;
 }
 
-int dp_display_request_irq(struct msm_dp *dp_display)
+static int dp_display_request_irq(struct dp_display_private *dp)
 {
        int rc = 0;
-       struct dp_display_private *dp;
-
-       if (!dp_display) {
-               DRM_ERROR("invalid input\n");
-               return -EINVAL;
-       }
+       struct platform_device *pdev = dp->dp_display.pdev;
 
-       dp = container_of(dp_display, struct dp_display_private, dp_display);
-
-       dp->irq = irq_of_parse_and_map(dp->dp_display.pdev->dev.of_node, 0);
-       if (!dp->irq) {
+       dp->irq = platform_get_irq(pdev, 0);
+       if (dp->irq < 0) {
                DRM_ERROR("failed to get irq\n");
-               return -EINVAL;
+               return dp->irq;
        }
 
-       rc = devm_request_irq(dp_display->drm_dev->dev, dp->irq,
-                       dp_display_irq_handler,
-                       IRQF_TRIGGER_HIGH, "dp_display_isr", dp);
+       rc = devm_request_irq(&pdev->dev, dp->irq, dp_display_irq_handler,
+                             IRQF_TRIGGER_HIGH|IRQF_NO_AUTOEN,
+                             "dp_display_isr", dp);
+
        if (rc < 0) {
                DRM_ERROR("failed to request IRQ%u: %d\n",
                                dp->irq, rc);
@@ -1239,6 +1211,29 @@ static const struct msm_dp_desc *dp_display_get_desc(struct platform_device *pde
        return NULL;
 }
 
+static int dp_display_get_next_bridge(struct msm_dp *dp);
+
+static int dp_display_probe_tail(struct device *dev)
+{
+       struct msm_dp *dp = dev_get_drvdata(dev);
+       int ret;
+
+       ret = dp_display_get_next_bridge(dp);
+       if (ret)
+               return ret;
+
+       ret = component_add(dev, &dp_display_comp_ops);
+       if (ret)
+               DRM_ERROR("component add failed, rc=%d\n", ret);
+
+       return ret;
+}
+
+static int dp_auxbus_done_probe(struct drm_dp_aux *aux)
+{
+       return dp_display_probe_tail(aux->dev);
+}
+
 static int dp_display_probe(struct platform_device *pdev)
 {
        int rc = 0;
@@ -1272,6 +1267,18 @@ static int dp_display_probe(struct platform_device *pdev)
                return -EPROBE_DEFER;
        }
 
+       rc = dp->parser->parse(dp->parser);
+       if (rc) {
+               DRM_ERROR("device tree parsing failed\n");
+               goto err;
+       }
+
+       rc = dp_power_client_init(dp->power);
+       if (rc) {
+               DRM_ERROR("Power client create failed\n");
+               goto err;
+       }
+
        /* setup event q */
        mutex_init(&dp->event_mutex);
        init_waitqueue_head(&dp->event_q);
@@ -1284,13 +1291,31 @@ static int dp_display_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, &dp->dp_display);
 
-       rc = component_add(&pdev->dev, &dp_display_comp_ops);
-       if (rc) {
-               DRM_ERROR("component add failed, rc=%d\n", rc);
-               dp_display_deinit_sub_modules(dp);
+       rc = devm_pm_runtime_enable(&pdev->dev);
+       if (rc)
+               goto err;
+
+       rc = dp_display_request_irq(dp);
+       if (rc)
+               goto err;
+
+       if (dp->dp_display.is_edp) {
+               rc = devm_of_dp_aux_populate_bus(dp->aux, dp_auxbus_done_probe);
+               if (rc) {
+                       DRM_ERROR("eDP auxbus population failed, rc=%d\n", rc);
+                       goto err;
+               }
+       } else {
+               rc = dp_display_probe_tail(&pdev->dev);
+               if (rc)
+                       goto err;
        }
 
        return rc;
+
+err:
+       dp_display_deinit_sub_modules(dp);
+       return rc;
 }
 
 static void dp_display_remove(struct platform_device *pdev)
@@ -1299,113 +1324,50 @@ static void dp_display_remove(struct platform_device *pdev)
 
        component_del(&pdev->dev, &dp_display_comp_ops);
        dp_display_deinit_sub_modules(dp);
-
        platform_set_drvdata(pdev, NULL);
 }
 
-static int dp_pm_resume(struct device *dev)
+static int dp_pm_runtime_suspend(struct device *dev)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct msm_dp *dp_display = platform_get_drvdata(pdev);
-       struct dp_display_private *dp;
-       int sink_count = 0;
-
-       dp = container_of(dp_display, struct dp_display_private, dp_display);
-
-       mutex_lock(&dp->event_mutex);
-
-       drm_dbg_dp(dp->drm_dev,
-               "Before, type=%d core_inited=%d phy_inited=%d power_on=%d\n",
-               dp->dp_display.connector_type, dp->core_initialized,
-               dp->phy_initialized, dp_display->power_on);
-
-       /* start from disconnected state */
-       dp->hpd_state = ST_DISCONNECTED;
-
-       /* turn on dp ctrl/phy */
-       dp_display_host_init(dp);
-
-       if (dp_display->is_edp)
-               dp_catalog_ctrl_hpd_enable(dp->catalog);
+       struct dp_display_private *dp = dev_get_dp_display_private(dev);
 
-       if (dp_catalog_link_is_connected(dp->catalog)) {
-               /*
-                * set sink to normal operation mode -- D0
-                * before dpcd read
-                */
-               dp_display_host_phy_init(dp);
-               dp_link_psm_config(dp->link, &dp->panel->link_info, false);
-               sink_count = drm_dp_read_sink_count(dp->aux);
-               if (sink_count < 0)
-                       sink_count = 0;
+       disable_irq(dp->irq);
 
+       if (dp->dp_display.is_edp) {
                dp_display_host_phy_exit(dp);
+               dp_catalog_ctrl_hpd_disable(dp->catalog);
        }
-
-       dp->link->sink_count = sink_count;
-       /*
-        * can not declared display is connected unless
-        * HDMI cable is plugged in and sink_count of
-        * dongle become 1
-        * also only signal audio when disconnected
-        */
-       if (dp->link->sink_count) {
-               dp->dp_display.is_connected = true;
-       } else {
-               dp->dp_display.is_connected = false;
-               dp_display_handle_plugged_change(dp_display, false);
-       }
-
-       drm_dbg_dp(dp->drm_dev,
-               "After, type=%d sink=%d conn=%d core_init=%d phy_init=%d power=%d\n",
-               dp->dp_display.connector_type, dp->link->sink_count,
-               dp->dp_display.is_connected, dp->core_initialized,
-               dp->phy_initialized, dp_display->power_on);
-
-       mutex_unlock(&dp->event_mutex);
+       dp_display_host_deinit(dp);
 
        return 0;
 }
 
-static int dp_pm_suspend(struct device *dev)
+static int dp_pm_runtime_resume(struct device *dev)
 {
-       struct platform_device *pdev = to_platform_device(dev);
-       struct msm_dp *dp_display = platform_get_drvdata(pdev);
-       struct dp_display_private *dp;
-
-       dp = container_of(dp_display, struct dp_display_private, dp_display);
-
-       mutex_lock(&dp->event_mutex);
-
-       drm_dbg_dp(dp->drm_dev,
-               "Before, type=%d core_inited=%d  phy_inited=%d power_on=%d\n",
-               dp->dp_display.connector_type, dp->core_initialized,
-               dp->phy_initialized, dp_display->power_on);
-
-       /* mainlink enabled */
-       if (dp_power_clk_status(dp->power, DP_CTRL_PM))
-               dp_ctrl_off_link_stream(dp->ctrl);
-
-       dp_display_host_phy_exit(dp);
-
-       /* host_init will be called at pm_resume */
-       dp_display_host_deinit(dp);
-
-       dp->hpd_state = ST_SUSPENDED;
-
-       drm_dbg_dp(dp->drm_dev,
-               "After, type=%d core_inited=%d phy_inited=%d power_on=%d\n",
-               dp->dp_display.connector_type, dp->core_initialized,
-               dp->phy_initialized, dp_display->power_on);
+       struct dp_display_private *dp = dev_get_dp_display_private(dev);
 
-       mutex_unlock(&dp->event_mutex);
+       /*
+        * for eDP, host cotroller, HPD block and PHY are enabled here
+        * but with HPD irq disabled
+        *
+        * for DP, only host controller is enabled here.
+        * HPD block is enabled at dp_bridge_hpd_enable()
+        * PHY will be enabled at plugin handler later
+        */
+       dp_display_host_init(dp);
+       if (dp->dp_display.is_edp) {
+               dp_catalog_ctrl_hpd_enable(dp->catalog);
+               dp_display_host_phy_init(dp);
+       }
 
+       enable_irq(dp->irq);
        return 0;
 }
 
 static const struct dev_pm_ops dp_pm_ops = {
-       .suspend = dp_pm_suspend,
-       .resume =  dp_pm_resume,
+       SET_RUNTIME_PM_OPS(dp_pm_runtime_suspend, dp_pm_runtime_resume, NULL)
+       SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+                               pm_runtime_force_resume)
 };
 
 static struct platform_driver dp_display_driver = {
@@ -1435,19 +1397,6 @@ void __exit msm_dp_unregister(void)
        platform_driver_unregister(&dp_display_driver);
 }
 
-void msm_dp_irq_postinstall(struct msm_dp *dp_display)
-{
-       struct dp_display_private *dp;
-
-       if (!dp_display)
-               return;
-
-       dp = container_of(dp_display, struct dp_display_private, dp_display);
-
-       if (!dp_display->is_edp)
-               dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 0);
-}
-
 bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)
 {
        struct dp_display_private *dp;
@@ -1457,7 +1406,7 @@ bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)
        return dp->wide_bus_en;
 }
 
-void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
+void dp_display_debugfs_init(struct msm_dp *dp_display, struct dentry *root, bool is_edp)
 {
        struct dp_display_private *dp;
        struct device *dev;
@@ -1468,7 +1417,7 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor)
 
        dp->debug = dp_debug_get(dev, dp->panel,
                                        dp->link, dp->dp_display.connector,
-                                       minor);
+                                       root, is_edp);
        if (IS_ERR(dp->debug)) {
                rc = PTR_ERR(dp->debug);
                DRM_ERROR("failed to initialize debug, rc = %d\n", rc);
@@ -1480,33 +1429,8 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
 {
        int rc;
        struct dp_display_private *dp_priv;
-       struct device_node *aux_bus;
-       struct device *dev;
 
        dp_priv = container_of(dp, struct dp_display_private, dp_display);
-       dev = &dp_priv->dp_display.pdev->dev;
-       aux_bus = of_get_child_by_name(dev->of_node, "aux-bus");
-
-       if (aux_bus && dp->is_edp) {
-               dp_display_host_init(dp_priv);
-               dp_catalog_ctrl_hpd_enable(dp_priv->catalog);
-               dp_display_host_phy_init(dp_priv);
-
-               /*
-                * The code below assumes that the panel will finish probing
-                * by the time devm_of_dp_aux_populate_ep_devices() returns.
-                * This isn't a great assumption since it will fail if the
-                * panel driver is probed asynchronously but is the best we
-                * can do without a bigger driver reorganization.
-                */
-               rc = of_dp_aux_populate_bus(dp_priv->aux, NULL);
-               of_node_put(aux_bus);
-               if (rc)
-                       goto error;
-       } else if (dp->is_edp) {
-               DRM_ERROR("eDP aux_bus not found\n");
-               return -ENODEV;
-       }
 
        /*
         * External bridges are mandatory for eDP interfaces: one has to
@@ -1515,21 +1439,13 @@ static int dp_display_get_next_bridge(struct msm_dp *dp)
         * For DisplayPort interfaces external bridges are optional, so
         * silently ignore an error if one is not present (-ENODEV).
         */
-       rc = devm_dp_parser_find_next_bridge(dp->drm_dev->dev, dp_priv->parser);
+       rc = devm_dp_parser_find_next_bridge(&dp->pdev->dev, dp_priv->parser);
        if (!dp->is_edp && rc == -ENODEV)
                return 0;
 
-       if (!rc) {
+       if (!rc)
                dp->next_bridge = dp_priv->parser->next_bridge;
-               return 0;
-       }
 
-error:
-       if (dp->is_edp) {
-               of_dp_aux_depopulate_bus(dp_priv->aux);
-               dp_display_host_phy_exit(dp_priv);
-               dp_display_host_deinit(dp_priv);
-       }
        return rc;
 }
 
@@ -1543,16 +1459,6 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,
 
        dp_priv = container_of(dp_display, struct dp_display_private, dp_display);
 
-       ret = dp_display_request_irq(dp_display);
-       if (ret) {
-               DRM_ERROR("request_irq failed, ret=%d\n", ret);
-               return ret;
-       }
-
-       ret = dp_display_get_next_bridge(dp_display);
-       if (ret)
-               return ret;
-
        ret = dp_bridge_init(dp_display, dev, encoder);
        if (ret) {
                DRM_DEV_ERROR(dev->dev,
@@ -1594,6 +1500,11 @@ void dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,
                dp_hpd_plug_handle(dp_display, 0);
 
        mutex_lock(&dp_display->event_mutex);
+       if (pm_runtime_resume_and_get(&dp->pdev->dev)) {
+               DRM_ERROR("failed to pm_runtime_resume\n");
+               mutex_unlock(&dp_display->event_mutex);
+               return;
+       }
 
        state = dp_display->hpd_state;
        if (state != ST_DISPLAY_OFF && state != ST_MAINLINK_READY) {
@@ -1658,10 +1569,9 @@ void dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
        mutex_lock(&dp_display->event_mutex);
 
        state = dp_display->hpd_state;
-       if (state != ST_DISCONNECT_PENDING && state != ST_CONNECTED) {
-               mutex_unlock(&dp_display->event_mutex);
-               return;
-       }
+       if (state != ST_DISCONNECT_PENDING && state != ST_CONNECTED)
+               drm_dbg_dp(dp->drm_dev, "type=%d wrong hpd_state=%d\n",
+                          dp->connector_type, state);
 
        dp_display_disable(dp_display);
 
@@ -1674,6 +1584,8 @@ void dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,
        }
 
        drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);
+
+       pm_runtime_put_sync(&dp->pdev->dev);
        mutex_unlock(&dp_display->event_mutex);
 }
 
@@ -1712,7 +1624,21 @@ void dp_bridge_hpd_enable(struct drm_bridge *bridge)
        struct msm_dp *dp_display = dp_bridge->dp_display;
        struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);
 
+       /*
+        * this is for external DP with hpd irq enabled case,
+        * step-1: dp_pm_runtime_resume() enable dp host only
+        * step-2: enable hdp block and have hpd irq enabled here
+        * step-3: waiting for plugin irq while phy is not initialized
+        * step-4: DP PHY is initialized at plugin handler before link training
+        *
+        */
        mutex_lock(&dp->event_mutex);
+       if (pm_runtime_resume_and_get(&dp_display->pdev->dev)) {
+               DRM_ERROR("failed to resume power\n");
+               mutex_unlock(&dp->event_mutex);
+               return;
+       }
+
        dp_catalog_ctrl_hpd_enable(dp->catalog);
 
        /* enable HDP interrupts */
@@ -1734,6 +1660,8 @@ void dp_bridge_hpd_disable(struct drm_bridge *bridge)
        dp_catalog_ctrl_hpd_disable(dp->catalog);
 
        dp_display->internal_hpd = false;
+
+       pm_runtime_put_sync(&dp_display->pdev->dev);
        mutex_unlock(&dp->event_mutex);
 }
 
@@ -1748,13 +1676,8 @@ void dp_bridge_hpd_notify(struct drm_bridge *bridge,
        if (dp_display->internal_hpd)
                return;
 
-       if (!dp->core_initialized) {
-               drm_dbg_dp(dp->drm_dev, "not initialized\n");
-               return;
-       }
-
-       if (!dp_display->is_connected && status == connector_status_connected)
+       if (!dp_display->link_ready && status == connector_status_connected)
                dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
-       else if (dp_display->is_connected && status == connector_status_disconnected)
+       else if (dp_display->link_ready && status == connector_status_disconnected)
                dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
 }