Merge "init: Add generic set_download_mode() function"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 6840c43..1ebc41e 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -90,6 +90,8 @@
static const char *emmc_cmdline = " androidboot.emmc=true";
static const char *usb_sn_cmdline = " androidboot.serialno=";
+static const char *androidboot_mode = " androidboot.mode=";
+static const char *loglevel = " quiet";
static const char *battchg_pause = " androidboot.mode=charger";
static const char *auth_kernel = " androidboot.authorized_kernel=true";
@@ -185,6 +187,8 @@
int have_cmdline = 0;
unsigned char *cmdline_final = NULL;
int pause_at_bootup = 0;
+ char ffbm[10];
+ bool boot_into_ffbm = get_ffbm(ffbm, sizeof(ffbm));
if (cmdline && cmdline[0]) {
cmdline_len = strlen(cmdline);
@@ -197,7 +201,12 @@
cmdline_len += strlen(usb_sn_cmdline);
cmdline_len += strlen(sn_buf);
- if (target_pause_for_battery_charge()) {
+ if (boot_into_ffbm) {
+ cmdline_len += strlen(androidboot_mode);
+ cmdline_len += strlen(ffbm);
+ /* reduce kernel console messages to speed-up boot */
+ cmdline_len += strlen(loglevel);
+ } else if (target_pause_for_battery_charge()) {
pause_at_bootup = 1;
cmdline_len += strlen(battchg_pause);
}
@@ -273,7 +282,17 @@
have_cmdline = 1;
while ((*dst++ = *src++));
- if (pause_at_bootup) {
+ if (boot_into_ffbm) {
+ src = androidboot_mode;
+ if (have_cmdline) --dst;
+ while ((*dst++ = *src++));
+ src = ffbm;
+ if (have_cmdline) --dst;
+ while ((*dst++ = *src++));
+ src = loglevel;
+ if (have_cmdline) --dst;
+ while ((*dst++ = *src++));
+ } else if (pause_at_bootup) {
src = battchg_pause;
if (have_cmdline) --dst;
while ((*dst++ = *src++));
diff --git a/app/aboot/recovery.c b/app/aboot/recovery.c
index 566d245..c96490f 100644
--- a/app/aboot/recovery.c
+++ b/app/aboot/recovery.c
@@ -37,6 +37,7 @@
#include <lib/ptable.h>
#include <dev/keys.h>
#include <platform.h>
+#include <target.h>
#include <partition_parser.h>
#include <mmc.h>
@@ -51,6 +52,7 @@
static const int MISC_PAGES = 3; // number of pages to save
static const int MISC_COMMAND_PAGE = 1; // bootloader command is this page
static char buf[4096];
+
unsigned boot_into_recovery = 0;
extern void reset_device_info();
@@ -295,10 +297,11 @@
// get recovery message
if (get_recovery_message(&msg))
return -1;
- if (msg.command[0] != 0 && msg.command[0] != 255) {
- dprintf(INFO, "Recovery command: %.*s\n", sizeof(msg.command), msg.command);
- }
msg.command[sizeof(msg.command)-1] = '\0'; //Ensure termination
+ if (msg.command[0] != 0 && msg.command[0] != 255) {
+ dprintf(INFO,"Recovery command: %d %s\n",
+ sizeof(msg.command), msg.command);
+ }
if (!strcmp("boot-recovery",msg.command))
{
@@ -429,10 +432,11 @@
// get recovery message
if(emmc_get_recovery_msg(&msg))
return -1;
- if (msg.command[0] != 0 && msg.command[0] != 255) {
- dprintf(INFO,"Recovery command: %d %s\n", sizeof(msg.command), msg.command);
- }
msg.command[sizeof(msg.command)-1] = '\0'; //Ensure termination
+ if (msg.command[0] != 0 && msg.command[0] != 255) {
+ dprintf(INFO,"Recovery command: %d %s\n",
+ sizeof(msg.command), msg.command);
+ }
if (!strncmp(msg.command, "boot-recovery", strlen("boot-recovery"))) {
boot_into_recovery = 1;
@@ -470,3 +474,193 @@
emmc_set_recovery_msg(&msg); // send recovery message
return 0;
}
+
+static int read_misc(unsigned page_offset, void *buf, unsigned size)
+{
+ const char *ptn_name = "misc";
+ void *scratch_addr = target_get_scratch_address();
+ unsigned offset;
+ unsigned aligned_size;
+
+ if (size == 0 || buf == NULL || scratch_addr == NULL)
+ return -1;
+
+ if (target_is_emmc_boot())
+ {
+ int index;
+ unsigned long long ptn;
+ unsigned long long ptn_size;
+
+ index = partition_get_index(ptn_name);
+ if (index == INVALID_PTN)
+ {
+ dprintf(CRITICAL, "No '%s' partition found\n", ptn_name);
+ return -1;
+ }
+
+ ptn = partition_get_offset(index);
+ ptn_size = partition_get_size(index);
+
+ offset = page_offset * BLOCK_SIZE;
+ aligned_size = ROUND_TO_PAGE(size, (unsigned)BLOCK_SIZE - 1);
+ if (ptn_size < offset + aligned_size)
+ {
+ dprintf(CRITICAL, "Read request out of '%s' boundaries\n",
+ ptn_name);
+ return -1;
+ }
+
+ if (mmc_read(ptn + offset, (unsigned int *)scratch_addr, aligned_size))
+ {
+ dprintf(CRITICAL, "Reading MMC failed\n");
+ return -1;
+ }
+ }
+ else
+ {
+ struct ptentry *ptn;
+ struct ptable *ptable;
+ unsigned pagesize = flash_page_size();
+
+ ptable = flash_get_ptable();
+ if (ptable == NULL)
+ {
+ dprintf(CRITICAL, "Partition table not found\n");
+ return -1;
+ }
+
+ ptn = ptable_find(ptable, ptn_name);
+ if (ptn == NULL)
+ {
+ dprintf(CRITICAL, "No '%s' partition found\n", ptn_name);
+ return -1;
+ }
+
+ offset = page_offset * pagesize;
+ aligned_size = ROUND_TO_PAGE(size, pagesize - 1);
+ if (ptn->length < offset + aligned_size)
+ {
+ dprintf(CRITICAL, "Read request out of '%s' boundaries\n",
+ ptn_name);
+ return -1;
+ }
+
+ if (flash_read(ptn, offset, scratch_addr, aligned_size)) {
+ dprintf(CRITICAL, "Reading flash failed\n");
+ return -1;
+ }
+ }
+
+ if (scratch_addr != buf)
+ memcpy(buf, scratch_addr, size);
+
+ return 0;
+}
+
+int write_misc(unsigned page_offset, void *buf, unsigned size)
+{
+ const char *ptn_name = "misc";
+ void *scratch_addr = target_get_scratch_address();
+ unsigned offset;
+ unsigned aligned_size;
+
+ if (size == 0 || buf == NULL || scratch_addr == NULL)
+ return -1;
+
+ if (target_is_emmc_boot())
+ {
+ int index;
+ unsigned long long ptn;
+ unsigned long long ptn_size;
+
+ index = partition_get_index(ptn_name);
+ if (index == INVALID_PTN)
+ {
+ dprintf(CRITICAL, "No '%s' partition found\n", ptn_name);
+ return -1;
+ }
+
+ ptn = partition_get_offset(index);
+ ptn_size = partition_get_size(index);
+
+ offset = page_offset * BLOCK_SIZE;
+ aligned_size = ROUND_TO_PAGE(size, (unsigned)BLOCK_SIZE - 1);
+ if (ptn_size < offset + aligned_size)
+ {
+ dprintf(CRITICAL, "Write request out of '%s' boundaries\n",
+ ptn_name);
+ return -1;
+ }
+
+ if (scratch_addr != buf)
+ memcpy(scratch_addr, buf, size);
+ if (mmc_write(ptn + offset, aligned_size, (unsigned int *)scratch_addr))
+ {
+ dprintf(CRITICAL, "Writing MMC failed\n");
+ return -1;
+ }
+ }
+ else
+ {
+ struct ptentry *ptn;
+ struct ptable *ptable;
+ unsigned pagesize = flash_page_size();
+
+ ptable = flash_get_ptable();
+ if (ptable == NULL)
+ {
+ dprintf(CRITICAL, "Partition table not found\n");
+ return -1;
+ }
+
+ ptn = ptable_find(ptable, ptn_name);
+ if (ptn == NULL)
+ {
+ dprintf(CRITICAL, "No '%s' partition found\n", ptn_name);
+ return -1;
+ }
+
+ offset = page_offset * pagesize;
+ aligned_size = ROUND_TO_PAGE(size, pagesize - 1);
+ if (ptn->length < offset + aligned_size)
+ {
+ dprintf(CRITICAL, "Write request out of '%s' boundaries\n",
+ ptn_name);
+ return -1;
+ }
+
+ if (scratch_addr != buf)
+ memcpy(scratch_addr, buf, size);
+ if (flash_write(ptn, offset, scratch_addr, aligned_size)) {
+ dprintf(CRITICAL, "Writing flash failed\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+bool get_ffbm(char *ffbm, unsigned size)
+{
+ const char *ffbm_cmd = "ffbm-";
+ const unsigned ffbm_submode_size = 2;
+ unsigned ffbm_mode_size = strlen(ffbm_cmd) + ffbm_submode_size;
+
+ if (size < ffbm_mode_size + 1)
+ {
+ dprintf(CRITICAL, "Buffer too short to get FFBM string\n");
+ return false;
+ }
+
+ if (read_misc(0, ffbm, ffbm_mode_size))
+ {
+ dprintf(CRITICAL, "Error reading MISC partition\n");
+ return false;
+ }
+ ffbm[ffbm_mode_size] = 0;
+
+ if (!strncmp(ffbm, ffbm_cmd, strlen(ffbm_cmd)))
+ return true;
+
+ return false;
+}
diff --git a/app/aboot/recovery.h b/app/aboot/recovery.h
index 6037213..0d6289a 100644
--- a/app/aboot/recovery.h
+++ b/app/aboot/recovery.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2013, 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
@@ -62,7 +62,7 @@
unsigned fail_bitmap_length;
};
-
+int write_misc(unsigned page_offset, void *buf, unsigned size);
int get_recovery_message(struct recovery_message *out);
int set_recovery_message(const struct recovery_message *in);
@@ -72,6 +72,8 @@
int recovery_init (void);
+bool get_ffbm(char *ffbm, unsigned size);
+
extern unsigned boot_into_recovery;
#endif
diff --git a/include/target.h b/include/target.h
index b9dde60..6c4486d 100644
--- a/include/target.h
+++ b/include/target.h
@@ -1,6 +1,8 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
@@ -46,6 +48,7 @@
unsigned target_baseband(void);
void target_serialno(unsigned char *buf);
void target_fastboot_init(void);
+struct mmc_device *target_mmc_device();
#endif
diff --git a/platform/msm8226/acpuclock.c b/platform/msm8226/acpuclock.c
index 96e8687..a9e14e3 100644
--- a/platform/msm8226/acpuclock.c
+++ b/platform/msm8226/acpuclock.c
@@ -118,9 +118,6 @@
snprintf(clk_name, 64, "sdc%u_core_clk", interface);
- /* Disalbe 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);
@@ -129,6 +126,10 @@
{
ret = clk_get_set_enable(clk_name, 50000000, 1);
}
+ else if(freq == MMC_CLK_200MHZ)
+ {
+ ret = clk_get_set_enable(clk_name, 200000000, 1);
+ }
else
{
dprintf(CRITICAL, "sdc frequency (%d) is not supported\n", freq);
@@ -141,9 +142,6 @@
dprintf(CRITICAL, "failed to set sdc1_core_clk ret = %d\n", ret);
ASSERT(0);
}
-
- /* Enable MCI CLK */
- mmc_boot_mci_clk_enable();
}
/* Configure UART clock based on the UART block id*/
diff --git a/platform/msm8226/include/platform/gpio.h b/platform/msm8226/include/platform/gpio.h
index ac554da..02849ab 100644
--- a/platform/msm8226/include/platform/gpio.h
+++ b/platform/msm8226/include/platform/gpio.h
@@ -30,6 +30,7 @@
#define __PLATFORM_MSM8226_GPIO_H
#include <bits.h>
+#include <gpio.h>
/* GPIO TLMM: Direction */
#define GPIO_INPUT 0
diff --git a/platform/msm8226/include/platform/iomap.h b/platform/msm8226/include/platform/iomap.h
index d459984..83f22b7 100644
--- a/platform/msm8226/include/platform/iomap.h
+++ b/platform/msm8226/include/platform/iomap.h
@@ -51,13 +51,16 @@
#define MSM_SDC1_BAM_BASE (PERIPH_SS_BASE + 0x00004000)
#define MSM_SDC1_BASE (PERIPH_SS_BASE + 0x00024000)
+#define MSM_SDC1_SDHCI_BASE (PERIPH_SS_BASE + 0x00024900)
#define MSM_SDC1_DML_BASE (PERIPH_SS_BASE + 0x00024800)
#define MSM_SDC3_BAM_BASE (PERIPH_SS_BASE + 0x00044000)
#define MSM_SDC3_BASE (PERIPH_SS_BASE + 0x00064000)
+#define MSM_SDC3_SDHCI_BASE (PERIPH_SS_BASE + 0x00064900)
#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 BLSP1_UART0_BASE (PERIPH_SS_BASE + 0x0011D000)
#define BLSP1_UART1_BASE (PERIPH_SS_BASE + 0x0011E000)
@@ -127,4 +130,11 @@
#define USB_HS_SYSTEM_CMD_RCGR (CLK_CTL_BASE + 0x490)
#define USB_HS_SYSTEM_CFG_RCGR (CLK_CTL_BASE + 0x494)
+/* SDHCI */
+#define SDCC_MCI_HC_MODE (PERIPH_SS_BASE + 0x00024078)
+#define SDCC_HC_PWRCTL_MASK_REG (PERIPH_SS_BASE + 0x000240E0)
+#define SDCC_HC_PWRCTL_CTL_REG (PERIPH_SS_BASE + 0x000240E8)
+
+/* DRV strength for sdcc */
+#define SDC1_HDRV_PULL_CTL (TLMM_BASE_ADDR + 0x00002044)
#endif
diff --git a/platform/msm8226/include/platform/irqs.h b/platform/msm8226/include/platform/irqs.h
index c490a0b..2e29d3a 100644
--- a/platform/msm8226/include/platform/irqs.h
+++ b/platform/msm8226/include/platform/irqs.h
@@ -47,6 +47,8 @@
#define USB1_HS_BAM_IRQ (GIC_SPI_START + 135)
#define USB1_HS_IRQ (GIC_SPI_START + 134)
+#define SDCC_PWRCTRL_IRQ (GIC_SPI_START + 138)
+
/* Retrofit universal macro names */
#define INT_USB_HS USB1_HS_IRQ
diff --git a/platform/msm8974/gpio.c b/platform/msm8974/gpio.c
index d36cd6d..13097da 100644
--- a/platform/msm8974/gpio.c
+++ b/platform/msm8974/gpio.c
@@ -89,32 +89,3 @@
};
}
}
-
-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 8c4bba8..8dc68f2 100644
--- a/platform/msm8974/include/platform/gpio.h
+++ b/platform/msm8974/include/platform/gpio.h
@@ -29,6 +29,8 @@
#ifndef __PLATFORM_COPPER_GPIO_H
#define __PLATFORM_COPPER_GPIO_H
+#include <gpio.h>
+
/* GPIO TLMM: Direction */
#define GPIO_INPUT 0
#define GPIO_OUTPUT 1
@@ -53,36 +55,6 @@
#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/msm_shared/gpio.c b/platform/msm_shared/gpio.c
new file mode 100644
index 0000000..137f00a
--- /dev/null
+++ b/platform/msm_shared/gpio.c
@@ -0,0 +1,62 @@
+/* Copyright (c) 2013, 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
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <debug.h>
+#include <reg.h>
+#include <bits.h>
+#include <platform/iomap.h>
+#include <gpio.h>
+
+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/msm_shared/include/gpio.h b/platform/msm_shared/include/gpio.h
new file mode 100644
index 0000000..2a95eda
--- /dev/null
+++ b/platform/msm_shared/include/gpio.h
@@ -0,0 +1,68 @@
+/* Copyright (c) 2013, 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
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _GPIO_H_
+#define _GPIO_H_
+
+#define TLMM_PULL_MASK 0x3
+#define TLMM_HDRV_MASK 0x7
+
+/* Current values for tlmm pins */
+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;
+
+/* Bit offsets in the TLMM register */
+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;
+
+/* Input for the tlmm config function */
+struct tlmm_cfgs {
+ uint32_t off; /* Bit offeset in the register */
+ uint8_t val; /* Current value */
+ uint8_t mask; /* Mask for the clk/dat/cmd control */
+};
+
+/* APIs: exposed for other drivers */
+/* API: Hdrive control for tlmm pins */
+void tlmm_set_hdrive_ctrl(struct tlmm_cfgs *, uint8_t);
+/* API: Pull control for tlmm pins */
+void tlmm_set_pull_ctrl(struct tlmm_cfgs *, uint8_t);
+#endif
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 46f7cb3..107960d 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -93,7 +93,8 @@
$(LOCAL_DIR)/crypto_hash.o \
$(LOCAL_DIR)/crypto5_eng.o \
$(LOCAL_DIR)/crypto5_wrapper.o \
- $(LOCAL_DIR)/i2c_qup.o
+ $(LOCAL_DIR)/i2c_qup.o \
+ $(LOCAL_DIR)/gpio.o
endif
ifeq ($(PLATFORM),msm8226)
@@ -114,7 +115,8 @@
$(LOCAL_DIR)/crypto_hash.o \
$(LOCAL_DIR)/crypto5_eng.o \
$(LOCAL_DIR)/crypto5_wrapper.o \
- $(LOCAL_DIR)/dev_tree.o
+ $(LOCAL_DIR)/dev_tree.o \
+ $(LOCAL_DIR)/gpio.o
endif
ifeq ($(PLATFORM),msm8610)
diff --git a/project/msm8226.mk b/project/msm8226.mk
index a9d45b2..262abc8 100644
--- a/project/msm8226.mk
+++ b/project/msm8226.mk
@@ -7,6 +7,7 @@
MODULES += app/aboot
DEBUG := 1
+ENABLE_SDHCI_SUPPORT := 1
#DEFINES += WITH_DEBUG_DCC=1
DEFINES += WITH_DEBUG_UART=1
@@ -14,3 +15,7 @@
DEFINES += DEVICE_TREE=1
#DEFINES += MMC_BOOT_BAM=1
DEFINES += CRYPTO_BAM=1
+
+ifeq ($(ENABLE_SDHCI_SUPPORT),1)
+DEFINES += MMC_SDHCI_SUPPORT=1
+endif
diff --git a/target/init.c b/target/init.c
index 764901a..937f136 100644
--- a/target/init.c
+++ b/target/init.c
@@ -24,7 +24,6 @@
#include <debug.h>
#include <target.h>
#include <compiler.h>
-#include <mmc.h>
#define EXPAND(NAME) #NAME
#define TARGET(NAME) EXPAND(NAME)
@@ -123,14 +122,3 @@
__WEAK void target_usb_stop(void)
{
}
-
-/*
- * Default target specific function to set the capabilities for the host
- */
-__WEAK 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_4_BIT;
- host->caps.hs_clk_rate = MMC_CLK_50MHZ;
-}
diff --git a/target/msm8226/init.c b/target/msm8226/init.c
index e07c4b1..e037090 100644
--- a/target/msm8226/init.c
+++ b/target/msm8226/init.c
@@ -32,7 +32,7 @@
#include <target.h>
#include <platform.h>
#include <uart_dm.h>
-#include <mmc.h>
+#include <mmc_sdhci.h>
#include <platform/gpio.h>
#include <spmi.h>
#include <board.h>
@@ -44,6 +44,7 @@
#include <hsusb.h>
extern bool target_use_signed_kernel(void);
+static void set_sdc_power_ctrl(void);
#define PMIC_ARB_CHANNEL_NUM 0
#define PMIC_ARB_OWNER_ID 0
@@ -57,8 +58,10 @@
#define TLMM_VOL_UP_BTN_GPIO 106
-static uint32_t mmc_sdc_base[] =
- { MSM_SDC1_BASE, MSM_SDC2_BASE, MSM_SDC3_BASE };
+static uint32_t mmc_sdhci_base[] =
+ { MSM_SDC1_SDHCI_BASE, MSM_SDC2_SDHCI_BASE, MSM_SDC3_SDHCI_BASE };
+
+struct mmc_device *dev;
void target_early_init(void)
{
@@ -124,31 +127,53 @@
crypto_init_params(&ce_params);
}
+void target_sdc_init()
+{
+ struct mmc_config_data config;
+
+ /*
+ * Set drive strength & pull ctrl for emmc
+ */
+ set_sdc_power_ctrl();
+
+ /* Enable sdhci mode */
+ sdhci_mode_enable(1);
+
+ config.bus_width = DATA_BUS_WIDTH_8BIT;
+ config.max_clk_rate = MMC_CLK_200MHZ;
+
+ /* Trying Slot 1*/
+ config.slot = 1;
+ config.base = mmc_sdhci_base[config.slot - 1];
+ if (!(dev = mmc_init(&config)))
+ {
+ /* Trying Slot 2 next */
+ config.slot = 2;
+ config.base = mmc_sdhci_base[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);
+ }
+}
+
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();
- /* Trying Slot 1*/
- slot = 1;
- base_addr = mmc_sdc_base[slot - 1];
- if (mmc_boot_main(slot, base_addr))
- {
-
- /* 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!");
- ASSERT(0);
- }
- }
+ target_sdc_init();
if (target_use_signed_kernel())
target_crypto_init_params();
@@ -295,3 +320,31 @@
{
return _emmc_recovery_init();
}
+
+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_10MA, 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));
+}
+
+struct mmc_device *target_mmc_device()
+{
+ return dev;
+}