Forráskód Böngészése

disp: msm: sde: migrated new sde icb bus scaling driver for lahaina

Migrate to icb framework API in drm and sde driver. And
also removes old msm_bus custom APIs from the driver.

Change-Id: Ifcf6d6f157594638075742fe328b29a9be065bca
Signed-off-by: Yuan Zhao <[email protected]>
Yuan Zhao 5 éve
szülő
commit
6cb205cbba
5 módosított fájl, 169 hozzáadás és 177 törlés
  1. 1 0
      msm/sde/sde_encoder.c
  2. 0 1
      msm/sde/sde_hw_catalog.h
  3. 101 153
      msm/sde_power_handle.c
  4. 35 18
      msm/sde_power_handle.h
  5. 32 5
      msm/sde_rsc.c

+ 1 - 0
msm/sde/sde_encoder.c

@@ -19,6 +19,7 @@
 #define pr_fmt(fmt)	"[drm:%s:%d] " fmt, __func__, __LINE__
 #include <linux/kthread.h>
 #include <linux/debugfs.h>
+#include <linux/input.h>
 #include <linux/seq_file.h>
 #include <linux/sde_rsc.h>
 

+ 0 - 1
msm/sde/sde_hw_catalog.h

@@ -10,7 +10,6 @@
 #include <linux/bug.h>
 #include <linux/bitmap.h>
 #include <linux/err.h>
-#include <linux/msm-bus.h>
 #include <linux/of_fdt.h>
 #include <drm/drmP.h>
 #include "sde_hw_mdss.h"

+ 101 - 153
msm/sde_power_handle.c

@@ -14,8 +14,6 @@
 #include <linux/mutex.h>
 #include <linux/of_platform.h>
 
-#include <linux/msm-bus.h>
-#include <linux/msm-bus-board.h>
 #include <linux/sde_io_util.h>
 #include <linux/sde_rsc.h>
 
@@ -23,6 +21,13 @@
 #include "sde_trace.h"
 #include "sde_dbg.h"
 
+static const struct sde_power_bus_scaling_data sde_reg_bus_table[] = {
+	{0, 0},
+	{0, 76800},
+	{0, 150000},
+	{0, 300000},
+};
+
 static const char *data_bus_name[SDE_POWER_HANDLE_DBUS_ID_MAX] = {
 	[SDE_POWER_HANDLE_DBUS_ID_MNOC] = "qcom,sde-data-bus",
 	[SDE_POWER_HANDLE_DBUS_ID_LLCC] = "qcom,sde-llcc-bus",
@@ -277,67 +282,49 @@ clk_err:
 	return rc;
 }
 
