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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [powerpc/] [boot/] [prpmc2800.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * Motorola ECC prpmc280/f101 & prpmc2800/f101e platform code.
3
 *
4
 * Author: Mark A. Greer <mgreer@mvista.com>
5
 *
6
 * 2007 (c) MontaVista, Software, Inc.  This file is licensed under
7
 * the terms of the GNU General Public License version 2.  This program
8
 * is licensed "as is" without any warranty of any kind, whether express
9
 * or implied.
10
 */
11
 
12
#include <stdarg.h>
13
#include <stddef.h>
14
#include "types.h"
15
#include "elf.h"
16
#include "page.h"
17
#include "string.h"
18
#include "stdio.h"
19
#include "io.h"
20
#include "ops.h"
21
#include "gunzip_util.h"
22
#include "mv64x60.h"
23
 
24
#define KB      1024U
25
#define MB      (KB*KB)
26
#define GB      (KB*MB)
27
#define MHz     (1000U*1000U)
28
#define GHz     (1000U*MHz)
29
 
30
#define BOARD_MODEL     "PrPMC2800"
31
#define BOARD_MODEL_MAX 32 /* max strlen(BOARD_MODEL) + 1 */
32
 
33
#define EEPROM2_ADDR    0xa4
34
#define EEPROM3_ADDR    0xa8
35
 
36
BSS_STACK(16*KB);
37
 
38
static u8 *bridge_base;
39
 
40
typedef enum {
41
        BOARD_MODEL_PRPMC280,
42
        BOARD_MODEL_PRPMC2800,
43
} prpmc2800_board_model;
44
 
45
typedef enum {
46
        BRIDGE_TYPE_MV64360,
47
        BRIDGE_TYPE_MV64362,
48
} prpmc2800_bridge_type;
49
 
50
struct prpmc2800_board_info {
51
        prpmc2800_board_model model;
52
        char variant;
53
        prpmc2800_bridge_type bridge_type;
54
        u8 subsys0;
55
        u8 subsys1;
56
        u8 vpd4;
57
        u8 vpd4_mask;
58
        u32 core_speed;
59
        u32 mem_size;
60
        u32 boot_flash;
61
        u32 user_flash;
62
};
63
 
64
static struct prpmc2800_board_info prpmc2800_board_info[] = {
65
        {
66
                .model          = BOARD_MODEL_PRPMC280,
67
                .variant        = 'a',
68
                .bridge_type    = BRIDGE_TYPE_MV64360,
69
                .subsys0        = 0xff,
70
                .subsys1        = 0xff,
71
                .vpd4           = 0x00,
72
                .vpd4_mask      = 0x0f,
73
                .core_speed     = 1*GHz,
74
                .mem_size       = 512*MB,
75
                .boot_flash     = 1*MB,
76
                .user_flash     = 64*MB,
77
        },
78
        {
79
                .model          = BOARD_MODEL_PRPMC280,
80
                .variant        = 'b',
81
                .bridge_type    = BRIDGE_TYPE_MV64362,
82
                .subsys0        = 0xff,
83
                .subsys1        = 0xff,
84
                .vpd4           = 0x01,
85
                .vpd4_mask      = 0x0f,
86
                .core_speed     = 1*GHz,
87
                .mem_size       = 512*MB,
88
                .boot_flash     = 0,
89
                .user_flash     = 0,
90
        },
91
        {
92
                .model          = BOARD_MODEL_PRPMC280,
93
                .variant        = 'c',
94
                .bridge_type    = BRIDGE_TYPE_MV64360,
95
                .subsys0        = 0xff,
96
                .subsys1        = 0xff,
97
                .vpd4           = 0x02,
98
                .vpd4_mask      = 0x0f,
99
                .core_speed     = 733*MHz,
100
                .mem_size       = 512*MB,
101
                .boot_flash     = 1*MB,
102
                .user_flash     = 64*MB,
103
        },
104
        {
105
                .model          = BOARD_MODEL_PRPMC280,
106
                .variant        = 'd',
107
                .bridge_type    = BRIDGE_TYPE_MV64360,
108
                .subsys0        = 0xff,
109
                .subsys1        = 0xff,
110
                .vpd4           = 0x03,
111
                .vpd4_mask      = 0x0f,
112
                .core_speed     = 1*GHz,
113
                .mem_size       = 1*GB,
114
                .boot_flash     = 1*MB,
115
                .user_flash     = 64*MB,
116
        },
117
        {
118
                .model          = BOARD_MODEL_PRPMC280,
119
                .variant        = 'e',
120
                .bridge_type    = BRIDGE_TYPE_MV64360,
121
                .subsys0        = 0xff,
122
                .subsys1        = 0xff,
123
                .vpd4           = 0x04,
124
                .vpd4_mask      = 0x0f,
125
                .core_speed     = 1*GHz,
126
                .mem_size       = 512*MB,
127
                .boot_flash     = 1*MB,
128
                .user_flash     = 64*MB,
129
        },
130
        {
131
                .model          = BOARD_MODEL_PRPMC280,
132
                .variant        = 'f',
133
                .bridge_type    = BRIDGE_TYPE_MV64362,
134
                .subsys0        = 0xff,
135
                .subsys1        = 0xff,
136
                .vpd4           = 0x05,
137
                .vpd4_mask      = 0x0f,
138
                .core_speed     = 733*MHz,
139
                .mem_size       = 128*MB,
140
                .boot_flash     = 1*MB,
141
                .user_flash     = 0,
142
        },
143
        {
144
                .model          = BOARD_MODEL_PRPMC280,
145
                .variant        = 'g',
146
                .bridge_type    = BRIDGE_TYPE_MV64360,
147
                .subsys0        = 0xff,
148
                .subsys1        = 0xff,
149
                .vpd4           = 0x06,
150
                .vpd4_mask      = 0x0f,
151
                .core_speed     = 1*GHz,
152
                .mem_size       = 256*MB,
153
                .boot_flash     = 1*MB,
154
                .user_flash     = 0,
155
        },
156
        {
157
                .model          = BOARD_MODEL_PRPMC280,
158
                .variant        = 'h',
159
                .bridge_type    = BRIDGE_TYPE_MV64360,
160
                .subsys0        = 0xff,
161
                .subsys1        = 0xff,
162
                .vpd4           = 0x07,
163
                .vpd4_mask      = 0x0f,
164
                .core_speed     = 1*GHz,
165
                .mem_size       = 1*GB,
166
                .boot_flash     = 1*MB,
167
                .user_flash     = 64*MB,
168
        },
169
        {
170
                .model          = BOARD_MODEL_PRPMC2800,
171
                .variant        = 'a',
172
                .bridge_type    = BRIDGE_TYPE_MV64360,
173
                .subsys0        = 0xb2,
174
                .subsys1        = 0x8c,
175
                .vpd4           = 0x00,
176
                .vpd4_mask      = 0x00,
177
                .core_speed     = 1*GHz,
178
                .mem_size       = 512*MB,
179
                .boot_flash     = 2*MB,
180
                .user_flash     = 64*MB,
181
        },
182
        {
183
                .model          = BOARD_MODEL_PRPMC2800,
184
                .variant        = 'b',
185
                .bridge_type    = BRIDGE_TYPE_MV64362,
186
                .subsys0        = 0xb2,
187
                .subsys1        = 0x8d,
188
                .vpd4           = 0x00,
189
                .vpd4_mask      = 0x00,
190
                .core_speed     = 1*GHz,
191
                .mem_size       = 512*MB,
192
                .boot_flash     = 0,
193
                .user_flash     = 0,
194
        },
195
        {
196
                .model          = BOARD_MODEL_PRPMC2800,
197
                .variant        = 'c',
198
                .bridge_type    = BRIDGE_TYPE_MV64360,
199
                .subsys0        = 0xb2,
200
                .subsys1        = 0x8e,
201
                .vpd4           = 0x00,
202
                .vpd4_mask      = 0x00,
203
                .core_speed     = 733*MHz,
204
                .mem_size       = 512*MB,
205
                .boot_flash     = 2*MB,
206
                .user_flash     = 64*MB,
207
        },
208
        {
209
                .model          = BOARD_MODEL_PRPMC2800,
210
                .variant        = 'd',
211
                .bridge_type    = BRIDGE_TYPE_MV64360,
212
                .subsys0        = 0xb2,
213
                .subsys1        = 0x8f,
214
                .vpd4           = 0x00,
215
                .vpd4_mask      = 0x00,
216
                .core_speed     = 1*GHz,
217
                .mem_size       = 1*GB,
218
                .boot_flash     = 2*MB,
219
                .user_flash     = 64*MB,
220
        },
221
        {
222
                .model          = BOARD_MODEL_PRPMC2800,
223
                .variant        = 'e',
224
                .bridge_type    = BRIDGE_TYPE_MV64360,
225
                .subsys0        = 0xa2,
226
                .subsys1        = 0x8a,
227
                .vpd4           = 0x00,
228
                .vpd4_mask      = 0x00,
229
                .core_speed     = 1*GHz,
230
                .mem_size       = 512*MB,
231
                .boot_flash     = 2*MB,
232
                .user_flash     = 64*MB,
233
        },
234
        {
235
                .model          = BOARD_MODEL_PRPMC2800,
236
                .variant        = 'f',
237
                .bridge_type    = BRIDGE_TYPE_MV64362,
238
                .subsys0        = 0xa2,
239
                .subsys1        = 0x8b,
240
                .vpd4           = 0x00,
241
                .vpd4_mask      = 0x00,
242
                .core_speed     = 733*MHz,
243
                .mem_size       = 128*MB,
244
                .boot_flash     = 2*MB,
245
                .user_flash     = 0,
246
        },
247
        {
248
                .model          = BOARD_MODEL_PRPMC2800,
249
                .variant        = 'g',
250
                .bridge_type    = BRIDGE_TYPE_MV64360,
251
                .subsys0        = 0xa2,
252
                .subsys1        = 0x8c,
253
                .vpd4           = 0x00,
254
                .vpd4_mask      = 0x00,
255
                .core_speed     = 1*GHz,
256
                .mem_size       = 2*GB,
257
                .boot_flash     = 2*MB,
258
                .user_flash     = 64*MB,
259
        },
260
        {
261
                .model          = BOARD_MODEL_PRPMC2800,
262
                .variant        = 'h',
263
                .bridge_type    = BRIDGE_TYPE_MV64360,
264
                .subsys0        = 0xa2,
265
                .subsys1        = 0x8d,
266
                .vpd4           = 0x00,
267
                .vpd4_mask      = 0x00,
268
                .core_speed     = 733*MHz,
269
                .mem_size       = 1*GB,
270
                .boot_flash     = 2*MB,
271
                .user_flash     = 64*MB,
272
        },
273
};
274
 
275
static struct prpmc2800_board_info *prpmc2800_get_board_info(u8 *vpd)
276
{
277
        struct prpmc2800_board_info *bip;
278
        int i;
279
 
280
        for (i=0,bip=prpmc2800_board_info; i<ARRAY_SIZE(prpmc2800_board_info);
281
                        i++,bip++)
282
                if ((vpd[0] == bip->subsys0) && (vpd[1] == bip->subsys1)
283
                                && ((vpd[4] & bip->vpd4_mask) == bip->vpd4))
284
                        return bip;
285
 
286
        return NULL;
287
}
288
 
289
/* Get VPD from i2c eeprom 2, then match it to a board info entry */
290
static struct prpmc2800_board_info *prpmc2800_get_bip(void)
291
{
292
        struct prpmc2800_board_info *bip;
293
        u8 vpd[5];
294
        int rc;
295
 
296
        if (mv64x60_i2c_open())
297
                fatal("Error: Can't open i2c device\n\r");
298
 
299
        /* Get VPD from i2c eeprom-2 */
300
        memset(vpd, 0, sizeof(vpd));
301
        rc = mv64x60_i2c_read(EEPROM2_ADDR, vpd, 0x1fde, 2, sizeof(vpd));
302
        if (rc < 0)
303
                fatal("Error: Couldn't read eeprom2\n\r");
304
        mv64x60_i2c_close();
305
 
306
        /* Get board type & related info */
307
        bip = prpmc2800_get_board_info(vpd);
308
        if (bip == NULL) {
309
                printf("Error: Unsupported board or corrupted VPD:\n\r");
310
                printf("  0x%x 0x%x 0x%x 0x%x 0x%x\n\r",
311
                                vpd[0], vpd[1], vpd[2], vpd[3], vpd[4]);
312
                printf("Using device tree defaults...\n\r");
313
        }
314
 
315
        return bip;
316
}
317
 
318
static void prpmc2800_bridge_setup(u32 mem_size)
319
{
320
        u32 i, v[12], enables, acc_bits;
321
        u32 pci_base_hi, pci_base_lo, size, buf[2];
322
        unsigned long cpu_base;
323
        int rc;
324
        void *devp;
325
        u8 *bridge_pbase, is_coherent;
326
        struct mv64x60_cpu2pci_win *tbl;
327
 
328
        bridge_pbase = mv64x60_get_bridge_pbase();
329
        is_coherent = mv64x60_is_coherent();
330
 
331
        if (is_coherent)
332
                acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_WB
333
                        | MV64x60_PCI_ACC_CNTL_SWAP_NONE
334
                        | MV64x60_PCI_ACC_CNTL_MBURST_32_BYTES
335
                        | MV64x60_PCI_ACC_CNTL_RDSIZE_32_BYTES;
336
        else
337
                acc_bits = MV64x60_PCI_ACC_CNTL_SNOOP_NONE
338
                        | MV64x60_PCI_ACC_CNTL_SWAP_NONE
339
                        | MV64x60_PCI_ACC_CNTL_MBURST_128_BYTES
340
                        | MV64x60_PCI_ACC_CNTL_RDSIZE_256_BYTES;
341
 
342
        mv64x60_config_ctlr_windows(bridge_base, bridge_pbase, is_coherent);
343
        mv64x60_config_pci_windows(bridge_base, bridge_pbase, 0, 0, mem_size,
344
                        acc_bits);
345
 
346
        /* Get the cpu -> pci i/o & mem mappings from the device tree */
347
        devp = finddevice("/mv64x60/pci@80000000");
348
        if (devp == NULL)
349
                fatal("Error: Missing /mv64x60/pci@80000000"
350
                                " device tree node\n\r");
351
 
352
        rc = getprop(devp, "ranges", v, sizeof(v));
353
        if (rc != sizeof(v))
354
                fatal("Error: Can't find /mv64x60/pci@80000000/ranges"
355
                                " property\n\r");
356
 
357
        /* Get the cpu -> pci i/o & mem mappings from the device tree */
358
        devp = finddevice("/mv64x60");
359
        if (devp == NULL)
360
                fatal("Error: Missing /mv64x60 device tree node\n\r");
361
 
362
        enables = in_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE));
