platform: Add support for sdxhedgehog

Add the required clock, platform id changes to support
sdxhedgehog.
Update the QUSB2 reset sequence on sdxhedgehog.

CRs-Fixed: 1076197
Change-Id: I8aa00b487b8366b8e294c8d98f434ff800f52d1b
diff --git a/include/platform.h b/include/platform.h
index 2eaa95b..945ed27 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -86,4 +86,5 @@
 void get_baseband_version(unsigned char *buf);
 bool is_device_locked();
 bool platform_is_mdmcalifornium();
+bool platform_is_sdxhedgehog();
 #endif
diff --git a/platform/mdm9640/acpuclock.c b/platform/mdm9640/acpuclock.c
index d927fa6..38b1f22 100644
--- a/platform/mdm9640/acpuclock.c
+++ b/platform/mdm9640/acpuclock.c
@@ -106,7 +106,10 @@
 
 	clock_usb30_gdsc_enable();
 
-	ret = clk_get_set_enable("usb30_master_clk", 125000000, 1);
+	if (platform_is_sdxhedgehog())
+		ret = clk_get_set_enable("usb30_master_clk_sdxhedgehog", 200000000, 1);
+	else
+		ret = clk_get_set_enable("usb30_master_clk", 125000000, 1);
 	if(ret)
 	{
 		dprintf(CRITICAL, "failed to set usb30_master_clk. ret = %d\n", ret);
@@ -115,6 +118,8 @@
 
 	if (platform_is_mdmcalifornium())
 		ret = clk_get_set_enable("usb30_pipe_clk_mdmcalifornium", 0, 1);
+	else if (platform_is_sdxhedgehog())
+		ret = clk_get_set_enable("usb30_pipe_clk_sdxhedgehog", 0, 1);
 	else
 		ret = clk_get_set_enable("usb30_pipe_clk", 19200000, 1);
 
@@ -131,7 +136,10 @@
 		ASSERT(0);
 	}
 
-	ret = clk_get_set_enable("usb30_mock_utmi_clk", 60000000, true);
+	if (platform_is_sdxhedgehog())
+		ret = clk_get_set_enable("usb30_mock_utmi_clk_sdxhedgehog", 19200000, 1);
+	else
+		ret = clk_get_set_enable("usb30_mock_utmi_clk", 60000000, true);
 	if(ret)
 	{
 		dprintf(CRITICAL, "failed to set usb30_mock_utmi_clk ret = %d\n", ret);
@@ -175,7 +183,10 @@
 	int ret = 0;
 	char clk_name[64];
 
-	snprintf(clk_name, sizeof(clk_name), "sdc%u_core_clk", interface);
+	if(platform_is_sdxhedgehog())
+		snprintf(clk_name, sizeof(clk_name), "sdc%u_core_clk_sdxhedgehog", interface);
+	else
+		snprintf(clk_name, sizeof(clk_name), "sdc%u_core_clk", interface);
 
 	if(freq == MMC_CLK_400KHZ)
 	{
@@ -222,6 +233,9 @@
 	}
 }
 
+/*
+ * This is the clock reset function for USB3
+ */
 void clock_reset_usb_phy()
 {
 	int ret;
@@ -237,8 +251,14 @@
 	phy_reset_clk = clk_get("usb30_phy_reset");
 	ASSERT(phy_reset_clk);
 
-	pipe_reset_clk = clk_get("usb30_pipe_clk");
-	ASSERT(pipe_reset_clk);
+	if(platform_is_sdxhedgehog()){
+		pipe_reset_clk = clk_get("usb30_pipe_clk_sdxhedgehog");
+		ASSERT(pipe_reset_clk);
+	}
+	else{
+		pipe_reset_clk = clk_get("usb30_pipe_clk");
+		ASSERT(pipe_reset_clk);
+	}
 
 	/* ASSERT */
 	ret = clk_reset(master_clk, CLK_RESET_ASSERT);
diff --git a/platform/mdm9640/mdm9640-clock.c b/platform/mdm9640/mdm9640-clock.c
index 8e26bcf..b6ad898 100644
--- a/platform/mdm9640/mdm9640-clock.c
+++ b/platform/mdm9640/mdm9640-clock.c
@@ -147,6 +147,46 @@
 	},
 };
 
