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

Subversion Repositories test_project

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/****************************************************************************/
2
 
3
/*
4
 *      nettel.c -- mappings for NETtel/SecureEdge/SnapGear (x86) boards.
5
 *
6
 *      (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
7
 *      (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
8
 *
9
 *      $Id: nettel.c,v 1.12 2005/11/29 14:30:00 gleixner Exp $
10
 */
11
 
12
/****************************************************************************/
13
 
14
#include <linux/module.h>
15
#include <linux/init.h>
16
#include <linux/types.h>
17
#include <linux/kernel.h>
18
#include <linux/mtd/mtd.h>
19
#include <linux/mtd/map.h>
20
#include <linux/mtd/partitions.h>
21
#include <linux/mtd/cfi.h>
22
#include <linux/reboot.h>
23
#include <linux/err.h>
24
#include <linux/kdev_t.h>
25
#include <linux/root_dev.h>
26
#include <asm/io.h>
27
 
28
/****************************************************************************/
29
 
30
#define INTEL_BUSWIDTH          1
31
#define AMD_WINDOW_MAXSIZE      0x00200000
32
#define AMD_BUSWIDTH            1
33
 
34
/*
35
 *      PAR masks and shifts, assuming 64K pages.
36
 */
37
#define SC520_PAR_ADDR_MASK     0x00003fff
38
#define SC520_PAR_ADDR_SHIFT    16
39
#define SC520_PAR_TO_ADDR(par) \
40
        (((par)&SC520_PAR_ADDR_MASK) << SC520_PAR_ADDR_SHIFT)
41
 
42
#define SC520_PAR_SIZE_MASK     0x01ffc000
43
#define SC520_PAR_SIZE_SHIFT    2
44
#define SC520_PAR_TO_SIZE(par) \
45
        ((((par)&SC520_PAR_SIZE_MASK) << SC520_PAR_SIZE_SHIFT) + (64*1024))
46
 
47
#define SC520_PAR(cs, addr, size) \
48
        ((cs) | \
49
        ((((size)-(64*1024)) >> SC520_PAR_SIZE_SHIFT) & SC520_PAR_SIZE_MASK) | \
50
        (((addr) >> SC520_PAR_ADDR_SHIFT) & SC520_PAR_ADDR_MASK))
51
 
52
#define SC520_PAR_BOOTCS        0x8a000000
53
#define SC520_PAR_ROMCS1        0xaa000000
54
#define SC520_PAR_ROMCS2        0xca000000      /* Cache disabled, 64K page */
55
 
56
static void *nettel_mmcrp = NULL;
57
 
58
#ifdef CONFIG_MTD_CFI_INTELEXT
59
static struct mtd_info *intel_mtd;
60
#endif
61
static struct mtd_info *amd_mtd;
62
 
63
/****************************************************************************/
64
 
65
/****************************************************************************/
66
 
67
#ifdef CONFIG_MTD_CFI_INTELEXT
68
static struct map_info nettel_intel_map = {
69
        .name = "SnapGear Intel",
70
        .size = 0,
71
        .bankwidth = INTEL_BUSWIDTH,
72
};
73
 
74
static struct mtd_partition nettel_intel_partitions[] = {
75
        {
76
                .name = "SnapGear kernel",
77
                .offset = 0,
78
                .size = 0x000e0000
79
        },
80
        {
81
                .name = "SnapGear filesystem",
82
                .offset = 0x00100000,
83
        },
84
        {
85
                .name = "SnapGear config",
86
                .offset = 0x000e0000,
87
                .size = 0x00020000
88
        },
89
        {
90
                .name = "SnapGear Intel",
91
                .offset = 0
92
        },
93
        {
94
                .name = "SnapGear BIOS Config",
95
                .offset = 0x007e0000,
96
                .size = 0x00020000
97
        },
98
        {
99
                .name = "SnapGear BIOS",
100
                .offset = 0x007e0000,
101
                .size = 0x00020000
102
        },
103
};
104
#endif
105
 
106
static struct map_info nettel_amd_map = {
107
        .name = "SnapGear AMD",
108
        .size = AMD_WINDOW_MAXSIZE,
109
        .bankwidth = AMD_BUSWIDTH,
110
};
111
 
112
static struct mtd_partition nettel_amd_partitions[] = {
113
        {
114
                .name = "SnapGear BIOS config",
115
                .offset = 0x000e0000,
116
                .size = 0x00010000
117
        },
118
        {
119
                .name = "SnapGear BIOS",
120
                .offset = 0x000f0000,
121
                .size = 0x00010000
122
        },
123
        {
124
                .name = "SnapGear AMD",
125
                .offset = 0
126
        },
127
        {
128
                .name = "SnapGear high BIOS",
129
                .offset = 0x001f0000,
130
                .size = 0x00010000
131
        }
132
};
133
 
