From: Sean Paul <seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
To: Rajesh Yadav <ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org,
hoegsberg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org,
freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Subject: Re: [DPU PATCH v2 11/12] drm/msm/dpu: move dpu_power_handle to dpu folder
Date: Fri, 11 May 2018 11:48:46 -0400 [thread overview]
Message-ID: <20180511154846.GW33053@art_vandelay> (raw)
In-Reply-To: <1526050178-31893-12-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
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
>
--
Sean Paul, Software Engineer, Google / Chromium OS
_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno
next prev parent reply other threads:[~2018-05-11 15:48 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-11 14:49 [DPU PATCH v2 00/12] Refactor DPU device/driver hierarchy and add runtime_pm support Rajesh Yadav
2018-05-11 14:49 ` [DPU PATCH v2 02/12] drm/msm/mdp5: subclass msm_mdss for mdp5 Rajesh Yadav
[not found] ` <1526050178-31893-1-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-11 14:49 ` [DPU PATCH v2 01/12] drm/msm: remove redundant pm_runtime_enable call from msm_drv Rajesh Yadav
2018-05-11 14:49 ` [DPU PATCH v2 03/12] drm/msm/dpu: add MDSS top level driver for dpu Rajesh Yadav
2018-05-11 15:28 ` Sean Paul
2018-05-14 14:06 ` ryadav
[not found] ` <1526050178-31893-4-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-11 17:05 ` Jordan Crouse
[not found] ` <20180511170523.GF4995-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
2018-05-11 18:32 ` Sean Paul
2018-05-11 14:49 ` [DPU PATCH v2 04/12] drm/msm/dpu: create new platform driver for dpu device Rajesh Yadav
[not found] ` <1526050178-31893-5-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-11 15:30 ` Sean Paul
2018-05-11 17:06 ` Jordan Crouse
2018-05-11 14:49 ` [DPU PATCH v2 06/12] drm/msm/dpu: use runtime_pm calls on " Rajesh Yadav
2018-05-11 14:49 ` [DPU PATCH v2 07/12] drm/msm/dpu: remove clock management code from dpu_power_handle Rajesh Yadav
[not found] ` <1526050178-31893-8-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-11 15:35 ` Sean Paul
2018-05-11 14:49 ` [DPU PATCH v2 08/12] drm/msm/dpu: remove power " Rajesh Yadav
[not found] ` <1526050178-31893-9-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-11 15:40 ` Sean Paul
2018-05-11 14:49 ` [DPU PATCH v2 09/12] drm/msm/dp: remove dpu_power_handle calls from dp driver Rajesh Yadav
2018-05-11 14:49 ` [DPU PATCH v2 10/12] drm/msm/dpu: use runtime_pm calls in dpu_dbg Rajesh Yadav
[not found] ` <1526050178-31893-11-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-11 15:47 ` Sean Paul
2018-05-11 14:49 ` [DPU PATCH v2 11/12] drm/msm/dpu: move dpu_power_handle to dpu folder Rajesh Yadav
[not found] ` <1526050178-31893-12-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-05-11 15:48 ` Sean Paul [this message]
2018-05-11 14:49 ` [DPU PATCH v2 12/12] drm/msm/dpu: add error handling in dpu_core_perf_crtc_update Rajesh Yadav
2018-05-11 15:49 ` Sean Paul
2018-05-11 14:49 ` [DPU PATCH v2 05/12] drm/msm/dpu: update dpu sub-block offsets wrt dpu base address Rajesh Yadav
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180511154846.GW33053@art_vandelay \
--to=seanpaul-f7+t8e8rja9g9huczpvpmw@public.gmane.org \
--cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
--cc=freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
--cc=hoegsberg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org \
--cc=linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).