target/platform: msm8994: Add usb30 support

Add support for usb30 clocks, phy and target init
code.

CRs-Fixed: 636135
Change-Id: I260eef5fff73a431ba89b095def92fe0070b1662
diff --git a/platform/msm8994/acpuclock.c b/platform/msm8994/acpuclock.c
index c90718e..64c2a14 100644
--- a/platform/msm8994/acpuclock.c
+++ b/platform/msm8994/acpuclock.c
@@ -205,3 +205,71 @@
 	clock_ce_enable(instance);
 
 }
+
+void clock_usb30_gdsc_enable(void)
+{
+	uint32_t reg = readl(GCC_USB30_GDSCR);
+
+	reg &= ~(0x1);
+
+	writel(reg, GCC_USB30_GDSCR);
+}
+
+/* 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);
+	}
+
+	clock_usb30_gdsc_enable();
+
+	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);
+	}
+
+	pm8x41_lnbb_clock_ctrl(1);
+}
+
+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/msm8994/include/platform/clock.h b/platform/msm8994/include/platform/clock.h
index c6b0ab4..bad5743 100644
--- a/platform/msm8994/include/platform/clock.h
+++ b/platform/msm8994/include/platform/clock.h
@@ -45,5 +45,6 @@
 void mdp_clock_init(void);
 void clock_ce_enable(uint8_t instance);
 void clock_ce_disable(uint8_t instance);
+void clock_usb30_init(void);
 
 #endif
diff --git a/platform/msm8994/include/platform/iomap.h b/platform/msm8994/include/platform/iomap.h
index 4a6c22d..592a369 100644
--- a/platform/msm8994/include/platform/iomap.h
+++ b/platform/msm8994/include/platform/iomap.h
@@ -76,6 +76,12 @@
 
 #define MSM_USB_BASE                (PERIPH_SS_BASE + 0x00255000)
 
+#define MSM_USB30_BASE              0xF9200000
+#define MSM_USB30_QSCRATCH_BASE     0xF92F8800
+
+/* SS QMP (Qulacomm Multi Protocol) */
+#define QMP_PHY_BASE                0xF9B38000
+
 /* Clocks */
 #define CLK_CTL_BASE                0xFC400000
 
@@ -109,6 +115,29 @@
 #define USB_HS_SYSTEM_CMD_RCGR      (CLK_CTL_BASE + 0x490)
 #define USB_HS_SYSTEM_CFG_RCGR      (CLK_CTL_BASE + 0x494)
 
+/* USB3 clocks */
+#define SYS_NOC_USB3_AXI_CBCR       (CLK_CTL_BASE + 0x03FC)
+#define USB2B_PHY_SLEEP_CBCR        (CLK_CTL_BASE + 0x04AC)
+#define USB2B_PHY_BCR               (CLK_CTL_BASE + 0x04A8)
+#define USB30_MASTER_CMD_RCGR       (CLK_CTL_BASE + 0x03D4)
+#define USB30_MASTER_CFG_RCGR       (CLK_CTL_BASE + 0x03D8)
+#define USB30_MASTER_M              (CLK_CTL_BASE + 0x03DC)
+#define USB30_MASTER_N              (CLK_CTL_BASE + 0x03E0)
+#define USB30_MASTER_D              (CLK_CTL_BASE + 0x03E4)
+#define USB30_MASTER_CBCR           (CLK_CTL_BASE + 0x03C8)
+#define USB_30_BCR                  (CLK_CTL_BASE + 0x03C0)
+#define USB30_MOCK_UTMI_CMD_RCGR    (CLK_CTL_BASE + 0x03E8)
+#define USB30_MOCK_UTMI_CFG_RCGR    (CLK_CTL_BASE + 0x03EC)
+#define USB30_MOCK_UTMI_CBCR        (CLK_CTL_BASE + 0x03D0)
+#define USB30_SLEEP_CBCR            (CLK_CTL_BASE + 0x03CC)
+#define USB30_PHY_AUX_CMD_RCGR      (CLK_CTL_BASE + 0x1414)
+#define USB30_PHY_AUX_CFG_RCGR      (CLK_CTL_BASE + 0x1418)
+#define USB30_PHY_AUX_CBCR          (CLK_CTL_BASE + 0x1408)
+#define USB30_PHY_PIPE_CBCR         (CLK_CTL_BASE + 0x140C)
+#define USB30_PHY_BCR               (CLK_CTL_BASE + 0x1400)
+#define USB30PHY_PHY_BCR            (CLK_CTL_BASE + 0x1404)
+#define GCC_USB30_GDSCR             (CLK_CTL_BASE + 0x03C4)
+
 /* SDCC */
 #define SDCC1_BCR                   (CLK_CTL_BASE + 0x4C0) /* block reset */
 #define SDCC1_APPS_CBCR             (CLK_CTL_BASE + 0x4C4) /* branch control */
