2 * Motorola ECC prpmc280/f101 & prpmc2800/f101e platform code.
4 * Author: Mark A. Greer <mgreer@mvista.com>
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
21 #include "gunzip_util.h"
25 extern char _vmlinux_start
[], _vmlinux_end
[];
26 extern char _dtb_start
[], _dtb_end
[];
28 extern void udelay(long delay
);
33 #define MHz (1000U*1000U)
34 #define GHz (1000U*MHz)
36 #define BOARD_MODEL "PrPMC2800"
37 #define BOARD_MODEL_MAX 32 /* max strlen(BOARD_MODEL) + 1 */
39 #define EEPROM2_ADDR 0xa4
40 #define EEPROM3_ADDR 0xa8
44 static u8
*bridge_base
;
48 BOARD_MODEL_PRPMC2800
,
49 } prpmc2800_board_model
;
54 } prpmc2800_bridge_type
;
56 struct prpmc2800_board_info
{
57 prpmc2800_board_model model
;
59 prpmc2800_bridge_type bridge_type
;
70 static struct prpmc2800_board_info prpmc2800_board_info
[] = {
72 .model
= BOARD_MODEL_PRPMC280
,
74 .bridge_type
= BRIDGE_TYPE_MV64360
,
85 .model
= BOARD_MODEL_PRPMC280
,
87 .bridge_type
= BRIDGE_TYPE_MV64362
,
98 .model
= BOARD_MODEL_PRPMC280
,
100 .bridge_type
= BRIDGE_TYPE_MV64360
,
105 .core_speed
= 733*MHz
,
111 .model
= BOARD_MODEL_PRPMC280
,
113 .bridge_type
= BRIDGE_TYPE_MV64360
,
124 .model
= BOARD_MODEL_PRPMC280
,
126 .bridge_type
= BRIDGE_TYPE_MV64360
,
137 .model
= BOARD_MODEL_PRPMC280
,
139 .bridge_type
= BRIDGE_TYPE_MV64362
,
144 .core_speed
= 733*MHz
,
150 .model
= BOARD_MODEL_PRPMC280
,
152 .bridge_type
= BRIDGE_TYPE_MV64360
,
163 .model
= BOARD_MODEL_PRPMC280
,
165 .bridge_type
= BRIDGE_TYPE_MV64360
,
176 .model
= BOARD_MODEL_PRPMC2800
,
178 .bridge_type
= BRIDGE_TYPE_MV64360
,
189 .model
= BOARD_MODEL_PRPMC2800
,
191 .bridge_type
= BRIDGE_TYPE_MV64362
,
202 .model
= BOARD_MODEL_PRPMC2800
,
204 .bridge_type
= BRIDGE_TYPE_MV64360
,
209 .core_speed
= 733*MHz
,
215 .model
= BOARD_MODEL_PRPMC2800
,
217 .bridge_type
= BRIDGE_TYPE_MV64360
,
228 .model
= BOARD_MODEL_PRPMC2800
,
230 .bridge_type
= BRIDGE_TYPE_MV64360
,
241 .model
= BOARD_MODEL_PRPMC2800
,
243 .bridge_type
= BRIDGE_TYPE_MV64362
,
248 .core_speed
= 733*MHz
,
254 .model
= BOARD_MODEL_PRPMC2800
,
256 .bridge_type
= BRIDGE_TYPE_MV64360
,
267 .model
= BOARD_MODEL_PRPMC2800
,
269 .bridge_type
= BRIDGE_TYPE_MV64360
,
274 .core_speed
= 733*MHz
,
281 static struct prpmc2800_board_info
*prpmc2800_get_board_info(u8
*vpd
)
283 struct prpmc2800_board_info
*bip
;
286 for (i
=0,bip
=prpmc2800_board_info
; i
<ARRAY_SIZE(prpmc2800_board_info
);
288 if ((vpd
[0] == bip
->subsys0
) && (vpd
[1] == bip
->subsys1
)
289 && ((vpd
[4] & bip
->vpd4_mask
) == bip
->vpd4
))
295 /* Get VPD from i2c eeprom 2, then match it to a board info entry */
296 static struct prpmc2800_board_info
*prpmc2800_get_bip(void)
298 struct prpmc2800_board_info
*bip
;
302 if (mv64x60_i2c_open())
303 fatal("Error: Can't open i2c device\n\r");
305 /* Get VPD from i2c eeprom-2 */
306 memset(vpd
, 0, sizeof(vpd
));
307 rc
= mv64x60_i2c_read(EEPROM2_ADDR
, vpd
, 0x1fde, 2, sizeof(vpd
));
309 fatal("Error: Couldn't read eeprom2\n\r");
312 /* Get board type & related info */
313 bip
= prpmc2800_get_board_info(vpd
);
315 printf("Error: Unsupported board or corrupted VPD:\n\r");
316 printf(" 0x%x 0x%x 0x%x 0x%x 0x%x\n\r",
317 vpd
[0], vpd
[1], vpd
[2], vpd
[3], vpd
[4]);
318 printf("Using device tree defaults...\n\r");
324 static void prpmc2800_bridge_setup(u32 mem_size
)
326 u32 i
, v
[12], enables
, acc_bits
;
327 u32 pci_base_hi
, pci_base_lo
, size
, buf
[2];
328 unsigned long cpu_base
;
331 u8
*bridge_pbase
, is_coherent
;
332 struct mv64x60_cpu2pci_win
*tbl
;
334 bridge_pbase
= mv64x60_get_bridge_pbase();
335 is_coherent
= mv64x60_is_coherent();
338 acc_bits
= MV64x60_PCI_ACC_CNTL_SNOOP_WB
339 | MV64x60_PCI_ACC_CNTL_SWAP_NONE
340 | MV64x60_PCI_ACC_CNTL_MBURST_32_BYTES
341 | MV64x60_PCI_ACC_CNTL_RDSIZE_32_BYTES
;
343 acc_bits
= MV64x60_PCI_ACC_CNTL_SNOOP_NONE
344 | MV64x60_PCI_ACC_CNTL_SWAP_NONE
345 | MV64x60_PCI_ACC_CNTL_MBURST_128_BYTES
346 | MV64x60_PCI_ACC_CNTL_RDSIZE_256_BYTES
;
348 mv64x60_config_ctlr_windows(bridge_base
, bridge_pbase
, is_coherent
);
349 mv64x60_config_pci_windows(bridge_base
, bridge_pbase
, 0, 0, mem_size
,
352 /* Get the cpu -> pci i/o & mem mappings from the device tree */
353 devp
= finddevice("/mv64x60/pci@80000000");
355 fatal("Error: Missing /mv64x60/pci@80000000"
356 " device tree node\n\r");
358 rc
= getprop(devp
, "ranges", v
, sizeof(v
));
360 fatal("Error: Can't find /mv64x60/pci@80000000/ranges"
363 /* Get the cpu -> pci i/o & mem mappings from the device tree */
364 devp
= finddevice("/mv64x60");
366 fatal("Error: Missing /mv64x60 device tree node\n\r");
368 enables
= in_le32((u32
*)(bridge_base
+ MV64x60_CPU_BAR_ENABLE
));
369 enables
|= 0x0007fe00; /* Disable all cpu->pci windows */
370 out_le32((u32
*)(bridge_base
+ MV64x60_CPU_BAR_ENABLE
), enables
);
372 for (i
=0; i
<12; i
+=6) {
373 switch (v
[i
] & 0xff000000) {
374 case 0x01000000: /* PCI I/O Space */
375 tbl
= mv64x60_cpu2pci_io
;
377 case 0x02000000: /* PCI MEM Space */
378 tbl
= mv64x60_cpu2pci_mem
;
384 pci_base_hi
= v
[i
+1];
385 pci_base_lo
= v
[i
+2];
392 if (!dt_xlate_addr(devp
, buf
, sizeof(buf
), &cpu_base
))
393 fatal("Error: Can't translate PCI address 0x%x\n\r",
396 mv64x60_config_cpu2pci_window(bridge_base
, 0, pci_base_hi
,
397 pci_base_lo
, cpu_base
, size
, tbl
);
400 enables
&= ~0x00000600; /* Enable cpu->pci0 i/o, cpu->pci0 mem0 */
401 out_le32((u32
*)(bridge_base
+ MV64x60_CPU_BAR_ENABLE
), enables
);
404 static void prpmc2800_fixups(void)
406 u32 v
[2], l
, mem_size
;
409 char model
[BOARD_MODEL_MAX
];
410 struct prpmc2800_board_info
*bip
;
412 bip
= prpmc2800_get_bip(); /* Get board info based on VPD */
414 mem_size
= (bip
) ? bip
->mem_size
: mv64x60_get_mem_size(bridge_base
);
415 prpmc2800_bridge_setup(mem_size
); /* Do necessary bridge setup */
417 /* If the VPD doesn't match what we know about, just use the
418 * defaults already in the device tree.
423 /* Know the board type so override device tree defaults */
424 /* Set /model appropriately */
425 devp
= finddevice("/");
427 fatal("Error: Missing '/' device tree node\n\r");
428 memset(model
, 0, BOARD_MODEL_MAX
);
429 strncpy(model
, BOARD_MODEL
, BOARD_MODEL_MAX
- 2);
431 if (bip
->model
== BOARD_MODEL_PRPMC280
)
433 model
[l
++] = bip
->variant
;
435 setprop(devp
, "model", model
, l
);
437 /* Set /cpus/PowerPC,7447/clock-frequency */
438 devp
= finddevice("/cpus/PowerPC,7447");
440 fatal("Error: Missing proper /cpus device tree node\n\r");
441 v
[0] = bip
->core_speed
;
442 setprop(devp
, "clock-frequency", &v
[0], sizeof(v
[0]));
444 /* Set /memory/reg size */
445 devp
= finddevice("/memory");
447 fatal("Error: Missing /memory device tree node\n\r");
449 v
[1] = bip
->mem_size
;
450 setprop(devp
, "reg", v
, sizeof(v
));
452 /* Update /mv64x60/model, if this is a mv64362 */
453 if (bip
->bridge_type
== BRIDGE_TYPE_MV64362
) {
454 devp
= finddevice("/mv64x60");
456 fatal("Error: Missing /mv64x60 device tree node\n\r");
457 setprop(devp
, "model", "mv64362", strlen("mv64362") + 1);
460 /* Set User FLASH size */
461 devp
= finddevice("/mv64x60/flash@a0000000");
463 fatal("Error: Missing User FLASH device tree node\n\r");
464 rc
= getprop(devp
, "reg", v
, sizeof(v
));
466 fatal("Error: Can't find User FLASH reg property\n\r");
467 v
[1] = bip
->user_flash
;
468 setprop(devp
, "reg", v
, sizeof(v
));
471 #define MV64x60_MPP_CNTL_0 0xf000
472 #define MV64x60_MPP_CNTL_2 0xf008
473 #define MV64x60_GPP_IO_CNTL 0xf100
474 #define MV64x60_GPP_LEVEL_CNTL 0xf110
475 #define MV64x60_GPP_VALUE_SET 0xf118
477 static void prpmc2800_reset(void)
483 if (bridge_base
!= 0) {
484 temp
= in_le32((u32
*)(bridge_base
+ MV64x60_MPP_CNTL_0
));
486 out_le32((u32
*)(bridge_base
+ MV64x60_MPP_CNTL_0
), temp
);
488 temp
= in_le32((u32
*)(bridge_base
+ MV64x60_GPP_LEVEL_CNTL
));
490 out_le32((u32
*)(bridge_base
+ MV64x60_GPP_LEVEL_CNTL
), temp
);
492 temp
= in_le32((u32
*)(bridge_base
+ MV64x60_GPP_IO_CNTL
));
494 out_le32((u32
*)(bridge_base
+ MV64x60_GPP_IO_CNTL
), temp
);
496 temp
= in_le32((u32
*)(bridge_base
+ MV64x60_MPP_CNTL_2
));
498 out_le32((u32
*)(bridge_base
+ MV64x60_MPP_CNTL_2
), temp
);
500 temp
= in_le32((u32
*)(bridge_base
+ MV64x60_GPP_LEVEL_CNTL
));
502 out_le32((u32
*)(bridge_base
+ MV64x60_GPP_LEVEL_CNTL
), temp
);
504 temp
= in_le32((u32
*)(bridge_base
+ MV64x60_GPP_IO_CNTL
));
506 out_le32((u32
*)(bridge_base
+ MV64x60_GPP_IO_CNTL
), temp
);
508 out_le32((u32
*)(bridge_base
+ MV64x60_GPP_VALUE_SET
),
515 #define HEAP_SIZE (16*MB)
516 static struct gunzip_state gzstate
;
518 void platform_init(unsigned long r3
, unsigned long r4
, unsigned long r5
,
519 unsigned long r6
, unsigned long r7
)
522 char *heap_start
, *dtb
;
523 int dt_size
= _dtb_end
- _dtb_start
;
524 void *vmlinuz_addr
= _vmlinux_start
;
525 unsigned long vmlinuz_size
= _vmlinux_end
- _vmlinux_start
;
528 if (dt_size
<= 0) /* No fdt */
532 * Start heap after end of the kernel (after decompressed to
533 * address 0) or the end of the zImage, whichever is higher.
534 * That's so things allocated by simple_alloc won't overwrite
535 * any part of the zImage and the kernel won't overwrite the dtb
536 * when decompressed & relocated.
538 gunzip_start(&gzstate
, vmlinuz_addr
, vmlinuz_size
);
539 gunzip_exactly(&gzstate
, elfheader
, sizeof(elfheader
));
541 if (!parse_elf32(elfheader
, &ei
))
544 heap_start
= (char *)(ei
.memsize
+ ei
.elfoffset
); /* end of kernel*/
545 heap_start
= max(heap_start
, (char *)_end
); /* end of zImage */
547 if ((unsigned)simple_alloc_init(heap_start
, HEAP_SIZE
, 2*KB
, 16)
551 /* Relocate dtb to safe area past end of zImage & kernel */
552 dtb
= malloc(dt_size
);
555 memmove(dtb
, _dtb_start
, dt_size
);
556 if (ft_init(dtb
, dt_size
, 16))
559 bridge_base
= mv64x60_get_bridge_base();
561 platform_ops
.fixups
= prpmc2800_fixups
;
562 platform_ops
.exit
= prpmc2800_reset
;
564 if (serial_console_init() < 0)
568 /* _zimage_start called very early--need to turn off external interrupts */
569 asm (" .globl _zimage_start\n\
572 rlwinm 10,10,0,~(1<<15) /* Clear MSR_EE */\n\
576 b _zimage_start_lib\n\