apq8084: Add support and enable sdhci driver

Change-Id: I6589dd0f2d15d41569695966e27b13e0f51d3f9a
diff --git a/platform/apq8084/acpuclock.c b/platform/apq8084/acpuclock.c
index 2190be1..8c3f841 100644
--- a/platform/apq8084/acpuclock.c
+++ b/platform/apq8084/acpuclock.c
@@ -120,9 +120,6 @@
 
 	snprintf(clk_name, 64, "sdc%u_core_clk", interface);
 
-	/* Disable MCI_CLK before changing the sdcc clock */
-	mmc_boot_mci_clk_disable();
-
 	if(freq == MMC_CLK_400KHZ)
 	{
 		ret = clk_get_set_enable(clk_name, 400000, 1);
@@ -152,8 +149,6 @@
 		ASSERT(0);
 	}
 
-	/* Enable MCI CLK */
-	mmc_boot_mci_clk_enable();
 }
 
 /* Configure UART clock based on the UART block id*/
diff --git a/platform/apq8084/include/platform/iomap.h b/platform/apq8084/include/platform/iomap.h
index 9d6f15b..7e6e7d5 100644
--- a/platform/apq8084/include/platform/iomap.h
+++ b/platform/apq8084/include/platform/iomap.h
@@ -131,4 +131,11 @@
 /* DRV strength for sdcc */
 #define SDC1_HDRV_PULL_CTL           (TLMM_BASE_ADDR + 0x00002044)
 
+/* SDHCI */
+#define SDCC_MCI_HC_MODE            (0x00000078)
+#define SDCC_HC_PWRCTL_STATUS_REG   (0x000000DC)
+#define SDCC_HC_PWRCTL_MASK_REG     (0x000000E0)
+#define SDCC_HC_PWRCTL_CLEAR_REG    (0x000000E4)
+#define SDCC_HC_PWRCTL_CTL_REG      (0x000000E8)
+
 #endif
diff --git a/platform/apq8084/include/platform/irqs.h b/platform/apq8084/include/platform/irqs.h
index 9db58bb..8b25b0c 100644
--- a/platform/apq8084/include/platform/irqs.h
+++ b/platform/apq8084/include/platform/irqs.h
@@ -62,5 +62,8 @@
 #define NR_IRQS                                (NR_MSM_IRQS + NR_GPIO_IRQS + \
                                                NR_BOARD_IRQS)
 
-#define SDCC_PWRCTRL_IRQ                       (GIC_SPI_START + 138)
+#define SDCC1_PWRCTL_IRQ                       (GIC_SPI_START + 138)
+#define SDCC2_PWRCTL_IRQ                       (GIC_SPI_START + 221)
+#define SDCC3_PWRCTL_IRQ                       (GIC_SPI_START + 224)
+#define SDCC4_PWRCTL_IRQ                       (GIC_SPI_START + 227)
 #endif	/* __IRQS_APQ8084_H */
diff --git a/project/apq8084.mk b/project/apq8084.mk
index cbf43c8..8b1075b 100644
--- a/project/apq8084.mk
+++ b/project/apq8084.mk
@@ -8,7 +8,7 @@
 
 DEBUG := 1
 EMMC_BOOT := 1
-ENABLE_SDHCI_SUPPORT := 0
+ENABLE_SDHCI_SUPPORT := 1
 
 #DEFINES += WITH_DEBUG_DCC=1
 DEFINES += WITH_DEBUG_UART=1
diff --git a/target/apq8084/init.c b/target/apq8084/init.c
index 034c3e0..3aaa70f 100644
--- a/target/apq8084/init.c
+++ b/target/apq8084/init.c
@@ -28,6 +28,7 @@
 
 #include <debug.h>
 #include <platform/iomap.h>
+#include <platform/irqs.h>
 #include <platform/gpio.h>
 #include <reg.h>
 #include <target.h>
@@ -48,6 +49,7 @@
 #include <scm.h>
 #include <platform/clock.h>
 #include <platform/gpio.h>
+#include <platform/timer.h>
 #include <stdlib.h>
 
 #define PMIC_ARB_CHANNEL_NUM    0
@@ -55,8 +57,18 @@
 
 #define FASTBOOT_MODE           0x77665500
 
