disp: msm: sde: increase display kickoff timeout for hw-fences
Starting with HW-Fencing, the frames hw kickoff can take longer to trigger, given that HW will wait for the input fences signal. Therefore, this change increments the time-outs to wait up to ~10 secs, which corresponds to the current input dma-fences timeout. This ~10secs wait is given in intervals, where the dma-fence is also checked, so in case that the client producer of the fence signals the dma-fence, but misses the hw-fence signaling, Display driver can handle this case and do a sw-override to start the fetching of the incoming frame without waiting for the input hw-fence ipc signal. Change-Id: I6fcacbbaa79ca9847da616bd52efdda4bb8fccae Signed-off-by: Christina Oliveira <quic_coliveir@quicinc.com>
This commit is contained in:
@@ -384,6 +384,55 @@ static int _sde_encoder_wait_timeout(int32_t drm_id, int32_t hw_id,
|
||||
return rc;
|
||||
}
|
||||
|
||||
int sde_encoder_helper_hw_fence_extended_wait(struct sde_encoder_phys *phys_enc,
|
||||
struct sde_hw_ctl *ctl, struct sde_encoder_wait_info *wait_info, int wait_type)
|
||||
{
|
||||
int ret = -ETIMEDOUT;
|
||||
s64 standard_kickoff_timeout_ms = wait_info->timeout_ms;
|
||||
int timeout_iters = EXTENDED_KICKOFF_TIMEOUT_ITERS;
|
||||
|
||||
wait_info->timeout_ms = EXTENDED_KICKOFF_TIMEOUT_MS;
|
||||
|
||||
while (ret == -ETIMEDOUT && timeout_iters--) {
|
||||
ret = sde_encoder_helper_wait_for_irq(phys_enc, wait_type, wait_info);
|
||||
if (ret == -ETIMEDOUT) {
|
||||
/* if dma_fence is not signaled, keep waiting */
|
||||
if (!sde_crtc_is_fence_signaled(phys_enc->parent->crtc))
|
||||
continue;
|
||||
|
||||
/* timed-out waiting and no sw-override support for hw-fences */
|
||||
if (!ctl || !ctl->ops.hw_fence_trigger_sw_override) {
|
||||
SDE_ERROR("invalid argument(s)\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* In case the sw and hw fences were triggered at the same time,
|
||||
* wait the standard kickoff time one more time. Only override if
|
||||
* we timeout again.
|
||||
*/
|
||||
wait_info->timeout_ms = standard_kickoff_timeout_ms;
|
||||
ret = sde_encoder_helper_wait_for_irq(phys_enc, wait_type, wait_info);
|
||||
if (ret == -ETIMEDOUT) {
|
||||
sde_encoder_helper_hw_fence_sw_override(phys_enc, ctl);
|
||||
|
||||
/*
|
||||
* wait the original timeout time again if we
|
||||
* did sw override due to fence being signaled
|
||||
*/
|
||||
ret = sde_encoder_helper_wait_for_irq(phys_enc, wait_type,
|
||||
wait_info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* reset the timeout value */
|
||||
wait_info->timeout_ms = standard_kickoff_timeout_ms;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool sde_encoder_is_primary_display(struct drm_encoder *drm_enc)
|
||||
{
|
||||
struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
|
||||
@@ -4888,6 +4937,18 @@ int sde_encoder_helper_reset_mixers(struct sde_encoder_phys *phys_enc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sde_encoder_helper_hw_fence_sw_override(struct sde_encoder_phys *phys_enc,
|
||||
struct sde_hw_ctl *ctl)
|
||||
{
|
||||
if (!ctl || !ctl->ops.hw_fence_trigger_sw_override)
|
||||
return;
|
||||
|
||||
SDE_EVT32(DRMID(phys_enc->parent), ctl->idx, ctl->ops.get_hw_fence_status ?
|
||||
ctl->ops.get_hw_fence_status(ctl) : SDE_EVTLOG_ERROR);
|
||||
sde_encoder_helper_reset_mixers(phys_enc, NULL);
|
||||
ctl->ops.hw_fence_trigger_sw_override(ctl);
|
||||
}
|
||||
|
||||
int sde_encoder_prepare_commit(struct drm_encoder *drm_enc)
|
||||
{
|
||||
struct sde_encoder_virt *sde_enc;
|
||||
|
Viittaa uudesa ongelmassa
Block a user