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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [mtd/] [devices/] [lart.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
 
2
/*
3
 * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART.
4
 *
5
 * $Id: lart.c,v 1.1.1.1 2004-04-15 01:52:04 phoenix Exp $
6
 *
7
 * Author: Abraham vd Merwe <abraham@2d3d.co.za>
8
 *
9
 * Copyright (c) 2001, 2d3D, Inc.
10
 *
11
 * This code is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License version 2 as
13
 * published by the Free Software Foundation.
14
 *
15
 * References:
16
 *
17
 *    [1] 3 Volt Fast Boot Block Flash Memory" Intel Datasheet
18
 *           - Order Number: 290644-005
19
 *           - January 2000
20
 *
21
 *    [2] MTD internal API documentation
22
 *           - http://www.linux-mtd.infradead.org/tech/
23
 *
24
 * Limitations:
25
 *
26
 *    Even though this driver is written for 3 Volt Fast Boot
27
 *    Block Flash Memory, it is rather specific to LART. With
28
 *    Minor modifications, notably the without data/address line
29
 *    mangling and different bus settings, etc. it should be
30
 *    trivial to adapt to other platforms.
31
 *
32
 *    If somebody would sponsor me a different board, I'll
33
 *    adapt the driver (:
34
 */
35
 
36
/* debugging */
37
//#define LART_DEBUG
38
 
39
/* partition support */
40
#define HAVE_PARTITIONS
41
 
42
#include <linux/kernel.h>
43
#include <linux/module.h>
44
#include <linux/types.h>
45
#include <linux/version.h>
46
#include <linux/errno.h>
47
#include <linux/mtd/mtd.h>
48
#ifdef HAVE_PARTITIONS
49
#include <linux/mtd/partitions.h>
50
#endif
51
 
52
#ifndef CONFIG_SA1100_LART
53
#error This is for LART architecture only
54
#endif
55
 
56
static char module_name[] = "lart";
57
 
58
/*
59
 * These values is specific to 28Fxxxx3 flash memory.
60
 * See section 2.3.1 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet
61
 */
62
#define FLASH_BLOCKSIZE_PARAM           (4096 * BUSWIDTH)
63
#define FLASH_NUMBLOCKS_16m_PARAM       8
64
#define FLASH_NUMBLOCKS_8m_PARAM        8
65
 
66
/*
67
 * These values is specific to 28Fxxxx3 flash memory.
68
 * See section 2.3.2 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet
69
 */
70
#define FLASH_BLOCKSIZE_MAIN            (32768 * BUSWIDTH)
71
#define FLASH_NUMBLOCKS_16m_MAIN        31
72
#define FLASH_NUMBLOCKS_8m_MAIN         15
73
 
74
/*
75
 * These values are specific to LART
76
 */
77
 
78
/* general */
79
#define BUSWIDTH                        4                               /* don't change this - a lot of the code _will_ break if you change this */
80
#define FLASH_OFFSET            0xe8000000              /* see linux/arch/arm/mach-sa1100/lart.c */
81
 
82
/* blob */
83
#define NUM_BLOB_BLOCKS         FLASH_NUMBLOCKS_16m_PARAM
84
#define BLOB_START                      0x00000000
85
#define BLOB_LEN                        (NUM_BLOB_BLOCKS * FLASH_BLOCKSIZE_PARAM)
86
 
87
/* kernel */
88
#define NUM_KERNEL_BLOCKS       7
89
#define KERNEL_START            (BLOB_START + BLOB_LEN)
90
#define KERNEL_LEN                      (NUM_KERNEL_BLOCKS * FLASH_BLOCKSIZE_MAIN)
91
 
92
/* initial ramdisk */
93
#define NUM_INITRD_BLOCKS       24
94
#define INITRD_START            (KERNEL_START + KERNEL_LEN)
95
#define INITRD_LEN                      (NUM_INITRD_BLOCKS * FLASH_BLOCKSIZE_MAIN)
96
 
97
/*
98
 * See section 4.0 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet
99
 */
100
#define READ_ARRAY                      0x00FF00FF              /* Read Array/Reset */
101
#define READ_ID_CODES           0x00900090              /* Read Identifier Codes */
102
#define ERASE_SETUP                     0x00200020              /* Block Erase */
103
#define ERASE_CONFIRM           0x00D000D0              /* Block Erase and Program Resume */
104
#define PGM_SETUP                       0x00400040              /* Program */
105
#define STATUS_READ                     0x00700070              /* Read Status Register */
106
#define STATUS_CLEAR            0x00500050              /* Clear Status Register */
107
#define STATUS_BUSY                     0x00800080              /* Write State Machine Status (WSMS) */
108
#define STATUS_ERASE_ERR        0x00200020              /* Erase Status (ES) */
109
#define STATUS_PGM_ERR          0x00100010              /* Program Status (PS) */
110
 
111
/*
112
 * See section 4.2 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet
113
 */
114
#define FLASH_MANUFACTURER                      0x00890089
115
#define FLASH_DEVICE_8mbit_TOP          0x88f188f1
116
#define FLASH_DEVICE_8mbit_BOTTOM       0x88f288f2
117
#define FLASH_DEVICE_16mbit_TOP         0x88f388f3
118
#define FLASH_DEVICE_16mbit_BOTTOM      0x88f488f4
119
 
120
/***************************************************************************************************/
121
 
122
/*
123
 * The data line mapping on LART is as follows:
124
 *
125
 *       U2  CPU |   U3  CPU
126
 *       -------------------
127
 *        0  20  |   0   12
128
 *        1  22  |   1   14
129
 *        2  19  |   2   11
130
 *        3  17  |   3   9
131
 *        4  24  |   4   0
132
 *        5  26  |   5   2
133
 *        6  31  |   6   7
134
 *        7  29  |   7   5
135
 *        8  21  |   8   13
136
 *        9  23  |   9   15
137
 *        10 18  |   10  10
138
 *        11 16  |   11  8
139
 *        12 25  |   12  1
140
 *        13 27  |   13  3
141
 *        14 30  |   14  6
142
 *        15 28  |   15  4
143
 */
144
 
145
/* Mangle data (x) */
146
#define DATA_TO_FLASH(x)                                \
147
        (                                                                       \
148
                (((x) & 0x08009000) >> 11)      +       \
149
                (((x) & 0x00002000) >> 10)      +       \
150
                (((x) & 0x04004000) >> 8)       +       \
151
                (((x) & 0x00000010) >> 4)       +       \
152
                (((x) & 0x91000820) >> 3)       +       \
153
                (((x) & 0x22080080) >> 2)       +       \
154
                ((x) & 0x40000400)                      +       \
155
                (((x) & 0x00040040) << 1)       +       \
156
                (((x) & 0x00110000) << 4)       +       \
157
                (((x) & 0x00220100) << 5)       +       \
158
                (((x) & 0x00800208) << 6)       +       \
159
                (((x) & 0x00400004) << 9)       +       \
160
                (((x) & 0x00000001) << 12)      +       \
161
                (((x) & 0x00000002) << 13)              \
162
        )
163
 
164
/* Unmangle data (x) */
165
#define FLASH_TO_DATA(x)                                \
166
        (                                                                       \
167
                (((x) & 0x00010012) << 11)      +       \
168
                (((x) & 0x00000008) << 10)      +       \
169
                (((x) & 0x00040040) << 8)       +       \
170
                (((x) & 0x00000001) << 4)       +       \
171
                (((x) & 0x12200104) << 3)       +       \
172
                (((x) & 0x08820020) << 2)       +       \
173
                ((x) & 0x40000400)                      +       \
174
                (((x) & 0x00080080) >> 1)       +       \
175
                (((x) & 0x01100000) >> 4)       +       \
176
                (((x) & 0x04402000) >> 5)       +       \
177
                (((x) & 0x20008200) >> 6)       +       \
178
                (((x) & 0x80000800) >> 9)       +       \
179
                (((x) & 0x00001000) >> 12)      +       \
180
                (((x) & 0x00004000) >> 13)              \
181
        )
182
 
183
/*
184
 * The address line mapping on LART is as follows:
185
 *
186
 *       U3  CPU |   U2  CPU
187
 *       -------------------
188
 *        0  2   |   0   2
189
 *        1  3   |   1   3
190
 *        2  9   |   2   9
191
 *        3  13  |   3   8
192
 *        4  8   |   4   7
193
 *        5  12  |   5   6
194
 *        6  11  |   6   5
195
 *        7  10  |   7   4
196
 *        8  4   |   8   10
197
 *        9  5   |   9   11
198
 *       10  6   |   10  12
199
 *       11  7   |   11  13
200
 *
201
 *       BOOT BLOCK BOUNDARY
202
 *
203
 *       12  15  |   12  15
204
 *       13  14  |   13  14
205
 *       14  16  |   14  16
206
 *
207
 *       MAIN BLOCK BOUNDARY
208
 *
209
 *       15  17  |   15  18
210
 *       16  18  |   16  17
211
 *       17  20  |   17  20
212
 *       18  19  |   18  19
213
 *       19  21  |   19  21
214
 *
215
 * As we can see from above, the addresses aren't mangled across
216
 * block boundaries, so we don't need to worry about address
217
 * translations except for sending/reading commands during
218
 * initialization
219
 */
220
 
221
/* Mangle address (x) on chip U2 */
222
#define ADDR_TO_FLASH_U2(x)                             \
223
        (                                                                       \
224
                (((x) & 0x00000f00) >> 4)       +       \
225
                (((x) & 0x00042000) << 1)       +       \
226
                (((x) & 0x0009c003) << 2)       +       \
227
                (((x) & 0x00021080) << 3)       +       \
228
                (((x) & 0x00000010) << 4)       +       \
229
                (((x) & 0x00000040) << 5)       +       \
230
                (((x) & 0x00000024) << 7)       +       \
231
                (((x) & 0x00000008) << 10)              \
232
        )
233
 
234
/* Unmangle address (x) on chip U2 */
235
#define FLASH_U2_TO_ADDR(x)                             \
236
        (                                                                       \
237
                (((x) << 4) & 0x00000f00)       +       \
238
                (((x) >> 1) & 0x00042000)       +       \
239
                (((x) >> 2) & 0x0009c003)       +       \
240
                (((x) >> 3) & 0x00021080)       +       \
241
                (((x) >> 4) & 0x00000010)       +       \
242
                (((x) >> 5) & 0x00000040)       +       \
243
                (((x) >> 7) & 0x00000024)       +       \
244
                (((x) >> 10) & 0x00000008)              \
245
        )
246
 
247
/* Mangle address (x) on chip U3 */
248
#define ADDR_TO_FLASH_U3(x)                             \
249
        (                                                                       \
250
                (((x) & 0x00000080) >> 3)       +       \
251
                (((x) & 0x00000040) >> 1)       +       \
252
                (((x) & 0x00052020) << 1)       +       \
253
                (((x) & 0x00084f03) << 2)       +       \
254
                (((x) & 0x00029010) << 3)       +       \
255
                (((x) & 0x00000008) << 5)       +       \
256
                (((x) & 0x00000004) << 7)               \
257
        )
258
 
259
/* Unmangle address (x) on chip U3 */
260
#define FLASH_U3_TO_ADDR(x)                             \
261
        (                                                                       \
262
                (((x) << 3) & 0x00000080)       +       \
263
                (((x) << 1) & 0x00000040)       +       \
264
                (((x) >> 1) & 0x00052020)       +       \
265
                (((x) >> 2) & 0x00084f03)       +       \
266
                (((x) >> 3) & 0x00029010)       +       \
267
                (((x) >> 5) & 0x00000008)       +       \
268
                (((x) >> 7) & 0x00000004)               \
269
        )
270
 
271
/***************************************************************************************************/
272
 
273
static __u8 read8 (__u32 offset)
274
{
275
   volatile __u8 *data = (__u8 *) (FLASH_OFFSET + offset);
276
#ifdef LART_DEBUG
277
   printk (KERN_DEBUG "%s(): 0x%.8x -> 0x%.2x\n",__FUNCTION__,offset,*data);
278
#endif
279
   return (*data);
280
}
281
 
282
static __u32 read32 (__u32 offset)
283
{
284
   volatile __u32 *data = (__u32 *) (FLASH_OFFSET + offset);
285
#ifdef LART_DEBUG
286
   printk (KERN_DEBUG "%s(): 0x%.8x -> 0x%.8x\n",__FUNCTION__,offset,*data);
287
#endif
288
   return (*data);
289
}
290
 
291
static void write32 (__u32 x,__u32 offset)
292
{
293
   volatile __u32 *data = (__u32 *) (FLASH_OFFSET + offset);
294
   *data = x;
295
#ifdef LART_DEBUG
296
   printk (KERN_DEBUG "%s(): 0x%.8x <- 0x%.8x\n",__FUNCTION__,offset,*data);
297
#endif
298
}
299
 
300
/***************************************************************************************************/
301
 
302
/*
303
 * Probe for 16mbit flash memory on a LART board without doing
304
 * too much damage. Since we need to write 1 dword to memory,
305
 * we're f**cked if this happens to be DRAM since we can't
306
 * restore the memory (otherwise we might exit Read Array mode).
307
 *
308
 * Returns 1 if we found 16mbit flash memory on LART, 0 otherwise.
309
 */
310
static int flash_probe (void)
311
{
312
   __u32 manufacturer,devtype;
313
 
314
   /* setup "Read Identifier Codes" mode */
315
   write32 (DATA_TO_FLASH (READ_ID_CODES),0x00000000);
316
 
317
   /* probe U2. U2/U3 returns the same data since the first 3
318
        * address lines is mangled in the same way */
319
   manufacturer = FLASH_TO_DATA (read32 (ADDR_TO_FLASH_U2 (0x00000000)));
320
   devtype = FLASH_TO_DATA (read32 (ADDR_TO_FLASH_U2 (0x00000001)));
321
 
322
   /* put the flash back into command mode */
323
   write32 (DATA_TO_FLASH (READ_ARRAY),0x00000000);
324
 
325
   return (manufacturer == FLASH_MANUFACTURER && (devtype == FLASH_DEVICE_16mbit_TOP || FLASH_DEVICE_16mbit_BOTTOM));
326
}
327
 
328
/*
329
 * Erase one block of flash memory at offset ``offset'' which is any
330
 * address within the block which should be erased.
331
 *
332
 * Returns 1 if successful, 0 otherwise.
333
 */
334
static inline int erase_block (__u32 offset)
335
{
336
   __u32 status;
337
 
338
#ifdef LART_DEBUG
339
   printk (KERN_DEBUG "%s(): 0x%.8x\n",__FUNCTION__,offset);
340
#endif
341
 
342
   /* erase and confirm */
343
   write32 (DATA_TO_FLASH (ERASE_SETUP),offset);
344
   write32 (DATA_TO_FLASH (ERASE_CONFIRM),offset);
345
 
346
   /* wait for block erase to finish */
347
   do
348
         {
349
                write32 (DATA_TO_FLASH (STATUS_READ),offset);
350
                status = FLASH_TO_DATA (read32 (offset));
351
         }
352
   while ((~status & STATUS_BUSY) != 0);
353
 
354
   /* put the flash back into command mode */
355
   write32 (DATA_TO_FLASH (READ_ARRAY),offset);
356
 
357
   /* was the erase successfull? */
358
   if ((status & STATUS_ERASE_ERR))
359
         {
360
                printk (KERN_WARNING "%s: erase error at address 0x%.8x.\n",module_name,offset);
361
                return (0);
362
         }
363
 
364
   return (1);
365
}
366
 
367
static int flash_erase (struct mtd_info *mtd,struct erase_info *instr)
368
{
369
   __u32 addr,len;
370
   int i,first;
371
 
372
#ifdef LART_DEBUG
373
   printk (KERN_DEBUG "%s(addr = 0x%.8x, len = %d)\n",__FUNCTION__,instr->addr,instr->len);
374
#endif
375
 
376
   /* sanity checks */
377
   if (instr->addr + instr->len > mtd->size) return (-EINVAL);
378
 
379
   /*
380
        * check that both start and end of the requested erase are
381
        * aligned with the erasesize at the appropriate addresses.
382
        *
383
        * skip all erase regions which are ended before the start of
384
        * the requested erase. Actually, to save on the calculations,
385
        * we skip to the first erase region which starts after the
386
        * start of the requested erase, and then go back one.
387
        */
388
   for (i = 0; i < mtd->numeraseregions && instr->addr >= mtd->eraseregions[i].offset; i++) ;
389
   i--;
390
 
391
   /*
392
        * ok, now i is pointing at the erase region in which this
393
        * erase request starts. Check the start of the requested
394
        * erase range is aligned with the erase size which is in
395
        * effect here.
396
        */
397
   if (instr->addr & (mtd->eraseregions[i].erasesize - 1)) return (-EINVAL);
398
 
399
   /* Remember the erase region we start on */
400
   first = i;
401
 
402
   /*
403
        * next, check that the end of the requested erase is aligned
404
        * with the erase region at that address.
405
        *
406
        * as before, drop back one to point at the region in which
407
        * the address actually falls
408
        */
409
   for (; i < mtd->numeraseregions && instr->addr + instr->len >= mtd->eraseregions[i].offset; i++) ;
410
   i--;
411
 
412
   /* is the end aligned on a block boundary? */
413
   if ((instr->addr + instr->len) & (mtd->eraseregions[i].erasesize - 1)) return (-EINVAL);
414
 
415
   addr = instr->addr;
416
   len = instr->len;
417
 
418
   i = first;
419
 
420
   /* now erase those blocks */
421
   while (len)
422
         {
423
                if (!erase_block (addr))
424
                  {
425
                         instr->state = MTD_ERASE_FAILED;
426
                         return (-EIO);
427
                  }
428
 
429
                addr += mtd->eraseregions[i].erasesize;
430
                len -= mtd->eraseregions[i].erasesize;
431
 
432
                if (addr == mtd->eraseregions[i].offset + (mtd->eraseregions[i].erasesize * mtd->eraseregions[i].numblocks)) i++;
433
         }
434
 
435
   instr->state = MTD_ERASE_DONE;
436
   if (instr->callback) instr->callback (instr);
437
 
438
   return (0);
439
}
440
 
441
static int flash_read (struct mtd_info *mtd,loff_t from,size_t len,size_t *retlen,u_char *buf)
442
{
443
#ifdef LART_DEBUG
444
   printk (KERN_DEBUG "%s(from = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) from,len);
445
#endif
446
 
447
   /* sanity checks */
448
   if (!len) return (0);
449
   if (from + len > mtd->size) return (-EINVAL);
450
 
451
   /* we always read len bytes */
452
   *retlen = len;
453
 
454
   /* first, we read bytes until we reach a dword boundary */
455
   if (from & (BUSWIDTH - 1))
456
         {
457
                int gap = BUSWIDTH - (from & (BUSWIDTH - 1));
458
 
459
                while (len && gap--) *buf++ = read8 (from++), len--;
460
         }
461
 
462
   /* now we read dwords until we reach a non-dword boundary */
463
   while (len >= BUSWIDTH)
464
         {
465
                *((__u32 *) buf) = read32 (from);
466
 
467
                buf += BUSWIDTH;
468
                from += BUSWIDTH;
469
                len -= BUSWIDTH;
470
         }
471
 
472
   /* top up the last unaligned bytes */
473
   if (len & (BUSWIDTH - 1))
474
         while (len--) *buf++ = read8 (from++);
475
 
476
   return (0);
477
}
478
 
479
/*
480
 * Write one dword ``x'' to flash memory at offset ``offset''. ``offset''
481
 * must be 32 bits, i.e. it must be on a dword boundary.
482
 *
483
 * Returns 1 if successful, 0 otherwise.
484
 */
485
static inline int write_dword (__u32 offset,__u32 x)
486
{
487
   __u32 status;
488
 
489
#ifdef LART_DEBUG
490
   printk (KERN_DEBUG "%s(): 0x%.8x <- 0x%.8x\n",__FUNCTION__,offset,x);
491
#endif
492
 
493
   /* setup writing */
494
   write32 (DATA_TO_FLASH (PGM_SETUP),offset);
495
 
496
   /* write the data */
497
   write32 (x,offset);
498
 
499
   /* wait for the write to finish */
500
   do
501
         {
502
                write32 (DATA_TO_FLASH (STATUS_READ),offset);
503
                status = FLASH_TO_DATA (read32 (offset));
504
         }
505
   while ((~status & STATUS_BUSY) != 0);
506
 
507
   /* put the flash back into command mode */
508
   write32 (DATA_TO_FLASH (READ_ARRAY),offset);
509
 
510
   /* was the write successfull? */
511
   if ((status & STATUS_PGM_ERR) || read32 (offset) != x)
512
         {
513
                printk (KERN_WARNING "%s: write error at address 0x%.8x.\n",module_name,offset);
514
                return (0);
515
         }
516
 
517
   return (1);
518
}
519
 
520
static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf)
521
{
522
   __u8 tmp[4];
523
   int i,n;
524
 
525
#ifdef LART_DEBUG
526
   printk (KERN_DEBUG "%s(to = 0x%.8x, len = %d)\n",__FUNCTION__,(__u32) to,len);
527
#endif
528
 
529
   *retlen = 0;
530
 
531
   /* sanity checks */
532
   if (!len) return (0);
533
   if (to + len > mtd->size) return (-EINVAL);
534
 
535
   /* first, we write a 0xFF.... padded byte until we reach a dword boundary */
536
   if (to & (BUSWIDTH - 1))
537
         {
538
                __u32 aligned = to & ~(BUSWIDTH - 1);
539
                int gap = to - aligned;
540
 
541
                i = n = 0;
542
 
543
                while (gap--) tmp[i++] = 0xFF;
544
                while (len && i < BUSWIDTH) tmp[i++] = buf[n++], len--;
545
                while (i < BUSWIDTH) tmp[i++] = 0xFF;
546
 
547
                if (!write_dword (aligned,*((__u32 *) tmp))) return (-EIO);
548
 
549
                to += n;
550
                buf += n;
551
                *retlen += n;
552
         }
553
 
554
   /* now we write dwords until we reach a non-dword boundary */
555
   while (len >= BUSWIDTH)
556
         {
557
                if (!write_dword (to,*((__u32 *) buf))) return (-EIO);
558
 
559
                to += BUSWIDTH;
560
                buf += BUSWIDTH;
561
                *retlen += BUSWIDTH;
562
                len -= BUSWIDTH;
563
         }
564
 
565
   /* top up the last unaligned bytes, padded with 0xFF.... */
566
   if (len & (BUSWIDTH - 1))
567
         {
568
                i = n = 0;
569
 
570
                while (len--) tmp[i++] = buf[n++];
571
                while (i < BUSWIDTH) tmp[i++] = 0xFF;
572
 
573
                if (!write_dword (to,*((__u32 *) tmp))) return (-EIO);
574
 
575
                *retlen += n;
576
         }
577
 
578
   return (0);
579
}
580
 
581
/***************************************************************************************************/
582
 
583
#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
584
 
585
static struct mtd_info mtd;
586
 
587
static struct mtd_erase_region_info erase_regions[] =
588
{
589
   /* parameter blocks */
590
   {
591
             offset: 0x00000000,
592
          erasesize: FLASH_BLOCKSIZE_PARAM,
593
          numblocks: FLASH_NUMBLOCKS_16m_PARAM
594
   },
595
   /* main blocks */
596
   {
597
             offset: FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM,
598
          erasesize: FLASH_BLOCKSIZE_MAIN,
599
          numblocks: FLASH_NUMBLOCKS_16m_MAIN
600
   }
601
};
602
 
603
#ifdef HAVE_PARTITIONS
604
static struct mtd_partition lart_partitions[] =
605
{
606
   /* blob */
607
   {
608
               name: "blob",
609
             offset: BLOB_START,
610
               size: BLOB_LEN,
611
         mask_flags: 0
612
   },
613
   /* kernel */
614
   {
615
               name: "kernel",
616
             offset: KERNEL_START,                      /* MTDPART_OFS_APPEND */
617
               size: KERNEL_LEN,
618
         mask_flags: 0
619
   },
620
   /* initial ramdisk / file system */
621
   {
622
               name: "file system",
623
             offset: INITRD_START,                      /* MTDPART_OFS_APPEND */
624
               size: INITRD_LEN,                        /* MTDPART_SIZ_FULL */
625
         mask_flags: 0
626
   }
627
};
628
#endif
629
 
630
int __init lart_flash_init (void)
631
{
632
   int result;
633
   memset (&mtd,0,sizeof (mtd));
634
   printk ("MTD driver for LART. Written by Abraham vd Merwe <abraham@2d3d.co.za>\n");
635
   printk ("%s: Probing for 28F160x3 flash on LART...\n",module_name);
636
   if (!flash_probe ())
637
         {
638
                printk (KERN_WARNING "%s: Found no LART compatible flash device\n",module_name);
639
                return (-ENXIO);
640
         }
641
   printk ("%s: This looks like a LART board to me.\n",module_name);
642
   mtd.name = module_name;
643
   mtd.type = MTD_NORFLASH;
644
   mtd.flags = MTD_CAP_NORFLASH;
645
   mtd.size = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM + FLASH_BLOCKSIZE_MAIN * FLASH_NUMBLOCKS_16m_MAIN;
646
   mtd.erasesize = FLASH_BLOCKSIZE_MAIN;
647
   mtd.numeraseregions = NB_OF (erase_regions);
648
   mtd.eraseregions = erase_regions;
649
   mtd.module = THIS_MODULE;
650
   mtd.erase = flash_erase;
651
   mtd.read = flash_read;
652
   mtd.write = flash_write;
653
 
654
#ifdef LART_DEBUG
655
   printk (KERN_DEBUG
656
                   "mtd.name = %s\n"
657
                   "mtd.size = 0x%.8x (%uM)\n"
658
                   "mtd.erasesize = 0x%.8x (%uK)\n"
659
                   "mtd.numeraseregions = %d\n",
660
                   mtd.name,
661
                   mtd.size,mtd.size / (1024*1024),
662
                   mtd.erasesize,mtd.erasesize / 1024,
663
                   mtd.numeraseregions);
664
 
665
   if (mtd.numeraseregions)
666
         for (result = 0; result < mtd.numeraseregions; result++)
667
           printk (KERN_DEBUG
668
                           "\n\n"
669
                           "mtd.eraseregions[%d].offset = 0x%.8x\n"
670
                           "mtd.eraseregions[%d].erasesize = 0x%.8x (%uK)\n"
671
                           "mtd.eraseregions[%d].numblocks = %d\n",
672
                           result,mtd.eraseregions[result].offset,
673
                           result,mtd.eraseregions[result].erasesize,mtd.eraseregions[result].erasesize / 1024,
674
                           result,mtd.eraseregions[result].numblocks);
675
 
676
#ifdef HAVE_PARTITIONS
677
   printk ("\npartitions = %d\n",NB_OF (lart_partitions));
678
 
679
   for (result = 0; result < NB_OF (lart_partitions); result++)
680
         printk (KERN_DEBUG
681
                         "\n\n"
682
                         "lart_partitions[%d].name = %s\n"
683
                         "lart_partitions[%d].offset = 0x%.8x\n"
684
                         "lart_partitions[%d].size = 0x%.8x (%uK)\n",
685
                         result,lart_partitions[result].name,
686
                         result,lart_partitions[result].offset,
687
                         result,lart_partitions[result].size,lart_partitions[result].size / 1024);
688
#endif
689
#endif
690
 
691
#ifndef HAVE_PARTITIONS
692
   result = add_mtd_device (&mtd);
693
#else
694
   result = add_mtd_partitions (&mtd,lart_partitions,NB_OF (lart_partitions));
695
#endif
696
 
697
   return (result);
698
}
699
 
700
void __exit lart_flash_exit (void)
701
{
702
#ifndef HAVE_PARTITIONS
703
   del_mtd_device (&mtd);
704
#else
705
   del_mtd_partitions (&mtd);
706
#endif
707
}
708
 
709
module_init (lart_flash_init);
710
module_exit (lart_flash_exit);
711
 
712
MODULE_LICENSE("GPL");
713
MODULE_AUTHOR("Abraham vd Merwe <abraham@2d3d.co.za>");
714
MODULE_DESCRIPTION("MTD driver for Intel 28F160F3 on LART board");
715
 
716
 

powered by: WebSVN 2.1.0

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