-static uint32_t mmc_sdc_base[] =
-	{ MSM_SDC1_BASE, MSM_SDC2_BASE, MSM_SDC3_BASE, MSM_SDC4_BASE };
+static void set_sdc_power_ctrl(void);
+
+static uint32_t mmc_pwrctl_base[] =
+	{ MSM_SDC1_BASE, MSM_SDC2_BASE };
+
+static uint32_t mmc_sdhci_base[] =
+	{ MSM_SDC1_SDHCI_BASE, MSM_SDC2_SDHCI_BASE };
+
+static uint32_t  mmc_sdc_pwrctl_irq[] =
+	{ SDCC1_PWRCTL_IRQ, SDCC2_PWRCTL_IRQ };
+
+struct mmc_device *dev;
 
 extern void ulpi_write(unsigned val, unsigned reg);
 
@@ -128,32 +140,6 @@
 	ulpi_write(ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT, ULPI_MISC_A_CLEAR);
 }
 
-static void target_mmc_mci_init()
-{
-	uint32_t base_addr;
-	uint8_t slot;
-
-	slot = MMC_SLOT;
-	base_addr = mmc_sdc_base[slot - 1];
-
-	if (mmc_boot_main(slot, base_addr))
-	{
-		dprintf(CRITICAL, "mmc init failed!");
-		ASSERT(0);
-	}
-}
-
-/*
- * Function to set the capabilities for the host
- */
-void target_mmc_caps(struct mmc_host *host)
-{
-	host->caps.bus_width = MMC_BOOT_BUS_WIDTH_8_BIT;
-	host->caps.ddr_mode = 1;
-	host->caps.hs200_mode = 1;
-	host->caps.hs_clk_rate = MMC_CLK_96MHZ;
-}
-
 static void set_sdc_power_ctrl()
 {
 	/* Drive strength configs for sdc pins */
@@ -177,6 +163,50 @@
 	tlmm_set_pull_ctrl(sdc1_pull_cfg, ARRAY_SIZE(sdc1_pull_cfg));
 }
 
+void target_sdc_init()
+{
+	struct mmc_config_data config;
+
+	/* Set drive strength & pull ctrl values */
+	set_sdc_power_ctrl();
+
+	config.bus_width = DATA_BUS_WIDTH_8BIT;
+	config.max_clk_rate = MMC_CLK_200MHZ;
+
+	/* Try slot 1*/
+	config.slot = 1;
+	config.sdhc_base = mmc_sdhci_base[config.slot - 1];
+	config.pwrctl_base = mmc_pwrctl_base[config.slot - 1];
+	config.pwr_irq     = mmc_sdc_pwrctl_irq[config.slot - 1];
+
+	if (!(dev = mmc_init(&config)))
+	{
+		/* Try slot 2 */
+		config.slot = 2;
+		config.sdhc_base = mmc_sdhci_base[config.slot - 1];
+		config.pwrctl_base = mmc_pwrctl_base[config.slot - 1];
+		config.pwr_irq     = mmc_sdc_pwrctl_irq[config.slot - 1];
+
+		if (!(dev = mmc_init(&config)))
+		{
+			dprintf(CRITICAL, "mmc init failed!");
+			ASSERT(0);
+		}
+	}
+
+	/* MMC initialization is complete, read the partition table info */
+	if (partition_read_table())
+	{
+		dprintf(CRITICAL, "Error reading the partition table info\n");
+		ASSERT(0);
+	}
+}
+
+struct mmc_device *target_mmc_device()
+{
+	return dev;
+}
+
 void target_init(void)
 {
 	dprintf(INFO, "target_init()\n");
@@ -185,23 +215,7 @@
 
 	target_keystatus();
 
-	/*
-	 * Set drive strength & pull ctrl for
-	 * emmc
-	 */
-	/*Uncomment during bringup after the pull up values are finalized*/
-	//set_sdc_power_ctrl();
-
-	target_mmc_mci_init();
-
-	/*
-	 * MMC initialization is complete, read the partition table info
-	 */
-	if (partition_read_table())
-	{
-		dprintf(CRITICAL, "Error reading the partition table info\n");
-		ASSERT(0);
-	}
+	target_sdc_init();
 }
 
 unsigned board_machtype(void)
@@ -209,11 +223,6 @@
 	return LINUX_MACHTYPE_UNKNOWN;
 }
 
-void target_fastboot_init(void)
-{
-	/* Set the BOOT_DONE flag in PM8921 */
-}
-
 /* Detect the target type */
 void target_detect(struct board_data *board)
 {