363
        enables |= 0x0007fe00; /* Disable all cpu->pci windows */
364
        out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), enables);
365
 
366
        for (i=0; i<12; i+=6) {
367
                switch (v[i] & 0xff000000) {
368
                case 0x01000000: /* PCI I/O Space */
369
                        tbl = mv64x60_cpu2pci_io;
370
                        break;
371
                case 0x02000000: /* PCI MEM Space */
372
                        tbl = mv64x60_cpu2pci_mem;
373
                        break;
374
                default:
375
                        continue;
376
                }
377
 
378
                pci_base_hi = v[i+1];
379
                pci_base_lo = v[i+2];
380
                cpu_base = v[i+3];
381
                size = v[i+5];
382
 
383
                buf[0] = cpu_base;
384
                buf[1] = size;
385
 
386
                if (!dt_xlate_addr(devp, buf, sizeof(buf), &cpu_base))
387
                        fatal("Error: Can't translate PCI address 0x%x\n\r",
388
                                        (u32)cpu_base);
389
 
390
                mv64x60_config_cpu2pci_window(bridge_base, 0, pci_base_hi,
391
                                pci_base_lo, cpu_base, size, tbl);
392
        }
393
 
394
        enables &= ~0x00000600; /* Enable cpu->pci0 i/o, cpu->pci0 mem0 */
395
        out_le32((u32 *)(bridge_base + MV64x60_CPU_BAR_ENABLE), enables);
396
}
397
 
398
static void prpmc2800_fixups(void)
399
{
400
        u32 v[2], l, mem_size;
401
        int rc;
402
        void *devp;
403
        char model[BOARD_MODEL_MAX];
404
        struct prpmc2800_board_info *bip;
405
 
406
        bip = prpmc2800_get_bip(); /* Get board info based on VPD */
407
 
408
        mem_size = (bip) ? bip->mem_size : mv64x60_get_mem_size(bridge_base);
409
        prpmc2800_bridge_setup(mem_size); /* Do necessary bridge setup */
410
 
411
        /* If the VPD doesn't match what we know about, just use the
412
         * defaults already in the device tree.
413
         */
414
        if (!bip)
415
                return;
416
 
417
        /* Know the board type so override device tree defaults */
418
        /* Set /model appropriately */
419
        devp = finddevice("/");
420
        if (devp == NULL)
421
                fatal("Error: Missing '/' device tree node\n\r");
422
        memset(model, 0, BOARD_MODEL_MAX);
423
        strncpy(model, BOARD_MODEL, BOARD_MODEL_MAX - 2);
424
        l = strlen(model);
425
        if (bip->model == BOARD_MODEL_PRPMC280)
426
                l--;
427
        model[l++] = bip->variant;
428
        model[l++] = '\0';
429
        setprop(devp, "model", model, l);
430
 
431
        /* Set /cpus/PowerPC,7447/clock-frequency */
432
        devp = finddevice("/cpus/PowerPC,7447");
433
        if (devp == NULL)
434
                fatal("Error: Missing proper /cpus device tree node\n\r");
435
        v[0] = bip->core_speed;
436
        setprop(devp, "clock-frequency", &v[0], sizeof(v[0]));
437
 
438
        /* Set /memory/reg size */
439
        devp = finddevice("/memory");
440
        if (devp == NULL)
441
                fatal("Error: Missing /memory device tree node\n\r");
442
        v[0] = 0;
443
        v[1] = bip->mem_size;
444
        setprop(devp, "reg", v, sizeof(v));
445
 
446
        /* Update /mv64x60/model, if this is a mv64362 */
447
        if (bip->bridge_type == BRIDGE_TYPE_MV64362) {
448
                devp = finddevice("/mv64x60");
449
                if (devp == NULL)
450
                        fatal("Error: Missing /mv64x60 device tree node\n\r");
451
                setprop(devp, "model", "mv64362", strlen("mv64362") + 1);
452
        }
453
 
454
        /* Set User FLASH size */
455
        devp = finddevice("/mv64x60/flash@a0000000");
456
        if (devp == NULL)
457
                fatal("Error: Missing User FLASH device tree node\n\r");
458
        rc = getprop(devp, "reg", v, sizeof(v));
459
        if (rc != sizeof(v))
460
                fatal("Error: Can't find User FLASH reg property\n\r");
461
        v[1] = bip->user_flash;
462
        setprop(devp, "reg", v, sizeof(v));
463
}
464
 
465
#define MV64x60_MPP_CNTL_0      0xf000
466
#define MV64x60_MPP_CNTL_2      0xf008
467
#define MV64x60_GPP_IO_CNTL     0xf100
468
#define MV64x60_GPP_LEVEL_CNTL  0xf110
469
#define MV64x60_GPP_VALUE_SET   0xf118
470
 
471
static void prpmc2800_reset(void)
472
{
473
        u32 temp;
474
 
475
        udelay(5000000);
476
 
477
        if (bridge_base != 0) {
478
                temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0));
479
                temp &= 0xFFFF0FFF;
480
                out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_0), temp);
481
 
482
                temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL));
483
                temp |= 0x00000004;
484
                out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp);
485
 
486
                temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
487
                temp |= 0x00000004;
488
                out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
489
 
490
                temp = in_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2));
491
                temp &= 0xFFFF0FFF;
492
                out_le32((u32 *)(bridge_base + MV64x60_MPP_CNTL_2), temp);
493
 
494
                temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL));
495
                temp |= 0x00080000;
496
                out_le32((u32 *)(bridge_base + MV64x60_GPP_LEVEL_CNTL), temp);
497
 
498
                temp = in_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL));
499
                temp |= 0x00080000;
500
                out_le32((u32 *)(bridge_base + MV64x60_GPP_IO_CNTL), temp);
