gtar --force-local -zcvf `date "+$$F-%Y-%m-%d-%T.tar.gz"` $$F
#########################################################################
+
+-include sb.mk
*
* Last ChangeLog Entry
* $Log$
- * Revision 1.1.3.2 2011-02-28 14:52:53 lothar
- * imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
+ * Revision 1.1.2.1 2011-06-14 08:39:03 lothar
+ * TX28 Release 2011-05-30
*
* Revision 1.4 2005/03/02 16:40:20 mleeman
* remove empty labels (3.4 complains)
*
* Last ChangeLog Entry
* $Log$
- * Revision 1.1.3.2 2011-02-28 14:52:53 lothar
- * imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
+ * Revision 1.1.2.1 2011-06-14 08:39:03 lothar
+ * TX28 Release 2011-05-30
*
* Revision 1.2 2005/02/21 12:48:58 mleeman
* update of copyright years (feedback wd)
*
* Last ChangeLog Entry
* $Log$
- * Revision 1.1.3.2 2011-02-28 14:52:53 lothar
- * imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
+ * Revision 1.1.2.1 2011-06-14 08:39:03 lothar
+ * TX28 Release 2011-05-30
*
* Revision 1.3 2005/02/21 12:48:58 mleeman
* update of copyright years (feedback wd)
*
* Last ChangeLog Entry
* $Log$
- * Revision 1.1.3.2 2011-02-28 14:52:53 lothar
- * imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
+ * Revision 1.1.2.1 2011-06-14 08:39:03 lothar
+ * TX28 Release 2011-05-30
*
* Revision 1.2 2005/02/21 12:48:58 mleeman
* update of copyright years (feedback wd)
LIB = $(obj)lib$(BOARD).a
COBJS := tx28.o
+ifeq ($(CONFIG_CMD_ROMUPDATE),y)
+ COBJS += flash.o
+endif
SOBJS := lowlevel_init.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
#include <version.h>
/* Set up the platform, once the cpu has been initialized */
-.globl lowlevel_init
+ .globl lowlevel_init
lowlevel_init:
/* All SDRAM settings are done by sdram_prep */
{ PINID_SSP0_SCK, PIN_FUN1, PAD_8MA, PAD_3V3, 1 },
};
-static struct pin_desc mmc1_pins_desc[] = {
- { PINID_GPMI_D00, PIN_FUN2, PAD_8MA, PAD_3V3, 1 },
- { PINID_GPMI_D01, PIN_FUN2, PAD_8MA, PAD_3V3, 1 },
- { PINID_GPMI_D02, PIN_FUN2, PAD_8MA, PAD_3V3, 1 },
- { PINID_GPMI_D03, PIN_FUN2, PAD_8MA, PAD_3V3, 1 },
- { PINID_GPMI_D04, PIN_FUN2, PAD_8MA, PAD_3V3, 1 },
- { PINID_GPMI_D05, PIN_FUN2, PAD_8MA, PAD_3V3, 1 },
- { PINID_GPMI_D06, PIN_FUN2, PAD_8MA, PAD_3V3, 1 },
- { PINID_GPMI_D07, PIN_FUN2, PAD_8MA, PAD_3V3, 1 },
- { PINID_GPMI_RDY1, PIN_FUN2, PAD_8MA, PAD_3V3, 1 },
- { PINID_GPMI_RDY0, PIN_FUN2, PAD_8MA, PAD_3V3, 1 },
- { PINID_GPMI_WRN, PIN_FUN2, PAD_8MA, PAD_3V3, 1 }
-};
-
static struct pin_group mmc0_pins = {
.pins = mmc0_pins_desc,
.nr_pins = ARRAY_SIZE(mmc0_pins_desc)
};
-static struct pin_group mmc1_pins = {
- .pins = mmc1_pins_desc,
- .nr_pins = ARRAY_SIZE(mmc1_pins_desc)
-};
-
struct imx_ssp_mmc_cfg ssp_mmc_cfg[2] = {
{REGS_SSP0_BASE, HW_CLKCTRL_SSP0, BM_CLKCTRL_CLKSEQ_BYPASS_SSP0},
{REGS_SSP1_BASE, HW_CLKCTRL_SSP1, BM_CLKCTRL_CLKSEQ_BYPASS_SSP1},
.nr_pins = ARRAY_SIZE(duart_pins_desc),
};
+static struct pin_desc gpmi_pins_desc[] = {
+ { PINID_GPMI_D00, PIN_FUN1, },
+ { PINID_GPMI_D01, PIN_FUN1, },
+ { PINID_GPMI_D02, PIN_FUN1, },
+ { PINID_GPMI_D03, PIN_FUN1, },
+ { PINID_GPMI_D04, PIN_FUN1, },
+ { PINID_GPMI_D05, PIN_FUN1, },
+ { PINID_GPMI_D06, PIN_FUN1, },
+ { PINID_GPMI_D07, PIN_FUN1, },
+ { PINID_GPMI_CE0N, PIN_FUN1, },
+ { PINID_GPMI_RDY0, PIN_FUN1, },
+ { PINID_GPMI_RDN, PIN_FUN1, },
+ { PINID_GPMI_WRN, PIN_FUN1, },
+ { PINID_GPMI_ALE, PIN_FUN1, },
+ { PINID_GPMI_CLE, PIN_FUN1, },
+ { PINID_GPMI_RESETN, PIN_FUN1, },
+};
+
+static struct pin_group gpmi_pins = {
+ .pins = gpmi_pins_desc,
+ .nr_pins = ARRAY_SIZE(gpmi_pins_desc),
+};
+
/*
* Functions
*/
}
#endif
-#define PINID_SSP0_GPIO_WP PINID_SSP1_SCK
-#define PINID_SSP1_GPIO_WP PINID_GPMI_RESETN
u32 ssp_mmc_is_wp(struct mmc *mmc)
{
pin_set_group(&mmc0_pins);
break;
- case 1:
- /* Set up MMC pins */
- pin_set_group(&mmc1_pins);
- break;
-
default:
printf("Warning: more ssp mmc controllers configured(%d) than supported by the board(2)\n",
CONFIG_SYS_SSP_MMC_NUM);
pin_gpio_set(PINID_ENET0_RX_CLK, 1);
}
+#ifdef CONFIG_MXS_NAND
+#include <linux/mtd/nand.h>
+extern int mxs_gpmi_nand_init(struct mtd_info *mtd, struct nand_chip *chip);
+
+int board_nand_init(struct mtd_info *mtd, struct nand_chip *chip)
+{
+ pin_set_group(&gpmi_pins);
+ return mxs_gpmi_nand_init(mtd, chip);
+}
+#endif
+
int checkboard(void)
{
printf("Board: Ka-Ro TX28\n");
-PLATFORM_CPPFLAGS += -march=armv5te
-PLATFORM_CPPFLAGS += $(call cc-option,-mtune=arm926ejs,)
\ No newline at end of file
+PLATFORM_CPPFLAGS += $(call cc-option,-mtune=arm926ejs,)
#include <asm/errno.h>
#include <asm/arch/regs-clkctrl.h>
#include <asm/cache-cp15.h>
+#include <asm/io.h>
#include <asm/fec.h>
+#define MXS_MODULE_SFTRST (1 << 31)
+#define MXS_MODULE_CLKGATE (1 << 30)
+
+static inline void __mxs_clrl(u32 mask, volatile void *addr)
+{
+ __raw_writel(mask, addr + MXS_CLR_ADDR);
+}
+
+static inline void __mxs_setl(u32 mask, volatile void *addr)
+{
+ __raw_writel(mask, addr + MXS_SET_ADDR);
+}
+
+/*
+ * Clear the bit and poll it cleared. This is usually called with
+ * a reset address and mask being either SFTRST(bit 31) or CLKGATE
+ * (bit 30).
+ */
+static int clear_poll_bit(volatile void *addr, u32 mask)
+{
+ int timeout = 0x400;
+
+ /* clear the bit */
+ __mxs_clrl(mask, addr);
+
+ /*
+ * SFTRST needs 3 GPMI clocks to settle, the reference manual
+ * recommends to wait 1us.
+ */
+ udelay(1);
+
+ /* poll the bit becoming clear */
+ while ((__raw_readl(addr) & mask) && --timeout)
+ udelay(1);
+
+ return !timeout;
+}
+
+int mxs_reset_block(volatile void *reset_addr)
+{
+ int ret;
+ int timeout = 0x400000;
+
+ /* clear and poll SFTRST */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
+ if (ret)
+ goto error;
+
+ /* clear CLKGATE */
+ __mxs_clrl(MXS_MODULE_CLKGATE, reset_addr);
+
+ /* set SFTRST to reset the block */
+ __mxs_setl(MXS_MODULE_SFTRST, reset_addr);
+ udelay(1);
+
+ /* poll CLKGATE becoming set */
+ while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
+ udelay(1);
+
+ if (!timeout)
+ goto error;
+
+ /* clear and poll SFTRST */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
+ if (ret)
+ goto error;
+
+ /* clear and poll CLKGATE */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
+ if (ret)
+ goto error;
+
+ return 0;
+
+error:
+ printf("%s(%p): module reset timeout\n", __func__, reset_addr);
+ return -ETIMEDOUT;
+}
+
static u32 mx28_get_pclk(void)
{
const u32 xtal = 24, ref = 480;
return emiclk;
}
+
static inline void __enable_gpmi_clk(void)
{
/* Clear bypass bit*/
BM_CLKCTRL_CLKSEQ_BYPASS_GPMI);
/* Set gpmi clock to ref_gpmi/12 */
REG_WR(REGS_CLKCTRL_BASE, HW_CLKCTRL_GPMI,
- REG_RD(REGS_CLKCTRL_BASE, HW_CLKCTRL_GPMI) &
- (~(BM_CLKCTRL_GPMI_DIV)) &
- (~(BM_CLKCTRL_GPMI_CLKGATE)) |
- 1);
+ (REG_RD(REGS_CLKCTRL_BASE, HW_CLKCTRL_GPMI) &
+ (~(BM_CLKCTRL_GPMI_DIV |
+ ~BM_CLKCTRL_GPMI_CLKGATE))) |
+ 1);
}
+
static u32 mx28_get_gpmiclk(void)
{
const u32 xtal = 24, ref = 480;
return gpmiclk;
}
+
u32 mxc_get_clock(enum mxc_clock clk)
{
switch (clk) {
COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
COBJS-$(CONFIG_MX31_NAND) += mx31_nand.o
COBJS-$(CONFIG_MXC_NAND) += mxc_nand.o nand_device_info.o
+COBJS-$(CONFIG_MXS_NAND) += mxs_gpmi.o
endif
COBJS := $(COBJS-y)
mtd->priv = nand;
nand->IO_ADDR_R = nand->IO_ADDR_W = (void __iomem *)base_addr;
- if (board_nand_init(nand) == 0) {
+ if (board_nand_init(mtd, nand) == 0) {
if (nand_scan(mtd, maxchips) == 0) {
if (!mtd->name)
mtd->name = (char *)default_nand_name;
* Description:
*
* When nand_scan_bbt is called, then it tries to find the bad block table
- * depending on the options in the bbt descriptor(s). If a bbt is found
- * then the contents are read and the memory based bbt is created. If a
- * mirrored bbt is selected then the mirror is searched too and the
- * versions are compared. If the mirror has a greater version number
- * than the mirror bbt is used to build the memory based bbt.
+ * depending on the options in the BBT descriptor(s). If no flash based BBT
+ * (NAND_USE_FLASH_BBT) is specified then the device is scanned for factory
+ * marked good / bad blocks. This information is used to create a memory BBT.
+ * Once a new bad block is discovered then the "factory" information is updated
+ * on the device.
+ * If a flash based BBT is specified then the function first tries to find the
+ * BBT on flash. If a BBT is found then the contents are read and the memory
+ * based BBT is created. If a mirrored BBT is selected then the mirror is
+ * searched too and the versions are compared. If the mirror has a greater
+ * version number than the mirror BBT is used to build the memory based BBT.
* If the tables are not versioned, then we "or" the bad block information.
- * If one of the bbt's is out of date or does not exist it is (re)created.
- * If no bbt exists at all then the device is scanned for factory marked
+ * If one of the BBTs is out of date or does not exist it is (re)created.
+ * If no BBT exists at all then the device is scanned for factory marked
* good / bad blocks and the bad block tables are created.
*
- * For manufacturer created bbts like the one found on M-SYS DOC devices
- * the bbt is searched and read but never created
+ * For manufacturer created BBTs like the one found on M-SYS DOC devices
+ * the BBT is searched and read but never created
*
- * The autogenerated bad block table is located in the last good blocks
+ * The auto generated bad block table is located in the last good blocks
* of the device. The table is mirrored, so it can be updated eventually.
- * The table is marked in the oob area with an ident pattern and a version
- * number which indicates which of both tables is more up to date.
+ * The table is marked in the OOB area with an ident pattern and a version
+ * number which indicates which of both tables is more up to date. If the NAND
+ * controller needs the complete OOB area for the ECC information then the
+ * option NAND_USE_FLASH_BBT_NO_OOB should be used: it moves the ident pattern
+ * and the version byte into the data area and the OOB area will remain
+ * untouched.
*
* The table uses 2 bits per block
- * 11b: block is good
- * 00b: block is factory marked bad
+ * 11b: block is good
+ * 00b: block is factory marked bad
* 01b, 10b: block is marked bad due to wear
*
* The memory bad block table uses the following scheme:
#include <linux/delay.h>
#include <linux/vmalloc.h>
#endif
+static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td)
+{
+ int ret;
+
+ ret = memcmp(buf, td->pattern, td->len);
+ if (!ret)
+ return ret;
+ return -1;
+}
/**
* check_pattern - [GENERIC] check if a pattern is in the buffer
int i, end = 0;
uint8_t *p = buf;
+ if (td->options & NAND_BBT_NO_OOB)
+ return check_pattern_no_oob(buf, td);
+
end = paglen + td->offs;
if (td->options & NAND_BBT_SCANEMPTY) {
for (i = 0; i < end; i++) {
return 0;
}
+/**
+ * add_marker_len - compute the length of the marker in data area
+ * @td: BBT descriptor used for computation
+ *
+ * The length will be 0 if the markeris located in OOB area.
+ */
+static u32 add_marker_len(struct nand_bbt_descr *td)
+{
+ u32 len;
+
+ if (!(td->options & NAND_BBT_NO_OOB))
+ return 0;
+
+ len = td->len;
+ if (td->options & NAND_BBT_VERSION)
+ len++;
+ return len;
+}
+
/**
* read_bbt - [GENERIC] Read the bad block table starting from page
* @mtd: MTD device structure
* @buf: temporary buffer
* @page: the starting page
* @num: the number of bbt descriptors to read
- * @bits: number of bits per block
+ * @td: the bbt describtion table
* @offs: offset in the memory table
- * @reserved_block_code: Pattern to identify reserved blocks
*
* Read the bad block table starting from page.
*
*/
static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num,
- int bits, int offs, int reserved_block_code)
+ struct nand_bbt_descr *td, int offs)
{
int res, i, j, act = 0;
struct nand_chip *this = mtd->priv;
size_t retlen, len, totlen;
loff_t from;
+ int bits = td->options & NAND_BBT_NRBITS_MSK;
uint8_t msk = (uint8_t) ((1 << bits) - 1);
+ u32 marker_len;
+ int reserved_block_code = td->reserved_block_code;
totlen = (num * bits) >> 3;
+ marker_len = add_marker_len(td);
from = ((loff_t) page) << this->page_shift;
while (totlen) {
len = min(totlen, (size_t) (1 << this->bbt_erase_shift));
+ if (marker_len) {
+ /*
+ * In case the BBT marker is not in the OOB area it
+ * will be just in the first page.
+ */
+ len -= marker_len;
+ from += marker_len;
+ marker_len = 0;
+ }
res = mtd->read(mtd, from, len, &retlen, buf);
if (res < 0) {
if (retlen != len) {
}
/* Leave it for now, if its matured we can move this
* message to MTD_DEBUG_LEVEL0 */
- printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
- ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
+ MTDDEBUG(MTD_DEBUG_LEVEL0, "nand_read_bbt: Bad block at 0x%08x\n",
+ ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
/* Factory marked bad or worn out ? */
if (tmp == 0)
this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
{
struct nand_chip *this = mtd->priv;
int res = 0, i;
- int bits;
- bits = td->options & NAND_BBT_NRBITS_MSK;
if (td->options & NAND_BBT_PERCHIP) {
int offs = 0;
for (i = 0; i < this->numchips; i++) {
if (chip == -1 || chip == i)
- res = read_bbt (mtd, buf, td->pages[i], this->chipsize >> this->bbt_erase_shift, bits, offs, td->reserved_block_code);
+ res = read_bbt(mtd, buf, td->pages[i],
+ this->chipsize >> this->bbt_erase_shift,
+ td, offs);
if (res)
return res;
offs += this->chipsize >> (this->bbt_erase_shift + 2);
}
} else {
- res = read_bbt (mtd, buf, td->pages[0], mtd->size >> this->bbt_erase_shift, bits, 0, td->reserved_block_code);
+ res = read_bbt(mtd, buf, td->pages[0],
+ mtd->size >> this->bbt_erase_shift, td, 0);
if (res)
return res;
}
return 0;
}
+/*
+ * BBT marker is in the first page, no OOB.
+ */
+static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+ struct nand_bbt_descr *td)
+{
+ size_t retlen;
+ size_t len;
+
+ len = td->len;
+ if (td->options & NAND_BBT_VERSION)
+ len++;
+
+ return mtd->read(mtd, offs, len, &retlen, buf);
+}
+
/*
* Scan read raw data from flash
*/
-static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
size_t len)
{
struct mtd_oob_ops ops;
+ int res;
ops.mode = MTD_OOB_RAW;
ops.ooboffs = 0;
ops.ooblen = mtd->oobsize;
- ops.oobbuf = buf;
- ops.datbuf = buf;
- ops.len = len;
- return mtd->read_oob(mtd, offs, &ops);
+
+ while (len > 0) {
+ if (len <= mtd->writesize) {
+ ops.oobbuf = buf + len;
+ ops.datbuf = buf;
+ ops.len = len;
+ return mtd->read_oob(mtd, offs, &ops);
+ } else {
+ ops.oobbuf = buf + mtd->writesize;
+ ops.datbuf = buf;
+ ops.len = mtd->writesize;
+ res = mtd->read_oob(mtd, offs, &ops);
+
+ if (res)
+ return res;
+ }
+
+ buf += mtd->oobsize + mtd->writesize;
+ len -= mtd->writesize;
+ }
+ return 0;
+}
+
+static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
+ size_t len, struct nand_bbt_descr *td)
+{
+ if (td->options & NAND_BBT_NO_OOB)
+ return scan_read_raw_data(mtd, buf, offs, td);
+ else
+ return scan_read_raw_oob(mtd, buf, offs, len);
}
/*
return mtd->write_oob(mtd, offs, &ops);
}
+static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td)
+{
+ u32 ver_offs = td->veroffs;
+
+ if (!(td->options & NAND_BBT_NO_OOB))
+ ver_offs += mtd->writesize;
+ return ver_offs;
+}
+
/**
* read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
* @mtd: MTD device structure
/* Read the primary version, if available */
if (td->options & NAND_BBT_VERSION) {
scan_read_raw(mtd, buf, td->pages[0] << this->page_shift,
- mtd->writesize);
- td->version[0] = buf[mtd->writesize + td->veroffs];
+ mtd->writesize, td);
+ td->version[0] = buf[bbt_get_ver_offs(mtd, td)];
printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
td->pages[0], td->version[0]);
}
/* Read the mirror version, if available */
if (md && (md->options & NAND_BBT_VERSION)) {
scan_read_raw(mtd, buf, md->pages[0] << this->page_shift,
- mtd->writesize);
- md->version[0] = buf[mtd->writesize + md->veroffs];
+ mtd->writesize, td);
+ md->version[0] = buf[bbt_get_ver_offs(mtd, md)];
printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
md->pages[0], md->version[0]);
}
{
int ret, j;
- ret = scan_read_raw(mtd, buf, offs, readlen);
+ ret = scan_read_raw_oob(mtd, buf, offs, readlen);
if (ret)
return ret;
loff_t from;
size_t readlen;
- MTDDEBUG (MTD_DEBUG_LEVEL0, "Scanning device for bad blocks\n");
+ printk(KERN_INFO "Scanning device for bad blocks\n");
if (bd->options & NAND_BBT_SCANALLPAGES)
len = 1 << (this->bbt_erase_shift - this->page_shift);
- else {
- if (bd->options & NAND_BBT_SCAN2NDPAGE)
- len = 2;
- else
- len = 1;
- }
+ else if (bd->options & NAND_BBT_SCAN2NDPAGE)
+ len = 2;
+ else
+ len = 1;
if (!(bd->options & NAND_BBT_SCANEMPTY)) {
/* We need only read few bytes from the OOB area */
for (i = startblock; i < numblocks;) {
int ret;
+ BUG_ON(bd->options & NAND_BBT_NO_OOB);
+
if (bd->options & NAND_BBT_SCANALLPAGES)
ret = scan_block_full(mtd, bd, from, buf, readlen,
scanlen, len);
if (ret) {
this->bbt[i >> 3] |= 0x03 << (i & 0x6);
- MTDDEBUG (MTD_DEBUG_LEVEL0,
- "Bad eraseblock %d at 0x%08x\n",
- i >> 1, (unsigned int)from);
+ printk(KERN_WARNING "Bad eraseblock %d at 0x%012llx\n",
+ i >> 1, (unsigned long long)from);
mtd->ecc_stats.badblocks++;
}
loff_t offs = actblock << this->bbt_erase_shift;
/* Read first page */
- scan_read_raw(mtd, buf, offs, mtd->writesize);
+ scan_read_raw(mtd, buf, offs, mtd->writesize, td);
if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
td->pages[i] = actblock << blocktopage;
if (td->options & NAND_BBT_VERSION) {
- td->version[i] = buf[mtd->writesize + td->veroffs];
+ offs = bbt_get_ver_offs(mtd, td);
+ td->version[i] = buf[offs];
}
break;
}
if (td->pages[i] == -1)
printk(KERN_WARNING "Bad block table not found for chip %d\n", i);
else
- printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i],
- td->version[i]);
+ MTDDEBUG(MTD_DEBUG_LEVEL0,
+ "Bad block table found at page %d, version 0x%02X\n",
+ td->pages[i], td->version[i]);
}
return 0;
}
memset(&buf[offs], 0xff, (size_t) (numblocks >> sft));
ooboffs = len + (pageoffs * mtd->oobsize);
+ } else if (td->options & NAND_BBT_NO_OOB) {
+ ooboffs = 0;
+ offs = td->len;
+ /* the version byte */
+ if (td->options & NAND_BBT_VERSION)
+ offs++;
+ /* Calc length */
+ len = (size_t) (numblocks >> sft);
+ len += offs;
+ /* Make it page aligned ! */
+ len = ALIGN(len, mtd->writesize);
+ /* Preset the buffer with 0xff */
+ memset(buf, 0xff, len);
+ /* Pattern is located at the begin of first page */
+ memcpy(buf, td->pattern, td->len);
} else {
/* Calc length */
len = (size_t) (numblocks >> sft);
/* Make it page aligned ! */
- len = (len + (mtd->writesize - 1)) &
- ~(mtd->writesize - 1);
+ len = ALIGN(len, mtd->writesize);
/* Preset the buffer with 0xff */
memset(buf, 0xff, len +
(len >> this->page_shift)* mtd->oobsize);
if (res < 0)
goto outerr;
- res = scan_write_bbt(mtd, to, len, buf, &buf[len]);
+ res = scan_write_bbt(mtd, to, len, buf,
+ td->options & NAND_BBT_NO_OOB ? NULL :
+ &buf[len]);
if (res < 0)
goto outerr;
new ones have been marked, then we need to update the stored
bbts. This should only happen once. */
if (update && td->reserved_block_code)
- nand_update_bbt(mtd, (block - 2) << (this->bbt_erase_shift - 1));
+ nand_update_bbt(mtd, (loff_t)(block - 2) << (this->bbt_erase_shift - 1));
}
}
+/**
+ * verify_bbt_descr - verify the bad block description
+ * @mtd: MTD device structure
+ * @bd: the table to verify
+ *
+ * This functions performs a few sanity checks on the bad block description
+ * table.
+ */
+static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd)
+{
+ struct nand_chip *this = mtd->priv;
+ u32 pattern_len = bd->len;
+ u32 bits = bd->options & NAND_BBT_NRBITS_MSK;
+ u32 table_size;
+
+ if (!bd)
+ return;
+ BUG_ON((this->options & NAND_USE_FLASH_BBT_NO_OOB) &&
+ !(this->options & NAND_USE_FLASH_BBT));
+ BUG_ON(!bits);
+
+ if (bd->options & NAND_BBT_VERSION)
+ pattern_len++;
+
+ if (bd->options & NAND_BBT_NO_OOB) {
+ BUG_ON(!(this->options & NAND_USE_FLASH_BBT));
+ BUG_ON(!(this->options & NAND_USE_FLASH_BBT_NO_OOB));
+ BUG_ON(bd->offs);
+ if (bd->options & NAND_BBT_VERSION)
+ BUG_ON(bd->veroffs != bd->len);
+ BUG_ON(bd->options & NAND_BBT_SAVECONTENT);
+ }
+
+ if (bd->options & NAND_BBT_PERCHIP)
+ table_size = this->chipsize >> this->bbt_erase_shift;
+ else
+ table_size = mtd->size >> this->bbt_erase_shift;
+ table_size >>= 3;
+ table_size *= bits;
+ if (bd->options & NAND_BBT_NO_OOB)
+ table_size += pattern_len;
+ BUG_ON(table_size > (1 << this->bbt_erase_shift));
+}
+
/**
* nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s)
* @mtd: MTD device structure
}
return res;
}
+ verify_bbt_descr(mtd, td);
+ verify_bbt_descr(mtd, md);
/* Allocate a temporary buffer for one eraseblock incl. oob */
len = (1 << this->bbt_erase_shift);
if (!this->bbt || !td)
return -EINVAL;
- len = mtd->size >> (this->bbt_erase_shift + 2);
/* Allocate a temporary buffer for one eraseblock incl. oob */
len = (1 << this->bbt_erase_shift);
len += (len >> this->page_shift) * mtd->oobsize;
* while scanning a device for factory marked good / bad blocks. */
static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
-static struct nand_bbt_descr smallpage_memorybased = {
- .options = NAND_BBT_SCAN2NDPAGE,
- .offs = 5,
- .len = 1,
- .pattern = scan_ff_pattern
-};
-
-static struct nand_bbt_descr largepage_memorybased = {
- .options = 0,
- .offs = 0,
- .len = 2,
- .pattern = scan_ff_pattern
-};
-
static struct nand_bbt_descr smallpage_flashbased = {
.options = NAND_BBT_SCAN2NDPAGE,
- .offs = 5,
+ .offs = NAND_SMALL_BADBLOCK_POS,
.len = 1,
.pattern = scan_ff_pattern
};
static struct nand_bbt_descr largepage_flashbased = {
.options = NAND_BBT_SCAN2NDPAGE,
- .offs = 0,
+ .offs = NAND_LARGE_BADBLOCK_POS,
.len = 2,
.pattern = scan_ff_pattern
};
.pattern = mirror_pattern
};
+static struct nand_bbt_descr bbt_main_no_bbt_descr = {
+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+ | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
+ | NAND_BBT_NO_OOB,
+ .len = 4,
+ .veroffs = 4,
+ .maxblocks = 4,
+ .pattern = bbt_pattern
+};
+
+static struct nand_bbt_descr bbt_mirror_no_bbt_descr = {
+ .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
+ | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP
+ | NAND_BBT_NO_OOB,
+ .len = 4,
+ .veroffs = 4,
+ .maxblocks = 4,
+ .pattern = mirror_pattern
+};
+
+#define BBT_SCAN_OPTIONS (NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE | \
+ NAND_BBT_SCANBYTE1AND6)
+/**
+ * nand_create_default_bbt_descr - [Internal] Creates a BBT descriptor structure
+ * @this: NAND chip to create descriptor for
+ *
+ * This function allocates and initializes a nand_bbt_descr for BBM detection
+ * based on the properties of "this". The new descriptor is stored in
+ * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when
+ * passed to this function.
+ *
+ * TODO: Handle other flags, replace other static structs
+ * (e.g. handle NAND_BBT_FLASH for flash-based BBT,
+ * replace smallpage_flashbased)
+ *
+ */
+static int nand_create_default_bbt_descr(struct nand_chip *this)
+{
+ struct nand_bbt_descr *bd;
+ if (this->badblock_pattern) {
+ printk(KERN_WARNING "BBT descr already allocated; not replacing.\n");
+ return -EINVAL;
+ }
+ bd = kzalloc(sizeof(*bd), GFP_KERNEL);
+ if (!bd) {
+ printk(KERN_ERR "nand_create_default_bbt_descr: Out of memory\n");
+ return -ENOMEM;
+ }
+ bd->options = this->options & BBT_SCAN_OPTIONS;
+ bd->offs = this->badblockpos;
+ bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1;
+ bd->pattern = scan_ff_pattern;
+ bd->options |= NAND_BBT_DYNAMICSTRUCT;
+ this->badblock_pattern = bd;
+ return 0;
+}
+
/**
* nand_default_bbt - [NAND Interface] Select a default bad block table for the device
* @mtd: MTD device structure
if (this->options & NAND_USE_FLASH_BBT) {
/* Use the default pattern descriptors */
if (!this->bbt_td) {
- this->bbt_td = &bbt_main_descr;
- this->bbt_md = &bbt_mirror_descr;
+ if (this->options & NAND_USE_FLASH_BBT_NO_OOB) {
+ this->bbt_td = &bbt_main_no_bbt_descr;
+ this->bbt_md = &bbt_mirror_no_bbt_descr;
+ } else {
+ this->bbt_td = &bbt_main_descr;
+ this->bbt_md = &bbt_mirror_descr;
+ }
}
if (!this->badblock_pattern) {
this->badblock_pattern = (mtd->writesize > 512) ? &largepage_flashbased : &smallpage_flashbased;
} else {
this->bbt_td = NULL;
this->bbt_md = NULL;
- if (!this->badblock_pattern) {
- this->badblock_pattern = (mtd->writesize > 512) ?
- &largepage_memorybased : &smallpage_memorybased;
- }
+ if (!this->badblock_pattern)
+ nand_create_default_bbt_descr(this);
}
return nand_scan_bbt(mtd, this->badblock_pattern);
}
res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
MTDDEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: "
- "(block %d) 0x%02x\n", (unsigned int)offs, res, block >> 1);
+ "(block %d) 0x%02x\n", (unsigned int)offs, res, block >> 1);
switch ((int)res) {
case 0x00:
info->rxbd[i].cbd_bufaddr =
iomem_to_phys((ulong)info->rxbuf[i]);
#else
- info->rxbd[i].cbd_bufaddr = NetRxPackets[i];
+ info->rxbd[i].cbd_bufaddr = (ulong)NetRxPackets[i];
#endif
}
info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
unsigned int mxc_get_clock(enum mxc_clock clk);
void enet_board_init(void);
+
+extern int mxs_reset_block(volatile void *addr);
#endif
/*
/*
* Register base address
*/
-#define REGS_ICOL_BASE (0x80000000)
-#define REGS_HSADC_BASE (0x80002000)
-#define REGS_APBH_BASE (0x80004000)
-#define REGS_PERFMON_BASE (0x80006000)
-#define REGS_BCH_BASE (0x8000A000)
-#define REGS_GPMI_BASE (0x8000C000)
-#define REGS_SSP0_BASE (0x80010000)
-#define REGS_SSP1_BASE (0x80012000)
-#define REGS_SSP2_BASE (0x80014000)
-#define REGS_SSP3_BASE (0x80016000)
-#define REGS_PINCTRL_BASE (0x80018000)
-#define REGS_DIGCTL_BASE (0x8001C000)
-#define REGS_ETM_BASE (0x80022000)
-#define REGS_APBX_BASE (0x80024000)
-#define REGS_DCP_BASE (0x80028000)
-#define REGS_PXP_BASE (0x8002A000)
-#define REGS_OCOTP_BASE (0x8002C000)
-#define REGS_AXI_AHB0_BASE (0x8002E000)
-#define REGS_LCDIF_BASE (0x80030000)
-#define REGS_CAN0_BASE (0x80032000)
-#define REGS_CAN1_BASE (0x80034000)
-#define REGS_SIMDBG_BASE (0x8003C000)
-#define REGS_SIMGPMISEL_BASE (0x8003C200)
-#define REGS_SIMSSPSEL_BASE (0x8003C300)
-#define REGS_SIMMEMSEL_BASE (0x8003C400)
-#define REGS_GPIOMON_BASE (0x8003C500)
-#define REGS_SIMENET_BASE (0x8003C700)
-#define REGS_ARMJTAG_BASE (0x8003C800)
-#define REGS_CLKCTRL_BASE (0x80040000)
-#define REGS_SAIF0_BASE (0x80042000)
-#define REGS_POWER_BASE (0x80044000)
-#define REGS_SAIF1_BASE (0x80046000)
-#define REGS_LRADC_BASE (0x80050000)
-#define REGS_SPDIF_BASE (0x80054000)
-#define REGS_RTC_BASE (0x80056000)
-#define REGS_I2C0_BASE (0x80058000)
-#define REGS_I2C1_BASE (0x8005A000)
-#define REGS_PWM_BASE (0x80064000)
-#define REGS_TIMROT_BASE (0x80068000)
-#define REGS_UARTAPP0_BASE (0x8006A000)
-#define REGS_UARTAPP1_BASE (0x8006C000)
-#define REGS_UARTAPP2_BASE (0x8006E000)
-#define REGS_UARTAPP3_BASE (0x80070000)
-#define REGS_UARTAPP4_BASE (0x80072000)
-#define REGS_UARTDBG_BASE (0x80074000)
-#define REGS_USBPHY0_BASE (0x8007C000)
-#define REGS_USBPHY1_BASE (0x8007E000)
-#define REGS_USBCTRL0_BASE (0x80080000)
-#define REGS_USBCTRL1_BASE (0x80090000)
-#define REGS_DFLPT_BASE (0x800C0000)
-#define REGS_DRAM_BASE (0x800E0000)
-#define REGS_ENET_BASE (0x800F0000)
+#define REGS_ICOL_BASE 0x80000000
+#define REGS_HSADC_BASE 0x80002000
+#define REGS_APBH_BASE 0x80004000
+#define REGS_PERFMON_BASE 0x80006000
+#define REGS_BCH_BASE 0x8000A000
+#define REGS_GPMI_BASE 0x8000C000
+#define REGS_SSP0_BASE 0x80010000
+#define REGS_SSP1_BASE 0x80012000
+#define REGS_SSP2_BASE 0x80014000
+#define REGS_SSP3_BASE 0x80016000
+#define REGS_PINCTRL_BASE 0x80018000
+#define REGS_DIGCTL_BASE 0x8001C000
+#define REGS_ETM_BASE 0x80022000
+#define REGS_APBX_BASE 0x80024000
+#define REGS_DCP_BASE 0x80028000
+#define REGS_PXP_BASE 0x8002A000
+#define REGS_OCOTP_BASE 0x8002C000
+#define REGS_AXI_AHB0_BASE 0x8002E000
+#define REGS_LCDIF_BASE 0x80030000
+#define REGS_CAN0_BASE 0x80032000
+#define REGS_CAN1_BASE 0x80034000
+#define REGS_SIMDBG_BASE 0x8003C000
+#define REGS_SIMGPMISEL_BASE 0x8003C200
+#define REGS_SIMSSPSEL_BASE 0x8003C300
+#define REGS_SIMMEMSEL_BASE 0x8003C400
+#define REGS_GPIOMON_BASE 0x8003C500
+#define REGS_SIMENET_BASE 0x8003C700
+#define REGS_ARMJTAG_BASE 0x8003C800
+#define REGS_CLKCTRL_BASE 0x80040000
+#define REGS_SAIF0_BASE 0x80042000
+#define REGS_POWER_BASE 0x80044000
+#define REGS_SAIF1_BASE 0x80046000
+#define REGS_LRADC_BASE 0x80050000
+#define REGS_SPDIF_BASE 0x80054000
+#define REGS_RTC_BASE 0x80056000
+#define REGS_I2C0_BASE 0x80058000
+#define REGS_I2C1_BASE 0x8005A000
+#define REGS_PWM_BASE 0x80064000
+#define REGS_TIMROT_BASE 0x80068000
+#define REGS_UARTAPP0_BASE 0x8006A000
+#define REGS_UARTAPP1_BASE 0x8006C000
+#define REGS_UARTAPP2_BASE 0x8006E000
+#define REGS_UARTAPP3_BASE 0x80070000
+#define REGS_UARTAPP4_BASE 0x80072000
+#define REGS_UARTDBG_BASE 0x80074000
+#define REGS_USBPHY0_BASE 0x8007C000
+#define REGS_USBPHY1_BASE 0x8007E000
+#define REGS_USBCTRL0_BASE 0x80080000
+#define REGS_USBCTRL1_BASE 0x80090000
+#define REGS_DFLPT_BASE 0x800C0000
+#define REGS_DRAM_BASE 0x800E0000
+#define REGS_ENET_BASE 0x800F0000
+
+#define BCH_BASE_ADDR REGS_BCH_BASE
+#define GPMI_BASE_ADDR REGS_GPMI_BASE
+#define APBHDMA_BASE_ADDR REGS_APBH_BASE
+#define CLKCTRL_BASE_ADDR REGS_CLKCTRL_BASE
+
+#define MXS_SET_ADDR 0x04
+#define MXS_CLR_ADDR 0x08
+#define MXS_TOG_ADDR 0x0c
-#define BCH_BASE_ADDR REGS_BCH_BASE
-#define GPMI_BASE_ADDR REGS_GPMI_BASE
-#define ABPHDMA_BASE_ADDR REGS_APBH_BASE
#endif /* __MX28_H */
DMA_BIDIRECTIONAL = 0,
DMA_TO_DEVICE = 1,
DMA_FROM_DEVICE = 2,
+ DMA_NONE = 3,
};
static void *dma_alloc_coherent(size_t len, unsigned long *handle)
* linux/Documentation/IO-mapping.txt. If you want a
* physical address, use __ioremap instead.
*/
+#ifdef CONFIG_ARCH_MMU
extern void * __ioremap(unsigned long offset, size_t size, unsigned long flags);
extern void __iounmap(void *addr);
+#else
+static inline void *__ioremap(unsigned long offset, size_t size, unsigned long flags)
+{
+ return (void *)offset;
+}
+static inline void __iounmap(void *addr)
+{
+}
+#endif
/*
* Generic ioremap support.
*
* History:
*
* $Log$
- * Revision 1.1.3.2 2011-02-28 14:53:42 lothar
- * imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
+ * Revision 1.1.2.1 2011-06-14 08:40:02 lothar
+ * TX28 Release 2011-05-30
*
* Revision 1.3 2003/04/26 04:58:13 brad
* Cosmetic changes and compiler warning cleanups
*
*
* $Log$
- * Revision 1.1.3.2 2011-02-28 14:53:36 lothar
- * imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
+ * Revision 1.1.2.1 2011-06-14 08:40:05 lothar
+ * TX28 Release 2011-05-30
*
* Revision 1.21 2005/06/03 15:05:25 tsawyer
* MB rev 2.0.3 KA rev 0.0.7. Add CONFIG_VERSION_VARIABLE, Add fakeled to MB
*
* Last ChangeLog Entry
* $Log$
- * Revision 1.1.3.2 2011-02-28 14:53:37 lothar
- * imported Ka-Ro specific additions to U-Boot 2009.08 for TX28
+ * Revision 1.1.2.1 2011-06-14 08:40:09 lothar
+ * TX28 Release 2011-05-30
*
* Revision 1.2 2005/02/21 12:48:58 mleeman
* update of copyright years (feedback wd)
#define CONFIG_BOOTFILE "uImage"
#define CONFIG_BOOTARGS "console=ttyAM0,115200n8 "
#define CONFIG_BOOTCOMMAND "run bootcmd_net"
-#define CONFIG_LOADADDR 0x42000000
+#define CONFIG_LOADADDR 0x40100000
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
/*
* Extra Environments
*/
-#define CONFIG_EXTRA_ENV_SETTINGS \
- "nfsroot=/home/notroot/nfs/rootfs\0" \
- "bootargs_nfs=setenv bootargs ${bootargs} root=/dev/nfs " \
- "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp " \
- "fec_mac=${ethaddr}\0" \
- "bootcmd_net=run bootargs_nfs; dhcp; bootm\0" \
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "nfsroot=/home/notroot/nfs/rootfs\0" \
+ "bootargs_nfs=setenv bootargs ${bootargs} root=/dev/nfs " \
+ "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp " \
+ "fec_mac=${ethaddr}\0" \
+ "bootcmd_net=run bootargs_nfs; dhcp; bootm\0" \
"bootargs_mmc=setenv bootargs ${bootargs} root=/dev/mmcblk0p3 " \
- "rw rootwait ip=dhcp fec_mac=${ethaddr}\0" \
- "bootcmd_mmc=run bootargs_mmc; " \
- "mmc read 0 ${loadaddr} 100 3000; bootm\0" \
+ "rw rootwait ip=dhcp fec_mac=${ethaddr}\0" \
+ "bootcmd_mmc=run bootargs_mmc; " \
+ "mmc read 0 ${loadaddr} 100 3000; bootm\0" \
+ "mtdids=" MTDIDS_DEFAULT "\0" \
+ "mtdparts=" MTDPARTS_DEFAULT "\0" \
+
+#define MTDIDS_DEFAULT "nand0=gpmi-nfc"
+#define MTDPARTS_DEFAULT "mtdparts=gpmi-nfc:1m@0x40000(u-boot),4m(linux),16m(rootfs),-(userfs)\0" \
/*
* U-Boot Commands
#define CONFIG_BOOTP_GATEWAY
#define CONFIG_BOOTP_DNS
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_MTDPARTS
+
+/*
+ * NAND flash driver
+ */
+#ifdef CONFIG_CMD_NAND
+#define CONFIG_MTD_DEVICE
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_MXS_NAND
+#define CONFIG_SYS_MXS_DMA_CHANNEL 4
+#define CONFIG_SYS_MAX_FLASH_SECT 1024
+#define CONFIG_SYS_MAX_FLASH_BANKS 1
+#define CONFIG_SYS_NAND_MAX_CHIPS 1
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#ifdef CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_ENV_OFFSET 0x20000
+#define CONFIG_ENV_SIZE 0x20000 /* 128 KiB */
+#endif
+#ifndef CONFIG_SYS_NO_FLASH
+#define CONFIG_CMD_FLASH
+#define CONFIG_SYS_NAND_BASE 0xa0000000
+#define CONFIG_FIT
+#define CONFIG_OF_LIBFDT
+#else
+#define CONFIG_SYS_NAND_BASE 0x00000000
+#define CONFIG_CMD_ROMUPDATE
+#endif
+#endif /* CONFIG_CMD_NAND */
+
/*
* MMC Driver
*/
-#define CONFIG_CMD_MMC
+#ifdef CONFIG_CMD_MMC
+#ifndef CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_IS_IN_MMC
+#endif
#define CONFIG_MMC
#define CONFIG_IMX_SSP_MMC /* MMC driver based on SSP */
#define CONFIG_GENERIC_MMC
-#define CONFIG_SYS_MMC_ENV_DEV 0
#define CONFIG_DOS_PARTITION
#define CONFIG_CMD_FAT
-#define CONFIG_SYS_SSP_MMC_NUM 2
+#define CONFIG_SYS_SSP_MMC_NUM 1
#define CONFIG_BOOT_PARTITION_ACCESS
#define CONFIG_DOS_PARTITION
/*
* Environments on MMC
*/
+#ifdef CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV 0
#define CONFIG_CMD_ENV
#define CONFIG_ENV_OVERWRITE
-#define CONFIG_ENV_IS_IN_MMC
/* Assoiated with the MMC layout defined in mmcops.c */
#define CONFIG_ENV_OFFSET 0x400 /* 1 KB */
#define CONFIG_ENV_SIZE (0x20000 - 0x400) /* 127 KB */
#define CONFIG_DYNAMIC_MMC_DEVNO
+#endif /* CONFIG_ENV_IS_IN_MMC */
+#endif /* CONFIG_CMD_MMC */
/* The global boot mode will be detected by ROM code and
* a boot mode value will be stored at fixed address:
* NAND family Bad Block Management (BBM) header file
* - Bad Block Table (BBT) implementation
*
- * Copyright (c) 2005-2007 Samsung Electronics
+ * Copyright © 2005 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
*
- * Copyright (c) 2000-2005
+ * Copyright © 2000-2005
* Thomas Gleixner <tglx@linuxtronix.de>
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
*/
#ifndef __LINUX_MTD_BBM_H
#define __LINUX_MTD_BBM_H
/**
* struct nand_bbt_descr - bad block table descriptor
- * @param options options for this descriptor
- * @param pages the page(s) where we find the bbt, used with
- * option BBT_ABSPAGE when bbt is searched,
- * then we store the found bbts pages here.
- * Its an array and supports up to 8 chips now
- * @param offs offset of the pattern in the oob area of the page
- * @param veroffs offset of the bbt version counter in the oob are of the page
- * @param version version read from the bbt page during scan
- * @param len length of the pattern, if 0 no pattern check is performed
- * @param maxblocks maximum number of blocks to search for a bbt. This number of
- * blocks is reserved at the end of the device
- * where the tables are written.
- * @param reserved_block_code if non-0, this pattern denotes a reserved
- * (rather than bad) block in the stored bbt
- * @param pattern pattern to identify bad block table or factory marked
- * good / bad blocks, can be NULL, if len = 0
+ * @options: options for this descriptor
+ * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE
+ * when bbt is searched, then we store the found bbts pages here.
+ * Its an array and supports up to 8 chips now
+ * @offs: offset of the pattern in the oob area of the page
+ * @veroffs: offset of the bbt version counter in the oob are of the page
+ * @version: version read from the bbt page during scan
+ * @len: length of the pattern, if 0 no pattern check is performed
+ * @maxblocks: maximum number of blocks to search for a bbt. This number of
+ * blocks is reserved at the end of the device where the tables are
+ * written.
+ * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than
+ * bad) block in the stored bbt
+ * @pattern: pattern to identify bad block table or factory marked good /
+ * bad blocks, can be NULL, if len = 0
*
* Descriptor for the bad block table marker and the descriptor for the
* pattern which identifies good and bad blocks. The assumption is made
#define NAND_BBT_PERCHIP 0x00000080
/* bbt has a version counter at offset veroffs */
#define NAND_BBT_VERSION 0x00000100
-/* Create a bbt if none axists */
+/* Create a bbt if none exists */
#define NAND_BBT_CREATE 0x00000200
/* Search good / bad pattern through all pages of a block */
#define NAND_BBT_SCANALLPAGES 0x00000400
#define NAND_BBT_SAVECONTENT 0x00002000
/* Search good / bad pattern on the first and the second page */
#define NAND_BBT_SCAN2NDPAGE 0x00004000
+/* Search good / bad pattern on the last page of the eraseblock */
+#define NAND_BBT_SCANLASTPAGE 0x00008000
+/* Chip stores bad block marker on BOTH 1st and 6th bytes of OOB */
+#define NAND_BBT_SCANBYTE1AND6 0x00100000
+/* The nand_bbt_descr was created dynamicaly and must be freed */
+#define NAND_BBT_DYNAMICSTRUCT 0x00200000
+/* The bad block table does not OOB for marker */
+#define NAND_BBT_NO_OOB 0x00400000
/* The maximum number of blocks to scan for a bbt */
#define NAND_BBT_SCAN_MAXBLOCKS 4
/*
* Constants for oob configuration
*/
-#define ONENAND_BADBLOCK_POS 0
+#define NAND_SMALL_BADBLOCK_POS 5
+#define NAND_LARGE_BADBLOCK_POS 0
+#define ONENAND_BADBLOCK_POS 0
/*
* Bad block scanning errors
*/
-#define ONENAND_BBT_READ_ERROR 1
-#define ONENAND_BBT_READ_ECC_ERROR 2
-#define ONENAND_BBT_READ_FATAL_ERROR 4
+#define ONENAND_BBT_READ_ERROR 1
+#define ONENAND_BBT_READ_ECC_ERROR 2
+#define ONENAND_BBT_READ_FATAL_ERROR 4
/**
- * struct bbt_info - [GENERIC] Bad Block Table data structure
- * @param bbt_erase_shift [INTERN] number of address bits in a bbt entry
- * @param badblockpos [INTERN] position of the bad block marker in the oob area
- * @param bbt [INTERN] bad block table pointer
- * @param badblock_pattern [REPLACEABLE] bad block scan pattern used for initial bad block scan
- * @param priv [OPTIONAL] pointer to private bbm date
+ * struct bbm_info - [GENERIC] Bad Block Table data structure
+ * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
+ * @badblockpos: [INTERN] position of the bad block marker in the oob area
+ * @options: options for this descriptor
+ * @bbt: [INTERN] bad block table pointer
+ * @isbad_bbt: function to determine if a block is bad
+ * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for
+ * initial bad block scan
+ * @priv: [OPTIONAL] pointer to private bbm date
*/
struct bbm_info {
int bbt_erase_shift;
uint8_t *bbt;
- int (*isbad_bbt) (struct mtd_info * mtd, loff_t ofs, int allowbbt);
+ int (*isbad_bbt)(struct mtd_info *mtd, loff_t ofs, int allowbbt);
/* TODO Add more NAND specific fileds */
struct nand_bbt_descr *badblock_pattern;
};
/* OneNAND BBT interface */
-extern int onenand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd);
-extern int onenand_default_bbt (struct mtd_info *mtd);
+extern int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd);
+extern int onenand_default_bbt(struct mtd_info *mtd);
-#endif /* __LINUX_MTD_BBM_H */
+#endif /* __LINUX_MTD_BBM_H */
#include "linux/mtd/mtd.h"
#include "linux/mtd/bbm.h"
-
struct mtd_info;
/* Scan and identify a NAND device */
extern int nand_scan (struct mtd_info *mtd, int max_chips);
/* This option is defined if the board driver allocates its own buffers
(e.g. because it needs them DMA-coherent */
#define NAND_OWN_BUFFERS 0x00040000
+/*
+ * If passed additionally to NAND_USE_FLASH_BBT then BBT code will not touch
+ * the OOB area.
+ */
+#define NAND_USE_FLASH_BBT_NO_OOB 0x00100000
/* Options set by nand scan */
/* bbt has already been read */
#define NAND_BBT_SCANNED 0x40000000
return chip->priv;
}
-
#endif /* __LINUX_MTD_NAND_H */
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
-extern int board_nand_init(struct nand_chip *nand);
+extern int board_nand_init(struct mtd_info *mtd, struct nand_chip *nand);
typedef struct mtd_info nand_info_t;
printf("raise: Signal # %d caught\n", signum);
return 0;
}
+
+/* Dummy function to avoid linker complaints */
+void __aeabi_unwind_cpp_pr0(void)
+{
+}
continue;
}
#ifdef CONFIG_SYS_64BIT_VSPRINTF
- if (qualifier == 'L') /* "quad" for 64 bit variables */
- num = va_arg(args, unsigned long long);
+#ifndef GCC_VERSION
+#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
+#endif
+ if (qualifier == 'L') /* "quad" for 64 bit variables */
+#if GCC_VERSION <= 3003 || GCC_VERSION > 4004
+ /* gcc 3.3.2 handles this correctly
+ * at least gcc >= 4.3.4 and <= 4.4.1 misalign long long arguments on stack!
+ */
+ num = va_arg(args, long long);
+#else
+#define get_addr(arg) ({ \
+ unsigned long __sp; \
+ asm volatile ("mov %0, %1" : "=r"(__sp) : "r"(arg)); \
+ __sp; \
+ })
+ /* workaround for broken gcc */
+ {
+ if (!(get_addr(args) & 0x7))
+ num = va_arg(args, long);
+ num = va_arg(args, long);
+ num |= (unsigned long long)va_arg(args, long) << 32;
+ }
+#endif
else
#endif
if (qualifier == 'l') {