disp: msm: update POMS detection logic

Currently, SDE relies on DSI to set a flag for POMS however
if a power ON modeset comes with a different mode than
previously configured, DSI is unable to detect the mode change
and does not set the flag nor perform the mode switch itself.

DSI should always align the panel mode to match the timing node
that is selected regardless of prior configurations.

SDE encoder can detect if POMS is required for the INTF block
without the flag from DSI by comparing the currently configured
INTF mode with the panel mode that is being set. The POMS flag
from DSI is still needed for any active panel mode change so
that the post-modeset cleanup operations are triggered.

Change-Id: Ib198b3098f21338ab35b2022b04be1c01c4cbd94
Signed-off-by: Steve Cohen <cohens@codeaurora.org>
此提交包含在:
Steve Cohen
2020-09-10 19:53:26 -04:00
父節點 13154febbc
當前提交 38a8d2134b
共有 2 個檔案被更改,包括 23 行新增11 行删除

查看文件

@@ -2065,17 +2065,17 @@ static void sde_encoder_virt_mode_switch(struct drm_encoder *drm_enc,
if (intf_mode == INTF_MODE_CMD) {
for (i = 0; i < sde_enc->num_phys_encs; i++)
sde_enc->phys_encs[i] = sde_enc->phys_vid_encs[i];
SDE_DEBUG_ENC(sde_enc, "switch to video physical encoder\n");
SDE_EVT32(DRMID(&sde_enc->base), intf_mode,
msm_is_mode_seamless_poms(adj_mode),
SDE_EVTLOG_FUNC_CASE1);
SDE_EVT32(DRMID(&sde_enc->base), intf_mode, adj_mode->flags,
adj_mode->private_flags, SDE_EVTLOG_FUNC_CASE1);
} else if (intf_mode == INTF_MODE_VIDEO) {
for (i = 0; i < sde_enc->num_phys_encs; i++)
sde_enc->phys_encs[i] = sde_enc->phys_cmd_encs[i];
SDE_EVT32(DRMID(&sde_enc->base), intf_mode,
msm_is_mode_seamless_poms(adj_mode),
SDE_EVTLOG_FUNC_CASE2);
SDE_DEBUG_ENC(sde_enc, "switch to command physical encoder\n");
SDE_EVT32(DRMID(&sde_enc->base), intf_mode, adj_mode->flags,
adj_mode->private_flags, SDE_EVTLOG_FUNC_CASE2);
}
}
@@ -2168,6 +2168,19 @@ static void _sde_encoder_virt_populate_hw_res(struct drm_encoder *drm_enc)
}
}
static bool sde_encoder_detect_panel_mode_switch(
struct drm_display_mode *adj_mode, enum sde_intf_mode intf_mode)
{
/* don't rely on POMS flag as it may not be set for power-on modeset */
if ((intf_mode == INTF_MODE_CMD &&
adj_mode->flags & DRM_MODE_FLAG_VID_MODE_PANEL) ||
(intf_mode == INTF_MODE_VIDEO &&
adj_mode->flags & DRM_MODE_FLAG_CMD_MODE_PANEL))
return true;
return false;
}
static int sde_encoder_virt_modeset_rc(struct drm_encoder *drm_enc,
struct drm_display_mode *adj_mode, bool pre_modeset)
{
@@ -2199,7 +2212,8 @@ static int sde_encoder_virt_modeset_rc(struct drm_encoder *drm_enc,
* modeset to guarantee previous kickoff has finished.
*/
sde_encoder_dce_disable(sde_enc);
} else if (msm_is_mode_seamless_poms(adj_mode)) {
} else if (sde_encoder_detect_panel_mode_switch(adj_mode,
intf_mode)) {
_sde_encoder_modeset_helper_locked(drm_enc,
SDE_ENC_RC_EVENT_PRE_MODESET);
sde_encoder_virt_mode_switch(drm_enc, intf_mode,