diff mbox

[DPU,v2,11/12] drm/msm/dpu: move dpu_power_handle to dpu folder

Message ID 1526050178-31893-12-git-send-email-ryadav@codeaurora.org (mailing list archive)
State Not Applicable, archived
Delegated to: Andy Gross
Headers show

Commit Message

Rajesh Yadav May 11, 2018, 2:49 p.m. UTC
Now, since dpu_power_handle manages only bus scaling
and power enable/disable notifications which are restricted
to dpu driver, move dpu_power_handle to dpu folder.

Changes in v2:
	- resolved conflict in dpu_unbind
	- dropped (Reviewed-by: Sean Paul) due to above change

Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
---
 drivers/gpu/drm/msm/Makefile                     |   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c     |   1 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c    |   5 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c         |   7 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h         |   2 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c      |   1 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c          |  39 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h          |   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c | 693 +++++++++++++++++++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h | 288 ++++++++++
 drivers/gpu/drm/msm/dpu_power_handle.c           | 693 -----------------------
 drivers/gpu/drm/msm/dpu_power_handle.h           | 288 ----------
 drivers/gpu/drm/msm/msm_drv.c                    |   9 -
 drivers/gpu/drm/msm/msm_drv.h                    |   4 -
 14 files changed, 1013 insertions(+), 1020 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h
 delete mode 100644 drivers/gpu/drm/msm/dpu_power_handle.c
 delete mode 100644 drivers/gpu/drm/msm/dpu_power_handle.h

Comments

Sean Paul May 11, 2018, 3:48 p.m. UTC | #1
On Fri, May 11, 2018 at 08:19:37PM +0530, Rajesh Yadav wrote:
> Now, since dpu_power_handle manages only bus scaling
> and power enable/disable notifications which are restricted
> to dpu driver, move dpu_power_handle to dpu folder.
> 
> Changes in v2:
> 	- resolved conflict in dpu_unbind
> 	- dropped (Reviewed-by: Sean Paul) due to above change
> 

Reviewed-by: Sean Paul <seanpaul@chromium.org>

> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
> ---
>  drivers/gpu/drm/msm/Makefile                     |   2 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c     |   1 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c    |   5 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c         |   7 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h         |   2 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c      |   1 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c          |  39 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h          |   1 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c | 693 +++++++++++++++++++++++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h | 288 ++++++++++
>  drivers/gpu/drm/msm/dpu_power_handle.c           | 693 -----------------------
>  drivers/gpu/drm/msm/dpu_power_handle.h           | 288 ----------
>  drivers/gpu/drm/msm/msm_drv.c                    |   9 -
>  drivers/gpu/drm/msm/msm_drv.h                    |   4 -
>  14 files changed, 1013 insertions(+), 1020 deletions(-)
>  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
>  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h
>  delete mode 100644 drivers/gpu/drm/msm/dpu_power_handle.c
>  delete mode 100644 drivers/gpu/drm/msm/dpu_power_handle.h
> 
> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
> index d9826c1..f578d5a 100644
> --- a/drivers/gpu/drm/msm/Makefile
> +++ b/drivers/gpu/drm/msm/Makefile
> @@ -82,10 +82,10 @@ msm-y := \
>  	disp/dpu1/dpu_rm.o \
>  	disp/dpu1/dpu_vbif.o \
>  	disp/dpu1/dpu_mdss.o \
> +	disp/dpu1/dpu_power_handle.o \
>  	dpu_dbg.o \
>  	dpu_io_util.o \
>  	dpu_dbg_evtlog.o \
> -	dpu_power_handle.o \
>  	msm_prop.o \
>  	msm_atomic.o \
>  	msm_debugfs.o \
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
> index 5c5cc56..33ab2ac 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
> @@ -18,7 +18,6 @@
>  #include <linux/kthread.h>
>  
>  #include "dpu_core_irq.h"
> -#include "dpu_power_handle.h"
>  
>  /**
>   * dpu_core_irq_callback_handler - dispatch core interrupts
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
> index 2cf3fca..d3a1ed9 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
> @@ -257,7 +257,6 @@ static void _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
>  					= dpu_crtc_get_client_type(crtc);
>  	struct drm_crtc *tmp_crtc;
>  	struct dpu_crtc_state *dpu_cstate;
> -	struct msm_drm_private *priv = kms->dev->dev_private;
>  
>  	drm_for_each_crtc(tmp_crtc, crtc->dev) {
>  		if (_dpu_core_perf_crtc_is_power_on(tmp_crtc) &&
> @@ -287,7 +286,7 @@ static void _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
>  
>  	switch (curr_client_type) {
>  	case NRT_CLIENT:
> -		dpu_power_data_bus_set_quota(&priv->phandle, kms->core_client,
> +		dpu_power_data_bus_set_quota(&kms->phandle, kms->core_client,
>  				DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT,
>  				bus_id, bus_ab_quota, bus_ib_quota);
>  		DPU_DEBUG("client:%s bus_id=%d ab=%llu ib=%llu\n", "nrt",
> @@ -295,7 +294,7 @@ static void _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
>  		break;
>  
>  	case RT_CLIENT:
> -		dpu_power_data_bus_set_quota(&priv->phandle, kms->core_client,
> +		dpu_power_data_bus_set_quota(&kms->phandle, kms->core_client,
>  				DPU_POWER_HANDLE_DATA_BUS_CLIENT_RT,
>  				bus_id, bus_ab_quota, bus_ib_quota);
>  		DPU_DEBUG("client:%s bus_id=%d ab=%llu ib=%llu\n", "rt",
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index e2d2e32..99c5e75 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -598,6 +598,7 @@ static void dpu_crtc_destroy(struct drm_crtc *crtc)
>  	_dpu_crtc_destroy_dest_scaler(dpu_crtc);
>  
>  	_dpu_crtc_deinit_events(dpu_crtc);
> +	dpu_crtc->phandle = NULL;
>  
>  	drm_crtc_cleanup(crtc);
>  	mutex_destroy(&dpu_crtc->crtc_lock);
> @@ -2572,7 +2573,7 @@ static void dpu_crtc_disable(struct drm_crtc *crtc)
>  	}
>  
>  	if (dpu_crtc->power_event)
> -		dpu_power_handle_unregister_event(&priv->phandle,
> +		dpu_power_handle_unregister_event(dpu_crtc->phandle,
>  				dpu_crtc->power_event);
>  
>  
> @@ -2643,7 +2644,7 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
>  	mutex_unlock(&dpu_crtc->crtc_lock);
>  
>  	dpu_crtc->power_event = dpu_power_handle_register_event(
> -		&priv->phandle,
> +		dpu_crtc->phandle,
>  		DPU_POWER_EVENT_POST_ENABLE | DPU_POWER_EVENT_POST_DISABLE |
>  		DPU_POWER_EVENT_PRE_DISABLE,
>  		dpu_crtc_handle_power_event, crtc, dpu_crtc->name);
> @@ -3938,6 +3939,8 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane)
>  	dpu_cp_crtc_init(crtc);
>  	dpu_cp_crtc_install_properties(crtc);
>  
> +	dpu_crtc->phandle = &kms->phandle;
> +
>  	DPU_DEBUG("%s: successfully initialized crtc\n", dpu_crtc->name);
>  	return crtc;
>  }
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> index 9304058..671d909 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> @@ -184,6 +184,7 @@ struct dpu_crtc_event {
>   * @misr_enable   : boolean entry indicates misr enable/disable status.
>   * @misr_frame_count  : misr frame count provided by client
>   * @misr_data     : store misr data before turning off the clocks.
> + * @phandle: Pointer to power handler
>   * @power_event   : registered power event handle
>   * @cur_perf      : current performance committed to clock/bandwidth driver
>   * @rp_lock       : serialization lock for resource pool
> @@ -240,6 +241,7 @@ struct dpu_crtc {
>  	u32 misr_frame_count;
>  	u32 misr_data[CRTC_DUAL_MIXERS];
>  
> +	struct dpu_power_handle *phandle;
>  	struct dpu_power_event *power_event;
>  
>  	struct dpu_core_perf_params cur_perf;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index 298a6ef..11ae6cc 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -31,7 +31,6 @@
>  #include "dpu_hw_ctl.h"
>  #include "dpu_formats.h"
>  #include "dpu_encoder_phys.h"
> -#include "dpu_power_handle.h"
>  #include "dpu_crtc.h"
>  #include "dpu_trace.h"
>  #include "dpu_core_irq.h"
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index 9c3b220..0598cfb 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> @@ -1017,24 +1017,19 @@ static long dpu_kms_round_pixclk(struct msm_kms *kms, unsigned long rate,
>  static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
>  {
>  	struct drm_device *dev;
> -	struct msm_drm_private *priv;
>  	int i;
>  
>  	dev = dpu_kms->dev;
>  	if (!dev)
>  		return;
>  
> -	priv = dev->dev_private;
> -	if (!priv)
> -		return;
> -
>  	if (dpu_kms->hw_intr)
>  		dpu_hw_intr_destroy(dpu_kms->hw_intr);
>  	dpu_kms->hw_intr = NULL;
>  
>  	if (dpu_kms->power_event)
>  		dpu_power_handle_unregister_event(
> -				&priv->phandle, dpu_kms->power_event);
> +				&dpu_kms->phandle, dpu_kms->power_event);
>  
>  	/* safe to call these more than once during shutdown */
>  	_dpu_debugfs_destroy(dpu_kms);
> @@ -1067,7 +1062,8 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
>  	dpu_kms->catalog = NULL;
>  
>  	if (dpu_kms->core_client)
> -		dpu_power_client_destroy(&priv->phandle, dpu_kms->core_client);
> +		dpu_power_client_destroy(&dpu_kms->phandle,
> +			dpu_kms->core_client);
>  	dpu_kms->core_client = NULL;
>  
>  	if (dpu_kms->vbif[VBIF_NRT])
> @@ -1624,7 +1620,8 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
>  	}
>  #endif
>  
> -	dpu_kms->core_client = dpu_power_client_create(&priv->phandle, "core");
> +	dpu_kms->core_client = dpu_power_client_create(&dpu_kms->phandle,
> +					"core");
>  	if (IS_ERR_OR_NULL(dpu_kms->core_client)) {
>  		rc = PTR_ERR(dpu_kms->core_client);
>  		if (!dpu_kms->core_client)
> @@ -1721,7 +1718,8 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
>  #endif
>  
>  	rc = dpu_core_perf_init(&dpu_kms->perf, dev, dpu_kms->catalog,
> -			&priv->phandle, _dpu_kms_get_clk(dpu_kms, "core_clk"));
> +			&dpu_kms->phandle,
> +			_dpu_kms_get_clk(dpu_kms, "core_clk"));
>  	if (rc) {
>  		DPU_ERROR("failed to init perf %d\n", rc);
>  		goto perf_err;
> @@ -1765,7 +1763,8 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
>  	 * Handle (re)initializations during power enable
>  	 */
>  	dpu_kms_handle_power_event(DPU_POWER_EVENT_POST_ENABLE, dpu_kms);
> -	dpu_kms->power_event = dpu_power_handle_register_event(&priv->phandle,
> +	dpu_kms->power_event = dpu_power_handle_register_event(
> +			&dpu_kms->phandle,
>  			DPU_POWER_EVENT_POST_ENABLE,
>  			dpu_kms_handle_power_event, dpu_kms, "kms");
>  
> @@ -1841,6 +1840,12 @@ static int dpu_bind(struct device *dev, struct device *master, void *data)
>  		goto clk_rate_error;
>  	}
>  
> +	ret = dpu_power_resource_init(pdev, &dpu_kms->phandle);
> +	if (ret) {
> +		pr_err("dpu power resource init failed\n");
> +		goto power_init_fail;
> +	}
> +
>  	platform_set_drvdata(pdev, dpu_kms);
>  
>  	msm_kms_init(&dpu_kms->base, &kms_funcs);
> @@ -1853,6 +1858,7 @@ static int dpu_bind(struct device *dev, struct device *master, void *data)
>  	priv->kms = &dpu_kms->base;
>  	return ret;
>  
> +power_init_fail:
>  clk_rate_error:
>  	msm_dss_put_clk(mp->clk_config, mp->num_clk);
>  clk_get_error:
> @@ -1867,6 +1873,7 @@ static void dpu_unbind(struct device *dev, struct device *master, void *data)
>  	struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
>  	struct dss_module_power *mp = &dpu_kms->mp;
>  
> +	dpu_power_resource_deinit(pdev, &dpu_kms->phandle);
>  	msm_dss_put_clk(mp->clk_config, mp->num_clk);
>  	devm_kfree(&pdev->dev, mp->clk_config);
>  	mp->num_clk = 0;
> @@ -1897,7 +1904,6 @@ static int dpu_runtime_suspend(struct device *dev)
>  	struct platform_device *pdev = to_platform_device(dev);
>  	struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
>  	struct drm_device *ddev;
> -	struct msm_drm_private *priv;
>  	struct dss_module_power *mp = &dpu_kms->mp;
>  
>  	ddev = dpu_kms->dev;
> @@ -1905,10 +1911,9 @@ static int dpu_runtime_suspend(struct device *dev)
>  		DPU_ERROR("invalid drm_device\n");
>  		goto exit;
>  	}
> -	priv = ddev->dev_private;
>  
> -	rc = dpu_power_resource_enable(&priv->phandle,
> -		dpu_kms->core_client, false);
> +	rc = dpu_power_resource_enable(&dpu_kms->phandle,
> +			dpu_kms->core_client, false);
>  	if (rc)
>  		DPU_ERROR("resource disable failed: %d\n", rc);
>  
> @@ -1926,7 +1931,6 @@ static int dpu_runtime_resume(struct device *dev)
>  	struct platform_device *pdev = to_platform_device(dev);
>  	struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
>  	struct drm_device *ddev;
> -	struct msm_drm_private *priv;
>  	struct dss_module_power *mp = &dpu_kms->mp;
>  
>  	ddev = dpu_kms->dev;
> @@ -1934,7 +1938,6 @@ static int dpu_runtime_resume(struct device *dev)
>  		DPU_ERROR("invalid drm_device\n");
>  		goto exit;
>  	}
> -	priv = ddev->dev_private;
>  
>  	rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true);
>  	if (rc) {
> @@ -1942,8 +1945,8 @@ static int dpu_runtime_resume(struct device *dev)
>  		goto exit;
>  	}
>  
> -	rc = dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client,
> -		true);
> +	rc = dpu_power_resource_enable(&dpu_kms->phandle,
> +			dpu_kms->core_client, true);
>  	if (rc)
>  		DPU_ERROR("resource enable failed: %d\n", rc);
>  
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> index a8255fe..c48ed4e 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> @@ -164,6 +164,7 @@ struct dpu_kms {
>  	struct dpu_mdss_cfg *catalog;
>  
>  	struct msm_gem_address_space *aspace[MSM_SMMU_DOMAIN_MAX];
> +	struct dpu_power_handle phandle;
>  	struct dpu_power_client *core_client;
>  #ifdef CONFIG_ION
>  	struct ion_client *iclient;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
> new file mode 100644
> index 0000000..77be106
> --- /dev/null
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
> @@ -0,0 +1,693 @@
> +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#define pr_fmt(fmt)	"[drm:%s:%d]: " fmt, __func__, __LINE__
> +
> +#include <linux/kernel.h>
> +#include <linux/of.h>
> +#include <linux/string.h>
> +#include <linux/of_address.h>
> +#include <linux/slab.h>
> +#include <linux/mutex.h>
> +#include <linux/of_platform.h>
> +#ifdef CONFIG_QCOM_BUS_SCALING
> +#include <linux/msm-bus.h>
> +#include <linux/msm-bus-board.h>
> +#endif
> +#include <linux/dpu_io_util.h>
> +
> +#include "dpu_power_handle.h"
> +#include "dpu_trace.h"
> +
> +static const char *data_bus_name[DPU_POWER_HANDLE_DBUS_ID_MAX] = {
> +	[DPU_POWER_HANDLE_DBUS_ID_MNOC] = "qcom,dpu-data-bus",
> +	[DPU_POWER_HANDLE_DBUS_ID_LLCC] = "qcom,dpu-llcc-bus",
> +	[DPU_POWER_HANDLE_DBUS_ID_EBI] = "qcom,dpu-ebi-bus",
> +};
> +
> +const char *dpu_power_handle_get_dbus_name(u32 bus_id)
> +{
> +	if (bus_id < DPU_POWER_HANDLE_DBUS_ID_MAX)
> +		return data_bus_name[bus_id];
> +
> +	return NULL;
> +}
> +
> +static void dpu_power_event_trigger_locked(struct dpu_power_handle *phandle,
> +		u32 event_type)
> +{
> +	struct dpu_power_event *event;
> +
> +	list_for_each_entry(event, &phandle->event_list, list) {
> +		if (event->event_type & event_type)
> +			event->cb_fnc(event_type, event->usr);
> +	}
> +}
> +
> +struct dpu_power_client *dpu_power_client_create(
> +	struct dpu_power_handle *phandle, char *client_name)
> +{
> +	struct dpu_power_client *client;
> +	static u32 id;
> +
> +	if (!client_name || !phandle) {
> +		pr_err("client name is null or invalid power data\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	client = kzalloc(sizeof(struct dpu_power_client), GFP_KERNEL);
> +	if (!client)
> +		return ERR_PTR(-ENOMEM);
> +
> +	mutex_lock(&phandle->phandle_lock);
> +	strlcpy(client->name, client_name, MAX_CLIENT_NAME_LEN);
> +	client->usecase_ndx = VOTE_INDEX_DISABLE;
> +	client->id = id;
> +	client->active = true;
> +	pr_debug("client %s created:%pK id :%d\n", client_name,
> +		client, id);
> +	id++;
> +	list_add(&client->list, &phandle->power_client_clist);
> +	mutex_unlock(&phandle->phandle_lock);
> +
> +	return client;
> +}
> +
> +void dpu_power_client_destroy(struct dpu_power_handle *phandle,
> +	struct dpu_power_client *client)
> +{
> +	if (!client  || !phandle) {
> +		pr_err("reg bus vote: invalid client handle\n");
> +	} else if (!client->active) {
> +		pr_err("dpu power deinit already done\n");
> +		kfree(client);
> +	} else {
> +		pr_debug("bus vote client %s destroyed:%pK id:%u\n",
> +			client->name, client, client->id);
> +		mutex_lock(&phandle->phandle_lock);
> +		list_del_init(&client->list);
> +		mutex_unlock(&phandle->phandle_lock);
> +		kfree(client);
> +	}
> +}
> +
> +#ifdef CONFIG_QCOM_BUS_SCALING
> +
> +#define MAX_AXI_PORT_COUNT 3
> +
> +static int _dpu_power_data_bus_set_quota(
> +		struct dpu_power_data_bus_handle *pdbus,
> +		u64 ab_quota_rt, u64 ab_quota_nrt,
> +		u64 ib_quota_rt, u64 ib_quota_nrt)
> +{
> +	int new_uc_idx;
> +	u64 ab_quota[MAX_AXI_PORT_COUNT] = {0, 0};
> +	u64 ib_quota[MAX_AXI_PORT_COUNT] = {0, 0};
> +	int rc;
> +
> +	if (pdbus->data_bus_hdl < 1) {
> +		pr_err("invalid bus handle %d\n", pdbus->data_bus_hdl);
> +		return -EINVAL;
> +	}
> +
> +	pdbus->ab_rt = ab_quota_rt;
> +	pdbus->ib_rt = ib_quota_rt;
> +	pdbus->ab_nrt = ab_quota_nrt;
> +	pdbus->ib_nrt = ib_quota_nrt;
> +
> +	if (pdbus->enable) {
> +		ab_quota_rt = max_t(u64, ab_quota_rt,
> +				DPU_POWER_HANDLE_ENABLE_BUS_AB_QUOTA);
> +		ib_quota_rt = max_t(u64, ib_quota_rt,
> +				DPU_POWER_HANDLE_ENABLE_BUS_IB_QUOTA);
> +		ab_quota_nrt = max_t(u64, ab_quota_nrt,
> +				DPU_POWER_HANDLE_ENABLE_BUS_AB_QUOTA);
> +		ib_quota_nrt = max_t(u64, ib_quota_nrt,
> +				DPU_POWER_HANDLE_ENABLE_BUS_IB_QUOTA);
> +	} else {
> +		ab_quota_rt = min_t(u64, ab_quota_rt,
> +				DPU_POWER_HANDLE_DISABLE_BUS_AB_QUOTA);
> +		ib_quota_rt = min_t(u64, ib_quota_rt,
> +				DPU_POWER_HANDLE_DISABLE_BUS_IB_QUOTA);
> +		ab_quota_nrt = min_t(u64, ab_quota_nrt,
> +				DPU_POWER_HANDLE_DISABLE_BUS_AB_QUOTA);
> +		ib_quota_nrt = min_t(u64, ib_quota_nrt,
> +				DPU_POWER_HANDLE_DISABLE_BUS_IB_QUOTA);
> +	}
> +
> +	if (!ab_quota_rt && !ab_quota_nrt && !ib_quota_rt && !ib_quota_nrt)  {
> +		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 nrt_axi_port_cnt = pdbus->nrt_axi_port_cnt;
> +		u32 total_axi_port_cnt = pdbus->axi_port_cnt;
> +		u32 rt_axi_port_cnt = total_axi_port_cnt - nrt_axi_port_cnt;
> +
> +		if (!bw_table || !total_axi_port_cnt ||
> +		    total_axi_port_cnt > MAX_AXI_PORT_COUNT) {
> +			pr_err("invalid input\n");
> +			return -EINVAL;
> +		}
> +
> +		if (pdbus->bus_channels) {
> +			ib_quota_rt = div_u64(ib_quota_rt,
> +						pdbus->bus_channels);
> +			ib_quota_nrt = div_u64(ib_quota_nrt,
> +						pdbus->bus_channels);
> +		}
> +
> +		if (nrt_axi_port_cnt) {
> +
> +			ab_quota_rt = div_u64(ab_quota_rt, rt_axi_port_cnt);
> +			ab_quota_nrt = div_u64(ab_quota_nrt, nrt_axi_port_cnt);
> +
> +			for (i = 0; i < total_axi_port_cnt; i++) {
> +				if (i < rt_axi_port_cnt) {
> +					ab_quota[i] = ab_quota_rt;
> +					ib_quota[i] = ib_quota_rt;
> +				} else {
> +					ab_quota[i] = ab_quota_nrt;
> +					ib_quota[i] = ib_quota_nrt;
> +				}
> +			}
> +		} else {
> +			ab_quota[0] = div_u64(ab_quota_rt + ab_quota_nrt,
> +					total_axi_port_cnt);
> +			ib_quota[0] = ib_quota_rt + ib_quota_nrt;
> +
> +			for (i = 1; i < total_axi_port_cnt; i++) {
> +				ab_quota[i] = ab_quota[0];
> +				ib_quota[i] = ib_quota[0];
> +			}
> +		}
> +
> +		new_uc_idx = (pdbus->curr_bw_uc_idx %
> +			(bw_table->num_usecases - 1)) + 1;
> +
> +		for (i = 0; i < total_axi_port_cnt; i++) {
> +			vect = &bw_table->usecase[new_uc_idx].vectors[i];
> +			vect->ab = ab_quota[i];
> +			vect->ib = ib_quota[i];
> +
> +			pr_debug(
> +				"%s uc_idx=%d %s path idx=%d ab=%llu ib=%llu\n",
> +				bw_table->name,
> +				new_uc_idx, (i < rt_axi_port_cnt) ? "rt" : "nrt"
> +				, i, vect->ab, vect->ib);
> +		}
> +	}
> +	pdbus->curr_bw_uc_idx = new_uc_idx;
> +	pdbus->ao_bw_uc_idx = new_uc_idx;
> +
> +	DPU_ATRACE_BEGIN("msm_bus_scale_req");
> +	rc = msm_bus_scale_client_update_request(pdbus->data_bus_hdl,
> +			new_uc_idx);
> +	DPU_ATRACE_END("msm_bus_scale_req");
> +
> +	return rc;
> +}
> +
> +int dpu_power_data_bus_set_quota(struct dpu_power_handle *phandle,
> +		struct dpu_power_client *pclient,
> +		int bus_client, u32 bus_id,
> +		u64 ab_quota, u64 ib_quota)
> +{
> +	int rc = 0;
> +	int i;
> +	u64 total_ab_rt = 0, total_ib_rt = 0;
> +	u64 total_ab_nrt = 0, total_ib_nrt = 0;
> +	struct dpu_power_client *client;
> +
> +	if (!phandle || !pclient ||
> +			bus_client >= DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX ||
> +			bus_id >= DPU_POWER_HANDLE_DBUS_ID_MAX) {
> +		pr_err("invalid parameters\n");
> +		return -EINVAL;
> +	}
> +
> +	mutex_lock(&phandle->phandle_lock);
> +
> +	pclient->ab[bus_client] = ab_quota;
> +	pclient->ib[bus_client] = ib_quota;
> +	trace_dpu_perf_update_bus(bus_client, ab_quota, ib_quota);
> +
> +	list_for_each_entry(client, &phandle->power_client_clist, list) {
> +		for (i = 0; i < DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX; i++) {
> +			if (i == DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT) {
> +				total_ab_nrt += client->ab[i];
> +				total_ib_nrt += client->ib[i];
> +			} else {
> +				total_ab_rt += client->ab[i];
> +				total_ib_rt = max(total_ib_rt, client->ib[i]);
> +			}
> +		}
> +	}
> +
> +	if (phandle->data_bus_handle[bus_id].data_bus_hdl)
> +		rc = _dpu_power_data_bus_set_quota(
> +			&phandle->data_bus_handle[bus_id],
> +			total_ab_rt, total_ab_nrt,
> +			total_ib_rt, total_ib_nrt);
> +
> +	mutex_unlock(&phandle->phandle_lock);
> +
> +	return rc;
> +}
> +
> +static void dpu_power_data_bus_unregister(
> +		struct dpu_power_data_bus_handle *pdbus)
> +{
> +	if (pdbus->data_bus_hdl) {
> +		msm_bus_scale_unregister_client(pdbus->data_bus_hdl);
> +		pdbus->data_bus_hdl = 0;
> +	}
> +}
> +
> +static int dpu_power_data_bus_parse(struct platform_device *pdev,
> +	struct dpu_power_data_bus_handle *pdbus, const char *name)
> +{
> +	struct device_node *node;
> +	int rc = 0;
> +	int paths;
> +
> +	pdbus->bus_channels = 1;
> +	rc = of_property_read_u32(pdev->dev.of_node,
> +		"qcom,dpu-dram-channels", &pdbus->bus_channels);
> +	if (rc) {
> +		pr_debug("number of channels property not specified\n");
> +		rc = 0;
> +	}
> +
> +	pdbus->nrt_axi_port_cnt = 0;
> +	rc = of_property_read_u32(pdev->dev.of_node,
> +			"qcom,dpu-num-nrt-paths",
> +			&pdbus->nrt_axi_port_cnt);
> +	if (rc) {
> +		pr_debug("number of axi port property not specified\n");
> +		rc = 0;
> +	}
> +
> +	node = of_get_child_by_name(pdev->dev.of_node, name);
> +	if (node) {
> +		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;
> +		}
> +		pdbus->axi_port_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;
> +		}
> +		pr_debug("register %s data_bus_hdl=%x\n", name,
> +				pdbus->data_bus_hdl);
> +	}
> +
> +end:
> +	return rc;
> +}
> +
> +static int dpu_power_reg_bus_parse(struct platform_device *pdev,
> +	struct dpu_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,dpu-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);
> +	}
> +
> +end:
> +	return rc;
> +}
> +
> +static void dpu_power_reg_bus_unregister(u32 reg_bus_hdl)
> +{
> +	if (reg_bus_hdl)
> +		msm_bus_scale_unregister_client(reg_bus_hdl);
> +}
> +
> +int dpu_power_data_bus_state_update(struct dpu_power_handle *phandle,
> +							bool enable)
> +{
> +	int i;
> +
> +	if (!phandle) {
> +		pr_err("invalid param\n");
> +		return -EINVAL;
> +	}
> +
> +	for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC;
> +			i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
> +		phandle->data_bus_handle[i].enable = enable;
> +
> +	return 0;
> +}
> +
> +static int dpu_power_data_bus_update(struct dpu_power_data_bus_handle *pdbus,
> +							bool enable)
> +{
> +	int rc = 0;
> +
> +	pdbus->enable = enable;
> +
> +	if (pdbus->data_bus_hdl)
> +		rc = _dpu_power_data_bus_set_quota(pdbus, pdbus->ab_rt,
> +				pdbus->ab_nrt, pdbus->ib_rt, pdbus->ib_nrt);
> +
> +	if (rc)
> +		pr_err("failed to set data bus vote rc=%d enable:%d\n",
> +							rc, enable);
> +
> +	return rc;
> +}
> +
> +static int dpu_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
> +{
> +	int rc = 0;
> +
> +	if (reg_bus_hdl)
> +		rc = msm_bus_scale_client_update_request(reg_bus_hdl,
> +								usecase_ndx);
> +	if (rc)
> +		pr_err("failed to set reg bus vote rc=%d\n", rc);
> +
> +	return rc;
> +}
> +#else
> +static int dpu_power_data_bus_parse(struct platform_device *pdev,
> +		struct dpu_power_data_bus_handle *pdbus, const char *name)
> +{
> +	return 0;
> +}
> +
> +static void dpu_power_data_bus_unregister(
> +		struct dpu_power_data_bus_handle *pdbus)
> +{
> +}
> +
> +int dpu_power_data_bus_set_quota(struct dpu_power_handle *phandle,
> +		struct dpu_power_client *pclient,
> +		int bus_client, u32 bus_id,
> +		u64 ab_quota, u64 ib_quota)
> +{
> +	return 0;
> +}
> +
> +static int dpu_power_reg_bus_parse(struct platform_device *pdev,
> +	struct dpu_power_handle *phandle)
> +{
> +	return 0;
> +}
> +
> +static void dpu_power_reg_bus_unregister(u32 reg_bus_hdl)
> +{
> +}
> +
> +static int dpu_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
> +{
> +	return 0;
> +}
> +
> +static int dpu_power_data_bus_update(struct dpu_power_data_bus_handle *pdbus,
> +							bool enable)
> +{
> +	return 0;
> +}
> +
> +int dpu_power_data_bus_state_update(struct dpu_power_handle *phandle,
> +							bool enable)
> +{
> +	return 0;
> +}
> +#endif
> +
> +int dpu_power_resource_init(struct platform_device *pdev,
> +	struct dpu_power_handle *phandle)
> +{
> +	int rc = 0, i;
> +
> +	if (!phandle || !pdev) {
> +		pr_err("invalid input param\n");
> +		return -EINVAL;
> +	}
> +
> +	phandle->dev = &pdev->dev;
> +
> +	rc = dpu_power_reg_bus_parse(pdev, phandle);
> +	if (rc) {
> +		pr_err("register bus parse failed rc=%d\n", rc);
> +		return rc;
> +	}
> +
> +	for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC;
> +			i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
> +		rc = dpu_power_data_bus_parse(pdev,
> +				&phandle->data_bus_handle[i],
> +				data_bus_name[i]);
> +		if (rc) {
> +			pr_err("register data bus parse failed id=%d rc=%d\n",
> +					i, rc);
> +			goto data_bus_err;
> +		}
> +	}
> +
> +	INIT_LIST_HEAD(&phandle->power_client_clist);
> +	INIT_LIST_HEAD(&phandle->event_list);
> +
> +	mutex_init(&phandle->phandle_lock);
> +
> +	return rc;
> +
> +data_bus_err:
> +	for (i--; i >= 0; i--)
> +		dpu_power_data_bus_unregister(&phandle->data_bus_handle[i]);
> +	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
> +	return rc;
> +}
> +
> +void dpu_power_resource_deinit(struct platform_device *pdev,
> +	struct dpu_power_handle *phandle)
> +{
> +	struct dpu_power_client *curr_client, *next_client;
> +	struct dpu_power_event *curr_event, *next_event;
> +	int i;
> +
> +	if (!phandle || !pdev) {
> +		pr_err("invalid input param\n");
> +		return;
> +	}
> +
> +	mutex_lock(&phandle->phandle_lock);
> +	list_for_each_entry_safe(curr_client, next_client,
> +			&phandle->power_client_clist, list) {
> +		pr_err("cliend:%s-%d still registered with refcount:%d\n",
> +				curr_client->name, curr_client->id,
> +				curr_client->refcount);
> +		curr_client->active = false;
> +		list_del(&curr_client->list);
> +	}
> +
> +	list_for_each_entry_safe(curr_event, next_event,
> +			&phandle->event_list, list) {
> +		pr_err("event:%d, client:%s still registered\n",
> +				curr_event->event_type,
> +				curr_event->client_name);
> +		curr_event->active = false;
> +		list_del(&curr_event->list);
> +	}
> +	mutex_unlock(&phandle->phandle_lock);
> +
> +	for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
> +		dpu_power_data_bus_unregister(&phandle->data_bus_handle[i]);
> +
> +	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
> +}
> +
> +int dpu_power_resource_enable(struct dpu_power_handle *phandle,
> +	struct dpu_power_client *pclient, bool enable)
> +{
> +	int rc = 0, i;
> +	bool changed = false;
> +	u32 max_usecase_ndx = VOTE_INDEX_DISABLE, prev_usecase_ndx;
> +	struct dpu_power_client *client;
> +
> +	if (!phandle || !pclient) {
> +		pr_err("invalid input argument\n");
> +		return -EINVAL;
> +	}
> +
> +	mutex_lock(&phandle->phandle_lock);
> +	if (enable)
> +		pclient->refcount++;
> +	else if (pclient->refcount)
> +		pclient->refcount--;
> +
> +	if (pclient->refcount)
> +		pclient->usecase_ndx = VOTE_INDEX_LOW;
> +	else
> +		pclient->usecase_ndx = VOTE_INDEX_DISABLE;
> +
> +	list_for_each_entry(client, &phandle->power_client_clist, list) {
> +		if (client->usecase_ndx < VOTE_INDEX_MAX &&
> +		    client->usecase_ndx > max_usecase_ndx)
> +			max_usecase_ndx = client->usecase_ndx;
> +	}
> +
> +	if (phandle->current_usecase_ndx != max_usecase_ndx) {
> +		changed = true;
> +		prev_usecase_ndx = phandle->current_usecase_ndx;
> +		phandle->current_usecase_ndx = max_usecase_ndx;
> +	}
> +
> +	pr_debug("%pS: changed=%d current idx=%d request client %s id:%u enable:%d refcount:%d\n",
> +		__builtin_return_address(0), changed, max_usecase_ndx,
> +		pclient->name, pclient->id, enable, pclient->refcount);
> +
> +	if (!changed)
> +		goto end;
> +
> +	if (enable) {
> +		dpu_power_event_trigger_locked(phandle,
> +				DPU_POWER_EVENT_PRE_ENABLE);
> +
> +		for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
> +			rc = dpu_power_data_bus_update(
> +					&phandle->data_bus_handle[i], enable);
> +			if (rc) {
> +				pr_err("failed to set data bus vote id=%d rc=%d\n",
> +						i, rc);
> +				goto data_bus_hdl_err;
> +			}
> +		}
> +
> +		rc = dpu_power_reg_bus_update(phandle->reg_bus_hdl,
> +							max_usecase_ndx);
> +		if (rc) {
> +			pr_err("failed to set reg bus vote rc=%d\n", rc);
> +			goto reg_bus_hdl_err;
> +		}
> +
> +		dpu_power_event_trigger_locked(phandle,
> +				DPU_POWER_EVENT_POST_ENABLE);
> +
> +	} else {
> +		dpu_power_event_trigger_locked(phandle,
> +				DPU_POWER_EVENT_PRE_DISABLE);
> +
> +		dpu_power_reg_bus_update(phandle->reg_bus_hdl,
> +							max_usecase_ndx);
> +
> +		for (i = 0 ; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
> +			dpu_power_data_bus_update(&phandle->data_bus_handle[i],
> +					enable);
> +
> +		dpu_power_event_trigger_locked(phandle,
> +				DPU_POWER_EVENT_POST_DISABLE);
> +	}
> +
> +end:
> +	mutex_unlock(&phandle->phandle_lock);
> +	return rc;
> +
> +reg_bus_hdl_err:
> +	for (i = 0 ; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
> +		dpu_power_data_bus_update(&phandle->data_bus_handle[i], 0);
> +data_bus_hdl_err:
> +	phandle->current_usecase_ndx = prev_usecase_ndx;
> +	mutex_unlock(&phandle->phandle_lock);
> +	return rc;
> +}
> +
> +struct dpu_power_event *dpu_power_handle_register_event(
> +		struct dpu_power_handle *phandle,
> +		u32 event_type, void (*cb_fnc)(u32 event_type, void *usr),
> +		void *usr, char *client_name)
> +{
> +	struct dpu_power_event *event;
> +
> +	if (!phandle) {
> +		pr_err("invalid power handle\n");
> +		return ERR_PTR(-EINVAL);
> +	} else if (!cb_fnc || !event_type) {
> +		pr_err("no callback fnc or event type\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	event = kzalloc(sizeof(struct dpu_power_event), GFP_KERNEL);
> +	if (!event)
> +		return ERR_PTR(-ENOMEM);
> +
> +	event->event_type = event_type;
> +	event->cb_fnc = cb_fnc;
> +	event->usr = usr;
> +	strlcpy(event->client_name, client_name, MAX_CLIENT_NAME_LEN);
> +	event->active = true;
> +
> +	mutex_lock(&phandle->phandle_lock);
> +	list_add(&event->list, &phandle->event_list);
> +	mutex_unlock(&phandle->phandle_lock);
> +
> +	return event;
> +}
> +
> +void dpu_power_handle_unregister_event(
> +		struct dpu_power_handle *phandle,
> +		struct dpu_power_event *event)
> +{
> +	if (!phandle || !event) {
> +		pr_err("invalid phandle or event\n");
> +	} else if (!event->active) {
> +		pr_err("power handle deinit already done\n");
> +		kfree(event);
> +	} else {
> +		mutex_lock(&phandle->phandle_lock);
> +		list_del_init(&event->list);
> +		mutex_unlock(&phandle->phandle_lock);
> +		kfree(event);
> +	}
> +}
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h
> new file mode 100644
> index 0000000..9a6d4b9
> --- /dev/null
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h
> @@ -0,0 +1,288 @@
> +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + */
> +
> +#ifndef _DPU_POWER_HANDLE_H_
> +#define _DPU_POWER_HANDLE_H_
> +
> +#define MAX_CLIENT_NAME_LEN 128
> +
> +#define DPU_POWER_HANDLE_ENABLE_BUS_AB_QUOTA	0
> +#define DPU_POWER_HANDLE_DISABLE_BUS_AB_QUOTA	0
> +#define DPU_POWER_HANDLE_ENABLE_BUS_IB_QUOTA	1600000000
> +#define DPU_POWER_HANDLE_DISABLE_BUS_IB_QUOTA	0
> +
> +#include <linux/dpu_io_util.h>
> +
> +/* event will be triggered before power handler disable */
> +#define DPU_POWER_EVENT_PRE_DISABLE	0x1
> +
> +/* event will be triggered after power handler disable */
> +#define DPU_POWER_EVENT_POST_DISABLE	0x2
> +
> +/* event will be triggered before power handler enable */
> +#define DPU_POWER_EVENT_PRE_ENABLE	0x4
> +
> +/* event will be triggered after power handler enable */
> +#define DPU_POWER_EVENT_POST_ENABLE	0x8
> +
> +/**
> + * mdss_bus_vote_type: register bus vote type
> + * VOTE_INDEX_DISABLE: removes the client vote
> + * VOTE_INDEX_LOW: keeps the lowest vote for register bus
> + * VOTE_INDEX_MAX: invalid
> + */
> +enum mdss_bus_vote_type {
> +	VOTE_INDEX_DISABLE,
> +	VOTE_INDEX_LOW,
> +	VOTE_INDEX_MAX,
> +};
> +
> +/**
> + * enum dpu_power_handle_data_bus_client - type of axi bus clients
> + * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_RT: core real-time bus client
> + * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT: core non-real-time bus client
> + * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX: maximum number of bus client type
> + */
> +enum dpu_power_handle_data_bus_client {
> +	DPU_POWER_HANDLE_DATA_BUS_CLIENT_RT,
> +	DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT,
> +	DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX
> +};
> +
> +/**
> + * enum DPU_POWER_HANDLE_DBUS_ID - data bus identifier
> + * @DPU_POWER_HANDLE_DBUS_ID_MNOC: DPU/MNOC data bus
> + * @DPU_POWER_HANDLE_DBUS_ID_LLCC: MNOC/LLCC data bus
> + * @DPU_POWER_HANDLE_DBUS_ID_EBI: LLCC/EBI data bus
> + */
> +enum DPU_POWER_HANDLE_DBUS_ID {
> +	DPU_POWER_HANDLE_DBUS_ID_MNOC,
> +	DPU_POWER_HANDLE_DBUS_ID_LLCC,
> +	DPU_POWER_HANDLE_DBUS_ID_EBI,
> +	DPU_POWER_HANDLE_DBUS_ID_MAX,
> +};
> +
> +/**
> + * struct dpu_power_client: stores the power client for dpu driver
> + * @name:	name of the client
> + * @usecase_ndx: current regs bus vote type
> + * @refcount:	current refcount if multiple modules are using same
> + *              same client for enable/disable. Power module will
> + *              aggregate the refcount and vote accordingly for this
> + *              client.
> + * @id:		assigned during create. helps for debugging.
> + * @list:	list to attach power handle master list
> + * @ab:         arbitrated bandwidth for each bus client
> + * @ib:         instantaneous bandwidth for each bus client
> + * @active:	inidcates the state of dpu power handle
> + */
> +struct dpu_power_client {
> +	char name[MAX_CLIENT_NAME_LEN];
> +	short usecase_ndx;
> +	short refcount;
> +	u32 id;
> +	struct list_head list;
> +	u64 ab[DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX];
> +	u64 ib[DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX];
> +	bool active;
> +};
> +
> +/**
> + * struct dpu_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
> + * @axi_port_cnt: number of rt axi ports
> + * @nrt_axi_port_cnt: number of nrt axi ports
> + * @bus_channels: number of memory bus channels
> + * @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 dpu_power_data_bus_handle {
> +	struct msm_bus_scale_pdata *data_bus_scale_table;
> +	u32 data_bus_hdl;
> +	u32 axi_port_cnt;
> +	u32 nrt_axi_port_cnt;
> +	u32 bus_channels;
> +	u32 curr_bw_uc_idx;
> +	u32 ao_bw_uc_idx;
> +	u64 ab_rt;
> +	u64 ib_rt;
> +	u64 ab_nrt;
> +	u64 ib_nrt;
> +	bool enable;
> +};
> +
> +/*
> + * struct dpu_power_event - local event registration structure
> + * @client_name: name of the client registering
> + * @cb_fnc: pointer to desired callback function
> + * @usr: user pointer to pass to callback event trigger
> + * @event: refer to DPU_POWER_HANDLE_EVENT_*
> + * @list: list to attach event master list
> + * @active: indicates the state of dpu power handle
> + */
> +struct dpu_power_event {
> +	char client_name[MAX_CLIENT_NAME_LEN];
> +	void (*cb_fnc)(u32 event_type, void *usr);
> +	void *usr;
> +	u32 event_type;
> +	struct list_head list;
> +	bool active;
> +};
> +
> +/**
> + * struct dpu_power_handle: power handle main struct
> + * @client_clist: master list to store all clients
> + * @phandle_lock: lock to synchronize the enable/disable
> + * @dev: pointer to device structure
> + * @usecase_ndx: current usecase index
> + * @reg_bus_hdl: current register bus handle
> + * @data_bus_handle: context structure for data bus control
> + * @event_list: current power handle event list
> + */
> +struct dpu_power_handle {
> +	struct list_head power_client_clist;
> +	struct mutex phandle_lock;
> +	struct device *dev;
> +	u32 current_usecase_ndx;
> +	u32 reg_bus_hdl;
> +	struct dpu_power_data_bus_handle data_bus_handle
> +		[DPU_POWER_HANDLE_DBUS_ID_MAX];
> +	struct list_head event_list;
> +};
> +
> +/**
> + * dpu_power_resource_init() - initializes the dpu power handle
> + * @pdev:   platform device to search the power resources
> + * @pdata:  power handle to store the power resources
> + *
> + * Return: error code.
> + */
> +int dpu_power_resource_init(struct platform_device *pdev,
> +	struct dpu_power_handle *pdata);
> +
> +/**
> + * dpu_power_resource_deinit() - release the dpu power handle
> + * @pdev:   platform device for power resources
> + * @pdata:  power handle containing the resources
> + *
> + * Return: error code.
> + */
> +void dpu_power_resource_deinit(struct platform_device *pdev,
> +	struct dpu_power_handle *pdata);
> +
> +/**
> + * dpu_power_client_create() - create the client on power handle
> + * @pdata:  power handle containing the resources
> + * @client_name: new client name for registration
> + *
> + * Return: error code.
> + */
> +struct dpu_power_client *dpu_power_client_create(struct dpu_power_handle *pdata,
> +	char *client_name);
> +
> +/**
> + * dpu_power_client_destroy() - destroy the client on power handle
> + * @pdata:  power handle containing the resources
> + * @client_name: new client name for registration
> + *
> + * Return: none
> + */
> +void dpu_power_client_destroy(struct dpu_power_handle *phandle,
> +	struct dpu_power_client *client);
> +
> +/**
> + * dpu_power_resource_enable() - enable/disable the power resources
> + * @pdata:  power handle containing the resources
> + * @client: client information to enable/disable its vote
> + * @enable: boolean request for enable/disable
> + *
> + * Return: error code.
> + */
> +int dpu_power_resource_enable(struct dpu_power_handle *pdata,
> +	struct dpu_power_client *pclient, bool enable);
> +
> +/**
> + * dpu_power_data_bus_state_update() - update data bus state
> + * @pdata:  power handle containing the resources
> + * @enable: take enable vs disable path
> + *
> + * Return: error code.
> + */
> +int dpu_power_data_bus_state_update(struct dpu_power_handle *phandle,
> +							bool enable);
> +
> +/**
> + * dpu_power_data_bus_set_quota() - set data bus quota for power client
> + * @phandle:  power handle containing the resources
> + * @client: client information to set quota
> + * @bus_client: real-time or non-real-time bus client
> + * @bus_id: identifier of data bus, see DPU_POWER_HANDLE_DBUS_ID
> + * @ab_quota: arbitrated bus bandwidth
> + * @ib_quota: instantaneous bus bandwidth
> + *
> + * Return: zero if success, or error code otherwise
> + */
> +int dpu_power_data_bus_set_quota(struct dpu_power_handle *phandle,
> +		struct dpu_power_client *pclient,
> +		int bus_client, u32 bus_id,
> +		u64 ab_quota, u64 ib_quota);
> +
> +/**
> + * dpu_power_data_bus_bandwidth_ctrl() - control data bus bandwidth enable
> + * @phandle:  power handle containing the resources
> + * @client: client information to bandwidth control
> + * @enable: true to enable bandwidth for data base
> + *
> + * Return: none
> + */
> +void dpu_power_data_bus_bandwidth_ctrl(struct dpu_power_handle *phandle,
> +		struct dpu_power_client *pclient, int enable);
> +
> +/**
> + * dpu_power_handle_register_event - register a callback function for an event.
> + *	Clients can register for multiple events with a single register.
> + *	Any block with access to phandle can register for the event
> + *	notification.
> + * @phandle:	power handle containing the resources
> + * @event_type:	event type to register; refer DPU_POWER_HANDLE_EVENT_*
> + * @cb_fnc:	pointer to desired callback function
> + * @usr:	user pointer to pass to callback on event trigger
> + *
> + * Return:	event pointer if success, or error code otherwise
> + */
> +struct dpu_power_event *dpu_power_handle_register_event(
> +		struct dpu_power_handle *phandle,
> +		u32 event_type, void (*cb_fnc)(u32 event_type, void *usr),
> +		void *usr, char *client_name);
> +/**
> + * dpu_power_handle_unregister_event - unregister callback for event(s)
> + * @phandle:	power handle containing the resources
> + * @event:	event pointer returned after power handle register
> + */
> +void dpu_power_handle_unregister_event(struct dpu_power_handle *phandle,
> +		struct dpu_power_event *event);
> +
> +/**
> + * dpu_power_handle_get_dbus_name - get name of given data bus identifier
> + * @bus_id:	data bus identifier
> + * Return:	Pointer to name string if success; NULL otherwise
> + */
> +const char *dpu_power_handle_get_dbus_name(u32 bus_id);
> +
> +#endif /* _DPU_POWER_HANDLE_H_ */
> diff --git a/drivers/gpu/drm/msm/dpu_power_handle.c b/drivers/gpu/drm/msm/dpu_power_handle.c
> deleted file mode 100644
> index 77be106..0000000
> --- a/drivers/gpu/drm/msm/dpu_power_handle.c
> +++ /dev/null
> @@ -1,693 +0,0 @@
> -/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 and
> - * only version 2 as published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - *
> - */
> -
> -#define pr_fmt(fmt)	"[drm:%s:%d]: " fmt, __func__, __LINE__
> -
> -#include <linux/kernel.h>
> -#include <linux/of.h>
> -#include <linux/string.h>
> -#include <linux/of_address.h>
> -#include <linux/slab.h>
> -#include <linux/mutex.h>
> -#include <linux/of_platform.h>
> -#ifdef CONFIG_QCOM_BUS_SCALING
> -#include <linux/msm-bus.h>
> -#include <linux/msm-bus-board.h>
> -#endif
> -#include <linux/dpu_io_util.h>
> -
> -#include "dpu_power_handle.h"
> -#include "dpu_trace.h"
> -
> -static const char *data_bus_name[DPU_POWER_HANDLE_DBUS_ID_MAX] = {
> -	[DPU_POWER_HANDLE_DBUS_ID_MNOC] = "qcom,dpu-data-bus",
> -	[DPU_POWER_HANDLE_DBUS_ID_LLCC] = "qcom,dpu-llcc-bus",
> -	[DPU_POWER_HANDLE_DBUS_ID_EBI] = "qcom,dpu-ebi-bus",
> -};
> -
> -const char *dpu_power_handle_get_dbus_name(u32 bus_id)
> -{
> -	if (bus_id < DPU_POWER_HANDLE_DBUS_ID_MAX)
> -		return data_bus_name[bus_id];
> -
> -	return NULL;
> -}
> -
> -static void dpu_power_event_trigger_locked(struct dpu_power_handle *phandle,
> -		u32 event_type)
> -{
> -	struct dpu_power_event *event;
> -
> -	list_for_each_entry(event, &phandle->event_list, list) {
> -		if (event->event_type & event_type)
> -			event->cb_fnc(event_type, event->usr);
> -	}
> -}
> -
> -struct dpu_power_client *dpu_power_client_create(
> -	struct dpu_power_handle *phandle, char *client_name)
> -{
> -	struct dpu_power_client *client;
> -	static u32 id;
> -
> -	if (!client_name || !phandle) {
> -		pr_err("client name is null or invalid power data\n");
> -		return ERR_PTR(-EINVAL);
> -	}
> -
> -	client = kzalloc(sizeof(struct dpu_power_client), GFP_KERNEL);
> -	if (!client)
> -		return ERR_PTR(-ENOMEM);
> -
> -	mutex_lock(&phandle->phandle_lock);
> -	strlcpy(client->name, client_name, MAX_CLIENT_NAME_LEN);
> -	client->usecase_ndx = VOTE_INDEX_DISABLE;
> -	client->id = id;
> -	client->active = true;
> -	pr_debug("client %s created:%pK id :%d\n", client_name,
> -		client, id);
> -	id++;
> -	list_add(&client->list, &phandle->power_client_clist);
> -	mutex_unlock(&phandle->phandle_lock);
> -
> -	return client;
> -}
> -
> -void dpu_power_client_destroy(struct dpu_power_handle *phandle,
> -	struct dpu_power_client *client)
> -{
> -	if (!client  || !phandle) {
> -		pr_err("reg bus vote: invalid client handle\n");
> -	} else if (!client->active) {
> -		pr_err("dpu power deinit already done\n");
> -		kfree(client);
> -	} else {
> -		pr_debug("bus vote client %s destroyed:%pK id:%u\n",
> -			client->name, client, client->id);
> -		mutex_lock(&phandle->phandle_lock);
> -		list_del_init(&client->list);
> -		mutex_unlock(&phandle->phandle_lock);
> -		kfree(client);
> -	}
> -}
> -
> -#ifdef CONFIG_QCOM_BUS_SCALING
> -
> -#define MAX_AXI_PORT_COUNT 3
> -
> -static int _dpu_power_data_bus_set_quota(
> -		struct dpu_power_data_bus_handle *pdbus,
> -		u64 ab_quota_rt, u64 ab_quota_nrt,
> -		u64 ib_quota_rt, u64 ib_quota_nrt)
> -{
> -	int new_uc_idx;
> -	u64 ab_quota[MAX_AXI_PORT_COUNT] = {0, 0};
> -	u64 ib_quota[MAX_AXI_PORT_COUNT] = {0, 0};
> -	int rc;
> -
> -	if (pdbus->data_bus_hdl < 1) {
> -		pr_err("invalid bus handle %d\n", pdbus->data_bus_hdl);
> -		return -EINVAL;
> -	}
> -
> -	pdbus->ab_rt = ab_quota_rt;
> -	pdbus->ib_rt = ib_quota_rt;
> -	pdbus->ab_nrt = ab_quota_nrt;
> -	pdbus->ib_nrt = ib_quota_nrt;
> -
> -	if (pdbus->enable) {
> -		ab_quota_rt = max_t(u64, ab_quota_rt,
> -				DPU_POWER_HANDLE_ENABLE_BUS_AB_QUOTA);
> -		ib_quota_rt = max_t(u64, ib_quota_rt,
> -				DPU_POWER_HANDLE_ENABLE_BUS_IB_QUOTA);
> -		ab_quota_nrt = max_t(u64, ab_quota_nrt,
> -				DPU_POWER_HANDLE_ENABLE_BUS_AB_QUOTA);
> -		ib_quota_nrt = max_t(u64, ib_quota_nrt,
> -				DPU_POWER_HANDLE_ENABLE_BUS_IB_QUOTA);
> -	} else {
> -		ab_quota_rt = min_t(u64, ab_quota_rt,
> -				DPU_POWER_HANDLE_DISABLE_BUS_AB_QUOTA);
> -		ib_quota_rt = min_t(u64, ib_quota_rt,
> -				DPU_POWER_HANDLE_DISABLE_BUS_IB_QUOTA);
> -		ab_quota_nrt = min_t(u64, ab_quota_nrt,
> -				DPU_POWER_HANDLE_DISABLE_BUS_AB_QUOTA);
> -		ib_quota_nrt = min_t(u64, ib_quota_nrt,
> -				DPU_POWER_HANDLE_DISABLE_BUS_IB_QUOTA);
> -	}
> -
> -	if (!ab_quota_rt && !ab_quota_nrt && !ib_quota_rt && !ib_quota_nrt)  {
> -		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 nrt_axi_port_cnt = pdbus->nrt_axi_port_cnt;
> -		u32 total_axi_port_cnt = pdbus->axi_port_cnt;
> -		u32 rt_axi_port_cnt = total_axi_port_cnt - nrt_axi_port_cnt;
> -
> -		if (!bw_table || !total_axi_port_cnt ||
> -		    total_axi_port_cnt > MAX_AXI_PORT_COUNT) {
> -			pr_err("invalid input\n");
> -			return -EINVAL;
> -		}
> -
> -		if (pdbus->bus_channels) {
> -			ib_quota_rt = div_u64(ib_quota_rt,
> -						pdbus->bus_channels);
> -			ib_quota_nrt = div_u64(ib_quota_nrt,
> -						pdbus->bus_channels);
> -		}
> -
> -		if (nrt_axi_port_cnt) {
> -
> -			ab_quota_rt = div_u64(ab_quota_rt, rt_axi_port_cnt);
> -			ab_quota_nrt = div_u64(ab_quota_nrt, nrt_axi_port_cnt);
> -
> -			for (i = 0; i < total_axi_port_cnt; i++) {
> -				if (i < rt_axi_port_cnt) {
> -					ab_quota[i] = ab_quota_rt;
> -					ib_quota[i] = ib_quota_rt;
> -				} else {
> -					ab_quota[i] = ab_quota_nrt;
> -					ib_quota[i] = ib_quota_nrt;
> -				}
> -			}
> -		} else {
> -			ab_quota[0] = div_u64(ab_quota_rt + ab_quota_nrt,
> -					total_axi_port_cnt);
> -			ib_quota[0] = ib_quota_rt + ib_quota_nrt;
> -
> -			for (i = 1; i < total_axi_port_cnt; i++) {
> -				ab_quota[i] = ab_quota[0];
> -				ib_quota[i] = ib_quota[0];
> -			}
> -		}
> -
> -		new_uc_idx = (pdbus->curr_bw_uc_idx %
> -			(bw_table->num_usecases - 1)) + 1;
> -
> -		for (i = 0; i < total_axi_port_cnt; i++) {
> -			vect = &bw_table->usecase[new_uc_idx].vectors[i];
> -			vect->ab = ab_quota[i];
> -			vect->ib = ib_quota[i];
> -
> -			pr_debug(
> -				"%s uc_idx=%d %s path idx=%d ab=%llu ib=%llu\n",
> -				bw_table->name,
> -				new_uc_idx, (i < rt_axi_port_cnt) ? "rt" : "nrt"
> -				, i, vect->ab, vect->ib);
> -		}
> -	}
> -	pdbus->curr_bw_uc_idx = new_uc_idx;
> -	pdbus->ao_bw_uc_idx = new_uc_idx;
> -
> -	DPU_ATRACE_BEGIN("msm_bus_scale_req");
> -	rc = msm_bus_scale_client_update_request(pdbus->data_bus_hdl,
> -			new_uc_idx);
> -	DPU_ATRACE_END("msm_bus_scale_req");
> -
> -	return rc;
> -}
> -
> -int dpu_power_data_bus_set_quota(struct dpu_power_handle *phandle,
> -		struct dpu_power_client *pclient,
> -		int bus_client, u32 bus_id,
> -		u64 ab_quota, u64 ib_quota)
> -{
> -	int rc = 0;
> -	int i;
> -	u64 total_ab_rt = 0, total_ib_rt = 0;
> -	u64 total_ab_nrt = 0, total_ib_nrt = 0;
> -	struct dpu_power_client *client;
> -
> -	if (!phandle || !pclient ||
> -			bus_client >= DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX ||
> -			bus_id >= DPU_POWER_HANDLE_DBUS_ID_MAX) {
> -		pr_err("invalid parameters\n");
> -		return -EINVAL;
> -	}
> -
> -	mutex_lock(&phandle->phandle_lock);
> -
> -	pclient->ab[bus_client] = ab_quota;
> -	pclient->ib[bus_client] = ib_quota;
> -	trace_dpu_perf_update_bus(bus_client, ab_quota, ib_quota);
> -
> -	list_for_each_entry(client, &phandle->power_client_clist, list) {
> -		for (i = 0; i < DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX; i++) {
> -			if (i == DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT) {
> -				total_ab_nrt += client->ab[i];
> -				total_ib_nrt += client->ib[i];
> -			} else {
> -				total_ab_rt += client->ab[i];
> -				total_ib_rt = max(total_ib_rt, client->ib[i]);
> -			}
> -		}
> -	}
> -
> -	if (phandle->data_bus_handle[bus_id].data_bus_hdl)
> -		rc = _dpu_power_data_bus_set_quota(
> -			&phandle->data_bus_handle[bus_id],
> -			total_ab_rt, total_ab_nrt,
> -			total_ib_rt, total_ib_nrt);
> -
> -	mutex_unlock(&phandle->phandle_lock);
> -
> -	return rc;
> -}
> -
> -static void dpu_power_data_bus_unregister(
> -		struct dpu_power_data_bus_handle *pdbus)
> -{
> -	if (pdbus->data_bus_hdl) {
> -		msm_bus_scale_unregister_client(pdbus->data_bus_hdl);
> -		pdbus->data_bus_hdl = 0;
> -	}
> -}
> -
> -static int dpu_power_data_bus_parse(struct platform_device *pdev,
> -	struct dpu_power_data_bus_handle *pdbus, const char *name)
> -{
> -	struct device_node *node;
> -	int rc = 0;
> -	int paths;
> -
> -	pdbus->bus_channels = 1;
> -	rc = of_property_read_u32(pdev->dev.of_node,
> -		"qcom,dpu-dram-channels", &pdbus->bus_channels);
> -	if (rc) {
> -		pr_debug("number of channels property not specified\n");
> -		rc = 0;
> -	}
> -
> -	pdbus->nrt_axi_port_cnt = 0;
> -	rc = of_property_read_u32(pdev->dev.of_node,
> -			"qcom,dpu-num-nrt-paths",
> -			&pdbus->nrt_axi_port_cnt);
> -	if (rc) {
> -		pr_debug("number of axi port property not specified\n");
> -		rc = 0;
> -	}
> -
> -	node = of_get_child_by_name(pdev->dev.of_node, name);
> -	if (node) {
> -		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;
> -		}
> -		pdbus->axi_port_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;
> -		}
> -		pr_debug("register %s data_bus_hdl=%x\n", name,
> -				pdbus->data_bus_hdl);
> -	}
> -
> -end:
> -	return rc;
> -}
> -
> -static int dpu_power_reg_bus_parse(struct platform_device *pdev,
> -	struct dpu_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,dpu-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);
> -	}
> -
> -end:
> -	return rc;
> -}
> -
> -static void dpu_power_reg_bus_unregister(u32 reg_bus_hdl)
> -{
> -	if (reg_bus_hdl)
> -		msm_bus_scale_unregister_client(reg_bus_hdl);
> -}
> -
> -int dpu_power_data_bus_state_update(struct dpu_power_handle *phandle,
> -							bool enable)
> -{
> -	int i;
> -
> -	if (!phandle) {
> -		pr_err("invalid param\n");
> -		return -EINVAL;
> -	}
> -
> -	for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC;
> -			i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
> -		phandle->data_bus_handle[i].enable = enable;
> -
> -	return 0;
> -}
> -
> -static int dpu_power_data_bus_update(struct dpu_power_data_bus_handle *pdbus,
> -							bool enable)
> -{
> -	int rc = 0;
> -
> -	pdbus->enable = enable;
> -
> -	if (pdbus->data_bus_hdl)
> -		rc = _dpu_power_data_bus_set_quota(pdbus, pdbus->ab_rt,
> -				pdbus->ab_nrt, pdbus->ib_rt, pdbus->ib_nrt);
> -
> -	if (rc)
> -		pr_err("failed to set data bus vote rc=%d enable:%d\n",
> -							rc, enable);
> -
> -	return rc;
> -}
> -
> -static int dpu_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
> -{
> -	int rc = 0;
> -
> -	if (reg_bus_hdl)
> -		rc = msm_bus_scale_client_update_request(reg_bus_hdl,
> -								usecase_ndx);
> -	if (rc)
> -		pr_err("failed to set reg bus vote rc=%d\n", rc);
> -
> -	return rc;
> -}
> -#else
> -static int dpu_power_data_bus_parse(struct platform_device *pdev,
> -		struct dpu_power_data_bus_handle *pdbus, const char *name)
> -{
> -	return 0;
> -}
> -
> -static void dpu_power_data_bus_unregister(
> -		struct dpu_power_data_bus_handle *pdbus)
> -{
> -}
> -
> -int dpu_power_data_bus_set_quota(struct dpu_power_handle *phandle,
> -		struct dpu_power_client *pclient,
> -		int bus_client, u32 bus_id,
> -		u64 ab_quota, u64 ib_quota)
> -{
> -	return 0;
> -}
> -
> -static int dpu_power_reg_bus_parse(struct platform_device *pdev,
> -	struct dpu_power_handle *phandle)
> -{
> -	return 0;
> -}
> -
> -static void dpu_power_reg_bus_unregister(u32 reg_bus_hdl)
> -{
> -}
> -
> -static int dpu_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
> -{
> -	return 0;
> -}
> -
> -static int dpu_power_data_bus_update(struct dpu_power_data_bus_handle *pdbus,
> -							bool enable)
> -{
> -	return 0;
> -}
> -
> -int dpu_power_data_bus_state_update(struct dpu_power_handle *phandle,
> -							bool enable)
> -{
> -	return 0;
> -}
> -#endif
> -
> -int dpu_power_resource_init(struct platform_device *pdev,
> -	struct dpu_power_handle *phandle)
> -{
> -	int rc = 0, i;
> -
> -	if (!phandle || !pdev) {
> -		pr_err("invalid input param\n");
> -		return -EINVAL;
> -	}
> -
> -	phandle->dev = &pdev->dev;
> -
> -	rc = dpu_power_reg_bus_parse(pdev, phandle);
> -	if (rc) {
> -		pr_err("register bus parse failed rc=%d\n", rc);
> -		return rc;
> -	}
> -
> -	for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC;
> -			i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
> -		rc = dpu_power_data_bus_parse(pdev,
> -				&phandle->data_bus_handle[i],
> -				data_bus_name[i]);
> -		if (rc) {
> -			pr_err("register data bus parse failed id=%d rc=%d\n",
> -					i, rc);
> -			goto data_bus_err;
> -		}
> -	}
> -
> -	INIT_LIST_HEAD(&phandle->power_client_clist);
> -	INIT_LIST_HEAD(&phandle->event_list);
> -
> -	mutex_init(&phandle->phandle_lock);
> -
> -	return rc;
> -
> -data_bus_err:
> -	for (i--; i >= 0; i--)
> -		dpu_power_data_bus_unregister(&phandle->data_bus_handle[i]);
> -	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
> -	return rc;
> -}
> -
> -void dpu_power_resource_deinit(struct platform_device *pdev,
> -	struct dpu_power_handle *phandle)
> -{
> -	struct dpu_power_client *curr_client, *next_client;
> -	struct dpu_power_event *curr_event, *next_event;
> -	int i;
> -
> -	if (!phandle || !pdev) {
> -		pr_err("invalid input param\n");
> -		return;
> -	}
> -
> -	mutex_lock(&phandle->phandle_lock);
> -	list_for_each_entry_safe(curr_client, next_client,
> -			&phandle->power_client_clist, list) {
> -		pr_err("cliend:%s-%d still registered with refcount:%d\n",
> -				curr_client->name, curr_client->id,
> -				curr_client->refcount);
> -		curr_client->active = false;
> -		list_del(&curr_client->list);
> -	}
> -
> -	list_for_each_entry_safe(curr_event, next_event,
> -			&phandle->event_list, list) {
> -		pr_err("event:%d, client:%s still registered\n",
> -				curr_event->event_type,
> -				curr_event->client_name);
> -		curr_event->active = false;
> -		list_del(&curr_event->list);
> -	}
> -	mutex_unlock(&phandle->phandle_lock);
> -
> -	for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
> -		dpu_power_data_bus_unregister(&phandle->data_bus_handle[i]);
> -
> -	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
> -}
> -
> -int dpu_power_resource_enable(struct dpu_power_handle *phandle,
> -	struct dpu_power_client *pclient, bool enable)
> -{
> -	int rc = 0, i;
> -	bool changed = false;
> -	u32 max_usecase_ndx = VOTE_INDEX_DISABLE, prev_usecase_ndx;
> -	struct dpu_power_client *client;
> -
> -	if (!phandle || !pclient) {
> -		pr_err("invalid input argument\n");
> -		return -EINVAL;
> -	}
> -
> -	mutex_lock(&phandle->phandle_lock);
> -	if (enable)
> -		pclient->refcount++;
> -	else if (pclient->refcount)
> -		pclient->refcount--;
> -
> -	if (pclient->refcount)
> -		pclient->usecase_ndx = VOTE_INDEX_LOW;
> -	else
> -		pclient->usecase_ndx = VOTE_INDEX_DISABLE;
> -
> -	list_for_each_entry(client, &phandle->power_client_clist, list) {
> -		if (client->usecase_ndx < VOTE_INDEX_MAX &&
> -		    client->usecase_ndx > max_usecase_ndx)
> -			max_usecase_ndx = client->usecase_ndx;
> -	}
> -
> -	if (phandle->current_usecase_ndx != max_usecase_ndx) {
> -		changed = true;
> -		prev_usecase_ndx = phandle->current_usecase_ndx;
> -		phandle->current_usecase_ndx = max_usecase_ndx;
> -	}
> -
> -	pr_debug("%pS: changed=%d current idx=%d request client %s id:%u enable:%d refcount:%d\n",
> -		__builtin_return_address(0), changed, max_usecase_ndx,
> -		pclient->name, pclient->id, enable, pclient->refcount);
> -
> -	if (!changed)
> -		goto end;
> -
> -	if (enable) {
> -		dpu_power_event_trigger_locked(phandle,
> -				DPU_POWER_EVENT_PRE_ENABLE);
> -
> -		for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
> -			rc = dpu_power_data_bus_update(
> -					&phandle->data_bus_handle[i], enable);
> -			if (rc) {
> -				pr_err("failed to set data bus vote id=%d rc=%d\n",
> -						i, rc);
> -				goto data_bus_hdl_err;
> -			}
> -		}
> -
> -		rc = dpu_power_reg_bus_update(phandle->reg_bus_hdl,
> -							max_usecase_ndx);
> -		if (rc) {
> -			pr_err("failed to set reg bus vote rc=%d\n", rc);
> -			goto reg_bus_hdl_err;
> -		}
> -
> -		dpu_power_event_trigger_locked(phandle,
> -				DPU_POWER_EVENT_POST_ENABLE);
> -
> -	} else {
> -		dpu_power_event_trigger_locked(phandle,
> -				DPU_POWER_EVENT_PRE_DISABLE);
> -
> -		dpu_power_reg_bus_update(phandle->reg_bus_hdl,
> -							max_usecase_ndx);
> -
> -		for (i = 0 ; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
> -			dpu_power_data_bus_update(&phandle->data_bus_handle[i],
> -					enable);
> -
> -		dpu_power_event_trigger_locked(phandle,
> -				DPU_POWER_EVENT_POST_DISABLE);
> -	}
> -
> -end:
> -	mutex_unlock(&phandle->phandle_lock);
> -	return rc;
> -
> -reg_bus_hdl_err:
> -	for (i = 0 ; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
> -		dpu_power_data_bus_update(&phandle->data_bus_handle[i], 0);
> -data_bus_hdl_err:
> -	phandle->current_usecase_ndx = prev_usecase_ndx;
> -	mutex_unlock(&phandle->phandle_lock);
> -	return rc;
> -}
> -
> -struct dpu_power_event *dpu_power_handle_register_event(
> -		struct dpu_power_handle *phandle,
> -		u32 event_type, void (*cb_fnc)(u32 event_type, void *usr),
> -		void *usr, char *client_name)
> -{
> -	struct dpu_power_event *event;
> -
> -	if (!phandle) {
> -		pr_err("invalid power handle\n");
> -		return ERR_PTR(-EINVAL);
> -	} else if (!cb_fnc || !event_type) {
> -		pr_err("no callback fnc or event type\n");
> -		return ERR_PTR(-EINVAL);
> -	}
> -
> -	event = kzalloc(sizeof(struct dpu_power_event), GFP_KERNEL);
> -	if (!event)
> -		return ERR_PTR(-ENOMEM);
> -
> -	event->event_type = event_type;
> -	event->cb_fnc = cb_fnc;
> -	event->usr = usr;
> -	strlcpy(event->client_name, client_name, MAX_CLIENT_NAME_LEN);
> -	event->active = true;
> -
> -	mutex_lock(&phandle->phandle_lock);
> -	list_add(&event->list, &phandle->event_list);
> -	mutex_unlock(&phandle->phandle_lock);
> -
> -	return event;
> -}
> -
> -void dpu_power_handle_unregister_event(
> -		struct dpu_power_handle *phandle,
> -		struct dpu_power_event *event)
> -{
> -	if (!phandle || !event) {
> -		pr_err("invalid phandle or event\n");
> -	} else if (!event->active) {
> -		pr_err("power handle deinit already done\n");
> -		kfree(event);
> -	} else {
> -		mutex_lock(&phandle->phandle_lock);
> -		list_del_init(&event->list);
> -		mutex_unlock(&phandle->phandle_lock);
> -		kfree(event);
> -	}
> -}
> diff --git a/drivers/gpu/drm/msm/dpu_power_handle.h b/drivers/gpu/drm/msm/dpu_power_handle.h
> deleted file mode 100644
> index 9a6d4b9..0000000
> --- a/drivers/gpu/drm/msm/dpu_power_handle.h
> +++ /dev/null
> @@ -1,288 +0,0 @@
> -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
> - *
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License version 2 and
> - * only version 2 as published by the Free Software Foundation.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> - * GNU General Public License for more details.
> - *
> - */
> -
> -#ifndef _DPU_POWER_HANDLE_H_
> -#define _DPU_POWER_HANDLE_H_
> -
> -#define MAX_CLIENT_NAME_LEN 128
> -
> -#define DPU_POWER_HANDLE_ENABLE_BUS_AB_QUOTA	0
> -#define DPU_POWER_HANDLE_DISABLE_BUS_AB_QUOTA	0
> -#define DPU_POWER_HANDLE_ENABLE_BUS_IB_QUOTA	1600000000
> -#define DPU_POWER_HANDLE_DISABLE_BUS_IB_QUOTA	0
> -
> -#include <linux/dpu_io_util.h>
> -
> -/* event will be triggered before power handler disable */
> -#define DPU_POWER_EVENT_PRE_DISABLE	0x1
> -
> -/* event will be triggered after power handler disable */
> -#define DPU_POWER_EVENT_POST_DISABLE	0x2
> -
> -/* event will be triggered before power handler enable */
> -#define DPU_POWER_EVENT_PRE_ENABLE	0x4
> -
> -/* event will be triggered after power handler enable */
> -#define DPU_POWER_EVENT_POST_ENABLE	0x8
> -
> -/**
> - * mdss_bus_vote_type: register bus vote type
> - * VOTE_INDEX_DISABLE: removes the client vote
> - * VOTE_INDEX_LOW: keeps the lowest vote for register bus
> - * VOTE_INDEX_MAX: invalid
> - */
> -enum mdss_bus_vote_type {
> -	VOTE_INDEX_DISABLE,
> -	VOTE_INDEX_LOW,
> -	VOTE_INDEX_MAX,
> -};
> -
> -/**
> - * enum dpu_power_handle_data_bus_client - type of axi bus clients
> - * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_RT: core real-time bus client
> - * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT: core non-real-time bus client
> - * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX: maximum number of bus client type
> - */
> -enum dpu_power_handle_data_bus_client {
> -	DPU_POWER_HANDLE_DATA_BUS_CLIENT_RT,
> -	DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT,
> -	DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX
> -};
> -
> -/**
> - * enum DPU_POWER_HANDLE_DBUS_ID - data bus identifier
> - * @DPU_POWER_HANDLE_DBUS_ID_MNOC: DPU/MNOC data bus
> - * @DPU_POWER_HANDLE_DBUS_ID_LLCC: MNOC/LLCC data bus
> - * @DPU_POWER_HANDLE_DBUS_ID_EBI: LLCC/EBI data bus
> - */
> -enum DPU_POWER_HANDLE_DBUS_ID {
> -	DPU_POWER_HANDLE_DBUS_ID_MNOC,
> -	DPU_POWER_HANDLE_DBUS_ID_LLCC,
> -	DPU_POWER_HANDLE_DBUS_ID_EBI,
> -	DPU_POWER_HANDLE_DBUS_ID_MAX,
> -};
> -
> -/**
> - * struct dpu_power_client: stores the power client for dpu driver
> - * @name:	name of the client
> - * @usecase_ndx: current regs bus vote type
> - * @refcount:	current refcount if multiple modules are using same
> - *              same client for enable/disable. Power module will
> - *              aggregate the refcount and vote accordingly for this
> - *              client.
> - * @id:		assigned during create. helps for debugging.
> - * @list:	list to attach power handle master list
> - * @ab:         arbitrated bandwidth for each bus client
> - * @ib:         instantaneous bandwidth for each bus client
> - * @active:	inidcates the state of dpu power handle
> - */
> -struct dpu_power_client {
> -	char name[MAX_CLIENT_NAME_LEN];
> -	short usecase_ndx;
> -	short refcount;
> -	u32 id;
> -	struct list_head list;
> -	u64 ab[DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX];
> -	u64 ib[DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX];
> -	bool active;
> -};
> -
> -/**
> - * struct dpu_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
> - * @axi_port_cnt: number of rt axi ports
> - * @nrt_axi_port_cnt: number of nrt axi ports
> - * @bus_channels: number of memory bus channels
> - * @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 dpu_power_data_bus_handle {
> -	struct msm_bus_scale_pdata *data_bus_scale_table;
> -	u32 data_bus_hdl;
> -	u32 axi_port_cnt;
> -	u32 nrt_axi_port_cnt;
> -	u32 bus_channels;
> -	u32 curr_bw_uc_idx;
> -	u32 ao_bw_uc_idx;
> -	u64 ab_rt;
> -	u64 ib_rt;
> -	u64 ab_nrt;
> -	u64 ib_nrt;
> -	bool enable;
> -};
> -
> -/*
> - * struct dpu_power_event - local event registration structure
> - * @client_name: name of the client registering
> - * @cb_fnc: pointer to desired callback function
> - * @usr: user pointer to pass to callback event trigger
> - * @event: refer to DPU_POWER_HANDLE_EVENT_*
> - * @list: list to attach event master list
> - * @active: indicates the state of dpu power handle
> - */
> -struct dpu_power_event {
> -	char client_name[MAX_CLIENT_NAME_LEN];
> -	void (*cb_fnc)(u32 event_type, void *usr);
> -	void *usr;
> -	u32 event_type;
> -	struct list_head list;
> -	bool active;
> -};
> -
> -/**
> - * struct dpu_power_handle: power handle main struct
> - * @client_clist: master list to store all clients
> - * @phandle_lock: lock to synchronize the enable/disable
> - * @dev: pointer to device structure
> - * @usecase_ndx: current usecase index
> - * @reg_bus_hdl: current register bus handle
> - * @data_bus_handle: context structure for data bus control
> - * @event_list: current power handle event list
> - */
> -struct dpu_power_handle {
> -	struct list_head power_client_clist;
> -	struct mutex phandle_lock;
> -	struct device *dev;
> -	u32 current_usecase_ndx;
> -	u32 reg_bus_hdl;
> -	struct dpu_power_data_bus_handle data_bus_handle
> -		[DPU_POWER_HANDLE_DBUS_ID_MAX];
> -	struct list_head event_list;
> -};
> -
> -/**
> - * dpu_power_resource_init() - initializes the dpu power handle
> - * @pdev:   platform device to search the power resources
> - * @pdata:  power handle to store the power resources
> - *
> - * Return: error code.
> - */
> -int dpu_power_resource_init(struct platform_device *pdev,
> -	struct dpu_power_handle *pdata);
> -
> -/**
> - * dpu_power_resource_deinit() - release the dpu power handle
> - * @pdev:   platform device for power resources
> - * @pdata:  power handle containing the resources
> - *
> - * Return: error code.
> - */
> -void dpu_power_resource_deinit(struct platform_device *pdev,
> -	struct dpu_power_handle *pdata);
> -
> -/**
> - * dpu_power_client_create() - create the client on power handle
> - * @pdata:  power handle containing the resources
> - * @client_name: new client name for registration
> - *
> - * Return: error code.
> - */
> -struct dpu_power_client *dpu_power_client_create(struct dpu_power_handle *pdata,
> -	char *client_name);
> -
> -/**
> - * dpu_power_client_destroy() - destroy the client on power handle
> - * @pdata:  power handle containing the resources
> - * @client_name: new client name for registration
> - *
> - * Return: none
> - */
> -void dpu_power_client_destroy(struct dpu_power_handle *phandle,
> -	struct dpu_power_client *client);
> -
> -/**
> - * dpu_power_resource_enable() - enable/disable the power resources
> - * @pdata:  power handle containing the resources
> - * @client: client information to enable/disable its vote
> - * @enable: boolean request for enable/disable
> - *
> - * Return: error code.
> - */
> -int dpu_power_resource_enable(struct dpu_power_handle *pdata,
> -	struct dpu_power_client *pclient, bool enable);
> -
> -/**
> - * dpu_power_data_bus_state_update() - update data bus state
> - * @pdata:  power handle containing the resources
> - * @enable: take enable vs disable path
> - *
> - * Return: error code.
> - */
> -int dpu_power_data_bus_state_update(struct dpu_power_handle *phandle,
> -							bool enable);
> -
> -/**
> - * dpu_power_data_bus_set_quota() - set data bus quota for power client
> - * @phandle:  power handle containing the resources
> - * @client: client information to set quota
> - * @bus_client: real-time or non-real-time bus client
> - * @bus_id: identifier of data bus, see DPU_POWER_HANDLE_DBUS_ID
> - * @ab_quota: arbitrated bus bandwidth
> - * @ib_quota: instantaneous bus bandwidth
> - *
> - * Return: zero if success, or error code otherwise
> - */
> -int dpu_power_data_bus_set_quota(struct dpu_power_handle *phandle,
> -		struct dpu_power_client *pclient,
> -		int bus_client, u32 bus_id,
> -		u64 ab_quota, u64 ib_quota);
> -
> -/**
> - * dpu_power_data_bus_bandwidth_ctrl() - control data bus bandwidth enable
> - * @phandle:  power handle containing the resources
> - * @client: client information to bandwidth control
> - * @enable: true to enable bandwidth for data base
> - *
> - * Return: none
> - */
> -void dpu_power_data_bus_bandwidth_ctrl(struct dpu_power_handle *phandle,
> -		struct dpu_power_client *pclient, int enable);
> -
> -/**
> - * dpu_power_handle_register_event - register a callback function for an event.
> - *	Clients can register for multiple events with a single register.
> - *	Any block with access to phandle can register for the event
> - *	notification.
> - * @phandle:	power handle containing the resources
> - * @event_type:	event type to register; refer DPU_POWER_HANDLE_EVENT_*
> - * @cb_fnc:	pointer to desired callback function
> - * @usr:	user pointer to pass to callback on event trigger
> - *
> - * Return:	event pointer if success, or error code otherwise
> - */
> -struct dpu_power_event *dpu_power_handle_register_event(
> -		struct dpu_power_handle *phandle,
> -		u32 event_type, void (*cb_fnc)(u32 event_type, void *usr),
> -		void *usr, char *client_name);
> -/**
> - * dpu_power_handle_unregister_event - unregister callback for event(s)
> - * @phandle:	power handle containing the resources
> - * @event:	event pointer returned after power handle register
> - */
> -void dpu_power_handle_unregister_event(struct dpu_power_handle *phandle,
> -		struct dpu_power_event *event);
> -
> -/**
> - * dpu_power_handle_get_dbus_name - get name of given data bus identifier
> - * @bus_id:	data bus identifier
> - * Return:	Pointer to name string if success; NULL otherwise
> - */
> -const char *dpu_power_handle_get_dbus_name(u32 bus_id);
> -
> -#endif /* _DPU_POWER_HANDLE_H_ */
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index 5c267cd..60b6919 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -340,7 +340,6 @@ static int msm_drm_uninit(struct device *dev)
>  	component_unbind_all(dev, ddev);
>  
>  #ifdef CONFIG_DRM_MSM_DPU
> -	dpu_power_resource_deinit(pdev, &priv->phandle);
>  	dpu_dbg_destroy();
>  #endif
>  
> @@ -519,12 +518,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
>  	drm_mode_config_init(ddev);
>  
>  #ifdef CONFIG_DRM_MSM_DPU
> -	ret = dpu_power_resource_init(pdev, &priv->phandle);
> -	if (ret) {
> -		pr_err("dpu power resource init failed\n");
> -		goto power_init_fail;
> -	}
> -
>  	ret = dpu_dbg_init(&pdev->dev);
>  	if (ret) {
>  		dev_err(dev, "failed to init dpu dbg: %d\n", ret);
> @@ -733,8 +726,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
>  #ifdef CONFIG_DRM_MSM_DPU
>  	dpu_dbg_destroy();
>  dbg_init_fail:
> -	dpu_power_resource_deinit(pdev, &priv->phandle);
> -power_init_fail:
>  #endif
>  	if (mdss && mdss->funcs)
>  		mdss->funcs->destroy(ddev);
> diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
> index f9ae96f..27a73a8 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -46,8 +46,6 @@
>  #include <drm/msm_drm.h>
>  #include <drm/drm_gem.h>
>  
> -#include "dpu_power_handle.h"
> -
>  #define GET_MAJOR_REV(rev)		((rev) >> 28)
>  #define GET_MINOR_REV(rev)		(((rev) >> 16) & 0xFFF)
>  #define GET_STEP_REV(rev)		((rev) & 0xFFFF)
> @@ -375,8 +373,6 @@ struct msm_drm_private {
>  
>  	struct msm_kms *kms;
>  
> -	struct dpu_power_handle phandle;
> -
>  	/* subordinate devices, if present: */
>  	struct platform_device *gpu_pdev;
>  
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index d9826c1..f578d5a 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -82,10 +82,10 @@  msm-y := \
 	disp/dpu1/dpu_rm.o \
 	disp/dpu1/dpu_vbif.o \
 	disp/dpu1/dpu_mdss.o \
+	disp/dpu1/dpu_power_handle.o \
 	dpu_dbg.o \
 	dpu_io_util.o \
 	dpu_dbg_evtlog.o \
-	dpu_power_handle.o \
 	msm_prop.o \
 	msm_atomic.o \
 	msm_debugfs.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
index 5c5cc56..33ab2ac 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
@@ -18,7 +18,6 @@ 
 #include <linux/kthread.h>
 
 #include "dpu_core_irq.h"
-#include "dpu_power_handle.h"
 
 /**
  * dpu_core_irq_callback_handler - dispatch core interrupts
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
index 2cf3fca..d3a1ed9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -257,7 +257,6 @@  static void _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
 					= dpu_crtc_get_client_type(crtc);
 	struct drm_crtc *tmp_crtc;
 	struct dpu_crtc_state *dpu_cstate;
-	struct msm_drm_private *priv = kms->dev->dev_private;
 
 	drm_for_each_crtc(tmp_crtc, crtc->dev) {
 		if (_dpu_core_perf_crtc_is_power_on(tmp_crtc) &&
@@ -287,7 +286,7 @@  static void _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
 
 	switch (curr_client_type) {
 	case NRT_CLIENT:
-		dpu_power_data_bus_set_quota(&priv->phandle, kms->core_client,
+		dpu_power_data_bus_set_quota(&kms->phandle, kms->core_client,
 				DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT,
 				bus_id, bus_ab_quota, bus_ib_quota);
 		DPU_DEBUG("client:%s bus_id=%d ab=%llu ib=%llu\n", "nrt",
@@ -295,7 +294,7 @@  static void _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
 		break;
 
 	case RT_CLIENT:
-		dpu_power_data_bus_set_quota(&priv->phandle, kms->core_client,
+		dpu_power_data_bus_set_quota(&kms->phandle, kms->core_client,
 				DPU_POWER_HANDLE_DATA_BUS_CLIENT_RT,
 				bus_id, bus_ab_quota, bus_ib_quota);
 		DPU_DEBUG("client:%s bus_id=%d ab=%llu ib=%llu\n", "rt",
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index e2d2e32..99c5e75 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -598,6 +598,7 @@  static void dpu_crtc_destroy(struct drm_crtc *crtc)
 	_dpu_crtc_destroy_dest_scaler(dpu_crtc);
 
 	_dpu_crtc_deinit_events(dpu_crtc);
+	dpu_crtc->phandle = NULL;
 
 	drm_crtc_cleanup(crtc);
 	mutex_destroy(&dpu_crtc->crtc_lock);
@@ -2572,7 +2573,7 @@  static void dpu_crtc_disable(struct drm_crtc *crtc)
 	}
 
 	if (dpu_crtc->power_event)
-		dpu_power_handle_unregister_event(&priv->phandle,
+		dpu_power_handle_unregister_event(dpu_crtc->phandle,
 				dpu_crtc->power_event);
 
 
@@ -2643,7 +2644,7 @@  static void dpu_crtc_enable(struct drm_crtc *crtc,
 	mutex_unlock(&dpu_crtc->crtc_lock);
 
 	dpu_crtc->power_event = dpu_power_handle_register_event(
-		&priv->phandle,
+		dpu_crtc->phandle,
 		DPU_POWER_EVENT_POST_ENABLE | DPU_POWER_EVENT_POST_DISABLE |
 		DPU_POWER_EVENT_PRE_DISABLE,
 		dpu_crtc_handle_power_event, crtc, dpu_crtc->name);
@@ -3938,6 +3939,8 @@  struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane)
 	dpu_cp_crtc_init(crtc);
 	dpu_cp_crtc_install_properties(crtc);
 
+	dpu_crtc->phandle = &kms->phandle;
+
 	DPU_DEBUG("%s: successfully initialized crtc\n", dpu_crtc->name);
 	return crtc;
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 9304058..671d909 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -184,6 +184,7 @@  struct dpu_crtc_event {
  * @misr_enable   : boolean entry indicates misr enable/disable status.
  * @misr_frame_count  : misr frame count provided by client
  * @misr_data     : store misr data before turning off the clocks.
+ * @phandle: Pointer to power handler
  * @power_event   : registered power event handle
  * @cur_perf      : current performance committed to clock/bandwidth driver
  * @rp_lock       : serialization lock for resource pool
@@ -240,6 +241,7 @@  struct dpu_crtc {
 	u32 misr_frame_count;
 	u32 misr_data[CRTC_DUAL_MIXERS];
 
+	struct dpu_power_handle *phandle;
 	struct dpu_power_event *power_event;
 
 	struct dpu_core_perf_params cur_perf;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 298a6ef..11ae6cc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -31,7 +31,6 @@ 
 #include "dpu_hw_ctl.h"
 #include "dpu_formats.h"
 #include "dpu_encoder_phys.h"
-#include "dpu_power_handle.h"
 #include "dpu_crtc.h"
 #include "dpu_trace.h"
 #include "dpu_core_irq.h"
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 9c3b220..0598cfb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1017,24 +1017,19 @@  static long dpu_kms_round_pixclk(struct msm_kms *kms, unsigned long rate,
 static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
 {
 	struct drm_device *dev;
-	struct msm_drm_private *priv;
 	int i;
 
 	dev = dpu_kms->dev;
 	if (!dev)
 		return;
 
-	priv = dev->dev_private;
-	if (!priv)
-		return;
-
 	if (dpu_kms->hw_intr)
 		dpu_hw_intr_destroy(dpu_kms->hw_intr);
 	dpu_kms->hw_intr = NULL;
 
 	if (dpu_kms->power_event)
 		dpu_power_handle_unregister_event(
-				&priv->phandle, dpu_kms->power_event);
+				&dpu_kms->phandle, dpu_kms->power_event);
 
 	/* safe to call these more than once during shutdown */
 	_dpu_debugfs_destroy(dpu_kms);
@@ -1067,7 +1062,8 @@  static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
 	dpu_kms->catalog = NULL;
 
 	if (dpu_kms->core_client)
-		dpu_power_client_destroy(&priv->phandle, dpu_kms->core_client);
+		dpu_power_client_destroy(&dpu_kms->phandle,
+			dpu_kms->core_client);
 	dpu_kms->core_client = NULL;
 
 	if (dpu_kms->vbif[VBIF_NRT])
@@ -1624,7 +1620,8 @@  static int dpu_kms_hw_init(struct msm_kms *kms)
 	}
 #endif
 
-	dpu_kms->core_client = dpu_power_client_create(&priv->phandle, "core");
+	dpu_kms->core_client = dpu_power_client_create(&dpu_kms->phandle,
+					"core");
 	if (IS_ERR_OR_NULL(dpu_kms->core_client)) {
 		rc = PTR_ERR(dpu_kms->core_client);
 		if (!dpu_kms->core_client)
@@ -1721,7 +1718,8 @@  static int dpu_kms_hw_init(struct msm_kms *kms)
 #endif
 
 	rc = dpu_core_perf_init(&dpu_kms->perf, dev, dpu_kms->catalog,
-			&priv->phandle, _dpu_kms_get_clk(dpu_kms, "core_clk"));
+			&dpu_kms->phandle,
+			_dpu_kms_get_clk(dpu_kms, "core_clk"));
 	if (rc) {
 		DPU_ERROR("failed to init perf %d\n", rc);
 		goto perf_err;
@@ -1765,7 +1763,8 @@  static int dpu_kms_hw_init(struct msm_kms *kms)
 	 * Handle (re)initializations during power enable
 	 */
 	dpu_kms_handle_power_event(DPU_POWER_EVENT_POST_ENABLE, dpu_kms);
-	dpu_kms->power_event = dpu_power_handle_register_event(&priv->phandle,
+	dpu_kms->power_event = dpu_power_handle_register_event(
+			&dpu_kms->phandle,
 			DPU_POWER_EVENT_POST_ENABLE,
 			dpu_kms_handle_power_event, dpu_kms, "kms");
 
@@ -1841,6 +1840,12 @@  static int dpu_bind(struct device *dev, struct device *master, void *data)
 		goto clk_rate_error;
 	}
 
+	ret = dpu_power_resource_init(pdev, &dpu_kms->phandle);
+	if (ret) {
+		pr_err("dpu power resource init failed\n");
+		goto power_init_fail;
+	}
+
 	platform_set_drvdata(pdev, dpu_kms);
 
 	msm_kms_init(&dpu_kms->base, &kms_funcs);
@@ -1853,6 +1858,7 @@  static int dpu_bind(struct device *dev, struct device *master, void *data)
 	priv->kms = &dpu_kms->base;
 	return ret;
 
+power_init_fail:
 clk_rate_error:
 	msm_dss_put_clk(mp->clk_config, mp->num_clk);
 clk_get_error:
@@ -1867,6 +1873,7 @@  static void dpu_unbind(struct device *dev, struct device *master, void *data)
 	struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
 	struct dss_module_power *mp = &dpu_kms->mp;
 
+	dpu_power_resource_deinit(pdev, &dpu_kms->phandle);
 	msm_dss_put_clk(mp->clk_config, mp->num_clk);
 	devm_kfree(&pdev->dev, mp->clk_config);
 	mp->num_clk = 0;
@@ -1897,7 +1904,6 @@  static int dpu_runtime_suspend(struct device *dev)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
 	struct drm_device *ddev;
-	struct msm_drm_private *priv;
 	struct dss_module_power *mp = &dpu_kms->mp;
 
 	ddev = dpu_kms->dev;
@@ -1905,10 +1911,9 @@  static int dpu_runtime_suspend(struct device *dev)
 		DPU_ERROR("invalid drm_device\n");
 		goto exit;
 	}
-	priv = ddev->dev_private;
 
-	rc = dpu_power_resource_enable(&priv->phandle,
-		dpu_kms->core_client, false);
+	rc = dpu_power_resource_enable(&dpu_kms->phandle,
+			dpu_kms->core_client, false);
 	if (rc)
 		DPU_ERROR("resource disable failed: %d\n", rc);
 
@@ -1926,7 +1931,6 @@  static int dpu_runtime_resume(struct device *dev)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
 	struct drm_device *ddev;
-	struct msm_drm_private *priv;
 	struct dss_module_power *mp = &dpu_kms->mp;
 
 	ddev = dpu_kms->dev;
@@ -1934,7 +1938,6 @@  static int dpu_runtime_resume(struct device *dev)
 		DPU_ERROR("invalid drm_device\n");
 		goto exit;
 	}
-	priv = ddev->dev_private;
 
 	rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true);
 	if (rc) {
@@ -1942,8 +1945,8 @@  static int dpu_runtime_resume(struct device *dev)
 		goto exit;
 	}
 
-	rc = dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client,
-		true);
+	rc = dpu_power_resource_enable(&dpu_kms->phandle,
+			dpu_kms->core_client, true);
 	if (rc)
 		DPU_ERROR("resource enable failed: %d\n", rc);
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index a8255fe..c48ed4e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -164,6 +164,7 @@  struct dpu_kms {
 	struct dpu_mdss_cfg *catalog;
 
 	struct msm_gem_address_space *aspace[MSM_SMMU_DOMAIN_MAX];
+	struct dpu_power_handle phandle;
 	struct dpu_power_client *core_client;
 #ifdef CONFIG_ION
 	struct ion_client *iclient;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
new file mode 100644
index 0000000..77be106
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c
@@ -0,0 +1,693 @@ 
+/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#define pr_fmt(fmt)	"[drm:%s:%d]: " fmt, __func__, __LINE__
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/string.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/of_platform.h>
+#ifdef CONFIG_QCOM_BUS_SCALING
+#include <linux/msm-bus.h>
+#include <linux/msm-bus-board.h>
+#endif
+#include <linux/dpu_io_util.h>
+
+#include "dpu_power_handle.h"
+#include "dpu_trace.h"
+
+static const char *data_bus_name[DPU_POWER_HANDLE_DBUS_ID_MAX] = {
+	[DPU_POWER_HANDLE_DBUS_ID_MNOC] = "qcom,dpu-data-bus",
+	[DPU_POWER_HANDLE_DBUS_ID_LLCC] = "qcom,dpu-llcc-bus",
+	[DPU_POWER_HANDLE_DBUS_ID_EBI] = "qcom,dpu-ebi-bus",
+};
+
+const char *dpu_power_handle_get_dbus_name(u32 bus_id)
+{
+	if (bus_id < DPU_POWER_HANDLE_DBUS_ID_MAX)
+		return data_bus_name[bus_id];
+
+	return NULL;
+}
+
+static void dpu_power_event_trigger_locked(struct dpu_power_handle *phandle,
+		u32 event_type)
+{
+	struct dpu_power_event *event;
+
+	list_for_each_entry(event, &phandle->event_list, list) {
+		if (event->event_type & event_type)
+			event->cb_fnc(event_type, event->usr);
+	}
+}
+
+struct dpu_power_client *dpu_power_client_create(
+	struct dpu_power_handle *phandle, char *client_name)
+{
+	struct dpu_power_client *client;
+	static u32 id;
+
+	if (!client_name || !phandle) {
+		pr_err("client name is null or invalid power data\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	client = kzalloc(sizeof(struct dpu_power_client), GFP_KERNEL);
+	if (!client)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_lock(&phandle->phandle_lock);
+	strlcpy(client->name, client_name, MAX_CLIENT_NAME_LEN);
+	client->usecase_ndx = VOTE_INDEX_DISABLE;
+	client->id = id;
+	client->active = true;
+	pr_debug("client %s created:%pK id :%d\n", client_name,
+		client, id);
+	id++;
+	list_add(&client->list, &phandle->power_client_clist);
+	mutex_unlock(&phandle->phandle_lock);
+
+	return client;
+}
+
+void dpu_power_client_destroy(struct dpu_power_handle *phandle,
+	struct dpu_power_client *client)
+{
+	if (!client  || !phandle) {
+		pr_err("reg bus vote: invalid client handle\n");
+	} else if (!client->active) {
+		pr_err("dpu power deinit already done\n");
+		kfree(client);
+	} else {
+		pr_debug("bus vote client %s destroyed:%pK id:%u\n",
+			client->name, client, client->id);
+		mutex_lock(&phandle->phandle_lock);
+		list_del_init(&client->list);
+		mutex_unlock(&phandle->phandle_lock);
+		kfree(client);
+	}
+}
+
+#ifdef CONFIG_QCOM_BUS_SCALING
+
+#define MAX_AXI_PORT_COUNT 3
+
+static int _dpu_power_data_bus_set_quota(
+		struct dpu_power_data_bus_handle *pdbus,
+		u64 ab_quota_rt, u64 ab_quota_nrt,
+		u64 ib_quota_rt, u64 ib_quota_nrt)
+{
+	int new_uc_idx;
+	u64 ab_quota[MAX_AXI_PORT_COUNT] = {0, 0};
+	u64 ib_quota[MAX_AXI_PORT_COUNT] = {0, 0};
+	int rc;
+
+	if (pdbus->data_bus_hdl < 1) {
+		pr_err("invalid bus handle %d\n", pdbus->data_bus_hdl);
+		return -EINVAL;
+	}
+
+	pdbus->ab_rt = ab_quota_rt;
+	pdbus->ib_rt = ib_quota_rt;
+	pdbus->ab_nrt = ab_quota_nrt;
+	pdbus->ib_nrt = ib_quota_nrt;
+
+	if (pdbus->enable) {
+		ab_quota_rt = max_t(u64, ab_quota_rt,
+				DPU_POWER_HANDLE_ENABLE_BUS_AB_QUOTA);
+		ib_quota_rt = max_t(u64, ib_quota_rt,
+				DPU_POWER_HANDLE_ENABLE_BUS_IB_QUOTA);
+		ab_quota_nrt = max_t(u64, ab_quota_nrt,
+				DPU_POWER_HANDLE_ENABLE_BUS_AB_QUOTA);
+		ib_quota_nrt = max_t(u64, ib_quota_nrt,
+				DPU_POWER_HANDLE_ENABLE_BUS_IB_QUOTA);
+	} else {
+		ab_quota_rt = min_t(u64, ab_quota_rt,
+				DPU_POWER_HANDLE_DISABLE_BUS_AB_QUOTA);
+		ib_quota_rt = min_t(u64, ib_quota_rt,
+				DPU_POWER_HANDLE_DISABLE_BUS_IB_QUOTA);
+		ab_quota_nrt = min_t(u64, ab_quota_nrt,
+				DPU_POWER_HANDLE_DISABLE_BUS_AB_QUOTA);
+		ib_quota_nrt = min_t(u64, ib_quota_nrt,
+				DPU_POWER_HANDLE_DISABLE_BUS_IB_QUOTA);
+	}
+
+	if (!ab_quota_rt && !ab_quota_nrt && !ib_quota_rt && !ib_quota_nrt)  {
+		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 nrt_axi_port_cnt = pdbus->nrt_axi_port_cnt;
+		u32 total_axi_port_cnt = pdbus->axi_port_cnt;
+		u32 rt_axi_port_cnt = total_axi_port_cnt - nrt_axi_port_cnt;
+
+		if (!bw_table || !total_axi_port_cnt ||
+		    total_axi_port_cnt > MAX_AXI_PORT_COUNT) {
+			pr_err("invalid input\n");
+			return -EINVAL;
+		}
+
+		if (pdbus->bus_channels) {
+			ib_quota_rt = div_u64(ib_quota_rt,
+						pdbus->bus_channels);
+			ib_quota_nrt = div_u64(ib_quota_nrt,
+						pdbus->bus_channels);
+		}
+
+		if (nrt_axi_port_cnt) {
+
+			ab_quota_rt = div_u64(ab_quota_rt, rt_axi_port_cnt);
+			ab_quota_nrt = div_u64(ab_quota_nrt, nrt_axi_port_cnt);
+
+			for (i = 0; i < total_axi_port_cnt; i++) {
+				if (i < rt_axi_port_cnt) {
+					ab_quota[i] = ab_quota_rt;
+					ib_quota[i] = ib_quota_rt;
+				} else {
+					ab_quota[i] = ab_quota_nrt;
+					ib_quota[i] = ib_quota_nrt;
+				}
+			}
+		} else {
+			ab_quota[0] = div_u64(ab_quota_rt + ab_quota_nrt,
+					total_axi_port_cnt);
+			ib_quota[0] = ib_quota_rt + ib_quota_nrt;
+
+			for (i = 1; i < total_axi_port_cnt; i++) {
+				ab_quota[i] = ab_quota[0];
+				ib_quota[i] = ib_quota[0];
+			}
+		}
+
+		new_uc_idx = (pdbus->curr_bw_uc_idx %
+			(bw_table->num_usecases - 1)) + 1;
+
+		for (i = 0; i < total_axi_port_cnt; i++) {
+			vect = &bw_table->usecase[new_uc_idx].vectors[i];
+			vect->ab = ab_quota[i];
+			vect->ib = ib_quota[i];
+
+			pr_debug(
+				"%s uc_idx=%d %s path idx=%d ab=%llu ib=%llu\n",
+				bw_table->name,
+				new_uc_idx, (i < rt_axi_port_cnt) ? "rt" : "nrt"
+				, i, vect->ab, vect->ib);
+		}
+	}
+	pdbus->curr_bw_uc_idx = new_uc_idx;
+	pdbus->ao_bw_uc_idx = new_uc_idx;
+
+	DPU_ATRACE_BEGIN("msm_bus_scale_req");
+	rc = msm_bus_scale_client_update_request(pdbus->data_bus_hdl,
+			new_uc_idx);
+	DPU_ATRACE_END("msm_bus_scale_req");
+
+	return rc;
+}
+
+int dpu_power_data_bus_set_quota(struct dpu_power_handle *phandle,
+		struct dpu_power_client *pclient,
+		int bus_client, u32 bus_id,
+		u64 ab_quota, u64 ib_quota)
+{
+	int rc = 0;
+	int i;
+	u64 total_ab_rt = 0, total_ib_rt = 0;
+	u64 total_ab_nrt = 0, total_ib_nrt = 0;
+	struct dpu_power_client *client;
+
+	if (!phandle || !pclient ||
+			bus_client >= DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX ||
+			bus_id >= DPU_POWER_HANDLE_DBUS_ID_MAX) {
+		pr_err("invalid parameters\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&phandle->phandle_lock);
+
+	pclient->ab[bus_client] = ab_quota;
+	pclient->ib[bus_client] = ib_quota;
+	trace_dpu_perf_update_bus(bus_client, ab_quota, ib_quota);
+
+	list_for_each_entry(client, &phandle->power_client_clist, list) {
+		for (i = 0; i < DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX; i++) {
+			if (i == DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT) {
+				total_ab_nrt += client->ab[i];
+				total_ib_nrt += client->ib[i];
+			} else {
+				total_ab_rt += client->ab[i];
+				total_ib_rt = max(total_ib_rt, client->ib[i]);
+			}
+		}
+	}
+
+	if (phandle->data_bus_handle[bus_id].data_bus_hdl)
+		rc = _dpu_power_data_bus_set_quota(
+			&phandle->data_bus_handle[bus_id],
+			total_ab_rt, total_ab_nrt,
+			total_ib_rt, total_ib_nrt);
+
+	mutex_unlock(&phandle->phandle_lock);
+
+	return rc;
+}
+
+static void dpu_power_data_bus_unregister(
+		struct dpu_power_data_bus_handle *pdbus)
+{
+	if (pdbus->data_bus_hdl) {
+		msm_bus_scale_unregister_client(pdbus->data_bus_hdl);
+		pdbus->data_bus_hdl = 0;
+	}
+}
+
+static int dpu_power_data_bus_parse(struct platform_device *pdev,
+	struct dpu_power_data_bus_handle *pdbus, const char *name)
+{
+	struct device_node *node;
+	int rc = 0;
+	int paths;
+
+	pdbus->bus_channels = 1;
+	rc = of_property_read_u32(pdev->dev.of_node,
+		"qcom,dpu-dram-channels", &pdbus->bus_channels);
+	if (rc) {
+		pr_debug("number of channels property not specified\n");
+		rc = 0;
+	}
+
+	pdbus->nrt_axi_port_cnt = 0;
+	rc = of_property_read_u32(pdev->dev.of_node,
+			"qcom,dpu-num-nrt-paths",
+			&pdbus->nrt_axi_port_cnt);
+	if (rc) {
+		pr_debug("number of axi port property not specified\n");
+		rc = 0;
+	}
+
+	node = of_get_child_by_name(pdev->dev.of_node, name);
+	if (node) {
+		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;
+		}
+		pdbus->axi_port_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;
+		}
+		pr_debug("register %s data_bus_hdl=%x\n", name,
+				pdbus->data_bus_hdl);
+	}
+
+end:
+	return rc;
+}
+
+static int dpu_power_reg_bus_parse(struct platform_device *pdev,
+	struct dpu_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,dpu-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);
+	}
+
+end:
+	return rc;
+}
+
+static void dpu_power_reg_bus_unregister(u32 reg_bus_hdl)
+{
+	if (reg_bus_hdl)
+		msm_bus_scale_unregister_client(reg_bus_hdl);
+}
+
+int dpu_power_data_bus_state_update(struct dpu_power_handle *phandle,
+							bool enable)
+{
+	int i;
+
+	if (!phandle) {
+		pr_err("invalid param\n");
+		return -EINVAL;
+	}
+
+	for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC;
+			i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
+		phandle->data_bus_handle[i].enable = enable;
+
+	return 0;
+}
+
+static int dpu_power_data_bus_update(struct dpu_power_data_bus_handle *pdbus,
+							bool enable)
+{
+	int rc = 0;
+
+	pdbus->enable = enable;
+
+	if (pdbus->data_bus_hdl)
+		rc = _dpu_power_data_bus_set_quota(pdbus, pdbus->ab_rt,
+				pdbus->ab_nrt, pdbus->ib_rt, pdbus->ib_nrt);
+
+	if (rc)
+		pr_err("failed to set data bus vote rc=%d enable:%d\n",
+							rc, enable);
+
+	return rc;
+}
+
+static int dpu_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
+{
+	int rc = 0;
+
+	if (reg_bus_hdl)
+		rc = msm_bus_scale_client_update_request(reg_bus_hdl,
+								usecase_ndx);
+	if (rc)
+		pr_err("failed to set reg bus vote rc=%d\n", rc);
+
+	return rc;
+}
+#else
+static int dpu_power_data_bus_parse(struct platform_device *pdev,
+		struct dpu_power_data_bus_handle *pdbus, const char *name)
+{
+	return 0;
+}
+
+static void dpu_power_data_bus_unregister(
+		struct dpu_power_data_bus_handle *pdbus)
+{
+}
+
+int dpu_power_data_bus_set_quota(struct dpu_power_handle *phandle,
+		struct dpu_power_client *pclient,
+		int bus_client, u32 bus_id,
+		u64 ab_quota, u64 ib_quota)
+{
+	return 0;
+}
+
+static int dpu_power_reg_bus_parse(struct platform_device *pdev,
+	struct dpu_power_handle *phandle)
+{
+	return 0;
+}
+
+static void dpu_power_reg_bus_unregister(u32 reg_bus_hdl)
+{
+}
+
+static int dpu_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
+{
+	return 0;
+}
+
+static int dpu_power_data_bus_update(struct dpu_power_data_bus_handle *pdbus,
+							bool enable)
+{
+	return 0;
+}
+
+int dpu_power_data_bus_state_update(struct dpu_power_handle *phandle,
+							bool enable)
+{
+	return 0;
+}
+#endif
+
+int dpu_power_resource_init(struct platform_device *pdev,
+	struct dpu_power_handle *phandle)
+{
+	int rc = 0, i;
+
+	if (!phandle || !pdev) {
+		pr_err("invalid input param\n");
+		return -EINVAL;
+	}
+
+	phandle->dev = &pdev->dev;
+
+	rc = dpu_power_reg_bus_parse(pdev, phandle);
+	if (rc) {
+		pr_err("register bus parse failed rc=%d\n", rc);
+		return rc;
+	}
+
+	for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC;
+			i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
+		rc = dpu_power_data_bus_parse(pdev,
+				&phandle->data_bus_handle[i],
+				data_bus_name[i]);
+		if (rc) {
+			pr_err("register data bus parse failed id=%d rc=%d\n",
+					i, rc);
+			goto data_bus_err;
+		}
+	}
+
+	INIT_LIST_HEAD(&phandle->power_client_clist);
+	INIT_LIST_HEAD(&phandle->event_list);
+
+	mutex_init(&phandle->phandle_lock);
+
+	return rc;
+
+data_bus_err:
+	for (i--; i >= 0; i--)
+		dpu_power_data_bus_unregister(&phandle->data_bus_handle[i]);
+	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
+	return rc;
+}
+
+void dpu_power_resource_deinit(struct platform_device *pdev,
+	struct dpu_power_handle *phandle)
+{
+	struct dpu_power_client *curr_client, *next_client;
+	struct dpu_power_event *curr_event, *next_event;
+	int i;
+
+	if (!phandle || !pdev) {
+		pr_err("invalid input param\n");
+		return;
+	}
+
+	mutex_lock(&phandle->phandle_lock);
+	list_for_each_entry_safe(curr_client, next_client,
+			&phandle->power_client_clist, list) {
+		pr_err("cliend:%s-%d still registered with refcount:%d\n",
+				curr_client->name, curr_client->id,
+				curr_client->refcount);
+		curr_client->active = false;
+		list_del(&curr_client->list);
+	}
+
+	list_for_each_entry_safe(curr_event, next_event,
+			&phandle->event_list, list) {
+		pr_err("event:%d, client:%s still registered\n",
+				curr_event->event_type,
+				curr_event->client_name);
+		curr_event->active = false;
+		list_del(&curr_event->list);
+	}
+	mutex_unlock(&phandle->phandle_lock);
+
+	for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
+		dpu_power_data_bus_unregister(&phandle->data_bus_handle[i]);
+
+	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
+}
+
+int dpu_power_resource_enable(struct dpu_power_handle *phandle,
+	struct dpu_power_client *pclient, bool enable)
+{
+	int rc = 0, i;
+	bool changed = false;
+	u32 max_usecase_ndx = VOTE_INDEX_DISABLE, prev_usecase_ndx;
+	struct dpu_power_client *client;
+
+	if (!phandle || !pclient) {
+		pr_err("invalid input argument\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&phandle->phandle_lock);
+	if (enable)
+		pclient->refcount++;
+	else if (pclient->refcount)
+		pclient->refcount--;
+
+	if (pclient->refcount)
+		pclient->usecase_ndx = VOTE_INDEX_LOW;
+	else
+		pclient->usecase_ndx = VOTE_INDEX_DISABLE;
+
+	list_for_each_entry(client, &phandle->power_client_clist, list) {
+		if (client->usecase_ndx < VOTE_INDEX_MAX &&
+		    client->usecase_ndx > max_usecase_ndx)
+			max_usecase_ndx = client->usecase_ndx;
+	}
+
+	if (phandle->current_usecase_ndx != max_usecase_ndx) {
+		changed = true;
+		prev_usecase_ndx = phandle->current_usecase_ndx;
+		phandle->current_usecase_ndx = max_usecase_ndx;
+	}
+
+	pr_debug("%pS: changed=%d current idx=%d request client %s id:%u enable:%d refcount:%d\n",
+		__builtin_return_address(0), changed, max_usecase_ndx,
+		pclient->name, pclient->id, enable, pclient->refcount);
+
+	if (!changed)
+		goto end;
+
+	if (enable) {
+		dpu_power_event_trigger_locked(phandle,
+				DPU_POWER_EVENT_PRE_ENABLE);
+
+		for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
+			rc = dpu_power_data_bus_update(
+					&phandle->data_bus_handle[i], enable);
+			if (rc) {
+				pr_err("failed to set data bus vote id=%d rc=%d\n",
+						i, rc);
+				goto data_bus_hdl_err;
+			}
+		}
+
+		rc = dpu_power_reg_bus_update(phandle->reg_bus_hdl,
+							max_usecase_ndx);
+		if (rc) {
+			pr_err("failed to set reg bus vote rc=%d\n", rc);
+			goto reg_bus_hdl_err;
+		}
+
+		dpu_power_event_trigger_locked(phandle,
+				DPU_POWER_EVENT_POST_ENABLE);
+
+	} else {
+		dpu_power_event_trigger_locked(phandle,
+				DPU_POWER_EVENT_PRE_DISABLE);
+
+		dpu_power_reg_bus_update(phandle->reg_bus_hdl,
+							max_usecase_ndx);
+
+		for (i = 0 ; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
+			dpu_power_data_bus_update(&phandle->data_bus_handle[i],
+					enable);
+
+		dpu_power_event_trigger_locked(phandle,
+				DPU_POWER_EVENT_POST_DISABLE);
+	}
+
+end:
+	mutex_unlock(&phandle->phandle_lock);
+	return rc;
+
+reg_bus_hdl_err:
+	for (i = 0 ; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
+		dpu_power_data_bus_update(&phandle->data_bus_handle[i], 0);
+data_bus_hdl_err:
+	phandle->current_usecase_ndx = prev_usecase_ndx;
+	mutex_unlock(&phandle->phandle_lock);
+	return rc;
+}
+
+struct dpu_power_event *dpu_power_handle_register_event(
+		struct dpu_power_handle *phandle,
+		u32 event_type, void (*cb_fnc)(u32 event_type, void *usr),
+		void *usr, char *client_name)
+{
+	struct dpu_power_event *event;
+
+	if (!phandle) {
+		pr_err("invalid power handle\n");
+		return ERR_PTR(-EINVAL);
+	} else if (!cb_fnc || !event_type) {
+		pr_err("no callback fnc or event type\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	event = kzalloc(sizeof(struct dpu_power_event), GFP_KERNEL);
+	if (!event)
+		return ERR_PTR(-ENOMEM);
+
+	event->event_type = event_type;
+	event->cb_fnc = cb_fnc;
+	event->usr = usr;
+	strlcpy(event->client_name, client_name, MAX_CLIENT_NAME_LEN);
+	event->active = true;
+
+	mutex_lock(&phandle->phandle_lock);
+	list_add(&event->list, &phandle->event_list);
+	mutex_unlock(&phandle->phandle_lock);
+
+	return event;
+}
+
+void dpu_power_handle_unregister_event(
+		struct dpu_power_handle *phandle,
+		struct dpu_power_event *event)
+{
+	if (!phandle || !event) {
+		pr_err("invalid phandle or event\n");
+	} else if (!event->active) {
+		pr_err("power handle deinit already done\n");
+		kfree(event);
+	} else {
+		mutex_lock(&phandle->phandle_lock);
+		list_del_init(&event->list);
+		mutex_unlock(&phandle->phandle_lock);
+		kfree(event);
+	}
+}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h
new file mode 100644
index 0000000..9a6d4b9
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h
@@ -0,0 +1,288 @@ 
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _DPU_POWER_HANDLE_H_
+#define _DPU_POWER_HANDLE_H_
+
+#define MAX_CLIENT_NAME_LEN 128
+
+#define DPU_POWER_HANDLE_ENABLE_BUS_AB_QUOTA	0
+#define DPU_POWER_HANDLE_DISABLE_BUS_AB_QUOTA	0
+#define DPU_POWER_HANDLE_ENABLE_BUS_IB_QUOTA	1600000000
+#define DPU_POWER_HANDLE_DISABLE_BUS_IB_QUOTA	0
+
+#include <linux/dpu_io_util.h>
+
+/* event will be triggered before power handler disable */
+#define DPU_POWER_EVENT_PRE_DISABLE	0x1
+
+/* event will be triggered after power handler disable */
+#define DPU_POWER_EVENT_POST_DISABLE	0x2
+
+/* event will be triggered before power handler enable */
+#define DPU_POWER_EVENT_PRE_ENABLE	0x4
+
+/* event will be triggered after power handler enable */
+#define DPU_POWER_EVENT_POST_ENABLE	0x8
+
+/**
+ * mdss_bus_vote_type: register bus vote type
+ * VOTE_INDEX_DISABLE: removes the client vote
+ * VOTE_INDEX_LOW: keeps the lowest vote for register bus
+ * VOTE_INDEX_MAX: invalid
+ */
+enum mdss_bus_vote_type {
+	VOTE_INDEX_DISABLE,
+	VOTE_INDEX_LOW,
+	VOTE_INDEX_MAX,
+};
+
+/**
+ * enum dpu_power_handle_data_bus_client - type of axi bus clients
+ * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_RT: core real-time bus client
+ * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT: core non-real-time bus client
+ * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX: maximum number of bus client type
+ */
+enum dpu_power_handle_data_bus_client {
+	DPU_POWER_HANDLE_DATA_BUS_CLIENT_RT,
+	DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT,
+	DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX
+};
+
+/**
+ * enum DPU_POWER_HANDLE_DBUS_ID - data bus identifier
+ * @DPU_POWER_HANDLE_DBUS_ID_MNOC: DPU/MNOC data bus
+ * @DPU_POWER_HANDLE_DBUS_ID_LLCC: MNOC/LLCC data bus
+ * @DPU_POWER_HANDLE_DBUS_ID_EBI: LLCC/EBI data bus
+ */
+enum DPU_POWER_HANDLE_DBUS_ID {
+	DPU_POWER_HANDLE_DBUS_ID_MNOC,
+	DPU_POWER_HANDLE_DBUS_ID_LLCC,
+	DPU_POWER_HANDLE_DBUS_ID_EBI,
+	DPU_POWER_HANDLE_DBUS_ID_MAX,
+};
+
+/**
+ * struct dpu_power_client: stores the power client for dpu driver
+ * @name:	name of the client
+ * @usecase_ndx: current regs bus vote type
+ * @refcount:	current refcount if multiple modules are using same
+ *              same client for enable/disable. Power module will
+ *              aggregate the refcount and vote accordingly for this
+ *              client.
+ * @id:		assigned during create. helps for debugging.
+ * @list:	list to attach power handle master list
+ * @ab:         arbitrated bandwidth for each bus client
+ * @ib:         instantaneous bandwidth for each bus client
+ * @active:	inidcates the state of dpu power handle
+ */
+struct dpu_power_client {
+	char name[MAX_CLIENT_NAME_LEN];
+	short usecase_ndx;
+	short refcount;
+	u32 id;
+	struct list_head list;
+	u64 ab[DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX];
+	u64 ib[DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX];
+	bool active;
+};
+
+/**
+ * struct dpu_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
+ * @axi_port_cnt: number of rt axi ports
+ * @nrt_axi_port_cnt: number of nrt axi ports
+ * @bus_channels: number of memory bus channels
+ * @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 dpu_power_data_bus_handle {
+	struct msm_bus_scale_pdata *data_bus_scale_table;
+	u32 data_bus_hdl;
+	u32 axi_port_cnt;
+	u32 nrt_axi_port_cnt;
+	u32 bus_channels;
+	u32 curr_bw_uc_idx;
+	u32 ao_bw_uc_idx;
+	u64 ab_rt;
+	u64 ib_rt;
+	u64 ab_nrt;
+	u64 ib_nrt;
+	bool enable;
+};
+
+/*
+ * struct dpu_power_event - local event registration structure
+ * @client_name: name of the client registering
+ * @cb_fnc: pointer to desired callback function
+ * @usr: user pointer to pass to callback event trigger
+ * @event: refer to DPU_POWER_HANDLE_EVENT_*
+ * @list: list to attach event master list
+ * @active: indicates the state of dpu power handle
+ */
+struct dpu_power_event {
+	char client_name[MAX_CLIENT_NAME_LEN];
+	void (*cb_fnc)(u32 event_type, void *usr);
+	void *usr;
+	u32 event_type;
+	struct list_head list;
+	bool active;
+};
+
+/**
+ * struct dpu_power_handle: power handle main struct
+ * @client_clist: master list to store all clients
+ * @phandle_lock: lock to synchronize the enable/disable
+ * @dev: pointer to device structure
+ * @usecase_ndx: current usecase index
+ * @reg_bus_hdl: current register bus handle
+ * @data_bus_handle: context structure for data bus control
+ * @event_list: current power handle event list
+ */
+struct dpu_power_handle {
+	struct list_head power_client_clist;
+	struct mutex phandle_lock;
+	struct device *dev;
+	u32 current_usecase_ndx;
+	u32 reg_bus_hdl;
+	struct dpu_power_data_bus_handle data_bus_handle
+		[DPU_POWER_HANDLE_DBUS_ID_MAX];
+	struct list_head event_list;
+};
+
+/**
+ * dpu_power_resource_init() - initializes the dpu power handle
+ * @pdev:   platform device to search the power resources
+ * @pdata:  power handle to store the power resources
+ *
+ * Return: error code.
+ */
+int dpu_power_resource_init(struct platform_device *pdev,
+	struct dpu_power_handle *pdata);
+
+/**
+ * dpu_power_resource_deinit() - release the dpu power handle
+ * @pdev:   platform device for power resources
+ * @pdata:  power handle containing the resources
+ *
+ * Return: error code.
+ */
+void dpu_power_resource_deinit(struct platform_device *pdev,
+	struct dpu_power_handle *pdata);
+
+/**
+ * dpu_power_client_create() - create the client on power handle
+ * @pdata:  power handle containing the resources
+ * @client_name: new client name for registration
+ *
+ * Return: error code.
+ */
+struct dpu_power_client *dpu_power_client_create(struct dpu_power_handle *pdata,
+	char *client_name);
+
+/**
+ * dpu_power_client_destroy() - destroy the client on power handle
+ * @pdata:  power handle containing the resources
+ * @client_name: new client name for registration
+ *
+ * Return: none
+ */
+void dpu_power_client_destroy(struct dpu_power_handle *phandle,
+	struct dpu_power_client *client);
+
+/**
+ * dpu_power_resource_enable() - enable/disable the power resources
+ * @pdata:  power handle containing the resources
+ * @client: client information to enable/disable its vote
+ * @enable: boolean request for enable/disable
+ *
+ * Return: error code.
+ */
+int dpu_power_resource_enable(struct dpu_power_handle *pdata,
+	struct dpu_power_client *pclient, bool enable);
+
+/**
+ * dpu_power_data_bus_state_update() - update data bus state
+ * @pdata:  power handle containing the resources
+ * @enable: take enable vs disable path
+ *
+ * Return: error code.
+ */
+int dpu_power_data_bus_state_update(struct dpu_power_handle *phandle,
+							bool enable);
+
+/**
+ * dpu_power_data_bus_set_quota() - set data bus quota for power client
+ * @phandle:  power handle containing the resources
+ * @client: client information to set quota
+ * @bus_client: real-time or non-real-time bus client
+ * @bus_id: identifier of data bus, see DPU_POWER_HANDLE_DBUS_ID
+ * @ab_quota: arbitrated bus bandwidth
+ * @ib_quota: instantaneous bus bandwidth
+ *
+ * Return: zero if success, or error code otherwise
+ */
+int dpu_power_data_bus_set_quota(struct dpu_power_handle *phandle,
+		struct dpu_power_client *pclient,
+		int bus_client, u32 bus_id,
+		u64 ab_quota, u64 ib_quota);
+
+/**
+ * dpu_power_data_bus_bandwidth_ctrl() - control data bus bandwidth enable
+ * @phandle:  power handle containing the resources
+ * @client: client information to bandwidth control
+ * @enable: true to enable bandwidth for data base
+ *
+ * Return: none
+ */
+void dpu_power_data_bus_bandwidth_ctrl(struct dpu_power_handle *phandle,
+		struct dpu_power_client *pclient, int enable);
+
+/**
+ * dpu_power_handle_register_event - register a callback function for an event.
+ *	Clients can register for multiple events with a single register.
+ *	Any block with access to phandle can register for the event
+ *	notification.
+ * @phandle:	power handle containing the resources
+ * @event_type:	event type to register; refer DPU_POWER_HANDLE_EVENT_*
+ * @cb_fnc:	pointer to desired callback function
+ * @usr:	user pointer to pass to callback on event trigger
+ *
+ * Return:	event pointer if success, or error code otherwise
+ */
+struct dpu_power_event *dpu_power_handle_register_event(
+		struct dpu_power_handle *phandle,
+		u32 event_type, void (*cb_fnc)(u32 event_type, void *usr),
+		void *usr, char *client_name);
+/**
+ * dpu_power_handle_unregister_event - unregister callback for event(s)
+ * @phandle:	power handle containing the resources
+ * @event:	event pointer returned after power handle register
+ */
+void dpu_power_handle_unregister_event(struct dpu_power_handle *phandle,
+		struct dpu_power_event *event);
+
+/**
+ * dpu_power_handle_get_dbus_name - get name of given data bus identifier
+ * @bus_id:	data bus identifier
+ * Return:	Pointer to name string if success; NULL otherwise
+ */
+const char *dpu_power_handle_get_dbus_name(u32 bus_id);
+
+#endif /* _DPU_POWER_HANDLE_H_ */
diff --git a/drivers/gpu/drm/msm/dpu_power_handle.c b/drivers/gpu/drm/msm/dpu_power_handle.c
deleted file mode 100644
index 77be106..0000000
--- a/drivers/gpu/drm/msm/dpu_power_handle.c
+++ /dev/null
@@ -1,693 +0,0 @@ 
-/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#define pr_fmt(fmt)	"[drm:%s:%d]: " fmt, __func__, __LINE__
-
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/string.h>
-#include <linux/of_address.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/of_platform.h>
-#ifdef CONFIG_QCOM_BUS_SCALING
-#include <linux/msm-bus.h>
-#include <linux/msm-bus-board.h>
-#endif
-#include <linux/dpu_io_util.h>
-
-#include "dpu_power_handle.h"
-#include "dpu_trace.h"
-
-static const char *data_bus_name[DPU_POWER_HANDLE_DBUS_ID_MAX] = {
-	[DPU_POWER_HANDLE_DBUS_ID_MNOC] = "qcom,dpu-data-bus",
-	[DPU_POWER_HANDLE_DBUS_ID_LLCC] = "qcom,dpu-llcc-bus",
-	[DPU_POWER_HANDLE_DBUS_ID_EBI] = "qcom,dpu-ebi-bus",
-};
-
-const char *dpu_power_handle_get_dbus_name(u32 bus_id)
-{
-	if (bus_id < DPU_POWER_HANDLE_DBUS_ID_MAX)
-		return data_bus_name[bus_id];
-
-	return NULL;
-}
-
-static void dpu_power_event_trigger_locked(struct dpu_power_handle *phandle,
-		u32 event_type)
-{
-	struct dpu_power_event *event;
-
-	list_for_each_entry(event, &phandle->event_list, list) {
-		if (event->event_type & event_type)
-			event->cb_fnc(event_type, event->usr);
-	}
-}
-
-struct dpu_power_client *dpu_power_client_create(
-	struct dpu_power_handle *phandle, char *client_name)
-{
-	struct dpu_power_client *client;
-	static u32 id;
-
-	if (!client_name || !phandle) {
-		pr_err("client name is null or invalid power data\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	client = kzalloc(sizeof(struct dpu_power_client), GFP_KERNEL);
-	if (!client)
-		return ERR_PTR(-ENOMEM);
-
-	mutex_lock(&phandle->phandle_lock);
-	strlcpy(client->name, client_name, MAX_CLIENT_NAME_LEN);
-	client->usecase_ndx = VOTE_INDEX_DISABLE;
-	client->id = id;
-	client->active = true;
-	pr_debug("client %s created:%pK id :%d\n", client_name,
-		client, id);
-	id++;
-	list_add(&client->list, &phandle->power_client_clist);
-	mutex_unlock(&phandle->phandle_lock);
-
-	return client;
-}
-
-void dpu_power_client_destroy(struct dpu_power_handle *phandle,
-	struct dpu_power_client *client)
-{
-	if (!client  || !phandle) {
-		pr_err("reg bus vote: invalid client handle\n");
-	} else if (!client->active) {
-		pr_err("dpu power deinit already done\n");
-		kfree(client);
-	} else {
-		pr_debug("bus vote client %s destroyed:%pK id:%u\n",
-			client->name, client, client->id);
-		mutex_lock(&phandle->phandle_lock);
-		list_del_init(&client->list);
-		mutex_unlock(&phandle->phandle_lock);
-		kfree(client);
-	}
-}
-
-#ifdef CONFIG_QCOM_BUS_SCALING
-
-#define MAX_AXI_PORT_COUNT 3
-
-static int _dpu_power_data_bus_set_quota(
-		struct dpu_power_data_bus_handle *pdbus,
-		u64 ab_quota_rt, u64 ab_quota_nrt,
-		u64 ib_quota_rt, u64 ib_quota_nrt)
-{
-	int new_uc_idx;
-	u64 ab_quota[MAX_AXI_PORT_COUNT] = {0, 0};
-	u64 ib_quota[MAX_AXI_PORT_COUNT] = {0, 0};
-	int rc;
-
-	if (pdbus->data_bus_hdl < 1) {
-		pr_err("invalid bus handle %d\n", pdbus->data_bus_hdl);
-		return -EINVAL;
-	}
-
-	pdbus->ab_rt = ab_quota_rt;
-	pdbus->ib_rt = ib_quota_rt;
-	pdbus->ab_nrt = ab_quota_nrt;
-	pdbus->ib_nrt = ib_quota_nrt;
-
-	if (pdbus->enable) {
-		ab_quota_rt = max_t(u64, ab_quota_rt,
-				DPU_POWER_HANDLE_ENABLE_BUS_AB_QUOTA);
-		ib_quota_rt = max_t(u64, ib_quota_rt,
-				DPU_POWER_HANDLE_ENABLE_BUS_IB_QUOTA);
-		ab_quota_nrt = max_t(u64, ab_quota_nrt,
-				DPU_POWER_HANDLE_ENABLE_BUS_AB_QUOTA);
-		ib_quota_nrt = max_t(u64, ib_quota_nrt,
-				DPU_POWER_HANDLE_ENABLE_BUS_IB_QUOTA);
-	} else {
-		ab_quota_rt = min_t(u64, ab_quota_rt,
-				DPU_POWER_HANDLE_DISABLE_BUS_AB_QUOTA);
-		ib_quota_rt = min_t(u64, ib_quota_rt,
-				DPU_POWER_HANDLE_DISABLE_BUS_IB_QUOTA);
-		ab_quota_nrt = min_t(u64, ab_quota_nrt,
-				DPU_POWER_HANDLE_DISABLE_BUS_AB_QUOTA);
-		ib_quota_nrt = min_t(u64, ib_quota_nrt,
-				DPU_POWER_HANDLE_DISABLE_BUS_IB_QUOTA);
-	}
-
-	if (!ab_quota_rt && !ab_quota_nrt && !ib_quota_rt && !ib_quota_nrt)  {
-		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 nrt_axi_port_cnt = pdbus->nrt_axi_port_cnt;
-		u32 total_axi_port_cnt = pdbus->axi_port_cnt;
-		u32 rt_axi_port_cnt = total_axi_port_cnt - nrt_axi_port_cnt;
-
-		if (!bw_table || !total_axi_port_cnt ||
-		    total_axi_port_cnt > MAX_AXI_PORT_COUNT) {
-			pr_err("invalid input\n");
-			return -EINVAL;
-		}
-
-		if (pdbus->bus_channels) {
-			ib_quota_rt = div_u64(ib_quota_rt,
-						pdbus->bus_channels);
-			ib_quota_nrt = div_u64(ib_quota_nrt,
-						pdbus->bus_channels);
-		}
-
-		if (nrt_axi_port_cnt) {
-
-			ab_quota_rt = div_u64(ab_quota_rt, rt_axi_port_cnt);
-			ab_quota_nrt = div_u64(ab_quota_nrt, nrt_axi_port_cnt);
-
-			for (i = 0; i < total_axi_port_cnt; i++) {
-				if (i < rt_axi_port_cnt) {
-					ab_quota[i] = ab_quota_rt;
-					ib_quota[i] = ib_quota_rt;
-				} else {
-					ab_quota[i] = ab_quota_nrt;
-					ib_quota[i] = ib_quota_nrt;
-				}
-			}
-		} else {
-			ab_quota[0] = div_u64(ab_quota_rt + ab_quota_nrt,
-					total_axi_port_cnt);
-			ib_quota[0] = ib_quota_rt + ib_quota_nrt;
-
-			for (i = 1; i < total_axi_port_cnt; i++) {
-				ab_quota[i] = ab_quota[0];
-				ib_quota[i] = ib_quota[0];
-			}
-		}
-
-		new_uc_idx = (pdbus->curr_bw_uc_idx %
-			(bw_table->num_usecases - 1)) + 1;
-
-		for (i = 0; i < total_axi_port_cnt; i++) {
-			vect = &bw_table->usecase[new_uc_idx].vectors[i];
-			vect->ab = ab_quota[i];
-			vect->ib = ib_quota[i];
-
-			pr_debug(
-				"%s uc_idx=%d %s path idx=%d ab=%llu ib=%llu\n",
-				bw_table->name,
-				new_uc_idx, (i < rt_axi_port_cnt) ? "rt" : "nrt"
-				, i, vect->ab, vect->ib);
-		}
-	}
-	pdbus->curr_bw_uc_idx = new_uc_idx;
-	pdbus->ao_bw_uc_idx = new_uc_idx;
-
-	DPU_ATRACE_BEGIN("msm_bus_scale_req");
-	rc = msm_bus_scale_client_update_request(pdbus->data_bus_hdl,
-			new_uc_idx);
-	DPU_ATRACE_END("msm_bus_scale_req");
-
-	return rc;
-}
-
-int dpu_power_data_bus_set_quota(struct dpu_power_handle *phandle,
-		struct dpu_power_client *pclient,
-		int bus_client, u32 bus_id,
-		u64 ab_quota, u64 ib_quota)
-{
-	int rc = 0;
-	int i;
-	u64 total_ab_rt = 0, total_ib_rt = 0;
-	u64 total_ab_nrt = 0, total_ib_nrt = 0;
-	struct dpu_power_client *client;
-
-	if (!phandle || !pclient ||
-			bus_client >= DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX ||
-			bus_id >= DPU_POWER_HANDLE_DBUS_ID_MAX) {
-		pr_err("invalid parameters\n");
-		return -EINVAL;
-	}
-
-	mutex_lock(&phandle->phandle_lock);
-
-	pclient->ab[bus_client] = ab_quota;
-	pclient->ib[bus_client] = ib_quota;
-	trace_dpu_perf_update_bus(bus_client, ab_quota, ib_quota);
-
-	list_for_each_entry(client, &phandle->power_client_clist, list) {
-		for (i = 0; i < DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX; i++) {
-			if (i == DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT) {
-				total_ab_nrt += client->ab[i];
-				total_ib_nrt += client->ib[i];
-			} else {
-				total_ab_rt += client->ab[i];
-				total_ib_rt = max(total_ib_rt, client->ib[i]);
-			}
-		}
-	}
-
-	if (phandle->data_bus_handle[bus_id].data_bus_hdl)
-		rc = _dpu_power_data_bus_set_quota(
-			&phandle->data_bus_handle[bus_id],
-			total_ab_rt, total_ab_nrt,
-			total_ib_rt, total_ib_nrt);
-
-	mutex_unlock(&phandle->phandle_lock);
-
-	return rc;
-}
-
-static void dpu_power_data_bus_unregister(
-		struct dpu_power_data_bus_handle *pdbus)
-{
-	if (pdbus->data_bus_hdl) {
-		msm_bus_scale_unregister_client(pdbus->data_bus_hdl);
-		pdbus->data_bus_hdl = 0;
-	}
-}
-
-static int dpu_power_data_bus_parse(struct platform_device *pdev,
-	struct dpu_power_data_bus_handle *pdbus, const char *name)
-{
-	struct device_node *node;
-	int rc = 0;
-	int paths;
-
-	pdbus->bus_channels = 1;
-	rc = of_property_read_u32(pdev->dev.of_node,
-		"qcom,dpu-dram-channels", &pdbus->bus_channels);
-	if (rc) {
-		pr_debug("number of channels property not specified\n");
-		rc = 0;
-	}
-
-	pdbus->nrt_axi_port_cnt = 0;
-	rc = of_property_read_u32(pdev->dev.of_node,
-			"qcom,dpu-num-nrt-paths",
-			&pdbus->nrt_axi_port_cnt);
-	if (rc) {
-		pr_debug("number of axi port property not specified\n");
-		rc = 0;
-	}
-
-	node = of_get_child_by_name(pdev->dev.of_node, name);
-	if (node) {
-		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;
-		}
-		pdbus->axi_port_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;
-		}
-		pr_debug("register %s data_bus_hdl=%x\n", name,
-				pdbus->data_bus_hdl);
-	}
-
-end:
-	return rc;
-}
-
-static int dpu_power_reg_bus_parse(struct platform_device *pdev,
-	struct dpu_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,dpu-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);
-	}
-
-end:
-	return rc;
-}
-
-static void dpu_power_reg_bus_unregister(u32 reg_bus_hdl)
-{
-	if (reg_bus_hdl)
-		msm_bus_scale_unregister_client(reg_bus_hdl);
-}
-
-int dpu_power_data_bus_state_update(struct dpu_power_handle *phandle,
-							bool enable)
-{
-	int i;
-
-	if (!phandle) {
-		pr_err("invalid param\n");
-		return -EINVAL;
-	}
-
-	for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC;
-			i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
-		phandle->data_bus_handle[i].enable = enable;
-
-	return 0;
-}
-
-static int dpu_power_data_bus_update(struct dpu_power_data_bus_handle *pdbus,
-							bool enable)
-{
-	int rc = 0;
-
-	pdbus->enable = enable;
-
-	if (pdbus->data_bus_hdl)
-		rc = _dpu_power_data_bus_set_quota(pdbus, pdbus->ab_rt,
-				pdbus->ab_nrt, pdbus->ib_rt, pdbus->ib_nrt);
-
-	if (rc)
-		pr_err("failed to set data bus vote rc=%d enable:%d\n",
-							rc, enable);
-
-	return rc;
-}
-
-static int dpu_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
-{
-	int rc = 0;
-
-	if (reg_bus_hdl)
-		rc = msm_bus_scale_client_update_request(reg_bus_hdl,
-								usecase_ndx);
-	if (rc)
-		pr_err("failed to set reg bus vote rc=%d\n", rc);
-
-	return rc;
-}
-#else
-static int dpu_power_data_bus_parse(struct platform_device *pdev,
-		struct dpu_power_data_bus_handle *pdbus, const char *name)
-{
-	return 0;
-}
-
-static void dpu_power_data_bus_unregister(
-		struct dpu_power_data_bus_handle *pdbus)
-{
-}
-
-int dpu_power_data_bus_set_quota(struct dpu_power_handle *phandle,
-		struct dpu_power_client *pclient,
-		int bus_client, u32 bus_id,
-		u64 ab_quota, u64 ib_quota)
-{
-	return 0;
-}
-
-static int dpu_power_reg_bus_parse(struct platform_device *pdev,
-	struct dpu_power_handle *phandle)
-{
-	return 0;
-}
-
-static void dpu_power_reg_bus_unregister(u32 reg_bus_hdl)
-{
-}
-
-static int dpu_power_reg_bus_update(u32 reg_bus_hdl, u32 usecase_ndx)
-{
-	return 0;
-}
-
-static int dpu_power_data_bus_update(struct dpu_power_data_bus_handle *pdbus,
-							bool enable)
-{
-	return 0;
-}
-
-int dpu_power_data_bus_state_update(struct dpu_power_handle *phandle,
-							bool enable)
-{
-	return 0;
-}
-#endif
-
-int dpu_power_resource_init(struct platform_device *pdev,
-	struct dpu_power_handle *phandle)
-{
-	int rc = 0, i;
-
-	if (!phandle || !pdev) {
-		pr_err("invalid input param\n");
-		return -EINVAL;
-	}
-
-	phandle->dev = &pdev->dev;
-
-	rc = dpu_power_reg_bus_parse(pdev, phandle);
-	if (rc) {
-		pr_err("register bus parse failed rc=%d\n", rc);
-		return rc;
-	}
-
-	for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC;
-			i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
-		rc = dpu_power_data_bus_parse(pdev,
-				&phandle->data_bus_handle[i],
-				data_bus_name[i]);
-		if (rc) {
-			pr_err("register data bus parse failed id=%d rc=%d\n",
-					i, rc);
-			goto data_bus_err;
-		}
-	}
-
-	INIT_LIST_HEAD(&phandle->power_client_clist);
-	INIT_LIST_HEAD(&phandle->event_list);
-
-	mutex_init(&phandle->phandle_lock);
-
-	return rc;
-
-data_bus_err:
-	for (i--; i >= 0; i--)
-		dpu_power_data_bus_unregister(&phandle->data_bus_handle[i]);
-	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
-	return rc;
-}
-
-void dpu_power_resource_deinit(struct platform_device *pdev,
-	struct dpu_power_handle *phandle)
-{
-	struct dpu_power_client *curr_client, *next_client;
-	struct dpu_power_event *curr_event, *next_event;
-	int i;
-
-	if (!phandle || !pdev) {
-		pr_err("invalid input param\n");
-		return;
-	}
-
-	mutex_lock(&phandle->phandle_lock);
-	list_for_each_entry_safe(curr_client, next_client,
-			&phandle->power_client_clist, list) {
-		pr_err("cliend:%s-%d still registered with refcount:%d\n",
-				curr_client->name, curr_client->id,
-				curr_client->refcount);
-		curr_client->active = false;
-		list_del(&curr_client->list);
-	}
-
-	list_for_each_entry_safe(curr_event, next_event,
-			&phandle->event_list, list) {
-		pr_err("event:%d, client:%s still registered\n",
-				curr_event->event_type,
-				curr_event->client_name);
-		curr_event->active = false;
-		list_del(&curr_event->list);
-	}
-	mutex_unlock(&phandle->phandle_lock);
-
-	for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
-		dpu_power_data_bus_unregister(&phandle->data_bus_handle[i]);
-
-	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
-}
-
-int dpu_power_resource_enable(struct dpu_power_handle *phandle,
-	struct dpu_power_client *pclient, bool enable)
-{
-	int rc = 0, i;
-	bool changed = false;
-	u32 max_usecase_ndx = VOTE_INDEX_DISABLE, prev_usecase_ndx;
-	struct dpu_power_client *client;
-
-	if (!phandle || !pclient) {
-		pr_err("invalid input argument\n");
-		return -EINVAL;
-	}
-
-	mutex_lock(&phandle->phandle_lock);
-	if (enable)
-		pclient->refcount++;
-	else if (pclient->refcount)
-		pclient->refcount--;
-
-	if (pclient->refcount)
-		pclient->usecase_ndx = VOTE_INDEX_LOW;
-	else
-		pclient->usecase_ndx = VOTE_INDEX_DISABLE;
-
-	list_for_each_entry(client, &phandle->power_client_clist, list) {
-		if (client->usecase_ndx < VOTE_INDEX_MAX &&
-		    client->usecase_ndx > max_usecase_ndx)
-			max_usecase_ndx = client->usecase_ndx;
-	}
-
-	if (phandle->current_usecase_ndx != max_usecase_ndx) {
-		changed = true;
-		prev_usecase_ndx = phandle->current_usecase_ndx;
-		phandle->current_usecase_ndx = max_usecase_ndx;
-	}
-
-	pr_debug("%pS: changed=%d current idx=%d request client %s id:%u enable:%d refcount:%d\n",
-		__builtin_return_address(0), changed, max_usecase_ndx,
-		pclient->name, pclient->id, enable, pclient->refcount);
-
-	if (!changed)
-		goto end;
-
-	if (enable) {
-		dpu_power_event_trigger_locked(phandle,
-				DPU_POWER_EVENT_PRE_ENABLE);
-
-		for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
-			rc = dpu_power_data_bus_update(
-					&phandle->data_bus_handle[i], enable);
-			if (rc) {
-				pr_err("failed to set data bus vote id=%d rc=%d\n",
-						i, rc);
-				goto data_bus_hdl_err;
-			}
-		}
-
-		rc = dpu_power_reg_bus_update(phandle->reg_bus_hdl,
-							max_usecase_ndx);
-		if (rc) {
-			pr_err("failed to set reg bus vote rc=%d\n", rc);
-			goto reg_bus_hdl_err;
-		}
-
-		dpu_power_event_trigger_locked(phandle,
-				DPU_POWER_EVENT_POST_ENABLE);
-
-	} else {
-		dpu_power_event_trigger_locked(phandle,
-				DPU_POWER_EVENT_PRE_DISABLE);
-
-		dpu_power_reg_bus_update(phandle->reg_bus_hdl,
-							max_usecase_ndx);
-
-		for (i = 0 ; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
-			dpu_power_data_bus_update(&phandle->data_bus_handle[i],
-					enable);
-
-		dpu_power_event_trigger_locked(phandle,
-				DPU_POWER_EVENT_POST_DISABLE);
-	}
-
-end:
-	mutex_unlock(&phandle->phandle_lock);
-	return rc;
-
-reg_bus_hdl_err:
-	for (i = 0 ; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
-		dpu_power_data_bus_update(&phandle->data_bus_handle[i], 0);
-data_bus_hdl_err:
-	phandle->current_usecase_ndx = prev_usecase_ndx;
-	mutex_unlock(&phandle->phandle_lock);
-	return rc;
-}
-
-struct dpu_power_event *dpu_power_handle_register_event(
-		struct dpu_power_handle *phandle,
-		u32 event_type, void (*cb_fnc)(u32 event_type, void *usr),
-		void *usr, char *client_name)
-{
-	struct dpu_power_event *event;
-
-	if (!phandle) {
-		pr_err("invalid power handle\n");
-		return ERR_PTR(-EINVAL);
-	} else if (!cb_fnc || !event_type) {
-		pr_err("no callback fnc or event type\n");
-		return ERR_PTR(-EINVAL);
-	}
-
-	event = kzalloc(sizeof(struct dpu_power_event), GFP_KERNEL);
-	if (!event)
-		return ERR_PTR(-ENOMEM);
-
-	event->event_type = event_type;
-	event->cb_fnc = cb_fnc;
-	event->usr = usr;
-	strlcpy(event->client_name, client_name, MAX_CLIENT_NAME_LEN);
-	event->active = true;
-
-	mutex_lock(&phandle->phandle_lock);
-	list_add(&event->list, &phandle->event_list);
-	mutex_unlock(&phandle->phandle_lock);
-
-	return event;
-}
-
-void dpu_power_handle_unregister_event(
-		struct dpu_power_handle *phandle,
-		struct dpu_power_event *event)
-{
-	if (!phandle || !event) {
-		pr_err("invalid phandle or event\n");
-	} else if (!event->active) {
-		pr_err("power handle deinit already done\n");
-		kfree(event);
-	} else {
-		mutex_lock(&phandle->phandle_lock);
-		list_del_init(&event->list);
-		mutex_unlock(&phandle->phandle_lock);
-		kfree(event);
-	}
-}
diff --git a/drivers/gpu/drm/msm/dpu_power_handle.h b/drivers/gpu/drm/msm/dpu_power_handle.h
deleted file mode 100644
index 9a6d4b9..0000000
--- a/drivers/gpu/drm/msm/dpu_power_handle.h
+++ /dev/null
@@ -1,288 +0,0 @@ 
-/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _DPU_POWER_HANDLE_H_
-#define _DPU_POWER_HANDLE_H_
-
-#define MAX_CLIENT_NAME_LEN 128
-
-#define DPU_POWER_HANDLE_ENABLE_BUS_AB_QUOTA	0
-#define DPU_POWER_HANDLE_DISABLE_BUS_AB_QUOTA	0
-#define DPU_POWER_HANDLE_ENABLE_BUS_IB_QUOTA	1600000000
-#define DPU_POWER_HANDLE_DISABLE_BUS_IB_QUOTA	0
-
-#include <linux/dpu_io_util.h>
-
-/* event will be triggered before power handler disable */
-#define DPU_POWER_EVENT_PRE_DISABLE	0x1
-
-/* event will be triggered after power handler disable */
-#define DPU_POWER_EVENT_POST_DISABLE	0x2
-
-/* event will be triggered before power handler enable */
-#define DPU_POWER_EVENT_PRE_ENABLE	0x4
-
-/* event will be triggered after power handler enable */
-#define DPU_POWER_EVENT_POST_ENABLE	0x8
-
-/**
- * mdss_bus_vote_type: register bus vote type
- * VOTE_INDEX_DISABLE: removes the client vote
- * VOTE_INDEX_LOW: keeps the lowest vote for register bus
- * VOTE_INDEX_MAX: invalid
- */
-enum mdss_bus_vote_type {
-	VOTE_INDEX_DISABLE,
-	VOTE_INDEX_LOW,
-	VOTE_INDEX_MAX,
-};
-
-/**
- * enum dpu_power_handle_data_bus_client - type of axi bus clients
- * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_RT: core real-time bus client
- * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT: core non-real-time bus client
- * @DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX: maximum number of bus client type
- */
-enum dpu_power_handle_data_bus_client {
-	DPU_POWER_HANDLE_DATA_BUS_CLIENT_RT,
-	DPU_POWER_HANDLE_DATA_BUS_CLIENT_NRT,
-	DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX
-};
-
-/**
- * enum DPU_POWER_HANDLE_DBUS_ID - data bus identifier
- * @DPU_POWER_HANDLE_DBUS_ID_MNOC: DPU/MNOC data bus
- * @DPU_POWER_HANDLE_DBUS_ID_LLCC: MNOC/LLCC data bus
- * @DPU_POWER_HANDLE_DBUS_ID_EBI: LLCC/EBI data bus
- */
-enum DPU_POWER_HANDLE_DBUS_ID {
-	DPU_POWER_HANDLE_DBUS_ID_MNOC,
-	DPU_POWER_HANDLE_DBUS_ID_LLCC,
-	DPU_POWER_HANDLE_DBUS_ID_EBI,
-	DPU_POWER_HANDLE_DBUS_ID_MAX,
-};
-
-/**
- * struct dpu_power_client: stores the power client for dpu driver
- * @name:	name of the client
- * @usecase_ndx: current regs bus vote type
- * @refcount:	current refcount if multiple modules are using same
- *              same client for enable/disable. Power module will
- *              aggregate the refcount and vote accordingly for this
- *              client.
- * @id:		assigned during create. helps for debugging.
- * @list:	list to attach power handle master list
- * @ab:         arbitrated bandwidth for each bus client
- * @ib:         instantaneous bandwidth for each bus client
- * @active:	inidcates the state of dpu power handle
- */
-struct dpu_power_client {
-	char name[MAX_CLIENT_NAME_LEN];
-	short usecase_ndx;
-	short refcount;
-	u32 id;
-	struct list_head list;
-	u64 ab[DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX];
-	u64 ib[DPU_POWER_HANDLE_DATA_BUS_CLIENT_MAX];
-	bool active;
-};
-
-/**
- * struct dpu_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
- * @axi_port_cnt: number of rt axi ports
- * @nrt_axi_port_cnt: number of nrt axi ports
- * @bus_channels: number of memory bus channels
- * @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 dpu_power_data_bus_handle {
-	struct msm_bus_scale_pdata *data_bus_scale_table;
-	u32 data_bus_hdl;
-	u32 axi_port_cnt;
-	u32 nrt_axi_port_cnt;
-	u32 bus_channels;
-	u32 curr_bw_uc_idx;
-	u32 ao_bw_uc_idx;
-	u64 ab_rt;
-	u64 ib_rt;
-	u64 ab_nrt;
-	u64 ib_nrt;
-	bool enable;
-};
-
-/*
- * struct dpu_power_event - local event registration structure
- * @client_name: name of the client registering
- * @cb_fnc: pointer to desired callback function
- * @usr: user pointer to pass to callback event trigger
- * @event: refer to DPU_POWER_HANDLE_EVENT_*
- * @list: list to attach event master list
- * @active: indicates the state of dpu power handle
- */
-struct dpu_power_event {
-	char client_name[MAX_CLIENT_NAME_LEN];
-	void (*cb_fnc)(u32 event_type, void *usr);
-	void *usr;
-	u32 event_type;
-	struct list_head list;
-	bool active;
-};
-
-/**
- * struct dpu_power_handle: power handle main struct
- * @client_clist: master list to store all clients
- * @phandle_lock: lock to synchronize the enable/disable
- * @dev: pointer to device structure
- * @usecase_ndx: current usecase index
- * @reg_bus_hdl: current register bus handle
- * @data_bus_handle: context structure for data bus control
- * @event_list: current power handle event list
- */
-struct dpu_power_handle {
-	struct list_head power_client_clist;
-	struct mutex phandle_lock;
-	struct device *dev;
-	u32 current_usecase_ndx;
-	u32 reg_bus_hdl;
-	struct dpu_power_data_bus_handle data_bus_handle
-		[DPU_POWER_HANDLE_DBUS_ID_MAX];
-	struct list_head event_list;
-};
-
-/**
- * dpu_power_resource_init() - initializes the dpu power handle
- * @pdev:   platform device to search the power resources
- * @pdata:  power handle to store the power resources
- *
- * Return: error code.
- */
-int dpu_power_resource_init(struct platform_device *pdev,
-	struct dpu_power_handle *pdata);
-
-/**
- * dpu_power_resource_deinit() - release the dpu power handle
- * @pdev:   platform device for power resources
- * @pdata:  power handle containing the resources
- *
- * Return: error code.
- */
-void dpu_power_resource_deinit(struct platform_device *pdev,
-	struct dpu_power_handle *pdata);
-
-/**
- * dpu_power_client_create() - create the client on power handle
- * @pdata:  power handle containing the resources
- * @client_name: new client name for registration
- *
- * Return: error code.
- */
-struct dpu_power_client *dpu_power_client_create(struct dpu_power_handle *pdata,
-	char *client_name);
-
-/**
- * dpu_power_client_destroy() - destroy the client on power handle
- * @pdata:  power handle containing the resources
- * @client_name: new client name for registration
- *
- * Return: none
- */
-void dpu_power_client_destroy(struct dpu_power_handle *phandle,
-	struct dpu_power_client *client);
-
-/**
- * dpu_power_resource_enable() - enable/disable the power resources
- * @pdata:  power handle containing the resources
- * @client: client information to enable/disable its vote
- * @enable: boolean request for enable/disable
- *
- * Return: error code.
- */
-int dpu_power_resource_enable(struct dpu_power_handle *pdata,
-	struct dpu_power_client *pclient, bool enable);
-
-/**
- * dpu_power_data_bus_state_update() - update data bus state
- * @pdata:  power handle containing the resources
- * @enable: take enable vs disable path
- *
- * Return: error code.
- */
-int dpu_power_data_bus_state_update(struct dpu_power_handle *phandle,
-							bool enable);
-
-/**
- * dpu_power_data_bus_set_quota() - set data bus quota for power client
- * @phandle:  power handle containing the resources
- * @client: client information to set quota
- * @bus_client: real-time or non-real-time bus client
- * @bus_id: identifier of data bus, see DPU_POWER_HANDLE_DBUS_ID
- * @ab_quota: arbitrated bus bandwidth
- * @ib_quota: instantaneous bus bandwidth
- *
- * Return: zero if success, or error code otherwise
- */
-int dpu_power_data_bus_set_quota(struct dpu_power_handle *phandle,
-		struct dpu_power_client *pclient,
-		int bus_client, u32 bus_id,
-		u64 ab_quota, u64 ib_quota);
-
-/**
- * dpu_power_data_bus_bandwidth_ctrl() - control data bus bandwidth enable
- * @phandle:  power handle containing the resources
- * @client: client information to bandwidth control
- * @enable: true to enable bandwidth for data base
- *
- * Return: none
- */
-void dpu_power_data_bus_bandwidth_ctrl(struct dpu_power_handle *phandle,
-		struct dpu_power_client *pclient, int enable);
-
-/**
- * dpu_power_handle_register_event - register a callback function for an event.
- *	Clients can register for multiple events with a single register.
- *	Any block with access to phandle can register for the event
- *	notification.
- * @phandle:	power handle containing the resources
- * @event_type:	event type to register; refer DPU_POWER_HANDLE_EVENT_*
- * @cb_fnc:	pointer to desired callback function
- * @usr:	user pointer to pass to callback on event trigger
- *
- * Return:	event pointer if success, or error code otherwise
- */
-struct dpu_power_event *dpu_power_handle_register_event(
-		struct dpu_power_handle *phandle,
-		u32 event_type, void (*cb_fnc)(u32 event_type, void *usr),
-		void *usr, char *client_name);
-/**
- * dpu_power_handle_unregister_event - unregister callback for event(s)
- * @phandle:	power handle containing the resources
- * @event:	event pointer returned after power handle register
- */
-void dpu_power_handle_unregister_event(struct dpu_power_handle *phandle,
-		struct dpu_power_event *event);
-
-/**
- * dpu_power_handle_get_dbus_name - get name of given data bus identifier
- * @bus_id:	data bus identifier
- * Return:	Pointer to name string if success; NULL otherwise
- */
-const char *dpu_power_handle_get_dbus_name(u32 bus_id);
-
-#endif /* _DPU_POWER_HANDLE_H_ */
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 5c267cd..60b6919 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -340,7 +340,6 @@  static int msm_drm_uninit(struct device *dev)
 	component_unbind_all(dev, ddev);
 
 #ifdef CONFIG_DRM_MSM_DPU
-	dpu_power_resource_deinit(pdev, &priv->phandle);
 	dpu_dbg_destroy();
 #endif
 
@@ -519,12 +518,6 @@  static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 	drm_mode_config_init(ddev);
 
 #ifdef CONFIG_DRM_MSM_DPU
-	ret = dpu_power_resource_init(pdev, &priv->phandle);
-	if (ret) {
-		pr_err("dpu power resource init failed\n");
-		goto power_init_fail;
-	}
-
 	ret = dpu_dbg_init(&pdev->dev);
 	if (ret) {
 		dev_err(dev, "failed to init dpu dbg: %d\n", ret);
@@ -733,8 +726,6 @@  static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 #ifdef CONFIG_DRM_MSM_DPU
 	dpu_dbg_destroy();
 dbg_init_fail:
-	dpu_power_resource_deinit(pdev, &priv->phandle);
-power_init_fail:
 #endif
 	if (mdss && mdss->funcs)
 		mdss->funcs->destroy(ddev);
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index f9ae96f..27a73a8 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -46,8 +46,6 @@ 
 #include <drm/msm_drm.h>
 #include <drm/drm_gem.h>
 
-#include "dpu_power_handle.h"
-
 #define GET_MAJOR_REV(rev)		((rev) >> 28)
 #define GET_MINOR_REV(rev)		(((rev) >> 16) & 0xFFF)
 #define GET_STEP_REV(rev)		((rev) & 0xFFFF)
@@ -375,8 +373,6 @@  struct msm_drm_private {
 
 	struct msm_kms *kms;
 
-	struct dpu_power_handle phandle;
-
 	/* subordinate devices, if present: */
 	struct platform_device *gpu_pdev;