Selaa lähdekoodia

disp: msm: avoid BW_INDICATION write if BW does not change

This change avoids writing of BW_INDICATION registers on each
frame, instead it updates only when there is a change in bandwidth.

Change-Id: Iae32ceb065d2e49e81c2febbbac5508a624d090e
Signed-off-by: Narendra Muppalla <[email protected]>
Narendra Muppalla 3 vuotta sitten
vanhempi
sitoutus
f95fc01a9b
3 muutettua tiedostoa jossa 51 lisäystä ja 5 poistoa
  1. 9 3
      msm/sde_rsc.c
  2. 23 1
      msm/sde_rsc_hw_v3.c
  3. 19 1
      msm/sde_rsc_priv.h

+ 9 - 3
msm/sde_rsc.c

@@ -1039,7 +1039,6 @@ int sde_rsc_client_trigger_vote(struct sde_rsc_client *caller_client,
 {
 {
 	int rc = 0, rsc_index, i;
 	int rc = 0, rsc_index, i;
 	struct sde_rsc_priv *rsc;
 	struct sde_rsc_priv *rsc;
-	bool bw_increase = false;
 
 
 	if (caller_client && caller_client->rsc_index >= MAX_RSC_COUNT) {
 	if (caller_client && caller_client->rsc_index >= MAX_RSC_COUNT) {
 		pr_err("invalid rsc index\n");
 		pr_err("invalid rsc index\n");
@@ -1051,6 +1050,9 @@ int sde_rsc_client_trigger_vote(struct sde_rsc_client *caller_client,
 	if (!rsc)
 	if (!rsc)
 		return -EINVAL;
 		return -EINVAL;
 
 
+	if (rsc->bwi_update == BW_NO_CHANGE && !delta_vote && rsc->version >= SDE_RSC_REV_5)
+		return 0;
+
 	pr_debug("client:%s trigger bw delta vote:%d\n",
 	pr_debug("client:%s trigger bw delta vote:%d\n",
 		caller_client ? caller_client->name : "unknown", delta_vote);
 		caller_client ? caller_client->name : "unknown", delta_vote);
 
 
@@ -1060,10 +1062,11 @@ int sde_rsc_client_trigger_vote(struct sde_rsc_client *caller_client,
 			(rsc->current_state == SDE_RSC_CLK_STATE))
 			(rsc->current_state == SDE_RSC_CLK_STATE))
 		goto end;
 		goto end;
 
 
+	rsc->bwi_update = BW_HIGH_TO_LOW;
 	for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX && delta_vote; i++) {
 	for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX && delta_vote; i++) {
 		if (rsc->bw_config.new_ab_vote[i] > rsc->bw_config.ab_vote[i] ||
 		if (rsc->bw_config.new_ab_vote[i] > rsc->bw_config.ab_vote[i] ||
 		    rsc->bw_config.new_ib_vote[i] > rsc->bw_config.ib_vote[i])
 		    rsc->bw_config.new_ib_vote[i] > rsc->bw_config.ib_vote[i])
-			bw_increase = true;
+			rsc->bwi_update = BW_LOW_TO_HIGH;
 
 
 		rsc->bw_config.ab_vote[i] = rsc->bw_config.new_ab_vote[i];
 		rsc->bw_config.ab_vote[i] = rsc->bw_config.new_ab_vote[i];
 		rsc->bw_config.ib_vote[i] = rsc->bw_config.new_ib_vote[i];
 		rsc->bw_config.ib_vote[i] = rsc->bw_config.new_ib_vote[i];
@@ -1092,10 +1095,13 @@ int sde_rsc_client_trigger_vote(struct sde_rsc_client *caller_client,
 		rpmh_write_sleep_and_wake(rsc->rpmh_dev);
 		rpmh_write_sleep_and_wake(rsc->rpmh_dev);
 	}
 	}
 
 
+	if (rsc->version >= SDE_RSC_REV_5 && !delta_vote)
+		rsc->bwi_update = BW_NO_CHANGE;
+
 	if (rsc->hw_ops.bwi_status &&
 	if (rsc->hw_ops.bwi_status &&
 	    (rsc->current_state == SDE_RSC_CMD_STATE ||
 	    (rsc->current_state == SDE_RSC_CMD_STATE ||
 	     rsc->current_state == SDE_RSC_VID_STATE))
 	     rsc->current_state == SDE_RSC_VID_STATE))
-		rsc->hw_ops.bwi_status(rsc, bw_increase);
+		rsc->hw_ops.bwi_status(rsc);
 	else if (rsc->hw_ops.tcs_use_ok)
 	else if (rsc->hw_ops.tcs_use_ok)
 		rsc->hw_ops.tcs_use_ok(rsc);
 		rsc->hw_ops.tcs_use_ok(rsc);
 
 

+ 23 - 1
msm/sde_rsc_hw_v3.c

@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 // SPDX-License-Identifier: GPL-2.0-only
 /*
 /*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
  * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
  */
  */
 
 
@@ -13,6 +14,11 @@
 #include "sde_rsc_hw.h"
 #include "sde_rsc_hw.h"
 #include "sde_dbg.h"
 #include "sde_dbg.h"
 
 
+#define BWI_HIGH_TO_LOW		 0x00
+#define BWI_LOW_TO_HIGH		 0x01
+#define BWI_NO_CHANGE		 0x10
+
+
 static int _rsc_hw_qtimer_init(struct sde_rsc_priv *rsc)
 static int _rsc_hw_qtimer_init(struct sde_rsc_priv *rsc)
 {
 {
 	pr_debug("rsc hardware qtimer init\n");
 	pr_debug("rsc hardware qtimer init\n");
@@ -539,10 +545,26 @@ end:
 	return rc;
 	return rc;
 }
 }
 
 
-int rsc_hw_bwi_status_v3(struct sde_rsc_priv *rsc, bool bw_indication)
+int rsc_hw_bwi_status_v3(struct sde_rsc_priv *rsc)
 {
 {
 	int count, bw_ack;
 	int count, bw_ack;
 	int rc = 0;
 	int rc = 0;
+	u32 bw_indication = 0;
+
+	switch (rsc->bwi_update) {
+	case BW_HIGH_TO_LOW:
+		bw_indication = BWI_HIGH_TO_LOW;
+		break;
+	case BW_LOW_TO_HIGH:
+		bw_indication = BWI_LOW_TO_HIGH;
+		break;
+	case BW_NO_CHANGE:
+		bw_indication = BWI_NO_CHANGE;
+		break;
+	default:
+		pr_err("unsupported bwi data\n");
+		break;
+	}
 
 
 	dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_BW_INDICATION,
 	dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_BW_INDICATION,
 						bw_indication, rsc->debug_mode);
 						bw_indication, rsc->debug_mode);

+ 19 - 1
msm/sde_rsc_priv.h

@@ -94,7 +94,7 @@ struct sde_rsc_hw_ops {
 	int (*hw_vsync)(struct sde_rsc_priv *rsc, enum rsc_vsync_req request,
 	int (*hw_vsync)(struct sde_rsc_priv *rsc, enum rsc_vsync_req request,
 		char *buffer, int buffer_size, u32 mode);
 		char *buffer, int buffer_size, u32 mode);
 	int (*tcs_use_ok)(struct sde_rsc_priv *rsc);
 	int (*tcs_use_ok)(struct sde_rsc_priv *rsc);
-	int (*bwi_status)(struct sde_rsc_priv *rsc, bool bw_indication);
+	int (*bwi_status)(struct sde_rsc_priv *rsc);
 	bool (*is_amc_mode)(struct sde_rsc_priv *rsc);
 	bool (*is_amc_mode)(struct sde_rsc_priv *rsc);
 	void (*debug_dump)(struct sde_rsc_priv *rsc, u32 mux_sel);
 	void (*debug_dump)(struct sde_rsc_priv *rsc, u32 mux_sel);
 	int (*state_update)(struct sde_rsc_priv *rsc, enum sde_rsc_state state);
 	int (*state_update)(struct sde_rsc_priv *rsc, enum sde_rsc_state state);
@@ -149,6 +149,22 @@ struct sde_rsc_bw_config {
 	u64	new_ab_vote[SDE_POWER_HANDLE_DBUS_ID_MAX];
 	u64	new_ab_vote[SDE_POWER_HANDLE_DBUS_ID_MAX];
 	u64	new_ib_vote[SDE_POWER_HANDLE_DBUS_ID_MAX];
 	u64	new_ib_vote[SDE_POWER_HANDLE_DBUS_ID_MAX];
 };
 };
+
+/**
+ * enum sde_rsc_bw_delta bandwidth change
+ *
+ * @BW_HIGH_TO_LOW:	Bandwidth vote from high to low
+ * @BW_LOW_TO_HIGH:	Bandwidth vote from low  to high
+ * @BW_NO_CHANGE:	No change in Bandwidth vote
+ * @BW_DELTA_MAX:	Maximum value
+ */
+enum sde_rsc_bw_delta {
+	BW_HIGH_TO_LOW,
+	BW_LOW_TO_HIGH,
+	BW_NO_CHANGE,
+	BW_DELTA_MAX,
+};
+
 /**
 /**
  * struct sde_rsc_priv: sde resource state coordinator(rsc) private handle
  * struct sde_rsc_priv: sde resource state coordinator(rsc) private handle
  * @version:		rsc sequence version
  * @version:		rsc sequence version
@@ -196,6 +212,7 @@ struct sde_rsc_bw_config {
  * profiling_supp:	Indicates if HW has support for profiling counters
  * profiling_supp:	Indicates if HW has support for profiling counters
  * profiling_en:	Flag for rsc lpm profiling counters, true=enabled
  * profiling_en:	Flag for rsc lpm profiling counters, true=enabled
  * post_poms:		bool if a panel mode change occurred
  * post_poms:		bool if a panel mode change occurred
+ * bwi_update:		enum to indidate a bandwitdh vote change
  */
  */
 struct sde_rsc_priv {
 struct sde_rsc_priv {
 	u32 version;
 	u32 version;
@@ -241,6 +258,7 @@ struct sde_rsc_priv {
 	bool profiling_en;
 	bool profiling_en;
 
 
 	bool post_poms;
 	bool post_poms;
+	enum sde_rsc_bw_delta bwi_update;
 };
 };
 
 
 /**
 /**