Merge "target: msmzirc: fix meminfo"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 3b3d40b..c7522d6 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -112,7 +112,7 @@
 
 #define ADD_OF(a, b) (UINT_MAX - b > a) ? (a + b) : UINT_MAX
 
-#if UFS_SUPPORT
+#if UFS_SUPPORT || USE_BOOTDEV_CMDLINE
 static const char *emmc_cmdline = " androidboot.bootdevice=";
 #else
 static const char *emmc_cmdline = " androidboot.emmc=true";
@@ -233,7 +233,7 @@
 	}
 	if (target_is_emmc_boot()) {
 		cmdline_len += strlen(emmc_cmdline);
-#if UFS_SUPPORT
+#if UFS_SUPPORT || USE_BOOTDEV_CMDLINE
 		boot_dev_buf = (char *) malloc(sizeof(char) * BOOT_DEV_MAX_LEN);
 		ASSERT(boot_dev_buf);
 		platform_boot_dev_cmdline(boot_dev_buf);
@@ -346,7 +346,7 @@
 			if (have_cmdline) --dst;
 			have_cmdline = 1;
 			while ((*dst++ = *src++));
-#if UFS_SUPPORT
+#if UFS_SUPPORT  || USE_BOOTDEV_CMDLINE
 			src = boot_dev_buf;
 			if (have_cmdline) --dst;
 			while ((*dst++ = *src++));
@@ -2400,16 +2400,16 @@
 
 	fb_display = fbcon_display();
 	if (fb_display) {
-		uint8_t *base = (uint8_t *) fb_display->base;
-		if (logo->header.width != fb_display->width || logo->header.height != fb_display->height) {
-				base += LOGO_IMG_OFFSET;
+		if ((logo->header.width != fb_display->width) || (logo->header.height != fb_display->height)) {
+			dprintf(CRITICAL, "Logo config doesn't match with fb config. Fall back to default logo\n");
+			return NULL;
 		}
-
+		uint8_t *base = (uint8_t *) fb_display->base;
 		if (flash_read(ptn + sizeof(logo->header), 0,
 			base,
 			((((logo->header.width * logo->header.height * fb_display->bpp/8) + 511) >> 9) << 9))) {
 			fbcon_clear();
-			dprintf(CRITICAL, "ERROR: Cannot read splash image\n");
+			dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
 			return NULL;
 		}
 		logo->image = base;
@@ -2449,15 +2449,16 @@
 
 	fb_display = fbcon_display();
 	if (fb_display) {
+		if ((logo->header.width != fb_display->width) || (logo->header.height != fb_display->height)) {
+			dprintf(CRITICAL, "Logo config doesn't match with fb config. Fall back default logo\n");
+			return NULL;
+		}
 		uint8_t *base = (uint8_t *) fb_display->base;
-		if (logo->header.width != fb_display->width || logo->header.height != fb_display->height)
-				base += LOGO_IMG_OFFSET;
-
 		if (mmc_read(ptn + sizeof(logo->header),
 			base,
 			((((logo->header.width * logo->header.height * fb_display->bpp/8) + 511) >> 9) << 9))) {
 			fbcon_clear();
-			dprintf(CRITICAL, "ERROR: Cannot read splash image\n");
+			dprintf(CRITICAL, "ERROR: Cannot read splash image from partition\n");
 			return NULL;
 		}
 
diff --git a/platform/msm_shared/boot_device.c b/platform/msm_shared/boot_device.c
index 556ca85..a5e6131 100644
--- a/platform/msm_shared/boot_device.c
+++ b/platform/msm_shared/boot_device.c
@@ -30,6 +30,7 @@
 #include <ufs.h>
 #include <platform/iomap.h>
 #include <boot_device.h>
+#include <qpic_nand.h>
 
 static uint32_t boot_device;
 
@@ -77,6 +78,9 @@
 		case BOOT_UFS:
 			sprintf(buf, "%x.ufshc", ((struct ufs_dev *)dev)->base);
 			break;
+		case BOOT_NAND:
+			sprintf(buf, "%x.nandc", nand_device_base());
+			break;
 		default:
 			dprintf(CRITICAL,"ERROR: Unexpected boot_device val=%x",val);
 			ASSERT(0);
diff --git a/platform/msm_shared/include/boot_device.h b/platform/msm_shared/include/boot_device.h
index 0c666f8..b393afd 100644
--- a/platform/msm_shared/include/boot_device.h
+++ b/platform/msm_shared/include/boot_device.h
@@ -39,6 +39,7 @@
 	BOOT_DEFAULT=0,
 	BOOT_EMMC=2,
 	BOOT_UFS=4,
+	BOOT_NAND=5,
 };
 
 void platform_read_boot_config();
diff --git a/platform/msm_shared/include/qpic_nand.h b/platform/msm_shared/include/qpic_nand.h
index 0676301..bb429fb 100644
--- a/platform/msm_shared/include/qpic_nand.h
+++ b/platform/msm_shared/include/qpic_nand.h
@@ -346,5 +346,7 @@
 flash_block_size(void);
 void
 qpic_nand_uninit();
+/* Api to return the nand base */
+uint32_t nand_device_base();
 
 #endif
diff --git a/platform/msm_shared/mmc_wrapper.c b/platform/msm_shared/mmc_wrapper.c
index 1e1ff7d..276840b 100755
--- a/platform/msm_shared/mmc_wrapper.c
+++ b/platform/msm_shared/mmc_wrapper.c
@@ -567,6 +567,7 @@
 				dprintf(CRITICAL, "Error reading the partition table info for lun %d\n", lun);
 			}
 		}
+		mmc_set_lun(0);
 	}
 	else
 	{
diff --git a/platform/msm_shared/qpic_nand.c b/platform/msm_shared/qpic_nand.c
index 46c26c3..f21e032 100644
--- a/platform/msm_shared/qpic_nand.c
+++ b/platform/msm_shared/qpic_nand.c
@@ -36,6 +36,7 @@
 #include <sys/types.h>
 #include <platform.h>
 #include <platform/clock.h>
+#include <platform/iomap.h>
 
 static uint32_t nand_base;
 static struct ptable *flash_ptable;
@@ -1759,3 +1760,8 @@
 	dprintf(INFO, "flash_write_image: success\n");
 	return 0;
 }
