Merge "platform/target: msm8996: Remove support for 3gb map"
diff --git a/app/rpmbtests/ufs_rpmb.c b/app/rpmbtests/ufs_rpmb.c
index d951933..b84dfe7 100644
--- a/app/rpmbtests/ufs_rpmb.c
+++ b/app/rpmbtests/ufs_rpmb.c
@@ -86,6 +86,44 @@
 	printf("\n");
 }
 
+bool swp_test()
+{
+	int ret = 0;
+	qsee_stor_secure_wp_info_t cb = {0};
+	// Write protect 4 partitions in Lun 0.
+	cb.lun_number = 0;
+	cb.num_entries = 4;
+	cb.wp_entries[0].wp_enable = 0x1;
+	cb.wp_entries[0].wp_type_mask = 0x1;
+	cb.wp_entries[0].addr = 8;
+	cb.wp_entries[0].num_blocks = 8192;
+
+	cb.wp_entries[1].wp_enable = 0x1;
+	cb.wp_entries[1].wp_type_mask = 0x1;
+	cb.wp_entries[1].addr = 74120;
+	cb.wp_entries[1].num_blocks = 32;
+
+	cb.wp_entries[2].wp_enable = 0x1;
+	cb.wp_entries[2].wp_type_mask = 0x1;
+	cb.wp_entries[2].addr = 6;
+	cb.wp_entries[2].num_blocks = 2;
+
+	cb.wp_entries[3].wp_enable = 0x1;
+	cb.wp_entries[3].wp_type_mask = 0x1;
+	cb.wp_entries[3].addr = 73736;
+	cb.wp_entries[3].num_blocks = 256;
+
+	ret = swp_write(cb);
+	if (ret)
+	{
+		dprintf(CRITICAL, "SWP Write Test Failed\n");
+		return false;
+	}
+	else
+		dprintf(CRITICAL, "SWP Write Test Passed\n");
+	return true;
+}
+
 bool rpmb_test(struct ufs_dev *dev, uint16_t address, uint16_t rpmb_num_blocks)
 {
 	struct rpmb_frame data_frame, result_frame[rpmb_num_blocks];
diff --git a/app/rpmbtests/ufs_rpmb.h b/app/rpmbtests/ufs_rpmb.h
index 5d16a7b..06f221e 100644
--- a/app/rpmbtests/ufs_rpmb.h
+++ b/app/rpmbtests/ufs_rpmb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015 The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -40,6 +40,7 @@
 	printf("\n");
 }
 
+bool swp_test();
 void rpmb_run_test();
 bool rpmb_test(struct ufs_dev *dev, uint16_t address, uint16_t rpmb_num_blocks);
 void dump_rpmb_data(struct rpmb_frame *result_frame);
diff --git a/dev/gcdb/display/gcdb_display.c b/dev/gcdb/display/gcdb_display.c
index a847aaa..dfb6484 100644
--- a/dev/gcdb/display/gcdb_display.c
+++ b/dev/gcdb/display/gcdb_display.c
@@ -487,6 +487,30 @@
 	pan_type = oem_panel_select(panel_name, &panelstruct, &(panel.panel_info),
 				 &dsi_video_mode_phy_db);
 
+	if ((panel.panel_info.lm_split[0] > 0) &&
+	    (panel.panel_info.lm_split[1] > 0))
+		panelstruct.paneldata->panel_operating_mode |= DUAL_PIPE_FLAG;
+
+	if (panelstruct.paneldata->panel_operating_mode & DUAL_PIPE_FLAG) {
+		if ((panel.panel_info.lm_split[0] <= 0) ||
+		    (panel.panel_info.lm_split[1] <= 0)) {
+			panel.panel_info.lm_split[0] =
+				panelstruct.panelres->panel_width / 2;
+			panel.panel_info.lm_split[1] =
+				panel.panel_info.lm_split[0];
+		}
+	}
+
+	if (panelstruct.config && panelstruct.config->use_pingpong_split)
+		panelstruct.paneldata->panel_operating_mode |= DST_SPLIT_FLAG;
+
+	if ((panelstruct.paneldata->panel_operating_mode & DUAL_PIPE_FLAG) &&
+	    (panelstruct.paneldata->panel_operating_mode & DST_SPLIT_FLAG)) {
+		dprintf(CRITICAL, "DUAL_PIPE_FLAG and DST_SPLIT_FLAG cannot be selected togather\n");
+		ret = ERROR;
+		goto error_gcdb_display_init;
+	}
+
 	if (pan_type == PANEL_TYPE_DSI) {
 		target_dsi_phy_config(&dsi_video_mode_phy_db);
 		mdss_dsi_check_swap_status();
diff --git a/dev/gcdb/display/gcdb_display.h b/dev/gcdb/display/gcdb_display.h
index aaed691..a4f1685 100755
--- a/dev/gcdb/display/gcdb_display.h
+++ b/dev/gcdb/display/gcdb_display.h
@@ -76,6 +76,8 @@
 	uint32_t sim_mode;
 	char dsi_config[DSI_CFG_SIZE];
 	uint32_t dsi_pll_src;
+	/* If dual-DSI, slave cfg will use 2nd index */
+	int cfg_num[2]; /* -ve number means no overide */
 };
 
 enum {
diff --git a/dev/gcdb/display/gcdb_display_param.c b/dev/gcdb/display/gcdb_display_param.c
index 7d189a5..44b3454 100644
--- a/dev/gcdb/display/gcdb_display_param.c
+++ b/dev/gcdb/display/gcdb_display_param.c
@@ -38,7 +38,7 @@
 #include "fastboot_oem_display.h"
 
 struct oem_panel_data oem_data = {{'\0'}, {'\0'}, false, false, false, SIM_NONE,
-	"single_dsi", DSI_PLL_DEFAULT};
+	"single_dsi", DSI_PLL_DEFAULT, {-1, -1}};
 
 static int panel_name_to_dt_string(struct panel_lookup_list supp_panels[],
 			  uint32_t supp_panels_size,
@@ -186,8 +186,20 @@
 		for (i = 0; (ch + i) < ch_tmp; i++)
 			oem_data.sec_panel[i] = *(ch + i);
 		oem_data.sec_panel[i] = '\0';
+
+		/* Topology configuration for secondary panel */
+		ch_tmp = strstr((char *) ch, ":cfg");
+		if (ch_tmp)
+			oem_data.cfg_num[1] = atoi((const char*)(ch_tmp + 4));
+	} else {
+		oem_data.sec_panel[0] = '\0';
 	}
 
+	/* Topology configuration for primary panel */
+	ch_tmp = strstr((char *) panel_name, ":cfg");
+	if (ch_tmp && (!ch || (ch && (ch_tmp < ch))))
+		oem_data.cfg_num[0] = atoi((const char*)(ch_tmp + 4));
+
 	/* Skip LK configuration */
 	ch = strstr((char *) panel_name, ":skip");
 	oem_data.skip = ch ? true : false;
@@ -222,7 +234,6 @@
 	/* disable cont splash when booting in simulator mode */
 	if (oem_data.sim_mode)
 		oem_data.cont_splash = false;
-
 }
 
 static bool mdss_dsi_set_panel_node(char *panel_name, char **dsi_id,
@@ -284,6 +295,8 @@
 	int panel_mode = SPLIT_DISPLAY_FLAG | DUAL_PIPE_FLAG | DST_SPLIT_FLAG;
 	int prefix_string_len = strlen(DISPLAY_CMDLINE_PREFIX);
 	char *sctl_string, *pll_src_string = NULL;
+	char prim_cfg_name[10]="\0", slave_cfg_name[10]="\0"; /* config[0-99] */
+	char *display_cmd_line = pbuf;
 
 	panelstruct = mdss_dsi_get_panel_data();
 
@@ -332,7 +345,7 @@
 
 	if (((panel_mode & SPLIT_DISPLAY_FLAG) ||
 	     (panel_mode & DST_SPLIT_FLAG)) && slave_panel_node == NULL) {
-		dprintf(CRITICAL, "slave node not present in dual dsi case\n");
+		dprintf(CRITICAL, "slave node not present in split-dsi case\n");
 		return false;
 	}
 
@@ -413,6 +426,40 @@
 		}
 	}
 
