[U-Boot] [PATCH V3 1/4] README: document CONFIG_ENV_IS_IN_MMC

From: Stephen Warren swarren@nvidia.com
Describe the meaning of CONFIG_ENV_IS_IN_MMC, and all related defines that must or can be set when using that option.
Signed-off-by: Stephen Warren swarren@nvidia.com --- v3: * Mention that env size/offset are in bytes. * Fix typo; s/CONFIG_ENV_OFFSET/CONFIG_ENV_SIZE/ in one place. v2: New patch. --- README | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)
diff --git a/README b/README index 3012dcd..e7fedb8 100644 --- a/README +++ b/README @@ -3606,6 +3606,46 @@ 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. + + 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 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

From: Stephen Warren swarren@nvidia.com
Enhance the MMC core to calculate the size of each MMC partition, and update mmc->capacity whenever a partition is selected. This causes:
mmc dev 0 1 ; mmcinfo
... to report the size of the currently selected partition, rather than always reporting the size of the user partition.
Signed-off-by: Stephen Warren swarren@nvidia.com --- v3: No change. v2: No change. --- drivers/mmc/mmc.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++------ include/mmc.h | 7 ++++++ 2 files changed, 68 insertions(+), 7 deletions(-)
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 0a2f535..31036f7 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -700,16 +700,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 +950,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 +1068,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 +1112,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 +1154,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/include/mmc.h b/include/mmc.h index 566db59..ea198d8 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);

From: Stephen Warren swarren@nvidia.com
A negative value of CONFIG_ENV_OFFSET is treated as a backwards offset from the end of the eMMC device/partition, rather than a forwards offset from the start.
This is useful when a single board may be stuffed with different eMMC devices, each of which has a different capacity, and you always want the environment to be stored at the very end of the device (or eMMC boot partition for example).
One example of this case is NVIDIA's Ventana reference board.
Signed-off-by: Stephen Warren swarren@nvidia.com --- v3: No change. v2: Also update README to describe the change. --- README | 11 +++++++++++ common/env_mmc.c | 12 ++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/README b/README index e7fedb8..56d5e91 100644 --- a/README +++ b/README @@ -3627,6 +3627,14 @@ but it can not erase, write this NOR flash by SRIO or PCIE interface. 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.
@@ -3637,6 +3645,9 @@ but it can not erase, write this NOR flash by SRIO or PCIE interface. 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.
diff --git a/common/env_mmc.c b/common/env_mmc.c index 9ca098f..5d3a769 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; }

From: Stephen Warren swarren@nvidia.com
Use a negative value of CONFIG_ENV_OFFSET for all NVIDIA reference boards that store the U-Boot environment in the 2nd eMMC boot partition. This makes U-Boot agnostic to the size of the eMMC boot partition, which can vary depending on which eMMC device was actually stuffed into the board.
Signed-off-by: Stephen Warren swarren@nvidia.com --- v3: No change. v2: No change. --- include/configs/beaver.h | 2 +- include/configs/cardhu.h | 2 +- include/configs/dalmore.h | 2 +- include/configs/paz00.h | 2 +- include/configs/seaboard.h | 2 +- include/configs/ventana.h | 2 +- include/configs/whistler.h | 4 ++-- 7 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/include/configs/beaver.h b/include/configs/beaver.h index 058da4f..d51f5f8 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 fd46083..142d20b 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 2723843..b6e0161 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 eac1ef9..9e2686a 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 f66173e..f0da1fc 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 5755f11..41a7176 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 9542c7e..994edec 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

"S" == Stephen Warren swarren@wwwdotorg.org writes:
S> From: Stephen Warren swarren@nvidia.com S> Describe the meaning of CONFIG_ENV_IS_IN_MMC, and all related defines that S> must or can be set when using that option.
S> Signed-off-by: Stephen Warren swarren@nvidia.com S> --- S> v3: S> * Mention that env size/offset are in bytes. S> * Fix typo; s/CONFIG_ENV_OFFSET/CONFIG_ENV_SIZE/ in one place. S> v2: New patch. S> --- S> README | 40 ++++++++++++++++++++++++++++++++++++++++ S> 1 file changed, 40 insertions(+)
S> diff --git a/README b/README S> index 3012dcd..e7fedb8 100644 S> --- a/README S> +++ b/README S> @@ -3606,6 +3606,46 @@ but it can not erase, write this NOR flash by SRIO or PCIE interface. S> You will probably want to define these to avoid a really noisy system S> when storing the env in UBI.
S> +- CONFIG_ENV_IS_IN_MMC: S> + S> + Define this if you have an MMC device which you want to use for the S> + environment. S> + S> + - CONFIG_SYS_MMC_ENV_DEV: S> + S> + Specifies which MMC device the environment is stored in. S> + S> + - CONFIG_SYS_MMC_ENV_PART (optional): S> + S> + Specifies which MMC partition the environment is stored in. If not S> + set, defaults to partition 0, the user area. Common values might be S> + 1 (first MMC boot partition), 2 (second MMC boot partition). S> + S> + - CONFIG_ENV_OFFSET: S> + - CONFIG_ENV_SIZE: S> + S> + These two #defines specify the offset and size of the environment S> + area within the specified MMC device. S> + S> + These two values are in units of bytes, but must be aligned to an S> + MMC sector boundary.
s/to an/t a/
Other than that:
Reviewed-by: Peter Korsgaard jacmet@sunsite.dk

