Merge "platform: msm_shared: add scrambling support for 4K 60fps modes"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index e84e2e5..fc41a24 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -134,6 +134,7 @@
 /* make 4096 as default size to ensure EFS,EXT4's erasing */
 #define DEFAULT_ERASE_SIZE  4096
 #define MAX_PANEL_BUF_SIZE 196
+#define FOOTER_SIZE 16384
 
 #define DISPLAY_DEFAULT_PREFIX "mdss_mdp"
 #define BOOT_DEV_MAX_LEN  64
@@ -2503,6 +2504,7 @@
 	unsigned long long size = 0;
 	int index = INVALID_PTN;
 	uint8_t lun = 0;
+	char *footer = NULL;
 
 #if VERIFIED_BOOT
 	if(!strcmp(arg, KEYSTORE_PTN_NAME))
@@ -2545,6 +2547,21 @@
 			fastboot_fail("failed to erase partition");
 			return;
 		}
+		/*Erase FDE metadata at the userdata footer*/
+		if(!(strncmp(arg, "userdata", 8)))
+		{
+			footer = memalign(CACHE_LINE, FOOTER_SIZE);
+			memset((void *)footer, 0, FOOTER_SIZE);
+
+			size = partition_get_size(index);
+
+			if (mmc_write((ptn + size) - FOOTER_SIZE , FOOTER_SIZE, (unsigned int *)footer)) {
+				fastboot_fail("failed to erase userdata footer");
+				free(footer);
+				return;
+			}
+			free(footer);
+		}
 	}
 #if VERIFIED_BOOT
 #if !VBOOT_MOTA
@@ -3168,6 +3185,7 @@
 	struct ptentry *ptn;
 	struct ptable *ptable;
 	unsigned extra = 0;
