Răsfoiți Sursa

disp: msm: wb: Add support for IRQs in new Pingpong blocks

For dedicated CWB pingpong blocks, the overflow irq needs
to be mapped properly to existing IRQ handlers. Add the
needed changes in code.

Change-Id: Ibf398faac60acc027e4577504f9292ac2b72bae2
Signed-off-by: Chandan Uddaraju <[email protected]>
Chandan Uddaraju 4 ani în urmă
părinte
comite
2c252d9f5c
3 a modificat fișierele cu 84 adăugiri și 54 ștergeri
  1. 3 1
      msm/sde/sde_encoder_phys.h
  2. 77 52
      msm/sde/sde_encoder_phys_wb.c
  3. 4 1
      msm/sde/sde_hw_interrupts.c

+ 3 - 1
msm/sde/sde_encoder_phys.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef __SDE_ENCODER_PHYS_H__
@@ -202,6 +202,7 @@ struct sde_encoder_phys_ops {
  * @INTR_IDX_PP3_OVFL: Pingpong overflow interrupt on PP3 for Concurrent WB
  * @INTR_IDX_PP4_OVFL: Pingpong overflow interrupt on PP4 for Concurrent WB
  * @INTR_IDX_PP5_OVFL: Pingpong overflow interrupt on PP5 for Concurrent WB
+ * @INTR_IDX_PP_CWB_OVFL: Pingpong overflow interrupt on PP_CWB0/1 for Concurrent WB
  * @INTR_IDX_AUTOREFRESH_DONE:  Autorefresh done for cmd mode panel meaning
  *                              autorefresh has triggered a double buffer flip
  * @INTR_IDX_WRPTR:    Writepointer start interrupt for cmd mode panel
@@ -219,6 +220,7 @@ enum sde_intr_idx {
 	INTR_IDX_PP3_OVFL,
 	INTR_IDX_PP4_OVFL,
 	INTR_IDX_PP5_OVFL,
+	INTR_IDX_PP_CWB_OVFL,
 	INTR_IDX_WRPTR,
 	INTR_IDX_MAX,
 };

+ 77 - 52
msm/sde/sde_encoder_phys_wb.c

@@ -30,7 +30,7 @@
 
 static const u32 cwb_irq_tbl[PINGPONG_MAX] = {SDE_NONE, INTR_IDX_PP1_OVFL,
 	INTR_IDX_PP2_OVFL, INTR_IDX_PP3_OVFL, INTR_IDX_PP4_OVFL,
-	INTR_IDX_PP5_OVFL, SDE_NONE, SDE_NONE};
+	INTR_IDX_PP5_OVFL, INTR_IDX_PP_CWB_OVFL, SDE_NONE};
 
 /**
  * sde_rgb2yuv_601l - rgb to yuv color space conversion matrix
@@ -1164,8 +1164,10 @@ static void sde_encoder_phys_wb_irq_ctrl(
 {
 
 	struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys);
+	const struct sde_wb_cfg *wb_cfg;
 	int index = 0, refcount;
 	int ret = 0, pp = 0;
+	u32 max_num_of_irqs = 0;
 
 	if (!wb_enc)
 		return;
@@ -1178,15 +1180,23 @@ static void sde_encoder_phys_wb_irq_ctrl(
 		SDE_ERROR("invalid pingpong index for WB or CWB\n");
 		return;
 	}
-
 	refcount = atomic_read(&phys->wbirq_refcount);
 
+	/*
+	 * For Dedicated CWB, only one overflow IRQ is used for
+	 * both the PP_CWB blks. Make sure only one IRQ is registered
+	 * when D-CWB is enabled.
+	 */
+	wb_cfg = wb_enc->hw_wb->caps;
+	max_num_of_irqs = (wb_cfg->features & BIT(SDE_WB_HAS_DCWB)) ?
+					1 : CRTC_DUAL_MIXERS_ONLY;
+
 	if (enable && atomic_inc_return(&phys->wbirq_refcount) == 1) {
 		sde_encoder_helper_register_irq(phys, INTR_IDX_WB_DONE);
 		if (ret)
 			atomic_dec_return(&phys->wbirq_refcount);
 
-		for (index = 0; index < CRTC_DUAL_MIXERS_ONLY; index++)
+		for (index = 0; index < max_num_of_irqs; index++)
 			if (cwb_irq_tbl[index + pp] != SDE_NONE)
 				sde_encoder_helper_register_irq(phys,
 					cwb_irq_tbl[index + pp]);
@@ -1196,7 +1206,7 @@ static void sde_encoder_phys_wb_irq_ctrl(
 		if (ret)
 			atomic_inc_return(&phys->wbirq_refcount);
 
-		for (index = 0; index < CRTC_DUAL_MIXERS_ONLY; index++)
+		for (index = 0; index < max_num_of_irqs; index++)
 			if (cwb_irq_tbl[index + pp] != SDE_NONE)
 				sde_encoder_helper_unregister_irq(phys,
 					cwb_irq_tbl[index + pp]);
@@ -1870,6 +1880,7 @@ struct sde_encoder_phys *sde_encoder_phys_wb_init(
 {
 	struct sde_encoder_phys *phys_enc;
 	struct sde_encoder_phys_wb *wb_enc;
+	const struct sde_wb_cfg *wb_cfg;
 	struct sde_hw_mdp *hw_mdp;
 	struct sde_encoder_irq *irq;
 	int ret = 0;
@@ -1952,6 +1963,7 @@ struct sde_encoder_phys *sde_encoder_phys_wb_init(
 	atomic_set(&phys_enc->pending_retire_fence_cnt, 0);
 	atomic_set(&phys_enc->wbirq_refcount, 0);
 	init_waitqueue_head(&phys_enc->pending_kickoff_wq);
+	wb_cfg = wb_enc->hw_wb->caps;
 
 	irq = &phys_enc->irq[INTR_IDX_WB_DONE];
 	INIT_LIST_HEAD(&irq->cb.list);
@@ -1963,55 +1975,68 @@ struct sde_encoder_phys *sde_encoder_phys_wb_init(
 	irq->cb.arg = wb_enc;
 	irq->cb.func = sde_encoder_phys_wb_done_irq;
 
-	irq = &phys_enc->irq[INTR_IDX_PP1_OVFL];
-	INIT_LIST_HEAD(&irq->cb.list);
-	irq->name = "pp1_overflow";
-	irq->hw_idx = CWB_1;
-	irq->irq_idx = -1;
-	irq->intr_type = SDE_IRQ_TYPE_CWB_OVERFLOW;
-	irq->intr_idx = INTR_IDX_PP1_OVFL;
-	irq->cb.arg = wb_enc;
-	irq->cb.func = sde_encoder_phys_cwb_ovflow;
-
-	irq = &phys_enc->irq[INTR_IDX_PP2_OVFL];
-	INIT_LIST_HEAD(&irq->cb.list);
-	irq->name = "pp2_overflow";
-	irq->hw_idx = CWB_2;
-	irq->irq_idx = -1;
-	irq->intr_type = SDE_IRQ_TYPE_CWB_OVERFLOW;
-	irq->intr_idx = INTR_IDX_PP2_OVFL;
-	irq->cb.arg = wb_enc;
-	irq->cb.func = sde_encoder_phys_cwb_ovflow;
-
-	irq = &phys_enc->irq[INTR_IDX_PP3_OVFL];
-	INIT_LIST_HEAD(&irq->cb.list);
-	irq->name = "pp3_overflow";
-	irq->hw_idx = CWB_3;
-	irq->irq_idx = -1;
-	irq->intr_type = SDE_IRQ_TYPE_CWB_OVERFLOW;
-	irq->intr_idx = INTR_IDX_PP3_OVFL;
-	irq->cb.arg = wb_enc;
-	irq->cb.func = sde_encoder_phys_cwb_ovflow;
-
-	irq = &phys_enc->irq[INTR_IDX_PP4_OVFL];
-	INIT_LIST_HEAD(&irq->cb.list);
-	irq->name = "pp4_overflow";
-	irq->hw_idx = CWB_4;
-	irq->irq_idx = -1;
-	irq->intr_type = SDE_IRQ_TYPE_CWB_OVERFLOW;
-	irq->intr_idx = INTR_IDX_PP4_OVFL;
-	irq->cb.arg = wb_enc;
-	irq->cb.func = sde_encoder_phys_cwb_ovflow;
+	if (wb_cfg && (wb_cfg->features & BIT(SDE_WB_HAS_DCWB))) {
+		irq = &phys_enc->irq[INTR_IDX_PP_CWB_OVFL];
+		INIT_LIST_HEAD(&irq->cb.list);
+		irq->name = "pp_cwb0_overflow";
+		irq->hw_idx = PINGPONG_CWB_0;
+		irq->irq_idx = -1;
+		irq->intr_type = SDE_IRQ_TYPE_CWB_OVERFLOW;
+		irq->intr_idx = INTR_IDX_PP_CWB_OVFL;
+		irq->cb.arg = wb_enc;
+		irq->cb.func = sde_encoder_phys_cwb_ovflow;
 
-	irq = &phys_enc->irq[INTR_IDX_PP5_OVFL];
-	INIT_LIST_HEAD(&irq->cb.list);
-	irq->name = "pp5_overflow";
-	irq->hw_idx = CWB_5;
-	irq->irq_idx = -1;
-	irq->intr_type = SDE_IRQ_TYPE_CWB_OVERFLOW;
-	irq->intr_idx = INTR_IDX_PP5_OVFL;
-	irq->cb.arg = wb_enc;
-	irq->cb.func = sde_encoder_phys_cwb_ovflow;
+	} else {
+		irq = &phys_enc->irq[INTR_IDX_PP1_OVFL];
+		INIT_LIST_HEAD(&irq->cb.list);
+		irq->name = "pp1_overflow";
+		irq->hw_idx = CWB_1;
+		irq->irq_idx = -1;
+		irq->intr_type = SDE_IRQ_TYPE_CWB_OVERFLOW;
+		irq->intr_idx = INTR_IDX_PP1_OVFL;
+		irq->cb.arg = wb_enc;
+		irq->cb.func = sde_encoder_phys_cwb_ovflow;
+
+		irq = &phys_enc->irq[INTR_IDX_PP2_OVFL];
+		INIT_LIST_HEAD(&irq->cb.list);
+		irq->name = "pp2_overflow";
+		irq->hw_idx = CWB_2;
+		irq->irq_idx = -1;
+		irq->intr_type = SDE_IRQ_TYPE_CWB_OVERFLOW;
+		irq->intr_idx = INTR_IDX_PP2_OVFL;
+		irq->cb.arg = wb_enc;
+		irq->cb.func = sde_encoder_phys_cwb_ovflow;
+
+		irq = &phys_enc->irq[INTR_IDX_PP3_OVFL];
+		INIT_LIST_HEAD(&irq->cb.list);
+		irq->name = "pp3_overflow";
+		irq->hw_idx = CWB_3;
+		irq->irq_idx = -1;
+		irq->intr_type = SDE_IRQ_TYPE_CWB_OVERFLOW;
+		irq->intr_idx = INTR_IDX_PP3_OVFL;
+		irq->cb.arg = wb_enc;
+		irq->cb.func = sde_encoder_phys_cwb_ovflow;
+
+		irq = &phys_enc->irq[INTR_IDX_PP4_OVFL];
+		INIT_LIST_HEAD(&irq->cb.list);
+		irq->name = "pp4_overflow";
+		irq->hw_idx = CWB_4;
+		irq->irq_idx = -1;
+		irq->intr_type = SDE_IRQ_TYPE_CWB_OVERFLOW;
+		irq->intr_idx = INTR_IDX_PP4_OVFL;
+		irq->cb.arg = wb_enc;
+		irq->cb.func = sde_encoder_phys_cwb_ovflow;
+
+		irq = &phys_enc->irq[INTR_IDX_PP5_OVFL];
+		INIT_LIST_HEAD(&irq->cb.list);
+		irq->name = "pp5_overflow";
+		irq->hw_idx = CWB_5;
+		irq->irq_idx = -1;
+		irq->intr_type = SDE_IRQ_TYPE_CWB_OVERFLOW;
+		irq->intr_idx = INTR_IDX_PP5_OVFL;
+		irq->cb.arg = wb_enc;
+		irq->cb.func = sde_encoder_phys_cwb_ovflow;
+	}
 
 	/* create internal buffer for disable logic */
 	if (_sde_encoder_phys_wb_init_internal_fb(wb_enc,

+ 4 - 1
msm/sde/sde_hw_interrupts.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/bitops.h>
@@ -121,6 +121,7 @@
 #define SDE_INTR_CWB_3_OVERFLOW BIT(15)
 #define SDE_INTR_CWB_4_OVERFLOW BIT(20)
 #define SDE_INTR_CWB_5_OVERFLOW BIT(21)
+#define SDE_INTR_CWB_OVERFLOW BIT(29)
 
 /**
  * Histogram VIG done interrupt status bit definitions
@@ -344,6 +345,8 @@ static struct sde_irq_type sde_irq_intr2_map[] = {
 	{ SDE_IRQ_TYPE_PING_PONG_TE_CHECK, PINGPONG_S0,
 		SDE_INTR_PING_PONG_S0_TE_DETECTED, -1},
 
+	{ SDE_IRQ_TYPE_CWB_OVERFLOW, PINGPONG_CWB_0, SDE_INTR_CWB_OVERFLOW, -1},
+
 	{ SDE_IRQ_TYPE_PING_PONG_COMP, PINGPONG_4,
 		SDE_INTR_PING_PONG_4_DONE, -1},
 	{ SDE_IRQ_TYPE_PING_PONG_COMP, PINGPONG_5,