OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [mtd/] [devices/] [doc2001.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
 
2
/*
3
 * Linux driver for Disk-On-Chip Millennium
4
 * (c) 1999 Machine Vision Holdings, Inc.
5
 * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
6
 *
7
 * $Id: doc2001.c,v 1.49 2005/11/07 11:14:24 gleixner Exp $
8
 */
9
 
10
#include <linux/kernel.h>
11
#include <linux/module.h>
12
#include <asm/errno.h>
13
#include <asm/io.h>
14
#include <asm/uaccess.h>
15
#include <linux/miscdevice.h>
16
#include <linux/delay.h>
17
#include <linux/slab.h>
18
#include <linux/init.h>
19
#include <linux/types.h>
20
#include <linux/bitops.h>
21
 
22
#include <linux/mtd/mtd.h>
23
#include <linux/mtd/nand.h>
24
#include <linux/mtd/doc2000.h>
25
 
26
/* #define ECC_DEBUG */
27
 
28
/* I have no idea why some DoC chips can not use memcop_form|to_io().
29
 * This may be due to the different revisions of the ASIC controller built-in or
30
 * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment
31
 * this:*/
32
#undef USE_MEMCPY
33
 
34
static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
35
                    size_t *retlen, u_char *buf);
36
static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
37
                     size_t *retlen, const u_char *buf);
38
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
39
                        struct mtd_oob_ops *ops);
40
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
41
                         struct mtd_oob_ops *ops);
42
static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
43
 
44
static struct mtd_info *docmillist = NULL;
45
 
46
/* Perform the required delay cycles by reading from the NOP register */
47
static void DoC_Delay(void __iomem * docptr, unsigned short cycles)
48
{
49
        volatile char dummy;
50
        int i;
51
 
52
        for (i = 0; i < cycles; i++)
53
                dummy = ReadDOC(docptr, NOP);
54
}
55
 
56
/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
57
static int _DoC_WaitReady(void __iomem * docptr)
58
{
59
        unsigned short c = 0xffff;
60
 
61
        DEBUG(MTD_DEBUG_LEVEL3,
62
              "_DoC_WaitReady called for out-of-line wait\n");
63
 
64
        /* Out-of-line routine to wait for chip response */
65
        while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B) && --c)
66
                ;
67
 
68
        if (c == 0)
69
                DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
70
 
71
        return (c == 0);
72
}
73
 
74
static inline int DoC_WaitReady(void __iomem * docptr)
75
{
76
        /* This is inline, to optimise the common case, where it's ready instantly */
77
        int ret = 0;
78
 
79
        /* 4 read form NOP register should be issued in prior to the read from CDSNControl
80
           see Software Requirement 11.4 item 2. */
81
        DoC_Delay(docptr, 4);
82
 
83
        if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
84
                /* Call the out-of-line routine to wait */
85
                ret = _DoC_WaitReady(docptr);
86
 
87
        /* issue 2 read from NOP register after reading from CDSNControl register
88
           see Software Requirement 11.4 item 2. */
89
        DoC_Delay(docptr, 2);
90
 
91
        return ret;
92
}
93
 
94
/* DoC_Command: Send a flash command to the flash chip through the CDSN IO register
95
   with the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
96
   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
97
 
98
static void DoC_Command(void __iomem * docptr, unsigned char command,
99
                               unsigned char xtraflags)
100
{
101
        /* Assert the CLE (Command Latch Enable) line to the flash chip */
102
        WriteDOC(xtraflags | CDSN_CTRL_CLE | CDSN_CTRL_CE, docptr, CDSNControl);
103
        DoC_Delay(docptr, 4);
104
 
105
        /* Send the command */
106
        WriteDOC(command, docptr, Mil_CDSN_IO);
107
        WriteDOC(0x00, docptr, WritePipeTerm);
108
 
109
        /* Lower the CLE line */
110
        WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
111
        DoC_Delay(docptr, 4);
112
}
113
 
114
/* DoC_Address: Set the current address for the flash chip through the CDSN IO register
115
   with the internal pipeline. Each of 4 delay cycles (read from the NOP register) is
116
   required after writing to CDSN Control register, see Software Requirement 11.4 item 3. */
117
 
118
static inline void DoC_Address(void __iomem * docptr, int numbytes, unsigned long ofs,
119
                               unsigned char xtraflags1, unsigned char xtraflags2)
120
{
121
        /* Assert the ALE (Address Latch Enable) line to the flash chip */
122
        WriteDOC(xtraflags1 | CDSN_CTRL_ALE | CDSN_CTRL_CE, docptr, CDSNControl);
123
        DoC_Delay(docptr, 4);
124
 
125
        /* Send the address */
126
        switch (numbytes)
127
            {
128
            case 1:
129
                    /* Send single byte, bits 0-7. */
130
                    WriteDOC(ofs & 0xff, docptr, Mil_CDSN_IO);
131
                    WriteDOC(0x00, docptr, WritePipeTerm);
132
                    break;
133
            case 2:
134
                    /* Send bits 9-16 followed by 17-23 */
135
                    WriteDOC((ofs >> 9)  & 0xff, docptr, Mil_CDSN_IO);
136
                    WriteDOC((ofs >> 17) & 0xff, docptr, Mil_CDSN_IO);
137
                    WriteDOC(0x00, docptr, WritePipeTerm);
138
                break;
139
            case 3:
140
                    /* Send 0-7, 9-16, then 17-23 */
141
                    WriteDOC(ofs & 0xff, docptr, Mil_CDSN_IO);
142
                    WriteDOC((ofs >> 9)  & 0xff, docptr, Mil_CDSN_IO);
143
                    WriteDOC((ofs >> 17) & 0xff, docptr, Mil_CDSN_IO);
144
                    WriteDOC(0x00, docptr, WritePipeTerm);
145
                break;
146
            default:
147
                return;
148
            }
149
 
150
        /* Lower the ALE line */
151
        WriteDOC(xtraflags1 | xtraflags2 | CDSN_CTRL_CE, docptr, CDSNControl);
152
        DoC_Delay(docptr, 4);
153
}
154
 
155
/* DoC_SelectChip: Select a given flash chip within the current floor */
156
static int DoC_SelectChip(void __iomem * docptr, int chip)
157
{
158
        /* Select the individual flash chip requested */
159
        WriteDOC(chip, docptr, CDSNDeviceSelect);
160
        DoC_Delay(docptr, 4);
161
 
162
        /* Wait for it to be ready */
163
        return DoC_WaitReady(docptr);
164
}
165
 
166
/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
167
static int DoC_SelectFloor(void __iomem * docptr, int floor)
168
{
169
        /* Select the floor (bank) of chips required */
170
        WriteDOC(floor, docptr, FloorSelect);
171
 
172
        /* Wait for the chip to be ready */
173
        return DoC_WaitReady(docptr);
174
}
175
 
176
/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
177
static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
178
{
179
        int mfr, id, i, j;
180
        volatile char dummy;
181
 
182
        /* Page in the required floor/chip
183
           FIXME: is this supported by Millennium ?? */
184
        DoC_SelectFloor(doc->virtadr, floor);
185
        DoC_SelectChip(doc->virtadr, chip);
186
 
187
        /* Reset the chip, see Software Requirement 11.4 item 1. */
188
        DoC_Command(doc->virtadr, NAND_CMD_RESET, CDSN_CTRL_WP);
189
        DoC_WaitReady(doc->virtadr);
190
 
191
        /* Read the NAND chip ID: 1. Send ReadID command */
192
        DoC_Command(doc->virtadr, NAND_CMD_READID, CDSN_CTRL_WP);
193
 
194
        /* Read the NAND chip ID: 2. Send address byte zero */
195
        DoC_Address(doc->virtadr, 1, 0x00, CDSN_CTRL_WP, 0x00);
196
 
197
        /* Read the manufacturer and device id codes of the flash device through
198
           CDSN IO register see Software Requirement 11.4 item 5.*/
199
        dummy = ReadDOC(doc->virtadr, ReadPipeInit);
200
        DoC_Delay(doc->virtadr, 2);
201
        mfr = ReadDOC(doc->virtadr, Mil_CDSN_IO);
202
 
203
        DoC_Delay(doc->virtadr, 2);
204
        id  = ReadDOC(doc->virtadr, Mil_CDSN_IO);
205
        dummy = ReadDOC(doc->virtadr, LastDataRead);
206
 
207
        /* No response - return failure */
208
        if (mfr == 0xff || mfr == 0)
209
                return 0;
210
 
211
        /* FIXME: to deal with multi-flash on multi-Millennium case more carefully */
212
        for (i = 0; nand_flash_ids[i].name != NULL; i++) {
213
                if ( id == nand_flash_ids[i].id) {
214
                        /* Try to identify manufacturer */
215
                        for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
216
                                if (nand_manuf_ids[j].id == mfr)
217
                                        break;
218
                        }
219
                        printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, "
220
                               "Chip ID: %2.2X (%s:%s)\n",
221
                               mfr, id, nand_manuf_ids[j].name, nand_flash_ids[i].name);
222
                        doc->mfr = mfr;
223
                        doc->id = id;
224
                        doc->chipshift = ffs((nand_flash_ids[i].chipsize << 20)) - 1;
225
                        break;
226
                }