-#ifdef CONFIG_QCOM_BUS_SCALING
-
 #define MAX_AXI_PORT_COUNT 3
 
 static int _sde_power_data_bus_set_quota(
 	struct sde_power_data_bus_handle *pdbus,
 	u64 in_ab_quota, u64 in_ib_quota)
 {
-	int new_uc_idx;
-	u64 ab_quota[MAX_AXI_PORT_COUNT] = {0, 0};
-	u64 ib_quota[MAX_AXI_PORT_COUNT] = {0, 0};
-	int rc;
+	int rc = 0, i = 0, j = 0;
 
-	if (pdbus->data_bus_hdl < 1) {
-		pr_err("invalid bus handle %d\n", pdbus->data_bus_hdl);
+	if (!pdbus->data_paths_cnt) {
+		pr_err("invalid data bus handle\n");
 		return -EINVAL;
 	}
 
-	if (!in_ab_quota && !in_ib_quota)  {
-		new_uc_idx = 0;
-	} else {
-		int i;
-		struct msm_bus_vectors *vect = NULL;
-		struct msm_bus_scale_pdata *bw_table =
-			pdbus->data_bus_scale_table;
-		u32 total_data_paths_cnt = pdbus->data_paths_cnt;
-
-		if (!bw_table || !total_data_paths_cnt ||
-		    total_data_paths_cnt > MAX_AXI_PORT_COUNT) {
-			pr_err("invalid input\n");
-			return -EINVAL;
-		}
+	pr_debug("ab=%llu ib=%llu\n", in_ab_quota, in_ib_quota);
 
-		ab_quota[0] = div_u64(in_ab_quota, total_data_paths_cnt);
-		ib_quota[0] = div_u64(in_ib_quota, total_data_paths_cnt);
+	in_ab_quota = div_u64(in_ab_quota, pdbus->data_paths_cnt);
 
-		for (i = 1; i < total_data_paths_cnt; i++) {
-			ab_quota[i] = ab_quota[0];
-			ib_quota[i] = ib_quota[0];
+	SDE_ATRACE_BEGIN("msm_bus_scale_req");
+	for (i = 0; i < pdbus->data_paths_cnt; i++) {
+		if (pdbus->data_bus_hdl[i]) {
+			rc = icc_set_bw(pdbus->data_bus_hdl[i],
+				in_ab_quota, in_ib_quota);
+			if (rc)
+				goto err;
 		}
+	}
 
-		new_uc_idx = (pdbus->curr_bw_uc_idx %
-			(bw_table->num_usecases - 1)) + 1;
+	pdbus->curr_val.ab = in_ab_quota;
+	pdbus->curr_val.ib = in_ib_quota;
 
-		for (i = 0; i < total_data_paths_cnt; i++) {
-			vect = &bw_table->usecase[new_uc_idx].vectors[i];
-			vect->ab = ab_quota[i];
-			vect->ib = ib_quota[i];
+	SDE_ATRACE_END("msm_bus_scale_req");
 
-			pr_debug(
-				"%s uc_idx=%d idx=%d ab=%llu ib=%llu\n",
-				bw_table->name, new_uc_idx, i, vect->ab,
-				vect->ib);
-		}
-	}
-	pdbus->curr_bw_uc_idx = new_uc_idx;
+	return rc;
+err:
+	for (j = 0; j < i; j++)
+		if (pdbus->data_bus_hdl[j])
+			icc_set_bw(pdbus->data_bus_hdl[j],
+				   pdbus->curr_val.ab,
+				   pdbus->curr_val.ib);
 
-	SDE_ATRACE_BEGIN("msm_bus_scale_req");
-	rc = msm_bus_scale_client_update_request(pdbus->data_bus_hdl,
-			new_uc_idx);
 	SDE_ATRACE_END("msm_bus_scale_req");
+	pr_err("failed to set data bus vote ab=%llu ib=%llu rc=%d\n",
+	       rc, in_ab_quota, in_ib_quota);
 
 	return rc;
 }
@@ -356,7 +343,7 @@ int sde_power_data_bus_set_quota(struct sde_power_handle *phandle,
 
 	trace_sde_perf_update_bus(bus_id, ab_quota, ib_quota);
 
-	if (phandle->data_bus_handle[bus_id].data_bus_hdl)
+	if (phandle->data_bus_handle[bus_id].data_paths_cnt > 0)
 		rc = _sde_power_data_bus_set_quota(
 			&phandle->data_bus_handle[bus_id], ab_quota, ib_quota);
 
@@ -368,96 +355,96 @@ int sde_power_data_bus_set_quota(struct sde_power_handle *phandle,
 static void sde_power_data_bus_unregister(
 		struct sde_power_data_bus_handle *pdbus)
 {
-	if (pdbus->data_bus_hdl) {
-		msm_bus_scale_unregister_client(pdbus->data_bus_hdl);
-		pdbus->data_bus_hdl = 0;
+	int i = 0;
+
+	for (i = 0; i < pdbus->data_paths_cnt; i++) {
+		if (pdbus->data_bus_hdl[i]) {
+			icc_put(pdbus->data_bus_hdl[i]);
+			pdbus->data_bus_hdl[i] = NULL;
+		}
 	}
 }
 
 static int sde_power_data_bus_parse(struct platform_device *pdev,
 	struct sde_power_data_bus_handle *pdbus, const char *name)
 {
-	struct device_node *node;
-	int rc = 0;
-	int paths;
-
-	node = of_get_child_by_name(pdev->dev.of_node, name);
-	if (!node)
-		goto end;
-
-	rc = of_property_read_u32(node, "qcom,msm-bus,num-paths", &paths);
-	if (rc) {
-		pr_err("Error. qcom,msm-bus,num-paths not found\n");
-		return rc;
+	char bus_name[32];
+	int i = 0, ret = 0;
+
+	for (i = 0; i < DATA_BUS_PATH_MAX; i++) {
+		snprintf(bus_name, sizeof(bus_name), "%s%d", name, i);
+		ret = of_property_match_string(pdev->dev.of_node,
+			"interconnect-names", bus_name);
+		if (ret < 0) {
+			if (!pdbus->data_paths_cnt) {
+				pr_debug("sde: bus %s dt node missing\n", bus_name);
+				return 0;
+			} else
+				goto end;
+		} else
+			pdbus->data_bus_hdl[i] = of_icc_get(&pdev->dev, bus_name);
+
+		if (IS_ERR_OR_NULL(pdbus->data_bus_hdl[i])) {
+			pr_debug("icc get path failed for %s\n", bus_name);
+			break;
+		}
+		pdbus->data_paths_cnt++;
 	}
-	pdbus->data_paths_cnt = paths;
 
-	pdbus->data_bus_scale_table = msm_bus_pdata_from_node(pdev, node);
-	if (IS_ERR_OR_NULL(pdbus->data_bus_scale_table)) {
-		pr_err("reg bus handle parsing failed\n");
-		rc = PTR_ERR(pdbus->data_bus_scale_table);
-		if (!pdbus->data_bus_scale_table)
-			rc = -EINVAL;
-		goto end;
-	}
-	pdbus->data_bus_hdl = msm_bus_scale_register_client(
-			pdbus->data_bus_scale_table);
-	if (!pdbus->data_bus_hdl) {
-		pr_err("data_bus_client register failed\n");
-		rc = -EINVAL;
-		goto end;
+	if (!pdbus->data_paths_cnt) {
+		pr_err("get none data bus path for %s\n", name);
+		return -EINVAL;
 	}
-	pr_debug("register %s data_bus_hdl=%x\n", name, pdbus->data_bus_hdl);
 
 end:
-	return rc;
+	if (of_find_property(pdev->dev.of_node,
+			     "qcom,msm-bus,active-only", NULL)) {
+		pdbus->bus_active_only = true;
+		for (i = 0; i < pdbus->data_paths_cnt; i++) {
+			icc_set_tag(pdbus->data_bus_hdl[i],
+				    QCOM_ICC_TAG_ACTIVE_ONLY);
+		}
+	}
+
+	pr_debug("register %s data_bus success, path number=%d\n",
+		name, pdbus->data_paths_cnt);
+
+	return 0;
 }
 
 static int sde_power_reg_bus_parse(struct platform_device *pdev,
 	struct sde_power_handle *phandle)
 {
-	struct device_node *node;
-	struct msm_bus_scale_pdata *bus_scale_table;
 	int rc = 0;
 
-	node = of_get_child_by_name(pdev->dev.of_node, "qcom,sde-reg-bus");
-	if (node) {
-		bus_scale_table = msm_bus_pdata_from_node(pdev, node);
-		if (IS_ERR_OR_NULL(bus_scale_table)) {
-			pr_err("reg bus handle parsing failed\n");
-			rc = PTR_ERR(bus_scale_table);
-			if (!bus_scale_table)
-				rc = -EINVAL;
-			goto end;
-		}
-		phandle->reg_bus_hdl = msm_bus_scale_register_client(
-			      bus_scale_table);
-		if (!phandle->reg_bus_hdl) {
-			pr_err("reg_bus_client register failed\n");
-			rc = -EINVAL;
-			goto end;
-		}
-		pr_debug("register reg_bus_hdl=%x\n", phandle->reg_bus_hdl);
+	phandle->reg_bus_hdl = of_icc_get(&pdev->dev, "qcom,sde-reg-bus");
+	if (IS_ERR_OR_NULL(phandle->reg_bus_hdl)) {
+		pr_err("reg bus handle parsing failed\n");
+		phandle->reg_bus_hdl = NULL;
+		rc = -EINVAL;
+	} else {
+		pr_debug("reg_bus_hdl parsing success\n");
 	}
 
-end:
 	return rc;
 }
 
-static void sde_power_reg_bus_unregister(u32 reg_bus_hdl)
+static void sde_power_reg_bus_unregister(struct icc_path *reg_bus_hdl)
 {
 	if (reg_bus_hdl)
-		msm_bus_scale_unregister_client(reg_bus_hdl);
+		icc_put(reg_bus_hdl);
 }
 
-static int sde_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
+static int sde_power_reg_bus_update(struct icc_path *reg_bus_hdl,
+	u32 usecase_ndx)
 {
 	int rc = 0;
 
 	if (reg_bus_hdl) {
 		SDE_ATRACE_BEGIN("msm_bus_scale_req");
-		rc = msm_bus_scale_client_update_request(reg_bus_hdl,
-								usecase_ndx);
+		rc = icc_set_bw(reg_bus_hdl,
+			sde_reg_bus_table[usecase_ndx].ab,
+			sde_reg_bus_table[usecase_ndx].ib);
 		SDE_ATRACE_END("msm_bus_scale_req");
 	}
 
@@ -466,52 +453,6 @@ static int sde_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
 
 	return rc;
 }
-#else
-static int _sde_power_data_bus_set_quota(
-	struct sde_power_data_bus_handle *pdbus,
-	u64 in_ab_quota, u64 in_ib_quota)
-{
-	return 0;
-}
-
-static int sde_power_data_bus_parse(struct platform_device *pdev,
-		struct sde_power_data_bus_handle *pdbus, const char *name)
-{
-	return 0;
-}
-
-static void sde_power_data_bus_unregister(
-		struct sde_power_data_bus_handle *pdbus)
-{
-}
-
-int sde_power_data_bus_set_quota(struct sde_power_handle *phandle,
-	u32 bus_id, u64 ab_quota, u64 ib_quota)
-{
-	return 0;
-}
-
-static int sde_power_reg_bus_parse(struct platform_device *pdev,
-	struct sde_power_handle *phandle)
-{
-	return 0;
-}
-
-static void sde_power_reg_bus_unregister(u32 reg_bus_hdl)
-{
-}
-
-static int sde_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
-{
-	return 0;
-}
-
-int sde_power_data_bus_state_update(struct sde_power_handle *phandle,
-							bool enable)
-{
-	return 0;
-}
-#endif
 
 int sde_power_resource_init(struct platform_device *pdev,
 	struct sde_power_handle *phandle)
@@ -675,6 +616,13 @@ int sde_power_scale_reg_bus(struct sde_power_handle *phandle,
 						usecase_ndx);
 	if (rc)
 		pr_err("failed to set reg bus vote rc=%d\n", rc);
+	else {
+		phandle->reg_bus_curr_val.ab =
+			sde_reg_bus_table[usecase_ndx].ab;
+		phandle->reg_bus_curr_val.ib =
+			sde_reg_bus_table[usecase_ndx].ib;
+		phandle->current_usecase_ndx = usecase_ndx;
+	}
 
 	if (!skip_lock)
 		mutex_unlock(&phandle->phandle_lock);
@@ -723,7 +671,7 @@ int sde_power_resource_enable(struct sde_power_handle *phandle, bool enable)
 				SDE_POWER_EVENT_PRE_ENABLE);
 
 		for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX &&
-		     phandle->data_bus_handle[i].data_bus_hdl; i++) {
+			phandle->data_bus_handle[i].data_paths_cnt > 0; i++) {
 			rc = _sde_power_data_bus_set_quota(
 				&phandle->data_bus_handle[i],
 				SDE_POWER_HANDLE_ENABLE_BUS_AB_QUOTA,
@@ -777,7 +725,7 @@ int sde_power_resource_enable(struct sde_power_handle *phandle, bool enable)
 		msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, enable);
 
 		for (i = SDE_POWER_HANDLE_DBUS_ID_MAX - 1; i >= 0; i--)
-			if (phandle->data_bus_handle[i].data_bus_hdl)
+			if (phandle->data_bus_handle[i].data_paths_cnt > 0)
 				_sde_power_data_bus_set_quota(
 					&phandle->data_bus_handle[i],
 					SDE_POWER_HANDLE_DISABLE_BUS_AB_QUOTA,
@@ -799,7 +747,7 @@ rsc_err:
 reg_bus_hdl_err:
 	msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, 0);
 vreg_err:
-	for (i-- ; i >= 0 && phandle->data_bus_handle[i].data_bus_hdl; i--)
+	for (i-- ; i >= 0 && phandle->data_bus_handle[i].data_paths_cnt > 0; i--)
 		_sde_power_data_bus_set_quota(
 			&phandle->data_bus_handle[i],
 			SDE_POWER_HANDLE_DISABLE_BUS_AB_QUOTA,

+ 35 - 18
msm/sde_power_handle.h

@@ -18,6 +18,7 @@
 #define SDE_POWER_HANDLE_CONT_SPLASH_BUS_AB_QUOTA	3000000000ULL
 
 #include <linux/sde_io_util.h>
+#include <linux/interconnect.h>
 #include <soc/qcom/cx_ipeak.h>
 
 /* event will be triggered before power handler disable */
@@ -31,6 +32,23 @@
 
 /* event will be triggered after power handler enable */
 #define SDE_POWER_EVENT_POST_ENABLE	0x8
+#define DATA_BUS_PATH_MAX	0x2
+
+/*
+ * The AMC bucket denotes constraints that are applied to hardware when
+ * icc_set_bw() completes, whereas the WAKE and SLEEP constraints are applied
+ * when the execution environment transitions between active and low power mode.
+ */
+#define QCOM_ICC_BUCKET_AMC            0
+#define QCOM_ICC_BUCKET_WAKE           1
+#define QCOM_ICC_BUCKET_SLEEP          2
+#define QCOM_ICC_NUM_BUCKETS           3
+#define QCOM_ICC_TAG_AMC               BIT(QCOM_ICC_BUCKET_AMC)
+#define QCOM_ICC_TAG_WAKE              BIT(QCOM_ICC_BUCKET_WAKE)
+#define QCOM_ICC_TAG_SLEEP             BIT(QCOM_ICC_BUCKET_SLEEP)
+#define QCOM_ICC_TAG_ACTIVE_ONLY       (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE)
+#define QCOM_ICC_TAG_ALWAYS            (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE |\
+                                        QCOM_ICC_TAG_SLEEP)
 
 /**
  * mdss_bus_vote_type: register bus vote type
@@ -73,30 +91,27 @@ enum SDE_POWER_HANDLE_DBUS_ID {
 	SDE_POWER_HANDLE_DBUS_ID_MAX,
 };
 
+/**
+ * struct sde_power_bus_scaling_data: struct for bus setting
+ * @ab: average bandwidth in kilobytes per second
+ * @ib: peak bandwidth in kilobytes per second
+ */
+struct sde_power_bus_scaling_data {
+	uint64_t ab; /* Arbitrated bandwidth */
+	uint64_t ib; /* Instantaneous bandwidth */
+};
+
 /**
  * struct sde_power_data_handle: power handle struct for data bus
- * @data_bus_scale_table: pointer to bus scaling table
  * @data_bus_hdl: current data bus handle
+ * @curr_val : save the current bus value
  * @data_paths_cnt: number of rt data path ports
- * @curr_bw_uc_idx: current use case index of data bus
- * @ao_bw_uc_idx: active only use case index of data bus
- * @ab_rt: realtime ab quota
- * @ib_rt: realtime ib quota
- * @ab_nrt: non-realtime ab quota
- * @ib_nrt: non-realtime ib quota
- * @enable: true if bus is enabled
  */
 struct sde_power_data_bus_handle {
-	struct msm_bus_scale_pdata *data_bus_scale_table;
-	u32 data_bus_hdl;
+	struct icc_path *data_bus_hdl[DATA_BUS_PATH_MAX];
+	struct sde_power_bus_scaling_data curr_val;
 	u32 data_paths_cnt;
-	u32 curr_bw_uc_idx;
-	u32 ao_bw_uc_idx;
-	u64 ab_rt;
-	u64 ib_rt;
-	u64 ab_nrt;
-	u64 ib_nrt;
-	bool enable;
+	bool bus_active_only;
 };
 
 /*
@@ -124,6 +139,7 @@ struct sde_power_event {
  * @dev: pointer to device structure
  * @usecase_ndx: current usecase index
  * @reg_bus_hdl: current register bus handle
+ * @reg_bus_curr_val: save currecnt reg bus value
  * @data_bus_handle: context structure for data bus control
  * @event_list: current power handle event list
  * @rsc_client: sde rsc client pointer
@@ -135,7 +151,8 @@ struct sde_power_handle {
 	struct mutex phandle_lock;
 	struct device *dev;
 	u32 current_usecase_ndx;
-	u32 reg_bus_hdl;
+	struct icc_path *reg_bus_hdl;
+	struct sde_power_bus_scaling_data reg_bus_curr_val;
 	struct sde_power_data_bus_handle data_bus_handle
 		[SDE_POWER_HANDLE_DBUS_ID_MAX];
 	struct list_head event_list;

+ 32 - 5
msm/sde_rsc.c

@@ -15,7 +15,6 @@
 #include <linux/mutex.h>
 #include <linux/of_platform.h>
 #include <linux/module.h>
-#include <linux/msm-bus.h>
 
 #include <soc/qcom/rpmh.h>
 #include <drm/drmP.h>
@@ -64,6 +63,21 @@
 static struct sde_rsc_priv *rsc_prv_list[MAX_RSC_COUNT];
 static struct device *rpmh_dev[MAX_RSC_COUNT];
 
+static void sde_rsc_set_data_bus_mode(struct sde_power_handle *phandle, u32 tag)
+{
+	int i = 0, j = 0;
+
+	for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) {
+		if (!phandle->data_bus_handle[i].bus_active_only)
+			continue;
+
+		for (j = 0; j < phandle->data_bus_handle[i].data_paths_cnt; j++)
+			icc_set_tag(phandle->data_bus_handle[i].data_bus_hdl[j],
+				    tag);
+
+	}
+}
+
 /**
  * sde_rsc_client_create() - create the client for sde rsc.
  * Different displays like DSI, HDMI, DP, WB, etc should call this
@@ -523,8 +537,11 @@ static int sde_rsc_switch_to_cmd(struct sde_rsc_priv *rsc,
 
 	if (rsc->hw_ops.state_update) {
 		rc = rsc->hw_ops.state_update(rsc, SDE_RSC_CMD_STATE);
-		if (!rc)
+		if (!rc) {
 			rpmh_mode_solver_set(rsc->rpmh_dev, true);
+			sde_rsc_set_data_bus_mode(&rsc->phandle,
+						  QCOM_ICC_TAG_WAKE);
+		}
 	}
 
 vsync_wait:
@@ -574,8 +591,11 @@ static int sde_rsc_switch_to_clk(struct sde_rsc_priv *rsc,
 
 	if (rsc->hw_ops.state_update) {
 		rc = rsc->hw_ops.state_update(rsc, SDE_RSC_CLK_STATE);
-		if (!rc)
+		if (!rc) {
 			rpmh_mode_solver_set(rsc->rpmh_dev, false);
+			sde_rsc_set_data_bus_mode(&rsc->phandle,
+						  QCOM_ICC_TAG_AMC);
+		}
 	}
 
 	/* indicate wait for vsync for cmd/vid to clk state switch */
@@ -661,9 +681,13 @@ static int sde_rsc_switch_to_vid(struct sde_rsc_priv *rsc,
 
 	if (rsc->hw_ops.state_update) {
 		rc = rsc->hw_ops.state_update(rsc, SDE_RSC_VID_STATE);
-		if (!rc)
+		if (!rc) {
 			rpmh_mode_solver_set(rsc->rpmh_dev,
 				rsc->version == SDE_RSC_REV_3 ? true : false);
+			sde_rsc_set_data_bus_mode(&rsc->phandle,
+				rsc->version == SDE_RSC_REV_3 ?
+				QCOM_ICC_TAG_WAKE : QCOM_ICC_TAG_AMC);
+		}
 	}
 
 vsync_wait:
@@ -737,8 +761,11 @@ static int sde_rsc_switch_to_idle(struct sde_rsc_priv *rsc,
 			rc = CLK_MODE_SWITCH_SUCCESS;
 	} else if (rsc->hw_ops.state_update) {
 		rc = rsc->hw_ops.state_update(rsc, SDE_RSC_IDLE_STATE);
-		if (!rc)
+		if (!rc) {
 			rpmh_mode_solver_set(rsc->rpmh_dev, true);
+			sde_rsc_set_data_bus_mode(&rsc->phandle,
+						  QCOM_ICC_TAG_WAKE);
+		}
 	}
 
 	return rc;