drm: msm: dsi-staging: add support for DSI controller v2.0.0

Add a separate DSI controller h/w driver to support DSI
controller v2.0.0. This includes reorganizing the DSI controller
programming sequence which is common between DSI v1.4.0 and
DSI v2.0.0 to a common DSI h/w driver file.

CRs-Fixed: 2008002
Change-Id: I6e2821b6874924c8fbaca888f940e8ad34ee90ec
Signed-off-by: Padmanabhan Komanduru <pkomandu@codeaurora.org>
Signed-off-by: Shashank Babu Chinta Venkata <sbchin@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c
index 07503f5..83daed1 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.c
@@ -18,56 +18,74 @@
 #include "dsi_catalog.h"
 
 /**
- * dsi_catalog_14_init() - catalog init for dsi controller v1.4
+ * dsi_catalog_cmn_init() - catalog init for dsi controller v1.4
  */
-static void dsi_catalog_14_init(struct dsi_ctrl_hw *ctrl)
+static void dsi_catalog_cmn_init(struct dsi_ctrl_hw *ctrl,
+		enum dsi_ctrl_version version)
 {
-	ctrl->ops.host_setup             = dsi_ctrl_hw_14_host_setup;
-	ctrl->ops.setup_lane_map         = dsi_ctrl_hw_14_setup_lane_map;
-	ctrl->ops.video_engine_en        = dsi_ctrl_hw_14_video_engine_en;
-	ctrl->ops.video_engine_setup     = dsi_ctrl_hw_14_video_engine_setup;
-	ctrl->ops.set_video_timing       = dsi_ctrl_hw_14_set_video_timing;
-	ctrl->ops.cmd_engine_setup       = dsi_ctrl_hw_14_cmd_engine_setup;
-	ctrl->ops.setup_cmd_stream       = dsi_ctrl_hw_14_setup_cmd_stream;
-	ctrl->ops.ctrl_en                = dsi_ctrl_hw_14_ctrl_en;
-	ctrl->ops.cmd_engine_en          = dsi_ctrl_hw_14_cmd_engine_en;
-	ctrl->ops.phy_sw_reset           = dsi_ctrl_hw_14_phy_sw_reset;
-	ctrl->ops.soft_reset             = dsi_ctrl_hw_14_soft_reset;
-	ctrl->ops.kickoff_command        = dsi_ctrl_hw_14_kickoff_command;
-	ctrl->ops.kickoff_fifo_command   = dsi_ctrl_hw_14_kickoff_fifo_command;
-	ctrl->ops.reset_cmd_fifo         = dsi_ctrl_hw_14_reset_cmd_fifo;
-	ctrl->ops.trigger_command_dma    = dsi_ctrl_hw_14_trigger_command_dma;
-	ctrl->ops.ulps_ops.ulps_request           = dsi_ctrl_hw_14_ulps_request;
-	ctrl->ops.ulps_ops.ulps_exit     = dsi_ctrl_hw_14_ulps_exit;
-	ctrl->ops.ulps_ops.wait_for_lane_idle = dsi_ctrl_hw_wait_for_lane_idle;
-	ctrl->ops.ulps_ops.get_lanes_in_ulps = dsi_ctrl_hw_14_get_lanes_in_ulps;
-	ctrl->ops.clamp_enable           = dsi_ctrl_hw_14_clamp_enable;
-	ctrl->ops.clamp_disable          = dsi_ctrl_hw_14_clamp_disable;
-	ctrl->ops.get_interrupt_status   = dsi_ctrl_hw_14_get_interrupt_status;
-	ctrl->ops.get_error_status       = dsi_ctrl_hw_14_get_error_status;
-	ctrl->ops.clear_error_status     = dsi_ctrl_hw_14_clear_error_status;
+	/* common functions */
+	ctrl->ops.host_setup             = dsi_ctrl_hw_cmn_host_setup;
+	ctrl->ops.video_engine_en        = dsi_ctrl_hw_cmn_video_engine_en;
+	ctrl->ops.video_engine_setup     = dsi_ctrl_hw_cmn_video_engine_setup;
+	ctrl->ops.set_video_timing       = dsi_ctrl_hw_cmn_set_video_timing;
+	ctrl->ops.cmd_engine_setup       = dsi_ctrl_hw_cmn_cmd_engine_setup;
+	ctrl->ops.setup_cmd_stream       = dsi_ctrl_hw_cmn_setup_cmd_stream;
+	ctrl->ops.ctrl_en                = dsi_ctrl_hw_cmn_ctrl_en;
+	ctrl->ops.cmd_engine_en          = dsi_ctrl_hw_cmn_cmd_engine_en;
+	ctrl->ops.phy_sw_reset           = dsi_ctrl_hw_cmn_phy_sw_reset;
+	ctrl->ops.soft_reset             = dsi_ctrl_hw_cmn_soft_reset;
+	ctrl->ops.kickoff_command        = dsi_ctrl_hw_cmn_kickoff_command;
+	ctrl->ops.kickoff_fifo_command   = dsi_ctrl_hw_cmn_kickoff_fifo_command;
+	ctrl->ops.reset_cmd_fifo         = dsi_ctrl_hw_cmn_reset_cmd_fifo;
+	ctrl->ops.trigger_command_dma    = dsi_ctrl_hw_cmn_trigger_command_dma;
+	ctrl->ops.get_interrupt_status   = dsi_ctrl_hw_cmn_get_interrupt_status;
+	ctrl->ops.get_error_status       = dsi_ctrl_hw_cmn_get_error_status;
+	ctrl->ops.clear_error_status     = dsi_ctrl_hw_cmn_clear_error_status;
 	ctrl->ops.clear_interrupt_status =
-		dsi_ctrl_hw_14_clear_interrupt_status;
+		dsi_ctrl_hw_cmn_clear_interrupt_status;
 	ctrl->ops.enable_status_interrupts =
-		dsi_ctrl_hw_14_enable_status_interrupts;
+		dsi_ctrl_hw_cmn_enable_status_interrupts;
 	ctrl->ops.enable_error_interrupts =
-		dsi_ctrl_hw_14_enable_error_interrupts;
+		dsi_ctrl_hw_cmn_enable_error_interrupts;
 	ctrl->ops.video_test_pattern_setup =
-		dsi_ctrl_hw_14_video_test_pattern_setup;
+		dsi_ctrl_hw_cmn_video_test_pattern_setup;
 	ctrl->ops.cmd_test_pattern_setup =
-		dsi_ctrl_hw_14_cmd_test_pattern_setup;
-	ctrl->ops.test_pattern_enable    = dsi_ctrl_hw_14_test_pattern_enable;
+		dsi_ctrl_hw_cmn_cmd_test_pattern_setup;
+	ctrl->ops.test_pattern_enable    = dsi_ctrl_hw_cmn_test_pattern_enable;
 	ctrl->ops.trigger_cmd_test_pattern =
-		dsi_ctrl_hw_14_trigger_cmd_test_pattern;
-	ctrl->ops.reg_dump_to_buffer    = dsi_ctrl_hw_14_reg_dump_to_buffer;
-}
+		dsi_ctrl_hw_cmn_trigger_cmd_test_pattern;
+	ctrl->ops.clear_phy0_ln_err = dsi_ctrl_hw_dln0_phy_err;
+	ctrl->ops.phy_reset_config = dsi_ctrl_hw_cmn_phy_reset_config;
 