+
+uint32_t nand_device_base()
+{
+	return nand_base;
+}
diff --git a/platform/msm_shared/ufs_hci.c b/platform/msm_shared/ufs_hci.c
index 479c0ff..0605678 100644
--- a/platform/msm_shared/ufs_hci.c
+++ b/platform/msm_shared/ufs_hci.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -35,6 +35,7 @@
 #include <platform/irqs.h>
 #include <ufs_hw.h>
 #include <utp.h>
+#include <ufs.h>
 
 uint64_t ufs_alloc_trans_req_list()
 {
@@ -97,10 +98,32 @@
 
 	val = readl(UFS_IS(dev->base));
 
-	if (val & UFS_IS_SBFES || val & UFS_IS_HCFES || val & UFS_IS_UTPES || val & UFS_IS_DFES || val & UFS_IS_UE)
+	if (val & UFS_IS_SBFES)
 	{
 		/* Controller might be in a bad state, unrecoverable error. */
-		dprintf(CRITICAL, "UFS error\n");
+		dprintf(CRITICAL, "UFS error: System Bus Fatal Error\n");
+		ASSERT(0);
+	}
+	else if (val & UFS_IS_UTPES)
+	{
+		/* Unrecoverable error occured at the utp layer */
+		dprintf(CRITICAL, "UFS error: UTP Error\n");
+		ASSERT(0);
+	}
+	else if ((val & UFS_IS_HCFES) || (val & UFS_IS_DFES))
+	{
+		/* Controller might be in a bad state, unrecoverable error. */
+		/* HCFES: Host Controller Fatal Error Status */
+		/* DFES: Device Fatal Error Status */
+		dprintf(CRITICAL, "UFS error: HCFES:0x%x DFES:0x%x\n",
+		                val & UFS_IS_HCFES, val & UFS_IS_DFES);
+		ASSERT(0);
+	}
+	else if (val & UFS_IS_UE)
+	{
+		/* Error in one of the layers in the UniPro stack */
+		dprintf(CRITICAL, "UFS error: UE. Dumping UIC Error code registers\n");
+		ufs_dump_hc_registers(dev);
 		ASSERT(0);
 	}
 
diff --git a/project/msmzirc.mk b/project/msmzirc.mk
index ec959a4..f021b26 100644
--- a/project/msmzirc.mk
+++ b/project/msmzirc.mk
@@ -17,6 +17,7 @@
 DEFINES += DEVICE_TREE=1
 DEFINES += SPMI_CORE_V2=1
 DEFINES += BAM_V170=1
+DEFINES += USE_BOOTDEV_CMDLINE=1
 
 ifeq ($(ENABLE_USB30_SUPPORT),1)
 DEFINES += USB30_SUPPORT=1
diff --git a/target/msm8994/include/target/display.h b/target/msm8994/include/target/display.h
index 8449ee0..b9d5dfe 100644
--- a/target/msm8994/include/target/display.h
+++ b/target/msm8994/include/target/display.h
@@ -45,13 +45,10 @@
   "pm8994_gpios", 14, 3, 1, 0, 1
 };
 
-static struct gpio_pin bkl_gpio = {	/* lcd_bklt_reg_en */
+static struct gpio_pin bklt_gpio = {	/* lcd_bklt_reg_en */
   "pmi8994_gpios", 2, 3, 1, 0, 1
 };
 
-static struct gpio_pin pwm_gpio = {	/* pmi_mpp01, lpg = 0 */
-  "pmi8994_mpps", 1, 0, 1, 0, 1
-};
 /*---------------------------------------------------------------------------*/
 /* LDO configuration                                                         */
 /*---------------------------------------------------------------------------*/
@@ -107,6 +104,6 @@
 #define MIPI_VSYNC_BACK_PORCH_LINES  2
 #define MIPI_VSYNC_FRONT_PORCH_LINES 4
 
-#define PWM_BL_LPG_CHAN_ID           0
+#define PWM_BL_LPG_CHAN_ID           4	/* lpg_out<3> */
 
 #endif
diff --git a/target/msm8994/oem_panel.c b/target/msm8994/oem_panel.c
index f0d7ba5..2d95439 100644
--- a/target/msm8994/oem_panel.c
+++ b/target/msm8994/oem_panel.c
@@ -139,11 +139,7 @@
 			= &jdi_qhd_dualdsi_video_timing_info;
 		panelstruct->panelresetseq
 					 = &jdi_qhd_dualdsi_video_reset_seq;
-
-		/* force backlight to WLED */
 		panelstruct->backlightinfo = &jdi_qhd_dualdsi_video_backlight;
-		jdi_qhd_dualdsi_video_backlight.bl_interface_type = BL_WLED;
-
 		pinfo->mipi.panel_cmds
 			= jdi_qhd_dualdsi_video_on_command;
 		pinfo->mipi.num_of_panel_cmds
@@ -165,11 +161,7 @@
 			= &jdi_qhd_dualdsi_cmd_timing_info;
 		panelstruct->panelresetseq
 					 = &jdi_qhd_dualdsi_cmd_reset_seq;
-
-		/* force backlight to WLED */
-		jdi_qhd_dualdsi_cmd_backlight.bl_interface_type = BL_WLED;
 		panelstruct->backlightinfo = &jdi_qhd_dualdsi_cmd_backlight;
-
 		pinfo->mipi.panel_cmds
 			= jdi_qhd_dualdsi_cmd_on_command;
 		pinfo->mipi.num_of_panel_cmds
diff --git a/target/msm8994/target_display.c b/target/msm8994/target_display.c
index 67b0d73..e1c4155 100644
--- a/target/msm8994/target_display.c
+++ b/target/msm8994/target_display.c
@@ -108,7 +108,7 @@
 
 static int msm8994_wled_backlight_ctrl(uint8_t enable)
 {
-	uint8_t slave_id = 3;
+	uint8_t slave_id = 3;	/* pmi */
 
 	if (enable) {
 		pm8x41_wled_config_slave_id(slave_id);
@@ -120,8 +120,67 @@
 
 static int msm8994_pwm_backlight_ctrl(uint8_t enable)
 {
-	dprintf(INFO, "%s: NOt implemented\n", __func__);
-	return NO_ERROR;
+	uint8_t slave_id = 3; /* lpg at pmi */
+
+        if (enable) {
+		/* mpp-1 had been configured already */
+                /* lpg channel 4 */
+
+		 /* LPG_ENABLE_CONTROL */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x0);
+		mdelay(100);
+
+		 /* LPG_VALUE_LSB, duty cycle = 0x80/0x200 = 1/4 */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x44, 0x80);
+		/* LPG_VALUE_MSB */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x45, 0x00);
+		/* LPG_PWM_SYNC */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x47, 0x01);
+
+		 /* LPG_PWM_SIZE_CLK, */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x41, 0x13);
+		 /* LPG_PWM_FREQ_PREDIV */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x42, 0x02);
+		 /* LPG_PWM_TYPE_CONFIG */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x43, 0x20);
+		 /* LPG_ENABLE_CONTROL */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x04);
+
+		 /* SEC_ACCESS */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0xD0, 0xA5);
+		 /* DTEST4, OUT_HI */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0xE5, 0x01);
+		 /* LPG_ENABLE_CONTROL */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0xA4);
+        } else {
+		 /* LPG_ENABLE_CONTROL */
+                pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x0);
+        }
+
+        return NO_ERROR;
+}
+
+void lcd_bklt_reg_enable(void)
+{
+	uint8_t slave_id = 2;	/* gpio at pmi */
+
+	struct pm8x41_gpio gpio = {
+                .direction = PM_GPIO_DIR_OUT,
+                .function = PM_GPIO_FUNC_HIGH,
+                .vin_sel = 2,   /* VIN_2 */
+                .output_buffer = PM_GPIO_OUT_CMOS,
+                .out_strength = PM_GPIO_OUT_DRIVE_LOW,
+        };
+
+        pm8x41_gpio_config_sid(slave_id, bklt_gpio.pin_id, &gpio);
+	pm8x41_gpio_set_sid(slave_id, bklt_gpio.pin_id, 1);
+}
+
+void lcd_bklt_reg_disable(void)
+{
+	uint8_t slave_id = 2;	/* gpio at pmi */
+
+	pm8x41_gpio_set_sid(slave_id, bklt_gpio.pin_id, 0);
 }
 
 void lcd_reg_enable(void)
