]> git.karo-electronics.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://www.denx.de/git/u-boot-mmc
authorTom Rini <trini@ti.com>
Fri, 14 Jun 2013 20:06:49 +0000 (16:06 -0400)
committerTom Rini <trini@ti.com>
Fri, 14 Jun 2013 20:06:49 +0000 (16:06 -0400)
14 files changed:
README
common/env_mmc.c
drivers/mmc/fsl_esdhc.c
drivers/mmc/mmc.c
drivers/mmc/sdhci.c
include/configs/beaver.h
include/configs/cardhu.h
include/configs/dalmore.h
include/configs/paz00.h
include/configs/seaboard.h
include/configs/ventana.h
include/configs/whistler.h
include/environment.h
include/mmc.h

diff --git a/README b/README
index ac1ec44d155b06620303a6ccf7672fd2f15e5201..cd0336c3c887a2efdaac7c4c8ed3092f2b08e276 100644 (file)
--- a/README
+++ b/README
@@ -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
index 9ca098fa674dbb56911ed1ab3517152d6db84f3c..5d3a769db0e94ae05912568a3edd2c88b8be36b1 100644 (file)
@@ -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;
 }
 
index 861f4b9d6ca52844cb76b341574d74342032b03d..973b19f337b59b9646f58cff06454b0182b85ae5 100644 (file)
@@ -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(&regs->irqsigen, 0);
+
        /* Send the command */
        esdhc_write32(&regs->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(&regs->xfertyp, xfertyp);
 #endif
 
-       /* Mask all irqs */
-       esdhc_write32(&regs->irqsigen, 0);
-
        /* Wait for the command to complete */
        while (!(esdhc_read32(&regs->irqstat) & (IRQSTAT_CC | IRQSTAT_CTOE)))
                ;
 
        irqstat = esdhc_read32(&regs->irqstat);
-       esdhc_write32(&regs->irqstat, irqstat);
 
        /* Reset CMD and DATA portions on error */
        if (irqstat & (CMD_ERR | IRQSTAT_CTOE)) {
index 0a2f5358e2fe386a322a151fdb93cbd5ea50f497..e6a296a5762c939736d47aed83529f113c983635 100644 (file)
@@ -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
index 1eaea04ad108ac27fe5e4c954eed7fb1221384d2..c5631bff6721da8487e7b4bf79a595d55cb5260b 100644 (file)
@@ -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;
 
index 058da4fa13b60169baa5f3fca3d8707f667591fc..d51f5f885f0f9c1d880f4f58acf0dc2a159d7bd9 100644 (file)
@@ -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
 
index 6a991752114ae70ecba7c5829dec2eebf35ae533..f3916de55d61fb0426e3000340dc27d067753cbf 100644 (file)
@@ -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
 
index 7b68f7ca987515d5473a56ebc3637927e348d33f..6d7a187cf1da954cc71753c876ff0522d9b7becb 100644 (file)
@@ -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 */
 
index eac1ef9e0217098e8c0892111d770fedae0e1f87..9e2686ac449e8625094bafe5e66653fe3fcd1712 100644 (file)
@@ -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
 
index f66173e0f23bffac173e45e5dec7a53a8cdc55a7..f0da1fcf1f69dc1fed0227fac19d53e95cad1c42 100644 (file)
@@ -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
 
index 5755f11714f911a01a71cacad86a10d284d9fd26..41a717622d3ccc41258f617b034c9579a46dd2c6 100644 (file)
@@ -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
 
index 9542c7e213141fe07c5667e33be4997e3cdf6135..994edecaab3aa53bc807a31b5f4addc096053eb1 100644 (file)
 
 /*
  * 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
 
index 4c6a37b112119243a3dff63e2f9288f2ff293e5f..460ccb42affda4d823db40bd7866fa9dff8e399a 100644 (file)
 # 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
index 566db59ac9fdd5e682f5866b34673164e49e8d15..ea198d87b7a3228d8310c49d90f18004e3ac0565 100644 (file)
 /*
  * 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 */
 #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);