drm/msm: common display interface for mdp driver

Display_manager.h provides a commong display interface for
MDP driver to query DSI, HDMI and DP display properties.

This is a replacement for the previous dsi-manager component.

Change-Id: Ifdd213b3341ca3c21ca13aca4e56d9c2404030ff
Signed-off-by: Ajay Singh Parmar <aparmar@codeaurora.org>
Signed-off-by: Dhaval Patel <pdhaval@codeaurora.org>
Signed-off-by: Narendra Muppalla <narendram@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/drm/msm/sde-dsi.txt b/Documentation/devicetree/bindings/drm/msm/sde-dsi.txt
index 52482a1..6be5332 100644
--- a/Documentation/devicetree/bindings/drm/msm/sde-dsi.txt
+++ b/Documentation/devicetree/bindings/drm/msm/sde-dsi.txt
@@ -60,6 +60,11 @@
 - qcom,dsi-display-active: Current active display
 - qcom,dsi-ctrl: handle to dsi controller device
 - qcom,dsi-phy: handle to dsi phy device
+- qcom,dsi-manager:       Specifies dsi manager is present
+- qcom,dsi-display:       Specifies dsi display is present
+- qcom,display-manager:   Specifies display manager is present
+- qcom,hdmi-display:      Specifies hdmi is present
+- qcom,dp-display:        Specified dp is present
 - qcom,<type>-supply-entries:		A node that lists the elements of the supply used by the
 					a particular "type" of DSI module. The module "types"
 					can be "core", "ctrl", and "phy". Within the same type,
