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

Subversion Repositories test_project

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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