Merge tag 'drm-next-2021-08-31-1' of git://anongit.freedesktop.org/drm/drm
[linux-2.6-microblaze.git] / drivers / gpu / drm / msm / dp / dp_display.c
index 867388a..fbe4c2c 100644 (file)
@@ -55,7 +55,6 @@ enum {
        EV_HPD_INIT_SETUP,
        EV_HPD_PLUG_INT,
        EV_IRQ_HPD_INT,
-       EV_HPD_REPLUG_INT,
        EV_HPD_UNPLUG_INT,
        EV_USER_NOTIFICATION,
        EV_CONNECT_PENDING_TIMEOUT,
@@ -102,8 +101,6 @@ struct dp_display_private {
        struct dp_display_mode dp_mode;
        struct msm_dp dp_display;
 
-       bool encoder_mode_set;
-
        /* wait for audio signaling */
        struct completion audio_comp;
 
@@ -268,6 +265,8 @@ static bool dp_display_is_ds_bridge(struct dp_panel *panel)
 
 static bool dp_display_is_sink_count_zero(struct dp_display_private *dp)
 {
+       DRM_DEBUG_DP("present=%#x sink_count=%d\n", dp->panel->dpcd[DP_DOWNSTREAMPORT_PRESENT],
+               dp->link->sink_count);
        return dp_display_is_ds_bridge(dp->panel) &&
                (dp->link->sink_count == 0);
 }
@@ -284,20 +283,6 @@ static void dp_display_send_hpd_event(struct msm_dp *dp_display)
 }
 
 
-static void dp_display_set_encoder_mode(struct dp_display_private *dp)
-{
-       struct msm_drm_private *priv = dp->dp_display.drm_dev->dev_private;
-       struct msm_kms *kms = priv->kms;
-
-       if (!dp->encoder_mode_set && dp->dp_display.encoder &&
-                               kms->funcs->set_encoder_mode) {
-               kms->funcs->set_encoder_mode(kms,
-                               dp->dp_display.encoder, false);
-
-               dp->encoder_mode_set = true;
-       }
-}
-
 static int dp_display_send_hpd_notification(struct dp_display_private *dp,
                                            bool hpd)
 {
@@ -313,6 +298,7 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp,
 
        dp->dp_display.is_connected = hpd;
 
+       DRM_DEBUG_DP("hpd=%d\n", hpd);
        dp_display_send_hpd_event(&dp->dp_display);
 
        return 0;
@@ -362,6 +348,7 @@ static void dp_display_host_init(struct dp_display_private *dp, int reset)
 {
        bool flip = false;
 
+       DRM_DEBUG_DP("core_initialized=%d\n", dp->core_initialized);
        if (dp->core_initialized) {
                DRM_DEBUG_DP("DP core already initialized\n");
                return;
@@ -370,8 +357,6 @@ static void dp_display_host_init(struct dp_display_private *dp, int reset)
        if (dp->usbpd->orientation == ORIENTATION_CC2)
                flip = true;
 
-       dp_display_set_encoder_mode(dp);
-
        dp_power_init(dp->power, flip);
        dp_ctrl_host_init(dp->ctrl, flip, reset);
        dp_aux_init(dp->aux);
@@ -466,8 +451,10 @@ static int dp_display_handle_irq_hpd(struct dp_display_private *dp)
 {
        u32 sink_request = dp->link->sink_request;
 
+       DRM_DEBUG_DP("%d\n", sink_request);
        if (dp->hpd_state == ST_DISCONNECTED) {
                if (sink_request & DP_LINK_STATUS_UPDATED) {
+                       DRM_DEBUG_DP("Disconnected sink_request: %d\n", sink_request);
                        DRM_ERROR("Disconnected, no DP_LINK_STATUS_UPDATED\n");
                        return -EINVAL;
                }
@@ -499,6 +486,7 @@ static int dp_display_usbpd_attention_cb(struct device *dev)
        rc = dp_link_process_request(dp->link);
        if (!rc) {
                sink_request = dp->link->sink_request;
+               DRM_DEBUG_DP("hpd_state=%d sink_request=%d\n", dp->hpd_state, sink_request);
                if (sink_request & DS_PORT_STATUS_CHANGED)
                        rc = dp_display_handle_port_ststus_changed(dp);
                else
@@ -521,6 +509,7 @@ static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)
        mutex_lock(&dp->event_mutex);
 
        state =  dp->hpd_state;
+       DRM_DEBUG_DP("hpd_state=%d\n", state);
        if (state == ST_DISPLAY_OFF || state == ST_SUSPENDED) {
                mutex_unlock(&dp->event_mutex);
                return 0;
@@ -656,6 +645,7 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)
        /* start sentinel checking in case of missing uevent */
        dp_add_event(dp, EV_DISCONNECT_PENDING_TIMEOUT, 0, DP_TIMEOUT_5_SECOND);
 
+       DRM_DEBUG_DP("hpd_state=%d\n", state);
        /* signal the disconnect event early to ensure proper teardown */
        dp_display_handle_plugged_change(g_dp_display, false);
 
@@ -714,6 +704,7 @@ static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data)
        if (ret == -ECONNRESET) { /* cable unplugged */
                dp->core_initialized = false;
        }
+       DRM_DEBUG_DP("hpd_state=%d\n", state);
 
        mutex_unlock(&dp->event_mutex);
 
@@ -855,6 +846,7 @@ static int dp_display_enable(struct dp_display_private *dp, u32 data)
 
        dp_display = g_dp_display;
 
+       DRM_DEBUG_DP("sink_count=%d\n", dp->link->sink_count);
        if (dp_display->power_on) {
                DRM_DEBUG_DP("Link already setup, return\n");
                return 0;
@@ -916,6 +908,7 @@ static int dp_display_disable(struct dp_display_private *dp, u32 data)
 
        dp_display->power_on = false;
 
+       DRM_DEBUG_DP("sink count: %d\n", dp->link->sink_count);
        return 0;
 }
 
@@ -1015,10 +1008,8 @@ int dp_display_get_test_bpp(struct msm_dp *dp)
 void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp)
 {
        struct dp_display_private *dp_display;
-       struct drm_device *drm;
 
        dp_display = container_of(dp, struct dp_display_private, dp_display);
-       drm = dp->drm_dev;
 
        /*
         * if we are reading registers we need the link clocks to be on
@@ -1119,9 +1110,6 @@ static int hpd_event_thread(void *data)
                case EV_IRQ_HPD_INT:
                        dp_irq_hpd_handle(dp_priv, todo->data);
                        break;
-               case EV_HPD_REPLUG_INT:
-                       /* do nothing */
-                       break;
                case EV_USER_NOTIFICATION:
                        dp_display_send_hpd_notification(dp_priv,
                                                todo->data);
@@ -1163,12 +1151,11 @@ static irqreturn_t dp_display_irq_handler(int irq, void *dev_id)
 
        hpd_isr_status = dp_catalog_hpd_get_intr_status(dp->catalog);
 
+       DRM_DEBUG_DP("hpd isr status=%#x\n", hpd_isr_status);
        if (hpd_isr_status & 0x0F) {
                /* hpd related interrupts */
-               if (hpd_isr_status & DP_DP_HPD_PLUG_INT_MASK ||
-                       hpd_isr_status & DP_DP_HPD_REPLUG_INT_MASK) {
+               if (hpd_isr_status & DP_DP_HPD_PLUG_INT_MASK)
                        dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);
-               }
 
                if (hpd_isr_status & DP_DP_IRQ_HPD_INT_MASK) {
                        /* stop sentinel connect pending checking */
@@ -1176,8 +1163,10 @@ static irqreturn_t dp_display_irq_handler(int irq, void *dev_id)
                        dp_add_event(dp, EV_IRQ_HPD_INT, 0, 0);
                }
 
-               if (hpd_isr_status & DP_DP_HPD_REPLUG_INT_MASK)
-                       dp_add_event(dp, EV_HPD_REPLUG_INT, 0, 0);
+               if (hpd_isr_status & DP_DP_HPD_REPLUG_INT_MASK) {
+                       dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
+                       dp_add_event(dp, EV_HPD_PLUG_INT, 0, 3);
+               }
 
                if (hpd_isr_status & DP_DP_HPD_UNPLUG_INT_MASK)
                        dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);
@@ -1286,12 +1275,15 @@ static int dp_pm_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;
-       u32 status;
+       int sink_count = 0;
 
        dp = container_of(dp_display, struct dp_display_private, dp_display);
 
        mutex_lock(&dp->event_mutex);
 
+       DRM_DEBUG_DP("Before, core_inited=%d power_on=%d\n",
+                       dp->core_initialized, dp_display->power_on);
+
        /* start from disconnected state */
        dp->hpd_state = ST_DISCONNECTED;
 
@@ -1300,14 +1292,25 @@ static int dp_pm_resume(struct device *dev)
 
        dp_catalog_ctrl_hpd_config(dp->catalog);
 
-       status = dp_catalog_link_is_connected(dp->catalog);
+       /*
+        * set sink to normal operation mode -- D0
+        * before dpcd read
+        */
+       dp_link_psm_config(dp->link, &dp->panel->link_info, false);
+
+       if (dp_catalog_link_is_connected(dp->catalog)) {
+               sink_count = drm_dp_read_sink_count(dp->aux);
+               if (sink_count < 0)
+                       sink_count = 0;
+       }
 
+       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
         */
-       if (status && dp->link->sink_count)
+       if (dp->link->sink_count)
                dp->dp_display.is_connected = true;
        else
                dp->dp_display.is_connected = false;
@@ -1315,6 +1318,9 @@ static int dp_pm_resume(struct device *dev)
        dp_display_handle_plugged_change(g_dp_display,
                                dp->dp_display.is_connected);
 
+       DRM_DEBUG_DP("After, sink_count=%d is_connected=%d core_inited=%d power_on=%d\n",
+                       dp->link->sink_count, dp->dp_display.is_connected,
+                       dp->core_initialized, dp_display->power_on);
 
        mutex_unlock(&dp->event_mutex);
 
@@ -1331,6 +1337,9 @@ static int dp_pm_suspend(struct device *dev)
 
        mutex_lock(&dp->event_mutex);
 
+       DRM_DEBUG_DP("Before, core_inited=%d power_on=%d\n",
+                       dp->core_initialized, dp_display->power_on);
+
        if (dp->core_initialized == true) {
                /* mainlink enabled */
                if (dp_power_clk_status(dp->power, DP_CTRL_PM))
@@ -1344,6 +1353,9 @@ static int dp_pm_suspend(struct device *dev)
        /* host_init will be called at pm_resume */
        dp->core_initialized = false;
 
+       DRM_DEBUG_DP("After, core_inited=%d power_on=%d\n",
+                       dp->core_initialized, dp_display->power_on);
+
        mutex_unlock(&dp->event_mutex);
 
        return 0;