-/**
- * dsi_catalog_20_init() - catalog init for dsi controller v2.0
- */
-static void dsi_catalog_20_init(struct dsi_ctrl_hw *ctrl)
-{
-	set_bit(DSI_CTRL_CPHY, ctrl->feature_map);
+	switch (version) {
+	case DSI_CTRL_VERSION_1_4:
+		ctrl->ops.setup_lane_map = dsi_ctrl_hw_14_setup_lane_map;
+		ctrl->ops.ulps_ops.ulps_request = dsi_ctrl_hw_14_ulps_request;
+		ctrl->ops.ulps_ops.ulps_exit = dsi_ctrl_hw_14_ulps_exit;
+		ctrl->ops.wait_for_lane_idle =
+			dsi_ctrl_hw_14_wait_for_lane_idle;
+		ctrl->ops.ulps_ops.get_lanes_in_ulps =
+			dsi_ctrl_hw_14_get_lanes_in_ulps;
+		ctrl->ops.clamp_enable = dsi_ctrl_hw_14_clamp_enable;
+		ctrl->ops.clamp_disable = dsi_ctrl_hw_14_clamp_disable;
+		ctrl->ops.reg_dump_to_buffer =
+			dsi_ctrl_hw_14_reg_dump_to_buffer;
+		break;
+	case DSI_CTRL_VERSION_2_0:
+		ctrl->ops.setup_lane_map = dsi_ctrl_hw_20_setup_lane_map;
+		ctrl->ops.wait_for_lane_idle =
+			dsi_ctrl_hw_20_wait_for_lane_idle;
+		ctrl->ops.reg_dump_to_buffer =
+			dsi_ctrl_hw_20_reg_dump_to_buffer;
+		ctrl->ops.ulps_ops.ulps_request = NULL;
+		ctrl->ops.ulps_ops.ulps_exit = NULL;
+		ctrl->ops.ulps_ops.get_lanes_in_ulps = NULL;
+		ctrl->ops.clamp_enable = NULL;
+		ctrl->ops.clamp_disable = NULL;
+		break;
+	default:
+		break;
+	}
 }
 
 /**
@@ -102,10 +120,8 @@
 
 	switch (version) {
 	case DSI_CTRL_VERSION_1_4:
-		dsi_catalog_14_init(ctrl);
-		break;
 	case DSI_CTRL_VERSION_2_0:
-		dsi_catalog_20_init(ctrl);
+		dsi_catalog_cmn_init(ctrl, version);
 		break;
 	default:
 		return -ENOTSUPP;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h
index 03bf905..b4625d5 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_catalog.h
@@ -60,43 +60,69 @@
 void dsi_phy_hw_v4_0_idle_on(struct dsi_phy_hw *phy, struct dsi_phy_cfg *cfg);
 void dsi_phy_hw_v4_0_idle_off(struct dsi_phy_hw *phy);
 
-/* Definitions for 1.4 controller hardware driver */
-void dsi_ctrl_hw_14_host_setup(struct dsi_ctrl_hw *ctrl,
+/* DSI controller common ops */
+u32 dsi_ctrl_hw_cmn_get_interrupt_status(struct dsi_ctrl_hw *ctrl);
+void dsi_ctrl_hw_cmn_clear_interrupt_status(struct dsi_ctrl_hw *ctrl, u32 ints);
+void dsi_ctrl_hw_cmn_enable_status_interrupts(struct dsi_ctrl_hw *ctrl,
+					     u32 ints);
+
+u64 dsi_ctrl_hw_cmn_get_error_status(struct dsi_ctrl_hw *ctrl);
+void dsi_ctrl_hw_cmn_clear_error_status(struct dsi_ctrl_hw *ctrl, u64 errors);
+void dsi_ctrl_hw_cmn_enable_error_interrupts(struct dsi_ctrl_hw *ctrl,
+					    u64 errors);
+
+void dsi_ctrl_hw_cmn_video_test_pattern_setup(struct dsi_ctrl_hw *ctrl,
+				 enum dsi_test_pattern type,
+				 u32 init_val);
+void dsi_ctrl_hw_cmn_cmd_test_pattern_setup(struct dsi_ctrl_hw *ctrl,
+			       enum dsi_test_pattern  type,
+			       u32 init_val,
+			       u32 stream_id);
+void dsi_ctrl_hw_cmn_test_pattern_enable(struct dsi_ctrl_hw *ctrl, bool enable);
+void dsi_ctrl_hw_cmn_trigger_cmd_test_pattern(struct dsi_ctrl_hw *ctrl,
+				 u32 stream_id);
+
+void dsi_ctrl_hw_cmn_host_setup(struct dsi_ctrl_hw *ctrl,
 			       struct dsi_host_common_cfg *config);
-void dsi_ctrl_hw_14_video_engine_en(struct dsi_ctrl_hw *ctrl, bool on);
-void dsi_ctrl_hw_14_video_engine_setup(struct dsi_ctrl_hw *ctrl,
+void dsi_ctrl_hw_cmn_video_engine_en(struct dsi_ctrl_hw *ctrl, bool on);
+void dsi_ctrl_hw_cmn_video_engine_setup(struct dsi_ctrl_hw *ctrl,
 				       struct dsi_host_common_cfg *common_cfg,
 				       struct dsi_video_engine_cfg *cfg);
-void dsi_ctrl_hw_14_set_video_timing(struct dsi_ctrl_hw *ctrl,
+void dsi_ctrl_hw_cmn_set_video_timing(struct dsi_ctrl_hw *ctrl,
 			 struct dsi_mode_info *mode);
 
-void dsi_ctrl_hw_14_cmd_engine_setup(struct dsi_ctrl_hw *ctrl,
+void dsi_ctrl_hw_cmn_cmd_engine_setup(struct dsi_ctrl_hw *ctrl,
 				     struct dsi_host_common_cfg *common_cfg,
 				     struct dsi_cmd_engine_cfg *cfg);
 
-void dsi_ctrl_hw_14_ctrl_en(struct dsi_ctrl_hw *ctrl, bool on);
-void dsi_ctrl_hw_14_cmd_engine_en(struct dsi_ctrl_hw *ctrl, bool on);
+void dsi_ctrl_hw_cmn_ctrl_en(struct dsi_ctrl_hw *ctrl, bool on);
+void dsi_ctrl_hw_cmn_cmd_engine_en(struct dsi_ctrl_hw *ctrl, bool on);
 
-void dsi_ctrl_hw_14_setup_cmd_stream(struct dsi_ctrl_hw *ctrl,
+void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl,
 				     u32 width_in_pixels,
 				     u32 h_stride,
 				     u32 height_in_lines,
 				     u32 vc_id);
-void dsi_ctrl_hw_14_phy_sw_reset(struct dsi_ctrl_hw *ctrl);
-void dsi_ctrl_hw_14_soft_reset(struct dsi_ctrl_hw *ctrl);
+void dsi_ctrl_hw_cmn_phy_sw_reset(struct dsi_ctrl_hw *ctrl);
+void dsi_ctrl_hw_cmn_soft_reset(struct dsi_ctrl_hw *ctrl);
 
-void dsi_ctrl_hw_14_setup_lane_map(struct dsi_ctrl_hw *ctrl,
-		       struct dsi_lane_mapping *lane_map);
-void dsi_ctrl_hw_14_kickoff_command(struct dsi_ctrl_hw *ctrl,
+void dsi_ctrl_hw_cmn_kickoff_command(struct dsi_ctrl_hw *ctrl,
 			struct dsi_ctrl_cmd_dma_info *cmd,
 			u32 flags);
 
-void dsi_ctrl_hw_14_kickoff_fifo_command(struct dsi_ctrl_hw *ctrl,
+void dsi_ctrl_hw_cmn_kickoff_fifo_command(struct dsi_ctrl_hw *ctrl,
 			     struct dsi_ctrl_cmd_dma_fifo_info *cmd,
 			     u32 flags);
-void dsi_ctrl_hw_14_reset_cmd_fifo(struct dsi_ctrl_hw *ctrl);
-void dsi_ctrl_hw_14_trigger_command_dma(struct dsi_ctrl_hw *ctrl);
-int dsi_ctrl_hw_wait_for_lane_idle(struct dsi_ctrl_hw *ctrl, u32 lanes);
+void dsi_ctrl_hw_cmn_reset_cmd_fifo(struct dsi_ctrl_hw *ctrl);
+void dsi_ctrl_hw_cmn_trigger_command_dma(struct dsi_ctrl_hw *ctrl);
+void dsi_ctrl_hw_dln0_phy_err(struct dsi_ctrl_hw *ctrl);
+void dsi_ctrl_hw_cmn_phy_reset_config(struct dsi_ctrl_hw *ctrl,
+			bool enable);
+
+/* Definitions specific to 1.4 DSI controller hardware */
+int dsi_ctrl_hw_14_wait_for_lane_idle(struct dsi_ctrl_hw *ctrl, u32 lanes);
+void dsi_ctrl_hw_14_setup_lane_map(struct dsi_ctrl_hw *ctrl,
+		       struct dsi_lane_map *lane_map);
 void dsi_ctrl_hw_14_ulps_request(struct dsi_ctrl_hw *ctrl, u32 lanes);
 void dsi_ctrl_hw_14_ulps_exit(struct dsi_ctrl_hw *ctrl, u32 lanes);
 u32 dsi_ctrl_hw_14_get_lanes_in_ulps(struct dsi_ctrl_hw *ctrl);
@@ -108,27 +134,16 @@
 void dsi_ctrl_hw_14_clamp_disable(struct dsi_ctrl_hw *ctrl,
 				  u32 lanes,
 				  bool disable_ulps);
-u32 dsi_ctrl_hw_14_get_interrupt_status(struct dsi_ctrl_hw *ctrl);
-void dsi_ctrl_hw_14_clear_interrupt_status(struct dsi_ctrl_hw *ctrl, u32 ints);
-void dsi_ctrl_hw_14_enable_status_interrupts(struct dsi_ctrl_hw *ctrl,
-					     u32 ints);
-
-u64 dsi_ctrl_hw_14_get_error_status(struct dsi_ctrl_hw *ctrl);
-void dsi_ctrl_hw_14_clear_error_status(struct dsi_ctrl_hw *ctrl, u64 errors);
-void dsi_ctrl_hw_14_enable_error_interrupts(struct dsi_ctrl_hw *ctrl,
-					    u64 errors);
-
-void dsi_ctrl_hw_14_video_test_pattern_setup(struct dsi_ctrl_hw *ctrl,
-				 enum dsi_test_pattern type,
-				 u32 init_val);
-void dsi_ctrl_hw_14_cmd_test_pattern_setup(struct dsi_ctrl_hw *ctrl,
-			       enum dsi_test_pattern  type,
-			       u32 init_val,
-			       u32 stream_id);
-void dsi_ctrl_hw_14_test_pattern_enable(struct dsi_ctrl_hw *ctrl, bool enable);
-void dsi_ctrl_hw_14_trigger_cmd_test_pattern(struct dsi_ctrl_hw *ctrl,
-				 u32 stream_id);
 ssize_t dsi_ctrl_hw_14_reg_dump_to_buffer(struct dsi_ctrl_hw *ctrl,
 					  char *buf,
 					  u32 size);
+
+/* Definitions specific to 2.0 DSI controller hardware */
+void dsi_ctrl_hw_20_setup_lane_map(struct dsi_ctrl_hw *ctrl,
+		       struct dsi_lane_map *lane_map);
+int dsi_ctrl_hw_20_wait_for_lane_idle(struct dsi_ctrl_hw *ctrl, u32 lanes);
+ssize_t dsi_ctrl_hw_20_reg_dump_to_buffer(struct dsi_ctrl_hw *ctrl,
+					  char *buf,
+					  u32 size);
+
 #endif /* _DSI_CATALOG_H_ */
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index 3e0e9f6..10e91ac 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -155,6 +155,7 @@
 		return rc;
 	}
 
+	if (dsi_ctrl->hw.ops.reg_dump_to_buffer)
 	len = dsi_ctrl->hw.ops.reg_dump_to_buffer(&dsi_ctrl->hw,
 		  buf, SZ_4K);
 
@@ -162,6 +163,7 @@
 	rc = dsi_ctrl->clk_cb.dsi_clk_cb(dsi_ctrl->clk_cb.priv, clk_info);
 	if (rc) {
 		pr_err("failed to disable DSI core clocks\n");
+		kfree(buf);
 		return rc;
 	}
 
@@ -1007,12 +1009,18 @@
 	if (dsi_ctrl->host_config.panel_mode == DSI_OP_CMD_MODE)
 		lanes = dsi_ctrl->host_config.common_config.data_lanes;
 
-	rc = dsi_ctrl->hw.ops.ulps_ops.wait_for_lane_idle(&dsi_ctrl->hw, lanes);
+	rc = dsi_ctrl->hw.ops.wait_for_lane_idle(&dsi_ctrl->hw, lanes);
 	if (rc) {
 		pr_err("lanes not entering idle, skip ULPS\n");
 		return rc;
 	}
 
+	if (!dsi_ctrl->hw.ops.ulps_ops.ulps_request ||
+			!dsi_ctrl->hw.ops.ulps_ops.ulps_exit) {
+		pr_debug("DSI controller ULPS ops not present\n");
+		return 0;
+	}
+
 	lanes |= DSI_CLOCK_LANE;
 	dsi_ctrl->hw.ops.ulps_ops.ulps_request(&dsi_ctrl->hw, lanes);
 
@@ -1032,10 +1040,19 @@
 	int rc = 0;
 	u32 ulps_lanes, lanes = 0;
 
+	dsi_ctrl->hw.ops.clear_phy0_ln_err(&dsi_ctrl->hw);
+
+	if (!dsi_ctrl->hw.ops.ulps_ops.ulps_request ||
+			!dsi_ctrl->hw.ops.ulps_ops.ulps_exit) {
+		pr_debug("DSI controller ULPS ops not present\n");
+		return 0;
+	}
+
 	if (dsi_ctrl->host_config.panel_mode == DSI_OP_CMD_MODE)
 		lanes = dsi_ctrl->host_config.common_config.data_lanes;
 
 	lanes |= DSI_CLOCK_LANE;
+
 	ulps_lanes = dsi_ctrl->hw.ops.ulps_ops.get_lanes_in_ulps(&dsi_ctrl->hw);
 
 	if ((lanes & ulps_lanes) != lanes)
@@ -1565,6 +1582,26 @@
 	return rc;
 }
 
+/**
+ * dsi_ctrl_phy_reset_config() - Mask/unmask propagation of ahb reset signal
+ *	to DSI PHY hardware.
+ * @dsi_ctrl:        DSI controller handle.
+ * @enable:			Mask/unmask the PHY reset signal.
+ *
+ * Return: error code.
+ */
+int dsi_ctrl_phy_reset_config(struct dsi_ctrl *dsi_ctrl, bool enable)
+{
+	if (!dsi_ctrl) {
+		pr_err("Invalid params\n");
+		return -EINVAL;
+	}
+
+	if (dsi_ctrl->hw.ops.phy_reset_config)
+		dsi_ctrl->hw.ops.phy_reset_config(&dsi_ctrl->hw, enable);
+
+	return 0;
+}
 
 /**
  * dsi_ctrl_host_init() - Initialize DSI host hardware.
@@ -2089,12 +2126,6 @@
 		return -EINVAL;
 	}
 
-	if (!dsi_ctrl->hw.ops.ulps_ops.ulps_request ||
-			!dsi_ctrl->hw.ops.ulps_ops.ulps_exit) {
-		pr_debug("DSI controller ULPS ops not present\n");
-		return 0;
-	}
-
 	mutex_lock(&dsi_ctrl->ctrl_lock);
 
 	if (enable)
@@ -2133,6 +2164,12 @@
 		return -EINVAL;
 	}
 
+	if (!dsi_ctrl->hw.ops.clamp_enable ||
+			!dsi_ctrl->hw.ops.clamp_disable) {
+		pr_debug("No clamp control for DSI controller\n");
+		return 0;
+	}
+
 	mutex_lock(&dsi_ctrl->ctrl_lock);
 
 	rc = dsi_enable_io_clamp(dsi_ctrl, enable, ulps_enabled);
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
index 5b3e25c..1df09b4 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
@@ -319,6 +319,16 @@
 int dsi_ctrl_phy_sw_reset(struct dsi_ctrl *dsi_ctrl);
 
 /**
+ * dsi_ctrl_phy_reset_config() - Mask/unmask propagation of ahb reset signal
+ *	to DSI PHY hardware.
+ * @dsi_ctrl:        DSI controller handle.
+ * @enable:			Mask/unmask the PHY reset signal.
+ *
+ * Return: error code.
+ */
+int dsi_ctrl_phy_reset_config(struct dsi_ctrl *dsi_ctrl, bool enable);
+
+/**
  * dsi_ctrl_host_init() - Initialize DSI host hardware.
  * @dsi_ctrl:        DSI controller handle.
  *
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
index a25c780..009795a 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw.h
@@ -215,15 +215,7 @@
 
 struct dsi_ctrl_hw;
 
-struct ulps_config_ops {
-	/**
-	 * wait_for_lane_idle() - wait for DSI lanes to go to idle state
-	 * @ctrl:          Pointer to the controller host hardware.
-	 * @lanes:         ORed list of lanes (enum dsi_data_lanes) which need
-	 *                 to be checked to be in idle state.
-	 */
-	int (*wait_for_lane_idle)(struct dsi_ctrl_hw *ctrl, u32 lanes);
-
+struct ctrl_ulps_config_ops {
 	/**
 	 * ulps_request() - request ulps entry for specified lanes
 	 * @ctrl:          Pointer to the controller host hardware.
@@ -256,7 +248,6 @@
 	 * Return: List of lanes in ULPS state.
 	 */
 	u32 (*get_lanes_in_ulps)(struct dsi_ctrl_hw *ctrl);
-
 };
 
 /**
@@ -371,7 +362,7 @@
 	 *                 lanes and physical lanes.
 	 */
 	void (*setup_lane_map)(struct dsi_ctrl_hw *ctrl,
-			       struct dsi_lane_mapping *lane_map);
+			       struct dsi_lane_map *lane_map);
 
 	/**
 	 * kickoff_command() - transmits commands stored in memory
@@ -427,7 +418,22 @@
 				 u8 *rd_buf,
 				 u32 total_read_len);
 
-	struct ulps_config_ops ulps_ops;
+	/**
+	 * wait_for_lane_idle() - wait for DSI lanes to go to idle state
+	 * @ctrl:          Pointer to the controller host hardware.
+	 * @lanes:         ORed list of lanes (enum dsi_data_lanes) which need
+	 *                 to be checked to be in idle state.
+	 */
+	int (*wait_for_lane_idle)(struct dsi_ctrl_hw *ctrl, u32 lanes);
+
+	struct ctrl_ulps_config_ops ulps_ops;
+
+	/**
+	 * clamp_enable() - enable DSI clamps
+	 * @ctrl:         Pointer to the controller host hardware.
+	 * @lanes:        ORed list of lanes which need to have clamps released.
+	 * @enable_ulps: ulps state.
+	 */
 
 	/**
 	 * clamp_enable() - enable DSI clamps to keep PHY driving a stable link
@@ -443,13 +449,22 @@
 	 * clamp_disable() - disable DSI clamps
 	 * @ctrl:         Pointer to the controller host hardware.
 	 * @lanes:        ORed list of lanes which need to have clamps released.
-	 * @disable_ulps: TODO:??
+	 * @disable_ulps: ulps state.
 	 */
 	void (*clamp_disable)(struct dsi_ctrl_hw *ctrl,
 			      u32 lanes,
 			      bool disable_ulps);
 
 	/**
+	 * phy_reset_config() - Disable/enable propagation of  reset signal
+	 *	from ahb domain to DSI PHY
+	 * @ctrl:         Pointer to the controller host hardware.
+	 * @enable:	True to mask the reset signal, false to unmask
+	 */
+	void (*phy_reset_config)(struct dsi_ctrl_hw *ctrl,
+			     bool enable);
+
+	/**
 	 * get_interrupt_status() - returns the interrupt status
 	 * @ctrl:          Pointer to the controller host hardware.
 	 *
@@ -541,6 +556,12 @@
 	void (*test_pattern_enable)(struct dsi_ctrl_hw *ctrl, bool enable);
 
 	/**
+	 * clear_phy0_ln_err() - clear DSI PHY lane-0 errors
+	 * @ctrl:          Pointer to the controller host hardware.
+	 */
+	void (*clear_phy0_ln_err)(struct dsi_ctrl_hw *ctrl);
+
+	/**
 	 * trigger_cmd_test_pattern() - trigger a command mode frame update with
 	 *                              test pattern
 	 * @ctrl:          Pointer to the controller host hardware.
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_1_4.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_1_4.c
index e367db3..37473b8 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_1_4.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_1_4.c
@@ -17,585 +17,28 @@
 #include <linux/iopoll.h>
 
 #include "dsi_ctrl_hw.h"
-#include "dsi_ctrl_reg_1_4.h"
+#include "dsi_ctrl_reg.h"
 #include "dsi_hw.h"
 
 #define MMSS_MISC_CLAMP_REG_OFF           0x0014
 
-/* Unsupported formats default to RGB888 */
-static const u8 cmd_mode_format_map[DSI_PIXEL_FORMAT_MAX] = {
-	0x6, 0x7, 0x8, 0x8, 0x0, 0x3, 0x4 };
-static const u8 video_mode_format_map[DSI_PIXEL_FORMAT_MAX] = {
-	0x0, 0x1, 0x2, 0x3, 0x3, 0x3, 0x3 };
-
-
 /**
- * dsi_setup_trigger_controls() - setup dsi trigger configurations
- * @ctrl:             Pointer to the controller host hardware.
- * @cfg:              DSI host configuration that is common to both video and
- *                    command modes.
- */
-static void dsi_setup_trigger_controls(struct dsi_ctrl_hw *ctrl,
-				       struct dsi_host_common_cfg *cfg)
-{
-	u32 reg = 0;
-	const u8 trigger_map[DSI_TRIGGER_MAX] = {
-		0x0, 0x2, 0x1, 0x4, 0x5, 0x6 };
-
-	reg |= (cfg->te_mode == DSI_TE_ON_EXT_PIN) ? BIT(31) : 0;
-	reg |= (trigger_map[cfg->dma_cmd_trigger] & 0x7);
-	reg |= (trigger_map[cfg->mdp_cmd_trigger] & 0x7) << 4;
-	DSI_W32(ctrl, DSI_TRIG_CTRL, reg);
-}
-
-/**
- * dsi_ctrl_hw_14_host_setup() - setup dsi host configuration
- * @ctrl:             Pointer to the controller host hardware.
- * @cfg:              DSI host configuration that is common to both video and
- *                    command modes.
- */
-void dsi_ctrl_hw_14_host_setup(struct dsi_ctrl_hw *ctrl,
-			       struct dsi_host_common_cfg *cfg)
-{
-	u32 reg_value = 0;
-
-	dsi_setup_trigger_controls(ctrl, cfg);
-
-	/* Setup clocking timing controls */
-	reg_value = ((cfg->t_clk_post & 0x3F) << 8);
-	reg_value |= (cfg->t_clk_pre & 0x3F);
-	DSI_W32(ctrl, DSI_CLKOUT_TIMING_CTRL, reg_value);
-
-	/* EOT packet control */
-	reg_value = cfg->append_tx_eot ? 1 : 0;
-	reg_value |= (cfg->ignore_rx_eot ? (1 << 4) : 0);
-	DSI_W32(ctrl, DSI_EOT_PACKET_CTRL, reg_value);
-
-	/* Turn on dsi clocks */
-	DSI_W32(ctrl, DSI_CLK_CTRL, 0x23F);
-
-	/* Setup DSI control register */
-	reg_value = 0;
-	reg_value |= (cfg->en_crc_check ? BIT(24) : 0);
-	reg_value |= (cfg->en_ecc_check ? BIT(20) : 0);
-	reg_value |= BIT(8); /* Clock lane */
-	reg_value |= ((cfg->data_lanes & DSI_DATA_LANE_3) ? BIT(7) : 0);
-	reg_value |= ((cfg->data_lanes & DSI_DATA_LANE_2) ? BIT(6) : 0);
-	reg_value |= ((cfg->data_lanes & DSI_DATA_LANE_1) ? BIT(5) : 0);
-	reg_value |= ((cfg->data_lanes & DSI_DATA_LANE_0) ? BIT(4) : 0);
-
-	DSI_W32(ctrl, DSI_CTRL, reg_value);
-
-	pr_debug("[DSI_%d]Host configuration complete\n", ctrl->index);
-}
-
-/**
- * phy_sw_reset() - perform a soft reset on the PHY.
- * @ctrl:        Pointer to the controller host hardware.
- */
-void dsi_ctrl_hw_14_phy_sw_reset(struct dsi_ctrl_hw *ctrl)
-{
-	DSI_W32(ctrl, DSI_PHY_SW_RESET, 0x1);
-	udelay(1000);
-	DSI_W32(ctrl, DSI_PHY_SW_RESET, 0x0);
-	udelay(100);
-
-	pr_debug("[DSI_%d] phy sw reset done\n", ctrl->index);
-}
-
-/**
- * soft_reset() - perform a soft reset on DSI controller
- * @ctrl:          Pointer to the controller host hardware.
- *
- * The video, command and controller engines will be disable before the
- * reset is triggered. These engines will not be enabled after the reset
- * is complete. Caller must re-enable the engines.
- *
- * If the reset is done while MDP timing engine is turned on, the video
- * enigne should be re-enabled only during the vertical blanking time.
- */
-void dsi_ctrl_hw_14_soft_reset(struct dsi_ctrl_hw *ctrl)
-{
-	u32 reg = 0;
-	u32 reg_ctrl = 0;
-
-	/* Clear DSI_EN, VIDEO_MODE_EN, CMD_MODE_EN */
-	reg_ctrl = DSI_R32(ctrl, DSI_CTRL);
-	DSI_W32(ctrl, DSI_CTRL, reg_ctrl & ~0x7);
-
-	/* Force enable PCLK, BYTECLK, AHBM_HCLK */
-	reg = DSI_R32(ctrl, DSI_CLK_CTRL);
-	reg |= 0x23F;
-	DSI_W32(ctrl, DSI_CLK_CTRL, reg);
-
-	/* Trigger soft reset */
-	DSI_W32(ctrl, DSI_SOFT_RESET, 0x1);
-	udelay(1);
-	DSI_W32(ctrl, DSI_SOFT_RESET, 0x0);
-
-	/* Disable force clock on */
-	reg &= ~(BIT(20) | BIT(11));
-	DSI_W32(ctrl, DSI_CLK_CTRL, reg);
-
-	/* Re-enable DSI controller */
-	DSI_W32(ctrl, DSI_CTRL, reg_ctrl);
-	pr_debug("[DSI_%d] ctrl soft reset done\n", ctrl->index);
-}
-
-/**
- * set_video_timing() - set up the timing for video frame
- * @ctrl:          Pointer to controller host hardware.
- * @mode:          Video mode information.
- *
- * Set up the video timing parameters for the DSI video mode operation.
- */
-void dsi_ctrl_hw_14_set_video_timing(struct dsi_ctrl_hw *ctrl,
-				     struct dsi_mode_info *mode)
-{
-	u32 reg = 0;
-	u32 hs_start = 0;
-	u32 hs_end, active_h_start, active_h_end, h_total;
-	u32 vs_start = 0, vs_end = 0;
-	u32 vpos_start = 0, vpos_end, active_v_start, active_v_end, v_total;
-
-	hs_end = mode->h_sync_width;
-	active_h_start = mode->h_sync_width + mode->h_back_porch;
-	active_h_end = active_h_start + mode->h_active;
-	h_total = (mode->h_sync_width + mode->h_back_porch + mode->h_active +
-		   mode->h_front_porch) - 1;
-
-	vpos_end = mode->v_sync_width;
-	active_v_start = mode->v_sync_width + mode->v_back_porch;
-	active_v_end = active_v_start + mode->v_active;
-	v_total = (mode->v_sync_width + mode->v_back_porch + mode->v_active +
-		   mode->v_front_porch) - 1;
-
-	reg = ((active_h_end & 0xFFFF) << 16) | (active_h_start & 0xFFFF);
-	DSI_W32(ctrl, DSI_VIDEO_MODE_ACTIVE_H, reg);
-
-	reg = ((active_v_end & 0xFFFF) << 16) | (active_v_start & 0xFFFF);
-	DSI_W32(ctrl, DSI_VIDEO_MODE_ACTIVE_V, reg);
-
-	reg = ((v_total & 0xFFFF) << 16) | (h_total & 0xFFFF);
-	DSI_W32(ctrl, DSI_VIDEO_MODE_TOTAL, reg);
-
-	reg = ((hs_end & 0xFFFF) << 16) | (hs_start & 0xFFFF);
-	DSI_W32(ctrl, DSI_VIDEO_MODE_HSYNC, reg);
-
-	reg = ((vs_end & 0xFFFF) << 16) | (vs_start & 0xFFFF);
-	DSI_W32(ctrl, DSI_VIDEO_MODE_VSYNC, reg);
-
-	reg = ((vpos_end & 0xFFFF) << 16) | (vpos_start & 0xFFFF);
-	DSI_W32(ctrl, DSI_VIDEO_MODE_VSYNC_VPOS, reg);
-
-	/* TODO: HS TIMER value? */
-	DSI_W32(ctrl, DSI_HS_TIMER_CTRL, 0x3FD08);
-	DSI_W32(ctrl, DSI_MISR_VIDEO_CTRL, 0x10100);
-	DSI_W32(ctrl, DSI_DSI_TIMING_FLUSH, 0x1);
-	pr_debug("[DSI_%d] ctrl video parameters updated\n", ctrl->index);
-}
-
-/**
- * setup_cmd_stream() - set up parameters for command pixel streams
- * @ctrl:          Pointer to controller host hardware.
- * @width_in_pixels:   Width of the stream in pixels.
- * @h_stride:          Horizontal stride in bytes.
- * @height_inLines:    Number of lines in the stream.
- * @vc_id:             stream_id
- *
- * Setup parameters for command mode pixel stream size.
- */
-void dsi_ctrl_hw_14_setup_cmd_stream(struct dsi_ctrl_hw *ctrl,
-				     u32 width_in_pixels,
-				     u32 h_stride,
-				     u32 height_in_lines,
-				     u32 vc_id)
-{
-	u32 reg = 0;
-
-	reg = (h_stride + 1) << 16;
-	reg |= (vc_id & 0x3) << 8;
-	reg |= 0x39; /* packet data type */
-	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM0_CTRL, reg);
-	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM1_CTRL, reg);
-
-	reg = (height_in_lines << 16) | width_in_pixels;
-	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM0_TOTAL, reg);
-	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM1_TOTAL, reg);
-}
-
-/**
- * video_engine_setup() - Setup dsi host controller for video mode
- * @ctrl:          Pointer to controller host hardware.
- * @common_cfg:    Common configuration parameters.
- * @cfg:           Video mode configuration.
- *
- * Set up DSI video engine with a specific configuration. Controller and
- * video engine are not enabled as part of this function.
- */
-void dsi_ctrl_hw_14_video_engine_setup(struct dsi_ctrl_hw *ctrl,
-				       struct dsi_host_common_cfg *common_cfg,
-				       struct dsi_video_engine_cfg *cfg)
-{
-	u32 reg = 0;
-
-	reg |= (cfg->last_line_interleave_en ? BIT(31) : 0);
-	reg |= (cfg->pulse_mode_hsa_he ? BIT(28) : 0);
-	reg |= (cfg->hfp_lp11_en ? BIT(24) : 0);
-	reg |= (cfg->hbp_lp11_en ? BIT(20) : 0);
-	reg |= (cfg->hsa_lp11_en ? BIT(16) : 0);
-	reg |= (cfg->eof_bllp_lp11_en ? BIT(15) : 0);
-	reg |= (cfg->bllp_lp11_en ? BIT(12) : 0);
-	reg |= (cfg->traffic_mode & 0x3) << 8;
-	reg |= (cfg->vc_id & 0x3);
-	reg |= (video_mode_format_map[common_cfg->dst_format] & 0x3) << 4;
-	DSI_W32(ctrl, DSI_VIDEO_MODE_CTRL, reg);
-
-	reg = (common_cfg->swap_mode & 0x7) << 12;
-	reg |= (common_cfg->bit_swap_red ? BIT(0) : 0);
-	reg |= (common_cfg->bit_swap_green ? BIT(4) : 0);
-	reg |= (common_cfg->bit_swap_blue ? BIT(8) : 0);
-	DSI_W32(ctrl, DSI_VIDEO_MODE_DATA_CTRL, reg);
-	/* Enable Timing double buffering */
-	DSI_W32(ctrl, DSI_DSI_TIMING_DB_MODE, 0x1);
-
-
-	pr_debug("[DSI_%d] Video engine setup done\n", ctrl->index);
-}
-
-/**
- * cmd_engine_setup() - setup dsi host controller for command mode
- * @ctrl:          Pointer to the controller host hardware.
- * @common_cfg:    Common configuration parameters.
- * @cfg:           Command mode configuration.
- *
- * Setup DSI CMD engine with a specific configuration. Controller and
- * command engine are not enabled as part of this function.
- */
-void dsi_ctrl_hw_14_cmd_engine_setup(struct dsi_ctrl_hw *ctrl,
-				     struct dsi_host_common_cfg *common_cfg,
-				     struct dsi_cmd_engine_cfg *cfg)
-{
-	u32 reg = 0;
-
-	reg = (cfg->max_cmd_packets_interleave & 0xF) << 20;
-	reg |= (common_cfg->bit_swap_red ? BIT(4) : 0);
-	reg |= (common_cfg->bit_swap_green ? BIT(8) : 0);
-	reg |= (common_cfg->bit_swap_blue ? BIT(12) : 0);
-	reg |= cmd_mode_format_map[common_cfg->dst_format];
-	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_CTRL, reg);
-
-	reg = DSI_R32(ctrl, DSI_COMMAND_MODE_MDP_CTRL2);
-	reg |= BIT(16);
-	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_CTRL2, reg);
-
-	reg = cfg->wr_mem_start & 0xFF;
-	reg |= (cfg->wr_mem_continue & 0xFF) << 8;
-	reg |= (cfg->insert_dcs_command ? BIT(16) : 0);
-	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_DCS_CMD_CTRL, reg);
-
-	pr_debug("[DSI_%d] Cmd engine setup done\n", ctrl->index);
-}
-
-/**
- * video_engine_en() - enable DSI video engine
- * @ctrl:          Pointer to controller host hardware.
- * @on:            Enable/disabel video engine.
- */
-void dsi_ctrl_hw_14_video_engine_en(struct dsi_ctrl_hw *ctrl, bool on)
-{
-	u32 reg = 0;
-
-	/* Set/Clear VIDEO_MODE_EN bit */
-	reg = DSI_R32(ctrl, DSI_CTRL);
-	if (on)
-		reg |= BIT(1);
-	else
-		reg &= ~BIT(1);
-
-	DSI_W32(ctrl, DSI_CTRL, reg);
-
-	pr_debug("[DSI_%d] Video engine = %d\n", ctrl->index, on);
-}
-
-/**
- * ctrl_en() - enable DSI controller engine
- * @ctrl:          Pointer to the controller host hardware.
- * @on:            turn on/off the DSI controller engine.
- */
-void dsi_ctrl_hw_14_ctrl_en(struct dsi_ctrl_hw *ctrl, bool on)
-{
-	u32 reg = 0;
-
-	/* Set/Clear DSI_EN bit */
-	reg = DSI_R32(ctrl, DSI_CTRL);
-	if (on)
-		reg |= BIT(0);
-	else
-		reg &= ~BIT(0);
-
-	DSI_W32(ctrl, DSI_CTRL, reg);
-
-	pr_debug("[DSI_%d] Controller engine = %d\n", ctrl->index, on);
-}
-
-/**
- * cmd_engine_en() - enable DSI controller command engine
- * @ctrl:          Pointer to the controller host hardware.
- * @on:            Turn on/off the DSI command engine.
- */
-void dsi_ctrl_hw_14_cmd_engine_en(struct dsi_ctrl_hw *ctrl, bool on)
-{
-	u32 reg = 0;
-
-	/* Set/Clear CMD_MODE_EN bit */
-	reg = DSI_R32(ctrl, DSI_CTRL);
-	if (on)
-		reg |= BIT(2);
-	else
-		reg &= ~BIT(2);
-
-	DSI_W32(ctrl, DSI_CTRL, reg);
-
-	pr_debug("[DSI_%d] command engine = %d\n", ctrl->index, on);
-}
-
-/**
- * setup_lane_map() - setup mapping between logical and physical lanes
+ * dsi_ctrl_hw_14_setup_lane_map() - setup mapping between
+ *	logical and physical lanes
  * @ctrl:          Pointer to the controller host hardware.
  * @lane_map:      Structure defining the mapping between DSI logical
  *                 lanes and physical lanes.
  */
 void dsi_ctrl_hw_14_setup_lane_map(struct dsi_ctrl_hw *ctrl,
-			       struct dsi_lane_mapping *lane_map)
+			       struct dsi_lane_map *lane_map)
 {
-	u32 reg_value = 0;
-	u32 lane_number = ((lane_map->physical_lane0 * 1000)+
-			   (lane_map->physical_lane1 * 100) +
-			   (lane_map->physical_lane2 * 10) +
-			   (lane_map->physical_lane3));
-
-	if (lane_number == 123)
-		reg_value = 0;
-	else if (lane_number == 3012)
-		reg_value = 1;
-	else if (lane_number == 2301)
-		reg_value = 2;
-	else if (lane_number == 1230)
-		reg_value = 3;
-	else if (lane_number == 321)
-		reg_value = 4;
-	else if (lane_number == 1032)
-		reg_value = 5;
-	else if (lane_number == 2103)
-		reg_value = 6;
-	else if (lane_number == 3210)
-		reg_value = 7;
-
-	DSI_W32(ctrl, DSI_LANE_SWAP_CTRL, reg_value);
+	DSI_W32(ctrl, DSI_LANE_SWAP_CTRL, lane_map->lane_map_v1);
 
 	pr_debug("[DSI_%d] Lane swap setup complete\n", ctrl->index);
 }
 
 /**
- * kickoff_command() - transmits commands stored in memory
- * @ctrl:          Pointer to the controller host hardware.
- * @cmd:           Command information.
- * @flags:         Modifiers for command transmission.
- *
- * The controller hardware is programmed with address and size of the
- * command buffer. The transmission is kicked off if
- * DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER flag is not set. If this flag is
- * set, caller should make a separate call to trigger_command_dma() to
- * transmit the command.
- */
-void dsi_ctrl_hw_14_kickoff_command(struct dsi_ctrl_hw *ctrl,
-				    struct dsi_ctrl_cmd_dma_info *cmd,
-				    u32 flags)
-{
-	u32 reg = 0;
-
-	/*Set BROADCAST_EN and EMBEDDED_MODE */
-	reg = DSI_R32(ctrl, DSI_COMMAND_MODE_DMA_CTRL);
-	if (cmd->en_broadcast)
-		reg |= BIT(31);
-	else
-		reg &= ~BIT(31);
-
-	if (cmd->is_master)
-		reg |= BIT(30);
-	else
-		reg &= ~BIT(30);
-
-	if (cmd->use_lpm)
-		reg |= BIT(26);
-	else
-		reg &= ~BIT(26);
-
-	reg |= BIT(28);
-	DSI_W32(ctrl, DSI_COMMAND_MODE_DMA_CTRL, reg);
-
-	DSI_W32(ctrl, DSI_DMA_CMD_OFFSET, cmd->offset);
-	DSI_W32(ctrl, DSI_DMA_CMD_LENGTH, (cmd->length & 0xFFFFFF));
-
-	/* wait for writes to complete before kick off */
-	wmb();
-
-	if (!(flags & DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER))
-		DSI_W32(ctrl, DSI_CMD_MODE_DMA_SW_TRIGGER, 0x1);
-}
-
-/**
- * kickoff_fifo_command() - transmits a command using FIFO in dsi
- *                          hardware.
- * @ctrl:          Pointer to the controller host hardware.
- * @cmd:           Command information.
- * @flags:         Modifiers for command transmission.
- *
- * The controller hardware FIFO is programmed with command header and
- * payload. The transmission is kicked off if
- * DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER flag is not set. If this flag is
- * set, caller should make a separate call to trigger_command_dma() to
- * transmit the command.
- */
-void dsi_ctrl_hw_14_kickoff_fifo_command(struct dsi_ctrl_hw *ctrl,
-					 struct dsi_ctrl_cmd_dma_fifo_info *cmd,
-					 u32 flags)
-{
-	u32 reg = 0, i = 0;
-	u32 *ptr = cmd->command;
-	/*
-	 * Set CMD_DMA_TPG_EN, TPG_DMA_FIFO_MODE and
-	 * CMD_DMA_PATTERN_SEL = custom pattern stored in TPG DMA FIFO
-	 */
-	reg = (BIT(1) | BIT(2) | (0x3 << 16));
-	DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CTRL, reg);
-
-	/*
-	 * Program the FIFO with command buffer. Hardware requires an extra
-	 * DWORD (set to zero) if the length of command buffer is odd DWORDS.
-	 */
-	for (i = 0; i < cmd->size; i += 4) {
-		DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CMD_DMA_INIT_VAL, *ptr);
-		ptr++;
-	}
-
-	if ((cmd->size / 4) & 0x1)
-		DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CMD_DMA_INIT_VAL, 0);
-
-	/*Set BROADCAST_EN and EMBEDDED_MODE */
-	reg = DSI_R32(ctrl, DSI_COMMAND_MODE_DMA_CTRL);
-	if (cmd->en_broadcast)
-		reg |= BIT(31);
-	else
-		reg &= ~BIT(31);
-
-	if (cmd->is_master)
-		reg |= BIT(30);
-	else
-		reg &= ~BIT(30);
-
-	if (cmd->use_lpm)
-		reg |= BIT(26);
-	else
-		reg &= ~BIT(26);
-
-	reg |= BIT(28);
-
-	DSI_W32(ctrl, DSI_COMMAND_MODE_DMA_CTRL, reg);
-
-	DSI_W32(ctrl, DSI_DMA_CMD_LENGTH, (cmd->size & 0xFFFFFFFF));
-	/* Finish writes before command trigger */
-	wmb();
-
-	if (!(flags & DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER))
-		DSI_W32(ctrl, DSI_CMD_MODE_DMA_SW_TRIGGER, 0x1);
-
-	pr_debug("[DSI_%d]size=%d, trigger = %d\n",
-		 ctrl->index, cmd->size,
-		 (flags & DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER) ? false : true);
-}
-
-void dsi_ctrl_hw_14_reset_cmd_fifo(struct dsi_ctrl_hw *ctrl)
-{
-	/* disable cmd dma tpg */
-	DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CTRL, 0x0);
-
-	DSI_W32(ctrl, DSI_TPG_DMA_FIFO_RESET, 0x1);
-	udelay(1);
-	DSI_W32(ctrl, DSI_TPG_DMA_FIFO_RESET, 0x0);
-}
-
-/**
- * trigger_command_dma() - trigger transmission of command buffer.
- * @ctrl:          Pointer to the controller host hardware.
- *
- * This trigger can be only used if there was a prior call to
- * kickoff_command() of kickoff_fifo_command() with
- * DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER flag.
- */
-void dsi_ctrl_hw_14_trigger_command_dma(struct dsi_ctrl_hw *ctrl)
-{
-	DSI_W32(ctrl, DSI_CMD_MODE_DMA_SW_TRIGGER, 0x1);
-	pr_debug("[DSI_%d] CMD DMA triggered\n", ctrl->index);
-}
-
-/**
- * get_cmd_read_data() - get data read from the peripheral
- * @ctrl:           Pointer to the controller host hardware.
- * @rd_buf:         Buffer where data will be read into.
- * @total_read_len: Number of bytes to read.
- *
- * return: number of bytes read.
- */
-u32 dsi_ctrl_hw_14_get_cmd_read_data(struct dsi_ctrl_hw *ctrl,
-				     u8 *rd_buf,
-				     u32 read_offset,
-				     u32 total_read_len)
-{
-	u32 *lp, *temp, data;
-	int i, j = 0, cnt;
-	u32 read_cnt;
-	u32 rx_byte = 0;
-	u32 repeated_bytes = 0;
-	u8 reg[16];
-	u32 pkt_size = 0;
-	int buf_offset = read_offset;
-
-	lp = (u32 *)rd_buf;
-	temp = (u32 *)reg;
-	cnt = (rx_byte + 3) >> 2;
-
-	if (cnt > 4)
-		cnt = 4;
-
-	if (rx_byte == 4)
-		read_cnt = 4;
-	else
-		read_cnt = pkt_size + 6;
-
-	if (read_cnt > 16) {
-		int bytes_shifted;
-
-		bytes_shifted = read_cnt - 16;
-		repeated_bytes = buf_offset - bytes_shifted;
-	}
-
-	for (i = cnt - 1; i >= 0; i--) {
-		data = DSI_R32(ctrl, DSI_RDBK_DATA0 + i*4);
-		*temp++ = ntohl(data);
-	}
-
-	for (i = repeated_bytes; i < 16; i++)
-		rd_buf[j++] = reg[i];
-
-	pr_debug("[DSI_%d] Read %d bytes\n", ctrl->index, j);
-	return j;
-}
-
-
-/**
- * dsi_ctrl_hw_wait_for_lane_idle()
+ * dsi_ctrl_hw_14_wait_for_lane_idle()
  * This function waits for all the active DSI lanes to be idle by polling all
  * the FIFO_EMPTY bits and polling he lane status to ensure that all the lanes
  * are in stop state. This function assumes that the bus clocks required to
@@ -607,7 +50,7 @@
  *
  * return: Error code.
  */
-int dsi_ctrl_hw_wait_for_lane_idle(struct dsi_ctrl_hw *ctrl, u32 lanes)
+int dsi_ctrl_hw_14_wait_for_lane_idle(struct dsi_ctrl_hw *ctrl, u32 lanes)
 {
 	int rc = 0, val = 0;
 	u32 stop_state_mask = 0, fifo_empty_mask = 0;
@@ -691,17 +134,6 @@
 		 lanes);
 }
 
-static void dsi_ctrl_hw_dln0_phy_err(struct dsi_ctrl_hw *ctrl)
-{
-	u32 status = 0;
-
-	status = DSI_R32(ctrl, DSI_DLN0_PHY_ERR);
-	if (status & 0x011111) {
-		DSI_W32(ctrl, DSI_DLN0_PHY_ERR, status);
-		pr_err("%s: phy_err_status = %x\n", __func__, status);
-	}
-}
-
 /**
  * ulps_exit() - exit ULPS on specified lanes
  * @ctrl:          Pointer to the controller host hardware.
@@ -715,13 +147,6 @@
 {
 	u32 reg = 0;
 
-	/*
-	 * Clear out any phy errors prior to exiting ULPS
-	 * This fixes certain instances where phy does not exit
-	 * ULPS cleanly. Also, do not print error during such cases.
-	 */
-	dsi_ctrl_hw_dln0_phy_err(ctrl);
-
 	if (lanes & DSI_CLOCK_LANE)
 		reg = BIT(12);
 	if (lanes & DSI_DATA_LANE_0)
@@ -837,10 +262,6 @@
 	reg |= (BIT(15) << bit_shift);	/* Enable clamp */
 	DSI_MMSS_MISC_W32(ctrl, MMSS_MISC_CLAMP_REG_OFF, reg);
 
-	reg = DSI_MMSS_MISC_R32(ctrl, MMSS_MISC_CLAMP_REG_OFF);
-	reg |= BIT(30); /* Disable PHY reset */
-	DSI_MMSS_MISC_W32(ctrl, MMSS_MISC_CLAMP_REG_OFF, reg);
-
 	pr_debug("[DSI_%d] Clamps enabled for lanes=0x%x\n", ctrl->index,
 		 lanes);
 }
@@ -895,11 +316,6 @@
 	clamp_reg |= BIT(15); /* Enable clamp */
 	clamp_reg <<= bit_shift;
 
-	/* Clear disable PHY reset bit */
-	reg = DSI_MMSS_MISC_R32(ctrl, MMSS_MISC_CLAMP_REG_OFF);
-	reg &= ~BIT(30);
-	DSI_MMSS_MISC_W32(ctrl, MMSS_MISC_CLAMP_REG_OFF, reg);
-
 	reg = DSI_MMSS_MISC_R32(ctrl, MMSS_MISC_CLAMP_REG_OFF);
 	reg &= ~(clamp_reg);
 	DSI_MMSS_MISC_W32(ctrl, MMSS_MISC_CLAMP_REG_OFF, reg);
@@ -907,521 +323,6 @@
 	pr_debug("[DSI_%d] Disable clamps for lanes=%d\n", ctrl->index, lanes);
 }
 
