From: Kyungmin Park Date: Tue, 12 Jan 2010 09:15:00 +0000 (+0900) Subject: Merge branch 'master' of http://git.denx.de/u-boot X-Git-Tag: JA03_20100114~18 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a934fa4459c976888ceeb187a198e865eebb9e12;p=kernel%2Fu-boot.git Merge branch 'master' of http://git.denx.de/u-boot Conflicts: common/env_onenand.c drivers/mtd/onenand/onenand_base.c include/linux/mtd/onenand_regs.h Signed-off-by: Kyungmin Park --- a934fa4459c976888ceeb187a198e865eebb9e12 diff --cc common/Makefile index ab5eb00,7784180..ad9b1e7 --- a/common/Makefile +++ b/common/Makefile @@@ -86,8 -89,8 +89,9 @@@ COBJS-$(CONFIG_CMD_ECHO) += cmd_echo. COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += cmd_eeprom.o COBJS-$(CONFIG_CMD_EEPROM) += cmd_eeprom.o COBJS-$(CONFIG_CMD_ELF) += cmd_elf.o + COBJS-$(CONFIG_SYS_HUSH_PARSER) += cmd_exit.o COBJS-$(CONFIG_CMD_EXT2) += cmd_ext2.o +COBJS-$(CONFIG_CMD_ONENAND_EXT2) += cmd_onenand_ext2.o COBJS-$(CONFIG_CMD_FAT) += cmd_fat.o COBJS-$(CONFIG_CMD_FDC)$(CONFIG_CMD_FDOS) += cmd_fdc.o COBJS-$(CONFIG_OF_LIBFDT) += cmd_fdt.o fdt_support.o diff --cc common/env_onenand.c index 0250aa6,23d2caa..ce243cf --- a/common/env_onenand.c +++ b/common/env_onenand.c @@@ -53,6 -52,6 +53,13 @@@ env_t *env_ptr = (env_t *) onenand_env DECLARE_GLOBAL_DATA_PTR; ++#ifndef CONFIG_ENV_ADDR_FLEX ++#define CONFIG_ENV_ADDR_FLEX CONFIG_ENV_ADDR ++#endif ++#ifndef CONFIG_ENV_SIZE_FLEX ++#define CONFIG_ENV_SIZE_FLEX CONFIG_ENV_SIZE ++#endif ++ uchar env_get_char_spec(int index) { return (*((uchar *) (gd->env_addr + index))); @@@ -96,14 -99,15 +107,20 @@@ int saveenv(void struct erase_info instr = { .callback = NULL, }; - size_t retlen; + size_t retlen, len; + + len = CONFIG_ENV_SIZE; + + if (len < mtd->erasesize) + len = ALIGN(len, mtd->erasesize); - instr.len = CONFIG_ENV_SIZE; + instr.len = len; + if (FLEXONENAND(this)) { + env_addr = CONFIG_ENV_ADDR_FLEX; + instr.len = CONFIG_ENV_SIZE_FLEX; + instr.len <<= onenand_mtd.eraseregions[0].numblocks == 1 ? + 1 : 0; + } instr.addr = env_addr; instr.mtd = mtd; if (mtd->erase(mtd, &instr)) { diff --cc cpu/arm_cortexa8/s5pc1xx/timer.c index dc4a2ce,c5df5c5..297e69a --- a/cpu/arm_cortexa8/s5pc1xx/timer.c +++ b/cpu/arm_cortexa8/s5pc1xx/timer.c @@@ -121,9 -115,9 +121,9 @@@ void set_timer(unsigned long t } /* delay x useconds */ - void udelay(unsigned long usec) + void __udelay(unsigned long usec) { - unsigned long tmo, tmp; + unsigned long tmo, tmp, now, until; if (usec >= 1000) { /* diff --cc drivers/mtd/onenand/onenand_base.c index e53bb0f,f9273ab..da0858e --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@@ -23,10 -28,8 +28,10 @@@ #include #include +extern void *memcpy32(void *dst, const void *src, int len); + /* It should access 16-bit instead of 8-bit */ - static inline void *memcpy_16(void *dst, const void *src, unsigned int len) + static void *memcpy_16(void *dst, const void *src, unsigned int len) { void *ret = dst; short *d = dst; @@@ -299,10 -392,10 +396,11 @@@ static int onenand_command(struct mtd_i int dataram; switch (cmd) { + case FLEXONENAND_CMD_RECOVER_LSB: case ONENAND_CMD_READ: case ONENAND_CMD_READOOB: - if (ONENAND_IS_MLC(this)) + if (ONENAND_IS_4KB_PAGE(this)) + /* It is always BufferRAM0 */ dataram = ONENAND_SET_BUFFERRAM0(this); else dataram = ONENAND_SET_NEXT_BUFFERRAM(this); @@@ -337,8 -431,21 +435,21 @@@ */ static int onenand_read_ecc(struct onenand_chip *this) { - /* TODO Handle 4bit ecc */ - return this->read_word(this->base + ONENAND_REG_ECC_STATUS); + int ecc, i; + - if (!FLEXONENAND(this)) ++ if (!ONENAND_IS_4KB_PAGE(this)) + return this->read_word(this->base + ONENAND_REG_ECC_STATUS); + + for (i = 0; i < 4; i++) { + ecc = this->read_word(this->base + + ((ONENAND_REG_ECC_STATUS + i) << 1)); + if (likely(!ecc)) + continue; + if (ecc & FLEXONENAND_UNCORRECTABLE_ERROR) + return ONENAND_ECC_2BIT_ALL; + } + + return 0; } /** @@@ -697,8 -874,11 +844,10 @@@ static int onenand_read_ops_nolock(stru /* Do first load to bufferRAM */ if (read < len) { if (!onenand_check_bufferram(mtd, from)) { - this->main_buf = buf; this->command(mtd, ONENAND_CMD_READ, from, writesize); ret = this->wait(mtd, FL_READING); + if (unlikely(ret)) + ret = onenand_recover_lsb(mtd, from, ret); onenand_update_bufferram(mtd, from, !ret); if (ret == -EBADMSG) ret = 0; @@@ -765,11 -950,13 +914,13 @@@ skip_read_while_load thislen = min_t(int, writesize, len - read); column = 0; - /* Now wait for load */ - ret = this->wait(mtd, FL_READING); - onenand_update_bufferram(mtd, from, !ret); - if (ret == -EBADMSG) - ret = 0; - if (!ONENAND_IS_MLC(this)) { ++ if (ONENAND_IS_4KB_PAGE(this)) { + /* Now wait for load */ + ret = this->wait(mtd, FL_READING); + onenand_update_bufferram(mtd, from, !ret); + if (ret == -EBADMSG) + ret = 0; + } } /* @@@ -841,7 -1030,8 +994,7 @@@ static int onenand_read_oob_nolock(stru thislen = oobsize - column; thislen = min_t(int, thislen, len); - this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize); - this->spare_buf = buf; + this->command(mtd, readcmd, from, mtd->oobsize); onenand_update_bufferram(mtd, from, 0); @@@ -1025,7 -1223,8 +1186,7 @@@ int onenand_bbt_read_oob(struct mtd_inf thislen = mtd->oobsize - column; thislen = min_t(int, thislen, len); - this->command(mtd, ONENAND_CMD_READOOB, from, mtd->oobsize); - this->spare_buf = buf; + this->command(mtd, readcmd, from, mtd->oobsize); onenand_update_bufferram(mtd, from, 0); @@@ -1562,16 -1794,11 +1754,9 @@@ static int onenand_erase(struct mtd_inf else MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_erase: " "Failed erase, block %d\n", - (unsigned)(addr >> this->erase_shift)); - if (ret == -EPERM) - printk("onenand_erase: " - "Device is write protected!!!\n"); - else - printk("onenand_erase: " - "Failed erase, block %d\n", - (unsigned)(addr >> this->erase_shift)); + onenand_block(this, addr)); instr->state = MTD_ERASE_FAILED; instr->fail_addr = addr; - - goto erase_exit; } len -= block_size; @@@ -1926,6 -2167,14 +2128,14 @@@ static void onenand_check_features(stru break; } - if (ONENAND_IS_MLC(this)) ++ if (ONENAND_IS_4KB_PAGE(this)) + this->options &= ~ONENAND_HAS_2PLANE; + + if (FLEXONENAND(this)) { + this->options &= ~ONENAND_HAS_CONT_LOCK; + this->options |= ONENAND_HAS_UNLOCK_ALL; + } + if (this->options & ONENAND_HAS_CONT_LOCK) printk(KERN_DEBUG "Lock scheme is Continuous Lock\n"); if (this->options & ONENAND_HAS_UNLOCK_ALL) @@@ -2056,23 -2557,31 +2522,34 @@@ static int onenand_probe(struct mtd_inf this->device_id = dev_id; this->version_id = ver_id; + /* Check OneNAND features */ + onenand_check_features(mtd); + density = onenand_get_density(dev_id); + if (FLEXONENAND(this)) { + this->dies = ONENAND_IS_DDP(this) ? 2 : 1; + /* Maximum possible erase regions */ + mtd->numeraseregions = this->dies << 1; + mtd->eraseregions = malloc(sizeof(struct mtd_erase_region_info) + * (this->dies << 1)); + if (!mtd->eraseregions) + return -ENOMEM; + } + + /* + * For Flex-OneNAND, chipsize represents maximum possible device size. + * mtd->size represents the actual device size. + */ this->chipsize = (16 << density) << 20; - /* Set density mask. it is used for DDP */ - if (ONENAND_IS_DDP(this)) - this->density_mask = (1 << (density + 6)); - else - this->density_mask = 0; /* OneNAND page size & block size */ /* The data buffer size is equal to page size */ mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE); + /* We use the full BufferRAM */ - if (ONENAND_IS_MLC(this)) + if (ONENAND_IS_4KB_PAGE(this)) mtd->writesize <<= 1; + mtd->oobsize = mtd->writesize >> 5; /* Pagers per block is always 64 in OneNAND */ mtd->erasesize = mtd->writesize << 6; @@@ -2086,8 -2605,14 +2573,11 @@@ /* REVIST: Multichip handling */ - mtd->size = this->chipsize; + if (FLEXONENAND(this)) + flexonenand_get_size(mtd); + else + mtd->size = this->chipsize; - /* Check OneNAND features */ - onenand_check_features(mtd); - mtd->flags = MTD_CAP_NANDFLASH; mtd->erase = onenand_erase; mtd->read = onenand_read; diff --cc drivers/mtd/onenand/onenand_bbt.c index e02e480,1354877..620e963 --- a/drivers/mtd/onenand/onenand_bbt.c +++ b/drivers/mtd/onenand/onenand_bbt.c @@@ -190,14 -158,9 +196,14 @@@ static int onenand_isbad_bbt(struct mtd uint8_t res; /* Get block number * 2 */ - block = (int)(offs >> (bbm->bbt_erase_shift - 1)); + block = (int) (onenand_block(this, offs) << 1); res = (bbm->bbt[block >> 3] >> (block & 0x06)) & 0x03; + if (this->options & ONENAND_RUNTIME_BADBLOCK_CHECK) { + if (res == 0x02) + res = read_page_oob(mtd, offs, this->oob_buf); + } + MTDDEBUG (MTD_DEBUG_LEVEL2, "onenand_isbad_bbt: bbt info for offs 0x%08x: (block %d) 0x%02x\n", (unsigned int)offs, block >> 1, res); diff --cc include/common.h index f7c93bf,07897f6..16c7795 --- a/include/common.h +++ b/include/common.h @@@ -608,11 -612,17 +612,23 @@@ ulong usec2ticks (unsigned long usec ulong ticks2usec (unsigned long ticks); int init_timebase (void); + /* lib_generic/gunzip.c */ + int gunzip(void *, int, unsigned char *, unsigned long *); + int zunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp, + int stoponerr, int offset); ++/* lib_generic/net_utils.c */ ++#include ++static inline IPaddr_t getenv_IPaddr (char *var) ++{ ++ return (string_to_ip(getenv(var))); ++} + + /* lib_generic/time.c */ + void udelay (unsigned long); + /* lib_generic/vsprintf.c */ ulong simple_strtoul(const char *cp,char **endp,unsigned int base); - #ifdef CONFIG_SYS_64BIT_VSPRINTF unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base); - #endif long simple_strtol(const char *cp,char **endp,unsigned int base); void panic(const char *fmt, ...) __attribute__ ((format (__printf__, 1, 2))); diff --cc include/net.h index 1c8ab12,1c8ab12..3f6a5d1 --- a/include/net.h +++ b/include/net.h @@@ -508,9 -508,9 +508,6 @@@ extern void VLAN_to_string (ushort x, c /* Convert a string to a vlan id */ extern ushort string_to_VLAN(char *s); --/* read an IP address from a environment variable */ --extern IPaddr_t getenv_IPaddr (char *); -- /* read a VLAN id from an environment variable */ extern ushort getenv_VLAN(char *); diff --cc include/onenand_uboot.h index c4e6e87,92279d5..7449a68 --- a/include/onenand_uboot.h +++ b/include/onenand_uboot.h @@@ -29,8 -30,24 +30,17 @@@ extern void onenand_board_init(struct m /* Functions */ extern void onenand_init(void); -extern int onenand_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t * retlen, u_char * buf); -extern int onenand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops); -extern int onenand_write(struct mtd_info *mtd, loff_t from, size_t len, - size_t * retlen, const u_char * buf); -extern int onenand_erase(struct mtd_info *mtd, struct erase_info *instr); - extern char *onenand_print_device_info(int device, int version); + extern unsigned onenand_block(struct onenand_chip *this, loff_t addr); + + extern loff_t onenand_addr(struct onenand_chip *this, int block); + + extern int flexonenand_region(struct mtd_info *mtd, loff_t addr); + + extern int flexonenand_set_boundary(struct mtd_info *mtd, int die, + int boundary, int lock); + /* S3C64xx */ extern void s3c64xx_onenand_init(struct mtd_info *); extern void s3c64xx_set_width_regs(struct onenand_chip *); diff --cc lib_generic/Makefile index 2ec261a,bfaf346..c17179c --- a/lib_generic/Makefile +++ b/lib_generic/Makefile @@@ -41,6 -41,6 +41,7 @@@ COBJS-y += gunzip. COBJS-y += lmb.o COBJS-y += ldiv.o COBJS-$(CONFIG_MD5) += md5.o ++COBJS-y += net_utils.o COBJS-y += sha1.o COBJS-$(CONFIG_SHA256) += sha256.o COBJS-y += string.o diff --cc net/net.c index fd13cd9,595abd9..7d2220d --- a/net/net.c +++ b/net/net.c @@@ -1894,27 -1890,27 +1890,6 @@@ void ip_to_string (IPaddr_t x, char *s ); } --IPaddr_t string_to_ip(char *s) --{ -- IPaddr_t addr; -- char *e; -- int i; -- -- if (s == NULL) -- return(0); -- -- for (addr=0, i=0; i<4; ++i) { -- ulong val = s ? simple_strtoul(s, &e, 10) : 0; -- addr <<= 8; -- addr |= (val & 0xFF); -- if (s) { -- s = (*e) ? e+1 : e; -- } -- } -- -- return (htonl(addr)); --} -- void VLAN_to_string(ushort x, char *s) { x = ntohs(x); @@@ -1943,11 -1939,11 +1918,6 @@@ ushort string_to_VLAN(char *s return htons(id); } --IPaddr_t getenv_IPaddr (char *var) --{ -- return (string_to_ip(getenv(var))); --} -- ushort getenv_VLAN(char *var) { return (string_to_VLAN(getenv(var)));