disp: msm: sde: update retire-fence with precise vsync timestamp

Retire fence for frames are signaled based on vsync. Use the HW
vsync timestamp counter to calculate the precise vsync timestamp
and update the retire fence signal timestamp. This will offset
all IRQ and SW delays and sends the precise timestamp. Avoid
calculating the timestamp on error or panel dead events and
set the current ktime for those cases.

Change-Id: Ic762f7cd6daead9c8fdcb0f8aad6386cf980407d
Signed-off-by: Veera Sundaram Sankaran <veeras@codeaurora.org>
这个提交包含在:
Veera Sundaram Sankaran
2020-09-28 12:26:52 -07:00
父节点 3cef1faa29
当前提交 b965fdcee5
修改 3 个文件,包含 25 行新增12 行删除

查看文件

@@ -3225,7 +3225,7 @@ void sde_encoder_register_vblank_callback(struct drm_encoder *drm_enc,
}
void sde_encoder_register_frame_event_callback(struct drm_encoder *drm_enc,
void (*frame_event_cb)(void *, u32 event),
void (*frame_event_cb)(void *, u32 event, ktime_t ts),
struct drm_crtc *crtc)
{
struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
@@ -3252,14 +3252,16 @@ static void sde_encoder_frame_done_callback(
struct sde_encoder_phys *ready_phys, u32 event)
{
struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
struct sde_kms *sde_kms = sde_encoder_get_kms(&sde_enc->base);
unsigned int i;
bool trigger = true;
bool is_cmd_mode = false;
enum sde_rm_topology_name topology = SDE_RM_TOPOLOGY_NONE;
ktime_t ts = 0;
if (!drm_enc || !sde_enc->cur_master) {
SDE_ERROR("invalid param: drm_enc %pK, cur_master %pK\n",
drm_enc, drm_enc ? sde_enc->cur_master : 0);
if (!sde_kms || !sde_enc->cur_master) {
SDE_ERROR("invalid param: sde_kms %pK, cur_master %pK\n",
sde_kms, sde_enc->cur_master);
return;
}
@@ -3268,6 +3270,19 @@ static void sde_encoder_frame_done_callback(
if (sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE))
is_cmd_mode = true;
/* get precise vsync timestamp for retire fence, if precise vsync timestamp is enabled */
if (sde_kms->catalog->has_precise_vsync_ts
&& (event & SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE)
&& (!(event & (SDE_ENCODER_FRAME_EVENT_ERROR | SDE_ENCODER_FRAME_EVENT_PANEL_DEAD))))
ts = sde_encoder_calc_last_vsync_timestamp(drm_enc);
/*
* get current ktime for other events and when precise timestamp is not
* available for retire-fence
*/
if (!ts)
ts = ktime_get();
if (event & (SDE_ENCODER_FRAME_EVENT_DONE
| SDE_ENCODER_FRAME_EVENT_ERROR
| SDE_ENCODER_FRAME_EVENT_PANEL_DEAD) && is_cmd_mode) {
@@ -3301,15 +3316,13 @@ static void sde_encoder_frame_done_callback(
if (trigger) {
if (sde_enc->crtc_frame_event_cb)
sde_enc->crtc_frame_event_cb(
&sde_enc->crtc_frame_event_cb_data,
event);
&sde_enc->crtc_frame_event_cb_data, event, ts);
for (i = 0; i < sde_enc->num_phys_encs; i++)
atomic_add_unless(&sde_enc->frame_done_cnt[i],
-1, 0);
}
} else if (sde_enc->crtc_frame_event_cb) {
sde_enc->crtc_frame_event_cb(
&sde_enc->crtc_frame_event_cb_data, event);
sde_enc->crtc_frame_event_cb(&sde_enc->crtc_frame_event_cb_data, event, ts);
}
}