501
 
502
                out_le32((u32 *)(bridge_base + MV64x60_GPP_VALUE_SET),
503
                                0x00080004);
504
        }
505
 
506
        for (;;);
507
}
508
 
509
#define HEAP_SIZE       (16*MB)
510
static struct gunzip_state gzstate;
511
 
512
void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
513
                   unsigned long r6, unsigned long r7)
514
{
515
        struct elf_info ei;
516
        char *heap_start, *dtb;
517
        int dt_size = _dtb_end - _dtb_start;
518
        void *vmlinuz_addr = _vmlinux_start;
519
        unsigned long vmlinuz_size = _vmlinux_end - _vmlinux_start;
520
        char elfheader[256];
521
 
522
        if (dt_size <= 0) /* No fdt */
523
                exit();
524
 
525
        /*
526
         * Start heap after end of the kernel (after decompressed to
527
         * address 0) or the end of the zImage, whichever is higher.
528
         * That's so things allocated by simple_alloc won't overwrite
529
         * any part of the zImage and the kernel won't overwrite the dtb
530
         * when decompressed & relocated.
531
         */
532
        gunzip_start(&gzstate, vmlinuz_addr, vmlinuz_size);
533
        gunzip_exactly(&gzstate, elfheader, sizeof(elfheader));
534
 
535
        if (!parse_elf32(elfheader, &ei))
536
                exit();
537
 
538
        heap_start = (char *)(ei.memsize + ei.elfoffset); /* end of kernel*/
539
        heap_start = max(heap_start, (char *)_end); /* end of zImage */
540
 
541
        if ((unsigned)simple_alloc_init(heap_start, HEAP_SIZE, 2*KB, 16)
542
                        > (128*MB))
543
                exit();
544
 
545
        /* Relocate dtb to safe area past end of zImage & kernel */
546
        dtb = malloc(dt_size);
547
        if (!dtb)
548
                exit();
549
        memmove(dtb, _dtb_start, dt_size);
550
        if (ft_init(dtb, dt_size, 16))
551
                exit();
552
 
553
        bridge_base = mv64x60_get_bridge_base();
554
 
555
        platform_ops.fixups = prpmc2800_fixups;
556
        platform_ops.exit = prpmc2800_reset;
557
 
558
        if (serial_console_init() < 0)
559
                exit();
560
}
561
 
562
/* _zimage_start called very early--need to turn off external interrupts */
563
asm ("  .globl _zimage_start\n\
564
        _zimage_start:\n\
565
                mfmsr   10\n\
566
                rlwinm  10,10,0,~(1<<15)        /* Clear MSR_EE */\n\
567
                sync\n\
568
                mtmsr   10\n\
569
                isync\n\
570
                b _zimage_start_lib\n\
571
");

powered by: WebSVN 2.1.0

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