+	dprintf(SPEW, "dsi_cfg:%s mdp_cfg[0]=%d mdp_cfg[1]=%d\n",
+		oem_data.dsi_config, oem_data.cfg_num[0], oem_data.cfg_num[1]);
+
+	if ((oem_data.cfg_num[0] >= 0) && (oem_data.cfg_num[0] < 100)) {
+		snprintf(prim_cfg_name, sizeof(prim_cfg_name),
+			":config%d", oem_data.cfg_num[0]);
+		arg_size += strlen(prim_cfg_name);
+	} else if (panelstruct.config != NULL) {
+		/*
+		 * if oem command wasn't set then take topology config
+		 * used by per target oem panel driver if available.
+		 */
+		snprintf(prim_cfg_name, sizeof(prim_cfg_name),
+			":%s", panelstruct.config->config_name);
+		arg_size += strlen(prim_cfg_name);
+	}
+
+	/* in split-dsi, primary and slave panel share same topology config */
+	if (!strcmp(oem_data.dsi_config, "split_dsi"))
+		snprintf(slave_cfg_name, sizeof(slave_cfg_name),
+			"%s", prim_cfg_name);
+
+	if (!strcmp(oem_data.dsi_config, "dual_dsi")) {
+		if ((oem_data.cfg_num[1] >= 0) && (oem_data.cfg_num[1] < 100)) {
+			snprintf(slave_cfg_name, sizeof(slave_cfg_name),
+				":config%d", oem_data.cfg_num[1]);
+			arg_size += strlen(slave_cfg_name);
+		}
+		/*
+		 * In dual-dsi, secondary or slave panels isn't supported
+		 * in bootloader so "else" case like above is not possible.
+		 */
+	}
+
 	if (buf_size < arg_size) {
 		dprintf(CRITICAL, "display command line buffer is small\n");
 		ret = false;
@@ -433,6 +480,13 @@
 		pbuf += panel_node_len;
 		buf_size -= panel_node_len;
 
+		/* writeout primary topology config */
+		if (strlen(prim_cfg_name) > 0) {
+			strlcpy(pbuf, prim_cfg_name, buf_size);
+			pbuf += strlen(prim_cfg_name);
+			buf_size -= strlen(prim_cfg_name);
+		}
+
 		strlcpy(pbuf, sctl_string, buf_size);
 		pbuf += strlen(sctl_string);
 		buf_size -= strlen(sctl_string);
@@ -441,6 +495,13 @@
 		pbuf += slave_panel_node_len;
 		buf_size -= slave_panel_node_len;
 
+		/* writeout slave panel, split-dsi, or secondary panel, dual-dsi, topology config */
+		if (strlen(slave_cfg_name) > 0) {
+			strlcpy(pbuf, slave_cfg_name, buf_size);
+			pbuf += strlen(slave_cfg_name);
+			buf_size -= strlen(slave_cfg_name);
+		}
+
 		strlcpy(pbuf, DSI_CFG_STRING, buf_size);
 		pbuf += DSI_CFG_STRING_LEN;
 		buf_size -= DSI_CFG_STRING_LEN;
@@ -464,6 +525,9 @@
 			pbuf += strlen(sim_mode_string);
 			buf_size -= strlen(sim_mode_string);
 		}
+
+		dprintf(INFO, "display kernel cmdline:%s\n",
+			display_cmd_line);
 	}
 	return ret;
 }
diff --git a/dev/gcdb/display/include/panel.h b/dev/gcdb/display/include/panel.h
index c9aee8b..11f471c 100755
--- a/dev/gcdb/display/include/panel.h
+++ b/dev/gcdb/display/include/panel.h
@@ -217,9 +217,18 @@
 	uint32_t bpc;		/* target bpc, byte per component */
 	uint32_t slice_per_pkt;
 	uint32_t block_prediction;
-	uint32_t ich_reset_override;
-	uint32_t ich_reset_value;
-	uint32_t data_path_mode;
+};
+
+struct topology_config {
+	char *config_name; /* matches with kernel cmdline */
+	/*
+	 * lm_split: -ve value means that lm_split is not used.
+	 *           If lm_split is used then DUAL_PIPE flag will be added.
+	 */
+	int lm_split[2];
+	int num_dsc_enc; /* how many encoder to use */
+	struct dsc_parameters *dsc;
+	int use_pingpong_split;
 };
 
 #endif /*_PANEL_H_ */
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_cmd.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_cmd.h
index b059bb3..f1a39b0 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_cmd.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_cmd.h
@@ -332,8 +332,23 @@
 /*---------------------------------------------------------------------------*/
 /* DSC									     */
 /*---------------------------------------------------------------------------*/
-static const struct dsc_parameters nt35597_wqxga_dsc_cmd_paras = {
-	1, 0, 0, 16, 720, 8, 8, 2, 1, 0, 0, 0
+struct dsc_parameters nt35597_wqxga_dsc_cmd_params0 = {
+	1, 0, 0, 16, 720, 8, 8, 2, 1
+};
+
+/* 1LM + 1 DSC_ENC */
+struct topology_config nt35597_wqxga_dsc_cmd_config0 = {
+	"config0", {-1, -1}, 1, &nt35597_wqxga_dsc_cmd_params0, false
+};
+
+/* 2LM + 3D Mux + 1 DSC_ENC */
+struct topology_config nt35597_wqxga_dsc_cmd_config1 = {
+	"config1", {720, 720}, 1, &nt35597_wqxga_dsc_cmd_params0, false
+};
+
+/* 2LM + 2 DSC_ENC + DSC_MERGE */
+struct topology_config nt35597_wqxga_dsc_cmd_config2 = {
+	"config2", {720, 720}, 2, &nt35597_wqxga_dsc_cmd_params0, false
 };
 
 #endif
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_video.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_video.h
index 382d75c..572d2d5 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_video.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dsc_video.h
@@ -319,8 +319,23 @@
 /*---------------------------------------------------------------------------*/
 /* DSC									     */
 /*---------------------------------------------------------------------------*/
-static const struct dsc_parameters nt35597_wqxga_dsc_video_paras = {
-	1, 0, 0, 16, 720, 8, 8, 2, 1, 0, 0, 0
+struct dsc_parameters nt35597_wqxga_dsc_video_params0 = {
+	1, 0, 0, 16, 720, 8, 8, 2, 1
+};
+
+/* 1LM + 1 DSC_ENC */
+struct topology_config nt35597_wqxga_dsc_video_config0 = {
+	"config0", {-1, -1}, 1, &nt35597_wqxga_dsc_video_params0, false
+};
+
+/* 2LM + 3D Mux + 1 DSC_ENC */
+struct topology_config nt35597_wqxga_dsc_video_config1 = {
+	"config1", {720, 720}, 1, &nt35597_wqxga_dsc_video_params0, false
+};
+
+/* 2LM + 2 DSC_ENC + DSC_MERGE */
+struct topology_config nt35597_wqxga_dsc_video_config2 = {
+	"config2", {720, 720}, 2, &nt35597_wqxga_dsc_video_params0, false
 };
 
 #endif
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h
index b01752a..17248ba 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h
@@ -270,4 +270,14 @@
 	1, 8, {53, 54, 55, 56, 57, 58, 59, 60}
 };
 
+/* 2LM + 2CTL */
+struct topology_config nt35597_wqxga_dualdsi_cmd_config0 = {
+	"config0", {720, 720}, 0, NULL, false
+};
+
+/* 1LM + 1CTL + PP_SPLIT */
+struct topology_config nt35597_wqxga_dualdsi_cmd_config1 = {
+	"config1", {-1, -1}, 0, NULL, true
+};
+
 #endif
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
index b5f7cd8..556d657 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
@@ -262,4 +262,14 @@
 	1, 8, {53, 54, 55, 56, 57, 58, 59, 60}
 };
 
+/* 2LM + 2CTL */
+struct topology_config nt35597_wqxga_dualdsi_video_config0 = {
+	"config0", {720, 720}, 0, NULL, false
+};
+
+/* 1LM + 1CTL + PP_SPLIT */
+struct topology_config nt35597_wqxga_dualdsi_video_config1 = {
+	"config1", {-1, -1}, 0, NULL, true
+};
+
 #endif
diff --git a/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h b/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
index ef5bc4c..470ddda 100644
--- a/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
@@ -166,6 +166,16 @@
 	1, 8, {53, 54, 55, 56, 57, 58, 59, 60}
 };
 