+	uint64_t partition_size = 0;
 
 	ptable = flash_get_ptable();
 	if (ptable == NULL) {
@@ -3199,6 +3217,17 @@
 	else
 		sz = ROUND_TO_PAGE(sz, page_mask);
 
+	partition_size = (uint64_t)ptn->length * (uint64_t)flash_num_pages_per_blk() *  (uint64_t)flash_page_size();
+	if (partition_size > UINT_MAX) {
+		fastboot_fail("Invalid partition size");
+		return;
+	}
+
+	if (sz > partition_size) {
+		fastboot_fail("Image size too large");
+		return;
+	}
+
 	dprintf(INFO, "writing %d bytes to '%s'\n", sz, ptn->name);
 	if (!memcmp((void *)data, UBI_MAGIC, UBI_MAGIC_SIZE)) {
 		if (flash_ubi_img(ptn, data, sz)) {
diff --git a/dev/qpnp_wled/include/qpnp_wled.h b/dev/qpnp_wled/include/qpnp_wled.h
index 64e85e0..d90ca0b 100644
--- a/dev/qpnp_wled/include/qpnp_wled.h
+++ b/dev/qpnp_wled/include/qpnp_wled.h
@@ -47,8 +47,11 @@
 #define QPNP_WLED_VLOOP_COMP_RES(b)            (b + 0x55)
 #define QPNP_WLED_VLOOP_COMP_GM(b)             (b + 0x56)
 #define QPNP_WLED_PSM_CTRL(b)                  (b + 0x5B)
-#define QPNP_WLED_TEST4(b)		       (b + 0xE5)
+#define QPNP_WLED_TEST4(b)                     (b + 0xE5)
+#define QPNP_WLED_CTRL_SPARE_REG(b)            (b + 0xDF)
+#define QPNP_WLED_REF_7P7_TRIM_REG(b)          (b + 0xF2)
 
+#define QPNP_WLED_7P7_TRIM_MASK                0xF
 #define QPNP_WLED_EN_MASK                      0x7F
 #define QPNP_WLED_EN_SHIFT                     7
 #define QPNP_WLED_FDBK_OP_MASK                 0xF8
@@ -183,6 +186,19 @@
 
 #define PWRDN_DLY2_MASK                        0x3
 
+#define NUM_SUPPORTED_AVDD_VOLTAGES 		   6
+
+/* Supported values  7900, 7600, 7300, 6400, 6100, 5800 */
+#if TARGET_QPNP_WLED_AVDD_DEFAULT_VOLTAGE_MV
+#define QPNP_WLED_AVDD_DEFAULT_VOLTAGE_MV	   TARGET_QPNP_WLED_AVDD_DEFAULT_VOLTAGE_MV
+#else
+#define QPNP_WLED_AVDD_DEFAULT_VOLTAGE_MV	   7600
+#endif
+
+#define QPNP_WLED_AVDD_MIN_TRIM_VALUE          0x0
+#define QPNP_WLED_AVDD_MAX_TRIM_VALUE          0xF
+#define QPNP_WLED_AVDD_SET_BIT                 BIT(4)
+
 /* output feedback mode */
 enum qpnp_wled_fdbk_op {
        QPNP_WLED_FDBK_AUTO,
diff --git a/dev/qpnp_wled/qpnp_wled.c b/dev/qpnp_wled/qpnp_wled.c
index 3aa41f8..ad2f5d5 100644
--- a/dev/qpnp_wled/qpnp_wled.c
+++ b/dev/qpnp_wled/qpnp_wled.c
@@ -34,6 +34,18 @@
 #include <pm8x41_wled.h>
 #include <qtimer.h>
 
+static int qpnp_wled_avdd_target_voltages[NUM_SUPPORTED_AVDD_VOLTAGES] = {
+	7900, 7600, 7300, 6400, 6100, 5800,
+};
+
+static uint8_t qpnp_wled_ovp_reg_settings[NUM_SUPPORTED_AVDD_VOLTAGES] = {
+	0x0, 0x0, 0x1, 0x2, 0x2, 0x3,
+};
+
+static int qpnp_wled_avdd_trim_adjustments[NUM_SUPPORTED_AVDD_VOLTAGES] = {
+	3, 0, -2, 7, 3, 3,
+};
+
 static int fls(uint16_t n)
 {
 	int i = 0;
@@ -311,6 +323,44 @@
 	reg |= temp;
 	pm8x41_wled_reg_write(QPNP_WLED_OVP_REG(wled->ctrl_base), reg);
 
+	if (wled->disp_type_amoled) {
+		for (i = 0; i < NUM_SUPPORTED_AVDD_VOLTAGES; i++) {
+			if (QPNP_WLED_AVDD_DEFAULT_VOLTAGE_MV == qpnp_wled_avdd_target_voltages[i])
+				break;
+		}
+		if (i == NUM_SUPPORTED_AVDD_VOLTAGES)
+		{
+			dprintf(CRITICAL, "Invalid avdd target voltage specified \n");
+			return ERR_NOT_VALID;
+		}
+		/* Update WLED_OVP register based on desired target voltage */
+		reg = qpnp_wled_ovp_reg_settings[i];
+		pm8x41_wled_reg_write(QPNP_WLED_OVP_REG(wled->ctrl_base), reg);
+		/* Update WLED_TRIM register based on desired target voltage */
+		reg = pm8x41_wled_reg_read(
+			QPNP_WLED_REF_7P7_TRIM_REG(wled->ctrl_base));
+		reg += qpnp_wled_avdd_trim_adjustments[i];
+		if ((int8_t)reg < QPNP_WLED_AVDD_MIN_TRIM_VALUE)
+			reg = QPNP_WLED_AVDD_MIN_TRIM_VALUE;
+		else if((int8_t)reg > QPNP_WLED_AVDD_MAX_TRIM_VALUE)
+			reg = QPNP_WLED_AVDD_MAX_TRIM_VALUE;
+
+		rc = qpnp_wled_sec_access(wled, wled->ctrl_base);
+		if (rc)
+			return rc;
+
+		temp = pm8x41_wled_reg_read(
+			QPNP_WLED_REF_7P7_TRIM_REG(wled->ctrl_base));
+		temp &= ~QPNP_WLED_7P7_TRIM_MASK;
+		temp |= (reg & QPNP_WLED_7P7_TRIM_MASK);
+		pm8x41_wled_reg_write(QPNP_WLED_REF_7P7_TRIM_REG(wled->ctrl_base), temp);
+		/* Write to spare to avoid reconfiguration in HLOS */
+		reg = pm8x41_wled_reg_read(
+			QPNP_WLED_CTRL_SPARE_REG(wled->ctrl_base));
+		reg |= QPNP_WLED_AVDD_SET_BIT;
+		pm8x41_wled_reg_write(QPNP_WLED_CTRL_SPARE_REG(wled->ctrl_base), reg);
+	}
+
 	/* Configure the MODULATION register */
 	if (wled->mod_freq_khz <= QPNP_WLED_MOD_FREQ_1200_KHZ) {
 		wled->mod_freq_khz = QPNP_WLED_MOD_FREQ_1200_KHZ;
diff --git a/include/dev/flash.h b/include/dev/flash.h
index 9c41561..f908db8 100644
--- a/include/dev/flash.h
+++ b/include/dev/flash.h
@@ -77,6 +77,8 @@
 {
 	return flash_read_ext(ptn, 0, offset, data, bytes);
 }
+
+unsigned flash_num_pages_per_blk(void);
 unsigned flash_page_size(void);
 unsigned flash_block_size(void);
 unsigned flash_spare_size(void);
diff --git a/include/target.h b/include/target.h
index e0a0264..d0d830d 100644
--- a/include/target.h
+++ b/include/target.h
@@ -70,6 +70,7 @@
 
 const char * target_usb_controller();
 void target_usb_phy_reset(void);
+void target_usb_phy_sec_reset(void);
 void target_usb_phy_mux_configure(void);
 target_usb_iface_t * target_usb30_init();
 bool target_is_cdp_qvga();
diff --git a/lib/heap/heap.c b/lib/heap/heap.c
index a4835f9..2f41f6c 100644
--- a/lib/heap/heap.c
+++ b/lib/heap/heap.c
@@ -156,19 +156,19 @@
 // nearby ones if possible. Returns base of whatever chunk it became in the list.
 static struct free_heap_chunk *heap_insert_free_chunk(struct free_heap_chunk *chunk)
 {
-#if DEBUGLEVEL > INFO
+#if DEBUG_HEAP
 	vaddr_t chunk_end = (vaddr_t)chunk + chunk->len;
+	dprintf(CRITICAL,"%s: chunk ptr %p, size 0x%lx, chunk_end 0x%x\n",
+				__FUNCTION__, chunk, chunk->len, chunk_end);
 #endif
 
-//	dprintf("%s: chunk ptr %p, size 0x%lx, chunk_end 0x%x\n", __FUNCTION__, chunk, chunk->len, chunk_end);
-
 	struct free_heap_chunk *next_chunk;
 	struct free_heap_chunk *last_chunk;
 
 	// walk through the list, finding the node to insert before
 	list_for_every_entry(&theheap.free_list, next_chunk, struct free_heap_chunk, node) {
 		if (chunk < next_chunk) {
-			DEBUG_ASSERT(chunk_end <= (vaddr_t)next_chunk);
+			DEBUG_ASSERT(((vaddr_t)chunk + chunk->len) <= (vaddr_t)next_chunk);
 
 			list_add_before(&next_chunk->node, &chunk->node);
 
diff --git a/platform/msm8996/acpuclock.c b/platform/msm8996/acpuclock.c
index ec4820a..c74e2e6 100644
--- a/platform/msm8996/acpuclock.c
+++ b/platform/msm8996/acpuclock.c
@@ -208,6 +208,40 @@
 	writel(reg, GCC_USB30_GDSCR);
 }
 
+/* enables usb20 clocks */
+void clock_usb20_init(void)
+{
+	int ret;
+
+	ret = clk_get_set_enable("usb20_noc_usb20_clk", 0, true);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb20_noc_clk. ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	ret = clk_get_set_enable("usb20_master_clk", 120000000, true);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb20_master_clk. ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	ret = clk_get_set_enable("usb20_mock_utmi_clk", 60000000, true);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb20_mock_utmi_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	ret = clk_get_set_enable("usb20_sleep_clk", 0, true);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb2_sleep_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+}
+
 /* enables usb30 clocks */
 void clock_usb30_init(void)
 {
diff --git a/platform/msm8996/include/platform/clock.h b/platform/msm8996/include/platform/clock.h
index 7cdd3d3..f2b0455 100644
--- a/platform/msm8996/include/platform/clock.h
+++ b/platform/msm8996/include/platform/clock.h
@@ -118,6 +118,7 @@
 void clock_ce_enable(uint8_t instance);
 void clock_ce_disable(uint8_t instance);
 void clock_usb30_init(void);
+void clock_usb20_init(void);
 void clock_reset_usb_phy();
 
 void mmss_dsi_clock_enable(uint32_t cfg_rcgr, uint32_t dual_dsi);
diff --git a/platform/msm8996/include/platform/iomap.h b/platform/msm8996/include/platform/iomap.h
index f8e77dd..63dca93 100644
--- a/platform/msm8996/include/platform/iomap.h
+++ b/platform/msm8996/include/platform/iomap.h
@@ -75,15 +75,33 @@
 #define GCC_BLSP2_QUP2_CFG_RCGR     (CLK_CTL_BASE + 0x28010)
 #define GCC_BLSP2_QUP2_CMD_RCGR     (CLK_CTL_BASE + 0x2800C)
 
+/* USB platform specific bases*/
+unsigned int usb_ctrl_base();
+unsigned int usb_qscratch_base();
+unsigned int usb_phy_base();
+unsigned int usb_phy_bcr();
+
+#define MSM_USB30_BASE              (usb_ctrl_base())
+#define MSM_USB30_QSCRATCH_BASE     (usb_qscratch_base())
+#define QUSB2_PHY_BASE              (usb_phy_base())
+#define GCC_QUSB2_PHY_BCR           (usb_phy_bcr())
+
 /* USB3.0 */
-#define MSM_USB30_BASE              0x6A00000
-#define MSM_USB30_QSCRATCH_BASE     0x6AF8800
+#define MSM_USB30_PRIM_BASE              0x6A00000
+#define MSM_USB30_QSCRATCH_PRIM_BASE     0x6AF8800
+/* USB2.0 */
+#define MSM_USB20_SEC_BASE              0x7600000
+#define MSM_USB20_SEC_QSCRATCH_BASE     0x76F8800
 /* SS QMP (Qulacomm Multi Protocol) */
 #define QMP_PHY_BASE                0x7410000
 
-/* QUSB2 PHY */
-#define QUSB2_PHY_BASE              0x7411000
-#define GCC_QUSB2_PHY_BCR           (CLK_CTL_BASE + 0x00012038)
+/* QUSB2 PHY primary */
+#define QUSB2_PRIM_PHY_BASE              0x7411000
+#define GCC_QUSB2_PRIM_PHY_BCR           (CLK_CTL_BASE + 0x00012038)
+
+/* QUSB2 PHY secondary */
+#define QUSB2_SEC_PHY_BASE              0x7412000
+#define GCC_QUSB2_SEC_PHY_BCR           (CLK_CTL_BASE + 0x0001203C)
 
 #define AHB2_PHY_BASE               0x7416000
 #define PERIPH_SS_AHB2PHY_TOP_CFG   (AHB2_PHY_BASE + 0x10)
@@ -138,6 +156,20 @@
 #define USB_PHY_CFG_AHB2PHY_CBCR    (CLK_CTL_BASE + 0x6A004)
 #define GCC_AGGRE2_USB3_AXI_CBCR    (CLK_CTL_BASE + 0x83018)
 
+/* USB20 clocks */
+#define USB_20_BCR                  (CLK_CTL_BASE + 0x12000)
+#define USB20_MASTER_CBCR           (CLK_CTL_BASE + 0x12004)
+#define USB20_SLEEP_CBCR            (CLK_CTL_BASE + 0x12008)
+#define USB20_MOCK_UTMI_CBCR        (CLK_CTL_BASE + 0x1200C)
+#define USB20_MASTER_CMD_RCGR       (CLK_CTL_BASE + 0x12010)
+#define USB20_MASTER_CFG_RCGR       (CLK_CTL_BASE + 0x12014)
+#define USB20_MASTER_M              (CLK_CTL_BASE + 0x12018)
+#define USB20_MASTER_N              (CLK_CTL_BASE + 0x1201c)
+#define USB20_MASTER_D              (CLK_CTL_BASE + 0x12020)
+#define USB20_MOCK_UTMI_CMD_RCGR    (CLK_CTL_BASE + 0x12024)
+#define USB20_MOCK_UTMI_CFG_RCGR    (CLK_CTL_BASE + 0x12028)
+#define PERIPH_NOC_USB20_AHB_CBCR   (CLK_CTL_BASE + 0x06010)
+
 /* SDCC */
 #define SDCC1_BCR                   (CLK_CTL_BASE + 0x13000) /* block reset */
 #define SDCC1_APPS_CBCR             (CLK_CTL_BASE + 0x13004) /* branch control */
@@ -209,7 +241,7 @@
  * as device memory, define the start address
  * and size in MB
  */
-#define RPMB_SND_RCV_BUF            0x91A00000
+#define RPMB_SND_RCV_BUF            0x91C00000
 #define RPMB_SND_RCV_BUF_SZ         0x2
 
 #define TCSR_BOOT_MISC_DETECT       0x007B3000
diff --git a/platform/msm8996/include/platform/irqs.h b/platform/msm8996/include/platform/irqs.h
index 61d267b..e5cc23d 100644
--- a/platform/msm8996/include/platform/irqs.h
+++ b/platform/msm8996/include/platform/irqs.h
@@ -45,7 +45,13 @@
 
 #define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP      (GIC_SPI_START + 31)
 
-#define USB30_EE1_IRQ                          (GIC_SPI_START + 131)
+/* to support secondary port usage, secondary port Interrupt*/
+int usb_irq();
+
+#define USB30_EE1_IRQ  			   (usb_irq())
+
+#define USB30_IRQ                          (GIC_SPI_START + 131)
+#define USB20_IRQ                          (GIC_SPI_START + 138)
 
 #define GLINK_IPC_IRQ                          (GIC_SPI_START + 168)
 
diff --git a/platform/msm8996/msm8996-clock.c b/platform/msm8996/msm8996-clock.c
index a5304c9..c92974a 100644
--- a/platform/msm8996/msm8996-clock.c
+++ b/platform/msm8996/msm8996-clock.c
@@ -336,6 +336,16 @@
 	},
 };
 
+static struct branch_clk gcc_periph_noc_usb20_ahb_clk = {
+	.cbcr_reg    = (uint32_t *) PERIPH_NOC_USB20_AHB_CBCR,
+	.has_sibling = 1,
+
+	.c = {
+		.dbg_name = "periph_noc_usb20_ahb_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 static struct clk_freq_tbl ftbl_gcc_usb30_master_clk[] = {
 	F(  19200000, cxo,    1,    0,    0),
 	F( 120000000, gpll0,    5,    0,    0),
@@ -343,6 +353,13 @@
 	F_END
 };
 
+static struct clk_freq_tbl ftbl_gcc_usb20_master_clk[] = {
+	F(  19200000, cxo,    1,    0,    0),
+	F( 120000000, gpll0,    5,    0,    0),
+	F( 150000000, gpll0,    4,    0,    0),
+	F_END
+};
+
 static struct rcg_clk usb30_master_clk_src = {
 	.cmd_reg      = (uint32_t *) USB30_MASTER_CMD_RCGR,
 	.cfg_reg      = (uint32_t *) USB30_MASTER_CFG_RCGR,
@@ -360,6 +377,23 @@
 	},
 };
 
+static struct rcg_clk usb20_master_clk_src = {
+	.cmd_reg      = (uint32_t *) USB20_MASTER_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) USB20_MASTER_CFG_RCGR,
+	.m_reg        = (uint32_t *) USB20_MASTER_M,
+	.n_reg        = (uint32_t *) USB20_MASTER_N,
+	.d_reg        = (uint32_t *) USB20_MASTER_D,
+
+	.set_rate     = clock_lib2_rcg_set_rate_mnd,
+	.freq_tbl     = ftbl_gcc_usb20_master_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "usb20_master_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
 static struct branch_clk gcc_usb30_master_clk = {
 	.cbcr_reg = (uint32_t *) USB30_MASTER_CBCR,
 	.bcr_reg  = (uint32_t *) USB_30_BCR,
@@ -371,6 +405,17 @@
 	},
 };
 
+static struct branch_clk gcc_usb20_master_clk = {
+	.cbcr_reg = (uint32_t *) USB20_MASTER_CBCR,
+	.bcr_reg  = (uint32_t *) USB_20_BCR,
+	.parent   = &usb20_master_clk_src.c,
+
+	.c = {
+		.dbg_name = "usb20_master_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 static struct branch_clk gcc_aggre2_usb3_axi_clk = {
 	.cbcr_reg     = (uint32_t *) GCC_AGGRE2_USB3_AXI_CBCR,
 	.parent       = &usb30_master_clk_src.c,
@@ -386,6 +431,11 @@
 	F_END
 };
 
+static struct clk_freq_tbl ftbl_gcc_usb20_mock_utmi_clk_src[] = {
+	F(  60000000, gpll0,   10,    0,     0),
+	F_END
+};
+
 static struct rcg_clk usb30_mock_utmi_clk_src = {
 	.cmd_reg      = (uint32_t *) USB30_MOCK_UTMI_CMD_RCGR,
 	.cfg_reg      = (uint32_t *) USB30_MOCK_UTMI_CFG_RCGR,
@@ -399,6 +449,19 @@
 	},
 };
 
+static struct rcg_clk usb20_mock_utmi_clk_src = {
+	.cmd_reg      = (uint32_t *) USB20_MOCK_UTMI_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) USB20_MOCK_UTMI_CFG_RCGR,
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_usb20_mock_utmi_clk_src,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "usb20_mock_utmi_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
 static struct branch_clk gcc_usb30_mock_utmi_clk = {
 	.cbcr_reg    = (uint32_t *) USB30_MOCK_UTMI_CBCR,
 	.has_sibling = 0,
@@ -410,6 +473,18 @@
 	},
 };
 
+static struct branch_clk gcc_usb20_mock_utmi_clk = {
+	.cbcr_reg    = (uint32_t *) USB20_MOCK_UTMI_CBCR,
+	.has_sibling = 0,
+	.parent      = &usb20_mock_utmi_clk_src.c,
+
+	.c = {
+		.dbg_name = "usb20_mock_utmi_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+
 static struct branch_clk gcc_usb30_sleep_clk = {
 	.cbcr_reg    = (uint32_t *) USB30_SLEEP_CBCR,
 	.has_sibling = 1,
@@ -420,6 +495,16 @@
 	},
 };
 
+static struct branch_clk gcc_usb20_sleep_clk = {
+	.cbcr_reg    = (uint32_t *) USB20_SLEEP_CBCR,
+	.has_sibling = 1,
+
+	.c = {
+		.dbg_name = "usb20_sleep_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 static struct clk_freq_tbl ftbl_gcc_usb30_phy_aux_clk_src[] = {
 	F(   1200000,         cxo,   16,    0,     0),
 	F_END
@@ -823,6 +908,12 @@
 
 	CLK_LOOKUP("usb_phy_cfg_ahb2phy_clk",     gcc_usb_phy_cfg_ahb2phy_clk.c),
 
+	/* USB20 clocks */
+	CLK_LOOKUP("usb20_noc_usb20_clk",     gcc_periph_noc_usb20_ahb_clk.c),
+	CLK_LOOKUP("usb20_master_clk",    gcc_usb20_master_clk.c),
+	CLK_LOOKUP("usb20_mock_utmi_clk", gcc_usb20_mock_utmi_clk.c),
+	CLK_LOOKUP("usb20_sleep_clk",     gcc_usb20_sleep_clk.c),
+
 	/* mdss clocks */
 	CLK_LOOKUP("mdss_mdp_clk",     mdss_mdp_clk.c),
 	CLK_LOOKUP("mdss_vsync_clk",       mdss_vsync_clk.c),
diff --git a/platform/msm8996/platform.c b/platform/msm8996/platform.c
index 79bf7c9..a3c2d3e 100644
--- a/platform/msm8996/platform.c
+++ b/platform/msm8996/platform.c
@@ -181,3 +181,46 @@
 
 	return false;
 }
+
+
+/* USB platform specific bases*/
+uint32_t usb_ctrl_base()
+{
+	if (board_hardware_id() == HW_PLATFORM_SBC)
+		return	MSM_USB20_SEC_BASE;
+	else
+		return	MSM_USB30_PRIM_BASE;
+
+}
+
+uint32_t usb_qscratch_base()
+{
+	if (board_hardware_id() == HW_PLATFORM_SBC)
+		return	MSM_USB20_SEC_QSCRATCH_BASE;
+	else
+		return	MSM_USB30_QSCRATCH_PRIM_BASE;
+}
+
+uint32_t usb_phy_base()
+{
+	if (board_hardware_id() == HW_PLATFORM_SBC)
+		return	QUSB2_SEC_PHY_BASE;
+	else
+		return	QUSB2_PRIM_PHY_BASE;
+}
+
+uint32_t usb_phy_bcr()
+{
+	if (board_hardware_id() == HW_PLATFORM_SBC)
+		return	GCC_QUSB2_SEC_PHY_BCR;
+	else
+		return	GCC_QUSB2_PRIM_PHY_BCR;
+}
+
+int usb_irq()
+{
+	if (board_hardware_id() == HW_PLATFORM_SBC)
+		return	USB20_IRQ;
+	else
+		return	USB30_IRQ;
+}
diff --git a/platform/msm_shared/board.c b/platform/msm_shared/board.c
index 19ec937..a4d3be4 100644
--- a/platform/msm_shared/board.c
+++ b/platform/msm_shared/board.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -289,30 +289,26 @@
 
 void pmic_info_populate()
 {
-	struct smem_board_info_v11 *bi_v11=NULL;
-	unsigned int board_info_len = 0;
-	unsigned ret = 0;
 	uint32_t pmic_type = 0;
+	void *smem_board_info_addr = NULL;
+	uint32_t smem_board_info_size = 0;
 
 	if (format_minor < 0xB)
 	{
 		// not needed for smem versions < 0xB
 		return;
 	}
-
-	board_info_len = sizeof(struct smem_board_info_v11) + board.num_pmics * sizeof(struct smem_pmic_info);
-	if(!(bi_v11 = malloc(board_info_len)))
+	smem_board_info_addr = smem_get_alloc_entry(SMEM_BOARD_INFO_LOCATION, &smem_board_info_size);
+	if (smem_board_info_addr == NULL)
 	{
-		dprintf(CRITICAL, "Error allocating memory for board structure\n");
+		dprintf(CRITICAL, "Error reading the smem board info address\n");
 		ASSERT(0);
 	}
-	ret = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION,
-					bi_v11,
-					board_info_len);
-	if (ret)
+
+	if (smem_board_info_size < board.pmic_array_offset)
 	{
-		dprintf(CRITICAL, "Error reading from SMEM for populating pmic info\n");
-		goto free_bi_v11;
+		dprintf(CRITICAL, "Invalid SMEM board info\n");
+		ASSERT(0);
 	}
 
 	if(!(board.pmic_info_array = malloc(board.num_pmics * sizeof(struct board_pmic_data))))
@@ -320,10 +316,11 @@
 		dprintf(CRITICAL, "Error allocating memory for pmic info array\n");
 		ASSERT(0);
 	}
+
 	struct board_pmic_data *info = board.pmic_info_array;
 	for (uint8_t i = 0; i < board.num_pmics; i++)
 	{
-		memcpy(info, (void *)(bi_v11) + board.pmic_array_offset + (i * sizeof(struct smem_pmic_info)), sizeof(struct smem_pmic_info));
+		memcpy(info, smem_board_info_addr + board.pmic_array_offset + (i * sizeof(struct smem_pmic_info)), sizeof(struct smem_pmic_info));
 		/*
 		 * fill in pimc_board_info with pmic type and pmic version information
 		 * bit no  		  	    |31  24|23         16|15          8|7		 0|
@@ -335,8 +332,6 @@
 			   ((info->pmic_version & 0xff) << 8) | (pmic_type & 0xff);
 		info++;
 	}
-free_bi_v11:
-	free(bi_v11);
 }
 
 void board_init()
diff --git a/platform/msm_shared/hsusb.c b/platform/msm_shared/hsusb.c
index 5f8d3e4..9ebe36e 100644
--- a/platform/msm_shared/hsusb.c
+++ b/platform/msm_shared/hsusb.c
@@ -2,7 +2,7 @@
  * Copyright (c) 2008, Google Inc.
  * All rights reserved.
  *
- * Copyright (c) 2009-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-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
@@ -62,7 +62,10 @@
 {
 	struct udc_descriptor *desc;
 	if ((len > 255) || (len < 2) || (num > 255) || (type > 255))
-		return 0;
+	{
+		dprintf(CRITICAL, "Invalid parameters for descriptor allocation\n");
+		ASSERT(0);
+	}
 
 	desc = malloc(sizeof(struct udc_descriptor) + len);
 	ASSERT(desc);
diff --git a/platform/msm_shared/qpic_nand.c b/platform/msm_shared/qpic_nand.c
index baba30d..3fec647 100644
--- a/platform/msm_shared/qpic_nand.c
+++ b/platform/msm_shared/qpic_nand.c
@@ -1378,6 +1378,12 @@
 }
 
 unsigned
+flash_num_pages_per_blk(void)
+{
+	return flash.num_pages_per_blk;
+}
+
+unsigned
 flash_spare_size(void)
 {
     return flash.spare_size;
diff --git a/platform/msm_shared/reboot.c b/platform/msm_shared/reboot.c
index f3441cd..d9a1310 100644
--- a/platform/msm_shared/reboot.c
+++ b/platform/msm_shared/reboot.c
@@ -109,13 +109,16 @@
 		return;
 	}
 
+	if (reboot_reason != NORMAL_DLOAD && reboot_reason != EMERGENCY_DLOAD) {
 #if USE_PON_REBOOT_REG
-	value = REG_READ(PON_SOFT_RB_SPARE);
-	value |= (reboot_reason << 2);
-	REG_WRITE(PON_SOFT_RB_SPARE, value);
+		value = REG_READ(PON_SOFT_RB_SPARE);
+		value |= (reboot_reason << 2);
+		REG_WRITE(PON_SOFT_RB_SPARE, value);
 #else
-	writel(reboot_reason, RESTART_REASON_ADDR);
+		writel(reboot_reason, RESTART_REASON_ADDR);
 #endif
+	}
+
 	/* For Dload cases do a warm reset
 	 * For other cases do a hard reset
 	 */
diff --git a/platform/msm_shared/reboot.h b/platform/msm_shared/reboot.h
index 58085df..2794d72 100644
--- a/platform/msm_shared/reboot.h
+++ b/platform/msm_shared/reboot.h
@@ -48,7 +48,9 @@
 	DM_VERITY_ENFORCING	= 0x77665509,
 	DM_VERITY_KEYSCLEAR	= 0x7766550A,
 #endif
-	/* warm reset start from  0xF0000000 */
+	/* Don't write the reason to PON reg or SMEM
+	 * if the value is more than 0xF0000000
+	 */
 	NORMAL_DLOAD		= 0xF0000001,
 	EMERGENCY_DLOAD,
 };
diff --git a/platform/msm_shared/usb30_udc.c b/platform/msm_shared/usb30_udc.c
index f175cb8..a2923f1 100644
--- a/platform/msm_shared/usb30_udc.c
+++ b/platform/msm_shared/usb30_udc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-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
@@ -1380,7 +1380,10 @@
 {
 	struct udc_descriptor *desc;
 	if ((len > 255) || (len < 2) || (num > 255) || (type > 255))
-		return 0;
+	{
+		dprintf(CRITICAL, "Invalid parameters for descriptor allocation\n");
+		ASSERT(0);
+	}
 
 	desc = malloc(sizeof(struct udc_descriptor) + len);
 	ASSERT(desc);
diff --git a/target/msm8996/init.c b/target/msm8996/init.c
index 25c1b14..51051c9 100644
--- a/target/msm8996/init.c
+++ b/target/msm8996/init.c
@@ -500,6 +500,11 @@
 	qusb2_phy_reset();
 }
 
+void target_usb_phy_sec_reset()
+{
+	qusb2_phy_reset();
+}
+
 target_usb_iface_t* target_usb30_init()
 {
 	target_usb_iface_t *t_usb_iface;
@@ -507,9 +512,20 @@
 	t_usb_iface = calloc(1, sizeof(target_usb_iface_t));
 	ASSERT(t_usb_iface);
 
-	t_usb_iface->phy_init   = usb30_qmp_phy_init;
-	t_usb_iface->phy_reset  = target_usb_phy_reset;
-	t_usb_iface->clock_init = clock_usb30_init;
+
+	/* for SBC we use secondary port */
+	if (board_hardware_id() == HW_PLATFORM_SBC)
+	{
+		/* secondary port have no QMP phy,use only QUSB2 phy that have only reset */
+		t_usb_iface->phy_init   = NULL;
+		t_usb_iface->phy_reset  = target_usb_phy_sec_reset;
+		t_usb_iface->clock_init = clock_usb20_init;
+	} else {
+		t_usb_iface->phy_init   = usb30_qmp_phy_init;
+		t_usb_iface->phy_reset  = target_usb_phy_reset;
+		t_usb_iface->clock_init = clock_usb30_init;
+	}
+
 	t_usb_iface->vbus_override = 1;
 
 	return t_usb_iface;
diff --git a/target/msm8996/rules.mk b/target/msm8996/rules.mk
index e59bfc2..c6918f7 100644
--- a/target/msm8996/rules.mk
+++ b/target/msm8996/rules.mk
@@ -8,13 +8,13 @@
 
 PLATFORM := msm8996
 
-MEMBASE := 0x91600000 # SDRAM
+MEMBASE := 0x91800000 # SDRAM
 MEMSIZE := 0x00400000 # 4MB
 
 BASE_ADDR    := 0x0000000
 
-SCRATCH_ADDR := 0x91C00000
-SCRATCH_SIZE := 740
+SCRATCH_ADDR := 0x91E00000
+SCRATCH_SIZE := 738
 KERNEL_ADDR  := 0x80000000
 KERNEL_SIZE  := 88