Merge "msm_shared: Remove qpic nand clock init for mdm9x25 from lk"
diff --git a/platform/init.c b/platform/init.c
index 0c5a850..be48ad6 100644
--- a/platform/init.c
+++ b/platform/init.c
@@ -88,7 +88,7 @@
return 0;
}
-__WEAK ce_clock_init(void)
+__WEAK void ce_clock_init(void)
{
}
diff --git a/platform/msm8226/acpuclock.c b/platform/msm8226/acpuclock.c
index f45a4b1..96e8687 100644
--- a/platform/msm8226/acpuclock.c
+++ b/platform/msm8226/acpuclock.c
@@ -60,9 +60,6 @@
iclk = clk_get("usb_iface_clk");
cclk = clk_get("usb_core_clk");
- /* Disable USB all clock init */
- writel(0, USB_BOOT_CLOCK_CTL);
-
clk_disable(iclk);
clk_disable(cclk);
@@ -169,7 +166,118 @@
}
}
+/* Function to asynchronously reset CE.
+ * Function assumes that all the CE clocks are off.
+ */
+static void ce_async_reset(uint8_t instance)
+{
+ if (instance == 1)
+ {
+ /* Start the block reset for CE */
+ writel(1, GCC_CE1_BCR);
+
+ udelay(2);
+
+ /* Take CE block out of reset */
+ writel(0, GCC_CE1_BCR);
+
+ udelay(2);
+ }
+ else
+ {
+ dprintf(CRITICAL, "CE instance not supported instance = %d", instance);
+ ASSERT(0);
+ }
+}
+
+void clock_ce_enable(uint8_t instance)
+{
+ int ret;
+ char clk_name[64];
+
+ snprintf(clk_name, 64, "ce%u_src_clk", instance);
+ ret = clk_get_set_enable(clk_name, 100000000, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set ce_src_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ snprintf(clk_name, 64, "ce%u_core_clk", instance);
+ ret = clk_get_set_enable(clk_name, 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set ce_core_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
+ ret = clk_get_set_enable(clk_name, 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set ce_ahb_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ snprintf(clk_name, 64, "ce%u_axi_clk", instance);
+ ret = clk_get_set_enable(clk_name, 0, 1);
+ if(ret)
+ {
+ dprintf(CRITICAL, "failed to set ce_axi_clk ret = %d\n", ret);
+ ASSERT(0);
+ }
+
+ /* Wait for 48 * #pipes cycles.
+ * This is necessary as immediately after an access control reset (boot up)
+ * or a debug re-enable, the Crypto core sequentially clears its internal
+ * pipe key storage memory. If pipe key initialization writes are attempted
+ * during this time, they may be overwritten by the internal clearing logic.
+ */
+ udelay(1);
+}
+
+void clock_ce_disable(uint8_t instance)
+{
+ struct clk *ahb_clk;
+ struct clk *cclk;
+ struct clk *axi_clk;
+ struct clk *src_clk;
+ char clk_name[64];
+
+ snprintf(clk_name, 64, "ce%u_src_clk", instance);
+ src_clk = clk_get(clk_name);
+
+ snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
+ ahb_clk = clk_get(clk_name);
+
+ snprintf(clk_name, 64, "ce%u_axi_clk", instance);
+ axi_clk = clk_get(clk_name);
+
+ snprintf(clk_name, 64, "ce%u_core_clk", instance);
+ cclk = clk_get(clk_name);
+
+ clk_disable(ahb_clk);
+ clk_disable(axi_clk);
+ clk_disable(cclk);
+ clk_disable(src_clk);
+
+ /* Some delay for the clocks to stabalize. */
+ udelay(1);
+}
+
void clock_config_ce(uint8_t instance)
{
+ /* Need to enable the clock before disabling since the clk_disable()
+ * has a check to default to nop when the clk_enable() is not called
+ * on that particular clock.
+ */
+ clock_ce_enable(instance);
+
+ clock_ce_disable(instance);
+
+ ce_async_reset(instance);
+
+ clock_ce_enable(instance);
+
}
diff --git a/platform/msm8226/include/platform/iomap.h b/platform/msm8226/include/platform/iomap.h
index 9519882..d459984 100644
--- a/platform/msm8226/include/platform/iomap.h
+++ b/platform/msm8226/include/platform/iomap.h
@@ -72,7 +72,6 @@
#define GCC_WDOG_DEBUG (CLK_CTL_BASE + 0x00001780)
#define USB_HS_BCR (CLK_CTL_BASE + 0x480)
-#define USB_BOOT_CLOCK_CTL (CLK_CTL_BASE + 0x1A00)
#define SPMI_BASE 0xFC4C0000
#define SPMI_GENI_BASE (SPMI_BASE + 0xA000)
@@ -94,6 +93,14 @@
#define APCS_GPLL_ENA_VOTE (CLK_CTL_BASE + 0x1480)
#define APCS_CLOCK_BRANCH_ENA_VOTE (CLK_CTL_BASE + 0x1484)
+/* CE 1 */
+#define GCC_CE1_BCR (CLK_CTL_BASE + 0x1040)
+#define GCC_CE1_CMD_RCGR (CLK_CTL_BASE + 0x1050)
+#define GCC_CE1_CFG_RCGR (CLK_CTL_BASE + 0x1054)
+#define GCC_CE1_CBCR (CLK_CTL_BASE + 0x1044)
+#define GCC_CE1_AXI_CBCR (CLK_CTL_BASE + 0x1048)
+#define GCC_CE1_AHB_CBCR (CLK_CTL_BASE + 0x104C)
+
/* SDCC */
#define SDCC1_BCR (CLK_CTL_BASE + 0x4C0) /* block reset */
#define SDCC1_APPS_CBCR (CLK_CTL_BASE + 0x4C4) /* branch control */
diff --git a/platform/msm8226/msm8226-clock.c b/platform/msm8226/msm8226-clock.c
index 9f5818b..ccec8fc 100644
--- a/platform/msm8226/msm8226-clock.c
+++ b/platform/msm8226/msm8226-clock.c
@@ -270,6 +270,59 @@
},
};
+static struct clk_freq_tbl ftbl_gcc_ce1_clk[] = {
+ F( 50000000, gpll0, 12, 0, 0),
+ F(100000000, gpll0, 6, 0, 0),
+ F_END
+};
+
+static struct rcg_clk ce1_clk_src = {
+ .cmd_reg = (uint32_t *) GCC_CE1_CMD_RCGR,
+ .cfg_reg = (uint32_t *) GCC_CE1_CFG_RCGR,
+ .set_rate = clock_lib2_rcg_set_rate_hid,
+ .freq_tbl = ftbl_gcc_ce1_clk,
+ .current_freq = &rcg_dummy_freq,
+
+ .c = {
+ .dbg_name = "ce1_clk_src",
+ .ops = &clk_ops_rcg,
+ },
+};
+
+static struct vote_clk gcc_ce1_clk = {
+ .cbcr_reg = (uint32_t *) GCC_CE1_CBCR,
+ .vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(5),
+
+ .c = {
+ .dbg_name = "gcc_ce1_clk",
+ .ops = &clk_ops_vote,
+ },
+};
+
+static struct vote_clk gcc_ce1_ahb_clk = {
+ .cbcr_reg = (uint32_t *) GCC_CE1_AHB_CBCR,
+ .vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(3),
+
+ .c = {
+ .dbg_name = "gcc_ce1_ahb_clk",
+ .ops = &clk_ops_vote,
+ },
+};
+
+static struct vote_clk gcc_ce1_axi_clk = {
+ .cbcr_reg = (uint32_t *) GCC_CE1_AXI_CBCR,
+ .vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(4),
+
+ .c = {
+ .dbg_name = "gcc_ce1_axi_clk",
+ .ops = &clk_ops_vote,
+ },
+};
+
+
/* Clock lookup table */
static struct clk_lookup msm_clocks_8226[] =
{
@@ -281,6 +334,11 @@
CLK_LOOKUP("usb_iface_clk", gcc_usb_hs_ahb_clk.c),
CLK_LOOKUP("usb_core_clk", gcc_usb_hs_system_clk.c),
+
+ CLK_LOOKUP("ce1_ahb_clk", gcc_ce1_ahb_clk.c),
+ CLK_LOOKUP("ce1_axi_clk", gcc_ce1_axi_clk.c),
+ CLK_LOOKUP("ce1_core_clk", gcc_ce1_clk.c),
+ CLK_LOOKUP("ce1_src_clk", ce1_clk_src.c),
};
void platform_clock_init(void)
diff --git a/platform/msm8960/acpuclock.c b/platform/msm8960/acpuclock.c
index 2681138..0375c15 100644
--- a/platform/msm8960/acpuclock.c
+++ b/platform/msm8960/acpuclock.c
@@ -227,6 +227,9 @@
case MMC_CLK_50MHZ: /* Max supported is 48MHZ */
rate = 48000000;
break;
+ case MMC_CLK_96MHZ:
+ rate = 96000000;
+ break;
default:
ASSERT(0);
diff --git a/platform/msm8974/acpuclock.c b/platform/msm8974/acpuclock.c
index d466f40..9392c69 100644
--- a/platform/msm8974/acpuclock.c
+++ b/platform/msm8974/acpuclock.c
@@ -130,6 +130,10 @@
{
ret = clk_get_set_enable(clk_name, 50000000, 1);
}
+ else if(freq == MMC_CLK_96MHZ)
+ {
+ ret = clk_get_set_enable(clk_name, 100000000, 1);
+ }
else
{
dprintf(CRITICAL, "sdc frequency (%d) is not supported\n", freq);
diff --git a/platform/msm8974/gpio.c b/platform/msm8974/gpio.c
index 13097da..d36cd6d 100644
--- a/platform/msm8974/gpio.c
+++ b/platform/msm8974/gpio.c
@@ -89,3 +89,32 @@
};
}
}
+
+static void tlmm_set_sdc_pins(struct tlmm_cfgs *cfg)
+{
+ uint32_t reg_val;
+
+ reg_val = readl(SDC1_HDRV_PULL_CTL);
+
+ reg_val &= ~(cfg->mask << cfg->off);
+
+ reg_val |= (cfg->val << cfg->off);
+
+ writel(reg_val, SDC1_HDRV_PULL_CTL);
+}
+
+void tlmm_set_hdrive_ctrl(struct tlmm_cfgs *hdrv_cfgs, uint8_t sz)
+{
+ uint8_t i;
+
+ for (i = 0; i < sz; i++)
+ tlmm_set_sdc_pins(&hdrv_cfgs[i]);
+}
+
+void tlmm_set_pull_ctrl(struct tlmm_cfgs *pull_cfgs, uint8_t sz)
+{
+ uint8_t i;
+
+ for (i = 0; i < sz; i++)
+ tlmm_set_sdc_pins(&pull_cfgs[i]);
+}
diff --git a/platform/msm8974/include/platform/gpio.h b/platform/msm8974/include/platform/gpio.h
index 27d5358..8c4bba8 100644
--- a/platform/msm8974/include/platform/gpio.h
+++ b/platform/msm8974/include/platform/gpio.h
@@ -53,7 +53,36 @@
#define GPIO_ENABLE 0
#define GPIO_DISABLE 1
+#define TLMM_PULL_MASK 0x3
+#define TLMM_HDRV_MASK 0x7
+
+enum {
+ TLMM_CUR_VAL_16MA = 0x7,
+ TLMM_CUR_VAL_10MA = 0x4,
+} tlmm_drive_config;
+
+enum {
+ TLMM_PULL_UP = 0x3,
+ TLMM_NO_PULL = 0x0,
+} tlmm_pull_values;
+
+enum {
+ SDC1_DATA_HDRV_CTL_OFF = 0,
+ SDC1_CMD_HDRV_CTL_OFF = 3,
+ SDC1_CLK_HDRV_CTL_OFF = 6,
+ SDC1_DATA_PULL_CTL_OFF = 9,
+ SDC1_CMD_PULL_CTL_OFF = 11,
+ SDC1_CLK_PULL_CTL_OFF = 13,
+} tlmm_drv_ctrl;
+
+struct tlmm_cfgs {
+ uint32_t off;
+ uint8_t val;
+ uint8_t mask;
+};
+
void gpio_config_uart_dm(uint8_t id);
void gpio_config_blsp_i2c(uint8_t, uint8_t);
-
+void tlmm_set_hdrive_ctrl(struct tlmm_cfgs *, uint8_t);
+void tlmm_set_pull_ctrl(struct tlmm_cfgs *, uint8_t);
#endif
diff --git a/platform/msm8974/include/platform/iomap.h b/platform/msm8974/include/platform/iomap.h
index a033ac8..b873889 100644
--- a/platform/msm8974/include/platform/iomap.h
+++ b/platform/msm8974/include/platform/iomap.h
@@ -166,4 +166,6 @@
#define MDP_BASE (0xfd900000)
#define REG_MDP(off) (MDP_BASE + (off))
+/* DRV strength for sdcc */
+#define SDC1_HDRV_PULL_CTL (TLMM_BASE_ADDR + 0x00002044)
#endif
diff --git a/platform/msm_shared/include/mmc.h b/platform/msm_shared/include/mmc.h
index 39b1786..4feaab6 100644
--- a/platform/msm_shared/include/mmc.h
+++ b/platform/msm_shared/include/mmc.h
@@ -81,6 +81,16 @@
#define MMC_BOOT_BUS_WIDTH_4_BIT 2
#define MMC_BOOT_BUS_WIDTH_8_BIT 3
+/* Bus width support for DDR mode */
+#define MMC_DDR_BUS_WIDTH_4_BIT 6
+#define MMC_DDR_BUS_WIDTH_8_BIT 7
+
+/* DDR mode select */
+#define MMC_MCI_MODE_SELECT 14
+#define MMC_MCI_DDR_MODE_EN 0x3
+
+#define MMC_DEVICE_TYPE 196
+
#define MMC_BOOT_MCI_ARGUMENT MMC_BOOT_MCI_REG(0x008) /* 32 bits */
#define MMC_BOOT_MCI_CMD MMC_BOOT_MCI_REG(0x00C) /* 16 bits */
@@ -507,11 +517,20 @@
#define MMC_BOOT_XFER_MULTI_BLOCK 0
#define MMC_BOOT_XFER_SINGLE_BLOCK 1
+/* Capabilities for the mmc host */
+struct mmc_caps {
+ uint8_t ddr_mode; /* DDR mode support */
+ uint8_t hs200_mode; /* HS200 mode support */
+ uint8_t bus_width; /* bus width */
+ uint32_t hs_clk_rate; /* Clock rate for high speed mode */
+};
+
struct mmc_host {
unsigned int mclk_rate;
unsigned int ocr;
unsigned int cmd_retry;
uint32_t mmc_cont_version;
+ struct mmc_caps caps;
};
/* MACRO used to evoke regcomp */
@@ -577,6 +596,7 @@
#define MMC_CLK_25MHZ 25000000
#define MMC_CLK_48MHZ 48000000
#define MMC_CLK_50MHZ 49152000
+#define MMC_CLK_96MHZ 96000000
#define MMC_CLK_ENABLE 1
#define MMC_CLK_DISABLE 0
@@ -606,4 +626,6 @@
void mmc_mclk_reg_wr_delay();
void mmc_boot_mci_clk_enable();
void mmc_boot_mci_clk_disable();
+uint8_t card_supports_ddr_mode();
+uint8_t card_supports_hs200_mode();
#endif
diff --git a/platform/msm_shared/include/partition_parser.h b/platform/msm_shared/include/partition_parser.h
index e5c1ff8..13a123d 100644
--- a/platform/msm_shared/include/partition_parser.h
+++ b/platform/msm_shared/include/partition_parser.h
@@ -26,6 +26,11 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef __PARTITION_PARSER_H
+#define __PARTITION_PARSER_H
+
+#include <mmc.h>
+
#define INVALID_PTN -1
#define PARTITION_TYPE_MBR 0
@@ -162,7 +167,7 @@
unsigned int *partition_type);
unsigned int partition_get_type(unsigned size, unsigned char *partition,
unsigned int *partition_type);
-unsigned int partition_read_table(struct mmc_host *mmc_host,
+unsigned int partition_read_table(void *mmc_host,
struct mmc_card *mmc_card);
unsigned int partition_parse_gpt_header(unsigned char *buffer,
unsigned long long *first_usable_lba,
@@ -180,3 +185,5 @@
/* For Debugging */
void partition_dump(void);
+
+#endif
diff --git a/platform/msm_shared/mmc.c b/platform/msm_shared/mmc.c
index 5fb0b40..8ed7ec6 100644
--- a/platform/msm_shared/mmc.c
+++ b/platform/msm_shared/mmc.c
@@ -34,6 +34,7 @@
#include <partition_parser.h>
#include <platform/iomap.h>
#include <platform/timer.h>
+#include <bits.h>
#if MMC_BOOT_ADM
#include "adm.h"
@@ -1292,6 +1293,7 @@
} else if (width == MMC_BOOT_BUS_WIDTH_8_BIT) {
mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT;
}
+
writel(mmc_reg, MMC_BOOT_MCI_CLK);
/* Wait for the MMC_BOOT_MCI_CLK write to go through. */
@@ -1301,6 +1303,104 @@
}
/*
+ * Function to enable HS200 mode
+ * 1. Set the clock frequency to 100 MHZ
+ * 2. Set the bus width to 4/8 bit SDR as supported byt the target & host
+ * 3. Set the HS_TIMING on ext_csd 185 for the card
+ */
+static uint32_t mmc_set_hs200_mode(struct mmc_host *host,
+ struct mmc_card *card)
+{
+ uint32_t mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ /* Set Clock @ 100 MHZ */
+ clock_config_mmc(mmc_slot, host->caps.hs_clk_rate);
+ host->mclk_rate = host->caps.hs_clk_rate;
+
+ /* Set 4/8 bit SDR bus width */
+ mmc_ret = mmc_boot_set_bus_width(card, host->caps.bus_width);
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ dprintf(CRITICAL,
+ "Error No.%d: Failure to set wide bus for Card(RCA:%x)\n",
+ mmc_ret, card->rca);
+ return mmc_ret;
+ }
+
+ /* Setting HS200 in HS_TIMING using EXT_CSD (CMD6) */
+ mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE,
+ MMC_BOOT_EXT_CMMC_HS_TIMING, 2);
+
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ dprintf(CRITICAL, "Switch cmd returned failure %d\n", __LINE__);
+ return mmc_ret;
+ }
+
+ return mmc_ret;
+}
+
+/*
+ * Function to enable DDR mode
+ * 1. Set the bus width to 8 bit DDR
+ * 1. Set the clock frequency to 100 MHZ
+ * 3. Set DDR mode in mci clk register
+ * 4. Set Widebus enable in mci clock register
+ */
+static uint32_t mmc_set_ddr_mode(struct mmc_host *host,
+ struct mmc_card *card)
+{
+ uint8_t mmc_ret = MMC_BOOT_E_SUCCESS;
+ uint32_t mmc_reg = 0;
+ uint32_t width = 0;
+
+ switch (host->caps.bus_width) {
+ case MMC_BOOT_BUS_WIDTH_4_BIT:
+ width = MMC_DDR_BUS_WIDTH_4_BIT;
+ break;
+ case MMC_BOOT_BUS_WIDTH_8_BIT:
+ width = MMC_DDR_BUS_WIDTH_8_BIT;
+ break;
+ default:
+ dprintf(CRITICAL, "Invalid bus width, DDR mode is not enabled\n");
+ mmc_ret = MMC_BOOT_E_FAILURE;
+ goto end;
+ };
+
+ /* Set width for 4/8 bit DDR bus width */
+ mmc_ret = mmc_boot_set_bus_width(card, width);
+
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ dprintf(CRITICAL,
+ "Error No.%d: Failure to set wide bus for Card(RCA:%x)\n",
+ mmc_ret, card->rca);
+ return mmc_ret;
+ }
+
+ /* Bump up the clock frequency */
+ clock_config_mmc(mmc_slot, host->caps.hs_clk_rate);
+ host->mclk_rate = host->caps.hs_clk_rate;
+
+ /* Select DDR mode in mci register */
+ mmc_reg = readl(MMC_BOOT_MCI_CLK);
+ mmc_reg |= (MMC_MCI_DDR_MODE_EN << MMC_MCI_MODE_SELECT);
+
+ writel(mmc_reg, MMC_BOOT_MCI_CLK);
+
+ /* Wait for the MMC_BOOT_MCI_CLK write to go through. */
+ mmc_mclk_reg_wr_delay();
+
+ /* Enable wide bus for DDR */
+ mmc_reg = readl(MMC_BOOT_MCI_CLK);
+ mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_MODE;
+ writel(mmc_reg, MMC_BOOT_MCI_CLK);
+
+ /* Wait for the MMC_BOOT_MCI_CLK write to go through. */
+ mmc_mclk_reg_wr_delay();
+
+end:
+ return MMC_BOOT_E_SUCCESS;
+}
+
+/*
* A command to start data read from card. Either a single block or
* multiple blocks can be read. Multiple blocks read will continuously
* transfer data from card to host unless requested to stop by issuing
@@ -2206,19 +2306,39 @@
mmc_return);
return mmc_return;
}
-
- /* enable wide bus */
- mmc_bus_width = target_mmc_bus_width();
- mmc_return =
- mmc_boot_set_bus_width(card, mmc_bus_width);
- if (mmc_return != MMC_BOOT_E_SUCCESS) {
- dprintf(CRITICAL,
- "Error No.%d: Failure to set wide bus for Card(RCA:%x)\n",
- mmc_return, card->rca);
- return mmc_return;
- }
}
+ /* Enable HS200 mode by default if supported,
+ * else if DDR mode is supported enable it.
+ * else use default 4/8 bit mode
+ */
+ if (card_supports_hs200_mode() && host->caps.hs200_mode) {
+ mmc_return = mmc_set_hs200_mode(host, card);
+ if (mmc_return != MMC_BOOT_E_SUCCESS) {
+ dprintf(CRITICAL,
+ "Error No.%d: Failure to set HS200 mode for Card(RCA:%x)\n",
+ mmc_return, card->rca);
+ return mmc_return;
+ }
+ } else if (card_supports_ddr_mode() && host->caps.ddr_mode) {
+ mmc_return = mmc_set_ddr_mode(host, card);
+ if (mmc_return != MMC_BOOT_E_SUCCESS) {
+ dprintf(CRITICAL,
+ "Error No.%d: Failure to set DDR mode for Card(RCA:%x)\n",
+ mmc_return, card->rca);
+ return mmc_return;
+ }
+ } else {
+ mmc_return =
+ mmc_boot_set_bus_width(card, host->caps.bus_width);
+ if (mmc_return != MMC_BOOT_E_SUCCESS) {
+ dprintf(CRITICAL,
+ "Error No.%d: Failure to set wide bus for Card(RCA:%x)\n",
+ mmc_return, card->rca);
+ return mmc_return;
+ }
+ }
+
/* Just checking whether we're in TRAN state after changing speed and bus width */
mmc_return = mmc_boot_get_card_status(card, 0, &status);
if (mmc_return != MMC_BOOT_E_SUCCESS) {
@@ -2263,6 +2383,9 @@
mmc_slot = slot;
mmc_boot_mci_base = base;
+ /* Get the capabilities for the host/target */
+ target_mmc_caps(&mmc_host);
+
/* Initialize necessary data structure and enable/set clock and power */
dprintf(SPEW, " Initializing MMC host data structure and clock!\n");
mmc_ret = mmc_boot_init(&mmc_host);
@@ -3262,3 +3385,27 @@
}
#endif
+
+/*
+ * Check if card supports DDR mode
+ */
+uint8_t card_supports_ddr_mode()
+{
+ if (IS_BIT_SET_EXT_CSD(MMC_DEVICE_TYPE, 2) ||
+ IS_BIT_SET_EXT_CSD(MMC_DEVICE_TYPE, 3))
+ return 1;
+ else
+ return 0;
+}
+
+/*
+ * Check if card suppports HS200 mode
+ */
+uint8_t card_supports_hs200_mode()
+{
+ if (IS_BIT_SET_EXT_CSD(MMC_DEVICE_TYPE, 4) ||
+ IS_BIT_SET_EXT_CSD(MMC_DEVICE_TYPE, 5))
+ return 1;
+ else
+ return 0;
+}
diff --git a/platform/msm_shared/partition_parser.c b/platform/msm_shared/partition_parser.c
index dc985db..c80f7d3 100644
--- a/platform/msm_shared/partition_parser.c
+++ b/platform/msm_shared/partition_parser.c
@@ -44,7 +44,7 @@
//TODO: Remove the dependency of mmc in these functions
unsigned int
-partition_read_table(struct mmc_host *mmc_host,
+partition_read_table(void *mmc_host,
struct mmc_card *mmc_card)
{
unsigned int ret;
diff --git a/target/init.c b/target/init.c
index fc5c34a..78a7bad 100644
--- a/target/init.c
+++ b/target/init.c
@@ -119,8 +119,13 @@
{
}
-/* Default target specific function for mmc bus width */
-__WEAK int target_mmc_bus_width()
+/*
+ * Default target specific function to set the capabilities for the host
+ */
+__WEAK void target_mmc_caps(struct mmc_host *host)
{
- return MMC_BOOT_BUS_WIDTH_4_BIT;
+ host->caps.ddr_mode = 0;
+ host->caps.hs200_mode = 0;
+ host->caps.bus_width = MMC_BOOT_BUS_WIDTH_4_BIT;
+ host->caps.hs_clk_rate = MMC_CLK_50MHZ;
}
diff --git a/target/msm8610/init.c b/target/msm8610/init.c
index 7e962b3..326b26f 100644
--- a/target/msm8610/init.c
+++ b/target/msm8610/init.c
@@ -40,6 +40,7 @@
#include <baseband.h>
#include <dev/keys.h>
#include <pm8x41.h>
+#include <hsusb.h>
#define PMIC_ARB_CHANNEL_NUM 0
#define PMIC_ARB_OWNER_ID 0
@@ -222,6 +223,30 @@
return 0;
}
+void target_usb_stop(void)
+{
+ /* Disable VBUS mimicing in the controller. */
+ ulpi_write(ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT, ULPI_MISC_A_CLEAR);
+}
+
+void target_usb_init(void)
+{
+ uint32_t val;
+
+ /* 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);
+}
+
+
unsigned board_machtype(void)
{
return 0;
diff --git a/target/msm8960/init.c b/target/msm8960/init.c
index f26f982..2eb3e55 100755
--- a/target/msm8960/init.c
+++ b/target/msm8960/init.c
@@ -515,7 +515,14 @@
}
}
-int target_mmc_bus_width()
+
+/*
+ * Function to set the capabilities for the host
+ */
+void target_mmc_caps(struct mmc_host *host)
{
- return MMC_BOOT_BUS_WIDTH_8_BIT;
+ host->caps.ddr_mode = 1;
+ host->caps.hs200_mode = 1;
+ host->caps.bus_width = MMC_BOOT_BUS_WIDTH_8_BIT;
+ host->caps.hs_clk_rate = MMC_CLK_96MHZ;
}
diff --git a/target/msm8974/init.c b/target/msm8974/init.c
index b21142f..a3d48b7 100644
--- a/target/msm8974/init.c
+++ b/target/msm8974/init.c
@@ -28,6 +28,7 @@
#include <debug.h>
#include <platform/iomap.h>
+#include <platform/gpio.h>
#include <reg.h>
#include <target.h>
#include <platform.h>
@@ -47,6 +48,7 @@
#include <platform/clock.h>
extern bool target_use_signed_kernel(void);
+static void set_sdc_power_ctrl();
static unsigned int target_id;
static uint32_t pmic_ver;
@@ -177,6 +179,12 @@
dprintf(INFO, "Display Init: Done\n");
#endif
+ /*
+ * Set drive strength & pull ctrl for
+ * emmc
+ */
+ set_sdc_power_ctrl();
+
/* Trying Slot 1*/
slot = 1;
base_addr = mmc_sdc_base[slot - 1];
@@ -435,3 +443,37 @@
dprintf(CRITICAL, "Shutdown failed\n");
}
+
+/*
+ * Function to set the capabilities for the host
+ */
+void target_mmc_caps(struct mmc_host *host)
+{
+ host->caps.ddr_mode = 1;
+ host->caps.hs200_mode = 1;
+ host->caps.bus_width = MMC_BOOT_BUS_WIDTH_8_BIT;
+ host->caps.hs_clk_rate = MMC_CLK_96MHZ;
+}
+
+static void set_sdc_power_ctrl()
+{
+ /* Drive strength configs for sdc pins */
+ struct tlmm_cfgs sdc1_hdrv_cfg[] =
+ {
+ { SDC1_CLK_HDRV_CTL_OFF, TLMM_CUR_VAL_16MA, 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 },
+ };
+
+ /* 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 },
+ };
+
+ /* Set the drive strength & pull control values */
+ tlmm_set_hdrive_ctrl(sdc1_hdrv_cfg, ARRAY_SIZE(sdc1_hdrv_cfg));
+ tlmm_set_pull_ctrl(sdc1_pull_cfg, ARRAY_SIZE(sdc1_pull_cfg));
+}