From 8948ea830275afaa7c91fe7e13dd3c4b894a453f Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 30 Jul 2012 10:55:43 +0000 Subject: mmc: detect boot sectors using EXT_CSD_BOOT_MULT too Some eMMC devices contain boot partitions, but do not set the PART_SUPPORT bit in EXT_CSD_PARTITIONING_SUPPORT. Allow partition selection on such devices, by enabling partition switching when EXT_CSD_BOOT_MULT is set. Note that the Linux kernel enables access to boot partitions solely based on the value of EXT_CSD_BOOT_MULT; EXT_CSD_PARTITIONING_SUPPORT only influences access to "general" partitions. eMMC devices affected by this issue exist on various NVIDIA Tegra platforms (and presumably many others too), such as Harmony (plug-in eMMC), Seaboard, Springbank, and Whistler (plug-in eMMC). Signed-off-by: Stephen Warren Signed-off-by: Andy Fleming --- include/mmc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/mmc.h b/include/mmc.h index 7b094a4146e..a13e2bdcf16 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -160,6 +160,7 @@ #define EXT_CSD_CARD_TYPE 196 /* RO */ #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ +#define EXT_CSD_BOOT_MULT 226 /* RO */ /* * EXT_CSD field definitions -- cgit v1.3.1 From 1c1ec3c0b599e3759f5e232a46f5460221941097 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 30 Jul 2012 10:55:45 +0000 Subject: tegra: put eMMC environment into the boot sectors When I set up Tegra's config files to put the environment into eMMC, I assumed that CONFIG_ENV_OFFSET was a linearized address relative to the start of the eMMC device, and spanning HW partitions boot0, boot1, general* and the user area in order. However, it turns out that the offset is actually relative to the beginning of the user area. Hence, the environment block ended up in a different location to expected and documented. Set CONFIG_SYS_MMC_ENV_PART=2 (boot1) to solve this, and adjust CONFIG_ENV_OFFSET to be relative to the start of boot1, not the entire eMMC. Signed-off-by: Stephen Warren Signed-off-by: Andy Fleming --- include/configs/paz00.h | 3 ++- include/configs/seaboard.h | 3 ++- include/configs/ventana.h | 3 ++- include/configs/whistler.h | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/configs/paz00.h b/include/configs/paz00.h index 0eb9f3b6045..99b8753c586 100644 --- a/include/configs/paz00.h +++ b/include/configs/paz00.h @@ -51,8 +51,9 @@ /* Environment in eMMC, at the end of 2nd "boot sector" */ #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET ((2 * 1024 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET ((1024 * 1024) - CONFIG_ENV_SIZE) #define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_SYS_MMC_ENV_PART 2 /* USB Host support */ #define CONFIG_USB_EHCI diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h index afc4a855bf0..8dc6d4b907b 100644 --- a/include/configs/seaboard.h +++ b/include/configs/seaboard.h @@ -77,8 +77,9 @@ /* Environment in eMMC, at the end of 2nd "boot sector" */ #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET ((2 * 512 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET ((512 * 1024) - CONFIG_ENV_SIZE) #define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_SYS_MMC_ENV_PART 2 /* USB Host support */ #define CONFIG_USB_EHCI diff --git a/include/configs/ventana.h b/include/configs/ventana.h index 25ec2ebfec7..f5e1bf81ff1 100644 --- a/include/configs/ventana.h +++ b/include/configs/ventana.h @@ -58,8 +58,9 @@ /* Environment in eMMC, at the end of 2nd "boot sector" */ #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET ((2 * 1024 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET ((1024 * 1024) - CONFIG_ENV_SIZE) #define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_SYS_MMC_ENV_PART 2 /* USB Host support */ #define CONFIG_USB_EHCI diff --git a/include/configs/whistler.h b/include/configs/whistler.h index b747d0e2b2c..32357181556 100644 --- a/include/configs/whistler.h +++ b/include/configs/whistler.h @@ -72,8 +72,9 @@ * particular card is standard practice as far as I know. */ #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET ((2 * 512 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET ((512 * 1024) - CONFIG_ENV_SIZE) #define CONFIG_SYS_MMC_ENV_DEV 0 +#define CONFIG_SYS_MMC_ENV_PART 2 /* USB Host support */ #define CONFIG_USB_EHCI -- cgit v1.3.1 From 470dcc7511431db4210a79ea4e6b14cf109a24dc Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 17 Aug 2012 10:18:55 +0000 Subject: mmc: Add a SDHCI quirk for boards that have no CD Some boards have no Card Detect wired. In that case, set the CD test bits in the standard interface. Signed-off-by: Joe Hershberger Signed-off-by: Andy Fleming --- drivers/mmc/sdhci.c | 17 +++++++++++++++-- include/sdhci.h | 7 ++++++- 2 files changed, 21 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index b07dc0064e7..3bb0ad0491e 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -381,12 +381,25 @@ int sdhci_init(struct mmc *mmc) } } + sdhci_set_power(host, fls(mmc->voltages) - 1); + + if (host->quirks & SDHCI_QUIRK_NO_CD) { + unsigned int status; + + sdhci_writel(host, SDHCI_CTRL_CD_TEST_INS | SDHCI_CTRL_CD_TEST, + SDHCI_HOST_CONTROL); + + status = sdhci_readl(host, SDHCI_PRESENT_STATE); + while ((!(status & SDHCI_CARD_PRESENT)) || + (!(status & SDHCI_CARD_STATE_STABLE)) || + (!(status & SDHCI_CARD_DETECT_PIN_LEVEL))) + status = sdhci_readl(host, SDHCI_PRESENT_STATE); + } + /* Eable all state */ sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_ENABLE); sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_SIGNAL_ENABLE); - sdhci_set_power(host, fls(mmc->voltages) - 1); - return 0; } diff --git a/include/sdhci.h b/include/sdhci.h index 9d371832436..d41287f67b4 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -76,6 +76,8 @@ #define SDHCI_SPACE_AVAILABLE 0x00000400 #define SDHCI_DATA_AVAILABLE 0x00000800 #define SDHCI_CARD_PRESENT 0x00010000 +#define SDHCI_CARD_STATE_STABLE 0x00020000 +#define SDHCI_CARD_DETECT_PIN_LEVEL 0x00040000 #define SDHCI_WRITE_PROTECT 0x00080000 #define SDHCI_HOST_CONTROL 0x28 @@ -87,7 +89,9 @@ #define SDHCI_CTRL_ADMA1 0x08 #define SDHCI_CTRL_ADMA32 0x10 #define SDHCI_CTRL_ADMA64 0x18 -#define SDHCI_CTRL_8BITBUS 0x20 +#define SDHCI_CTRL_8BITBUS 0x20 +#define SDHCI_CTRL_CD_TEST_INS 0x40 +#define SDHCI_CTRL_CD_TEST 0x80 #define SDHCI_POWER_CONTROL 0x29 #define SDHCI_POWER_ON 0x01 @@ -219,6 +223,7 @@ #define SDHCI_QUIRK_BROKEN_R1B (1 << 2) #define SDHCI_QUIRK_NO_HISPD_BIT (1 << 3) #define SDHCI_QUIRK_BROKEN_VOLTAGE (1 << 4) +#define SDHCI_QUIRK_NO_CD (1 << 5) /* to make gcc happy */ struct sdhci_host; -- cgit v1.3.1 From b09ed6e4fe6065851751e7fc381ff40c23fb09f1 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Thu, 30 Aug 2012 16:24:11 +0000 Subject: mmc: s5p_sdhci: add the set_mmc_clk for cmu control Samsung SoC use the cmu control to set clock. Signed-off-by: Jaehoon Chung Signed-off-by: Kyungmin Park Signed-off-by: Andy Fleming --- drivers/mmc/s5p_sdhci.c | 3 +++ drivers/mmc/sdhci.c | 3 +++ include/configs/trats.h | 1 + include/sdhci.h | 2 ++ 4 files changed, 9 insertions(+) (limited to 'include') diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index 9378e36b399..b9782367e2a 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -21,6 +21,7 @@ #include #include #include +#include static char *S5P_NAME = "SAMSUNG SDHCI"; static void s5p_sdhci_set_control_reg(struct sdhci_host *host) @@ -87,6 +88,8 @@ int s5p_sdhci_init(u32 regbase, int index, int bus_width) host->version = sdhci_readw(host, SDHCI_HOST_VERSION); host->set_control_reg = &s5p_sdhci_set_control_reg; + host->set_clock = set_mmc_clk; + host->index = index; host->host_caps = MMC_MODE_HC; diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 3bb0ad0491e..2e3c408bc55 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -279,6 +279,9 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) } div >>= 1; + if (host->set_clock) + host->set_clock(host->index, div); + clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) << SDHCI_DIVIDER_HI_SHIFT; diff --git a/include/configs/trats.h b/include/configs/trats.h index f8da9c01c2e..794b6fb7931 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -78,6 +78,7 @@ #define CONFIG_MMC #define CONFIG_S5P_SDHCI #define CONFIG_SDHCI +#define CONFIG_MMC_SDMA /* PWM */ #define CONFIG_PWM diff --git a/include/sdhci.h b/include/sdhci.h index d41287f67b4..c0345ed86ef 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -253,8 +253,10 @@ struct sdhci_host { unsigned int clock; struct mmc *mmc; const struct sdhci_ops *ops; + int index; void (*set_control_reg)(struct sdhci_host *host); + void (*set_clock)(int dev_index, unsigned int div); uint voltages; }; -- cgit v1.3.1