@@ -167,4 +196,7 @@
 
 #define MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL    0xFC4A3000
 
+#define TCSR_PHSS_USB2_PHY_SEL               0xFD4AB000
+#define PLATFORM_QMP_OFFSET                  0x8
+
 #endif
diff --git a/platform/msm8994/include/platform/irqs.h b/platform/msm8994/include/platform/irqs.h
index aeb5cb8..25383cb 100644
--- a/platform/msm8994/include/platform/irqs.h
+++ b/platform/msm8994/include/platform/irqs.h
@@ -45,6 +45,7 @@
 
 #define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP      (GIC_SPI_START + 9)
 
+#define USB30_EE1_IRQ                          (GIC_SPI_START + 131)
 #define USB1_HS_IRQ                            (GIC_SPI_START + 134)
 
 #define SDCC1_PWRCTL_IRQ                       (GIC_SPI_START + 138)
diff --git a/platform/msm8994/msm8994-clock.c b/platform/msm8994/msm8994-clock.c
index 0bf5ce0..e876088 100644
--- a/platform/msm8994/msm8994-clock.c
+++ b/platform/msm8994/msm8994-clock.c
@@ -50,11 +50,17 @@
 
 
 /* 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,
 	.disable    = clock_lib2_branch_clk_disable,
 	.set_rate   = clock_lib2_branch_set_rate,
+	.reset      = clock_lib2_branch_clk_reset,
 };
 
 static struct clk_ops clk_ops_rcg_mnd =
@@ -327,6 +333,148 @@
 	},
 };
 
+static struct branch_clk gcc_sys_noc_usb30_axi_clk = {
+	.cbcr_reg    = (uint32_t *) 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 *) USB2B_PHY_SLEEP_CBCR,
+	.bcr_reg     = (uint32_t *) USB2B_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 *) USB30_MASTER_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) USB30_MASTER_CFG_RCGR,
+	.m_reg        = (uint32_t *) USB30_MASTER_M,
+	.n_reg        = (uint32_t *) USB30_MASTER_N,
+	.d_reg        = (uint32_t *) 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 *) USB30_MASTER_CBCR,
+	.bcr_reg  = (uint32_t *) USB_30_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 *) USB30_MOCK_UTMI_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) 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 *) 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 *) 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 *) USB30_PHY_AUX_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) USB30_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 *)USB30_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 *) USB30PHY_PHY_BCR,
+	.cbcr_reg     = (uint32_t *) USB30_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 *)USB30_PHY_BCR,
+
+	.c = {
+		.dbg_name = "usb30_phy_reset",
+		.ops      = &clk_ops_rst,
+	},
+};
+
 /* Clock lookup table */
 static struct clk_lookup msm_8994_clocks[] =
 {
@@ -338,6 +486,16 @@
 
 	CLK_LOOKUP("usb_iface_clk",  gcc_usb_hs_ahb_clk.c),
 	CLK_LOOKUP("usb_core_clk",   gcc_usb_hs_system_clk.c),
+
+	/* USB30 clocks */
+	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),
+	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),
 };
 
 void platform_clock_init(void)
diff --git a/target/msm8994/init.c b/target/msm8994/init.c
index 5890110..71ee5d2 100644
--- a/target/msm8994/init.c
+++ b/target/msm8994/init.c
@@ -53,6 +53,7 @@
 #include <stdlib.h>
 #include <ufs.h>
 #include <boot_device.h>
+#include <qmp_phy.h>
 
 #define PMIC_ARB_CHANNEL_NUM    0
 #define PMIC_ARB_OWNER_ID       0
@@ -326,3 +327,41 @@
 {
 	return _emmc_recovery_init();
 }
+
+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   = usb30_qmp_phy_init;
+	t_usb_iface->phy_reset  = usb30_qmp_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";
+}
+
+/* mux hs phy to route to dwc controller */
+static void phy_mux_configure_with_tcsr()
+{
+	/* As per the hardware team, set the mux for snps controller */
+	RMWREG32(TCSR_PHSS_USB2_PHY_SEL, 0x0, 0x1, 0x1);
+}
+
+/* configure hs phy mux if using dwc controller */
+void target_usb_phy_mux_configure(void)
+{
+	if(!strcmp(target_usb_controller(), "dwc"))
+	{
+		phy_mux_configure_with_tcsr();
+	}
+}