disp: msm: sde: disable autorefresh on encoder disable

Disable the autorefresh during encoder disable to avoid any
pending frame transfers while disabling. Additionally, handle
frame_done for new autorefresh frames to signal the fences and
proper accounting of pending_kickoff counter.

Change-Id: I8af114972b19ccdf0edab6b4c454ee90b4e8d8cf
Signed-off-by: Veera Sundaram Sankaran <quic_veeras@quicinc.com>
This commit is contained in:
Veera Sundaram Sankaran
2022-03-24 15:01:29 -07:00
parent 6e050f641a
commit e50d08286f
3 changed files with 29 additions and 13 deletions

View File

@@ -3177,9 +3177,18 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
SDE_EVT32(DRMID(drm_enc)); SDE_EVT32(DRMID(drm_enc));
/* wait for idle */ if (!sde_encoder_in_clone_mode(drm_enc)) {
if (!sde_encoder_in_clone_mode(drm_enc)) /* disable autorefresh */
for (i = 0; i < sde_enc->num_phys_encs; i++) {
struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
if (phys && phys->ops.disable_autorefresh)
phys->ops.disable_autorefresh(phys);
}
/* wait for idle */
sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE); sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
}
_sde_encoder_input_handler_unregister(drm_enc); _sde_encoder_input_handler_unregister(drm_enc);

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
*/ */
@@ -136,6 +136,7 @@ struct sde_encoder_virt_ops {
* @get_underrun_line_count: Obtain and log current internal vertical line * @get_underrun_line_count: Obtain and log current internal vertical line
* count and underrun line count * count and underrun line count
* @add_to_minidump: Add this phys_enc data to minidumps * @add_to_minidump: Add this phys_enc data to minidumps
* @disable_autorefresh: Disable autorefresh
*/ */
struct sde_encoder_phys_ops { struct sde_encoder_phys_ops {
@@ -189,6 +190,7 @@ struct sde_encoder_phys_ops {
struct msm_display_info *disp_info); struct msm_display_info *disp_info);
u32 (*get_underrun_line_count)(struct sde_encoder_phys *phys); u32 (*get_underrun_line_count)(struct sde_encoder_phys *phys);
void (*add_to_minidump)(struct sde_encoder_phys *phys); void (*add_to_minidump)(struct sde_encoder_phys *phys);
void (*disable_autorefresh)(struct sde_encoder_phys *phys);
}; };
/** /**

View File

@@ -250,10 +250,11 @@ static void sde_encoder_phys_cmd_autorefresh_done_irq(void *arg, int irq_idx)
new_cnt = atomic_add_unless(&cmd_enc->autorefresh.kickoff_cnt, -1, 0); new_cnt = atomic_add_unless(&cmd_enc->autorefresh.kickoff_cnt, -1, 0);
spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
SDE_EVT32_IRQ(DRMID(phys_enc->parent), SDE_EVT32_IRQ(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0,
phys_enc->hw_pp->idx - PINGPONG_0, phys_enc->hw_intf->idx - INTF_0, new_cnt);
phys_enc->hw_intf->idx - INTF_0,
new_cnt); if (new_cnt)
_sde_encoder_phys_signal_frame_done(phys_enc);
/* Signal any waiting atomic commit thread */ /* Signal any waiting atomic commit thread */
wake_up_all(&cmd_enc->autorefresh.kickoff_wq); wake_up_all(&cmd_enc->autorefresh.kickoff_wq);
@@ -1858,9 +1859,7 @@ static void _sde_encoder_autorefresh_disable_seq2(
tear_status.write_count); tear_status.write_count);
} }
} }
static void _sde_encoder_phys_disable_autorefresh(struct sde_encoder_phys *phys_enc)
static void sde_encoder_phys_cmd_prepare_commit(
struct sde_encoder_phys *phys_enc)
{ {
struct sde_encoder_phys_cmd *cmd_enc = to_sde_encoder_phys_cmd(phys_enc); struct sde_encoder_phys_cmd *cmd_enc = to_sde_encoder_phys_cmd(phys_enc);
struct sde_kms *sde_kms; struct sde_kms *sde_kms;
@@ -1868,13 +1867,13 @@ static void sde_encoder_phys_cmd_prepare_commit(
if (!phys_enc || !sde_encoder_phys_cmd_is_master(phys_enc)) if (!phys_enc || !sde_encoder_phys_cmd_is_master(phys_enc))
return; return;
sde_kms = phys_enc->sde_kms; if (!sde_encoder_phys_cmd_is_autorefresh_enabled(phys_enc))
return;
SDE_EVT32(DRMID(phys_enc->parent), phys_enc->intf_idx - INTF_0, SDE_EVT32(DRMID(phys_enc->parent), phys_enc->intf_idx - INTF_0,
cmd_enc->autorefresh.cfg.enable); cmd_enc->autorefresh.cfg.enable);
if (!sde_encoder_phys_cmd_is_autorefresh_enabled(phys_enc)) sde_kms = phys_enc->sde_kms;
return;
sde_encoder_phys_cmd_connect_te(phys_enc, false); sde_encoder_phys_cmd_connect_te(phys_enc, false);
_sde_encoder_phys_cmd_config_autorefresh(phys_enc, 0); _sde_encoder_phys_cmd_config_autorefresh(phys_enc, 0);
@@ -1888,6 +1887,11 @@ static void sde_encoder_phys_cmd_prepare_commit(
SDE_DEBUG_CMDENC(cmd_enc, "autorefresh disabled successfully\n"); SDE_DEBUG_CMDENC(cmd_enc, "autorefresh disabled successfully\n");
} }
static void sde_encoder_phys_cmd_prepare_commit(struct sde_encoder_phys *phys_enc)
{
return _sde_encoder_phys_disable_autorefresh(phys_enc);
}
static void sde_encoder_phys_cmd_trigger_start( static void sde_encoder_phys_cmd_trigger_start(
struct sde_encoder_phys *phys_enc) struct sde_encoder_phys *phys_enc)
{ {
@@ -2009,6 +2013,7 @@ static void sde_encoder_phys_cmd_init_ops(struct sde_encoder_phys_ops *ops)
ops->setup_misr = sde_encoder_helper_setup_misr; ops->setup_misr = sde_encoder_helper_setup_misr;
ops->collect_misr = sde_encoder_helper_collect_misr; ops->collect_misr = sde_encoder_helper_collect_misr;
ops->add_to_minidump = sde_encoder_phys_cmd_add_enc_to_minidump; ops->add_to_minidump = sde_encoder_phys_cmd_add_enc_to_minidump;
ops->disable_autorefresh = _sde_encoder_phys_disable_autorefresh;
} }
static inline bool sde_encoder_phys_cmd_intf_te_supported( static inline bool sde_encoder_phys_cmd_intf_te_supported(