Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a79d9426 authored by Dhaval Patel's avatar Dhaval Patel
Browse files

drm/msm/sde: trigger single frame_done evt for vid encoder



Commit 5db43498 ("drm/msm/sde: avoid frame_done
event trigger for idle scenario") supports frame_done
event merging with release and retire fence for
video mode. This works for single dsi display but it
causes issue for dual dsi display. Dual dsi display
needs two frame_done events in current design. The
second dummy frame_done event is generated by physical
video mode display. This patch simplifies the
frame_done event trigger for video mode by generating
single event. It aligns the logic with wb display.
Command mode display still waits for two pp_done
IRQs and triggers the frame_done interrupt when
both events are arrived.

Change-Id: I8d5a15d1d478001450b3e86a84f19e031f777d8d
Signed-off-by: default avatarDhaval Patel <pdhaval@codeaurora.org>
parent 35d3c928
Loading
Loading
Loading
Loading
+10 −5
Original line number Original line Diff line number Diff line
@@ -3534,7 +3534,7 @@ static void sde_encoder_frame_done_callback(
{
{
	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
	unsigned int i;
	unsigned int i;
	bool trigger = true;
	bool trigger = true, is_cmd_mode;
	enum sde_rm_topology_name topology = SDE_RM_TOPOLOGY_NONE;
	enum sde_rm_topology_name topology = SDE_RM_TOPOLOGY_NONE;


	if (!drm_enc || !sde_enc->cur_master) {
	if (!drm_enc || !sde_enc->cur_master) {
@@ -3545,10 +3545,12 @@ static void sde_encoder_frame_done_callback(


	sde_enc->crtc_frame_event_cb_data.connector =
	sde_enc->crtc_frame_event_cb_data.connector =
				sde_enc->cur_master->connector;
				sde_enc->cur_master->connector;
	is_cmd_mode = sde_enc->disp_info.capabilities &
					MSM_DISPLAY_CAP_CMD_MODE;


	if (event & (SDE_ENCODER_FRAME_EVENT_DONE
	if (event & (SDE_ENCODER_FRAME_EVENT_DONE
			| SDE_ENCODER_FRAME_EVENT_ERROR
			| SDE_ENCODER_FRAME_EVENT_ERROR
			| SDE_ENCODER_FRAME_EVENT_PANEL_DEAD)) {
			| SDE_ENCODER_FRAME_EVENT_PANEL_DEAD) && is_cmd_mode) {


		if (ready_phys->connector)
		if (ready_phys->connector)
			topology = sde_connector_get_topology_name(
			topology = sde_connector_get_topology_name(
@@ -3588,8 +3590,11 @@ static void sde_encoder_frame_done_callback(
			for (i = 0; i < sde_enc->num_phys_encs; i++)
			for (i = 0; i < sde_enc->num_phys_encs; i++)
				atomic_set(&sde_enc->frame_done_cnt[i], 0);
				atomic_set(&sde_enc->frame_done_cnt[i], 0);
		}
		}
	} else {
	} else if (sde_enc->crtc_frame_event_cb) {
		if (sde_enc->crtc_frame_event_cb)
		if (!is_cmd_mode)
			sde_encoder_resource_control(drm_enc,
					SDE_ENC_RC_EVENT_FRAME_DONE);

		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);
	}
	}
+13 −28
Original line number Original line Diff line number Diff line
@@ -471,10 +471,9 @@ static void sde_encoder_phys_vid_vblank_irq(void *arg, int irq_idx)
	pend_ret_fence_cnt = atomic_read(&phys_enc->pending_retire_fence_cnt);
	pend_ret_fence_cnt = atomic_read(&phys_enc->pending_retire_fence_cnt);


	/* signal only for master, where there is a pending kickoff */
	/* signal only for master, where there is a pending kickoff */
	if (sde_encoder_phys_vid_is_master(phys_enc)) {
	if (sde_encoder_phys_vid_is_master(phys_enc) &&
		if (atomic_add_unless(&phys_enc->pending_retire_fence_cnt,
	    atomic_add_unless(&phys_enc->pending_retire_fence_cnt, -1, 0)) {
					-1, 0))
		event = SDE_ENCODER_FRAME_EVENT_DONE |
			event |= SDE_ENCODER_FRAME_EVENT_DONE |
			SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE |
			SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE |
			SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE;
			SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE;
	}
	}
@@ -823,20 +822,15 @@ static int _sde_encoder_phys_vid_wait_for_vblank(
{
{
	struct sde_encoder_wait_info wait_info;
	struct sde_encoder_wait_info wait_info;
	int ret = 0;
	int ret = 0;
	u32 event = 0, event_helper = 0;
	u32 event = SDE_ENCODER_FRAME_EVENT_ERROR |
		SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE |
		SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE;


	if (!phys_enc) {
	if (!phys_enc) {
		pr_err("invalid encoder\n");
		pr_err("invalid encoder\n");
		return -EINVAL;
		return -EINVAL;
	}
	}


	if (!sde_encoder_phys_vid_is_master(phys_enc)) {
		/* signal done for slave video encoder, unless it is pp-split */
		if (!_sde_encoder_phys_is_ppsplit(phys_enc) && notify)
			event = SDE_ENCODER_FRAME_EVENT_DONE;
		goto end;
	}

	wait_info.wq = &phys_enc->pending_kickoff_wq;
	wait_info.wq = &phys_enc->pending_kickoff_wq;
	wait_info.atomic_cnt = &phys_enc->pending_kickoff_cnt;
	wait_info.atomic_cnt = &phys_enc->pending_kickoff_cnt;
	wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
	wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
@@ -845,23 +839,14 @@ static int _sde_encoder_phys_vid_wait_for_vblank(
	ret = sde_encoder_helper_wait_for_irq(phys_enc, INTR_IDX_VSYNC,
	ret = sde_encoder_helper_wait_for_irq(phys_enc, INTR_IDX_VSYNC,
			&wait_info);
			&wait_info);


	event_helper = SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE
	if (notify && (ret == -ETIMEDOUT) &&
			| SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE;
	    atomic_add_unless(&phys_enc->pending_retire_fence_cnt, -1, 0) &&

	    phys_enc->parent_ops.handle_frame_done)
	if (notify && (ret == -ETIMEDOUT)) {
		phys_enc->parent_ops.handle_frame_done(
		event = SDE_ENCODER_FRAME_EVENT_ERROR;
			phys_enc->parent, phys_enc, event);
		if (atomic_add_unless(&phys_enc->pending_retire_fence_cnt,
				-1, 0))
			event |= event_helper;
	}


end:
	SDE_EVT32(DRMID(phys_enc->parent), event, notify, ret,
	SDE_EVT32(DRMID(phys_enc->parent), event, notify, ret,
			ret ? SDE_EVTLOG_FATAL : 0);
			ret ? SDE_EVTLOG_FATAL : 0);
	if (phys_enc->parent_ops.handle_frame_done && event)
		phys_enc->parent_ops.handle_frame_done(
				phys_enc->parent, phys_enc,
				event);
	return ret;
	return ret;
}
}