drm/msm/sde: remove display manager

Convert dsi and wb into actual drivers, and don't bind them
from within the display manager any more. With this change,
the display manager is no longer necessary, and may be safely
removed.

Change-Id: Ifac790fe31120d72cf78000a1476e22d000db4ae
Signed-off-by: Clarence Ip <cip@codeaurora.org>
diff --git a/Documentation/devicetree/bindings/drm/msm/sde-dsi.txt b/Documentation/devicetree/bindings/drm/msm/sde-dsi.txt
index 6be5332..ea35d14 100644
--- a/Documentation/devicetree/bindings/drm/msm/sde-dsi.txt
+++ b/Documentation/devicetree/bindings/drm/msm/sde-dsi.txt
@@ -62,7 +62,6 @@
 - 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
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index 26b6bc8..b080525 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -1,5 +1,4 @@
 ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/msm -Idrivers/gpu/drm/msm/dsi-staging
-ccflags-y += -Idrivers/gpu/drm/msm/display-manager
 ccflags-$(CONFIG_DRM_MSM_DSI) += -Idrivers/gpu/drm/msm/dsi
 ccflags-$(CONFIG_SYNC) += -Idrivers/staging/android
 ccflags-$(CONFIG_DRM_MSM_DSI_PLL) += -Idrivers/gpu/drm/msm/dsi
@@ -44,25 +43,7 @@
 	sde/sde_plane.o \
 	sde/sde_connector.o \
 	sde/sde_color_processing.o \
-	sde/sde_vbif.o \
-	msm_atomic.o \
-	msm_debugfs.o \
-	msm_drv.o \
-	msm_fb.o \
-	msm_fence.o \
-	msm_gem.o \
-	msm_gem_prime.o \
-	msm_gem_shrinker.o \
-	msm_gem_submit.o \
-	msm_gpu.o \
-	msm_iommu.o \
-	msm_smmu.o \
-	msm_perf.o \
-	msm_rd.o \
-	msm_ringbuffer.o \
-	msm_evtlog.o \
-	sde_power_handle.o \
-	msm_prop.o \
+	sde/sde_vbif.o
 
 # use drm gpu driver only if qcom_kgsl driver not available
 ifneq ($(CONFIG_QCOM_KGSL),y)
@@ -118,9 +99,11 @@
 				dsi-staging/dsi_panel.o \
 				dsi-staging/dsi_display_test.o
 
-obj-$(CONFIG_DRM_MSM)	+= msm_drm.o
+msm_drm-$(CONFIG_DRM_MSM_DSI_PLL) += dsi/pll/dsi_pll.o \
+				dsi/pll/dsi_pll_28nm.o
 
-obj-$(CONFIG_DRM_MSM) += sde/sde_hw_catalog.o \
+msm_drm-$(CONFIG_DRM_MSM) += \
+	sde/sde_hw_catalog.o \
 	sde/sde_hw_cdm.o \
 	sde/sde_hw_dspp.o \
 	sde/sde_hw_intf.o \
@@ -134,8 +117,25 @@
 	sde/sde_hw_interrupts.o \
 	sde/sde_hw_vbif.o \
 	sde/sde_formats.o \
+	sde_power_handle.o
 
-obj-$(CONFIG_DRM_MSM) += display-manager/display_manager.o
-
-obj-$(CONFIG_DRM_SDE_WB) += sde/sde_wb.o \
+msm_drm-$(CONFIG_DRM_SDE_WB) += sde/sde_wb.o \
 	sde/sde_encoder_phys_wb.o