@@ -181,6 +240,19 @@
 		ret = msm8994_wled_backlight_ctrl(enable);
 		break;
 	case BL_PWM:
+		/* Enable MPP1 */
+		pmi8994_config_mpp_slave_id(PMIC_MPP_SLAVE_ID);
+	        mpp.base = PM8x41_MMP1_BASE;
+		mpp.vin = MPP_VIN2;
+		mpp.mode = MPP_DTEST4;
+		if (enable) {
+			pm8x41_config_output_mpp(&mpp);
+			pm8x41_enable_mpp(&mpp, MPP_ENABLE);
+		} else {
+			pm8x41_enable_mpp(&mpp, MPP_DISABLE);
+		}
+		/* Need delay before power on regulators */
+		mdelay(20);
 		ret = msm8994_pwm_backlight_ctrl(enable);
 		break;
 	default:
@@ -248,7 +320,9 @@
 				gpio_set(reset_gpio.pin_id, GPIO_STATE_HIGH);
 			mdelay(resetseq->sleep[i]);
 		}
+		lcd_bklt_reg_enable();
 	} else {
+		lcd_bklt_reg_disable();
 		gpio_set(reset_gpio.pin_id, 0);
 	}
 
@@ -303,6 +377,13 @@
 
 void target_display_init(const char *panel_name)
 {
+	if ((!strcmp(panel_name, NO_PANEL_CONFIG))
+			|| (!strcmp(panel_name, SIM_VIDEO_PANEL))
+			|| (!strcmp(panel_name, SIM_DUALDSI_VIDEO_PANEL))) {
+		dprintf(INFO, "Selected panel: %s\nSkip panel configuration\n",
+				panel_name);
+		return;
+	}
 	if (gcdb_display_init(panel_name, MDP_REV_50, MIPI_FB_ADDR))
 		msm_display_off();
 }