Merge "MPQ8092: SDHCI: Adding support for SDHCI"
diff --git a/platform/mpq8092/acpuclock.c b/platform/mpq8092/acpuclock.c
index 1e2ee63..e93788a 100644
--- a/platform/mpq8092/acpuclock.c
+++ b/platform/mpq8092/acpuclock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -114,7 +114,6 @@
char clk_name[64];
snprintf(clk_name, sizeof(clk_name), "sdc%u_core_clk", interface);
- mmc_boot_mci_clk_disable();
if(freq == MMC_CLK_400KHZ)
{
ret = clk_get_set_enable(clk_name, 400000, 1);
@@ -142,8 +141,6 @@
dprintf(CRITICAL, "failed to set sdc%u_core_clk ret = %d\n", interface, ret);
ASSERT(0);
}
- /* Enable MCI clk */
- mmc_boot_mci_clk_enable();
}
/* Configure UART clock based on the UART block id*/
diff --git a/platform/mpq8092/include/platform/iomap.h b/platform/mpq8092/include/platform/iomap.h
index 4957aa0..d942192 100644
--- a/platform/mpq8092/include/platform/iomap.h
+++ b/platform/mpq8092/include/platform/iomap.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -53,12 +53,14 @@
#define MSM_SDC1_BAM_BASE (PERIPH_SS_BASE + 0x00004000)
#define MSM_SDC1_BASE (PERIPH_SS_BASE + 0x00024000)
#define MSM_SDC1_DML_BASE (PERIPH_SS_BASE + 0x00024800)
+#define MSM_SDC1_SDHCI_BASE (PERIPH_SS_BASE + 0x00024900)
#define MSM_SDC3_BAM_BASE (PERIPH_SS_BASE + 0x00044000)
#define MSM_SDC3_BASE (PERIPH_SS_BASE + 0x00064000)
#define MSM_SDC3_DML_BASE (PERIPH_SS_BASE + 0x00064800)
#define MSM_SDC2_BAM_BASE (PERIPH_SS_BASE + 0x00084000)
#define MSM_SDC2_BASE (PERIPH_SS_BASE + 0x000A4000)
#define MSM_SDC2_DML_BASE (PERIPH_SS_BASE + 0x000A4800)
+#define MSM_SDC2_SDHCI_BASE (PERIPH_SS_BASE + 0x000A4900)
#define MSM_SDC4_BAM_BASE (PERIPH_SS_BASE + 0x000C4000)
#define MSM_SDC4_BASE (PERIPH_SS_BASE + 0x000E4000)
#define MSM_SDC4_DML_BASE (PERIPH_SS_BASE + 0x000E4800)
@@ -144,6 +146,24 @@
#define SDC1_HDRV_PULL_CTL (TLMM_BASE_ADDR + 0x00002044)
+/* SDCC2 */
+#define SDCC2_BCR (CLK_CTL_BASE + 0x500) /* block reset */
+#define SDCC2_APPS_CBCR (CLK_CTL_BASE + 0x504) /* branch control */
+#define SDCC2_AHB_CBCR (CLK_CTL_BASE + 0x508)
+#define SDCC2_INACTIVITY_TIMER_CBCR (CLK_CTL_BASE + 0x50C)
+#define SDCC2_CMD_RCGR (CLK_CTL_BASE + 0x510) /* cmd */
+#define SDCC2_CFG_RCGR (CLK_CTL_BASE + 0x514) /* cfg */
+#define SDCC2_M (CLK_CTL_BASE + 0x518) /* m */
+#define SDCC2_N (CLK_CTL_BASE + 0x51C) /* n */
+#define SDCC2_D (CLK_CTL_BASE + 0x520) /* d */
+
+/* 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)
+
/* UART */
#define BLSP1_UART2_APPS_CBCR (CLK_CTL_BASE + 0x704)
#define BLSP1_UART2_APPS_CMD_RCGR (CLK_CTL_BASE + 0x70C)
diff --git a/platform/mpq8092/include/platform/irqs.h b/platform/mpq8092/include/platform/irqs.h
index 33430cb..ce914af 100644
--- a/platform/mpq8092/include/platform/irqs.h
+++ b/platform/mpq8092/include/platform/irqs.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -47,6 +47,8 @@
#define USB1_HS_BAM_IRQ (GIC_SPI_START + 135)
#define USB1_HS_IRQ (GIC_SPI_START + 134)
+#define SDCC1_PWRCTL_IRQ (GIC_SPI_START + 138)
+#define SDCC2_PWRCTL_IRQ (GIC_SPI_START + 221)
/* Retrofit universal macro names */
#define INT_USB_HS USB1_HS_IRQ
diff --git a/platform/mpq8092/mpq8092-clock.c b/platform/mpq8092/mpq8092-clock.c
index 2da2809..9fa9095 100644
--- a/platform/mpq8092/mpq8092-clock.c
+++ b/platform/mpq8092/mpq8092-clock.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 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
@@ -282,6 +282,46 @@
},
};
+static struct rcg_clk sdcc2_apps_clk_src = {
+
+ .cmd_reg = (uint32_t *) SDCC2_CMD_RCGR,
+ .cfg_reg = (uint32_t *) SDCC2_CFG_RCGR,
+ .m_reg = (uint32_t *) SDCC2_M,
+ .n_reg = (uint32_t *) SDCC2_N,
+ .d_reg = (uint32_t *) SDCC2_D,
+
+ .set_rate = clock_lib2_rcg_set_rate_mnd,
+ .freq_tbl = ftbl_gcc_sdcc1_2_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+
+ .c = {
+ .dbg_name = "sdc2_clk",
+ .ops = &clk_ops_rcg_mnd,
+ },
+};
+
+static struct branch_clk gcc_sdcc2_apps_clk = {
+
+ .cbcr_reg = (uint32_t *) SDCC2_APPS_CBCR,
+ .parent = &sdcc2_apps_clk_src.c,
+
+ .c = {
+ .dbg_name = "gcc_sdcc2_apps_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct branch_clk gcc_sdcc2_ahb_clk = {
+
+ .cbcr_reg = (uint32_t *) SDCC2_AHB_CBCR,
+ .has_sibling = 1,
+
+ .c = {
+ .dbg_name = "gcc_sdcc2_ahb_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
/* Clock lookup table */
static struct clk_lookup msm_clocks_8092[] =
@@ -289,6 +329,9 @@
CLK_LOOKUP("sdc1_iface_clk", gcc_sdcc1_ahb_clk.c),
CLK_LOOKUP("sdc1_core_clk", gcc_sdcc1_apps_clk.c),
+ CLK_LOOKUP("sdc2_iface_clk", gcc_sdcc2_ahb_clk.c),
+ CLK_LOOKUP("sdc2_core_clk", gcc_sdcc2_apps_clk.c),
+
CLK_LOOKUP("uart4_iface_clk", gcc_blsp1_ahb_clk.c),
CLK_LOOKUP("uart4_core_clk", gcc_blsp1_uart5_apps_clk.c),
diff --git a/project/mpq8092.mk b/project/mpq8092.mk
index be71729..36be395 100644
--- a/project/mpq8092.mk
+++ b/project/mpq8092.mk
@@ -7,7 +7,7 @@
MODULES += app/aboot
DEBUG := 1
-
+ENABLE_SDHCI_SUPPORT := 1
#DEFINES += WITH_DEBUG_DCC=1
DEFINES += WITH_DEBUG_UART=1
#DEFINES += WITH_DEBUG_FBCON=1
@@ -20,3 +20,7 @@
DEFINES += ABOOT_FORCE_KERNEL_ADDR=0x00008000
DEFINES += ABOOT_FORCE_RAMDISK_ADDR=0x02000000
DEFINES += ABOOT_FORCE_TAGS_ADDR=0x01e00000
+
+ifeq ($(ENABLE_SDHCI_SUPPORT),1)
+DEFINES += MMC_SDHCI_SUPPORT=1
+endif
diff --git a/target/mpq8092/init.c b/target/mpq8092/init.c
index 162322b..92dda35 100644
--- a/target/mpq8092/init.c
+++ b/target/mpq8092/init.c
@@ -41,16 +41,24 @@
#include <dev/keys.h>
#include <pm8x41.h>
#include <platform/gpio.h>
+#include <platform/irqs.h>
#define PMIC_ARB_CHANNEL_NUM 0
#define PMIC_ARB_OWNER_ID 0
#define FASTBOOT_MODE 0x77665500
-static uint32_t mmc_sdc_base[] =
+static uint32_t mmc_pwrctl_base[] =
{ MSM_SDC1_BASE, MSM_SDC2_BASE, MSM_SDC3_BASE, MSM_SDC4_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 };
+
static void set_sdc_power_ctrl();
+struct mmc_device *dev;
void target_early_init(void)
{
#if WITH_DEBUG_UART
@@ -58,14 +66,6 @@
#endif
}
-void target_mmc_caps(struct mmc_host *host)
-{
- host->caps.ddr_mode = 0;
- host->caps.hs200_mode = 0;
- host->caps.bus_width = MMC_BOOT_BUS_WIDTH_8_BIT;
- host->caps.hs_clk_rate = MMC_CLK_50MHZ;
-}
-
/* Return 1 if vol_down pressed */
uint32_t target_volume_down()
{
@@ -104,6 +104,37 @@
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);
+ }
+ }
+}
+
+
/*Turn on DVB tuner regulator required by
* kernel drivers for probing devices*/
static void dvb_tuner_enable(void)
@@ -122,31 +153,21 @@
void target_init(void)
{
- uint32_t base_addr;
- uint8_t slot;
-
dprintf(INFO, "target_init()\n");
spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
target_keystatus();
- set_sdc_power_ctrl();
+ target_sdc_init();
- /* Trying Slot 1*/
- slot = 1;
- base_addr = mmc_sdc_base[slot - 1];
- if (mmc_boot_main(slot, base_addr))
+ /* Storage initialization is complete, read the partition table info */
+ if (partition_read_table())
{
-
- /* Trying Slot 2 next */
- slot = 2;
- base_addr = mmc_sdc_base[slot - 1];
- if (mmc_boot_main(slot, base_addr)) {
- dprintf(CRITICAL, "mmc init failed!");
+ dprintf(CRITICAL, "Error reading the partition table info\n");
ASSERT(0);
}
- }
+
dvb_tuner_enable();
}
@@ -264,3 +285,8 @@
{
return board_baseband();
}
+
+void *target_mmc_device()
+{
+ return (void *) dev;
+}