+
+msm_drm-$(CONFIG_DRM_MSM) += \
+	msm_atomic.o \
+	msm_drv.o \
+	msm_fb.o \
+	msm_gem.o \
+	msm_gem_prime.o \
+	msm_gem_submit.o \
+	msm_gpu.o \
+	msm_iommu.o \
+	msm_smmu.o \
+	msm_perf.o \
+	msm_rd.o \
+	msm_ringbuffer.o \
+	msm_evtlog.o \
+	msm_prop.o
+
+obj-$(CONFIG_DRM_MSM)	+= msm_drm.o
diff --git a/drivers/gpu/drm/msm/display-manager/display_manager.c b/drivers/gpu/drm/msm/display-manager/display_manager.c
deleted file mode 100644
index 0b5d2f9..0000000
--- a/drivers/gpu/drm/msm/display-manager/display_manager.c
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- * 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.
- *
- */
-
-#define pr_fmt(fmt)	"dm-drm:[%s] " fmt, __func__
-#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 "sde_connector.h"
-
-#include "dsi_display.h"
-#include "dsi_drm.h"
-#include "sde_wb.h"
-#include "display_manager.h"
-
-/**
- * _dm_cache_active_displays - determine display type based on index
- * @disp_m: Pointer to display manager structure
- * Returns: Number of active displays in the system
- */
-static u32 _dm_cache_active_displays(struct display_manager *disp_m)
-{
-	u32 count;
-
-	if (!disp_m)
-		return 0;
-
-	disp_m->display_count = 0;
-
-	/* query dsi displays */
-	disp_m->dsi_display_count = dsi_display_get_num_of_displays();
-
-	/* query hdmi displays */
-	disp_m->hdmi_display_count = 0;
-
-	/* query dp displays */
-	disp_m->dp_display_count = 0;
-
-	/* query wb displays */
-	disp_m->wb_display_count = sde_wb_get_num_of_displays();
-	DBG("wb display count=%d", disp_m->wb_display_count);
-
-	count = disp_m->dsi_display_count
-		+ disp_m->hdmi_display_count
-		+ disp_m->dp_display_count
-		+ disp_m->wb_display_count;
-
-	disp_m->displays = kcalloc(count, sizeof(void *), GFP_KERNEL);
-	if (!disp_m->displays) {
-		disp_m->dsi_displays = 0;
-		disp_m->dsi_display_count = 0;
-
-		disp_m->hdmi_displays = 0;
-		disp_m->hdmi_display_count = 0;
-
-		disp_m->dp_displays = 0;
-		disp_m->dp_display_count = 0;
-
-		disp_m->wb_displays = 0;
-		disp_m->wb_display_count = 0;
-	} else {
-		/* get final dsi display list */
-		disp_m->dsi_displays = disp_m->displays;
-		disp_m->dsi_display_count =
-			dsi_display_get_active_displays(disp_m->dsi_displays,
-					disp_m->dsi_display_count);
-
-		/* get final hdmi display list */
-		disp_m->hdmi_displays = disp_m->dsi_displays
-			+ disp_m->dsi_display_count;
-		disp_m->hdmi_display_count = 0;
-
-		/* get final dp display list */
-		disp_m->dp_displays = disp_m->hdmi_displays
-			+ disp_m->hdmi_display_count;
-		disp_m->dp_display_count = 0;
-
-		/* get final wb display list */
-		disp_m->wb_displays = disp_m->dp_displays
-			+ disp_m->dp_display_count;
-		disp_m->wb_display_count =
-			wb_display_get_displays(disp_m->wb_displays,
-					disp_m->wb_display_count);
-	}
-
-	/* set final display count */
-	disp_m->display_count = disp_m->dsi_display_count
-		+ disp_m->hdmi_display_count
-		+ disp_m->dp_display_count
-		+ disp_m->wb_display_count;
-
-	return disp_m->display_count;
-}
-
-/**
- * _dm_get_type_by_index - determine display type based on index
- * @disp_m: Pointer to display manager structure
- * @display_index: Incoming display index
- * Returns: DRM_MODE_CONNECTOR_ definition corresponding to display_index
- */
-static int _dm_get_type_by_index(struct display_manager *disp_m,
-				      u32 display_index)
-{
-	if (disp_m) {
-		if (display_index < disp_m->dsi_display_count)
-			return DRM_MODE_CONNECTOR_DSI;
-		display_index -= disp_m->dsi_display_count;
-
-		if (display_index < disp_m->hdmi_display_count)
-			return DRM_MODE_CONNECTOR_HDMIA;
-		display_index -= disp_m->hdmi_display_count;
-
-		if (display_index < disp_m->dp_display_count)
-			return DRM_MODE_CONNECTOR_DisplayPort;
-		display_index -= disp_m->dp_display_count;
-
-		if (display_index < disp_m->wb_display_count)
-			return DRM_MODE_CONNECTOR_VIRTUAL;
-		display_index -= disp_m->wb_display_count;
-	}
-	return DRM_MODE_CONNECTOR_Unknown;
-}
-
-/**
- * _dm_init_active_displays - initialize active display drivers
- * @disp_m: Pointer to display manager structure
- * Returns: Zero on success
- */
-static int _dm_init_active_displays(struct display_manager *disp_m)
-{
-	void *display;
-	int rc = 0;
-	int dsi_idx, wb_idx;
-
-	for (dsi_idx = 0; dsi_idx < disp_m->dsi_display_count; dsi_idx++) {
-		display = disp_m->dsi_displays[dsi_idx];
-
-		rc = dsi_display_dev_init(display);
-		if (rc) {
-			pr_err("failed to init dsi display, rc=%d\n", rc);
-			goto error_deinit_dsi_displays;
-		}
-	}
-
-	for (wb_idx = 0; wb_idx < disp_m->wb_display_count; wb_idx++) {
-		display = disp_m->wb_displays[wb_idx];
-
-		rc = sde_wb_dev_init(display);
-		if (rc) {
-			pr_err("failed to init wb display, rc=%d\n", rc);
-			goto error_deinit_sde_wb;
-		}
-	}
-
-	/* TODO: INIT HDMI and DP displays here */
-	return rc;
-
-error_deinit_sde_wb:
-	for (wb_idx = wb_idx - 1; wb_idx >= 0; wb_idx--) {
-		display = disp_m->wb_displays[wb_idx];
-		(void)sde_wb_dev_deinit(display);
-	}
-
-error_deinit_dsi_displays:
-	for (dsi_idx = dsi_idx - 1; dsi_idx >= 0; dsi_idx--) {
-		display = disp_m->dsi_displays[dsi_idx];
-		(void)dsi_display_dev_deinit(display);
-	}
-
-	return rc;
-}
-
-/**
- * _dm_deinit_active_displays - deconstruct active display drivers
- * @disp_m: Pointer to display manager structure
- * Returns: Zero on success
- */
-static void _dm_deinit_active_displays(struct display_manager *disp_m)
-{
-	void *display;
-	int rc, i;
-
-	for (i = 0; i < disp_m->wb_display_count; i++) {
-		display = disp_m->wb_displays[i];
-
-		rc = sde_wb_dev_deinit(display);
-		if (rc)
-			pr_err("failed to deinit wb display, rc=%d\n", rc);
-	}
-
-	for (i = 0; i < disp_m->dsi_display_count; i++) {
-		display = disp_m->dsi_displays[i];
-		rc = dsi_display_dev_deinit(display);
-		if (rc)
-			pr_err("failed to deinit dsi display, rc=%d\n", rc);
-	}
-
-	/* TODO: DEINIT HDMI and DP displays here */
-}
-
-static int disp_manager_comp_ops_bind(struct device *dev,
-				     struct device *master,
-				     void *data)
-{
-	struct drm_device *drm;
-	struct msm_drm_private *priv;
-	struct display_manager *disp_m;
-	void *display;
-	int dsi_idx, wb_idx;
-	int rc = -EINVAL;
-
-	if (master && dev) {
-		drm = dev_get_drvdata(master);
-		disp_m = platform_get_drvdata(to_platform_device(dev));
-		if (drm && drm->dev_private && disp_m)
-			rc = 0;
-	}
-
-	if (rc) {
-		pr_err("Invalid params\n");
-		return -EINVAL;
-	}
-
-	priv = drm->dev_private;
-	disp_m->drm_dev = drm;
-
-	/* DSI displays */
-	for (dsi_idx = 0; dsi_idx < disp_m->dsi_display_count; dsi_idx++) {
-		display = disp_m->dsi_displays[dsi_idx];
-
-		rc = dsi_display_bind(display, drm);
-		if (rc) {
-			if (rc != -EPROBE_DEFER)
-				pr_err("Failed to bind dsi display_%d, rc=%d\n",
-					dsi_idx, rc);
-			goto error_unbind_dsi;
-		}
-	}
-
-	/* WB displays */
-	for (wb_idx = 0; wb_idx < disp_m->wb_display_count; wb_idx++) {
-		display = disp_m->wb_displays[wb_idx];
-
-		rc = sde_wb_bind(display, drm);
-		if (rc) {
-			pr_err("Failed to bind wb display_%d, rc=%d\n",
-				wb_idx, rc);
-			goto error_unbind_wb;
-		}
-	}
-
-	/* TODO: BIND HDMI display here */
-	/* TODO: BIND DP display here */
-	priv->dm = disp_m;
-	return rc;
-
-error_unbind_wb:
-	for (wb_idx = wb_idx - 1; wb_idx >= 0; wb_idx--) {
-		display = disp_m->wb_displays[wb_idx];
-		(void)sde_wb_unbind(display);
-	}
-
-error_unbind_dsi:
-	for (dsi_idx = dsi_idx - 1; dsi_idx >= 0; dsi_idx--) {
-		display = disp_m->dsi_displays[dsi_idx];
-		(void)dsi_display_unbind(display);
-	}
-	return rc;
-}
-
-static void disp_manager_comp_ops_unbind(struct device *dev,
-					struct device *master,
-					void *data)
-{
-	int rc = 0;
-	struct platform_device *pdev = to_platform_device(dev);
-	struct display_manager *disp_m;
-	void *display;
-	int i;
-
-	if (!dev) {
-		pr_err("Invalid params\n");
-		return;
-	}
-
-	disp_m = platform_get_drvdata(pdev);
-
-	/* WB displays */
-	for (i = 0; i < disp_m->wb_display_count; i++) {
-		display = disp_m->wb_displays[i];
-
-		rc = sde_wb_unbind(display);
-		if (rc)
-			pr_err("failed to unbind wb display_%d, rc=%d\n",
-			       i, rc);
-	}
-
-	/* DSI displays */
-	for (i = 0; i < disp_m->dsi_display_count; i++) {
-		display = disp_m->dsi_displays[i];
-
-		rc = dsi_display_unbind(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"},
-	{.compatible = "qcom,wb-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_cache_active_displays(disp_m);
-	if (!disp_m->display_count) {
-		rc = -ENODEV;
-		pr_err("no displays found, rc=%d\n", rc);
-		goto error_free_disp_m;
-	}
-
-	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:
-	_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)
-{
-	struct display_manager *disp_m;
-
-	if (!pdev) {
-		pr_err("invalid pdev argument\n");
-		return -ENODEV;
-	}
-
-	disp_m = platform_get_drvdata(pdev);
-
-	_dm_deinit_active_displays(disp_m);
-	of_platform_depopulate(&pdev->dev);
-	devm_kfree(&pdev->dev, disp_m);
-
-	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 0;
-	}
-
-	mutex_lock(&disp_m->lock);
-
-	count = disp_m->display_count;
-
-	mutex_unlock(&disp_m->lock);
-	return count;
-}
-
-int display_manager_get_info_by_index(struct display_manager *disp_m,
-				      u32 display_index,
-				      struct msm_display_info *info)
-{
-	void *display;
-	int rc = 0;
-
-	if (!disp_m || !info || (display_index >= disp_m->display_count)) {
-		pr_err("Invalid params\n");
-		return -EINVAL;
-	}
-
-	memset(info, 0, sizeof(*info));
-
-	mutex_lock(&disp_m->lock);
-
-	display = disp_m->displays[display_index];
-
-	switch (_dm_get_type_by_index(disp_m, display_index)) {
-	case DRM_MODE_CONNECTOR_DSI:
-		rc = dsi_display_get_info(info, display);
-		if (rc) {
-			pr_err("failed to get dsi info, rc=%d\n", rc);
-			rc = -EINVAL;
-		}
-		break;
-	case DRM_MODE_CONNECTOR_VIRTUAL:
-		rc = sde_wb_get_info(info, display);
-		if (rc) {
-			pr_err("failed to get wb info, rc=%d\n", rc);
-			rc = -EINVAL;
-		}
-		break;
-	default:
-		pr_err("invalid index %d\n", display_index);
-		rc = -EINVAL;
-		break;
-	}
-	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)
-{
-	static const struct sde_connector_ops dsi_ops = {
-		.post_init =  dsi_conn_post_init,
-		.detect =     dsi_conn_detect,
-		.get_modes =  dsi_connector_get_modes,
-		.mode_valid = dsi_conn_mode_valid,
-		.get_info =   dsi_display_get_info,
-	};
-	static const struct sde_connector_ops wb_ops = {
-		.post_init =    sde_wb_connector_post_init,
-		.detect =       sde_wb_connector_detect,
-		.get_modes =    sde_wb_connector_get_modes,
-		.set_property = sde_wb_connector_set_property,
-		.get_info =     sde_wb_get_info,
-	};
-	void *display;
-	int rc = -EINVAL;
-	struct drm_connector *connector;
-
-	if (!disp_m || !encoder || (display_index >= disp_m->display_count)) {
-		pr_err("Invalid params\n");
-		return -EINVAL;
-	}
-
-	mutex_lock(&disp_m->lock);
-
-	display = disp_m->displays[display_index];
-
-	switch (_dm_get_type_by_index(disp_m, display_index)) {
-	case DRM_MODE_CONNECTOR_DSI:
-		rc = dsi_display_drm_bridge_init(display, encoder);
-		if (rc) {
-			pr_err("dsi bridge init failed\n");
-			break;
-		}
-
-		connector = sde_connector_init(disp_m->drm_dev,
-				encoder,
-				0,
-				display,
-				&dsi_ops,
-				DRM_CONNECTOR_POLL_HPD,
-				DRM_MODE_CONNECTOR_DSI);
-		if (!connector)
-			rc = -ENOMEM;
-		else if (IS_ERR(connector))
-			rc = PTR_ERR(connector);
-		break;
-	case DRM_MODE_CONNECTOR_VIRTUAL:
-		rc = sde_wb_drm_init(display, encoder);
-		if (rc) {
-			pr_err("writeback init failed\n");
-			break;
-		}
-
-		connector = sde_connector_init(disp_m->drm_dev,
-				encoder,
-				0,
-				display,
-				&wb_ops,
-				DRM_CONNECTOR_POLL_HPD,
-				DRM_MODE_CONNECTOR_VIRTUAL);
-		if (!connector)
-			rc = -ENOMEM;
-		else if (IS_ERR(connector))
-			rc = PTR_ERR(connector);
-		break;
-	default:
-		pr_err("invalid index %d\n", display_index);
-		break;
-	}
-
-	mutex_unlock(&disp_m->lock);
-
-	return rc;
-}
-
-int display_manager_drm_deinit_by_index(struct display_manager *disp_m,
-					u32 display_index)
-{
-	void *display;
-	int rc = 0;
-
-	if (!disp_m) {
-		pr_err("Invalid params\n");
-		return -EINVAL;
-	}
-
-	mutex_lock(&disp_m->lock);
-
-	if (display_index < disp_m->display_count)
-		display = disp_m->displays[display_index];
-
-	switch (_dm_get_type_by_index(disp_m, display_index)) {
-	case DRM_MODE_CONNECTOR_DSI:
-		dsi_display_drm_bridge_deinit(display);
-		break;
-	default:
-		pr_err("invalid index\n");
-		rc = -EINVAL;
-		break;
-	}
-
-	mutex_unlock(&disp_m->lock);
-
-	return rc;
-}
-
-
-void display_manager_register(void)
-{
-	dsi_phy_drv_register();
-	dsi_ctrl_drv_register();
-	dsi_display_register();
-	sde_wb_register();
-	platform_driver_register(&disp_manager_driver);
-}
-void display_manager_unregister(void)
-{
-	platform_driver_unregister(&disp_manager_driver);
-	sde_wb_unregister();
-	dsi_display_unregister();
-	dsi_ctrl_drv_unregister();
-	dsi_phy_drv_unregister();
-}
diff --git a/drivers/gpu/drm/msm/display-manager/display_manager.h b/drivers/gpu/drm/msm/display-manager/display_manager.h
deleted file mode 100644
index d220fc0..0000000
--- a/drivers/gpu/drm/msm/display-manager/display_manager.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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_
-
-struct display_manager {
-	struct drm_device *drm_dev;
-	struct platform_device *pdev;
-	const char *name;
-
-	struct mutex lock;
-
-	u32 display_count;
-	void **displays;
-
-	u32 dsi_display_count;
-	void **dsi_displays;
-
-	u32 hdmi_display_count;
-	void **hdmi_displays;
-
-	u32 dp_display_count;
-	void **dp_displays;
-
-	u32 wb_display_count;
-	void **wb_displays;
-
-	/* 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 msm_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_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index 59e9899..825bf2d 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -126,7 +126,7 @@
 	return rc;
 }
 
-static int dsi_dipslay_debugfs_deinit(struct dsi_display *display)
+static int dsi_display_debugfs_deinit(struct dsi_display *display)
 {
 	debugfs_remove_recursive(display->root);
 
@@ -1592,6 +1592,228 @@
 	return rc;
 }
 
+/**
+ * _dsi_display_dev_init - initializes the display device
+ * Initialization will acquire references to the resources required for the
+ * display hardware to function.
+ * @display:         Handle to the display
+ * Returns:          Zero on success
+ */
+static int _dsi_display_dev_init(struct dsi_display *display)
+{
+	int rc = 0;
+
+	if (!display) {
+		pr_err("invalid display\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&display->display_lock);
+
+	rc = dsi_display_parse_dt(display);
+	if (rc) {
+		pr_err("[%s] failed to parse dt, rc=%d\n", display->name, rc);
+		goto error;
+	}
+
+	rc = dsi_display_res_init(display);
+	if (rc) {
+		pr_err("[%s] failed to initialize resources, rc=%d\n",
+		       display->name, rc);
+		goto error;
+	}
+error:
+	mutex_unlock(&display->display_lock);
+	return rc;
+}
+
+/**
+ * _dsi_display_dev_deinit - deinitializes the display device
+ * All the resources acquired during device init will be released.
+ * @display:        Handle to the display
+ * Returns:         Zero on success
+ */
+static int _dsi_display_dev_deinit(struct dsi_display *display)
+{
+	int rc = 0;
+
+	if (!display) {
+		pr_err("invalid display\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&display->display_lock);
+
+	rc = dsi_display_res_deinit(display);
+	if (rc)
+		pr_err("[%s] failed to deinitialize resource, rc=%d\n",
+		       display->name, rc);
+
+	mutex_unlock(&display->display_lock);
+
+	return rc;
+}
+
+/**
+ * dsi_display_bind - bind dsi device with controlling device
+ * @dev:        Pointer to base of platform device
+ * @master:     Pointer to container of drm device
+ * @data:       Pointer to private data
+ * Returns:     Zero on success
+ */
+static int dsi_display_bind(struct device *dev,
+		struct device *master,
+		void *data)
+{
+	struct dsi_display_ctrl *display_ctrl;
+	struct drm_device *drm;
+	struct dsi_display *display;
+	struct platform_device *pdev = to_platform_device(dev);
+	int i, rc = 0;
+
+	if (!dev || !pdev || !master) {
+		pr_err("invalid param(s), dev %pK, pdev %pK, master %pK\n",
+				dev, pdev, master);
+		return -EINVAL;
+	}
+
+	drm = dev_get_drvdata(master);
+	display = platform_get_drvdata(pdev);
+	if (!drm || !display) {
+		pr_err("invalid param(s), drm %pK, display %pK\n",
+				drm, display);
+		return -EINVAL;
+	}
+
+	mutex_lock(&display->display_lock);
+
+	rc = dsi_display_debugfs_init(display);
+	if (rc) {
+		pr_err("[%s] debugfs init failed, rc=%d\n", display->name, rc);
+		goto error;
+	}
+
+	for (i = 0; i < display->ctrl_count; i++) {
+		display_ctrl = &display->ctrl[i];
+
+		rc = dsi_ctrl_drv_init(display_ctrl->ctrl, display->root);
+		if (rc) {
+			pr_err("[%s] failed to initialize ctrl[%d], rc=%d\n",
+			       display->name, i, rc);
+			goto error_ctrl_deinit;
+		}
+
+		rc = dsi_phy_drv_init(display_ctrl->phy);
+		if (rc) {
+			pr_err("[%s] Failed to initialize phy[%d], rc=%d\n",
+				display->name, i, rc);
+			(void)dsi_ctrl_drv_deinit(display_ctrl->ctrl);
+			goto error_ctrl_deinit;
+		}
+	}
+
+	rc = dsi_display_mipi_host_init(display);
+	if (rc) {
+		pr_err("[%s] failed to initialize mipi host, rc=%d\n",
+		       display->name, rc);
+		goto error_ctrl_deinit;
+	}
+
+	rc = dsi_panel_drv_init(display->panel, &display->host);
+	if (rc) {
+		if (rc != -EPROBE_DEFER)
+			pr_err("[%s] failed to initialize panel driver, rc=%d\n",
+			       display->name, rc);
+		goto error_host_deinit;
+	}
+
+	rc = dsi_panel_get_mode_count(display->panel, &display->num_of_modes);
+	if (rc) {
+		pr_err("[%s] failed to get mode count, rc=%d\n",
+		       display->name, rc);
+		goto error_panel_deinit;
+	}
+
+	display->drm_dev = drm;
+	goto error;
+
+error_panel_deinit:
+	(void)dsi_panel_drv_deinit(display->panel);
+error_host_deinit:
+	(void)dsi_display_mipi_host_deinit(display);
+error_ctrl_deinit:
+	for (i = i - 1; i >= 0; i--) {
+		display_ctrl = &display->ctrl[i];
+		(void)dsi_phy_drv_deinit(display_ctrl->phy);
+		(void)dsi_ctrl_drv_deinit(display_ctrl->ctrl);
+	}
+	(void)dsi_display_debugfs_deinit(display);
+error:
+	mutex_unlock(&display->display_lock);
+	return rc;
+}
+
+/**
+ * dsi_display_unbind - unbind dsi from controlling device
+ * @dev:        Pointer to base of platform device
+ * @master:     Pointer to container of drm device
+ * @data:       Pointer to private data
+ */
+static void dsi_display_unbind(struct device *dev,
+		struct device *master, void *data)
+{
+	struct dsi_display_ctrl *display_ctrl;
+	struct dsi_display *display;
+	struct platform_device *pdev = to_platform_device(dev);
+	int i, rc = 0;
+
+	if (!dev || !pdev) {
+		pr_err("invalid param(s)\n");
+		return;
+	}
+
+	display = platform_get_drvdata(pdev);
+	if (!display) {
+		pr_err("invalid display\n");
+		return;
+	}
+
+	mutex_lock(&display->display_lock);
+
+	rc = dsi_panel_drv_deinit(display->panel);
+	if (rc)
+		pr_err("[%s] failed to deinit panel driver, rc=%d\n",
+		       display->name, rc);
+
+	rc = dsi_display_mipi_host_deinit(display);
+	if (rc)
+		pr_err("[%s] failed to deinit mipi hosts, rc=%d\n",
+		       display->name,
+		       rc);
+
+	for (i = 0; i < display->ctrl_count; i++) {
+		display_ctrl = &display->ctrl[i];
+
+		rc = dsi_phy_drv_deinit(display_ctrl->phy);
+		if (rc)
+			pr_err("[%s] failed to deinit phy%d driver, rc=%d\n",
+			       display->name, i, rc);
+
+		rc = dsi_ctrl_drv_deinit(display_ctrl->ctrl);
+		if (rc)
+			pr_err("[%s] failed to deinit ctrl%d driver, rc=%d\n",
+			       display->name, i, rc);
+	}
+	(void)dsi_display_debugfs_deinit(display);
+
+	mutex_unlock(&display->display_lock);
+}
+
+static const struct component_ops dsi_display_comp_ops = {
+	.bind = dsi_display_bind,
+	.unbind = dsi_display_unbind,
+};
+
 static struct platform_driver dsi_display_driver = {
 	.probe = dsi_display_dev_probe,
 	.remove = dsi_display_dev_remove,
@@ -1632,8 +1854,19 @@
 	mutex_lock(&dsi_display_list_lock);
 	list_add(&display->list, &dsi_display_list);
 	mutex_unlock(&dsi_display_list_lock);
-	if (display->is_active)
+
+	if (display->is_active) {
 		main_display = display;
+		rc = _dsi_display_dev_init(display);
+		if (rc) {
+			pr_err("device init failed, rc=%d\n", rc);
+			return rc;
+		}
+
+		rc = component_add(&pdev->dev, &dsi_display_comp_ops);
+		if (rc)
+			pr_err("component add failed, rc=%d\n", rc);
+	}
 	return rc;
 }
 
@@ -1650,6 +1883,8 @@
 
 	display = platform_get_drvdata(pdev);
 
+	(void)_dsi_display_dev_deinit(display);
+
 	mutex_lock(&dsi_display_list_lock);
 	list_for_each_entry_safe(pos, tmp, &dsi_display_list, list) {
 		if (pos == display) {
@@ -1664,9 +1899,9 @@
 	return rc;
 }
 
-u32 dsi_display_get_num_of_displays(void)
+int dsi_display_get_num_of_displays(void)
 {
-	u32 count = 0;
+	int count = 0;
 	struct dsi_display *display;
 
 	mutex_lock(&dsi_display_list_lock);
@@ -1728,178 +1963,6 @@
 	mutex_unlock(&display->display_lock);
 }
 
-int dsi_display_dev_init(struct dsi_display *display)
-{
-	int rc = 0;
-
-	if (!display) {
-		pr_err("Invalid params\n");
-		return -EINVAL;
-	}
-
-	mutex_lock(&display->display_lock);
-
-	rc = dsi_display_parse_dt(display);
-	if (rc) {
-		pr_err("[%s] failed to parse dt, rc=%d\n", display->name, rc);
-		goto error;
-	}
-
-	rc = dsi_display_res_init(display);
-	if (rc) {
-		pr_err("[%s] failed to initialize resources, rc=%d\n",
-		       display->name, rc);
-		goto error;
-	}
-error:
-	mutex_unlock(&display->display_lock);
-	return rc;
-}
-
-int dsi_display_dev_deinit(struct dsi_display *display)
-{
-	int rc = 0;
-
-	if (!display) {
-		pr_err("Invalid params\n");
-		return -EINVAL;
-	}
-
-	mutex_lock(&display->display_lock);
-
-	rc = dsi_display_res_deinit(display);
-	if (rc)
-		pr_err("[%s] failed to deinitialize resource, rc=%d\n",
-		       display->name, rc);
-
-	mutex_unlock(&display->display_lock);
-
-	return rc;
-}
-
-int dsi_display_bind(struct dsi_display *display, struct drm_device *dev)
-{
-	int rc = 0;
-	int i;
-	struct dsi_display_ctrl *display_ctrl;
-
-	if (!display) {
-		pr_err("Invalid params\n");
-		return -EINVAL;
-	}
-
-	mutex_lock(&display->display_lock);
-
-	rc = dsi_display_debugfs_init(display);
-	if (rc) {
-		pr_err("[%s]Debugfs init failed, rc=%d\n", display->name, rc);
-		goto error;
-	}
-
-	for (i = 0; i < display->ctrl_count; i++) {
-		display_ctrl = &display->ctrl[i];
-
-		rc = dsi_ctrl_drv_init(display_ctrl->ctrl, display->root);
-		if (rc) {
-			pr_err("[%s] Failed to initialize ctrl[%d], rc=%d\n",
-			       display->name, i, rc);
-			goto error_ctrl_deinit;
-		}
-
-		rc = dsi_phy_drv_init(display_ctrl->phy);
-		if (rc) {
-			pr_err("[%s] Failed to initialize phy[%d], rc=%d\n",
-				display->name, i, rc);
-			(void)dsi_ctrl_drv_deinit(display_ctrl->ctrl);
-			goto error_ctrl_deinit;
-		}
-	}
-
-	rc = dsi_display_mipi_host_init(display);
-	if (rc) {
-		pr_err("[%s] Failed to initialize mipi host, rc=%d\n",
-		       display->name, rc);
-		goto error_ctrl_deinit;
-	}
-
-	rc = dsi_panel_drv_init(display->panel, &display->host);
-	if (rc) {
-		if (rc != -EPROBE_DEFER)
-			pr_err("[%s] Failed to initialize panel driver, rc=%d\n",
-			       display->name, rc);
-		goto error_host_deinit;
-	}
-
-	rc = dsi_panel_get_mode_count(display->panel, &display->num_of_modes);
-	if (rc) {
-		pr_err("[%s] Failed to get mode count, rc=%d\n",
-		       display->name, rc);
-		goto error_panel_deinit;
-	}
-
-	display->drm_dev = dev;
-	goto error;
-
-error_panel_deinit:
-	(void)dsi_panel_drv_deinit(display->panel);
-error_host_deinit:
-	(void)dsi_display_mipi_host_deinit(display);
-error_ctrl_deinit:
-	for (i = i - 1; i >= 0; i--) {
-		display_ctrl = &display->ctrl[i];
-		(void)dsi_phy_drv_deinit(display_ctrl->phy);
-		(void)dsi_ctrl_drv_deinit(display_ctrl->ctrl);
-	}
-	(void)dsi_dipslay_debugfs_deinit(display);
-error:
-	mutex_unlock(&display->display_lock);
-	return rc;
-}
-
-int dsi_display_unbind(struct dsi_display *display)
-{
-	int rc = 0;
-	int i;
-	struct dsi_display_ctrl *display_ctrl;
-
-	if (!display) {
-		pr_err("Invalid params\n");
-		return -EINVAL;
-	}
-
-	mutex_lock(&display->display_lock);
-
-	rc = dsi_panel_drv_deinit(display->panel);
-	if (rc)
-		pr_err("[%s] failed to deinit panel driver, rc=%d\n",
-		       display->name, rc);
-
-	rc = dsi_display_mipi_host_deinit(display);
-	if (rc)
-		pr_err("[%s] failed to deinit mipi hosts, rc=%d\n",
-		       display->name,
-		       rc);
-
-	for (i = 0; i < display->ctrl_count; i++) {
-		display_ctrl = &display->ctrl[i];
-
-		rc = dsi_phy_drv_deinit(display_ctrl->phy);
-		if (rc)
-			pr_err("[%s] failed to deinit phy%d driver, rc=%d\n",
-			       display->name, i, rc);
-
-		rc = dsi_ctrl_drv_deinit(display_ctrl->ctrl);
-		if (rc)
-			pr_err("[%s] failed to deinit ctrl%d driver, rc=%d\n",
-			       display->name, i, rc);
-	}
-
-	(void)dsi_dipslay_debugfs_deinit(display);
-
-	mutex_unlock(&display->display_lock);
-	return rc;
-}
-
 int dsi_display_drm_bridge_init(struct dsi_display *display,
 		struct drm_encoder *enc)
 {
@@ -1907,8 +1970,8 @@
 	struct dsi_bridge *bridge;
 	struct msm_drm_private *priv = NULL;
 
-	if (!display || !enc) {
-		pr_err("Invalid params\n");
+	if (!display || !display->drm_dev || !enc) {
+		pr_err("invalid param(s)\n");
 		return -EINVAL;
 	}
 
@@ -2489,12 +2552,19 @@
 	return rc;
 }
 
-void dsi_display_register(void)
+static int __init dsi_display_register(void)
 {
-	platform_driver_register(&dsi_display_driver);
+	dsi_phy_drv_register();
+	dsi_ctrl_drv_register();
+	return platform_driver_register(&dsi_display_driver);
 }
 
-void dsi_display_unregister(void)
+static void __exit dsi_display_unregister(void)
 {
 	platform_driver_unregister(&dsi_display_driver);
+	dsi_ctrl_drv_unregister();
+	dsi_phy_drv_unregister();
 }
+
+module_init(dsi_display_register);
+module_exit(dsi_display_unregister);
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
index f941cd4..813e7e3 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
@@ -159,22 +159,12 @@
 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.
  *
  * Return: number of displays.
  */
-u32 dsi_display_get_num_of_displays(void);
+int dsi_display_get_num_of_displays(void);
 
 /**
  * dsi_display_get_active_displays - returns pointers for active display devices
@@ -201,44 +191,6 @@
 void dsi_display_set_active_state(struct dsi_display *display, bool is_active);
 
 /**
- * dsi_display_dev_init() - Initializes the display device
- * @display:         Handle to the display.
- *
- * Initialization will acquire references to the resources required for the
- * display hardware to function.
- *
- * Return: error code.
- */
-int dsi_display_dev_init(struct dsi_display *display);
-
-/**
- * dsi_display_dev_deinit() - Desinitializes the display device
- * @display:        Handle to the display.
- *
- * All the resources acquired during device init will be released.
- *
- * Return: error code.
- */
-int dsi_display_dev_deinit(struct dsi_display *display);
-
-/**
- * dsi_display_bind() - Binds the display device to the DRM device
- * @display:       Handle to the display.
- * @dev:           Pointer to the DRM device.
- *
- * Return: error code.
- */
-int dsi_display_bind(struct dsi_display *display, struct drm_device *dev);
-
-/**
- * dsi_display_unbind() - Unbinds the display device from the DRM device
- * @display:         Handle to the display.
- *
- * Return: error code.
- */
-int dsi_display_unbind(struct dsi_display *display);
-
-/**
  * dsi_display_drm_bridge_init() - initializes DRM bridge object for DSI
  * @display:            Handle to the display.
  * @encoder:            Pointer to the encoder object which is connected to the
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 8e30f04..d127f2c 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -21,7 +21,6 @@
 #include "msm_fence.h"
 #include "msm_gpu.h"
 #include "msm_kms.h"
-#include "display_manager.h"
 #include "sde_wb.h"
 
 /*
@@ -1325,8 +1324,6 @@
 static int __init msm_drm_register(void)
 {
 	DBG("init");
-	msm_mdp_register();
-	display_manager_register();
 	msm_dsi_register();
 	msm_edp_register();
 	msm_hdmi_register();
@@ -1342,7 +1339,6 @@
 	adreno_unregister();
 	msm_edp_unregister();
 	msm_dsi_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 e5adb11..4624996 100644
--- a/drivers/gpu/drm/msm/msm_drv.h
+++ b/drivers/gpu/drm/msm/msm_drv.h
@@ -208,7 +208,20 @@
 	enum msm_display_compression compression;
 };
 
-struct display_manager;
+/**
+ * struct msm_drm_event - defines custom event notification struct
+ * @base: base object required for event notification by DRM framework.
+ * @event: event object required for event notification by DRM framework.
+ * @info: contains information of DRM object for which events has been
+ *        requested.
+ * @data: memory location which contains response payload for event.
+ */
+struct msm_drm_event {
+	struct drm_pending_event base;
+	struct drm_event event;
+	struct drm_msm_event_req info;
+	u8 data[];
+};
 
 struct msm_drm_private {
 
@@ -239,9 +252,6 @@
 	/* 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;
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index fd57404..5f35f0b 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -25,7 +25,6 @@
 #include "sde_hw_ctl.h"
 #include "sde_formats.h"
 #include "sde_encoder_phys.h"
-#include "display_manager.h"
 #include "sde_color_processing.h"
 
 #define SDE_DEBUG_ENC(e, fmt, ...) SDE_DEBUG("enc%d " fmt,\
@@ -218,7 +217,7 @@
 	}
 }
 
-static void sde_encoder_destroy(struct drm_encoder *drm_enc)
+void sde_encoder_destroy(struct drm_encoder *drm_enc)
 {
 	struct sde_encoder_virt *sde_enc = NULL;
 	int i = 0;
@@ -1049,8 +1048,9 @@
 	return ret;
 }
 
-static struct drm_encoder *sde_encoder_virt_init(
-		struct drm_device *dev, struct msm_display_info *disp_info)
+struct drm_encoder *sde_encoder_init(
+		struct drm_device *dev,
+		struct msm_display_info *disp_info)
 {
 	struct msm_drm_private *priv = dev->dev_private;
 	struct sde_kms *sde_kms = to_sde_kms(priv->kms);
@@ -1119,64 +1119,3 @@
 	return ret;
 }
 
-/* encoders init,
- * initialize encoder based on displays
- */
-void sde_encoders_init(struct drm_device *dev)
-{
-	struct msm_drm_private *priv = NULL;
-	struct display_manager *disp_man = NULL;
-	u32 i = 0;
-	u32 num_displays = 0;
-
-	SDE_DEBUG("\n");
-
-	if (!dev || !dev->dev_private) {
-		SDE_ERROR("invalid device %d\n", dev != 0);
-		return;
-	}
-
-	priv = dev->dev_private;
-	priv->num_encoders = 0;
-	if (!priv->kms || !priv->dm) {
-		SDE_ERROR("invalid priv pointer, kms %d dm %d\n",
-				priv->kms != 0, priv->dm != 0);
-		return;
-	}
-	disp_man = priv->dm;
-
-	num_displays = display_manager_get_count(disp_man);
-	SDE_DEBUG("num_displays %d\n", num_displays);
-
-	if (num_displays > ARRAY_SIZE(priv->encoders)) {
-		num_displays = ARRAY_SIZE(priv->encoders);
-		SDE_ERROR("too many displays found, capping to %d\n",
-				num_displays);
-	}
-
-	for (i = 0; i < num_displays; i++) {
-		struct msm_display_info info = { 0 };
-		struct drm_encoder *enc = NULL;
-		u32 ret = 0;
-
-		ret = display_manager_get_info_by_index(disp_man, i, &info);
-		if (ret) {
-			SDE_ERROR("failed to get display info, %d\n", ret);
-			return;
-		}
-
-		enc = sde_encoder_virt_init(dev, &info);
-		if (IS_ERR_OR_NULL(enc)) {
-			SDE_ERROR("encoder initialization failed\n");
-			return;
-		}
-
-		ret = display_manager_drm_init_by_index(disp_man, i, enc);
-		if (ret) {
-			SDE_ERROR("display drm_init failed, %d\n", ret);
-			return;
-		}
-
-		priv->encoders[priv->num_encoders++] = enc;
-	}
-}
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 650ef84..f05fe79 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -17,6 +17,11 @@
 
 #include "msm_drv.h"
 #include "msm_mmu.h"
+
+#include "dsi_display.h"
+#include "dsi_drm.h"
+#include "sde_wb.h"
+
 #include "sde_kms.h"
 #include "sde_core_irq.h"
 #include "sde_formats.h"
@@ -320,6 +325,215 @@
 		sde_connector_prepare_fence(connector);
 }
 
+/**
+ * _sde_kms_get_displays - query for underlying display handles and cache them
+ * @sde_kms:    Pointer to sde kms structure
+ * Returns:     Zero on success
+ */
+static int _sde_kms_get_displays(struct sde_kms *sde_kms)
+{
+	int rc = -ENOMEM;
+
+	if (!sde_kms) {
+		SDE_ERROR("invalid sde kms\n");
+		return -EINVAL;
+	}
+
+	/* dsi */
+	sde_kms->dsi_displays = NULL;
+	sde_kms->dsi_display_count = dsi_display_get_num_of_displays();
+	if (sde_kms->dsi_display_count) {
+		sde_kms->dsi_displays = kcalloc(sde_kms->dsi_display_count,
+				sizeof(void *),
+				GFP_KERNEL);
+		if (!sde_kms->dsi_displays) {
+			SDE_ERROR("failed to allocate dsi displays\n");
+			goto exit_deinit_dsi;
+		}
+		sde_kms->dsi_display_count =
+			dsi_display_get_active_displays(sde_kms->dsi_displays,
+					sde_kms->dsi_display_count);
+	}
+
+	/* wb */
+	sde_kms->wb_displays = NULL;
+	sde_kms->wb_display_count = sde_wb_get_num_of_displays();
+	if (sde_kms->wb_display_count) {
+		sde_kms->wb_displays = kcalloc(sde_kms->wb_display_count,
+				sizeof(void *),
+				GFP_KERNEL);
+		if (!sde_kms->wb_displays) {
+			SDE_ERROR("failed to allocate wb displays\n");
+			goto exit_deinit_wb;
+		}
+		sde_kms->wb_display_count =
+			wb_display_get_displays(sde_kms->wb_displays,
+					sde_kms->wb_display_count);
+	}
+	return 0;
+
+exit_deinit_wb:
+	kfree(sde_kms->wb_displays);
+	sde_kms->wb_display_count = 0;
+	sde_kms->wb_displays = NULL;
+
+exit_deinit_dsi:
+	kfree(sde_kms->dsi_displays);
+	sde_kms->dsi_display_count = 0;
+	sde_kms->dsi_displays = NULL;
+	return rc;
+}
+
+/**
+ * _sde_kms_release_displays - release cache of underlying display handles
+ * @sde_kms:    Pointer to sde kms structure
+ */
+static void _sde_kms_release_displays(struct sde_kms *sde_kms)
+{
+	if (!sde_kms) {
+		SDE_ERROR("invalid sde kms\n");
+		return;
+	}
+
+	kfree(sde_kms->wb_displays);
+	sde_kms->wb_displays = NULL;
+	sde_kms->wb_display_count = 0;
+
+	kfree(sde_kms->dsi_displays);
+	sde_kms->dsi_displays = NULL;
+	sde_kms->dsi_display_count = 0;
+}
+
+/**
+ * _sde_kms_setup_displays - create encoders, bridges and connectors
+ *                           for underlying displays
+ * @dev:        Pointer to drm device structure
+ * @priv:       Pointer to private drm device data
+ * @sde_kms:    Pointer to sde kms structure
+ * Returns:     Zero on success
+ */
+static int _sde_kms_setup_displays(struct drm_device *dev,
+		struct msm_drm_private *priv,
+		struct sde_kms *sde_kms)
+{
+	static const struct sde_connector_ops dsi_ops = {
+		.post_init =  dsi_conn_post_init,
+		.detect =     dsi_conn_detect,
+		.get_modes =  dsi_connector_get_modes,
+		.mode_valid = dsi_conn_mode_valid,
+		.get_info =   dsi_display_get_info,
+	};
+	static const struct sde_connector_ops wb_ops = {
+		.post_init =    sde_wb_connector_post_init,
+		.detect =       sde_wb_connector_detect,
+		.get_modes =    sde_wb_connector_get_modes,
+		.set_property = sde_wb_connector_set_property,
+		.get_info =     sde_wb_get_info,
+	};
+	struct msm_display_info info;
+	struct drm_encoder *encoder;
+	void *display, *connector;
+	int i, max_encoders;
+	int rc = 0;
+
+	if (!dev || !priv || !sde_kms) {
+		SDE_ERROR("invalid argument(s)\n");
+		return -EINVAL;
+	}
+
+	max_encoders = sde_kms->dsi_display_count + sde_kms->wb_display_count;
+	if (max_encoders > ARRAY_SIZE(priv->encoders)) {
+		max_encoders = ARRAY_SIZE(priv->encoders);
+		SDE_ERROR("capping number of displays to %d", max_encoders);
+	}
+
+	/* dsi */
+	for (i = 0; i < sde_kms->dsi_display_count &&
+		priv->num_encoders < max_encoders; ++i) {
+		display = sde_kms->dsi_displays[i];
+		encoder = NULL;
+
+		memset(&info, 0x0, sizeof(info));
+		rc = dsi_display_get_info(&info, display);
+		if (rc) {
+			SDE_ERROR("dsi get_info %d failed\n", i);
+			continue;
+		}
+
+		encoder = sde_encoder_init(dev, &info);
+		if (IS_ERR_OR_NULL(encoder)) {
+			SDE_ERROR("encoder init failed for dsi %d\n", i);
+			continue;
+		}
+
+		rc = dsi_display_drm_bridge_init(display, encoder);
+		if (rc) {
+			SDE_ERROR("dsi bridge %d init failed, %d\n", i, rc);
+			sde_encoder_destroy(encoder);
+			continue;
+		}
+
+		connector = sde_connector_init(dev,
+					encoder,
+					0,
+					display,
+					&dsi_ops,
+					DRM_CONNECTOR_POLL_HPD,
+					DRM_MODE_CONNECTOR_DSI);
+		if (connector) {
+			priv->encoders[priv->num_encoders++] = encoder;
+		} else {
+			SDE_ERROR("dsi %d connector init failed\n", i);
+			dsi_display_drm_bridge_deinit(display);
+			sde_encoder_destroy(encoder);
+		}
+	}
+
+	/* wb */
+	for (i = 0; i < sde_kms->wb_display_count &&
+		priv->num_encoders < max_encoders; ++i) {
+		display = sde_kms->wb_displays[i];
+		encoder = NULL;
+
+		memset(&info, 0x0, sizeof(info));
+		rc = sde_wb_get_info(&info, display);
+		if (rc) {
+			SDE_ERROR("wb get_info %d failed\n", i);
+			continue;
+		}
+
+		encoder = sde_encoder_init(dev, &info);
+		if (IS_ERR_OR_NULL(encoder)) {
+			SDE_ERROR("encoder init failed for wb %d\n", i);
+			continue;
+		}
+
+		rc = sde_wb_drm_init(display, encoder);
+		if (rc) {
+			SDE_ERROR("wb bridge %d init failed, %d\n", i, rc);
+			sde_encoder_destroy(encoder);
+			continue;
+		}
+
+		connector = sde_connector_init(dev,
+				encoder,
+				0,
+				display,
+				&wb_ops,
+				DRM_CONNECTOR_POLL_HPD,
+				DRM_MODE_CONNECTOR_VIRTUAL);
+		if (connector) {
+			priv->encoders[priv->num_encoders++] = encoder;
+		} else {
+			SDE_ERROR("wb %d connector init failed\n", i);
+			sde_wb_drm_deinit(display);
+			sde_encoder_destroy(encoder);
+		}
+	}
+
+	return 0;
+}
+
 static int modeset_init(struct sde_kms *sde_kms)
 {
 	struct drm_device *dev;
@@ -341,8 +555,12 @@
 	priv = dev->dev_private;
 	catalog = sde_kms->catalog;
 
-	/* Enumerate displays supported */
-	sde_encoders_init(dev);
+	/*
+	 * Query for underlying display drivers, and create connectors,
+	 * bridges and encoders for them.
+	 */
+	if (!_sde_kms_get_displays(sde_kms))
+		(void)_sde_kms_setup_displays(dev, priv, sde_kms);
 
 	max_crtc_count = min(catalog->mixer_count, priv->num_encoders);
 	max_plane_count = min_t(u32, catalog->sspp_count, MAX_PLANES);
@@ -440,6 +658,7 @@
 			sde_hw_vbif_destroy(sde_kms->hw_vbif[vbif_idx]);
 	}
 
+	_sde_kms_release_displays(sde_kms);
 	sde_debugfs_destroy(sde_kms);
 	sde_hw_intr_destroy(sde_kms->hw_intr);
 	sde_rm_destroy(&sde_kms->rm);
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h
index d1ec5c0..6dca0a1 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.h
+++ b/drivers/gpu/drm/msm/sde/sde_kms.h
@@ -143,6 +143,10 @@
 
 	struct sde_hw_vbif *hw_vbif[VBIF_MAX];
 	struct sde_hw_mdp *hw_mdp;
+	int dsi_display_count;
+	void **dsi_displays;
+	int wb_display_count;
+	void **wb_displays;
 };
 
 struct vsync_info {
@@ -463,10 +467,19 @@
 int sde_encoder_wait_for_commit_done(struct drm_encoder *drm_encoder);
 
 /**
- * sde_encoders_init - query platform, create all encoders and bridges,
- *	and register them with the drm_device
- * @dev:	drm device pointer
+ * sde_encoder_init - initialize virtual encoder object
+ * @dev:        Pointer to drm device structure
+ * @disp_info:  Pointer to display information structure
+ * Returns:     Pointer to newly created drm encoder
  */
-void sde_encoders_init(struct drm_device *dev);
+struct drm_encoder *sde_encoder_init(
+		struct drm_device *dev,
+		struct msm_display_info *disp_info);
+
+/**
+ * sde_encoder_destroy - destroy previously initialized virtual encoder
+ * @drm_enc:    Pointer to previously created drm encoder structure
+ */
+void sde_encoder_destroy(struct drm_encoder *drm_enc);
 
 #endif /* __sde_kms_H__ */
diff --git a/drivers/gpu/drm/msm/sde/sde_wb.c b/drivers/gpu/drm/msm/sde/sde_wb.c
index 1778721..647cb58 100644
--- a/drivers/gpu/drm/msm/sde/sde_wb.c
+++ b/drivers/gpu/drm/msm/sde/sde_wb.c
@@ -487,7 +487,11 @@
 	return rc;
 }
 
-int sde_wb_dev_init(struct sde_wb_device *wb_dev)
+/**
+ * _sde_wb_dev_init - perform device initialization
+ * @wb_dev:	Pointer to writeback device
+ */
+static int _sde_wb_dev_init(struct sde_wb_device *wb_dev)
 {
 	int rc = 0;
 
@@ -501,7 +505,11 @@
 	return rc;
 }
 
-int sde_wb_dev_deinit(struct sde_wb_device *wb_dev)
+/**
+ * _sde_wb_dev_deinit - perform device de-initialization
+ * @wb_dev:	Pointer to writeback device
+ */
+static int _sde_wb_dev_deinit(struct sde_wb_device *wb_dev)
 {
 	int rc = 0;
 
@@ -515,31 +523,57 @@
 	return rc;
 }
 
-int sde_wb_bind(struct sde_wb_device *wb_dev, struct drm_device *drm_dev)
+/**
+ * sde_wb_bind - bind writeback device with controlling device
+ * @dev:        Pointer to base of platform device
+ * @master:     Pointer to container of drm device
+ * @data:       Pointer to private data
+ * Returns:     Zero on success
+ */
+static int sde_wb_bind(struct device *dev, struct device *master, void *data)
 {
-	int rc = 0;
+	struct sde_wb_device *wb_dev;
 
-	if (!wb_dev || !drm_dev) {
+	if (!dev || !master) {
 		SDE_ERROR("invalid params\n");
 		return -EINVAL;
 	}
 
+	wb_dev = platform_get_drvdata(to_platform_device(dev));
+	if (!wb_dev) {
+		SDE_ERROR("invalid wb device\n");
+		return -EINVAL;
+	}
+
 	SDE_DEBUG("\n");
 
 	mutex_lock(&wb_dev->wb_lock);
-	wb_dev->drm_dev = drm_dev;
+	wb_dev->drm_dev = dev_get_drvdata(master);
 	mutex_unlock(&wb_dev->wb_lock);
 
-	return rc;
+	return 0;
 }
 
-int sde_wb_unbind(struct sde_wb_device *wb_dev)
+/**
+ * sde_wb_unbind - unbind writeback from controlling device
+ * @dev:        Pointer to base of platform device
+ * @master:     Pointer to container of drm device
+ * @data:       Pointer to private data
+ */
+static void sde_wb_unbind(struct device *dev,
+		struct device *master, void *data)
 {
-	int rc = 0;
+	struct sde_wb_device *wb_dev;
 
-	if (!wb_dev) {
+	if (!dev) {
 		SDE_ERROR("invalid params\n");
-		return -EINVAL;
+		return;
+	}
+
+	wb_dev = platform_get_drvdata(to_platform_device(dev));
+	if (!wb_dev) {
+		SDE_ERROR("invalid wb device\n");
+		return;
 	}
 
 	SDE_DEBUG("\n");
@@ -547,15 +581,23 @@
 	mutex_lock(&wb_dev->wb_lock);
 	wb_dev->drm_dev = NULL;
 	mutex_unlock(&wb_dev->wb_lock);
-
-	return rc;
 }
 
+static const struct component_ops sde_wb_comp_ops = {
+	.bind = sde_wb_bind,
+	.unbind = sde_wb_unbind,
+};
+
+/**
+ * sde_wb_drm_init - perform DRM initialization
+ * @wb_dev:	Pointer to writeback device
+ * @encoder:	Pointer to associated encoder
+ */
 int sde_wb_drm_init(struct sde_wb_device *wb_dev, struct drm_encoder *encoder)
 {
 	int rc = 0;
 
-	if (!wb_dev || !encoder) {
+	if (!wb_dev || !wb_dev->drm_dev || !encoder) {
 		SDE_ERROR("invalid params\n");
 		return -EINVAL;
 	}
@@ -631,7 +673,13 @@
 	list_add(&wb_dev->wb_list, &sde_wb_list);
 	mutex_unlock(&sde_wb_list_lock);
 
-	return 0;
+	if (!_sde_wb_dev_init(wb_dev)) {
+		ret = component_add(&pdev->dev, &sde_wb_comp_ops);
+		if (ret)
+			pr_err("component add failed\n");
+	}
+
+	return ret;
 }
 
 /**
@@ -649,6 +697,8 @@
 
 	SDE_DEBUG("\n");
 
+	(void)_sde_wb_dev_deinit(wb_dev);
+
 	mutex_lock(&sde_wb_list_lock);
 	list_for_each_entry_safe(curr, next, &sde_wb_list, wb_list) {
 		if (curr == wb_dev) {
@@ -681,12 +731,15 @@
 	},
 };
 
-void sde_wb_register(void)
+static int __init sde_wb_register(void)
 {
-	platform_driver_register(&sde_wb_driver);
+	return platform_driver_register(&sde_wb_driver);
 }
 
-void sde_wb_unregister(void)
+static void __exit sde_wb_unregister(void)
 {
 	platform_driver_unregister(&sde_wb_driver);
 }
+
+module_init(sde_wb_register);
+module_exit(sde_wb_unregister);
diff --git a/drivers/gpu/drm/msm/sde/sde_wb.h b/drivers/gpu/drm/msm/sde/sde_wb.h
index 7905620..a2afc16 100644
--- a/drivers/gpu/drm/msm/sde/sde_wb.h
+++ b/drivers/gpu/drm/msm/sde/sde_wb.h
@@ -93,35 +93,8 @@
  */
 int wb_display_get_displays(void **display_array, u32 max_display_count);
 
-/**
- * wb_display_get_displays - returns pointers for supported display devices
- * @display_array: Pointer to display array to be filled
- * @max_display_count: Size of display_array
- * @Returns: Number of display entries filled
- */
-int sde_wb_dev_init(struct sde_wb_device *wb_dev);
-
-/**
- * sde_wb_dev_deinit - perform device de-initialization
- * @wb_dev:	Pointer to writeback device
- * Returns:	0 if success; error code otherwise
- */
-int sde_wb_dev_deinit(struct sde_wb_device *wb_dev);
-
-/**
- * sde_wb_bind - bind writeback device with controlling device
- * @wb_dev:	Pointer to writeback device
- * @drm_dev:	Pointer to controlling DRM device
- * Returns:	0 if success; error code otherwise
- */
-int sde_wb_bind(struct sde_wb_device *wb_dev, struct drm_device *drm_dev);
-
-/**
- * sde_wb_unbind - unbind writeback from controlling device
- * @wb_dev:	Pointer to writeback device
- * Returns:	0 if success; error code otherwise
- */
-int sde_wb_unbind(struct sde_wb_device *wb_dev);
+void sde_wb_set_active_state(struct sde_wb_device *wb_dev, bool is_active);
+bool sde_wb_is_active(struct sde_wb_device *wb_dev);
 
 /**
  * sde_wb_drm_init - perform DRM initialization
@@ -139,16 +112,6 @@
 int sde_wb_drm_deinit(struct sde_wb_device *wb_dev);
 
 /**
- * sde_wb_register - register writeback module
- */
-void sde_wb_register(void);
-
-/**
- * sde_wb_unregister - unregister writeback module
- */
-void sde_wb_unregister(void);
-
-/**
  * sde_wb_config - setup connection status and available drm modes of the
  *			given writeback connector
  * @drm_dev:	Pointer to DRM device
@@ -274,24 +237,13 @@
 	return 0;
 }
 static inline
-int sde_wb_dev_init(struct sde_wb_device *wb_dev)
+void sde_wb_set_active_state(struct sde_wb_device *wb_dev, bool is_active)
 {
-	return 0;
 }
 static inline
-int sde_wb_dev_deinit(struct sde_wb_device *wb_dev)
+bool sde_wb_is_active(struct sde_wb_device *wb_dev)
 {
-	return 0;
-}
-static inline
-int sde_wb_bind(struct sde_wb_device *wb_dev, struct drm_device *drm_dev)
-{
-	return 0;
-}
-static inline
-int sde_wb_unbind(struct sde_wb_device *wb_dev)
-{
-	return 0;
+	return false;
 }
 static inline
 int sde_wb_drm_init(struct sde_wb_device *wb_dev, struct drm_encoder *encoder)
@@ -304,14 +256,6 @@
 	return 0;
 }
 static inline
-void sde_wb_register(void)
-{
-}
-static inline
-void sde_wb_unregister(void)
-{
-}
-static inline
 int sde_wb_config(struct drm_device *drm_dev, void *data,
 				struct drm_file *file_priv)
 {