[U-Boot] [PATCH 1/2] mmc: Fix calculation of capacity for hc cards
When using a high capacity card with a density less than 2 GB a wrong size is calculated. According to JEDEC 4.41 there is no differentiation for C_SIZE register between low and high capacity cards. Use ext_csd sector count to calculate capacity instead. Signed-off-by: Oliver Metz --- drivers/mmc/mmc.c | 20 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 84dae4d..ff11ff9 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -884,15 +884,9 @@ static int mmc_startup(struct mmc *mmc) else mmc->write_bl_len = 1 << ((cmd.response[3] >> 22) & 0xf); - if (mmc->high_capacity) { - csize = (mmc->csd[1] & 0x3f) << 16 - | (mmc->csd[2] & 0x) >> 16; - cmult = 8; - } else { - csize = (mmc->csd[1] & 0x3ff) << 2 - | (mmc->csd[2] & 0xc000) >> 30; - cmult = (mmc->csd[2] & 0x00038000) >> 15; - } + csize = (mmc->csd[1] & 0x3ff) << 2 + | (mmc->csd[2] & 0xc000) >> 30; + cmult = (mmc->csd[2] & 0x00038000) >> 15; mmc->capacity_user = (csize + 1) << (cmult + 2); mmc->capacity_user *= mmc->read_bl_len; @@ -927,18 +921,12 @@ static int mmc_startup(struct mmc *mmc) /* check ext_csd version and capacity */ err = mmc_send_ext_csd(mmc, ext_csd); if (!err && (ext_csd[EXT_CSD_REV] >= 2)) { - /* -* According to the JEDEC Standard, the value of -* ext_csd's capacity is valid if the value is more -* than 2GB -*/ capacity = ext_csd[EXT_CSD_SEC_CNT] << 0 | ext_csd[EXT_CSD_SEC_CNT + 1] << 8 | ext_csd[EXT_CSD_SEC_CNT + 2] << 16 | ext_csd[EXT_CSD_SEC_CNT + 3] << 24; capacity *= MMC_MAX_BLOCK_LEN; - if ((capacity >> 20) > 2 * 1024) - mmc->capacity_user = capacity; + mmc->capacity_user = capacity; } switch (ext_csd[EXT_CSD_REV]) { -- 1.8.4 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 2/2] mmc: Fix erase_grp_size for partitioned card
EXT_CSD_ERASE_GROUP_DEF is lost every time after a reset or power off. Set it if device has enhanced partitions. Signed-off-by: Oliver Metz --- drivers/mmc/mmc.c | 17 + include/mmc.h | 2 ++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index ff11ff9..17c6b11 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -948,15 +948,24 @@ static int mmc_startup(struct mmc *mmc) } /* -* Check whether GROUP_DEF is set, if yes, read out -* group size from ext_csd directly, or calculate -* the group size from the csd value. +* Host needs to enable ERASE_GRP_DEF bit if device is +* partitioned. This bit will be lost every time after a reset +* or power off. This will affect erase size. */ - if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) { + if ((ext_csd[EXT_CSD_PARTITIONING_SUPPORT] & PART_SUPPORT) && + (ext_csd[EXT_CSD_PARTITIONS_ATTRIBUTE] & PART_ENH_ATTRIB)) { + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_ERASE_GROUP_DEF, 1); + + if (err) + return err; + + /* Read out group size from ext_csd */ mmc->erase_grp_size = ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * MMC_MAX_BLOCK_LEN * 1024; } else { + /* Calculate the group size from the csd value. */ int erase_gsz, erase_gmul; erase_gsz = (mmc->csd[2] & 0x7c00) >> 10; erase_gmul = (mmc->csd[2] & 0x03e0) >> 5; diff --git a/include/mmc.h b/include/mmc.h index 214b9ed..cb558da 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -148,6 +148,7 @@ * EXT_CSD fields */ #define EXT_CSD_GP_SIZE_MULT 143 /* R/W */ +#define EXT_CSD_PARTITIONS_ATTRIBUTE 156 /* R/W */ #define EXT_CSD_PARTITIONING_SUPPORT 160 /* RO */ #define EXT_CSD_RPMB_MULT 168 /* RO */ #define EXT_CSD_ERASE_GROUP_DEF175 /* R/W */ @@ -210,6 +211,7 @@ #define MMCPART_NOAVAILABLE(0xff) #define PART_ACCESS_MASK (0x7) #define PART_SUPPORT (0x1) +#define PART_ENH_ATTRIB(0x1f) /* Maximum block size for MMC */ #define MMC_MAX_BLOCK_LEN 512 -- 1.8.4 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 0/2] mmc: Fix capacity calculation and erase_group_size
These patches are addressing two issues that I had after activating enhanced user area feature for a 4GB card so the capacity was less than 2 GB afterwards. 1. The capacity for a high density device is calculated in a wrong way. I was not able to find any hints for this implementation in JEDEC 4.41. Anyhow, if we have ext_csd revision >= 2 we can use SEC_COUNT field to calculate the size. 2. If we have a partitioned device, e.g. enhanced user area, the ERASE_GROUP_DEF bit in ext_csd shall be set (see JEDEC 4.41, chapter 7.2.3 Configure partitions). This bit defaults to "0" on power on. Oliver Metz (2): When using a high capacity card with a density less than 2 GB a wrong size is shown. According to JEDEC 4.41 there is no differentiation for C_SIZE register between low and high capacity cards EXT_CSD_ERASE_GROUP_DEF is lost every time after a reset or reboot. Set it if device has enhanced partitions. drivers/mmc/mmc.c | 49 +++-- include/mmc.h | 2 ++ 2 files changed, 25 insertions(+), 26 deletions(-) -- 1.8.4 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH] net: fec: Avoid MX28 bus sync issue
Dear Fabio, >Hi Robert and Hector, > >On Fri, Sep 13, 2013 at 2:46 PM, Wolfgang Denk <[hidden email]> wrote: > >> That's ALLOC_CACHE_ALIGN_BUFFER. Thanks. > >Could you please let us know wthether the change below fix the problem? > >Thanks, > >Fabio Estevam > >--- a/drivers/net/fec_mxc.c >+++ b/drivers/net/fec_mxc.c >@@ -794,7 +794,7 @@ static int fec_recv(struct eth_device *dev) >uint16_t bd_status; >uint32_t addr, size, end; >int i; >- uchar buff[FEC_MAX_PKT_SIZE] __aligned(ARCH_DMA_MINALIGN); >+ ALLOC_CACHE_ALIGN_BUFFER(uchar, buff, FEC_MAX_PKT_SIZE); > >/* > * Check if any critical events have happened I can confirm that this patch fixes the issue for me on the mx28 board. Before the patch transmitting a linux kernel archive failed many times. With the patch applied the file was transfered successfully with the first try. Used gcc version: gcc version 4.5.4 20110808 (prerelease) (Linaro GCC 4.5-2011.08) Regards Oliver ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
Re: [U-Boot] [PATCH 1/2] fw_env: add redundand env support for MTD_ABSENT
Robert P. J. Day schrieb am 26.08.2013 16:25: > On Sun, 25 Aug 2013, Oliver Metz wrote: > >> Signed-off-by: Oliver Metz >> --- >> tools/env/fw_env.c | 3 +++ >> 1 file changed, 3 insertions(+) >> >> diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c >> index 44607b1..65be5f3 100644 >> --- a/tools/env/fw_env.c >> +++ b/tools/env/fw_env.c >> @@ -1136,6 +1136,9 @@ int fw_env_open(void) >> } else if (DEVTYPE(dev_current) == MTD_UBIVOLUME && >> DEVTYPE(!dev_current) == MTD_UBIVOLUME) { >> environment.flag_scheme = FLAG_INCREMENTAL; >> +} else if (DEVTYPE(dev_current) == MTD_ABSENT && >> + DEVTYPE(!dev_current) == MTD_ABSENT) { >> +environment.flag_scheme = FLAG_INCREMENTAL; >> } else { >> fprintf (stderr, "Incompatible flash types!\n"); >> return -1; > > pedantically, it's "redundant", not "redundand". and it might be > useful to add some commentary in the sample fw_env.config file that > explains this new feature, as the patch is clearly not adding any > documentation. > > rday > I will send a new version of the patches with the typo fixed. But I'm unsure how to comment the changes in fw_env.config since redundant env description is already in the comment at the top. Is something like this enough? diff --git a/tools/env/fw_env.config b/tools/env/fw_env.config index 90e499d..fcaab55 100644 --- a/tools/env/fw_env.config +++ b/tools/env/fw_env.config @@ -20,3 +20,4 @@ # Block device example #/dev/mmcblk0 0xc 0x2 +#/dev/mmcblk0 0xe 0x2 -- Oliver ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 1/2] fw_env: add redundand env support for MTD_ABSENT
Signed-off-by: Oliver Metz --- tools/env/fw_env.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 44607b1..65be5f3 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -1136,6 +1136,9 @@ int fw_env_open(void) } else if (DEVTYPE(dev_current) == MTD_UBIVOLUME && DEVTYPE(!dev_current) == MTD_UBIVOLUME) { environment.flag_scheme = FLAG_INCREMENTAL; + } else if (DEVTYPE(dev_current) == MTD_ABSENT && + DEVTYPE(!dev_current) == MTD_ABSENT) { + environment.flag_scheme = FLAG_INCREMENTAL; } else { fprintf (stderr, "Incompatible flash types!\n"); return -1; -- 1.8.3.4 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 2/2] fw_env: fix writing environment for mtd devices
Signed-off-by: Oliver Metz --- tools/env/fw_env.c | 71 -- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 65be5f3..7454676 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -727,27 +727,39 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, MEMGETBADBLOCK needs 64 bits */ int rc; - blocklen = DEVESIZE (dev); + /* +* For mtd devices only offset and size of the environment do matter +*/ + if (mtd_type == MTD_ABSENT) { + blocklen = count; + top_of_range = offset + count; + erase_len = blocklen; + blockstart = offset; + block_seek = 0; + write_total = blocklen; + } else { + blocklen = DEVESIZE (dev); - top_of_range = ((DEVOFFSET(dev) / blocklen) + - ENVSECTORS (dev)) * blocklen; + top_of_range = ((DEVOFFSET(dev) / blocklen) + + ENVSECTORS (dev)) * blocklen; - erase_offset = (offset / blocklen) * blocklen; + erase_offset = (offset / blocklen) * blocklen; - /* Maximum area we may use */ - erase_len = top_of_range - erase_offset; + /* Maximum area we may use */ + erase_len = top_of_range - erase_offset; - blockstart = erase_offset; - /* Offset inside a block */ - block_seek = offset - erase_offset; + blockstart = erase_offset; + /* Offset inside a block */ + block_seek = offset - erase_offset; - /* -* Data size we actually have to write: from the start of the block -* to the start of the data, then count bytes of data, and to the -* end of the block -*/ - write_total = ((block_seek + count + blocklen - 1) / - blocklen) * blocklen; + /* +* Data size we actually write: from the start of the block +* to the start of the data, then count bytes of data, and to the +* end of the block +*/ + write_total = ((block_seek + count + blocklen - 1) / + blocklen) * blocklen; + } /* * Support data anywhere within erase sectors: read out the complete @@ -818,17 +830,18 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, continue; } - erase.start = blockstart; - ioctl (fd, MEMUNLOCK, &erase); - /* These do not need an explicit erase cycle */ - if (mtd_type != MTD_ABSENT && - mtd_type != MTD_DATAFLASH) - if (ioctl (fd, MEMERASE, &erase) != 0) { - fprintf (stderr, "MTD erase error on %s: %s\n", -DEVNAME (dev), -strerror (errno)); - return -1; - } + if (mtd_type != MTD_ABSENT) { + erase.start = blockstart; + ioctl (fd, MEMUNLOCK, &erase); + /* These do not need an explicit erase cycle */ + if (mtd_type != MTD_DATAFLASH) + if (ioctl (fd, MEMERASE, &erase) != 0) { + fprintf (stderr, "MTD erase error on %s: %s\n", +DEVNAME (dev), +strerror (errno)); + return -1; + } + } if (lseek (fd, blockstart, SEEK_SET) == -1) { fprintf (stderr, @@ -846,8 +859,8 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, DEVNAME (dev), strerror (errno)); return -1; } - - ioctl (fd, MEMLOCK, &erase); + if (mtd_type != MTD_ABSENT) + ioctl (fd, MEMLOCK, &erase); processed += blocklen; block_seek = 0; -- 1.8.3.4 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot