Merge "app: aboot: initialise watch dog to catch the early kernel crashes."
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index fe8e928..da32a54 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -2271,6 +2271,8 @@
 	int index = INVALID_PTN;
 	uint32_t i;
 	uint8_t lun = 0;
+	/*End of the sparse image address*/
+	uint32_t data_end = (uint32_t)data + sz;
 
 	index = partition_get_index(arg);
 	ptn = partition_get_offset(index);
@@ -2280,28 +2282,34 @@
 	}
 
 	size = partition_get_size(index);
-	if (ROUND_TO_PAGE(sz,511) > size) {
-		fastboot_fail("size too large");
-		return;
-	}
 
 	lun = partition_get_lun(index);
 	mmc_set_lun(lun);
 
+	if (sz < sizeof(sparse_header_t)) {
+		fastboot_fail("size too low");
+		return;
+	}
+
 	/* Read and skip over sparse image header */
 	sparse_header = (sparse_header_t *) data;
+
 	if (((uint64_t)sparse_header->total_blks * (uint64_t)sparse_header->blk_sz) > size) {
 		fastboot_fail("size too large");
 		return;
 	}
 
-	data += sparse_header->file_hdr_sz;
-	if(sparse_header->file_hdr_sz > sizeof(sparse_header_t))
+	data += sizeof(sparse_header_t);
+
+	if (data_end < (uint32_t)data) {
+		fastboot_fail("buffer overreads occured due to invalid sparse header");
+		return;
+	}
+
+	if(sparse_header->file_hdr_sz != sizeof(sparse_header_t))
 	{
-		/* Skip the remaining bytes in a header that is longer than
-		 * we expected.
-		 */
-		data += (sparse_header->file_hdr_sz - sizeof(sparse_header_t));
+		fastboot_fail("sparse header size mismatch");
+		return;
 	}
 
 	dprintf (SPEW, "=== Sparse Image Header ===\n");
@@ -2326,17 +2334,20 @@
 		chunk_header = (chunk_header_t *) data;
 		data += sizeof(chunk_header_t);
 
+		if (data_end < (uint32_t)data) {
+			fastboot_fail("buffer overreads occured due to invalid sparse header");
+			return;
+		}
+
 		dprintf (SPEW, "=== Chunk Header ===\n");
 		dprintf (SPEW, "chunk_type: 0x%x\n", chunk_header->chunk_type);
 		dprintf (SPEW, "chunk_data_sz: 0x%x\n", chunk_header->chunk_sz);
 		dprintf (SPEW, "total_size: 0x%x\n", chunk_header->total_sz);
 
-		if(sparse_header->chunk_hdr_sz > sizeof(chunk_header_t))
+		if(sparse_header->chunk_hdr_sz != sizeof(chunk_header_t))
 		{
-			/* Skip the remaining bytes in a header that is longer than
-			 * we expected.
-			 */
-			data += (sparse_header->chunk_hdr_sz - sizeof(chunk_header_t));
+			fastboot_fail("chunk header size mismatch");
+			return;
 		}
 
 		chunk_data_sz = sparse_header->blk_sz * chunk_header->chunk_sz;
@@ -2367,6 +2378,11 @@
 				return;
 			}
 
+			if (data_end < (uint32_t)data + chunk_data_sz) {
+				fastboot_fail("buffer overreads occured due to invalid sparse header");
+				return;
+			}
+
 			if(mmc_write(ptn + ((uint64_t)total_blocks*sparse_header->blk_sz),
 						chunk_data_sz,
 						(unsigned int*)data))
@@ -2397,6 +2413,10 @@
 				return;
 			}
 
+			if (data_end < (uint32_t)data + sizeof(uint32_t)) {
+				fastboot_fail("buffer overreads occured due to invalid sparse header");
+				return;
+			}
 			fill_val = *(uint32_t *)data;
 			data = (char *) data + sizeof(uint32_t);
 			chunk_blk_cnt = chunk_data_sz / sparse_header->blk_sz;
@@ -2449,7 +2469,15 @@
 				return;
 			}
 			total_blocks += chunk_header->chunk_sz;
+			if ((uint32_t)data > UINT_MAX - chunk_data_sz) {
+				fastboot_fail("integer overflow occured");
+				return;
+			}
 			data += chunk_data_sz;
+			if (data_end < (uint32_t)data) {
+				fastboot_fail("buffer overreads occured due to invalid sparse header");
+				return;
+			}
 			break;
 
 			default:
diff --git a/app/aboot/mdtp.c b/app/aboot/mdtp.c
index 3db1d21..578f4de 100644
--- a/app/aboot/mdtp.c
+++ b/app/aboot/mdtp.c
@@ -62,6 +62,7 @@
 
 int check_aboot_addr_range_overlap(uint32_t start, uint32_t size);
 int scm_random(uint32_t * rbuf, uint32_t  r_len);
+void free_mdtp_image(void);
 
 /********************************************************************************/
 
@@ -422,7 +423,7 @@
 				// Valid PIN - deactivate and continue boot
 				dprintf(SPEW, "mdtp: display_recovery_ui: valid PIN, continue boot\n");
 				write_deactivated_DIP();
-				return;
+				goto out;
 			}
 			else
 			{
@@ -440,6 +441,9 @@
 		dprintf(CRITICAL, "mdtp: display_recovery_ui: Local deactivation disabled, unable to display recovery UI\n");
 		display_error_msg(); /* This will never return */
 	}
+
+	out:
+	free_mdtp_image();
 }
 
 /* Verify the boot or recovery partitions using boot_verifier. */
diff --git a/app/aboot/mdtp_ui.c b/app/aboot/mdtp_ui.c
index 6200eb5..fcf7259 100644
--- a/app/aboot/mdtp_ui.c
+++ b/app/aboot/mdtp_ui.c
@@ -99,7 +99,7 @@
 
 static bool g_initial_screen_displayed = false;
 
-static struct mdtp_fbimage g_mdtp_header;
+static struct mdtp_fbimage *g_mdtp_header = NULL;
 static struct fbcon_config *fb_config = NULL;
 
 /*----------------------------------------------------------------------------
@@ -107,13 +107,33 @@
  * -------------------------------------------------------------------------*/
 
 /**
+ * Allocate mdtp image
+ */
+static void alloc_mdtp_image() {
+	if (!g_mdtp_header) {
+		g_mdtp_header = (struct mdtp_fbimage *)malloc(sizeof(struct mdtp_fbimage));
+		ASSERT(g_mdtp_header);
+	}
+}
+
+/**
+ * Free mdtp image
+ */
+void free_mdtp_image() {
+	if (g_mdtp_header) {
+		free(g_mdtp_header);
+		g_mdtp_header = NULL;
+	}
+}
+
+/**
  * Load images from EMMC
  */
 static struct mdtp_fbimage* mdtp_read_mmc_image(uint32_t offset, uint32_t width, uint32_t height)
 {
 	int index = INVALID_PTN;
 	unsigned long long ptn = 0;
-	struct mdtp_fbimage *logo = &g_mdtp_header;
+	struct mdtp_fbimage *logo = g_mdtp_header;
 	uint32_t block_size = mmc_get_device_blocksize();
 
 	index = partition_get_index("mdtp");
@@ -433,12 +453,13 @@
  */
 static void display_initial_screen(uint32_t pin_length)
 {
-    if (g_initial_screen_displayed == true)
+	if (g_initial_screen_displayed == true)
 		return;
 
-    fb_config = fbcon_display();
+	fb_config = fbcon_display();
+	alloc_mdtp_image();
 
-    if (fb_config)
+	if (fb_config)
 	{
 		fbcon_clear();
 
@@ -589,6 +610,7 @@
 void display_error_msg()
 {
 	fb_config = fbcon_display();
+	alloc_mdtp_image();
 
 	if (fb_config)
 	{
diff --git a/platform/msm8952/include/platform/clock.h b/platform/msm8952/include/platform/clock.h
index 6cda324..495914d 100644
--- a/platform/msm8952/include/platform/clock.h
+++ b/platform/msm8952/include/platform/clock.h
@@ -65,6 +65,19 @@
 #define DSI_PIXEL0_N                    REG_MM(0x4D00C)
 #define DSI_PIXEL0_D                    REG_MM(0x4D010)
 
+#define DSI_BYTE1_CMD_RCGR              REG_MM(0x4D0B0)
+#define DSI_BYTE1_CFG_RCGR              REG_MM(0x4D0B4)
+#define DSI_BYTE1_CBCR                  REG_MM(0x4D0A0)
+#define DSI_ESC1_CMD_RCGR               REG_MM(0x4D0A8)
+#define DSI_ESC1_CFG_RCGR               REG_MM(0x4D0AC)
+#define DSI_ESC1_CBCR                   REG_MM(0x4D09C)
+#define DSI_PIXEL1_CMD_RCGR             REG_MM(0x4D0B8)
+#define DSI_PIXEL1_CFG_RCGR             REG_MM(0x4D0BC)
+#define DSI_PIXEL1_CBCR                 REG_MM(0x4D0A4)
+#define DSI_PIXEL1_M                    REG_MM(0x4D0C0)
+#define DSI_PIXEL1_N                    REG_MM(0x4D0C4)
+#define DSI_PIXEL1_D                    REG_MM(0x4D0C8)
+
 void platform_clock_init(void);
 
 void clock_init_mmc(uint32_t interface);
diff --git a/platform/msm8952/include/platform/iomap.h b/platform/msm8952/include/platform/iomap.h
index 8ea20f4..68b8227 100644
--- a/platform/msm8952/include/platform/iomap.h
+++ b/platform/msm8952/include/platform/iomap.h
@@ -99,6 +99,7 @@
 #define APCS_CLOCK_BRANCH_ENA_VOTE         (CLK_CTL_BASE + 0x45004)
 #define GPLL4_MODE                         (CLK_CTL_BASE + 0x24000)
 #define GPLL4_STATUS                       (CLK_CTL_BASE + 0x24024)
+#define GPLL6_STATUS                       (CLK_CTL_BASE + 0x3701C)
 
 /* SDCC */
 #define SDC1_HDRV_PULL_CTL                 (TLMM_BASE_ADDR + 0x10A000)
@@ -149,11 +150,11 @@
 /* MDSS */
 #define MIPI_DSI_BASE               (0x1A98000)
 #define MIPI_DSI0_BASE              MIPI_DSI_BASE
-#define MIPI_DSI1_BASE              MIPI_DSI_BASE
+#define MIPI_DSI1_BASE              (0x1A96000)
 #define DSI0_PHY_BASE               (0x1A98500)
-#define DSI1_PHY_BASE               DSI0_PHY_BASE
+#define DSI1_PHY_BASE               (0x1A96400)
 #define DSI0_PLL_BASE               (0x1A98300)
-#define DSI1_PLL_BASE               DSI0_PLL_BASE
+#define DSI1_PLL_BASE               (0x1A96A00)
 #define DSI0_REGULATOR_BASE         (0x1A98780)
 #define DSI1_REGULATOR_BASE         DSI0_REGULATOR_BASE
 #define MDP_BASE                    (0x1A00000)
diff --git a/platform/msm8952/msm8952-clock.c b/platform/msm8952/msm8952-clock.c
index fd1d6f7..b87406d 100644
--- a/platform/msm8952/msm8952-clock.c
+++ b/platform/msm8952/msm8952-clock.c
@@ -41,7 +41,8 @@
 #define gpll0_source_val  1
 #define gpll4_source_val  2
 #define cxo_mm_source_val 0
-#define gpll0_mm_source_val 1
+#define gpll0_mm_source_val 6
+#define gpll6_mm_source_val 3
 
 struct clk_freq_tbl rcg_dummy_freq = F_END;
 
@@ -126,6 +127,21 @@
 	},
 };
 
+static struct pll_vote_clk gpll6_clk_src =
+{
+	.en_reg       = (void *) APCS_GPLL_ENA_VOTE,
+	.en_mask      = BIT(7),
+	.status_reg   = (void *) GPLL6_STATUS,
+	.status_mask  = BIT(17),
+	.parent       = &cxo_clk_src.c,
+
+	.c = {
+		.rate     = 1080000000,
+		.dbg_name = "gpll6_clk_src",
+		.ops      = &clk_ops_pll_vote,
+	},
+};
+
 /* SDCC Clocks */
 static struct clk_freq_tbl ftbl_gcc_sdcc1_apps_clk[] =
 {
@@ -346,11 +362,30 @@
 	F_END
 };
 
+static struct clk_freq_tbl ftbl_mdss_esc1_1_clk[] = {
+	F_MM(19200000,    cxo,   1,   0,   0),
+	F_END
+};
+
 static struct clk_freq_tbl ftbl_mdp_clk[] = {
-	F_MM( 80000000,  gpll0,   10,    0,    0),
-	F_MM( 100000000, gpll0,    8,    0,    0),
-	F_MM( 200000000, gpll0,    4,    0,    0),
-	F_MM( 320000000, gpll0,  2.5,    0,    0),
+	F( 80000000,  gpll0,   10,    0,    0),
+	F( 100000000, gpll0,    8,    0,    0),
+	F( 200000000, gpll0,    4,    0,    0),
+	F( 320000000, gpll0,  2.5,    0,    0),
+	F_END
+};
+
+static struct clk_freq_tbl ftbl_mdp_clk_8956[] = {
+	F_MM(  50000000, gpll0,   16,    0,     0),
+	F_MM(  80000000, gpll0,   10,    0,     0),
+	F_MM( 100000000, gpll0,    8,    0,     0),
+	F_MM( 145454545, gpll0,  5.5,    0,     0),
+	F_MM( 160000000, gpll0,    5,    0,     0),
+	F_MM( 177777778, gpll0,  4.5,    0,     0),
+	F_MM( 200000000, gpll0,    4,    0,     0),
+	F_MM( 270000000, gpll6,    4,    0,     0),
+	F_MM( 320000000, gpll0,  2.5,    0,     0),
+	F_MM( 360000000, gpll6,    3,    0,     0),
 	F_END
 };
 
@@ -366,6 +401,18 @@
 	},
 };
 
+static struct rcg_clk dsi_esc1_clk_src = {
+	.cmd_reg  = (uint32_t *) DSI_ESC1_CMD_RCGR,
+	.cfg_reg  = (uint32_t *) DSI_ESC1_CFG_RCGR,
+	.set_rate = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl = ftbl_mdss_esc1_1_clk,
+
+	.c        = {
+		.dbg_name = "dsi_esc1_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
 static struct clk_freq_tbl ftbl_mdss_vsync_clk[] = {
 	F_MM(19200000,    cxo,   1,   0,   0),
 	F_END
@@ -394,6 +441,17 @@
 	},
 };
 
+static struct branch_clk mdss_esc1_clk = {
+	.cbcr_reg    = (uint32_t *) DSI_ESC1_CBCR,
+	.parent      = &dsi_esc1_clk_src.c,
+	.has_sibling = 0,
+
+	.c           = {
+		.dbg_name = "mdss_esc1_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 static struct branch_clk mdss_axi_clk = {
 	.cbcr_reg    = (uint32_t *) MDP_AXI_CBCR,
 	.has_sibling = 1,
@@ -517,6 +575,7 @@
 
 	CLK_LOOKUP("mdp_ahb_clk",          mdp_ahb_clk.c),
 	CLK_LOOKUP("mdss_esc0_clk",        mdss_esc0_clk.c),
+	CLK_LOOKUP("mdss_esc1_clk",        mdss_esc1_clk.c),
 	CLK_LOOKUP("mdss_axi_clk",         mdss_axi_clk.c),
 	CLK_LOOKUP("mdss_vsync_clk",       mdss_vsync_clk.c),
 	CLK_LOOKUP("mdss_mdp_clk_src",     mdss_mdp_clk_src.c),
@@ -532,6 +591,7 @@
 {
 	gpll4_clk_src.status_reg = (void *)GPLL4_STATUS;
 	gpll4_clk_src.status_mask = BIT(17);
+	mdss_mdp_clk_src.freq_tbl = ftbl_mdp_clk_8956;
 }
 
 void platform_clock_init(void)
diff --git a/platform/msm_shared/rpm-glink.c b/platform/msm_shared/rpm-glink.c
index 77538f0..bc95db0 100644
--- a/platform/msm_shared/rpm-glink.c
+++ b/platform/msm_shared/rpm-glink.c
@@ -53,7 +53,8 @@
 
 glink_handle_type rpm_glink_port, ssr_glink_port;
 static uint32_t msg_id;
-static event_t wait_for_init;
+static event_t wait_for_rpm_init;
+static event_t wait_for_ssr_init;
 static event_t wait_for_data;
 
 extern glink_err_type glink_wait_link_down(glink_handle_type handle);
@@ -262,7 +263,17 @@
 {
 	if(event == GLINK_CONNECTED)
 	{
-		event_signal(&wait_for_init, false);
+		event_signal(&wait_for_rpm_init, false);
+		dprintf(INFO, "Glink Connection between APPS and RPM established\n");
+		return;
+	}
+}
+
+void rpm_glink_notify_state_ssr_isr(glink_handle_type handle, void *data, glink_channel_event_type event)
+{
+	if(event == GLINK_CONNECTED)
+	{
+		event_signal(&wait_for_ssr_init, false);
 		dprintf(INFO, "Glink Connection between APPS and RPM established\n");
 		return;
 	}
@@ -303,7 +314,7 @@
 	glink_ssr_open_cfg.notify_rx = NULL;
 	glink_ssr_open_cfg.notify_rxv = (glink_rxv_notification_cb)rpm_vector_glink_ssr_isr;
 	glink_ssr_open_cfg.notify_tx_done = (glink_tx_notification_cb)rpm_glink_tx_done_isr;
-	glink_ssr_open_cfg.notify_state = (glink_state_notification_cb)rpm_glink_notify_state_isr;
+	glink_ssr_open_cfg.notify_state = (glink_state_notification_cb)rpm_glink_notify_state_ssr_isr;
 	glink_ssr_open_cfg.priv = NULL;
 
 	ret = glink_open(&glink_ssr_open_cfg, &ssr_glink_port);
@@ -321,7 +332,8 @@
 {
 	glink_err_type ret;
 	glink_link_id_type link_id;
-	event_init(&wait_for_init, false, EVENT_FLAG_AUTOUNSIGNAL);
+	event_init(&wait_for_rpm_init, false, EVENT_FLAG_AUTOUNSIGNAL);
+	event_init(&wait_for_ssr_init, false, EVENT_FLAG_AUTOUNSIGNAL);
 
 	dprintf(INFO, "RPM GLink Init\n");
 	// Initialize RPM transport
@@ -339,7 +351,8 @@
 		dprintf(CRITICAL, "RPM Glink Init Failure 0x%x\n", ret);
 		ASSERT(0);
 	}
-	event_wait(&wait_for_init);
+	event_wait(&wait_for_rpm_init);
+	event_wait(&wait_for_ssr_init);
 }
 
 void rpm_glink_uninit()
diff --git a/target/msm8952/init.c b/target/msm8952/init.c
index fb83af9..1f4f60c 100644
--- a/target/msm8952/init.c
+++ b/target/msm8952/init.c
@@ -167,21 +167,21 @@
 int target_volume_up()
 {
 	uint8_t status = 0;
+	uint32_t vol_up_gpio;
 
 	if(platform_is_msm8956())
-	{
-		gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO_8956, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
-	}
+		vol_up_gpio = TLMM_VOL_UP_BTN_GPIO_8956;
+
 	else
-	{
-		gpio_tlmm_config(TLMM_VOL_UP_BTN_GPIO, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
-	}
+		vol_up_gpio = TLMM_VOL_UP_BTN_GPIO;
+
+	gpio_tlmm_config(vol_up_gpio, 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA, GPIO_ENABLE);
 
 	/* Wait for the gpio config to take effect - debounce time */
 	thread_sleep(10);
 
 	/* Get status of GPIO */
-	status = gpio_status(TLMM_VOL_UP_BTN_GPIO);
+	status = gpio_status(vol_up_gpio);
 
 	/* Active low signal. */
 	return !status;
diff --git a/target/msm8952/oem_panel.c b/target/msm8952/oem_panel.c
index b503962..7fe6a47 100644
--- a/target/msm8952/oem_panel.c
+++ b/target/msm8952/oem_panel.c
@@ -75,6 +75,8 @@
 
 static uint32_t panel_id;
 
+#define TRULY_1080P_CMD_PANEL_ON_DELAY 40
+
 int oem_panel_rotation()
 {
 	return NO_ERROR;
@@ -89,7 +91,10 @@
 	if (panel_id == OTM1906C_1080P_CMD_PANEL) {
 		/* needs extra delay to avoid unexpected artifacts */
 		mdelay(OTM1906C_1080P_CMD_PANEL_ON_DELAY);
+	} else if (panel_id == TRULY_1080P_CMD_PANEL) {
+		mdelay(TRULY_1080P_CMD_PANEL_ON_DELAY);
 	}
+
 	return NO_ERROR;
 }