Explorar el Código

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 <[email protected]>
Veera Sundaram Sankaran hace 3 años
padre
commit
e50d08286f
Se han modificado 3 ficheros con 29 adiciones y 13 borrados
  1. 11 2
      msm/sde/sde_encoder.c
  2. 3 1
      msm/sde/sde_encoder_phys.h
  3. 15 10
      msm/sde/sde_encoder_phys_cmd.c

+ 11 - 2
msm/sde/sde_encoder.c

@@ -3177,9 +3177,18 @@ static void sde_encoder_virt_disable(struct drm_encoder *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_input_handler_unregister(drm_enc);
 

+ 3 - 1
msm/sde/sde_encoder_phys.h

@@ -1,6 +1,6 @@
 /* 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.
  */
 
@@ -136,6 +136,7 @@ struct sde_encoder_virt_ops {
  * @get_underrun_line_count:	Obtain and log current internal vertical line
  *                              count and underrun line count
  * @add_to_minidump:		Add this phys_enc data to minidumps
+ * @disable_autorefresh:	Disable autorefresh
  */
 
 struct sde_encoder_phys_ops {
@@ -189,6 +190,7 @@ struct sde_encoder_phys_ops {
 			struct msm_display_info *disp_info);
 	u32 (*get_underrun_line_count)(struct sde_encoder_phys *phys);
 	void (*add_to_minidump)(struct sde_encoder_phys *phys);
+	void (*disable_autorefresh)(struct sde_encoder_phys *phys);
 };
 
 /**

+ 15 - 10
msm/sde/sde_encoder_phys_cmd.c

@@ -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);
 	spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
 
-	SDE_EVT32_IRQ(DRMID(phys_enc->parent),
-			phys_enc->hw_pp->idx - PINGPONG_0,
-			phys_enc->hw_intf->idx - INTF_0,
-			new_cnt);
+	SDE_EVT32_IRQ(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0,
+			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 */
 	wake_up_all(&cmd_enc->autorefresh.kickoff_wq);
@@ -1858,9 +1859,7 @@ static void _sde_encoder_autorefresh_disable_seq2(
 			tear_status.write_count);
 	}
 }
-
-static void sde_encoder_phys_cmd_prepare_commit(
-		struct sde_encoder_phys *phys_enc)
+static void _sde_encoder_phys_disable_autorefresh(struct sde_encoder_phys *phys_enc)
 {
 	struct sde_encoder_phys_cmd *cmd_enc = to_sde_encoder_phys_cmd(phys_enc);
 	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))
 		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,
 			cmd_enc->autorefresh.cfg.enable);
 
-	if (!sde_encoder_phys_cmd_is_autorefresh_enabled(phys_enc))
-		return;
+	sde_kms = phys_enc->sde_kms;
 
 	sde_encoder_phys_cmd_connect_te(phys_enc, false);
 	_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");
 }
 
+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(
 		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->collect_misr = sde_encoder_helper_collect_misr;
 	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(