aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/au1550nd.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 839b35a386b6..d9a0143e1d3a 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -14,6 +14,7 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/interrupt.h>
17#include <linux/mtd/mtd.h> 18#include <linux/mtd/mtd.h>
18#include <linux/mtd/nand.h> 19#include <linux/mtd/nand.h>
19#include <linux/mtd/partitions.h> 20#include <linux/mtd/partitions.h>
@@ -318,6 +319,141 @@ int au1550_device_ready(struct mtd_info *mtd)
318 return ret; 319 return ret;
319} 320}
320 321
322/**
323 * au1550_select_chip - control -CE line
324 * Forbid driving -CE manually permitting the NAND controller to do this.
325 * Keeping -CE asserted during the whole sector reads interferes with the
326 * NOR flash and PCMCIA drivers as it causes contention on the static bus.
327 * We only have to hold -CE low for the NAND read commands since the flash
328 * chip needs it to be asserted during chip not ready time but the NAND
329 * controller keeps it released.
330 *
331 * @mtd: MTD device structure
332 * @chip: chipnumber to select, -1 for deselect
333 */
334static void au1550_select_chip(struct mtd_info *mtd, int chip)
335{
336}
337
338/**
339 * au1550_command - Send command to NAND device
340 * @mtd: MTD device structure
341 * @command: the command to be sent
342 * @column: the column address for this command, -1 if none
343 * @page_addr: the page address for this command, -1 if none
344 */
345static void au1550_command(struct mtd_info *mtd, unsigned command, int column, int page_addr)
346{
347 register struct nand_chip *this = mtd->priv;
348 int ce_override = 0, i;
349 ulong flags;
350
351 /* Begin command latch cycle */
352 this->hwcontrol(mtd, NAND_CTL_SETCLE);
353 /*
354 * Write out the command to the device.
355 */
356 if (command == NAND_CMD_SEQIN) {
357 int readcmd;
358
359 if (column >= mtd->oobblock) {
360 /* OOB area */
361 column -= mtd->oobblock;
362 readcmd = NAND_CMD_READOOB;
363 } else if (column < 256) {
364 /* First 256 bytes --> READ0 */
365 readcmd = NAND_CMD_READ0;
366 } else {
367 column -= 256;
368 readcmd = NAND_CMD_READ1;
369 }
370 this->write_byte(mtd, readcmd);
371 }
372 this->write_byte(mtd, command);
373
374 /* Set ALE and clear CLE to start address cycle */
375 this->hwcontrol(mtd, NAND_CTL_CLRCLE);
376
377 if (column != -1 || page_addr != -1) {
378 this->hwcontrol(mtd, NAND_CTL_SETALE);
379
380 /* Serially input address */
381 if (column != -1) {
382 /* Adjust columns for 16 bit buswidth */
383 if (this->options & NAND_BUSWIDTH_16)
384 column >>= 1;
385 this->write_byte(mtd, column);
386 }
387 if (page_addr != -1) {
388 this->write_byte(mtd, (u8)(page_addr & 0xff));
389
390 if (command == NAND_CMD_READ0 ||
391 command == NAND_CMD_READ1 ||
392 command == NAND_CMD_READOOB) {
393 /*
394 * NAND controller will release -CE after
395 * the last address byte is written, so we'll
396 * have to forcibly assert it. No interrupts
397 * are allowed while we do this as we don't
398 * want the NOR flash or PCMCIA drivers to
399 * steal our precious bytes of data...
400 */
401 ce_override = 1;
402 local_irq_save(flags);
403 this->hwcontrol(mtd, NAND_CTL_SETNCE);
404 }
405
406 this->write_byte(mtd, (u8)(page_addr >> 8));
407
408 /* One more address cycle for devices > 32MiB */
409 if (this->chipsize > (32 << 20))
410 this->write_byte(mtd, (u8)((page_addr >> 16) & 0x0f));
411 }
412 /* Latch in address */
413 this->hwcontrol(mtd, NAND_CTL_CLRALE);
414 }
415
416 /*
417 * Program and erase have their own busy handlers.
418 * Status and sequential in need no delay.
419 */
420 switch (command) {
421
422 case NAND_CMD_PAGEPROG:
423 case NAND_CMD_ERASE1:
424 case NAND_CMD_ERASE2:
425 case NAND_CMD_SEQIN:
426 case NAND_CMD_STATUS:
427 return;
428
429 case NAND_CMD_RESET:
430 break;
431
432 case NAND_CMD_READ0:
433 case NAND_CMD_READ1:
434 case NAND_CMD_READOOB:
435 /* Check if we're really driving -CE low (just in case) */
436 if (unlikely(!ce_override))
437 break;
438
439 /* Apply a short delay always to ensure that we do wait tWB. */
440 ndelay(100);
441 /* Wait for a chip to become ready... */
442 for (i = this->chip_delay; !this->dev_ready(mtd) && i > 0; --i)
443 udelay(1);
444
445 /* Release -CE and re-enable interrupts. */
446 this->hwcontrol(mtd, NAND_CTL_CLRNCE);
447 local_irq_restore(flags);
448 return;
449 }
450 /* Apply this short delay always to ensure that we do wait tWB. */
451 ndelay(100);
452
453 while(!this->dev_ready(mtd));
454}
455
456
321/* 457/*
322 * Main initialization routine 458 * Main initialization routine
323 */ 459 */
@@ -437,6 +573,9 @@ static int __init au1xxx_nand_init(void)
437 /* Set address of hardware control function */ 573 /* Set address of hardware control function */
438 this->hwcontrol = au1550_hwcontrol; 574 this->hwcontrol = au1550_hwcontrol;
439 this->dev_ready = au1550_device_ready; 575 this->dev_ready = au1550_device_ready;
576 this->select_chip = au1550_select_chip;
577 this->cmdfunc = au1550_command;
578
440 /* 30 us command delay time */ 579 /* 30 us command delay time */
441 this->chip_delay = 30; 580 this->chip_delay = 30;
442 this->eccmode = NAND_ECC_SOFT; 581 this->eccmode = NAND_ECC_SOFT;