Commit 2bab52af authored by Brian Masney's avatar Brian Masney Committed by Sean Paul

drm/msm: add support for per-CRTC max_vblank_count on mdp5

The mdp5 drm/kms driver currently does not work on command-mode DSI
panels due to 'vblank wait timed out' errors. This causes a latency
of seconds, or tens of seconds in some cases, before content is shown
on the panel. This hardware does not have the something that we can use
as a frame counter available when running in command mode, so we need to
fall back to using timestamps by setting the max_vblank_count to zero.
This can be done on a per-CRTC basis, so the convert mdp5 to use
drm_crtc_set_max_vblank_count().

This change was tested on a LG Nexus 5 (hammerhead) phone.
Suggested-by: default avatarJeffrey Hugo <jeffrey.l.hugo@gmail.com>
Reviewed-by: default avatarJeffrey Hugo <jeffrey.l.hugo@gmail.com>
Signed-off-by: default avatarBrian Masney <masneyb@onstation.org>
Signed-off-by: default avatarSean Paul <seanpaul@chromium.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20190531094619.31704-3-masneyb@onstation.org
parent 3de433c5
...@@ -439,6 +439,18 @@ static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc, ...@@ -439,6 +439,18 @@ static void mdp5_crtc_atomic_disable(struct drm_crtc *crtc,
mdp5_crtc->enabled = false; mdp5_crtc->enabled = false;
} }
static void mdp5_crtc_vblank_on(struct drm_crtc *crtc)
{
struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
struct mdp5_interface *intf = mdp5_cstate->pipeline.intf;
u32 count;
count = intf->mode == MDP5_INTF_DSI_MODE_COMMAND ? 0 : 0xffffffff;
drm_crtc_set_max_vblank_count(crtc, count);
drm_crtc_vblank_on(crtc);
}
static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc, static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc,
struct drm_crtc_state *old_state) struct drm_crtc_state *old_state)
{ {
...@@ -475,7 +487,7 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc, ...@@ -475,7 +487,7 @@ static void mdp5_crtc_atomic_enable(struct drm_crtc *crtc,
} }
/* Restore vblank irq handling after power is enabled */ /* Restore vblank irq handling after power is enabled */
drm_crtc_vblank_on(crtc); mdp5_crtc_vblank_on(crtc);
mdp5_crtc_mode_set_nofb(crtc); mdp5_crtc_mode_set_nofb(crtc);
...@@ -1028,6 +1040,8 @@ static void mdp5_crtc_reset(struct drm_crtc *crtc) ...@@ -1028,6 +1040,8 @@ static void mdp5_crtc_reset(struct drm_crtc *crtc)
mdp5_crtc_destroy_state(crtc, crtc->state); mdp5_crtc_destroy_state(crtc, crtc->state);
__drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base); __drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base);
drm_crtc_vblank_reset(crtc);
} }
static const struct drm_crtc_funcs mdp5_crtc_funcs = { static const struct drm_crtc_funcs mdp5_crtc_funcs = {
......
...@@ -740,7 +740,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev) ...@@ -740,7 +740,7 @@ struct msm_kms *mdp5_kms_init(struct drm_device *dev)
dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos;
dev->driver->get_scanout_position = mdp5_get_scanoutpos; dev->driver->get_scanout_position = mdp5_get_scanoutpos;
dev->driver->get_vblank_counter = mdp5_get_vblank_counter; dev->driver->get_vblank_counter = mdp5_get_vblank_counter;
dev->max_vblank_count = 0xffffffff; dev->max_vblank_count = 0; /* max_vblank_count is set on each CRTC */
dev->vblank_disable_immediate = true; dev->vblank_disable_immediate = true;
return kms; return kms;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment