dev: gcdb: add support to pass panel sim mode using fastboot oem

Command mode simulator panels need terminator card for HW TE
generation if tear check logic is enabled. If tear check logic
is not needed, SW TE can be used. This change adds support
to pass panel simulator mode that needs to be used in kernel via
fastboot oem command.

eg:
- simulator single DSI cmd mode with SW TE
        fastboot oem select-display-panel sim_cmd_panel#sim-swte
- simulator single DSI cmd mode with HW TE
        fastboot oem select-display-panel sim_cmd_panel#sim-hwte
- Simulator dual DSI cmd mode with SW TE
        fastboot oem select-display-panel
        sim_dualdsi_cmd_panel#sim-swte
- JDI 1080p video mode panel in simulator mode
        fastboot oem select-display-panel jdi_1080p_video#sim

Change-Id: Ib169f47ef981d596a8ed7c053ab6423affa53833
diff --git a/dev/gcdb/display/fastboot_oem_display.h b/dev/gcdb/display/fastboot_oem_display.h
index 7492d2f..9dd8b5c 100644
--- a/dev/gcdb/display/fastboot_oem_display.h
+++ b/dev/gcdb/display/fastboot_oem_display.h
@@ -30,9 +30,14 @@
 #ifndef _FASTBOOT_OEM_DISPLAY_H_
 #define _FASTBOOT_OEM_DISPLAY_H_
 
-/*---------------------------------------------------------------------------*/
-/* Lookup table for skip panels                                              */
-/*---------------------------------------------------------------------------*/
+#define SIM_OVERRIDE_LEN 10
+
+enum {
+    SIM_NONE,
+    SIM_MODE,
+    SIM_SWTE,
+    SIM_HWTE,
+};
 
 struct panel_lookup_list {
 	char name[MAX_PANEL_ID_LEN];
@@ -40,6 +45,15 @@
 	bool is_split_dsi;
 };
 
+struct sim_lookup_list {
+	uint32_t sim_mode;
+	char override_string[SIM_OVERRIDE_LEN];
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lookup table for skip panels                                              */
+/*---------------------------------------------------------------------------*/
+
 struct panel_lookup_list lookup_skip_panels[] = {
 	{"adv7533_1080p_video", "qcom,mdss_dsi_adv7533_1080p60_video", false},
 	{"adv7533_720p_video", "qcom,mdss_dsi_adv7533_720p60_video", false},
@@ -89,4 +103,10 @@
 	{"truly_wvga_video", "qcom,mdss_dsi_truly_wvga_video", false},
 };
 
+struct sim_lookup_list lookup_sim[] = {
+	{SIM_MODE, "sim"},
+	{SIM_SWTE, "sim-swte"},
+	{SIM_HWTE, "sim-hwte"},
+};
+
 #endif /*_FASTBOOT_OEM_DISPLAY_H_ */
diff --git a/dev/gcdb/display/gcdb_display.h b/dev/gcdb/display/gcdb_display.h
index 1fbc2f7..5a5f3ed 100755
--- a/dev/gcdb/display/gcdb_display.h
+++ b/dev/gcdb/display/gcdb_display.h
@@ -68,6 +68,7 @@
 	char panel[MAX_PANEL_ID_LEN];
 	bool cont_splash;
 	bool skip;
+	uint32_t sim_mode;
 };
 
 #endif /*_GCDB_DISPLAY_H_ */
diff --git a/dev/gcdb/display/gcdb_display_param.c b/dev/gcdb/display/gcdb_display_param.c
index 027207c..3734e8d 100644
--- a/dev/gcdb/display/gcdb_display_param.c
+++ b/dev/gcdb/display/gcdb_display_param.c
@@ -37,7 +37,7 @@
 #include "target/display.h"
 #include "fastboot_oem_display.h"
 
-struct oem_panel_data oem_data = {{'\0'}, false, false};
+struct oem_panel_data oem_data = {{'\0'}, false, false, SIM_NONE};
 
 void panel_name_to_dt_string(struct panel_lookup_list supp_panels[],
 			  uint32_t supp_panels_size,
@@ -71,6 +71,23 @@
 			panel_name);
 }
 
+void sim_override_to_cmdline(struct sim_lookup_list sim[],
+			  uint32_t sim_size, uint32_t sim_mode,
+			  char **sim_string)
+{
+	uint32_t i;
+
+	for (i = 0; i < sim_size; i++) {
+		if (sim_mode == sim[i].sim_mode) {
+			*sim_string = sim[i].override_string;
+			break;
+		}
+	}
+
+	if (i == sim_size)
+		dprintf(CRITICAL, "Sim_mode not found in lookup table\n");
+}
+
 struct oem_panel_data mdss_dsi_get_oem_data(void)
 {
 	return oem_data;
@@ -78,13 +95,22 @@
 
 void set_panel_cmd_string(const char *panel_name)
 {
-	char *ch = NULL;
+	char *ch = NULL, *ch_hash = NULL, *ch_col = NULL;
 	int i;
 
 	panel_name += strspn(panel_name, " ");
 
-	/* Panel string */
-	ch = strchr((char *) panel_name, ':');
+	/* Panel string - ':' and '#' are delimiters */
+	ch_col = strchr((char *) panel_name, ':');
+	ch_hash = strchr((char *) panel_name, '#');
+
+	if (ch_col && ch_hash)
+		ch = (ch_col < ch_hash) ? ch_col : ch_hash;
+	else if (ch_col)
+		ch = ch_col;
+	else if (ch_hash)
+		ch = ch_hash;
+
 	if (ch) {
 		for (i = 0; (panel_name + i) < ch; i++)
 			oem_data.panel[i] = *(panel_name + i);
@@ -100,6 +126,16 @@
 	/* Cont. splash status */
 	ch = strstr((char *) panel_name, ":disable");
 	oem_data.cont_splash = ch ? false : true;
+
+	/* Simulator status */
+	oem_data.sim_mode = SIM_NONE;
+	if (strstr((char *) panel_name, "#sim-hwte"))
+		oem_data.sim_mode = SIM_HWTE;
+	else if (strstr((char *) panel_name, "#sim-swte"))
+		oem_data.sim_mode = SIM_SWTE;
+	else if (strstr((char *) panel_name, "#sim"))
+		oem_data.sim_mode = SIM_MODE;
+
 }
 
 static bool mdss_dsi_set_panel_node(char *panel_name, char **dsi_id,
@@ -140,6 +176,7 @@
 	char *dsi_id = NULL;
 	char *panel_node = NULL;
 	char *slave_panel_node = NULL;
+	char *sim_mode_string = NULL;
 	uint16_t dsi_id_len = 0, panel_node_len = 0, slave_panel_node_len = 0;
 	uint32_t arg_size = 0;
 	bool ret = true;
@@ -213,6 +250,19 @@
 
 	arg_size += strlen(sctl_string) + slave_panel_node_len;
 
+	if (oem_data.sim_mode != SIM_NONE) {
+		sim_override_to_cmdline(lookup_sim,
+			ARRAY_SIZE(lookup_sim), oem_data.sim_mode,
+			&sim_mode_string);
+		if (sim_mode_string) {
+			arg_size += LK_SIM_OVERRIDE_LEN +
+				strlen(sim_mode_string);
+		} else {
+			dprintf(CRITICAL, "SIM string NULL but mode is not NONE\n");
+			return false;
+		}
+	}
+
 	if (buf_size < arg_size) {
 		dprintf(CRITICAL, "display command line buffer is small\n");
 		ret = false;
@@ -230,14 +280,26 @@
 		buf_size -= dsi_id_len;
 
 		strlcpy(pbuf, panel_node, buf_size);
-
 		pbuf += panel_node_len;
 		buf_size -= panel_node_len;
 
 		strlcpy(pbuf, sctl_string, buf_size);
 		pbuf += strlen(sctl_string);
 		buf_size -= strlen(sctl_string);
+
 		strlcpy(pbuf, slave_panel_node, buf_size);
+		pbuf += slave_panel_node_len;
+		buf_size -= slave_panel_node_len;
+
+		if (sim_mode_string) {
+			strlcpy(pbuf, LK_SIM_OVERRIDE, buf_size);
+			pbuf += LK_SIM_OVERRIDE_LEN;
+			buf_size -= LK_SIM_OVERRIDE_LEN;
+
+			strlcpy(pbuf, sim_mode_string, buf_size);
+			pbuf += strlen(sim_mode_string);
+			buf_size -= strlen(sim_mode_string);
+		}
 	}
 	return ret;
 }
diff --git a/dev/gcdb/display/include/display_resource.h b/dev/gcdb/display/include/display_resource.h
index 6fc177a..e40a899 100755
--- a/dev/gcdb/display/include/display_resource.h
+++ b/dev/gcdb/display/include/display_resource.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-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
@@ -42,6 +42,9 @@
 #define LK_OVERRIDE_PANEL      "1:"
 #define LK_OVERRIDE_PANEL_LEN  2
 
+#define LK_SIM_OVERRIDE     "#override:"
+#define LK_SIM_OVERRIDE_LEN  10
+
 #define DSI_0_STRING           ":0:"
 #define DSI_0_STRING_LEN       3
 #define DSI_1_STRING           ":1:"