134
#define NUM_AMD_PARTITIONS ARRAY_SIZE(nettel_amd_partitions)
135
 
136
/****************************************************************************/
137
 
138
#ifdef CONFIG_MTD_CFI_INTELEXT
139
 
140
/*
141
 *      Set the Intel flash back to read mode since some old boot
142
 *      loaders don't.
143
 */
144
static int nettel_reboot_notifier(struct notifier_block *nb, unsigned long val, void *v)
145
{
146
        struct cfi_private *cfi = nettel_intel_map.fldrv_priv;
147
        unsigned long b;
148
 
149
        /* Make sure all FLASH chips are put back into read mode */
150
        for (b = 0; (b < nettel_intel_partitions[3].size); b += 0x100000) {
151
                cfi_send_gen_cmd(0xff, 0x55, b, &nettel_intel_map, cfi,
152
                        cfi->device_type, NULL);
153
        }
154
        return(NOTIFY_OK);
155
}
156
 
157
static struct notifier_block nettel_notifier_block = {
158
        nettel_reboot_notifier, NULL, 0
159
};
160
 
161
#endif
162
 
163
/****************************************************************************/
164
 
165
static int __init nettel_init(void)
166
{
167
        volatile unsigned long *amdpar;
168
        unsigned long amdaddr, maxsize;
169
        int num_amd_partitions=0;
170
#ifdef CONFIG_MTD_CFI_INTELEXT
171
        volatile unsigned long *intel0par, *intel1par;
172
        unsigned long orig_bootcspar, orig_romcs1par;
173
        unsigned long intel0addr, intel0size;
174
        unsigned long intel1addr, intel1size;
175
        int intelboot, intel0cs, intel1cs;
176
        int num_intel_partitions;
177
#endif
178
        int rc = 0;
179
 
180
        nettel_mmcrp = (void *) ioremap_nocache(0xfffef000, 4096);
181
        if (nettel_mmcrp == NULL) {
182
                printk("SNAPGEAR: failed to disable MMCR cache??\n");
183
                return(-EIO);
184
        }
185
 
186
        /* Set CPU clock to be 33.000MHz */
187
        *((unsigned char *) (nettel_mmcrp + 0xc64)) = 0x01;
188
 
189
        amdpar = (volatile unsigned long *) (nettel_mmcrp + 0xc4);
190
 
191
#ifdef CONFIG_MTD_CFI_INTELEXT
192
        intelboot = 0;
193
        intel0cs = SC520_PAR_ROMCS1;
194
        intel0par = (volatile unsigned long *) (nettel_mmcrp + 0xc0);
195
        intel1cs = SC520_PAR_ROMCS2;
196
        intel1par = (volatile unsigned long *) (nettel_mmcrp + 0xbc);
197
 
198
        /*
199
         *      Save the CS settings then ensure ROMCS1 and ROMCS2 are off,
200
         *      otherwise they might clash with where we try to map BOOTCS.
201
         */
202
        orig_bootcspar = *amdpar;
203
        orig_romcs1par = *intel0par;
204
        *intel0par = 0;
205
        *intel1par = 0;
206
#endif
207
 
208
        /*
209
         *      The first thing to do is determine if we have a separate
210
         *      boot FLASH device. Typically this is a small (1 to 2MB)
211
         *      AMD FLASH part. It seems that device size is about the
212
         *      only way to tell if this is the case...
213
         */
214
        amdaddr = 0x20000000;
215
        maxsize = AMD_WINDOW_MAXSIZE;
216
 
217
        *amdpar = SC520_PAR(SC520_PAR_BOOTCS, amdaddr, maxsize);
218
        __asm__ ("wbinvd");
219
 
220
        nettel_amd_map.phys = amdaddr;
221
        nettel_amd_map.virt = ioremap_nocache(amdaddr, maxsize);
222
        if (!nettel_amd_map.virt) {
223
                printk("SNAPGEAR: failed to ioremap() BOOTCS\n");
224
                iounmap(nettel_mmcrp);
225
                return(-EIO);
226
        }
227
        simple_map_init(&nettel_amd_map);
228
 
229
        if ((amd_mtd = do_map_probe("jedec_probe", &nettel_amd_map))) {
230
                printk(KERN_NOTICE "SNAPGEAR: AMD flash device size = %dK\n",
231
                        amd_mtd->size>>10);
232
 
233
                amd_mtd->owner = THIS_MODULE;
234
 
235
                /* The high BIOS partition is only present for 2MB units */
236
                num_amd_partitions = NUM_AMD_PARTITIONS;
237
                if (amd_mtd->size < AMD_WINDOW_MAXSIZE)
238
                        num_amd_partitions--;
239
                /* Don't add the partition until after the primary INTEL's */
240
 
241
#ifdef CONFIG_MTD_CFI_INTELEXT
242
                /*
243
                 *      Map the Intel flash into memory after the AMD
244
                 *      It has to start on a multiple of maxsize.
245
                 */
246
                maxsize = SC520_PAR_TO_SIZE(orig_romcs1par);
247
                if (maxsize < (32 * 1024 * 1024))
248
                        maxsize = (32 * 1024 * 1024);
249
                intel0addr = amdaddr + maxsize;
250
#endif
251
        } else {
252
#ifdef CONFIG_MTD_CFI_INTELEXT
253
                /* INTEL boot FLASH */
254
                intelboot++;
255
 
256
                if (!orig_romcs1par) {
257
                        intel0cs = SC520_PAR_BOOTCS;
258
                        intel0par = (volatile unsigned long *)
259
                                (nettel_mmcrp + 0xc4);
260
                        intel1cs = SC520_PAR_ROMCS1;
261
                        intel1par = (volatile unsigned long *)
262
                                (nettel_mmcrp + 0xc0);
263
 
264
                        intel0addr = SC520_PAR_TO_ADDR(orig_bootcspar);
265
                        maxsize = SC520_PAR_TO_SIZE(orig_bootcspar);
266
                } else {
267
                        /* Kernel base is on ROMCS1, not BOOTCS */
268
                        intel0cs = SC520_PAR_ROMCS1;
269
                        intel0par = (volatile unsigned long *)
270
                                (nettel_mmcrp + 0xc0);
271
                        intel1cs = SC520_PAR_BOOTCS;
272
                        intel1par = (volatile unsigned long *)
273
                                (nettel_mmcrp + 0xc4);
274
 
275
                        intel0addr = SC520_PAR_TO_ADDR(orig_romcs1par);
276
                        maxsize = SC520_PAR_TO_SIZE(orig_romcs1par);
277
                }
278
 
279
                /* Destroy useless AMD MTD mapping */
280
                amd_mtd = NULL;
281
                iounmap(nettel_amd_map.virt);
282
                nettel_amd_map.virt = NULL;
283
#else
284
                /* Only AMD flash supported */
285
                rc = -ENXIO;
286
                goto out_unmap2;
287
#endif
288
        }
289
 
290
#ifdef CONFIG_MTD_CFI_INTELEXT
291
        /*
292
         *      We have determined the INTEL FLASH configuration, so lets
293
         *      go ahead and probe for them now.
294
         */
295
 
296
        /* Set PAR to the maximum size */
297
        if (maxsize < (32 * 1024 * 1024))
298
                maxsize = (32 * 1024 * 1024);
299
        *intel0par = SC520_PAR(intel0cs, intel0addr, maxsize);
300
 
301
        /* Turn other PAR off so the first probe doesn't find it */
302
        *intel1par = 0;
303
 
304
        /* Probe for the size of the first Intel flash */
305
        nettel_intel_map.size = maxsize;
306
        nettel_intel_map.phys = intel0addr;
307
        nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
308
        if (!nettel_intel_map.virt) {
309
                printk("SNAPGEAR: failed to ioremap() ROMCS1\n");
310
                rc = -EIO;
311
                goto out_unmap2;
312
        }
313
        simple_map_init(&nettel_intel_map);
314
 
315
        intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
316
        if (!intel_mtd) {
317
                rc = -ENXIO;
318
                goto out_unmap1;
319
        }
320
 
321
        /* Set PAR to the detected size */
322
        intel0size = intel_mtd->size;
323
        *intel0par = SC520_PAR(intel0cs, intel0addr, intel0size);
324
 
325
        /*
326
         *      Map second Intel FLASH right after first. Set its size to the
327
         *      same maxsize used for the first Intel FLASH.
328
         */
329
        intel1addr = intel0addr + intel0size;
330
        *intel1par = SC520_PAR(intel1cs, intel1addr, maxsize);
331
        __asm__ ("wbinvd");
332
 
333
        maxsize += intel0size;
334
 
335
        /* Delete the old map and probe again to do both chips */
336
        map_destroy(intel_mtd);
337
        intel_mtd = NULL;
338
        iounmap(nettel_intel_map.virt);
339
 
340
        nettel_intel_map.size = maxsize;
341
        nettel_intel_map.virt = ioremap_nocache(intel0addr, maxsize);
342
        if (!nettel_intel_map.virt) {
343
                printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n");
344
                rc = -EIO;
345
                goto out_unmap2;
346
        }
347
 
348
        intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
349
        if (! intel_mtd) {
350
                rc = -ENXIO;
351
                goto out_unmap1;
352
        }
353
 
354
        intel1size = intel_mtd->size - intel0size;
355
        if (intel1size > 0) {
356
                *intel1par = SC520_PAR(intel1cs, intel1addr, intel1size);
357
                __asm__ ("wbinvd");
358
        } else {
359
                *intel1par = 0;
360
        }
361
 
362
        printk(KERN_NOTICE "SNAPGEAR: Intel flash device size = %dK\n",
363
                (intel_mtd->size >> 10));
364
 
365
        intel_mtd->owner = THIS_MODULE;
366
 
367
        num_intel_partitions = sizeof(nettel_intel_partitions) /
368
                sizeof(nettel_intel_partitions[0]);
369
 
370
        if (intelboot) {
371
                /*
372
                 *      Adjust offset and size of last boot partition.
373
                 *      Must allow for BIOS region at end of FLASH.
374
                 */
375
                nettel_intel_partitions[1].size = (intel0size + intel1size) -
376
                        (1024*1024 + intel_mtd->erasesize);
377
                nettel_intel_partitions[3].size = intel0size + intel1size;
378
                nettel_intel_partitions[4].offset =
379
                        (intel0size + intel1size) - intel_mtd->erasesize;
380
                nettel_intel_partitions[4].size = intel_mtd->erasesize;
381
                nettel_intel_partitions[5].offset =
382
                        nettel_intel_partitions[4].offset;
383
                nettel_intel_partitions[5].size =
384
                        nettel_intel_partitions[4].size;
385
        } else {
386
                /* No BIOS regions when AMD boot */
387
                num_intel_partitions -= 2;
388
        }
389
        rc = add_mtd_partitions(intel_mtd, nettel_intel_partitions,
390
                num_intel_partitions);
391
#endif
392
 
393
        if (amd_mtd) {
394
                rc = add_mtd_partitions(amd_mtd, nettel_amd_partitions,
395
                        num_amd_partitions);
396
        }
397
 
398
#ifdef CONFIG_MTD_CFI_INTELEXT
399
        register_reboot_notifier(&nettel_notifier_block);
400
#endif
401
 
402
        return(rc);
403
 
404
#ifdef CONFIG_MTD_CFI_INTELEXT
405
out_unmap1:
406
        iounmap(nettel_intel_map.virt);
407
#endif
408
 
409
out_unmap2:
410
        iounmap(nettel_mmcrp);
411
        iounmap(nettel_amd_map.virt);
412
 
413
        return(rc);
414
 
415
}
416
 