227
        }
228
 
229
        if (nand_flash_ids[i].name == NULL)
230
                return 0;
231
        else
232
                return 1;
233
}
234
 
235
/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
236
static void DoC_ScanChips(struct DiskOnChip *this)
237
{
238
        int floor, chip;
239
        int numchips[MAX_FLOORS_MIL];
240
        int ret;
241
 
242
        this->numchips = 0;
243
        this->mfr = 0;
244
        this->id = 0;
245
 
246
        /* For each floor, find the number of valid chips it contains */
247
        for (floor = 0,ret = 1; floor < MAX_FLOORS_MIL; floor++) {
248
                numchips[floor] = 0;
249
                for (chip = 0; chip < MAX_CHIPS_MIL && ret != 0; chip++) {
250
                        ret = DoC_IdentChip(this, floor, chip);
251
                        if (ret) {
252
                                numchips[floor]++;
253
                                this->numchips++;
254
                        }
255
                }
256
        }
257
        /* If there are none at all that we recognise, bail */
258
        if (!this->numchips) {
259
                printk("No flash chips recognised.\n");
260
                return;
261
        }
262
 
263
        /* Allocate an array to hold the information for each chip */
264
        this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
265
        if (!this->chips){
266
                printk("No memory for allocating chip info structures\n");
267
                return;
268
        }
269
 
270
        /* Fill out the chip array with {floor, chipno} for each
271
         * detected chip in the device. */
272
        for (floor = 0, ret = 0; floor < MAX_FLOORS_MIL; floor++) {
273
                for (chip = 0 ; chip < numchips[floor] ; chip++) {
274
                        this->chips[ret].floor = floor;
275
                        this->chips[ret].chip = chip;
276
                        this->chips[ret].curadr = 0;
277
                        this->chips[ret].curmode = 0x50;
278
                        ret++;
279
                }
280
        }
281
 
282
        /* Calculate and print the total size of the device */
283
        this->totlen = this->numchips * (1 << this->chipshift);
284
        printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n",
285
               this->numchips ,this->totlen >> 20);
286
}
287
 
288
static int DoCMil_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
289
{
290
        int tmp1, tmp2, retval;
291
 
292
        if (doc1->physadr == doc2->physadr)
293
                return 1;
294
 
295
        /* Use the alias resolution register which was set aside for this
296
         * purpose. If it's value is the same on both chips, they might
297
         * be the same chip, and we write to one and check for a change in
298
         * the other. It's unclear if this register is usuable in the
299
         * DoC 2000 (it's in the Millenium docs), but it seems to work. */
300
        tmp1 = ReadDOC(doc1->virtadr, AliasResolution);
301
        tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
302
        if (tmp1 != tmp2)
303
                return 0;
304
 
305
        WriteDOC((tmp1+1) % 0xff, doc1->virtadr, AliasResolution);
306
        tmp2 = ReadDOC(doc2->virtadr, AliasResolution);
307
        if (tmp2 == (tmp1+1) % 0xff)
308
                retval = 1;
309
        else
310
                retval = 0;
311
 
312
        /* Restore register contents.  May not be necessary, but do it just to
313
         * be safe. */
314
        WriteDOC(tmp1, doc1->virtadr, AliasResolution);
315
 
316
        return retval;
317
}
318
 
319
/* This routine is found from the docprobe code by symbol_get(),
320
 * which will bump the use count of this module. */
321
void DoCMil_init(struct mtd_info *mtd)
322
{
323
        struct DiskOnChip *this = mtd->priv;
324
        struct DiskOnChip *old = NULL;
325
 
326
        /* We must avoid being called twice for the same device. */
327
        if (docmillist)
328
                old = docmillist->priv;
329
 
330
        while (old) {
331
                if (DoCMil_is_alias(this, old)) {
332
                        printk(KERN_NOTICE "Ignoring DiskOnChip Millennium at "
333
                               "0x%lX - already configured\n", this->physadr);
334
                        iounmap(this->virtadr);
335
                        kfree(mtd);
336
                        return;
337
                }
338
                if (old->nextdoc)
339
                        old = old->nextdoc->priv;
340
                else
341
                        old = NULL;
342
        }
343
 
344
        mtd->name = "DiskOnChip Millennium";
345
        printk(KERN_NOTICE "DiskOnChip Millennium found at address 0x%lX\n",
346
               this->physadr);
347
 
348
        mtd->type = MTD_NANDFLASH;
349
        mtd->flags = MTD_CAP_NANDFLASH;
350
        mtd->size = 0;
351
 
352
        /* FIXME: erase size is not always 8KiB */
353
        mtd->erasesize = 0x2000;
354
 
355
        mtd->writesize = 512;
356
        mtd->oobsize = 16;
357
        mtd->owner = THIS_MODULE;
358
        mtd->erase = doc_erase;
359
        mtd->point = NULL;
360
        mtd->unpoint = NULL;
361
        mtd->read = doc_read;
362
        mtd->write = doc_write;
363
        mtd->read_oob = doc_read_oob;
364
        mtd->write_oob = doc_write_oob;
365
        mtd->sync = NULL;
366
 
367
        this->totlen = 0;
368
        this->numchips = 0;
369
        this->curfloor = -1;
370
        this->curchip = -1;
371
 
372
        /* Ident all the chips present. */
373
        DoC_ScanChips(this);
374
 
375
        if (!this->totlen) {
376
                kfree(mtd);
377
                iounmap(this->virtadr);
378
        } else {
379
                this->nextdoc = docmillist;
380
                docmillist = mtd;
381
                mtd->size  = this->totlen;
382
                add_mtd_device(mtd);
383
                return;
384
        }
385
}
386
EXPORT_SYMBOL_GPL(DoCMil_init);
387
 
388
static int doc_read (struct mtd_info *mtd, loff_t from, size_t len,
389
                     size_t *retlen, u_char *buf)
390
{
391
        int i, ret;
392
        volatile char dummy;
393
        unsigned char syndrome[6], eccbuf[6];
394
        struct DiskOnChip *this = mtd->priv;
395
        void __iomem *docptr = this->virtadr;
396
        struct Nand *mychip = &this->chips[from >> (this->chipshift)];
397
 
398
        /* Don't allow read past end of device */
399
        if (from >= this->totlen)
400
                return -EINVAL;
401
 
402
        /* Don't allow a single read to cross a 512-byte block boundary */
403
        if (from + len > ((from | 0x1ff) + 1))
404
                len = ((from | 0x1ff) + 1) - from;
405
 
406
        /* Find the chip which is to be used and select it */
407
        if (this->curfloor != mychip->floor) {
408
                DoC_SelectFloor(docptr, mychip->floor);
409
                DoC_SelectChip(docptr, mychip->chip);
410
        } else if (this->curchip != mychip->chip) {
411
                DoC_SelectChip(docptr, mychip->chip);
412
        }
413
        this->curfloor = mychip->floor;
414
        this->curchip = mychip->chip;
415
 
416
        /* issue the Read0 or Read1 command depend on which half of the page
417
           we are accessing. Polling the Flash Ready bit after issue 3 bytes
418
           address in Sequence Read Mode, see Software Requirement 11.4 item 1.*/
419
        DoC_Command(docptr, (from >> 8) & 1, CDSN_CTRL_WP);
420
        DoC_Address(docptr, 3, from, CDSN_CTRL_WP, 0x00);
421
        DoC_WaitReady(docptr);
422
 
423
        /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
424
        WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
425
        WriteDOC (DOC_ECC_EN, docptr, ECCConf);
426
 
427
        /* Read the data via the internal pipeline through CDSN IO register,
428
           see Pipelined Read Operations 11.3 */
429
        dummy = ReadDOC(docptr, ReadPipeInit);
430
#ifndef USE_MEMCPY
431
        for (i = 0; i < len-1; i++) {
432
                /* N.B. you have to increase the source address in this way or the
433
                   ECC logic will not work properly */
434
                buf[i] = ReadDOC(docptr, Mil_CDSN_IO + (i & 0xff));
435
        }
436
#else
437
        memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len - 1);