-/**
- * get_interrupt_status() - returns the interrupt status
- * @ctrl:          Pointer to the controller host hardware.
- *
- * Returns the ORed list of interrupts(enum dsi_status_int_type) that
- * are active. This list does not include any error interrupts. Caller
- * should call get_error_status for error interrupts.
- *
- * Return: List of active interrupts.
- */
-u32 dsi_ctrl_hw_14_get_interrupt_status(struct dsi_ctrl_hw *ctrl)
-{
-	u32 reg = 0;
-	u32 ints = 0;
-
-	reg = DSI_R32(ctrl, DSI_INT_CTRL);
-
-	if (reg & BIT(0))
-		ints |= DSI_CMD_MODE_DMA_DONE;
-	if (reg & BIT(8))
-		ints |= DSI_CMD_FRAME_DONE;
-	if (reg & BIT(10))
-		ints |= DSI_CMD_STREAM0_FRAME_DONE;
-	if (reg & BIT(12))
-		ints |= DSI_CMD_STREAM1_FRAME_DONE;
-	if (reg & BIT(14))
-		ints |= DSI_CMD_STREAM2_FRAME_DONE;
-	if (reg & BIT(16))
-		ints |= DSI_VIDEO_MODE_FRAME_DONE;
-	if (reg & BIT(20))
-		ints |= DSI_BTA_DONE;
-	if (reg & BIT(28))
-		ints |= DSI_DYN_REFRESH_DONE;
-	if (reg & BIT(30))
-		ints |= DSI_DESKEW_DONE;
-
-	pr_debug("[DSI_%d] Interrupt status = 0x%x, INT_CTRL=0x%x\n",
-		 ctrl->index, ints, reg);
-	return ints;
-}
-
-/**
- * clear_interrupt_status() - clears the specified interrupts
- * @ctrl:          Pointer to the controller host hardware.
- * @ints:          List of interrupts to be cleared.
- */
-void dsi_ctrl_hw_14_clear_interrupt_status(struct dsi_ctrl_hw *ctrl, u32 ints)
-{
-	u32 reg = 0;
-
-	if (ints & DSI_CMD_MODE_DMA_DONE)
-		reg |= BIT(0);
-	if (ints & DSI_CMD_FRAME_DONE)
-		reg |= BIT(8);
-	if (ints & DSI_CMD_STREAM0_FRAME_DONE)
-		reg |= BIT(10);
-	if (ints & DSI_CMD_STREAM1_FRAME_DONE)
-		reg |= BIT(12);
-	if (ints & DSI_CMD_STREAM2_FRAME_DONE)
-		reg |= BIT(14);
-	if (ints & DSI_VIDEO_MODE_FRAME_DONE)
-		reg |= BIT(16);
-	if (ints & DSI_BTA_DONE)
-		reg |= BIT(20);
-	if (ints & DSI_DYN_REFRESH_DONE)
-		reg |= BIT(28);
-	if (ints & DSI_DESKEW_DONE)
-		reg |= BIT(30);
-
-	DSI_W32(ctrl, DSI_INT_CTRL, reg);
-
-	pr_debug("[DSI_%d] Clear interrupts, ints = 0x%x, INT_CTRL=0x%x\n",
-		 ctrl->index, ints, reg);
-}
-
-/**
- * enable_status_interrupts() - enable the specified interrupts
- * @ctrl:          Pointer to the controller host hardware.
- * @ints:          List of interrupts to be enabled.
- *
- * Enables the specified interrupts. This list will override the
- * previous interrupts enabled through this function. Caller has to
- * maintain the state of the interrupts enabled. To disable all
- * interrupts, set ints to 0.
- */
-void dsi_ctrl_hw_14_enable_status_interrupts(struct dsi_ctrl_hw *ctrl, u32 ints)
-{
-	u32 reg = 0;
-
-	/* Do not change value of DSI_ERROR_MASK bit */
-	reg |= (DSI_R32(ctrl, DSI_INT_CTRL) & BIT(25));
-	if (ints & DSI_CMD_MODE_DMA_DONE)
-		reg |= BIT(1);
-	if (ints & DSI_CMD_FRAME_DONE)
-		reg |= BIT(9);
-	if (ints & DSI_CMD_STREAM0_FRAME_DONE)
-		reg |= BIT(11);
-	if (ints & DSI_CMD_STREAM1_FRAME_DONE)
-		reg |= BIT(13);
-	if (ints & DSI_CMD_STREAM2_FRAME_DONE)
-		reg |= BIT(15);
-	if (ints & DSI_VIDEO_MODE_FRAME_DONE)
-		reg |= BIT(17);
-	if (ints & DSI_BTA_DONE)
-		reg |= BIT(21);
-	if (ints & DSI_DYN_REFRESH_DONE)
-		reg |= BIT(29);
-	if (ints & DSI_DESKEW_DONE)
-		reg |= BIT(31);
-
-	DSI_W32(ctrl, DSI_INT_CTRL, reg);
-
-	pr_debug("[DSI_%d] Enable interrupts 0x%x, INT_CTRL=0x%x\n",
-		 ctrl->index, ints, reg);
-}
-
-/**
- * get_error_status() - returns the error status
- * @ctrl:          Pointer to the controller host hardware.
- *
- * Returns the ORed list of errors(enum dsi_error_int_type) that are
- * active. This list does not include any status interrupts. Caller
- * should call get_interrupt_status for status interrupts.
- *
- * Return: List of active error interrupts.
- */
-u64 dsi_ctrl_hw_14_get_error_status(struct dsi_ctrl_hw *ctrl)
-{
-	u32 dln0_phy_err;
-	u32 fifo_status;
-	u32 ack_error;
-	u32 timeout_errors;
-	u32 clk_error;
-	u32 dsi_status;
-	u64 errors = 0;
-
-	dln0_phy_err = DSI_R32(ctrl, DSI_DLN0_PHY_ERR);
-	if (dln0_phy_err & BIT(0))
-		errors |= DSI_DLN0_ESC_ENTRY_ERR;
-	if (dln0_phy_err & BIT(4))
-		errors |= DSI_DLN0_ESC_SYNC_ERR;
-	if (dln0_phy_err & BIT(8))
-		errors |= DSI_DLN0_LP_CONTROL_ERR;
-	if (dln0_phy_err & BIT(12))
-		errors |= DSI_DLN0_LP0_CONTENTION;
-	if (dln0_phy_err & BIT(16))
-		errors |= DSI_DLN0_LP1_CONTENTION;
-
-	fifo_status = DSI_R32(ctrl, DSI_FIFO_STATUS);
-	if (fifo_status & BIT(7))
-		errors |= DSI_CMD_MDP_FIFO_UNDERFLOW;
-	if (fifo_status & BIT(10))
-		errors |= DSI_CMD_DMA_FIFO_UNDERFLOW;
-	if (fifo_status & BIT(18))
-		errors |= DSI_DLN0_HS_FIFO_OVERFLOW;
-	if (fifo_status & BIT(19))
-		errors |= DSI_DLN0_HS_FIFO_UNDERFLOW;
-	if (fifo_status & BIT(22))
-		errors |= DSI_DLN1_HS_FIFO_OVERFLOW;
-	if (fifo_status & BIT(23))
-		errors |= DSI_DLN1_HS_FIFO_UNDERFLOW;
-	if (fifo_status & BIT(26))
-		errors |= DSI_DLN2_HS_FIFO_OVERFLOW;
-	if (fifo_status & BIT(27))
-		errors |= DSI_DLN2_HS_FIFO_UNDERFLOW;
-	if (fifo_status & BIT(30))
-		errors |= DSI_DLN3_HS_FIFO_OVERFLOW;
-	if (fifo_status & BIT(31))
-		errors |= DSI_DLN3_HS_FIFO_UNDERFLOW;
-
-	ack_error = DSI_R32(ctrl, DSI_ACK_ERR_STATUS);
-	if (ack_error & BIT(16))
-		errors |= DSI_RDBK_SINGLE_ECC_ERR;
-	if (ack_error & BIT(17))
-		errors |= DSI_RDBK_MULTI_ECC_ERR;
-	if (ack_error & BIT(20))
-		errors |= DSI_RDBK_CRC_ERR;
-	if (ack_error & BIT(23))
-		errors |= DSI_RDBK_INCOMPLETE_PKT;
-	if (ack_error & BIT(24))
-		errors |= DSI_PERIPH_ERROR_PKT;
-
-	timeout_errors = DSI_R32(ctrl, DSI_TIMEOUT_STATUS);
-	if (timeout_errors & BIT(0))
-		errors |= DSI_HS_TX_TIMEOUT;
-	if (timeout_errors & BIT(4))
-		errors |= DSI_LP_RX_TIMEOUT;
-	if (timeout_errors & BIT(8))
-		errors |= DSI_BTA_TIMEOUT;
-
-	clk_error = DSI_R32(ctrl, DSI_CLK_STATUS);
-	if (clk_error & BIT(16))
-		errors |= DSI_PLL_UNLOCK;
-
-	dsi_status = DSI_R32(ctrl, DSI_STATUS);
-	if (dsi_status & BIT(31))
-		errors |= DSI_INTERLEAVE_OP_CONTENTION;
-
-	pr_debug("[DSI_%d] Error status = 0x%llx, phy=0x%x, fifo=0x%x",
-		 ctrl->index, errors, dln0_phy_err, fifo_status);
-	pr_debug("[DSI_%d] ack=0x%x, timeout=0x%x, clk=0x%x, dsi=0x%x\n",
-		 ctrl->index, ack_error, timeout_errors, clk_error, dsi_status);
-	return errors;
-}
-
-/**
- * clear_error_status() - clears the specified errors
- * @ctrl:          Pointer to the controller host hardware.
- * @errors:          List of errors to be cleared.
- */
-void dsi_ctrl_hw_14_clear_error_status(struct dsi_ctrl_hw *ctrl, u64 errors)
-{
-	u32 dln0_phy_err = 0;
-	u32 fifo_status = 0;
-	u32 ack_error = 0;
-	u32 timeout_error = 0;
-	u32 clk_error = 0;
-	u32 dsi_status = 0;
-	u32 int_ctrl = 0;
-
-	if (errors & DSI_RDBK_SINGLE_ECC_ERR)
-		ack_error |= BIT(16);
-	if (errors & DSI_RDBK_MULTI_ECC_ERR)
-		ack_error |= BIT(17);
-	if (errors & DSI_RDBK_CRC_ERR)
-		ack_error |= BIT(20);
-	if (errors & DSI_RDBK_INCOMPLETE_PKT)
-		ack_error |= BIT(23);
-	if (errors & DSI_PERIPH_ERROR_PKT)
-		ack_error |= BIT(24);
-
-	if (errors & DSI_LP_RX_TIMEOUT)
-		timeout_error |= BIT(4);
-	if (errors & DSI_HS_TX_TIMEOUT)
-		timeout_error |= BIT(0);
-	if (errors & DSI_BTA_TIMEOUT)
-		timeout_error |= BIT(8);
-
-	if (errors & DSI_PLL_UNLOCK)
-		clk_error |= BIT(16);
-
-	if (errors & DSI_DLN0_LP0_CONTENTION)
-		dln0_phy_err |= BIT(12);
-	if (errors & DSI_DLN0_LP1_CONTENTION)
-		dln0_phy_err |= BIT(16);
-	if (errors & DSI_DLN0_ESC_ENTRY_ERR)
-		dln0_phy_err |= BIT(0);
-	if (errors & DSI_DLN0_ESC_SYNC_ERR)
-		dln0_phy_err |= BIT(4);
-	if (errors & DSI_DLN0_LP_CONTROL_ERR)
-		dln0_phy_err |= BIT(8);
-
-	if (errors & DSI_CMD_DMA_FIFO_UNDERFLOW)
-		fifo_status |= BIT(10);
-	if (errors & DSI_CMD_MDP_FIFO_UNDERFLOW)
-		fifo_status |= BIT(7);
-	if (errors & DSI_DLN0_HS_FIFO_OVERFLOW)
-		fifo_status |= BIT(18);
-	if (errors & DSI_DLN1_HS_FIFO_OVERFLOW)
-		fifo_status |= BIT(22);
-	if (errors & DSI_DLN2_HS_FIFO_OVERFLOW)
-		fifo_status |= BIT(26);
-	if (errors & DSI_DLN3_HS_FIFO_OVERFLOW)
-		fifo_status |= BIT(30);
-	if (errors & DSI_DLN0_HS_FIFO_UNDERFLOW)
-		fifo_status |= BIT(19);
-	if (errors & DSI_DLN1_HS_FIFO_UNDERFLOW)
-		fifo_status |= BIT(23);
-	if (errors & DSI_DLN2_HS_FIFO_UNDERFLOW)
-		fifo_status |= BIT(27);
-	if (errors & DSI_DLN3_HS_FIFO_UNDERFLOW)
-		fifo_status |= BIT(31);
-
-	if (errors & DSI_INTERLEAVE_OP_CONTENTION)
-		dsi_status |= BIT(31);
-
-	DSI_W32(ctrl, DSI_DLN0_PHY_ERR, dln0_phy_err);
-	DSI_W32(ctrl, DSI_FIFO_STATUS, fifo_status);
-	DSI_W32(ctrl, DSI_ACK_ERR_STATUS, ack_error);
-	DSI_W32(ctrl, DSI_TIMEOUT_STATUS, timeout_error);
-	DSI_W32(ctrl, DSI_CLK_STATUS, clk_error);
-	DSI_W32(ctrl, DSI_STATUS, dsi_status);
-
-	int_ctrl = DSI_R32(ctrl, DSI_INT_CTRL);
-	int_ctrl |= BIT(24);
-	DSI_W32(ctrl, DSI_INT_CTRL, int_ctrl);
-	pr_debug("[DSI_%d] clear errors = 0x%llx, phy=0x%x, fifo=0x%x",
-		 ctrl->index, errors, dln0_phy_err, fifo_status);
-	pr_debug("[DSI_%d] ack=0x%x, timeout=0x%x, clk=0x%x, dsi=0x%x\n",
-		 ctrl->index, ack_error, timeout_error, clk_error, dsi_status);
-}
-
-/**
- * enable_error_interrupts() - enable the specified interrupts
- * @ctrl:          Pointer to the controller host hardware.
- * @errors:        List of errors to be enabled.
- *
- * Enables the specified interrupts. This list will override the
- * previous interrupts enabled through this function. Caller has to
- * maintain the state of the interrupts enabled. To disable all
- * interrupts, set errors to 0.
- */
-void dsi_ctrl_hw_14_enable_error_interrupts(struct dsi_ctrl_hw *ctrl,
-					    u64 errors)
-{
-	u32 int_ctrl = 0;
-	u32 int_mask0 = 0x7FFF3BFF;
-
-	int_ctrl = DSI_R32(ctrl, DSI_INT_CTRL);
-	if (errors)
-		int_ctrl |= BIT(25);
-	else
-		int_ctrl &= ~BIT(25);
-
-	if (errors & DSI_RDBK_SINGLE_ECC_ERR)
-		int_mask0 &= ~BIT(0);
-	if (errors & DSI_RDBK_MULTI_ECC_ERR)
-		int_mask0 &= ~BIT(1);
-	if (errors & DSI_RDBK_CRC_ERR)
-		int_mask0 &= ~BIT(2);
-	if (errors & DSI_RDBK_INCOMPLETE_PKT)
-		int_mask0 &= ~BIT(3);
-	if (errors & DSI_PERIPH_ERROR_PKT)
-		int_mask0 &= ~BIT(4);
-
-	if (errors & DSI_LP_RX_TIMEOUT)
-		int_mask0 &= ~BIT(5);
-	if (errors & DSI_HS_TX_TIMEOUT)
-		int_mask0 &= ~BIT(6);
-	if (errors & DSI_BTA_TIMEOUT)
-		int_mask0 &= ~BIT(7);
-
-	if (errors & DSI_PLL_UNLOCK)
-		int_mask0 &= ~BIT(28);
-
-	if (errors & DSI_DLN0_LP0_CONTENTION)
-		int_mask0 &= ~BIT(24);
-	if (errors & DSI_DLN0_LP1_CONTENTION)
-		int_mask0 &= ~BIT(25);
-	if (errors & DSI_DLN0_ESC_ENTRY_ERR)
-		int_mask0 &= ~BIT(21);
-	if (errors & DSI_DLN0_ESC_SYNC_ERR)
-		int_mask0 &= ~BIT(22);
-	if (errors & DSI_DLN0_LP_CONTROL_ERR)
-		int_mask0 &= ~BIT(23);
-
-	if (errors & DSI_CMD_DMA_FIFO_UNDERFLOW)
-		int_mask0 &= ~BIT(9);
-	if (errors & DSI_CMD_MDP_FIFO_UNDERFLOW)
-		int_mask0 &= ~BIT(11);
-	if (errors & DSI_DLN0_HS_FIFO_OVERFLOW)
-		int_mask0 &= ~BIT(16);
-	if (errors & DSI_DLN1_HS_FIFO_OVERFLOW)
-		int_mask0 &= ~BIT(17);
-	if (errors & DSI_DLN2_HS_FIFO_OVERFLOW)
-		int_mask0 &= ~BIT(18);
-	if (errors & DSI_DLN3_HS_FIFO_OVERFLOW)
-		int_mask0 &= ~BIT(19);
-	if (errors & DSI_DLN0_HS_FIFO_UNDERFLOW)
-		int_mask0 &= ~BIT(26);
-	if (errors & DSI_DLN1_HS_FIFO_UNDERFLOW)
-		int_mask0 &= ~BIT(27);
-	if (errors & DSI_DLN2_HS_FIFO_UNDERFLOW)
-		int_mask0 &= ~BIT(29);
-	if (errors & DSI_DLN3_HS_FIFO_UNDERFLOW)
-		int_mask0 &= ~BIT(30);
-
-	if (errors & DSI_INTERLEAVE_OP_CONTENTION)
-		int_mask0 &= ~BIT(8);
-
-	DSI_W32(ctrl, DSI_INT_CTRL, int_ctrl);
-	DSI_W32(ctrl, DSI_ERR_INT_MASK0, int_mask0);
-
-	pr_debug("[DSI_%d] enable errors = 0x%llx, int_mask0=0x%x\n",
-		 ctrl->index, errors, int_mask0);
-}
-
-/**
- * video_test_pattern_setup() - setup test pattern engine for video mode
- * @ctrl:          Pointer to the controller host hardware.
- * @type:          Type of test pattern.
- * @init_val:      Initial value to use for generating test pattern.
- */
-void dsi_ctrl_hw_14_video_test_pattern_setup(struct dsi_ctrl_hw *ctrl,
-					     enum dsi_test_pattern type,
-					     u32 init_val)
-{
-	u32 reg = 0;
-
-	DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_VIDEO_INIT_VAL, init_val);
-
-	switch (type) {
-	case DSI_TEST_PATTERN_FIXED:
-		reg |= (0x2 << 4);
-		break;
-	case DSI_TEST_PATTERN_INC:
-		reg |= (0x1 << 4);
-		break;
-	case DSI_TEST_PATTERN_POLY:
-		DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_VIDEO_POLY, 0xF0F0F);
-		break;
-	default:
-		break;
-	}
-
-	DSI_W32(ctrl, DSI_TPG_MAIN_CONTROL, 0x100);
-	DSI_W32(ctrl, DSI_TPG_VIDEO_CONFIG, 0x5);
-	DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CTRL, reg);
-
-	pr_debug("[DSI_%d] Video test pattern setup done\n", ctrl->index);
-}
-
-/**
- * cmd_test_pattern_setup() - setup test patttern engine for cmd mode
- * @ctrl:          Pointer to the controller host hardware.
- * @type:          Type of test pattern.
- * @init_val:      Initial value to use for generating test pattern.
- * @stream_id:     Stream Id on which packets are generated.
- */
-void dsi_ctrl_hw_14_cmd_test_pattern_setup(struct dsi_ctrl_hw *ctrl,
-					   enum dsi_test_pattern type,
-					   u32 init_val,
-					   u32 stream_id)
-{
-	u32 reg = 0;
-	u32 init_offset;
-	u32 poly_offset;
-	u32 pattern_sel_shift;
-
-	switch (stream_id) {
-	case 0:
-		init_offset = DSI_TEST_PATTERN_GEN_CMD_MDP_INIT_VAL0;
-		poly_offset = DSI_TEST_PATTERN_GEN_CMD_MDP_STREAM0_POLY;
-		pattern_sel_shift = 8;
-		break;
-	case 1:
-		init_offset = DSI_TEST_PATTERN_GEN_CMD_MDP_INIT_VAL1;
-		poly_offset = DSI_TEST_PATTERN_GEN_CMD_MDP_STREAM1_POLY;
-		pattern_sel_shift = 12;
-		break;
-	case 2:
-		init_offset = DSI_TEST_PATTERN_GEN_CMD_MDP_INIT_VAL2;
-		poly_offset = DSI_TEST_PATTERN_GEN_CMD_MDP_STREAM2_POLY;
-		pattern_sel_shift = 20;
-		break;
-	default:
-		return;
-	}
-
-	DSI_W32(ctrl, init_offset, init_val);
-
-	switch (type) {
-	case DSI_TEST_PATTERN_FIXED:
-		reg |= (0x2 << pattern_sel_shift);
-		break;
-	case DSI_TEST_PATTERN_INC:
-		reg |= (0x1 << pattern_sel_shift);
-		break;
-	case DSI_TEST_PATTERN_POLY:
-		DSI_W32(ctrl, poly_offset, 0xF0F0F);
-		break;
-	default:
-		break;
-	}
-
-	DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CTRL, reg);
-	pr_debug("[DSI_%d] Cmd test pattern setup done\n", ctrl->index);
-}
-
-/**
- * test_pattern_enable() - enable test pattern engine
- * @ctrl:          Pointer to the controller host hardware.
- * @enable:        Enable/Disable test pattern engine.
- */
-void dsi_ctrl_hw_14_test_pattern_enable(struct dsi_ctrl_hw *ctrl,
-					bool enable)
-{
-	u32 reg = DSI_R32(ctrl, DSI_TEST_PATTERN_GEN_CTRL);
-
-	if (enable)
-		reg |= BIT(0);
-	else
-		reg &= ~BIT(0);
-
-	DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CTRL, reg);
-
-	pr_debug("[DSI_%d] Test pattern enable=%d\n", ctrl->index, enable);
-}
-
-/**
- * trigger_cmd_test_pattern() - trigger a command mode frame update with
- *                              test pattern
- * @ctrl:          Pointer to the controller host hardware.
- * @stream_id:     Stream on which frame update is sent.
- */
-void dsi_ctrl_hw_14_trigger_cmd_test_pattern(struct dsi_ctrl_hw *ctrl,
-					     u32 stream_id)
-{
-	switch (stream_id) {
-	case 0:
-		DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CMD_STREAM0_TRIGGER, 0x1);
-		break;
-	case 1:
-		DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CMD_STREAM1_TRIGGER, 0x1);
-		break;
-	case 2:
-		DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CMD_STREAM2_TRIGGER, 0x1);
-		break;
-	default:
-		break;
-	}
-
-	pr_debug("[DSI_%d] Cmd Test pattern trigger\n", ctrl->index);
-}
-
 #define DUMP_REG_VALUE(off) "\t%-30s: 0x%08x\n", #off, DSI_R32(ctrl, off)
 ssize_t dsi_ctrl_hw_14_reg_dump_to_buffer(struct dsi_ctrl_hw *ctrl,
 					  char *buf,
@@ -1577,5 +478,3 @@
 	pr_err("LLENGTH = %d\n", len);
 	return len;
 }
-
-
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_0.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_0.c
new file mode 100644
index 0000000..c22849a
--- /dev/null
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_2_0.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2016-2017, 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) "dsi-hw:" fmt
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+
+#include "dsi_ctrl_hw.h"
+#include "dsi_ctrl_reg.h"
+#include "dsi_hw.h"
+
+void dsi_ctrl_hw_20_setup_lane_map(struct dsi_ctrl_hw *ctrl,
+		       struct dsi_lane_map *lane_map)
+{
+	u32 reg_value = lane_map->lane_map_v2[DSI_LOGICAL_LANE_0] |
+			(lane_map->lane_map_v2[DSI_LOGICAL_LANE_1] << 4) |
+			(lane_map->lane_map_v2[DSI_LOGICAL_LANE_2] << 8) |
+			(lane_map->lane_map_v2[DSI_LOGICAL_LANE_3] << 12);
+
+	DSI_W32(ctrl, DSI_LANE_SWAP_CTRL, reg_value);
+
+	pr_debug("[DSI_%d] Lane swap setup complete\n", ctrl->index);
+}
+
+int dsi_ctrl_hw_20_wait_for_lane_idle(struct dsi_ctrl_hw *ctrl,
+		u32 lanes)
+{
+	int rc = 0, val = 0;
+	u32 fifo_empty_mask = 0;
+	u32 const sleep_us = 10;
+	u32 const timeout_us = 100;
+
+	if (lanes & DSI_DATA_LANE_0)
+		fifo_empty_mask |= (BIT(12) | BIT(16));
+
+	if (lanes & DSI_DATA_LANE_1)
+		fifo_empty_mask |= BIT(20);
+
+	if (lanes & DSI_DATA_LANE_2)
+		fifo_empty_mask |= BIT(24);
+
+	if (lanes & DSI_DATA_LANE_3)
+		fifo_empty_mask |= BIT(28);
+
+	pr_debug("%s: polling for fifo empty, mask=0x%08x\n", __func__,
+		fifo_empty_mask);
+	rc = readl_poll_timeout(ctrl->base + DSI_FIFO_STATUS, val,
+			(val & fifo_empty_mask), sleep_us, timeout_us);
+	if (rc) {
+		pr_err("%s: fifo not empty, FIFO_STATUS=0x%08x\n",
+				__func__, val);
+		goto error;
+	}
+
+error:
+	return rc;
+}
+
+#define DUMP_REG_VALUE(off) "\t%-30s: 0x%08x\n", #off, DSI_R32(ctrl, off)
+ssize_t dsi_ctrl_hw_20_reg_dump_to_buffer(struct dsi_ctrl_hw *ctrl,
+					  char *buf,
+					  u32 size)
+{
+	u32 len = 0;
+
+	len += snprintf((buf + len), (size - len), "CONFIGURATION REGS:\n");
+
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_HW_VERSION));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_STATUS));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_FIFO_STATUS));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_VIDEO_MODE_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_VIDEO_MODE_SYNC_DATATYPE));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_VIDEO_MODE_PIXEL_DATATYPE));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_VIDEO_MODE_BLANKING_DATATYPE));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_VIDEO_MODE_DATA_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_VIDEO_MODE_ACTIVE_H));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_VIDEO_MODE_ACTIVE_V));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_VIDEO_MODE_TOTAL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_VIDEO_MODE_HSYNC));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_VIDEO_MODE_VSYNC));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_VIDEO_MODE_VSYNC_VPOS));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_COMMAND_MODE_DMA_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_COMMAND_MODE_MDP_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_COMMAND_MODE_MDP_DCS_CMD_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_DMA_CMD_OFFSET));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_DMA_CMD_LENGTH));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_DMA_FIFO_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_DMA_NULL_PACKET_DATA));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_COMMAND_MODE_MDP_STREAM0_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_COMMAND_MODE_MDP_STREAM0_TOTAL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_COMMAND_MODE_MDP_STREAM1_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_COMMAND_MODE_MDP_STREAM1_TOTAL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_ACK_ERR_STATUS));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_RDBK_DATA0));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_RDBK_DATA1));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_RDBK_DATA2));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_RDBK_DATA3));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_RDBK_DATATYPE0));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_RDBK_DATATYPE1));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_TRIG_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_EXT_MUX));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_EXT_MUX_TE_PULSE_DETECT_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_CMD_MODE_DMA_SW_TRIGGER));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_CMD_MODE_MDP_SW_TRIGGER));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_CMD_MODE_BTA_SW_TRIGGER));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_RESET_SW_TRIGGER));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_LANE_STATUS));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_LANE_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_LANE_SWAP_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_DLN0_PHY_ERR));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_LP_TIMER_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_HS_TIMER_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_TIMEOUT_STATUS));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_CLKOUT_TIMING_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_EOT_PACKET));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_EOT_PACKET_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_GENERIC_ESC_TX_TRIGGER));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_ERR_INT_MASK0));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_INT_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_SOFT_RESET));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_CLK_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_CLK_STATUS));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_PHY_SW_RESET));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_AXI2AHB_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_COMMAND_MODE_MDP_CTRL2));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_COMMAND_MODE_MDP_STREAM2_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_COMMAND_MODE_MDP_STREAM2_TOTAL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_VBIF_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_AES_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_RDBK_DATA_CTRL));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_TEST_PATTERN_GEN_CMD_DMA_INIT_VAL2));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_TPG_DMA_FIFO_STATUS));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_TPG_DMA_FIFO_WRITE_TRIGGER));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_DSI_TIMING_FLUSH));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_DSI_TIMING_DB_MODE));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_TPG_DMA_FIFO_RESET));
+	len += snprintf((buf + len), (size - len),
+			DUMP_REG_VALUE(DSI_VERSION));
+
+	pr_err("LLENGTH = %d\n", len);
+	return len;
+}
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
new file mode 100644
index 0000000..9a6fc77
--- /dev/null
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_hw_cmn.c
@@ -0,0 +1,1104 @@
+/*
+ * Copyright (c) 2015-2017, 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) "dsi-hw:" fmt
+#include <linux/delay.h>
+#include <linux/iopoll.h>
+
+#include "dsi_ctrl_hw.h"
+#include "dsi_ctrl_reg.h"
+#include "dsi_hw.h"
+
+#define MMSS_MISC_CLAMP_REG_OFF           0x0014
+
+/* Unsupported formats default to RGB888 */
+static const u8 cmd_mode_format_map[DSI_PIXEL_FORMAT_MAX] = {
+	0x6, 0x7, 0x8, 0x8, 0x0, 0x3, 0x4 };
+static const u8 video_mode_format_map[DSI_PIXEL_FORMAT_MAX] = {
+	0x0, 0x1, 0x2, 0x3, 0x3, 0x3, 0x3 };
+
+/**
+ * dsi_setup_trigger_controls() - setup dsi trigger configurations
+ * @ctrl:             Pointer to the controller host hardware.
+ * @cfg:              DSI host configuration that is common to both video and
+ *                    command modes.
+ */
+static void dsi_setup_trigger_controls(struct dsi_ctrl_hw *ctrl,
+				       struct dsi_host_common_cfg *cfg)
+{
+	u32 reg = 0;
+	const u8 trigger_map[DSI_TRIGGER_MAX] = {
+		0x0, 0x2, 0x1, 0x4, 0x5, 0x6 };
+
+	reg |= (cfg->te_mode == DSI_TE_ON_EXT_PIN) ? BIT(31) : 0;
+	reg |= (trigger_map[cfg->dma_cmd_trigger] & 0x7);
+	reg |= (trigger_map[cfg->mdp_cmd_trigger] & 0x7) << 4;
+	DSI_W32(ctrl, DSI_TRIG_CTRL, reg);
+}
+
+/**
+ * dsi_ctrl_hw_cmn_host_setup() - setup dsi host configuration
+ * @ctrl:             Pointer to the controller host hardware.
+ * @cfg:              DSI host configuration that is common to both video and
+ *                    command modes.
+ */
+void dsi_ctrl_hw_cmn_host_setup(struct dsi_ctrl_hw *ctrl,
+			       struct dsi_host_common_cfg *cfg)
+{
+	u32 reg_value = 0;
+
+	dsi_setup_trigger_controls(ctrl, cfg);
+
+	/* Setup clocking timing controls */
+	reg_value = ((cfg->t_clk_post & 0x3F) << 8);
+	reg_value |= (cfg->t_clk_pre & 0x3F);
+	DSI_W32(ctrl, DSI_CLKOUT_TIMING_CTRL, reg_value);
+
+	/* EOT packet control */
+	reg_value = cfg->append_tx_eot ? 1 : 0;
+	reg_value |= (cfg->ignore_rx_eot ? (1 << 4) : 0);
+	DSI_W32(ctrl, DSI_EOT_PACKET_CTRL, reg_value);
+
+	/* Turn on dsi clocks */
+	DSI_W32(ctrl, DSI_CLK_CTRL, 0x23F);
+
+	/* Setup DSI control register */
+	reg_value = 0;
+	reg_value |= (cfg->en_crc_check ? BIT(24) : 0);
+	reg_value |= (cfg->en_ecc_check ? BIT(20) : 0);
+	reg_value |= BIT(8); /* Clock lane */
+	reg_value |= ((cfg->data_lanes & DSI_DATA_LANE_3) ? BIT(7) : 0);
+	reg_value |= ((cfg->data_lanes & DSI_DATA_LANE_2) ? BIT(6) : 0);
+	reg_value |= ((cfg->data_lanes & DSI_DATA_LANE_1) ? BIT(5) : 0);
+	reg_value |= ((cfg->data_lanes & DSI_DATA_LANE_0) ? BIT(4) : 0);
+
+	DSI_W32(ctrl, DSI_CTRL, reg_value);
+
+	pr_debug("[DSI_%d]Host configuration complete\n", ctrl->index);
+}
+
+/**
+ * phy_sw_reset() - perform a soft reset on the PHY.
+ * @ctrl:        Pointer to the controller host hardware.
+ */
+void dsi_ctrl_hw_cmn_phy_sw_reset(struct dsi_ctrl_hw *ctrl)
+{
+	DSI_W32(ctrl, DSI_PHY_SW_RESET, 0x1);
+	udelay(1000);
+	DSI_W32(ctrl, DSI_PHY_SW_RESET, 0x0);
+	udelay(100);
+
+	pr_debug("[DSI_%d] phy sw reset done\n", ctrl->index);
+}
+
+/**
+ * soft_reset() - perform a soft reset on DSI controller
+ * @ctrl:          Pointer to the controller host hardware.
+ *
+ * The video, command and controller engines will be disable before the
+ * reset is triggered. These engines will not be enabled after the reset
+ * is complete. Caller must re-enable the engines.
+ *
+ * If the reset is done while MDP timing engine is turned on, the video
+ * enigne should be re-enabled only during the vertical blanking time.
+ */
+void dsi_ctrl_hw_cmn_soft_reset(struct dsi_ctrl_hw *ctrl)
+{
+	u32 reg = 0;
+	u32 reg_ctrl = 0;
+
+	/* Clear DSI_EN, VIDEO_MODE_EN, CMD_MODE_EN */
+	reg_ctrl = DSI_R32(ctrl, DSI_CTRL);
+	DSI_W32(ctrl, DSI_CTRL, reg_ctrl & ~0x7);
+
+	/* Force enable PCLK, BYTECLK, AHBM_HCLK */
+	reg = DSI_R32(ctrl, DSI_CLK_CTRL);
+	reg |= 0x23F;
+	DSI_W32(ctrl, DSI_CLK_CTRL, reg);
+
+	/* Trigger soft reset */
+	DSI_W32(ctrl, DSI_SOFT_RESET, 0x1);
+	udelay(1);
+	DSI_W32(ctrl, DSI_SOFT_RESET, 0x0);
+
+	/* Disable force clock on */
+	reg &= ~(BIT(20) | BIT(11));
+	DSI_W32(ctrl, DSI_CLK_CTRL, reg);
+
+	/* Re-enable DSI controller */
+	DSI_W32(ctrl, DSI_CTRL, reg_ctrl);
+	pr_debug("[DSI_%d] ctrl soft reset done\n", ctrl->index);
+}
+
+/**
+ * set_video_timing() - set up the timing for video frame
+ * @ctrl:          Pointer to controller host hardware.
+ * @mode:          Video mode information.
+ *
+ * Set up the video timing parameters for the DSI video mode operation.
+ */
+void dsi_ctrl_hw_cmn_set_video_timing(struct dsi_ctrl_hw *ctrl,
+				     struct dsi_mode_info *mode)
+{
+	u32 reg = 0;
+	u32 hs_start = 0;
+	u32 hs_end, active_h_start, active_h_end, h_total;
+	u32 vs_start = 0, vs_end = 0;
+	u32 vpos_start = 0, vpos_end, active_v_start, active_v_end, v_total;
+
+	hs_end = mode->h_sync_width;
+	active_h_start = mode->h_sync_width + mode->h_back_porch;
+	active_h_end = active_h_start + mode->h_active;
+	h_total = (mode->h_sync_width + mode->h_back_porch + mode->h_active +
+		   mode->h_front_porch) - 1;
+
+	vpos_end = mode->v_sync_width;
+	active_v_start = mode->v_sync_width + mode->v_back_porch;
+	active_v_end = active_v_start + mode->v_active;
+	v_total = (mode->v_sync_width + mode->v_back_porch + mode->v_active +
+		   mode->v_front_porch) - 1;
+
+	reg = ((active_h_end & 0xFFFF) << 16) | (active_h_start & 0xFFFF);
+	DSI_W32(ctrl, DSI_VIDEO_MODE_ACTIVE_H, reg);
+
+	reg = ((active_v_end & 0xFFFF) << 16) | (active_v_start & 0xFFFF);
+	DSI_W32(ctrl, DSI_VIDEO_MODE_ACTIVE_V, reg);
+
+	reg = ((v_total & 0xFFFF) << 16) | (h_total & 0xFFFF);
+	DSI_W32(ctrl, DSI_VIDEO_MODE_TOTAL, reg);
+
+	reg = ((hs_end & 0xFFFF) << 16) | (hs_start & 0xFFFF);
+	DSI_W32(ctrl, DSI_VIDEO_MODE_HSYNC, reg);
+
+	reg = ((vs_end & 0xFFFF) << 16) | (vs_start & 0xFFFF);
+	DSI_W32(ctrl, DSI_VIDEO_MODE_VSYNC, reg);
+
+	reg = ((vpos_end & 0xFFFF) << 16) | (vpos_start & 0xFFFF);
+	DSI_W32(ctrl, DSI_VIDEO_MODE_VSYNC_VPOS, reg);
+
+	/* TODO: HS TIMER value? */
+	DSI_W32(ctrl, DSI_HS_TIMER_CTRL, 0x3FD08);
+	DSI_W32(ctrl, DSI_MISR_VIDEO_CTRL, 0x10100);
+	DSI_W32(ctrl, DSI_DSI_TIMING_FLUSH, 0x1);
+	pr_debug("[DSI_%d] ctrl video parameters updated\n", ctrl->index);
+}
+
+/**
+ * setup_cmd_stream() - set up parameters for command pixel streams
+ * @ctrl:          Pointer to controller host hardware.
+ * @width_in_pixels:   Width of the stream in pixels.
+ * @h_stride:          Horizontal stride in bytes.
+ * @height_inLines:    Number of lines in the stream.
+ * @vc_id:             stream_id
+ *
+ * Setup parameters for command mode pixel stream size.
+ */
+void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl,
+				     u32 width_in_pixels,
+				     u32 h_stride,
+				     u32 height_in_lines,
+				     u32 vc_id)
+{
+	u32 reg = 0;
+
+	reg = (h_stride + 1) << 16;
+	reg |= (vc_id & 0x3) << 8;
+	reg |= 0x39; /* packet data type */
+	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM0_CTRL, reg);
+	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM1_CTRL, reg);
+
+	reg = (height_in_lines << 16) | width_in_pixels;
+	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM0_TOTAL, reg);
+	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_STREAM1_TOTAL, reg);
+}
+
+/**
+ * video_engine_setup() - Setup dsi host controller for video mode
+ * @ctrl:          Pointer to controller host hardware.
+ * @common_cfg:    Common configuration parameters.
+ * @cfg:           Video mode configuration.
+ *
+ * Set up DSI video engine with a specific configuration. Controller and
+ * video engine are not enabled as part of this function.
+ */
+void dsi_ctrl_hw_cmn_video_engine_setup(struct dsi_ctrl_hw *ctrl,
+				       struct dsi_host_common_cfg *common_cfg,
+				       struct dsi_video_engine_cfg *cfg)
+{
+	u32 reg = 0;
+
+	reg |= (cfg->last_line_interleave_en ? BIT(31) : 0);
+	reg |= (cfg->pulse_mode_hsa_he ? BIT(28) : 0);
+	reg |= (cfg->hfp_lp11_en ? BIT(24) : 0);
+	reg |= (cfg->hbp_lp11_en ? BIT(20) : 0);
+	reg |= (cfg->hsa_lp11_en ? BIT(16) : 0);
+	reg |= (cfg->eof_bllp_lp11_en ? BIT(15) : 0);
+	reg |= (cfg->bllp_lp11_en ? BIT(12) : 0);
+	reg |= (cfg->traffic_mode & 0x3) << 8;
+	reg |= (cfg->vc_id & 0x3);
+	reg |= (video_mode_format_map[common_cfg->dst_format] & 0x3) << 4;
+	DSI_W32(ctrl, DSI_VIDEO_MODE_CTRL, reg);
+
+	reg = (common_cfg->swap_mode & 0x7) << 12;
+	reg |= (common_cfg->bit_swap_red ? BIT(0) : 0);
+	reg |= (common_cfg->bit_swap_green ? BIT(4) : 0);
+	reg |= (common_cfg->bit_swap_blue ? BIT(8) : 0);
+	DSI_W32(ctrl, DSI_VIDEO_MODE_DATA_CTRL, reg);
+	/* Enable Timing double buffering */
+	DSI_W32(ctrl, DSI_DSI_TIMING_DB_MODE, 0x1);
+
+
+	pr_debug("[DSI_%d] Video engine setup done\n", ctrl->index);
+}
+
+/**
+ * cmd_engine_setup() - setup dsi host controller for command mode
+ * @ctrl:          Pointer to the controller host hardware.
+ * @common_cfg:    Common configuration parameters.
+ * @cfg:           Command mode configuration.
+ *
+ * Setup DSI CMD engine with a specific configuration. Controller and
+ * command engine are not enabled as part of this function.
+ */
+void dsi_ctrl_hw_cmn_cmd_engine_setup(struct dsi_ctrl_hw *ctrl,
+				     struct dsi_host_common_cfg *common_cfg,
+				     struct dsi_cmd_engine_cfg *cfg)
+{
+	u32 reg = 0;
+
+	reg = (cfg->max_cmd_packets_interleave & 0xF) << 20;
+	reg |= (common_cfg->bit_swap_red ? BIT(4) : 0);
+	reg |= (common_cfg->bit_swap_green ? BIT(8) : 0);
+	reg |= (common_cfg->bit_swap_blue ? BIT(12) : 0);
+	reg |= cmd_mode_format_map[common_cfg->dst_format];
+	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_CTRL, reg);
+
+	reg = DSI_R32(ctrl, DSI_COMMAND_MODE_MDP_CTRL2);
+	reg |= BIT(16);
+	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_CTRL2, reg);
+
+	reg = cfg->wr_mem_start & 0xFF;
+	reg |= (cfg->wr_mem_continue & 0xFF) << 8;
+	reg |= (cfg->insert_dcs_command ? BIT(16) : 0);
+	DSI_W32(ctrl, DSI_COMMAND_MODE_MDP_DCS_CMD_CTRL, reg);
+
+	pr_debug("[DSI_%d] Cmd engine setup done\n", ctrl->index);
+}
+
+/**
+ * video_engine_en() - enable DSI video engine
+ * @ctrl:          Pointer to controller host hardware.
+ * @on:            Enable/disabel video engine.
+ */
+void dsi_ctrl_hw_cmn_video_engine_en(struct dsi_ctrl_hw *ctrl, bool on)
+{
+	u32 reg = 0;
+
+	/* Set/Clear VIDEO_MODE_EN bit */
+	reg = DSI_R32(ctrl, DSI_CTRL);
+	if (on)
+		reg |= BIT(1);
+	else
+		reg &= ~BIT(1);
+
+	DSI_W32(ctrl, DSI_CTRL, reg);
+
+	pr_debug("[DSI_%d] Video engine = %d\n", ctrl->index, on);
+}
+
+/**
+ * ctrl_en() - enable DSI controller engine
+ * @ctrl:          Pointer to the controller host hardware.
+ * @on:            turn on/off the DSI controller engine.
+ */
+void dsi_ctrl_hw_cmn_ctrl_en(struct dsi_ctrl_hw *ctrl, bool on)
+{
+	u32 reg = 0;
+
+	/* Set/Clear DSI_EN bit */
+	reg = DSI_R32(ctrl, DSI_CTRL);
+	if (on)
+		reg |= BIT(0);
+	else
+		reg &= ~BIT(0);
+
+	DSI_W32(ctrl, DSI_CTRL, reg);
+
+	pr_debug("[DSI_%d] Controller engine = %d\n", ctrl->index, on);
+}
+
+/**
+ * cmd_engine_en() - enable DSI controller command engine
+ * @ctrl:          Pointer to the controller host hardware.
+ * @on:            Turn on/off the DSI command engine.
+ */
+void dsi_ctrl_hw_cmn_cmd_engine_en(struct dsi_ctrl_hw *ctrl, bool on)
+{
+	u32 reg = 0;
+
+	/* Set/Clear CMD_MODE_EN bit */
+	reg = DSI_R32(ctrl, DSI_CTRL);
+	if (on)
+		reg |= BIT(2);
+	else
+		reg &= ~BIT(2);
+
+	DSI_W32(ctrl, DSI_CTRL, reg);
+
+	pr_debug("[DSI_%d] command engine = %d\n", ctrl->index, on);
+}
+
+/**
+ * kickoff_command() - transmits commands stored in memory
+ * @ctrl:          Pointer to the controller host hardware.
+ * @cmd:           Command information.
+ * @flags:         Modifiers for command transmission.
+ *
+ * The controller hardware is programmed with address and size of the
+ * command buffer. The transmission is kicked off if
+ * DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER flag is not set. If this flag is
+ * set, caller should make a separate call to trigger_command_dma() to
+ * transmit the command.
+ */
+void dsi_ctrl_hw_cmn_kickoff_command(struct dsi_ctrl_hw *ctrl,
+				    struct dsi_ctrl_cmd_dma_info *cmd,
+				    u32 flags)
+{
+	u32 reg = 0;
+
+	/*Set BROADCAST_EN and EMBEDDED_MODE */
+	reg = DSI_R32(ctrl, DSI_COMMAND_MODE_DMA_CTRL);
+	if (cmd->en_broadcast)
+		reg |= BIT(31);
+	else
+		reg &= ~BIT(31);
+
+	if (cmd->is_master)
+		reg |= BIT(30);
+	else
+		reg &= ~BIT(30);
+
+	if (cmd->use_lpm)
+		reg |= BIT(26);
+	else
+		reg &= ~BIT(26);
+
+	reg |= BIT(28);
+	DSI_W32(ctrl, DSI_COMMAND_MODE_DMA_CTRL, reg);
+
+	DSI_W32(ctrl, DSI_DMA_CMD_OFFSET, cmd->offset);
+	DSI_W32(ctrl, DSI_DMA_CMD_LENGTH, (cmd->length & 0xFFFFFF));
+
+	/* wait for writes to complete before kick off */
+	wmb();
+
+	if (!(flags & DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER))
+		DSI_W32(ctrl, DSI_CMD_MODE_DMA_SW_TRIGGER, 0x1);
+}
+
+/**
+ * kickoff_fifo_command() - transmits a command using FIFO in dsi
+ *                          hardware.
+ * @ctrl:          Pointer to the controller host hardware.
+ * @cmd:           Command information.
+ * @flags:         Modifiers for command transmission.
+ *
+ * The controller hardware FIFO is programmed with command header and
+ * payload. The transmission is kicked off if
+ * DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER flag is not set. If this flag is
+ * set, caller should make a separate call to trigger_command_dma() to
+ * transmit the command.
+ */
+void dsi_ctrl_hw_cmn_kickoff_fifo_command(struct dsi_ctrl_hw *ctrl,
+					 struct dsi_ctrl_cmd_dma_fifo_info *cmd,
+					 u32 flags)
+{
+	u32 reg = 0, i = 0;
+	u32 *ptr = cmd->command;
+	/*
+	 * Set CMD_DMA_TPG_EN, TPG_DMA_FIFO_MODE and
+	 * CMD_DMA_PATTERN_SEL = custom pattern stored in TPG DMA FIFO
+	 */
+	reg = (BIT(1) | BIT(2) | (0x3 << 16));
+	DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CTRL, reg);
+
+	/*
+	 * Program the FIFO with command buffer. Hardware requires an extra
+	 * DWORD (set to zero) if the length of command buffer is odd DWORDS.
+	 */
+	for (i = 0; i < cmd->size; i += 4) {
+		DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CMD_DMA_INIT_VAL, *ptr);
+		ptr++;
+	}
+
+	if ((cmd->size / 4) & 0x1)
+		DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CMD_DMA_INIT_VAL, 0);
+
+	/*Set BROADCAST_EN and EMBEDDED_MODE */
+	reg = DSI_R32(ctrl, DSI_COMMAND_MODE_DMA_CTRL);
+	if (cmd->en_broadcast)
+		reg |= BIT(31);
+	else
+		reg &= ~BIT(31);
+
+	if (cmd->is_master)
+		reg |= BIT(30);
+	else
+		reg &= ~BIT(30);
+
+	if (cmd->use_lpm)
+		reg |= BIT(26);
+	else
+		reg &= ~BIT(26);
+
+	reg |= BIT(28);
+
+	DSI_W32(ctrl, DSI_COMMAND_MODE_DMA_CTRL, reg);
+
+	DSI_W32(ctrl, DSI_DMA_CMD_LENGTH, (cmd->size & 0xFFFFFFFF));
+	/* Finish writes before command trigger */
+	wmb();
+
+	if (!(flags & DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER))
+		DSI_W32(ctrl, DSI_CMD_MODE_DMA_SW_TRIGGER, 0x1);
+
+	pr_debug("[DSI_%d]size=%d, trigger = %d\n",
+		 ctrl->index, cmd->size,
+		 (flags & DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER) ? false : true);
+}
+
+void dsi_ctrl_hw_cmn_reset_cmd_fifo(struct dsi_ctrl_hw *ctrl)
+{
+	/* disable cmd dma tpg */
+	DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CTRL, 0x0);
+
+	DSI_W32(ctrl, DSI_TPG_DMA_FIFO_RESET, 0x1);
+	udelay(1);
+	DSI_W32(ctrl, DSI_TPG_DMA_FIFO_RESET, 0x0);
+}
+
+/**
+ * trigger_command_dma() - trigger transmission of command buffer.
+ * @ctrl:          Pointer to the controller host hardware.
+ *
+ * This trigger can be only used if there was a prior call to
+ * kickoff_command() of kickoff_fifo_command() with
+ * DSI_CTRL_HW_CMD_WAIT_FOR_TRIGGER flag.
+ */
+void dsi_ctrl_hw_cmn_trigger_command_dma(struct dsi_ctrl_hw *ctrl)
+{
+	DSI_W32(ctrl, DSI_CMD_MODE_DMA_SW_TRIGGER, 0x1);
+	pr_debug("[DSI_%d] CMD DMA triggered\n", ctrl->index);
+}
+
+/**
+ * get_cmd_read_data() - get data read from the peripheral
+ * @ctrl:           Pointer to the controller host hardware.
+ * @rd_buf:         Buffer where data will be read into.
+ * @total_read_len: Number of bytes to read.
+ *
+ * return: number of bytes read.
+ */
+u32 dsi_ctrl_hw_cmn_get_cmd_read_data(struct dsi_ctrl_hw *ctrl,
+				     u8 *rd_buf,
+				     u32 read_offset,
+				     u32 total_read_len)
+{
+	u32 *lp, *temp, data;
+	int i, j = 0, cnt;
+	u32 read_cnt;
+	u32 rx_byte = 0;
+	u32 repeated_bytes = 0;
+	u8 reg[16] = {0};
+	u32 pkt_size = 0;
+	int buf_offset = read_offset;
+
+	lp = (u32 *)rd_buf;
+	temp = (u32 *)reg;
+	cnt = (rx_byte + 3) >> 2;
+
+	if (cnt > 4)
+		cnt = 4;
+
+	if (rx_byte == 4)
+		read_cnt = 4;
+	else
+		read_cnt = pkt_size + 6;
+
+	if (read_cnt > 16) {
+		int bytes_shifted;
+
+		bytes_shifted = read_cnt - 16;
+		repeated_bytes = buf_offset - bytes_shifted;
+	}
+
+	for (i = cnt - 1; i >= 0; i--) {
+		data = DSI_R32(ctrl, DSI_RDBK_DATA0 + i*4);
+		*temp++ = ntohl(data);
+	}
+
+	for (i = repeated_bytes; i < 16; i++)
+		rd_buf[j++] = reg[i];
+
+	pr_debug("[DSI_%d] Read %d bytes\n", ctrl->index, j);
+	return j;
+}
+
+/**
+ * get_interrupt_status() - returns the interrupt status
+ * @ctrl:          Pointer to the controller host hardware.
+ *
+ * Returns the ORed list of interrupts(enum dsi_status_int_type) that
+ * are active. This list does not include any error interrupts. Caller
+ * should call get_error_status for error interrupts.
+ *
+ * Return: List of active interrupts.
+ */
+u32 dsi_ctrl_hw_cmn_get_interrupt_status(struct dsi_ctrl_hw *ctrl)
+{
+	u32 reg = 0;
+	u32 ints = 0;
+
+	reg = DSI_R32(ctrl, DSI_INT_CTRL);
+
+	if (reg & BIT(0))
+		ints |= DSI_CMD_MODE_DMA_DONE;
+	if (reg & BIT(8))
+		ints |= DSI_CMD_FRAME_DONE;
+	if (reg & BIT(10))
+		ints |= DSI_CMD_STREAM0_FRAME_DONE;
+	if (reg & BIT(12))
+		ints |= DSI_CMD_STREAM1_FRAME_DONE;
+	if (reg & BIT(14))
+		ints |= DSI_CMD_STREAM2_FRAME_DONE;
+	if (reg & BIT(16))
+		ints |= DSI_VIDEO_MODE_FRAME_DONE;
+	if (reg & BIT(20))
+		ints |= DSI_BTA_DONE;
+	if (reg & BIT(28))
+		ints |= DSI_DYN_REFRESH_DONE;
+	if (reg & BIT(30))
+		ints |= DSI_DESKEW_DONE;
+
+	pr_debug("[DSI_%d] Interrupt status = 0x%x, INT_CTRL=0x%x\n",
+		 ctrl->index, ints, reg);
+	return ints;
+}
+
+/**
+ * clear_interrupt_status() - clears the specified interrupts
+ * @ctrl:          Pointer to the controller host hardware.
+ * @ints:          List of interrupts to be cleared.
+ */
+void dsi_ctrl_hw_cmn_clear_interrupt_status(struct dsi_ctrl_hw *ctrl, u32 ints)
+{
+	u32 reg = 0;
+
+	if (ints & DSI_CMD_MODE_DMA_DONE)
+		reg |= BIT(0);
+	if (ints & DSI_CMD_FRAME_DONE)
+		reg |= BIT(8);
+	if (ints & DSI_CMD_STREAM0_FRAME_DONE)
+		reg |= BIT(10);
+	if (ints & DSI_CMD_STREAM1_FRAME_DONE)
+		reg |= BIT(12);
+	if (ints & DSI_CMD_STREAM2_FRAME_DONE)
+		reg |= BIT(14);
+	if (ints & DSI_VIDEO_MODE_FRAME_DONE)
+		reg |= BIT(16);
+	if (ints & DSI_BTA_DONE)
+		reg |= BIT(20);
+	if (ints & DSI_DYN_REFRESH_DONE)
+		reg |= BIT(28);
+	if (ints & DSI_DESKEW_DONE)
+		reg |= BIT(30);
+
+	DSI_W32(ctrl, DSI_INT_CTRL, reg);
+
+	pr_debug("[DSI_%d] Clear interrupts, ints = 0x%x, INT_CTRL=0x%x\n",
+		 ctrl->index, ints, reg);
+}
+
+/**
+ * enable_status_interrupts() - enable the specified interrupts
+ * @ctrl:          Pointer to the controller host hardware.
+ * @ints:          List of interrupts to be enabled.
+ *
+ * Enables the specified interrupts. This list will override the
+ * previous interrupts enabled through this function. Caller has to
+ * maintain the state of the interrupts enabled. To disable all
+ * interrupts, set ints to 0.
+ */
+void dsi_ctrl_hw_cmn_enable_status_interrupts(
+		struct dsi_ctrl_hw *ctrl, u32 ints)
+{
+	u32 reg = 0;
+
+	/* Do not change value of DSI_ERROR_MASK bit */
+	reg |= (DSI_R32(ctrl, DSI_INT_CTRL) & BIT(25));
+	if (ints & DSI_CMD_MODE_DMA_DONE)
+		reg |= BIT(1);
+	if (ints & DSI_CMD_FRAME_DONE)
+		reg |= BIT(9);
+	if (ints & DSI_CMD_STREAM0_FRAME_DONE)
+		reg |= BIT(11);
+	if (ints & DSI_CMD_STREAM1_FRAME_DONE)
+		reg |= BIT(13);
+	if (ints & DSI_CMD_STREAM2_FRAME_DONE)
+		reg |= BIT(15);
+	if (ints & DSI_VIDEO_MODE_FRAME_DONE)
+		reg |= BIT(17);
+	if (ints & DSI_BTA_DONE)
+		reg |= BIT(21);
+	if (ints & DSI_DYN_REFRESH_DONE)
+		reg |= BIT(29);
+	if (ints & DSI_DESKEW_DONE)
+		reg |= BIT(31);
+
+	DSI_W32(ctrl, DSI_INT_CTRL, reg);
+
+	pr_debug("[DSI_%d] Enable interrupts 0x%x, INT_CTRL=0x%x\n",
+		 ctrl->index, ints, reg);
+}
+
+/**
+ * get_error_status() - returns the error status
+ * @ctrl:          Pointer to the controller host hardware.
+ *
+ * Returns the ORed list of errors(enum dsi_error_int_type) that are
+ * active. This list does not include any status interrupts. Caller
+ * should call get_interrupt_status for status interrupts.
+ *
+ * Return: List of active error interrupts.
+ */
+u64 dsi_ctrl_hw_cmn_get_error_status(struct dsi_ctrl_hw *ctrl)
+{
+	u32 dln0_phy_err;
+	u32 fifo_status;
+	u32 ack_error;
+	u32 timeout_errors;
+	u32 clk_error;
+	u32 dsi_status;
+	u64 errors = 0;
+
+	dln0_phy_err = DSI_R32(ctrl, DSI_DLN0_PHY_ERR);
+	if (dln0_phy_err & BIT(0))
+		errors |= DSI_DLN0_ESC_ENTRY_ERR;
+	if (dln0_phy_err & BIT(4))
+		errors |= DSI_DLN0_ESC_SYNC_ERR;
+	if (dln0_phy_err & BIT(8))
+		errors |= DSI_DLN0_LP_CONTROL_ERR;
+	if (dln0_phy_err & BIT(12))
+		errors |= DSI_DLN0_LP0_CONTENTION;
+	if (dln0_phy_err & BIT(16))
+		errors |= DSI_DLN0_LP1_CONTENTION;
+
+	fifo_status = DSI_R32(ctrl, DSI_FIFO_STATUS);
+	if (fifo_status & BIT(7))
+		errors |= DSI_CMD_MDP_FIFO_UNDERFLOW;
+	if (fifo_status & BIT(10))
+		errors |= DSI_CMD_DMA_FIFO_UNDERFLOW;
+	if (fifo_status & BIT(18))
+		errors |= DSI_DLN0_HS_FIFO_OVERFLOW;
+	if (fifo_status & BIT(19))
+		errors |= DSI_DLN0_HS_FIFO_UNDERFLOW;
+	if (fifo_status & BIT(22))
+		errors |= DSI_DLN1_HS_FIFO_OVERFLOW;
+	if (fifo_status & BIT(23))
+		errors |= DSI_DLN1_HS_FIFO_UNDERFLOW;
+	if (fifo_status & BIT(26))
+		errors |= DSI_DLN2_HS_FIFO_OVERFLOW;
+	if (fifo_status & BIT(27))
+		errors |= DSI_DLN2_HS_FIFO_UNDERFLOW;
+	if (fifo_status & BIT(30))
+		errors |= DSI_DLN3_HS_FIFO_OVERFLOW;
+	if (fifo_status & BIT(31))
+		errors |= DSI_DLN3_HS_FIFO_UNDERFLOW;
+
+	ack_error = DSI_R32(ctrl, DSI_ACK_ERR_STATUS);
+	if (ack_error & BIT(16))
+		errors |= DSI_RDBK_SINGLE_ECC_ERR;
+	if (ack_error & BIT(17))
+		errors |= DSI_RDBK_MULTI_ECC_ERR;
+	if (ack_error & BIT(20))
+		errors |= DSI_RDBK_CRC_ERR;
+	if (ack_error & BIT(23))
+		errors |= DSI_RDBK_INCOMPLETE_PKT;
+	if (ack_error & BIT(24))
+		errors |= DSI_PERIPH_ERROR_PKT;
+
+	timeout_errors = DSI_R32(ctrl, DSI_TIMEOUT_STATUS);
+	if (timeout_errors & BIT(0))
+		errors |= DSI_HS_TX_TIMEOUT;
+	if (timeout_errors & BIT(4))
+		errors |= DSI_LP_RX_TIMEOUT;
+	if (timeout_errors & BIT(8))
+		errors |= DSI_BTA_TIMEOUT;
+
+	clk_error = DSI_R32(ctrl, DSI_CLK_STATUS);
+	if (clk_error & BIT(16))
+		errors |= DSI_PLL_UNLOCK;
+
+	dsi_status = DSI_R32(ctrl, DSI_STATUS);
+	if (dsi_status & BIT(31))
+		errors |= DSI_INTERLEAVE_OP_CONTENTION;
+
+	pr_debug("[DSI_%d] Error status = 0x%llx, phy=0x%x, fifo=0x%x",
+		 ctrl->index, errors, dln0_phy_err, fifo_status);
+	pr_debug("[DSI_%d] ack=0x%x, timeout=0x%x, clk=0x%x, dsi=0x%x\n",
+		 ctrl->index, ack_error, timeout_errors, clk_error, dsi_status);
+	return errors;
+}
+
+/**
+ * clear_error_status() - clears the specified errors
+ * @ctrl:          Pointer to the controller host hardware.
+ * @errors:          List of errors to be cleared.
+ */
+void dsi_ctrl_hw_cmn_clear_error_status(struct dsi_ctrl_hw *ctrl, u64 errors)
+{
+	u32 dln0_phy_err = 0;
+	u32 fifo_status = 0;
+	u32 ack_error = 0;
+	u32 timeout_error = 0;
+	u32 clk_error = 0;
+	u32 dsi_status = 0;
+	u32 int_ctrl = 0;
+
+	if (errors & DSI_RDBK_SINGLE_ECC_ERR)
+		ack_error |= BIT(16);
+	if (errors & DSI_RDBK_MULTI_ECC_ERR)
+		ack_error |= BIT(17);
+	if (errors & DSI_RDBK_CRC_ERR)
+		ack_error |= BIT(20);
+	if (errors & DSI_RDBK_INCOMPLETE_PKT)
+		ack_error |= BIT(23);
+	if (errors & DSI_PERIPH_ERROR_PKT)
+		ack_error |= BIT(24);
+
+	if (errors & DSI_LP_RX_TIMEOUT)
+		timeout_error |= BIT(4);
+	if (errors & DSI_HS_TX_TIMEOUT)
+		timeout_error |= BIT(0);
+	if (errors & DSI_BTA_TIMEOUT)
+		timeout_error |= BIT(8);
+
+	if (errors & DSI_PLL_UNLOCK)
+		clk_error |= BIT(16);
+
+	if (errors & DSI_DLN0_LP0_CONTENTION)
+		dln0_phy_err |= BIT(12);
+	if (errors & DSI_DLN0_LP1_CONTENTION)
+		dln0_phy_err |= BIT(16);
+	if (errors & DSI_DLN0_ESC_ENTRY_ERR)
+		dln0_phy_err |= BIT(0);
+	if (errors & DSI_DLN0_ESC_SYNC_ERR)
+		dln0_phy_err |= BIT(4);
+	if (errors & DSI_DLN0_LP_CONTROL_ERR)
+		dln0_phy_err |= BIT(8);
+
+	if (errors & DSI_CMD_DMA_FIFO_UNDERFLOW)
+		fifo_status |= BIT(10);
+	if (errors & DSI_CMD_MDP_FIFO_UNDERFLOW)
+		fifo_status |= BIT(7);
+	if (errors & DSI_DLN0_HS_FIFO_OVERFLOW)
+		fifo_status |= BIT(18);
+	if (errors & DSI_DLN1_HS_FIFO_OVERFLOW)
+		fifo_status |= BIT(22);
+	if (errors & DSI_DLN2_HS_FIFO_OVERFLOW)
+		fifo_status |= BIT(26);
+	if (errors & DSI_DLN3_HS_FIFO_OVERFLOW)
+		fifo_status |= BIT(30);
+	if (errors & DSI_DLN0_HS_FIFO_UNDERFLOW)
+		fifo_status |= BIT(19);
+	if (errors & DSI_DLN1_HS_FIFO_UNDERFLOW)
+		fifo_status |= BIT(23);
+	if (errors & DSI_DLN2_HS_FIFO_UNDERFLOW)
+		fifo_status |= BIT(27);
+	if (errors & DSI_DLN3_HS_FIFO_UNDERFLOW)
+		fifo_status |= BIT(31);
+
+	if (errors & DSI_INTERLEAVE_OP_CONTENTION)
+		dsi_status |= BIT(31);
+
+	DSI_W32(ctrl, DSI_DLN0_PHY_ERR, dln0_phy_err);
+	DSI_W32(ctrl, DSI_FIFO_STATUS, fifo_status);
+	DSI_W32(ctrl, DSI_ACK_ERR_STATUS, ack_error);
+	DSI_W32(ctrl, DSI_TIMEOUT_STATUS, timeout_error);
+	DSI_W32(ctrl, DSI_CLK_STATUS, clk_error);
+	DSI_W32(ctrl, DSI_STATUS, dsi_status);
+
+	int_ctrl = DSI_R32(ctrl, DSI_INT_CTRL);
+	int_ctrl |= BIT(24);
+	DSI_W32(ctrl, DSI_INT_CTRL, int_ctrl);
+	pr_debug("[DSI_%d] clear errors = 0x%llx, phy=0x%x, fifo=0x%x",
+		 ctrl->index, errors, dln0_phy_err, fifo_status);
+	pr_debug("[DSI_%d] ack=0x%x, timeout=0x%x, clk=0x%x, dsi=0x%x\n",
+		 ctrl->index, ack_error, timeout_error, clk_error, dsi_status);
+}
+
+/**
+ * enable_error_interrupts() - enable the specified interrupts
+ * @ctrl:          Pointer to the controller host hardware.
+ * @errors:        List of errors to be enabled.
+ *
+ * Enables the specified interrupts. This list will override the
+ * previous interrupts enabled through this function. Caller has to
+ * maintain the state of the interrupts enabled. To disable all
+ * interrupts, set errors to 0.
+ */
+void dsi_ctrl_hw_cmn_enable_error_interrupts(struct dsi_ctrl_hw *ctrl,
+					    u64 errors)
+{
+	u32 int_ctrl = 0;
+	u32 int_mask0 = 0x7FFF3BFF;
+
+	int_ctrl = DSI_R32(ctrl, DSI_INT_CTRL);
+	if (errors)
+		int_ctrl |= BIT(25);
+	else
+		int_ctrl &= ~BIT(25);
+
+	if (errors & DSI_RDBK_SINGLE_ECC_ERR)
+		int_mask0 &= ~BIT(0);
+	if (errors & DSI_RDBK_MULTI_ECC_ERR)
+		int_mask0 &= ~BIT(1);
+	if (errors & DSI_RDBK_CRC_ERR)
+		int_mask0 &= ~BIT(2);
+	if (errors & DSI_RDBK_INCOMPLETE_PKT)
+		int_mask0 &= ~BIT(3);
+	if (errors & DSI_PERIPH_ERROR_PKT)
+		int_mask0 &= ~BIT(4);
+
+	if (errors & DSI_LP_RX_TIMEOUT)
+		int_mask0 &= ~BIT(5);
+	if (errors & DSI_HS_TX_TIMEOUT)
+		int_mask0 &= ~BIT(6);
+	if (errors & DSI_BTA_TIMEOUT)
+		int_mask0 &= ~BIT(7);
+
+	if (errors & DSI_PLL_UNLOCK)
+		int_mask0 &= ~BIT(28);
+
+	if (errors & DSI_DLN0_LP0_CONTENTION)
+		int_mask0 &= ~BIT(24);
+	if (errors & DSI_DLN0_LP1_CONTENTION)
+		int_mask0 &= ~BIT(25);
+	if (errors & DSI_DLN0_ESC_ENTRY_ERR)
+		int_mask0 &= ~BIT(21);
+	if (errors & DSI_DLN0_ESC_SYNC_ERR)
+		int_mask0 &= ~BIT(22);
+	if (errors & DSI_DLN0_LP_CONTROL_ERR)
+		int_mask0 &= ~BIT(23);
+
+	if (errors & DSI_CMD_DMA_FIFO_UNDERFLOW)
+		int_mask0 &= ~BIT(9);
+	if (errors & DSI_CMD_MDP_FIFO_UNDERFLOW)
+		int_mask0 &= ~BIT(11);
+	if (errors & DSI_DLN0_HS_FIFO_OVERFLOW)
+		int_mask0 &= ~BIT(16);
+	if (errors & DSI_DLN1_HS_FIFO_OVERFLOW)
+		int_mask0 &= ~BIT(17);
+	if (errors & DSI_DLN2_HS_FIFO_OVERFLOW)
+		int_mask0 &= ~BIT(18);
+	if (errors & DSI_DLN3_HS_FIFO_OVERFLOW)
+		int_mask0 &= ~BIT(19);
+	if (errors & DSI_DLN0_HS_FIFO_UNDERFLOW)
+		int_mask0 &= ~BIT(26);
+	if (errors & DSI_DLN1_HS_FIFO_UNDERFLOW)
+		int_mask0 &= ~BIT(27);
+	if (errors & DSI_DLN2_HS_FIFO_UNDERFLOW)
+		int_mask0 &= ~BIT(29);
+	if (errors & DSI_DLN3_HS_FIFO_UNDERFLOW)
+		int_mask0 &= ~BIT(30);
+
+	if (errors & DSI_INTERLEAVE_OP_CONTENTION)
+		int_mask0 &= ~BIT(8);
+
+	DSI_W32(ctrl, DSI_INT_CTRL, int_ctrl);
+	DSI_W32(ctrl, DSI_ERR_INT_MASK0, int_mask0);
+
+	pr_debug("[DSI_%d] enable errors = 0x%llx, int_mask0=0x%x\n",
+		 ctrl->index, errors, int_mask0);
+}
+
+/**
+ * video_test_pattern_setup() - setup test pattern engine for video mode
+ * @ctrl:          Pointer to the controller host hardware.
+ * @type:          Type of test pattern.
+ * @init_val:      Initial value to use for generating test pattern.
+ */
+void dsi_ctrl_hw_cmn_video_test_pattern_setup(struct dsi_ctrl_hw *ctrl,
+					     enum dsi_test_pattern type,
+					     u32 init_val)
+{
+	u32 reg = 0;
+
+	DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_VIDEO_INIT_VAL, init_val);
+
+	switch (type) {
+	case DSI_TEST_PATTERN_FIXED:
+		reg |= (0x2 << 4);
+		break;
+	case DSI_TEST_PATTERN_INC:
+		reg |= (0x1 << 4);
+		break;
+	case DSI_TEST_PATTERN_POLY:
+		DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_VIDEO_POLY, 0xF0F0F);
+		break;
+	default:
+		break;
+	}
+
+	DSI_W32(ctrl, DSI_TPG_MAIN_CONTROL, 0x100);
+	DSI_W32(ctrl, DSI_TPG_VIDEO_CONFIG, 0x5);
+	DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CTRL, reg);
+
+	pr_debug("[DSI_%d] Video test pattern setup done\n", ctrl->index);
+}
+
+/**
+ * cmd_test_pattern_setup() - setup test patttern engine for cmd mode
+ * @ctrl:          Pointer to the controller host hardware.
+ * @type:          Type of test pattern.
+ * @init_val:      Initial value to use for generating test pattern.
+ * @stream_id:     Stream Id on which packets are generated.
+ */
+void dsi_ctrl_hw_cmn_cmd_test_pattern_setup(struct dsi_ctrl_hw *ctrl,
+					   enum dsi_test_pattern type,
+					   u32 init_val,
+					   u32 stream_id)
+{
+	u32 reg = 0;
+	u32 init_offset;
+	u32 poly_offset;
+	u32 pattern_sel_shift;
+
+	switch (stream_id) {
+	case 0:
+		init_offset = DSI_TEST_PATTERN_GEN_CMD_MDP_INIT_VAL0;
+		poly_offset = DSI_TEST_PATTERN_GEN_CMD_MDP_STREAM0_POLY;
+		pattern_sel_shift = 8;
+		break;
+	case 1:
+		init_offset = DSI_TEST_PATTERN_GEN_CMD_MDP_INIT_VAL1;
+		poly_offset = DSI_TEST_PATTERN_GEN_CMD_MDP_STREAM1_POLY;
+		pattern_sel_shift = 12;
+		break;
+	case 2:
+		init_offset = DSI_TEST_PATTERN_GEN_CMD_MDP_INIT_VAL2;
+		poly_offset = DSI_TEST_PATTERN_GEN_CMD_MDP_STREAM2_POLY;
+		pattern_sel_shift = 20;
+		break;
+	default:
+		return;
+	}
+
+	DSI_W32(ctrl, init_offset, init_val);
+
+	switch (type) {
+	case DSI_TEST_PATTERN_FIXED:
+		reg |= (0x2 << pattern_sel_shift);
+		break;
+	case DSI_TEST_PATTERN_INC:
+		reg |= (0x1 << pattern_sel_shift);
+		break;
+	case DSI_TEST_PATTERN_POLY:
+		DSI_W32(ctrl, poly_offset, 0xF0F0F);
+		break;
+	default:
+		break;
+	}
+
+	DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CTRL, reg);
+	pr_debug("[DSI_%d] Cmd test pattern setup done\n", ctrl->index);
+}
+
+/**
+ * test_pattern_enable() - enable test pattern engine
+ * @ctrl:          Pointer to the controller host hardware.
+ * @enable:        Enable/Disable test pattern engine.
+ */
+void dsi_ctrl_hw_cmn_test_pattern_enable(struct dsi_ctrl_hw *ctrl,
+					bool enable)
+{
+	u32 reg = DSI_R32(ctrl, DSI_TEST_PATTERN_GEN_CTRL);
+
+	if (enable)
+		reg |= BIT(0);
+	else
+		reg &= ~BIT(0);
+
+	DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CTRL, reg);
+
+	pr_debug("[DSI_%d] Test pattern enable=%d\n", ctrl->index, enable);
+}
+
+/**
+ * trigger_cmd_test_pattern() - trigger a command mode frame update with
+ *                              test pattern
+ * @ctrl:          Pointer to the controller host hardware.
+ * @stream_id:     Stream on which frame update is sent.
+ */
+void dsi_ctrl_hw_cmn_trigger_cmd_test_pattern(struct dsi_ctrl_hw *ctrl,
+					     u32 stream_id)
+{
+	switch (stream_id) {
+	case 0:
+		DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CMD_STREAM0_TRIGGER, 0x1);
+		break;
+	case 1:
+		DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CMD_STREAM1_TRIGGER, 0x1);
+		break;
+	case 2:
+		DSI_W32(ctrl, DSI_TEST_PATTERN_GEN_CMD_STREAM2_TRIGGER, 0x1);
+		break;
+	default:
+		break;
+	}
+
+	pr_debug("[DSI_%d] Cmd Test pattern trigger\n", ctrl->index);
+}
+
+void dsi_ctrl_hw_dln0_phy_err(struct dsi_ctrl_hw *ctrl)
+{
+	u32 status = 0;
+	/*
+	 * Clear out any phy errors prior to exiting ULPS
+	 * This fixes certain instances where phy does not exit
+	 * ULPS cleanly. Also, do not print error during such cases.
+	 */
+	status = DSI_R32(ctrl, DSI_DLN0_PHY_ERR);
+	if (status & 0x011111) {
+		DSI_W32(ctrl, DSI_DLN0_PHY_ERR, status);
+		pr_err("%s: phy_err_status = %x\n", __func__, status);
+	}
+}
+
+void dsi_ctrl_hw_cmn_phy_reset_config(struct dsi_ctrl_hw *ctrl,
+		bool enable)
+{
+	u32 reg = 0;
+
+	reg = DSI_MMSS_MISC_R32(ctrl, MMSS_MISC_CLAMP_REG_OFF);
+
+	/* Mask/unmask disable PHY reset bit */
+	if (enable)
+		reg |= BIT(30);
+	else
+		reg &= ~BIT(30);
+
+	DSI_MMSS_MISC_W32(ctrl, MMSS_MISC_CLAMP_REG_OFF, reg);
+}
+
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_reg_1_4.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_reg.h
similarity index 98%
rename from drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_reg_1_4.h
rename to drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_reg.h
index 028ad46..34e9e72 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_reg_1_4.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl_reg.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2017, 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
@@ -187,6 +187,7 @@
 #define DSI_SECURE_DISPLAY_STATUS                  (0x02CC)
 #define DSI_SECURE_DISPLAY_BLOCK_COMMAND_COLOR     (0x02D0)
 #define DSI_SECURE_DISPLAY_BLOCK_VIDEO_COLOR       (0x02D4)
+#define DSI_LOGICAL_LANE_SWAP_CTRL                 (0x0310)
 
 
 #endif /* _DSI_CTRL_REG_H_ */
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h
index 2caa32e..a30fdb5 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_defs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017, 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
@@ -70,22 +70,6 @@
 };
 
 /**
- * enum dsi_data_lanes - dsi physical lanes
- * @DSI_DATA_LANE_0: Physical lane 0
- * @DSI_DATA_LANE_1: Physical lane 1
- * @DSI_DATA_LANE_2: Physical lane 2
- * @DSI_DATA_LANE_3: Physical lane 3
- * @DSI_CLOCK_LANE:  Physical clock lane
- */
-enum dsi_data_lanes {
-	DSI_DATA_LANE_0 = BIT(0),
-	DSI_DATA_LANE_1 = BIT(1),
-	DSI_DATA_LANE_2 = BIT(2),
-	DSI_DATA_LANE_3 = BIT(3),
-	DSI_CLOCK_LANE  = BIT(4)
-};
-
-/**
  * enum dsi_logical_lane - dsi logical lanes
  * @DSI_LOGICAL_LANE_0:     Logical lane 0
  * @DSI_LOGICAL_LANE_1:     Logical lane 1
@@ -104,6 +88,63 @@
 };
 
 /**
+ * enum dsi_data_lanes - BIT map for DSI data lanes
+ * This is used to identify the active DSI data lanes for
+ * various operations like DSI data lane enable/ULPS/clamp
+ * configurations.
+ * @DSI_DATA_LANE_0: BIT(DSI_LOGICAL_LANE_0)
+ * @DSI_DATA_LANE_1: BIT(DSI_LOGICAL_LANE_1)
+ * @DSI_DATA_LANE_2: BIT(DSI_LOGICAL_LANE_2)
+ * @DSI_DATA_LANE_3: BIT(DSI_LOGICAL_LANE_3)
+ * @DSI_CLOCK_LANE:  BIT(DSI_LOGICAL_CLOCK_LANE)
+ */
+enum dsi_data_lanes {
+	DSI_DATA_LANE_0 = BIT(DSI_LOGICAL_LANE_0),
+	DSI_DATA_LANE_1 = BIT(DSI_LOGICAL_LANE_1),
+	DSI_DATA_LANE_2 = BIT(DSI_LOGICAL_LANE_2),
+	DSI_DATA_LANE_3 = BIT(DSI_LOGICAL_LANE_3),
+	DSI_CLOCK_LANE  = BIT(DSI_LOGICAL_CLOCK_LANE)
+};
+
+/**
+ * enum dsi_phy_data_lanes - dsi physical lanes
+ * used for DSI logical to physical lane mapping
+ * @DSI_PHYSICAL_LANE_INVALID: Physical lane valid/invalid
+ * @DSI_PHYSICAL_LANE_0: Physical lane 0
+ * @DSI_PHYSICAL_LANE_1: Physical lane 1
+ * @DSI_PHYSICAL_LANE_2: Physical lane 2
+ * @DSI_PHYSICAL_LANE_3: Physical lane 3
+ */
+enum dsi_phy_data_lanes {
+	DSI_PHYSICAL_LANE_INVALID = 0,
+	DSI_PHYSICAL_LANE_0 = BIT(0),
+	DSI_PHYSICAL_LANE_1 = BIT(1),
+	DSI_PHYSICAL_LANE_2 = BIT(2),
+	DSI_PHYSICAL_LANE_3  = BIT(3)
+};
+
+enum dsi_lane_map_type_v1 {
+	DSI_LANE_MAP_0123,
+	DSI_LANE_MAP_3012,
+	DSI_LANE_MAP_2301,
+	DSI_LANE_MAP_1230,
+	DSI_LANE_MAP_0321,
+	DSI_LANE_MAP_1032,
+	DSI_LANE_MAP_2103,
+	DSI_LANE_MAP_3210,
+};
+
+/**
+ * lane_map: DSI logical <-> physical lane mapping
+ * lane_map_v1: Lane mapping for DSI controllers < v2.0
+ * lane_map_v2: Lane mapping for DSI controllers >= 2.0
+ */
+struct dsi_lane_map {
+	enum dsi_lane_map_type_v1 lane_map_v1;
+	u8 lane_map_v2[DSI_LANE_MAX - 1];
+};
+
+/**
  * enum dsi_trigger_type - dsi trigger type
  * @DSI_TRIGGER_NONE:     No trigger.
  * @DSI_TRIGGER_TE:       TE trigger.
@@ -224,20 +265,6 @@
 };
 
 /**
- * struct dsi_lane_mapping - Mapping between DSI logical and physical lanes
- * @physical_lane0:   Logical lane to which physical lane 0 is mapped.
- * @physical_lane1:   Logical lane to which physical lane 1 is mapped.
- * @physical_lane2:   Logical lane to which physical lane 2 is mapped.
- * @physical_lane3:   Logical lane to which physical lane 3 is mapped.
- */
-struct dsi_lane_mapping {
-	enum dsi_logical_lane physical_lane0;
-	enum dsi_logical_lane physical_lane1;
-	enum dsi_logical_lane physical_lane2;
-	enum dsi_logical_lane physical_lane3;
-};
-
-/**
  * struct dsi_host_common_cfg - Host configuration common to video and cmd mode
  * @dst_format:          Destination pixel format.
  * @data_lanes:          Physical data lanes to be enabled.
@@ -247,6 +274,7 @@
  * @mdp_cmd_trigger:     MDP frame update trigger for command mode.
  * @dma_cmd_trigger:     Command DMA trigger.
  * @cmd_trigger_stream:  Command mode stream to trigger.
+ * @swap_mode:           DSI color swap mode.
  * @bit_swap_read:       Is red color bit swapped.
  * @bit_swap_green:      Is green color bit swapped.
  * @bit_swap_blue:       Is blue color bit swapped.
@@ -281,7 +309,6 @@
 
 /**
  * struct dsi_video_engine_cfg - DSI video engine configuration
- * @host_cfg:                  Pointer to host common configuration.
  * @last_line_interleave_en:   Allow command mode op interleaved on last line of
  *                             video stream.
  * @pulse_mode_hsa_he:         Send HSA and HE following VS/VE packet if set to
@@ -309,8 +336,6 @@
 
 /**
  * struct dsi_cmd_engine_cfg - DSI command engine configuration
- * @host_cfg:                  Pointer to host common configuration.
- * @host_cfg:                      Common host configuration
  * @max_cmd_packets_interleave     Maximum number of command mode RGB packets to
  *                                 send with in one horizontal blanking period
  *                                 of the video mode frame.
@@ -339,7 +364,6 @@
  * @bit_clk_rate_hz:       Bit clock frequency in Hz.
  * @video_timing:          Video timing information of a frame.
  * @lane_map:              Mapping between logical and physical lanes.
- * @phy_type:              PHY type to be used.
  */
 struct dsi_host_config {
 	enum dsi_op_mode panel_mode;
@@ -351,7 +375,7 @@
 	u64 esc_clk_rate_hz;
 	u64 bit_clk_rate_hz;
 	struct dsi_mode_info video_timing;
-	struct dsi_lane_mapping lane_map;
+	struct dsi_lane_map lane_map;
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index 06f9ccb..a39ebb7 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -582,6 +582,25 @@
 	return 0;
 }
 