diff --git a/drivers/gpu/drm/msm/dsi-staging/display_manager.c b/drivers/gpu/drm/msm/dsi-staging/display_manager.c
new file mode 100644
index 0000000..45d1433
--- /dev/null
+++ b/drivers/gpu/drm/msm/dsi-staging/display_manager.c
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2016, 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.
+ *
+ */
+
+#include <linux/of_device.h>
+#include <linux/err.h>
+#include <linux/regulator/consumer.h>
+#include <linux/clk.h>
+#include <linux/msm-bus.h>
+#include <linux/of_irq.h>
+
+#include "msm_drv.h"
+#include "msm_kms.h"
+#include "msm_gpu.h"
+#include "display_manager.h"
+#include "dsi_display.h"
+
+static u32 dm_get_num_of_displays(struct display_manager *disp_m)
+{
+	u32 count = 0;
+
+	count = dsi_display_get_num_of_displays();
+	disp_m->display_count = count;
+	disp_m->dsi_display_count = count;
+
+	/* TODO: get HDMI and DP display count here */
+	return disp_m->display_count;
+}
+
+static int dm_set_active_displays(struct display_manager *disp_m)
+{
+	/* TODO: Make changes from DT config here */
+	return 0;
+}
+
+static int dm_init_active_displays(struct display_manager *disp_m)
+{
+	int rc = 0;
+	int i = 0;
+	struct dsi_display *dsi_display;
+
+	for (i = 0; i < disp_m->dsi_display_count; i++) {
+		dsi_display = dsi_display_get_display_by_index(i);
+		if (!dsi_display || !dsi_display_is_active(dsi_display))
+			continue;
+
+		rc = dsi_display_dev_init(dsi_display);
+		if (rc) {
+			pr_err("failed to init dsi display, rc=%d\n", rc);
+			goto error_deinit_dsi_displays;
+		}
+	}
+
+	/* TODO: INIT HDMI and DP displays here */
+	return rc;
+error_deinit_dsi_displays:
+	for (i = i - 1; i >= 0; i--) {
+		dsi_display = dsi_display_get_display_by_index(i);
+		if (dsi_display && dsi_display_is_active(dsi_display))
+			(void)dsi_display_dev_deinit(dsi_display);
+	}
+
+	return rc;
+}
+
+static int dm_deinit_active_displays(struct display_manager *disp_m)
+{
+	int rc = 0;
+	int i = 0;
+	struct dsi_display *dsi_display;
+
+	for (i = 0; i < disp_m->dsi_display_count; i++) {
+		dsi_display = dsi_display_get_display_by_index(i);
+		if (!dsi_display || !dsi_display_is_active(dsi_display))
+			continue;
+
+		rc = dsi_display_dev_deinit(dsi_display);
+		if (rc)
+			pr_err("failed to deinit dsi display, rc=%d\n", rc);
+	}
+
+	/* TODO: DEINIT HDMI and DP displays here */
+	return rc;
+}
+
+static int disp_manager_comp_ops_bind(struct device *dev,
+				     struct device *master,
+				     void *data)
+{
+	int rc = 0;
+	struct drm_device *drm = dev_get_drvdata(master);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct msm_drm_private *priv = drm->dev_private;
+	struct display_manager *disp_m;
+	struct dsi_display *dsi_display;
+	int i = 0;
+
+	if (!pdev || !drm) {
+		pr_err("Invalid params\n");
+		return -EINVAL;
+	}
+
+	disp_m = platform_get_drvdata(pdev);
+
+	/* DSI displays */
+	for (i = 0; i < disp_m->dsi_display_count; i++) {
+		dsi_display = dsi_display_get_display_by_index(i);
+		if (!dsi_display) {
+			pr_err("Display does not exist\n");
+			continue;
+		}
+
+		if (!dsi_display_is_active(dsi_display))
+			continue;
+
+		rc = dsi_display_bind(dsi_display, drm);
+		if (rc) {
+			pr_err("Failed to bind dsi display_%d, rc=%d\n", i, rc);
+			goto error_unbind_dsi;
+		}
+	}
+
+	/* TODO: BIND HDMI display here */
+	/* TODO: BIND DP display here */
+
+	priv->dm = disp_m;
+	return rc;
+error_unbind_dsi:
+	for (i = i - 1; i >= 0; i--) {
+		dsi_display = dsi_display_get_display_by_index(i);
+		if (!dsi_display || !dsi_display_is_active(dsi_display))
+			continue;
+		(void)dsi_display_unbind(dsi_display);
+	}
+	return rc;
+}
+
+static void disp_manager_comp_ops_unbind(struct device *dev,
+					struct device *master,
+					void *data)
+{
+	int rc = 0;
+	struct drm_device *drm = dev_get_drvdata(master);
+	struct platform_device *pdev = to_platform_device(dev);
+	struct display_manager *disp_m;
+	struct dsi_display *dsi_display;
+	int i = 0;
+
+	if (!pdev || !drm) {
+		pr_err("Invalid params\n");
+		return;
+	}
+
+	disp_m = platform_get_drvdata(pdev);
+
+	/* DSI displays */
+	for (i = 0; i < disp_m->dsi_display_count; i++) {
+		dsi_display = dsi_display_get_display_by_index(i);
+		if (!dsi_display || !dsi_display_is_active(dsi_display))
+			continue;
+
+		rc = dsi_display_unbind(dsi_display);
+		if (rc)
+			pr_err("failed to unbind dsi display_%d, rc=%d\n",
+			       i, rc);
+	}
+
+	/* TODO: UNBIND HDMI display here */
+	/* TODO: UNBIND DP display here */
+}
+
+static const struct of_device_id displays_dt_match[] = {
+	{.compatible = "qcom,dsi-display"},
+	{.compatible = "qcom,hdmi-display"},
+	{.compatible = "qcom,dp-display"},
+	{}
+};
+
+static const struct component_ops disp_manager_comp_ops = {
+	.bind = disp_manager_comp_ops_bind,
+	.unbind = disp_manager_comp_ops_unbind,
+};
+
+static int disp_manager_dev_probe(struct platform_device *pdev)
+{
+	struct display_manager *disp_m;
+	int rc = 0;
+
+	if (!pdev || !pdev->dev.of_node) {
+		pr_err("pdev not found\n");
+		return -ENODEV;
+	}
+
+	disp_m = devm_kzalloc(&pdev->dev, sizeof(*disp_m), GFP_KERNEL);
+	if (!disp_m)
+		return -ENOMEM;
+
+	disp_m->name = "qcom,display-manager";
+
+	of_platform_populate(pdev->dev.of_node, displays_dt_match,
+			     NULL, &pdev->dev);
+
+	disp_m->display_count = dm_get_num_of_displays(disp_m);
+	if (!disp_m->display_count) {
+		rc = -ENODEV;
+		pr_err("No display found, rc=%d\n", rc);
+		goto error_free_disp_m;
+	}
+
+	rc = dm_set_active_displays(disp_m);
+	if (rc) {
+		pr_err("failed to set active displays, rc=%d\n", rc);
+		goto error_remove_displays;
+	}
+
+	rc = dm_init_active_displays(disp_m);
+	if (rc) {
+		pr_err("failed to initialize displays, rc=%d\n", rc);
+		goto error_remove_displays;
+	}
+
+	rc = component_add(&pdev->dev, &disp_manager_comp_ops);
+	if (rc) {
+		pr_err("failed to add component, rc=%d\n", rc);
+		goto error_deinit_displays;
+	}
+
+	mutex_init(&disp_m->lock);
+	platform_set_drvdata(pdev, disp_m);
+
+	return rc;
+error_deinit_displays:
+	(void)dm_deinit_active_displays(disp_m);
+error_remove_displays:
+	of_platform_depopulate(&pdev->dev);
+error_free_disp_m:
+	devm_kfree(&pdev->dev, disp_m);
+	return rc;
+}
+
+static int disp_manager_dev_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static const struct of_device_id disp_manager_dt_match[] = {
+	{.compatible = "qcom,display-manager"},
+	{}
+};
+
+static struct platform_driver disp_manager_driver = {
+	.probe = disp_manager_dev_probe,
+	.remove = disp_manager_dev_remove,
+	.driver = {
+		.name = "msm-display-manager",
+		.of_match_table = disp_manager_dt_match,
+	},
+};
+
+
+int display_manager_get_count(struct display_manager *disp_m)
+{
+	int count;
+
+	if (!disp_m) {
+		pr_err("Invalid params\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&disp_m->lock);
+
+	count = 1; /* TODO: keep track of active displays */
+
+	mutex_unlock(&disp_m->lock);
+	return count;
+}
+
+int display_manager_get_info_by_index(struct display_manager *disp_m,
+				      u32 display_index,
+				      struct display_info *info)
+{
+	int rc = 0;
+	int i = 0, j = 0;
+	struct dsi_display *display;
+	struct dsi_display_info dsi_info;
+
+	if (!disp_m || !info) {
+		pr_err("Invalid params\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&disp_m->lock);
+
+	for (i = 0; i < disp_m->dsi_display_count; i++) {
+		display = dsi_display_get_display_by_index(i);
+		if (!display || !dsi_display_is_active(display))
+			continue;
+
+		memset(&dsi_info, 0x0, sizeof(dsi_info));
+		rc = dsi_display_get_info(display, &dsi_info);
+		if (rc) {
+			pr_err("failed to get display info, rc=%d\n", rc);
+			goto error;
+		}
+
+		info->intf = DISPLAY_INTF_DSI;
+		info->num_of_h_tiles = dsi_info.num_of_h_tiles;
+
+		for (j = 0; j < info->num_of_h_tiles; j++)
+			info->h_tile_instance[j] = dsi_info.h_tile_ids[j];
+
+		info->is_hot_pluggable = dsi_info.is_hot_pluggable;
+		info->is_connected = dsi_info.is_connected;
+		info->is_edid_supported = dsi_info.is_edid_supported;
+		info->max_width = 1920; /* TODO: */
+		info->max_height = 1080; /* TODO: */
+		info->compression = DISPLAY_COMPRESSION_NONE;
+		break;
+	}
+
+error:
+	mutex_unlock(&disp_m->lock);
+	return rc;
+}
+
+int display_manager_drm_init_by_index(struct display_manager *disp_m,
+				      u32 display_index,
+				      struct drm_encoder *encoder)
+{
+	int rc = 0;
+	int i = 0;
+	struct dsi_display *display;
+
+	if (!disp_m || !encoder) {
+		pr_err("Invalid params\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&disp_m->lock);
+
+	for (i = 0; i < disp_m->dsi_display_count; i++) {
+		display = dsi_display_get_display_by_index(i);
+		if (!display || !dsi_display_is_active(display))
+			continue;
+
+		dsi_display_drm_init(display, encoder);
+		break;
+	}
+
+	mutex_unlock(&disp_m->lock);
+
+	return rc;
+
+}
+
+int display_manager_drm_deinit_by_index(struct display_manager *disp_m,
+					u32 display_index)
+{
+	return 0;
+}
+
+
+void display_manager_register(void)
+{
+	dsi_phy_drv_register();
+	dsi_ctrl_drv_register();
+	dsi_display_register();
+
+	platform_driver_register(&disp_manager_driver);
+}
+void display_manager_unregister(void)
+{
+	platform_driver_unregister(&disp_manager_driver);
+	dsi_display_unregister();
+	dsi_ctrl_drv_register();
+	dsi_phy_drv_unregister();
+}
diff --git a/drivers/gpu/drm/msm/dsi-staging/display_manager.h b/drivers/gpu/drm/msm/dsi-staging/display_manager.h
new file mode 100644
index 0000000..0b7462b
--- /dev/null
+++ b/drivers/gpu/drm/msm/dsi-staging/display_manager.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2016, 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 _DISPLAY_MANAGER_H_
+#define _DISPLAY_MANAGER_H_
+
+#define MAX_H_TILES_PER_DISPLAY 2
+
+/**
+ * enum display_interface_type - enumerates display interface types
+ * @DISPLAY_INTF_DSI:        DSI interface
+ * @DISPLAY_INTF_HDMI:       HDMI interface
+ * @DISPLAY_INTF_DP:         Display Port interface
+ */
+enum display_interface_type {
+	DISPLAY_INTF_DSI = 0,
+	DISPLAY_INTF_HDMI,
+	DISPLAY_INTF_DP,
+	DISPLAY_INTF_MAX,
+};
+
+/**
+ * enum display_compression_type - compression method used for pixel stream
+ * @DISPLAY_COMPRESISON_NONE:     Pixel data is not compressed.
+ * @DISPLAY_COMPRESSION_DSC:      DSC compresison is used.
+ * @DISPLAY_COMPRESSION_FBC:      FBC compression is used.
+ */
+enum display_compression_type {
+	DISPLAY_COMPRESSION_NONE = 0,
+	DISPLAY_COMPRESSION_DSC,
+	DISPLAY_COMPRESSION_FBC,
+	DISPLAY_COMPRESISON_MAX
+};
+
+
+/**
+ * struct display_info - defines display properties
+ * @intf:               The interface on which display is connected to SOC.
+ * @num_of_h_tiles:     number of horizontal tiles in case of split interface.
+ * @h_tile_instance:    controller instance used per tile. Number of elements is
+ *			based on num_of_h_tiles.
+ * @is_hot_pluggable:   Set to true if hot plug detection is supported.
+ * @is_connected:       Set to true if display is connected.
+ * @is_edid_supported:  True if display supports EDID.
+ * @max_width:          Max width of display. In case of hot pluggable display,
+ *			this is max width supported by controller.
+ * @max_height:         Max height of display. In case of hot pluggable display,
+ *			this is max height supported by controller.
+ * @compression:        Compression supported by the display.
+ */
+struct display_info {
+	enum display_interface_type intf;
+
+	u32 num_of_h_tiles;
+	u32 h_tile_instance[MAX_H_TILES_PER_DISPLAY];
+
+	bool is_hot_pluggable;
+	bool is_connected;
+	bool is_edid_supported;
+
+	u32 max_width;
+	u32 max_height;
+
+	enum display_compression_type compression;
+};
+
+struct display_manager {
+	struct platform_device *pdev;
+	const char *name;
+
+	struct mutex lock;
+	u32 display_count;
+	u32 dsi_display_count;
+	u32 hdmi_display_count;
+	u32 dp_display_count;
+	/* Debug fs */
+	struct dentry *debugfs_root;
+};
+
+/**
+ * display_manager_get_count() - returns the number of display present
+ * @disp_m:      Handle to Display manager.
+ *
+ * Returns the sum total of DSI, HDMI and DP display present on the board.
+ *
+ * Return: error code (< 0) in case of error or number of display ( >= 0)
+ */
+int display_manager_get_count(struct display_manager *disp_m);
+
+/**
+ * display_manager_get_info_by_index() - returns display information
+ * @disp_m:        Handle to Display manager.
+ * @display_index: display index (valid indices are 0 to (display_count - 1).
+ * @info:          Structure where display info is copied.
+ *
+ * Return: error code.
+ */
+int display_manager_get_info_by_index(struct display_manager *disp_m,
+				      u32 display_index,
+				      struct display_info *info);
+
+/**
+ * display_manager_drm_init_by_index() - initialize drm objects for display
+ * @disp_m:         Handle to Display manager.
+ * @display_index:  display index (valid indices are 0 to (display_count - 1).
+ * @encoder:        Pointer to encoder object to which display is attached.
+ *
+ * Return: error code.
+ */
+int display_manager_drm_init_by_index(struct display_manager *disp_m,
+				      u32 display_index,
+				      struct drm_encoder *encoder);
+
+/**
+ * display_manager_drm_deinit_by_index() - detroys drm objects
+ * @disp_m:         Handle to Display manager.
+ * @display_index:  display index (valid indices are 0 to (display_count - 1).
+ *
+ * Return: error code.
+ */
+int display_manager_drm_deinit_by_index(struct display_manager *disp_m,
+					u32 display_index);
+
+/**
+ * display_manager_register() - register display interface drivers
+ */
+void display_manager_register(void);
+
+/**
+ * display_manager_unregister() - unregisters display interface drivers
+ */
+void display_manager_unregister(void);
+
+#endif /* _DISPLAY_MANAGER_H_ */
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index 1fac1b9..04a3a79 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -2335,7 +2335,7 @@
 /**
  * dsi_ctrl_drv_register() - register platform driver for dsi controller
  */
-void __init dsi_ctrl_drv_register(void)
+void dsi_ctrl_drv_register(void)
 {
 	platform_driver_register(&dsi_ctrl_driver);
 }
@@ -2343,7 +2343,7 @@
 /**
  * dsi_ctrl_drv_unregister() - unregister platform driver
  */
-void __exit dsi_ctrl_drv_unregister(void)
+void dsi_ctrl_drv_unregister(void)
 {
 	platform_driver_unregister(&dsi_ctrl_driver);
 }
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index 87a28dc..47fa708 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -29,6 +29,11 @@
 static DEFINE_MUTEX(dsi_display_list_lock);
 static LIST_HEAD(dsi_display_list);
 
+static const struct of_device_id dsi_display_dt_match[] = {
+	{.compatible = "qcom,dsi-display"},
+	{}
+};
+
 static struct dsi_display *main_display;
 
 static ssize_t debugfs_dump_info_read(struct file *file,
@@ -1259,6 +1264,15 @@
 	return rc;
 }
 
+static struct platform_driver dsi_display_driver = {
+	.probe = dsi_display_dev_probe,
+	.remove = dsi_display_dev_remove,
+	.driver = {
+		.name = "msm-dsi-display",
+		.of_match_table = dsi_display_dt_match,
+	},
+};
+
 int dsi_display_dev_probe(struct platform_device *pdev)
 {
 	int rc = 0;
@@ -2129,3 +2143,13 @@
 	mutex_unlock(&display->display_lock);
 	return rc;
 }
+
+void dsi_display_register(void)
+{
+	platform_driver_register(&dsi_display_driver);
+}
+
+void dsi_display_unregister(void)
+{
+	platform_driver_unregister(&dsi_display_driver);
+}
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
index 976baf6b..a8c0ebf 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
@@ -189,6 +189,16 @@
 int dsi_display_dev_remove(struct platform_device *pdev);
 
 /**
+ * dsi_display_register() - register dsi display platform driver
+ */
+void dsi_display_register(void);
+
+/**
+ * dsi_display_unregister() - unregister dsi display platform driver
+ */
+void dsi_display_unregister(void);
+
+/**
  * dsi_display_get_num_of_displays() - returns number of display devices
  *				       supported.
  *
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
index d53ef1140..1ccbbe7 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
@@ -510,7 +510,7 @@
 	.probe      = dsi_phy_driver_probe,
 	.remove     = dsi_phy_driver_remove,
 	.driver     = {
-		.name   = "msm_dsi_phy",
+		.name   = "dsi_phy",
 		.of_match_table = msm_dsi_phy_of_match,
 	},
 };
@@ -848,12 +848,12 @@
 	return rc;
 }
 
-void __init dsi_phy_drv_register(void)
+void dsi_phy_drv_register(void)
 {
 	platform_driver_register(&dsi_phy_platform_driver);
 }
 
-void __exit dsi_phy_drv_unregister(void)
+void dsi_phy_drv_unregister(void)
 {
 	platform_driver_unregister(&dsi_phy_platform_driver);
 }
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index f6e2e23..e4e37a3 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -20,6 +20,7 @@
 #include "msm_fence.h"
 #include "msm_gpu.h"
 #include "msm_kms.h"
+#include "display_manager.h"
 
 
 /*
@@ -1090,6 +1091,7 @@
 {
 	DBG("init");
 	msm_mdp_register();
+	display_manager_register();
 	msm_dsi_register();
 	msm_edp_register();
 	msm_hdmi_register();
@@ -1105,7 +1107,7 @@
 	adreno_unregister();
 	msm_edp_unregister();
 	msm_dsi_unregister();
-	msm_mdp_unregister();
+	display_manager_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 8a3f522..7c1d630 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -100,6 +100,8 @@
 	spinlock_t lock;
 };
 
+struct display_manager;
+
 struct msm_drm_private {
 
 	struct drm_device *dev;
@@ -126,6 +128,9 @@
 	/* DSI is shared by mdp4 and mdp5 */
 	struct msm_dsi *dsi[2];
 
+	/* Display manager for SDE driver */
+	struct display_manager *dm;
+
 	/* when we have more than one 'msm_gpu' these need to be an array: */
 	struct msm_gpu *gpu;
 	struct msm_file_private *lastctx;