#include <asm/io.h>
#include <asm/errno.h>
+/* It should access 16-bit instead of 8-bit */
+static inline void *memcpy_16(void *dst, const void *src, unsigned int len)
+{
+ void *ret = dst;
+ short *d = dst;
+ const short *s = src;
+
+ len >>= 1;
+ while (len-- > 0)
+ *d++ = *s++;
+ return ret;
+}
+
static const unsigned char ffchars[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 16 */
ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);
if (ctrl & ONENAND_CTRL_ERROR) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_wait: controller error = 0x%04x\n", ctrl);
+ MTDDEBUG (MTD_DEBUG_LEVEL0,
+ "onenand_wait: controller error = 0x%04x\n", ctrl);
return -EAGAIN;
}
if (ctrl & ONENAND_CTRL_LOCK) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_wait: it's locked error = 0x%04x\n", ctrl);
+ MTDDEBUG (MTD_DEBUG_LEVEL0,
+ "onenand_wait: it's locked error = 0x%04x\n", ctrl);
return -EIO;
}
if (interrupt & ONENAND_INT_READ) {
ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);
if (ecc & ONENAND_ECC_2BIT_ALL) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_wait: ECC error = 0x%04x\n", ecc);
+ MTDDEBUG (MTD_DEBUG_LEVEL0,
+ "onenand_wait: ECC error = 0x%04x\n", ecc);
return -EBADMSG;
}
}
bufferram = this->base + area;
bufferram += onenand_bufferram_offset(mtd, area);
- memcpy(buffer, bufferram + offset, count);
+ memcpy_16(buffer, bufferram + offset, count);
return 0;
}
this->mmcontrol(mtd, ONENAND_SYS_CFG1_SYNC_READ);
- memcpy(buffer, bufferram + offset, count);
+ memcpy_16(buffer, bufferram + offset, count);
this->mmcontrol(mtd, 0);
bufferram = this->base + area;
bufferram += onenand_bufferram_offset(mtd, area);
- memcpy(bufferram + offset, buffer, count);
+ memcpy_16(bufferram + offset, buffer, count);
return 0;
}
int thislen;
int ret = 0;
- DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_ecc: from = 0x%08x, len = %i\n",
- (unsigned int)from, (int)len);
+ MTDDEBUG (MTD_DEBUG_LEVEL3, "onenand_read_ecc: "
+ "from = 0x%08x, len = %i\n",
+ (unsigned int)from, (int)len);
/* Do not allow reads past end of device */
if ((from + len) > mtd->size) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_read_ecc: Attempt read beyond end of device\n");
+ MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_read_ecc: "
+ "Attempt read beyond end of device\n");
*retlen = 0;
return -EINVAL;
}
break;
if (ret) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_read_ecc: read failed = %d\n", ret);
+ MTDDEBUG (MTD_DEBUG_LEVEL0,
+ "onenand_read_ecc: read failed = %d\n", ret);
break;
}
int read = 0, thislen, column;
int ret = 0;
- DEBUG(MTD_DEBUG_LEVEL3, "onenand_read_oob: from = 0x%08x, len = %i\n",
- (unsigned int)from, (int)len);
+ MTDDEBUG (MTD_DEBUG_LEVEL3, "onenand_read_oob: "
+ "from = 0x%08x, len = %i\n",
+ (unsigned int)from, (int)len);
/* Initialize return length value */
*retlen = 0;
/* Do not allow reads past end of device */
if (unlikely((from + len) > mtd->size)) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_read_oob: Attempt read beyond end of device\n");
+ MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_read_oob: "
+ "Attempt read beyond end of device\n");
return -EINVAL;
}
break;
if (ret) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_read_oob: read failed = %d\n", ret);
+ MTDDEBUG (MTD_DEBUG_LEVEL0,
+ "onenand_read_oob: read failed = %d\n", ret);
break;
}
int written = 0;
int ret = 0;
- DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_ecc: to = 0x%08x, len = %i\n",
- (unsigned int)to, (int)len);
+ MTDDEBUG (MTD_DEBUG_LEVEL3, "onenand_write_ecc: "
+ "to = 0x%08x, len = %i\n",
+ (unsigned int)to, (int)len);
/* Initialize retlen, in case of early exit */
*retlen = 0;
/* Do not allow writes past end of device */
if (unlikely((to + len) > mtd->size)) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_write_ecc: Attempt write to past end of device\n");
+ MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_write_ecc: "
+ "Attempt write to past end of device\n");
return -EINVAL;
}
/* Reject writes, which are not page aligned */
if (unlikely(NOTALIGNED(to)) || unlikely(NOTALIGNED(len))) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_write_ecc: Attempt to write not page aligned data\n");
+ MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_write_ecc: "
+ "Attempt to write not page aligned data\n");
return -EINVAL;
}
ret = this->wait(mtd, FL_WRITING);
if (ret) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_write_ecc: write filaed %d\n", ret);
+ MTDDEBUG (MTD_DEBUG_LEVEL0,
+ "onenand_write_ecc: write filaed %d\n", ret);
break;
}
/* Only check verify write turn on */
ret = onenand_verify_page(mtd, (u_char *) buf, to, block, page);
if (ret) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_write_ecc: verify failed %d\n", ret);
+ MTDDEBUG (MTD_DEBUG_LEVEL0,
+ "onenand_write_ecc: verify failed %d\n", ret);
break;
}
int column, status;
int written = 0;
- DEBUG(MTD_DEBUG_LEVEL3, "onenand_write_oob: to = 0x%08x, len = %i\n",
- (unsigned int)to, (int)len);
+ MTDDEBUG (MTD_DEBUG_LEVEL3, "onenand_write_oob: "
+ "to = 0x%08x, len = %i\n",
+ (unsigned int)to, (int)len);
/* Initialize retlen, in case of early exit */
*retlen = 0;
/* Do not allow writes past end of device */
if (unlikely((to + len) > mtd->size)) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_write_oob: Attempt write to past end of device\n");
+ MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_write_oob: "
+ "Attempt write to past end of device\n");
return -EINVAL;
}
int len;
int ret = 0;
- DEBUG(MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n",
- (unsigned int)instr->addr, (unsigned int)instr->len);
+ MTDDEBUG (MTD_DEBUG_LEVEL3, "onenand_erase: start = 0x%08x, len = %i\n",
+ (unsigned int)instr->addr, (unsigned int)instr->len);
block_size = (1 << this->erase_shift);
/* Start address must align on block boundary */
if (unlikely(instr->addr & (block_size - 1))) {
- DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Unaligned address\n");
+ MTDDEBUG (MTD_DEBUG_LEVEL0,
+ "onenand_erase: Unaligned address\n");
return -EINVAL;
}
/* Length must align on block boundary */
if (unlikely(instr->len & (block_size - 1))) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_erase: Length not block aligned\n");
+ MTDDEBUG (MTD_DEBUG_LEVEL0,
+ "onenand_erase: Length not block aligned\n");
return -EINVAL;
}
/* Do not allow erase past end of device */
if (unlikely((instr->len + instr->addr) > mtd->size)) {
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_erase: Erase past end of device\n");
+ MTDDEBUG (MTD_DEBUG_LEVEL0,
+ "onenand_erase: Erase past end of device\n");
return -EINVAL;
}
/* Check, if it is write protected */
if (ret) {
if (ret == -EPERM)
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_erase: Device is write protected!!!\n");
+ MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_erase: "
+ "Device is write protected!!!\n");
else
- DEBUG(MTD_DEBUG_LEVEL0,
- "onenand_erase: Failed erase, block %d\n",
- (unsigned)(addr >> this->erase_shift));
+ MTDDEBUG (MTD_DEBUG_LEVEL0, "onenand_erase: "
+ "Failed erase, block %d\n",
+ (unsigned)(addr >> this->erase_shift));
instr->state = MTD_ERASE_FAILED;
instr->fail_addr = addr;
goto erase_exit;
*/
void onenand_sync(struct mtd_info *mtd)
{
- DEBUG(MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
+ MTDDEBUG (MTD_DEBUG_LEVEL3, "onenand_sync: called\n");
/* Grab the lock and see if the device is available */
onenand_get_device(mtd, FL_SYNCING);
if (maf_id != bram_maf_id || dev_id != bram_dev_id)
return -ENXIO;
+ /* FIXME : Current OneNAND MTD doesn't support Flex-OneNAND */
+ if (dev_id & (1 << 9)) {
+ printk("Not yet support Flex-OneNAND\n");
+ return -ENXIO;
+ }
+
/* Flash device information */
onenand_print_device_info(dev_id, 0);
this->device_id = dev_id;
{
}
-/*
- * OneNAND initialization at U-Boot
- */
-struct mtd_info onenand_mtd;
-struct onenand_chip onenand_chip;
-
-void onenand_init(void)
-{
- memset(&onenand_mtd, 0, sizeof(struct mtd_info));
- memset(&onenand_chip, 0, sizeof(struct onenand_chip));
-
- onenand_chip.base = (void *)CFG_ONENAND_BASE;
- onenand_mtd.priv = &onenand_chip;
-
- onenand_scan(&onenand_mtd, 1);
-
- puts("OneNAND: ");
- print_size(onenand_mtd.size, "\n");
-}
-
#endif /* CONFIG_CMD_ONENAND */