aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/au1550nd.c
diff options
context:
space:
mode:
authorPete Popov <ppopov@pacbell.net>2005-09-22 21:44:58 -0400
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-11-06 16:29:02 -0500
commitef6f0d1ffcd86484e01cec4fd2d2c5ca5887a43b (patch)
treeb69f78393c0c5f719e1fe0bcaccb467b126fc1a4 /drivers/mtd/nand/au1550nd.c
parent733802d974e5af42acb7cd61b16c0ce6dd03b7ed (diff)
[MTD] NAND: Alchemy board driver cleanup
- cleaned up the partitions and include files - added more flexible CS and address detection and setup Regression tested on db1200 and db1550. Signed-off-by: Pete Popov <ppopov@pacbell.net> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/mtd/nand/au1550nd.c')
-rw-r--r--drivers/mtd/nand/au1550nd.c115
1 files changed, 69 insertions, 46 deletions
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 4c7719ce3f48..953daf379b9b 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2004 Embedded Edge, LLC 4 * Copyright (C) 2004 Embedded Edge, LLC
5 * 5 *
6 * $Id: au1550nd.c,v 1.11 2004/11/04 12:53:10 gleixner Exp $ 6 * $Id: au1550nd.c,v 1.12 2005/09/23 01:44:55 ppopov Exp $
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -21,13 +21,7 @@
21 21
22/* fixme: this is ugly */ 22/* fixme: this is ugly */
23#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0) 23#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0)
24#include <asm/mach-au1x00/au1000.h> 24#include <asm/mach-au1x00/au1xxx.h>
25#ifdef CONFIG_MIPS_PB1550
26#include <asm/mach-pb1x00/pb1550.h>
27#endif
28#ifdef CONFIG_MIPS_DB1550
29#include <asm/mach-db1x00/db1x00.h>
30#endif
31#else 25#else
32#include <asm/au1000.h> 26#include <asm/au1000.h>
33#ifdef CONFIG_MIPS_PB1550 27#ifdef CONFIG_MIPS_PB1550
@@ -45,39 +39,22 @@ static struct mtd_info *au1550_mtd = NULL;
45static void __iomem *p_nand; 39static void __iomem *p_nand;
46static int nand_width = 1; /* default x8*/ 40static int nand_width = 1; /* default x8*/
47 41
48#define NAND_CS 1
49
50/* 42/*
51 * Define partitions for flash device 43 * Define partitions for flash device
52 */ 44 */
53const static struct mtd_partition partition_info[] = { 45const static struct mtd_partition partition_info[] = {
54#ifdef CONFIG_MIPS_PB1550
55#define NUM_PARTITIONS 2
56 {
57 .name = "Pb1550 NAND FS 0",
58 .offset = 0,
59 .size = 8*1024*1024
60 },
61 {
62 .name = "Pb1550 NAND FS 1",
63 .offset = MTDPART_OFS_APPEND,
64 .size = MTDPART_SIZ_FULL
65 }
66#endif
67#ifdef CONFIG_MIPS_DB1550
68#define NUM_PARTITIONS 2
69 { 46 {
70 .name = "Db1550 NAND FS 0", 47 .name = "NAND FS 0",
71 .offset = 0, 48 .offset = 0,
72 .size = 8*1024*1024 49 .size = 8*1024*1024
73 }, 50 },
74 { 51 {
75 .name = "Db1550 NAND FS 1", 52 .name = "NAND FS 1",
76 .offset = MTDPART_OFS_APPEND, 53 .offset = MTDPART_OFS_APPEND,
77 .size = MTDPART_SIZ_FULL 54 .size = MTDPART_SIZ_FULL
78 } 55 }
79#endif
80}; 56};
57#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
81 58
82 59
83/** 60/**
@@ -339,11 +316,13 @@ int au1550_device_ready(struct mtd_info *mtd)
339/* 316/*
340 * Main initialization routine 317 * Main initialization routine
341 */ 318 */
342int __init au1550_init (void) 319int __init au1xxx_nand_init (void)
343{ 320{
344 struct nand_chip *this; 321 struct nand_chip *this;
345 u16 boot_swapboot = 0; /* default value */ 322 u16 boot_swapboot = 0; /* default value */
346 int retval; 323 int retval;
324 u32 mem_staddr;
325 u32 nand_phys;
347 326
348 /* Allocate memory for MTD device structure and private data */ 327 /* Allocate memory for MTD device structure and private data */
349 au1550_mtd = kmalloc (sizeof(struct mtd_info) + 328 au1550_mtd = kmalloc (sizeof(struct mtd_info) +
@@ -364,8 +343,11 @@ int __init au1550_init (void)
364 au1550_mtd->priv = this; 343 au1550_mtd->priv = this;
365 344
366 345
367 /* MEM_STNDCTL: disable ints, disable nand boot */ 346 /* disable interrupts */
368 au_writel(0, MEM_STNDCTL); 347 au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL);
348
349 /* disable NAND boot */
350 au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL);
369 351
370#ifdef CONFIG_MIPS_PB1550 352#ifdef CONFIG_MIPS_PB1550
371 /* set gpio206 high */ 353 /* set gpio206 high */
@@ -397,19 +379,60 @@ int __init au1550_init (void)
397 } 379 }
398#endif 380#endif
399 381
400 /* Configure RCE1 - should be done by YAMON */ 382 /* Configure chip-select; normally done by boot code, e.g. YAMON */
401 au_writel(0x5 | (nand_width << 22), 0xB4001010); /* MEM_STCFG1 */ 383#ifdef NAND_STCFG
402 au_writel(NAND_TIMING, 0xB4001014); /* MEM_STTIME1 */ 384 if (NAND_CS == 0) {
403 au_sync(); 385 au_writel(NAND_STCFG, MEM_STCFG0);
386 au_writel(NAND_STTIME, MEM_STTIME0);
387 au_writel(NAND_STADDR, MEM_STADDR0);
388 }
389 if (NAND_CS == 1) {
390 au_writel(NAND_STCFG, MEM_STCFG1);
391 au_writel(NAND_STTIME, MEM_STTIME1);
392 au_writel(NAND_STADDR, MEM_STADDR1);
393 }
394 if (NAND_CS == 2) {
395 au_writel(NAND_STCFG, MEM_STCFG2);
396 au_writel(NAND_STTIME, MEM_STTIME2);
397 au_writel(NAND_STADDR, MEM_STADDR2);
398 }
399 if (NAND_CS == 3) {
400 au_writel(NAND_STCFG, MEM_STCFG3);
401 au_writel(NAND_STTIME, MEM_STTIME3);
402 au_writel(NAND_STADDR, MEM_STADDR3);
403 }
404#endif
405
406 /* Locate NAND chip-select in order to determine NAND phys address */
407 mem_staddr = 0x00000000;
408 if (((au_readl(MEM_STCFG0) & 0x7) == 0x5) && (NAND_CS == 0))
409 mem_staddr = au_readl(MEM_STADDR0);
410 else if (((au_readl(MEM_STCFG1) & 0x7) == 0x5) && (NAND_CS == 1))
411 mem_staddr = au_readl(MEM_STADDR1);
412 else if (((au_readl(MEM_STCFG2) & 0x7) == 0x5) && (NAND_CS == 2))
413 mem_staddr = au_readl(MEM_STADDR2);
414 else if (((au_readl(MEM_STCFG3) & 0x7) == 0x5) && (NAND_CS == 3))
415 mem_staddr = au_readl(MEM_STADDR3);
416
417 if (mem_staddr == 0x00000000) {
418 printk("Au1xxx NAND: ERROR WITH NAND CHIP-SELECT\n");
419 kfree(au1550_mtd);
420 return 1;
421 }
422 nand_phys = (mem_staddr << 4) & 0xFFFC0000;
404 423
405 /* setup and enable chip select, MEM_STADDR1 */ 424 p_nand = (void __iomem *)ioremap(nand_phys, 0x1000);
406 /* we really need to decode offsets only up till 0x20 */ 425
407 au_writel((1<<28) | (NAND_PHYS_ADDR>>4) | 426 /* make controller and MTD agree */
408 (((NAND_PHYS_ADDR + 0x1000)-1) & (0x3fff<<18)>>18), 427 if (NAND_CS == 0)
409 MEM_STADDR1); 428 nand_width = au_readl(MEM_STCFG0) & (1<<22);
410 au_sync(); 429 if (NAND_CS == 1)
430 nand_width = au_readl(MEM_STCFG1) & (1<<22);
431 if (NAND_CS == 2)
432 nand_width = au_readl(MEM_STCFG2) & (1<<22);
433 if (NAND_CS == 3)
434 nand_width = au_readl(MEM_STCFG3) & (1<<22);
411 435
412 p_nand = ioremap(NAND_PHYS_ADDR, 0x1000);
413 436
414 /* Set address of hardware control function */ 437 /* Set address of hardware control function */
415 this->hwcontrol = au1550_hwcontrol; 438 this->hwcontrol = au1550_hwcontrol;
@@ -438,7 +461,7 @@ int __init au1550_init (void)
438 } 461 }
439 462
440 /* Register the partitions */ 463 /* Register the partitions */
441 add_mtd_partitions(au1550_mtd, partition_info, NUM_PARTITIONS); 464 add_mtd_partitions(au1550_mtd, partition_info, NB_OF(partition_info));
442 465
443 return 0; 466 return 0;
444 467
@@ -450,7 +473,7 @@ int __init au1550_init (void)
450 return retval; 473 return retval;
451} 474}
452 475
453module_init(au1550_init); 476module_init(au1xxx_nand_init);
454 477
455/* 478/*
456 * Clean up routine 479 * Clean up routine