417
/****************************************************************************/
418
 
419
static void __exit nettel_cleanup(void)
420
{
421
#ifdef CONFIG_MTD_CFI_INTELEXT
422
        unregister_reboot_notifier(&nettel_notifier_block);
423
#endif
424
        if (amd_mtd) {
425
                del_mtd_partitions(amd_mtd);
426
                map_destroy(amd_mtd);
427
        }
428
        if (nettel_mmcrp) {
429
                iounmap(nettel_mmcrp);
430
                nettel_mmcrp = NULL;
431
        }
432
        if (nettel_amd_map.virt) {
433
                iounmap(nettel_amd_map.virt);
434
                nettel_amd_map.virt = NULL;
435
        }
436
#ifdef CONFIG_MTD_CFI_INTELEXT
437
        if (intel_mtd) {
438
                del_mtd_partitions(intel_mtd);
439
                map_destroy(intel_mtd);
440
        }
441
        if (nettel_intel_map.virt) {
442
                iounmap(nettel_intel_map.virt);
443
                nettel_intel_map.virt = NULL;
444
        }
445
#endif
446
}
447
 
448
/****************************************************************************/
449
 
450
module_init(nettel_init);
451
module_exit(nettel_cleanup);
452
 
453
MODULE_LICENSE("GPL");
454
MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
455
MODULE_DESCRIPTION("SnapGear/SecureEdge FLASH support");
456
 
457
/****************************************************************************/

powered by: WebSVN 2.1.0

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