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\