platform: fsm9010: Bring up on ASIC

- Enable SDHC controller at 200 MHz
- Enable UART
- Enable USB3 with HS PHY
- Fixed memory map

Change-Id: If655edbc2e7a6c1e6f55c1ac8299046621e47d7e
diff --git a/platform/fsm9010/acpuclock.c b/platform/fsm9010/acpuclock.c
index a8a8f54..289e360 100644
--- a/platform/fsm9010/acpuclock.c
+++ b/platform/fsm9010/acpuclock.c
@@ -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 are
@@ -149,14 +149,14 @@
 	}
 	else
 	{
-		dprintf(CRITICAL, "sdc frequency (%d) is not supported\n", freq);
+		dprintf(CRITICAL, "sdc frequency (%u) is not supported\n", freq);
+		ret = 0;
 		ASSERT(0);
 	}
 
-
 	if(ret)
 	{
-		dprintf(CRITICAL, "failed to set sdc1_core_clk ret = %d\n", ret);
+		dprintf(CRITICAL, "failed to set sdc%u_core_clk ret = %d\n", interface, ret);
 		ASSERT(0);
 	}
 
@@ -170,21 +170,23 @@
 void clock_config_uart_dm(uint8_t id)
 {
 	int ret;
-	char str[256];
+	char iclk[64];
+	char cclk[64];
 
-	sprintf(str, "uart%d_iface_clk", id);
-	ret = clk_get_set_enable(str, 0, 1);
+	snprintf(iclk, sizeof(iclk), "uart%u_iface_clk", id);
+	snprintf(cclk, sizeof(cclk), "uart%u_core_clk", id);
+
+	ret = clk_get_set_enable(iclk, 0, 1);
 	if(ret)
 	{
-		dprintf(CRITICAL, "failed to set uart2_iface_clk ret = %d\n", ret);
+		dprintf(CRITICAL, "failed to set uart%u_iface_clk ret = %d\n", id, ret);
 		ASSERT(0);
 	}
 
-	sprintf(str, "uart%d_core_clk", id);
-	ret = clk_get_set_enable(str, 7372800, 1);
+	ret = clk_get_set_enable(cclk, 7372800, 1);
 	if(ret)
 	{
-		dprintf(CRITICAL, "failed to set uart1_core_clk ret = %d\n", ret);
+		dprintf(CRITICAL, "failed to set uart%u_core_clk ret = %d\n", id, ret);
 		ASSERT(0);
 	}
 }
@@ -343,3 +345,66 @@
 		return;
 	}
 }