On 05/23/2013 03:59 PM, Peter Korsgaard wrote:
"S" == Stephen Warren swarren@wwwdotorg.org writes:
...
S> + These two values are in units of bytes, but must be aligned to an S> + MMC sector boundary.
s/to an/to a/
http://owl.english.purdue.edu/owl/resource/540/1/ disagrees since the M starts with a vowel sound. See the "An MSDS ..." example.
Either way though is fine by me though I guess.
I assume Tom can fix that up when applying, so I don't need to spam the list with another resend.

"Stephen" == Stephen Warren swarren@wwwdotorg.org writes:
Stephen> On 05/23/2013 03:59 PM, Peter Korsgaard wrote:
> "S" == Stephen Warren swarren@wwwdotorg.org writes:
Stephen> ... S> + These two values are in units of bytes, but must be aligned to an S> + MMC sector boundary.
s/to an/to a/
Stephen> http://owl.english.purdue.edu/owl/resource/540/1/ disagrees Stephen> since the M starts with a vowel sound. See the "An MSDS ..." Stephen> example.
Ok, I'm not a native speaker.

On Thu, May 23, 2013 at 02:51:44PM -0600, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
Describe the meaning of CONFIG_ENV_IS_IN_MMC, and all related defines that must or can be set when using that option.
Signed-off-by: Stephen Warren swarren@nvidia.com
Acked-by: Tom Rini trini@ti.com

On 05/24/2013 09:24 AM, Tom Rini wrote:
On Thu, May 23, 2013 at 02:51:44PM -0600, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
Describe the meaning of CONFIG_ENV_IS_IN_MMC, and all related defines that must or can be set when using that option.
Signed-off-by: Stephen Warren swarren@nvidia.com
Acked-by: Tom Rini trini@ti.com
TomR, I assume you want Andy Fleming to take this series through the MMC tree?
TomW, if patch 4/4 is OK with you, can you ack it so that someone else can take it, or do you want them to apply patches 1-3, wait until you can pick them up in the Tegra tree, and then apply patch 4 yourself?

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 05/24/2013 11:47 AM, Stephen Warren wrote:
On 05/24/2013 09:24 AM, Tom Rini wrote:
On Thu, May 23, 2013 at 02:51:44PM -0600, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
Describe the meaning of CONFIG_ENV_IS_IN_MMC, and all related defines that must or can be set when using that option.
Signed-off-by: Stephen Warren swarren@nvidia.com
Acked-by: Tom Rini trini@ti.com
TomR, I assume you want Andy Fleming to take this series through the MMC tree?
TomW, if patch 4/4 is OK with you, can you ack it so that someone else can take it, or do you want them to apply patches 1-3, wait until you can pick them up in the Tegra tree, and then apply patch 4 yourself?
Correct, and I've given these to Andy in patchwork as well. Thanks!
- -- Tom

Having to synchronize between repos is messy & error-prone.
Andy can take 'em all in to the MMC tree.
Patch 4/4: Acked-by: Tom Warren twarren@nvidia.com
-----Original Message----- From: Stephen Warren [mailto:swarren@wwwdotorg.org] Sent: Friday, May 24, 2013 8:48 AM To: Tom Rini; Tom Warren Cc: u-boot@lists.denx.de; Stephen Warren; Andy Fleming Subject: Re: [U-Boot] [PATCH V3 1/4] README: document CONFIG_ENV_IS_IN_MMC
On 05/24/2013 09:24 AM, Tom Rini wrote:
On Thu, May 23, 2013 at 02:51:44PM -0600, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
Describe the meaning of CONFIG_ENV_IS_IN_MMC, and all related
defines
that must or can be set when using that option.
Signed-off-by: Stephen Warren swarren@nvidia.com
Acked-by: Tom Rini trini@ti.com
TomR, I assume you want Andy Fleming to take this series through the MMC tree?
TomW, if patch 4/4 is OK with you, can you ack it so that someone else can take it, or do you want them to apply patches 1-3, wait until you can pick them up in the Tegra tree, and then apply patch 4 yourself?
-- nvpublic

On 05/23/2013 02:51 PM, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
Describe the meaning of CONFIG_ENV_IS_IN_MMC, and all related defines that must or can be set when using that option.
Andy, do you intend to take these patches for the upcoming release, or defer them until the next one? Thanks.

I'll take them. It's on my todo list for this week
On Jun 4, 2013, at 14:31, "Stephen Warren" swarren@wwwdotorg.org wrote:
On 05/23/2013 02:51 PM, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
Describe the meaning of CONFIG_ENV_IS_IN_MMC, and all related defines that must or can be set when using that option.
Andy, do you intend to take these patches for the upcoming release, or defer them until the next one? Thanks.
participants (5)
-
Fleming Andy-AFLEMING
-
Peter Korsgaard
-
Stephen Warren
-
Tom Rini
-
Tom Warren