[U-Boot] [PATCH 1/3] mmc: report capacity for the selected partition

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 --- 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 f65a7b0..abeff35 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -678,16 +678,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) @@ -895,7 +928,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; @@ -1013,8 +1046,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 > 512) mmc->read_bl_len = 512; @@ -1053,7 +1090,7 @@ static int mmc_startup(struct mmc *mmc) | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; capacity *= 512; if ((capacity >> 20) > 2 * 1024) - mmc->capacity = capacity; + mmc->capacity_user = capacity; }
switch (ext_csd[EXT_CSD_REV]) { @@ -1094,8 +1131,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 f0d4820..cb3f0aa 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -157,7 +157,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 */ @@ -165,6 +167,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 */
@@ -259,6 +262,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 --- common/env_mmc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/common/env_mmc.c b/common/env_mmc.c index 02bd5ae..4448085 100644 --- a/common/env_mmc.c +++ b/common/env_mmc.c @@ -48,7 +48,11 @@ DECLARE_GLOBAL_DATA_PTR;
__weak int mmc_get_env_addr(struct mmc *mmc, u32 *env_addr) { - *env_addr = CONFIG_ENV_OFFSET; + if (CONFIG_ENV_OFFSET < 0) + *env_addr = mmc->capacity + CONFIG_ENV_OFFSET; + else + *env_addr = CONFIG_ENV_OFFSET; + return 0; }

On Tue, May 21, 2013 at 02:25:20PM -0600, Stephen Warren wrote:
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
NAK because you aren't also covering CONFIG_ENV_OFFSET_REDUND and you need to update the README as it says ENV_OFFFSET is from the beginning not end.

On 05/22/2013 09:46 AM, Tom Rini wrote:
On Tue, May 21, 2013 at 02:25:20PM -0600, Stephen Warren wrote:
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
NAK because you aren't also covering CONFIG_ENV_OFFSET_REDUND and you need to update the README as it says ENV_OFFFSET is from the beginning not end.
env_mmc.c doesn't implement ENV_OFFSET_REDUND, and ENV_IS_IN_MMC isn't documented in the README (other config options like ENV_OFFSET are all documented relative to the ENV_IS_IN_xxx that defines their semantics in the README right now).
Are you saying you want me to fix those issues before this series will be accepted? I have no way to test ENV_OFFSET_REDUND, so I really wouldn't want to implement that for MMC, although I guess that I could add the ENV_IS_IN_MMC section to the README if you need.

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 05/22/2013 12:00 PM, Stephen Warren wrote:
On 05/22/2013 09:46 AM, Tom Rini wrote:
On Tue, May 21, 2013 at 02:25:20PM -0600, Stephen Warren wrote:
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
NAK because you aren't also covering CONFIG_ENV_OFFSET_REDUND and you need to update the README as it says ENV_OFFFSET is from the beginning not end.
env_mmc.c doesn't implement ENV_OFFSET_REDUND, and ENV_IS_IN_MMC isn't documented in the README (other config options like ENV_OFFSET are all documented relative to the ENV_IS_IN_xxx that defines their semantics in the README right now).
Are you saying you want me to fix those issues before this series will be accepted? I have no way to test ENV_OFFSET_REDUND, so I really wouldn't want to implement that for MMC, although I guess that I could add the ENV_IS_IN_MMC section to the README if you need.
CONFIG_ENV_OFFSET_REDUND is already there, but possibly not in the tegra tree yet? And yes, if you can write up the ENV_IS_IN_MMC section that slipped by before, I'd appreciate it. And you have no where to grab another 8KiB from? :(
- -- Tom

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 --- 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
participants (2)
-
Stephen Warren
-
Tom Rini