target: msm8974: Add panel autodetection for 8974

Adding support for autodetecting 720p/1080p
panel for 8974 platform. This allows either
panel to be attached/replaced without any code change.

Change-Id: I2c605c80f92a0e924f39908b668c5c28d4ea33ba
diff --git a/target/msm8974/init.c b/target/msm8974/init.c
index 5c8bfef..bb7fe08 100644
--- a/target/msm8974/init.c
+++ b/target/msm8974/init.c
@@ -587,23 +587,49 @@
 	}
 }
 
-/* Returns 1 if target supports continuous splash screen. */
-int target_cont_splash_screen()
+uint8_t target_panel_auto_detect_enabled()
 {
 	switch(board_hardware_id())
 	{
 		case HW_PLATFORM_SURF:
 		case HW_PLATFORM_MTP:
 		case HW_PLATFORM_FLUID:
-		case HW_PLATFORM_DRAGON:
-		case HW_PLATFORM_LIQUID:
-			dprintf(SPEW, "Target_cont_splash=1\n");
 			return 1;
 			break;
 		default:
-			dprintf(SPEW, "Target_cont_splash=0\n");
 			return 0;
+			break;
 	}
+	return 0;
+}
+
+static uint8_t splash_override;
+/* Returns 1 if target supports continuous splash screen. */
+int target_cont_splash_screen()
+{
+	uint8_t splash_screen = 0;
+	if(!splash_override) {
+		switch(board_hardware_id())
+		{
+			case HW_PLATFORM_SURF:
+			case HW_PLATFORM_MTP:
+			case HW_PLATFORM_FLUID:
+			case HW_PLATFORM_DRAGON:
+			case HW_PLATFORM_LIQUID:
+				dprintf(SPEW, "Target_cont_splash=1\n");
+				splash_screen = 1;
+				break;
+			default:
+				dprintf(SPEW, "Target_cont_splash=0\n");
+				splash_screen = 0;
+		}
+	}
+	return splash_screen;
+}
+
+void target_force_cont_splash_disable(uint8_t override)
+{
+	splash_override = override;
 }
 
 unsigned target_pause_for_battery_charge(void)
diff --git a/target/msm8974/oem_panel.c b/target/msm8974/oem_panel.c
index 56f3069..1f876d7 100755
--- a/target/msm8974/oem_panel.c
+++ b/target/msm8974/oem_panel.c
@@ -44,13 +44,16 @@
 #include "include/panel_sharp_qhd_video.h"
 #include "include/panel_jdi_1080p_video.h"
 
+#define DISPLAY_MAX_PANEL_DETECTION 2
+
 /*---------------------------------------------------------------------------*/
 /* static panel selection variable                                           */
 /*---------------------------------------------------------------------------*/
 enum {
+JDI_1080P_VIDEO_PANEL,
 TOSHIBA_720P_VIDEO_PANEL,
 SHARP_QHD_VIDEO_PANEL,
-JDI_1080P_VIDEO_PANEL
+UNKNOWN_PANEL
 };
 
 static uint32_t panel_id;
@@ -101,6 +104,7 @@
 					= TOSHIBA_720P_VIDEO_ON_COMMAND;
 		memcpy(phy_db->timing,
 			toshiba_720p_video_timings, TIMING_SIZE);
+		pinfo->mipi.signature 	= TOSHIBA_720P_VIDEO_SIGNATURE;
 		break;
 	case SHARP_QHD_VIDEO_PANEL:
 		panelstruct->paneldata    = &sharp_qhd_video_panel_data;
@@ -141,22 +145,51 @@
 			= JDI_1080P_VIDEO_ON_COMMAND;
 		memcpy(phy_db->timing,
 			jdi_1080p_video_timings, TIMING_SIZE);
+		pinfo->mipi.signature = JDI_1080P_VIDEO_SIGNATURE;
+		break;
+	case UNKNOWN_PANEL:
+		memset(panelstruct, 0, sizeof(struct panel_struct));
+		memset(pinfo->mipi.panel_cmds, 0, sizeof(struct mipi_dsi_cmd));
+		pinfo->mipi.num_of_panel_cmds = 0;
+		memset(phy_db->timing, 0, TIMING_SIZE);
+		pinfo->mipi.signature = 0;
 		break;
 	}
 }
 
+uint32_t oem_panel_max_auto_detect_panels()
+{
+	return target_panel_auto_detect_enabled() ?
+			DISPLAY_MAX_PANEL_DETECTION : 0;
+}
+
+static uint32_t auto_pan_loop = 0;
+
 bool oem_panel_select(struct panel_struct *panelstruct,
 			struct msm_panel_info *pinfo,
 			struct mdss_dsi_phy_ctrl *phy_db)
 {
 	uint32_t hw_id = board_hardware_id();
 	uint32_t target_id = board_target_id();
+	bool ret = true;
 
 	switch (hw_id) {
 	case HW_PLATFORM_MTP:
 	case HW_PLATFORM_FLUID:
 	case HW_PLATFORM_SURF:
-		panel_id = TOSHIBA_720P_VIDEO_PANEL;
+		switch (auto_pan_loop) {
+		case 0:
+			panel_id = JDI_1080P_VIDEO_PANEL;
+			break;
+		case 1:
+			panel_id = TOSHIBA_720P_VIDEO_PANEL;
+			break;
+		default:
+			panel_id = UNKNOWN_PANEL;
+			ret = false;
+			break;
+		}
+		auto_pan_loop++;
 		break;
 	case HW_PLATFORM_DRAGON:
 		panel_id = SHARP_QHD_VIDEO_PANEL;
@@ -169,5 +202,5 @@
 
 	init_panel_data(panelstruct, pinfo, phy_db);
 
-	return true;
+	return ret;
 }
diff --git a/target/msm8974/target_display.c b/target/msm8974/target_display.c
index addb135..096dc21 100644
--- a/target/msm8974/target_display.c
+++ b/target/msm8974/target_display.c
@@ -36,6 +36,7 @@
 #include <pm8x41_wled.h>
 #include <board.h>
 #include <mdp5.h>
+#include <endian.h>
 #include <platform/gpio.h>
 #include <platform/clock.h>
 #include <platform/iomap.h>
@@ -218,6 +219,33 @@
 	return NO_ERROR;
 }
 
+static uint32_t response_value = 0;
+
+uint32_t target_read_panel_signature(uint32_t panel_signature)
+{
+	uint32_t rec_buf[1];
+	uint32_t *lp = rec_buf, data;
+	int ret = response_value;
+
+	if (ret && ret != panel_signature)
+		goto exit_read_signature;
+
+	ret = mipi_dsi_cmds_tx(&read_ddb_start_cmd, 1);
+	if (ret)
+		goto exit_read_signature;
+	if (!mdss_dsi_cmds_rx(&lp, 1, 1))
+		goto exit_read_signature;
+
+	data = ntohl(*lp);
+	data = data >> 8;
+	response_value = data;
+	if (response_value != panel_signature)
+		ret = response_value;
+
+exit_read_signature:
+	return ret;
+}
+
 static int msm8974_mdss_edp_panel_clock(int enable)
 {
 	if (enable) {
@@ -294,6 +322,8 @@
 void display_init(void)
 {
 	uint32_t hw_id = board_hardware_id();
+	uint32_t panel_loop = 0;
+	uint32_t ret = 0;
 	switch (hw_id) {
 	case HW_PLATFORM_LIQUID:
 		edp_panel_init(&(panel.panel_info));
@@ -311,7 +341,17 @@
 		edp_enable = 1;
 		break;
 	default:
-		gcdb_display_init(MDP_REV_50, MIPI_FB_ADDR);
+		do {
+			ret = gcdb_display_init(MDP_REV_50, MIPI_FB_ADDR);
+			if (ret) {
+				target_force_cont_splash_disable(true);
+				msm_display_off();
+				target_force_cont_splash_disable(false);
+			}
+			else {
+				break;
+			}
+		} while (++panel_loop <= oem_panel_max_auto_detect_panels());
 		break;
 	}
 }