438
#endif
439
        buf[len - 1] = ReadDOC(docptr, LastDataRead);
440
 
441
        /* Let the caller know we completed it */
442
        *retlen = len;
443
        ret = 0;
444
 
445
        /* Read the ECC data from Spare Data Area,
446
           see Reed-Solomon EDC/ECC 11.1 */
447
        dummy = ReadDOC(docptr, ReadPipeInit);
448
#ifndef USE_MEMCPY
449
        for (i = 0; i < 5; i++) {
450
                /* N.B. you have to increase the source address in this way or the
451
                   ECC logic will not work properly */
452
                eccbuf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
453
        }
454
#else
455
        memcpy_fromio(eccbuf, docptr + DoC_Mil_CDSN_IO, 5);
456
#endif
457
        eccbuf[5] = ReadDOC(docptr, LastDataRead);
458
 
459
        /* Flush the pipeline */
460
        dummy = ReadDOC(docptr, ECCConf);
461
        dummy = ReadDOC(docptr, ECCConf);
462
 
463
        /* Check the ECC Status */
464
        if (ReadDOC(docptr, ECCConf) & 0x80) {
465
                int nb_errors;
466
                /* There was an ECC error */
467
#ifdef ECC_DEBUG
468
                printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
469
#endif
470
                /* Read the ECC syndrom through the DiskOnChip ECC logic.
471
                   These syndrome will be all ZERO when there is no error */
472
                for (i = 0; i < 6; i++) {
473
                        syndrome[i] = ReadDOC(docptr, ECCSyndrome0 + i);
474
                }
475
                nb_errors = doc_decode_ecc(buf, syndrome);
476
#ifdef ECC_DEBUG
477
                printk("ECC Errors corrected: %x\n", nb_errors);
478
#endif
479
                if (nb_errors < 0) {
480
                        /* We return error, but have actually done the read. Not that
481
                           this can be told to user-space, via sys_read(), but at least
482
                           MTD-aware stuff can know about it by checking *retlen */
483
                        ret = -EIO;
484
                }
485
        }
486
 
487
#ifdef PSYCHO_DEBUG
488
        printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
489
               (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
490
               eccbuf[4], eccbuf[5]);
491
#endif
492
 
493
        /* disable the ECC engine */
494
        WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
495
 
496
        return ret;
497
}
498
 
499
static int doc_write (struct mtd_info *mtd, loff_t to, size_t len,
500
                      size_t *retlen, const u_char *buf)
501
{
502
        int i,ret = 0;
503
        char eccbuf[6];
504
        volatile char dummy;
505
        struct DiskOnChip *this = mtd->priv;
506
        void __iomem *docptr = this->virtadr;
507
        struct Nand *mychip = &this->chips[to >> (this->chipshift)];
508
 
509
        /* Don't allow write past end of device */
510
        if (to >= this->totlen)
511
                return -EINVAL;
512
 
513
#if 0
514
        /* Don't allow a single write to cross a 512-byte block boundary */
515
        if (to + len > ( (to | 0x1ff) + 1))
516
                len = ((to | 0x1ff) + 1) - to;
517
#else
518
        /* Don't allow writes which aren't exactly one block */
519
        if (to & 0x1ff || len != 0x200)
520
                return -EINVAL;
521
#endif
522
 
523
        /* Find the chip which is to be used and select it */
524
        if (this->curfloor != mychip->floor) {
525
                DoC_SelectFloor(docptr, mychip->floor);
526
                DoC_SelectChip(docptr, mychip->chip);
527
        } else if (this->curchip != mychip->chip) {
528
                DoC_SelectChip(docptr, mychip->chip);
529
        }
530
        this->curfloor = mychip->floor;
531
        this->curchip = mychip->chip;
532
 
533
        /* Reset the chip, see Software Requirement 11.4 item 1. */
534
        DoC_Command(docptr, NAND_CMD_RESET, 0x00);
535
        DoC_WaitReady(docptr);
536
        /* Set device to main plane of flash */
537
        DoC_Command(docptr, NAND_CMD_READ0, 0x00);
538
 
539
        /* issue the Serial Data In command to initial the Page Program process */
540
        DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
541
        DoC_Address(docptr, 3, to, 0x00, 0x00);
542
        DoC_WaitReady(docptr);
543
 
544
        /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
545
        WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
546
        WriteDOC (DOC_ECC_EN | DOC_ECC_RW, docptr, ECCConf);
547
 
548
        /* Write the data via the internal pipeline through CDSN IO register,
549
           see Pipelined Write Operations 11.2 */
550
#ifndef USE_MEMCPY
551
        for (i = 0; i < len; i++) {
552
                /* N.B. you have to increase the source address in this way or the
553
                   ECC logic will not work properly */
554
                WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
555
        }
556
#else
557
        memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len);
558
#endif
559
        WriteDOC(0x00, docptr, WritePipeTerm);
560
 
561
        /* Write ECC data to flash, the ECC info is generated by the DiskOnChip ECC logic
562
           see Reed-Solomon EDC/ECC 11.1 */
563
        WriteDOC(0, docptr, NOP);
564
        WriteDOC(0, docptr, NOP);
565
        WriteDOC(0, docptr, NOP);
566
 
567
        /* Read the ECC data through the DiskOnChip ECC logic */
568
        for (i = 0; i < 6; i++) {
569
                eccbuf[i] = ReadDOC(docptr, ECCSyndrome0 + i);
570
        }
571
 
572
        /* ignore the ECC engine */
573
        WriteDOC(DOC_ECC_DIS, docptr , ECCConf);
574
 
575
#ifndef USE_MEMCPY
576
        /* Write the ECC data to flash */
577
        for (i = 0; i < 6; i++) {
578
                /* N.B. you have to increase the source address in this way or the
579
                   ECC logic will not work properly */
580
                WriteDOC(eccbuf[i], docptr, Mil_CDSN_IO + i);
581
        }
582
#else
583
        memcpy_toio(docptr + DoC_Mil_CDSN_IO, eccbuf, 6);
584
#endif
585
 
586
        /* write the block status BLOCK_USED (0x5555) at the end of ECC data
587
           FIXME: this is only a hack for programming the IPL area for LinuxBIOS
588
           and should be replace with proper codes in user space utilities */
589
        WriteDOC(0x55, docptr, Mil_CDSN_IO);
590
        WriteDOC(0x55, docptr, Mil_CDSN_IO + 1);
591
 
592
        WriteDOC(0x00, docptr, WritePipeTerm);
593
 
594
#ifdef PSYCHO_DEBUG
595
        printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
596
               (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
597
               eccbuf[4], eccbuf[5]);
598
#endif
599
 
600
        /* Commit the Page Program command and wait for ready
601
           see Software Requirement 11.4 item 1.*/
602
        DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
603
        DoC_WaitReady(docptr);
604
 
605
        /* Read the status of the flash device through CDSN IO register
606
           see Software Requirement 11.4 item 5.*/
607
        DoC_Command(docptr, NAND_CMD_STATUS, CDSN_CTRL_WP);
608
        dummy = ReadDOC(docptr, ReadPipeInit);
609
        DoC_Delay(docptr, 2);
610
        if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
611
                printk("Error programming flash\n");
612
                /* Error in programming
613
                   FIXME: implement Bad Block Replacement (in nftl.c ??) */
614
                *retlen = 0;
615
                ret = -EIO;
616
        }
617
        dummy = ReadDOC(docptr, LastDataRead);
618
 
619
        /* Let the caller know we completed it */
620
        *retlen = len;
621
 
622
        return ret;
623
}
624
 
625
static int doc_read_oob(struct mtd_info *mtd, loff_t ofs,
626
                        struct mtd_oob_ops *ops)
