Merge "target: msm8996: Make HDMI as primary by default for APQ8096"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index fc41a24..09ba226 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -143,6 +143,14 @@
 
 #define ADD_OF(a, b) (UINT_MAX - b > a) ? (a + b) : UINT_MAX
 
+//Size of the header that is used in case the boot image has
+//a uncompressed kernel + appended dtb
+#define PATCHED_KERNEL_HEADER_SIZE 20
+
+//String used to determine if the boot image has
+//a uncompressed kernel + appended dtb
+#define PATCHED_KERNEL_MAGIC "UNCOMPRESSED_IMG"
+
 #if USE_BOOTDEV_CMDLINE
 static const char *emmc_cmdline = " androidboot.bootdevice=";
 #else
@@ -168,6 +176,7 @@
 static const char *baseband_dsda2   = " androidboot.baseband=dsda2";
 static const char *baseband_sglte2  = " androidboot.baseband=sglte2";
 static const char *warmboot_cmdline = " qpnp-power-on.warm_boot=1";
+static const char *baseband_apq_nowgr   = " androidboot.baseband=baseband_apq_nowgr";
 
 #if VERIFIED_BOOT
 #if !VBOOT_MOTA
@@ -434,6 +443,9 @@
 		case BASEBAND_DSDA2:
 			cmdline_len += strlen(baseband_dsda2);
 			break;
+		case BASEBAND_APQ_NOWGR:
+			cmdline_len += strlen(baseband_apq_nowgr);
+			break;
 	}
 
 	if (cmdline) {
@@ -623,6 +635,11 @@
 				if (have_cmdline) --dst;
 				while ((*dst++ = *src++));
 				break;
+			case BASEBAND_APQ_NOWGR:
+				src = baseband_apq_nowgr;
+				if (have_cmdline) --dst;
+				while ((*dst++ = *src++));
+				break;
 		}
 
 		if (strlen(display_panel_buf)) {
@@ -1069,8 +1086,8 @@
 	uint32_t dtb_offset = 0;
 	unsigned char *kernel_start_addr = NULL;
 	unsigned int kernel_size = 0;
+	unsigned int patched_kernel_hdr_size = 0;
 	int rc;
-
 #if DEVICE_TREE
 	struct dt_table *table;
 	struct dt_entry dt_entry;
@@ -1295,9 +1312,30 @@
 		kernel_start_addr = out_addr;
 		kernel_size = out_len;
 	} else {
-		kptr = (struct kernel64_hdr *)(image_addr + page_size);
-		kernel_start_addr = (unsigned char *)(image_addr + page_size);
-		kernel_size = hdr->kernel_size;
+		dprintf(INFO, "Uncpmpressed kernel in use\n");
+		if (!strncmp((char*)(image_addr + page_size),
+					PATCHED_KERNEL_MAGIC,
+					sizeof(PATCHED_KERNEL_MAGIC) - 1)) {
+			dprintf(INFO, "Patched kernel detected\n");
+			kptr = (struct kernel64_hdr *)(image_addr + page_size +
+					PATCHED_KERNEL_HEADER_SIZE);
+			//The size of the kernel is stored at start of kernel image + 16
+			//The dtb would start just after the kernel
+			dtb_offset = *((uint32_t*)((unsigned char*)
+						(image_addr + page_size +
+						 sizeof(PATCHED_KERNEL_MAGIC) -
+						 1)));
+			//The actual kernel starts after the 20 byte header.
+			kernel_start_addr = (unsigned char*)(image_addr +
+					page_size + PATCHED_KERNEL_HEADER_SIZE);
+			kernel_size = hdr->kernel_size;
+			patched_kernel_hdr_size = PATCHED_KERNEL_HEADER_SIZE;
+		} else {
+			dprintf(INFO, "Kernel image not patched..Unable to locate dt offset\n");
+			kptr = (struct kernel64_hdr *)(image_addr + page_size);
+			kernel_start_addr = (unsigned char *)(image_addr + page_size);
+			kernel_size = hdr->kernel_size;
+		}
 	}
 
 	/*
@@ -1410,9 +1448,11 @@
 		 * Else update with the atags address in the kernel header
 		 */
 		void *dtb;
-		dtb = dev_tree_appended((void*)(image_addr + page_size),
-					hdr->kernel_size, dtb_offset,
-					(void *)hdr->tags_addr);
+		dtb = dev_tree_appended(
+				(void*)(image_addr + page_size +
+					patched_kernel_hdr_size),
+				hdr->kernel_size, dtb_offset,
+				(void *)hdr->tags_addr);
 		if (!dtb) {
 			dprintf(CRITICAL, "ERROR: Appended Device Tree Blob not found\n");
 			return -1;
@@ -3805,7 +3845,6 @@
 		page_size = flash_page_size();
 		page_mask = page_size - 1;
 	}
-
 	ASSERT((MEMBASE + MEMSIZE) > MEMBASE);
 
 	read_device_info(&device);
diff --git a/platform/msm_shared/include/baseband.h b/platform/msm_shared/include/baseband.h
index 64dde97..a1ed9ca 100644
--- a/platform/msm_shared/include/baseband.h
+++ b/platform/msm_shared/include/baseband.h
@@ -41,6 +41,7 @@
 	BASEBAND_DSDA2 = 8,
 	BASEBAND_SGLTE2 = 9,
 	BASEBAND_MDM2 = 10,
+	BASEBAND_APQ_NOWGR = 11,
 	BASEBAND_32BITS = 0x7FFFFFFF
 };
 
diff --git a/platform/msm_shared/include/mipi_dsi_autopll_thulium.h b/platform/msm_shared/include/mipi_dsi_autopll_thulium.h
index bac4776..622dba0 100644
--- a/platform/msm_shared/include/mipi_dsi_autopll_thulium.h
+++ b/platform/msm_shared/include/mipi_dsi_autopll_thulium.h
@@ -59,6 +59,7 @@
 
 #define DSIPHY_PLL_KVCO_COUNT1		0x0448
 #define DSIPHY_PLL_KVCO_COUNT2		0x044c
+#define DSIPHY_PLL_KVCO_CODE		0x0458
 
 #define DSIPHY_PLL_VCO_DIV_REF1		0x046c
 #define DSIPHY_PLL_VCO_DIV_REF2		0x0470
@@ -70,6 +71,13 @@
 #define DSIPHY_PLL_PLLLOCK_CMP_EN	0x0488
 
 #define DSIPHY_PLL_DEC_START		0x0490
+#define DSIPHY_PLL_SSC_EN_CENTER	0x0494
+#define DSIPHY_PLL_SSC_ADJ_PER1		0x0498
+#define DSIPHY_PLL_SSC_ADJ_PER2		0x049c
+#define DSIPHY_PLL_SSC_PER1		0x04a0
+#define DSIPHY_PLL_SSC_PER2		0x04a4
+#define DSIPHY_PLL_SSC_STEP_SIZE1	0x04a8
+#define DSIPHY_PLL_SSC_STEP_SIZE2	0x04ac
 #define DSIPHY_PLL_DIV_FRAC_START1	0x04b4
 #define DSIPHY_PLL_DIV_FRAC_START2	0x04b8
 #define DSIPHY_PLL_DIV_FRAC_START3	0x04bc
diff --git a/platform/msm_shared/mipi_dsi.c b/platform/msm_shared/mipi_dsi.c
index 1e768ad..44fb235 100644
--- a/platform/msm_shared/mipi_dsi.c
+++ b/platform/msm_shared/mipi_dsi.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2016, 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
@@ -317,6 +317,22 @@
 	return err;
 }
 
+static void mdss_dsi_force_clk_lane_hs(struct mipi_panel_info *mipi,
+		uint32_t dual_dsi)
+{
+	uint32_t tmp;
+
+	if (dual_dsi) {
+		tmp = readl(mipi->sctl_base + LANE_CTL);
+		tmp |= BIT(28);
+		writel(tmp, mipi->sctl_base + LANE_CTL);
+	}
+
+	tmp = readl(mipi->ctl_base + LANE_CTL);
+	tmp |= BIT(28);
+	writel(tmp, mipi->ctl_base + LANE_CTL);
+}
+
 int mdss_dsi_host_init(struct mipi_panel_info *mipi, uint32_t
 		dual_dsi, uint32_t broadcast)
 {
@@ -382,14 +398,6 @@
 		writel(lane_swap_dsi1, mipi->sctl_base + LANE_SWAP_CTL);
 		writel(timing_ctl, mipi->sctl_base + TIMING_CTL);
 
-		if (mipi->force_clk_lane_hs) {
-			uint32_t tmp;
-
-			tmp = readl(mipi->sctl_base + LANE_CTL);
-			tmp |= BIT(28);
-			writel(tmp, mipi->sctl_base + LANE_CTL);
-		}
-
 		if ((mipi->mode == DSI_CMD_MODE) &&
 				(readl(mipi->sctl_base) >= DSI_HW_REV_103)) {
 			uint32_t tmp;
@@ -414,14 +422,6 @@
 	writel(lane_swap, mipi->ctl_base + LANE_SWAP_CTL);
 	writel(timing_ctl, mipi->ctl_base + TIMING_CTL);
 
-	if (mipi->force_clk_lane_hs) {
-		uint32_t tmp;
-
-		tmp = readl(mipi->ctl_base + LANE_CTL);
-		tmp |= BIT(28);
-		writel(tmp, mipi->ctl_base + LANE_CTL);
-	}
-
 	if ((mipi->mode == DSI_CMD_MODE) &&
 			(readl(mipi->ctl_base) >= DSI_HW_REV_103)) {
 		uint32_t tmp;
@@ -677,6 +677,9 @@
 		}
 	}
 
+	if (mipi->force_clk_lane_hs)
+		mdss_dsi_force_clk_lane_hs(mipi, mipi->dual_dsi);
+
 	if (!mipi->cmds_post_tg) {
 		ret = mdss_dsi_panel_initialize(mipi, mipi->broadcast);
 		if (ret) {
diff --git a/platform/msm_shared/mipi_dsi_autopll_thulium.c b/platform/msm_shared/mipi_dsi_autopll_thulium.c
index 706a5ce..4b2bfb0 100644
--- a/platform/msm_shared/mipi_dsi_autopll_thulium.c
+++ b/platform/msm_shared/mipi_dsi_autopll_thulium.c
@@ -44,12 +44,14 @@
 
 #define VCO_REF_CLK_RATE 19200000
 
+#define CEIL(x, y)              (((x) + ((y)-1)) / (y))
+
 static void mdss_mdp_pll_input_init(struct dsi_pll_db *pdb)
 {
 	pdb->in.fref = 19200000;	/* 19.2 Mhz*/
 	pdb->in.fdata = 0;		/* bit clock rate */
 	pdb->in.dsiclk_sel = 1;		/* 1, reg: 0x0014 */
-	pdb->in.ssc_en = 0;		/* 1, reg: 0x0494, bit 0 */
+	pdb->in.ssc_en = 1;		/* 1, reg: 0x0494, bit 0 */
 	pdb->in.ldo_en = 0;		/* 0,  reg: 0x004c, bit 0 */
 
 	/* fixed  input */
@@ -119,6 +121,39 @@
 	pdb->out.cmn_ldo_cntrl = 0x3c;
 }
 
+static void mdss_mdp_pll_ssc_calc(struct dsi_pll_db *pdb,
+	uint32_t vco_clk_rate, uint32_t fref)
+{
+	uint32_t period, ssc_period;
+	uint32_t ref, rem;
+	uint64_t step_size;
+
+	ssc_period = pdb->in.ssc_freq / 500;
+	period = (unsigned long)fref / 1000;
+	ssc_period  = CEIL(period, ssc_period);
+	ssc_period -= 1;
+	pdb->out.ssc_per = ssc_period;
+
+	step_size = vco_clk_rate;
+	ref = fref;
+
+	ref /= 1000;
+	step_size /= ref;
+	step_size <<= 20;
+	step_size /= 1000;
+	step_size *= pdb->in.ssc_spread;
+	step_size /= 1000;
+	step_size *= (pdb->in.ssc_adj_per + 1);
+
+	rem = 0;
+	rem = step_size % (ssc_period + 1);
+	if (rem)
+		step_size++;
+
+	step_size &= 0x0ffff;   /* take lower 16 bits */
+	pdb->out.ssc_step_size = step_size;
+}
+
 static uint32_t mdss_mdp_pll_kvco_slop(uint32_t vrate)
 {
 	uint32_t slop = 0;
@@ -133,6 +168,22 @@
 	return slop;
 }
 
+static inline uint32_t mdss_mdp_pll_calc_kvco_code(uint32_t vco_clk_rate)
+{
+	uint32_t kvco_code;
+
+	if ((vco_clk_rate >= 2300000000ULL) &&
+	    (vco_clk_rate <= 2600000000ULL))
+		kvco_code = 0x2f;
+	else if ((vco_clk_rate >= 1800000000ULL) &&
+		 (vco_clk_rate < 2300000000ULL))
+		kvco_code = 0x2c;
+	else
+		kvco_code = 0x28;
+
+	return kvco_code;
+}
+
 static void mdss_mdp_pll_calc_vco_count(struct dsi_pll_db *pdb,
 	uint32_t vco_clk_rate, uint32_t fref)
 {
@@ -166,7 +217,7 @@
 	pdb->out.pll_resetsm_cntrl = 48;
 	pdb->out.pll_resetsm_cntrl2 = pdb->in.bandgap_timer << 3;
 	pdb->out.pll_resetsm_cntrl5 = pdb->in.pll_wakeup_timer;
-	pdb->out.pll_kvco_code = 0;
+	pdb->out.pll_kvco_code = mdss_mdp_pll_calc_kvco_code(vco_clk_rate);
 }
 
 static void mdss_mdp_pll_assert_and_div_cfg(uint32_t phy_base,
@@ -291,6 +342,9 @@
 	data &= 0x03;
 	writel(data, phy_base + DSIPHY_PLL_KVCO_COUNT2);
 
+	data = pdb->out.pll_kvco_code;
+	writel(data, phy_base + DSIPHY_PLL_KVCO_CODE);
+
 	/*
 	 * tx_band = pll_postdiv
 	 * 0: divided by 1 <== for now
@@ -311,6 +365,37 @@
 	dmb();	/* make sure register committed */
 }
 
+static void mdss_mdp_pll_ssc_config(uint32_t phy_base, struct dsi_pll_db *pdb)
+{
+	uint32_t data;
+
+	data = pdb->in.ssc_adj_per;
+	data &= 0x0ff;
+	writel(data, phy_base + DSIPHY_PLL_SSC_ADJ_PER1);
+	data = (pdb->in.ssc_adj_per >> 8);
+	data &= 0x03;
+	writel(data, phy_base + DSIPHY_PLL_SSC_ADJ_PER2);
+
+	data = pdb->out.ssc_per;
+	data &= 0x0ff;
+	writel(data, phy_base + DSIPHY_PLL_SSC_PER1);
+	data = (pdb->out.ssc_per >> 8);
+	data &= 0x0ff;
+	writel(data, phy_base + DSIPHY_PLL_SSC_PER2);
+
+	data = pdb->out.ssc_step_size;
+	data &= 0x0ff;
+	writel(data, phy_base + DSIPHY_PLL_SSC_STEP_SIZE1);
+	data = (pdb->out.ssc_step_size >> 8);
+	data &= 0x0ff;
+	writel(data, phy_base + DSIPHY_PLL_SSC_STEP_SIZE2);
+
+	data = (pdb->in.ssc_center_spread & 0x01);
+	data <<= 1;
+	data |= 0x01; /* enable */
+	writel(data, phy_base + DSIPHY_PLL_SSC_EN_CENTER);
+}
+
 static int mdss_dsi_phy_14nm_init(struct msm_panel_info *pinfo,
 	uint32_t phy_base)
 {
@@ -417,6 +502,9 @@
 	pdb.out.pll_n2div = pll_data->n2div;
 
 	mdss_mdp_pll_dec_frac_calc(&pdb, pll_data->vco_clock, VCO_REF_CLK_RATE);
+	if (pdb.in.ssc_en)
+		mdss_mdp_pll_ssc_calc(&pdb, pll_data->vco_clock,
+			VCO_REF_CLK_RATE);
 	mdss_mdp_pll_calc_vco_count(&pdb, pll_data->vco_clock, VCO_REF_CLK_RATE);
 
 	/* de-assert pll and start */
@@ -428,9 +516,13 @@
 	/* configure frequence */
 	mdss_mdp_pll_nonfreq_config(phy_base, &pdb);
 	mdss_mdp_pll_freq_config(phy_base, &pdb);
+	if (pdb.in.ssc_en)
+		mdss_mdp_pll_ssc_config(phy_base, &pdb);
 
 	if (pinfo->lcdc.split_display) {
 		mdss_mdp_pll_nonfreq_config(phy_1_base, &pdb);
 		mdss_mdp_pll_freq_config(phy_1_base, &pdb);
+		if (pdb.in.ssc_en)
+			mdss_mdp_pll_ssc_config(phy_1_base, &pdb);
 	}
 }
diff --git a/platform/msm_shared/scm.c b/platform/msm_shared/scm.c
index 05b5b6c..7f19b04 100644
--- a/platform/msm_shared/scm.c
+++ b/platform/msm_shared/scm.c
@@ -1107,6 +1107,8 @@
 		scm_arg.x2 = (uint32_t) rand_buf;
 		scm_arg.x3 = r_len;
 
+		arch_clean_invalidate_cache_range((addr_t) rand_buf, r_len);
+
 		ret = scm_call2(&scm_arg, NULL);
 		if (!ret)
 			arch_clean_invalidate_cache_range((addr_t) rand_buf, r_len);
diff --git a/target/msm8909/init.c b/target/msm8909/init.c
index 67aadfd..525d4c4 100644
--- a/target/msm8909/init.c
+++ b/target/msm8909/init.c
@@ -67,6 +67,7 @@
 #if PON_VIB_SUPPORT
 #define VIBRATE_TIME    250
 #endif
+#define HW_SUBTYPE_APQ_NOWGR 0xA
 
 #define CE1_INSTANCE            1
 #define CE_EE                   1
@@ -425,7 +426,11 @@
 		break;
 
 	case APQ8009:
-		board->baseband = BASEBAND_APQ;
+		if ((board->platform_hw == HW_PLATFORM_MTP) &&
+				(board->platform_subtype == HW_SUBTYPE_APQ_NOWGR))
+			board->baseband = BASEBAND_APQ_NOWGR;
+		else
+			board->baseband = BASEBAND_APQ;
 		break;
 
 	default:
@@ -472,40 +477,41 @@
         splash_override = override;
 }
 
+/*Update this command line only for LE based builds*/
 int get_target_boot_params(const char *cmdline, const char *part, char **buf)
 {
 	struct ptable *ptable;
 	int system_ptn_index = -1;
-	uint32_t buflen;
+	int le_based = -1;
 
-	if (!target_is_emmc_boot()) {
-		if (!cmdline || !part || !buf || buflen < 0) {
-			dprintf(CRITICAL, "WARN: Invalid input param\n");
-			return -1;
-		}
-		buflen = strlen(" root=/dev/mtdblock") + sizeof(int) + 1; /*1 character for null termination*/
-		*buf = (char *)malloc(buflen);
-		if(!(*buf)) {
-			dprintf(CRITICAL,"Unable to allocate memory for boot params\n");
-			return -1;
-		}
+	/*LE partition.xml will have recoveryfs partition*/
+	if (target_is_emmc_boot())
+		le_based = partition_get_index("recoveryfs");
+	else
+		/*Nand targets by default have this*/
+		le_based = 1;
 
-		ptable = flash_get_ptable();
-		if (!ptable) {
-			dprintf(CRITICAL,
-				"WARN: Cannot get flash partition table\n");
-			free(*buf);
-			return -1;
+	if (le_based != -1)
+	{
+		if (!target_is_emmc_boot())
+		{
+			ptable = flash_get_ptable();
+			if (!ptable)
+			{
+				dprintf(CRITICAL,
+					"WARN: Cannot get flash partition table\n");
+				return -1;
+			}
+			system_ptn_index = ptable_get_index(ptable, part);
 		}
-
-		system_ptn_index = ptable_get_index(ptable, part);
+		else
+			system_ptn_index = partition_get_index(part);
 		if (system_ptn_index < 0) {
 			dprintf(CRITICAL,
 				"WARN: Cannot get partition index for %s\n", part);
 			free(*buf);
 			return -1;
 		}
-
 		/*
 		* check if cmdline contains "root=" at the beginning of buffer or
 		* " root=" in the middle of buffer.
@@ -514,11 +520,15 @@
 			(strstr(cmdline, " root="))))
 			dprintf(DEBUG, "DEBUG: cmdline has root=\n");
 		else
-			snprintf(*buf, buflen, " root=/dev/mtdblock%d",
-                                 system_ptn_index);
 		/*in success case buf will be freed in the calling function of this*/
+		{
+			if (!target_is_emmc_boot())
+				snprintf(buf, buflen, " root=/dev/mtdblock%d",system_ptn_index);
+			else
+				/*For Emmc case increase the ptn_index by 1*/
+				snprintf(buf, buflen, " root=/dev/mmcblk0p%d",system_ptn_index + 1);
+		}
 	}
-
 	return 0;
 }
 
diff --git a/target/msm8952/target_display.c b/target/msm8952/target_display.c
index 6749bf8..bcbf1be 100644
--- a/target/msm8952/target_display.c
+++ b/target/msm8952/target_display.c
@@ -433,13 +433,14 @@
 	return ret;
 }
 
-static void wled_init(struct msm_panel_info *pinfo)
+static int wled_init(struct msm_panel_info *pinfo)
 {
 	struct qpnp_wled_config_data config = {0};
 	struct labibb_desc *labibb;
 	int display_type = 0;
 	bool swire_control = 0;
 	bool wled_avdd_control = 0;
+	int rc = NO_ERROR;
 
 	labibb = pinfo->labibb;
 
@@ -499,7 +500,9 @@
 	/* QPNP WLED init for display backlight */
 	pm8x41_wled_config_slave_id(PMIC_WLED_SLAVE_ID);
 
-	qpnp_wled_init(&config);
+	rc = qpnp_wled_init(&config);
+
+	return rc;
 }
 
 int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
@@ -531,6 +534,7 @@
 
 int target_ldo_ctrl(uint8_t enable, struct msm_panel_info *pinfo)
 {
+	int rc = 0;
 	uint32_t ldo_num = REG_LDO6 | REG_LDO17;
 
 	if (platform_is_msm8956())
@@ -541,8 +545,16 @@
 	if (enable) {
 		regulator_enable(ldo_num);
 		mdelay(10);
-		wled_init(pinfo);
-		qpnp_ibb_enable(true); /*5V boost*/
+		rc = wled_init(pinfo);
+		if (rc) {
+			dprintf(CRITICAL, "%s: wled init failed\n", __func__);
+			return rc;
+		}
+		rc = qpnp_ibb_enable(true); /*5V boost*/
+		if (rc) {
+			dprintf(CRITICAL, "%s: qpnp_ibb failed\n", __func__);
+			return rc;
+		}
 		mdelay(50);
 	} else {
 		/*