Skip to content
Snippets Groups Projects
Commit 6f752c18 authored by Liu Ying's avatar Liu Ying Committed by Jason Liu
Browse files

LF-4322 drm/imx: dcnano: Avoid double modeset


When running the below system suspend/resume test case on
i.MX8ulp EVK platform with the RM68200 MIPI DSI panel enabled,
DCNANO display controller power usage count and pixel clock enable
count would be unbalanced when the DRM connector's DPMS property
is changed from off to on after system resumes, if the DPMS property
is off before system suspends.  The root cause is that the
crtc_helper_funcs->mode_set_nofb() is called twice during the
procedure without crtc disablement, one at system resume stage and
one for DPMS on operation.  That means the pm_runtime_get_sync()
would be called twice at that function and pixel clock would be
enabled twice as well.  This patch introduces a flag to indicate
if the modeset is done or not to avoid the doulbe modeset so that
the reference counts are balanced.

while true; do modetest -M imx-dcnano -w 34:DPMS:3; done &
while true; do /unit_tests/SRTC/rtcwakeup.out -s 2 -m mem; done

Fixes: ce68244e ("MLK-25531-2 drm/imx: Add dcnano drm support")
Cc: Sandor Yu <Sandor.yu@nxp.com>
Reviewed-by: default avatarSandor Yu <Sandor.yu@nxp.com>
Signed-off-by: default avatarLiu Ying <victor.liu@nxp.com>
Acked-by: default avatarJason Liu <jason.hui.liu@nxp.com>
parent 755ee35f
No related branches found
No related tags found
No related merge requests found
......@@ -202,6 +202,9 @@ static void dcnano_crtc_mode_set_nofb(struct drm_crtc *crtc)
struct dcnano_dev *dcnano = crtc_to_dcnano_dev(crtc);
struct drm_display_mode *adj = &crtc->state->adjusted_mode;
if (dcnano->modeset_done)
return;
dcnano_crtc_dbg(crtc, "mode " DRM_MODE_FMT "\n", DRM_MODE_ARG(adj));
dcnano_crtc_set_pixel_clock(crtc);
......@@ -211,6 +214,8 @@ static void dcnano_crtc_mode_set_nofb(struct drm_crtc *crtc)
if (dcnano->port == DCNANO_DPI_PORT)
dcnano_crtc_mode_set_nofb_dpi(crtc);
dcnano->modeset_done = true;
}
static void dcnano_crtc_queue_state_event(struct drm_crtc *crtc)
......@@ -330,6 +335,8 @@ static void dcnano_crtc_atomic_disable(struct drm_crtc *crtc,
crtc->state->event = NULL;
}
spin_unlock_irq(&crtc->dev->event_lock);
dcnano->modeset_done = false;
}
static bool
......
......@@ -42,6 +42,8 @@ struct dcnano_dev {
struct drm_pending_vblank_event *event;
enum dcnano_port port;
bool modeset_done;
};
static inline struct dcnano_dev *to_dcnano_dev(struct drm_device *drm)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment