Bläddra i källkod

disp: msm: sde: update TEAR_SYNC_WRCOUNT register before vsync counter

During DMS, when tear check registers are updated near
rd_ptr line count, it was resulting in a spurious
rd_ptr_irq to which frame is getting latched and causing
tearing on the screen. This change updates
TEAR_SYNC_WRCOUNT register before disabling the vsync
counter and adds a spinlock to avoid pre-emption.

Change-Id: I986dc3ce6fb3da5fed758c2f50562df44f2ab557
Signed-off-by: Yashwanth <[email protected]>
Yashwanth 3 år sedan
förälder
incheckning
374c86e91b
1 ändrade filer med 12 tillägg och 2 borttagningar
  1. 12 2
      msm/sde/sde_hw_intf.c

+ 12 - 2
msm/sde/sde_hw_intf.c

@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
  */
 #include <linux/iopoll.h>
@@ -616,10 +617,12 @@ static int sde_hw_intf_setup_te_config(struct sde_hw_intf *intf,
 {
 	struct sde_hw_blk_reg_map *c;
 	u32 cfg = 0;
+	spinlock_t tearcheck_spinlock;
 
 	if (!intf)
 		return -EINVAL;
 
+	spin_lock_init(&tearcheck_spinlock);
 	c = &intf->hw;
 
 	if (te->hw_vsync_mode)
@@ -627,6 +630,14 @@ static int sde_hw_intf_setup_te_config(struct sde_hw_intf *intf,
 
 	cfg |= te->vsync_count;
 
+	/*
+	 * Local spinlock is acquired here to avoid pre-emption
+	 * as below register programming should be completed in
+	 * less than 2^16 vsync clk cycles.
+	 */
+	spin_lock(&tearcheck_spinlock);
+	SDE_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT,
+			(te->start_pos + te->sync_threshold_start + 1));
 	SDE_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg);
 	wmb(); /* disable vsync counter before updating single buffer registers */
 	SDE_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_HEIGHT, te->sync_cfg_height);
@@ -637,10 +648,9 @@ static int sde_hw_intf_setup_te_config(struct sde_hw_intf *intf,
 	SDE_REG_WRITE(c, INTF_TEAR_SYNC_THRESH,
 			((te->sync_threshold_continue << 16) |
 			 te->sync_threshold_start));
-	SDE_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT,
-			(te->start_pos + te->sync_threshold_start + 1));
 	cfg |= BIT(19); /* VSYNC_COUNTER_EN */
 	SDE_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg);
+	spin_unlock(&tearcheck_spinlock);
 
 	return 0;
 }