+static struct clk_freq_tbl ftbl_gcc_sdcc1_2_apps_clk_sdxhedgehog[] =
+{
+	F(    144000,    cxo,   16,    3,    25),
+	F(    400000,    cxo,   12,    1,     4),
+	F(  20000000, gpll0,   15,    1,     2),
+	F(  25000000, gpll0,   12,    1,     2),
+	F(  50000000, gpll0,   12,    0,     0),
+	F( 100000000, gpll0,    6,    0,     0),
+	F_END
+};
+
+static struct rcg_clk sdcc1_apps_clk_src_sdxhedgehog =
+{
+	.cmd_reg      = (uint32_t *) SDCC1_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) SDCC1_CFG_RCGR,
+	.m_reg        = (uint32_t *) SDCC1_M,
+	.n_reg        = (uint32_t *) SDCC1_N,
+	.d_reg        = (uint32_t *) SDCC1_D,
+
+	.set_rate     = clock_lib2_rcg_set_rate_mnd,
+	.freq_tbl     = ftbl_gcc_sdcc1_2_apps_clk_sdxhedgehog,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "sdc1_clk",
+		.ops      = &clk_ops_rcg_mnd,
+	},
+};
+
+static struct branch_clk gcc_sdcc1_apps_clk_sdxhedgehog =
+{
+	.cbcr_reg     = (uint32_t *) SDCC1_APPS_CBCR,
+	.parent       = &sdcc1_apps_clk_src_sdxhedgehog.c,
+
+	.c = {
+		.dbg_name = "gcc_sdcc1_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 static struct branch_clk gcc_sdcc1_apps_clk =
 {
 	.cbcr_reg     = (uint32_t *) SDCC1_APPS_CBCR,
@@ -276,6 +316,34 @@
 	},
 };
 
+static struct clk_freq_tbl ftbl_gcc_usb30_master_clk_sdxhedgehog[] =
+{
+	F(30000000, gpll0, 10, 0, 0),
+	F(60000000, gpll0, 5, 0, 0),
+	F(120000000, gpll0, 5, 0, 0),
+	F(171430000, gpll0, 3.5, 0, 0),
+	F(200000000, gpll0, 3, 0, 0),
+	F_END
+};
+
+static struct rcg_clk usb30_master_clk_src_sdxhedgehog =
+{
+	.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_sdxhedgehog,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "usb30_master_clk_src_sdxhedgehog",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
 static struct branch_clk gcc_usb30_master_clk =
 {
 	.cbcr_reg     = (uint32_t *) GCC_USB30_MASTER_CBCR,
@@ -288,6 +356,18 @@
 	},
 };
 
+static struct branch_clk gcc_usb30_master_clk_sdxhedgehog =
+{
+	.cbcr_reg     = (uint32_t *) GCC_USB30_MASTER_CBCR,
+	.bcr_reg      = (uint32_t *) USB_30_BCR,
+	.parent       = &usb30_master_clk_src_sdxhedgehog.c,
+
+	.c = {
+		.dbg_name = "gcc_usb30_master_clk_sdxhedgehog",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 static struct clk_freq_tbl ftbl_gcc_usb30_pipe_clk[] = {
 	F(          19200000,            cxo,    1,    0,     0),
 	F_EXT_SRC(	125000000,    usb30_pipe,    1,    0,     0),
@@ -319,6 +399,18 @@
 	},
 };
 
+static struct branch_clk gcc_usb30_pipe_clk_sdxhedgehog = {
+	.bcr_reg      = (uint32_t *) USB3_PIPE_BCR,
+	.cbcr_reg     = (uint32_t *) USB3_PIPE_CBCR,
+	.has_sibling  = 1,
+	.halt_check   = 0,
+
+	.c = {
+		.dbg_name = "usb30_pipe_clk_sdxhedgehog",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 
 static struct branch_clk gcc_usb30_pipe_clk_mdmcalifornium = {
 	.bcr_reg      = (uint32_t *) USB3_PIPE_BCR,
@@ -451,6 +543,24 @@
 	},
 };
 
+static struct clk_freq_tbl ftbl_gcc_usb30_mock_utmi_clk_src_sdxhedgehog[] = {
+	F(  19200000, cxo,   1,    0,     0),
+	F_END
+};
+
+static struct rcg_clk usb30_mock_utmi_clk_src_sdxhedgehog = {
+	.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_sdxhedgehog,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "usb30_mock_utmi_clk_src_sdxhedgehog",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
 static struct branch_clk gcc_usb30_mock_utmi_clk = {
 	.cbcr_reg    = (uint32_t *) USB30_MOCK_UTMI_CBCR,
 	.has_sibling = 0,
@@ -462,6 +572,17 @@
 	},
 };
 
+static struct branch_clk gcc_usb30_mock_utmi_clk_sdxhedgehog = {
+	.cbcr_reg    = (uint32_t *) USB30_MOCK_UTMI_CBCR,
+	.has_sibling = 0,
+	.parent      = &usb30_mock_utmi_clk_src_sdxhedgehog.c,
+
+	.c = {
+		.dbg_name = "usb30_mock_utmi_clk_sdxhedgehog",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 static struct branch_clk gcc_usb30_sleep_clk = {
 	.cbcr_reg    = (uint32_t *) USB30_SLEEP_CBCR,
 	.has_sibling = 1,
@@ -478,20 +599,24 @@
 {
 	CLK_LOOKUP("sdc1_iface_clk", gcc_sdcc1_ahb_clk.c),
 	CLK_LOOKUP("sdc1_core_clk",  gcc_sdcc1_apps_clk.c),
+	CLK_LOOKUP("sdc1_core_clk_sdxhedgehog",  gcc_sdcc1_apps_clk_sdxhedgehog.c),
 
 	CLK_LOOKUP("uart3_iface_clk", gcc_blsp1_ahb_clk.c),
 	CLK_LOOKUP("uart3_core_clk",  gcc_blsp1_uart3_apps_clk.c),
 
 	CLK_LOOKUP("usb30_iface_clk",  gcc_sys_noc_usb30_axi_clk.c),
 	CLK_LOOKUP("usb30_master_clk", gcc_usb30_master_clk.c),
+	CLK_LOOKUP("usb30_master_clk_sdxhedgehog", gcc_usb30_master_clk_sdxhedgehog.c),
 	CLK_LOOKUP("usb30_pipe_clk",   gcc_usb30_pipe_clk.c),
 	CLK_LOOKUP("usb30_pipe_clk_mdmcalifornium",   gcc_usb30_pipe_clk_mdmcalifornium.c),
+	CLK_LOOKUP("usb30_pipe_clk_sdxhedgehog",   gcc_usb30_pipe_clk_sdxhedgehog.c),
 	CLK_LOOKUP("usb30_aux_clk",    gcc_usb30_aux_clk.c),
 
 	CLK_LOOKUP("usb2b_phy_sleep_clk", gcc_usb2a_phy_sleep_clk.c),
 	CLK_LOOKUP("usb30_phy_reset",     gcc_usb30_phy_reset.c),
 
 	CLK_LOOKUP("usb30_mock_utmi_clk", gcc_usb30_mock_utmi_clk.c),
+	CLK_LOOKUP("usb30_mock_utmi_clk_sdxhedgehog", gcc_usb30_mock_utmi_clk_sdxhedgehog.c),
 	CLK_LOOKUP("usb_phy_cfg_ahb_clk", gcc_usb_phy_cfg_ahb_clk.c),
 	CLK_LOOKUP("usb30_sleep_clk",     gcc_usb30_sleep_clk.c),
 	CLK_LOOKUP("ce1_ahb_clk",  gcc_ce1_ahb_clk.c),
diff --git a/platform/mdm9640/platform.c b/platform/mdm9640/platform.c
index f69053c..29181be 100644
--- a/platform/mdm9640/platform.c
+++ b/platform/mdm9640/platform.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
@@ -177,11 +177,28 @@
 	return ret;
 }
 
+bool platform_is_sdxhedgehog()
+{
+	uint32_t platform_id = board_platform_id();
+	bool ret;
+
+	switch(platform_id)
+	{
+		case SDXHEDGEHOG:
+				ret = true;
+				break;
+		default:
+				ret = false;
+	};
+
+	return ret;
+}
+
 uint32_t platform_boot_config()
 {
 	uint32_t boot_config;
 
-	if (platform_is_mdmcalifornium())
+	if (platform_is_mdmcalifornium() || platform_is_sdxhedgehog())
 		boot_config = BOOT_CONFIG_REG_V2;
 	/* Else the platform is 9x45 */
 	else if (board_soc_version() >= 0x20000)
diff --git a/platform/msm_shared/include/qusb2_phy.h b/platform/msm_shared/include/qusb2_phy.h
index 1739d42..b8e8689 100644
--- a/platform/msm_shared/include/qusb2_phy.h
+++ b/platform/msm_shared/include/qusb2_phy.h
@@ -51,4 +51,16 @@
 #define QUSB2PHY_PLL_STATUS         (QUSB2_PHY_BASE + 0x00000038)
 
 
+/* QUSB2 PHY SDXHEDGEHOG */
+#define QUSB2PHY_PLL_ANALOG_CONTROLS_TWO_SDXHEDGEHOG		(QUSB2_PHY_BASE + 0x4)
+#define QUSB2PHY_PLL_CLOCK_INVERTERS_SDXHEDGEHOG			(QUSB2_PHY_BASE + 0x18c)
+#define QUSB2PHY_PLL_CMODE_SDXHEDGEHOG						(QUSB2_PHY_BASE + 0x02c)
+#define QUSB2PHY_PLL_LOCK_DELAY_SDXHEDGEHOG					(QUSB2_PHY_BASE + 0x90)
+#define QUSB2PHY_TUNE1_SDXHEDGEHOG							(QUSB2_PHY_BASE + 0x23c)
+#define QUSB2PHY_TUNE2_SDXHEDGEHOG							(QUSB2_PHY_BASE + 0x240)
+#define QUSB2PHY_IMP_CTRL1_SDXHEDGEHOG						(QUSB2_PHY_BASE + 0x21c)
+#define QUSB2PHY_PWR_CTRL1_SDXHEDGEHOG						(QUSB2_PHY_BASE + 0x210)
+#define QUSB2PHY_DEBUG_CTRL2_SDXHEDGEHOG				(QUSB2_PHY_BASE + 0x278)
+#define QUSB2PHY_DEBUG_STAT5_SDXHEDGEHOG					(QUSB2_PHY_BASE + 0x298)
+
 #endif
diff --git a/platform/msm_shared/qusb2_phy.c b/platform/msm_shared/qusb2_phy.c
index 32beb52..e13e441 100644
--- a/platform/msm_shared/qusb2_phy.c
+++ b/platform/msm_shared/qusb2_phy.c
@@ -59,6 +59,11 @@
 	return 0;
 }
 
+__WEAK int platform_is_sdxhedgehog()
+{
+	return 0;
+}
+
 void qusb2_phy_reset(void)
 {
 	uint32_t val;
@@ -66,6 +71,7 @@
 	uint8_t tune2 = 0xB3;
 	int retry = 100;
 	int se_clock = 1;
+	int status_reg = 0;
 
 	/* Disable the ref clock before phy reset */
 #if GCC_RX2_USB2_CLKREF_EN
@@ -115,6 +121,17 @@
 		writel(0x9F, QUSB2PHY_PLL_AUTOPGM_CTL1);
 		writel(0x00, QUSB2PHY_PLL_PWR_CTL);
 	}
+	else if (platform_is_sdxhedgehog())
+	{
+		writel(0x13, QUSB2PHY_PLL_ANALOG_CONTROLS_TWO_SDXHEDGEHOG);
+		writel(0x7C, QUSB2PHY_PLL_CLOCK_INVERTERS_SDXHEDGEHOG);
+		writel(0x80, QUSB2PHY_PLL_CMODE_SDXHEDGEHOG);
+		writel(0x0a, QUSB2PHY_PLL_LOCK_DELAY_SDXHEDGEHOG);
+		writel(0xa5, QUSB2PHY_TUNE1_SDXHEDGEHOG);
+		writel(0x09, QUSB2PHY_TUNE2_SDXHEDGEHOG);
+		writel(0x00, QUSB2PHY_IMP_CTRL1_SDXHEDGEHOG);
+		writel(0x22, QUSB2PHY_PWR_CTRL1_SDXHEDGEHOG);
+	}
 	else
 	{
 		/* Set HS impedance to 42ohms */
@@ -133,10 +150,17 @@
 	/* Enable ULPI mode */
 	if (platform_is_msm8994())
 		writel(0x0,  QUSB2PHY_PORT_UTMI_CTRL2);
-	/* set CLAMP_N_EN and USB PHY is enabled*/
-	writel(0x22, QUSB2PHY_PORT_POWERDOWN);
-	udelay(150);
 
+	/* set CLAMP_N_EN and USB PHY is enabled*/
+	if (platform_is_sdxhedgehog()){
+		writel(0x22, QUSB2PHY_PWR_CTRL1_SDXHEDGEHOG);
+		writel(0x04, QUSB2PHY_DEBUG_CTRL2_SDXHEDGEHOG);
+		udelay(88);
+	}
+	else{
+		writel(0x22, QUSB2PHY_PORT_POWERDOWN);
+		udelay(150);
+	}
 	/* TCSR register bit 0 indicates whether single ended clock
 	 * or differential clock configuration is enabled. Based on the
 	 * configuration set the PLL_TEST register.
@@ -162,7 +186,14 @@
 	udelay(100);
 
 	/* Check PLL status */
-	while (!(readl(QUSB2PHY_PLL_STATUS) & QUSB2PHY_PLL_LOCK))
+	if (platform_is_sdxhedgehog()){
+		status_reg = QUSB2PHY_DEBUG_STAT5_SDXHEDGEHOG;
+	}
+	else{
+		status_reg = QUSB2PHY_PLL_STATUS;
+	}
+
+	while (!(readl(status_reg) & QUSB2PHY_PLL_LOCK))
 	{
 		retry--;
 		if (!retry)
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index e8af142..1d65783 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -459,6 +459,7 @@
 	MSM8996AU = 310,
 	APQ8096AU = 311,
 	APQ8096SG = 312,
+	SDXHEDGEHOG = 314
 };
 
 enum platform {
diff --git a/target/mdm9640/init.c b/target/mdm9640/init.c
index 2429cb9..300e396 100644
--- a/target/mdm9640/init.c
+++ b/target/mdm9640/init.c
@@ -427,8 +427,8 @@
 	/* Reset sequence for californium is different from 9x40, use the reset sequence
 	 * from clock driver
 	 */
-	if (platform_is_mdmcalifornium())
-		clock_reset_usb_phy();
+	if (platform_is_mdmcalifornium() || platform_is_sdxhedgehog())
+		clock_reset_usb_phy(); // This is the reset function for USB3
 	else
 		usb30_qmp_phy_reset();
 
@@ -443,7 +443,10 @@
 	ASSERT(t_usb_iface);
 
 	t_usb_iface->mux_config = NULL;
-	t_usb_iface->phy_init   = usb30_qmp_phy_init;
+	if (platform_is_sdxhedgehog())
+		t_usb_iface->phy_init   = NULL;
+	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;
@@ -453,7 +456,7 @@
 
 uint32_t target_override_pll()
 {
-	if (platform_is_mdmcalifornium())
+	if (platform_is_mdmcalifornium() || platform_is_sdxhedgehog())
 		return 0;
 	else
 		return 1;
@@ -560,7 +563,7 @@
 
 struct qmp_reg *target_get_qmp_settings()
 {
-	if (platform_is_mdmcalifornium())
+	if (platform_is_mdmcalifornium() || platform_is_sdxhedgehog())
 		return qmp_settings;
 	else
 		return NULL;
@@ -568,7 +571,7 @@
 
 int target_get_qmp_regsize()
 {
-	if (platform_is_mdmcalifornium())
+	if (platform_is_mdmcalifornium() || platform_is_sdxhedgehog())
 		return ARRAY_SIZE(qmp_settings);
 	else
 		return 0;
diff --git a/target/mdm9640/keypad.c b/target/mdm9640/keypad.c
index 2f637f1..a79d80f 100644
--- a/target/mdm9640/keypad.c
+++ b/target/mdm9640/keypad.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -45,7 +45,7 @@
 {
 	int ret;
 
-	if (platform_is_mdmcalifornium())
+	if (platform_is_mdmcalifornium() || platform_is_sdxhedgehog())
 		ret = pm8x41_resin_status();
 	else
 	{