Browse Source

disp: msm: sde: add memory barrier to avoid out of order writes

add memory barrier before and after last command to avoid
out of order packet queuing to lut dma packet queue.

add memory barrier after ctrl flush to ensure lut dma
trigger, dspp flush and ctrl flush all are written to dpu
before control start.

Change-Id: I7e1613034af8407d55529cf3f95c70994334af82
Signed-off-by: Anjaneya Prasad Musunuri <[email protected]>
Anjaneya Prasad Musunuri 2 years ago
parent
commit
e56fac8872
2 changed files with 15 additions and 2 deletions
  1. 4 1
      msm/sde/sde_hw_ctl.c
  2. 11 1
      msm/sde/sde_hw_reg_dma_v1.c

+ 4 - 1
msm/sde/sde_hw_ctl.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 // SPDX-License-Identifier: GPL-2.0-only
 /*
 /*
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 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.
  */
  */
 
 
@@ -818,6 +818,9 @@ static inline int sde_hw_ctl_trigger_flush_v1(struct sde_hw_ctl *ctx)
 
 
 	SDE_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->flush.pending_flush_mask);
 	SDE_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->flush.pending_flush_mask);
 
 
+	/* ensure all register writes are written without re-ordering*/
+	wmb();
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 11 - 1
msm/sde/sde_hw_reg_dma_v1.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 // SPDX-License-Identifier: GPL-2.0-only
 /*
 /*
- * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
  */
  */
 
 
@@ -709,6 +709,13 @@ static int write_kick_off_v1(struct sde_reg_dma_kickoff_cfg *cfg)
 		SDE_EVT32(val);
 		SDE_EVT32(val);
 	}
 	}
 
 
+	if (cfg->last_command) {
+		/* ensure all packets are queued in packet queue before
+		 * queuing last command descriptor (last command)
+		 */
+		wmb();
+	}
+
 	if (cfg->dma_type == REG_DMA_TYPE_DB) {
 	if (cfg->dma_type == REG_DMA_TYPE_DB) {
 		SDE_REG_WRITE(&hw, reg_dma_ctl_queue_off[cfg->ctl->idx],
 		SDE_REG_WRITE(&hw, reg_dma_ctl_queue_off[cfg->ctl->idx],
 				cfg->dma_buf->iova);
 				cfg->dma_buf->iova);
@@ -722,6 +729,9 @@ static int write_kick_off_v1(struct sde_reg_dma_kickoff_cfg *cfg)
 	}
 	}
 
 
 	if (cfg->last_command) {
 	if (cfg->last_command) {
+		/* ensure last command is queued before lut dma trigger */
+		wmb();
+
 		mask = ctl_trigger_done_mask[cfg->ctl->idx][cfg->queue_select];
 		mask = ctl_trigger_done_mask[cfg->ctl->idx][cfg->queue_select];
 		SDE_REG_WRITE(&hw, reg_dma_intr_0_clear_offset[cfg->ctl->idx][cfg->queue_select],
 		SDE_REG_WRITE(&hw, reg_dma_intr_0_clear_offset[cfg->ctl->idx][cfg->queue_select],
 				mask);
 				mask);