Au1200 and NAND Flash - K9F1G08U0A -
Hi,
We want to use NAND flash on Alchemy Au1200 and have a custom board along with Db1200; so tried it both on our custom board and Db1200 without success. (Because Db1200 has a slot we opened it and replaced the original with our part)
Kernel -> 2.6.20.1. Error messages:
NAND device: Manufacturer ID: 0xec, Chip ID: 0xf1 (Samsung NAND 128MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 0 at 0x00000000
Bad eraseblock 1 at 0x00020000
...
Bad eraseblock 1022 at 0x07fc0000
Bad eraseblock 1023 at 0x07fe0000
Creating 2 MTD partitions on "NAND 128MiB 3,3V 8-bit":
It marks all the eraseblocks as BAD. As far as I understand "au1xxx_nand_command" seems doesnt work correctly. Has someone succeded to work with these large block parts in the Au1200/Au1550?
Thanks...
--
Bora SAHIN
Hi Bora,
I have the same problem here.
Did you find a solution for this nand large page device.
I tried to copy nand_command_lp from nand_base.c and added the -CE stuff including disabling interrupts during read.
The result is that I found just one bad block during scan :-). Also erasing nand seems to be possible (usinf eraseall /dev/mtdX). But if I write and read back the data (using dd) I get io errors :-(
I found your posting on this list wihout an answer so I hope you was able to manage the nand stuff.
Kind Regards,
Frank
Am Samstag, den 19.05.2007, 22:13 +0300 schrieb [email protected]:
Quoted 27 lines
Hi,
We want to use NAND flash on Alchemy Au1200 and have a custom board along with Db1200; so tried it both on our custom board and Db1200 without success. (Because Db1200 has a slot we opened it and replaced the original with our part)
Kernel -> 2.6.20.1. Error messages:
NAND device: Manufacturer ID:
0xec, Chip ID:0xf1(Samsung NAND 128MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 0 at0x00000000
Bad eraseblock 1 at0x00020000
...
Bad eraseblock 1022 at0x07fc0000
Bad eraseblock 1023 at0x07fe0000
Creating 2 MTD partitions on "NAND 128MiB 3,3V 8-bit":It marks all the eraseblocks as BAD. As far as I understand "
au1xxx_nand_command" seems doesnt work correctly. Has someone succeded to work with these large block parts in the Au1200/Au1550?Thanks...
--
Bora SAHIN
Quoted 11 lines · Frank Neuber
Hi Bora,
I have the same problem here.
Did you find a solution for this nand large page device.
I tried to copynand_command_lpfromnand_base.cand added the -CE stuff including disabling interrupts during read.
The result is that I found just one bad block during scan :-). Also erasing nand seems to be possible (usinf eraseall/dev/mtdX). But if I write and read back the data (using dd) I get io errors :-(I found your posting on this list wihout an answer so I hope you was able to manage the nand stuff.
Here's the NAND portion of a DB1200 board support rewrite I did a while ago. It uses gen_nand instead of the au1550nd.c driver (which seems to only work on the Db1550 and small page devices). It shouls also work on any Au1550 since the Au1200 has identical NAND hardware.
---------- 8< --------------------------- 8< ---------------------
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
[...]
static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
unsigned int ctrl)
{
struct nand_chip *this = mtd->priv;
unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
ioaddr &= 0xffffff00;
if (ctrl & NAND_CLE) {
ioaddr += MEM_STNAND_CMD;
} else if (ctrl & NAND_ALE) {
ioaddr += MEM_STNAND_ADDR;
} else {
/* assume we want to r/w real data by default */
ioaddr += MEM_STNAND_DATA;
}
this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
if (cmd != NAND_CMD_NONE) {
au_writeb(cmd, ioaddr);
au_sync();
}
}static int au1200_nand_device_ready(struct mtd_info *mtd)
{
return au_readl(MEM_STSTAT) & 1;
}static const char *db1200_part_probes[] = { "cmdlinepart", NULL };
static struct mtd_partition db1200_nand_parts[] = {
{
.name = "NAND FS 0",
.offset = 0,
.size = 8 * 1024 * 1024,
},
{
.name = "NAND FS 1",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL
},
};struct platform_nand_data db1200_nand_platdata = {
.chip = {
.nr_chips = 1,
.chip_offset = 0,
.nr_partitions = ARRAY_SIZE(db1200_nand_parts),
.partitions = db1200_nand_parts,
.chip_delay = 20,
.part_probe_types = db1200_part_probes,
},
.ctrl = {
.hwcontrol = 0,
.dev_ready = au1200_nand_device_ready,
.select_chip = 0,
.cmd_ctrl = au1200_nand_cmd_ctrl,
},
};static struct resource db1200_nand_res[] = {
[0] = {
.start = 0x20000000,
.end = 0x200000ff,
.flags = IORESOURCE_MEM,
},
};static struct platform_device nand_dev = {
.name = "gen_nand",
.num_resources = ARRAY_SIZE(db1200_nand_res),
.resource = db1200_nand_res,
.id = -1,
.dev = {
.platform_data = &db1200_nand_platdata,
}
};[...]
static struct platform_device *db1200_devs[] __initdata = {
[...]
&nand_dev,
[...]
};
-------------------- 8< ------------------------ 8< -------------------
Best regards,
Manuel Lauss
Thank you for this very quick answer ...
Am Donnerstag, den 12.02.2009, 09:17 +0100 schrieb Manuel Lauss:
Quoted 2 lines
Here's the NAND portion of a DB1200 board support rewrite I did a while ago. It uses
gen_nandinstead of theau1550nd.cdriver (which seems to
I saw this gen_nand (plat_nand.c) never before (because it is not configurable in the Makefile)
Quoted 2 lines
only work on the Db1550 and small page devices). It shouls also work on any Au1550 since the Au1200 has identical NAND hardware.
Do I understand right, this is not a handmade patch aginst plat_nand.c ?
I try to mix this code now with the plat_nand.c, rigth?
Kind regards,
Frank
Quoted 102 lines
---------- 8< --------------------------- 8< ---------------------
#include <
linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>[...]
static void au1200_nand_cmd_ctrl(struct
mtd_info*mtd, int cmd,
unsigned int ctrl){ struct nand_chip *this = mtd->priv; unsigned long ioaddr = (unsigned long)this->IO_ADDR_W; ioaddr &= 0xffffff00; if (ctrl & NAND_CLE) { ioaddr += MEM_STNAND_CMD; } else if (ctrl & NAND_ALE) { ioaddr += MEM_STNAND_ADDR; } else { /* assume we want to r/w real data by default */ ioaddr += MEM_STNAND_DATA; } this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr; if (cmd != NAND_CMD_NONE) { au_writeb(cmd, ioaddr); au_sync(); } }static int
au1200_nand_device_ready(struct mtd_info *mtd){ return au_readl(MEM_STSTAT) & 1; }static const char *db1200_part_probes[] = { "cmdlinepart", NULL };
static struct mtd_partition db1200_nand_parts[] = { { .name = "NAND FS 0", .offset = 0, .size = 8 * 1024 * 1024, }, { .name = "NAND FS 1", .offset = MTDPART_OFS_APPEND, .size = MTDPART_SIZ_FULL }, };struct platform_nand_data db1200_nand_platdata = { .chip = { .nr_chips = 1, .chip_offset = 0, .nr_partitions = ARRAY_SIZE(db1200_nand_parts), .partitions = db1200_nand_parts, .chip_delay = 20, .part_probe_types = db1200_part_probes, }, .ctrl = { .hwcontrol = 0, .dev_ready = au1200_nand_device_ready, .select_chip = 0, .cmd_ctrl = au1200_nand_cmd_ctrl, }, };static struct resource db1200_nand_res[] = { [0] = { .start = 0x20000000, .end = 0x200000ff, .flags = IORESOURCE_MEM, }, };static struct platform_device nand_dev = { .name = "gen_nand", .num_resources = ARRAY_SIZE(db1200_nand_res), .resource = db1200_nand_res, .id = -1, .dev = { .platform_data = &db1200_nand_platdata, } };[...]
static struct
platform_device*db1200_devs[]__initdata= {
[...]&nand_dev,[...]
};-------------------- 8< ------------------------ 8< -------------------
Best regards,
Manuel Lauss
Quoted 8 lines · Frank Neuber
Thank you for this very quick answer ...
Am Donnerstag, den 12.02.2009, 09:17 +0100 schrieb Manuel Lauss:
Quoted 2 lines
Here's the NAND portion of a DB1200 board support rewrite I did a while ago. It uses
gen_nandinstead of theau1550nd.cdriver (which seems toI saw this
gen_nand(plat_nand.c) never before (because it is not configurable in theMakefile)
Quoted 6 lines
Quoted 2 lines
only work on the Db1550 and small page devices). It shouls also work on any Au1550 since the Au1200 has identical NAND hardware.
Do I understand right, this is not a handmade patch aginst
plat_nand.c?I try to mix this code now with the
plat_nand.c, rigth?
No no no no: this belongs in your board code (board_setup.c or whatever you call it). It's nothing more than registration of a platform_device plus required information/callbacks for the gen_nand driver.
Manuel Lauss
Hi Manuel,
thank you for the code. It is working perfect :-) I added this in arch/mips/au1000/common/platform.c. 1,94 MByte/s read performance.
I think it is a good idea to remove the au1550nd.c.
Thank's again,
Frank
Am Donnerstag, den 12.02.2009, 09:53 +0100 schrieb Manuel Lauss:
Quoted 21 lines · Frank Neuber
Quoted 8 lines
Thank you for this very quick answer ...
Am Donnerstag, den 12.02.2009, 09:17 +0100 schrieb Manuel Lauss:
Quoted 2 lines
Here's the NAND portion of a DB1200 board support rewrite I did a while ago. It uses
gen_nandinstead of theau1550nd.cdriver (which seems toI saw this
gen_nand(plat_nand.c) never before (because it is not configurable in theMakefile)Quoted 6 lines
Quoted 2 lines
only work on the Db1550 and small page devices). It shouls also work on any Au1550 since the Au1200 has identical NAND hardware.
Do I understand right, this is not a handmade patch aginst
plat_nand.c?I try to mix this code now with the
plat_nand.c, rigth?No no no no: this belongs in your board code (
board_setup.cor whatever you call it). It's nothing more than registration of aplatform_deviceplus required information/callbacks for thegen_nanddriver.Manuel Lauss