From patchwork Sat Feb 12 18:06:26 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Remy Bohmer X-Patchwork-Id: 82940 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 662B8B7126 for ; Sun, 13 Feb 2011 05:06:42 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id E2D092819B; Sat, 12 Feb 2011 19:06:39 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id J493KvSe8QfH; Sat, 12 Feb 2011 19:06:39 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 189DA28186; Sat, 12 Feb 2011 19:06:38 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 2256728186 for ; Sat, 12 Feb 2011 19:06:35 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id J8EqrtSU8cvk for ; Sat, 12 Feb 2011 19:06:33 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-ey0-f172.google.com (mail-ey0-f172.google.com [209.85.215.172]) by theia.denx.de (Postfix) with ESMTPS id 0978728167 for ; Sat, 12 Feb 2011 19:06:31 +0100 (CET) Received: by eyd10 with SMTP id 10so1953061eyd.3 for ; Sat, 12 Feb 2011 10:06:31 -0800 (PST) Received: by 10.213.28.12 with SMTP id k12mr1924565ebc.84.1297533990906; Sat, 12 Feb 2011 10:06:30 -0800 (PST) Received: from localhost (541EDD7F.cm-5-7d.dynamic.ziggo.nl [84.30.221.127]) by mx.google.com with ESMTPS id q52sm679975eei.15.2011.02.12.10.06.29 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 12 Feb 2011 10:06:30 -0800 (PST) From: Remy Bohmer To: u-boot@lists.denx.de Date: Sat, 12 Feb 2011 19:06:26 +0100 Message-Id: <1297533986-13294-1-git-send-email-linux@bohmer.net> X-Mailer: git-send-email 1.7.1 Subject: [U-Boot] [PATCH] Add support for dataflash to U-boot environment settings tool. X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de * The sector size for SPI-dataflash (like AT45 flashes) are not always a power-of-2. So, the sector calculations are rewritten such that it works for either power-of-2 as any size sectors. * Make the flash sector size optional in case it is the same value as the environment size. Signed-off-by: Remy Bohmer --- tools/env/fw_env.c | 72 ++++++++++++++++++++++++++++++---------------- tools/env/fw_env.config | 10 ++++++- tools/env/fw_env.h | 2 - 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 8ff7052..e0f46bc 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -674,11 +674,7 @@ static int flash_read_buf (int dev, int fd, void *buf, size_t count, MEMGETBADBLOCK needs 64 bits */ int rc; - /* - * Start of the first block to be read, relies on the fact, that - * erase sector size is always a power of 2 - */ - blockstart = offset & ~(DEVESIZE (dev) - 1); + blockstart = (offset / DEVESIZE (dev)) * DEVESIZE (dev); /* Offset inside a block */ block_seek = offset - blockstart; @@ -694,8 +690,8 @@ static int flash_read_buf (int dev, int fd, void *buf, size_t count, * To calculate the top of the range, we have to use the * global DEVOFFSET (dev), which can be different from offset */ - top_of_range = (DEVOFFSET (dev) & ~(blocklen - 1)) + - ENVSECTORS (dev) * blocklen; + top_of_range = ((DEVOFFSET(dev) / blocklen) + + ENVSECTORS (dev)) * blocklen; /* Limit to one block for the first read */ if (readlen > blocklen - block_seek) @@ -749,9 +745,9 @@ static int flash_read_buf (int dev, int fd, void *buf, size_t count, } /* - * Write count bytes at offset, but stay within ENVSETCORS (dev) sectors of - * DEVOFFSET (dev). Similar to the read case above, on NOR we erase and write - * the whole data at once. + * Write count bytes at offset, but stay within ENVSECTORS (dev) sectors of + * DEVOFFSET (dev). Similar to the read case above, on NOR and dataflash we + * erase and write the whole data at once. */ static int flash_write_buf (int dev, int fd, void *buf, size_t count, off_t offset, uint8_t mtd_type) @@ -764,7 +760,7 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, size_t erasesize; /* erase / write length - one block on NAND, whole area on NOR */ size_t processed = 0; /* progress counter */ - size_t write_total; /* total size to actually write - excludinig + size_t write_total; /* total size to actually write - excluding bad blocks */ off_t erase_offset; /* offset to the first erase block (aligned) below offset */ @@ -777,11 +773,10 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, blocklen = DEVESIZE (dev); - /* Erase sector size is always a power of 2 */ - top_of_range = (DEVOFFSET (dev) & ~(blocklen - 1)) + - ENVSECTORS (dev) * blocklen; + top_of_range = ((DEVOFFSET(dev) / blocklen) + + ENVSECTORS (dev)) * blocklen; - erase_offset = offset & ~(blocklen - 1); + erase_offset = (offset / blocklen) * blocklen; /* Maximum area we may use */ erase_len = top_of_range - erase_offset; @@ -795,7 +790,8 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, * 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 - 1); + write_total = ((block_seek + count + blocklen - 1) / + blocklen) * blocklen; /* * Support data anywhere within erase sectors: read out the complete @@ -838,7 +834,7 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, erase.length = erasesize; - /* This only runs once on NOR flash */ + /* This only runs once on NOR flash and SPI-dataflash */ while (processed < write_total) { rc = flash_bad_block (fd, mtd_type, &blockstart); if (rc < 0) /* block test failed */ @@ -857,12 +853,14 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, erase.start = blockstart; ioctl (fd, MEMUNLOCK, &erase); - if (ioctl (fd, MEMERASE, &erase) != 0) { - fprintf (stderr, "MTD erase error on %s: %s\n", - DEVNAME (dev), - strerror (errno)); - return -1; - } + /* Dataflash does 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, @@ -973,7 +971,9 @@ static int flash_read (int fd) return -1; } - if (mtdinfo.type != MTD_NORFLASH && mtdinfo.type != MTD_NANDFLASH) { + if (mtdinfo.type != MTD_NORFLASH && + mtdinfo.type != MTD_NANDFLASH && + mtdinfo.type != MTD_DATAFLASH) { fprintf (stderr, "Unsupported flash type %u\n", mtdinfo.type); return -1; } @@ -1143,6 +1143,9 @@ int fw_env_open(void) } else if (DEVTYPE(dev_current) == MTD_NANDFLASH && DEVTYPE(!dev_current) == MTD_NANDFLASH) { environment.flag_scheme = FLAG_INCREMENTAL; + } else if (DEVTYPE(dev_current) == MTD_DATAFLASH && + DEVTYPE(!dev_current) == MTD_DATAFLASH) { + environment.flag_scheme = FLAG_BOOLEAN; } else { fprintf (stderr, "Incompatible flash types!\n"); return -1; @@ -1234,14 +1237,29 @@ static int parse_config () strcpy (DEVNAME (0), DEVICE1_NAME); DEVOFFSET (0) = DEVICE1_OFFSET; ENVSIZE (0) = ENV1_SIZE; + /* Default values are: erase-size=env-size, #sectors=1 */ + DEVESIZE (0) = ENVSIZE (0); + ENVSECTORS (0) = 1; +#ifdef DEVICE1_ESIZE DEVESIZE (0) = DEVICE1_ESIZE; +#endif +#ifdef DEVICE1_ENVSECTORS ENVSECTORS (0) = DEVICE1_ENVSECTORS; +#endif + #ifdef HAVE_REDUND strcpy (DEVNAME (1), DEVICE2_NAME); DEVOFFSET (1) = DEVICE2_OFFSET; ENVSIZE (1) = ENV2_SIZE; + /* Default values are: erase-size=env-size, #sectors=1 */ + DEVESIZE (1) = ENVSIZE (1); + ENVSECTORS (1) = 1; +#ifdef DEVICE2_ESIZE DEVESIZE (1) = DEVICE2_ESIZE; +#endif +#ifdef DEVICE2_ENVSECTORS ENVSECTORS (1) = DEVICE2_ENVSECTORS; +#endif HaveRedundEnv = 1; #endif #endif @@ -1285,9 +1303,13 @@ static int get_config (char *fname) &DEVESIZE (i), &ENVSECTORS (i)); - if (rc < 4) + if (rc < 3) continue; + if (rc < 4) + /* Assume the erase size is the same as the env-size */ + DEVESIZE(i) = ENVSIZE(i); + if (rc < 5) /* Default - 1 sector */ ENVSECTORS (i) = 1; diff --git a/tools/env/fw_env.config b/tools/env/fw_env.config index c8f12cf..8e21d5a 100644 --- a/tools/env/fw_env.config +++ b/tools/env/fw_env.config @@ -1,11 +1,19 @@ # Configuration file for fw_(printenv/saveenv) utility. # Up to two entries are valid, in this case the redundant # environment sector is assumed present. -# Notice, that the "Number of sectors" is ignored on NOR. +# Notice, that the "Number of sectors" is ignored on NOR and SPI-dataflash. +# Futhermore, if the Flash sector size is ommitted, this value is assumed to +# be the same as the Environment size, which is valid for NOR and SPI-dataflash +# NOR example # MTD device name Device offset Env. size Flash sector size Number of sectors /dev/mtd1 0x0000 0x4000 0x4000 /dev/mtd2 0x0000 0x4000 0x4000 +# MTD SPI-dataflash example +# MTD device name Device offset Env. size Flash sector size Number of sectors +#/dev/mtd5 0x4200 0x4200 +#/dev/mtd6 0x4200 0x4200 + # NAND example #/dev/mtd0 0x4000 0x4000 0x20000 2 diff --git a/tools/env/fw_env.h b/tools/env/fw_env.h index 8130fa1..c83d608 100644 --- a/tools/env/fw_env.h +++ b/tools/env/fw_env.h @@ -34,10 +34,8 @@ #define DEVICE2_NAME "/dev/mtd2" #define DEVICE1_OFFSET 0x0000 #define ENV1_SIZE 0x4000 -#define DEVICE1_ESIZE 0x4000 #define DEVICE2_OFFSET 0x0000 #define ENV2_SIZE 0x4000 -#define DEVICE2_ESIZE 0x4000 #define CONFIG_BAUDRATE 115200 #define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */