drm/bridge: add psr support for panel bridge callbacks
authorVinod Polimera <quic_vpolimer@quicinc.com>
Thu, 2 Mar 2023 16:33:06 +0000 (22:03 +0530)
committerDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Mon, 13 Mar 2023 01:43:49 +0000 (04:43 +0300)
This change will handle the psr entry exit cases in the panel
bridge atomic callback functions. For example, the panel power
should not turn off if the panel is entering psr.

Signed-off-by: Sankeerth Billakanti <quic_sbillaka@quicinc.com>
Signed-off-by: Vinod Polimera <quic_vpolimer@quicinc.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Patchwork: https://patchwork.freedesktop.org/patch/524721/
Link: https://lore.kernel.org/r/1677774797-31063-4-git-send-email-quic_vpolimer@quicinc.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
drivers/gpu/drm/bridge/panel.c

index 5c4b3f3bf0a537892412c2f2143ed401b3d653bd..c58f7bb6fca67b14cfaae8da5e0029e3a7b37eb3 100644 (file)
@@ -113,6 +113,18 @@ static void panel_bridge_atomic_pre_enable(struct drm_bridge *bridge,
                                struct drm_bridge_state *old_bridge_state)
 {
        struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
+       struct drm_atomic_state *atomic_state = old_bridge_state->base.state;
+       struct drm_encoder *encoder = bridge->encoder;
+       struct drm_crtc *crtc;
+       struct drm_crtc_state *old_crtc_state;
+
+       crtc = drm_atomic_get_new_crtc_for_encoder(atomic_state, encoder);
+       if (!crtc)
+               return;
+
+       old_crtc_state = drm_atomic_get_old_crtc_state(atomic_state, crtc);
+       if (old_crtc_state && old_crtc_state->self_refresh_active)
+               return;
 
        drm_panel_prepare(panel_bridge->panel);
 }
@@ -121,6 +133,18 @@ static void panel_bridge_atomic_enable(struct drm_bridge *bridge,
                                struct drm_bridge_state *old_bridge_state)
 {
        struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
+       struct drm_atomic_state *atomic_state = old_bridge_state->base.state;
+       struct drm_encoder *encoder = bridge->encoder;
+       struct drm_crtc *crtc;
+       struct drm_crtc_state *old_crtc_state;
+
+       crtc = drm_atomic_get_new_crtc_for_encoder(atomic_state, encoder);
+       if (!crtc)
+               return;
+
+       old_crtc_state = drm_atomic_get_old_crtc_state(atomic_state, crtc);
+       if (old_crtc_state && old_crtc_state->self_refresh_active)
+               return;
 
        drm_panel_enable(panel_bridge->panel);
 }
@@ -129,6 +153,18 @@ static void panel_bridge_atomic_disable(struct drm_bridge *bridge,
                                struct drm_bridge_state *old_bridge_state)
 {
        struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
+       struct drm_atomic_state *atomic_state = old_bridge_state->base.state;
+       struct drm_encoder *encoder = bridge->encoder;
+       struct drm_crtc *crtc;
+       struct drm_crtc_state *new_crtc_state;
+
+       crtc = drm_atomic_get_old_crtc_for_encoder(atomic_state, encoder);
+       if (!crtc)
+               return;
+
+       new_crtc_state = drm_atomic_get_new_crtc_state(atomic_state, crtc);
+       if (new_crtc_state && new_crtc_state->self_refresh_active)
+               return;
 
        drm_panel_disable(panel_bridge->panel);
 }
@@ -137,6 +173,18 @@ static void panel_bridge_atomic_post_disable(struct drm_bridge *bridge,
                                struct drm_bridge_state *old_bridge_state)
 {
        struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
+       struct drm_atomic_state *atomic_state = old_bridge_state->base.state;
+       struct drm_encoder *encoder = bridge->encoder;
+       struct drm_crtc *crtc;
+       struct drm_crtc_state *new_crtc_state;
+
+       crtc = drm_atomic_get_old_crtc_for_encoder(atomic_state, encoder);
+       if (!crtc)
+               return;
+
+       new_crtc_state = drm_atomic_get_new_crtc_state(atomic_state, crtc);
+       if (new_crtc_state && new_crtc_state->self_refresh_active)
+               return;
 
        drm_panel_unprepare(panel_bridge->panel);
 }