+
+/* enables usb30 clocks */
+void clock_usb30_init(void)
+{
+	int ret;
+
+	ret = clk_get_set_enable("usb30_iface_clk", 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb30_iface_clk. ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	ret = clk_get_set_enable("usb30_master_clk", 125000000, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb30_master_clk. ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	ret = clk_get_set_enable("usb30_phy_aux_clk", 1200000, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb30_phy_aux_clk. ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	ret = clk_get_set_enable("usb30_mock_utmi_clk", 60000000, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb30_mock_utmi_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	ret = clk_get_set_enable("usb30_sleep_clk", 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb30_sleep_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	ret = clk_get_set_enable("usb_phy_cfg_ahb2phy_clk", 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to enable usb_phy_cfg_ahb2phy_clk = %d\n", ret);
+		ASSERT(0);
+	}
+}
+
+void clock_bumpup_pipe3_clk()
+{
+	int ret = 0;
+
+	ret = clk_get_set_enable("usb30_pipe_clk", 0, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set usb30_pipe_clk. ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	return;
+}
+
diff --git a/platform/fsm9010/fsm9010-clock.c b/platform/fsm9010/fsm9010-clock.c
index a3d03e4..24bac83 100644
--- a/platform/fsm9010/fsm9010-clock.c
+++ b/platform/fsm9010/fsm9010-clock.c
@@ -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 are
@@ -49,6 +49,11 @@
 
 
 /* Clock Operations */
+static struct clk_ops clk_ops_rst =
+{
+	.reset     = clock_lib2_reset_clk_reset,
+};
+
 static struct clk_ops clk_ops_branch =
 {
 	.enable     = clock_lib2_branch_clk_enable,
@@ -357,6 +362,160 @@
 	},
 };
 
+/* USB30 Clocks */
+
+static struct branch_clk gcc_sys_noc_usb30_axi_clk = {
+	.cbcr_reg    = (uint32_t *) GCC_SYS_NOC_USB3_AXI_CBCR,
+	.has_sibling = 1,
+
+	.c = {
+		.dbg_name = "sys_noc_usb30_axi_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct branch_clk gcc_usb2b_phy_sleep_clk = {
+	.cbcr_reg    = (uint32_t *) GCC_USB2A_PHY_SLEEP_CBCR,
+	.bcr_reg     = (uint32_t *) GCC_USB2A_PHY_BCR,
+	.has_sibling = 1,
+
+	.c = {
+		.dbg_name = "usb2b_phy_sleep_clk",
+		.ops      = &clk_ops_branch,
+    },
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb30_master_clk[] = {
+	F( 125000000, gpll0,    1,    5,    24),
+	F_END
+};
+
+static struct rcg_clk usb30_master_clk_src = {
+	.cmd_reg      = (uint32_t *) GCC_USB30_MASTER_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_USB30_MASTER_CFG_RCGR,
+	.m_reg        = (uint32_t *) GCC_USB30_MASTER_M,
+	.n_reg        = (uint32_t *) GCC_USB30_MASTER_N,
+	.d_reg        = (uint32_t *) GCC_USB30_MASTER_D,
+
+	.set_rate     = clock_lib2_rcg_set_rate_mnd,
+	.freq_tbl     = ftbl_gcc_usb30_master_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "usb30_master_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct branch_clk gcc_usb30_master_clk = {
+	.cbcr_reg = (uint32_t *) GCC_USB30_MASTER_CBCR,
+	.bcr_reg  = (uint32_t *) GCC_USB30_BCR,
+	.parent   = &usb30_master_clk_src.c,
+
+	.c = {
+		.dbg_name = "usb30_master_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct clk_freq_tbl ftbl_gcc_usb30_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 *) GCC_USB30_MOCK_UTMI_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_USB30_MOCK_UTMI_CFG_RCGR,
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_usb30_mock_utmi_clk_src,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "usb30_mock_utmi_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct branch_clk gcc_usb30_mock_utmi_clk = {
+	.cbcr_reg    = (uint32_t *) GCC_USB30_MOCK_UTMI_CBCR,
+	.has_sibling = 0,
+	.parent      = &usb30_mock_utmi_clk_src.c,
+
+	.c = {
+		.dbg_name = "usb30_mock_utmi_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct branch_clk gcc_usb30_sleep_clk = {
+	.cbcr_reg    = (uint32_t *) GCC_USB30_SLEEP_CBCR,
+	.has_sibling = 1,
+
+	.c = {
+		.dbg_name = "usb30_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
+};
+
+static struct rcg_clk usb30_phy_aux_clk_src = {
+	.cmd_reg      = (uint32_t *) GCC_USB3_PHY_AUX_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_USB3_PHY_AUX_CFG_RCGR,
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_usb30_phy_aux_clk_src,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "usb30_phy_aux_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct branch_clk gcc_usb30_phy_aux_clk = {
+	.cbcr_reg    = (uint32_t *) GCC_USB3_PHY_AUX_CBCR,
+	.has_sibling = 0,
+	.parent      = &usb30_phy_aux_clk_src.c,
+
+	.c = {
+		.dbg_name = "usb30_phy_aux_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct branch_clk gcc_usb30_pipe_clk = {
+	.bcr_reg      = (uint32_t *) GCC_USB3_PHY_PHY_BCR,
+	.cbcr_reg     = (uint32_t *) GCC_USB3_PHY_PIPE_CBCR,
+	.has_sibling  = 1,
+
+	.c = {
+		.dbg_name = "usb30_pipe_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
+static struct reset_clk gcc_usb30_phy_reset = {
+	.bcr_reg = (uint32_t ) GCC_USB3_PHY_BCR,
+
+	.c = {
+		.dbg_name = "usb30_phy_reset",
+		.ops      = &clk_ops_rst,
+	},
+};
+
+static struct branch_clk gcc_usb_phy_cfg_ahb2phy_clk = {
+	.cbcr_reg = (uint32_t *) GCC_USB_HS_PHY_CFG_AHB_CBCR,
+	.has_sibling = 1,
+
+	.c = {
+		.dbg_name = "usb_phy_cfg_ahb2phy_clk",
+		.ops = &clk_ops_branch,
+	},
+};
+
 /* CE Clocks */
 static struct clk_freq_tbl ftbl_gcc_ce2_clk[] = {
 	F( 50000000,  gpll0,  12,   0,   0),
@@ -481,6 +640,17 @@
 	CLK_LOOKUP("usb_iface_clk",  gcc_usb_hs_ahb_clk.c),
 	CLK_LOOKUP("usb_core_clk",   gcc_usb_hs_system_clk.c),
 
+	CLK_LOOKUP("usb2b_phy_sleep_clk", gcc_usb2b_phy_sleep_clk.c),
+	CLK_LOOKUP("usb30_master_clk",    gcc_usb30_master_clk.c),
+	CLK_LOOKUP("usb30_iface_clk",     gcc_sys_noc_usb30_axi_clk.c),
+	CLK_LOOKUP("usb30_mock_utmi_clk", gcc_usb30_mock_utmi_clk.c),
+	CLK_LOOKUP("usb30_sleep_clk",     gcc_usb30_sleep_clk.c),
+	CLK_LOOKUP("usb30_phy_aux_clk",   gcc_usb30_phy_aux_clk.c),
+	CLK_LOOKUP("usb30_pipe_clk",      gcc_usb30_pipe_clk.c),
+	CLK_LOOKUP("usb30_phy_reset",     gcc_usb30_phy_reset.c),
+
+	CLK_LOOKUP("usb_phy_cfg_ahb2phy_clk",     gcc_usb_phy_cfg_ahb2phy_clk.c),
+
 	CLK_LOOKUP("ce2_ahb_clk",  gcc_ce2_ahb_clk.c),
 	CLK_LOOKUP("ce2_axi_clk",  gcc_ce2_axi_clk.c),
 	CLK_LOOKUP("ce2_core_clk", gcc_ce2_clk.c),
diff --git a/platform/fsm9010/gpio.c b/platform/fsm9010/gpio.c
index e4d38c3..538831f 100644
--- a/platform/fsm9010/gpio.c
+++ b/platform/fsm9010/gpio.c
@@ -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 are
@@ -57,23 +57,24 @@
 	static struct {
 		unsigned int gpio_tx;
 		unsigned int gpio_rx;
+		unsigned int function;
 	} gpio_table[] = {
-		{ 12, 13 },
-		{ 4, 5 },
-		{ 8, 6 },
-		{ 10, 11 },
+		{ 8, 6, 3 },
+		{ 4, 5, 2 },
+		{ 12, 13, 2 },
+		{ 10, 11, 1 },
 	};
 
 	if (id >= ARRAY_SIZE(gpio_table))
 		return;
 
 	/* configure rx gpio */
-	gpio_tlmm_config(gpio_table[id].gpio_rx, 2, GPIO_INPUT, GPIO_NO_PULL,
-				GPIO_8MA, GPIO_DISABLE);
+	gpio_tlmm_config(gpio_table[id].gpio_rx, gpio_table[id].function,
+		GPIO_INPUT, GPIO_NO_PULL, GPIO_8MA, GPIO_DISABLE);
 
 	/* configure tx gpio */
-	gpio_tlmm_config(gpio_table[id].gpio_tx, 2, GPIO_OUTPUT, GPIO_NO_PULL,
-				GPIO_8MA, GPIO_DISABLE);
+	gpio_tlmm_config(gpio_table[id].gpio_tx,  gpio_table[id].function,
+		GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA, GPIO_DISABLE);
 }
 
 void gpio_config_blsp_i2c(uint8_t blsp_id, uint8_t qup_id)
diff --git a/platform/fsm9010/include/platform/clock.h b/platform/fsm9010/include/platform/clock.h
index 2690f53..fdb68d2 100644
--- a/platform/fsm9010/include/platform/clock.h
+++ b/platform/fsm9010/include/platform/clock.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 are
@@ -32,7 +32,7 @@
 #include <clock.h>
 #include <clock_lib2.h>
 
-#define UART_DM_CLK_RX_TX_BIT_RATE 0x99
+#define UART_DM_CLK_RX_TX_BIT_RATE 0xcc
 
 void platform_clock_init(void);
 
@@ -43,5 +43,6 @@
 void clock_config_ce(uint8_t instance);
 void clock_ce_enable(uint8_t instance);
 void clock_ce_disable(uint8_t instance);
+void clock_usb30_init(void);
 
 #endif
diff --git a/platform/fsm9010/include/platform/iomap.h b/platform/fsm9010/include/platform/iomap.h
index fca1800..bfd31df 100644
--- a/platform/fsm9010/include/platform/iomap.h
+++ b/platform/fsm9010/include/platform/iomap.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 are
@@ -67,6 +67,7 @@
 #define BLSP1_UART3_BASE            (PERIPH_SS_BASE + 0x00120000)
 
 #define MSM_USB_BASE                (PERIPH_SS_BASE + 0x00200000)
+#define TCSR_PHSS_USB2_PHY_SEL      0xFD4AB000
 
 #define CLK_CTL_BASE                0xFC400000
 
@@ -176,4 +177,57 @@
 #define SDCC_HC_PWRCTL_MASK_REG     (0x000000E0)
 #define SDCC_HC_PWRCTL_CLEAR_REG    (0x000000E4)
 #define SDCC_HC_PWRCTL_CTL_REG      (0x000000E8)
+
+/* USB 3.0 clocks */
+#define GCC_USB30_MASTER_CBCR       (CLK_CTL_BASE + 0x0240)
+#define GCC_USB30_SLEEP_CBCR        (CLK_CTL_BASE + 0x0244)
+#define GCC_USB30_MOCK_UTMI_CBCR    (CLK_CTL_BASE + 0x0248)
+#define GCC_USB30_MASTER_CMD_RCGR   (CLK_CTL_BASE + 0x024C)
+#define GCC_USB30_MASTER_CFG_RCGR   (CLK_CTL_BASE + 0x0250)
+#define GCC_USB30_MASTER_M          (CLK_CTL_BASE + 0x0254)
+#define GCC_USB30_MASTER_N          (CLK_CTL_BASE + 0x0258)
+#define GCC_USB30_MASTER_D          (CLK_CTL_BASE + 0x025C)
+#define GCC_USB30_MOCK_UTMI_CMD_RCGR (CLK_CTL_BASE + 0x0260)
+#define GCC_USB30_MOCK_UTMI_CFG_RCGR (CLK_CTL_BASE + 0x0264)
+
+/* USB Phy */
+#define GCC_USB3_PHY_BCR            (CLK_CTL_BASE + 0x280)
+#define GCC_USB3PHY_PHY_BCR         (CLK_CTL_BASE + 0x284)
+#define GCC_USB3_PHY_AUX_CBCR       (CLK_CTL_BASE + 0x288)
+#define GCC_USB3_PHY_PIPE_CBCR      (CLK_CTL_BASE + 0x28C)
+#define GCC_USB3_PHY_PIPE_MISC      (CLK_CTL_BASE + 0x290)
+#define GCC_USB3_PHY_AUX_CMD_RCGR   (CLK_CTL_BASE + 0x294)
+#define GCC_USB3_PHY_AUX_CFG_RCGR   (CLK_CTL_BASE + 0x298)
+
+#define GCC_USB30_BCR               (CLK_CTL_BASE + 0x274)
+#define GCC_SYS_NOC_USB3_AXI_CBCR   (CLK_CTL_BASE + 0x278)
+
+/* USB Misc */
+#define GCC_USB_HS_HSIC_BCR         (CLK_CTL_BASE + 0x3C0)
+#define GCC_USB_HS_HSIC_GDSCR       (CLK_CTL_BASE + 0x3C4)
+#define GCC_USB_BOOT_CLOCK_CTL      (CLK_CTL_BASE + 0x1A00)
+#define GCC_USB_HS_PHY_CFG_AHB_CBCR (CLK_CTL_BASE + 0x3EC0)
+#define GCC_USB_SS_PHY_LDO_EN       (CLK_CTL_BASE + 0x3F00)
+
+/* USB HS */
+#define GCC_USB_HS_BCR              (CLK_CTL_BASE + 0x480)
+#define GCC_USB_HS_SYSTEM_CBCR      (CLK_CTL_BASE + 0x484)
+#define GCC_USB_HS_AHB_CBCR         (CLK_CTL_BASE + 0x488)
+#define GCC_USB_HS_SYSTEM_CMD_RCGR  (CLK_CTL_BASE + 0x490)
+#define GCC_USB_HS_SYSTEM_CFG_RCGR  (CLK_CTL_BASE + 0x494)
+#define GCC_USB2A_PHY_BCR           (CLK_CTL_BASE + 0x4A8)
+#define GCC_USB2A_PHY_SLEEP_CBCR    (CLK_CTL_BASE + 0x4AC)
+#define GCC_USB2_HS_PHY_ONLY_BCR    (CLK_CTL_BASE + 0x4B0)
+
+#define GCC_QUSB2_PHY_BCR           GCC_USB2A_PHY_BCR
+
+/* USB30 base */
+#define MSM_USB30_BASE              0xF9200000
+#define MSM_USB30_QSCRATCH_BASE     0xF92F8800
+
+/* USB PHY */
+#define CM_DWC_USB2_CM_DWC_USB2_BASE 0xFCA00000
+#define CM_DWC_USB3_CM_DWC_USB3_BASE 0xFCA10000
+#define AHB2PHY_AHB2PHY_BASE         0xFCA06000
+
 #endif
diff --git a/platform/fsm9010/include/platform/irqs.h b/platform/fsm9010/include/platform/irqs.h
index 6b4900f..cba9a03 100644
--- a/platform/fsm9010/include/platform/irqs.h
+++ b/platform/fsm9010/include/platform/irqs.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 are
@@ -45,9 +45,11 @@
 
 #define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP      (GIC_SPI_START + 8)
 
-#define USB1_HS_BAM_IRQ                        (GIC_SPI_START + 135)
 #define USB1_HS_IRQ                            (GIC_SPI_START + 134)
-#define USB1_IRQ                               (GIC_SPI_START + 142)
+#define USB30_EE1_IRQ                          (GIC_SPI_START + 224)
+#define USB30_EE2_IRQ                          (GIC_SPI_START + 225)
+#define USB30_POWER_EVENT_IRQ                  (GIC_SPI_START + 226)
+#define USB30_HS_PHY_IRQ                       (GIC_SPI_START + 227)
 
 /* Retrofit universal macro names */
 #define INT_USB_HS                             USB1_HS_IRQ
diff --git a/project/fsm9010.mk b/project/fsm9010.mk
index bd48cd7..7759f73 100644
--- a/project/fsm9010.mk
+++ b/project/fsm9010.mk
@@ -13,7 +13,8 @@
 endif
 
 EMMC_BOOT := 1
-ENABLE_SDHCI_SUPPORT := 0
+ENABLE_SDHCI_SUPPORT := 1
+ENABLE_USB30_SUPPORT := 1
 
 DEFINES += WITH_DEBUG_DCC=1
 DEFINES += WITH_DEBUG_UART=1
@@ -33,3 +34,7 @@
 ifeq ($(ENABLE_SDHCI_SUPPORT),1)
 DEFINES += MMC_SDHCI_SUPPORT=1
 endif
+
+ifeq ($(ENABLE_USB30_SUPPORT),1)
+DEFINES += USB30_SUPPORT=1
+endif
diff --git a/target/fsm9010/init.c b/target/fsm9010/init.c
index 8f3da01..7e47d47 100644
--- a/target/fsm9010/init.c
+++ b/target/fsm9010/init.c
@@ -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 are
@@ -50,6 +50,8 @@
 #include <platform/gpio.h>
 #include <platform/timer.h>
 #include <stdlib.h>
+#include <string.h>
+#include <sdhci_msm.h>
 
 extern  bool target_use_signed_kernel(void);
 static void set_sdc_power_ctrl();
@@ -91,7 +93,7 @@
 void target_early_init(void)
 {
 #if WITH_DEBUG_UART
-	uart_dm_init(2, 0, BLSP1_UART2_BASE);
+	uart_dm_init(3, 0, BLSP1_UART3_BASE);
 #endif
 }
 
@@ -155,31 +157,39 @@
 }
 
 #if MMC_SDHCI_SUPPORT
+
 static void target_mmc_sdhci_init()
 {
-	struct mmc_config_data config = {0};
+	static uint32_t mmc_clks[] = {
+		MMC_CLK_200MHZ, MMC_CLK_96MHZ, MMC_CLK_50MHZ };
 
+	struct mmc_config_data config;
+	unsigned int i;
+
+	memset(&config, 0, sizeof config);
 	config.bus_width = DATA_BUS_WIDTH_8BIT;
-	config.max_clk_rate = MMC_CLK_96MHZ;
 
 	/* Trying Slot 1*/
 	config.slot = 1;
 	config.sdhc_base = mmc_sdhci_base[config.slot - 1];
 	config.pwrctl_base = mmc_sdc_base[config.slot - 1];
 	config.pwr_irq     = mmc_sdc_pwrctl_irq[config.slot - 1];
+	config.hs400_support = 0;
 
-	if (!(dev = mmc_init(&config))) {
+	for (i = 0; i < ARRAY_SIZE(mmc_clks); ++i) {
+		config.max_clk_rate = mmc_clks[i];
+		dprintf(INFO, "SDHC Running at %u MHz\n",
+			config.max_clk_rate / 1000000);
+		dev = mmc_init(&config);
+		if (dev && partition_read_table() == 0)
+			return;
+	}
+
+	if (dev == NULL)
 		dprintf(CRITICAL, "mmc init failed!");
-		ASSERT(0);
-	}
-
-	/*
-	 * MMC initialization is complete, read the partition table info
-	 */
-	if (partition_read_table()) {
+	else
 		dprintf(CRITICAL, "Error reading the partition table info\n");
-		ASSERT(0);
-	}
+	ASSERT(0);
 }
 
 void *target_mmc_device()
@@ -347,34 +357,6 @@
 	return 0;
 }
 
-/* Check if MSM needs VBUS mimic for USB */
-static int target_needs_vbus_mimic()
-{
-	return 1;
-}
-
-/* Do target specific usb initialization */
-void target_usb_init(void)
-{
-	uint32_t val;
-
-	extern void ulpi_write(unsigned val, unsigned reg);
-
-	if (target_needs_vbus_mimic()) {
-		/* Select and enable external configuration with USB PHY */
-		ulpi_write(ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT, ULPI_MISC_A_SET);
-
-		/* Enable sess_vld */
-		val = readl(USB_GENCONFIG_2) | GEN2_SESS_VLD_CTRL_EN;
-		writel(val, USB_GENCONFIG_2);
-
-		/* Enable external vbus configuration in the LINK */
-		val = readl(USB_USBCMD);
-		val |= SESS_VLD_CTRL;
-		writel(val, USB_USBCMD);
-	}
-}
-
 /* Returns 1 if target supports continuous splash screen. */
 int target_cont_splash_screen()
 {
@@ -390,6 +372,7 @@
 {
 #if MMC_SDHCI_SUPPORT
 	mmc_put_card_to_sleep(dev);
+	sdhci_mode_disable(&dev->host);
 #else
 	mmc_put_card_to_sleep();
 #endif
@@ -412,17 +395,41 @@
 	/* Drive strength configs for sdc pins */
 	struct tlmm_cfgs sdc1_hdrv_cfg[] =
 	{
-		{ SDC1_CLK_HDRV_CTL_OFF,  TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK },
-		{ SDC1_CMD_HDRV_CTL_OFF,  TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK },
-		{ SDC1_DATA_HDRV_CTL_OFF, TLMM_CUR_VAL_10MA, TLMM_HDRV_MASK },
+		{
+			off: SDC1_CLK_HDRV_CTL_OFF,
+			val: TLMM_CUR_VAL_10MA,
+			mask: TLMM_HDRV_MASK
+		},
+		{
+			off: SDC1_CMD_HDRV_CTL_OFF,
+			val: TLMM_CUR_VAL_10MA,
+			mask: TLMM_HDRV_MASK
+		},
+		{
+			off: SDC1_DATA_HDRV_CTL_OFF,
+			val: TLMM_CUR_VAL_10MA,
+			mask: TLMM_HDRV_MASK
+		},
 	};
 
 	/* Pull configs for sdc pins */
 	struct tlmm_cfgs sdc1_pull_cfg[] =
 	{
-		{ SDC1_CLK_PULL_CTL_OFF,  TLMM_NO_PULL, TLMM_PULL_MASK },
-		{ SDC1_CMD_PULL_CTL_OFF,  TLMM_PULL_UP, TLMM_PULL_MASK },
-		{ SDC1_DATA_PULL_CTL_OFF, TLMM_PULL_UP, TLMM_PULL_MASK },
+		{
+			off: SDC1_CLK_PULL_CTL_OFF,
+			val: TLMM_NO_PULL,
+			mask: TLMM_PULL_MASK
+		},
+		{
+			off: SDC1_CMD_PULL_CTL_OFF,
+			val: TLMM_PULL_UP,
+			mask: TLMM_PULL_MASK
+		},
+		{
+			off: SDC1_DATA_PULL_CTL_OFF,
+			val: TLMM_PULL_UP,
+			mask: TLMM_PULL_MASK
+		},
 	};
 
 	/* Set the drive strength & pull control values */
@@ -437,6 +444,92 @@
 	return _emmc_recovery_init();
 }
 
+#define USB30_QSCRATCH_GENERAL_CFG			(MSM_USB30_QSCRATCH_BASE + 0x08)
+#define USB30_QSCRATCH_GENERAL_CFG_PIPE_UTMI_CLK_SEL	(1 << 0)
+#define USB30_QSCRATCH_GENERAL_CFG_PIPE3_PHYSTATUS_SW	(1 << 3)
+#define USB30_QSCRATCH_GENERAL_CFG_PIPE_UTMI_CLK_DIS	(1 << 8)
+
+#define CM_DWC_USB2_USB_PHY_UTMI_CTRL5			(CM_DWC_USB2_CM_DWC_USB2_BASE + 0x74)
+#define CM_DWC_USB2_USB_PHY_HS_PHY_CTRL_COMMON0		(CM_DWC_USB2_CM_DWC_USB2_BASE + 0x78)
+#define CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X0	(CM_DWC_USB2_CM_DWC_USB2_BASE + 0x98)
+#define CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X1	(CM_DWC_USB2_CM_DWC_USB2_BASE + 0x9c)
+#define CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X2	(CM_DWC_USB2_CM_DWC_USB2_BASE + 0xa0)
+#define CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X3	(CM_DWC_USB2_CM_DWC_USB2_BASE + 0xa4)
+#define CM_DWC_USB2_USB_PHY_REFCLK_CTRL			(CM_DWC_USB2_CM_DWC_USB2_BASE + 0xe8)
+
+void target_usb_phy_mux_configure(void)
+{
+}
+
+void target_usb_phy_init(void)
+{
+	uint32_t val;
+
+	/* Disable clock */
+	val = readl(USB30_QSCRATCH_GENERAL_CFG);
+	val |= USB30_QSCRATCH_GENERAL_CFG_PIPE_UTMI_CLK_DIS;
+	writel(val, USB30_QSCRATCH_GENERAL_CFG);
+	mdelay(1);
+
+	/* Select UTMI instead of PIPE3 */
+	val |= USB30_QSCRATCH_GENERAL_CFG_PIPE_UTMI_CLK_SEL;
+	writel(val, USB30_QSCRATCH_GENERAL_CFG);
+	val |= USB30_QSCRATCH_GENERAL_CFG_PIPE3_PHYSTATUS_SW;
+	writel(val, USB30_QSCRATCH_GENERAL_CFG);
+	mdelay(1);
+
+	/* Enable clock */
+	val &= ~USB30_QSCRATCH_GENERAL_CFG_PIPE_UTMI_CLK_DIS;
+	writel(val, USB30_QSCRATCH_GENERAL_CFG);
+
+	/* Initialize HS PICO PHY */
+	writel(0xc4, CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X0);
+	writel(0x88, CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X1);
+	writel(0x11, CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X2);
+	writel(0x03, CM_DWC_USB2_USB_PHY_PARAMETER_OVERRIDE_X3);
+
+	writel(0x02, CM_DWC_USB2_USB_PHY_UTMI_CTRL5);
+	mdelay(1);
+	writel(0x00, CM_DWC_USB2_USB_PHY_UTMI_CTRL5);
+
+	val = readl(CM_DWC_USB2_USB_PHY_REFCLK_CTRL);
+	val &= ~(7 << 1);
+	val |= (6 << 1);
+	writel(val, CM_DWC_USB2_USB_PHY_REFCLK_CTRL);
+
+	val = readl(CM_DWC_USB2_USB_PHY_HS_PHY_CTRL_COMMON0);
+	val &= ~(7 << 4);
+	val |= (7 << 4);
+	writel(val, CM_DWC_USB2_USB_PHY_HS_PHY_CTRL_COMMON0);
+}
+
+void target_usb_phy_reset(void)
+{
+}
+
+target_usb_iface_t* target_usb30_init()
+{
+	target_usb_iface_t *t_usb_iface;
+
+	t_usb_iface = calloc(1, sizeof(target_usb_iface_t));
+	ASSERT(t_usb_iface);
+
+	t_usb_iface->mux_config = target_usb_phy_mux_configure;
+	t_usb_iface->phy_init   = target_usb_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;
+}
+
+/* identify the usb controller to be used for the target */
+const char * target_usb_controller()
+{
+	return "dwc";
+}
+
+/* configure hs phy mux if using dwc controller */
 void target_usb_stop(void)
 {
 }
diff --git a/target/fsm9010/meminfo.c b/target/fsm9010/meminfo.c
index c6dd53e..fa0f96a 100644
--- a/target/fsm9010/meminfo.c
+++ b/target/fsm9010/meminfo.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, 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 are
@@ -90,6 +90,6 @@
 
 unsigned target_get_max_flash_size(void)
 {
-	return (512 * 1024 * 1024);
+	return (86 * 1024 * 1024);
 }
 #endif /* DEVICE_TREE */
diff --git a/target/fsm9010/rules.mk b/target/fsm9010/rules.mk
index 36cdc57..17a1b1d 100644
--- a/target/fsm9010/rules.mk
+++ b/target/fsm9010/rules.mk
@@ -4,7 +4,7 @@
 
 PLATFORM := fsm9010
 
-MEMBASE := 0x0F900000 # SDRAM
+MEMBASE := 0x18a00000 # SDRAM
 MEMSIZE := 0x00100000 # 1MB
 
 BASE_ADDR        := 0x0b600000
@@ -12,12 +12,13 @@
 TAGS_ADDR        := BASE_ADDR+0x01e00000
 KERNEL_ADDR      := BASE_ADDR+0x00008000
 RAMDISK_ADDR     := BASE_ADDR+0x02000000
-SCRATCH_ADDR     := 0x0ff00000
+SCRATCH_ADDR     := 0x0e000000
 
 MODULES += \
 	dev/keys \
-    lib/ptable \
-    lib/libfdt
+	lib/ptable \
+	lib/libfdt \
+	dev/pmic/pm8x41
 
 DEFINES += \
 	MEMSIZE=$(MEMSIZE) \