2005-08-17 10:55:25 +00:00
|
|
|
/*
|
|
|
|
* (C) Copyright 2005
|
|
|
|
* 2N Telekomunikace, a.s. <www.2n.cz>
|
|
|
|
* Ladislav Michl <michl@2n.cz>
|
|
|
|
*
|
|
|
|
* See file CREDITS for list of people who contributed to this
|
|
|
|
* project.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
2013-10-07 11:07:26 +00:00
|
|
|
* version 2 as published by the Free Software Foundation.
|
2005-08-17 10:55:25 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _NAND_H_
|
|
|
|
#define _NAND_H_
|
|
|
|
|
2012-01-13 01:42:58 +00:00
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
/*
|
|
|
|
* All boards using a given driver must convert to self-init
|
|
|
|
* at the same time, so do it here. When all drivers are
|
|
|
|
* converted, this will go away.
|
|
|
|
*/
|
2014-03-03 06:47:16 +00:00
|
|
|
#ifdef CONFIG_SPL_BUILD
|
|
|
|
#if defined(CONFIG_NAND_FSL_ELBC) || defined(CONFIG_NAND_FSL_IFC)
|
|
|
|
#define CONFIG_SYS_NAND_SELF_INIT
|
|
|
|
#endif
|
|
|
|
#else
|
2013-04-04 18:44:06 +00:00
|
|
|
#if defined(CONFIG_NAND_FSL_ELBC) || defined(CONFIG_NAND_ATMEL)\
|
|
|
|
|| defined(CONFIG_NAND_FSL_IFC)
|
2012-01-13 01:42:58 +00:00
|
|
|
#define CONFIG_SYS_NAND_SELF_INIT
|
|
|
|
#endif
|
2014-03-03 06:47:16 +00:00
|
|
|
#endif
|
2012-01-13 01:42:58 +00:00
|
|
|
|
2008-07-09 22:47:52 +00:00
|
|
|
extern void nand_init(void);
|
|
|
|
|
2012-04-09 13:39:55 +00:00
|
|
|
#include <linux/compat.h>
|
2005-08-17 10:55:25 +00:00
|
|
|
#include <linux/mtd/mtd.h>
|
|
|
|
#include <linux/mtd/nand.h>
|
|
|
|
|
2012-01-13 01:07:23 +00:00
|
|
|
#ifdef CONFIG_SYS_NAND_SELF_INIT
|
|
|
|
void board_nand_init(void);
|
|
|
|
int nand_register(int devnum);
|
|
|
|
#else
|
2008-12-06 07:40:55 +00:00
|
|
|
extern int board_nand_init(struct nand_chip *nand);
|
2012-01-13 01:07:23 +00:00
|
|
|
#endif
|
2008-12-06 07:40:55 +00:00
|
|
|
|
2005-08-17 10:55:25 +00:00
|
|
|
typedef struct mtd_info nand_info_t;
|
|
|
|
|
|
|
|
extern int nand_curr_device;
|
|
|
|
extern nand_info_t nand_info[];
|
|
|
|
|
2009-05-16 12:27:40 +00:00
|
|
|
static inline int nand_read(nand_info_t *info, loff_t ofs, size_t *len, u_char *buf)
|
2005-08-17 10:55:25 +00:00
|
|
|
{
|
2013-01-14 03:46:50 +00:00
|
|
|
return mtd_read(info, ofs, *len, (size_t *)len, buf);
|
2005-08-17 10:55:25 +00:00
|
|
|
}
|
|
|
|
|
2009-05-16 12:27:40 +00:00
|
|
|
static inline int nand_write(nand_info_t *info, loff_t ofs, size_t *len, u_char *buf)
|
2005-08-17 10:55:25 +00:00
|
|
|
{
|
2013-01-14 03:46:50 +00:00
|
|
|
return mtd_write(info, ofs, *len, (size_t *)len, buf);
|
2005-08-17 10:55:25 +00:00
|
|
|
}
|
|
|
|
|
2009-05-16 12:27:40 +00:00
|
|
|
static inline int nand_block_isbad(nand_info_t *info, loff_t ofs)
|
2005-08-17 10:55:25 +00:00
|
|
|
{
|
2013-01-14 03:46:50 +00:00
|
|
|
return mtd_block_isbad(info, ofs);
|
2005-08-17 10:55:25 +00:00
|
|
|
}
|
|
|
|
|
2009-05-16 12:27:40 +00:00
|
|
|
static inline int nand_erase(nand_info_t *info, loff_t off, size_t size)
|
2005-08-17 10:55:25 +00:00
|
|
|
{
|
2005-11-02 13:29:12 +00:00
|
|
|
struct erase_info instr;
|
|
|
|
|
|
|
|
instr.mtd = info;
|
|
|
|
instr.addr = off;
|
|
|
|
instr.len = size;
|
|
|
|
instr.callback = 0;
|
|
|
|
|
2013-01-14 03:46:50 +00:00
|
|
|
return mtd_erase(info, &instr);
|
2005-08-17 10:55:25 +00:00
|
|
|
}
|
|
|
|
|
2006-10-10 10:36:02 +00:00
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
* declarations from nand_util.c
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
struct nand_write_options {
|
|
|
|
u_char *buffer; /* memory block containing image to write */
|
|
|
|
ulong length; /* number of bytes to write */
|
|
|
|
ulong offset; /* start address in NAND */
|
|
|
|
int quiet; /* don't display progress messages */
|
|
|
|
int autoplace; /* if true use auto oob layout */
|
|
|
|
int forcejffs2; /* force jffs2 oob layout */
|
|
|
|
int forceyaffs; /* force yaffs oob layout */
|
|
|
|
int noecc; /* write without ecc */
|
|
|
|
int writeoob; /* image contains oob data */
|
|
|
|
int pad; /* pad to page size */
|
|
|
|
int blockalign; /* 1|2|4 set multiple of eraseblocks
|
|
|
|
* to align to */
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct nand_write_options nand_write_options_t;
|
2007-10-31 12:53:06 +00:00
|
|
|
typedef struct mtd_oob_ops mtd_oob_ops_t;
|
2006-10-10 10:36:02 +00:00
|
|
|
|
|
|
|
struct nand_read_options {
|
|
|
|
u_char *buffer; /* memory block in which read image is written*/
|
|
|
|
ulong length; /* number of bytes to read */
|
|
|
|
ulong offset; /* start address in NAND */
|
|
|
|
int quiet; /* don't display progress messages */
|
|
|
|
int readoob; /* put oob data in image */
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct nand_read_options nand_read_options_t;
|
|
|
|
|
|
|
|
struct nand_erase_options {
|
nand erase: .spread, .part, .chip subcommands
A while back, in http://lists.denx.de/pipermail/u-boot/2009-June/054428.html,
Michele De Candia posted a patch to not count bad blocks toward the
requested size to be erased. This is desireable when you're passing in
something like $filesize, but not when you're trying to erase a partition.
Thus, a .spread subcommand (named for consistency with
http://lists.denx.de/pipermail/u-boot/2010-August/075163.html) is introduced
to make explicit the user's desire to erase for a given amount of data,
rather than to erase a specific region of the chip.
While passing $filesize to "nand erase" is useful, accidentally passing
something like $fliesize currently produces quite unpleasant results, as the
variable evaluates to nothing and U-Boot assumes that you want to erase
the entire rest of the chip/partition. To improve the safety of the
erase command, require the user to make explicit their intentions by
using a .part or .chip subcommand. This is an incompatible user interface
change, but keeping compatibility would eliminate the safety gain, and IMHO
it's worth it.
While touching nand_erase_opts(), make it accept 64-bit offsets and sizes,
fix the percentage display when erase length is rounded up, eliminate
an inconsistent warning about rounding up the erase length which only
happened when the length was less than one block (rounding up for $filesize
is normal operation), and add a diagnostic if there's an attempt to erase
beginning at a non-block boundary.
Signed-off-by: Scott Wood <scottwood@freescale.com>
Tested-by: Ben Gardiner <bengardiner@nanometrics.ca>
2010-08-25 19:43:29 +00:00
|
|
|
loff_t length; /* number of bytes to erase */
|
|
|
|
loff_t offset; /* first address in NAND to erase */
|
2006-10-10 10:36:02 +00:00
|
|
|
int quiet; /* don't display progress messages */
|
|
|
|
int jffs2; /* if true: format for jffs2 usage
|
|
|
|
* (write appropriate cleanmarker blocks) */
|
|
|
|
int scrub; /* if true, really clean NAND by erasing
|
|
|
|
* bad blocks (UNSAFE) */
|
nand erase: .spread, .part, .chip subcommands
A while back, in http://lists.denx.de/pipermail/u-boot/2009-June/054428.html,
Michele De Candia posted a patch to not count bad blocks toward the
requested size to be erased. This is desireable when you're passing in
something like $filesize, but not when you're trying to erase a partition.
Thus, a .spread subcommand (named for consistency with
http://lists.denx.de/pipermail/u-boot/2010-August/075163.html) is introduced
to make explicit the user's desire to erase for a given amount of data,
rather than to erase a specific region of the chip.
While passing $filesize to "nand erase" is useful, accidentally passing
something like $fliesize currently produces quite unpleasant results, as the
variable evaluates to nothing and U-Boot assumes that you want to erase
the entire rest of the chip/partition. To improve the safety of the
erase command, require the user to make explicit their intentions by
using a .part or .chip subcommand. This is an incompatible user interface
change, but keeping compatibility would eliminate the safety gain, and IMHO
it's worth it.
While touching nand_erase_opts(), make it accept 64-bit offsets and sizes,
fix the percentage display when erase length is rounded up, eliminate
an inconsistent warning about rounding up the erase length which only
happened when the length was less than one block (rounding up for $filesize
is normal operation), and add a diagnostic if there's an attempt to erase
beginning at a non-block boundary.
Signed-off-by: Scott Wood <scottwood@freescale.com>
Tested-by: Ben Gardiner <bengardiner@nanometrics.ca>
2010-08-25 19:43:29 +00:00
|
|
|
|
|
|
|
/* Don't include skipped bad blocks in size to be erased */
|
|
|
|
int spread;
|
2013-06-24 16:50:40 +00:00
|
|
|
/* maximum size that actual may be in order to not exceed the buf */
|
|
|
|
loff_t lim;
|
2006-10-10 10:36:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct nand_erase_options nand_erase_options_t;
|
|
|
|
|
2009-05-16 12:27:40 +00:00
|
|
|
int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
|
2013-03-14 05:32:50 +00:00
|
|
|
size_t *actual, loff_t lim, u_char *buffer);
|
nand_util: convert nand_write_skip_bad() to flags
In a future commit the behaviour of nand_write_skip_bad()
will be further extended.
Convert the only flag currently passed to the nand_write_
skip_bad() function to a bitfield of only one allocated
member. This should avoid an explosion of int's at the
end of the parameter list or the ambiguous calls like
nand_write_skip_bad(info, offset, len, buf, 0, 1, 1);
nand_write_skip_bad(info, offset, len, buf, 0, 1, 0);
Instead there will be:
nand_write_skip_bad(info, offset, len, buf, WITH_YAFFS_OOB |
WITH_OTHER);
Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca>
Acked-by: Detlev Zundel <dzu@denx.de>
Signed-off-by: Scott Wood <scottwood@freescale.com>
2011-05-24 14:18:35 +00:00
|
|
|
|
2011-06-14 20:35:05 +00:00
|
|
|
#define WITH_YAFFS_OOB (1 << 0) /* whether write with yaffs format. This flag
|
|
|
|
* is a 'mode' meaning it cannot be mixed with
|
|
|
|
* other flags */
|
2011-06-14 20:35:06 +00:00
|
|
|
#define WITH_DROP_FFS (1 << 1) /* drop trailing all-0xff pages */
|
nand_util: convert nand_write_skip_bad() to flags
In a future commit the behaviour of nand_write_skip_bad()
will be further extended.
Convert the only flag currently passed to the nand_write_
skip_bad() function to a bitfield of only one allocated
member. This should avoid an explosion of int's at the
end of the parameter list or the ambiguous calls like
nand_write_skip_bad(info, offset, len, buf, 0, 1, 1);
nand_write_skip_bad(info, offset, len, buf, 0, 1, 0);
Instead there will be:
nand_write_skip_bad(info, offset, len, buf, WITH_YAFFS_OOB |
WITH_OTHER);
Signed-off-by: Ben Gardiner <bengardiner@nanometrics.ca>
Acked-by: Detlev Zundel <dzu@denx.de>
Signed-off-by: Scott Wood <scottwood@freescale.com>
2011-05-24 14:18:35 +00:00
|
|
|
|
2009-05-16 12:27:40 +00:00
|
|
|
int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,
|
2013-03-14 05:32:50 +00:00
|
|
|
size_t *actual, loff_t lim, u_char *buffer, int flags);
|
2006-10-10 10:36:02 +00:00
|
|
|
int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts);
|
2012-11-16 19:20:54 +00:00
|
|
|
int nand_torture(nand_info_t *nand, loff_t offset);
|
2006-10-10 10:36:02 +00:00
|
|
|
|
|
|
|
#define NAND_LOCK_STATUS_TIGHT 0x01
|
|
|
|
#define NAND_LOCK_STATUS_UNLOCK 0x04
|
|
|
|
|
2012-08-22 21:49:42 +00:00
|
|
|
int nand_lock(nand_info_t *meminfo, int tight);
|
2012-08-22 21:49:43 +00:00
|
|
|
int nand_unlock(nand_info_t *meminfo, loff_t start, size_t length,
|
|
|
|
int allexcept);
|
2009-05-16 12:27:40 +00:00
|
|
|
int nand_get_lock_status(nand_info_t *meminfo, loff_t offset);
|
2006-10-10 10:36:02 +00:00
|
|
|
|
2011-09-14 19:30:16 +00:00
|
|
|
int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst);
|
2011-09-14 19:29:26 +00:00
|
|
|
void nand_deselect(void);
|
|
|
|
|
2008-10-16 13:01:15 +00:00
|
|
|
#ifdef CONFIG_SYS_NAND_SELECT_DEVICE
|
2006-10-20 12:28:52 +00:00
|
|
|
void board_nand_select_device(struct nand_chip *nand, int chip);
|
|
|
|
#endif
|
|
|
|
|
2008-06-30 19:13:28 +00:00
|
|
|
__attribute__((noreturn)) void nand_boot(void);
|
|
|
|
|
2005-08-17 10:55:25 +00:00
|
|
|
#endif
|
2010-07-05 17:27:07 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_ENV_OFFSET_OOB
|
|
|
|
#define ENV_OOB_MARKER 0x30425645 /*"EVB0" in little-endian -- offset is stored
|
|
|
|
as block number*/
|
|
|
|
#define ENV_OOB_MARKER_OLD 0x30564e45 /*"ENV0" in little-endian -- offset is
|
|
|
|
stored as byte number */
|
|
|
|
#define ENV_OFFSET_SIZE 8
|
|
|
|
int get_nand_env_oob(nand_info_t *nand, unsigned long *result);
|
|
|
|
#endif
|