+/* 2LM + 2CTL */
+struct topology_config sharp_wqxga_dualdsi_video_config0 = {
+	"config0", {800, 800}, 0, NULL, false
+};
+
+/* 1LM + 1CTL + PP_SPLIT */
+struct topology_config sharp_wqxga_dualdsi_video_config1 = {
+	"config1", {-1, -1}, 0, NULL, true
+};
+
 #define SHARP_WQXGA_DUALDSI_VIDEO_SIGNATURE 0x210000
 
 #endif /*_PANEL_SHARP_WQXGA_DUALDSI_VIDEO_H_*/
diff --git a/dev/gcdb/display/panel_display.c b/dev/gcdb/display/panel_display.c
index 1c0a82a..6ae60ae 100755
--- a/dev/gcdb/display/panel_display.c
+++ b/dev/gcdb/display/panel_display.c
@@ -148,6 +148,8 @@
 	pinfo->xres += (pinfo->border_left + pinfo->border_right);
 	pinfo->yres += (pinfo->border_top + pinfo->border_bottom);
 
+	dprintf(INFO, "panel_operating_mode=0x%x\n",
+		pstruct->paneldata->panel_operating_mode);
 	if (pstruct->paneldata->panel_operating_mode & DUAL_PIPE_FLAG)
 		pinfo->lcdc.dual_pipe = 1;
 	if (pstruct->paneldata->panel_operating_mode & PIPE_SWAP_FLAG)
@@ -156,6 +158,14 @@
 		pinfo->lcdc.split_display = 1;
 	if (pstruct->paneldata->panel_operating_mode & DST_SPLIT_FLAG)
 		pinfo->lcdc.dst_split = 1;
+	if (pstruct->paneldata->panel_operating_mode & DUAL_DSI_FLAG)
+		pinfo->mipi.dual_dsi = 1;
+	if (pstruct->paneldata->panel_operating_mode & USE_DSI1_PLL_FLAG)
+		pinfo->mipi.use_dsi1_pll = 1;
+
+	dprintf(SPEW, "dual_pipe=%d pipe_swap=%d split_display=%d dst_split=%d\n",
+		pinfo->lcdc.dual_pipe, pinfo->lcdc.pipe_swap,
+		pinfo->lcdc.split_display, pinfo->lcdc.dst_split);
 
 	/* Color setting*/
 	pinfo->lcdc.border_clr = pstruct->color->border_color;
@@ -194,10 +204,6 @@
 	pinfo->mipi.vc = pstruct->paneldata->dsi_virtualchannel_id;
 	pinfo->mipi.frame_rate = pstruct->paneldata->panel_framerate;
 	pinfo->mipi.stream = pstruct->paneldata->dsi_stream;
