Skip to content
This repository has been archived by the owner on Dec 14, 2020. It is now read-only.

Commit

Permalink
Add support for newer flash chips in latest RT-N66U hardware revision
Browse files Browse the repository at this point in the history
  • Loading branch information
RMerl committed Jul 11, 2013
1 parent 91976d8 commit 3504e69
Showing 1 changed file with 44 additions and 45 deletions.
89 changes: 44 additions & 45 deletions release/src-rt/linux/linux-2.6/drivers/mtd/chips/cfi_cmdset_0002.c
Expand Up @@ -162,9 +162,17 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
struct cfi_pri_amdstd *extp = cfi->cmdset_priv;

if (cfi->cfiq->BufWriteTimeoutTyp) {
DEBUG(MTD_DEBUG_LEVEL1, "Using buffer write method\n" );
mtd->write = cfi_amdstd_write_buffers;

if (extp->SiliconRevision >= 0x1C) {
mtd->writesize = 512;
mtd->flags &= ~MTD_BIT_WRITEABLE;
printk(KERN_INFO "Enabling Spansion 65nm mode, writesize = 512 bytes\n");
}
}
}

Expand Down Expand Up @@ -294,7 +302,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
}

if (extp->MajorVersion < '0' || extp->MajorVersion > '3' ||
(extp->MinorVersion < '0' || extp->MinorVersion > '4')) {
(extp->MinorVersion < '0' || extp->MinorVersion > '5')) {
if (cfi->mfr == MANUFACTURER_SAMSUNG &&
((extp->MajorVersion == '3' && extp->MinorVersion == '3') ||
(extp->MajorVersion == '0'))) {
Expand Down Expand Up @@ -1247,21 +1255,18 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
}


/*
* FIXME: interleaved mode not tested, and probably not supported!
*/
static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
unsigned long adr, const u_char *buf,
int len)
{
struct cfi_private *cfi = map->fldrv_priv;
unsigned long timeo = jiffies + HZ;
/* see comments in do_write_oneword() regarding uWriteTimeo. */
unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
/* see comments in do_write_oneword() regarding uWriteTimeout, 20ms */
unsigned long uWriteTimeout = ( HZ / 50 ) + 1;
int ret = -EIO;
unsigned long cmd_adr;
int z, words;
map_word datum;
int z, words, prolog, epilog, buflen = len;
map_word datum, pdat, edat;

adr += chip->start;
cmd_adr = adr;
Expand All @@ -1282,6 +1287,21 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
ENABLE_VPP(map);
xip_disable(map, chip, cmd_adr);

/* If start is not bus-aligned, prepend old contents of flash */
prolog = (adr & (map_bankwidth(map)-1));
if (prolog) {
adr -= prolog;
cmd_adr -= prolog;
len += prolog;
pdat = map_read(map, adr);
}
/* If end is not bus-aligned, append old contents of flash */
epilog = ((adr + len) & (map_bankwidth(map)-1));
if (epilog) {
len += map_bankwidth(map)-epilog;
edat = map_read(map, adr + len - map_bankwidth(map));
}

cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
//cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
Expand All @@ -1296,8 +1316,19 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
map_write(map, CMD(words - 1), cmd_adr);
/* Write data */
z = 0;
if (prolog) {
datum = map_word_load_partial(map, pdat, buf, prolog,
min_t(int, buflen, map_bankwidth(map) - prolog));
map_write(map, datum, adr);

z += map_bankwidth(map);
buf += map_bankwidth(map) - prolog;
}
while(z < words * map_bankwidth(map)) {
datum = map_word_load(map, buf);
if (epilog && z >= (words-1) * map_bankwidth(map))
datum = map_word_load_partial(map, edat, buf, 0, epilog);
else
datum = map_word_load(map, buf);
map_write(map, datum, adr + z);

z += map_bankwidth(map);
Expand Down Expand Up @@ -1346,8 +1377,10 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,

/* reset on all failures. */
map_write( map, CMD(0xF0), chip->start );
cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
xip_enable(map, chip, adr);
/* FIXME - should have reset delay before continuing */

printk(KERN_WARNING "MTD %s(): software timeout\n",
__func__ );
Expand Down Expand Up @@ -1379,36 +1412,12 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
chipnum = to >> cfi->chipshift;
ofs = to - (chipnum << cfi->chipshift);

/* If it's not bus-aligned, do the first word write */
if (ofs & (map_bankwidth(map)-1)) {
size_t local_len = (-ofs)&(map_bankwidth(map)-1);
if (local_len > len)
local_len = len;
ret = cfi_amdstd_write_words(mtd, ofs + (chipnum<<cfi->chipshift),
local_len, retlen, buf);
if (ret)
return ret;
ofs += local_len;
buf += local_len;
len -= local_len;

if (ofs >> cfi->chipshift) {
chipnum ++;
ofs = 0;
if (chipnum == cfi->numchips)
return 0;
}
}

/* Write buffer is worth it only if more than one word to write... */
while (len >= map_bankwidth(map) * 2) {
while (len) {
/* We must not cross write block boundaries */
int size = wbufsize - (ofs & (wbufsize-1));

if (size > len)
size = len;
if (size % map_bankwidth(map))
size -= size % map_bankwidth(map);

ret = do_write_buffer(map, &cfi->chips[chipnum],
ofs, buf, size);
Expand All @@ -1428,16 +1437,6 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
}
}

if (len) {
size_t retlen_dregs = 0;

ret = cfi_amdstd_write_words(mtd, ofs + (chipnum<<cfi->chipshift),
len, &retlen_dregs, buf);

*retlen += retlen_dregs;
return ret;
}

return 0;
}

Expand Down

0 comments on commit 3504e69

Please sign in to comment.