ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / cris / arch-v10 / drivers / axisflashmap.c
1 /*
2  * Physical mapping layer for MTD using the Axis partitiontable format
3  *
4  * Copyright (c) 2001, 2002 Axis Communications AB
5  *
6  * This file is under the GPL.
7  *
8  * First partition is always sector 0 regardless of if we find a partitiontable
9  * or not. In the start of the next sector, there can be a partitiontable that
10  * tells us what other partitions to define. If there isn't, we use a default
11  * partition split defined below.
12  *
13  * $Log: axisflashmap.c,v $
14  * Revision 1.6  2003/07/04 08:27:37  starvik
15  * Merge of Linux 2.5.74
16  *
17  * Revision 1.5  2002/12/11 13:13:57  starvik
18  * Added arch/ to v10 specific includes
19  * Added fix from Linux 2.4 in serial.c (flush_to_flip_buffer)
20  *
21  * Revision 1.4  2002/11/20 11:56:10  starvik
22  * Merge of Linux 2.5.48
23  *
24  * Revision 1.3  2002/11/13 14:54:13  starvik
25  * Copied from linux 2.4
26  *
27  * Revision 1.28  2002/10/01 08:08:43  jonashg
28  * The first partition ends at the start of the partition table.
29  *
30  * Revision 1.27  2002/08/21 09:23:13  jonashg
31  * Speling.
32  *
33  * Revision 1.26  2002/08/21 08:35:20  jonashg
34  * Cosmetic change to printouts.
35  *
36  * Revision 1.25  2002/08/21 08:15:42  jonashg
37  * Made it compile even without CONFIG_MTD_CONCAT defined.
38  *
39  * Revision 1.24  2002/08/20 13:12:35  jonashg
40  * * New approach to probing. Probe cse0 and cse1 separately and (mtd)concat
41  *   the results.
42  * * Removed compile time tests concerning how the mtdram driver has been
43  *   configured. The user will know about the misconfiguration at runtime
44  *   instead. (The old approach made it impossible to use mtdram for anything
45  *   else than RAM boot).
46  *
47  * Revision 1.23  2002/05/13 12:12:28  johana
48  * Allow compile without CONFIG_MTD_MTDRAM but warn at compiletime and
49  * be informative at runtime.
50  *
51  * Revision 1.22  2002/05/13 10:24:44  johana
52  * Added #if checks on MTDRAM CONFIG
53  *
54  * Revision 1.21  2002/05/06 16:05:20  johana
55  * Removed debug printout.
56  *
57  * Revision 1.20  2002/05/06 16:03:00  johana
58  * No more cramfs as root hack in generic code.
59  * It's handled by axisflashmap using mtdram.
60  *
61  * Revision 1.19  2002/03/15 17:10:28  bjornw
62  * Changed comment about cached access since we changed this before
63  *
64  * Revision 1.18  2002/03/05 17:06:15  jonashg
65  * Try amd_flash probe before cfi_probe since amd_flash driver can handle two
66  * (or more) flash chips of different model and the cfi driver cannot.
67  *
68  * Revision 1.17  2001/11/12 19:42:38  pkj
69  * Fixed compiler warnings.
70  *
71  * Revision 1.16  2001/11/08 11:18:58  jonashg
72  * Always read from uncached address to avoid problems with flushing
73  * cachelines after write and MTD-erase. No performance loss have been
74  * seen yet.
75  *
76  * Revision 1.15  2001/10/19 12:41:04  jonashg
77  * Name of probe has changed in MTD.
78  *
79  * Revision 1.14  2001/09/21 07:14:10  jonashg
80  * Made root filesystem (cramfs) use mtdblock driver when booting from flash.
81  *
82  * Revision 1.13  2001/08/15 13:57:35  jonashg
83  * Entire MTD updated to the linux 2.4.7 version.
84  *
85  * Revision 1.12  2001/06/11 09:50:30  jonashg
86  * Oops, 2MB is 0x200000 bytes.
87  *
88  * Revision 1.11  2001/06/08 11:39:44  jonashg
89  * Changed sizes and offsets in axis_default_partitions to use
90  * CONFIG_ETRAX_PTABLE_SECTOR.
91  *
92  * Revision 1.10  2001/05/29 09:42:03  jonashg
93  * Use macro for end marker length instead of sizeof.
94  *
95  * Revision 1.9  2001/05/29 08:52:52  jonashg
96  * Gave names to the magic fours (size of the ptable end marker).
97  *
98  * Revision 1.8  2001/05/28 15:36:20  jonashg
99  * * Removed old comment about ptable location in flash (it's a CONFIG_ option).
100  * * Variable ptable was initialized twice to the same value.
101  *
102  * Revision 1.7  2001/04/05 13:41:46  markusl
103  * Updated according to review remarks
104  *
105  * Revision 1.6  2001/03/07 09:21:21  bjornw
106  * No need to waste .data
107  *
108  * Revision 1.5  2001/03/06 16:27:01  jonashg
109  * Probe the entire flash area for flash devices.
110  *
111  * Revision 1.4  2001/02/23 12:47:15  bjornw
112  * Uncached flash in LOW_MAP moved from 0xe to 0x8
113  *
114  * Revision 1.3  2001/02/16 12:11:45  jonashg
115  * MTD driver amd_flash is now included in MTD CVS repository.
116  * (It's now in drivers/mtd).
117  *
118  * Revision 1.2  2001/02/09 11:12:22  jonashg
119  * Support for AMD compatible non-CFI flash chips.
120  * Only tested with Toshiba TC58FVT160 so far.
121  *
122  * Revision 1.1  2001/01/12 17:01:18  bjornw
123  * * Added axisflashmap.c, a physical mapping for MTD that reads and understands
124  *   Axis partition-table format.
125  *
126  *
127  */
128
129 #include <linux/module.h>
130 #include <linux/types.h>
131 #include <linux/kernel.h>
132 #include <linux/config.h>
133 #include <linux/init.h>
134
135 #include <linux/mtd/concat.h>
136 #include <linux/mtd/map.h>
137 #include <linux/mtd/mtd.h>
138 #include <linux/mtd/mtdram.h>
139 #include <linux/mtd/partitions.h>
140
141 #include <asm/axisflashmap.h>
142 #include <asm/mmu.h>
143 #include <asm/arch/sv_addr_ag.h>
144
145 #ifdef CONFIG_CRIS_LOW_MAP
146 #define FLASH_UNCACHED_ADDR  KSEG_8
147 #define FLASH_CACHED_ADDR    KSEG_5
148 #else
149 #define FLASH_UNCACHED_ADDR  KSEG_E
150 #define FLASH_CACHED_ADDR    KSEG_F
151 #endif
152
153 /* From head.S */
154 extern unsigned long romfs_start, romfs_length, romfs_in_flash;
155
156 /* Map driver functions. */
157
158 static __u8 flash_read8(struct map_info *map, unsigned long ofs)
159 {
160         return *(__u8 *)(map->map_priv_1 + ofs);
161 }
162
163 static __u16 flash_read16(struct map_info *map, unsigned long ofs)
164 {
165         return *(__u16 *)(map->map_priv_1 + ofs);
166 }
167
168 static __u32 flash_read32(struct map_info *map, unsigned long ofs)
169 {
170         return *(volatile unsigned int *)(map->map_priv_1 + ofs);
171 }
172
173 static void flash_copy_from(struct map_info *map, void *to,
174                             unsigned long from, ssize_t len)
175 {
176         memcpy(to, (void *)(map->map_priv_1 + from), len);
177 }
178
179 static void flash_write8(struct map_info *map, __u8 d, unsigned long adr)
180 {
181         *(__u8 *)(map->map_priv_1 + adr) = d;
182 }
183
184 static void flash_write16(struct map_info *map, __u16 d, unsigned long adr)
185 {
186         *(__u16 *)(map->map_priv_1 + adr) = d;
187 }
188
189 static void flash_write32(struct map_info *map, __u32 d, unsigned long adr)
190 {
191         *(__u32 *)(map->map_priv_1 + adr) = d;
192 }
193
194 /*
195  * The map for chip select e0.
196  *
197  * We run into tricky coherence situations if we mix cached with uncached
198  * accesses to we only use the uncached version here.
199  *
200  * The size field is the total size where the flash chips may be mapped on the
201  * chip select. MTD probes should find all devices there and it does not matter
202  * if there are unmapped gaps or aliases (mirrors of flash devices). The MTD
203  * probes will ignore them.
204  *
205  * The start address in map_priv_1 is in virtual memory so we cannot use
206  * MEM_CSE0_START but must rely on that FLASH_UNCACHED_ADDR is the start
207  * address of cse0.
208  */
209 static struct map_info map_cse0 = {
210         .name = "cse0",
211         .size = MEM_CSE0_SIZE,
212         .buswidth = CONFIG_ETRAX_FLASH_BUSWIDTH,
213         .read8 = flash_read8,
214         .read16 = flash_read16,
215         .read32 = flash_read32,
216         .copy_from = flash_copy_from,
217         .write8 = flash_write8,
218         .write16 = flash_write16,
219         .write32 = flash_write32,
220         .map_priv_1 = FLASH_UNCACHED_ADDR
221 };
222
223 /*
224  * The map for chip select e1.
225  *
226  * If there was a gap between cse0 and cse1, map_priv_1 would get the wrong
227  * address, but there isn't.
228  */
229 static struct map_info map_cse1 = {
230         .name = "cse1",
231         .size = MEM_CSE1_SIZE,
232         .buswidth = CONFIG_ETRAX_FLASH_BUSWIDTH,
233         .read8 = flash_read8,
234         .read16 = flash_read16,
235         .read32 = flash_read32,
236         .copy_from = flash_copy_from,
237         .write8 = flash_write8,
238         .write16 = flash_write16,
239         .write32 = flash_write32,
240         .map_priv_1 = FLASH_UNCACHED_ADDR + MEM_CSE0_SIZE
241 };
242
243 /* If no partition-table was found, we use this default-set. */
244 #define MAX_PARTITIONS         7  
245 #define NUM_DEFAULT_PARTITIONS 3
246
247 /*
248  * Default flash size is 2MB. CONFIG_ETRAX_PTABLE_SECTOR is most likely the
249  * size of one flash block and "filesystem"-partition needs 5 blocks to be able
250  * to use JFFS.
251  */
252 static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
253         {
254                 .name = "boot firmware",
255                 .size = CONFIG_ETRAX_PTABLE_SECTOR,
256                 .offset = 0
257         },
258         {
259                 .name = "kernel",
260                 .size = 0x200000 - (6 * CONFIG_ETRAX_PTABLE_SECTOR),
261                 .offset = CONFIG_ETRAX_PTABLE_SECTOR
262         },
263         {
264                 .name = "filesystem",
265                 .size = 5 * CONFIG_ETRAX_PTABLE_SECTOR,
266                 .offset = 0x200000 - (5 * CONFIG_ETRAX_PTABLE_SECTOR)
267         }
268 };
269
270 /* Initialize the ones normally used. */
271 static struct mtd_partition axis_partitions[MAX_PARTITIONS] = {
272         {
273                 .name = "part0",
274                 .size = CONFIG_ETRAX_PTABLE_SECTOR,
275                 .offset = 0
276         },
277         {
278                 .name = "part1",
279                 .size = 0,
280                 .offset = 0
281         },
282         {
283                 .name = "part2",
284                 .size = 0,
285                 .offset = 0
286         },
287         {
288                 .name = "part3",
289                 .size = 0,
290                 .offset = 0
291         },
292         {
293                 .name = "part4",
294                 .size = 0,
295                 .offset = 0
296         },
297         {
298                 .name = "part5",
299                 .size = 0,
300                 .offset = 0
301         },
302         {
303                 .name = "part6",
304                 .size = 0,
305                 .offset = 0
306         },
307 };
308
309 /*
310  * Probe a chip select for AMD-compatible (JEDEC) or CFI-compatible flash
311  * chips in that order (because the amd_flash-driver is faster).
312  */
313 static struct mtd_info *probe_cs(struct map_info *map_cs)
314 {
315         struct mtd_info *mtd_cs = NULL;
316
317         printk("%s: Probing a 0x%08lx bytes large window at 0x%08lx.\n",
318                map_cs->name, map_cs->size, map_cs->map_priv_1);
319
320 #ifdef CONFIG_MTD_AMDSTD
321         mtd_cs = do_map_probe("amd_flash", map_cs);
322 #endif
323 #ifdef CONFIG_MTD_CFI
324         if (!mtd_cs) {
325                 mtd_cs = do_map_probe("cfi_probe", map_cs);
326         }
327 #endif
328
329         return mtd_cs;
330 }
331
332 /* 
333  * Probe each chip select individually for flash chips. If there are chips on
334  * both cse0 and cse1, the mtd_info structs will be concatenated to one struct
335  * so that MTD partitions can cross chip boundries.
336  *
337  * The only known restriction to how you can mount your chips is that each
338  * chip select must hold similar flash chips. But you need external hardware
339  * to do that anyway and you can put totally different chips on cse0 and cse1
340  * so it isn't really much of a restriction.
341  */
342 static struct mtd_info *flash_probe(void)
343 {
344         struct mtd_info *mtd_cse0;
345         struct mtd_info *mtd_cse1;
346         struct mtd_info *mtd_cse;
347
348         mtd_cse0 = probe_cs(&map_cse0);
349         mtd_cse1 = probe_cs(&map_cse1);
350
351         if (!mtd_cse0 && !mtd_cse1) {
352                 /* No chip found. */
353                 return NULL;
354         }
355
356         if (mtd_cse0 && mtd_cse1) {
357 #ifdef CONFIG_MTD_CONCAT
358                 struct mtd_info *mtds[] = { mtd_cse0, mtd_cse1 };
359                 
360                 /* Since the concatenation layer adds a small overhead we
361                  * could try to figure out if the chips in cse0 and cse1 are
362                  * identical and reprobe the whole cse0+cse1 window. But since
363                  * flash chips are slow, the overhead is relatively small.
364                  * So we use the MTD concatenation layer instead of further
365                  * complicating the probing procedure.
366                  */
367                 mtd_cse = mtd_concat_create(mtds,
368                                             sizeof(mtds) / sizeof(mtds[0]),
369                                             "cse0+cse1");
370 #else
371                 printk(KERN_ERR "%s and %s: Cannot concatenate due to kernel "
372                        "(mis)configuration!\n", map_cse0.name, map_cse1.name);
373                 mtd_cse = NULL;
374 #endif
375                 if (!mtd_cse) {
376                         printk(KERN_ERR "%s and %s: Concatenation failed!\n",
377                                map_cse0.name, map_cse1.name);
378
379                         /* The best we can do now is to only use what we found
380                          * at cse0.
381                          */ 
382                         mtd_cse = mtd_cse0;
383                         map_destroy(mtd_cse1);
384                 }
385         } else {
386                 mtd_cse = mtd_cse0? mtd_cse0 : mtd_cse1;
387         }
388
389         return mtd_cse;
390 }
391
392 /*
393  * Probe the flash chip(s) and, if it succeeds, read the partition-table
394  * and register the partitions with MTD.
395  */
396 static int __init init_axis_flash(void)
397 {
398         struct mtd_info *mymtd;
399         int err = 0;
400         int pidx = 0;
401         struct partitiontable_head *ptable_head;
402         struct partitiontable_entry *ptable;
403         int use_default_ptable = 1; /* Until proven otherwise. */
404         const char *pmsg = "  /dev/flash%d at 0x%08x, size 0x%08x\n";
405
406         if (!(mymtd = flash_probe())) {
407                 /* There's no reason to use this module if no flash chip can
408                  * be identified. Make sure that's understood.
409                  */
410                 panic("axisflashmap found no flash chip!\n");
411         }
412
413         printk("%s: 0x%08x bytes of flash memory.\n",
414                mymtd->name, mymtd->size);
415
416         mymtd->owner = THIS_MODULE;
417
418         ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR +
419                       CONFIG_ETRAX_PTABLE_SECTOR + PARTITION_TABLE_OFFSET);
420         pidx++;  /* First partition is always set to the default. */
421
422         if ((ptable_head->magic == PARTITION_TABLE_MAGIC)
423             && (ptable_head->size <
424                 (MAX_PARTITIONS * sizeof(struct partitiontable_entry) +
425                 PARTITIONTABLE_END_MARKER_SIZE))
426             && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) +
427                                   ptable_head->size -
428                                   PARTITIONTABLE_END_MARKER_SIZE)
429                 == PARTITIONTABLE_END_MARKER)) {
430                 /* Looks like a start, sane length and end of a
431                  * partition table, lets check csum etc.
432                  */
433                 int ptable_ok = 0;
434                 struct partitiontable_entry *max_addr =
435                         (struct partitiontable_entry *)
436                         ((unsigned long)ptable_head + sizeof(*ptable_head) +
437                          ptable_head->size);
438                 unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR;
439                 unsigned char *p;
440                 unsigned long csum = 0;
441                 
442                 ptable = (struct partitiontable_entry *)
443                         ((unsigned long)ptable_head + sizeof(*ptable_head));
444
445                 /* Lets be PARANOID, and check the checksum. */
446                 p = (unsigned char*) ptable;
447
448                 while (p <= (unsigned char*)max_addr) {
449                         csum += *p++;
450                         csum += *p++;
451                         csum += *p++;
452                         csum += *p++;
453                 }
454                 ptable_ok = (csum == ptable_head->checksum);
455
456                 /* Read the entries and use/show the info.  */
457                 printk(" Found a%s partition table at 0x%p-0x%p.\n",
458                        (ptable_ok ? " valid" : "n invalid"), ptable_head,
459                        max_addr);
460
461                 /* We have found a working bootblock.  Now read the
462                  * partition table.  Scan the table.  It ends when
463                  * there is 0xffffffff, that is, empty flash.
464                  */
465                 while (ptable_ok
466                        && ptable->offset != 0xffffffff
467                        && ptable < max_addr
468                        && pidx < MAX_PARTITIONS) {
469
470                         axis_partitions[pidx].offset = offset + ptable->offset;
471                         axis_partitions[pidx].size = ptable->size;
472
473                         printk(pmsg, pidx, axis_partitions[pidx].offset,
474                                axis_partitions[pidx].size);
475                         pidx++;
476                         ptable++;
477                 }
478                 use_default_ptable = !ptable_ok;
479         }
480
481         if (romfs_in_flash) {
482                 /* Add an overlapping device for the root partition (romfs). */
483
484                 axis_partitions[pidx].name = "romfs";
485                 axis_partitions[pidx].size = romfs_length;
486                 axis_partitions[pidx].offset = romfs_start - FLASH_CACHED_ADDR;
487                 axis_partitions[pidx].mask_flags |= MTD_WRITEABLE;
488
489                 printk(" Adding readonly flash partition for romfs image:\n");
490                 printk(pmsg, pidx, axis_partitions[pidx].offset,
491                        axis_partitions[pidx].size);
492                 pidx++;
493         }
494
495         if (use_default_ptable) {
496                 printk(" Using default partition table.\n");
497                 err = add_mtd_partitions(mymtd, axis_default_partitions,
498                                          NUM_DEFAULT_PARTITIONS);
499         } else {
500                 err = add_mtd_partitions(mymtd, axis_partitions, pidx);
501         }
502
503         if (err) {
504                 panic("axisflashmap could not add MTD partitions!\n");
505         }
506
507         if (!romfs_in_flash) {
508                 /* Create an RAM device for the root partition (romfs). */
509
510 #if !defined(CONFIG_MTD_MTDRAM) || (CONFIG_MTDRAM_TOTAL_SIZE != 0) || (CONFIG_MTDRAM_ABS_POS != 0)
511                 /* No use trying to boot this kernel from RAM. Panic! */
512                 printk(KERN_EMERG "axisflashmap: Cannot create an MTD RAM "
513                        "device due to kernel (mis)configuration!\n");
514                 panic("This kernel cannot boot from RAM!\n");
515 #else
516                 struct mtd_info *mtd_ram;
517
518                 mtd_ram = (struct mtd_info *)kmalloc(sizeof(struct mtd_info),
519                                                      GFP_KERNEL);
520                 if (!mtd_ram) {
521                         panic("axisflashmap couldn't allocate memory for "
522                               "mtd_info!\n");
523                 }
524
525                 printk(" Adding RAM partition for romfs image:\n");
526                 printk(pmsg, pidx, romfs_start, romfs_length);
527
528                 err = mtdram_init_device(mtd_ram, (void*)romfs_start, 
529                                          romfs_length, "romfs");
530                 if (err) {
531                         panic("axisflashmap could not initialize MTD RAM "
532                               "device!\n");
533                 }
534 #endif
535         }
536
537         return err;
538 }
539
540 /* This adds the above to the kernels init-call chain. */
541 module_init(init_axis_flash);