Browse Source

disp: msm: add api to get active status of hw blocks

This change introduces new ctl path api read_active_status to check
if a particular hw block is active or not in the current control path.
This is specially required in continuous splash use case when bootloader
has programmed certain blocks and the kernel driver tries to find
out the same configuration. This is used to ascertain which DSC block
is active in continuous splash case since DSC blocks are not tied to
mixer blocks.

Change-Id: I8dd590aa2dc764bd340727c166e1133ef9ce7af5
Signed-off-by: Abhijit Kulkarni <[email protected]>
Abhijit Kulkarni 5 years ago
parent
commit
1ef5cee6ca
3 changed files with 65 additions and 21 deletions
  1. 38 1
      msm/sde/sde_hw_ctl.c
  2. 12 1
      msm/sde/sde_hw_ctl.h
  3. 15 19
      msm/sde/sde_rm.c

+ 38 - 1
msm/sde/sde_hw_ctl.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/delay.h>
@@ -1220,6 +1220,42 @@ static inline u32 sde_hw_ctl_read_ctl_layers(struct sde_hw_ctl *ctx, int index)
 	return ctl_top;
 }
 
+static inline bool sde_hw_ctl_read_active_status(struct sde_hw_ctl *ctx,
+		enum sde_hw_blk_type blk, int index)
+{
+	struct sde_hw_blk_reg_map *c;
+
+	if (!ctx) {
+		pr_err("Invalid input argument\n");
+		return 0;
+	}
+
+	c = &ctx->hw;
+
+	switch (blk) {
+	case SDE_HW_BLK_MERGE_3D:
+		return (SDE_REG_READ(c, CTL_MERGE_3D_ACTIVE) &
+			BIT(index - MERGE_3D_0)) ? true : false;
+	case SDE_HW_BLK_DSC:
+		return (SDE_REG_READ(c, CTL_DSC_ACTIVE) &
+			BIT(index - DSC_0)) ? true : false;
+	case SDE_HW_BLK_WB:
+		return (SDE_REG_READ(c, CTL_WB_ACTIVE) &
+			BIT(index - WB_0)) ? true : false;
+	case SDE_HW_BLK_CDM:
+		return (SDE_REG_READ(c, CTL_CDM_ACTIVE) &
+			BIT(index - CDM_0)) ? true : false;
+	case SDE_HW_BLK_INTF:
+		return (SDE_REG_READ(c, CTL_INTF_ACTIVE) &
+			BIT(index - INTF_0)) ? true : false;
+	default:
+		pr_err("unsupported blk %d\n", blk);
+		return false;
+	};
+
+	return false;
+}
+
 static int sde_hw_reg_dma_flush(struct sde_hw_ctl *ctx, bool blocking)
 {
 	struct sde_hw_reg_dma_ops *ops = sde_reg_dma_get_ops();
@@ -1259,6 +1295,7 @@ static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops,
 		ops->get_ctl_intf = sde_hw_ctl_get_intf_v1;
 		ops->reset_post_disable = sde_hw_ctl_reset_post_disable;
 		ops->get_scheduler_status = sde_hw_ctl_get_scheduler_status;
+		ops->read_active_status = sde_hw_ctl_read_active_status;
 	} else {
 		ops->update_pending_flush = sde_hw_ctl_update_pending_flush;
 		ops->trigger_flush = sde_hw_ctl_trigger_flush;

+ 12 - 1
msm/sde/sde_hw_ctl.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _SDE_HW_CTL_H
@@ -435,6 +435,17 @@ struct sde_hw_ctl_ops {
 	 */
 	u32 (*read_ctl_layers)(struct sde_hw_ctl *ctx, int index);
 
+	/**
+	 * read active register configuration for this block
+	 * @ctx       : ctl path ctx pointer
+	 * @blk       : hw blk type, supported blocks are DSC, MERGE_3D, INTF,
+	 *              CDM, WB
+	 * @index     : blk index
+	 * @return    : true if blk at idx is active or false
+	 */
+	bool (*read_active_status)(struct sde_hw_ctl *ctx,
+			enum sde_hw_blk_type blk, int index);
+
 	/**
 	 * Set all blend stages to disabled
 	 * @ctx       : ctl path ctx pointer

+ 15 - 19
msm/sde/sde_rm.c

@@ -1264,11 +1264,6 @@ static int _sde_rm_reserve_dsc(
 		bool has_422_420_support =
 			BIT(SDE_DSC_NATIVE_422_EN) & features;
 
-		SDE_DEBUG("blk id = %d, is_422_420_req:%d ,is_supported:%d\n",
-				iter_i.blk->id,
-				(dsc_info->config.native_422 ||
-				dsc_info->config.native_420),
-				has_422_420_support);
 		memset(&dsc, 0, sizeof(dsc));
 		alloc_count = 0;
 
@@ -1660,8 +1655,7 @@ static int _sde_rm_get_hw_blk_for_cont_splash(struct sde_rm *rm,
 		struct sde_splash_display *splash_display)
 {
 	u32 lm_reg;
-	struct sde_rm_hw_iter iter_lm, iter_pp;
-	struct sde_hw_pingpong *pp;
+	struct sde_rm_hw_iter iter_lm, iter_dsc;
 
 	if (!rm || !ctl || !splash_display) {
 		SDE_ERROR("invalid input parameters\n");
@@ -1669,10 +1663,8 @@ static int _sde_rm_get_hw_blk_for_cont_splash(struct sde_rm *rm,
 	}
 
 	sde_rm_init_hw_iter(&iter_lm, 0, SDE_HW_BLK_LM);
-	sde_rm_init_hw_iter(&iter_pp, 0, SDE_HW_BLK_PINGPONG);
+	sde_rm_init_hw_iter(&iter_dsc, 0, SDE_HW_BLK_DSC);
 	while (_sde_rm_get_hw_locked(rm, &iter_lm)) {
-		_sde_rm_get_hw_locked(rm, &iter_pp);
-
 		if (splash_display->lm_cnt >= MAX_DATA_PATH_PER_DSIPLAY)
 			break;
 
@@ -1695,16 +1687,20 @@ static int _sde_rm_get_hw_blk_for_cont_splash(struct sde_rm *rm,
 					iter_lm.blk->id - LM_0);
 			return 0;
 		}
+	}
 
-		pp = to_sde_hw_pingpong(iter_pp.blk->hw);
-		if (pp && pp->ops.get_dsc_status &&
-				pp->ops.get_dsc_status(pp)) {
-			splash_display->dsc_ids[splash_display->dsc_cnt++] =
-				iter_pp.blk->id;
-			SDE_DEBUG("lm/pp[%d] path, using dsc[%d]\n",
-					iter_lm.blk->id - LM_0,
-					iter_pp.blk->id - DSC_0);
-		}
+	while (_sde_rm_get_hw_locked(rm, &iter_dsc)) {
+		if (!ctl->ops.read_active_status &&
+				!(ctl->ops.read_active_status(ctl,
+					SDE_HW_BLK_DSC,
+					iter_dsc.blk->id)))
+			continue;
+
+		splash_display->dsc_ids[splash_display->dsc_cnt++] =
+				iter_dsc.blk->id;
+		SDE_DEBUG("CTL[%d] path, using dsc[%d]\n",
+				ctl->idx,
+				iter_dsc.blk->id - DSC_0);
 	}
 
 	return splash_display->lm_cnt;