diff options
author | Tom Rini | 2013-06-14 16:06:49 -0400 |
---|---|---|
committer | Tom Rini | 2013-06-14 16:06:49 -0400 |
commit | dfdb3d37dd0fa8bdabdf7b5ffb597af470e74621 (patch) | |
tree | d18616299f81b663fb2cda18f30423df796121f3 | |
parent | 216a793cc1702227fd4ad624080f585038d1fa45 (diff) | |
parent | 91171091c6733cd290e18bf25a8aedbe682d2430 (diff) |
Merge branch 'master' of git://www.denx.de/git/u-boot-mmc
-rw-r--r-- | README | 51 | ||||
-rw-r--r-- | common/env_mmc.c | 12 | ||||
-rw-r--r-- | drivers/mmc/fsl_esdhc.c | 9 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 76 | ||||
-rw-r--r-- | drivers/mmc/sdhci.c | 6 | ||||
-rw-r--r-- | include/configs/beaver.h | 2 | ||||
-rw-r--r-- | include/configs/cardhu.h | 2 | ||||
-rw-r--r-- | include/configs/dalmore.h | 2 | ||||
-rw-r--r-- | include/configs/paz00.h | 2 | ||||
-rw-r--r-- | include/configs/seaboard.h | 2 | ||||
-rw-r--r-- | include/configs/ventana.h | 2 | ||||
-rw-r--r-- | include/configs/whistler.h | 4 | ||||
-rw-r--r-- | include/environment.h | 6 | ||||
-rw-r--r-- | include/mmc.h | 7 |
14 files changed, 156 insertions, 27 deletions
@@ -3648,6 +3648,57 @@ but it can not erase, write this NOR flash by SRIO or PCIE interface. You will probably want to define these to avoid a really noisy system when storing the env in UBI. +- CONFIG_ENV_IS_IN_MMC: + + Define this if you have an MMC device which you want to use for the + environment. + + - CONFIG_SYS_MMC_ENV_DEV: + + Specifies which MMC device the environment is stored in. + + - CONFIG_SYS_MMC_ENV_PART (optional): + + Specifies which MMC partition the environment is stored in. If not + set, defaults to partition 0, the user area. Common values might be + 1 (first MMC boot partition), 2 (second MMC boot partition). + + - CONFIG_ENV_OFFSET: + - CONFIG_ENV_SIZE: + + These two #defines specify the offset and size of the environment + area within the specified MMC device. + + If offset is positive (the usual case), it is treated as relative to + the start of the MMC partition. If offset is negative, it is treated + as relative to the end of the MMC partition. This can be useful if + your board may be fitted with different MMC devices, which have + different sizes for the MMC partitions, and you always want the + environment placed at the very end of the partition, to leave the + maximum possible space before it, to store other data. + + These two values are in units of bytes, but must be aligned to an + MMC sector boundary. + + - CONFIG_ENV_OFFSET_REDUND (optional): + + Specifies a second storage area, of CONFIG_ENV_SIZE size, used to + hold a redundant copy of the environment data. This provides a + valid backup copy in case the other copy is corrupted, e.g. due + to a power failure during a "saveenv" operation. + + This value may also be positive or negative; this is handled in the + same way as CONFIG_ENV_OFFSET. + + This value is also in units of bytes, but must also be aligned to + an MMC sector boundary. + + - CONFIG_ENV_SIZE_REDUND (optional): + + This value need not be set, even when CONFIG_ENV_OFFSET_REDUND is + set. If this value is set, it must be set to the same value as + CONFIG_ENV_SIZE. + - CONFIG_SYS_SPI_INIT_OFFSET Defines offset to the initial SPI buffer area in DPRAM. The diff --git a/common/env_mmc.c b/common/env_mmc.c index 9ca098fa674..5d3a769db0e 100644 --- a/common/env_mmc.c +++ b/common/env_mmc.c @@ -53,11 +53,19 @@ DECLARE_GLOBAL_DATA_PTR; __weak int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr) { - *env_addr = CONFIG_ENV_OFFSET; + s64 offset; + + offset = CONFIG_ENV_OFFSET; #ifdef CONFIG_ENV_OFFSET_REDUND if (copy) - *env_addr = CONFIG_ENV_OFFSET_REDUND; + offset = CONFIG_ENV_OFFSET_REDUND; #endif + + if (offset < 0) + offset += mmc->capacity; + + *env_addr = offset; + return 0; } diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index 861f4b9d6ca..973b19f337b 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -178,7 +178,7 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data) int timeout; struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base; -#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO +#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO uint wml_value; wml_value = data->blocksize/4; @@ -310,6 +310,9 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) /* Figure out the transfer arguments */ xfertyp = esdhc_xfertyp(cmd, data); + /* Mask all irqs */ + esdhc_write32(®s->irqsigen, 0); + /* Send the command */ esdhc_write32(®s->cmdarg, cmd->cmdarg); #if defined(CONFIG_FSL_USDHC) @@ -320,15 +323,11 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) esdhc_write32(®s->xfertyp, xfertyp); #endif - /* Mask all irqs */ - esdhc_write32(®s->irqsigen, 0); - /* Wait for the command to complete */ while (!(esdhc_read32(®s->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE))) ; irqstat = esdhc_read32(®s->irqstat); - esdhc_write32(®s->irqstat, irqstat); /* Reset CMD and DATA portions on error */ if (irqstat & (CMD_ERR | IRQSTAT_CTOE)) { diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 0a2f5358e2f..e6a296a5762 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -301,10 +301,12 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src) return 0; } - if (blkcnt > 1) - cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK; - else + if (blkcnt == 0) + return 0; + else if (blkcnt == 1) cmd.cmdidx = MMC_CMD_WRITE_SINGLE_BLOCK; + else + cmd.cmdidx = MMC_CMD_WRITE_MULTIPLE_BLOCK; if (mmc->high_capacity) cmd.cmdarg = start; @@ -700,16 +702,49 @@ static int mmc_change_freq(struct mmc *mmc) return 0; } +static int mmc_set_capacity(struct mmc *mmc, int part_num) +{ + switch (part_num) { + case 0: + mmc->capacity = mmc->capacity_user; + break; + case 1: + case 2: + mmc->capacity = mmc->capacity_boot; + break; + case 3: + mmc->capacity = mmc->capacity_rpmb; + break; + case 4: + case 5: + case 6: + case 7: + mmc->capacity = mmc->capacity_gp[part_num - 4]; + break; + default: + return -1; + } + + mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len); + + return 0; +} + int mmc_switch_part(int dev_num, unsigned int part_num) { struct mmc *mmc = find_mmc_device(dev_num); + int ret; if (!mmc) return -1; - return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF, - (mmc->part_config & ~PART_ACCESS_MASK) - | (part_num & PART_ACCESS_MASK)); + ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF, + (mmc->part_config & ~PART_ACCESS_MASK) + | (part_num & PART_ACCESS_MASK)); + if (ret) + return ret; + + return mmc_set_capacity(mmc, part_num); } int mmc_getcd(struct mmc *mmc) @@ -917,7 +952,7 @@ static void mmc_set_bus_width(struct mmc *mmc, uint width) static int mmc_startup(struct mmc *mmc) { - int err; + int err, i; uint mult, freq; u64 cmult, csize, capacity; struct mmc_cmd cmd; @@ -1035,8 +1070,12 @@ static int mmc_startup(struct mmc *mmc) cmult = (mmc->csd[2] & 0x00038000) >> 15; } - mmc->capacity = (csize + 1) << (cmult + 2); - mmc->capacity *= mmc->read_bl_len; + mmc->capacity_user = (csize + 1) << (cmult + 2); + mmc->capacity_user *= mmc->read_bl_len; + mmc->capacity_boot = 0; + mmc->capacity_rpmb = 0; + for (i = 0; i < 4; i++) + mmc->capacity_gp[i] = 0; if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN) mmc->read_bl_len = MMC_MAX_BLOCK_LEN; @@ -1075,7 +1114,7 @@ static int mmc_startup(struct mmc *mmc) | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; capacity *= MMC_MAX_BLOCK_LEN; if ((capacity >> 20) > 2 * 1024) - mmc->capacity = capacity; + mmc->capacity_user = capacity; } switch (ext_csd[EXT_CSD_REV]) { @@ -1117,8 +1156,25 @@ static int mmc_startup(struct mmc *mmc) if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) || ext_csd[EXT_CSD_BOOT_MULT]) mmc->part_config = ext_csd[EXT_CSD_PART_CONF]; + + mmc->capacity_boot = ext_csd[EXT_CSD_BOOT_MULT] << 17; + + mmc->capacity_rpmb = ext_csd[EXT_CSD_RPMB_MULT] << 17; + + for (i = 0; i < 4; i++) { + int idx = EXT_CSD_GP_SIZE_MULT + i * 3; + mmc->capacity_gp[i] = (ext_csd[idx + 2] << 16) + + (ext_csd[idx + 1] << 8) + ext_csd[idx]; + mmc->capacity_gp[i] *= + ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; + mmc->capacity_gp[i] *= ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; + } } + err = mmc_set_capacity(mmc, mmc->part_num); + if (err) + return err; + if (IS_SD(mmc)) err = sd_change_freq(mmc); else diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 1eaea04ad10..c5631bff672 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -486,8 +486,10 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) mmc->voltages |= host->voltages; mmc->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT; - if (caps & SDHCI_CAN_DO_8BIT) - mmc->host_caps |= MMC_MODE_8BIT; + if ((host->version & SDHCI_SPEC_VER_MASK) >= SDHCI_SPEC_300) { + if (caps & SDHCI_CAN_DO_8BIT) + mmc->host_caps |= MMC_MODE_8BIT; + } if (host->host_caps) mmc->host_caps |= host->host_caps; diff --git a/include/configs/beaver.h b/include/configs/beaver.h index 058da4fa13b..d51f5f885f0 100644 --- a/include/configs/beaver.h +++ b/include/configs/beaver.h @@ -56,7 +56,7 @@ /* Environment in eMMC, at the end of 2nd "boot sector" */ #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET ((1024 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE) #define CONFIG_SYS_MMC_ENV_DEV 0 #define CONFIG_SYS_MMC_ENV_PART 2 diff --git a/include/configs/cardhu.h b/include/configs/cardhu.h index 6a991752114..f3916de55d6 100644 --- a/include/configs/cardhu.h +++ b/include/configs/cardhu.h @@ -55,7 +55,7 @@ /* Environment in eMMC, at the end of 2nd "boot sector" */ #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET ((512 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE) #define CONFIG_SYS_MMC_ENV_DEV 0 #define CONFIG_SYS_MMC_ENV_PART 2 diff --git a/include/configs/dalmore.h b/include/configs/dalmore.h index 7b68f7ca987..6d7a187cf1d 100644 --- a/include/configs/dalmore.h +++ b/include/configs/dalmore.h @@ -60,7 +60,7 @@ #define CONFIG_ENV_IS_IN_MMC #define CONFIG_SYS_MMC_ENV_DEV 0 #define CONFIG_SYS_MMC_ENV_PART 2 -#define CONFIG_ENV_OFFSET ((4096 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE) #define MACH_TYPE_DALMORE 4304 /* not yet in mach-types.h */ diff --git a/include/configs/paz00.h b/include/configs/paz00.h index eac1ef9e021..9e2686ac449 100644 --- a/include/configs/paz00.h +++ b/include/configs/paz00.h @@ -46,7 +46,7 @@ /* Environment in eMMC, at the end of 2nd "boot sector" */ #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET ((1024 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE) #define CONFIG_SYS_MMC_ENV_DEV 0 #define CONFIG_SYS_MMC_ENV_PART 2 diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h index f66173e0f23..f0da1fcf1f6 100644 --- a/include/configs/seaboard.h +++ b/include/configs/seaboard.h @@ -72,7 +72,7 @@ /* Environment in eMMC, at the end of 2nd "boot sector" */ #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET ((512 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE) #define CONFIG_SYS_MMC_ENV_DEV 0 #define CONFIG_SYS_MMC_ENV_PART 2 diff --git a/include/configs/ventana.h b/include/configs/ventana.h index 5755f11714f..41a717622d3 100644 --- a/include/configs/ventana.h +++ b/include/configs/ventana.h @@ -52,7 +52,7 @@ /* Environment in eMMC, at the end of 2nd "boot sector" */ #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET ((1024 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE) #define CONFIG_SYS_MMC_ENV_DEV 0 #define CONFIG_SYS_MMC_ENV_PART 2 diff --git a/include/configs/whistler.h b/include/configs/whistler.h index 9542c7e2131..994edecaab3 100644 --- a/include/configs/whistler.h +++ b/include/configs/whistler.h @@ -61,12 +61,12 @@ /* * Environment in eMMC, at the end of 2nd "boot sector". Note: This assumes - * the user plugged the standard 8MB MoviNAND card into J29/HSMMC/POP. If + * the user plugged the standard 8GB MoviNAND card into J29/HSMMC/POP. If * they didn't, the boot sector layout may be different. However, use of that * particular card is standard practice as far as I know. */ #define CONFIG_ENV_IS_IN_MMC -#define CONFIG_ENV_OFFSET ((512 * 1024) - CONFIG_ENV_SIZE) +#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE) #define CONFIG_SYS_MMC_ENV_DEV 0 #define CONFIG_SYS_MMC_ENV_PART 2 diff --git a/include/environment.h b/include/environment.h index 4c6a37b1121..460ccb42aff 100644 --- a/include/environment.h +++ b/include/environment.h @@ -75,6 +75,12 @@ # endif #endif /* CONFIG_ENV_IS_IN_FLASH */ +#if defined(CONFIG_ENV_IS_IN_MMC) +# ifdef CONFIG_ENV_OFFSET_REDUND +# define CONFIG_SYS_REDUNDAND_ENVIRONMENT +# endif +#endif + #if defined(CONFIG_ENV_IS_IN_NAND) # if defined(CONFIG_ENV_OFFSET_OOB) # ifdef CONFIG_ENV_OFFSET_REDUND diff --git a/include/mmc.h b/include/mmc.h index 566db59ac9f..ea198d87b7a 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -158,7 +158,9 @@ /* * EXT_CSD fields */ +#define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ #define EXT_CSD_PARTITIONING_SUPPORT 160 /* RO */ +#define EXT_CSD_RPMB_MULT 168 /* RO */ #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */ #define EXT_CSD_PART_CONF 179 /* R/W */ #define EXT_CSD_BUS_WIDTH 183 /* R/W */ @@ -166,6 +168,7 @@ #define EXT_CSD_REV 192 /* RO */ #define EXT_CSD_CARD_TYPE 196 /* RO */ #define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ +#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */ #define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */ #define EXT_CSD_BOOT_MULT 226 /* RO */ @@ -263,6 +266,10 @@ struct mmc { uint write_bl_len; uint erase_grp_size; u64 capacity; + u64 capacity_user; + u64 capacity_boot; + u64 capacity_rpmb; + u64 capacity_gp[4]; block_dev_desc_t block_dev; int (*send_cmd)(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data); |