linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [DPU PATCH v2 00/12] Refactor DPU device/driver hierarchy and add runtime_pm support
@ 2018-05-11 14:49 Rajesh Yadav
  2018-05-11 14:49 ` [DPU PATCH v2 02/12] drm/msm/mdp5: subclass msm_mdss for mdp5 Rajesh Yadav
                   ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Rajesh Yadav @ 2018-05-11 14:49 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
  Cc: robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw, Rajesh Yadav,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw

SoCs containing mdp5 or dpu have a MDSS top level wrapper which includes
sub-blocks as mdp5/dpu, dsi, dp, hdmi etc. The MDSS top level wrapper
manages common resources like common clocks, main power supply and
interrupts for its sub-blocks.

But current dpu driver implementation is based on a flat device hierarchy
where MDSS/DPU HW blocks were represented by single device and DSI/DP etc.
are represented as independent devices w/o any relationships b/t these
nodes which doesn't model the HW associations precisely.

A minimal MDSS and DPU controller device separation is done in following
patch series [1] but currently both these devices match to a single driver
which is getting probed two times and all the resources are still tied to
DPU device.

Moreover, all the power resource management in DPU driver is part of
power_handle module which manages these resources via a custom
implementation.

Irq domain handling is part of DPU device, due to lack of a dedicated
driver for MDSS top level wrapper device.

This patch series aims at adding separate drivers for MDSS top level
wrapper device and DPU child device. MDP5 device/driver is used as a
reference for this refactoring effort. Both the drivers implement
runtime_pm support for their power resource management. Child nodes can
control common resources managed by parent device due to parent child
relationship defined in dt. The top level MDSS device acts as an
interrupt controller and manages hwirq mappings for its child devices. 

Inorder to add MDP5 and DPU specific MDSS driver implementation, this patch
series also subclasses existing msm_mdss define. A helper interface
(msm_mdss_funcs) is added to invoke the platform specific implementations.

This change also corrects hw catalog offsets for all sub blocks present
within DPU device. The offset are now defined wrt DPU base address
(instead of using MDSS base address).

Clock and Power handling code have been removed from dpu_power_handle since
each device manages it's resources via runtime_pm. Now, since
dpu_power_handle manages only bus scaling and power enable/disable
notifications and it's usage is restricted to DPU driver only, moved
dpu_power_handle code to DPU folder.

The dt bindings update patch will be sent subsequently.

This patch series depends on [1].

1 - https://lists.freedesktop.org/archives/freedreno/2018-April/002354.html

Changes in v2:
	- fix indentation issues in dpu_mdss (Sean Paul)
	- merge tiny static functions (like _dpu_mdss_hw_rev_init()
	  and _dpu_mdss_get_intr_sources()) in caller functions (Sean Paul)
	- remove unnecessary goto statements from dpu_mdss_irq (Sean Paul)
	- remove redundant input param checks from dpu_mdss
	  and dpu_kms (Sean Paul/Jordan Crouse)
	- return error code from dpu_mdss_enable/disable (Sean Paul/Jordan Crouse)
	- remove explicit calls to devm_kfree (Sean Paul/Jordan Crouse)
	- remove compatibility check from dpu_mdss_init as
	  it is conditionally called from msm_drv (Sean Paul)
	- reworked msm_dss_parse_clock() to add return checks for
	  of_property_read_* calls, fix log message and
	  fix alignment issues (Sean Paul/Jordan Crouse)
	- remove redundant param checks from __intr_offset and
	  make it a void function to avoid unnecessary error
	  handling from caller (Jordan Crouse)
	- use %pK for kernel pointers (Jordan Crouse)
	- don't export msm_dss_parse_clock since it is used
	  only by dpu driver (Jordan Crouse)
	- merge dpu_init into dpu_bind and dpu_destroy into dpu_unbind (Sean Paul)
	- remove explicit devm allocation failure message (Jordan Crouse)
	- remove local variable to hold and return error code
	  in _dpu_core_perf_set_core_clk_rate() instead return
	  retcode directly from msm_dss_clk_set_rate() call (Sean Paul)
	- return &mp->clk_config[i] directly to avoid local variable
	  in _dpu_kms_get_clk() (Sean Paul)
	- invert conditional check to eliminate local rate variable
	  from dpu_kms_get_clk_rate() (Sean Paul)
	- remove end label from dpu_power_resource_init() and return
	  directly on dpu_power_parse_dt_supply() failure as no cleanup
	  is needed (Sean Paul)
	- remove checks for vtotal and vrefresh from
 	  dpu_encoder_phys_cmd_tearcheck_config() as they should be
	  valid in mode_set() call (Sean Paul)
	- add error handling in dpu_core_perf_crtc_update() (Sean Paul)

Rajesh Yadav (12):
  drm/msm: remove pm_runtime_enable call from msm_drv
  drm/msm/mdp5: subclass msm_mdss for mdp5
  drm/msm/dpu: add MDSS top level driver for dpu
  drm/msm/dpu: create new platform driver for dpu device
  drm/msm/dpu: update dpu sub-block offsets wrt dpu base address
  drm/msm/dpu: use runtime_pm calls on dpu device
  drm/msm/dpu: remove clock management code from dpu_power_handle
  drm/msm/dpu: remove power management code from dpu_power_handle
  drm/msm/dp: remove dpu_power_handle calls from dp driver
  drm/msm/dpu: use runtime_pm calls in dpu_dbg
  drm/msm/dpu: move dpu_power_handle to dpu folder
  drm/msm/dpu: add error handling in dpu_core_perf_crtc_update

 drivers/gpu/drm/msm/Makefile                       |    3 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c       |  106 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h       |   14 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c      |   82 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h      |   15 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c           |   19 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h           |    2 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c        |   17 +-
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c   |    9 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c     |   77 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h     |    7 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c  |   46 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h  |   11 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c            |   48 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c            |  337 ++++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h            |   16 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c           |  254 +++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c          |    6 +-
 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/disp/mdp5/mdp5_mdss.c          |  154 +--
 drivers/gpu/drm/msm/dp/dp_power.c                  |   32 +-
 drivers/gpu/drm/msm/dp/dp_power.h                  |    4 +-
 drivers/gpu/drm/msm/dpu_dbg.c                      |   18 +-
 drivers/gpu/drm/msm/dpu_dbg.h                      |   13 +-
 drivers/gpu/drm/msm/dpu_io_util.c                  |   57 ++
 drivers/gpu/drm/msm/dpu_power_handle.c             | 1075 --------------------
 drivers/gpu/drm/msm/dpu_power_handle.h             |  330 ------
 drivers/gpu/drm/msm/msm_drv.c                      |   86 +-
 drivers/gpu/drm/msm/msm_drv.h                      |   10 +-
 drivers/gpu/drm/msm/msm_kms.h                      |   21 +-
 include/linux/dpu_io_util.h                        |    2 +
 32 files changed, 1818 insertions(+), 2034 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
 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

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [DPU PATCH v2 01/12] drm/msm: remove redundant pm_runtime_enable call from msm_drv
       [not found] ` <1526050178-31893-1-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
@ 2018-05-11 14:49   ` Rajesh Yadav
  2018-05-11 14:49   ` [DPU PATCH v2 03/12] drm/msm/dpu: add MDSS top level driver for dpu Rajesh Yadav
                     ` (8 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Rajesh Yadav @ 2018-05-11 14:49 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
  Cc: robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw, Rajesh Yadav,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw

MDSS top level device includes the common power resources
and it's corresponding driver (i.e. mdp5_mdss) handles call
to enable/disable runtime_pm for enabling these resources.
Remove redundant pm_runtime_enable call from msm_drv.

Changes in v2:
	- none

Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
---
 drivers/gpu/drm/msm/msm_drv.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index ebc40a9..9bb436f 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -581,7 +581,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 		goto fail;
 	}
 	priv->kms = kms;
-	pm_runtime_enable(dev);
 
 	/**
 	 * Since kms->funcs->hw_init(kms) might call
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [DPU PATCH v2 02/12] drm/msm/mdp5: subclass msm_mdss for mdp5
  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 ` Rajesh Yadav
       [not found] ` <1526050178-31893-1-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
  2018-05-11 14:49 ` [DPU PATCH v2 05/12] drm/msm/dpu: update dpu sub-block offsets wrt dpu base address Rajesh Yadav
  2 siblings, 0 replies; 24+ messages in thread
From: Rajesh Yadav @ 2018-05-11 14:49 UTC (permalink / raw)
  To: dri-devel, freedreno, linux-arm-msm; +Cc: Rajesh Yadav, hoegsberg

SoCs having mdp5 or dpu have identical tree like
device hierarchy where MDSS top level wrapper manages
common power resources for all child devices.

Subclass msm_mdss so that msm_mdss includes common defines
and mdp5/dpu mdss derivations to include any extensions.

Add mdss helper interface (msm_mdss_funcs) to msm_mdss
base for mdp5/dpu mdss specific implementation calls.

This change subclasses msm_mdss for mdp5, dpu specific
changes will be done separately.

Changes in v2:
	- fixed indentation for irq_domain_add_linear call (Sean Paul)

Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
---
 drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c | 154 ++++++++++++++++--------------
 drivers/gpu/drm/msm/msm_drv.c             |  23 +++--
 drivers/gpu/drm/msm/msm_kms.h             |  20 ++--
 3 files changed, 110 insertions(+), 87 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c
index f2a0db7..1cc4e57 100644
--- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c
+++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_mdss.c
@@ -20,12 +20,10 @@
 #include "msm_drv.h"
 #include "mdp5_kms.h"
 
-/*
- * If needed, this can become more specific: something like struct mdp5_mdss,
- * which contains a 'struct msm_mdss base' member.
- */
-struct msm_mdss {
-	struct drm_device *dev;
+#define to_mdp5_mdss(x) container_of(x, struct mdp5_mdss, base)
+
+struct mdp5_mdss {
+	struct msm_mdss base;
 
 	void __iomem *mmio, *vbif;
 
@@ -41,22 +39,22 @@ struct msm_mdss {
 	} irqcontroller;
 };
 
-static inline void mdss_write(struct msm_mdss *mdss, u32 reg, u32 data)
+static inline void mdss_write(struct mdp5_mdss *mdp5_mdss, u32 reg, u32 data)
 {
-	msm_writel(data, mdss->mmio + reg);
+	msm_writel(data, mdp5_mdss->mmio + reg);
 }
 
-static inline u32 mdss_read(struct msm_mdss *mdss, u32 reg)
+static inline u32 mdss_read(struct mdp5_mdss *mdp5_mdss, u32 reg)
 {
-	return msm_readl(mdss->mmio + reg);
+	return msm_readl(mdp5_mdss->mmio + reg);
 }
 
 static irqreturn_t mdss_irq(int irq, void *arg)
 {
-	struct msm_mdss *mdss = arg;
+	struct mdp5_mdss *mdp5_mdss = arg;
 	u32 intr;
 
-	intr = mdss_read(mdss, REG_MDSS_HW_INTR_STATUS);
+	intr = mdss_read(mdp5_mdss, REG_MDSS_HW_INTR_STATUS);
 
 	VERB("intr=%08x", intr);
 
@@ -64,7 +62,7 @@ static irqreturn_t mdss_irq(int irq, void *arg)
 		irq_hw_number_t hwirq = fls(intr) - 1;
 
 		generic_handle_irq(irq_find_mapping(
-				mdss->irqcontroller.domain, hwirq));
+				mdp5_mdss->irqcontroller.domain, hwirq));
 		intr &= ~(1 << hwirq);
 	}
 
@@ -84,19 +82,19 @@ static irqreturn_t mdss_irq(int irq, void *arg)
 
 static void mdss_hw_mask_irq(struct irq_data *irqd)
 {
-	struct msm_mdss *mdss = irq_data_get_irq_chip_data(irqd);
+	struct mdp5_mdss *mdp5_mdss = irq_data_get_irq_chip_data(irqd);
 
 	smp_mb__before_atomic();
-	clear_bit(irqd->hwirq, &mdss->irqcontroller.enabled_mask);
+	clear_bit(irqd->hwirq, &mdp5_mdss->irqcontroller.enabled_mask);
 	smp_mb__after_atomic();
 }
 
 static void mdss_hw_unmask_irq(struct irq_data *irqd)
 {
-	struct msm_mdss *mdss = irq_data_get_irq_chip_data(irqd);
+	struct mdp5_mdss *mdp5_mdss = irq_data_get_irq_chip_data(irqd);
 
 	smp_mb__before_atomic();
-	set_bit(irqd->hwirq, &mdss->irqcontroller.enabled_mask);
+	set_bit(irqd->hwirq, &mdp5_mdss->irqcontroller.enabled_mask);
 	smp_mb__after_atomic();
 }
 
@@ -109,13 +107,13 @@ static void mdss_hw_unmask_irq(struct irq_data *irqd)
 static int mdss_hw_irqdomain_map(struct irq_domain *d, unsigned int irq,
 				 irq_hw_number_t hwirq)
 {
-	struct msm_mdss *mdss = d->host_data;
+	struct mdp5_mdss *mdp5_mdss = d->host_data;
 
 	if (!(VALID_IRQS & (1 << hwirq)))
 		return -EPERM;
 
 	irq_set_chip_and_handler(irq, &mdss_hw_irq_chip, handle_level_irq);
-	irq_set_chip_data(irq, mdss);
+	irq_set_chip_data(irq, mdp5_mdss);
 
 	return 0;
 }
@@ -126,90 +124,99 @@ static int mdss_hw_irqdomain_map(struct irq_domain *d, unsigned int irq,
 };
 
 
-static int mdss_irq_domain_init(struct msm_mdss *mdss)
+static int mdss_irq_domain_init(struct mdp5_mdss *mdp5_mdss)
 {
-	struct device *dev = mdss->dev->dev;
+	struct device *dev = mdp5_mdss->base.dev->dev;
 	struct irq_domain *d;
 
 	d = irq_domain_add_linear(dev->of_node, 32, &mdss_hw_irqdomain_ops,
-				  mdss);
+				  mdp5_mdss);
 	if (!d) {
 		dev_err(dev, "mdss irq domain add failed\n");
 		return -ENXIO;
 	}
 
-	mdss->irqcontroller.enabled_mask = 0;
-	mdss->irqcontroller.domain = d;
+	mdp5_mdss->irqcontroller.enabled_mask = 0;
+	mdp5_mdss->irqcontroller.domain = d;
 
 	return 0;
 }
 
-int msm_mdss_enable(struct msm_mdss *mdss)
+static int mdp5_mdss_enable(struct msm_mdss *mdss)
 {
+	struct mdp5_mdss *mdp5_mdss = to_mdp5_mdss(mdss);
 	DBG("");
 
-	clk_prepare_enable(mdss->ahb_clk);
-	if (mdss->axi_clk)
-		clk_prepare_enable(mdss->axi_clk);
-	if (mdss->vsync_clk)
-		clk_prepare_enable(mdss->vsync_clk);
+	clk_prepare_enable(mdp5_mdss->ahb_clk);
+	if (mdp5_mdss->axi_clk)
+		clk_prepare_enable(mdp5_mdss->axi_clk);
+	if (mdp5_mdss->vsync_clk)
+		clk_prepare_enable(mdp5_mdss->vsync_clk);
 
 	return 0;
 }
 
-int msm_mdss_disable(struct msm_mdss *mdss)
+static int mdp5_mdss_disable(struct msm_mdss *mdss)
 {
+	struct mdp5_mdss *mdp5_mdss = to_mdp5_mdss(mdss);
 	DBG("");
 
-	if (mdss->vsync_clk)
-		clk_disable_unprepare(mdss->vsync_clk);
-	if (mdss->axi_clk)
-		clk_disable_unprepare(mdss->axi_clk);
-	clk_disable_unprepare(mdss->ahb_clk);
+	if (mdp5_mdss->vsync_clk)
+		clk_disable_unprepare(mdp5_mdss->vsync_clk);
+	if (mdp5_mdss->axi_clk)
+		clk_disable_unprepare(mdp5_mdss->axi_clk);
+	clk_disable_unprepare(mdp5_mdss->ahb_clk);
 
 	return 0;
 }
 
-static int msm_mdss_get_clocks(struct msm_mdss *mdss)
+static int msm_mdss_get_clocks(struct mdp5_mdss *mdp5_mdss)
 {
-	struct platform_device *pdev = to_platform_device(mdss->dev->dev);
+	struct platform_device *pdev =
+			to_platform_device(mdp5_mdss->base.dev->dev);
 
-	mdss->ahb_clk = msm_clk_get(pdev, "iface");
-	if (IS_ERR(mdss->ahb_clk))
-		mdss->ahb_clk = NULL;
+	mdp5_mdss->ahb_clk = msm_clk_get(pdev, "iface");
+	if (IS_ERR(mdp5_mdss->ahb_clk))
+		mdp5_mdss->ahb_clk = NULL;
 
-	mdss->axi_clk = msm_clk_get(pdev, "bus");
-	if (IS_ERR(mdss->axi_clk))
-		mdss->axi_clk = NULL;
+	mdp5_mdss->axi_clk = msm_clk_get(pdev, "bus");
+	if (IS_ERR(mdp5_mdss->axi_clk))
+		mdp5_mdss->axi_clk = NULL;
 
-	mdss->vsync_clk = msm_clk_get(pdev, "vsync");
-	if (IS_ERR(mdss->vsync_clk))
-		mdss->vsync_clk = NULL;
+	mdp5_mdss->vsync_clk = msm_clk_get(pdev, "vsync");
+	if (IS_ERR(mdp5_mdss->vsync_clk))
+		mdp5_mdss->vsync_clk = NULL;
 
 	return 0;
 }
 
-void msm_mdss_destroy(struct drm_device *dev)
+static void mdp5_mdss_destroy(struct drm_device *dev)
 {
 	struct msm_drm_private *priv = dev->dev_private;
-	struct msm_mdss *mdss = priv->mdss;
+	struct mdp5_mdss *mdp5_mdss = to_mdp5_mdss(priv->mdss);
 
-	if (!mdss)
+	if (!mdp5_mdss)
 		return;
 
-	irq_domain_remove(mdss->irqcontroller.domain);
-	mdss->irqcontroller.domain = NULL;
+	irq_domain_remove(mdp5_mdss->irqcontroller.domain);
+	mdp5_mdss->irqcontroller.domain = NULL;
 
-	regulator_disable(mdss->vdd);
+	regulator_disable(mdp5_mdss->vdd);
 
 	pm_runtime_disable(dev->dev);
 }
 
-int msm_mdss_init(struct drm_device *dev)
+static const struct msm_mdss_funcs mdss_funcs = {
+	.enable	= mdp5_mdss_enable,
+	.disable = mdp5_mdss_disable,
+	.destroy = mdp5_mdss_destroy,
+};
+
+int mdp5_mdss_init(struct drm_device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev->dev);
 	struct msm_drm_private *priv = dev->dev_private;
-	struct msm_mdss *mdss;
+	struct mdp5_mdss *mdp5_mdss;
 	int ret;
 
 	DBG("");
@@ -217,40 +224,40 @@ int msm_mdss_init(struct drm_device *dev)
 	if (!of_device_is_compatible(dev->dev->of_node, "qcom,mdss"))
 		return 0;
 
-	mdss = devm_kzalloc(dev->dev, sizeof(*mdss), GFP_KERNEL);
-	if (!mdss) {
+	mdp5_mdss = devm_kzalloc(dev->dev, sizeof(*mdp5_mdss), GFP_KERNEL);
+	if (!mdp5_mdss) {
 		ret = -ENOMEM;
 		goto fail;
 	}
 
-	mdss->dev = dev;
+	mdp5_mdss->base.dev = dev;
 
-	mdss->mmio = msm_ioremap(pdev, "mdss_phys", "MDSS");
-	if (IS_ERR(mdss->mmio)) {
-		ret = PTR_ERR(mdss->mmio);
+	mdp5_mdss->mmio = msm_ioremap(pdev, "mdss_phys", "MDSS");
+	if (IS_ERR(mdp5_mdss->mmio)) {
+		ret = PTR_ERR(mdp5_mdss->mmio);
 		goto fail;
 	}
 
-	mdss->vbif = msm_ioremap(pdev, "vbif_phys", "VBIF");
-	if (IS_ERR(mdss->vbif)) {
-		ret = PTR_ERR(mdss->vbif);
+	mdp5_mdss->vbif = msm_ioremap(pdev, "vbif_phys", "VBIF");
+	if (IS_ERR(mdp5_mdss->vbif)) {
+		ret = PTR_ERR(mdp5_mdss->vbif);
 		goto fail;
 	}
 
-	ret = msm_mdss_get_clocks(mdss);
+	ret = msm_mdss_get_clocks(mdp5_mdss);
 	if (ret) {
 		dev_err(dev->dev, "failed to get clocks: %d\n", ret);
 		goto fail;
 	}
 
 	/* Regulator to enable GDSCs in downstream kernels */
-	mdss->vdd = devm_regulator_get(dev->dev, "vdd");
-	if (IS_ERR(mdss->vdd)) {
-		ret = PTR_ERR(mdss->vdd);
+	mdp5_mdss->vdd = devm_regulator_get(dev->dev, "vdd");
+	if (IS_ERR(mdp5_mdss->vdd)) {
+		ret = PTR_ERR(mdp5_mdss->vdd);
 		goto fail;
 	}
 
-	ret = regulator_enable(mdss->vdd);
+	ret = regulator_enable(mdp5_mdss->vdd);
 	if (ret) {
 		dev_err(dev->dev, "failed to enable regulator vdd: %d\n",
 			ret);
@@ -258,25 +265,26 @@ int msm_mdss_init(struct drm_device *dev)
 	}
 
 	ret = devm_request_irq(dev->dev, platform_get_irq(pdev, 0),
-			       mdss_irq, 0, "mdss_isr", mdss);
+			       mdss_irq, 0, "mdss_isr", mdp5_mdss);
 	if (ret) {
 		dev_err(dev->dev, "failed to init irq: %d\n", ret);
 		goto fail_irq;
 	}
 
-	ret = mdss_irq_domain_init(mdss);
+	ret = mdss_irq_domain_init(mdp5_mdss);
 	if (ret) {
 		dev_err(dev->dev, "failed to init sub-block irqs: %d\n", ret);
 		goto fail_irq;
 	}
 
-	priv->mdss = mdss;
+	mdp5_mdss->base.funcs = &mdss_funcs;
+	priv->mdss = &mdp5_mdss->base;
 
 	pm_runtime_enable(dev->dev);
 
 	return 0;
 fail_irq:
-	regulator_disable(mdss->vdd);
+	regulator_disable(mdp5_mdss->vdd);
 fail:
 	return ret;
 }
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 9bb436f..5d8f1b6 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -270,6 +270,7 @@ static int msm_drm_uninit(struct device *dev)
 	struct drm_device *ddev = platform_get_drvdata(pdev);
 	struct msm_drm_private *priv = ddev->dev_private;
 	struct msm_kms *kms = priv->kms;
+	struct msm_mdss *mdss = priv->mdss;
 	struct msm_vblank_ctrl *vbl_ctrl = &priv->vblank_ctrl;
 	struct vblank_event *vbl_ev, *tmp;
 	int i;
@@ -346,8 +347,8 @@ static int msm_drm_uninit(struct device *dev)
 
 	debugfs_remove_recursive(priv->debug_root);
 
-	msm_mdss_destroy(ddev);
-
+	if (mdss && mdss->funcs)
+		mdss->funcs->destroy(ddev);
 
 	ddev->dev_private = NULL;
 	kfree(priv);
@@ -476,6 +477,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 	struct drm_device *ddev;
 	struct msm_drm_private *priv;
 	struct msm_kms *kms;
+	struct msm_mdss *mdss;
 
 #ifdef CONFIG_DRM_MSM_DPU
 	struct dpu_dbg_power_ctrl dbg_power_ctrl = { 0 };
@@ -501,10 +503,12 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 	ddev->dev_private = priv;
 	priv->dev = ddev;
 
-	ret = msm_mdss_init(ddev);
+	ret = mdp5_mdss_init(ddev);
 	if (ret)
 		goto mdss_init_fail;
 
+	mdss = priv->mdss;
+
 	priv->wq = alloc_ordered_workqueue("msm", 0);
 
 	INIT_LIST_HEAD(&priv->client_event_list);
@@ -746,7 +750,8 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 	dpu_power_resource_deinit(pdev, &priv->phandle);
 power_init_fail:
 #endif
-	msm_mdss_destroy(ddev);
+	if (mdss && mdss->funcs)
+		mdss->funcs->destroy(ddev);
 mdss_init_fail:
 	kfree(priv);
 priv_alloc_fail:
@@ -1416,11 +1421,12 @@ static int msm_runtime_suspend(struct device *dev)
 {
 	struct drm_device *ddev = dev_get_drvdata(dev);
 	struct msm_drm_private *priv = ddev->dev_private;
+	struct msm_mdss *mdss = priv->mdss;
 
 	DBG("");
 
-	if (priv->mdss)
-		return 0; // msm_mdss_disable(priv->mdss);
+	if (mdss && mdss->funcs)
+		mdss->funcs->disable(mdss);
 
 	return 0;
 }
@@ -1429,11 +1435,12 @@ static int msm_runtime_resume(struct device *dev)
 {
 	struct drm_device *ddev = dev_get_drvdata(dev);
 	struct msm_drm_private *priv = ddev->dev_private;
+	struct msm_mdss *mdss = priv->mdss;
 
 	DBG("");
 
-	if (priv->mdss)
-		return 0;//msm_mdss_enable(priv->mdss);
+	if (mdss && mdss->funcs)
+		mdss->funcs->enable(mdss);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index 5b09ce5..9a7bc7d 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -126,16 +126,24 @@ static inline void msm_kms_init(struct msm_kms *kms,
 	kms->funcs = funcs;
 }
 
-struct msm_kms *mdp4_kms_init(struct drm_device *dev);
-
-int msm_mdss_init(struct drm_device *dev);
-void msm_mdss_destroy(struct drm_device *dev);
 struct msm_kms *mdp5_kms_init(struct drm_device *dev);
 
 struct msm_kms *dpu_kms_init(struct drm_device *dev);
 
-int msm_mdss_enable(struct msm_mdss *mdss);
-int msm_mdss_disable(struct msm_mdss *mdss);
+struct msm_kms *mdp4_kms_init(struct drm_device *dev);
+
+struct msm_mdss_funcs {
+	int (*enable)(struct msm_mdss *mdss);
+	int (*disable)(struct msm_mdss *mdss);
+	void (*destroy)(struct drm_device *dev);
+};
+
+struct msm_mdss {
+	struct drm_device *dev;
+	const struct msm_mdss_funcs *funcs;
+};
+
+int mdp5_mdss_init(struct drm_device *dev);
 
 /**
  * Mode Set Utility Functions
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [DPU PATCH v2 03/12] drm/msm/dpu: add MDSS top level driver for dpu
       [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   ` Rajesh Yadav
  2018-05-11 15:28     ` Sean Paul
       [not found]     ` <1526050178-31893-4-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
  2018-05-11 14:49   ` [DPU PATCH v2 04/12] drm/msm/dpu: create new platform driver for dpu device Rajesh Yadav
                     ` (7 subsequent siblings)
  9 siblings, 2 replies; 24+ messages in thread
From: Rajesh Yadav @ 2018-05-11 14:49 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
  Cc: robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw, Rajesh Yadav,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw

SoCs containing dpu have a MDSS top level wrapper
which includes sub-blocks as dpu, dsi, phy, dp etc.
MDSS top level wrapper manages common resources like
common clocks, power and irq for its sub-blocks.

Currently, in dpu driver, all the power resource
management is part of power_handle which manages
these resources via a custom implementation. And
the resource relationships are not modelled properly
in dt.  Moreover the irq domain handling code is part
of dpu device (which is a child device) due to lack
of a dedicated driver for MDSS top level wrapper
device.

This change adds dpu_mdss top level driver to handle
common clock like - core clock, ahb clock
(for register access), main power supply (i.e. gdsc)
and irq management.
The top level mdss device/driver acts as an interrupt
controller and manage hwirq mapping for its child
devices.

It implements runtime_pm support for resource management.
Child nodes can control these resources via runtime_pm
get/put calls on their corresponding devices due to parent
child relationship defined in dt.

Changes in v2:
	- merge _dpu_mdss_hw_rev_init to dpu_mdss_init (Sean Paul)
	- merge _dpu_mdss_get_intr_sources to dpu_mdss_irq (Sean Paul)
	- fix indentation for irq_find_mapping call (Sean Paul)
	- remove unnecessary goto statements from dpu_mdss_irq (Sean Paul)
	- remove redundant param checks from
	  dpu_mdss_irq_mask/unmask (Sean Paul/Jordan Crouse)
	- remove redundant param checks from
	  dpu_mdss_irqdomain_map (Sean Paul/Jordan Crouse)
	- return error code from dpu_mdss_enable/disable (Sean Paul/Jordan Crouse)
	- remove redundant param check from dpu_mdss_destroy (Sean Paul)
	- remove explicit calls to devm_kfree (Sean Paul/Jordan Crouse)
	- remove compatibility check from dpu_mdss_init as
	  it is conditionally called from msm_drv (Sean Paul)
	- reworked msm_dss_parse_clock() to add return checks for
	  of_property_read_* calls, fix log message and
	  fix alignment issues (Sean Paul/Jordan Crouse)
	- remove extra line before dpu_mdss_init (Sean Paul)
	- remove redundant param checks from __intr_offset and
	  make it a void function to avoid unnecessary error
	  handling from caller (Jordan Crouse)
	- remove redundant param check from dpu_mdss_irq (Jordan Crouse)
	- change mdss address space log message to debug and use %pK for
	  kernel pointers (Jordan Crouse)
	- remove unnecessary log message from msm_dss_parse_clock (Jordan Crouse)
	- don't export msm_dss_parse_clock since it is used
	  only by dpu driver (Jordan Crouse)

Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
---
 drivers/gpu/drm/msm/Makefile                      |   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c      |  97 ---------
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h      |  14 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    |   9 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |   7 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c |  28 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  11 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c           |  48 +---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c           |   6 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h           |   2 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c          | 254 ++++++++++++++++++++++
 drivers/gpu/drm/msm/dpu_io_util.c                 |  57 +++++
 drivers/gpu/drm/msm/msm_drv.c                     |  26 ++-
 drivers/gpu/drm/msm/msm_drv.h                     |   2 +-
 drivers/gpu/drm/msm/msm_kms.h                     |   1 +
 include/linux/dpu_io_util.h                       |   2 +
 16 files changed, 339 insertions(+), 226 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index d7558ed..d9826c1 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -81,6 +81,7 @@ msm-y := \
 	disp/dpu1/dpu_reg_dma.o \
 	disp/dpu1/dpu_rm.o \
 	disp/dpu1/dpu_vbif.o \
+	disp/dpu1/dpu_mdss.o \
 	dpu_dbg.o \
 	dpu_io_util.o \
 	dpu_dbg_evtlog.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 fe33013..977adc4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
@@ -515,103 +515,6 @@ void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms)
 	dpu_kms->irq_obj.total_irqs = 0;
 }
 
-static void dpu_core_irq_mask(struct irq_data *irqd)
-{
-	struct dpu_kms *dpu_kms;
-
-	if (!irqd || !irq_data_get_irq_chip_data(irqd)) {
-		DPU_ERROR("invalid parameters irqd %d\n", irqd != NULL);
-		return;
-	}
-	dpu_kms = irq_data_get_irq_chip_data(irqd);
-
-	/* memory barrier */
-	smp_mb__before_atomic();
-	clear_bit(irqd->hwirq, &dpu_kms->irq_controller.enabled_mask);
-	/* memory barrier */
-	smp_mb__after_atomic();
-}
-
-static void dpu_core_irq_unmask(struct irq_data *irqd)
-{
-	struct dpu_kms *dpu_kms;
-
-	if (!irqd || !irq_data_get_irq_chip_data(irqd)) {
-		DPU_ERROR("invalid parameters irqd %d\n", irqd != NULL);
-		return;
-	}
-	dpu_kms = irq_data_get_irq_chip_data(irqd);
-
-	/* memory barrier */
-	smp_mb__before_atomic();
-	set_bit(irqd->hwirq, &dpu_kms->irq_controller.enabled_mask);
-	/* memory barrier */
-	smp_mb__after_atomic();
-}
-
-static struct irq_chip dpu_core_irq_chip = {
-	.name = "dpu",
-	.irq_mask = dpu_core_irq_mask,
-	.irq_unmask = dpu_core_irq_unmask,
-};
-
-static int dpu_core_irqdomain_map(struct irq_domain *domain,
-		unsigned int irq, irq_hw_number_t hwirq)
-{
-	struct dpu_kms *dpu_kms;
-	int rc;
-
-	if (!domain || !domain->host_data) {
-		DPU_ERROR("invalid parameters domain %d\n", domain != NULL);
-		return -EINVAL;
-	}
-	dpu_kms = domain->host_data;
-
-	irq_set_chip_and_handler(irq, &dpu_core_irq_chip, handle_level_irq);
-	rc = irq_set_chip_data(irq, dpu_kms);
-
-	return rc;
-}
-
-static const struct irq_domain_ops dpu_core_irqdomain_ops = {
-	.map = dpu_core_irqdomain_map,
-	.xlate = irq_domain_xlate_onecell,
-};
-
-int dpu_core_irq_domain_add(struct dpu_kms *dpu_kms)
-{
-	struct device *dev;
-	struct irq_domain *domain;
-
-	if (!dpu_kms->dev || !dpu_kms->dev->dev) {
-		pr_err("invalid device handles\n");
-		return -EINVAL;
-	}
-
-	dev = dpu_kms->dev->dev;
-
-	domain = irq_domain_add_linear(dev->of_node, 32,
-			&dpu_core_irqdomain_ops, dpu_kms);
-	if (!domain) {
-		pr_err("failed to add irq_domain\n");
-		return -EINVAL;
-	}
-
-	dpu_kms->irq_controller.enabled_mask = 0;
-	dpu_kms->irq_controller.domain = domain;
-
-	return 0;
-}
-
-int dpu_core_irq_domain_fini(struct dpu_kms *dpu_kms)
-{
-	if (dpu_kms->irq_controller.domain) {
-		irq_domain_remove(dpu_kms->irq_controller.domain);
-		dpu_kms->irq_controller.domain = NULL;
-	}
-	return 0;
-}
-
 irqreturn_t dpu_core_irq(struct dpu_kms *dpu_kms)
 {
 	/*
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
index 64a54fe..8fa59db 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
@@ -38,20 +38,6 @@
 void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms);
 
 /**
- * dpu_core_irq_domain_add - Add core IRQ domain for DPU
- * @dpu_kms:		DPU handle
- * @return:		none
- */
-int dpu_core_irq_domain_add(struct dpu_kms *dpu_kms);
-
-/**
- * dpu_core_irq_domain_fini - uninstall core IRQ domain
- * @dpu_kms:		DPU handle
- * @return:		0 if success; error code otherwise
- */
-int dpu_core_irq_domain_fini(struct dpu_kms *dpu_kms);
-
-/**
  * dpu_core_irq - core IRQ handler
  * @dpu_kms:		DPU handle
  * @return:		interrupt handling status
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 8e779c0..c5b370f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -77,13 +77,6 @@
 	.has_idle_pc = true,
 };
 
-static struct dpu_mdss_base_cfg sdm845_mdss[] = {
-	{
-	.name = "mdss_0", .id = MDP_TOP,
-	.base = 0x0, .features = 0
-	},
-};
-
 static struct dpu_mdp_cfg sdm845_mdp[] = {
 	{
 	.name = "top_0", .id = MDP_TOP,
@@ -550,8 +543,6 @@ void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
 {
 	*dpu_cfg = (struct dpu_mdss_cfg){
 		.caps = &sdm845_dpu_caps,
-		.mdss_count = ARRAY_SIZE(sdm845_mdss),
-		.mdss = sdm845_mdss,
 		.mdp_count = ARRAY_SIZE(sdm845_mdp),
 		.mdp = sdm845_mdp,
 		.ctl_count = ARRAY_SIZE(sdm845_ctl),
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index 39bec0a..7084643 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -492,10 +492,6 @@ struct dpu_wb_sub_blocks {
 	u32 maxlinewidth;
 };
 
-struct dpu_mdss_base_cfg {
-	DPU_HW_BLK_INFO;
-};
-
 /**
  * dpu_clk_ctrl_type - Defines top level clock control signals
  */
@@ -875,9 +871,6 @@ struct dpu_mdss_cfg {
 
 	const struct dpu_caps *caps;
 
-	u32 mdss_count;
-	struct dpu_mdss_base_cfg *mdss;
-
 	u32 mdp_count;
 	struct dpu_mdp_cfg *mdp;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
index 9767cc8..73f084c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
@@ -22,7 +22,6 @@
  * Register offsets in MDSS register file for the interrupt registers
  * w.r.t. to the MDSS base
  */
-#define HW_INTR_STATUS			0x0010
 #define MDP_SSPP_TOP0_OFF		0x1000
 #define MDP_INTF_0_OFF			0x6B000
 #define MDP_INTF_1_OFF			0x6B800
@@ -1017,17 +1016,6 @@ static int dpu_hw_intr_get_valid_interrupts(struct dpu_hw_intr *intr,
 	return 0;
 }
 
-static int dpu_hw_intr_get_interrupt_sources(struct dpu_hw_intr *intr,
-		uint32_t *sources)
-{
-	if (!intr || !sources)
-		return -EINVAL;
-
-	*sources = DPU_REG_READ(&intr->hw, HW_INTR_STATUS);
-
-	return 0;
-}
-
 static void dpu_hw_intr_get_interrupt_statuses(struct dpu_hw_intr *intr)
 {
 	int i;
@@ -1162,7 +1150,6 @@ static void __setup_intr_ops(struct dpu_hw_intr_ops *ops)
 	ops->clear_all_irqs = dpu_hw_intr_clear_irqs;
 	ops->disable_all_irqs = dpu_hw_intr_disable_irqs;
 	ops->get_valid_interrupts = dpu_hw_intr_get_valid_interrupts;
-	ops->get_interrupt_sources = dpu_hw_intr_get_interrupt_sources;
 	ops->get_interrupt_statuses = dpu_hw_intr_get_interrupt_statuses;
 	ops->clear_interrupt_status = dpu_hw_intr_clear_interrupt_status;
 	ops->clear_intr_status_nolock = dpu_hw_intr_clear_intr_status_nolock;
@@ -1170,23 +1157,18 @@ static void __setup_intr_ops(struct dpu_hw_intr_ops *ops)
 	ops->get_intr_status_nolock = dpu_hw_intr_get_intr_status_nolock;
 }
 
-static struct dpu_mdss_base_cfg *__intr_offset(struct dpu_mdss_cfg *m,
+static void __intr_offset(struct dpu_mdss_cfg *m,
 		void __iomem *addr, struct dpu_hw_blk_reg_map *hw)
 {
-	if (!m || !addr || !hw || m->mdp_count == 0)
-		return NULL;
-
 	hw->base_off = addr;
-	hw->blk_off = m->mdss[0].base;
+	hw->blk_off = m->mdp[0].base;
 	hw->hwversion = m->hwversion;
-	return &m->mdss[0];
 }
 
 struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
 		struct dpu_mdss_cfg *m)
 {
 	struct dpu_hw_intr *intr;
-	struct dpu_mdss_base_cfg *cfg;
 
 	if (!addr || !m)
 		return ERR_PTR(-EINVAL);
@@ -1195,11 +1177,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
 	if (!intr)
 		return ERR_PTR(-ENOMEM);
 
-	cfg = __intr_offset(m, addr, &intr->hw);
-	if (!cfg) {
-		kfree(intr);
-		return ERR_PTR(-EINVAL);
-	}
+	__intr_offset(m, addr, &intr->hw);
 	__setup_intr_ops(&intr->ops);
 
 	intr->irq_idx_tbl_size = ARRAY_SIZE(dpu_irq_map);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
index 2f1a828..b52cdca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
@@ -242,17 +242,6 @@ struct dpu_hw_intr_ops {
 	int (*get_valid_interrupts)(
 			struct dpu_hw_intr *intr,
 			uint32_t *mask);
-
-	/**
-	 * get_interrupt_sources - Gets the bitmask of the DPU interrupt
-	 *                         source that are currently fired.
-	 * @intr:	HW interrupt handle
-	 * @sources:	Returning the DPU interrupt source status bit mask
-	 * @return:	0 for success, otherwise failure
-	 */
-	int (*get_interrupt_sources)(
-			struct dpu_hw_intr *intr,
-			uint32_t *sources);
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c
index 19c0929..d5e6ce0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c
@@ -19,56 +19,11 @@
 #include "dpu_irq.h"
 #include "dpu_core_irq.h"
 
-static uint32_t g_dpu_irq_status;
-
 irqreturn_t dpu_irq(struct msm_kms *kms)
 {
 	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
-	u32 interrupts;
-
-	dpu_kms->hw_intr->ops.get_interrupt_sources(dpu_kms->hw_intr,
-			&interrupts);
-
-	/* store irq status in case of irq-storm debugging */
-	g_dpu_irq_status = interrupts;
-
-	/*
-	 * Taking care of MDP interrupt
-	 */
-	if (interrupts & IRQ_SOURCE_MDP) {
-		interrupts &= ~IRQ_SOURCE_MDP;
-		dpu_core_irq(dpu_kms);
-	}
-
-	/*
-	 * Routing all other interrupts to external drivers
-	 */
-	while (interrupts) {
-		irq_hw_number_t hwirq = fls(interrupts) - 1;
-		unsigned int mapping;
-		int rc;
-
-		mapping = irq_find_mapping(dpu_kms->irq_controller.domain,
-				hwirq);
-		if (mapping == 0) {
-			DPU_EVT32(hwirq, DPU_EVTLOG_ERROR);
-			goto error;
-		}
-
-		rc = generic_handle_irq(mapping);
-		if (rc < 0) {
-			DPU_EVT32(hwirq, mapping, rc, DPU_EVTLOG_ERROR);
-			goto error;
-		}
-
-		interrupts &= ~(1 << hwirq);
-	}
-
-	return IRQ_HANDLED;
 
-error:
-	/* bad situation, inform irq system, it may disable overall MDSS irq */
-	return IRQ_NONE;
+	return dpu_core_irq(dpu_kms);
 }
 
 void dpu_irq_preinstall(struct msm_kms *kms)
@@ -108,5 +63,4 @@ void dpu_irq_uninstall(struct msm_kms *kms)
 	}
 
 	dpu_core_irq_uninstall(dpu_kms);
-	dpu_core_irq_domain_fini(dpu_kms);
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 06adb38..e4ab753 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -636,10 +636,6 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
 	priv = dev->dev_private;
 	catalog = dpu_kms->catalog;
 
-	ret = dpu_core_irq_domain_add(dpu_kms);
-	if (ret)
-		goto fail_irq;
-
 	/*
 	 * Create encoder and query display drivers to create
 	 * bridges and connectors
@@ -716,8 +712,6 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
 	return 0;
 fail:
 	_dpu_kms_drm_obj_destroy(dpu_kms);
-fail_irq:
-	dpu_core_irq_domain_fini(dpu_kms);
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 5b0c081..a1c0910 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -184,8 +184,6 @@ struct dpu_kms {
 	struct regulator *mmagic;
 	struct regulator *venus;
 
-	struct dpu_irq_controller irq_controller;
-
 	struct dpu_hw_intr *hw_intr;
 	struct dpu_irq irq_obj;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
new file mode 100644
index 0000000..ce680ea
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
@@ -0,0 +1,254 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) 2018, The Linux Foundation
+ */
+
+#include "dpu_kms.h"
+
+#define to_dpu_mdss(x) container_of(x, struct dpu_mdss, base)
+
+#define HW_INTR_STATUS			0x0010
+
+struct dpu_mdss {
+	struct msm_mdss base;
+	void __iomem *mmio;
+	unsigned long mmio_len;
+	u32 hwversion;
+	struct dss_module_power mp;
+	struct dpu_irq_controller irq_controller;
+};
+
+static irqreturn_t dpu_mdss_irq(int irq, void *arg)
+{
+	struct dpu_mdss *dpu_mdss = arg;
+	u32 interrupts;
+
+	interrupts = readl_relaxed(dpu_mdss->mmio + HW_INTR_STATUS);
+
+	while (interrupts) {
+		irq_hw_number_t hwirq = fls(interrupts) - 1;
+		unsigned int mapping;
+		int rc;
+
+		mapping = irq_find_mapping(dpu_mdss->irq_controller.domain,
+					   hwirq);
+		if (mapping == 0) {
+			DPU_EVT32(hwirq, DPU_EVTLOG_ERROR);
+			return IRQ_NONE;
+		}
+
+		rc = generic_handle_irq(mapping);
+		if (rc < 0) {
+			DPU_EVT32(hwirq, mapping, rc, DPU_EVTLOG_ERROR);
+			return IRQ_NONE;
+		}
+
+		interrupts &= ~(1 << hwirq);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void dpu_mdss_irq_mask(struct irq_data *irqd)
+{
+	struct dpu_mdss *dpu_mdss = irq_data_get_irq_chip_data(irqd);
+
+	/* memory barrier */
+	smp_mb__before_atomic();
+	clear_bit(irqd->hwirq, &dpu_mdss->irq_controller.enabled_mask);
+	/* memory barrier */
+	smp_mb__after_atomic();
+}
+
+static void dpu_mdss_irq_unmask(struct irq_data *irqd)
+{
+	struct dpu_mdss *dpu_mdss = irq_data_get_irq_chip_data(irqd);
+
+	/* memory barrier */
+	smp_mb__before_atomic();
+	set_bit(irqd->hwirq, &dpu_mdss->irq_controller.enabled_mask);
+	/* memory barrier */
+	smp_mb__after_atomic();
+}
+
+static struct irq_chip dpu_mdss_irq_chip = {
+	.name = "dpu_mdss",
+	.irq_mask = dpu_mdss_irq_mask,
+	.irq_unmask = dpu_mdss_irq_unmask,
+};
+
+static int dpu_mdss_irqdomain_map(struct irq_domain *domain,
+		unsigned int irq, irq_hw_number_t hwirq)
+{
+	struct dpu_mdss *dpu_mdss = domain->host_data;
+	int ret;
+
+	irq_set_chip_and_handler(irq, &dpu_mdss_irq_chip, handle_level_irq);
+	ret = irq_set_chip_data(irq, dpu_mdss);
+
+	return ret;
+}
+
+static const struct irq_domain_ops dpu_mdss_irqdomain_ops = {
+	.map = dpu_mdss_irqdomain_map,
+	.xlate = irq_domain_xlate_onecell,
+};
+
+static int _dpu_mdss_irq_domain_add(struct dpu_mdss *dpu_mdss)
+{
+	struct device *dev;
+	struct irq_domain *domain;
+
+	dev = dpu_mdss->base.dev->dev;
+
+	domain = irq_domain_add_linear(dev->of_node, 32,
+			&dpu_mdss_irqdomain_ops, dpu_mdss);
+	if (!domain) {
+		DPU_ERROR("failed to add irq_domain\n");
+		return -EINVAL;
+	}
+
+	dpu_mdss->irq_controller.enabled_mask = 0;
+	dpu_mdss->irq_controller.domain = domain;
+
+	return 0;
+}
+
+int _dpu_mdss_irq_domain_fini(struct dpu_mdss *dpu_mdss)
+{
+	if (dpu_mdss->irq_controller.domain) {
+		irq_domain_remove(dpu_mdss->irq_controller.domain);
+		dpu_mdss->irq_controller.domain = NULL;
+	}
+	return 0;
+}
+static int dpu_mdss_enable(struct msm_mdss *mdss)
+{
+	struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss);
+	struct dss_module_power *mp = &dpu_mdss->mp;
+	int ret;
+
+	ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true);
+	if (ret)
+		DPU_ERROR("clock enable failed, ret:%d\n", ret);
+
+	return ret;
+}
+
+static int dpu_mdss_disable(struct msm_mdss *mdss)
+{
+	struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss);
+	struct dss_module_power *mp = &dpu_mdss->mp;
+	int ret;
+
+	ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
+	if (ret)
+		DPU_ERROR("clock disable failed, ret:%d\n", ret);
+
+	return ret;
+}
+
+static void dpu_mdss_destroy(struct drm_device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev->dev);
+	struct msm_drm_private *priv = dev->dev_private;
+	struct dpu_mdss *dpu_mdss = to_dpu_mdss(priv->mdss);
+	struct dss_module_power *mp = &dpu_mdss->mp;
+
+	_dpu_mdss_irq_domain_fini(dpu_mdss);
+
+	msm_dss_put_clk(mp->clk_config, mp->num_clk);
+	devm_kfree(&pdev->dev, mp->clk_config);
+
+	if (dpu_mdss->mmio)
+		msm_iounmap(pdev, dpu_mdss->mmio);
+	dpu_mdss->mmio = NULL;
+
+	pm_runtime_disable(dev->dev);
+	priv->mdss = NULL;
+}
+
+static const struct msm_mdss_funcs mdss_funcs = {
+	.enable	= dpu_mdss_enable,
+	.disable = dpu_mdss_disable,
+	.destroy = dpu_mdss_destroy,
+};
+
+int dpu_mdss_init(struct drm_device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev->dev);
+	struct msm_drm_private *priv = dev->dev_private;
+	struct dpu_mdss *dpu_mdss;
+	struct dss_module_power *mp;
+	int ret = 0;
+
+	dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL);
+	if (!dpu_mdss)
+		return -ENOMEM;
+
+	dpu_mdss->mmio = msm_ioremap(pdev, "mdss_phys", "mdss_phys");
+	if (IS_ERR(dpu_mdss->mmio)) {
+		ret = PTR_ERR(dpu_mdss->mmio);
+		DPU_ERROR("mdss register memory map failed: %d\n", ret);
+		dpu_mdss->mmio = NULL;
+		return ret;
+	}
+	DRM_DEBUG("mapped mdss address space @%pK\n", dpu_mdss->mmio);
+	dpu_mdss->mmio_len = msm_iomap_size(pdev, "mdss_phys");
+
+	mp = &dpu_mdss->mp;
+	ret = msm_dss_parse_clock(pdev, mp);
+	if (ret) {
+		DPU_ERROR("failed to parse clocks, ret=%d\n", ret);
+		goto clk_parse_err;
+	}
+
+	ret = msm_dss_get_clk(&pdev->dev, mp->clk_config, mp->num_clk);
+	if (ret) {
+		DPU_ERROR("failed to get clocks, ret=%d\n", ret);
+		goto clk_get_error;
+	}
+
+	ret = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
+	if (ret) {
+		DPU_ERROR("failed to set clock rate, ret=%d\n", ret);
+		goto clk_rate_error;
+	}
+
+	dpu_mdss->base.dev = dev;
+	dpu_mdss->base.funcs = &mdss_funcs;
+
+	ret = _dpu_mdss_irq_domain_add(dpu_mdss);
+	if (ret)
+		goto irq_domain_error;
+
+	ret = devm_request_irq(dev->dev, platform_get_irq(pdev, 0),
+			dpu_mdss_irq, 0, "dpu_mdss_isr", dpu_mdss);
+	if (ret) {
+		DPU_ERROR("failed to init irq: %d\n", ret);
+		goto irq_error;
+	}
+
+	pm_runtime_enable(dev->dev);
+
+	pm_runtime_get_sync(dev->dev);
+	dpu_mdss->hwversion = readl_relaxed(dpu_mdss->mmio);
+	pm_runtime_put_sync(dev->dev);
+
+	priv->mdss = &dpu_mdss->base;
+
+	return ret;
+
+irq_error:
+	_dpu_mdss_irq_domain_fini(dpu_mdss);
+irq_domain_error:
+clk_rate_error:
+	msm_dss_put_clk(mp->clk_config, mp->num_clk);
+clk_get_error:
+	devm_kfree(&pdev->dev, mp->clk_config);
+clk_parse_err:
+	if (dpu_mdss->mmio)
+		msm_iounmap(pdev, dpu_mdss->mmio);
+	dpu_mdss->mmio = NULL;
+	return ret;
+}
diff --git a/drivers/gpu/drm/msm/dpu_io_util.c b/drivers/gpu/drm/msm/dpu_io_util.c
index a18bc99..c44f33f 100644
--- a/drivers/gpu/drm/msm/dpu_io_util.c
+++ b/drivers/gpu/drm/msm/dpu_io_util.c
@@ -448,6 +448,63 @@ int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable)
 } /* msm_dss_enable_clk */
 EXPORT_SYMBOL(msm_dss_enable_clk);
 
+int msm_dss_parse_clock(struct platform_device *pdev,
+		struct dss_module_power *mp)
+{
+	u32 i, rc = 0;
+	const char *clock_name;
+	u32 rate = 0, max_rate = 0;
+	int num_clk = 0;
+
+	if (!pdev || !mp)
+		return -EINVAL;
+
+	mp->num_clk = 0;
+	num_clk = of_property_count_strings(pdev->dev.of_node, "clock-names");
+	if (num_clk <= 0) {
+		pr_debug("clocks are not defined\n");
+		return 0;
+	}
+
+	mp->clk_config = devm_kzalloc(&pdev->dev,
+				      sizeof(struct dss_clk) * num_clk,
+				      GFP_KERNEL);
+	if (!mp->clk_config)
+		return -ENOMEM;
+
+	for (i = 0; i < num_clk; i++) {
+		rc = of_property_read_string_index(pdev->dev.of_node,
+						   "clock-names", i,
+						   &clock_name);
+		if (rc)
+			break;
+		strlcpy(mp->clk_config[i].clk_name, clock_name,
+			sizeof(mp->clk_config[i].clk_name));
+
+		rc = of_property_read_u32_index(pdev->dev.of_node,
+						"clock-rate", i,
+						&rate);
+		if (rc)
+			break;
+		mp->clk_config[i].rate = rate;
+		if (!mp->clk_config[i].rate)
+			mp->clk_config[i].type = DSS_CLK_AHB;
+		else
+			mp->clk_config[i].type = DSS_CLK_PCLK;
+
+		rc = of_property_read_u32_index(pdev->dev.of_node,
+						"clock-max-rate", i,
+						&max_rate);
+		if (rc)
+			break;
+		mp->clk_config[i].max_rate = max_rate;
+	}
+
+	if (!rc)
+		mp->num_clk = num_clk;
+
+	return rc;
+}
 
 int dpu_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
 			uint8_t reg_offset, uint8_t *read_buf)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 5d8f1b6..a0e73ea 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -503,7 +503,18 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 	ddev->dev_private = priv;
 	priv->dev = ddev;
 
-	ret = mdp5_mdss_init(ddev);
+	switch (get_mdp_ver(pdev)) {
+	case KMS_MDP5:
+		ret = mdp5_mdss_init(ddev);
+		break;
+	case KMS_DPU:
+		ret = dpu_mdss_init(ddev);
+		break;
+	default:
+		ret = 0;
+		break;
+	}
+
 	if (ret)
 		goto mdss_init_fail;
 
@@ -1539,12 +1550,13 @@ static int add_display_components(struct device *dev,
 	int ret;
 
 	/*
-	 * MDP5 based devices don't have a flat hierarchy. There is a top level
-	 * parent: MDSS, and children: MDP5, DSI, HDMI, eDP etc. Populate the
-	 * children devices, find the MDP5 node, and then add the interfaces
-	 * to our components list.
+	 * MDP5/DPU based devices don't have a flat hierarchy. There is a top
+	 * level parent: MDSS, and children: MDP5/DPU, DSI, HDMI, eDP etc.
+	 * Populate the children devices, find the MDP5/DPU node, and then add
+	 * the interfaces to our components list.
 	 */
-	if (of_device_is_compatible(dev->of_node, "qcom,mdss")) {
+	if (of_device_is_compatible(dev->of_node, "qcom,mdss") ||
+		of_device_is_compatible(dev->of_node, "qcom,dpu-mdss")) {
 		ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
 		if (ret) {
 			dev_err(dev, "failed to populate children devices\n");
@@ -1686,7 +1698,7 @@ static int msm_pdev_remove(struct platform_device *pdev)
 	{ .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 },
 	{ .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 },
 #ifdef CONFIG_DRM_MSM_DPU
-	{ .compatible = "qcom,dpu-kms", .data = (void *)KMS_DPU },
+	{ .compatible = "qcom,dpu-mdss", .data = (void *)KMS_DPU },
 #endif
 	{}
 };
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 90a2521..e8e5e73 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -381,7 +381,7 @@ struct msm_drm_private {
 	/* subordinate devices, if present: */
 	struct platform_device *gpu_pdev;
 
-	/* top level MDSS wrapper device (for MDP5 only) */
+	/* top level MDSS wrapper device (for MDP5/DPU only) */
 	struct msm_mdss *mdss;
 
 	/* possibly this should be in the kms component, but it is
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index 9a7bc7d..5e1de85 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -144,6 +144,7 @@ struct msm_mdss {
 };
 
 int mdp5_mdss_init(struct drm_device *dev);
+int dpu_mdss_init(struct drm_device *dev);
 
 /**
  * Mode Set Utility Functions
diff --git a/include/linux/dpu_io_util.h b/include/linux/dpu_io_util.h
index 7c73899..45e606f 100644
--- a/include/linux/dpu_io_util.h
+++ b/include/linux/dpu_io_util.h
@@ -104,6 +104,8 @@ int msm_dss_config_vreg(struct device *dev, struct dss_vreg *in_vreg,
 void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk);
 int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk);
 int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable);
+int msm_dss_parse_clock(struct platform_device *pdev,
+		struct dss_module_power *mp);
 
 int dpu_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
 		       uint8_t reg_offset, uint8_t *read_buf);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [DPU PATCH v2 04/12] drm/msm/dpu: create new platform driver for dpu device
       [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 14:49   ` Rajesh Yadav
       [not found]     ` <1526050178-31893-5-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
  2018-05-11 14:49   ` [DPU PATCH v2 06/12] drm/msm/dpu: use runtime_pm calls on " Rajesh Yadav
                     ` (6 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: Rajesh Yadav @ 2018-05-11 14:49 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
  Cc: robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw, Rajesh Yadav,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw

Current MSM display controller HW matches a tree like
hierarchy where MDSS top level wrapper is parent device
and mdp5/dpu, dsi, dp are child devices.

Each child device like mdp5, dsi etc. have a separate driver,
but currently dpu handling is tied to a single driver which
was managing both mdss and dpu resources.

Inorder to have the cleaner one to one device and driver
association, this change adds a new platform_driver for dpu
child device node which implements the kms functionality.

The dpu driver implements runtime_pm support for managing clocks
and bus bandwidth etc.

Changes in v2:
	- remove redundant param check from _dpu_kms_hw_destroy (Sean Paul)
	- remove explicit calls to devm_kfree (Sean Paul)
	- merge dpu_init into dpu_bind (Sean Paul)
	- merge dpu_destroy into dpu_unbind (Sean Paul)
	- use %pK for kernel pointer printing (Jordan Crouse)
	- remove explicit devm allocation failure message (Jordan Crouse)

Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 238 +++++++++++++++++++++++++-------
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |   4 +
 drivers/gpu/drm/msm/msm_drv.c           |   2 +
 drivers/gpu/drm/msm/msm_drv.h           |   3 +
 4 files changed, 196 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index e4ab753..85f3dbc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1030,16 +1030,12 @@ static long dpu_kms_round_pixclk(struct msm_kms *kms, unsigned long rate,
 	return rate;
 }
 
-static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms,
-		struct platform_device *pdev)
+static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
 {
 	struct drm_device *dev;
 	struct msm_drm_private *priv;
 	int i;
 
-	if (!dpu_kms || !pdev)
-		return;
-
 	dev = dpu_kms->dev;
 	if (!dev)
 		return;
@@ -1091,15 +1087,15 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms,
 	dpu_kms->core_client = NULL;
 
 	if (dpu_kms->vbif[VBIF_NRT])
-		msm_iounmap(pdev, dpu_kms->vbif[VBIF_NRT]);
+		msm_iounmap(dpu_kms->pdev, dpu_kms->vbif[VBIF_NRT]);
 	dpu_kms->vbif[VBIF_NRT] = NULL;
 
 	if (dpu_kms->vbif[VBIF_RT])
-		msm_iounmap(pdev, dpu_kms->vbif[VBIF_RT]);
+		msm_iounmap(dpu_kms->pdev, dpu_kms->vbif[VBIF_RT]);
 	dpu_kms->vbif[VBIF_RT] = NULL;
 
 	if (dpu_kms->mmio)
-		msm_iounmap(pdev, dpu_kms->mmio);
+		msm_iounmap(dpu_kms->pdev, dpu_kms->mmio);
 	dpu_kms->mmio = NULL;
 
 	dpu_reg_dma_deinit();
@@ -1172,8 +1168,6 @@ int dpu_kms_mmu_attach(struct dpu_kms *dpu_kms, bool secure_only)
 static void dpu_kms_destroy(struct msm_kms *kms)
 {
 	struct dpu_kms *dpu_kms;
-	struct drm_device *dev;
-	struct platform_device *platformdev;
 
 	if (!kms) {
 		DPU_ERROR("invalid kms\n");
@@ -1181,20 +1175,7 @@ static void dpu_kms_destroy(struct msm_kms *kms)
 	}
 
 	dpu_kms = to_dpu_kms(kms);
-	dev = dpu_kms->dev;
-	if (!dev) {
-		DPU_ERROR("invalid device\n");
-		return;
-	}
-
-	platformdev = to_platform_device(dev->dev);
-	if (!platformdev) {
-		DPU_ERROR("invalid platform device\n");
-		return;
-	}
-
-	_dpu_kms_hw_destroy(dpu_kms, platformdev);
-	kfree(dpu_kms);
+	_dpu_kms_hw_destroy(dpu_kms);
 }
 
 static void dpu_kms_preclose(struct msm_kms *kms, struct drm_file *file)
@@ -1550,7 +1531,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 	struct dpu_kms *dpu_kms;
 	struct drm_device *dev;
 	struct msm_drm_private *priv;
-	struct platform_device *platformdev;
 	int i, rc = -EINVAL;
 
 	if (!kms) {
@@ -1565,34 +1545,28 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 		goto end;
 	}
 
-	platformdev = to_platform_device(dev->dev);
-	if (!platformdev) {
-		DPU_ERROR("invalid platform device\n");
-		goto end;
-		}
-
 	priv = dev->dev_private;
 	if (!priv) {
 		DPU_ERROR("invalid private data\n");
 		goto end;
 	}
 
-	dpu_kms->mmio = msm_ioremap(platformdev, "mdp_phys", "mdp_phys");
+	dpu_kms->mmio = msm_ioremap(dpu_kms->pdev, "mdp_phys", "mdp_phys");
 	if (IS_ERR(dpu_kms->mmio)) {
 		rc = PTR_ERR(dpu_kms->mmio);
 		DPU_ERROR("mdp register memory map failed: %d\n", rc);
 		dpu_kms->mmio = NULL;
 		goto error;
 	}
-	DRM_INFO("mapped mdp address space @%p\n", dpu_kms->mmio);
-	dpu_kms->mmio_len = msm_iomap_size(platformdev, "mdp_phys");
+	DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
+	dpu_kms->mmio_len = msm_iomap_size(dpu_kms->pdev, "mdp_phys");
 
 	rc = dpu_dbg_reg_register_base(DPU_DBG_NAME, dpu_kms->mmio,
 			dpu_kms->mmio_len);
 	if (rc)
 		DPU_ERROR("dbg base register kms failed: %d\n", rc);
 
-	dpu_kms->vbif[VBIF_RT] = msm_ioremap(platformdev, "vbif_phys",
+	dpu_kms->vbif[VBIF_RT] = msm_ioremap(dpu_kms->pdev, "vbif_phys",
 								"vbif_phys");
 	if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
 		rc = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
@@ -1600,20 +1574,20 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 		dpu_kms->vbif[VBIF_RT] = NULL;
 		goto error;
 	}
-	dpu_kms->vbif_len[VBIF_RT] = msm_iomap_size(platformdev,
+	dpu_kms->vbif_len[VBIF_RT] = msm_iomap_size(dpu_kms->pdev,
 								"vbif_phys");
 	rc = dpu_dbg_reg_register_base("vbif_rt", dpu_kms->vbif[VBIF_RT],
 				dpu_kms->vbif_len[VBIF_RT]);
 	if (rc)
 		DPU_ERROR("dbg base register vbif_rt failed: %d\n", rc);
 
-	dpu_kms->vbif[VBIF_NRT] = msm_ioremap(platformdev, "vbif_nrt_phys",
+	dpu_kms->vbif[VBIF_NRT] = msm_ioremap(dpu_kms->pdev, "vbif_nrt_phys",
 								"vbif_nrt_phys");
 	if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) {
 		dpu_kms->vbif[VBIF_NRT] = NULL;
 		DPU_DEBUG("VBIF NRT is not defined");
 	} else {
-		dpu_kms->vbif_len[VBIF_NRT] = msm_iomap_size(platformdev,
+		dpu_kms->vbif_len[VBIF_NRT] = msm_iomap_size(dpu_kms->pdev,
 							"vbif_nrt_phys");
 		rc = dpu_dbg_reg_register_base("vbif_nrt",
 				dpu_kms->vbif[VBIF_NRT],
@@ -1624,13 +1598,13 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 	}
 
 #ifdef CONFIG_CHROME_REGDMA
-	dpu_kms->reg_dma = msm_ioremap(platformdev, "regdma_phys",
+	dpu_kms->reg_dma = msm_ioremap(dpu_kms->pdev, "regdma_phys",
 								"regdma_phys");
 	if (IS_ERR(dpu_kms->reg_dma)) {
 		dpu_kms->reg_dma = NULL;
 		DPU_DEBUG("REG_DMA is not defined");
 	} else {
-		dpu_kms->reg_dma_len = msm_iomap_size(platformdev,
+		dpu_kms->reg_dma_len = msm_iomap_size(dpu_kms->pdev,
 								"regdma_phys");
 		rc =  dpu_dbg_reg_register_base("reg_dma",
 				dpu_kms->reg_dma,
@@ -1804,14 +1778,13 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 	dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, false);
 	pm_runtime_put_sync(dev->dev);
 error:
-	_dpu_kms_hw_destroy(dpu_kms, platformdev);
+	_dpu_kms_hw_destroy(dpu_kms);
 end:
 	return rc;
 }
 
 struct msm_kms *dpu_kms_init(struct drm_device *dev)
 {
-	struct platform_device *pdev = to_platform_device(dev->dev);
 	struct msm_drm_private *priv;
 	struct dpu_kms *dpu_kms;
 	int irq;
@@ -1821,24 +1794,187 @@ struct msm_kms *dpu_kms_init(struct drm_device *dev)
 		return ERR_PTR(-EINVAL);
 	}
 
-	irq = platform_get_irq(pdev, 0);
+	priv = dev->dev_private;
+	dpu_kms = to_dpu_kms(priv->kms);
+
+	irq = irq_of_parse_and_map(dpu_kms->pdev->dev.of_node, 0);
 	if (irq < 0) {
 		DPU_ERROR("failed to get irq: %d\n", irq);
 		return ERR_PTR(irq);
 	}
+	dpu_kms->base.irq = irq;
 
-	priv = dev->dev_private;
+	return &dpu_kms->base;
+}
 
-	dpu_kms = kzalloc(sizeof(*dpu_kms), GFP_KERNEL);
-	if (!dpu_kms) {
-		DPU_ERROR("failed to allocate dpu kms\n");
-		return ERR_PTR(-ENOMEM);
+static int dpu_bind(struct device *dev, struct device *master, void *data)
+{
+	struct drm_device *ddev = dev_get_drvdata(master);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct msm_drm_private *priv = ddev->dev_private;
+	struct dpu_kms *dpu_kms;
+	struct dss_module_power *mp;
+	int ret = 0;
+
+	dpu_kms = devm_kzalloc(&pdev->dev, sizeof(*dpu_kms), GFP_KERNEL);
+	if (!dpu_kms)
+		return -ENOMEM;
+
+	mp = &dpu_kms->mp;
+	ret = msm_dss_parse_clock(pdev, mp);
+	if (ret) {
+		DPU_ERROR("failed to parse clocks, ret=%d\n", ret);
+		return ret;
+	}
+
+	ret = msm_dss_get_clk(&pdev->dev, mp->clk_config, mp->num_clk);
+	if (ret) {
+		pr_err("failed to get clocks, ret=%d\n", ret);
+		goto clk_get_error;
+	}
+
+	ret = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
+	if (ret) {
+		pr_err("failed to set clock rate, ret=%d\n", ret);
+		goto clk_rate_error;
 	}
 
+	platform_set_drvdata(pdev, dpu_kms);
+
 	msm_kms_init(&dpu_kms->base, &kms_funcs);
-	dpu_kms->dev = dev;
-	dpu_kms->base.irq = irq;
+	dpu_kms->dev = ddev;
+	dpu_kms->pdev = pdev;
 
-	return &dpu_kms->base;
+	pm_runtime_enable(&pdev->dev);
+	dpu_kms->rpm_enabled = true;
+
+	priv->kms = &dpu_kms->base;
+	return ret;
+
+clk_rate_error:
+	msm_dss_put_clk(mp->clk_config, mp->num_clk);
+clk_get_error:
+	devm_kfree(&pdev->dev, mp->clk_config);
+	mp->num_clk = 0;
+	return ret;
 }
 
+static void dpu_unbind(struct device *dev, struct device *master, void *data)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
+	struct dss_module_power *mp = &dpu_kms->mp;
+
+	msm_dss_put_clk(mp->clk_config, mp->num_clk);
+	devm_kfree(&pdev->dev, mp->clk_config);
+	mp->num_clk = 0;
+
+	if (dpu_kms->rpm_enabled)
+		pm_runtime_disable(&pdev->dev);
+}
+
+static const struct component_ops dpu_ops = {
+	.bind   = dpu_bind,
+	.unbind = dpu_unbind,
+};
+
+static int dpu_dev_probe(struct platform_device *pdev)
+{
+	return component_add(&pdev->dev, &dpu_ops);
+}
+
+static int dpu_dev_remove(struct platform_device *pdev)
+{
+	component_del(&pdev->dev, &dpu_ops);
+	return 0;
+}
+
+static int dpu_runtime_suspend(struct device *dev)
+{
+	int rc = -1;
+	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;
+	if (!ddev) {
+		DPU_ERROR("invalid drm_device\n");
+		goto exit;
+	}
+	priv = ddev->dev_private;
+
+	rc = dpu_power_resource_enable(&priv->phandle,
+		dpu_kms->core_client, false);
+	if (rc)
+		DPU_ERROR("resource disable failed: %d\n", rc);
+
+	rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
+	if (rc)
+		DPU_ERROR("clock disable failed rc:%d\n", rc);
+
+exit:
+	return rc;
+}
+
+static int dpu_runtime_resume(struct device *dev)
+{
+	int rc = -1;
+	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;
+	if (!ddev) {
+		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) {
+		DPU_ERROR("clock enable failed rc:%d\n", rc);
+		goto exit;
+	}
+
+	rc = dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client,
+		true);
+	if (rc)
+		DPU_ERROR("resource enable failed: %d\n", rc);
+
+exit:
+	return rc;
+}
+
+static const struct dev_pm_ops dpu_pm_ops = {
+	SET_RUNTIME_PM_OPS(dpu_runtime_suspend, dpu_runtime_resume, NULL)
+};
+
+static const struct of_device_id dpu_dt_match[] = {
+	{ .compatible = "qcom,dpu", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, dpu_dt_match);
+
+static struct platform_driver dpu_driver = {
+	.probe = dpu_dev_probe,
+	.remove = dpu_dev_remove,
+	.driver = {
+		.name = "msm_dpu",
+		.of_match_table = dpu_dt_match,
+		.pm = &dpu_pm_ops,
+	},
+};
+
+void __init msm_dpu_register(void)
+{
+	platform_driver_register(&dpu_driver);
+}
+
+void __exit msm_dpu_unregister(void)
+{
+	platform_driver_unregister(&dpu_driver);
+}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index a1c0910..3c69921 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -200,6 +200,10 @@ struct dpu_kms {
 	struct dpu_hw_mdp *hw_mdp;
 
 	bool has_danger_ctrl;
+
+	struct platform_device *pdev;
+	bool rpm_enabled;
+	struct dss_module_power mp;
 };
 
 struct vsync_info {
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index a0e73ea..5470529 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1731,6 +1731,7 @@ static int __init msm_drm_register(void)
 
 	DBG("init");
 	msm_mdp_register();
+	msm_dpu_register();
 	msm_dsi_register();
 	msm_edp_register();
 	msm_hdmi_register();
@@ -1747,6 +1748,7 @@ static void __exit msm_drm_unregister(void)
 	msm_edp_unregister();
 	msm_dsi_unregister();
 	msm_mdp_unregister();
+	msm_dpu_unregister();
 }
 
 module_init(msm_drm_register);
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index e8e5e73..22a3096 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -682,6 +682,9 @@ static inline int msm_dsi_modeset_init(struct msm_dsi *msm_dsi,
 void __init msm_mdp_register(void);
 void __exit msm_mdp_unregister(void);
 
+void __init msm_dpu_register(void);
+void __exit msm_dpu_unregister(void);
+
 #ifdef CONFIG_DEBUG_FS
 void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m);
 void msm_gem_describe_objects(struct list_head *list, struct seq_file *m);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [DPU PATCH v2 05/12] drm/msm/dpu: update dpu sub-block offsets wrt dpu base address
  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 ` Rajesh Yadav
  2 siblings, 0 replies; 24+ messages in thread
From: Rajesh Yadav @ 2018-05-11 14:49 UTC (permalink / raw)
  To: dri-devel, freedreno, linux-arm-msm; +Cc: Rajesh Yadav, hoegsberg

The dpu sub-block offsets were defined wrt mdss base address
instead of dpu base address.
Since, dpu is now defined as a separate device, update hw catalog
offsets for all dpu sub blocks wrt dpu base address.

Changes in v2:
	- none

Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 68 +++++++++++------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 18 +++---
 2 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index c5b370f..2fd3254 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -80,7 +80,7 @@
 static struct dpu_mdp_cfg sdm845_mdp[] = {
 	{
 	.name = "top_0", .id = MDP_TOP,
-	.base = 0x1000, .len = 0x45C,
+	.base = 0x0, .len = 0x45C,
 	.features = 0,
 	.highest_bank_bit = 0x2,
 	.has_dest_scaler = true,
@@ -111,27 +111,27 @@
 static struct dpu_ctl_cfg sdm845_ctl[] = {
 	{
 	.name = "ctl_0", .id = CTL_0,
-	.base = 0x2000, .len = 0xE4,
+	.base = 0x1000, .len = 0xE4,
 	.features = BIT(DPU_CTL_SPLIT_DISPLAY)
 	},
 	{
 	.name = "ctl_1", .id = CTL_1,
-	.base = 0x2200, .len = 0xE4,
+	.base = 0x1200, .len = 0xE4,
 	.features = BIT(DPU_CTL_SPLIT_DISPLAY)
 	},
 	{
 	.name = "ctl_2", .id = CTL_2,
-	.base = 0x2400, .len = 0xE4,
+	.base = 0x1400, .len = 0xE4,
 	.features = 0
 	},
 	{
 	.name = "ctl_3", .id = CTL_3,
-	.base = 0x2600, .len = 0xE4,
+	.base = 0x1600, .len = 0xE4,
 	.features = 0
 	},
 	{
 	.name = "ctl_4", .id = CTL_4,
-	.base = 0x2800, .len = 0xE4,
+	.base = 0x1800, .len = 0xE4,
 	.features = 0
 	},
 };
@@ -211,21 +211,21 @@
 	}
 
 static struct dpu_sspp_cfg sdm845_sspp[] = {
-	SSPP_VIG_BLK("sspp_0", SSPP_VIG0, 0x5000,
+	SSPP_VIG_BLK("sspp_0", SSPP_VIG0, 0x4000,
 		sdm845_vig_sblk_0, 0, DPU_CLK_CTRL_VIG0),
-	SSPP_VIG_BLK("sspp_1", SSPP_VIG1, 0x7000,
+	SSPP_VIG_BLK("sspp_1", SSPP_VIG1, 0x6000,
 		sdm845_vig_sblk_1, 4, DPU_CLK_CTRL_VIG1),
-	SSPP_VIG_BLK("sspp_2", SSPP_VIG2, 0x9000,
+	SSPP_VIG_BLK("sspp_2", SSPP_VIG2, 0x8000,
 		sdm845_vig_sblk_2, 8, DPU_CLK_CTRL_VIG2),
-	SSPP_VIG_BLK("sspp_3", SSPP_VIG3, 0xb000,
+	SSPP_VIG_BLK("sspp_3", SSPP_VIG3, 0xa000,
 		sdm845_vig_sblk_3, 12, DPU_CLK_CTRL_VIG3),
-	SSPP_DMA_BLK("sspp_8", SSPP_DMA0, 0x25000,
+	SSPP_DMA_BLK("sspp_8", SSPP_DMA0, 0x24000,
 		sdm845_dma_sblk_0, 1, DPU_CLK_CTRL_DMA0),
-	SSPP_DMA_BLK("sspp_9", SSPP_DMA1, 0x27000,
+	SSPP_DMA_BLK("sspp_9", SSPP_DMA1, 0x26000,
 		sdm845_dma_sblk_1, 5, DPU_CLK_CTRL_DMA1),
-	SSPP_DMA_BLK("sspp_10", SSPP_DMA2, 0x29000,
+	SSPP_DMA_BLK("sspp_10", SSPP_DMA2, 0x28000,
 		sdm845_dma_sblk_2, 9, DPU_CLK_CTRL_CURSOR0),
-	SSPP_DMA_BLK("sspp_11", SSPP_DMA3, 0x2b000,
+	SSPP_DMA_BLK("sspp_11", SSPP_DMA3, 0x2a000,
 		sdm845_dma_sblk_3, 13, DPU_CLK_CTRL_CURSOR1),
 };
 
@@ -252,17 +252,17 @@
 	.lm_pair_mask = (1 << _lmpair) \
 	}
 static struct dpu_lm_cfg sdm845_lm[] = {
-	LM_BLK("lm_0", LM_0, 0x45000, DSPP_0,
+	LM_BLK("lm_0", LM_0, 0x44000, DSPP_0,
 		DS_0, PINGPONG_0, LM_1),
-	LM_BLK("lm_1", LM_1, 0x46000, DSPP_1,
+	LM_BLK("lm_1", LM_1, 0x45000, DSPP_1,
 		DS_1, PINGPONG_1, LM_0),
-	LM_BLK("lm_2", LM_2, 0x47000, DSPP_2,
+	LM_BLK("lm_2", LM_2, 0x46000, DSPP_2,
 		DS_MAX, PINGPONG_2, LM_5),
 	LM_BLK("lm_3", LM_3, 0x0, DSPP_MAX,
 		DS_MAX, PINGPONG_MAX, 0),
 	LM_BLK("lm_4", LM_4, 0x0, DSPP_MAX,
 		DS_MAX, PINGPONG_MAX, 0),
-	LM_BLK("lm_5", LM_5, 0x4a000, DSPP_3,
+	LM_BLK("lm_5", LM_5, 0x49000, DSPP_3,
 		DS_MAX, PINGPONG_3, LM_2),
 };
 
@@ -270,7 +270,7 @@
  * DSPP sub blocks config
  *************************************************************/
 static struct dpu_dspp_top_cfg sdm845_dspp_top = {
-	.name = "dspp_top", .base = 0x1300, .len = 0xc
+	.name = "dspp_top", .base = 0x300, .len = 0xc
 };
 
 static const struct dpu_dspp_sub_blks sdm845_dspp_sblk = {
@@ -304,10 +304,10 @@
 	}
 
 static struct dpu_dspp_cfg sdm845_dspp[] = {
-	DSPP_BLK("dspp_0", DSPP_0, 0x55000),
-	DSPP_BLK("dspp_1", DSPP_1, 0x57000),
-	DSPP_BLK("dspp_2", DSPP_2, 0x59000),
-	DSPP_BLK("dspp_3", DSPP_3, 0x5b000),
+	DSPP_BLK("dspp_0", DSPP_0, 0x54000),
+	DSPP_BLK("dspp_1", DSPP_1, 0x56000),
+	DSPP_BLK("dspp_2", DSPP_2, 0x58000),
+	DSPP_BLK("dspp_3", DSPP_3, 0x5a000),
 };
 
 /*************************************************************
@@ -315,7 +315,7 @@
  *************************************************************/
 static const struct dpu_ds_top_cfg sdm845_ds_top = {
 	.name = "ds_top_0", .id = DS_TOP,
-	.base = 0x61000, .len = 0xc,
+	.base = 0x60000, .len = 0xc,
 	.maxinputwidth = DEFAULT_DPU_LINE_WIDTH,
 	.maxoutputwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 	.maxupscale = MAX_UPSCALE_RATIO,
@@ -365,10 +365,10 @@
 	}
 
 static struct dpu_pingpong_cfg sdm845_pp[] = {
-	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x71000),
-	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x71800),
-	PP_BLK("pingpong_2", PINGPONG_2, 0x72000),
-	PP_BLK("pingpong_3", PINGPONG_3, 0x72800),
+	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000),
+	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800),
+	PP_BLK("pingpong_2", PINGPONG_2, 0x71000),
+	PP_BLK("pingpong_3", PINGPONG_3, 0x71800),
 };
 
 /*************************************************************
@@ -384,10 +384,10 @@
 	}
 
 static struct dpu_intf_cfg sdm845_intf[] = {
-	INTF_BLK("intf_0", INTF_0, 0x6B000, INTF_DP, 0),
-	INTF_BLK("intf_1", INTF_1, 0x6B800, INTF_DSI, 0),
-	INTF_BLK("intf_2", INTF_2, 0x6C000, INTF_DSI, 1),
-	INTF_BLK("intf_3", INTF_3, 0x6C800, INTF_DP, 1),
+	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0),
+	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0),
+	INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1),
+	INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1),
 };
 
 /*************************************************************
@@ -401,7 +401,7 @@
 static struct dpu_wb_cfg sdm845_wb[] = {
 	{
 	.name = "wb_2", .id = WB_2,
-	.base = 0x66000, .len = 0x2c8,
+	.base = 0x65000, .len = 0x2c8,
 	.features = WB2_SDM845_MASK,
 	.sblk = &sdm845_wb2_sblk,
 	.format_list = wb2_formats,
@@ -414,7 +414,7 @@
 static struct dpu_cdm_cfg sdm845_cdm[] = {
 	{
 	.name = "cdm_0", .id = CDM_0,
-	.base = 0x7A200, .len = 0x224,
+	.base = 0x79200, .len = 0x224,
 	.features = 0,
 	.intf_connect = BIT(INTF_3),
 	.wb_connect = BIT(WB_2)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
index 73f084c..a7bced2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
@@ -20,16 +20,16 @@
 
 /**
  * Register offsets in MDSS register file for the interrupt registers
- * w.r.t. to the MDSS base
+ * w.r.t. to the MDP base
  */
-#define MDP_SSPP_TOP0_OFF		0x1000
-#define MDP_INTF_0_OFF			0x6B000
-#define MDP_INTF_1_OFF			0x6B800
-#define MDP_INTF_2_OFF			0x6C000
-#define MDP_INTF_3_OFF			0x6C800
-#define MDP_INTF_4_OFF			0x6D000
-#define MDP_AD4_0_OFF			0x7D000
-#define MDP_AD4_1_OFF			0x7E000
+#define MDP_SSPP_TOP0_OFF		0x0
+#define MDP_INTF_0_OFF			0x6A000
+#define MDP_INTF_1_OFF			0x6A800
+#define MDP_INTF_2_OFF			0x6B000
+#define MDP_INTF_3_OFF			0x6B800
+#define MDP_INTF_4_OFF			0x6C000
+#define MDP_AD4_0_OFF			0x7C000
+#define MDP_AD4_1_OFF			0x7D000
 #define MDP_AD4_INTR_EN_OFF		0x41c
 #define MDP_AD4_INTR_CLEAR_OFF		0x424
 #define MDP_AD4_INTR_STATUS_OFF		0x420
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [DPU PATCH v2 06/12] drm/msm/dpu: use runtime_pm calls on dpu device
       [not found] ` <1526050178-31893-1-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
                     ` (2 preceding siblings ...)
  2018-05-11 14:49   ` [DPU PATCH v2 04/12] drm/msm/dpu: create new platform driver for dpu device Rajesh Yadav
@ 2018-05-11 14:49   ` 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
                     ` (5 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Rajesh Yadav @ 2018-05-11 14:49 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
  Cc: robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw, Rajesh Yadav,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw

The dpu driver implements runtime_pm support for managing
dpu specific resources like - clocks, bus bandwidth etc.

Use pm_runtime_get/put_sync calls on dpu device.

The common clocks and power management for all child nodes
(mdp5/dpu, dsi, dp etc) is done by parent MDSS device/driver
via runtime_pm due to parent child relationship.

Changes in v2:
	- none

Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c |  8 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c     | 12 ++++----
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c  | 16 +++++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c      | 45 +++++++---------------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c    |  6 ++--
 5 files changed, 31 insertions(+), 56 deletions(-)

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 977adc4..5c5cc56 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
@@ -452,10 +452,10 @@ void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms)
 	}
 	priv = dpu_kms->dev->dev_private;
 
-	dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, true);
+	pm_runtime_get_sync(&dpu_kms->pdev->dev);
 	dpu_clear_all_irqs(dpu_kms);
 	dpu_disable_all_irqs(dpu_kms);
-	dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, false);
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
 
 	spin_lock_init(&dpu_kms->irq_obj.cb_lock);
 
@@ -496,7 +496,7 @@ void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms)
 	}
 	priv = dpu_kms->dev->dev_private;
 
-	dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, true);
+	pm_runtime_get_sync(&dpu_kms->pdev->dev);
 	for (i = 0; i < dpu_kms->irq_obj.total_irqs; i++)
 		if (atomic_read(&dpu_kms->irq_obj.enable_counts[i]) ||
 				!list_empty(&dpu_kms->irq_obj.irq_cb_tbl[i]))
@@ -504,7 +504,7 @@ void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms)
 
 	dpu_clear_all_irqs(dpu_kms);
 	dpu_disable_all_irqs(dpu_kms);
-	dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, false);
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
 
 	kfree(dpu_kms->irq_obj.irq_cb_tbl);
 	kfree(dpu_kms->irq_obj.enable_counts);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 48920b05..e2d2e32 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -86,8 +86,12 @@ static inline int _dpu_crtc_power_enable(struct dpu_crtc *dpu_crtc, bool enable)
 
 	dpu_kms = to_dpu_kms(priv->kms);
 
-	return dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client,
-									enable);
+	if (enable)
+		pm_runtime_get_sync(&dpu_kms->pdev->dev);
+	else
+		pm_runtime_put_sync(&dpu_kms->pdev->dev);
+
+	return 0;
 }
 
 /**
@@ -2250,7 +2254,6 @@ static int _dpu_crtc_vblank_enable_no_lock(
 
 		/* drop lock since power crtc cb may try to re-acquire lock */
 		mutex_unlock(&dpu_crtc->crtc_lock);
-		pm_runtime_get_sync(dev->dev);
 		ret = _dpu_crtc_power_enable(dpu_crtc, true);
 		mutex_lock(&dpu_crtc->crtc_lock);
 		if (ret)
@@ -2580,7 +2583,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc)
 	/* disable clk & bw control until clk & bw properties are set */
 	cstate->bw_control = false;
 	cstate->bw_split_vote = false;
-	pm_runtime_put_sync(crtc->dev->dev);
 
 	mutex_unlock(&dpu_crtc->crtc_lock);
 }
@@ -2611,8 +2613,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
 		return;
 	}
 
-	pm_runtime_get_sync(crtc->dev->dev);
-
 	drm_for_each_encoder(encoder, crtc->dev) {
 		if (encoder->crtc != crtc)
 			continue;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 4386360..298a6ef 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -268,8 +268,12 @@ static inline int _dpu_encoder_power_enable(struct dpu_encoder_virt *dpu_enc,
 
 	dpu_kms = to_dpu_kms(priv->kms);
 
-	return dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client,
-									enable);
+	if (enable)
+		pm_runtime_get_sync(&dpu_kms->pdev->dev);
+	else
+		pm_runtime_put_sync(&dpu_kms->pdev->dev);
+
+	return 0;
 }
 
 void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys *phys_enc,
@@ -796,10 +800,8 @@ static void _dpu_encoder_resource_control_helper(struct drm_encoder *drm_enc,
 	}
 
 	if (enable) {
-		pm_runtime_get_sync(dpu_kms->dev->dev);
 		/* enable DPU core clks */
-		dpu_power_resource_enable(&priv->phandle,
-				dpu_kms->core_client, true);
+		pm_runtime_get_sync(&dpu_kms->pdev->dev);
 
 		/* enable all the irq */
 		_dpu_encoder_irq_control(drm_enc, true);
@@ -809,9 +811,7 @@ static void _dpu_encoder_resource_control_helper(struct drm_encoder *drm_enc,
 		_dpu_encoder_irq_control(drm_enc, false);
 
 		/* disable DPU core clks */
-		dpu_power_resource_enable(&priv->phandle,
-				dpu_kms->core_client, false);
-		pm_runtime_put_sync(dpu_kms->dev->dev);
+		pm_runtime_put_sync(&dpu_kms->pdev->dev);
 	}
 
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 85f3dbc..cda4d12 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -100,8 +100,7 @@ static int _dpu_danger_signal_status(struct seq_file *s,
 	priv = kms->dev->dev_private;
 	memset(&status, 0, sizeof(struct dpu_danger_safe_status));
 
-	pm_runtime_get_sync(kms->dev->dev);
-	dpu_power_resource_enable(&priv->phandle, kms->core_client, true);
+	pm_runtime_get_sync(&kms->pdev->dev);
 	if (danger_status) {
 		seq_puts(s, "\nDanger signal status:\n");
 		if (kms->hw_mdp->ops.get_danger_status)
@@ -113,8 +112,7 @@ static int _dpu_danger_signal_status(struct seq_file *s,
 			kms->hw_mdp->ops.get_danger_status(kms->hw_mdp,
 					&status);
 	}
-	dpu_power_resource_enable(&priv->phandle, kms->core_client, false);
-	pm_runtime_put_sync(kms->dev->dev);
+	pm_runtime_put_sync(&kms->pdev->dev);
 
 	seq_printf(s, "MDP     :  0x%x\n", status.mdp);
 
@@ -215,11 +213,7 @@ static int _dpu_debugfs_show_regset32(struct seq_file *s, void *data)
 			seq_puts(s, "         ");
 	}
 
-	if (dpu_power_resource_enable(&priv->phandle,
-				dpu_kms->core_client, true)) {
-		seq_puts(s, "failed to enable dpu clocks\n");
-		return 0;
-	}
+	pm_runtime_get_sync(&dpu_kms->pdev->dev);
 
 	/* main register output */
 	for (i = 0; i < regset->blk_len; i += 4) {
@@ -229,7 +223,7 @@ static int _dpu_debugfs_show_regset32(struct seq_file *s, void *data)
 		seq_printf(s, " %08x", readl_relaxed(base + i));
 	}
 	seq_puts(s, "\n");
-	dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, false);
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
 
 	return 0;
 }
@@ -334,20 +328,12 @@ static void _dpu_debugfs_destroy(struct dpu_kms *dpu_kms)
 
 static int dpu_kms_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
 {
-	int ret;
-
-	pm_runtime_get_sync(crtc->dev->dev);
-	ret = dpu_crtc_vblank(crtc, true);
-	pm_runtime_put_sync(crtc->dev->dev);
-
-	return ret;
+	return dpu_crtc_vblank(crtc, true);
 }
 
 static void dpu_kms_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
 {
-	pm_runtime_get_sync(crtc->dev->dev);
 	dpu_crtc_vblank(crtc, false);
-	pm_runtime_put_sync(crtc->dev->dev);
 }
 
 static void dpu_kms_wait_for_frame_transfer_complete(struct msm_kms *kms,
@@ -409,8 +395,7 @@ static void dpu_kms_prepare_commit(struct msm_kms *kms,
 	if (!dev || !dev->dev_private)
 		return;
 	priv = dev->dev_private;
-	pm_runtime_get_sync(dev->dev);
-	dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, true);
+	pm_runtime_get_sync(&dpu_kms->pdev->dev);
 
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
 		if (encoder->crtc != NULL)
@@ -474,8 +459,7 @@ static void dpu_kms_complete_commit(struct msm_kms *kms,
 	for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i)
 		dpu_crtc_complete_commit(crtc, old_crtc_state);
 
-	dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, false);
-	pm_runtime_put_sync(dpu_kms->dev->dev);
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
 
 	DPU_EVT32_VERBOSE(DPU_EVTLOG_FUNC_EXIT);
 }
@@ -1624,13 +1608,8 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 		dpu_kms->core_client = NULL;
 		goto error;
 	}
-	pm_runtime_get_sync(dev->dev);
-	rc = dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client,
-		true);
-	if (rc) {
-		DPU_ERROR("resource enable failed: %d\n", rc);
-		goto error;
-	}
+
+	pm_runtime_get_sync(&dpu_kms->pdev->dev);
 
 	_dpu_kms_core_hw_rev_init(dpu_kms);
 
@@ -1765,8 +1744,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 			DPU_POWER_EVENT_POST_ENABLE,
 			dpu_kms_handle_power_event, dpu_kms, "kms");
 
-	dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, false);
-	pm_runtime_put_sync(dev->dev);
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
 
 	return 0;
 
@@ -1775,8 +1753,7 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
 hw_intr_init_err:
 perf_err:
 power_error:
-	dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, false);
-	pm_runtime_put_sync(dev->dev);
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
 error:
 	_dpu_kms_hw_destroy(dpu_kms);
 end:
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index ba5230d..cf6c3fd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -476,11 +476,9 @@ int dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
 	if (!pdpu->is_rt_pipe)
 		goto end;
 
-	dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, true);
-
+	pm_runtime_get_sync(&dpu_kms->pdev->dev);
 	_dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL);
-
-	dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, false);
+	pm_runtime_put_sync(&dpu_kms->pdev->dev);
 
 end:
 	return 0;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [DPU PATCH v2 07/12] drm/msm/dpu: remove clock management code from dpu_power_handle
       [not found] ` <1526050178-31893-1-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
                     ` (3 preceding siblings ...)
  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   ` Rajesh Yadav
       [not found]     ` <1526050178-31893-8-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
  2018-05-11 14:49   ` [DPU PATCH v2 08/12] drm/msm/dpu: remove power " Rajesh Yadav
                     ` (4 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: Rajesh Yadav @ 2018-05-11 14:49 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
  Cc: robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw, Rajesh Yadav,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw

MDSS and dpu drivers manage their respective clocks via
runtime_pm. Remove custom clock management code from
dpu_power_handle.

Also dpu core clock management code is restricted to
dpu_core_perf module.

Changes in v2:
	- remove local variable to hold and return error code
	  in _dpu_core_perf_set_core_clk_rate() instead return
	  retcode directly from msm_dss_clk_set_rate() call (Sean Paul)
	- dpu_core_perf_init() is called from dpu_kms_hw_init() and
	  most of the params passed are already validated so remove
	  redundant checks from dpu_core_perf_init() (Sean Paul)
	- return &mp->clk_config[i] directly to avoid local variable
	  in _dpu_kms_get_clk() (Sean Paul)
	- invert conditional check to eliminate local rate variable
	  from dpu_kms_get_clk_rate() (Sean Paul)
	- remove end label from dpu_power_resource_init() and return
	  directly on dpu_power_parse_dt_supply() failure as no cleanup
	  is needed (Sean Paul)
	- remove checks for vtotal and vrefresh from
 	  dpu_encoder_phys_cmd_tearcheck_config() as they should be
	  valid in mode_set call (Sean Paul)

Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c      |  41 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h      |   8 +-
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c   |   9 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c            |  28 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h            |   9 +
 drivers/gpu/drm/msm/dpu_power_handle.c             | 196 +--------------------
 drivers/gpu/drm/msm/dpu_power_handle.h             |  40 -----
 7 files changed, 63 insertions(+), 268 deletions(-)

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 981f77f..5b79077 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -365,6 +365,17 @@ void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc)
 	}
 }
 
+static int _dpu_core_perf_set_core_clk_rate(struct dpu_kms *kms, u64 rate)
+{
+	struct dss_clk *core_clk = kms->perf.core_clk;
+
+	if (core_clk->max_rate && (rate > core_clk->max_rate))
+		rate = core_clk->max_rate;
+
+	core_clk->rate = rate;
+	return msm_dss_clk_set_rate(core_clk, 1);
+}
+
 static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms)
 {
 	u64 clk_rate = kms->perf.perf_tune.min_core_clk;
@@ -376,7 +387,8 @@ static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms)
 			dpu_cstate = to_dpu_crtc_state(crtc->state);
 			clk_rate = max(dpu_cstate->new_perf.core_clk_rate,
 							clk_rate);
-			clk_rate = clk_round_rate(kms->perf.core_clk, clk_rate);
+			clk_rate = clk_round_rate(kms->perf.core_clk->clk,
+					clk_rate);
 		}
 	}
 
@@ -484,15 +496,11 @@ void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
 
 		DPU_EVT32(kms->dev, stop_req, clk_rate);
 
-		/* Temp change to avoid crash in clk_set_rate API. */
-#ifdef QCOM_DPU_SET_CLK
-		if (dpu_power_clk_set_rate(&priv->phandle,
-					   kms->perf.clk_name, clk_rate)) {
+		if (_dpu_core_perf_set_core_clk_rate(kms, clk_rate)) {
 			DPU_ERROR("failed to set %s clock rate %llu\n",
-					kms->perf.clk_name, clk_rate);
+					kms->perf.core_clk->clk_name, clk_rate);
 			return;
 		}
-#endif
 
 		kms->perf.core_clk_rate = clk_rate;
 		DPU_DEBUG("update clk rate = %lld HZ\n", clk_rate);
@@ -656,7 +664,6 @@ void dpu_core_perf_destroy(struct dpu_core_perf *perf)
 	dpu_core_perf_debugfs_destroy(perf);
 	perf->max_core_clk_rate = 0;
 	perf->core_clk = NULL;
-	perf->clk_name = NULL;
 	perf->phandle = NULL;
 	perf->catalog = NULL;
 	perf->dev = NULL;
@@ -667,9 +674,9 @@ int dpu_core_perf_init(struct dpu_core_perf *perf,
 		struct dpu_mdss_cfg *catalog,
 		struct dpu_power_handle *phandle,
 		struct dpu_power_client *pclient,
-		char *clk_name)
+		struct dss_clk *core_clk)
 {
-	if (!perf || !dev || !catalog || !phandle || !pclient || !clk_name) {
+	if (!pclient) {
 		DPU_ERROR("invalid parameters\n");
 		return -EINVAL;
 	}
@@ -678,23 +685,13 @@ int dpu_core_perf_init(struct dpu_core_perf *perf,
 	perf->catalog = catalog;
 	perf->phandle = phandle;
 	perf->pclient = pclient;
-	perf->clk_name = clk_name;
-
-	perf->core_clk = dpu_power_clk_get_clk(phandle, clk_name);
-	if (!perf->core_clk) {
-		DPU_ERROR("invalid core clk\n");
-		goto err;
-	}
+	perf->core_clk = core_clk;
 
-	perf->max_core_clk_rate = dpu_power_clk_get_max_rate(phandle, clk_name);
+	perf->max_core_clk_rate = core_clk->max_rate;
 	if (!perf->max_core_clk_rate) {
 		DPU_DEBUG("optional max core clk rate, use default\n");
 		perf->max_core_clk_rate = DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE;
 	}
 
 	return 0;
-
-err:
-	dpu_core_perf_destroy(perf);
-	return -ENODEV;
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
index 1965ff5..9c1a719 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
@@ -54,7 +54,6 @@ struct dpu_core_perf_tune {
  * @catalog: Pointer to catalog configuration
  * @phandle: Pointer to power handler
  * @pclient: Pointer to power client
- * @clk_name: core clock name
  * @core_clk: Pointer to core clock structure
  * @core_clk_rate: current core clock rate
  * @max_core_clk_rate: maximum allowable core clock rate
@@ -70,8 +69,7 @@ struct dpu_core_perf {
 	struct dpu_mdss_cfg *catalog;
 	struct dpu_power_handle *phandle;
 	struct dpu_power_client *pclient;
-	char *clk_name;
-	struct clk *core_clk;
+	struct dss_clk *core_clk;
 	u64 core_clk_rate;
 	u64 max_core_clk_rate;
 	struct dpu_core_perf_tune perf_tune;
@@ -118,14 +116,14 @@ void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
  * @catalog: Pointer to catalog
  * @phandle: Pointer to power handle
  * @pclient: Pointer to power client
- * @clk_name: core clock name
+ * @core_clk: pointer to core clock
  */
 int dpu_core_perf_init(struct dpu_core_perf *perf,
 		struct drm_device *dev,
 		struct dpu_mdss_cfg *catalog,
 		struct dpu_power_handle *phandle,
 		struct dpu_power_client *pclient,
-		char *clk_name);
+		struct dss_clk *core_clk);
 
 /**
  * dpu_core_perf_debugfs_init - initialize debugfs for core performance context
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index 072939c..388de38 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -428,11 +428,10 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
 	 * vsync_count is ratio of MDP VSYNC clock frequency to LCD panel
 	 * frequency divided by the no. of rows (lines) in the LCDpanel.
 	 */
-	vsync_hz = dpu_power_clk_get_rate(&priv->phandle, "vsync_clk");
-	if (!vsync_hz || !mode->vtotal || !mode->vrefresh) {
-		DPU_DEBUG_CMDENC(cmd_enc,
-			"invalid params - vsync_hz %u vtot %u vrefresh %u\n",
-			vsync_hz, mode->vtotal, mode->vrefresh);
+	vsync_hz = dpu_kms_get_clk_rate(dpu_kms, "vsync_clk");
+	if (vsync_hz <= 0) {
+		DPU_DEBUG_CMDENC(cmd_enc, "invalid - vsync_hz %u\n",
+				 vsync_hz);
 		return;
 	}
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index cda4d12..349bda5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1499,6 +1499,31 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms)
 	return ret;
 }
 
+static struct dss_clk *_dpu_kms_get_clk(struct dpu_kms *dpu_kms,
+		char *clock_name)
+{
+	struct dss_module_power *mp = &dpu_kms->mp;
+	int i;
+
+	for (i = 0; i < mp->num_clk; i++) {
+		if (!strcmp(mp->clk_config[i].clk_name, clock_name))
+			return &mp->clk_config[i];
+	}
+
+	return NULL;
+}
+
+u64 dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name)
+{
+	struct dss_clk *clk;
+
+	clk = _dpu_kms_get_clk(dpu_kms, clock_name);
+	if (!clk)
+		return -EINVAL;
+
+	return clk_get_rate(clk->clk);
+}
+
 static void dpu_kms_handle_power_event(u32 event_type, void *usr)
 {
 	struct dpu_kms *dpu_kms = usr;
@@ -1696,7 +1721,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, priv->pclient, "core_clk");
+			&priv->phandle, priv->pclient,
+			_dpu_kms_get_clk(dpu_kms, "core_clk"));
 	if (rc) {
 		DPU_ERROR("failed to init perf %d\n", rc);
 		goto perf_err;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 3c69921..a8255fe 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -537,4 +537,13 @@ struct dpu_kms_fbo *dpu_kms_fbo_alloc(struct drm_device *dev,
 
 void dpu_kms_encoder_enable(struct drm_encoder *encoder);
 
+/**
+ * dpu_kms_get_clk_rate() - get the clock rate
+ * @dpu_kms:  poiner to dpu_kms structure
+ * @clock_name: clock name to get the rate
+ *
+ * Return: current clock rate
+ */
+u64 dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name);
+
 #endif /* __dpu_kms_H__ */
diff --git a/drivers/gpu/drm/msm/dpu_power_handle.c b/drivers/gpu/drm/msm/dpu_power_handle.c
index e9e344a..12602ae 100644
--- a/drivers/gpu/drm/msm/dpu_power_handle.c
+++ b/drivers/gpu/drm/msm/dpu_power_handle.c
@@ -13,7 +13,6 @@
 
 #define pr_fmt(fmt)	"[drm:%s:%d]: " fmt, __func__, __LINE__
 
-#include <linux/clk.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/string.h>
@@ -246,62 +245,6 @@ static int dpu_power_parse_dt_supply(struct platform_device *pdev,
 	return rc;
 }
 
-static int dpu_power_parse_dt_clock(struct platform_device *pdev,
-					struct dss_module_power *mp)
-{
-	u32 i = 0, rc = 0;
-	const char *clock_name;
-	u32 clock_rate = 0;
-	u32 clock_max_rate = 0;
-	int num_clk = 0;
-
-	if (!pdev || !mp) {
-		pr_err("invalid input param pdev:%pK mp:%pK\n", pdev, mp);
-		return -EINVAL;
-	}
-
-	mp->num_clk = 0;
-	num_clk = of_property_count_strings(pdev->dev.of_node,
-							"clock-names");
-	if (num_clk <= 0) {
-		pr_debug("clocks are not defined\n");
-		goto clk_err;
-	}
-
-	mp->num_clk = num_clk;
-	mp->clk_config = devm_kzalloc(&pdev->dev,
-			sizeof(struct dss_clk) * num_clk, GFP_KERNEL);
-	if (!mp->clk_config) {
-		rc = -ENOMEM;
-		mp->num_clk = 0;
-		goto clk_err;
-	}
-
-	for (i = 0; i < num_clk; i++) {
-		of_property_read_string_index(pdev->dev.of_node, "clock-names",
-							i, &clock_name);
-		strlcpy(mp->clk_config[i].clk_name, clock_name,
-				sizeof(mp->clk_config[i].clk_name));
-
-		of_property_read_u32_index(pdev->dev.of_node, "clock-rate",
-							i, &clock_rate);
-		mp->clk_config[i].rate = clock_rate;
-
-		if (!clock_rate)
-			mp->clk_config[i].type = DSS_CLK_AHB;
-		else
-			mp->clk_config[i].type = DSS_CLK_PCLK;
-
-		clock_max_rate = 0;
-		of_property_read_u32_index(pdev->dev.of_node, "clock-max-rate",
-							i, &clock_max_rate);
-		mp->clk_config[i].max_rate = clock_max_rate;
-	}
-
-clk_err:
-	return rc;
-}
-
 #ifdef CONFIG_QCOM_BUS_SCALING
 
 #define MAX_AXI_PORT_COUNT 3
@@ -681,16 +624,10 @@ int dpu_power_resource_init(struct platform_device *pdev,
 	mp = &phandle->mp;
 	phandle->dev = &pdev->dev;
 
-	rc = dpu_power_parse_dt_clock(pdev, mp);
-	if (rc) {
-		pr_err("device clock parsing failed\n");
-		goto end;
-	}
-
 	rc = dpu_power_parse_dt_supply(pdev, mp);
 	if (rc) {
 		pr_err("device vreg supply parsing failed\n");
-		goto parse_vreg_err;
+		return rc;
 	}
 
 	rc = msm_dss_config_vreg(&pdev->dev,
@@ -700,18 +637,6 @@ int dpu_power_resource_init(struct platform_device *pdev,
 		goto vreg_err;
 	}
 
-	rc = msm_dss_get_clk(&pdev->dev, mp->clk_config, mp->num_clk);
-	if (rc) {
-		pr_err("clock get failed rc=%d\n", rc);
-		goto clk_err;
-	}
-
-	rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
-	if (rc) {
-		pr_err("clock set rate failed rc=%d\n", rc);
-		goto bus_err;
-	}
-
 	rc = dpu_power_reg_bus_parse(pdev, phandle);
 	if (rc) {
 		pr_err("register bus parse failed rc=%d\n", rc);
@@ -742,18 +667,11 @@ int dpu_power_resource_init(struct platform_device *pdev,
 		dpu_power_data_bus_unregister(&phandle->data_bus_handle[i]);
 	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
 bus_err:
-	msm_dss_put_clk(mp->clk_config, mp->num_clk);
-clk_err:
 	msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, 0);
 vreg_err:
 	if (mp->vreg_config)
 		devm_kfree(&pdev->dev, mp->vreg_config);
 	mp->num_vreg = 0;
-parse_vreg_err:
-	if (mp->clk_config)
-		devm_kfree(&pdev->dev, mp->clk_config);
-	mp->num_clk = 0;
-end:
 	return rc;
 }
 
@@ -796,19 +714,12 @@ void dpu_power_resource_deinit(struct platform_device *pdev,
 
 	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
 
-	msm_dss_put_clk(mp->clk_config, mp->num_clk);
-
 	msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, 0);
 
-	if (mp->clk_config)
-		devm_kfree(&pdev->dev, mp->clk_config);
-
 	if (mp->vreg_config)
 		devm_kfree(&pdev->dev, mp->vreg_config);
 
 	mp->num_vreg = 0;
-	mp->num_clk = 0;
-
 }
 
 int dpu_power_resource_enable(struct dpu_power_handle *phandle,
@@ -885,12 +796,6 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
 			goto reg_bus_hdl_err;
 		}
 
-		rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
-		if (rc) {
-			pr_err("clock enable failed rc:%d\n", rc);
-			goto clk_err;
-		}
-
 		dpu_power_event_trigger_locked(phandle,
 				DPU_POWER_EVENT_POST_ENABLE);
 
@@ -898,8 +803,6 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
 		dpu_power_event_trigger_locked(phandle,
 				DPU_POWER_EVENT_PRE_DISABLE);
 
-		msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
-
 		dpu_power_reg_bus_update(phandle->reg_bus_hdl,
 							max_usecase_ndx);
 
@@ -917,8 +820,6 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
 	mutex_unlock(&phandle->phandle_lock);
 	return rc;
 
-clk_err:
-	dpu_power_reg_bus_update(phandle->reg_bus_hdl, prev_usecase_ndx);
 reg_bus_hdl_err:
 	msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, 0);
 vreg_err:
@@ -930,101 +831,6 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
 	return rc;
 }
 
-int dpu_power_clk_set_rate(struct dpu_power_handle *phandle, char *clock_name,
-	u64 rate)
-{
-	int i, rc = -EINVAL;
-	struct dss_module_power *mp;
-
-	if (!phandle) {
-		pr_err("invalid input power handle\n");
-		return -EINVAL;
-	}
-	mp = &phandle->mp;
-
-	for (i = 0; i < mp->num_clk; i++) {
-		if (!strcmp(mp->clk_config[i].clk_name, clock_name)) {
-			if (mp->clk_config[i].max_rate &&
-					(rate > mp->clk_config[i].max_rate))
-				rate = mp->clk_config[i].max_rate;
-
-			mp->clk_config[i].rate = rate;
-			rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
-			break;
-		}
-	}
-
-	return rc;
-}
-
-u64 dpu_power_clk_get_rate(struct dpu_power_handle *phandle, char *clock_name)
-{
-	int i;
-	struct dss_module_power *mp;
-	u64 rate = -EINVAL;
-
-	if (!phandle) {
-		pr_err("invalid input power handle\n");
-		return -EINVAL;
-	}
-	mp = &phandle->mp;
-
-	for (i = 0; i < mp->num_clk; i++) {
-		if (!strcmp(mp->clk_config[i].clk_name, clock_name)) {
-			rate = clk_get_rate(mp->clk_config[i].clk);
-			break;
-		}
-	}
-
-	return rate;
-}
-
-u64 dpu_power_clk_get_max_rate(struct dpu_power_handle *phandle,
-		char *clock_name)
-{
-	int i;
-	struct dss_module_power *mp;
-	u64 rate = 0;
-
-	if (!phandle) {
-		pr_err("invalid input power handle\n");
-		return 0;
-	}
-	mp = &phandle->mp;
-
-	for (i = 0; i < mp->num_clk; i++) {
-		if (!strcmp(mp->clk_config[i].clk_name, clock_name)) {
-			rate = mp->clk_config[i].max_rate;
-			break;
-		}
-	}
-
-	return rate;
-}
-
-struct clk *dpu_power_clk_get_clk(struct dpu_power_handle *phandle,
-		char *clock_name)
-{
-	int i;
-	struct dss_module_power *mp;
-	struct clk *clk = NULL;
-
-	if (!phandle) {
-		pr_err("invalid input power handle\n");
-		return 0;
-	}
-	mp = &phandle->mp;
-
-	for (i = 0; i < mp->num_clk; i++) {
-		if (!strcmp(mp->clk_config[i].clk_name, clock_name)) {
-			clk = mp->clk_config[i].clk;
-			break;
-		}
-	}
-
-	return clk;
-}
-
 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),
diff --git a/drivers/gpu/drm/msm/dpu_power_handle.h b/drivers/gpu/drm/msm/dpu_power_handle.h
index 1edae5c..83f048d 100644
--- a/drivers/gpu/drm/msm/dpu_power_handle.h
+++ b/drivers/gpu/drm/msm/dpu_power_handle.h
@@ -230,46 +230,6 @@ int dpu_power_data_bus_state_update(struct dpu_power_handle *phandle,
 							bool enable);
 
 /**
- * dpu_power_clk_set_rate() - set the clock rate
- * @pdata:  power handle containing the resources
- * @clock_name: clock name which needs rate update.
- * @rate:       Requested rate.
- *
- * Return: error code.
- */
-int dpu_power_clk_set_rate(struct dpu_power_handle *pdata, char *clock_name,
-	u64 rate);
-
-/**
- * dpu_power_clk_get_rate() - get the clock rate
- * @pdata:  power handle containing the resources
- * @clock_name: clock name to get the rate
- *
- * Return: current clock rate
- */
-u64 dpu_power_clk_get_rate(struct dpu_power_handle *pdata, char *clock_name);
-
-/**
- * dpu_power_clk_get_max_rate() - get the maximum clock rate
- * @pdata:  power handle containing the resources
- * @clock_name: clock name to get the max rate.
- *
- * Return: maximum clock rate or 0 if not found.
- */
-u64 dpu_power_clk_get_max_rate(struct dpu_power_handle *pdata,
-		char *clock_name);
-
-/**
- * dpu_power_clk_get_clk() - get the clock
- * @pdata:  power handle containing the resources
- * @clock_name: clock name to get the clk pointer.
- *
- * Return: Pointer to clock
- */
-struct clk *dpu_power_clk_get_clk(struct dpu_power_handle *phandle,
-		char *clock_name);
-
-/**
  * 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
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [DPU PATCH v2 08/12] drm/msm/dpu: remove power management code from dpu_power_handle
       [not found] ` <1526050178-31893-1-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
                     ` (4 preceding siblings ...)
  2018-05-11 14:49   ` [DPU PATCH v2 07/12] drm/msm/dpu: remove clock management code from dpu_power_handle Rajesh Yadav
@ 2018-05-11 14:49   ` Rajesh Yadav
       [not found]     ` <1526050178-31893-9-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
  2018-05-11 14:49   ` [DPU PATCH v2 09/12] drm/msm/dp: remove dpu_power_handle calls from dp driver Rajesh Yadav
                     ` (3 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: Rajesh Yadav @ 2018-05-11 14:49 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
  Cc: robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw, Rajesh Yadav,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw

Mdss main power supply (mdss_gdsc) is implemented as a
generic power domain and mdss top level wrapper device
manage it via runtime_pm. Remove custom power management
code from dpu_power_handle.

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

Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
---
 drivers/gpu/drm/msm/dpu_power_handle.c | 194 +--------------------------------
 drivers/gpu/drm/msm/dpu_power_handle.h |   2 -
 2 files changed, 3 insertions(+), 193 deletions(-)

diff --git a/drivers/gpu/drm/msm/dpu_power_handle.c b/drivers/gpu/drm/msm/dpu_power_handle.c
index 12602ae..77be106 100644
--- a/drivers/gpu/drm/msm/dpu_power_handle.c
+++ b/drivers/gpu/drm/msm/dpu_power_handle.c
@@ -101,150 +101,6 @@ void dpu_power_client_destroy(struct dpu_power_handle *phandle,
 	}
 }
 
-static int dpu_power_parse_dt_supply(struct platform_device *pdev,
-				struct dss_module_power *mp)
-{
-	int i = 0, rc = 0;
-	u32 tmp = 0;
-	struct device_node *of_node = NULL, *supply_root_node = NULL;
-	struct device_node *supply_node = NULL;
-
-	if (!pdev || !mp) {
-		pr_err("invalid input param pdev:%pK mp:%pK\n", pdev, mp);
-		return -EINVAL;
-	}
-
-	of_node = pdev->dev.of_node;
-
-	mp->num_vreg = 0;
-	supply_root_node = of_get_child_by_name(of_node,
-						"qcom,platform-supply-entries");
-	if (!supply_root_node) {
-		pr_debug("no supply entry present\n");
-		return rc;
-	}
-
-	for_each_child_of_node(supply_root_node, supply_node)
-		mp->num_vreg++;
-
-	if (mp->num_vreg == 0) {
-		pr_debug("no vreg\n");
-		return rc;
-	}
-
-	pr_debug("vreg found. count=%d\n", mp->num_vreg);
-	mp->vreg_config = devm_kzalloc(&pdev->dev, sizeof(struct dss_vreg) *
-						mp->num_vreg, GFP_KERNEL);
-	if (!mp->vreg_config) {
-		rc = -ENOMEM;
-		return rc;
-	}
-
-	for_each_child_of_node(supply_root_node, supply_node) {
-
-		const char *st = NULL;
-
-		rc = of_property_read_string(supply_node,
-						"qcom,supply-name", &st);
-		if (rc) {
-			pr_err("error reading name. rc=%d\n", rc);
-			goto error;
-		}
-
-		strlcpy(mp->vreg_config[i].vreg_name, st,
-					sizeof(mp->vreg_config[i].vreg_name));
-
-		rc = of_property_read_u32(supply_node,
-					"qcom,supply-min-voltage", &tmp);
-		if (rc) {
-			pr_err("error reading min volt. rc=%d\n", rc);
-			goto error;
-		}
-		mp->vreg_config[i].min_voltage = tmp;
-
-		rc = of_property_read_u32(supply_node,
-					"qcom,supply-max-voltage", &tmp);
-		if (rc) {
-			pr_err("error reading max volt. rc=%d\n", rc);
-			goto error;
-		}
-		mp->vreg_config[i].max_voltage = tmp;
-
-		rc = of_property_read_u32(supply_node,
-					"qcom,supply-enable-load", &tmp);
-		if (rc) {
-			pr_err("error reading enable load. rc=%d\n", rc);
-			goto error;
-		}
-		mp->vreg_config[i].enable_load = tmp;
-
-		rc = of_property_read_u32(supply_node,
-					"qcom,supply-disable-load", &tmp);
-		if (rc) {
-			pr_err("error reading disable load. rc=%d\n", rc);
-			goto error;
-		}
-		mp->vreg_config[i].disable_load = tmp;
-
-		rc = of_property_read_u32(supply_node,
-					"qcom,supply-pre-on-sleep", &tmp);
-		if (rc)
-			pr_debug("error reading supply pre sleep value. rc=%d\n",
-							rc);
-
-		mp->vreg_config[i].pre_on_sleep = (!rc ? tmp : 0);
-
-		rc = of_property_read_u32(supply_node,
-					"qcom,supply-pre-off-sleep", &tmp);
-		if (rc)
-			pr_debug("error reading supply pre sleep value. rc=%d\n",
-							rc);
-
-		mp->vreg_config[i].pre_off_sleep = (!rc ? tmp : 0);
-
-		rc = of_property_read_u32(supply_node,
-					"qcom,supply-post-on-sleep", &tmp);
-		if (rc)
-			pr_debug("error reading supply post sleep value. rc=%d\n",
-							rc);
-
-		mp->vreg_config[i].post_on_sleep = (!rc ? tmp : 0);
-
-		rc = of_property_read_u32(supply_node,
-					"qcom,supply-post-off-sleep", &tmp);
-		if (rc)
-			pr_debug("error reading supply post sleep value. rc=%d\n",
-							rc);
-
-		mp->vreg_config[i].post_off_sleep = (!rc ? tmp : 0);
-
-		pr_debug("%s min=%d, max=%d, enable=%d, disable=%d, preonsleep=%d, postonsleep=%d, preoffsleep=%d, postoffsleep=%d\n",
-					mp->vreg_config[i].vreg_name,
-					mp->vreg_config[i].min_voltage,
-					mp->vreg_config[i].max_voltage,
-					mp->vreg_config[i].enable_load,
-					mp->vreg_config[i].disable_load,
-					mp->vreg_config[i].pre_on_sleep,
-					mp->vreg_config[i].post_on_sleep,
-					mp->vreg_config[i].pre_off_sleep,
-					mp->vreg_config[i].post_off_sleep);
-		++i;
-
-		rc = 0;
-	}
-
-	return rc;
-
-error:
-	if (mp->vreg_config) {
-		devm_kfree(&pdev->dev, mp->vreg_config);
-		mp->vreg_config = NULL;
-		mp->num_vreg = 0;
-	}
-
-	return rc;
-}
-
 #ifdef CONFIG_QCOM_BUS_SCALING
 
 #define MAX_AXI_PORT_COUNT 3
@@ -614,33 +470,18 @@ int dpu_power_resource_init(struct platform_device *pdev,
 	struct dpu_power_handle *phandle)
 {
 	int rc = 0, i;
-	struct dss_module_power *mp;
 
 	if (!phandle || !pdev) {
 		pr_err("invalid input param\n");
-		rc = -EINVAL;
-		goto end;
-	}
-	mp = &phandle->mp;
-	phandle->dev = &pdev->dev;
-
-	rc = dpu_power_parse_dt_supply(pdev, mp);
-	if (rc) {
-		pr_err("device vreg supply parsing failed\n");
-		return rc;
+		return -EINVAL;
 	}
 
-	rc = msm_dss_config_vreg(&pdev->dev,
-				mp->vreg_config, mp->num_vreg, 1);
-	if (rc) {
-		pr_err("vreg config failed rc=%d\n", rc);
-		goto vreg_err;
-	}
+	phandle->dev = &pdev->dev;
 
 	rc = dpu_power_reg_bus_parse(pdev, phandle);
 	if (rc) {
 		pr_err("register bus parse failed rc=%d\n", rc);
-		goto bus_err;
+		return rc;
 	}
 
 	for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC;
@@ -666,19 +507,12 @@ int dpu_power_resource_init(struct platform_device *pdev,
 	for (i--; i >= 0; i--)
 		dpu_power_data_bus_unregister(&phandle->data_bus_handle[i]);
 	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
-bus_err:
-	msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, 0);
-vreg_err:
-	if (mp->vreg_config)
-		devm_kfree(&pdev->dev, mp->vreg_config);
-	mp->num_vreg = 0;
 	return rc;
 }
 
 void dpu_power_resource_deinit(struct platform_device *pdev,
 	struct dpu_power_handle *phandle)
 {
-	struct dss_module_power *mp;
 	struct dpu_power_client *curr_client, *next_client;
 	struct dpu_power_event *curr_event, *next_event;
 	int i;
@@ -687,7 +521,6 @@ void dpu_power_resource_deinit(struct platform_device *pdev,
 		pr_err("invalid input param\n");
 		return;
 	}
-	mp = &phandle->mp;
 
 	mutex_lock(&phandle->phandle_lock);
 	list_for_each_entry_safe(curr_client, next_client,
@@ -713,13 +546,6 @@ void dpu_power_resource_deinit(struct platform_device *pdev,
 		dpu_power_data_bus_unregister(&phandle->data_bus_handle[i]);
 
 	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
-
-	msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, 0);
-
-	if (mp->vreg_config)
-		devm_kfree(&pdev->dev, mp->vreg_config);
-
-	mp->num_vreg = 0;
 }
 
 int dpu_power_resource_enable(struct dpu_power_handle *phandle,
@@ -729,15 +555,12 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
 	bool changed = false;
 	u32 max_usecase_ndx = VOTE_INDEX_DISABLE, prev_usecase_ndx;
 	struct dpu_power_client *client;
-	struct dss_module_power *mp;
 
 	if (!phandle || !pclient) {
 		pr_err("invalid input argument\n");
 		return -EINVAL;
 	}
 
-	mp = &phandle->mp;
-
 	mutex_lock(&phandle->phandle_lock);
 	if (enable)
 		pclient->refcount++;
@@ -782,13 +605,6 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
 			}
 		}
 
-		rc = msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg,
-								enable);
-		if (rc) {
-			pr_err("failed to enable vregs rc=%d\n", rc);
-			goto vreg_err;
-		}
-
 		rc = dpu_power_reg_bus_update(phandle->reg_bus_hdl,
 							max_usecase_ndx);
 		if (rc) {
@@ -806,8 +622,6 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
 		dpu_power_reg_bus_update(phandle->reg_bus_hdl,
 							max_usecase_ndx);
 
-		msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg,
-							enable);
 		for (i = 0 ; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
 			dpu_power_data_bus_update(&phandle->data_bus_handle[i],
 					enable);
@@ -821,8 +635,6 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
 	return rc;
 
 reg_bus_hdl_err:
-	msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, 0);
-vreg_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:
diff --git a/drivers/gpu/drm/msm/dpu_power_handle.h b/drivers/gpu/drm/msm/dpu_power_handle.h
index 83f048d..9a6d4b9 100644
--- a/drivers/gpu/drm/msm/dpu_power_handle.h
+++ b/drivers/gpu/drm/msm/dpu_power_handle.h
@@ -147,7 +147,6 @@ struct dpu_power_event {
 
 /**
  * struct dpu_power_handle: power handle main struct
- * @mp:		module power for clock and regulator
  * @client_clist: master list to store all clients
  * @phandle_lock: lock to synchronize the enable/disable
  * @dev: pointer to device structure
@@ -157,7 +156,6 @@ struct dpu_power_event {
  * @event_list: current power handle event list
  */
 struct dpu_power_handle {
-	struct dss_module_power mp;
 	struct list_head power_client_clist;
 	struct mutex phandle_lock;
 	struct device *dev;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [DPU PATCH v2 09/12] drm/msm/dp: remove dpu_power_handle calls from dp driver
       [not found] ` <1526050178-31893-1-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
                     ` (5 preceding siblings ...)
  2018-05-11 14:49   ` [DPU PATCH v2 08/12] drm/msm/dpu: remove power " Rajesh Yadav
@ 2018-05-11 14:49   ` Rajesh Yadav
  2018-05-11 14:49   ` [DPU PATCH v2 10/12] drm/msm/dpu: use runtime_pm calls in dpu_dbg Rajesh Yadav
                     ` (2 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Rajesh Yadav @ 2018-05-11 14:49 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
  Cc: robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw, Rajesh Yadav,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw

DP driver was dependent on dpu_power_handle for MDSS
common clocks and gdsc (main power supply).
The common clocks and power is managed by MDSS top
wrapper device now which is parent of all sub-devices
like DP device.
For same reason, clock and power management code is
removed from dpu_power_handle. Hence, remove the
dpu_power_handle calls from dp driver.

Changes in v2:
	- none

Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
Reviewed-by: Sean Paul <seanpaul@chromium.org>
---
 drivers/gpu/drm/msm/dp/dp_power.c | 32 +-------------------------------
 drivers/gpu/drm/msm/dp/dp_power.h |  4 +---
 2 files changed, 2 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_power.c b/drivers/gpu/drm/msm/dp/dp_power.c
index f6e341b..2a85b38 100644
--- a/drivers/gpu/drm/msm/dp/dp_power.c
+++ b/drivers/gpu/drm/msm/dp/dp_power.c
@@ -26,8 +26,6 @@ struct dp_power_private {
 	struct clk *pixel_parent;
 
 	struct dp_power dp_power;
-	struct dpu_power_client *dp_core_client;
-	struct dpu_power_handle *phandle;
 
 	bool core_clks_on;
 	bool link_clks_on;
@@ -410,8 +408,7 @@ static int dp_power_config_gpios(struct dp_power_private *power, bool flip,
 	return 0;
 }
 
-static int dp_power_client_init(struct dp_power *dp_power,
-		struct dpu_power_handle *phandle)
+static int dp_power_client_init(struct dp_power *dp_power)
 {
 	int rc = 0;
 	struct dp_power_private *power;
@@ -436,19 +433,8 @@ static int dp_power_client_init(struct dp_power *dp_power,
 		goto error_clk;
 	}
 
-	power->phandle = phandle;
-	snprintf(dp_client_name, DP_CLIENT_NAME_SIZE, "dp_core_client");
-	power->dp_core_client = dpu_power_client_create(phandle,
-			dp_client_name);
-	if (IS_ERR_OR_NULL(power->dp_core_client)) {
-		pr_err("[%s] client creation failed for DP", dp_client_name);
-		rc = -EINVAL;
-		goto error_client;
-	}
 	return 0;
 
-error_client:
-	dp_power_clk_init(power, false);
 error_clk:
 	dp_power_regulator_deinit(power);
 error_power:
@@ -466,7 +452,6 @@ static void dp_power_client_deinit(struct dp_power *dp_power)
 
 	power = container_of(dp_power, struct dp_power_private, dp_power);
 
-	dpu_power_client_destroy(power->phandle, power->dp_core_client);
 	dp_power_clk_init(power, false);
 	dp_power_regulator_deinit(power);
 }
@@ -521,13 +506,6 @@ static int dp_power_init(struct dp_power *dp_power, bool flip)
 		goto err_gpio;
 	}
 
-	rc = dpu_power_resource_enable(power->phandle,
-		power->dp_core_client, true);
-	if (rc) {
-		pr_err("Power resource enable failed\n");
-		goto err_dpu_power;
-	}
-
 	rc = dp_power_clk_enable(dp_power, DP_CORE_PM, true);
 	if (rc) {
 		pr_err("failed to enable DP core clocks\n");
@@ -537,8 +515,6 @@ static int dp_power_init(struct dp_power *dp_power, bool flip)
 	return 0;
 
 err_clk:
-	dpu_power_resource_enable(power->phandle, power->dp_core_client, false);
-err_dpu_power:
 	dp_power_config_gpios(power, flip, false);
 err_gpio:
 	dp_power_pinctrl_set(power, false);
@@ -562,12 +538,6 @@ static int dp_power_deinit(struct dp_power *dp_power)
 	power = container_of(dp_power, struct dp_power_private, dp_power);
 
 	dp_power_clk_enable(dp_power, DP_CORE_PM, false);
-	rc = dpu_power_resource_enable(power->phandle,
-			power->dp_core_client, false);
-	if (rc) {
-		pr_err("Power resource enable failed, rc=%d\n", rc);
-		goto exit;
-	}
 	dp_power_config_gpios(power, false, false);
 	dp_power_pinctrl_set(power, false);
 	dp_power_regulator_ctrl(power, false);
diff --git a/drivers/gpu/drm/msm/dp/dp_power.h b/drivers/gpu/drm/msm/dp/dp_power.h
index 84fe01d..d9dab72 100644
--- a/drivers/gpu/drm/msm/dp/dp_power.h
+++ b/drivers/gpu/drm/msm/dp/dp_power.h
@@ -16,7 +16,6 @@
 #define _DP_POWER_H_
 
 #include "dp_parser.h"
-#include "dpu_power_handle.h"
 
 /**
  * sruct dp_power - DisplayPort's power related data
@@ -32,8 +31,7 @@ struct dp_power {
 	int (*clk_enable)(struct dp_power *power, enum dp_pm_type pm_type,
 				bool enable);
 	int (*set_pixel_clk_parent)(struct dp_power *power);
-	int (*power_client_init)(struct dp_power *power,
-				struct dpu_power_handle *phandle);
+	int (*power_client_init)(struct dp_power *power);
 	void (*power_client_deinit)(struct dp_power *power);
 };
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [DPU PATCH v2 10/12] drm/msm/dpu: use runtime_pm calls in dpu_dbg
       [not found] ` <1526050178-31893-1-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
                     ` (6 preceding siblings ...)
  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   ` Rajesh Yadav
       [not found]     ` <1526050178-31893-11-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
  2018-05-11 14:49   ` [DPU PATCH v2 11/12] drm/msm/dpu: move dpu_power_handle to dpu folder Rajesh Yadav
  2018-05-11 14:49   ` [DPU PATCH v2 12/12] drm/msm/dpu: add error handling in dpu_core_perf_crtc_update Rajesh Yadav
  9 siblings, 1 reply; 24+ messages in thread
From: Rajesh Yadav @ 2018-05-11 14:49 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
  Cc: robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw, Rajesh Yadav,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw

Currently, msm_drv was creating dpu_power_handle client
which was used by dpu_dbg module to enable power resources
before register debug dumping.

Now since, the mdss core power resource handling is
implemented via runtime_pm and same has been removed
from dpu_power_handle. Remove dpu_power_handle dependency
from msm_drv and use pm_runtime_get/put_sync calls from
dpu_dbg module on dpu_mdss top level device for core,
ahb clock and power resource management (for register access).

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

Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c |  7 -------
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h |  4 ----
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c       |  3 +--
 drivers/gpu/drm/msm/dpu_dbg.c                 | 18 +++++++-----------
 drivers/gpu/drm/msm/dpu_dbg.h                 | 13 ++-----------
 drivers/gpu/drm/msm/msm_drv.c                 | 27 +--------------------------
 drivers/gpu/drm/msm/msm_drv.h                 |  1 -
 7 files changed, 11 insertions(+), 62 deletions(-)

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 5b79077..2cf3fca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -673,18 +673,11 @@ int dpu_core_perf_init(struct dpu_core_perf *perf,
 		struct drm_device *dev,
 		struct dpu_mdss_cfg *catalog,
 		struct dpu_power_handle *phandle,
-		struct dpu_power_client *pclient,
 		struct dss_clk *core_clk)
 {
-	if (!pclient) {
-		DPU_ERROR("invalid parameters\n");
-		return -EINVAL;
-	}
-
 	perf->dev = dev;
 	perf->catalog = catalog;
 	perf->phandle = phandle;
-	perf->pclient = pclient;
 	perf->core_clk = core_clk;
 
 	perf->max_core_clk_rate = core_clk->max_rate;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
index 9c1a719..cde48df 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
@@ -53,7 +53,6 @@ struct dpu_core_perf_tune {
  * @debugfs_root: top level debug folder
  * @catalog: Pointer to catalog configuration
  * @phandle: Pointer to power handler
- * @pclient: Pointer to power client
  * @core_clk: Pointer to core clock structure
  * @core_clk_rate: current core clock rate
  * @max_core_clk_rate: maximum allowable core clock rate
@@ -68,7 +67,6 @@ struct dpu_core_perf {
 	struct dentry *debugfs_root;
 	struct dpu_mdss_cfg *catalog;
 	struct dpu_power_handle *phandle;
-	struct dpu_power_client *pclient;
 	struct dss_clk *core_clk;
 	u64 core_clk_rate;
 	u64 max_core_clk_rate;
@@ -115,14 +113,12 @@ void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
  * @dev: Pointer to drm device
  * @catalog: Pointer to catalog
  * @phandle: Pointer to power handle
- * @pclient: Pointer to power client
  * @core_clk: pointer to core clock
  */
 int dpu_core_perf_init(struct dpu_core_perf *perf,
 		struct drm_device *dev,
 		struct dpu_mdss_cfg *catalog,
 		struct dpu_power_handle *phandle,
-		struct dpu_power_client *pclient,
 		struct dss_clk *core_clk);
 
 /**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 349bda5..9c3b220 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -1721,8 +1721,7 @@ 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, priv->pclient,
-			_dpu_kms_get_clk(dpu_kms, "core_clk"));
+			&priv->phandle, _dpu_kms_get_clk(dpu_kms, "core_clk"));
 	if (rc) {
 		DPU_ERROR("failed to init perf %d\n", rc);
 		goto perf_err;
diff --git a/drivers/gpu/drm/msm/dpu_dbg.c b/drivers/gpu/drm/msm/dpu_dbg.c
index 4a39b82..27538bc 100644
--- a/drivers/gpu/drm/msm/dpu_dbg.c
+++ b/drivers/gpu/drm/msm/dpu_dbg.c
@@ -20,6 +20,7 @@
 #include <linux/dma-buf.h>
 #include <linux/slab.h>
 #include <linux/list_sort.h>
+#include <linux/pm_runtime.h>
 
 #include "dpu_dbg.h"
 #include "disp/dpu1/dpu_hw_catalog.h"
@@ -167,7 +168,6 @@ struct dpu_dbg_vbif_debug_bus {
  * @evtlog: event log instance
  * @reg_base_list: list of register dumping regions
  * @dev: device pointer
- * @power_ctrl: callback structure for enabling power for reading hw registers
  * @req_dump_blks: list of blocks requested for dumping
  * @panic_on_err: whether to kernel panic after triggering dump via debugfs
  * @dump_work: work struct for deferring register dump work to separate thread
@@ -182,7 +182,6 @@ struct dpu_dbg_vbif_debug_bus {
 	struct dpu_dbg_evtlog *evtlog;
 	struct list_head reg_base_list;
 	struct device *dev;
-	struct dpu_dbg_power_ctrl power_ctrl;
 
 	struct dpu_dbg_reg_base *req_dump_blks[DPU_DBG_BASE_MAX];
 
@@ -2008,12 +2007,10 @@ static void _dpu_debug_bus_ppb1_dump(void __iomem *mem_base,
  */
 static inline void _dpu_dbg_enable_power(int enable)
 {
-	if (!dpu_dbg_base.power_ctrl.enable_fn)
-		return;
-	dpu_dbg_base.power_ctrl.enable_fn(
-			dpu_dbg_base.power_ctrl.handle,
-			dpu_dbg_base.power_ctrl.client,
-			enable);
+	if (enable)
+		pm_runtime_get_sync(dpu_dbg_base.dev);
+	else
+		pm_runtime_put_sync(dpu_dbg_base.dev);
 }
 
 /**
@@ -3099,16 +3096,15 @@ void dpu_dbg_init_dbg_buses(u32 hwversion)
 	}
 }
 
-int dpu_dbg_init(struct device *dev, struct dpu_dbg_power_ctrl *power_ctrl)
+int dpu_dbg_init(struct device *dev)
 {
-	if (!dev || !power_ctrl) {
+	if (!dev) {
 		pr_err("invalid params\n");
 		return -EINVAL;
 	}
 
 	INIT_LIST_HEAD(&dpu_dbg_base.reg_base_list);
 	dpu_dbg_base.dev = dev;
-	dpu_dbg_base.power_ctrl = *power_ctrl;
 
 	dpu_dbg_base.evtlog = dpu_evtlog_init();
 	if (IS_ERR_OR_NULL(dpu_dbg_base.evtlog))
diff --git a/drivers/gpu/drm/msm/dpu_dbg.h b/drivers/gpu/drm/msm/dpu_dbg.h
index e79b5aa..283dbbc 100644
--- a/drivers/gpu/drm/msm/dpu_dbg.h
+++ b/drivers/gpu/drm/msm/dpu_dbg.h
@@ -71,12 +71,6 @@ enum dpu_dbg_dump_flag {
 #define DPU_EVTLOG_BUF_MAX 512
 #define DPU_EVTLOG_BUF_ALIGN 32
 
-struct dpu_dbg_power_ctrl {
-	void *handle;
-	void *client;
-	int (*enable_fn)(void *handle, void *client, bool enable);
-};
-
 struct dpu_dbg_evtlog_log {
 	s64 time;
 	const char *name;
@@ -211,11 +205,9 @@ ssize_t dpu_evtlog_dump_to_buffer(struct dpu_dbg_evtlog *evtlog,
 /**
  * dpu_dbg_init - initialize global dpu debug facilities: evtlog, regdump
  * @dev:		device handle
- * @power_ctrl:		power control callback structure for enabling clocks
- *			during register dumping
  * Returns:		0 or -ERROR
  */
-int dpu_dbg_init(struct device *dev, struct dpu_dbg_power_ctrl *power_ctrl);
+int dpu_dbg_init(struct device *dev);
 
 /**
  * dpu_dbg_debugfs_register - register entries at the given debugfs dir
@@ -359,8 +351,7 @@ static inline void dpu_dbg_init_dbg_buses(u32 hwversion)
 {
 }
 
-static inline int dpu_dbg_init(struct device *dev,
-		struct dpu_dbg_power_ctrl *power_ctrl)
+static inline int dpu_dbg_init(struct device *dev)
 {
 	return 0;
 }
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 5470529..5c267cd 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_client_destroy(&priv->phandle, priv->pclient);
 	dpu_power_resource_deinit(pdev, &priv->phandle);
 	dpu_dbg_destroy();
 #endif
@@ -464,13 +463,6 @@ static int msm_component_bind_all(struct device *dev,
 }
 #endif
 
-#ifdef CONFIG_DRM_MSM_DPU
-static int msm_power_enable_wrapper(void *handle, void *client, bool enable)
-{
-	return dpu_power_resource_enable(handle, client, enable);
-}
-#endif
-
 static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -479,10 +471,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 	struct msm_kms *kms;
 	struct msm_mdss *mdss;
 
-#ifdef CONFIG_DRM_MSM_DPU
-	struct dpu_dbg_power_ctrl dbg_power_ctrl = { 0 };
-#endif
-
 	int ret, i;
 	struct sched_param param;
 
@@ -537,18 +525,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
 		goto power_init_fail;
 	}
 
-	priv->pclient = dpu_power_client_create(&priv->phandle, "dpu");
-	if (IS_ERR_OR_NULL(priv->pclient)) {
-		pr_err("dpu power client create failed\n");
-		ret = -EINVAL;
-		goto power_client_fail;
-	}
-
-	dbg_power_ctrl.handle = &priv->phandle;
-	dbg_power_ctrl.client = priv->pclient;
-	dbg_power_ctrl.enable_fn = msm_power_enable_wrapper;
-
-	ret = dpu_dbg_init(&pdev->dev, &dbg_power_ctrl);
+	ret = dpu_dbg_init(&pdev->dev);
 	if (ret) {
 		dev_err(dev, "failed to init dpu dbg: %d\n", ret);
 		goto dbg_init_fail;
@@ -756,8 +733,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_client_destroy(&priv->phandle, priv->pclient);
-power_client_fail:
 	dpu_power_resource_deinit(pdev, &priv->phandle);
 power_init_fail:
 #endif
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
index 22a3096..f9ae96f 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -376,7 +376,6 @@ struct msm_drm_private {
 	struct msm_kms *kms;
 
 	struct dpu_power_handle phandle;
-	struct dpu_power_client *pclient;
 
 	/* 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

_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [DPU PATCH v2 11/12] drm/msm/dpu: move dpu_power_handle to dpu folder
       [not found] ` <1526050178-31893-1-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
                     ` (7 preceding siblings ...)
  2018-05-11 14:49   ` [DPU PATCH v2 10/12] drm/msm/dpu: use runtime_pm calls in dpu_dbg Rajesh Yadav
@ 2018-05-11 14:49   ` Rajesh Yadav
       [not found]     ` <1526050178-31893-12-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
  2018-05-11 14:49   ` [DPU PATCH v2 12/12] drm/msm/dpu: add error handling in dpu_core_perf_crtc_update Rajesh Yadav
  9 siblings, 1 reply; 24+ messages in thread
From: Rajesh Yadav @ 2018-05-11 14:49 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
  Cc: robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw, Rajesh Yadav,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw

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

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

_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [DPU PATCH v2 12/12] drm/msm/dpu: add error handling in dpu_core_perf_crtc_update
       [not found] ` <1526050178-31893-1-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
                     ` (8 preceding siblings ...)
  2018-05-11 14:49   ` [DPU PATCH v2 11/12] drm/msm/dpu: move dpu_power_handle to dpu folder Rajesh Yadav
@ 2018-05-11 14:49   ` Rajesh Yadav
  2018-05-11 15:49     ` Sean Paul
  9 siblings, 1 reply; 24+ messages in thread
From: Rajesh Yadav @ 2018-05-11 14:49 UTC (permalink / raw)
  To: dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
  Cc: robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw, Rajesh Yadav,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw

dpu_core_perf_crtc_update() is responsible for aggregating
the data bus bandwidth and dpu core clock rate requirements
and request the same for all active crtcs.
Currently, there is no error handling support in this function
so there is no way caller can know if the perf request fails.
This change adds error handling code in dpu_core_perf_crtc_update().
The caller side error handling is not added in this patch.

Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 37 ++++++++++++++++++---------
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h |  3 ++-
 2 files changed, 27 insertions(+), 13 deletions(-)

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 d3a1ed9..85c0229 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
@@ -248,7 +248,7 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
 	return 0;
 }
 
-static void _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
+static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
 		struct drm_crtc *crtc, u32 bus_id)
 {
 	u64 bw_sum_of_intfs = 0, bus_ab_quota, bus_ib_quota;
@@ -257,6 +257,7 @@ 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;
+	int ret = 0;
 
 	drm_for_each_crtc(tmp_crtc, crtc->dev) {
 		if (_dpu_core_perf_crtc_is_power_on(tmp_crtc) &&
@@ -286,25 +287,28 @@ 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(&kms->phandle, kms->core_client,
+		ret = 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",
-				bus_id, bus_ab_quota, bus_ib_quota);
+			  bus_id, bus_ab_quota, bus_ib_quota);
 		break;
 
 	case RT_CLIENT:
-		dpu_power_data_bus_set_quota(&kms->phandle, kms->core_client,
+		ret = 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",
-				bus_id, bus_ab_quota, bus_ib_quota);
+			  bus_id, bus_ab_quota, bus_ib_quota);
 		break;
 
 	default:
 		DPU_ERROR("invalid client type:%d\n", curr_client_type);
 		break;
 	}
+	return ret;
 }
 
 /**
@@ -399,7 +403,7 @@ static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms)
 	return clk_rate;
 }
 
-void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
+int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
 		int params_changed, bool stop_req)
 {
 	struct dpu_core_perf_params *new, *old;
@@ -410,16 +414,17 @@ void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
 	int i;
 	struct msm_drm_private *priv;
 	struct dpu_kms *kms;
+	int ret;
 
 	if (!crtc) {
 		DPU_ERROR("invalid crtc\n");
-		return;
+		return -EINVAL;
 	}
 
 	kms = _dpu_crtc_get_kms(crtc);
 	if (!kms || !kms->catalog) {
 		DPU_ERROR("invalid kms\n");
-		return;
+		return -EINVAL;
 	}
 	priv = kms->dev->dev_private;
 
@@ -482,8 +487,14 @@ void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
 				update_bus, update_clk);
 
 	for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
-		if (update_bus & BIT(i))
-			_dpu_core_perf_crtc_update_bus(kms, crtc, i);
+		if (update_bus & BIT(i)) {
+			ret = _dpu_core_perf_crtc_update_bus(kms, crtc, i);
+			if (ret) {
+				DPU_ERROR("crtc-%d: failed to update bw vote for bus-%d\n",
+					  crtc->base.id, i);
+				return ret;
+			}
+		}
 	}
 
 	/*
@@ -495,15 +506,17 @@ void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
 
 		DPU_EVT32(kms->dev, stop_req, clk_rate);
 
-		if (_dpu_core_perf_set_core_clk_rate(kms, clk_rate)) {
+		ret = _dpu_core_perf_set_core_clk_rate(kms, clk_rate);
+		if (ret) {
 			DPU_ERROR("failed to set %s clock rate %llu\n",
 					kms->perf.core_clk->clk_name, clk_rate);
-			return;
+			return ret;
 		}
 
 		kms->perf.core_clk_rate = clk_rate;
 		DPU_DEBUG("update clk rate = %lld HZ\n", clk_rate);
 	}
+	return 0;
 }
 
 #ifdef CONFIG_DEBUG_FS
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
index cde48df..440d6a2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
@@ -91,8 +91,9 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
  * @crtc: Pointer to crtc
  * @params_changed: true if crtc parameters are modified
  * @stop_req: true if this is a stop request
+ * return: zero if success, or error code otherwise
  */
-void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
+int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
 		int params_changed, bool stop_req);
 
 /**
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [DPU PATCH v2 03/12] drm/msm/dpu: add MDSS top level driver for dpu
  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>
  1 sibling, 1 reply; 24+ messages in thread
From: Sean Paul @ 2018-05-11 15:28 UTC (permalink / raw)
  To: Rajesh Yadav; +Cc: linux-arm-msm, dri-devel, hoegsberg, freedreno

On Fri, May 11, 2018 at 08:19:29PM +0530, Rajesh Yadav wrote:
> SoCs containing dpu have a MDSS top level wrapper
> which includes sub-blocks as dpu, dsi, phy, dp etc.
> MDSS top level wrapper manages common resources like
> common clocks, power and irq for its sub-blocks.
> 
> Currently, in dpu driver, all the power resource
> management is part of power_handle which manages
> these resources via a custom implementation. And
> the resource relationships are not modelled properly
> in dt.  Moreover the irq domain handling code is part
> of dpu device (which is a child device) due to lack
> of a dedicated driver for MDSS top level wrapper
> device.
> 
> This change adds dpu_mdss top level driver to handle
> common clock like - core clock, ahb clock
> (for register access), main power supply (i.e. gdsc)
> and irq management.
> The top level mdss device/driver acts as an interrupt
> controller and manage hwirq mapping for its child
> devices.
> 
> It implements runtime_pm support for resource management.
> Child nodes can control these resources via runtime_pm
> get/put calls on their corresponding devices due to parent
> child relationship defined in dt.
> 
> Changes in v2:
> 	- merge _dpu_mdss_hw_rev_init to dpu_mdss_init (Sean Paul)
> 	- merge _dpu_mdss_get_intr_sources to dpu_mdss_irq (Sean Paul)
> 	- fix indentation for irq_find_mapping call (Sean Paul)
> 	- remove unnecessary goto statements from dpu_mdss_irq (Sean Paul)
> 	- remove redundant param checks from
> 	  dpu_mdss_irq_mask/unmask (Sean Paul/Jordan Crouse)
> 	- remove redundant param checks from
> 	  dpu_mdss_irqdomain_map (Sean Paul/Jordan Crouse)
> 	- return error code from dpu_mdss_enable/disable (Sean Paul/Jordan Crouse)
> 	- remove redundant param check from dpu_mdss_destroy (Sean Paul)
> 	- remove explicit calls to devm_kfree (Sean Paul/Jordan Crouse)
> 	- remove compatibility check from dpu_mdss_init as
> 	  it is conditionally called from msm_drv (Sean Paul)
> 	- reworked msm_dss_parse_clock() to add return checks for
> 	  of_property_read_* calls, fix log message and
> 	  fix alignment issues (Sean Paul/Jordan Crouse)
> 	- remove extra line before dpu_mdss_init (Sean Paul)
> 	- remove redundant param checks from __intr_offset and
> 	  make it a void function to avoid unnecessary error
> 	  handling from caller (Jordan Crouse)
> 	- remove redundant param check from dpu_mdss_irq (Jordan Crouse)
> 	- change mdss address space log message to debug and use %pK for
> 	  kernel pointers (Jordan Crouse)
> 	- remove unnecessary log message from msm_dss_parse_clock (Jordan Crouse)
> 	- don't export msm_dss_parse_clock since it is used
> 	  only by dpu driver (Jordan Crouse)
> 
> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
> ---
>  drivers/gpu/drm/msm/Makefile                      |   1 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c      |  97 ---------
>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h      |  14 --
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    |   9 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |   7 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c |  28 +--
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  11 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c           |  48 +---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c           |   6 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h           |   2 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c          | 254 ++++++++++++++++++++++
>  drivers/gpu/drm/msm/dpu_io_util.c                 |  57 +++++
>  drivers/gpu/drm/msm/msm_drv.c                     |  26 ++-
>  drivers/gpu/drm/msm/msm_drv.h                     |   2 +-
>  drivers/gpu/drm/msm/msm_kms.h                     |   1 +
>  include/linux/dpu_io_util.h                       |   2 +
>  16 files changed, 339 insertions(+), 226 deletions(-)
>  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> 

/snip

> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> new file mode 100644
> index 0000000..ce680ea
> --- /dev/null
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c

/snip

> +
> +int dpu_mdss_init(struct drm_device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev->dev);
> +	struct msm_drm_private *priv = dev->dev_private;
> +	struct dpu_mdss *dpu_mdss;
> +	struct dss_module_power *mp;
> +	int ret = 0;
> +
> +	dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL);
> +	if (!dpu_mdss)
> +		return -ENOMEM;
> +
> +	dpu_mdss->mmio = msm_ioremap(pdev, "mdss_phys", "mdss_phys");
> +	if (IS_ERR(dpu_mdss->mmio)) {
> +		ret = PTR_ERR(dpu_mdss->mmio);

remove this ...

> +		DPU_ERROR("mdss register memory map failed: %d\n", ret);
> +		dpu_mdss->mmio = NULL;
> +		return ret;

... and replace with
                return PTR_ERR(dpu_mdss->mmio);

> +	}
> +	DRM_DEBUG("mapped mdss address space @%pK\n", dpu_mdss->mmio);
> +	dpu_mdss->mmio_len = msm_iomap_size(pdev, "mdss_phys");
> +
> +	mp = &dpu_mdss->mp;
> +	ret = msm_dss_parse_clock(pdev, mp);
> +	if (ret) {
> +		DPU_ERROR("failed to parse clocks, ret=%d\n", ret);
> +		goto clk_parse_err;
> +	}
> +
> +	ret = msm_dss_get_clk(&pdev->dev, mp->clk_config, mp->num_clk);
> +	if (ret) {
> +		DPU_ERROR("failed to get clocks, ret=%d\n", ret);
> +		goto clk_get_error;
> +	}
> +
> +	ret = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
> +	if (ret) {
> +		DPU_ERROR("failed to set clock rate, ret=%d\n", ret);
> +		goto clk_rate_error;
> +	}
> +
> +	dpu_mdss->base.dev = dev;
> +	dpu_mdss->base.funcs = &mdss_funcs;
> +
> +	ret = _dpu_mdss_irq_domain_add(dpu_mdss);
> +	if (ret)
> +		goto irq_domain_error;
> +
> +	ret = devm_request_irq(dev->dev, platform_get_irq(pdev, 0),
> +			dpu_mdss_irq, 0, "dpu_mdss_isr", dpu_mdss);
> +	if (ret) {
> +		DPU_ERROR("failed to init irq: %d\n", ret);
> +		goto irq_error;
> +	}
> +
> +	pm_runtime_enable(dev->dev);
> +
> +	pm_runtime_get_sync(dev->dev);
> +	dpu_mdss->hwversion = readl_relaxed(dpu_mdss->mmio);
> +	pm_runtime_put_sync(dev->dev);
> +
> +	priv->mdss = &dpu_mdss->base;
> +
> +	return ret;
> +
> +irq_error:
> +	_dpu_mdss_irq_domain_fini(dpu_mdss);
> +irq_domain_error:
> +clk_rate_error:
> +	msm_dss_put_clk(mp->clk_config, mp->num_clk);
> +clk_get_error:
> +	devm_kfree(&pdev->dev, mp->clk_config);
> +clk_parse_err:
> +	if (dpu_mdss->mmio)
> +		msm_iounmap(pdev, dpu_mdss->mmio);
> +	dpu_mdss->mmio = NULL;
> +	return ret;
> +}
> diff --git a/drivers/gpu/drm/msm/dpu_io_util.c b/drivers/gpu/drm/msm/dpu_io_util.c
> index a18bc99..c44f33f 100644
> --- a/drivers/gpu/drm/msm/dpu_io_util.c
> +++ b/drivers/gpu/drm/msm/dpu_io_util.c
> @@ -448,6 +448,63 @@ int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable)
>  } /* msm_dss_enable_clk */
>  EXPORT_SYMBOL(msm_dss_enable_clk);
>  
> +int msm_dss_parse_clock(struct platform_device *pdev,
> +		struct dss_module_power *mp)
> +{
> +	u32 i, rc = 0;
> +	const char *clock_name;
> +	u32 rate = 0, max_rate = 0;
> +	int num_clk = 0;
> +
> +	if (!pdev || !mp)
> +		return -EINVAL;
> +
> +	mp->num_clk = 0;
> +	num_clk = of_property_count_strings(pdev->dev.of_node, "clock-names");
> +	if (num_clk <= 0) {
> +		pr_debug("clocks are not defined\n");
> +		return 0;
> +	}
> +
> +	mp->clk_config = devm_kzalloc(&pdev->dev,
> +				      sizeof(struct dss_clk) * num_clk,
> +				      GFP_KERNEL);
> +	if (!mp->clk_config)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < num_clk; i++) {
> +		rc = of_property_read_string_index(pdev->dev.of_node,
> +						   "clock-names", i,
> +						   &clock_name);
> +		if (rc)
> +			break;
> +		strlcpy(mp->clk_config[i].clk_name, clock_name,
> +			sizeof(mp->clk_config[i].clk_name));
> +
> +		rc = of_property_read_u32_index(pdev->dev.of_node,
> +						"clock-rate", i,
> +						&rate);
> +		if (rc)
> +			break;
> +		mp->clk_config[i].rate = rate;
> +		if (!mp->clk_config[i].rate)
> +			mp->clk_config[i].type = DSS_CLK_AHB;
> +		else
> +			mp->clk_config[i].type = DSS_CLK_PCLK;
> +
> +		rc = of_property_read_u32_index(pdev->dev.of_node,
> +						"clock-max-rate", i,
> +						&max_rate);

Hmm, I missed these in my first review, these need new dt bindings. I'm
far from an expert on dt bindings, but I think you'll be asked to define these
are clocks, and get the rate/max rate information from the clock subsystem
instead of breaking it all out like this.

Sean

> +		if (rc)
> +			break;
> +		mp->clk_config[i].max_rate = max_rate;
> +	}
> +
> +	if (!rc)
> +		mp->num_clk = num_clk;
> +
> +	return rc;
> +}
>  
>  int dpu_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
>  			uint8_t reg_offset, uint8_t *read_buf)
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index 5d8f1b6..a0e73ea 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -503,7 +503,18 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
>  	ddev->dev_private = priv;
>  	priv->dev = ddev;
>  
> -	ret = mdp5_mdss_init(ddev);
> +	switch (get_mdp_ver(pdev)) {
> +	case KMS_MDP5:
> +		ret = mdp5_mdss_init(ddev);
> +		break;
> +	case KMS_DPU:
> +		ret = dpu_mdss_init(ddev);
> +		break;
> +	default:
> +		ret = 0;
> +		break;
> +	}
> +
>  	if (ret)
>  		goto mdss_init_fail;
>  
> @@ -1539,12 +1550,13 @@ static int add_display_components(struct device *dev,
>  	int ret;
>  
>  	/*
> -	 * MDP5 based devices don't have a flat hierarchy. There is a top level
> -	 * parent: MDSS, and children: MDP5, DSI, HDMI, eDP etc. Populate the
> -	 * children devices, find the MDP5 node, and then add the interfaces
> -	 * to our components list.
> +	 * MDP5/DPU based devices don't have a flat hierarchy. There is a top
> +	 * level parent: MDSS, and children: MDP5/DPU, DSI, HDMI, eDP etc.
> +	 * Populate the children devices, find the MDP5/DPU node, and then add
> +	 * the interfaces to our components list.
>  	 */
> -	if (of_device_is_compatible(dev->of_node, "qcom,mdss")) {
> +	if (of_device_is_compatible(dev->of_node, "qcom,mdss") ||
> +		of_device_is_compatible(dev->of_node, "qcom,dpu-mdss")) {
>  		ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
>  		if (ret) {
>  			dev_err(dev, "failed to populate children devices\n");
> @@ -1686,7 +1698,7 @@ static int msm_pdev_remove(struct platform_device *pdev)
>  	{ .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 },
>  	{ .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 },
>  #ifdef CONFIG_DRM_MSM_DPU
> -	{ .compatible = "qcom,dpu-kms", .data = (void *)KMS_DPU },
> +	{ .compatible = "qcom,dpu-mdss", .data = (void *)KMS_DPU },
>  #endif
>  	{}
>  };
> diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
> index 90a2521..e8e5e73 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -381,7 +381,7 @@ struct msm_drm_private {
>  	/* subordinate devices, if present: */
>  	struct platform_device *gpu_pdev;
>  
> -	/* top level MDSS wrapper device (for MDP5 only) */
> +	/* top level MDSS wrapper device (for MDP5/DPU only) */
>  	struct msm_mdss *mdss;
>  
>  	/* possibly this should be in the kms component, but it is
> diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
> index 9a7bc7d..5e1de85 100644
> --- a/drivers/gpu/drm/msm/msm_kms.h
> +++ b/drivers/gpu/drm/msm/msm_kms.h
> @@ -144,6 +144,7 @@ struct msm_mdss {
>  };
>  
>  int mdp5_mdss_init(struct drm_device *dev);
> +int dpu_mdss_init(struct drm_device *dev);
>  
>  /**
>   * Mode Set Utility Functions
> diff --git a/include/linux/dpu_io_util.h b/include/linux/dpu_io_util.h
> index 7c73899..45e606f 100644
> --- a/include/linux/dpu_io_util.h
> +++ b/include/linux/dpu_io_util.h
> @@ -104,6 +104,8 @@ int msm_dss_config_vreg(struct device *dev, struct dss_vreg *in_vreg,
>  void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk);
>  int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk);
>  int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable);
> +int msm_dss_parse_clock(struct platform_device *pdev,
> +		struct dss_module_power *mp);
>  
>  int dpu_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
>  		       uint8_t reg_offset, uint8_t *read_buf);
> -- 
> 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
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [DPU PATCH v2 04/12] drm/msm/dpu: create new platform driver for dpu device
       [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
  1 sibling, 0 replies; 24+ messages in thread
From: Sean Paul @ 2018-05-11 15:30 UTC (permalink / raw)
  To: Rajesh Yadav
  Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Fri, May 11, 2018 at 08:19:30PM +0530, Rajesh Yadav wrote:
> Current MSM display controller HW matches a tree like
> hierarchy where MDSS top level wrapper is parent device
> and mdp5/dpu, dsi, dp are child devices.
> 
> Each child device like mdp5, dsi etc. have a separate driver,
> but currently dpu handling is tied to a single driver which
> was managing both mdss and dpu resources.
> 
> Inorder to have the cleaner one to one device and driver
> association, this change adds a new platform_driver for dpu
> child device node which implements the kms functionality.
> 
> The dpu driver implements runtime_pm support for managing clocks
> and bus bandwidth etc.
> 
> Changes in v2:
> 	- remove redundant param check from _dpu_kms_hw_destroy (Sean Paul)
> 	- remove explicit calls to devm_kfree (Sean Paul)
> 	- merge dpu_init into dpu_bind (Sean Paul)
> 	- merge dpu_destroy into dpu_unbind (Sean Paul)
> 	- use %pK for kernel pointer printing (Jordan Crouse)
> 	- remove explicit devm allocation failure message (Jordan Crouse)
> 
> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>

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

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 238 +++++++++++++++++++++++++-------
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |   4 +
>  drivers/gpu/drm/msm/msm_drv.c           |   2 +
>  drivers/gpu/drm/msm/msm_drv.h           |   3 +
>  4 files changed, 196 insertions(+), 51 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index e4ab753..85f3dbc 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> @@ -1030,16 +1030,12 @@ static long dpu_kms_round_pixclk(struct msm_kms *kms, unsigned long rate,
>  	return rate;
>  }
>  
> -static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms,
> -		struct platform_device *pdev)
> +static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
>  {
>  	struct drm_device *dev;
>  	struct msm_drm_private *priv;
>  	int i;
>  
> -	if (!dpu_kms || !pdev)
> -		return;
> -
>  	dev = dpu_kms->dev;
>  	if (!dev)
>  		return;
> @@ -1091,15 +1087,15 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms,
>  	dpu_kms->core_client = NULL;
>  
>  	if (dpu_kms->vbif[VBIF_NRT])
> -		msm_iounmap(pdev, dpu_kms->vbif[VBIF_NRT]);
> +		msm_iounmap(dpu_kms->pdev, dpu_kms->vbif[VBIF_NRT]);
>  	dpu_kms->vbif[VBIF_NRT] = NULL;
>  
>  	if (dpu_kms->vbif[VBIF_RT])
> -		msm_iounmap(pdev, dpu_kms->vbif[VBIF_RT]);
> +		msm_iounmap(dpu_kms->pdev, dpu_kms->vbif[VBIF_RT]);
>  	dpu_kms->vbif[VBIF_RT] = NULL;
>  
>  	if (dpu_kms->mmio)
> -		msm_iounmap(pdev, dpu_kms->mmio);
> +		msm_iounmap(dpu_kms->pdev, dpu_kms->mmio);
>  	dpu_kms->mmio = NULL;
>  
>  	dpu_reg_dma_deinit();
> @@ -1172,8 +1168,6 @@ int dpu_kms_mmu_attach(struct dpu_kms *dpu_kms, bool secure_only)
>  static void dpu_kms_destroy(struct msm_kms *kms)
>  {
>  	struct dpu_kms *dpu_kms;
> -	struct drm_device *dev;
> -	struct platform_device *platformdev;
>  
>  	if (!kms) {
>  		DPU_ERROR("invalid kms\n");
> @@ -1181,20 +1175,7 @@ static void dpu_kms_destroy(struct msm_kms *kms)
>  	}
>  
>  	dpu_kms = to_dpu_kms(kms);
> -	dev = dpu_kms->dev;
> -	if (!dev) {
> -		DPU_ERROR("invalid device\n");
> -		return;
> -	}
> -
> -	platformdev = to_platform_device(dev->dev);
> -	if (!platformdev) {
> -		DPU_ERROR("invalid platform device\n");
> -		return;
> -	}
> -
> -	_dpu_kms_hw_destroy(dpu_kms, platformdev);
> -	kfree(dpu_kms);
> +	_dpu_kms_hw_destroy(dpu_kms);
>  }
>  
>  static void dpu_kms_preclose(struct msm_kms *kms, struct drm_file *file)
> @@ -1550,7 +1531,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
>  	struct dpu_kms *dpu_kms;
>  	struct drm_device *dev;
>  	struct msm_drm_private *priv;
> -	struct platform_device *platformdev;
>  	int i, rc = -EINVAL;
>  
>  	if (!kms) {
> @@ -1565,34 +1545,28 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
>  		goto end;
>  	}
>  
> -	platformdev = to_platform_device(dev->dev);
> -	if (!platformdev) {
> -		DPU_ERROR("invalid platform device\n");
> -		goto end;
> -		}
> -
>  	priv = dev->dev_private;
>  	if (!priv) {
>  		DPU_ERROR("invalid private data\n");
>  		goto end;
>  	}
>  
> -	dpu_kms->mmio = msm_ioremap(platformdev, "mdp_phys", "mdp_phys");
> +	dpu_kms->mmio = msm_ioremap(dpu_kms->pdev, "mdp_phys", "mdp_phys");
>  	if (IS_ERR(dpu_kms->mmio)) {
>  		rc = PTR_ERR(dpu_kms->mmio);
>  		DPU_ERROR("mdp register memory map failed: %d\n", rc);
>  		dpu_kms->mmio = NULL;
>  		goto error;
>  	}
> -	DRM_INFO("mapped mdp address space @%p\n", dpu_kms->mmio);
> -	dpu_kms->mmio_len = msm_iomap_size(platformdev, "mdp_phys");
> +	DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
> +	dpu_kms->mmio_len = msm_iomap_size(dpu_kms->pdev, "mdp_phys");
>  
>  	rc = dpu_dbg_reg_register_base(DPU_DBG_NAME, dpu_kms->mmio,
>  			dpu_kms->mmio_len);
>  	if (rc)
>  		DPU_ERROR("dbg base register kms failed: %d\n", rc);
>  
> -	dpu_kms->vbif[VBIF_RT] = msm_ioremap(platformdev, "vbif_phys",
> +	dpu_kms->vbif[VBIF_RT] = msm_ioremap(dpu_kms->pdev, "vbif_phys",
>  								"vbif_phys");
>  	if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
>  		rc = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
> @@ -1600,20 +1574,20 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
>  		dpu_kms->vbif[VBIF_RT] = NULL;
>  		goto error;
>  	}
> -	dpu_kms->vbif_len[VBIF_RT] = msm_iomap_size(platformdev,
> +	dpu_kms->vbif_len[VBIF_RT] = msm_iomap_size(dpu_kms->pdev,
>  								"vbif_phys");
>  	rc = dpu_dbg_reg_register_base("vbif_rt", dpu_kms->vbif[VBIF_RT],
>  				dpu_kms->vbif_len[VBIF_RT]);
>  	if (rc)
>  		DPU_ERROR("dbg base register vbif_rt failed: %d\n", rc);
>  
> -	dpu_kms->vbif[VBIF_NRT] = msm_ioremap(platformdev, "vbif_nrt_phys",
> +	dpu_kms->vbif[VBIF_NRT] = msm_ioremap(dpu_kms->pdev, "vbif_nrt_phys",
>  								"vbif_nrt_phys");
>  	if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) {
>  		dpu_kms->vbif[VBIF_NRT] = NULL;
>  		DPU_DEBUG("VBIF NRT is not defined");
>  	} else {
> -		dpu_kms->vbif_len[VBIF_NRT] = msm_iomap_size(platformdev,
> +		dpu_kms->vbif_len[VBIF_NRT] = msm_iomap_size(dpu_kms->pdev,
>  							"vbif_nrt_phys");
>  		rc = dpu_dbg_reg_register_base("vbif_nrt",
>  				dpu_kms->vbif[VBIF_NRT],
> @@ -1624,13 +1598,13 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
>  	}
>  
>  #ifdef CONFIG_CHROME_REGDMA
> -	dpu_kms->reg_dma = msm_ioremap(platformdev, "regdma_phys",
> +	dpu_kms->reg_dma = msm_ioremap(dpu_kms->pdev, "regdma_phys",
>  								"regdma_phys");
>  	if (IS_ERR(dpu_kms->reg_dma)) {
>  		dpu_kms->reg_dma = NULL;
>  		DPU_DEBUG("REG_DMA is not defined");
>  	} else {
> -		dpu_kms->reg_dma_len = msm_iomap_size(platformdev,
> +		dpu_kms->reg_dma_len = msm_iomap_size(dpu_kms->pdev,
>  								"regdma_phys");
>  		rc =  dpu_dbg_reg_register_base("reg_dma",
>  				dpu_kms->reg_dma,
> @@ -1804,14 +1778,13 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
>  	dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, false);
>  	pm_runtime_put_sync(dev->dev);
>  error:
> -	_dpu_kms_hw_destroy(dpu_kms, platformdev);
> +	_dpu_kms_hw_destroy(dpu_kms);
>  end:
>  	return rc;
>  }
>  
>  struct msm_kms *dpu_kms_init(struct drm_device *dev)
>  {
> -	struct platform_device *pdev = to_platform_device(dev->dev);
>  	struct msm_drm_private *priv;
>  	struct dpu_kms *dpu_kms;
>  	int irq;
> @@ -1821,24 +1794,187 @@ struct msm_kms *dpu_kms_init(struct drm_device *dev)
>  		return ERR_PTR(-EINVAL);
>  	}
>  
> -	irq = platform_get_irq(pdev, 0);
> +	priv = dev->dev_private;
> +	dpu_kms = to_dpu_kms(priv->kms);
> +
> +	irq = irq_of_parse_and_map(dpu_kms->pdev->dev.of_node, 0);
>  	if (irq < 0) {
>  		DPU_ERROR("failed to get irq: %d\n", irq);
>  		return ERR_PTR(irq);
>  	}
> +	dpu_kms->base.irq = irq;
>  
> -	priv = dev->dev_private;
> +	return &dpu_kms->base;
> +}
>  
> -	dpu_kms = kzalloc(sizeof(*dpu_kms), GFP_KERNEL);
> -	if (!dpu_kms) {
> -		DPU_ERROR("failed to allocate dpu kms\n");
> -		return ERR_PTR(-ENOMEM);
> +static int dpu_bind(struct device *dev, struct device *master, void *data)
> +{
> +	struct drm_device *ddev = dev_get_drvdata(master);
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct msm_drm_private *priv = ddev->dev_private;
> +	struct dpu_kms *dpu_kms;
> +	struct dss_module_power *mp;
> +	int ret = 0;
> +
> +	dpu_kms = devm_kzalloc(&pdev->dev, sizeof(*dpu_kms), GFP_KERNEL);
> +	if (!dpu_kms)
> +		return -ENOMEM;
> +
> +	mp = &dpu_kms->mp;
> +	ret = msm_dss_parse_clock(pdev, mp);
> +	if (ret) {
> +		DPU_ERROR("failed to parse clocks, ret=%d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = msm_dss_get_clk(&pdev->dev, mp->clk_config, mp->num_clk);
> +	if (ret) {
> +		pr_err("failed to get clocks, ret=%d\n", ret);
> +		goto clk_get_error;
> +	}
> +
> +	ret = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
> +	if (ret) {
> +		pr_err("failed to set clock rate, ret=%d\n", ret);
> +		goto clk_rate_error;
>  	}
>  
> +	platform_set_drvdata(pdev, dpu_kms);
> +
>  	msm_kms_init(&dpu_kms->base, &kms_funcs);
> -	dpu_kms->dev = dev;
> -	dpu_kms->base.irq = irq;
> +	dpu_kms->dev = ddev;
> +	dpu_kms->pdev = pdev;
>  
> -	return &dpu_kms->base;
> +	pm_runtime_enable(&pdev->dev);
> +	dpu_kms->rpm_enabled = true;
> +
> +	priv->kms = &dpu_kms->base;
> +	return ret;
> +
> +clk_rate_error:
> +	msm_dss_put_clk(mp->clk_config, mp->num_clk);
> +clk_get_error:
> +	devm_kfree(&pdev->dev, mp->clk_config);
> +	mp->num_clk = 0;
> +	return ret;
>  }
>  
> +static void dpu_unbind(struct device *dev, struct device *master, void *data)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
> +	struct dss_module_power *mp = &dpu_kms->mp;
> +
> +	msm_dss_put_clk(mp->clk_config, mp->num_clk);
> +	devm_kfree(&pdev->dev, mp->clk_config);
> +	mp->num_clk = 0;
> +
> +	if (dpu_kms->rpm_enabled)
> +		pm_runtime_disable(&pdev->dev);
> +}
> +
> +static const struct component_ops dpu_ops = {
> +	.bind   = dpu_bind,
> +	.unbind = dpu_unbind,
> +};
> +
> +static int dpu_dev_probe(struct platform_device *pdev)
> +{
> +	return component_add(&pdev->dev, &dpu_ops);
> +}
> +
> +static int dpu_dev_remove(struct platform_device *pdev)
> +{
> +	component_del(&pdev->dev, &dpu_ops);
> +	return 0;
> +}
> +
> +static int dpu_runtime_suspend(struct device *dev)
> +{
> +	int rc = -1;
> +	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;
> +	if (!ddev) {
> +		DPU_ERROR("invalid drm_device\n");
> +		goto exit;
> +	}
> +	priv = ddev->dev_private;
> +
> +	rc = dpu_power_resource_enable(&priv->phandle,
> +		dpu_kms->core_client, false);
> +	if (rc)
> +		DPU_ERROR("resource disable failed: %d\n", rc);
> +
> +	rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
> +	if (rc)
> +		DPU_ERROR("clock disable failed rc:%d\n", rc);
> +
> +exit:
> +	return rc;
> +}
> +
> +static int dpu_runtime_resume(struct device *dev)
> +{
> +	int rc = -1;
> +	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;
> +	if (!ddev) {
> +		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) {
> +		DPU_ERROR("clock enable failed rc:%d\n", rc);
> +		goto exit;
> +	}
> +
> +	rc = dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client,
> +		true);
> +	if (rc)
> +		DPU_ERROR("resource enable failed: %d\n", rc);
> +
> +exit:
> +	return rc;
> +}
> +
> +static const struct dev_pm_ops dpu_pm_ops = {
> +	SET_RUNTIME_PM_OPS(dpu_runtime_suspend, dpu_runtime_resume, NULL)
> +};
> +
> +static const struct of_device_id dpu_dt_match[] = {
> +	{ .compatible = "qcom,dpu", },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, dpu_dt_match);
> +
> +static struct platform_driver dpu_driver = {
> +	.probe = dpu_dev_probe,
> +	.remove = dpu_dev_remove,
> +	.driver = {
> +		.name = "msm_dpu",
> +		.of_match_table = dpu_dt_match,
> +		.pm = &dpu_pm_ops,
> +	},
> +};
> +
> +void __init msm_dpu_register(void)
> +{
> +	platform_driver_register(&dpu_driver);
> +}
> +
> +void __exit msm_dpu_unregister(void)
> +{
> +	platform_driver_unregister(&dpu_driver);
> +}
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> index a1c0910..3c69921 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> @@ -200,6 +200,10 @@ struct dpu_kms {
>  	struct dpu_hw_mdp *hw_mdp;
>  
>  	bool has_danger_ctrl;
> +
> +	struct platform_device *pdev;
> +	bool rpm_enabled;
> +	struct dss_module_power mp;
>  };
>  
>  struct vsync_info {
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index a0e73ea..5470529 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -1731,6 +1731,7 @@ static int __init msm_drm_register(void)
>  
>  	DBG("init");
>  	msm_mdp_register();
> +	msm_dpu_register();
>  	msm_dsi_register();
>  	msm_edp_register();
>  	msm_hdmi_register();
> @@ -1747,6 +1748,7 @@ static void __exit msm_drm_unregister(void)
>  	msm_edp_unregister();
>  	msm_dsi_unregister();
>  	msm_mdp_unregister();
> +	msm_dpu_unregister();
>  }
>  
>  module_init(msm_drm_register);
> diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
> index e8e5e73..22a3096 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -682,6 +682,9 @@ static inline int msm_dsi_modeset_init(struct msm_dsi *msm_dsi,
>  void __init msm_mdp_register(void);
>  void __exit msm_mdp_unregister(void);
>  
> +void __init msm_dpu_register(void);
> +void __exit msm_dpu_unregister(void);
> +
>  #ifdef CONFIG_DEBUG_FS
>  void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m);
>  void msm_gem_describe_objects(struct list_head *list, struct seq_file *m);
> -- 
> 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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [DPU PATCH v2 07/12] drm/msm/dpu: remove clock management code from dpu_power_handle
       [not found]     ` <1526050178-31893-8-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
@ 2018-05-11 15:35       ` Sean Paul
  0 siblings, 0 replies; 24+ messages in thread
From: Sean Paul @ 2018-05-11 15:35 UTC (permalink / raw)
  To: Rajesh Yadav
  Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Fri, May 11, 2018 at 08:19:33PM +0530, Rajesh Yadav wrote:
> MDSS and dpu drivers manage their respective clocks via
> runtime_pm. Remove custom clock management code from
> dpu_power_handle.
> 
> Also dpu core clock management code is restricted to
> dpu_core_perf module.
> 
> Changes in v2:
> 	- remove local variable to hold and return error code
> 	  in _dpu_core_perf_set_core_clk_rate() instead return
> 	  retcode directly from msm_dss_clk_set_rate() call (Sean Paul)
> 	- dpu_core_perf_init() is called from dpu_kms_hw_init() and
> 	  most of the params passed are already validated so remove
> 	  redundant checks from dpu_core_perf_init() (Sean Paul)
> 	- return &mp->clk_config[i] directly to avoid local variable
> 	  in _dpu_kms_get_clk() (Sean Paul)
> 	- invert conditional check to eliminate local rate variable
> 	  from dpu_kms_get_clk_rate() (Sean Paul)
> 	- remove end label from dpu_power_resource_init() and return
> 	  directly on dpu_power_parse_dt_supply() failure as no cleanup
> 	  is needed (Sean Paul)
> 	- remove checks for vtotal and vrefresh from
>  	  dpu_encoder_phys_cmd_tearcheck_config() as they should be
> 	  valid in mode_set call (Sean Paul)
> 
> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>

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

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c      |  41 ++---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h      |   8 +-
>  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c   |   9 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c            |  28 ++-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h            |   9 +
>  drivers/gpu/drm/msm/dpu_power_handle.c             | 196 +--------------------
>  drivers/gpu/drm/msm/dpu_power_handle.h             |  40 -----
>  7 files changed, 63 insertions(+), 268 deletions(-)
> 
> 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 981f77f..5b79077 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
> @@ -365,6 +365,17 @@ void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc)
>  	}
>  }
>  
> +static int _dpu_core_perf_set_core_clk_rate(struct dpu_kms *kms, u64 rate)
> +{
> +	struct dss_clk *core_clk = kms->perf.core_clk;
> +
> +	if (core_clk->max_rate && (rate > core_clk->max_rate))
> +		rate = core_clk->max_rate;
> +
> +	core_clk->rate = rate;
> +	return msm_dss_clk_set_rate(core_clk, 1);
> +}
> +
>  static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms)
>  {
>  	u64 clk_rate = kms->perf.perf_tune.min_core_clk;
> @@ -376,7 +387,8 @@ static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms)
>  			dpu_cstate = to_dpu_crtc_state(crtc->state);
>  			clk_rate = max(dpu_cstate->new_perf.core_clk_rate,
>  							clk_rate);
> -			clk_rate = clk_round_rate(kms->perf.core_clk, clk_rate);
> +			clk_rate = clk_round_rate(kms->perf.core_clk->clk,
> +					clk_rate);
>  		}
>  	}
>  
> @@ -484,15 +496,11 @@ void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
>  
>  		DPU_EVT32(kms->dev, stop_req, clk_rate);
>  
> -		/* Temp change to avoid crash in clk_set_rate API. */
> -#ifdef QCOM_DPU_SET_CLK
> -		if (dpu_power_clk_set_rate(&priv->phandle,
> -					   kms->perf.clk_name, clk_rate)) {
> +		if (_dpu_core_perf_set_core_clk_rate(kms, clk_rate)) {
>  			DPU_ERROR("failed to set %s clock rate %llu\n",
> -					kms->perf.clk_name, clk_rate);
> +					kms->perf.core_clk->clk_name, clk_rate);
>  			return;
>  		}
> -#endif
>  
>  		kms->perf.core_clk_rate = clk_rate;
>  		DPU_DEBUG("update clk rate = %lld HZ\n", clk_rate);
> @@ -656,7 +664,6 @@ void dpu_core_perf_destroy(struct dpu_core_perf *perf)
>  	dpu_core_perf_debugfs_destroy(perf);
>  	perf->max_core_clk_rate = 0;
>  	perf->core_clk = NULL;
> -	perf->clk_name = NULL;
>  	perf->phandle = NULL;
>  	perf->catalog = NULL;
>  	perf->dev = NULL;
> @@ -667,9 +674,9 @@ int dpu_core_perf_init(struct dpu_core_perf *perf,
>  		struct dpu_mdss_cfg *catalog,
>  		struct dpu_power_handle *phandle,
>  		struct dpu_power_client *pclient,
> -		char *clk_name)
> +		struct dss_clk *core_clk)
>  {
> -	if (!perf || !dev || !catalog || !phandle || !pclient || !clk_name) {
> +	if (!pclient) {
>  		DPU_ERROR("invalid parameters\n");
>  		return -EINVAL;
>  	}
> @@ -678,23 +685,13 @@ int dpu_core_perf_init(struct dpu_core_perf *perf,
>  	perf->catalog = catalog;
>  	perf->phandle = phandle;
>  	perf->pclient = pclient;
> -	perf->clk_name = clk_name;
> -
> -	perf->core_clk = dpu_power_clk_get_clk(phandle, clk_name);
> -	if (!perf->core_clk) {
> -		DPU_ERROR("invalid core clk\n");
> -		goto err;
> -	}
> +	perf->core_clk = core_clk;
>  
> -	perf->max_core_clk_rate = dpu_power_clk_get_max_rate(phandle, clk_name);
> +	perf->max_core_clk_rate = core_clk->max_rate;
>  	if (!perf->max_core_clk_rate) {
>  		DPU_DEBUG("optional max core clk rate, use default\n");
>  		perf->max_core_clk_rate = DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE;
>  	}
>  
>  	return 0;
> -
> -err:
> -	dpu_core_perf_destroy(perf);
> -	return -ENODEV;
>  }
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
> index 1965ff5..9c1a719 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
> @@ -54,7 +54,6 @@ struct dpu_core_perf_tune {
>   * @catalog: Pointer to catalog configuration
>   * @phandle: Pointer to power handler
>   * @pclient: Pointer to power client
> - * @clk_name: core clock name
>   * @core_clk: Pointer to core clock structure
>   * @core_clk_rate: current core clock rate
>   * @max_core_clk_rate: maximum allowable core clock rate
> @@ -70,8 +69,7 @@ struct dpu_core_perf {
>  	struct dpu_mdss_cfg *catalog;
>  	struct dpu_power_handle *phandle;
>  	struct dpu_power_client *pclient;
> -	char *clk_name;
> -	struct clk *core_clk;
> +	struct dss_clk *core_clk;
>  	u64 core_clk_rate;
>  	u64 max_core_clk_rate;
>  	struct dpu_core_perf_tune perf_tune;
> @@ -118,14 +116,14 @@ void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
>   * @catalog: Pointer to catalog
>   * @phandle: Pointer to power handle
>   * @pclient: Pointer to power client
> - * @clk_name: core clock name
> + * @core_clk: pointer to core clock
>   */
>  int dpu_core_perf_init(struct dpu_core_perf *perf,
>  		struct drm_device *dev,
>  		struct dpu_mdss_cfg *catalog,
>  		struct dpu_power_handle *phandle,
>  		struct dpu_power_client *pclient,
> -		char *clk_name);
> +		struct dss_clk *core_clk);
>  
>  /**
>   * dpu_core_perf_debugfs_init - initialize debugfs for core performance context
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> index 072939c..388de38 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> @@ -428,11 +428,10 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
>  	 * vsync_count is ratio of MDP VSYNC clock frequency to LCD panel
>  	 * frequency divided by the no. of rows (lines) in the LCDpanel.
>  	 */
> -	vsync_hz = dpu_power_clk_get_rate(&priv->phandle, "vsync_clk");
> -	if (!vsync_hz || !mode->vtotal || !mode->vrefresh) {
> -		DPU_DEBUG_CMDENC(cmd_enc,
> -			"invalid params - vsync_hz %u vtot %u vrefresh %u\n",
> -			vsync_hz, mode->vtotal, mode->vrefresh);
> +	vsync_hz = dpu_kms_get_clk_rate(dpu_kms, "vsync_clk");
> +	if (vsync_hz <= 0) {
> +		DPU_DEBUG_CMDENC(cmd_enc, "invalid - vsync_hz %u\n",
> +				 vsync_hz);
>  		return;
>  	}
>  
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index cda4d12..349bda5 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> @@ -1499,6 +1499,31 @@ static int _dpu_kms_mmu_init(struct dpu_kms *dpu_kms)
>  	return ret;
>  }
>  
> +static struct dss_clk *_dpu_kms_get_clk(struct dpu_kms *dpu_kms,
> +		char *clock_name)
> +{
> +	struct dss_module_power *mp = &dpu_kms->mp;
> +	int i;
> +
> +	for (i = 0; i < mp->num_clk; i++) {
> +		if (!strcmp(mp->clk_config[i].clk_name, clock_name))
> +			return &mp->clk_config[i];
> +	}
> +
> +	return NULL;
> +}
> +
> +u64 dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name)
> +{
> +	struct dss_clk *clk;
> +
> +	clk = _dpu_kms_get_clk(dpu_kms, clock_name);
> +	if (!clk)
> +		return -EINVAL;
> +
> +	return clk_get_rate(clk->clk);
> +}
> +
>  static void dpu_kms_handle_power_event(u32 event_type, void *usr)
>  {
>  	struct dpu_kms *dpu_kms = usr;
> @@ -1696,7 +1721,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, priv->pclient, "core_clk");
> +			&priv->phandle, priv->pclient,
> +			_dpu_kms_get_clk(dpu_kms, "core_clk"));
>  	if (rc) {
>  		DPU_ERROR("failed to init perf %d\n", rc);
>  		goto perf_err;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> index 3c69921..a8255fe 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> @@ -537,4 +537,13 @@ struct dpu_kms_fbo *dpu_kms_fbo_alloc(struct drm_device *dev,
>  
>  void dpu_kms_encoder_enable(struct drm_encoder *encoder);
>  
> +/**
> + * dpu_kms_get_clk_rate() - get the clock rate
> + * @dpu_kms:  poiner to dpu_kms structure
> + * @clock_name: clock name to get the rate
> + *
> + * Return: current clock rate
> + */
> +u64 dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name);
> +
>  #endif /* __dpu_kms_H__ */
> diff --git a/drivers/gpu/drm/msm/dpu_power_handle.c b/drivers/gpu/drm/msm/dpu_power_handle.c
> index e9e344a..12602ae 100644
> --- a/drivers/gpu/drm/msm/dpu_power_handle.c
> +++ b/drivers/gpu/drm/msm/dpu_power_handle.c
> @@ -13,7 +13,6 @@
>  
>  #define pr_fmt(fmt)	"[drm:%s:%d]: " fmt, __func__, __LINE__
>  
> -#include <linux/clk.h>
>  #include <linux/kernel.h>
>  #include <linux/of.h>
>  #include <linux/string.h>
> @@ -246,62 +245,6 @@ static int dpu_power_parse_dt_supply(struct platform_device *pdev,
>  	return rc;
>  }
>  
> -static int dpu_power_parse_dt_clock(struct platform_device *pdev,
> -					struct dss_module_power *mp)
> -{
> -	u32 i = 0, rc = 0;
> -	const char *clock_name;
> -	u32 clock_rate = 0;
> -	u32 clock_max_rate = 0;
> -	int num_clk = 0;
> -
> -	if (!pdev || !mp) {
> -		pr_err("invalid input param pdev:%pK mp:%pK\n", pdev, mp);
> -		return -EINVAL;
> -	}
> -
> -	mp->num_clk = 0;
> -	num_clk = of_property_count_strings(pdev->dev.of_node,
> -							"clock-names");
> -	if (num_clk <= 0) {
> -		pr_debug("clocks are not defined\n");
> -		goto clk_err;
> -	}
> -
> -	mp->num_clk = num_clk;
> -	mp->clk_config = devm_kzalloc(&pdev->dev,
> -			sizeof(struct dss_clk) * num_clk, GFP_KERNEL);
> -	if (!mp->clk_config) {
> -		rc = -ENOMEM;
> -		mp->num_clk = 0;
> -		goto clk_err;
> -	}
> -
> -	for (i = 0; i < num_clk; i++) {
> -		of_property_read_string_index(pdev->dev.of_node, "clock-names",
> -							i, &clock_name);
> -		strlcpy(mp->clk_config[i].clk_name, clock_name,
> -				sizeof(mp->clk_config[i].clk_name));
> -
> -		of_property_read_u32_index(pdev->dev.of_node, "clock-rate",
> -							i, &clock_rate);
> -		mp->clk_config[i].rate = clock_rate;
> -
> -		if (!clock_rate)
> -			mp->clk_config[i].type = DSS_CLK_AHB;
> -		else
> -			mp->clk_config[i].type = DSS_CLK_PCLK;
> -
> -		clock_max_rate = 0;
> -		of_property_read_u32_index(pdev->dev.of_node, "clock-max-rate",
> -							i, &clock_max_rate);
> -		mp->clk_config[i].max_rate = clock_max_rate;
> -	}
> -
> -clk_err:
> -	return rc;
> -}
> -
>  #ifdef CONFIG_QCOM_BUS_SCALING
>  
>  #define MAX_AXI_PORT_COUNT 3
> @@ -681,16 +624,10 @@ int dpu_power_resource_init(struct platform_device *pdev,
>  	mp = &phandle->mp;
>  	phandle->dev = &pdev->dev;
>  
> -	rc = dpu_power_parse_dt_clock(pdev, mp);
> -	if (rc) {
> -		pr_err("device clock parsing failed\n");
> -		goto end;
> -	}
> -
>  	rc = dpu_power_parse_dt_supply(pdev, mp);
>  	if (rc) {
>  		pr_err("device vreg supply parsing failed\n");
> -		goto parse_vreg_err;
> +		return rc;
>  	}
>  
>  	rc = msm_dss_config_vreg(&pdev->dev,
> @@ -700,18 +637,6 @@ int dpu_power_resource_init(struct platform_device *pdev,
>  		goto vreg_err;
>  	}
>  
> -	rc = msm_dss_get_clk(&pdev->dev, mp->clk_config, mp->num_clk);
> -	if (rc) {
> -		pr_err("clock get failed rc=%d\n", rc);
> -		goto clk_err;
> -	}
> -
> -	rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
> -	if (rc) {
> -		pr_err("clock set rate failed rc=%d\n", rc);
> -		goto bus_err;
> -	}
> -
>  	rc = dpu_power_reg_bus_parse(pdev, phandle);
>  	if (rc) {
>  		pr_err("register bus parse failed rc=%d\n", rc);
> @@ -742,18 +667,11 @@ int dpu_power_resource_init(struct platform_device *pdev,
>  		dpu_power_data_bus_unregister(&phandle->data_bus_handle[i]);
>  	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
>  bus_err:
> -	msm_dss_put_clk(mp->clk_config, mp->num_clk);
> -clk_err:
>  	msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, 0);
>  vreg_err:
>  	if (mp->vreg_config)
>  		devm_kfree(&pdev->dev, mp->vreg_config);
>  	mp->num_vreg = 0;
> -parse_vreg_err:
> -	if (mp->clk_config)
> -		devm_kfree(&pdev->dev, mp->clk_config);
> -	mp->num_clk = 0;
> -end:
>  	return rc;
>  }
>  
> @@ -796,19 +714,12 @@ void dpu_power_resource_deinit(struct platform_device *pdev,
>  
>  	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
>  
> -	msm_dss_put_clk(mp->clk_config, mp->num_clk);
> -
>  	msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, 0);
>  
> -	if (mp->clk_config)
> -		devm_kfree(&pdev->dev, mp->clk_config);
> -
>  	if (mp->vreg_config)
>  		devm_kfree(&pdev->dev, mp->vreg_config);
>  
>  	mp->num_vreg = 0;
> -	mp->num_clk = 0;
> -
>  }
>  
>  int dpu_power_resource_enable(struct dpu_power_handle *phandle,
> @@ -885,12 +796,6 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
>  			goto reg_bus_hdl_err;
>  		}
>  
> -		rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
> -		if (rc) {
> -			pr_err("clock enable failed rc:%d\n", rc);
> -			goto clk_err;
> -		}
> -
>  		dpu_power_event_trigger_locked(phandle,
>  				DPU_POWER_EVENT_POST_ENABLE);
>  
> @@ -898,8 +803,6 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
>  		dpu_power_event_trigger_locked(phandle,
>  				DPU_POWER_EVENT_PRE_DISABLE);
>  
> -		msm_dss_enable_clk(mp->clk_config, mp->num_clk, enable);
> -
>  		dpu_power_reg_bus_update(phandle->reg_bus_hdl,
>  							max_usecase_ndx);
>  
> @@ -917,8 +820,6 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
>  	mutex_unlock(&phandle->phandle_lock);
>  	return rc;
>  
> -clk_err:
> -	dpu_power_reg_bus_update(phandle->reg_bus_hdl, prev_usecase_ndx);
>  reg_bus_hdl_err:
>  	msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, 0);
>  vreg_err:
> @@ -930,101 +831,6 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
>  	return rc;
>  }
>  
> -int dpu_power_clk_set_rate(struct dpu_power_handle *phandle, char *clock_name,
> -	u64 rate)
> -{
> -	int i, rc = -EINVAL;
> -	struct dss_module_power *mp;
> -
> -	if (!phandle) {
> -		pr_err("invalid input power handle\n");
> -		return -EINVAL;
> -	}
> -	mp = &phandle->mp;
> -
> -	for (i = 0; i < mp->num_clk; i++) {
> -		if (!strcmp(mp->clk_config[i].clk_name, clock_name)) {
> -			if (mp->clk_config[i].max_rate &&
> -					(rate > mp->clk_config[i].max_rate))
> -				rate = mp->clk_config[i].max_rate;
> -
> -			mp->clk_config[i].rate = rate;
> -			rc = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
> -			break;
> -		}
> -	}
> -
> -	return rc;
> -}
> -
> -u64 dpu_power_clk_get_rate(struct dpu_power_handle *phandle, char *clock_name)
> -{
> -	int i;
> -	struct dss_module_power *mp;
> -	u64 rate = -EINVAL;
> -
> -	if (!phandle) {
> -		pr_err("invalid input power handle\n");
> -		return -EINVAL;
> -	}
> -	mp = &phandle->mp;
> -
> -	for (i = 0; i < mp->num_clk; i++) {
> -		if (!strcmp(mp->clk_config[i].clk_name, clock_name)) {
> -			rate = clk_get_rate(mp->clk_config[i].clk);
> -			break;
> -		}
> -	}
> -
> -	return rate;
> -}
> -
> -u64 dpu_power_clk_get_max_rate(struct dpu_power_handle *phandle,
> -		char *clock_name)
> -{
> -	int i;
> -	struct dss_module_power *mp;
> -	u64 rate = 0;
> -
> -	if (!phandle) {
> -		pr_err("invalid input power handle\n");
> -		return 0;
> -	}
> -	mp = &phandle->mp;
> -
> -	for (i = 0; i < mp->num_clk; i++) {
> -		if (!strcmp(mp->clk_config[i].clk_name, clock_name)) {
> -			rate = mp->clk_config[i].max_rate;
> -			break;
> -		}
> -	}
> -
> -	return rate;
> -}
> -
> -struct clk *dpu_power_clk_get_clk(struct dpu_power_handle *phandle,
> -		char *clock_name)
> -{
> -	int i;
> -	struct dss_module_power *mp;
> -	struct clk *clk = NULL;
> -
> -	if (!phandle) {
> -		pr_err("invalid input power handle\n");
> -		return 0;
> -	}
> -	mp = &phandle->mp;
> -
> -	for (i = 0; i < mp->num_clk; i++) {
> -		if (!strcmp(mp->clk_config[i].clk_name, clock_name)) {
> -			clk = mp->clk_config[i].clk;
> -			break;
> -		}
> -	}
> -
> -	return clk;
> -}
> -
>  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),
> diff --git a/drivers/gpu/drm/msm/dpu_power_handle.h b/drivers/gpu/drm/msm/dpu_power_handle.h
> index 1edae5c..83f048d 100644
> --- a/drivers/gpu/drm/msm/dpu_power_handle.h
> +++ b/drivers/gpu/drm/msm/dpu_power_handle.h
> @@ -230,46 +230,6 @@ int dpu_power_data_bus_state_update(struct dpu_power_handle *phandle,
>  							bool enable);
>  
>  /**
> - * dpu_power_clk_set_rate() - set the clock rate
> - * @pdata:  power handle containing the resources
> - * @clock_name: clock name which needs rate update.
> - * @rate:       Requested rate.
> - *
> - * Return: error code.
> - */
> -int dpu_power_clk_set_rate(struct dpu_power_handle *pdata, char *clock_name,
> -	u64 rate);
> -
> -/**
> - * dpu_power_clk_get_rate() - get the clock rate
> - * @pdata:  power handle containing the resources
> - * @clock_name: clock name to get the rate
> - *
> - * Return: current clock rate
> - */
> -u64 dpu_power_clk_get_rate(struct dpu_power_handle *pdata, char *clock_name);
> -
> -/**
> - * dpu_power_clk_get_max_rate() - get the maximum clock rate
> - * @pdata:  power handle containing the resources
> - * @clock_name: clock name to get the max rate.
> - *
> - * Return: maximum clock rate or 0 if not found.
> - */
> -u64 dpu_power_clk_get_max_rate(struct dpu_power_handle *pdata,
> -		char *clock_name);
> -
> -/**
> - * dpu_power_clk_get_clk() - get the clock
> - * @pdata:  power handle containing the resources
> - * @clock_name: clock name to get the clk pointer.
> - *
> - * Return: Pointer to clock
> - */
> -struct clk *dpu_power_clk_get_clk(struct dpu_power_handle *phandle,
> -		char *clock_name);
> -
> -/**
>   * 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
> -- 
> 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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [DPU PATCH v2 08/12] drm/msm/dpu: remove power management code from dpu_power_handle
       [not found]     ` <1526050178-31893-9-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
@ 2018-05-11 15:40       ` Sean Paul
  0 siblings, 0 replies; 24+ messages in thread
From: Sean Paul @ 2018-05-11 15:40 UTC (permalink / raw)
  To: Rajesh Yadav
  Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Fri, May 11, 2018 at 08:19:34PM +0530, Rajesh Yadav wrote:
> Mdss main power supply (mdss_gdsc) is implemented as a
> generic power domain and mdss top level wrapper device
> manage it via runtime_pm. Remove custom power management
> code from dpu_power_handle.
> 
> Changes in v2:
> 	- resolved merge conflict in dpu_power_resource_init
> 	- dropped (Reviewed-by: Sean Paul) due to above change
> 
> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
> ---
>  drivers/gpu/drm/msm/dpu_power_handle.c | 194 +--------------------------------
>  drivers/gpu/drm/msm/dpu_power_handle.h |   2 -
>  2 files changed, 3 insertions(+), 193 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/dpu_power_handle.c b/drivers/gpu/drm/msm/dpu_power_handle.c
> index 12602ae..77be106 100644
> --- a/drivers/gpu/drm/msm/dpu_power_handle.c
> +++ b/drivers/gpu/drm/msm/dpu_power_handle.c

/snip

> @@ -614,33 +470,18 @@ int dpu_power_resource_init(struct platform_device *pdev,
>  	struct dpu_power_handle *phandle)
>  {
>  	int rc = 0, i;
> -	struct dss_module_power *mp;
>  
>  	if (!phandle || !pdev) {

Can this ever happen? It seems like another case of unnecessary checking.

Aside from this,

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


>  		pr_err("invalid input param\n");
> -		rc = -EINVAL;
> -		goto end;
> -	}
> -	mp = &phandle->mp;
> -	phandle->dev = &pdev->dev;
> -
> -	rc = dpu_power_parse_dt_supply(pdev, mp);
> -	if (rc) {
> -		pr_err("device vreg supply parsing failed\n");
> -		return rc;
> +		return -EINVAL;
>  	}
>  
> -	rc = msm_dss_config_vreg(&pdev->dev,
> -				mp->vreg_config, mp->num_vreg, 1);
> -	if (rc) {
> -		pr_err("vreg config failed rc=%d\n", rc);
> -		goto vreg_err;
> -	}
> +	phandle->dev = &pdev->dev;
>  
>  	rc = dpu_power_reg_bus_parse(pdev, phandle);
>  	if (rc) {
>  		pr_err("register bus parse failed rc=%d\n", rc);
> -		goto bus_err;
> +		return rc;
>  	}
>  
>  	for (i = DPU_POWER_HANDLE_DBUS_ID_MNOC;
> @@ -666,19 +507,12 @@ int dpu_power_resource_init(struct platform_device *pdev,
>  	for (i--; i >= 0; i--)
>  		dpu_power_data_bus_unregister(&phandle->data_bus_handle[i]);
>  	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
> -bus_err:
> -	msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, 0);
> -vreg_err:
> -	if (mp->vreg_config)
> -		devm_kfree(&pdev->dev, mp->vreg_config);
> -	mp->num_vreg = 0;
>  	return rc;
>  }
>  
>  void dpu_power_resource_deinit(struct platform_device *pdev,
>  	struct dpu_power_handle *phandle)
>  {
> -	struct dss_module_power *mp;
>  	struct dpu_power_client *curr_client, *next_client;
>  	struct dpu_power_event *curr_event, *next_event;
>  	int i;
> @@ -687,7 +521,6 @@ void dpu_power_resource_deinit(struct platform_device *pdev,
>  		pr_err("invalid input param\n");
>  		return;
>  	}
> -	mp = &phandle->mp;
>  
>  	mutex_lock(&phandle->phandle_lock);
>  	list_for_each_entry_safe(curr_client, next_client,
> @@ -713,13 +546,6 @@ void dpu_power_resource_deinit(struct platform_device *pdev,
>  		dpu_power_data_bus_unregister(&phandle->data_bus_handle[i]);
>  
>  	dpu_power_reg_bus_unregister(phandle->reg_bus_hdl);
> -
> -	msm_dss_config_vreg(&pdev->dev, mp->vreg_config, mp->num_vreg, 0);
> -
> -	if (mp->vreg_config)
> -		devm_kfree(&pdev->dev, mp->vreg_config);
> -
> -	mp->num_vreg = 0;
>  }
>  
>  int dpu_power_resource_enable(struct dpu_power_handle *phandle,
> @@ -729,15 +555,12 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
>  	bool changed = false;
>  	u32 max_usecase_ndx = VOTE_INDEX_DISABLE, prev_usecase_ndx;
>  	struct dpu_power_client *client;
> -	struct dss_module_power *mp;
>  
>  	if (!phandle || !pclient) {
>  		pr_err("invalid input argument\n");
>  		return -EINVAL;
>  	}
>  
> -	mp = &phandle->mp;
> -
>  	mutex_lock(&phandle->phandle_lock);
>  	if (enable)
>  		pclient->refcount++;
> @@ -782,13 +605,6 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
>  			}
>  		}
>  
> -		rc = msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg,
> -								enable);
> -		if (rc) {
> -			pr_err("failed to enable vregs rc=%d\n", rc);
> -			goto vreg_err;
> -		}
> -
>  		rc = dpu_power_reg_bus_update(phandle->reg_bus_hdl,
>  							max_usecase_ndx);
>  		if (rc) {
> @@ -806,8 +622,6 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
>  		dpu_power_reg_bus_update(phandle->reg_bus_hdl,
>  							max_usecase_ndx);
>  
> -		msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg,
> -							enable);
>  		for (i = 0 ; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++)
>  			dpu_power_data_bus_update(&phandle->data_bus_handle[i],
>  					enable);
> @@ -821,8 +635,6 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle,
>  	return rc;
>  
>  reg_bus_hdl_err:
> -	msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, 0);
> -vreg_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:
> diff --git a/drivers/gpu/drm/msm/dpu_power_handle.h b/drivers/gpu/drm/msm/dpu_power_handle.h
> index 83f048d..9a6d4b9 100644
> --- a/drivers/gpu/drm/msm/dpu_power_handle.h
> +++ b/drivers/gpu/drm/msm/dpu_power_handle.h
> @@ -147,7 +147,6 @@ struct dpu_power_event {
>  
>  /**
>   * struct dpu_power_handle: power handle main struct
> - * @mp:		module power for clock and regulator
>   * @client_clist: master list to store all clients
>   * @phandle_lock: lock to synchronize the enable/disable
>   * @dev: pointer to device structure
> @@ -157,7 +156,6 @@ struct dpu_power_event {
>   * @event_list: current power handle event list
>   */
>  struct dpu_power_handle {
> -	struct dss_module_power mp;
>  	struct list_head power_client_clist;
>  	struct mutex phandle_lock;
>  	struct device *dev;
> -- 
> 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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [DPU PATCH v2 10/12] drm/msm/dpu: use runtime_pm calls in dpu_dbg
       [not found]     ` <1526050178-31893-11-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
@ 2018-05-11 15:47       ` Sean Paul
  0 siblings, 0 replies; 24+ messages in thread
From: Sean Paul @ 2018-05-11 15:47 UTC (permalink / raw)
  To: Rajesh Yadav
  Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Fri, May 11, 2018 at 08:19:36PM +0530, Rajesh Yadav wrote:
> Currently, msm_drv was creating dpu_power_handle client
> which was used by dpu_dbg module to enable power resources
> before register debug dumping.
> 
> Now since, the mdss core power resource handling is
> implemented via runtime_pm and same has been removed
> from dpu_power_handle. Remove dpu_power_handle dependency
> from msm_drv and use pm_runtime_get/put_sync calls from
> dpu_dbg module on dpu_mdss top level device for core,
> ahb clock and power resource management (for register access).
> 
> Changes in v2:
> 	- resolved conflict in dpu_core_perf_init
> 	- 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/disp/dpu1/dpu_core_perf.c |  7 -------
>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h |  4 ----
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c       |  3 +--
>  drivers/gpu/drm/msm/dpu_dbg.c                 | 18 +++++++-----------
>  drivers/gpu/drm/msm/dpu_dbg.h                 | 13 ++-----------
>  drivers/gpu/drm/msm/msm_drv.c                 | 27 +--------------------------
>  drivers/gpu/drm/msm/msm_drv.h                 |  1 -
>  7 files changed, 11 insertions(+), 62 deletions(-)
> 
> 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 5b79077..2cf3fca 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
> @@ -673,18 +673,11 @@ int dpu_core_perf_init(struct dpu_core_perf *perf,
>  		struct drm_device *dev,
>  		struct dpu_mdss_cfg *catalog,
>  		struct dpu_power_handle *phandle,
> -		struct dpu_power_client *pclient,
>  		struct dss_clk *core_clk)
>  {
> -	if (!pclient) {
> -		DPU_ERROR("invalid parameters\n");
> -		return -EINVAL;
> -	}
> -
>  	perf->dev = dev;
>  	perf->catalog = catalog;
>  	perf->phandle = phandle;
> -	perf->pclient = pclient;
>  	perf->core_clk = core_clk;
>  
>  	perf->max_core_clk_rate = core_clk->max_rate;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
> index 9c1a719..cde48df 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
> @@ -53,7 +53,6 @@ struct dpu_core_perf_tune {
>   * @debugfs_root: top level debug folder
>   * @catalog: Pointer to catalog configuration
>   * @phandle: Pointer to power handler
> - * @pclient: Pointer to power client
>   * @core_clk: Pointer to core clock structure
>   * @core_clk_rate: current core clock rate
>   * @max_core_clk_rate: maximum allowable core clock rate
> @@ -68,7 +67,6 @@ struct dpu_core_perf {
>  	struct dentry *debugfs_root;
>  	struct dpu_mdss_cfg *catalog;
>  	struct dpu_power_handle *phandle;
> -	struct dpu_power_client *pclient;
>  	struct dss_clk *core_clk;
>  	u64 core_clk_rate;
>  	u64 max_core_clk_rate;
> @@ -115,14 +113,12 @@ void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
>   * @dev: Pointer to drm device
>   * @catalog: Pointer to catalog
>   * @phandle: Pointer to power handle
> - * @pclient: Pointer to power client
>   * @core_clk: pointer to core clock
>   */
>  int dpu_core_perf_init(struct dpu_core_perf *perf,
>  		struct drm_device *dev,
>  		struct dpu_mdss_cfg *catalog,
>  		struct dpu_power_handle *phandle,
> -		struct dpu_power_client *pclient,
>  		struct dss_clk *core_clk);
>  
>  /**
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index 349bda5..9c3b220 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> @@ -1721,8 +1721,7 @@ 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, priv->pclient,
> -			_dpu_kms_get_clk(dpu_kms, "core_clk"));
> +			&priv->phandle, _dpu_kms_get_clk(dpu_kms, "core_clk"));
>  	if (rc) {
>  		DPU_ERROR("failed to init perf %d\n", rc);
>  		goto perf_err;
> diff --git a/drivers/gpu/drm/msm/dpu_dbg.c b/drivers/gpu/drm/msm/dpu_dbg.c
> index 4a39b82..27538bc 100644
> --- a/drivers/gpu/drm/msm/dpu_dbg.c
> +++ b/drivers/gpu/drm/msm/dpu_dbg.c
> @@ -20,6 +20,7 @@
>  #include <linux/dma-buf.h>
>  #include <linux/slab.h>
>  #include <linux/list_sort.h>
> +#include <linux/pm_runtime.h>
>  
>  #include "dpu_dbg.h"
>  #include "disp/dpu1/dpu_hw_catalog.h"
> @@ -167,7 +168,6 @@ struct dpu_dbg_vbif_debug_bus {
>   * @evtlog: event log instance
>   * @reg_base_list: list of register dumping regions
>   * @dev: device pointer
> - * @power_ctrl: callback structure for enabling power for reading hw registers
>   * @req_dump_blks: list of blocks requested for dumping
>   * @panic_on_err: whether to kernel panic after triggering dump via debugfs
>   * @dump_work: work struct for deferring register dump work to separate thread
> @@ -182,7 +182,6 @@ struct dpu_dbg_vbif_debug_bus {
>  	struct dpu_dbg_evtlog *evtlog;
>  	struct list_head reg_base_list;
>  	struct device *dev;
> -	struct dpu_dbg_power_ctrl power_ctrl;
>  
>  	struct dpu_dbg_reg_base *req_dump_blks[DPU_DBG_BASE_MAX];
>  
> @@ -2008,12 +2007,10 @@ static void _dpu_debug_bus_ppb1_dump(void __iomem *mem_base,
>   */
>  static inline void _dpu_dbg_enable_power(int enable)
>  {
> -	if (!dpu_dbg_base.power_ctrl.enable_fn)
> -		return;
> -	dpu_dbg_base.power_ctrl.enable_fn(
> -			dpu_dbg_base.power_ctrl.handle,
> -			dpu_dbg_base.power_ctrl.client,
> -			enable);
> +	if (enable)
> +		pm_runtime_get_sync(dpu_dbg_base.dev);
> +	else
> +		pm_runtime_put_sync(dpu_dbg_base.dev);
>  }
>  
>  /**
> @@ -3099,16 +3096,15 @@ void dpu_dbg_init_dbg_buses(u32 hwversion)
>  	}
>  }
>  
> -int dpu_dbg_init(struct device *dev, struct dpu_dbg_power_ctrl *power_ctrl)
> +int dpu_dbg_init(struct device *dev)
>  {
> -	if (!dev || !power_ctrl) {
> +	if (!dev) {
>  		pr_err("invalid params\n");
>  		return -EINVAL;
>  	}
>  
>  	INIT_LIST_HEAD(&dpu_dbg_base.reg_base_list);
>  	dpu_dbg_base.dev = dev;
> -	dpu_dbg_base.power_ctrl = *power_ctrl;
>  
>  	dpu_dbg_base.evtlog = dpu_evtlog_init();
>  	if (IS_ERR_OR_NULL(dpu_dbg_base.evtlog))
> diff --git a/drivers/gpu/drm/msm/dpu_dbg.h b/drivers/gpu/drm/msm/dpu_dbg.h
> index e79b5aa..283dbbc 100644
> --- a/drivers/gpu/drm/msm/dpu_dbg.h
> +++ b/drivers/gpu/drm/msm/dpu_dbg.h
> @@ -71,12 +71,6 @@ enum dpu_dbg_dump_flag {
>  #define DPU_EVTLOG_BUF_MAX 512
>  #define DPU_EVTLOG_BUF_ALIGN 32
>  
> -struct dpu_dbg_power_ctrl {
> -	void *handle;
> -	void *client;
> -	int (*enable_fn)(void *handle, void *client, bool enable);
> -};
> -
>  struct dpu_dbg_evtlog_log {
>  	s64 time;
>  	const char *name;
> @@ -211,11 +205,9 @@ ssize_t dpu_evtlog_dump_to_buffer(struct dpu_dbg_evtlog *evtlog,
>  /**
>   * dpu_dbg_init - initialize global dpu debug facilities: evtlog, regdump
>   * @dev:		device handle
> - * @power_ctrl:		power control callback structure for enabling clocks
> - *			during register dumping
>   * Returns:		0 or -ERROR
>   */
> -int dpu_dbg_init(struct device *dev, struct dpu_dbg_power_ctrl *power_ctrl);
> +int dpu_dbg_init(struct device *dev);
>  
>  /**
>   * dpu_dbg_debugfs_register - register entries at the given debugfs dir
> @@ -359,8 +351,7 @@ static inline void dpu_dbg_init_dbg_buses(u32 hwversion)
>  {
>  }
>  
> -static inline int dpu_dbg_init(struct device *dev,
> -		struct dpu_dbg_power_ctrl *power_ctrl)
> +static inline int dpu_dbg_init(struct device *dev)
>  {
>  	return 0;
>  }
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index 5470529..5c267cd 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_client_destroy(&priv->phandle, priv->pclient);
>  	dpu_power_resource_deinit(pdev, &priv->phandle);
>  	dpu_dbg_destroy();
>  #endif
> @@ -464,13 +463,6 @@ static int msm_component_bind_all(struct device *dev,
>  }
>  #endif
>  
> -#ifdef CONFIG_DRM_MSM_DPU
> -static int msm_power_enable_wrapper(void *handle, void *client, bool enable)
> -{
> -	return dpu_power_resource_enable(handle, client, enable);
> -}
> -#endif
> -
>  static int msm_drm_init(struct device *dev, struct drm_driver *drv)
>  {
>  	struct platform_device *pdev = to_platform_device(dev);
> @@ -479,10 +471,6 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
>  	struct msm_kms *kms;
>  	struct msm_mdss *mdss;
>  
> -#ifdef CONFIG_DRM_MSM_DPU
> -	struct dpu_dbg_power_ctrl dbg_power_ctrl = { 0 };
> -#endif
> -
>  	int ret, i;
>  	struct sched_param param;
>  
> @@ -537,18 +525,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
>  		goto power_init_fail;
>  	}
>  
> -	priv->pclient = dpu_power_client_create(&priv->phandle, "dpu");
> -	if (IS_ERR_OR_NULL(priv->pclient)) {
> -		pr_err("dpu power client create failed\n");
> -		ret = -EINVAL;
> -		goto power_client_fail;
> -	}
> -
> -	dbg_power_ctrl.handle = &priv->phandle;
> -	dbg_power_ctrl.client = priv->pclient;
> -	dbg_power_ctrl.enable_fn = msm_power_enable_wrapper;
> -
> -	ret = dpu_dbg_init(&pdev->dev, &dbg_power_ctrl);
> +	ret = dpu_dbg_init(&pdev->dev);
>  	if (ret) {
>  		dev_err(dev, "failed to init dpu dbg: %d\n", ret);
>  		goto dbg_init_fail;
> @@ -756,8 +733,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_client_destroy(&priv->phandle, priv->pclient);
> -power_client_fail:
>  	dpu_power_resource_deinit(pdev, &priv->phandle);
>  power_init_fail:
>  #endif
> diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
> index 22a3096..f9ae96f 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -376,7 +376,6 @@ struct msm_drm_private {
>  	struct msm_kms *kms;
>  
>  	struct dpu_power_handle phandle;
> -	struct dpu_power_client *pclient;
>  
>  	/* 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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [DPU PATCH v2 11/12] drm/msm/dpu: move dpu_power_handle to dpu folder
       [not found]     ` <1526050178-31893-12-git-send-email-ryadav-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
@ 2018-05-11 15:48       ` Sean Paul
  0 siblings, 0 replies; 24+ messages in thread
From: Sean Paul @ 2018-05-11 15:48 UTC (permalink / raw)
  To: Rajesh Yadav
  Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [DPU PATCH v2 12/12] drm/msm/dpu: add error handling in dpu_core_perf_crtc_update
  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
  0 siblings, 0 replies; 24+ messages in thread
From: Sean Paul @ 2018-05-11 15:49 UTC (permalink / raw)
  To: Rajesh Yadav; +Cc: linux-arm-msm, dri-devel, hoegsberg, freedreno

On Fri, May 11, 2018 at 08:19:38PM +0530, Rajesh Yadav wrote:
> dpu_core_perf_crtc_update() is responsible for aggregating
> the data bus bandwidth and dpu core clock rate requirements
> and request the same for all active crtcs.
> Currently, there is no error handling support in this function
> so there is no way caller can know if the perf request fails.
> This change adds error handling code in dpu_core_perf_crtc_update().
> The caller side error handling is not added in this patch.
> 
> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>

Cool! Thanks for doing this :-)

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

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c | 37 ++++++++++++++++++---------
>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h |  3 ++-
>  2 files changed, 27 insertions(+), 13 deletions(-)
> 
> 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 d3a1ed9..85c0229 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c
> @@ -248,7 +248,7 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
>  	return 0;
>  }
>  
> -static void _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
> +static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms,
>  		struct drm_crtc *crtc, u32 bus_id)
>  {
>  	u64 bw_sum_of_intfs = 0, bus_ab_quota, bus_ib_quota;
> @@ -257,6 +257,7 @@ 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;
> +	int ret = 0;
>  
>  	drm_for_each_crtc(tmp_crtc, crtc->dev) {
>  		if (_dpu_core_perf_crtc_is_power_on(tmp_crtc) &&
> @@ -286,25 +287,28 @@ 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(&kms->phandle, kms->core_client,
> +		ret = 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",
> -				bus_id, bus_ab_quota, bus_ib_quota);
> +			  bus_id, bus_ab_quota, bus_ib_quota);
>  		break;
>  
>  	case RT_CLIENT:
> -		dpu_power_data_bus_set_quota(&kms->phandle, kms->core_client,
> +		ret = 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",
> -				bus_id, bus_ab_quota, bus_ib_quota);
> +			  bus_id, bus_ab_quota, bus_ib_quota);
>  		break;
>  
>  	default:
>  		DPU_ERROR("invalid client type:%d\n", curr_client_type);
>  		break;
>  	}
> +	return ret;
>  }
>  
>  /**
> @@ -399,7 +403,7 @@ static u64 _dpu_core_perf_get_core_clk_rate(struct dpu_kms *kms)
>  	return clk_rate;
>  }
>  
> -void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
> +int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
>  		int params_changed, bool stop_req)
>  {
>  	struct dpu_core_perf_params *new, *old;
> @@ -410,16 +414,17 @@ void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
>  	int i;
>  	struct msm_drm_private *priv;
>  	struct dpu_kms *kms;
> +	int ret;
>  
>  	if (!crtc) {
>  		DPU_ERROR("invalid crtc\n");
> -		return;
> +		return -EINVAL;
>  	}
>  
>  	kms = _dpu_crtc_get_kms(crtc);
>  	if (!kms || !kms->catalog) {
>  		DPU_ERROR("invalid kms\n");
> -		return;
> +		return -EINVAL;
>  	}
>  	priv = kms->dev->dev_private;
>  
> @@ -482,8 +487,14 @@ void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
>  				update_bus, update_clk);
>  
>  	for (i = 0; i < DPU_POWER_HANDLE_DBUS_ID_MAX; i++) {
> -		if (update_bus & BIT(i))
> -			_dpu_core_perf_crtc_update_bus(kms, crtc, i);
> +		if (update_bus & BIT(i)) {
> +			ret = _dpu_core_perf_crtc_update_bus(kms, crtc, i);
> +			if (ret) {
> +				DPU_ERROR("crtc-%d: failed to update bw vote for bus-%d\n",
> +					  crtc->base.id, i);
> +				return ret;
> +			}
> +		}
>  	}
>  
>  	/*
> @@ -495,15 +506,17 @@ void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
>  
>  		DPU_EVT32(kms->dev, stop_req, clk_rate);
>  
> -		if (_dpu_core_perf_set_core_clk_rate(kms, clk_rate)) {
> +		ret = _dpu_core_perf_set_core_clk_rate(kms, clk_rate);
> +		if (ret) {
>  			DPU_ERROR("failed to set %s clock rate %llu\n",
>  					kms->perf.core_clk->clk_name, clk_rate);
> -			return;
> +			return ret;
>  		}
>  
>  		kms->perf.core_clk_rate = clk_rate;
>  		DPU_DEBUG("update clk rate = %lld HZ\n", clk_rate);
>  	}
> +	return 0;
>  }
>  
>  #ifdef CONFIG_DEBUG_FS
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
> index cde48df..440d6a2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h
> @@ -91,8 +91,9 @@ int dpu_core_perf_crtc_check(struct drm_crtc *crtc,
>   * @crtc: Pointer to crtc
>   * @params_changed: true if crtc parameters are modified
>   * @stop_req: true if this is a stop request
> + * return: zero if success, or error code otherwise
>   */
> -void dpu_core_perf_crtc_update(struct drm_crtc *crtc,
> +int dpu_core_perf_crtc_update(struct drm_crtc *crtc,
>  		int params_changed, bool stop_req);
>  
>  /**
> -- 
> 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
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [DPU PATCH v2 03/12] drm/msm/dpu: add MDSS top level driver for dpu
       [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>
  0 siblings, 1 reply; 24+ messages in thread
From: Jordan Crouse @ 2018-05-11 17:05 UTC (permalink / raw)
  To: Rajesh Yadav
  Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Fri, May 11, 2018 at 08:19:29PM +0530, Rajesh Yadav wrote:
> SoCs containing dpu have a MDSS top level wrapper
> which includes sub-blocks as dpu, dsi, phy, dp etc.
> MDSS top level wrapper manages common resources like
> common clocks, power and irq for its sub-blocks.
> 
> Currently, in dpu driver, all the power resource
> management is part of power_handle which manages
> these resources via a custom implementation. And
> the resource relationships are not modelled properly
> in dt.  Moreover the irq domain handling code is part
> of dpu device (which is a child device) due to lack
> of a dedicated driver for MDSS top level wrapper
> device.
> 
> This change adds dpu_mdss top level driver to handle
> common clock like - core clock, ahb clock
> (for register access), main power supply (i.e. gdsc)
> and irq management.
> The top level mdss device/driver acts as an interrupt
> controller and manage hwirq mapping for its child
> devices.
> 
> It implements runtime_pm support for resource management.
> Child nodes can control these resources via runtime_pm
> get/put calls on their corresponding devices due to parent
> child relationship defined in dt.
> 
> Changes in v2:
> 	- merge _dpu_mdss_hw_rev_init to dpu_mdss_init (Sean Paul)
> 	- merge _dpu_mdss_get_intr_sources to dpu_mdss_irq (Sean Paul)
> 	- fix indentation for irq_find_mapping call (Sean Paul)
> 	- remove unnecessary goto statements from dpu_mdss_irq (Sean Paul)
> 	- remove redundant param checks from
> 	  dpu_mdss_irq_mask/unmask (Sean Paul/Jordan Crouse)
> 	- remove redundant param checks from
> 	  dpu_mdss_irqdomain_map (Sean Paul/Jordan Crouse)
> 	- return error code from dpu_mdss_enable/disable (Sean Paul/Jordan Crouse)
> 	- remove redundant param check from dpu_mdss_destroy (Sean Paul)
> 	- remove explicit calls to devm_kfree (Sean Paul/Jordan Crouse)
> 	- remove compatibility check from dpu_mdss_init as
> 	  it is conditionally called from msm_drv (Sean Paul)
> 	- reworked msm_dss_parse_clock() to add return checks for
> 	  of_property_read_* calls, fix log message and
> 	  fix alignment issues (Sean Paul/Jordan Crouse)
> 	- remove extra line before dpu_mdss_init (Sean Paul)
> 	- remove redundant param checks from __intr_offset and
> 	  make it a void function to avoid unnecessary error
> 	  handling from caller (Jordan Crouse)
> 	- remove redundant param check from dpu_mdss_irq (Jordan Crouse)
> 	- change mdss address space log message to debug and use %pK for
> 	  kernel pointers (Jordan Crouse)
> 	- remove unnecessary log message from msm_dss_parse_clock (Jordan Crouse)
> 	- don't export msm_dss_parse_clock since it is used
> 	  only by dpu driver (Jordan Crouse)
> 
> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>

Reviewed-by: Jordan Crouse <jcrouse@codeaurora.org>

I know you'll get a hundred different opinions from a hundred different people
but you don't need to credit me for every change - just a single line "fixed
bugs" works for me.

> ---
>  drivers/gpu/drm/msm/Makefile                      |   1 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c      |  97 ---------
>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h      |  14 --
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    |   9 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |   7 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c |  28 +--
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  11 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c           |  48 +---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c           |   6 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h           |   2 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c          | 254 ++++++++++++++++++++++
>  drivers/gpu/drm/msm/dpu_io_util.c                 |  57 +++++
>  drivers/gpu/drm/msm/msm_drv.c                     |  26 ++-
>  drivers/gpu/drm/msm/msm_drv.h                     |   2 +-
>  drivers/gpu/drm/msm/msm_kms.h                     |   1 +
>  include/linux/dpu_io_util.h                       |   2 +
>  16 files changed, 339 insertions(+), 226 deletions(-)
>  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> 
> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
> index d7558ed..d9826c1 100644
> --- a/drivers/gpu/drm/msm/Makefile
> +++ b/drivers/gpu/drm/msm/Makefile
> @@ -81,6 +81,7 @@ msm-y := \
>  	disp/dpu1/dpu_reg_dma.o \
>  	disp/dpu1/dpu_rm.o \
>  	disp/dpu1/dpu_vbif.o \
> +	disp/dpu1/dpu_mdss.o \
>  	dpu_dbg.o \
>  	dpu_io_util.o \
>  	dpu_dbg_evtlog.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 fe33013..977adc4 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
> @@ -515,103 +515,6 @@ void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms)
>  	dpu_kms->irq_obj.total_irqs = 0;
>  }
>  
> -static void dpu_core_irq_mask(struct irq_data *irqd)
> -{
> -	struct dpu_kms *dpu_kms;
> -
> -	if (!irqd || !irq_data_get_irq_chip_data(irqd)) {
> -		DPU_ERROR("invalid parameters irqd %d\n", irqd != NULL);
> -		return;
> -	}
> -	dpu_kms = irq_data_get_irq_chip_data(irqd);
> -
> -	/* memory barrier */
> -	smp_mb__before_atomic();
> -	clear_bit(irqd->hwirq, &dpu_kms->irq_controller.enabled_mask);
> -	/* memory barrier */
> -	smp_mb__after_atomic();
> -}
> -
> -static void dpu_core_irq_unmask(struct irq_data *irqd)
> -{
> -	struct dpu_kms *dpu_kms;
> -
> -	if (!irqd || !irq_data_get_irq_chip_data(irqd)) {
> -		DPU_ERROR("invalid parameters irqd %d\n", irqd != NULL);
> -		return;
> -	}
> -	dpu_kms = irq_data_get_irq_chip_data(irqd);
> -
> -	/* memory barrier */
> -	smp_mb__before_atomic();
> -	set_bit(irqd->hwirq, &dpu_kms->irq_controller.enabled_mask);
> -	/* memory barrier */
> -	smp_mb__after_atomic();
> -}
> -
> -static struct irq_chip dpu_core_irq_chip = {
> -	.name = "dpu",
> -	.irq_mask = dpu_core_irq_mask,
> -	.irq_unmask = dpu_core_irq_unmask,
> -};
> -
> -static int dpu_core_irqdomain_map(struct irq_domain *domain,
> -		unsigned int irq, irq_hw_number_t hwirq)
> -{
> -	struct dpu_kms *dpu_kms;
> -	int rc;
> -
> -	if (!domain || !domain->host_data) {
> -		DPU_ERROR("invalid parameters domain %d\n", domain != NULL);
> -		return -EINVAL;
> -	}
> -	dpu_kms = domain->host_data;
> -
> -	irq_set_chip_and_handler(irq, &dpu_core_irq_chip, handle_level_irq);
> -	rc = irq_set_chip_data(irq, dpu_kms);
> -
> -	return rc;
> -}
> -
> -static const struct irq_domain_ops dpu_core_irqdomain_ops = {
> -	.map = dpu_core_irqdomain_map,
> -	.xlate = irq_domain_xlate_onecell,
> -};
> -
> -int dpu_core_irq_domain_add(struct dpu_kms *dpu_kms)
> -{
> -	struct device *dev;
> -	struct irq_domain *domain;
> -
> -	if (!dpu_kms->dev || !dpu_kms->dev->dev) {
> -		pr_err("invalid device handles\n");
> -		return -EINVAL;
> -	}
> -
> -	dev = dpu_kms->dev->dev;
> -
> -	domain = irq_domain_add_linear(dev->of_node, 32,
> -			&dpu_core_irqdomain_ops, dpu_kms);
> -	if (!domain) {
> -		pr_err("failed to add irq_domain\n");
> -		return -EINVAL;
> -	}
> -
> -	dpu_kms->irq_controller.enabled_mask = 0;
> -	dpu_kms->irq_controller.domain = domain;
> -
> -	return 0;
> -}
> -
> -int dpu_core_irq_domain_fini(struct dpu_kms *dpu_kms)
> -{
> -	if (dpu_kms->irq_controller.domain) {
> -		irq_domain_remove(dpu_kms->irq_controller.domain);
> -		dpu_kms->irq_controller.domain = NULL;
> -	}
> -	return 0;
> -}
> -
>  irqreturn_t dpu_core_irq(struct dpu_kms *dpu_kms)
>  {
>  	/*
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
> index 64a54fe..8fa59db 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
> @@ -38,20 +38,6 @@
>  void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms);
>  
>  /**
> - * dpu_core_irq_domain_add - Add core IRQ domain for DPU
> - * @dpu_kms:		DPU handle
> - * @return:		none
> - */
> -int dpu_core_irq_domain_add(struct dpu_kms *dpu_kms);
> -
> -/**
> - * dpu_core_irq_domain_fini - uninstall core IRQ domain
> - * @dpu_kms:		DPU handle
> - * @return:		0 if success; error code otherwise
> - */
> -int dpu_core_irq_domain_fini(struct dpu_kms *dpu_kms);
> -
> -/**
>   * dpu_core_irq - core IRQ handler
>   * @dpu_kms:		DPU handle
>   * @return:		interrupt handling status
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> index 8e779c0..c5b370f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -77,13 +77,6 @@
>  	.has_idle_pc = true,
>  };
>  
> -static struct dpu_mdss_base_cfg sdm845_mdss[] = {
> -	{
> -	.name = "mdss_0", .id = MDP_TOP,
> -	.base = 0x0, .features = 0
> -	},
> -};
> -
>  static struct dpu_mdp_cfg sdm845_mdp[] = {
>  	{
>  	.name = "top_0", .id = MDP_TOP,
> @@ -550,8 +543,6 @@ void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
>  {
>  	*dpu_cfg = (struct dpu_mdss_cfg){
>  		.caps = &sdm845_dpu_caps,
> -		.mdss_count = ARRAY_SIZE(sdm845_mdss),
> -		.mdss = sdm845_mdss,
>  		.mdp_count = ARRAY_SIZE(sdm845_mdp),
>  		.mdp = sdm845_mdp,
>  		.ctl_count = ARRAY_SIZE(sdm845_ctl),
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> index 39bec0a..7084643 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -492,10 +492,6 @@ struct dpu_wb_sub_blocks {
>  	u32 maxlinewidth;
>  };
>  
> -struct dpu_mdss_base_cfg {
> -	DPU_HW_BLK_INFO;
> -};
> -
>  /**
>   * dpu_clk_ctrl_type - Defines top level clock control signals
>   */
> @@ -875,9 +871,6 @@ struct dpu_mdss_cfg {
>  
>  	const struct dpu_caps *caps;
>  
> -	u32 mdss_count;
> -	struct dpu_mdss_base_cfg *mdss;
> -
>  	u32 mdp_count;
>  	struct dpu_mdp_cfg *mdp;
>  
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
> index 9767cc8..73f084c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
> @@ -22,7 +22,6 @@
>   * Register offsets in MDSS register file for the interrupt registers
>   * w.r.t. to the MDSS base
>   */
> -#define HW_INTR_STATUS			0x0010
>  #define MDP_SSPP_TOP0_OFF		0x1000
>  #define MDP_INTF_0_OFF			0x6B000
>  #define MDP_INTF_1_OFF			0x6B800
> @@ -1017,17 +1016,6 @@ static int dpu_hw_intr_get_valid_interrupts(struct dpu_hw_intr *intr,
>  	return 0;
>  }
>  
> -static int dpu_hw_intr_get_interrupt_sources(struct dpu_hw_intr *intr,
> -		uint32_t *sources)
> -{
> -	if (!intr || !sources)
> -		return -EINVAL;
> -
> -	*sources = DPU_REG_READ(&intr->hw, HW_INTR_STATUS);
> -
> -	return 0;
> -}
> -
>  static void dpu_hw_intr_get_interrupt_statuses(struct dpu_hw_intr *intr)
>  {
>  	int i;
> @@ -1162,7 +1150,6 @@ static void __setup_intr_ops(struct dpu_hw_intr_ops *ops)
>  	ops->clear_all_irqs = dpu_hw_intr_clear_irqs;
>  	ops->disable_all_irqs = dpu_hw_intr_disable_irqs;
>  	ops->get_valid_interrupts = dpu_hw_intr_get_valid_interrupts;
> -	ops->get_interrupt_sources = dpu_hw_intr_get_interrupt_sources;
>  	ops->get_interrupt_statuses = dpu_hw_intr_get_interrupt_statuses;
>  	ops->clear_interrupt_status = dpu_hw_intr_clear_interrupt_status;
>  	ops->clear_intr_status_nolock = dpu_hw_intr_clear_intr_status_nolock;
> @@ -1170,23 +1157,18 @@ static void __setup_intr_ops(struct dpu_hw_intr_ops *ops)
>  	ops->get_intr_status_nolock = dpu_hw_intr_get_intr_status_nolock;
>  }
>  
> -static struct dpu_mdss_base_cfg *__intr_offset(struct dpu_mdss_cfg *m,
> +static void __intr_offset(struct dpu_mdss_cfg *m,
>  		void __iomem *addr, struct dpu_hw_blk_reg_map *hw)
>  {
> -	if (!m || !addr || !hw || m->mdp_count == 0)
> -		return NULL;
> -
>  	hw->base_off = addr;
> -	hw->blk_off = m->mdss[0].base;
> +	hw->blk_off = m->mdp[0].base;
>  	hw->hwversion = m->hwversion;
> -	return &m->mdss[0];
>  }
>  
>  struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
>  		struct dpu_mdss_cfg *m)
>  {
>  	struct dpu_hw_intr *intr;
> -	struct dpu_mdss_base_cfg *cfg;
>  
>  	if (!addr || !m)
>  		return ERR_PTR(-EINVAL);
> @@ -1195,11 +1177,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
>  	if (!intr)
>  		return ERR_PTR(-ENOMEM);
>  
> -	cfg = __intr_offset(m, addr, &intr->hw);
> -	if (!cfg) {
> -		kfree(intr);
> -		return ERR_PTR(-EINVAL);
> -	}
> +	__intr_offset(m, addr, &intr->hw);
>  	__setup_intr_ops(&intr->ops);
>  
>  	intr->irq_idx_tbl_size = ARRAY_SIZE(dpu_irq_map);
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
> index 2f1a828..b52cdca 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
> @@ -242,17 +242,6 @@ struct dpu_hw_intr_ops {
>  	int (*get_valid_interrupts)(
>  			struct dpu_hw_intr *intr,
>  			uint32_t *mask);
> -
> -	/**
> -	 * get_interrupt_sources - Gets the bitmask of the DPU interrupt
> -	 *                         source that are currently fired.
> -	 * @intr:	HW interrupt handle
> -	 * @sources:	Returning the DPU interrupt source status bit mask
> -	 * @return:	0 for success, otherwise failure
> -	 */
> -	int (*get_interrupt_sources)(
> -			struct dpu_hw_intr *intr,
> -			uint32_t *sources);
>  };
>  
>  /**
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c
> index 19c0929..d5e6ce0 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c
> @@ -19,56 +19,11 @@
>  #include "dpu_irq.h"
>  #include "dpu_core_irq.h"
>  
> -static uint32_t g_dpu_irq_status;
> -
>  irqreturn_t dpu_irq(struct msm_kms *kms)
>  {
>  	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
> -	u32 interrupts;
> -
> -	dpu_kms->hw_intr->ops.get_interrupt_sources(dpu_kms->hw_intr,
> -			&interrupts);
> -
> -	/* store irq status in case of irq-storm debugging */
> -	g_dpu_irq_status = interrupts;
> -
> -	/*
> -	 * Taking care of MDP interrupt
> -	 */
> -	if (interrupts & IRQ_SOURCE_MDP) {
> -		interrupts &= ~IRQ_SOURCE_MDP;
> -		dpu_core_irq(dpu_kms);
> -	}
> -
> -	/*
> -	 * Routing all other interrupts to external drivers
> -	 */
> -	while (interrupts) {
> -		irq_hw_number_t hwirq = fls(interrupts) - 1;
> -		unsigned int mapping;
> -		int rc;
> -
> -		mapping = irq_find_mapping(dpu_kms->irq_controller.domain,
> -				hwirq);
> -		if (mapping == 0) {
> -			DPU_EVT32(hwirq, DPU_EVTLOG_ERROR);
> -			goto error;
> -		}
> -
> -		rc = generic_handle_irq(mapping);
> -		if (rc < 0) {
> -			DPU_EVT32(hwirq, mapping, rc, DPU_EVTLOG_ERROR);
> -			goto error;
> -		}
> -
> -		interrupts &= ~(1 << hwirq);
> -	}
> -
> -	return IRQ_HANDLED;
>  
> -error:
> -	/* bad situation, inform irq system, it may disable overall MDSS irq */
> -	return IRQ_NONE;
> +	return dpu_core_irq(dpu_kms);
>  }
>  
>  void dpu_irq_preinstall(struct msm_kms *kms)
> @@ -108,5 +63,4 @@ void dpu_irq_uninstall(struct msm_kms *kms)
>  	}
>  
>  	dpu_core_irq_uninstall(dpu_kms);
> -	dpu_core_irq_domain_fini(dpu_kms);
>  }
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index 06adb38..e4ab753 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> @@ -636,10 +636,6 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
>  	priv = dev->dev_private;
>  	catalog = dpu_kms->catalog;
>  
> -	ret = dpu_core_irq_domain_add(dpu_kms);
> -	if (ret)
> -		goto fail_irq;
> -
>  	/*
>  	 * Create encoder and query display drivers to create
>  	 * bridges and connectors
> @@ -716,8 +712,6 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
>  	return 0;
>  fail:
>  	_dpu_kms_drm_obj_destroy(dpu_kms);
> -fail_irq:
> -	dpu_core_irq_domain_fini(dpu_kms);
>  	return ret;
>  }
>  
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> index 5b0c081..a1c0910 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> @@ -184,8 +184,6 @@ struct dpu_kms {
>  	struct regulator *mmagic;
>  	struct regulator *venus;
>  
> -	struct dpu_irq_controller irq_controller;
> -
>  	struct dpu_hw_intr *hw_intr;
>  	struct dpu_irq irq_obj;
>  
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> new file mode 100644
> index 0000000..ce680ea
> --- /dev/null
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> @@ -0,0 +1,254 @@
> +/*
> + * SPDX-License-Identifier: GPL-2.0
> + * Copyright (c) 2018, The Linux Foundation
> + */
> +
> +#include "dpu_kms.h"
> +
> +#define to_dpu_mdss(x) container_of(x, struct dpu_mdss, base)
> +
> +#define HW_INTR_STATUS			0x0010
> +
> +struct dpu_mdss {
> +	struct msm_mdss base;
> +	void __iomem *mmio;
> +	unsigned long mmio_len;
> +	u32 hwversion;
> +	struct dss_module_power mp;
> +	struct dpu_irq_controller irq_controller;
> +};
> +
> +static irqreturn_t dpu_mdss_irq(int irq, void *arg)
> +{
> +	struct dpu_mdss *dpu_mdss = arg;
> +	u32 interrupts;
> +
> +	interrupts = readl_relaxed(dpu_mdss->mmio + HW_INTR_STATUS);
> +
> +	while (interrupts) {
> +		irq_hw_number_t hwirq = fls(interrupts) - 1;
> +		unsigned int mapping;
> +		int rc;
> +
> +		mapping = irq_find_mapping(dpu_mdss->irq_controller.domain,
> +					   hwirq);
> +		if (mapping == 0) {
> +			DPU_EVT32(hwirq, DPU_EVTLOG_ERROR);
> +			return IRQ_NONE;
> +		}
> +
> +		rc = generic_handle_irq(mapping);
> +		if (rc < 0) {
> +			DPU_EVT32(hwirq, mapping, rc, DPU_EVTLOG_ERROR);
> +			return IRQ_NONE;
> +		}
> +
> +		interrupts &= ~(1 << hwirq);
> +	}
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static void dpu_mdss_irq_mask(struct irq_data *irqd)
> +{
> +	struct dpu_mdss *dpu_mdss = irq_data_get_irq_chip_data(irqd);
> +
> +	/* memory barrier */
> +	smp_mb__before_atomic();
> +	clear_bit(irqd->hwirq, &dpu_mdss->irq_controller.enabled_mask);
> +	/* memory barrier */
> +	smp_mb__after_atomic();
> +}
> +
> +static void dpu_mdss_irq_unmask(struct irq_data *irqd)
> +{
> +	struct dpu_mdss *dpu_mdss = irq_data_get_irq_chip_data(irqd);
> +
> +	/* memory barrier */
> +	smp_mb__before_atomic();
> +	set_bit(irqd->hwirq, &dpu_mdss->irq_controller.enabled_mask);
> +	/* memory barrier */
> +	smp_mb__after_atomic();
> +}
> +
> +static struct irq_chip dpu_mdss_irq_chip = {
> +	.name = "dpu_mdss",
> +	.irq_mask = dpu_mdss_irq_mask,
> +	.irq_unmask = dpu_mdss_irq_unmask,
> +};
> +
> +static int dpu_mdss_irqdomain_map(struct irq_domain *domain,
> +		unsigned int irq, irq_hw_number_t hwirq)
> +{
> +	struct dpu_mdss *dpu_mdss = domain->host_data;
> +	int ret;
> +
> +	irq_set_chip_and_handler(irq, &dpu_mdss_irq_chip, handle_level_irq);
> +	ret = irq_set_chip_data(irq, dpu_mdss);
> +
> +	return ret;
> +}
> +
> +static const struct irq_domain_ops dpu_mdss_irqdomain_ops = {
> +	.map = dpu_mdss_irqdomain_map,
> +	.xlate = irq_domain_xlate_onecell,
> +};
> +
> +static int _dpu_mdss_irq_domain_add(struct dpu_mdss *dpu_mdss)
> +{
> +	struct device *dev;
> +	struct irq_domain *domain;
> +
> +	dev = dpu_mdss->base.dev->dev;
> +
> +	domain = irq_domain_add_linear(dev->of_node, 32,
> +			&dpu_mdss_irqdomain_ops, dpu_mdss);
> +	if (!domain) {
> +		DPU_ERROR("failed to add irq_domain\n");
> +		return -EINVAL;
> +	}
> +
> +	dpu_mdss->irq_controller.enabled_mask = 0;
> +	dpu_mdss->irq_controller.domain = domain;
> +
> +	return 0;
> +}
> +
> +int _dpu_mdss_irq_domain_fini(struct dpu_mdss *dpu_mdss)
> +{
> +	if (dpu_mdss->irq_controller.domain) {
> +		irq_domain_remove(dpu_mdss->irq_controller.domain);
> +		dpu_mdss->irq_controller.domain = NULL;
> +	}
> +	return 0;
> +}
> +static int dpu_mdss_enable(struct msm_mdss *mdss)
> +{
> +	struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss);
> +	struct dss_module_power *mp = &dpu_mdss->mp;
> +	int ret;
> +
> +	ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true);
> +	if (ret)
> +		DPU_ERROR("clock enable failed, ret:%d\n", ret);
> +
> +	return ret;
> +}
> +
> +static int dpu_mdss_disable(struct msm_mdss *mdss)
> +{
> +	struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss);
> +	struct dss_module_power *mp = &dpu_mdss->mp;
> +	int ret;
> +
> +	ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
> +	if (ret)
> +		DPU_ERROR("clock disable failed, ret:%d\n", ret);
> +
> +	return ret;
> +}
> +
> +static void dpu_mdss_destroy(struct drm_device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev->dev);
> +	struct msm_drm_private *priv = dev->dev_private;
> +	struct dpu_mdss *dpu_mdss = to_dpu_mdss(priv->mdss);
> +	struct dss_module_power *mp = &dpu_mdss->mp;
> +
> +	_dpu_mdss_irq_domain_fini(dpu_mdss);
> +
> +	msm_dss_put_clk(mp->clk_config, mp->num_clk);
> +	devm_kfree(&pdev->dev, mp->clk_config);
> +
> +	if (dpu_mdss->mmio)
> +		msm_iounmap(pdev, dpu_mdss->mmio);
> +	dpu_mdss->mmio = NULL;
> +
> +	pm_runtime_disable(dev->dev);
> +	priv->mdss = NULL;
> +}
> +
> +static const struct msm_mdss_funcs mdss_funcs = {
> +	.enable	= dpu_mdss_enable,
> +	.disable = dpu_mdss_disable,
> +	.destroy = dpu_mdss_destroy,
> +};
> +
> +int dpu_mdss_init(struct drm_device *dev)
> +{
> +	struct platform_device *pdev = to_platform_device(dev->dev);
> +	struct msm_drm_private *priv = dev->dev_private;
> +	struct dpu_mdss *dpu_mdss;
> +	struct dss_module_power *mp;
> +	int ret = 0;
> +
> +	dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL);
> +	if (!dpu_mdss)
> +		return -ENOMEM;
> +
> +	dpu_mdss->mmio = msm_ioremap(pdev, "mdss_phys", "mdss_phys");
> +	if (IS_ERR(dpu_mdss->mmio)) {
> +		ret = PTR_ERR(dpu_mdss->mmio);
> +		DPU_ERROR("mdss register memory map failed: %d\n", ret);
> +		dpu_mdss->mmio = NULL;
> +		return ret;
> +	}
> +	DRM_DEBUG("mapped mdss address space @%pK\n", dpu_mdss->mmio);
> +	dpu_mdss->mmio_len = msm_iomap_size(pdev, "mdss_phys");
> +
> +	mp = &dpu_mdss->mp;
> +	ret = msm_dss_parse_clock(pdev, mp);
> +	if (ret) {
> +		DPU_ERROR("failed to parse clocks, ret=%d\n", ret);
> +		goto clk_parse_err;
> +	}
> +
> +	ret = msm_dss_get_clk(&pdev->dev, mp->clk_config, mp->num_clk);
> +	if (ret) {
> +		DPU_ERROR("failed to get clocks, ret=%d\n", ret);
> +		goto clk_get_error;
> +	}
> +
> +	ret = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
> +	if (ret) {
> +		DPU_ERROR("failed to set clock rate, ret=%d\n", ret);
> +		goto clk_rate_error;
> +	}
> +
> +	dpu_mdss->base.dev = dev;
> +	dpu_mdss->base.funcs = &mdss_funcs;
> +
> +	ret = _dpu_mdss_irq_domain_add(dpu_mdss);
> +	if (ret)
> +		goto irq_domain_error;
> +
> +	ret = devm_request_irq(dev->dev, platform_get_irq(pdev, 0),
> +			dpu_mdss_irq, 0, "dpu_mdss_isr", dpu_mdss);
> +	if (ret) {
> +		DPU_ERROR("failed to init irq: %d\n", ret);
> +		goto irq_error;
> +	}
> +
> +	pm_runtime_enable(dev->dev);
> +
> +	pm_runtime_get_sync(dev->dev);
> +	dpu_mdss->hwversion = readl_relaxed(dpu_mdss->mmio);
> +	pm_runtime_put_sync(dev->dev);
> +
> +	priv->mdss = &dpu_mdss->base;
> +
> +	return ret;
> +
> +irq_error:
> +	_dpu_mdss_irq_domain_fini(dpu_mdss);
> +irq_domain_error:
> +clk_rate_error:
> +	msm_dss_put_clk(mp->clk_config, mp->num_clk);
> +clk_get_error:
> +	devm_kfree(&pdev->dev, mp->clk_config);
> +clk_parse_err:
> +	if (dpu_mdss->mmio)
> +		msm_iounmap(pdev, dpu_mdss->mmio);
> +	dpu_mdss->mmio = NULL;
> +	return ret;
> +}
> diff --git a/drivers/gpu/drm/msm/dpu_io_util.c b/drivers/gpu/drm/msm/dpu_io_util.c
> index a18bc99..c44f33f 100644
> --- a/drivers/gpu/drm/msm/dpu_io_util.c
> +++ b/drivers/gpu/drm/msm/dpu_io_util.c
> @@ -448,6 +448,63 @@ int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable)
>  } /* msm_dss_enable_clk */
>  EXPORT_SYMBOL(msm_dss_enable_clk);
>  
> +int msm_dss_parse_clock(struct platform_device *pdev,
> +		struct dss_module_power *mp)
> +{
> +	u32 i, rc = 0;
> +	const char *clock_name;
> +	u32 rate = 0, max_rate = 0;
> +	int num_clk = 0;
> +
> +	if (!pdev || !mp)
> +		return -EINVAL;
> +
> +	mp->num_clk = 0;
> +	num_clk = of_property_count_strings(pdev->dev.of_node, "clock-names");
> +	if (num_clk <= 0) {
> +		pr_debug("clocks are not defined\n");
> +		return 0;
> +	}
> +
> +	mp->clk_config = devm_kzalloc(&pdev->dev,
> +				      sizeof(struct dss_clk) * num_clk,
> +				      GFP_KERNEL);
> +	if (!mp->clk_config)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < num_clk; i++) {
> +		rc = of_property_read_string_index(pdev->dev.of_node,
> +						   "clock-names", i,
> +						   &clock_name);
> +		if (rc)
> +			break;
> +		strlcpy(mp->clk_config[i].clk_name, clock_name,
> +			sizeof(mp->clk_config[i].clk_name));
> +
> +		rc = of_property_read_u32_index(pdev->dev.of_node,
> +						"clock-rate", i,
> +						&rate);
> +		if (rc)
> +			break;
> +		mp->clk_config[i].rate = rate;
> +		if (!mp->clk_config[i].rate)
> +			mp->clk_config[i].type = DSS_CLK_AHB;
> +		else
> +			mp->clk_config[i].type = DSS_CLK_PCLK;
> +
> +		rc = of_property_read_u32_index(pdev->dev.of_node,
> +						"clock-max-rate", i,
> +						&max_rate);
> +		if (rc)
> +			break;
> +		mp->clk_config[i].max_rate = max_rate;
> +	}
> +
> +	if (!rc)
> +		mp->num_clk = num_clk;
> +
> +	return rc;
> +}
>  
>  int dpu_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
>  			uint8_t reg_offset, uint8_t *read_buf)
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index 5d8f1b6..a0e73ea 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -503,7 +503,18 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
>  	ddev->dev_private = priv;
>  	priv->dev = ddev;
>  
> -	ret = mdp5_mdss_init(ddev);
> +	switch (get_mdp_ver(pdev)) {
> +	case KMS_MDP5:
> +		ret = mdp5_mdss_init(ddev);
> +		break;
> +	case KMS_DPU:
> +		ret = dpu_mdss_init(ddev);
> +		break;
> +	default:
> +		ret = 0;
> +		break;
> +	}
> +
>  	if (ret)
>  		goto mdss_init_fail;
>  
> @@ -1539,12 +1550,13 @@ static int add_display_components(struct device *dev,
>  	int ret;
>  
>  	/*
> -	 * MDP5 based devices don't have a flat hierarchy. There is a top level
> -	 * parent: MDSS, and children: MDP5, DSI, HDMI, eDP etc. Populate the
> -	 * children devices, find the MDP5 node, and then add the interfaces
> -	 * to our components list.
> +	 * MDP5/DPU based devices don't have a flat hierarchy. There is a top
> +	 * level parent: MDSS, and children: MDP5/DPU, DSI, HDMI, eDP etc.
> +	 * Populate the children devices, find the MDP5/DPU node, and then add
> +	 * the interfaces to our components list.
>  	 */
> -	if (of_device_is_compatible(dev->of_node, "qcom,mdss")) {
> +	if (of_device_is_compatible(dev->of_node, "qcom,mdss") ||
> +		of_device_is_compatible(dev->of_node, "qcom,dpu-mdss")) {
>  		ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
>  		if (ret) {
>  			dev_err(dev, "failed to populate children devices\n");
> @@ -1686,7 +1698,7 @@ static int msm_pdev_remove(struct platform_device *pdev)
>  	{ .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 },
>  	{ .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 },
>  #ifdef CONFIG_DRM_MSM_DPU
> -	{ .compatible = "qcom,dpu-kms", .data = (void *)KMS_DPU },
> +	{ .compatible = "qcom,dpu-mdss", .data = (void *)KMS_DPU },
>  #endif
>  	{}
>  };
> diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
> index 90a2521..e8e5e73 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -381,7 +381,7 @@ struct msm_drm_private {
>  	/* subordinate devices, if present: */
>  	struct platform_device *gpu_pdev;
>  
> -	/* top level MDSS wrapper device (for MDP5 only) */
> +	/* top level MDSS wrapper device (for MDP5/DPU only) */
>  	struct msm_mdss *mdss;
>  
>  	/* possibly this should be in the kms component, but it is
> diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
> index 9a7bc7d..5e1de85 100644
> --- a/drivers/gpu/drm/msm/msm_kms.h
> +++ b/drivers/gpu/drm/msm/msm_kms.h
> @@ -144,6 +144,7 @@ struct msm_mdss {
>  };
>  
>  int mdp5_mdss_init(struct drm_device *dev);
> +int dpu_mdss_init(struct drm_device *dev);
>  
>  /**
>   * Mode Set Utility Functions
> diff --git a/include/linux/dpu_io_util.h b/include/linux/dpu_io_util.h
> index 7c73899..45e606f 100644
> --- a/include/linux/dpu_io_util.h
> +++ b/include/linux/dpu_io_util.h
> @@ -104,6 +104,8 @@ int msm_dss_config_vreg(struct device *dev, struct dss_vreg *in_vreg,
>  void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk);
>  int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk);
>  int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable);
> +int msm_dss_parse_clock(struct platform_device *pdev,
> +		struct dss_module_power *mp);
>  
>  int dpu_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
>  		       uint8_t reg_offset, uint8_t *read_buf);
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 
> _______________________________________________
> Freedreno mailing list
> Freedreno@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/freedreno

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [DPU PATCH v2 04/12] drm/msm/dpu: create new platform driver for dpu device
       [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
  1 sibling, 0 replies; 24+ messages in thread
From: Jordan Crouse @ 2018-05-11 17:06 UTC (permalink / raw)
  To: Rajesh Yadav
  Cc: linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW

On Fri, May 11, 2018 at 08:19:30PM +0530, Rajesh Yadav wrote:
> Current MSM display controller HW matches a tree like
> hierarchy where MDSS top level wrapper is parent device
> and mdp5/dpu, dsi, dp are child devices.
> 
> Each child device like mdp5, dsi etc. have a separate driver,
> but currently dpu handling is tied to a single driver which
> was managing both mdss and dpu resources.
> 
> Inorder to have the cleaner one to one device and driver
> association, this change adds a new platform_driver for dpu
> child device node which implements the kms functionality.
> 
> The dpu driver implements runtime_pm support for managing clocks
> and bus bandwidth etc.
> 
> Changes in v2:
> 	- remove redundant param check from _dpu_kms_hw_destroy (Sean Paul)
> 	- remove explicit calls to devm_kfree (Sean Paul)
> 	- merge dpu_init into dpu_bind (Sean Paul)
> 	- merge dpu_destroy into dpu_unbind (Sean Paul)
> 	- use %pK for kernel pointer printing (Jordan Crouse)
> 	- remove explicit devm allocation failure message (Jordan Crouse)
>
> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>

Reviewed-by: Jordan Crouse <jcrouse@codeaurora.org>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 238 +++++++++++++++++++++++++-------
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |   4 +
>  drivers/gpu/drm/msm/msm_drv.c           |   2 +
>  drivers/gpu/drm/msm/msm_drv.h           |   3 +
>  4 files changed, 196 insertions(+), 51 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index e4ab753..85f3dbc 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> @@ -1030,16 +1030,12 @@ static long dpu_kms_round_pixclk(struct msm_kms *kms, unsigned long rate,
>  	return rate;
>  }
>  
> -static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms,
> -		struct platform_device *pdev)
> +static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms)
>  {
>  	struct drm_device *dev;
>  	struct msm_drm_private *priv;
>  	int i;
>  
> -	if (!dpu_kms || !pdev)
> -		return;
> -
>  	dev = dpu_kms->dev;
>  	if (!dev)
>  		return;
> @@ -1091,15 +1087,15 @@ static void _dpu_kms_hw_destroy(struct dpu_kms *dpu_kms,
>  	dpu_kms->core_client = NULL;
>  
>  	if (dpu_kms->vbif[VBIF_NRT])
> -		msm_iounmap(pdev, dpu_kms->vbif[VBIF_NRT]);
> +		msm_iounmap(dpu_kms->pdev, dpu_kms->vbif[VBIF_NRT]);
>  	dpu_kms->vbif[VBIF_NRT] = NULL;
>  
>  	if (dpu_kms->vbif[VBIF_RT])
> -		msm_iounmap(pdev, dpu_kms->vbif[VBIF_RT]);
> +		msm_iounmap(dpu_kms->pdev, dpu_kms->vbif[VBIF_RT]);
>  	dpu_kms->vbif[VBIF_RT] = NULL;
>  
>  	if (dpu_kms->mmio)
> -		msm_iounmap(pdev, dpu_kms->mmio);
> +		msm_iounmap(dpu_kms->pdev, dpu_kms->mmio);
>  	dpu_kms->mmio = NULL;
>  
>  	dpu_reg_dma_deinit();
> @@ -1172,8 +1168,6 @@ int dpu_kms_mmu_attach(struct dpu_kms *dpu_kms, bool secure_only)
>  static void dpu_kms_destroy(struct msm_kms *kms)
>  {
>  	struct dpu_kms *dpu_kms;
> -	struct drm_device *dev;
> -	struct platform_device *platformdev;
>  
>  	if (!kms) {
>  		DPU_ERROR("invalid kms\n");
> @@ -1181,20 +1175,7 @@ static void dpu_kms_destroy(struct msm_kms *kms)
>  	}
>  
>  	dpu_kms = to_dpu_kms(kms);
> -	dev = dpu_kms->dev;
> -	if (!dev) {
> -		DPU_ERROR("invalid device\n");
> -		return;
> -	}
> -
> -	platformdev = to_platform_device(dev->dev);
> -	if (!platformdev) {
> -		DPU_ERROR("invalid platform device\n");
> -		return;
> -	}
> -
> -	_dpu_kms_hw_destroy(dpu_kms, platformdev);
> -	kfree(dpu_kms);
> +	_dpu_kms_hw_destroy(dpu_kms);
>  }
>  
>  static void dpu_kms_preclose(struct msm_kms *kms, struct drm_file *file)
> @@ -1550,7 +1531,6 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
>  	struct dpu_kms *dpu_kms;
>  	struct drm_device *dev;
>  	struct msm_drm_private *priv;
> -	struct platform_device *platformdev;
>  	int i, rc = -EINVAL;
>  
>  	if (!kms) {
> @@ -1565,34 +1545,28 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
>  		goto end;
>  	}
>  
> -	platformdev = to_platform_device(dev->dev);
> -	if (!platformdev) {
> -		DPU_ERROR("invalid platform device\n");
> -		goto end;
> -		}
> -
>  	priv = dev->dev_private;
>  	if (!priv) {
>  		DPU_ERROR("invalid private data\n");
>  		goto end;
>  	}
>  
> -	dpu_kms->mmio = msm_ioremap(platformdev, "mdp_phys", "mdp_phys");
> +	dpu_kms->mmio = msm_ioremap(dpu_kms->pdev, "mdp_phys", "mdp_phys");
>  	if (IS_ERR(dpu_kms->mmio)) {
>  		rc = PTR_ERR(dpu_kms->mmio);
>  		DPU_ERROR("mdp register memory map failed: %d\n", rc);
>  		dpu_kms->mmio = NULL;
>  		goto error;
>  	}
> -	DRM_INFO("mapped mdp address space @%p\n", dpu_kms->mmio);
> -	dpu_kms->mmio_len = msm_iomap_size(platformdev, "mdp_phys");
> +	DRM_DEBUG("mapped dpu address space @%pK\n", dpu_kms->mmio);
> +	dpu_kms->mmio_len = msm_iomap_size(dpu_kms->pdev, "mdp_phys");
>  
>  	rc = dpu_dbg_reg_register_base(DPU_DBG_NAME, dpu_kms->mmio,
>  			dpu_kms->mmio_len);
>  	if (rc)
>  		DPU_ERROR("dbg base register kms failed: %d\n", rc);
>  
> -	dpu_kms->vbif[VBIF_RT] = msm_ioremap(platformdev, "vbif_phys",
> +	dpu_kms->vbif[VBIF_RT] = msm_ioremap(dpu_kms->pdev, "vbif_phys",
>  								"vbif_phys");
>  	if (IS_ERR(dpu_kms->vbif[VBIF_RT])) {
>  		rc = PTR_ERR(dpu_kms->vbif[VBIF_RT]);
> @@ -1600,20 +1574,20 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
>  		dpu_kms->vbif[VBIF_RT] = NULL;
>  		goto error;
>  	}
> -	dpu_kms->vbif_len[VBIF_RT] = msm_iomap_size(platformdev,
> +	dpu_kms->vbif_len[VBIF_RT] = msm_iomap_size(dpu_kms->pdev,
>  								"vbif_phys");
>  	rc = dpu_dbg_reg_register_base("vbif_rt", dpu_kms->vbif[VBIF_RT],
>  				dpu_kms->vbif_len[VBIF_RT]);
>  	if (rc)
>  		DPU_ERROR("dbg base register vbif_rt failed: %d\n", rc);
>  
> -	dpu_kms->vbif[VBIF_NRT] = msm_ioremap(platformdev, "vbif_nrt_phys",
> +	dpu_kms->vbif[VBIF_NRT] = msm_ioremap(dpu_kms->pdev, "vbif_nrt_phys",
>  								"vbif_nrt_phys");
>  	if (IS_ERR(dpu_kms->vbif[VBIF_NRT])) {
>  		dpu_kms->vbif[VBIF_NRT] = NULL;
>  		DPU_DEBUG("VBIF NRT is not defined");
>  	} else {
> -		dpu_kms->vbif_len[VBIF_NRT] = msm_iomap_size(platformdev,
> +		dpu_kms->vbif_len[VBIF_NRT] = msm_iomap_size(dpu_kms->pdev,
>  							"vbif_nrt_phys");
>  		rc = dpu_dbg_reg_register_base("vbif_nrt",
>  				dpu_kms->vbif[VBIF_NRT],
> @@ -1624,13 +1598,13 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
>  	}
>  
>  #ifdef CONFIG_CHROME_REGDMA
> -	dpu_kms->reg_dma = msm_ioremap(platformdev, "regdma_phys",
> +	dpu_kms->reg_dma = msm_ioremap(dpu_kms->pdev, "regdma_phys",
>  								"regdma_phys");
>  	if (IS_ERR(dpu_kms->reg_dma)) {
>  		dpu_kms->reg_dma = NULL;
>  		DPU_DEBUG("REG_DMA is not defined");
>  	} else {
> -		dpu_kms->reg_dma_len = msm_iomap_size(platformdev,
> +		dpu_kms->reg_dma_len = msm_iomap_size(dpu_kms->pdev,
>  								"regdma_phys");
>  		rc =  dpu_dbg_reg_register_base("reg_dma",
>  				dpu_kms->reg_dma,
> @@ -1804,14 +1778,13 @@ static int dpu_kms_hw_init(struct msm_kms *kms)
>  	dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client, false);
>  	pm_runtime_put_sync(dev->dev);
>  error:
> -	_dpu_kms_hw_destroy(dpu_kms, platformdev);
> +	_dpu_kms_hw_destroy(dpu_kms);
>  end:
>  	return rc;
>  }
>  
>  struct msm_kms *dpu_kms_init(struct drm_device *dev)
>  {
> -	struct platform_device *pdev = to_platform_device(dev->dev);
>  	struct msm_drm_private *priv;
>  	struct dpu_kms *dpu_kms;
>  	int irq;
> @@ -1821,24 +1794,187 @@ struct msm_kms *dpu_kms_init(struct drm_device *dev)
>  		return ERR_PTR(-EINVAL);
>  	}
>  
> -	irq = platform_get_irq(pdev, 0);
> +	priv = dev->dev_private;
> +	dpu_kms = to_dpu_kms(priv->kms);
> +
> +	irq = irq_of_parse_and_map(dpu_kms->pdev->dev.of_node, 0);
>  	if (irq < 0) {
>  		DPU_ERROR("failed to get irq: %d\n", irq);
>  		return ERR_PTR(irq);
>  	}
> +	dpu_kms->base.irq = irq;
>  
> -	priv = dev->dev_private;
> +	return &dpu_kms->base;
> +}
>  
> -	dpu_kms = kzalloc(sizeof(*dpu_kms), GFP_KERNEL);
> -	if (!dpu_kms) {
> -		DPU_ERROR("failed to allocate dpu kms\n");
> -		return ERR_PTR(-ENOMEM);
> +static int dpu_bind(struct device *dev, struct device *master, void *data)
> +{
> +	struct drm_device *ddev = dev_get_drvdata(master);
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct msm_drm_private *priv = ddev->dev_private;
> +	struct dpu_kms *dpu_kms;
> +	struct dss_module_power *mp;
> +	int ret = 0;
> +
> +	dpu_kms = devm_kzalloc(&pdev->dev, sizeof(*dpu_kms), GFP_KERNEL);
> +	if (!dpu_kms)
> +		return -ENOMEM;
> +
> +	mp = &dpu_kms->mp;
> +	ret = msm_dss_parse_clock(pdev, mp);
> +	if (ret) {
> +		DPU_ERROR("failed to parse clocks, ret=%d\n", ret);
> +		return ret;
> +	}
> +
> +	ret = msm_dss_get_clk(&pdev->dev, mp->clk_config, mp->num_clk);
> +	if (ret) {
> +		pr_err("failed to get clocks, ret=%d\n", ret);
> +		goto clk_get_error;
> +	}
> +
> +	ret = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
> +	if (ret) {
> +		pr_err("failed to set clock rate, ret=%d\n", ret);
> +		goto clk_rate_error;
>  	}
>  
> +	platform_set_drvdata(pdev, dpu_kms);
> +
>  	msm_kms_init(&dpu_kms->base, &kms_funcs);
> -	dpu_kms->dev = dev;
> -	dpu_kms->base.irq = irq;
> +	dpu_kms->dev = ddev;
> +	dpu_kms->pdev = pdev;
>  
> -	return &dpu_kms->base;
> +	pm_runtime_enable(&pdev->dev);
> +	dpu_kms->rpm_enabled = true;
> +
> +	priv->kms = &dpu_kms->base;
> +	return ret;
> +
> +clk_rate_error:
> +	msm_dss_put_clk(mp->clk_config, mp->num_clk);
> +clk_get_error:
> +	devm_kfree(&pdev->dev, mp->clk_config);
> +	mp->num_clk = 0;
> +	return ret;
>  }
>  
> +static void dpu_unbind(struct device *dev, struct device *master, void *data)
> +{
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct dpu_kms *dpu_kms = platform_get_drvdata(pdev);
> +	struct dss_module_power *mp = &dpu_kms->mp;
> +
> +	msm_dss_put_clk(mp->clk_config, mp->num_clk);
> +	devm_kfree(&pdev->dev, mp->clk_config);
> +	mp->num_clk = 0;
> +
> +	if (dpu_kms->rpm_enabled)
> +		pm_runtime_disable(&pdev->dev);
> +}
> +
> +static const struct component_ops dpu_ops = {
> +	.bind   = dpu_bind,
> +	.unbind = dpu_unbind,
> +};
> +
> +static int dpu_dev_probe(struct platform_device *pdev)
> +{
> +	return component_add(&pdev->dev, &dpu_ops);
> +}
> +
> +static int dpu_dev_remove(struct platform_device *pdev)
> +{
> +	component_del(&pdev->dev, &dpu_ops);
> +	return 0;
> +}
> +
> +static int dpu_runtime_suspend(struct device *dev)
> +{
> +	int rc = -1;
> +	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;
> +	if (!ddev) {
> +		DPU_ERROR("invalid drm_device\n");
> +		goto exit;
> +	}
> +	priv = ddev->dev_private;
> +
> +	rc = dpu_power_resource_enable(&priv->phandle,
> +		dpu_kms->core_client, false);
> +	if (rc)
> +		DPU_ERROR("resource disable failed: %d\n", rc);
> +
> +	rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
> +	if (rc)
> +		DPU_ERROR("clock disable failed rc:%d\n", rc);
> +
> +exit:
> +	return rc;
> +}
> +
> +static int dpu_runtime_resume(struct device *dev)
> +{
> +	int rc = -1;
> +	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;
> +	if (!ddev) {
> +		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) {
> +		DPU_ERROR("clock enable failed rc:%d\n", rc);
> +		goto exit;
> +	}
> +
> +	rc = dpu_power_resource_enable(&priv->phandle, dpu_kms->core_client,
> +		true);
> +	if (rc)
> +		DPU_ERROR("resource enable failed: %d\n", rc);
> +
> +exit:
> +	return rc;
> +}
> +
> +static const struct dev_pm_ops dpu_pm_ops = {
> +	SET_RUNTIME_PM_OPS(dpu_runtime_suspend, dpu_runtime_resume, NULL)
> +};
> +
> +static const struct of_device_id dpu_dt_match[] = {
> +	{ .compatible = "qcom,dpu", },
> +	{}
> +};
> +MODULE_DEVICE_TABLE(of, dpu_dt_match);
> +
> +static struct platform_driver dpu_driver = {
> +	.probe = dpu_dev_probe,
> +	.remove = dpu_dev_remove,
> +	.driver = {
> +		.name = "msm_dpu",
> +		.of_match_table = dpu_dt_match,
> +		.pm = &dpu_pm_ops,
> +	},
> +};
> +
> +void __init msm_dpu_register(void)
> +{
> +	platform_driver_register(&dpu_driver);
> +}
> +
> +void __exit msm_dpu_unregister(void)
> +{
> +	platform_driver_unregister(&dpu_driver);
> +}
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> index a1c0910..3c69921 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> @@ -200,6 +200,10 @@ struct dpu_kms {
>  	struct dpu_hw_mdp *hw_mdp;
>  
>  	bool has_danger_ctrl;
> +
> +	struct platform_device *pdev;
> +	bool rpm_enabled;
> +	struct dss_module_power mp;
>  };
>  
>  struct vsync_info {
> diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> index a0e73ea..5470529 100644
> --- a/drivers/gpu/drm/msm/msm_drv.c
> +++ b/drivers/gpu/drm/msm/msm_drv.c
> @@ -1731,6 +1731,7 @@ static int __init msm_drm_register(void)
>  
>  	DBG("init");
>  	msm_mdp_register();
> +	msm_dpu_register();
>  	msm_dsi_register();
>  	msm_edp_register();
>  	msm_hdmi_register();
> @@ -1747,6 +1748,7 @@ static void __exit msm_drm_unregister(void)
>  	msm_edp_unregister();
>  	msm_dsi_unregister();
>  	msm_mdp_unregister();
> +	msm_dpu_unregister();
>  }
>  
>  module_init(msm_drm_register);
> diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
> index e8e5e73..22a3096 100644
> --- a/drivers/gpu/drm/msm/msm_drv.h
> +++ b/drivers/gpu/drm/msm/msm_drv.h
> @@ -682,6 +682,9 @@ static inline int msm_dsi_modeset_init(struct msm_dsi *msm_dsi,
>  void __init msm_mdp_register(void);
>  void __exit msm_mdp_unregister(void);
>  
> +void __init msm_dpu_register(void);
> +void __exit msm_dpu_unregister(void);
> +
>  #ifdef CONFIG_DEBUG_FS
>  void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m);
>  void msm_gem_describe_objects(struct list_head *list, struct seq_file *m);
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 
> _______________________________________________
> Freedreno mailing list
> Freedreno@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/freedreno

-- 
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [DPU PATCH v2 03/12] drm/msm/dpu: add MDSS top level driver for dpu
       [not found]         ` <20180511170523.GF4995-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
@ 2018-05-11 18:32           ` Sean Paul
  0 siblings, 0 replies; 24+ messages in thread
From: Sean Paul @ 2018-05-11 18:32 UTC (permalink / raw)
  To: Rajesh Yadav, dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	freedreno-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
	linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
	robdclark-Re5JQEeQqe8AvxtiuMwx3w,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw,
	hoegsberg-F7+t8E8rja9g9hUCZPvPmw

On Fri, May 11, 2018 at 11:05:24AM -0600, Jordan Crouse wrote:
> On Fri, May 11, 2018 at 08:19:29PM +0530, Rajesh Yadav wrote:
> > SoCs containing dpu have a MDSS top level wrapper
> > which includes sub-blocks as dpu, dsi, phy, dp etc.
> > MDSS top level wrapper manages common resources like
> > common clocks, power and irq for its sub-blocks.
> > 
> > Currently, in dpu driver, all the power resource
> > management is part of power_handle which manages
> > these resources via a custom implementation. And
> > the resource relationships are not modelled properly
> > in dt.  Moreover the irq domain handling code is part
> > of dpu device (which is a child device) due to lack
> > of a dedicated driver for MDSS top level wrapper
> > device.
> > 
> > This change adds dpu_mdss top level driver to handle
> > common clock like - core clock, ahb clock
> > (for register access), main power supply (i.e. gdsc)
> > and irq management.
> > The top level mdss device/driver acts as an interrupt
> > controller and manage hwirq mapping for its child
> > devices.
> > 
> > It implements runtime_pm support for resource management.
> > Child nodes can control these resources via runtime_pm
> > get/put calls on their corresponding devices due to parent
> > child relationship defined in dt.
> > 
> > Changes in v2:
> > 	- merge _dpu_mdss_hw_rev_init to dpu_mdss_init (Sean Paul)
> > 	- merge _dpu_mdss_get_intr_sources to dpu_mdss_irq (Sean Paul)
> > 	- fix indentation for irq_find_mapping call (Sean Paul)
> > 	- remove unnecessary goto statements from dpu_mdss_irq (Sean Paul)
> > 	- remove redundant param checks from
> > 	  dpu_mdss_irq_mask/unmask (Sean Paul/Jordan Crouse)
> > 	- remove redundant param checks from
> > 	  dpu_mdss_irqdomain_map (Sean Paul/Jordan Crouse)
> > 	- return error code from dpu_mdss_enable/disable (Sean Paul/Jordan Crouse)
> > 	- remove redundant param check from dpu_mdss_destroy (Sean Paul)
> > 	- remove explicit calls to devm_kfree (Sean Paul/Jordan Crouse)
> > 	- remove compatibility check from dpu_mdss_init as
> > 	  it is conditionally called from msm_drv (Sean Paul)
> > 	- reworked msm_dss_parse_clock() to add return checks for
> > 	  of_property_read_* calls, fix log message and
> > 	  fix alignment issues (Sean Paul/Jordan Crouse)
> > 	- remove extra line before dpu_mdss_init (Sean Paul)
> > 	- remove redundant param checks from __intr_offset and
> > 	  make it a void function to avoid unnecessary error
> > 	  handling from caller (Jordan Crouse)
> > 	- remove redundant param check from dpu_mdss_irq (Jordan Crouse)
> > 	- change mdss address space log message to debug and use %pK for
> > 	  kernel pointers (Jordan Crouse)
> > 	- remove unnecessary log message from msm_dss_parse_clock (Jordan Crouse)
> > 	- don't export msm_dss_parse_clock since it is used
> > 	  only by dpu driver (Jordan Crouse)
> > 
> > Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
> 
> Reviewed-by: Jordan Crouse <jcrouse@codeaurora.org>
> 
> I know you'll get a hundred different opinions from a hundred different people

I'll interpret this as solicitation of my opinion :-)

I find this level of detail _extremely_ useful when reviewing, especially on
sets as big as this one.

It's a pretty good strategy to make reviews go as smoothly as possible, since
it's generally more difficult to read code than to write it.

Sean

/opinion

> but you don't need to credit me for every change - just a single line "fixed
> bugs" works for me.
> 
> > ---
> >  drivers/gpu/drm/msm/Makefile                      |   1 +
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c      |  97 ---------
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h      |  14 --
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    |   9 -
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |   7 -
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c |  28 +--
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  11 -
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c           |  48 +---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c           |   6 -
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h           |   2 -
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c          | 254 ++++++++++++++++++++++
> >  drivers/gpu/drm/msm/dpu_io_util.c                 |  57 +++++
> >  drivers/gpu/drm/msm/msm_drv.c                     |  26 ++-
> >  drivers/gpu/drm/msm/msm_drv.h                     |   2 +-
> >  drivers/gpu/drm/msm/msm_kms.h                     |   1 +
> >  include/linux/dpu_io_util.h                       |   2 +
> >  16 files changed, 339 insertions(+), 226 deletions(-)
> >  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> > 
> > diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
> > index d7558ed..d9826c1 100644
> > --- a/drivers/gpu/drm/msm/Makefile
> > +++ b/drivers/gpu/drm/msm/Makefile
> > @@ -81,6 +81,7 @@ msm-y := \
> >  	disp/dpu1/dpu_reg_dma.o \
> >  	disp/dpu1/dpu_rm.o \
> >  	disp/dpu1/dpu_vbif.o \
> > +	disp/dpu1/dpu_mdss.o \
> >  	dpu_dbg.o \
> >  	dpu_io_util.o \
> >  	dpu_dbg_evtlog.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 fe33013..977adc4 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
> > @@ -515,103 +515,6 @@ void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms)
> >  	dpu_kms->irq_obj.total_irqs = 0;
> >  }
> >  
> > -static void dpu_core_irq_mask(struct irq_data *irqd)
> > -{
> > -	struct dpu_kms *dpu_kms;
> > -
> > -	if (!irqd || !irq_data_get_irq_chip_data(irqd)) {
> > -		DPU_ERROR("invalid parameters irqd %d\n", irqd != NULL);
> > -		return;
> > -	}
> > -	dpu_kms = irq_data_get_irq_chip_data(irqd);
> > -
> > -	/* memory barrier */
> > -	smp_mb__before_atomic();
> > -	clear_bit(irqd->hwirq, &dpu_kms->irq_controller.enabled_mask);
> > -	/* memory barrier */
> > -	smp_mb__after_atomic();
> > -}
> > -
> > -static void dpu_core_irq_unmask(struct irq_data *irqd)
> > -{
> > -	struct dpu_kms *dpu_kms;
> > -
> > -	if (!irqd || !irq_data_get_irq_chip_data(irqd)) {
> > -		DPU_ERROR("invalid parameters irqd %d\n", irqd != NULL);
> > -		return;
> > -	}
> > -	dpu_kms = irq_data_get_irq_chip_data(irqd);
> > -
> > -	/* memory barrier */
> > -	smp_mb__before_atomic();
> > -	set_bit(irqd->hwirq, &dpu_kms->irq_controller.enabled_mask);
> > -	/* memory barrier */
> > -	smp_mb__after_atomic();
> > -}
> > -
> > -static struct irq_chip dpu_core_irq_chip = {
> > -	.name = "dpu",
> > -	.irq_mask = dpu_core_irq_mask,
> > -	.irq_unmask = dpu_core_irq_unmask,
> > -};
> > -
> > -static int dpu_core_irqdomain_map(struct irq_domain *domain,
> > -		unsigned int irq, irq_hw_number_t hwirq)
> > -{
> > -	struct dpu_kms *dpu_kms;
> > -	int rc;
> > -
> > -	if (!domain || !domain->host_data) {
> > -		DPU_ERROR("invalid parameters domain %d\n", domain != NULL);
> > -		return -EINVAL;
> > -	}
> > -	dpu_kms = domain->host_data;
> > -
> > -	irq_set_chip_and_handler(irq, &dpu_core_irq_chip, handle_level_irq);
> > -	rc = irq_set_chip_data(irq, dpu_kms);
> > -
> > -	return rc;
> > -}
> > -
> > -static const struct irq_domain_ops dpu_core_irqdomain_ops = {
> > -	.map = dpu_core_irqdomain_map,
> > -	.xlate = irq_domain_xlate_onecell,
> > -};
> > -
> > -int dpu_core_irq_domain_add(struct dpu_kms *dpu_kms)
> > -{
> > -	struct device *dev;
> > -	struct irq_domain *domain;
> > -
> > -	if (!dpu_kms->dev || !dpu_kms->dev->dev) {
> > -		pr_err("invalid device handles\n");
> > -		return -EINVAL;
> > -	}
> > -
> > -	dev = dpu_kms->dev->dev;
> > -
> > -	domain = irq_domain_add_linear(dev->of_node, 32,
> > -			&dpu_core_irqdomain_ops, dpu_kms);
> > -	if (!domain) {
> > -		pr_err("failed to add irq_domain\n");
> > -		return -EINVAL;
> > -	}
> > -
> > -	dpu_kms->irq_controller.enabled_mask = 0;
> > -	dpu_kms->irq_controller.domain = domain;
> > -
> > -	return 0;
> > -}
> > -
> > -int dpu_core_irq_domain_fini(struct dpu_kms *dpu_kms)
> > -{
> > -	if (dpu_kms->irq_controller.domain) {
> > -		irq_domain_remove(dpu_kms->irq_controller.domain);
> > -		dpu_kms->irq_controller.domain = NULL;
> > -	}
> > -	return 0;
> > -}
> > -
> >  irqreturn_t dpu_core_irq(struct dpu_kms *dpu_kms)
> >  {
> >  	/*
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
> > index 64a54fe..8fa59db 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
> > @@ -38,20 +38,6 @@
> >  void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms);
> >  
> >  /**
> > - * dpu_core_irq_domain_add - Add core IRQ domain for DPU
> > - * @dpu_kms:		DPU handle
> > - * @return:		none
> > - */
> > -int dpu_core_irq_domain_add(struct dpu_kms *dpu_kms);
> > -
> > -/**
> > - * dpu_core_irq_domain_fini - uninstall core IRQ domain
> > - * @dpu_kms:		DPU handle
> > - * @return:		0 if success; error code otherwise
> > - */
> > -int dpu_core_irq_domain_fini(struct dpu_kms *dpu_kms);
> > -
> > -/**
> >   * dpu_core_irq - core IRQ handler
> >   * @dpu_kms:		DPU handle
> >   * @return:		interrupt handling status
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > index 8e779c0..c5b370f 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > @@ -77,13 +77,6 @@
> >  	.has_idle_pc = true,
> >  };
> >  
> > -static struct dpu_mdss_base_cfg sdm845_mdss[] = {
> > -	{
> > -	.name = "mdss_0", .id = MDP_TOP,
> > -	.base = 0x0, .features = 0
> > -	},
> > -};
> > -
> >  static struct dpu_mdp_cfg sdm845_mdp[] = {
> >  	{
> >  	.name = "top_0", .id = MDP_TOP,
> > @@ -550,8 +543,6 @@ void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg)
> >  {
> >  	*dpu_cfg = (struct dpu_mdss_cfg){
> >  		.caps = &sdm845_dpu_caps,
> > -		.mdss_count = ARRAY_SIZE(sdm845_mdss),
> > -		.mdss = sdm845_mdss,
> >  		.mdp_count = ARRAY_SIZE(sdm845_mdp),
> >  		.mdp = sdm845_mdp,
> >  		.ctl_count = ARRAY_SIZE(sdm845_ctl),
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> > index 39bec0a..7084643 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> > @@ -492,10 +492,6 @@ struct dpu_wb_sub_blocks {
> >  	u32 maxlinewidth;
> >  };
> >  
> > -struct dpu_mdss_base_cfg {
> > -	DPU_HW_BLK_INFO;
> > -};
> > -
> >  /**
> >   * dpu_clk_ctrl_type - Defines top level clock control signals
> >   */
> > @@ -875,9 +871,6 @@ struct dpu_mdss_cfg {
> >  
> >  	const struct dpu_caps *caps;
> >  
> > -	u32 mdss_count;
> > -	struct dpu_mdss_base_cfg *mdss;
> > -
> >  	u32 mdp_count;
> >  	struct dpu_mdp_cfg *mdp;
> >  
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
> > index 9767cc8..73f084c 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
> > @@ -22,7 +22,6 @@
> >   * Register offsets in MDSS register file for the interrupt registers
> >   * w.r.t. to the MDSS base
> >   */
> > -#define HW_INTR_STATUS			0x0010
> >  #define MDP_SSPP_TOP0_OFF		0x1000
> >  #define MDP_INTF_0_OFF			0x6B000
> >  #define MDP_INTF_1_OFF			0x6B800
> > @@ -1017,17 +1016,6 @@ static int dpu_hw_intr_get_valid_interrupts(struct dpu_hw_intr *intr,
> >  	return 0;
> >  }
> >  
> > -static int dpu_hw_intr_get_interrupt_sources(struct dpu_hw_intr *intr,
> > -		uint32_t *sources)
> > -{
> > -	if (!intr || !sources)
> > -		return -EINVAL;
> > -
> > -	*sources = DPU_REG_READ(&intr->hw, HW_INTR_STATUS);
> > -
> > -	return 0;
> > -}
> > -
> >  static void dpu_hw_intr_get_interrupt_statuses(struct dpu_hw_intr *intr)
> >  {
> >  	int i;
> > @@ -1162,7 +1150,6 @@ static void __setup_intr_ops(struct dpu_hw_intr_ops *ops)
> >  	ops->clear_all_irqs = dpu_hw_intr_clear_irqs;
> >  	ops->disable_all_irqs = dpu_hw_intr_disable_irqs;
> >  	ops->get_valid_interrupts = dpu_hw_intr_get_valid_interrupts;
> > -	ops->get_interrupt_sources = dpu_hw_intr_get_interrupt_sources;
> >  	ops->get_interrupt_statuses = dpu_hw_intr_get_interrupt_statuses;
> >  	ops->clear_interrupt_status = dpu_hw_intr_clear_interrupt_status;
> >  	ops->clear_intr_status_nolock = dpu_hw_intr_clear_intr_status_nolock;
> > @@ -1170,23 +1157,18 @@ static void __setup_intr_ops(struct dpu_hw_intr_ops *ops)
> >  	ops->get_intr_status_nolock = dpu_hw_intr_get_intr_status_nolock;
> >  }
> >  
> > -static struct dpu_mdss_base_cfg *__intr_offset(struct dpu_mdss_cfg *m,
> > +static void __intr_offset(struct dpu_mdss_cfg *m,
> >  		void __iomem *addr, struct dpu_hw_blk_reg_map *hw)
> >  {
> > -	if (!m || !addr || !hw || m->mdp_count == 0)
> > -		return NULL;
> > -
> >  	hw->base_off = addr;
> > -	hw->blk_off = m->mdss[0].base;
> > +	hw->blk_off = m->mdp[0].base;
> >  	hw->hwversion = m->hwversion;
> > -	return &m->mdss[0];
> >  }
> >  
> >  struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
> >  		struct dpu_mdss_cfg *m)
> >  {
> >  	struct dpu_hw_intr *intr;
> > -	struct dpu_mdss_base_cfg *cfg;
> >  
> >  	if (!addr || !m)
> >  		return ERR_PTR(-EINVAL);
> > @@ -1195,11 +1177,7 @@ struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr,
> >  	if (!intr)
> >  		return ERR_PTR(-ENOMEM);
> >  
> > -	cfg = __intr_offset(m, addr, &intr->hw);
> > -	if (!cfg) {
> > -		kfree(intr);
> > -		return ERR_PTR(-EINVAL);
> > -	}
> > +	__intr_offset(m, addr, &intr->hw);
> >  	__setup_intr_ops(&intr->ops);
> >  
> >  	intr->irq_idx_tbl_size = ARRAY_SIZE(dpu_irq_map);
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
> > index 2f1a828..b52cdca 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
> > @@ -242,17 +242,6 @@ struct dpu_hw_intr_ops {
> >  	int (*get_valid_interrupts)(
> >  			struct dpu_hw_intr *intr,
> >  			uint32_t *mask);
> > -
> > -	/**
> > -	 * get_interrupt_sources - Gets the bitmask of the DPU interrupt
> > -	 *                         source that are currently fired.
> > -	 * @intr:	HW interrupt handle
> > -	 * @sources:	Returning the DPU interrupt source status bit mask
> > -	 * @return:	0 for success, otherwise failure
> > -	 */
> > -	int (*get_interrupt_sources)(
> > -			struct dpu_hw_intr *intr,
> > -			uint32_t *sources);
> >  };
> >  
> >  /**
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c
> > index 19c0929..d5e6ce0 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c
> > @@ -19,56 +19,11 @@
> >  #include "dpu_irq.h"
> >  #include "dpu_core_irq.h"
> >  
> > -static uint32_t g_dpu_irq_status;
> > -
> >  irqreturn_t dpu_irq(struct msm_kms *kms)
> >  {
> >  	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
> > -	u32 interrupts;
> > -
> > -	dpu_kms->hw_intr->ops.get_interrupt_sources(dpu_kms->hw_intr,
> > -			&interrupts);
> > -
> > -	/* store irq status in case of irq-storm debugging */
> > -	g_dpu_irq_status = interrupts;
> > -
> > -	/*
> > -	 * Taking care of MDP interrupt
> > -	 */
> > -	if (interrupts & IRQ_SOURCE_MDP) {
> > -		interrupts &= ~IRQ_SOURCE_MDP;
> > -		dpu_core_irq(dpu_kms);
> > -	}
> > -
> > -	/*
> > -	 * Routing all other interrupts to external drivers
> > -	 */
> > -	while (interrupts) {
> > -		irq_hw_number_t hwirq = fls(interrupts) - 1;
> > -		unsigned int mapping;
> > -		int rc;
> > -
> > -		mapping = irq_find_mapping(dpu_kms->irq_controller.domain,
> > -				hwirq);
> > -		if (mapping == 0) {
> > -			DPU_EVT32(hwirq, DPU_EVTLOG_ERROR);
> > -			goto error;
> > -		}
> > -
> > -		rc = generic_handle_irq(mapping);
> > -		if (rc < 0) {
> > -			DPU_EVT32(hwirq, mapping, rc, DPU_EVTLOG_ERROR);
> > -			goto error;
> > -		}
> > -
> > -		interrupts &= ~(1 << hwirq);
> > -	}
> > -
> > -	return IRQ_HANDLED;
> >  
> > -error:
> > -	/* bad situation, inform irq system, it may disable overall MDSS irq */
> > -	return IRQ_NONE;
> > +	return dpu_core_irq(dpu_kms);
> >  }
> >  
> >  void dpu_irq_preinstall(struct msm_kms *kms)
> > @@ -108,5 +63,4 @@ void dpu_irq_uninstall(struct msm_kms *kms)
> >  	}
> >  
> >  	dpu_core_irq_uninstall(dpu_kms);
> > -	dpu_core_irq_domain_fini(dpu_kms);
> >  }
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> > index 06adb38..e4ab753 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> > @@ -636,10 +636,6 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
> >  	priv = dev->dev_private;
> >  	catalog = dpu_kms->catalog;
> >  
> > -	ret = dpu_core_irq_domain_add(dpu_kms);
> > -	if (ret)
> > -		goto fail_irq;
> > -
> >  	/*
> >  	 * Create encoder and query display drivers to create
> >  	 * bridges and connectors
> > @@ -716,8 +712,6 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
> >  	return 0;
> >  fail:
> >  	_dpu_kms_drm_obj_destroy(dpu_kms);
> > -fail_irq:
> > -	dpu_core_irq_domain_fini(dpu_kms);
> >  	return ret;
> >  }
> >  
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> > index 5b0c081..a1c0910 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> > @@ -184,8 +184,6 @@ struct dpu_kms {
> >  	struct regulator *mmagic;
> >  	struct regulator *venus;
> >  
> > -	struct dpu_irq_controller irq_controller;
> > -
> >  	struct dpu_hw_intr *hw_intr;
> >  	struct dpu_irq irq_obj;
> >  
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> > new file mode 100644
> > index 0000000..ce680ea
> > --- /dev/null
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> > @@ -0,0 +1,254 @@
> > +/*
> > + * SPDX-License-Identifier: GPL-2.0
> > + * Copyright (c) 2018, The Linux Foundation
> > + */
> > +
> > +#include "dpu_kms.h"
> > +
> > +#define to_dpu_mdss(x) container_of(x, struct dpu_mdss, base)
> > +
> > +#define HW_INTR_STATUS			0x0010
> > +
> > +struct dpu_mdss {
> > +	struct msm_mdss base;
> > +	void __iomem *mmio;
> > +	unsigned long mmio_len;
> > +	u32 hwversion;
> > +	struct dss_module_power mp;
> > +	struct dpu_irq_controller irq_controller;
> > +};
> > +
> > +static irqreturn_t dpu_mdss_irq(int irq, void *arg)
> > +{
> > +	struct dpu_mdss *dpu_mdss = arg;
> > +	u32 interrupts;
> > +
> > +	interrupts = readl_relaxed(dpu_mdss->mmio + HW_INTR_STATUS);
> > +
> > +	while (interrupts) {
> > +		irq_hw_number_t hwirq = fls(interrupts) - 1;
> > +		unsigned int mapping;
> > +		int rc;
> > +
> > +		mapping = irq_find_mapping(dpu_mdss->irq_controller.domain,
> > +					   hwirq);
> > +		if (mapping == 0) {
> > +			DPU_EVT32(hwirq, DPU_EVTLOG_ERROR);
> > +			return IRQ_NONE;
> > +		}
> > +
> > +		rc = generic_handle_irq(mapping);
> > +		if (rc < 0) {
> > +			DPU_EVT32(hwirq, mapping, rc, DPU_EVTLOG_ERROR);
> > +			return IRQ_NONE;
> > +		}
> > +
> > +		interrupts &= ~(1 << hwirq);
> > +	}
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static void dpu_mdss_irq_mask(struct irq_data *irqd)
> > +{
> > +	struct dpu_mdss *dpu_mdss = irq_data_get_irq_chip_data(irqd);
> > +
> > +	/* memory barrier */
> > +	smp_mb__before_atomic();
> > +	clear_bit(irqd->hwirq, &dpu_mdss->irq_controller.enabled_mask);
> > +	/* memory barrier */
> > +	smp_mb__after_atomic();
> > +}
> > +
> > +static void dpu_mdss_irq_unmask(struct irq_data *irqd)
> > +{
> > +	struct dpu_mdss *dpu_mdss = irq_data_get_irq_chip_data(irqd);
> > +
> > +	/* memory barrier */
> > +	smp_mb__before_atomic();
> > +	set_bit(irqd->hwirq, &dpu_mdss->irq_controller.enabled_mask);
> > +	/* memory barrier */
> > +	smp_mb__after_atomic();
> > +}
> > +
> > +static struct irq_chip dpu_mdss_irq_chip = {
> > +	.name = "dpu_mdss",
> > +	.irq_mask = dpu_mdss_irq_mask,
> > +	.irq_unmask = dpu_mdss_irq_unmask,
> > +};
> > +
> > +static int dpu_mdss_irqdomain_map(struct irq_domain *domain,
> > +		unsigned int irq, irq_hw_number_t hwirq)
> > +{
> > +	struct dpu_mdss *dpu_mdss = domain->host_data;
> > +	int ret;
> > +
> > +	irq_set_chip_and_handler(irq, &dpu_mdss_irq_chip, handle_level_irq);
> > +	ret = irq_set_chip_data(irq, dpu_mdss);
> > +
> > +	return ret;
> > +}
> > +
> > +static const struct irq_domain_ops dpu_mdss_irqdomain_ops = {
> > +	.map = dpu_mdss_irqdomain_map,
> > +	.xlate = irq_domain_xlate_onecell,
> > +};
> > +
> > +static int _dpu_mdss_irq_domain_add(struct dpu_mdss *dpu_mdss)
> > +{
> > +	struct device *dev;
> > +	struct irq_domain *domain;
> > +
> > +	dev = dpu_mdss->base.dev->dev;
> > +
> > +	domain = irq_domain_add_linear(dev->of_node, 32,
> > +			&dpu_mdss_irqdomain_ops, dpu_mdss);
> > +	if (!domain) {
> > +		DPU_ERROR("failed to add irq_domain\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	dpu_mdss->irq_controller.enabled_mask = 0;
> > +	dpu_mdss->irq_controller.domain = domain;
> > +
> > +	return 0;
> > +}
> > +
> > +int _dpu_mdss_irq_domain_fini(struct dpu_mdss *dpu_mdss)
> > +{
> > +	if (dpu_mdss->irq_controller.domain) {
> > +		irq_domain_remove(dpu_mdss->irq_controller.domain);
> > +		dpu_mdss->irq_controller.domain = NULL;
> > +	}
> > +	return 0;
> > +}
> > +static int dpu_mdss_enable(struct msm_mdss *mdss)
> > +{
> > +	struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss);
> > +	struct dss_module_power *mp = &dpu_mdss->mp;
> > +	int ret;
> > +
> > +	ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true);
> > +	if (ret)
> > +		DPU_ERROR("clock enable failed, ret:%d\n", ret);
> > +
> > +	return ret;
> > +}
> > +
> > +static int dpu_mdss_disable(struct msm_mdss *mdss)
> > +{
> > +	struct dpu_mdss *dpu_mdss = to_dpu_mdss(mdss);
> > +	struct dss_module_power *mp = &dpu_mdss->mp;
> > +	int ret;
> > +
> > +	ret = msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
> > +	if (ret)
> > +		DPU_ERROR("clock disable failed, ret:%d\n", ret);
> > +
> > +	return ret;
> > +}
> > +
> > +static void dpu_mdss_destroy(struct drm_device *dev)
> > +{
> > +	struct platform_device *pdev = to_platform_device(dev->dev);
> > +	struct msm_drm_private *priv = dev->dev_private;
> > +	struct dpu_mdss *dpu_mdss = to_dpu_mdss(priv->mdss);
> > +	struct dss_module_power *mp = &dpu_mdss->mp;
> > +
> > +	_dpu_mdss_irq_domain_fini(dpu_mdss);
> > +
> > +	msm_dss_put_clk(mp->clk_config, mp->num_clk);
> > +	devm_kfree(&pdev->dev, mp->clk_config);
> > +
> > +	if (dpu_mdss->mmio)
> > +		msm_iounmap(pdev, dpu_mdss->mmio);
> > +	dpu_mdss->mmio = NULL;
> > +
> > +	pm_runtime_disable(dev->dev);
> > +	priv->mdss = NULL;
> > +}
> > +
> > +static const struct msm_mdss_funcs mdss_funcs = {
> > +	.enable	= dpu_mdss_enable,
> > +	.disable = dpu_mdss_disable,
> > +	.destroy = dpu_mdss_destroy,
> > +};
> > +
> > +int dpu_mdss_init(struct drm_device *dev)
> > +{
> > +	struct platform_device *pdev = to_platform_device(dev->dev);
> > +	struct msm_drm_private *priv = dev->dev_private;
> > +	struct dpu_mdss *dpu_mdss;
> > +	struct dss_module_power *mp;
> > +	int ret = 0;
> > +
> > +	dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL);
> > +	if (!dpu_mdss)
> > +		return -ENOMEM;
> > +
> > +	dpu_mdss->mmio = msm_ioremap(pdev, "mdss_phys", "mdss_phys");
> > +	if (IS_ERR(dpu_mdss->mmio)) {
> > +		ret = PTR_ERR(dpu_mdss->mmio);
> > +		DPU_ERROR("mdss register memory map failed: %d\n", ret);
> > +		dpu_mdss->mmio = NULL;
> > +		return ret;
> > +	}
> > +	DRM_DEBUG("mapped mdss address space @%pK\n", dpu_mdss->mmio);
> > +	dpu_mdss->mmio_len = msm_iomap_size(pdev, "mdss_phys");
> > +
> > +	mp = &dpu_mdss->mp;
> > +	ret = msm_dss_parse_clock(pdev, mp);
> > +	if (ret) {
> > +		DPU_ERROR("failed to parse clocks, ret=%d\n", ret);
> > +		goto clk_parse_err;
> > +	}
> > +
> > +	ret = msm_dss_get_clk(&pdev->dev, mp->clk_config, mp->num_clk);
> > +	if (ret) {
> > +		DPU_ERROR("failed to get clocks, ret=%d\n", ret);
> > +		goto clk_get_error;
> > +	}
> > +
> > +	ret = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
> > +	if (ret) {
> > +		DPU_ERROR("failed to set clock rate, ret=%d\n", ret);
> > +		goto clk_rate_error;
> > +	}
> > +
> > +	dpu_mdss->base.dev = dev;
> > +	dpu_mdss->base.funcs = &mdss_funcs;
> > +
> > +	ret = _dpu_mdss_irq_domain_add(dpu_mdss);
> > +	if (ret)
> > +		goto irq_domain_error;
> > +
> > +	ret = devm_request_irq(dev->dev, platform_get_irq(pdev, 0),
> > +			dpu_mdss_irq, 0, "dpu_mdss_isr", dpu_mdss);
> > +	if (ret) {
> > +		DPU_ERROR("failed to init irq: %d\n", ret);
> > +		goto irq_error;
> > +	}
> > +
> > +	pm_runtime_enable(dev->dev);
> > +
> > +	pm_runtime_get_sync(dev->dev);
> > +	dpu_mdss->hwversion = readl_relaxed(dpu_mdss->mmio);
> > +	pm_runtime_put_sync(dev->dev);
> > +
> > +	priv->mdss = &dpu_mdss->base;
> > +
> > +	return ret;
> > +
> > +irq_error:
> > +	_dpu_mdss_irq_domain_fini(dpu_mdss);
> > +irq_domain_error:
> > +clk_rate_error:
> > +	msm_dss_put_clk(mp->clk_config, mp->num_clk);
> > +clk_get_error:
> > +	devm_kfree(&pdev->dev, mp->clk_config);
> > +clk_parse_err:
> > +	if (dpu_mdss->mmio)
> > +		msm_iounmap(pdev, dpu_mdss->mmio);
> > +	dpu_mdss->mmio = NULL;
> > +	return ret;
> > +}
> > diff --git a/drivers/gpu/drm/msm/dpu_io_util.c b/drivers/gpu/drm/msm/dpu_io_util.c
> > index a18bc99..c44f33f 100644
> > --- a/drivers/gpu/drm/msm/dpu_io_util.c
> > +++ b/drivers/gpu/drm/msm/dpu_io_util.c
> > @@ -448,6 +448,63 @@ int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable)
> >  } /* msm_dss_enable_clk */
> >  EXPORT_SYMBOL(msm_dss_enable_clk);
> >  
> > +int msm_dss_parse_clock(struct platform_device *pdev,
> > +		struct dss_module_power *mp)
> > +{
> > +	u32 i, rc = 0;
> > +	const char *clock_name;
> > +	u32 rate = 0, max_rate = 0;
> > +	int num_clk = 0;
> > +
> > +	if (!pdev || !mp)
> > +		return -EINVAL;
> > +
> > +	mp->num_clk = 0;
> > +	num_clk = of_property_count_strings(pdev->dev.of_node, "clock-names");
> > +	if (num_clk <= 0) {
> > +		pr_debug("clocks are not defined\n");
> > +		return 0;
> > +	}
> > +
> > +	mp->clk_config = devm_kzalloc(&pdev->dev,
> > +				      sizeof(struct dss_clk) * num_clk,
> > +				      GFP_KERNEL);
> > +	if (!mp->clk_config)
> > +		return -ENOMEM;
> > +
> > +	for (i = 0; i < num_clk; i++) {
> > +		rc = of_property_read_string_index(pdev->dev.of_node,
> > +						   "clock-names", i,
> > +						   &clock_name);
> > +		if (rc)
> > +			break;
> > +		strlcpy(mp->clk_config[i].clk_name, clock_name,
> > +			sizeof(mp->clk_config[i].clk_name));
> > +
> > +		rc = of_property_read_u32_index(pdev->dev.of_node,
> > +						"clock-rate", i,
> > +						&rate);
> > +		if (rc)
> > +			break;
> > +		mp->clk_config[i].rate = rate;
> > +		if (!mp->clk_config[i].rate)
> > +			mp->clk_config[i].type = DSS_CLK_AHB;
> > +		else
> > +			mp->clk_config[i].type = DSS_CLK_PCLK;
> > +
> > +		rc = of_property_read_u32_index(pdev->dev.of_node,
> > +						"clock-max-rate", i,
> > +						&max_rate);
> > +		if (rc)
> > +			break;
> > +		mp->clk_config[i].max_rate = max_rate;
> > +	}
> > +
> > +	if (!rc)
> > +		mp->num_clk = num_clk;
> > +
> > +	return rc;
> > +}
> >  
> >  int dpu_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
> >  			uint8_t reg_offset, uint8_t *read_buf)
> > diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
> > index 5d8f1b6..a0e73ea 100644
> > --- a/drivers/gpu/drm/msm/msm_drv.c
> > +++ b/drivers/gpu/drm/msm/msm_drv.c
> > @@ -503,7 +503,18 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
> >  	ddev->dev_private = priv;
> >  	priv->dev = ddev;
> >  
> > -	ret = mdp5_mdss_init(ddev);
> > +	switch (get_mdp_ver(pdev)) {
> > +	case KMS_MDP5:
> > +		ret = mdp5_mdss_init(ddev);
> > +		break;
> > +	case KMS_DPU:
> > +		ret = dpu_mdss_init(ddev);
> > +		break;
> > +	default:
> > +		ret = 0;
> > +		break;
> > +	}
> > +
> >  	if (ret)
> >  		goto mdss_init_fail;
> >  
> > @@ -1539,12 +1550,13 @@ static int add_display_components(struct device *dev,
> >  	int ret;
> >  
> >  	/*
> > -	 * MDP5 based devices don't have a flat hierarchy. There is a top level
> > -	 * parent: MDSS, and children: MDP5, DSI, HDMI, eDP etc. Populate the
> > -	 * children devices, find the MDP5 node, and then add the interfaces
> > -	 * to our components list.
> > +	 * MDP5/DPU based devices don't have a flat hierarchy. There is a top
> > +	 * level parent: MDSS, and children: MDP5/DPU, DSI, HDMI, eDP etc.
> > +	 * Populate the children devices, find the MDP5/DPU node, and then add
> > +	 * the interfaces to our components list.
> >  	 */
> > -	if (of_device_is_compatible(dev->of_node, "qcom,mdss")) {
> > +	if (of_device_is_compatible(dev->of_node, "qcom,mdss") ||
> > +		of_device_is_compatible(dev->of_node, "qcom,dpu-mdss")) {
> >  		ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
> >  		if (ret) {
> >  			dev_err(dev, "failed to populate children devices\n");
> > @@ -1686,7 +1698,7 @@ static int msm_pdev_remove(struct platform_device *pdev)
> >  	{ .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 },
> >  	{ .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 },
> >  #ifdef CONFIG_DRM_MSM_DPU
> > -	{ .compatible = "qcom,dpu-kms", .data = (void *)KMS_DPU },
> > +	{ .compatible = "qcom,dpu-mdss", .data = (void *)KMS_DPU },
> >  #endif
> >  	{}
> >  };
> > diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
> > index 90a2521..e8e5e73 100644
> > --- a/drivers/gpu/drm/msm/msm_drv.h
> > +++ b/drivers/gpu/drm/msm/msm_drv.h
> > @@ -381,7 +381,7 @@ struct msm_drm_private {
> >  	/* subordinate devices, if present: */
> >  	struct platform_device *gpu_pdev;
> >  
> > -	/* top level MDSS wrapper device (for MDP5 only) */
> > +	/* top level MDSS wrapper device (for MDP5/DPU only) */
> >  	struct msm_mdss *mdss;
> >  
> >  	/* possibly this should be in the kms component, but it is
> > diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
> > index 9a7bc7d..5e1de85 100644
> > --- a/drivers/gpu/drm/msm/msm_kms.h
> > +++ b/drivers/gpu/drm/msm/msm_kms.h
> > @@ -144,6 +144,7 @@ struct msm_mdss {
> >  };
> >  
> >  int mdp5_mdss_init(struct drm_device *dev);
> > +int dpu_mdss_init(struct drm_device *dev);
> >  
> >  /**
> >   * Mode Set Utility Functions
> > diff --git a/include/linux/dpu_io_util.h b/include/linux/dpu_io_util.h
> > index 7c73899..45e606f 100644
> > --- a/include/linux/dpu_io_util.h
> > +++ b/include/linux/dpu_io_util.h
> > @@ -104,6 +104,8 @@ int msm_dss_config_vreg(struct device *dev, struct dss_vreg *in_vreg,
> >  void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk);
> >  int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk);
> >  int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int enable);
> > +int msm_dss_parse_clock(struct platform_device *pdev,
> > +		struct dss_module_power *mp);
> >  
> >  int dpu_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
> >  		       uint8_t reg_offset, uint8_t *read_buf);
> > -- 
> > The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> > a Linux Foundation Collaborative Project
> > 
> > _______________________________________________
> > Freedreno mailing list
> > Freedreno@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/freedreno
> 
> -- 
> The Qualcomm Innovation Center, Inc. is a member of 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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [DPU PATCH v2 03/12] drm/msm/dpu: add MDSS top level driver for dpu
  2018-05-11 15:28     ` Sean Paul
@ 2018-05-14 14:06       ` ryadav
  0 siblings, 0 replies; 24+ messages in thread
From: ryadav @ 2018-05-14 14:06 UTC (permalink / raw)
  To: Sean Paul; +Cc: linux-arm-msm, freedreno, hoegsberg, dri-devel

On 2018-05-11 20:58, Sean Paul wrote:
> On Fri, May 11, 2018 at 08:19:29PM +0530, Rajesh Yadav wrote:
>> SoCs containing dpu have a MDSS top level wrapper
>> which includes sub-blocks as dpu, dsi, phy, dp etc.
>> MDSS top level wrapper manages common resources like
>> common clocks, power and irq for its sub-blocks.
>> 
>> Currently, in dpu driver, all the power resource
>> management is part of power_handle which manages
>> these resources via a custom implementation. And
>> the resource relationships are not modelled properly
>> in dt.  Moreover the irq domain handling code is part
>> of dpu device (which is a child device) due to lack
>> of a dedicated driver for MDSS top level wrapper
>> device.
>> 
>> This change adds dpu_mdss top level driver to handle
>> common clock like - core clock, ahb clock
>> (for register access), main power supply (i.e. gdsc)
>> and irq management.
>> The top level mdss device/driver acts as an interrupt
>> controller and manage hwirq mapping for its child
>> devices.
>> 
>> It implements runtime_pm support for resource management.
>> Child nodes can control these resources via runtime_pm
>> get/put calls on their corresponding devices due to parent
>> child relationship defined in dt.
>> 
>> Changes in v2:
>> 	- merge _dpu_mdss_hw_rev_init to dpu_mdss_init (Sean Paul)
>> 	- merge _dpu_mdss_get_intr_sources to dpu_mdss_irq (Sean Paul)
>> 	- fix indentation for irq_find_mapping call (Sean Paul)
>> 	- remove unnecessary goto statements from dpu_mdss_irq (Sean Paul)
>> 	- remove redundant param checks from
>> 	  dpu_mdss_irq_mask/unmask (Sean Paul/Jordan Crouse)
>> 	- remove redundant param checks from
>> 	  dpu_mdss_irqdomain_map (Sean Paul/Jordan Crouse)
>> 	- return error code from dpu_mdss_enable/disable (Sean Paul/Jordan 
>> Crouse)
>> 	- remove redundant param check from dpu_mdss_destroy (Sean Paul)
>> 	- remove explicit calls to devm_kfree (Sean Paul/Jordan Crouse)
>> 	- remove compatibility check from dpu_mdss_init as
>> 	  it is conditionally called from msm_drv (Sean Paul)
>> 	- reworked msm_dss_parse_clock() to add return checks for
>> 	  of_property_read_* calls, fix log message and
>> 	  fix alignment issues (Sean Paul/Jordan Crouse)
>> 	- remove extra line before dpu_mdss_init (Sean Paul)
>> 	- remove redundant param checks from __intr_offset and
>> 	  make it a void function to avoid unnecessary error
>> 	  handling from caller (Jordan Crouse)
>> 	- remove redundant param check from dpu_mdss_irq (Jordan Crouse)
>> 	- change mdss address space log message to debug and use %pK for
>> 	  kernel pointers (Jordan Crouse)
>> 	- remove unnecessary log message from msm_dss_parse_clock (Jordan 
>> Crouse)
>> 	- don't export msm_dss_parse_clock since it is used
>> 	  only by dpu driver (Jordan Crouse)
>> 
>> Signed-off-by: Rajesh Yadav <ryadav@codeaurora.org>
>> ---
>>  drivers/gpu/drm/msm/Makefile                      |   1 +
>>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c      |  97 ---------
>>  drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h      |  14 --
>>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    |   9 -
>>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |   7 -
>>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c |  28 +--
>>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  11 -
>>  drivers/gpu/drm/msm/disp/dpu1/dpu_irq.c           |  48 +---
>>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c           |   6 -
>>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h           |   2 -
>>  drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c          | 254 
>> ++++++++++++++++++++++
>>  drivers/gpu/drm/msm/dpu_io_util.c                 |  57 +++++
>>  drivers/gpu/drm/msm/msm_drv.c                     |  26 ++-
>>  drivers/gpu/drm/msm/msm_drv.h                     |   2 +-
>>  drivers/gpu/drm/msm/msm_kms.h                     |   1 +
>>  include/linux/dpu_io_util.h                       |   2 +
>>  16 files changed, 339 insertions(+), 226 deletions(-)
>>  create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
>> 
> 
> /snip
> 
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
>> new file mode 100644
>> index 0000000..ce680ea
>> --- /dev/null
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c
> 
> /snip
> 
>> +
>> +int dpu_mdss_init(struct drm_device *dev)
>> +{
>> +	struct platform_device *pdev = to_platform_device(dev->dev);
>> +	struct msm_drm_private *priv = dev->dev_private;
>> +	struct dpu_mdss *dpu_mdss;
>> +	struct dss_module_power *mp;
>> +	int ret = 0;
>> +
>> +	dpu_mdss = devm_kzalloc(dev->dev, sizeof(*dpu_mdss), GFP_KERNEL);
>> +	if (!dpu_mdss)
>> +		return -ENOMEM;
>> +
>> +	dpu_mdss->mmio = msm_ioremap(pdev, "mdss_phys", "mdss_phys");
>> +	if (IS_ERR(dpu_mdss->mmio)) {
>> +		ret = PTR_ERR(dpu_mdss->mmio);
> 
> remove this ...
> 
>> +		DPU_ERROR("mdss register memory map failed: %d\n", ret);
>> +		dpu_mdss->mmio = NULL;
>> +		return ret;
> 
> ... and replace with
>                 return PTR_ERR(dpu_mdss->mmio);
> 
Sure, I'll update in v3.

>> +	}
>> +	DRM_DEBUG("mapped mdss address space @%pK\n", dpu_mdss->mmio);
>> +	dpu_mdss->mmio_len = msm_iomap_size(pdev, "mdss_phys");
>> +
>> +	mp = &dpu_mdss->mp;
>> +	ret = msm_dss_parse_clock(pdev, mp);
>> +	if (ret) {
>> +		DPU_ERROR("failed to parse clocks, ret=%d\n", ret);
>> +		goto clk_parse_err;
>> +	}
>> +
>> +	ret = msm_dss_get_clk(&pdev->dev, mp->clk_config, mp->num_clk);
>> +	if (ret) {
>> +		DPU_ERROR("failed to get clocks, ret=%d\n", ret);
>> +		goto clk_get_error;
>> +	}
>> +
>> +	ret = msm_dss_clk_set_rate(mp->clk_config, mp->num_clk);
>> +	if (ret) {
>> +		DPU_ERROR("failed to set clock rate, ret=%d\n", ret);
>> +		goto clk_rate_error;
>> +	}
>> +
>> +	dpu_mdss->base.dev = dev;
>> +	dpu_mdss->base.funcs = &mdss_funcs;
>> +
>> +	ret = _dpu_mdss_irq_domain_add(dpu_mdss);
>> +	if (ret)
>> +		goto irq_domain_error;
>> +
>> +	ret = devm_request_irq(dev->dev, platform_get_irq(pdev, 0),
>> +			dpu_mdss_irq, 0, "dpu_mdss_isr", dpu_mdss);
>> +	if (ret) {
>> +		DPU_ERROR("failed to init irq: %d\n", ret);
>> +		goto irq_error;
>> +	}
>> +
>> +	pm_runtime_enable(dev->dev);
>> +
>> +	pm_runtime_get_sync(dev->dev);
>> +	dpu_mdss->hwversion = readl_relaxed(dpu_mdss->mmio);
>> +	pm_runtime_put_sync(dev->dev);
>> +
>> +	priv->mdss = &dpu_mdss->base;
>> +
>> +	return ret;
>> +
>> +irq_error:
>> +	_dpu_mdss_irq_domain_fini(dpu_mdss);
>> +irq_domain_error:
>> +clk_rate_error:
>> +	msm_dss_put_clk(mp->clk_config, mp->num_clk);
>> +clk_get_error:
>> +	devm_kfree(&pdev->dev, mp->clk_config);
>> +clk_parse_err:
>> +	if (dpu_mdss->mmio)
>> +		msm_iounmap(pdev, dpu_mdss->mmio);
>> +	dpu_mdss->mmio = NULL;
>> +	return ret;
>> +}
>> diff --git a/drivers/gpu/drm/msm/dpu_io_util.c 
>> b/drivers/gpu/drm/msm/dpu_io_util.c
>> index a18bc99..c44f33f 100644
>> --- a/drivers/gpu/drm/msm/dpu_io_util.c
>> +++ b/drivers/gpu/drm/msm/dpu_io_util.c
>> @@ -448,6 +448,63 @@ int msm_dss_enable_clk(struct dss_clk *clk_arry, 
>> int num_clk, int enable)
>>  } /* msm_dss_enable_clk */
>>  EXPORT_SYMBOL(msm_dss_enable_clk);
>> 
>> +int msm_dss_parse_clock(struct platform_device *pdev,
>> +		struct dss_module_power *mp)
>> +{
>> +	u32 i, rc = 0;
>> +	const char *clock_name;
>> +	u32 rate = 0, max_rate = 0;
>> +	int num_clk = 0;
>> +
>> +	if (!pdev || !mp)
>> +		return -EINVAL;
>> +
>> +	mp->num_clk = 0;
>> +	num_clk = of_property_count_strings(pdev->dev.of_node, 
>> "clock-names");
>> +	if (num_clk <= 0) {
>> +		pr_debug("clocks are not defined\n");
>> +		return 0;
>> +	}
>> +
>> +	mp->clk_config = devm_kzalloc(&pdev->dev,
>> +				      sizeof(struct dss_clk) * num_clk,
>> +				      GFP_KERNEL);
>> +	if (!mp->clk_config)
>> +		return -ENOMEM;
>> +
>> +	for (i = 0; i < num_clk; i++) {
>> +		rc = of_property_read_string_index(pdev->dev.of_node,
>> +						   "clock-names", i,
>> +						   &clock_name);
>> +		if (rc)
>> +			break;
>> +		strlcpy(mp->clk_config[i].clk_name, clock_name,
>> +			sizeof(mp->clk_config[i].clk_name));
>> +
>> +		rc = of_property_read_u32_index(pdev->dev.of_node,
>> +						"clock-rate", i,
>> +						&rate);
>> +		if (rc)
>> +			break;
>> +		mp->clk_config[i].rate = rate;
>> +		if (!mp->clk_config[i].rate)
>> +			mp->clk_config[i].type = DSS_CLK_AHB;
>> +		else
>> +			mp->clk_config[i].type = DSS_CLK_PCLK;
>> +
>> +		rc = of_property_read_u32_index(pdev->dev.of_node,
>> +						"clock-max-rate", i,
>> +						&max_rate);
> 
> Hmm, I missed these in my first review, these need new dt bindings. I'm
> far from an expert on dt bindings, but I think you'll be asked to 
> define these
> are clocks, and get the rate/max rate information from the clock 
> subsystem
> instead of breaking it all out like this.
> 
> Sean
> 
I have checked the clock-bindings.txt and in the clock consumers example
I can see that clock-frequency binding is used, so I'll rename 
"clock-rate" to "clock-frequency".
Regarding max-rate/frequency, I have not see any references for it in 
clock-bindings.txt.
This properties is mainly used in downstream driver, i'll remove it.

Thanks,
Rajesh

>> +		if (rc)
>> +			break;
>> +		mp->clk_config[i].max_rate = max_rate;
>> +	}
>> +
>> +	if (!rc)
>> +		mp->num_clk = num_clk;
>> +
>> +	return rc;
>> +}
>> 
>>  int dpu_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
>>  			uint8_t reg_offset, uint8_t *read_buf)
>> diff --git a/drivers/gpu/drm/msm/msm_drv.c 
>> b/drivers/gpu/drm/msm/msm_drv.c
>> index 5d8f1b6..a0e73ea 100644
>> --- a/drivers/gpu/drm/msm/msm_drv.c
>> +++ b/drivers/gpu/drm/msm/msm_drv.c
>> @@ -503,7 +503,18 @@ static int msm_drm_init(struct device *dev, 
>> struct drm_driver *drv)
>>  	ddev->dev_private = priv;
>>  	priv->dev = ddev;
>> 
>> -	ret = mdp5_mdss_init(ddev);
>> +	switch (get_mdp_ver(pdev)) {
>> +	case KMS_MDP5:
>> +		ret = mdp5_mdss_init(ddev);
>> +		break;
>> +	case KMS_DPU:
>> +		ret = dpu_mdss_init(ddev);
>> +		break;
>> +	default:
>> +		ret = 0;
>> +		break;
>> +	}
>> +
>>  	if (ret)
>>  		goto mdss_init_fail;
>> 
>> @@ -1539,12 +1550,13 @@ static int add_display_components(struct 
>> device *dev,
>>  	int ret;
>> 
>>  	/*
>> -	 * MDP5 based devices don't have a flat hierarchy. There is a top 
>> level
>> -	 * parent: MDSS, and children: MDP5, DSI, HDMI, eDP etc. Populate 
>> the
>> -	 * children devices, find the MDP5 node, and then add the interfaces
>> -	 * to our components list.
>> +	 * MDP5/DPU based devices don't have a flat hierarchy. There is a 
>> top
>> +	 * level parent: MDSS, and children: MDP5/DPU, DSI, HDMI, eDP etc.
>> +	 * Populate the children devices, find the MDP5/DPU node, and then 
>> add
>> +	 * the interfaces to our components list.
>>  	 */
>> -	if (of_device_is_compatible(dev->of_node, "qcom,mdss")) {
>> +	if (of_device_is_compatible(dev->of_node, "qcom,mdss") ||
>> +		of_device_is_compatible(dev->of_node, "qcom,dpu-mdss")) {
>>  		ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
>>  		if (ret) {
>>  			dev_err(dev, "failed to populate children devices\n");
>> @@ -1686,7 +1698,7 @@ static int msm_pdev_remove(struct 
>> platform_device *pdev)
>>  	{ .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 },
>>  	{ .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 },
>>  #ifdef CONFIG_DRM_MSM_DPU
>> -	{ .compatible = "qcom,dpu-kms", .data = (void *)KMS_DPU },
>> +	{ .compatible = "qcom,dpu-mdss", .data = (void *)KMS_DPU },
>>  #endif
>>  	{}
>>  };
>> diff --git a/drivers/gpu/drm/msm/msm_drv.h 
>> b/drivers/gpu/drm/msm/msm_drv.h
>> index 90a2521..e8e5e73 100644
>> --- a/drivers/gpu/drm/msm/msm_drv.h
>> +++ b/drivers/gpu/drm/msm/msm_drv.h
>> @@ -381,7 +381,7 @@ struct msm_drm_private {
>>  	/* subordinate devices, if present: */
>>  	struct platform_device *gpu_pdev;
>> 
>> -	/* top level MDSS wrapper device (for MDP5 only) */
>> +	/* top level MDSS wrapper device (for MDP5/DPU only) */
>>  	struct msm_mdss *mdss;
>> 
>>  	/* possibly this should be in the kms component, but it is
>> diff --git a/drivers/gpu/drm/msm/msm_kms.h 
>> b/drivers/gpu/drm/msm/msm_kms.h
>> index 9a7bc7d..5e1de85 100644
>> --- a/drivers/gpu/drm/msm/msm_kms.h
>> +++ b/drivers/gpu/drm/msm/msm_kms.h
>> @@ -144,6 +144,7 @@ struct msm_mdss {
>>  };
>> 
>>  int mdp5_mdss_init(struct drm_device *dev);
>> +int dpu_mdss_init(struct drm_device *dev);
>> 
>>  /**
>>   * Mode Set Utility Functions
>> diff --git a/include/linux/dpu_io_util.h b/include/linux/dpu_io_util.h
>> index 7c73899..45e606f 100644
>> --- a/include/linux/dpu_io_util.h
>> +++ b/include/linux/dpu_io_util.h
>> @@ -104,6 +104,8 @@ int msm_dss_config_vreg(struct device *dev, struct 
>> dss_vreg *in_vreg,
>>  void msm_dss_put_clk(struct dss_clk *clk_arry, int num_clk);
>>  int msm_dss_clk_set_rate(struct dss_clk *clk_arry, int num_clk);
>>  int msm_dss_enable_clk(struct dss_clk *clk_arry, int num_clk, int 
>> enable);
>> +int msm_dss_parse_clock(struct platform_device *pdev,
>> +		struct dss_module_power *mp);
>> 
>>  int dpu_i2c_byte_read(struct i2c_client *client, uint8_t slave_addr,
>>  		       uint8_t reg_offset, uint8_t *read_buf);
>> --
>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
>> Forum,
>> a Linux Foundation Collaborative Project
>> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2018-05-14 14:06 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
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

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).