627
{
628
#ifndef USE_MEMCPY
629
        int i;
630
#endif
631
        volatile char dummy;
632
        struct DiskOnChip *this = mtd->priv;
633
        void __iomem *docptr = this->virtadr;
634
        struct Nand *mychip = &this->chips[ofs >> this->chipshift];
635
        uint8_t *buf = ops->oobbuf;
636
        size_t len = ops->len;
637
 
638
        BUG_ON(ops->mode != MTD_OOB_PLACE);
639
 
640
        ofs += ops->ooboffs;
641
 
642
        /* Find the chip which is to be used and select it */
643
        if (this->curfloor != mychip->floor) {
644
                DoC_SelectFloor(docptr, mychip->floor);
645
                DoC_SelectChip(docptr, mychip->chip);
646
        } else if (this->curchip != mychip->chip) {
647
                DoC_SelectChip(docptr, mychip->chip);
648
        }
649
        this->curfloor = mychip->floor;
650
        this->curchip = mychip->chip;
651
 
652
        /* disable the ECC engine */
653
        WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
654
        WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
655
 
656
        /* issue the Read2 command to set the pointer to the Spare Data Area.
657
           Polling the Flash Ready bit after issue 3 bytes address in
658
           Sequence Read Mode, see Software Requirement 11.4 item 1.*/
659
        DoC_Command(docptr, NAND_CMD_READOOB, CDSN_CTRL_WP);
660
        DoC_Address(docptr, 3, ofs, CDSN_CTRL_WP, 0x00);
661
        DoC_WaitReady(docptr);
662
 
663
        /* Read the data out via the internal pipeline through CDSN IO register,
664
           see Pipelined Read Operations 11.3 */
665
        dummy = ReadDOC(docptr, ReadPipeInit);
666
#ifndef USE_MEMCPY
667
        for (i = 0; i < len-1; i++) {
668
                /* N.B. you have to increase the source address in this way or the
669
                   ECC logic will not work properly */
670
                buf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
671
        }
672
#else
673
        memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len - 1);
674
#endif
675
        buf[len - 1] = ReadDOC(docptr, LastDataRead);
676
 
677
        ops->retlen = len;
678
 
679
        return 0;
680
}
681
 
682
static int doc_write_oob(struct mtd_info *mtd, loff_t ofs,
683
                         struct mtd_oob_ops *ops)
684
{
685
#ifndef USE_MEMCPY
686
        int i;
687
#endif
688
        volatile char dummy;
689
        int ret = 0;
690
        struct DiskOnChip *this = mtd->priv;
691
        void __iomem *docptr = this->virtadr;
692
        struct Nand *mychip = &this->chips[ofs >> this->chipshift];
693
        uint8_t *buf = ops->oobbuf;
694
        size_t len = ops->len;
695
 
696
        BUG_ON(ops->mode != MTD_OOB_PLACE);
697
 
698
        ofs += ops->ooboffs;
699
 
700
        /* Find the chip which is to be used and select it */
701
        if (this->curfloor != mychip->floor) {
702
                DoC_SelectFloor(docptr, mychip->floor);
703
                DoC_SelectChip(docptr, mychip->chip);
704
        } else if (this->curchip != mychip->chip) {
705
                DoC_SelectChip(docptr, mychip->chip);
706
        }
707
        this->curfloor = mychip->floor;
708
        this->curchip = mychip->chip;
709
 
710
        /* disable the ECC engine */
711
        WriteDOC (DOC_ECC_RESET, docptr, ECCConf);
712
        WriteDOC (DOC_ECC_DIS, docptr, ECCConf);
713
 
714
        /* Reset the chip, see Software Requirement 11.4 item 1. */
715
        DoC_Command(docptr, NAND_CMD_RESET, CDSN_CTRL_WP);
716
        DoC_WaitReady(docptr);
717
        /* issue the Read2 command to set the pointer to the Spare Data Area. */
718
        DoC_Command(docptr, NAND_CMD_READOOB, CDSN_CTRL_WP);
719
 
720
        /* issue the Serial Data In command to initial the Page Program process */
721
        DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
722
        DoC_Address(docptr, 3, ofs, 0x00, 0x00);
723
 
724
        /* Write the data via the internal pipeline through CDSN IO register,
725
           see Pipelined Write Operations 11.2 */
726
#ifndef USE_MEMCPY
727
        for (i = 0; i < len; i++) {
728
                /* N.B. you have to increase the source address in this way or the
729
                   ECC logic will not work properly */
730
                WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
731
        }
732
#else
733
        memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len);
734
#endif
735
        WriteDOC(0x00, docptr, WritePipeTerm);
736
 
737
        /* Commit the Page Program command and wait for ready
738
           see Software Requirement 11.4 item 1.*/
739
        DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
740
        DoC_WaitReady(docptr);
741
 
742
        /* Read the status of the flash device through CDSN IO register
743
           see Software Requirement 11.4 item 5.*/
744
        DoC_Command(docptr, NAND_CMD_STATUS, 0x00);
745
        dummy = ReadDOC(docptr, ReadPipeInit);
746
        DoC_Delay(docptr, 2);
747
        if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
748
                printk("Error programming oob data\n");
749
                /* FIXME: implement Bad Block Replacement (in nftl.c ??) */
750
                ops->retlen = 0;
751
                ret = -EIO;
752
        }
753
        dummy = ReadDOC(docptr, LastDataRead);
754
 
755
        ops->retlen = len;
756
 
757
        return ret;
758
}
759
 
760
int doc_erase (struct mtd_info *mtd, struct erase_info *instr)
761
{
762
        volatile char dummy;
763
        struct DiskOnChip *this = mtd->priv;
764
        __u32 ofs = instr->addr;
765
        __u32 len = instr->len;
766
        void __iomem *docptr = this->virtadr;
767
        struct Nand *mychip = &this->chips[ofs >> this->chipshift];
768
 
769
        if (len != mtd->erasesize)
770
                printk(KERN_WARNING "Erase not right size (%x != %x)n",
771
                       len, mtd->erasesize);
772
 
773
        /* Find the chip which is to be used and select it */
774
        if (this->curfloor != mychip->floor) {
775
                DoC_SelectFloor(docptr, mychip->floor);
776
                DoC_SelectChip(docptr, mychip->chip);
777
        } else if (this->curchip != mychip->chip) {
778
                DoC_SelectChip(docptr, mychip->chip);
779
        }
780
        this->curfloor = mychip->floor;
781
        this->curchip = mychip->chip;
782
 
783
        instr->state = MTD_ERASE_PENDING;
784
 
785
        /* issue the Erase Setup command */
786
        DoC_Command(docptr, NAND_CMD_ERASE1, 0x00);
787
        DoC_Address(docptr, 2, ofs, 0x00, 0x00);
788
 
789
        /* Commit the Erase Start command and wait for ready
790
           see Software Requirement 11.4 item 1.*/
791
        DoC_Command(docptr, NAND_CMD_ERASE2, 0x00);
792
        DoC_WaitReady(docptr);
793
 
794
        instr->state = MTD_ERASING;
795
 
796
        /* Read the status of the flash device through CDSN IO register
797
           see Software Requirement 11.4 item 5.
798
           FIXME: it seems that we are not wait long enough, some blocks are not
799
           erased fully */
800
        DoC_Command(docptr, NAND_CMD_STATUS, CDSN_CTRL_WP);
801
        dummy = ReadDOC(docptr, ReadPipeInit);
802
        DoC_Delay(docptr, 2);
803
        if (ReadDOC(docptr, Mil_CDSN_IO) & 1) {
804
                printk("Error Erasing at 0x%x\n", ofs);
805
                /* There was an error
806
                   FIXME: implement Bad Block Replacement (in nftl.c ??) */
807
                instr->state = MTD_ERASE_FAILED;
808
        } else
809
                instr->state = MTD_ERASE_DONE;
810
        dummy = ReadDOC(docptr, LastDataRead);
811
 
812
        mtd_erase_callback(instr);
813
 
814
        return 0;
815
}
816
 
817
/****************************************************************************
818
 *
819
 * Module stuff
820
 *
821
 ****************************************************************************/
822
 
823
static void __exit cleanup_doc2001(void)
824
{
825
        struct mtd_info *mtd;
826
        struct DiskOnChip *this;
827
 
828
        while ((mtd=docmillist)) {
829
                this = mtd->priv;
830
                docmillist = this->nextdoc;
831
 
832
                del_mtd_device(mtd);
833
 
834
                iounmap(this->virtadr);
835
                kfree(this->chips);
836
                kfree(mtd);
837
        }
838
}
839
 
840
module_exit(cleanup_doc2001);
841
 
842
MODULE_LICENSE("GPL");
843
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org> et al.");
844
MODULE_DESCRIPTION("Alternative driver for DiskOnChip Millennium");

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.