-	if (pstruct->paneldata->panel_operating_mode & DUAL_DSI_FLAG)
-		pinfo->mipi.dual_dsi = 1;
-	if (pstruct->paneldata->panel_operating_mode & USE_DSI1_PLL_FLAG)
-		pinfo->mipi.use_dsi1_pll = 1;
 	pinfo->mipi.mode_gpio_state = pstruct->paneldata->mode_gpio_state;
 	pinfo->mipi.bitclock = pstruct->paneldata->panel_bitclock_freq;
 	if (pinfo->mipi.bitclock) {
@@ -246,28 +252,34 @@
 	pinfo->fbc.comp_ratio = 1;
 
 	if (pinfo->compression_mode == COMPRESSION_DSC) {
-		struct dsc_desc *dsc = NULL;
+		struct dsc_desc *dsc = &pinfo->dsc;
+		struct dsc_parameters *dsc_params = NULL;
 
-		pinfo->dsc.major = pstruct->dsc_paras.major;
-		pinfo->dsc.minor = pstruct->dsc_paras.minor;
-		pinfo->dsc.pps_id = pstruct->dsc_paras.pps_id;
-		pinfo->dsc.slice_height = pstruct->dsc_paras.slice_height;
-		pinfo->dsc.slice_width = pstruct->dsc_paras.slice_width;
-		pinfo->dsc.bpp = pstruct->dsc_paras.bpp;
-		pinfo->dsc.bpc = pstruct->dsc_paras.bpc;
-		pinfo->dsc.slice_per_pkt = pstruct->dsc_paras.slice_per_pkt;
-		pinfo->dsc.ich_reset_value = pstruct->dsc_paras.ich_reset_value;
-		pinfo->dsc.ich_reset_override = pstruct->dsc_paras.ich_reset_override;
-		pinfo->dsc.block_pred_enable = pstruct->dsc_paras.block_prediction;
-		pinfo->dsc.enable_422 = 0;
-		pinfo->dsc.convert_rgb = 1;
-		pinfo->dsc.vbr_enable = 0;
+		if (!pstruct->config) {
+			dprintf(CRITICAL, "ERROR: DSC cannot be used without topology_config\n");
+			return ERR_NOT_ALLOWED;
+		}
+		dsc_params = pstruct->config->dsc;
+		if (!dsc_params) {
+			dprintf(CRITICAL, "ERROR: DSC params are NULL\n");
+			return ERR_INVALID_ARGS;
+		}
 
-		dsc = &pinfo->dsc;
-		if (dsc) {
-			if (dsc->parameter_calc)
-                                dsc->parameter_calc(pinfo);
-                }
+		dsc->major = dsc_params->major;
+		dsc->minor = dsc_params->minor;
+		dsc->pps_id = dsc_params->pps_id;
+		dsc->slice_height = dsc_params->slice_height;
+		dsc->slice_width = dsc_params->slice_width;
+		dsc->bpp = dsc_params->bpp;
+		dsc->bpc = dsc_params->bpc;
+		dsc->slice_per_pkt = dsc_params->slice_per_pkt;
+		dsc->block_pred_enable = dsc_params->block_prediction;
+		dsc->enable_422 = 0;
+		dsc->convert_rgb = 1;
+		dsc->vbr_enable = 0;
+
+		if (dsc->parameter_calc)
+			dsc->parameter_calc(pinfo);
 	} else if (pinfo->compression_mode == COMPRESSION_FBC) {
 		pinfo->fbc.enabled = pstruct->fbcinfo.enabled;
 		if (pinfo->fbc.enabled) {
diff --git a/dev/gcdb/display/panel_display.h b/dev/gcdb/display/panel_display.h
index a998fc2..ed99a98 100755
--- a/dev/gcdb/display/panel_display.h
+++ b/dev/gcdb/display/panel_display.h
@@ -53,7 +53,7 @@
 /*---------------------------------------------------------------------------*/
 /* struct definition                                                         */
 /*---------------------------------------------------------------------------*/
-struct panel_struct{
+struct panel_struct {
 	struct panel_config         *paneldata;
 	struct panel_resolution     *panelres;
 	struct color_info           *color;
@@ -65,7 +65,7 @@
 	struct panel_reset_sequence *panelresetseq;
 	struct backlight            *backlightinfo;
 	struct fb_compression	    fbcinfo;
-	struct dsc_parameters	    dsc_paras;
+	struct topology_config	    *config;
 };
 
 struct panel_list {
diff --git a/platform/msm8952/include/platform/iomap.h b/platform/msm8952/include/platform/iomap.h
index 035c7cb..ce98076 100644
--- a/platform/msm8952/include/platform/iomap.h
+++ b/platform/msm8952/include/platform/iomap.h
@@ -420,9 +420,15 @@
 #endif
 #define MDSS_MDP_PP_DCE_DATA_OUT_SWAP		0x0CC
 
-#define MDP_DSC_0_BASE				REG_MDP(0x81000)
-#define MDP_DSC_1_BASE				REG_MDP(0x81400)
+#ifdef MDP_DSC_0_BASE
+#undef MDP_DSC_0_BASE
+#endif
+#define MDP_DSC_0_BASE              REG_MDP(0x81000)
 
+#ifdef MDP_DSC_1_BASE
+#undef MDP_DSC_1_BASE
+#endif
+#define MDP_DSC_1_BASE              REG_MDP(0x81400)
 
 #define SOFT_RESET                  0x118
 #define CLK_CTRL                    0x11C
diff --git a/platform/msm8996/include/platform/iomap.h b/platform/msm8996/include/platform/iomap.h
index 657ea50..3fc75dd 100644
--- a/platform/msm8996/include/platform/iomap.h
+++ b/platform/msm8996/include/platform/iomap.h
@@ -229,8 +229,15 @@
 #endif
 #define MDP_PP_1_BASE               REG_MDP(0x71800)
 
-#define MDP_DSC_0_BASE			REG_MDP(0x81000)
-#define MDP_DSC_1_BASE			REG_MDP(0x81400)
+#ifdef MDP_DSC_0_BASE
+#undef MDP_DSC_0_BASE
+#endif
+#define MDP_DSC_0_BASE              REG_MDP(0x81000)
+
+#ifdef MDP_DSC_1_BASE
+#undef MDP_DSC_1_BASE
+#endif
+#define MDP_DSC_1_BASE              REG_MDP(0x81400)
 
 #ifdef MDP_HW_REV
 #undef MDP_HW_REV
diff --git a/platform/msm_shared/include/mdp5.h b/platform/msm_shared/include/mdp5.h
index 9253548..5a61f17 100644
--- a/platform/msm_shared/include/mdp5.h
+++ b/platform/msm_shared/include/mdp5.h
@@ -118,6 +118,9 @@
 #define MDP_PP_0_BASE                           REG_MDP(0x12D00)
 #define MDP_PP_1_BASE                           REG_MDP(0x12E00)
 
+#define MDP_DSC_0_BASE                          REG_MDP(0x81000)
+#define MDP_DSC_1_BASE                          REG_MDP(0x81400)
+
 #define CTL_LAYER_0                             0x00
 #define CTL_LAYER_1                             0x04
 #define CTL_TOP                                 0x14
@@ -251,6 +254,8 @@
 void mdss_dsc_parameters_calc(struct msm_panel_info *pinfo);
 int mdss_dsc_to_buf(struct msm_panel_info *pinfo);
 void mdss_dsc_dsi_config(uint32_t ctl_base, int mode, struct dsc_desc *dsc);
-void mdss_dsc_mdp_config(struct msm_panel_info *pinfo);
+void mdss_dsc_mdp_config(struct msm_panel_info *pinfo,
+	unsigned int pp_base, unsigned int dsc_base,
+	bool mux, bool split_mode);
 
 #endif
diff --git a/platform/msm_shared/include/msm_panel.h b/platform/msm_shared/include/msm_panel.h
index f918876..7066311 100755
--- a/platform/msm_shared/include/msm_panel.h
+++ b/platform/msm_shared/include/msm_panel.h
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <stdint.h>
 #include <dev/fbcon.h>
+#include <sys/types.h>
 
 #define DFPS_MAX_FRAME_RATE 10
 #define DFPS_PLL_CODES_SIZE 0x1000 /* One page */
@@ -132,9 +133,6 @@
 struct msm_panel_info;
 
 struct dsc_desc {
-	int data_path_model;            /* multiplex + split_panel */
-	int ich_reset_value;
-	int ich_reset_override;
 	int initial_lines;
 	int slice_last_group_size;
 	int bpp;        /* target bit per pixel */
@@ -197,8 +195,9 @@
 	void (*parameter_calc) (struct msm_panel_info *pinfo);
 	int (*dsc2buf) (struct msm_panel_info *pinfo);
 	void (*dsi_dsc_config) (uint32_t base, int mode, struct dsc_desc *dsc);
-	void (*mdp_dsc_config) (struct msm_panel_info *pinfo);
-
+	void (*mdp_dsc_config) (struct msm_panel_info *pinfo,
+		unsigned int pp_base, unsigned int dsc_base,
+		bool mux, bool split_mode);
 };
 
 struct fbc_panel_info {
@@ -395,6 +394,9 @@
 	uint32_t border_left;
 	uint32_t border_right;
 
+	int lm_split[2];
+	int num_dsc_enc;
+
 	struct lcd_panel_info lcd;
 	struct lcdc_panel_info lcdc;
 	struct fbc_panel_info fbc;
diff --git a/platform/msm_shared/include/qusb2_phy.h b/platform/msm_shared/include/qusb2_phy.h
index fc971c8..d3ed338 100644
--- a/platform/msm_shared/include/qusb2_phy.h
+++ b/platform/msm_shared/include/qusb2_phy.h
@@ -32,6 +32,8 @@
 
 void qusb2_phy_reset(void);
 
+#define QUSB2PHY_PLL_LOCK        0x20
+
 #define QUSB2PHY_PORT_POWERDOWN     (QUSB2_PHY_BASE + 0x000000B4)
 #define QUSB2PHY_PORT_UTMI_CTRL2    (QUSB2_PHY_BASE + 0x000000C4)
 #define QUSB2PHY_PLL_TEST           (QUSB2_PHY_BASE + 0x00000004)
@@ -45,6 +47,7 @@
 #define QUSB2PHY_PORT_TEST2         (QUSB2_PHY_BASE + 0x0000009C)
 #define QUSB2PHY_PLL_PWR_CTL        (QUSB2_PHY_BASE + 0x00000018)
 #define QUSB2PHY_PLL_AUTOPGM_CTL1   (QUSB2_PHY_BASE + 0x0000001C)
+#define QUSB2PHY_PLL_STATUS         (QUSB2_PHY_BASE + 0x00000038)
 
 
 #endif
diff --git a/platform/msm_shared/mdp5.c b/platform/msm_shared/mdp5.c
index 901f42e..19317ac 100755
--- a/platform/msm_shared/mdp5.c
+++ b/platform/msm_shared/mdp5.c
@@ -93,10 +93,12 @@
 
 	/* return MMSS_MDP_PPB0_CONFIG offset from MDSS base */
 	if ((mdss_mdp_rev == MDSS_MDP_HW_REV_108) ||
-		(mdss_mdp_rev == MDSS_MDP_HW_REV_111))
+	    (mdss_mdp_rev == MDSS_MDP_HW_REV_111))
 		mdss_mdp_ppb_off = 0x1420;
 	else if (mdss_mdp_rev == MDSS_MDP_HW_REV_110)
 		mdss_mdp_ppb_off = 0x1334;
+	else if (MDSS_IS_MAJOR_MINOR_MATCHING(mdss_mdp_rev, MDSS_MDP_HW_REV_107))
+		mdss_mdp_ppb_off = 0x1330;
 	else
 		dprintf(CRITICAL,"Invalid PPB0_CONFIG offset\n");
 
@@ -219,7 +221,7 @@
 static void mdss_source_pipe_config(struct fbcon_config *fb, struct msm_panel_info
 		*pinfo, uint32_t pipe_base)
 {
-	uint32_t src_size, out_size, stride;
+	uint32_t img_size, out_size, stride;
 	uint32_t fb_off = 0;
 	uint32_t flip_bits = 0;
 	uint32_t src_xy = 0, dst_xy = 0;
@@ -229,14 +231,17 @@
 	width = fb->width - pinfo->border_left - pinfo->border_right;
 
 	/* write active region size*/
-	src_size = (height << 16) + width;
-	out_size = src_size;
+	img_size = (height << 16) | width;
+	out_size = img_size;
 	if (pinfo->lcdc.dual_pipe) {
-		out_size = (height << 16) + (width / 2);
 		if ((pipe_base == MDP_VP_0_RGB_1_BASE) ||
-			(pipe_base == MDP_VP_0_DMA_1_BASE) ||
-			(pipe_base == MDP_VP_0_VIG_1_BASE))
+		    (pipe_base == MDP_VP_0_DMA_1_BASE) ||
+		    (pipe_base == MDP_VP_0_VIG_1_BASE)) {
 			fb_off = (pinfo->xres / 2);
+			out_size = (height << 16) + (pinfo->lm_split[1]);
+		} else {
+			out_size = (height << 16) + (pinfo->lm_split[0]);
+		}
 	}
 
 	stride = (fb->stride * fb->bpp/8);
@@ -253,7 +258,7 @@
 			 __func__, out_size, fb_off, src_xy, dst_xy);
 	writel((uint32_t) fb->base, pipe_base + PIPE_SSPP_SRC0_ADDR);
 	writel(stride, pipe_base + PIPE_SSPP_SRC_YSTRIDE);
-	writel(src_size, pipe_base + PIPE_SSPP_SRC_IMG_SIZE);
+	writel(img_size, pipe_base + PIPE_SSPP_SRC_IMG_SIZE);
 	writel(out_size, pipe_base + PIPE_SSPP_SRC_SIZE);
 	writel(out_size, pipe_base + PIPE_SSPP_SRC_OUT_SIZE);
 	writel(src_xy, pipe_base + PIPE_SSPP_SRC_XY);
@@ -443,7 +448,7 @@
 
 	/* Each pipe driving half the screen */
 	if (pinfo->lcdc.dual_pipe)
-		xres /= 2;
+		xres = pinfo->lm_split[0];
 
 	/* bpp = bytes per pixel of input image */
 	smp_cnt = (xres * bpp * 2) + smp_size - 1;
@@ -460,6 +465,11 @@
 	writel(smp_cnt * 0xc0, left_pipe + REQPRIORITY_FIFO_WATERMARK2);
 
 	if (pinfo->lcdc.dual_pipe) {
+		xres = pinfo->lm_split[1];
+
+		smp_cnt = (xres * bpp * 2) + smp_size - 1;
+		smp_cnt /= smp_size;
+
 		writel(smp_cnt * 0x40, right_pipe + REQPRIORITY_FIFO_WATERMARK0);
 		writel(smp_cnt * 0x80, right_pipe + REQPRIORITY_FIFO_WATERMARK1);
 		writel(smp_cnt * 0xc0, right_pipe + REQPRIORITY_FIFO_WATERMARK2);
@@ -479,7 +489,6 @@
 	uint32_t display_hctl, hsync_ctl, display_vstart, display_vend;
 	uint32_t adjust_xres = 0;
 	uint32_t upper = 0, lower = 0;
-	struct dsc_desc *dsc = NULL;
 
 	struct lcdc_panel_info *lcdc = NULL;
 	struct intf_timing_params itp = {0};
@@ -493,7 +502,15 @@
 
 	adjust_xres = pinfo->xres;
 	if (pinfo->lcdc.split_display) {
-		adjust_xres /= 2;
+		if (pinfo->lcdc.dst_split) {
+			adjust_xres /= 2;
+		} else if(pinfo->lcdc.dual_pipe) {
+			if (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset()))
+				adjust_xres = pinfo->lm_split[0];
+			else
+				adjust_xres = pinfo->lm_split[1];
+		}
+
 		if (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset())) {
 			if (pinfo->lcdc.pipe_swap) {
 				lower |= BIT(4);
@@ -508,26 +525,23 @@
 		}
 	}
 
-	if (pinfo->lcdc.dst_split &&  (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset()))) {
+	if (pinfo->lcdc.dst_split && (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset()))) {
 		uint32_t ppb_offset = mdss_mdp_get_ppb_offset();
-		writel(BIT(16), REG_MDP(ppb_offset + 0x4)); /* MMSS_MDP_PPB0_CNTL */
-		writel(BIT(5), REG_MDP(ppb_offset)); /* MMSS_MDP_PPB0_CONFIG */
+		writel(BIT(5), REG_MDP(ppb_offset)); /* MMSS_MDP_PPB0_CNTL */
+		writel(BIT(16) | (0x3 << 20), REG_MDP(ppb_offset + 0x4)); /* MMSS_MDP_PPB0_CONFIG */
 	}
 
-	if (pinfo->compression_mode == COMPRESSION_DSC) {
-		dsc = &pinfo->dsc;
-	} else if (pinfo->compression_mode == COMPRESSION_FBC) {
+	if (pinfo->compression_mode == COMPRESSION_FBC)
 		if (!pinfo->fbc.enabled || !pinfo->fbc.comp_ratio)
 			pinfo->fbc.comp_ratio = 1;
-	}
 
 	itp.xres = (adjust_xres / pinfo->fbc.comp_ratio);
 	itp.yres = pinfo->yres;
 	itp.width =((adjust_xres + pinfo->lcdc.xres_pad) / pinfo->fbc.comp_ratio);
 
-	if (dsc) {
-		itp.xres = dsc->pclk_per_line;
-		itp.width = dsc->pclk_per_line;
+	if (pinfo->compression_mode == COMPRESSION_DSC) {
+		itp.xres = pinfo->dsc.pclk_per_line;
+		itp.width = pinfo->dsc.pclk_per_line;
 	}
 
 	itp.height = pinfo->yres + pinfo->lcdc.yres_pad;
@@ -604,7 +618,6 @@
 	uint32_t prefetch_avail, prefetch_needed;
 	uint32_t adjust_xres = 0;
 	uint32_t fetch_enable = BIT(31);
-	struct dsc_desc *dsc;
 
 	struct lcdc_panel_info *lcdc = NULL;
 
@@ -626,12 +639,19 @@
 		return;
 
 	adjust_xres = pinfo->xres;
-	if (pinfo->lcdc.split_display)
-		adjust_xres /= 2;
+	if (pinfo->lcdc.split_display) {
+		if (pinfo->lcdc.dst_split) {
+			adjust_xres /= 2;
+		} else if(pinfo->lcdc.dual_pipe) {
+			if (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset()))
+				adjust_xres = pinfo->lm_split[0];
+			else
+				adjust_xres = pinfo->lm_split[1];
+		}
+	}
 
 	if (pinfo->compression_mode == COMPRESSION_DSC) {
-		dsc = &pinfo->dsc;
-		adjust_xres = dsc->pclk_per_line;
+		adjust_xres = pinfo->dsc.pclk_per_line;
 	} else if (pinfo->compression_mode == COMPRESSION_FBC) {
 		if (pinfo->fbc.enabled && pinfo->fbc.comp_ratio)
 			adjust_xres /= pinfo->fbc.comp_ratio;
@@ -678,7 +698,7 @@
 	width = fb->width;
 
 	if (pinfo->lcdc.dual_pipe && !pinfo->lcdc.dst_split)
-		width /= 2;
+		width = pinfo->lm_split[0];
 
 	/* write active region size*/
 	mdp_rgb_size = (height << 16) | width;
@@ -721,6 +741,9 @@
 	writel(left_staging_level, MDP_CTL_0_BASE + CTL_LAYER_0);
 
 	if (pinfo->lcdc.dual_pipe && !pinfo->lcdc.dst_split) {
+		/* write active region size*/
+		mdp_rgb_size = (height << 16) | pinfo->lm_split[1];
+
 		writel(mdp_rgb_size, MDP_VP_0_MIXER_1_BASE + LAYER_0_OUT_SIZE);
 		writel(0x00, MDP_VP_0_MIXER_1_BASE + LAYER_0_OP_MODE);
 		writel(0x100, MDP_VP_0_MIXER_1_BASE + LAYER_0_BLEND_OP);
@@ -965,28 +988,39 @@
 
 	/* enable 3D mux for dual_pipe but single interface config */
 	if (pinfo->lcdc.dual_pipe && !pinfo->mipi.dual_dsi &&
-		!pinfo->lcdc.split_display)
-		reg |= BIT(19) | BIT(20);
+		!pinfo->lcdc.split_display) {
+
+		if (pinfo->num_dsc_enc != 2)
+			reg |= BIT(19) | BIT(20);
+	}
 
 	writel(reg, MDP_CTL_0_BASE + CTL_TOP);
 
-	/*If dst_split is enabled only intf 2 needs to be enabled.
-	CTL_1 path should not be set since CTL_0 itself is going
-	to split after DSPP block*/
+	if ((pinfo->compression_mode == COMPRESSION_DSC) &&
+	    pinfo->dsc.mdp_dsc_config) {
+		struct dsc_desc *dsc = &pinfo->dsc;
 
-	if (pinfo->compression_mode == COMPRESSION_DSC) {
-		struct dsc_desc *dsc = NULL;
+		if (pinfo->lcdc.dual_pipe && !pinfo->mipi.dual_dsi &&
+		    !pinfo->lcdc.split_display && (pinfo->num_dsc_enc == 2)) {
 
-		dsc = &pinfo->dsc;
-		if (dsc) {
-			if (dsc->mdp_dsc_config)
-				dsc->mdp_dsc_config(pinfo);
+			dsc->mdp_dsc_config(pinfo, MDP_PP_0_BASE,
+				MDP_DSC_0_BASE, true, true);
+			dsc->mdp_dsc_config(pinfo, MDP_PP_1_BASE,
+				MDP_DSC_1_BASE, true, true);
+		} else {
+			dsc->mdp_dsc_config(pinfo, MDP_PP_0_BASE,
+				MDP_DSC_0_BASE, false, false);
 		}
 	} else if (pinfo->compression_mode == COMPRESSION_FBC) {
 		if (pinfo->fbc.enabled)
 			mdss_fbc_cfg(pinfo);
 	}
 
+	/*
+	 * if dst_split is enabled, intf 1 & 2 needs to be enabled but
+	 * CTL_1 path should not be set since CTL_0 itself is going
+	 * to split after DSPP block and drive both intf.
+	 */
 	if (pinfo->mipi.dual_dsi) {
 		if (!pinfo->lcdc.dst_split) {
 			reg = 0x1f00 | mdss_mdp_ctl_out_sel(pinfo,0);
@@ -1108,8 +1142,8 @@
 
 	if (pinfo->lcdc.dst_split) {
 		uint32_t ppb_offset = mdss_mdp_get_ppb_offset();
-		writel(BIT(16) | BIT(20) | BIT(21), REG_MDP(ppb_offset + 0x4)); /* MMSS_MDP_PPB0_CNTL */
-		writel(BIT(5), REG_MDP(ppb_offset)); /* MMSS_MDP_PPB0_CONFIG */
+		writel(BIT(5), REG_MDP(ppb_offset)); /* MMSS_MDP_PPB0_CNTL */
+		writel(BIT(16) | (0x3 << 20), REG_MDP(ppb_offset + 0x4)); /* MMSS_MDP_PPB0_CONFIG */
 	}
 
 	mdp_clk_gating_ctrl();
@@ -1134,15 +1168,31 @@
 
 	writel(0x213F, MDP_PANEL_FORMAT + intf_base);
 	reg = 0x21f00 | mdss_mdp_ctl_out_sel(pinfo, 1);
+
+	/* enable 3D mux for dual_pipe but single interface config */
+	if (pinfo->lcdc.dual_pipe && !pinfo->mipi.dual_dsi &&
+		!pinfo->lcdc.split_display) {
+
+		if (pinfo->num_dsc_enc != 2)
+			reg |= BIT(19) | BIT(20);
+	}
+
 	writel(reg, MDP_CTL_0_BASE + CTL_TOP);
 
-	if (pinfo->compression_mode == COMPRESSION_DSC) {
-		struct dsc_desc *dsc = NULL;
+	if ((pinfo->compression_mode == COMPRESSION_DSC) &&
+	    pinfo->dsc.mdp_dsc_config) {
+		struct dsc_desc *dsc = &pinfo->dsc;
 
-		dsc = &pinfo->dsc;
-		if (dsc) {
-			if (dsc->mdp_dsc_config)
-				dsc->mdp_dsc_config(pinfo);
+		if (pinfo->lcdc.dual_pipe && !pinfo->mipi.dual_dsi &&
+		    !pinfo->lcdc.split_display && (pinfo->num_dsc_enc == 2)) {
+
+			dsc->mdp_dsc_config(pinfo, MDP_PP_0_BASE,
+				MDP_DSC_0_BASE, true, true);
+			dsc->mdp_dsc_config(pinfo, MDP_PP_1_BASE,
+				MDP_DSC_1_BASE, true, true);
+		} else {
+			dsc->mdp_dsc_config(pinfo, MDP_PP_0_BASE,
+				MDP_DSC_0_BASE, false, false);
 		}
 	} else if (pinfo->compression_mode == COMPRESSION_FBC) {
 		if (pinfo->fbc.enabled)
diff --git a/platform/msm_shared/mipi_dsc.c b/platform/msm_shared/mipi_dsc.c
index 33821c0..a4ee313 100644
--- a/platform/msm_shared/mipi_dsc.c
+++ b/platform/msm_shared/mipi_dsc.c
@@ -346,7 +346,9 @@
 		dsc->scale_decrement_interval);
 }
 
-void mdss_dsc_mdp_config(struct msm_panel_info *pinfo)
+void mdss_dsc_mdp_config(struct msm_panel_info *pinfo,
+	unsigned int pp_base, unsigned int dsc_base,
+	bool mux, bool split_mode)
 {
 	unsigned int data;
 	unsigned int offset, off;
@@ -359,24 +361,27 @@
 	writel(0x0, MDSS_MDP_REG_DCE_SEL);
 
 	/* dsc enable */
-	writel(1, MDP_PP_0_BASE + MDSS_MDP_PP_DSC_MODE);
+	writel(1, pp_base + MDSS_MDP_PP_DSC_MODE);
 
-	data = readl(MDP_PP_0_BASE + MDSS_MDP_PP_DCE_DATA_OUT_SWAP);
+	data = readl(pp_base + MDSS_MDP_PP_DCE_DATA_OUT_SWAP);
 	data |= BIT(18);	/* endian flip */
-	writel(data, MDP_PP_0_BASE + MDSS_MDP_PP_DCE_DATA_OUT_SWAP);
+	writel(data, pp_base + MDSS_MDP_PP_DCE_DATA_OUT_SWAP);
 
-	offset = MDP_DSC_0_BASE;
+	offset = dsc_base;
 
 	data = 0;
 	dsc = &pinfo->dsc;
 	if (pinfo->type == MIPI_VIDEO_PANEL)
 		data = BIT(2);	/* video mode */
 
+	if (split_mode)
+		data |= BIT(0);
+	if (mux)
+		data |= BIT(1);
+
 	writel(data, offset + MDSS_MDP_DSC_COMMON_MODE);
 
-	data = dsc->ich_reset_value | dsc->ich_reset_override;
-	data <<= 28;
-	data |= (dsc->initial_lines << 20);
+	data = (dsc->initial_lines << 20);
 	data |= ((dsc->slice_last_group_size - 1) << 18);
 
 	/* bpp is 6.4 format, 4 LSBs bits are for fractional part */
@@ -392,8 +397,8 @@
 	data |= (dsc->convert_rgb << 1);
 	data |= dsc->input_10_bits;
 
-	dprintf(SPEW, "%s: %d %d %d %d %d %d %d %d %d %d, data=%x\n",
-		__func__, dsc->ich_reset_value, dsc->ich_reset_override,
+	dprintf(SPEW, "%s: %d %d %d %d %d %d %d %d, data=%x\n",
+		__func__,
 		dsc->initial_lines , dsc->slice_last_group_size,
 		dsc->bpp, dsc->block_pred_enable, dsc->line_buf_depth,
 		dsc->enable_422, dsc->convert_rgb, dsc->input_10_bits, data);
diff --git a/platform/msm_shared/qseecom_lk.c b/platform/msm_shared/qseecom_lk.c
index 7608509..445904a 100644
--- a/platform/msm_shared/qseecom_lk.c
+++ b/platform/msm_shared/qseecom_lk.c
@@ -855,6 +855,7 @@
 	struct qseecom_client_send_data_ireq send_data_req;
 	struct qseecom_command_scm_resp resp;
 	void *buf = NULL;
+	void *rsp_buf_temp = NULL;
 	uint32_t size = 0;
 
 	if (req->cmd_req_buf == NULL || req->resp_buf == NULL) {
@@ -864,10 +865,19 @@
 	}
 	dprintf(SPEW, "%s called\n", __func__);
 
-	/* Allocate for req or rsp len whichever is higher, both req and rsp point
-	 * to the same buffer
-	 */
-	size = (req->cmd_req_len > req->resp_len) ? req->cmd_req_len : req->resp_len;
+	if (req->cmd_req_len > (UINT_MAX - req->resp_len)) {
+		dprintf(CRITICAL, "%s:Integer overflow\n", __func__);
+		dprintf(CRITICAL, "req->cmd_req_len: %u\n", req->cmd_req_len);
+		dprintf(CRITICAL, "req->resp_len: %u\n", req->resp_len);
+		return GENERIC_ERROR;
+	}
+
+	if ((req->cmd_req_len + req->resp_len) > (RPMB_SND_RCV_BUF_SZ * 1024 * 1024)) {
+		dprintf(CRITICAL, "%s:Cmd + Rsp len greater than TA buf\n", __func__);
+		dprintf(CRITICAL, "req->cmd_req_len: %u\n", req->cmd_req_len);
+		dprintf(CRITICAL, "req->resp_len: %u\n", req->resp_len);
+		return GENERIC_ERROR;
+	}
 
 	/* The req rsp buffer will be xPU protected by TZ during a TZ APP call
 	 * This will still be protected during a listener call and there is a
@@ -883,8 +893,6 @@
 		return GENERIC_ERROR;
 	}
 
-	memscpy(buf, ROUNDUP(size, PAGE_SIZE), req->cmd_req_buf, req->cmd_req_len);
-
 	send_data_req.qsee_cmd_id = QSEE_CLIENT_SEND_DATA_COMMAND;
 	send_data_req.app_id = app_id;
 
@@ -893,14 +901,20 @@
 	 */
 	send_data_req.req_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
 	send_data_req.req_len = req->cmd_req_len;
-	send_data_req.rsp_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t) buf);
+	size = ROUNDUP(req->cmd_req_len, PAGE_SIZE);
+	rsp_buf_temp = (uint8_t *)buf + size;
+	send_data_req.rsp_ptr = (uint32_t)__qseecom_uvirt_to_kphys((uint32_t)rsp_buf_temp);
 	send_data_req.rsp_len = req->resp_len;
 
+	memscpy(buf, (RPMB_SND_RCV_BUF_SZ * 1024 * 1024), req->cmd_req_buf, req->cmd_req_len);
+	memscpy(rsp_buf_temp, req->resp_len, req->resp_buf, req->resp_len);
+
 	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
 				(void *)&send_data_req,
 				sizeof(send_data_req), (void *)&resp, sizeof(resp));
 
-	memscpy(req->resp_buf, req->resp_len, (void *)send_data_req.rsp_ptr, send_data_req.rsp_len);
+	memscpy(req->cmd_req_buf, req->cmd_req_len, (void *)buf, send_data_req.req_len);
+	memscpy(req->resp_buf, req->resp_len, (void *)rsp_buf_temp, send_data_req.rsp_len);
 	return ret;
 }
 
@@ -946,6 +960,16 @@
 					__func__, ret);
 			goto err;
 		}
+                dprintf(DEBUG, "Loading cmnlib done\n");
+#if ENABLE_CMNLIB64_LOADING
+                ret = qseecom_load_commonlib_image("cmnlib64");
+                if (ret) {
+                        dprintf(CRITICAL, "%s qseecom_load_commonlib_image failed with status:%d\n",
+                                        __func__, ret);
+                        goto err;
+                }
+                dprintf(DEBUG, "Loading cmnlib64 done\n");
+#endif
 		qseecom.cmnlib_loaded = 1;
 	}
 	/* Check if App already exits, if exits increase ref_cnt
diff --git a/platform/msm_shared/qusb2_phy.c b/platform/msm_shared/qusb2_phy.c
index 8981df7..edc0ecc 100644
--- a/platform/msm_shared/qusb2_phy.c
+++ b/platform/msm_shared/qusb2_phy.c
@@ -49,6 +49,11 @@
 	/* Default tune value */
 	uint8_t tune2 = 0xB3;
 
+	/* Disable the ref clock before phy reset */
+#if GCC_RX2_USB2_CLKREF_EN
+	writel((readl(GCC_RX2_USB2_CLKREF_EN) & ~0x1), GCC_RX2_USB2_CLKREF_EN);
+	dmb();
+#endif
 	/* Block Reset */
 	val = readl(GCC_QUSB2_PHY_BCR) | BIT(0);
 	writel(val, GCC_QUSB2_PHY_BCR);
@@ -113,4 +118,16 @@
 	/* Enable PHY */
 	/* set CLAMP_N_EN and USB PHY is enabled*/
 	writel(0x22, QUSB2PHY_PORT_POWERDOWN);
+	udelay(150);
+
+	/* Check PLL status */
+	if (!(readl(QUSB2PHY_PLL_STATUS) & QUSB2PHY_PLL_LOCK))
+	{
+		dprintf(CRITICAL, "QUSB2PHY failed to lock: %d", readl(QUSB2PHY_PLL_STATUS));
+	}
+
+#if GCC_RX2_USB2_CLKREF_EN
+	writel((readl(GCC_RX2_USB2_CLKREF_EN) | 0x1), GCC_RX2_USB2_CLKREF_EN);
+	dmb();
+#endif
 }
diff --git a/project/msm8996.mk b/project/msm8996.mk
index 7f47670..4d2953f 100644
--- a/project/msm8996.mk
+++ b/project/msm8996.mk
@@ -46,6 +46,8 @@
 DEFINES += USE_BOOTDEV_CMDLINE=1
 DEFINES += USE_RPMB_FOR_DEVINFO=1
 DEFINES += ENABLE_WBC=1
+#Enable below flag to compile cmnlib64
+#DEFINES += ENABLE_CMNLIB64_LOADING=1
 
 #Disable thumb mode
 ENABLE_THUMB := false
diff --git a/target/msm8952/oem_panel.c b/target/msm8952/oem_panel.c
index 30a56e9..114fa41 100644
--- a/target/msm8952/oem_panel.c
+++ b/target/msm8952/oem_panel.c
@@ -38,6 +38,7 @@
 #include <mdp5.h>
 #include <target/display.h>
 
+#include "gcdb_display.h"
 #include "include/panel.h"
 #include "panel_display.h"
 
@@ -132,6 +133,7 @@
 			struct mdss_dsi_phy_ctrl *phy_db)
 {
 	int pan_type = PANEL_TYPE_DSI;
+	struct oem_panel_data *oem_data = mdss_dsi_get_oem_data_ptr();
 
 	switch (panel_id) {
 	case TRULY_1080P_VIDEO_PANEL:
@@ -359,9 +361,27 @@
 		panelstruct->paneltiminginfo->tclk_post = 0x04;
 		panelstruct->paneltiminginfo->tclk_pre = 0x20;
 		pinfo->mipi.tx_eot_append = true;
+
+		panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG;
+		panelstruct->config = &nt35597_wqxga_dsc_video_config0;
+		if (oem_data) {
+			switch (oem_data->cfg_num[0]) {
+			case -1: /* default */
+			case 0:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_video_config0;
+				break;
+			default:
+				dprintf(CRITICAL, "topology config%d not supported. fallback to default config0\n",
+					oem_data->cfg_num[0]);
+				panelstruct->config = &nt35597_wqxga_dsc_video_config0;
+			}
+		}
+		pinfo->lm_split[0] = panelstruct->config->lm_split[0];
+		pinfo->lm_split[1] = panelstruct->config->lm_split[1];
+		pinfo->num_dsc_enc = panelstruct->config->num_dsc_enc;
 		pinfo->compression_mode = COMPRESSION_DSC;
-		memcpy(&panelstruct->dsc_paras, &nt35597_wqxga_dsc_video_paras,
-				sizeof(struct dsc_parameters));
+
 		pinfo->dsc.parameter_calc =  mdss_dsc_parameters_calc;
 		pinfo->dsc.dsc2buf = mdss_dsc_to_buf;
 		pinfo->dsc.dsi_dsc_config = mdss_dsc_dsi_config;
@@ -398,9 +418,27 @@
 		panelstruct->paneltiminginfo->tclk_post = 0x04;
 		panelstruct->paneltiminginfo->tclk_pre = 0x20;
 		pinfo->mipi.tx_eot_append = true;
+
+		panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG;
+		panelstruct->config = &nt35597_wqxga_dsc_cmd_config0;
+		if (oem_data) {
+			switch (oem_data->cfg_num[0]) {
+			case -1: /* default */
+			case 0:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_cmd_config0;
+				break;
+			default:
+				dprintf(CRITICAL, "topology config%d not supported. fallback to default config0\n",
+					oem_data->cfg_num[0]);
+				panelstruct->config = &nt35597_wqxga_dsc_cmd_config0;
+			}
+		}
+		pinfo->lm_split[0] = panelstruct->config->lm_split[0];
+		pinfo->lm_split[1] = panelstruct->config->lm_split[1];
+		pinfo->num_dsc_enc = panelstruct->config->num_dsc_enc;
 		pinfo->compression_mode = COMPRESSION_DSC;
-		memcpy(&panelstruct->dsc_paras, &nt35597_wqxga_dsc_cmd_paras,
-				sizeof(struct dsc_parameters));
+
 		pinfo->dsc.parameter_calc =  mdss_dsc_parameters_calc;
 		pinfo->dsc.dsc2buf = mdss_dsc_to_buf;
 		pinfo->dsc.dsi_dsc_config = mdss_dsc_dsi_config;
@@ -444,6 +482,11 @@
 		pan_type = PANEL_TYPE_UNKNOWN;
 		break;
 	}
+
+	dprintf(SPEW, "lm_split[0]=%d lm_split[1]=%d mode=0x%x\n",
+		pinfo->lm_split[0], pinfo->lm_split[1],
+		panelstruct->paneldata->panel_operating_mode);
+
 	return pan_type;
 }
 
diff --git a/target/msm8996/oem_panel.c b/target/msm8996/oem_panel.c
index 1a57835..8e98d95 100644
--- a/target/msm8996/oem_panel.c
+++ b/target/msm8996/oem_panel.c
@@ -37,6 +37,7 @@
 #include <qtimer.h>
 #include <platform.h>
 
+#include "gcdb_display.h"
 #include "include/panel.h"
 #include "target/display.h"
 #include "panel_display.h"
@@ -115,6 +116,7 @@
 			struct mdss_dsi_phy_ctrl *phy_db)
 {
 	int pan_type;
+	struct oem_panel_data *oem_data = mdss_dsi_get_oem_data_ptr();
 
 	switch (panel_id) {
 	case SHARP_WQXGA_DUALDSI_VIDEO_PANEL:
@@ -151,6 +153,32 @@
 			MAX_TIMING_CONFIG * sizeof(uint32_t));
 		pinfo->dfps.panel_dfps = sharp_wqxga_dualdsi_video_dfps;
 		pinfo->mipi.tx_eot_append = true;
+
+		/*
+		 * remove DUAL_PIPE_FLAG because on this target for this panel,
+		 * it will be added based on one of the selected configurations.
+		 */
+		panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG;
+		panelstruct->config = &sharp_wqxga_dualdsi_video_config0;
+		if (oem_data) {
+			switch (oem_data->cfg_num[0]) {
+			case -1: /* default */
+			case 0:
+				panelstruct->config =
+					&sharp_wqxga_dualdsi_video_config0;
+				break;
+			case 1:
+				panelstruct->config =
+					&sharp_wqxga_dualdsi_video_config1;
+				break;
+			default:
+				dprintf(CRITICAL, "topology config%d not supported. fallback to default config0\n",
+					oem_data->cfg_num[0]);
+				panelstruct->config = &sharp_wqxga_dualdsi_video_config0;
+			}
+		}
+		pinfo->lm_split[0] = panelstruct->config->lm_split[0];
+		pinfo->lm_split[1] = panelstruct->config->lm_split[1];
 		break;
 	case NT35597_WQXGA_DUALDSI_VIDEO_PANEL:
 		pan_type = PANEL_TYPE_DSI;
@@ -182,6 +210,32 @@
 			nt35597_wqxga_dualdsi_thulium_video_timings,
 			MAX_TIMING_CONFIG * sizeof(uint32_t));
 		pinfo->mipi.tx_eot_append = true;
+
+		/*
+		 * remove DUAL_PIPE_FLAG because on this target for this panel,
+		 * it will be added based on one of the selected configurations.
+		 */
+		panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG;
+		panelstruct->config = &nt35597_wqxga_dualdsi_video_config0;
+		if (oem_data) {
+			switch (oem_data->cfg_num[0]) {
+			case -1: /* default */
+			case 0:
+				panelstruct->config =
+					&nt35597_wqxga_dualdsi_video_config0;
+				break;
+			case 1:
+				panelstruct->config =
+					&nt35597_wqxga_dualdsi_video_config1;
+				break;
+			default:
+				dprintf(CRITICAL, "topology config%d not supported. fallback to default config0\n",
+					oem_data->cfg_num[0]);
+				panelstruct->config = &nt35597_wqxga_dualdsi_video_config0;
+			}
+		}
+		pinfo->lm_split[0] = panelstruct->config->lm_split[0];
+		pinfo->lm_split[1] = panelstruct->config->lm_split[1];
 		break;
 	case NT35597_WQXGA_DUALDSI_CMD_PANEL:
 		pan_type = PANEL_TYPE_DSI;
@@ -213,6 +267,32 @@
 			nt35597_wqxga_dualdsi_thulium_cmd_timings,
 			MAX_TIMING_CONFIG * sizeof(uint32_t));
 		pinfo->mipi.tx_eot_append = true;
+
+		/*
+		 * remove DUAL_PIPE_FLAG because on this target for this panel,
+		 * it will be added based on one of the selected configurations.
+		 */
+		panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG;
+		panelstruct->config = &nt35597_wqxga_dualdsi_cmd_config0;
+		if (oem_data) {
+			switch (oem_data->cfg_num[0]) {
+			case -1: /* default */
+			case 0:
+				panelstruct->config =
+					&nt35597_wqxga_dualdsi_cmd_config0;
+				break;
+			case 1:
+				panelstruct->config =
+					&nt35597_wqxga_dualdsi_cmd_config1;
+				break;
+			default:
+				dprintf(CRITICAL, "topology config%d not supported. fallback to default config0\n",
+					oem_data->cfg_num[0]);
+				panelstruct->config = &nt35597_wqxga_dualdsi_cmd_config0;
+			}
+		}
+		pinfo->lm_split[0] = panelstruct->config->lm_split[0];
+		pinfo->lm_split[1] = panelstruct->config->lm_split[1];
 		break;
 	case NT35597_WQXGA_DSC_VIDEO_PANEL:
 		pan_type = PANEL_TYPE_DSI;
@@ -245,9 +325,38 @@
 			MAX_TIMING_CONFIG * sizeof(uint32_t));
 		pinfo->mipi.tx_eot_append = true;
 
+		/*
+		 * remove DUAL_PIPE_FLAG because on this target for this panel,
+		 * it will be added based on one of the selected configurations.
+		 */
+		panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG;
+		panelstruct->config = &nt35597_wqxga_dsc_video_config2;
+		if (oem_data) {
+			switch (oem_data->cfg_num[0]) {
+			case -1: /* default */
+			case 0:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_video_config0;
+				break;
+			case 1:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_video_config1;
+				break;
+			case 2:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_video_config2;
+				break;
+			default:
+				dprintf(CRITICAL, "topology config%d not supported. fallback to default config2\n",
+					oem_data->cfg_num[0]);
+				panelstruct->config = &nt35597_wqxga_dsc_video_config2;
+			}
+		}
+		pinfo->lm_split[0] = panelstruct->config->lm_split[0];
+		pinfo->lm_split[1] = panelstruct->config->lm_split[1];
+		pinfo->num_dsc_enc = panelstruct->config->num_dsc_enc;
+
 		pinfo->compression_mode = COMPRESSION_DSC;
-		memcpy(&panelstruct->dsc_paras, &nt35597_wqxga_dsc_video_paras,
-				sizeof(struct dsc_parameters));
 		pinfo->dsc.parameter_calc =  mdss_dsc_parameters_calc;
 		pinfo->dsc.dsc2buf = mdss_dsc_to_buf;
 		pinfo->dsc.dsi_dsc_config = mdss_dsc_dsi_config;
@@ -284,9 +393,39 @@
 			MAX_TIMING_CONFIG * sizeof(uint32_t));
 		pinfo->mipi.tx_eot_append = true;
 
+		/*
+		 * remove DUAL_PIPE_FLAG because on this target for this panel,
+		 * it will be added based on one of the selected configurations.
+		 */
+		panelstruct->paneldata->panel_operating_mode &= ~DUAL_PIPE_FLAG;
+		panelstruct->config = &nt35597_wqxga_dsc_cmd_config2;
+		if (oem_data) {
+			switch (oem_data->cfg_num[0]) {
+			case 0:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_cmd_config0;
+				break;
+			case 1:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_cmd_config1;
+				break;
+			case -1: /* default */
+			case 2:
+				panelstruct->config =
+					&nt35597_wqxga_dsc_cmd_config2;
+				break;
+			default:
+				dprintf(CRITICAL, "topology config%d not supported. fallback to default config2\n",
+					oem_data->cfg_num[0]);
+				panelstruct->config = &nt35597_wqxga_dsc_cmd_config2;
+			}
+		}
+
+		pinfo->lm_split[0] = panelstruct->config->lm_split[0];
+		pinfo->lm_split[1] = panelstruct->config->lm_split[1];
+		pinfo->num_dsc_enc = panelstruct->config->num_dsc_enc;
+
 		pinfo->compression_mode = COMPRESSION_DSC;
-		memcpy(&panelstruct->dsc_paras, &nt35597_wqxga_dsc_cmd_paras,
-				sizeof(struct dsc_parameters));
 		pinfo->dsc.parameter_calc =  mdss_dsc_parameters_calc;
 		pinfo->dsc.dsc2buf = mdss_dsc_to_buf;
 		pinfo->dsc.dsi_dsc_config = mdss_dsc_dsi_config;
@@ -417,6 +556,11 @@
 		pan_type = PANEL_TYPE_UNKNOWN;
 		break;
 	}
+
+	dprintf(SPEW, "lm_split[0]=%d lm_split[1]=%d mode=0x%x\n",
+		pinfo->lm_split[0], pinfo->lm_split[1],
+		panelstruct->paneldata->panel_operating_mode);
+
 	return pan_type;
 }