aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/au1550nd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/au1550nd.c')
-rw-r--r--drivers/mtd/nand/au1550nd.c143
1 files changed, 73 insertions, 70 deletions
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index bde3550910a2..50cbfd4826fb 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -38,22 +38,20 @@
38 */ 38 */
39static struct mtd_info *au1550_mtd = NULL; 39static struct mtd_info *au1550_mtd = NULL;
40static void __iomem *p_nand; 40static void __iomem *p_nand;
41static int nand_width = 1; /* default x8*/ 41static int nand_width = 1; /* default x8 */
42 42
43/* 43/*
44 * Define partitions for flash device 44 * Define partitions for flash device
45 */ 45 */
46static const struct mtd_partition partition_info[] = { 46static const struct mtd_partition partition_info[] = {
47 { 47 {
48 .name = "NAND FS 0", 48 .name = "NAND FS 0",
49 .offset = 0, 49 .offset = 0,
50 .size = 8*1024*1024 50 .size = 8 * 1024 * 1024},
51 },
52 { 51 {
53 .name = "NAND FS 1", 52 .name = "NAND FS 1",
54 .offset = MTDPART_OFS_APPEND, 53 .offset = MTDPART_OFS_APPEND,
55 .size = MTDPART_SIZ_FULL 54 .size = MTDPART_SIZ_FULL}
56 }
57}; 55};
58 56
59/** 57/**
@@ -157,7 +155,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
157 int i; 155 int i;
158 struct nand_chip *this = mtd->priv; 156 struct nand_chip *this = mtd->priv;
159 157
160 for (i=0; i<len; i++) { 158 for (i = 0; i < len; i++) {
161 writeb(buf[i], this->IO_ADDR_W); 159 writeb(buf[i], this->IO_ADDR_W);
162 au_sync(); 160 au_sync();
163 } 161 }
@@ -176,7 +174,7 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
176 int i; 174 int i;
177 struct nand_chip *this = mtd->priv; 175 struct nand_chip *this = mtd->priv;
178 176
179 for (i=0; i<len; i++) { 177 for (i = 0; i < len; i++) {
180 buf[i] = readb(this->IO_ADDR_R); 178 buf[i] = readb(this->IO_ADDR_R);
181 au_sync(); 179 au_sync();
182 } 180 }
@@ -195,7 +193,7 @@ static int au_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
195 int i; 193 int i;
196 struct nand_chip *this = mtd->priv; 194 struct nand_chip *this = mtd->priv;
197 195
198 for (i=0; i<len; i++) { 196 for (i = 0; i < len; i++) {
199 if (buf[i] != readb(this->IO_ADDR_R)) 197 if (buf[i] != readb(this->IO_ADDR_R))
200 return -EFAULT; 198 return -EFAULT;
201 au_sync(); 199 au_sync();
@@ -219,7 +217,7 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
219 u16 *p = (u16 *) buf; 217 u16 *p = (u16 *) buf;
220 len >>= 1; 218 len >>= 1;
221 219
222 for (i=0; i<len; i++) { 220 for (i = 0; i < len; i++) {
223 writew(p[i], this->IO_ADDR_W); 221 writew(p[i], this->IO_ADDR_W);
224 au_sync(); 222 au_sync();
225 } 223 }
@@ -241,7 +239,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
241 u16 *p = (u16 *) buf; 239 u16 *p = (u16 *) buf;
242 len >>= 1; 240 len >>= 1;
243 241
244 for (i=0; i<len; i++) { 242 for (i = 0; i < len; i++) {
245 p[i] = readw(this->IO_ADDR_R); 243 p[i] = readw(this->IO_ADDR_R);
246 au_sync(); 244 au_sync();
247 } 245 }
@@ -262,7 +260,7 @@ static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
262 u16 *p = (u16 *) buf; 260 u16 *p = (u16 *) buf;
263 len >>= 1; 261 len >>= 1;
264 262
265 for (i=0; i<len; i++) { 263 for (i = 0; i < len; i++) {
266 if (p[i] != readw(this->IO_ADDR_R)) 264 if (p[i] != readw(this->IO_ADDR_R))
267 return -EFAULT; 265 return -EFAULT;
268 au_sync(); 266 au_sync();
@@ -275,27 +273,35 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
275{ 273{
276 register struct nand_chip *this = mtd->priv; 274 register struct nand_chip *this = mtd->priv;
277 275
278 switch(cmd){ 276 switch (cmd) {
277
278 case NAND_CTL_SETCLE:
279 this->IO_ADDR_W = p_nand + MEM_STNAND_CMD;
280 break;
281
282 case NAND_CTL_CLRCLE:
283 this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
284 break;
279 285
280 case NAND_CTL_SETCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_CMD; break; 286 case NAND_CTL_SETALE:
281 case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break; 287 this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR;
288 break;
282 289
283 case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break;
284 case NAND_CTL_CLRALE: 290 case NAND_CTL_CLRALE:
285 this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; 291 this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
286 /* FIXME: Nobody knows why this is neccecary, 292 /* FIXME: Nobody knows why this is necessary,
287 * but it works only that way */ 293 * but it works only that way */
288 udelay(1); 294 udelay(1);
289 break; 295 break;
290 296
291 case NAND_CTL_SETNCE: 297 case NAND_CTL_SETNCE:
292 /* assert (force assert) chip enable */ 298 /* assert (force assert) chip enable */
293 au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break; 299 au_writel((1 << (4 + NAND_CS)), MEM_STNDCTL);
294 break; 300 break;
295 301
296 case NAND_CTL_CLRNCE: 302 case NAND_CTL_CLRNCE:
297 /* deassert chip enable */ 303 /* deassert chip enable */
298 au_writel(0, MEM_STNDCTL); break; 304 au_writel(0, MEM_STNDCTL);
299 break; 305 break;
300 } 306 }
301 307
@@ -315,66 +321,63 @@ int au1550_device_ready(struct mtd_info *mtd)
315/* 321/*
316 * Main initialization routine 322 * Main initialization routine
317 */ 323 */
318int __init au1xxx_nand_init (void) 324int __init au1xxx_nand_init(void)
319{ 325{
320 struct nand_chip *this; 326 struct nand_chip *this;
321 u16 boot_swapboot = 0; /* default value */ 327 u16 boot_swapboot = 0; /* default value */
322 int retval; 328 int retval;
323 u32 mem_staddr; 329 u32 mem_staddr;
324 u32 nand_phys; 330 u32 nand_phys;
325 331
326 /* Allocate memory for MTD device structure and private data */ 332 /* Allocate memory for MTD device structure and private data */
327 au1550_mtd = kmalloc (sizeof(struct mtd_info) + 333 au1550_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
328 sizeof (struct nand_chip), GFP_KERNEL);
329 if (!au1550_mtd) { 334 if (!au1550_mtd) {
330 printk ("Unable to allocate NAND MTD dev structure.\n"); 335 printk("Unable to allocate NAND MTD dev structure.\n");
331 return -ENOMEM; 336 return -ENOMEM;
332 } 337 }
333 338
334 /* Get pointer to private data */ 339 /* Get pointer to private data */
335 this = (struct nand_chip *) (&au1550_mtd[1]); 340 this = (struct nand_chip *)(&au1550_mtd[1]);
336 341
337 /* Initialize structures */ 342 /* Initialize structures */
338 memset((char *) au1550_mtd, 0, sizeof(struct mtd_info)); 343 memset(au1550_mtd, 0, sizeof(struct mtd_info));
339 memset((char *) this, 0, sizeof(struct nand_chip)); 344 memset(this, 0, sizeof(struct nand_chip));
340 345
341 /* Link the private data with the MTD structure */ 346 /* Link the private data with the MTD structure */
342 au1550_mtd->priv = this; 347 au1550_mtd->priv = this;
343 348
344
345 /* disable interrupts */ 349 /* disable interrupts */
346 au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL); 350 au_writel(au_readl(MEM_STNDCTL) & ~(1 << 8), MEM_STNDCTL);
347 351
348 /* disable NAND boot */ 352 /* disable NAND boot */
349 au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL); 353 au_writel(au_readl(MEM_STNDCTL) & ~(1 << 0), MEM_STNDCTL);
350 354
351#ifdef CONFIG_MIPS_PB1550 355#ifdef CONFIG_MIPS_PB1550
352 /* set gpio206 high */ 356 /* set gpio206 high */
353 au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR); 357 au_writel(au_readl(GPIO2_DIR) & ~(1 << 6), GPIO2_DIR);
354 358
355 boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) | 359 boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr->status >> 6) & 0x1);
356 ((bcsr->status >> 6) & 0x1);
357 switch (boot_swapboot) { 360 switch (boot_swapboot) {
358 case 0: 361 case 0:
359 case 2: 362 case 2:
360 case 8: 363 case 8:
361 case 0xC: 364 case 0xC:
362 case 0xD: 365 case 0xD:
363 /* x16 NAND Flash */ 366 /* x16 NAND Flash */
364 nand_width = 0; 367 nand_width = 0;
365 break; 368 break;
366 case 1: 369 case 1:
367 case 9: 370 case 9:
368 case 3: 371 case 3:
369 case 0xE: 372 case 0xE:
370 case 0xF: 373 case 0xF:
371 /* x8 NAND Flash */ 374 /* x8 NAND Flash */
372 nand_width = 1; 375 nand_width = 1;
373 break; 376 break;
374 default: 377 default:
375 printk("Pb1550 NAND: bad boot:swap\n"); 378 printk("Pb1550 NAND: bad boot:swap\n");
376 retval = -EINVAL; 379 retval = -EINVAL;
377 goto outmem; 380 goto outmem;
378 } 381 }
379#endif 382#endif
380 383
@@ -424,14 +427,13 @@ int __init au1xxx_nand_init (void)
424 427
425 /* make controller and MTD agree */ 428 /* make controller and MTD agree */
426 if (NAND_CS == 0) 429 if (NAND_CS == 0)
427 nand_width = au_readl(MEM_STCFG0) & (1<<22); 430 nand_width = au_readl(MEM_STCFG0) & (1 << 22);
428 if (NAND_CS == 1) 431 if (NAND_CS == 1)
429 nand_width = au_readl(MEM_STCFG1) & (1<<22); 432 nand_width = au_readl(MEM_STCFG1) & (1 << 22);
430 if (NAND_CS == 2) 433 if (NAND_CS == 2)
431 nand_width = au_readl(MEM_STCFG2) & (1<<22); 434 nand_width = au_readl(MEM_STCFG2) & (1 << 22);
432 if (NAND_CS == 3) 435 if (NAND_CS == 3)
433 nand_width = au_readl(MEM_STCFG3) & (1<<22); 436 nand_width = au_readl(MEM_STCFG3) & (1 << 22);
434
435 437
436 /* Set address of hardware control function */ 438 /* Set address of hardware control function */
437 this->hwcontrol = au1550_hwcontrol; 439 this->hwcontrol = au1550_hwcontrol;
@@ -454,7 +456,7 @@ int __init au1xxx_nand_init (void)
454 this->verify_buf = (!nand_width) ? au_verify_buf16 : au_verify_buf; 456 this->verify_buf = (!nand_width) ? au_verify_buf16 : au_verify_buf;
455 457
456 /* Scan to find existence of the device */ 458 /* Scan to find existence of the device */
457 if (nand_scan (au1550_mtd, 1)) { 459 if (nand_scan(au1550_mtd, 1)) {
458 retval = -ENXIO; 460 retval = -ENXIO;
459 goto outio; 461 goto outio;
460 } 462 }
@@ -465,10 +467,10 @@ int __init au1xxx_nand_init (void)
465 return 0; 467 return 0;
466 468
467 outio: 469 outio:
468 iounmap ((void *)p_nand); 470 iounmap((void *)p_nand);
469 471
470 outmem: 472 outmem:
471 kfree (au1550_mtd); 473 kfree(au1550_mtd);
472 return retval; 474 return retval;
473} 475}
474 476
@@ -478,19 +480,20 @@ module_init(au1xxx_nand_init);
478 * Clean up routine 480 * Clean up routine
479 */ 481 */
480#ifdef MODULE 482#ifdef MODULE
481static void __exit au1550_cleanup (void) 483static void __exit au1550_cleanup(void)
482{ 484{
483 struct nand_chip *this = (struct nand_chip *) &au1550_mtd[1]; 485 struct nand_chip *this = (struct nand_chip *)&au1550_mtd[1];
484 486
485 /* Release resources, unregister device */ 487 /* Release resources, unregister device */
486 nand_release (au1550_mtd); 488 nand_release(au1550_mtd);
487 489
488 /* Free the MTD device structure */ 490 /* Free the MTD device structure */
489 kfree (au1550_mtd); 491 kfree(au1550_mtd);
490 492
491 /* Unmap */ 493 /* Unmap */
492 iounmap ((void *)p_nand); 494 iounmap((void *)p_nand);
493} 495}
496
494module_exit(au1550_cleanup); 497module_exit(au1550_cleanup);
495#endif 498#endif
496 499