+static int dsi_display_phy_reset_config(struct dsi_display *display,
+		bool enable)
+{
+	int rc = 0;
+	int i;
+	struct dsi_display_ctrl *ctrl;
+
+	for (i = 0 ; i < display->ctrl_count; i++) {
+		ctrl = &display->ctrl[i];
+		rc = dsi_ctrl_phy_reset_config(ctrl->ctrl, enable);
+		if (rc) {
+			pr_err("[%s] failed to %s phy reset, rc=%d\n",
+			       display->name, enable ? "mask" : "unmask", rc);
+			return rc;
+		}
+	}
+	return 0;
+}
+
 static int dsi_display_ctrl_init(struct dsi_display *display)
 {
 	int rc = 0;
@@ -1344,7 +1363,7 @@
 		if (mmss_clamp)
 			dsi_display_ctrl_setup(display);
 
-		if (display->ulps_enabled) {
+		if (display->ulps_enabled && mmss_clamp) {
 			/*
 			 * ULPS Entry Request. This is needed if the lanes were
 			 * in ULPS prior to power collapse, since after
@@ -1467,16 +1486,109 @@
 	return rc;
 }
 
+static void __set_lane_map_v2(u8 *lane_map_v2,
+	enum dsi_phy_data_lanes lane0,
+	enum dsi_phy_data_lanes lane1,
+	enum dsi_phy_data_lanes lane2,
+	enum dsi_phy_data_lanes lane3)
+{
+	lane_map_v2[DSI_LOGICAL_LANE_0] = lane0;
+	lane_map_v2[DSI_LOGICAL_LANE_1] = lane1;
+	lane_map_v2[DSI_LOGICAL_LANE_2] = lane2;
+	lane_map_v2[DSI_LOGICAL_LANE_3] = lane3;
+}
 
 static int dsi_display_parse_lane_map(struct dsi_display *display)
 {
-	int rc = 0;
+	int rc = 0, i = 0;
+	const char *data;
+	u8 temp[DSI_LANE_MAX - 1];
 
-	display->lane_map.physical_lane0 = DSI_LOGICAL_LANE_0;
-	display->lane_map.physical_lane1 = DSI_LOGICAL_LANE_1;
-	display->lane_map.physical_lane2 = DSI_LOGICAL_LANE_2;
-	display->lane_map.physical_lane3 = DSI_LOGICAL_LANE_3;
-	return rc;
+	if (!display) {
+		pr_err("invalid params\n");
+		return -EINVAL;
+	}
+
+	/* lane-map-v2 supersedes lane-map-v1 setting */
+	rc = of_property_read_u8_array(display->pdev->dev.of_node,
+		"qcom,lane-map-v2", temp, (DSI_LANE_MAX - 1));
+	if (!rc) {
+		for (i = DSI_LOGICAL_LANE_0; i < (DSI_LANE_MAX - 1); i++)
+			display->lane_map.lane_map_v2[i] = BIT(temp[i]);
+		return 0;
+	} else if (rc != EINVAL) {
+		pr_warn("Incorrect mapping, configure default\n");
+		goto set_default;
+	}
+
+	/* lane-map older version, for DSI controller version < 2.0 */
+	data = of_get_property(display->pdev->dev.of_node,
+		"qcom,lane-map", NULL);
+	if (!data)
+		goto set_default;
+
+	if (!strcmp(data, "lane_map_3012")) {
+		display->lane_map.lane_map_v1 = DSI_LANE_MAP_3012;
+		__set_lane_map_v2(display->lane_map.lane_map_v2,
+			DSI_PHYSICAL_LANE_1,
+			DSI_PHYSICAL_LANE_2,
+			DSI_PHYSICAL_LANE_3,
+			DSI_PHYSICAL_LANE_0);
+	} else if (!strcmp(data, "lane_map_2301")) {
+		display->lane_map.lane_map_v1 = DSI_LANE_MAP_2301;
+		__set_lane_map_v2(display->lane_map.lane_map_v2,
+			DSI_PHYSICAL_LANE_2,
+			DSI_PHYSICAL_LANE_3,
+			DSI_PHYSICAL_LANE_0,
+			DSI_PHYSICAL_LANE_1);
+	} else if (!strcmp(data, "lane_map_1230")) {
+		display->lane_map.lane_map_v1 = DSI_LANE_MAP_1230;
+		__set_lane_map_v2(display->lane_map.lane_map_v2,
+			DSI_PHYSICAL_LANE_3,
+			DSI_PHYSICAL_LANE_0,
+			DSI_PHYSICAL_LANE_1,
+			DSI_PHYSICAL_LANE_2);
+	} else if (!strcmp(data, "lane_map_0321")) {
+		display->lane_map.lane_map_v1 = DSI_LANE_MAP_0321;
+		__set_lane_map_v2(display->lane_map.lane_map_v2,
+			DSI_PHYSICAL_LANE_0,
+			DSI_PHYSICAL_LANE_3,
+			DSI_PHYSICAL_LANE_2,
+			DSI_PHYSICAL_LANE_1);
+	} else if (!strcmp(data, "lane_map_1032")) {
+		display->lane_map.lane_map_v1 = DSI_LANE_MAP_1032;
+		__set_lane_map_v2(display->lane_map.lane_map_v2,
+			DSI_PHYSICAL_LANE_1,
+			DSI_PHYSICAL_LANE_0,
+			DSI_PHYSICAL_LANE_3,
+			DSI_PHYSICAL_LANE_2);
+	} else if (!strcmp(data, "lane_map_2103")) {
+		display->lane_map.lane_map_v1 = DSI_LANE_MAP_2103;
+		__set_lane_map_v2(display->lane_map.lane_map_v2,
+			DSI_PHYSICAL_LANE_2,
+			DSI_PHYSICAL_LANE_1,
+			DSI_PHYSICAL_LANE_0,
+			DSI_PHYSICAL_LANE_3);
+	} else if (!strcmp(data, "lane_map_3210")) {
+		display->lane_map.lane_map_v1 = DSI_LANE_MAP_3210;
+		__set_lane_map_v2(display->lane_map.lane_map_v2,
+			DSI_PHYSICAL_LANE_3,
+			DSI_PHYSICAL_LANE_2,
+			DSI_PHYSICAL_LANE_1,
+			DSI_PHYSICAL_LANE_0);
+	} else {
+		pr_warn("%s: invalid lane map %s specified. defaulting to lane_map0123\n",
+			__func__, data);
+		goto set_default;
+	}
+	return 0;
+
+set_default:
+	/* default lane mapping */
+	__set_lane_map_v2(display->lane_map.lane_map_v2, DSI_PHYSICAL_LANE_0,
+		DSI_PHYSICAL_LANE_1, DSI_PHYSICAL_LANE_2, DSI_PHYSICAL_LANE_3);
+	display->lane_map.lane_map_v1 = DSI_LANE_MAP_0123;
+	return 0;
 }
 
 static int dsi_display_parse_dt(struct dsi_display *display)
@@ -1535,11 +1647,6 @@
 		display->panel_of = of_node;
 	}
 
-	rc = dsi_display_parse_lane_map(display);
-	if (rc) {
-		pr_err("Lane map not found, rc=%d\n", rc);
-		goto error;
-	}
 error:
 	return rc;
 }
@@ -1578,6 +1685,12 @@
 		goto error_ctrl_put;
 	}
 
+	rc = dsi_display_parse_lane_map(display);
+	if (rc) {
+		pr_err("Lane map not found, rc=%d\n", rc);
+		goto error_ctrl_put;
+	}
+
 	rc = dsi_display_clocks_init(display);
 	if (rc) {
 		pr_err("Failed to parse clock data, rc=%d\n", rc);
@@ -1978,7 +2091,6 @@
 			       display->name, rc);
 			goto error;
 		}
-
 	}
 error:
 	return rc;
@@ -2317,7 +2429,6 @@
 		display->display_type = "unknown";
 
 	mutex_init(&display->display_lock);
-
 	display->pdev = pdev;
 	platform_set_drvdata(pdev, display);
 	mutex_lock(&dsi_display_list_lock);
@@ -2773,11 +2884,18 @@
 		goto error_phy_disable;
 	}
 
+	rc = dsi_display_phy_reset_config(display, true);
+	if (rc) {
+		pr_err("[%s] failed to setup DSI controller, rc=%d\n",
+		       display->name, rc);
+		goto error_ctrl_deinit;
+	}
+
 	rc = dsi_display_set_clk_src(display);
 	if (rc) {
 		pr_err("[%s] failed to set DSI link clock source, rc=%d\n",
 			display->name, rc);
-		goto error_ctrl_deinit;
+		goto error_phy_reset_off;
 	}
 
 	rc = dsi_display_clk_ctrl(display->dsi_clk_handle,
@@ -2785,7 +2903,7 @@
 	if (rc) {
 		pr_err("[%s] failed to enable DSI link clocks, rc=%d\n",
 		       display->name, rc);
-		goto error_ctrl_deinit;
+		goto error_phy_reset_off;
 	}
 
 	rc = dsi_display_ctrl_host_enable(display);
@@ -2808,6 +2926,8 @@
 error_ctrl_link_off:
 	(void)dsi_display_clk_ctrl(display->dsi_clk_handle,
 			DSI_LINK_CLK, DSI_CLK_OFF);
+error_phy_reset_off:
+	(void)dsi_display_phy_reset_config(display, false);
 error_ctrl_deinit:
 	(void)dsi_display_ctrl_deinit(display);
 error_phy_disable:
@@ -2991,6 +3111,11 @@
 		pr_err("[%s] failed to disable DSI PHY, rc=%d\n",
 		       display->name, rc);
 
+	rc = dsi_display_phy_reset_config(display, false);
+	if (rc)
+		pr_err("[%s] failed to disable DSI PHY reset config, rc=%d\n",
+		       display->name, rc);
+
 	rc = dsi_display_clk_ctrl(display->dsi_clk_handle,
 			DSI_CORE_CLK, DSI_CLK_OFF);
 	if (rc)
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
index 1c1f4b4..563c525 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
@@ -149,7 +149,7 @@
 
 	struct dsi_display_clk_info clock_info;
 	struct dsi_host_config config;
-	struct dsi_lane_mapping lane_map;
+	struct dsi_lane_map lane_map;
 	u32 num_of_modes;
 	bool is_tpg_enabled;
 	bool ulps_enabled;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
index 4249ac4..27cee05 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
@@ -697,9 +697,9 @@
 		pr_debug("[PHY_%d] TODO: perform validation\n", phy->index);
 
 	memcpy(&phy->mode, &config->video_timing, sizeof(phy->mode));
+	memcpy(&phy->cfg.lane_map, &config->lane_map, sizeof(config->lane_map));
 	phy->data_lanes = config->common_config.data_lanes;
 	phy->dst_format = config->common_config.dst_format;
-	phy->lane_map = config->lane_map;
 	phy->cfg.pll_source = pll_source;
 
 	rc = phy->hw.ops.calculate_timing_params(&phy->hw,
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.h b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.h
index d8bfd15..a2b19505 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.h
@@ -67,7 +67,6 @@
  * @mode:              Current mode.
  * @data_lanes:        Number of data lanes used.
  * @dst_format:        Destination format.
- * @lane_map:          Map between logical and physical lanes.
  */
 struct msm_dsi_phy {
 	struct platform_device *pdev;
@@ -89,7 +88,6 @@
 	struct dsi_mode_info mode;
 	enum dsi_data_lanes data_lanes;
 	enum dsi_pixel_format dst_format;
-	struct dsi_lane_mapping lane_map;
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw.h b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw.h
index 78c59e2..1f5618f 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy_hw.h
@@ -80,6 +80,7 @@
  * @timing:           Timing parameters for lanes.
  * @regulators:       Regulator settings for lanes.
  * @pll_source:       PLL source.
+ * @lane_map:         DSI logical to PHY lane mapping.
  */
 struct dsi_phy_cfg {
 	struct dsi_phy_per_lane_cfgs lanecfg;
@@ -87,6 +88,7 @@
 	struct dsi_phy_per_lane_cfgs timing;
 	struct dsi_phy_per_lane_cfgs regulators;
 	enum dsi_phy_pll_source pll_source;
+	struct dsi_lane_map lane_map;
 };
 
 struct dsi_phy_hw;