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:
@@ -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);
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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(
|
||||||
|
Reference in New Issue
Block a user