diff options
Diffstat (limited to 'board/esd/pci405')
-rw-r--r-- | board/esd/pci405/Makefile | 6 | ||||
-rw-r--r-- | board/esd/pci405/cmd_pci405.c | 873 | ||||
-rw-r--r-- | board/esd/pci405/pci405.c | 153 |
3 files changed, 1022 insertions, 10 deletions
diff --git a/board/esd/pci405/Makefile b/board/esd/pci405/Makefile index fd72b18..6db564f 100644 --- a/board/esd/pci405/Makefile +++ b/board/esd/pci405/Makefile @@ -25,10 +25,12 @@ include $(TOPDIR)/config.mk LIB = lib$(BOARD).a -OBJS = $(BOARD).o flash.o cmd_pci405.o +OBJS = $(BOARD).o flash.o ../common/misc.o cmd_pci405.o +SOBJS = writeibm.o $(LIB): $(OBJS) $(SOBJS) - $(AR) crv $@ $(OBJS) +# $(AR) crv $@ $(OBJS) + $(AR) crv $@ $(OBJS) $(SOBJS) clean: rm -f $(SOBJS) $(OBJS) diff --git a/board/esd/pci405/cmd_pci405.c b/board/esd/pci405/cmd_pci405.c index dfc5dd0..e1ca583 100644 --- a/board/esd/pci405/cmd_pci405.c +++ b/board/esd/pci405/cmd_pci405.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2002 + * (C) Copyright 2002-2004 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com * * See file CREDITS for list of people who contributed to this @@ -28,6 +28,7 @@ #include <asm/io.h> #include <pci.h> #include <405gp_pci.h> +#include <asm/processor.h> #include "pci405.h" @@ -35,6 +36,8 @@ #if (CONFIG_COMMANDS & CFG_CMD_BSP) extern int do_bootm (cmd_tbl_t *, int, int, char *[]); +extern int do_bootvx (cmd_tbl_t *, int, int, char *[]); +unsigned long get_dcr(unsigned short); /* @@ -94,15 +97,43 @@ int do_loadpci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } else { sprintf(addr, "%08x", *ptr); +#if 0 /* * Boot image */ - printf("\nBooting image at addr 0x%s ...\n", addr); + if (*ptr & 0x00000001) { + /* + * Boot VxWorks image via bootvx + */ + addr[strlen(addr)-1] = '0'; + printf("\nBooting VxWorks-Image at addr 0x%s ...\n", addr); + setenv("loadaddr", addr); + + local_args[0] = argv[0]; + local_args[1] = NULL; + status = do_bootvx (cmdtp, 0, 1, local_args); + } else { + /* + * Boot image via bootm (normally Linux) + */ + printf("\nBooting Image at addr 0x%s ...\n", addr); + setenv("loadaddr", addr); + + local_args[0] = argv[0]; + local_args[1] = NULL; + status = do_bootm (cmdtp, 0, 1, local_args); + } +#else + /* + * Boot image via bootm + */ + printf("\nBooting Image at addr 0x%s ...\n", addr); setenv("loadaddr", addr); local_args[0] = argv[0]; local_args[1] = NULL; status = do_bootm (cmdtp, 0, 1, local_args); +#endif } return 0; @@ -114,3 +145,841 @@ U_BOOT_CMD( ); #endif + +#if 1 /* test-only */ +int do_getpci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + unsigned int val; + int i; + + printf("\nPCI Configuration Regs for PPC405GP:"); + for (i=0; i<0x64; i+=4) { + pci_read_config_dword(PCIDEVID_405GP, i, &val); + if (!(i % 0x10)) { + printf("\n%02x: ", i); + } + printf("%08x ", val); + } + printf("\n"); + + return 0; +} +U_BOOT_CMD( + getpci, 1, 1, do_getpci, + "getpci - Print own pci configuration registers\n", + NULL +); + +int do_setpci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + unsigned int addr; + unsigned int val; + + addr = simple_strtol (argv[1], NULL, 16); + val = simple_strtol (argv[2], NULL, 16); + + printf("\nWriting %08x to PCI reg %08x.\n", val, addr); + pci_write_config_dword(PCIDEVID_405GP, addr, val); + + return 0; +} +U_BOOT_CMD( + setpci, 3, 1, do_setpci, + "setpci - Set one pci configuration lword\n", + "<addr> <val>\n" + " - Write pci configuration lword <val> to <addr>.\n" +); + +int do_dumpdcr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + int i; + + printf("\nDevice Configuration Registers (DCR's) for PPC405GP:"); + for (i=0; i<=0x1e0; i++) { + if (!(i % 0x8)) { + printf("\n%04x ", i); + } + printf("%08lx ", get_dcr(i)); + } + printf("\n"); + + return 0; +} +U_BOOT_CMD( + dumpdcr, 1, 1, do_dumpdcr, + "dumpdcr - Dump all DCR registers\n", + NULL +); + + +int do_dumpspr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + printf("\nSpecial Purpose Registers (SPR's) for PPC405GP:"); + printf("\n%04x %08x ", 947, mfspr(947)); + printf("\n%04x %08x ", 9, mfspr(9)); + printf("\n%04x %08x ", 1014, mfspr(1014)); + printf("\n%04x %08x ", 1015, mfspr(1015)); + printf("\n%04x %08x ", 1010, mfspr(1010)); + printf("\n%04x %08x ", 957, mfspr(957)); + printf("\n%04x %08x ", 1008, mfspr(1008)); + printf("\n%04x %08x ", 1018, mfspr(1018)); + printf("\n%04x %08x ", 954, mfspr(954)); + printf("\n%04x %08x ", 950, mfspr(950)); + printf("\n%04x %08x ", 951, mfspr(951)); + printf("\n%04x %08x ", 981, mfspr(981)); + printf("\n%04x %08x ", 980, mfspr(980)); + printf("\n%04x %08x ", 982, mfspr(982)); + printf("\n%04x %08x ", 1012, mfspr(1012)); + printf("\n%04x %08x ", 1013, mfspr(1013)); + printf("\n%04x %08x ", 948, mfspr(948)); + printf("\n%04x %08x ", 949, mfspr(949)); + printf("\n%04x %08x ", 1019, mfspr(1019)); + printf("\n%04x %08x ", 979, mfspr(979)); + printf("\n%04x %08x ", 8, mfspr(8)); + printf("\n%04x %08x ", 945, mfspr(945)); + printf("\n%04x %08x ", 987, mfspr(987)); + printf("\n%04x %08x ", 287, mfspr(287)); + printf("\n%04x %08x ", 953, mfspr(953)); + printf("\n%04x %08x ", 955, mfspr(955)); + printf("\n%04x %08x ", 272, mfspr(272)); + printf("\n%04x %08x ", 273, mfspr(273)); + printf("\n%04x %08x ", 274, mfspr(274)); + printf("\n%04x %08x ", 275, mfspr(275)); + printf("\n%04x %08x ", 260, mfspr(260)); + printf("\n%04x %08x ", 276, mfspr(276)); + printf("\n%04x %08x ", 261, mfspr(261)); + printf("\n%04x %08x ", 277, mfspr(277)); + printf("\n%04x %08x ", 262, mfspr(262)); + printf("\n%04x %08x ", 278, mfspr(278)); + printf("\n%04x %08x ", 263, mfspr(263)); + printf("\n%04x %08x ", 279, mfspr(279)); + printf("\n%04x %08x ", 26, mfspr(26)); + printf("\n%04x %08x ", 27, mfspr(27)); + printf("\n%04x %08x ", 990, mfspr(990)); + printf("\n%04x %08x ", 991, mfspr(991)); + printf("\n%04x %08x ", 956, mfspr(956)); + printf("\n%04x %08x ", 284, mfspr(284)); + printf("\n%04x %08x ", 285, mfspr(285)); + printf("\n%04x %08x ", 986, mfspr(986)); + printf("\n%04x %08x ", 984, mfspr(984)); + printf("\n%04x %08x ", 256, mfspr(256)); + printf("\n%04x %08x ", 1, mfspr(1)); + printf("\n%04x %08x ", 944, mfspr(944)); + printf("\n"); + + return 0; +} +U_BOOT_CMD( + dumpspr, 1, 1, do_dumpspr, + "dumpspr - Dump all SPR registers\n", + NULL +); + + +#define PCI0_BRDGOPT1 0x4a +#define plb0_acr 0x87 + +int do_getplb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + unsigned short val; + + printf("PLB0_ACR=%08lx\n", get_dcr(0x87)); + pci_read_config_word(PCIDEVID_405GP, PCI0_BRDGOPT1, &val); + printf("PCI0_BRDGOPT1=%04x\n", val); + printf("CCR0=%08x\n", mfspr(ccr0)); + + return 0; +} +U_BOOT_CMD( + getplb, 1, 1, do_getplb, + "getplb - Dump all plb arbiter registers\n", + NULL +); + +int do_setplb(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + unsigned int my_acr; + unsigned int my_brdgopt1; + unsigned int my_ccr0; + + my_acr = simple_strtol (argv[1], NULL, 16); + my_brdgopt1 = simple_strtol (argv[2], NULL, 16); + my_ccr0 = simple_strtol (argv[3], NULL, 16); + + mtdcr(plb0_acr, my_acr); + pci_write_config_word(PCIDEVID_405GP, PCI0_BRDGOPT1, my_brdgopt1); + mtspr(ccr0, my_ccr0); + + return 0; +} +U_BOOT_CMD( + setplb, 4, 1, do_setplb, + "setplb - Set all plb arbiter registers\n", + "PLB0_ACR PCI0_BRDGOPT1 CCR0\n" + " - Set all plb arbiter registers\n" +); + + +/*********************************************************************** + * + * The following code is only for test purposes!!!! + * Please ignore this ugly stuff!!!!!!!!!!!!!!!!!!! + * + ***********************************************************************/ + +#define PCI_ADDR 0xc0000000 + +int do_writepci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + unsigned int addr; + unsigned int size; + unsigned int countmax; + int i; + int max; + volatile unsigned long *ptr; + volatile unsigned long val; + int loopcount = 0; + int test_pci_read = 0; + int test_pci_cfg_write = 0; + int test_sync = 0; + int test_pci_pre_read = 0; + + addr = simple_strtol (argv[1], NULL, 16); + size = simple_strtol (argv[2], NULL, 16); + countmax = simple_strtol (argv[3], NULL, 16); + if (countmax == 0) + countmax = 1000; + + do_getplb(NULL, 0, 0, NULL); + +#if 0 + out32r(PMM0LA, 0); + out32r(PMM0PCILA, 0); + out32r(PMM0PCIHA, 0); + out32r(PMM0MA, 0); + out32r(PMM1LA, PCI_ADDR); + out32r(PMM1PCILA, addr & 0xff000000); + out32r(PMM1PCIHA, 0x00000000); + out32r(PMM1MA, 0xff000001); +#endif + + printf("PMM1LA =%08lx\n", in32r(PMM1LA)); + printf("PMM1MA =%08lx\n", in32r(PMM1MA)); + printf("PMM1PCILA =%08lx\n", in32r(PMM1PCILA)); + printf("PMM1PCIHA =%08lx\n", in32r(PMM1PCIHA)); + + addr = PCI_ADDR | (addr & 0x00ffffff); + printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); + + max = size >> 2; + + pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ + + val = *(ulong *)0x00000000; + if (val & 0x00000008) { + test_pci_pre_read = 1; + printf("Running test with pre pci-memory-read access!\n"); + } + if (val & 0x00000004) { + test_sync = 1; + printf("Running test with sync instruction!\n"); + } + if (val & 0x00000001) { + test_pci_read = 1; + printf("Running test with pci-memory-read access!\n"); + } + if (val & 0x00000002) { + test_pci_cfg_write = 1; + printf("Running test with pci-config-write access!\n"); + } + + while (1) { + + if (test_pci_pre_read) { + /* + * Read one value back + */ + ptr = (volatile unsigned long *)addr; + val = *ptr; + } + + /* + * Write some values to host via pci busmastering + */ + ptr = (volatile unsigned long *)addr; + for (i=0; i<max; i++) { + *ptr++ = i; + } + + if (test_sync) { + /* + * Sync previous writes + */ + ppcSync(); + } + + if (test_pci_read) { + /* + * Read one value back + */ + ptr = (volatile unsigned long *)addr; + val = *ptr; + } + + if (test_pci_cfg_write) { + /* + * Generate IRQ to host via config regs + */ + pci_write_config_byte(PCIDEVID_405GP, 0x44, 0x00); + } + + if (loopcount++ > countmax) { + /* Abort if ctrl-c was pressed */ + if (ctrlc()) { + puts("\nAbort\n"); + return 0; + } + + putc('.'); + + loopcount = 0; + } + } + + return 0; +} +U_BOOT_CMD( + writepci, 4, 1, do_writepci, + "writepci - Write some data to pcibus\n", + "<addr> <size>\n" + " - Write some data to pcibus.\n" +); + +#define PCI_CFGADDR 0xeec00000 +#define PCI_CFGDATA 0xeec00004 + +int ibmPciConfigWrite +( + int offset, /* offset into the configuration space */ + int width, /* data width */ + unsigned int data /* data to be written */ + ) +{ + /* + * Write config register address to the PCI config address register + * bit 31 must be 1 and bits 1:0 must be 0 (note LE bit notation) + */ + out32r(PCI_CFGADDR, 0x80000000 | (offset & 0xFFFFFFFC)); + +#if 0 /* test-only */ + ppcSync(); +#endif + + /* + * Write value to be written to the PCI config data register + */ + switch ( width ) { + case 1: out32r(PCI_CFGDATA | (offset & 0x3), (unsigned char)(data & 0xFF)); + break; + case 2: out32r(PCI_CFGDATA | (offset & 0x3), (unsigned short)(data & 0xFFFF)); + break; + case 4: out32r(PCI_CFGDATA | (offset & 0x3), data); + break; + } + + return (0); +} + +int do_writepci2(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + unsigned int addr; + unsigned int size; + unsigned int countmax; + int max; + volatile unsigned long *ptr; + volatile unsigned long val; + int loopcount = 0; + + addr = simple_strtol (argv[1], NULL, 16); + size = simple_strtol (argv[2], NULL, 16); + countmax = simple_strtol (argv[3], NULL, 16); + if (countmax == 0) + countmax = 1000; + + do_getplb(NULL, 0, 0, NULL); + +#if 0 + out32r(PMM0LA, 0); + out32r(PMM0PCILA, 0); + out32r(PMM0PCIHA, 0); + out32r(PMM0MA, 0); + out32r(PMM1LA, PCI_ADDR); + out32r(PMM1PCILA, addr & 0xff000000); + out32r(PMM1PCIHA, 0x00000000); + out32r(PMM1MA, 0xff000001); +#endif + + printf("PMM1LA =%08lx\n", in32r(PMM1LA)); + printf("PMM1MA =%08lx\n", in32r(PMM1MA)); + printf("PMM1PCILA =%08lx\n", in32r(PMM1PCILA)); + printf("PMM1PCIHA =%08lx\n", in32r(PMM1PCIHA)); + + addr = PCI_ADDR | (addr & 0x00ffffff); + printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); + + max = size >> 2; + + pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ + + while (1) { + + /* + * Write one values to host via pci busmastering + */ + ptr = (volatile unsigned long *)addr; + *ptr = 0x01234567; + + /* + * Read one value back + */ + ptr = (volatile unsigned long *)addr; + val = *ptr; + + /* + * One pci config write + */ +/* pci_write_config_byte(PCIDEVID_405GP, 0x44, 0x00); */ +/* ibmPciConfigWrite(0x44, 1, 0x00); */ + ibmPciConfigWrite(0x2e, 2, 0x1234); /* subsystem id */ + + if (loopcount++ > countmax) { + /* Abort if ctrl-c was pressed */ + if (ctrlc()) { + puts("\nAbort\n"); + return 0; + } + + putc('.'); + + loopcount = 0; + } + } + + return 0; +} +U_BOOT_CMD( + writepci2, 4, 1, do_writepci2, + "writepci2- Write some data to pcibus\n", + "<addr> <size>\n" + " - Write some data to pcibus.\n" +); + +int do_writepci22(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + unsigned int addr; + unsigned int size; + unsigned int countmax = 0; + volatile unsigned long *ptr; + volatile unsigned long val; + + addr = simple_strtol (argv[1], NULL, 16); + size = simple_strtol (argv[2], NULL, 16); + + addr = PCI_ADDR | (addr & 0x00ffffff); + printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); + pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ + + while (1) { + + /* + * Write one values to host via pci busmastering + */ + ptr = (volatile unsigned long *)addr; + *ptr = 0x01234567; + + /* + * Read one value back + */ + ptr = (volatile unsigned long *)addr; + val = *ptr; + + /* + * One pci config write + */ + ibmPciConfigWrite(0x2e, 2, 0x1234); /* subsystem id */ + } + + return 0; +} +U_BOOT_CMD( + writepci22, 4, 1, do_writepci22, + "writepci22- Write some data to pcibus\n", + "<addr> <size>\n" + " - Write some data to pcibus.\n" +); + +int ibmPciConfigWrite3 +( + int offset, /* offset into the configuration space */ + int width, /* data width */ + unsigned int data /* data to be written */ + ) +{ + /* + * Write config register address to the PCI config address register + * bit 31 must be 1 and bits 1:0 must be 0 (note LE bit notation) + */ + out32r(PCI_CFGADDR, 0x80000000 | (offset & 0xFFFFFFFC)); + +#if 1 /* test-only */ + ppcSync(); +#endif + + /* + * Write value to be written to the PCI config data register + */ + switch ( width ) { + case 1: out32r(PCI_CFGDATA | (offset & 0x3), (unsigned char)(data & 0xFF)); + break; + case 2: out32r(PCI_CFGDATA | (offset & 0x3), (unsigned short)(data & 0xFFFF)); + break; + case 4: out32r(PCI_CFGDATA | (offset & 0x3), data); + break; + } + + return (0); +} + +int do_writepci3(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + unsigned int addr; + unsigned int size; + unsigned int countmax; + int max; + volatile unsigned long *ptr; + volatile unsigned long val; + int loopcount = 0; + + addr = simple_strtol (argv[1], NULL, 16); + size = simple_strtol (argv[2], NULL, 16); + countmax = simple_strtol (argv[3], NULL, 16); + if (countmax == 0) + countmax = 1000; + + do_getplb(NULL, 0, 0, NULL); + +#if 0 + out32r(PMM0LA, 0); + out32r(PMM0PCILA, 0); + out32r(PMM0PCIHA, 0); + out32r(PMM0MA, 0); + out32r(PMM1LA, PCI_ADDR); + out32r(PMM1PCILA, addr & 0xff000000); + out32r(PMM1PCIHA, 0x00000000); + out32r(PMM1MA, 0xff000001); +#endif + + printf("PMM1LA =%08lx\n", in32r(PMM1LA)); + printf("PMM1MA =%08lx\n", in32r(PMM1MA)); + printf("PMM1PCILA =%08lx\n", in32r(PMM1PCILA)); + printf("PMM1PCIHA =%08lx\n", in32r(PMM1PCIHA)); + + addr = PCI_ADDR | (addr & 0x00ffffff); + printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); + + max = size >> 2; + + pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ + + while (1) { + + /* + * Write one values to host via pci busmastering + */ + ptr = (volatile unsigned long *)addr; + *ptr = 0x01234567; + + /* + * Read one value back + */ + ptr = (volatile unsigned long *)addr; + val = *ptr; + + /* + * One pci config write + */ +/* pci_write_config_byte(PCIDEVID_405GP, 0x44, 0x00); */ +/* ibmPciConfigWrite(0x44, 1, 0x00); */ + ibmPciConfigWrite3(0x2e, 2, 0x1234); /* subsystem id */ + + if (loopcount++ > countmax) { + /* Abort if ctrl-c was pressed */ + if (ctrlc()) { + puts("\nAbort\n"); + return 0; + } + + putc('.'); + + loopcount = 0; + } + } + + return 0; +} +U_BOOT_CMD( + writepci3, 4, 1, do_writepci3, + "writepci3- Write some data to pcibus\n", + "<addr> <size>\n" + " - Write some data to pcibus.\n" +); + + +#define SECTOR_SIZE 32 /* 32 byte cache line */ +#define SECTOR_MASK 0x1F + +void my_flush_dcache(ulong lcl_addr, ulong count) +{ + unsigned int lcl_target; + + /* promote to nearest cache sector */ + lcl_target = (lcl_addr + count + SECTOR_SIZE - 1) & ~SECTOR_MASK; + lcl_addr &= ~SECTOR_MASK; + while (lcl_addr != lcl_target) + { + /* ppcDcbf((void *)lcl_addr);*/ + __asm__("dcbf 0,%0": :"r" (lcl_addr)); + lcl_addr += SECTOR_SIZE; + } + __asm__("sync"); /* Always flush prefetch queue in any case */ +} + +int do_writepci_cache(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + unsigned int addr; + unsigned int size; + unsigned int countmax; + int i; + volatile unsigned long *ptr; + volatile unsigned long val; + int loopcount = 0; + + addr = simple_strtol (argv[1], NULL, 16); + size = simple_strtol (argv[2], NULL, 16); + countmax = simple_strtol (argv[3], NULL, 16); + if (countmax == 0) + countmax = 1000; + + do_getplb(NULL, 0, 0, NULL); + +#if 0 + out32r(PMM0LA, 0); + out32r(PMM0PCILA, 0); + out32r(PMM0PCIHA, 0); + out32r(PMM0MA, 0); + out32r(PMM1LA, PCI_ADDR); + out32r(PMM1PCILA, addr & 0xff000000); + out32r(PMM1PCIHA, 0x00000000); + out32r(PMM1MA, 0xff000001); +#endif + + printf("PMM1LA =%08lx\n", in32r(PMM1LA)); + printf("PMM1MA =%08lx\n", in32r(PMM1MA)); + printf("PMM1PCILA =%08lx\n", in32r(PMM1PCILA)); + printf("PMM1PCIHA =%08lx\n", in32r(PMM1PCIHA)); + + addr = PCI_ADDR | (addr & 0x00ffffff); + printf("\nWriting at addr %08x, size %08x (countmax=%x)\n", addr, size, countmax); + + pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ + + i = 0; + + /* + * Set pci region as cachable + */ + ppcSync(); + __asm__ volatile (" addis 4,0,0x0000 "); + __asm__ volatile (" addi 4,4,0x0080 "); + __asm__ volatile (" mtdccr 4 "); + ppcSync(); + + while (1) { + + /* + * Write one values to host via pci busmastering + */ + ptr = (volatile unsigned long *)addr; + printf("A\n"); /* test-only */ + *ptr++ = i++; + *ptr++ = i++; + *ptr++ = i++; + *ptr++ = i++; + *ptr++ = i++; + *ptr++ = i++; + *ptr++ = i++; + *ptr++ = i++; + printf("B\n"); /* test-only */ + my_flush_dcache(addr, 32); + printf("C\n"); /* test-only */ + + /* + * Read one value back + */ + ptr = (volatile unsigned long *)addr; + val = *ptr; + printf("D\n"); /* test-only */ + + /* + * One pci config write + */ +/* pci_write_config_byte(PCIDEVID_405GP, 0x44, 0x00); */ +/* ibmPciConfigWrite(0x44, 1, 0x00); */ + ibmPciConfigWrite3(0x2e, 2, 0x1234); /* subsystem id */ + printf("E\n"); /* test-only */ + + if (loopcount++ > countmax) { + /* Abort if ctrl-c was pressed */ + if (ctrlc()) { + puts("\nAbort\n"); + return 0; + } + + putc('.'); + + loopcount = 0; + } + } + + return 0; +} +U_BOOT_CMD( + writepci_cache, 4, 1, do_writepci_cache, + "writepci_cache - Write some data to pcibus\n", + "<addr> <size>\n" + " - Write some data to pcibus.\n" +); + +int do_savepci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + unsigned int *ptr; + int i; + + /* + * Save own pci configuration in PRAM + */ + memset((char *)PCI_REGS_ADDR, 0, PCI_REGS_LEN); + ptr = (unsigned int *)PCI_REGS_ADDR + 1; + for (i=0; i<0x40; i+=4) { + pci_read_config_dword(PCIDEVID_405GP, i, ptr++); + } + ptr = (unsigned int *)PCI_REGS_ADDR; + *ptr = crc32(0, (char *)PCI_REGS_ADDR+4, PCI_REGS_LEN-4); + + printf("\nStoring PCI Configuration Regs...\n"); + + return 0; +} +U_BOOT_CMD( + savepci, 4, 1, do_savepci, + "savepci - Save all pci regs\n", + "<addr> <size>\n" + " - Write some data to pcibus.\n" +); + +int do_restorepci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + unsigned int *ptr; + int i; + + /* + * Rewrite pci config regs (only after soft-reset with magic set) + */ + ptr = (unsigned int *)PCI_REGS_ADDR; + if (crc32(0, (char *)PCI_REGS_ADDR+4, PCI_REGS_LEN-4) == *ptr) { + puts("Restoring PCI Configurations Regs!\n"); + ptr = (unsigned int *)PCI_REGS_ADDR + 1; + for (i=0; i<0x40; i+=4) { + pci_write_config_dword(PCIDEVID_405GP, i, *ptr++); + } + } + mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ + + return 0; +} +U_BOOT_CMD( + restorepci, 4, 1, do_restorepci, + "restorepci - Restore all pci regs\n", + "<addr> <size>\n" + " - Write some data to pcibus.\n" +); + + +extern void write_without_sync(void); +extern void write_with_sync(void); +extern void write_with_less_sync(void); +extern void write_with_more_sync(void); + +/* + * code from IBM-PPCSUPP + */ +int do_writeibm1(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ + + write_without_sync(); + + return 0; +} +U_BOOT_CMD( + writeibm1, 4, 1, do_writeibm1, + "writeibm1- Write some data to pcibus (without sync)\n", + "<addr> <size>\n" + " - Write some data to pcibus.\n" +); + +int do_writeibm2(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ + + write_with_sync(); + + return 0; +} +U_BOOT_CMD( + writeibm2, 4, 1, do_writeibm2, + "writeibm2- Write some data to pcibus (with sync)\n", + "<addr> <size>\n" + " - Write some data to pcibus.\n" +); + +int do_writeibm22(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ + + write_with_less_sync(); + + return 0; +} +U_BOOT_CMD( + writeibm22, 4, 1, do_writeibm22, + "writeibm22- Write some data to pcibus (with less sync)\n", + "<addr> <size>\n" + " - Write some data to pcibus.\n" +); + +int do_writeibm3(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ + pci_write_config_word(PCIDEVID_405GP, 0x04, 0x0106); /* write command reg */ + + write_with_more_sync(); + + return 0; +} +U_BOOT_CMD( + writeibm3, 4, 1, do_writeibm3, + "writeibm3- Write some data to pcibus (with more sync)\n", + "<addr> <size>\n" + " - Write some data to pcibus.\n" +); +#endif diff --git a/board/esd/pci405/pci405.c b/board/esd/pci405/pci405.c index 05f59a8..ae866b0 100644 --- a/board/esd/pci405/pci405.c +++ b/board/esd/pci405/pci405.c @@ -1,5 +1,5 @@ /* - * (C) Copyright 2001 + * (C) Copyright 2001-2004 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com * * See file CREDITS for list of people who contributed to this @@ -31,12 +31,20 @@ #include "pci405.h" -/* ------------------------------------------------------------------------- */ -extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);/*cmd_boot.c*/ +/* Prototypes */ +int gunzip(void *, int, unsigned char *, unsigned long *); +int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);/*cmd_boot.c*/ +unsigned long fpga_done_state(void); +unsigned long fpga_init_state(void); + #if 0 #define FPGA_DEBUG #endif +/* predefine these here */ +#define FPGA_DONE_STATE (fpga_done_state()) +#define FPGA_INIT_STATE (fpga_init_state()) + /* fpga configuration data - generated by bin2cc */ const unsigned char fpgadata[] = { @@ -48,9 +56,81 @@ const unsigned char fpgadata[] = */ #include "../common/fpga.c" +#define FPGA_DONE_STATE_V11 (in32(GPIO0_IR) & CFG_FPGA_DONE) +#define FPGA_DONE_STATE_V12 (in32(GPIO0_IR) & CFG_FPGA_DONE_V12) -/* Prototypes */ -int gunzip(void *, int, unsigned char *, unsigned long *); +#define FPGA_INIT_STATE_V11 (in32(GPIO0_IR) & CFG_FPGA_INIT) +#define FPGA_INIT_STATE_V12 (in32(GPIO0_IR) & CFG_FPGA_INIT_V12) + + +int board_revision(void) +{ + unsigned long cntrl0Reg; + unsigned long value; + + /* + * Get version of PCI405 board from GPIO's + */ + + /* + * Setup GPIO pins (CS2/GPIO11 and CS3/GPIO12 as GPIO) + */ + cntrl0Reg = mfdcr(cntrl0); + mtdcr(cntrl0, cntrl0Reg | 0x03000000); + out32(GPIO0_ODR, in32(GPIO0_ODR) & ~0x00180000); + out32(GPIO0_TCR, in32(GPIO0_TCR) & ~0x00180000); + udelay(1000); /* wait some time before reading input */ + value = in32(GPIO0_IR) & 0x00180000; /* get config bits */ + + /* + * Restore GPIO settings + */ + mtdcr(cntrl0, cntrl0Reg); + + switch (value) { + case 0x00180000: + /* CS2==1 && CS3==1 -> version 1.0 and 1.1 */ + return 1; + case 0x00080000: + /* CS2==0 && CS3==1 -> version 1.2 */ + return 2; +#if 0 /* not yet manufactured ! */ + case 0x00100000: + /* CS2==1 && CS3==0 -> version 1.3 */ + return 3; + case 0x00000000: + /* CS2==0 && CS3==0 -> version 1.4 */ + return 4; +#endif + default: + /* should not be reached! */ + return 0; + } +} + + +unsigned long fpga_done_state(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + if (gd->board_type < 2) { + return FPGA_DONE_STATE_V11; + } else { + return FPGA_DONE_STATE_V12; + } +} + + +unsigned long fpga_init_state(void) +{ + DECLARE_GLOBAL_DATA_PTR; + + if (gd->board_type < 2) { + return FPGA_INIT_STATE_V11; + } else { + return FPGA_INIT_STATE_V12; + } +} int board_early_init_f (void) @@ -58,6 +138,14 @@ int board_early_init_f (void) unsigned long cntrl0Reg; /* + * First pull fpga-prg pin low, to disable fpga logic (on version 1.2 board) + */ + out32(GPIO0_ODR, 0x00000000); /* no open drain pins */ + out32(GPIO0_TCR, CFG_FPGA_PRG); /* setup for output */ + out32(GPIO0_OR, CFG_FPGA_PRG); /* set output pins to high */ + out32(GPIO0_OR, 0); /* pull prg low */ + + /* * IRQ 0-15 405GP internally generated; active high; level sensitive * IRQ 16 405GP internally generated; active low; level sensitive * IRQ 17-24 RESERVED @@ -84,6 +172,11 @@ int board_early_init_f (void) mtdcr(cntrl0, cntrl0Reg | 0x00008000); /* + * Setup GPIO pins (CS6+CS7 as GPIO) + */ + mtdcr(cntrl0, cntrl0Reg | 0x00300000); + + /* * EBC Configuration Register: set ready timeout to 512 ebc-clks -> ca. 25 us */ mtebc (epcr, 0xa8400000); /* ebc always driven */ @@ -194,6 +287,28 @@ int misc_init_r (void) *magic = 0; /* clear pci reconfig magic again */ } +#if 1 /* test-only */ + /* + * Decrease PLB latency timeout and reduce priority of the PCI bridge master + */ +#define PCI0_BRDGOPT1 0x4a + pci_write_config_word(PCIDEVID_405GP, PCI0_BRDGOPT1, 0x3f20); +// pci_write_config_word(PCIDEVID_405GP, PCI0_BRDGOPT1, 0x3f60); + +#define plb0_acr 0x87 + /* + * Enable fairness and high bus utilization + */ + mtdcr(plb0_acr, 0x98000000); + +#if 0 /* test-only */ + printf("CCR0=%08x\n", mfspr(ccr0)); /* test-only */ +// mtspr(ccr0, (mfspr(ccr0) & 0xff8fffff) | 0x00100000); + mtspr(ccr0, (mfspr(ccr0) & 0xff8fffff) | 0x00000000); +#endif +// printf("CCR0=%08x\n", mfspr(ccr0)); /* test-only */ +#endif + free(dst); return (0); } @@ -205,6 +320,8 @@ int misc_init_r (void) int checkboard (void) { + DECLARE_GLOBAL_DATA_PTR; + unsigned char str[64]; int i = getenv_r ("serial#", str, sizeof(str)); @@ -215,7 +332,31 @@ int checkboard (void) } else { puts (str); } - putc ('\n'); + + gd->board_type = board_revision(); + printf(" (Rev 1.%ld", gd->board_type); + + if (gd->board_type >= 2) { + unsigned long cntrl0Reg; + unsigned long value; + + /* + * Setup GPIO pins (Trace/GPIO1 to GPIO) + */ + cntrl0Reg = mfdcr(cntrl0); + mtdcr(cntrl0, cntrl0Reg & ~0x08000000); + out32(GPIO0_ODR, in32(GPIO0_ODR) & ~0x40000000); + out32(GPIO0_TCR, in32(GPIO0_TCR) & ~0x40000000); + udelay(1000); /* wait some time before reading input */ + value = in32(GPIO0_IR) & 0x40000000; /* get config bits */ + if (value) { + puts(", 33 MHz PCI"); + } else { + puts(", 66 Mhz PCI"); + } + } + + puts(")\n"); return 0; } |