drm/bridge: it6505: Send DPCD SET_POWER to downstream
authorPin-Yen Lin <treapking@chromium.org>
Mon, 25 Apr 2022 13:44:24 +0000 (21:44 +0800)
committerRobert Foss <robert.foss@linaro.org>
Mon, 2 May 2022 14:36:23 +0000 (16:36 +0200)
Send DPCD SET_POWER command to downstream in .atomic_disable to make the
downstream monitor enter the power down mode, so the device suspend won't
be affected.

Fixes: b5c84a9edcd418 ("drm/bridge: add it6505 driver")
Signed-off-by: Pin-Yen Lin <treapking@chromium.org>
Signed-off-by: Robert Foss <robert.foss@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20220425134424.1150965-1-treapking@chromium.org
Reviewed-by: Robert Foss <robert.foss@linaro.org>
drivers/gpu/drm/bridge/ite-it6505.c

index 8fed30d..4b673c4 100644 (file)
@@ -737,8 +737,9 @@ static int it6505_drm_dp_link_probe(struct drm_dp_aux *aux,
        return 0;
 }
 
-static int it6505_drm_dp_link_power_up(struct drm_dp_aux *aux,
-                                      struct it6505_drm_dp_link *link)
+static int it6505_drm_dp_link_set_power(struct drm_dp_aux *aux,
+                                       struct it6505_drm_dp_link *link,
+                                       u8 mode)
 {
        u8 value;
        int err;
@@ -752,18 +753,20 @@ static int it6505_drm_dp_link_power_up(struct drm_dp_aux *aux,
                return err;
 
        value &= ~DP_SET_POWER_MASK;
-       value |= DP_SET_POWER_D0;
+       value |= mode;
 
        err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
        if (err < 0)
                return err;
 
-       /*
-        * According to the DP 1.1 specification, a "Sink Device must exit the
-        * power saving state within 1 ms" (Section 2.5.3.1, Table 5-52, "Sink
-        * Control Field" (register 0x600).
-        */
-       usleep_range(1000, 2000);
+       if (mode == DP_SET_POWER_D0) {
+               /*
+                * According to the DP 1.1 specification, a "Sink Device must
+                * exit the power saving state within 1 ms" (Section 2.5.3.1,
+                * Table 5-52, "Sink Control Field" (register 0x600).
+                */
+               usleep_range(1000, 2000);
+       }
 
        return 0;
 }
@@ -2624,7 +2627,8 @@ static enum drm_connector_status it6505_detect(struct it6505 *it6505)
        if (it6505_get_sink_hpd_status(it6505)) {
                it6505_aux_on(it6505);
                it6505_drm_dp_link_probe(&it6505->aux, &it6505->link);
-               it6505_drm_dp_link_power_up(&it6505->aux, &it6505->link);
+               it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
+                                            DP_SET_POWER_D0);
                it6505->auto_train_retry = AUTO_TRAIN_RETRY;
 
                if (it6505->dpcd[0] == 0) {
@@ -2960,8 +2964,11 @@ static void it6505_bridge_atomic_disable(struct drm_bridge *bridge,
 
        DRM_DEV_DEBUG_DRIVER(dev, "start");
 
-       if (it6505->powered)
+       if (it6505->powered) {
                it6505_video_disable(it6505);
+               it6505_drm_dp_link_set_power(&it6505->aux, &it6505->link,
+                                            DP_SET_POWER_D3);
+       }
 }
 
 static enum drm_connector_status