diff options
Diffstat (limited to 'board/esd')
-rw-r--r-- | board/esd/common/fpga.c | 262 | ||||
-rw-r--r-- | board/esd/common/pci.c | 202 | ||||
-rw-r--r-- | board/esd/cpci405/cpci405.c | 451 | ||||
-rw-r--r-- | board/esd/cpci440/cpci440.c | 140 | ||||
-rw-r--r-- | board/esd/cpci440/init.S | 96 | ||||
-rw-r--r-- | board/esd/pci405/pci405.c | 254 |
6 files changed, 1405 insertions, 0 deletions
diff --git a/board/esd/common/fpga.c b/board/esd/common/fpga.c new file mode 100644 index 0000000..666b490 --- /dev/null +++ b/board/esd/common/fpga.c @@ -0,0 +1,262 @@ +/* + * (C) Copyright 2001 + * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/processor.h> +#include <command.h> + +/* ------------------------------------------------------------------------- */ + +#ifdef FPGA_DEBUG +#define DBG(x...) printf(x) +#else +#define DBG(x...) +#endif /* DEBUG */ + +#define MAX_ONES 226 + +#define IBM405GP_GPIO0_OR 0xef600700 /* GPIO Output */ +#define IBM405GP_GPIO0_TCR 0xef600704 /* GPIO Three-State Control */ +#define IBM405GP_GPIO0_ODR 0xef600718 /* GPIO Open Drain */ +#define IBM405GP_GPIO0_IR 0xef60071c /* GPIO Input */ + +#ifdef CFG_FPGA_PRG +# define FPGA_PRG CFG_FPGA_PRG /* FPGA program pin (ppc output)*/ +# define FPGA_CLK CFG_FPGA_CLK /* FPGA clk pin (ppc output) */ +# define FPGA_DATA CFG_FPGA_DATA /* FPGA data pin (ppc output) */ +# define FPGA_DONE CFG_FPGA_DONE /* FPGA done pin (ppc input) */ +# define FPGA_INIT CFG_FPGA_INIT /* FPGA init pin (ppc input) */ +#else +# define FPGA_PRG 0x04000000 /* FPGA program pin (ppc output) */ +# define FPGA_CLK 0x02000000 /* FPGA clk pin (ppc output) */ +# define FPGA_DATA 0x01000000 /* FPGA data pin (ppc output) */ +# define FPGA_DONE 0x00800000 /* FPGA done pin (ppc input) */ +# define FPGA_INIT 0x00400000 /* FPGA init pin (ppc input) */ +#endif + +#define ERROR_FPGA_PRG_INIT_LOW -1 /* Timeout after PRG* asserted */ +#define ERROR_FPGA_PRG_INIT_HIGH -2 /* Timeout after PRG* deasserted */ +#define ERROR_FPGA_PRG_DONE -3 /* Timeout after programming */ + +#define SET_FPGA(data) out32(IBM405GP_GPIO0_OR, data) + +#define FPGA_WRITE_1 { \ + SET_FPGA(FPGA_PRG | FPGA_DATA); /* set clock to 0 */ \ + SET_FPGA(FPGA_PRG | FPGA_DATA); /* set data to 1 */ \ + SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set clock to 1 */ \ + SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1 */ + +#define FPGA_WRITE_0 { \ + SET_FPGA(FPGA_PRG | FPGA_DATA); /* set clock to 0 */ \ + SET_FPGA(FPGA_PRG); /* set data to 0 */ \ + SET_FPGA(FPGA_PRG | FPGA_CLK); /* set clock to 1 */ \ + SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);} /* set data to 1 */ + + +static int fpga_boot(unsigned char *fpgadata, int size) +{ + int i,index,len; + int count; +#ifdef CFG_FPGA_SPARTAN2 + int j; +#else + unsigned char b; + int bit; +#endif + + /* display infos on fpgaimage */ + index = 15; + for (i=0; i<4; i++) + { + len = fpgadata[index]; + DBG("FPGA: %s\n", &(fpgadata[index+1])); + index += len+3; + } + +#ifdef CFG_FPGA_SPARTAN2 + /* search for preamble 0xFFFFFFFF */ + while (1) + { + if ((fpgadata[index] == 0xff) && (fpgadata[index+1] == 0xff) && + (fpgadata[index+2] == 0xff) && (fpgadata[index+3] == 0xff)) + break; /* preamble found */ + else + index++; + } +#else + /* search for preamble 0xFF2X */ + for (index = 0; index < size-1 ; index++) + { + if ((fpgadata[index] == 0xff) && ((fpgadata[index+1] & 0xf0) == 0x30)) + break; + } + index += 2; +#endif + + DBG("FPGA: configdata starts at position 0x%x\n",index); + DBG("FPGA: length of fpga-data %d\n", size-index); + + /* + * Setup port pins for fpga programming + */ + out32(IBM405GP_GPIO0_ODR, 0x00000000); /* no open drain pins */ + out32(IBM405GP_GPIO0_TCR, FPGA_PRG | FPGA_CLK | FPGA_DATA); /* setup for output */ + out32(IBM405GP_GPIO0_OR, FPGA_PRG | FPGA_CLK | FPGA_DATA); /* set output pins to high */ + + DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" ); + DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" ); + + /* + * Init fpga by asserting and deasserting PROGRAM* + */ + SET_FPGA(FPGA_CLK | FPGA_DATA); + + /* Wait for FPGA init line low */ + count = 0; + while (in32(IBM405GP_GPIO0_IR) & FPGA_INIT) + { + udelay(1000); /* wait 1ms */ + /* Check for timeout - 100us max, so use 3ms */ + if (count++ > 3) + { + DBG("FPGA: Booting failed!\n"); + return ERROR_FPGA_PRG_INIT_LOW; + } + } + + DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" ); + DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" ); + + /* deassert PROGRAM* */ + SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA); + + /* Wait for FPGA end of init period . */ + count = 0; + while (!(in32(IBM405GP_GPIO0_IR) & FPGA_INIT)) + { + udelay(1000); /* wait 1ms */ + /* Check for timeout */ + if (count++ > 3) + { + DBG("FPGA: Booting failed!\n"); + return ERROR_FPGA_PRG_INIT_HIGH; + } + } + + DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" ); + DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" ); + + DBG("write configuration data into fpga\n"); + /* write configuration-data into fpga... */ + +#ifdef CFG_FPGA_SPARTAN2 + /* + * Load uncompressed image into fpga + */ + for (i=index; i<size; i++) + { + for (j=0; j<8; j++) + { + if ((fpgadata[i] & 0x80) == 0x80) + { + FPGA_WRITE_1; + } + else + { + FPGA_WRITE_0; + } + fpgadata[i] <<= 1; + } + } +#else + /* send 0xff 0x20 */ + FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1; + FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1; FPGA_WRITE_1; + FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_1; FPGA_WRITE_0; + FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_0; FPGA_WRITE_0; + + /* + ** Bit_DeCompression + ** Code 1 .. maxOnes : n '1's followed by '0' + ** maxOnes + 1 .. maxOnes + 1 : n - 1 '1's no '0' + ** maxOnes + 2 .. 254 : n - (maxOnes + 2) '0's followed by '1' + ** 255 : '1' + */ + + for (i=index; i<size; i++) + { + b = fpgadata[i]; + if ((b >= 1) && (b <= MAX_ONES)) + { + for(bit=0; bit<b; bit++) + { + FPGA_WRITE_1; + } + FPGA_WRITE_0; + } + else if (b == (MAX_ONES+1)) + { + for(bit=1; bit<b; bit++) + { + FPGA_WRITE_1; + } + } + else if ((b >= (MAX_ONES+2)) && (b <= 254)) + { + for(bit=0; bit<(b-(MAX_ONES+2)); bit++) + { + FPGA_WRITE_0; + } + FPGA_WRITE_1; + } + else if (b == 255) + { + FPGA_WRITE_1; + } + } +#endif + + DBG("%s, ",((in32(IBM405GP_GPIO0_IR) & FPGA_DONE) == 0) ? "NOT DONE" : "DONE" ); + DBG("%s\n",((in32(IBM405GP_GPIO0_IR) & FPGA_INIT) == 0) ? "NOT INIT" : "INIT" ); + + /* + * Check if fpga's DONE signal - correctly booted ? + */ + + /* Wait for FPGA end of programming period . */ + count = 0; + while (!(in32(IBM405GP_GPIO0_IR) & FPGA_DONE)) + { + udelay(1000); /* wait 1ms */ + /* Check for timeout */ + if (count++ > 3) + { + DBG("FPGA: Booting failed!\n"); + return ERROR_FPGA_PRG_DONE; + } + } + + DBG("FPGA: Booting successful!\n"); + return 0; +} diff --git a/board/esd/common/pci.c b/board/esd/common/pci.c new file mode 100644 index 0000000..f8f180c --- /dev/null +++ b/board/esd/common/pci.c @@ -0,0 +1,202 @@ +/* + * (C) Copyright 2001 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <ppc4xx.h> +#include <asm/processor.h> +#include <pci.h> + + +u_long pci9054_iobase; + + +#define PCI_PRIMARY_CAR (0x500000dc) /* PCI config address reg */ +#define PCI_PRIMARY_CDR (0x80000000) /* PCI config data reg */ + + +/*-----------------------------------------------------------------------------+ +| Subroutine: pci9054_read_config_dword +| Description: Read a PCI configuration register +| Inputs: +| hose PCI Controller +| dev PCI Bus+Device+Function number +| offset Configuration register number +| value Address of the configuration register value +| Return value: +| 0 Successful ++-----------------------------------------------------------------------------*/ +int pci9054_read_config_dword(struct pci_controller *hose, + pci_dev_t dev, int offset, u32* value) +{ + unsigned long conAdrVal; + unsigned long val; + + /* generate coded value for CON_ADR register */ + conAdrVal = dev | (offset & 0xfc) | 0x80000000; + + /* Load the CON_ADR (CAR) value first, then read from CON_DATA (CDR) */ + *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal; + + /* Note: *pResult comes back as -1 if machine check happened */ + val = in32r(PCI_PRIMARY_CDR); + + *value = (unsigned long) val; + + out32r(PCI_PRIMARY_CAR, 0); + + if ((*(unsigned long *)0x50000304) & 0x60000000) + { + /* clear pci master/target abort bits */ + *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304; + } + + return 0; +} + +/*-----------------------------------------------------------------------------+ +| Subroutine: pci9054_write_config_dword +| Description: Write a PCI configuration register. +| Inputs: +| hose PCI Controller +| dev PCI Bus+Device+Function number +| offset Configuration register number +| Value Configuration register value +| Return value: +| 0 Successful +| Updated for pass2 errata #6. Need to disable interrupts and clear the +| PCICFGADR reg after writing the PCICFGDATA reg. ++-----------------------------------------------------------------------------*/ +int pci9054_write_config_dword(struct pci_controller *hose, + pci_dev_t dev, int offset, u32 value) +{ + unsigned long conAdrVal; + + conAdrVal = dev | (offset & 0xfc) | 0x80000000; + + *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal; + + out32r(PCI_PRIMARY_CDR, value); + + out32r(PCI_PRIMARY_CAR, 0); + + /* clear pci master/target abort bits */ + *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304; + + return (0); +} + +/*----------------------------------------------------------------------- + */ + +#ifdef CONFIG_DASA_SIM +static void pci_dasa_sim_config_pci9054(struct pci_controller *hose, pci_dev_t dev, + struct pci_config_table *_) +{ + unsigned int iobase; + unsigned short status = 0; + unsigned char timer; + + /* + * Configure PLX PCI9054 + */ + pci_read_config_word(CFG_PCI9054_DEV_FN, PCI_COMMAND, &status); + status |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; + pci_write_config_word(CFG_PCI9054_DEV_FN, PCI_COMMAND, status); + + /* Check the latency timer for values >= 0x60. + */ + pci_read_config_byte(CFG_PCI9054_DEV_FN, PCI_LATENCY_TIMER, &timer); + if (timer < 0x60) + { + pci_write_config_byte(CFG_PCI9054_DEV_FN, PCI_LATENCY_TIMER, 0x60); + } + + /* Set I/O base register. + */ + pci_write_config_dword(CFG_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, CFG_PCI9054_IOBASE); + pci_read_config_dword(CFG_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, &iobase); + + pci9054_iobase = pci_mem_to_phys(CFG_PCI9054_DEV_FN, iobase & PCI_BASE_ADDRESS_MEM_MASK); + + if (pci9054_iobase == 0xffffffff) + { + printf("Error: Can not set I/O base register.\n"); + return; + } +} +#endif + +static struct pci_config_table pci9054_config_table[] = { +#ifndef CONFIG_PCI_PNP + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_BUS(CFG_ETH_DEV_FN), PCI_DEV(CFG_ETH_DEV_FN), PCI_FUNC(CFG_ETH_DEV_FN), + pci_cfgfunc_config_device, { CFG_ETH_IOBASE, + CFG_ETH_IOBASE, + PCI_COMMAND_IO | PCI_COMMAND_MASTER }}, +#ifdef CONFIG_DASA_SIM + { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_BUS(CFG_PCI9054_DEV_FN), PCI_DEV(CFG_PCI9054_DEV_FN), PCI_FUNC(CFG_PCI9054_DEV_FN), + pci_dasa_sim_config_pci9054 }, +#endif +#endif + { } +}; + +static struct pci_controller pci9054_hose = { + config_table: pci9054_config_table, +}; + +void pci_init(void) +{ + struct pci_controller *hose = &pci9054_hose; + + /* + * Register the hose + */ + hose->first_busno = 0; + hose->last_busno = 0xff; + + /* System memory space */ + pci_set_region(hose->regions + 0, + 0x00000000, 0x00000000, 0x01000000, + PCI_REGION_MEM | PCI_REGION_MEMORY); + + /* PCI Memory space */ + pci_set_region(hose->regions + 1, + 0x00000000, 0xc0000000, 0x10000000, + PCI_REGION_MEM); + + pci_set_ops(hose, + pci_hose_read_config_byte_via_dword, + pci_hose_read_config_word_via_dword, + pci9054_read_config_dword, + pci_hose_write_config_byte_via_dword, + pci_hose_write_config_word_via_dword, + pci9054_write_config_dword); + + hose->region_count = 2; + + pci_register_hose(hose); + + hose->last_busno = pci_hose_scan(hose); +} diff --git a/board/esd/cpci405/cpci405.c b/board/esd/cpci405/cpci405.c new file mode 100644 index 0000000..2dda8fa --- /dev/null +++ b/board/esd/cpci405/cpci405.c @@ -0,0 +1,451 @@ +/* + * (C) Copyright 2001 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/processor.h> +#include <command.h> +#include <cmd_boot.h> +#include <malloc.h> + +/* ------------------------------------------------------------------------- */ + +#if 0 +#define FPGA_DEBUG +#endif + +/* fpga configuration data - generated by bin2cc */ +const unsigned char fpgadata[] = +{ +#ifdef CONFIG_CPCI405_VER2 +# include "fpgadata_cpci4052.c" +#else +# include "fpgadata_cpci405.c" +#endif +}; + +/* + * include common fpga code (for esd boards) + */ +#include "../common/fpga.c" + + +/* Prototypes */ +int version2(void); +int gunzip(void *, int, unsigned char *, int *); + + +int board_pre_init (void) +{ +#ifndef CONFIG_CPCI405_VER2 + int index, len, i; + int status; +#endif + +#ifdef FPGA_DEBUG + DECLARE_GLOBAL_DATA_PTR; + + /* set up serial port with default baudrate */ + (void) get_clocks (); + gd->baudrate = CONFIG_BAUDRATE; + serial_init (); + console_init_f(); +#endif + + /* + * First pull fpga-prg pin low, to disable fpga logic (on version 2 board) + */ + out32(IBM405GP_GPIO0_ODR, 0x00000000); /* no open drain pins */ + out32(IBM405GP_GPIO0_TCR, CFG_FPGA_PRG); /* setup for output */ + out32(IBM405GP_GPIO0_OR, CFG_FPGA_PRG); /* set output pins to high */ + out32(IBM405GP_GPIO0_OR, 0); /* pull prg low */ + + /* + * Boot onboard FPGA + */ +#ifndef CONFIG_CPCI405_VER2 + if (!version2()) { + status = fpga_boot((unsigned char *)fpgadata, sizeof(fpgadata)); + if (status != 0) { + /* booting FPGA failed */ +#ifndef FPGA_DEBUG + DECLARE_GLOBAL_DATA_PTR; + + /* set up serial port with default baudrate */ + (void) get_clocks (); + gd->baudrate = CONFIG_BAUDRATE; + serial_init (); + console_init_f(); +#endif + printf("\nFPGA: Booting failed "); + switch (status) { + case ERROR_FPGA_PRG_INIT_LOW: + printf("(Timeout: INIT not low after asserting PROGRAM*)\n "); + break; + case ERROR_FPGA_PRG_INIT_HIGH: + printf("(Timeout: INIT not high after deasserting PROGRAM*)\n "); + break; + case ERROR_FPGA_PRG_DONE: + printf("(Timeout: DONE not high after programming FPGA)\n "); + break; + } + + /* display infos on fpgaimage */ + index = 15; + for (i=0; i<4; i++) { + len = fpgadata[index]; + printf("FPGA: %s\n", &(fpgadata[index+1])); + index += len+3; + } + putc ('\n'); + /* delayed reboot */ + for (i=20; i>0; i--) { + printf("Rebooting in %2d seconds \r",i); + for (index=0;index<1000;index++) + udelay(1000); + } + putc ('\n'); + do_reset(NULL, 0, 0, NULL); + } + } +#endif /* !CONFIG_CPCI405_VER2 */ + + /* + * IRQ 0-15 405GP internally generated; active high; level sensitive + * IRQ 16 405GP internally generated; active low; level sensitive + * IRQ 17-24 RESERVED + * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive + * IRQ 26 (EXT IRQ 1) CAN1 (+FPGA on CPCI4052) ; active low; level sensitive + * IRQ 27 (EXT IRQ 2) PCI SLOT 0; active low; level sensitive + * IRQ 28 (EXT IRQ 3) PCI SLOT 1; active low; level sensitive + * IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive + * IRQ 30 (EXT IRQ 5) PCI SLOT 3; active low; level sensitive + * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive + */ + mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ + mtdcr(uicer, 0x00000000); /* disable all ints */ + mtdcr(uiccr, 0x00000000); /* set all to be non-critical*/ + mtdcr(uicpr, 0xFFFFFF81); /* set int polarities */ + mtdcr(uictr, 0x10000000); /* set int trigger levels */ + mtdcr(uicvcr, 0x00000001); /* set vect base=0,INT0 highest priority*/ + mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ + + return 0; +} + + +/* ------------------------------------------------------------------------- */ + +int ctermm2(void) +{ +#ifdef CONFIG_CPCI405_VER2 + return 0; /* no, board is cpci405 */ +#else + if ((*(unsigned char *)0xf0000400 == 0x00) && + (*(unsigned char *)0xf0000401 == 0x01)) + return 0; /* no, board is cpci405 */ + else + return -1; /* yes, board is cterm-m2 */ +#endif +} + + +int cpci405_host(void) +{ + if (mfdcr(strap) & PSR_PCI_ARBIT_EN) + return -1; /* yes, board is cpci405 host */ + else + return 0; /* no, board is cpci405 adapter */ +} + + +int version2(void) +{ + unsigned long cntrl0Reg; + unsigned long value; + + /* + * Setup GPIO pins (CS2/GPIO11 as GPIO) + */ + cntrl0Reg = mfdcr(cntrl0); + mtdcr(cntrl0, cntrl0Reg | 0x02000000); + + udelay(1000); /* wait some time before reading input */ + value = in32(IBM405GP_GPIO0_IR) & 0x00100000; /* test GPIO11 */ + + /* + * Setup GPIO pins (CS2/GPIO11 as CS again) + */ + mtdcr(cntrl0, cntrl0Reg); + + if (value) + return 0; /* no, board is version 1.x */ + else + return -1; /* yes, board is version 2.x */ +} + + +int misc_init_f (void) +{ + return 0; /* dummy implementation */ +} + + +int misc_init_r (void) +{ + DECLARE_GLOBAL_DATA_PTR; + + bd_t *bd = gd->bd; + char * tmp; /* Temporary char pointer */ + +#ifdef CONFIG_CPCI405_VER2 + unsigned char *dst; + ulong len = sizeof(fpgadata); + int status; + int index; + int i; + unsigned long cntrl0Reg; + + /* + * On CPCI-405 version 2 the environment is saved in eeprom! + * FPGA can be gzip compressed (malloc) and booted this late. + */ + + if (version2()) { + /* + * Setup GPIO pins (CS6+CS7 as GPIO) + */ + cntrl0Reg = mfdcr(cntrl0); + mtdcr(cntrl0, cntrl0Reg | 0x00300000); + + dst = malloc(CFG_FPGA_MAX_SIZE); + if (gunzip (dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, (int *)&len) != 0) { + printf ("GUNZIP ERROR - must RESET board to recover\n"); + do_reset (NULL, 0, 0, NULL); + } + + status = fpga_boot(dst, len); + if (status != 0) { + printf("\nFPGA: Booting failed "); + switch (status) { + case ERROR_FPGA_PRG_INIT_LOW: + printf("(Timeout: INIT not low after asserting PROGRAM*)\n "); + break; + case ERROR_FPGA_PRG_INIT_HIGH: + printf("(Timeout: INIT not high after deasserting PROGRAM*)\n "); + break; + case ERROR_FPGA_PRG_DONE: + printf("(Timeout: DONE not high after programming FPGA)\n "); + break; + } + + /* display infos on fpgaimage */ + index = 15; + for (i=0; i<4; i++) { + len = dst[index]; + printf("FPGA: %s\n", &(dst[index+1])); + index += len+3; + } + putc ('\n'); + /* delayed reboot */ + for (i=20; i>0; i--) { + printf("Rebooting in %2d seconds \r",i); + for (index=0;index<1000;index++) + udelay(1000); + } + putc ('\n'); + do_reset(NULL, 0, 0, NULL); + } + + /* restore gpio/cs settings */ + mtdcr(cntrl0, cntrl0Reg); + + puts("FPGA: "); + + /* display infos on fpgaimage */ + index = 15; + for (i=0; i<4; i++) { + len = dst[index]; + printf("%s ", &(dst[index+1])); + index += len+3; + } + putc ('\n'); + + free(dst); + } + else { + printf("\n*** U-Boot Version does not match Board Version!\n"); + printf("*** CPCI-405 Version 2.x detected!\n"); + printf("*** Please use correct U-Boot version (CPCI4052)!\n\n"); + } + +#else /* CONFIG_CPCI405_VER2 */ + + /* + * Generate last byte of ip-addr from code-plug @ 0xf0000400 + */ + if (ctermm2()) { + char str[32]; + unsigned char ipbyte = *(unsigned char *)0xf0000400; + + /* + * Only overwrite ip-addr with allowed values + */ + if ((ipbyte != 0x00) && (ipbyte != 0xff)) { + bd->bi_ip_addr = (bd->bi_ip_addr & 0xffffff00) | ipbyte; + sprintf(str, "%ld.%ld.%ld.%ld", + (bd->bi_ip_addr & 0xff000000) >> 24, + (bd->bi_ip_addr & 0x00ff0000) >> 16, + (bd->bi_ip_addr & 0x0000ff00) >> 8, + (bd->bi_ip_addr & 0x000000ff)); + setenv("ipaddr", str); + } + } + + if (version2()) { + printf("\n*** U-Boot Version does not match Board Version!\n"); + printf("*** CPCI-405 Board Version 1.x detected!\n"); + printf("*** Please use correct U-Boot version (CPCI405)!\n\n"); + } + +#endif /* CONFIG_CPCI405_VER2 */ + + /* + * Write ethernet addr in NVRAM for VxWorks + */ + tmp = (char *)CFG_NVRAM_BASE_ADDR + CFG_NVRAM_VXWORKS_OFFS; + memcpy( (char *)tmp, (char *)&bd->bi_enetaddr[0], 6 ); + return (0); +} + + +/* + * Check Board Identity: + */ + +int checkboard (void) +{ +#ifndef CONFIG_CPCI405_VER2 + int index; + int len; +#endif + unsigned char str[64]; + int i = getenv_r ("serial#", str, sizeof(str)); + + puts ("Board: "); + + if (i == -1) { + puts ("### No HW ID - assuming CPCI405"); + } else { + puts(str); + } + + if (version2()) + puts (" (Ver 2.x, "); + else + puts (" (Ver 1.x, "); + +#if 0 + if ((*(unsigned short *)((unsigned long)CFG_FPGA_BASE_ADDR) + CFG_FPGA_STATUS) + & CFG_FPGA_STATUS_FLASH) + puts ("FLASH Bank A, "); + else + puts ("FLASH Bank B, "); +#endif + + if (ctermm2()) { + printf("CTERM-M2 - Id=0x%02x)", *(unsigned char *)0xf0000400); + } else { + if (cpci405_host()) { + puts ("PCI Host Version)"); + } else { + puts ("PCI Adapter Version)"); + } + } + +#ifndef CONFIG_CPCI405_VER2 + puts ("\nFPGA: "); + + /* display infos on fpgaimage */ + index = 15; + for (i=0; i<4; i++) { + len = fpgadata[index]; + printf("%s ", &(fpgadata[index+1])); + index += len+3; + } +#endif + + putc ('\n'); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +long int initdram (int board_type) +{ + unsigned long val; + + mtdcr(memcfga, mem_mb0cf); + val = mfdcr(memcfgd); + +#if 0 + printf("\nmb0cf=%x\n", val); /* test-only */ + printf("strap=%x\n", mfdcr(strap)); /* test-only */ +#endif + + return (4*1024*1024 << ((val & 0x000e0000) >> 17)); +} + +/* ------------------------------------------------------------------------- */ + +int testdram (void) +{ + /* TODO: XXX XXX XXX */ + printf ("test: 16 MB - ok\n"); + + return (0); +} + +/* ------------------------------------------------------------------------- */ + +#ifdef CONFIG_CPCI405_VER2 +#ifdef CONFIG_IDE_RESET + +void ide_set_reset(int on) +{ + volatile unsigned short *fpga_mode = (unsigned short *)CFG_FPGA_BASE_ADDR; + + /* + * Assert or deassert CompactFlash Reset Pin + */ + if (on) { /* assert RESET */ + *fpga_mode &= ~(CFG_FPGA_MODE_CF_RESET); + } else { /* release RESET */ + *fpga_mode |= CFG_FPGA_MODE_CF_RESET; + } +} + +#endif /* CONFIG_IDE_RESET */ +#endif /* CONFIG_CPCI405_VER2 */ + +/* ------------------------------------------------------------------------- */ diff --git a/board/esd/cpci440/cpci440.c b/board/esd/cpci440/cpci440.c new file mode 100644 index 0000000..51a5edd --- /dev/null +++ b/board/esd/cpci440/cpci440.c @@ -0,0 +1,140 @@ +/* + * (C) Copyright 2002 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#include <common.h> +#include <asm/processor.h> + + +long int fixed_sdram( void ); + +int board_pre_init (void) +{ + uint reg; + + /*-------------------------------------------------------------------- + * Setup the external bus controller/chip selects + *-------------------------------------------------------------------*/ + mtdcr( ebccfga, xbcfg ); + reg = mfdcr( ebccfgd ); + mtdcr( ebccfgd, reg | 0x04000000 ); /* Set ATC */ + + mtebc( pb0ap, 0x92015480 ); /* FLASH/SRAM */ + mtebc( pb0cr, 0xFF87A000 ); /* BAS=0xff8 8MB R/W 16-bit */ + /* test-only: other regs still missing... */ + + /*-------------------------------------------------------------------- + * Setup the interrupt controller polarities, triggers, etc. + *-------------------------------------------------------------------*/ + mtdcr( uic0sr, 0xffffffff ); /* clear all */ + mtdcr( uic0er, 0x00000000 ); /* disable all */ + mtdcr( uic0cr, 0x00000009 ); /* SMI & UIC1 crit are critical */ + mtdcr( uic0pr, 0xfffffe13 ); /* per ref-board manual */ + mtdcr( uic0tr, 0x01c00008 ); /* per ref-board manual */ + mtdcr( uic0vr, 0x00000001 ); /* int31 highest, base=0x000 */ + mtdcr( uic0sr, 0xffffffff ); /* clear all */ + + mtdcr( uic1sr, 0xffffffff ); /* clear all */ + mtdcr( uic1er, 0x00000000 ); /* disable all */ + mtdcr( uic1cr, 0x00000000 ); /* all non-critical */ + mtdcr( uic1pr, 0xffffe0ff ); /* per ref-board manual */ + mtdcr( uic1tr, 0x00ffc000 ); /* per ref-board manual */ + mtdcr( uic1vr, 0x00000001 ); /* int31 highest, base=0x000 */ + mtdcr( uic1sr, 0xffffffff ); /* clear all */ + + return 0; +} + + + +int checkboard (void) +{ + sys_info_t sysinfo; + get_sys_info(&sysinfo); + + printf("Board: esd CPCI-440\n"); + printf("\tVCO: %lu MHz\n", sysinfo.freqVCOMhz/1000000); + printf("\tCPU: %lu MHz\n", sysinfo.freqProcessor/1000000); + printf("\tPLB: %lu MHz\n", sysinfo.freqPLB/1000000); + printf("\tOPB: %lu MHz\n", sysinfo.freqOPB/1000000); + printf("\tEPB: %lu MHz\n", sysinfo.freqEPB/1000000); + return (0); +} + + +long int initdram (int board_type) +{ + long dram_size = 0; + + dram_size = fixed_sdram(); + return dram_size; +} + + +/************************************************************************* + * fixed sdram init -- doesn't use serial presence detect. + * + * Assumes: 64 MB, non-ECC, non-registered + * PLB @ 133 MHz + * + ************************************************************************/ +long int fixed_sdram( void ) +{ + uint reg; + + /*-------------------------------------------------------------------- + * Setup some default + *------------------------------------------------------------------*/ + mtsdram( mem_uabba, 0x00000000 ); /* ubba=0 (default) */ + mtsdram( mem_slio, 0x00000000 ); /* rdre=0 wrre=0 rarw=0 */ + mtsdram( mem_devopt,0x00000000 ); /* dll=0 ds=0 (normal) */ + mtsdram( mem_wddctr,0x40000000 ); /* wrcp=0 dcd=0 */ + mtsdram( mem_clktr, 0x40000000 ); /* clkp=1 (90 deg wr) dcdt=0 */ + + /*-------------------------------------------------------------------- + * Setup for board-specific specific mem + *------------------------------------------------------------------*/ + /* + * Following for CAS Latency = 2.5 @ 133 MHz PLB + */ + mtsdram( mem_b0cr, 0x00082001 );/* SDBA=0x000, 64MB, Mode 2, enabled*/ + mtsdram( mem_tr0, 0x410a4012 );/* WR=2 WD=1 CL=2.5 PA=3 CP=4 LD=2 */ + /* RA=10 RD=3 */ + mtsdram( mem_tr1, 0x8080082f );/* SS=T2 SL=STAGE 3 CD=1 CT=0x02f */ + mtsdram( mem_rtr, 0x08200000 );/* Rate 15.625 ns @ 133 MHz PLB */ + mtsdram( mem_cfg1, 0x00000000 );/* Self-refresh exit, disable PM */ + udelay( 400 ); /* Delay 200 usecs (min) */ + + /*-------------------------------------------------------------------- + * Enable the controller, then wait for DCEN to complete + *------------------------------------------------------------------*/ + mtsdram( mem_cfg0, 0x86000000 );/* DCEN=1, PMUD=1, 64-bit */ + for(;;) + { + mfsdram( mem_mcsts, reg ); + if( reg & 0x80000000 ) + break; + } + + return( 64 * 1024 * 1024 ); /* 64 MB */ +} diff --git a/board/esd/cpci440/init.S b/board/esd/cpci440/init.S new file mode 100644 index 0000000..2dab9f9 --- /dev/null +++ b/board/esd/cpci440/init.S @@ -0,0 +1,96 @@ +/* +* Copyright (C) 2002 Scott McNutt <smcnutt@artesyncp.com> +* +* See file CREDITS for list of people who contributed to this +* project. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, +* MA 02111-1307 USA +*/ + +#include <ppc_asm.tmpl> +#include <config.h> + +/* General */ +#define TLB_VALID 0x00000200 + +/* Supported page sizes */ + +#define SZ_1K 0x00000000 +#define SZ_4K 0x00000010 +#define SZ_16K 0x00000020 +#define SZ_64K 0x00000030 +#define SZ_256K 0x00000040 +#define SZ_1M 0x00000050 +#define SZ_16M 0x00000070 +#define SZ_256M 0x00000090 + +/* Storage attributes */ +#define SA_W 0x00000800 /* Write-through */ +#define SA_I 0x00000400 /* Caching inhibited */ +#define SA_M 0x00000200 /* Memory coherence */ +#define SA_G 0x00000100 /* Guarded */ +#define SA_E 0x00000080 /* Endian */ + +/* Access control */ +#define AC_X 0x00000024 /* Execute */ +#define AC_W 0x00000012 /* Write */ +#define AC_R 0x00000009 /* Read */ + +/* Some handy macros */ + +#define EPN(e) ((e) & 0xfffffc00) +#define TLB0(epn,sz) ( (EPN((epn)) | (sz) | TLB_VALID ) ) +#define TLB1(rpn,erpn) ( ((rpn)&0xfffffc00) | (erpn) ) +#define TLB2(a) ( (a)&0x00000fbf ) + +#define tlbtab_start\ + mflr r1 ;\ + bl 0f ; + +#define tlbtab_end\ + .long 0, 0, 0 ; \ +0: mflr r0 ; \ + mtlr r1 ; \ + blr ; + +#define tlbentry(epn,sz,rpn,erpn,attr)\ + .long TLB0(epn,sz),TLB1(rpn,erpn),TLB2(attr) + + +/************************************************************************** + * TLB TABLE + * + * This table is used by the cpu boot code to setup the initial tlb + * entries. Rather than make broad assumptions in the cpu source tree, + * this table lets each board set things up however they like. + * + * Pointer to the table is returned in r1 + * + *************************************************************************/ + + .section .bootpg,"ax" + .globl tlbtab + +tlbtab: + tlbtab_start + tlbentry( 0xf0000000, SZ_256M, 0xf0000000, 1, AC_R|AC_W|AC_X|SA_G|SA_I) + tlbentry( CFG_PERIPHERAL_BASE, SZ_256M, 0x40000000, 1, AC_R|AC_W|SA_G|SA_I) + tlbentry( CFG_ISRAM_BASE, SZ_4K, 0x80000000, 0, AC_R|AC_W|AC_X ) + tlbentry( CFG_ISRAM_BASE + 0x1000, SZ_4K, 0x80001000, 0, AC_R|AC_W|AC_X ) + tlbentry( CFG_SDRAM_BASE, SZ_256M, 0x00000000, 0, AC_R|AC_W|AC_X ) + tlbtab_end + + diff --git a/board/esd/pci405/pci405.c b/board/esd/pci405/pci405.c new file mode 100644 index 0000000..ed86c02 --- /dev/null +++ b/board/esd/pci405/pci405.c @@ -0,0 +1,254 @@ +/* + * (C) Copyright 2001 + * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/processor.h> +#include <command.h> +#include <cmd_boot.h> +#include <malloc.h> +#include <pci.h> +#include <405gp_pci.h> + +/* ------------------------------------------------------------------------- */ + +#if 0 +#define FPGA_DEBUG +#endif + +#define PCI_RECONFIG_MAGIC 0x07081967 + + +struct pci_config_regs { + unsigned short command; + unsigned char latency_timer; + unsigned char int_line; + unsigned long bar1; + unsigned long bar2; + unsigned long magic; +}; + + +/* fpga configuration data - generated by bin2cc */ +const unsigned char fpgadata[] = +{ +#include "fpgadata.c" +}; + +/* + * include common fpga code (for esd boards) + */ +#include "../common/fpga.c" + + +/* Prototypes */ +int gunzip(void *, int, unsigned char *, int *); + + +int board_pre_init (void) +{ + unsigned long cntrl0Reg; + + /* + * IRQ 0-15 405GP internally generated; active high; level sensitive + * IRQ 16 405GP internally generated; active low; level sensitive + * IRQ 17-24 RESERVED + * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive + * IRQ 26 (EXT IRQ 1) CAN1; active low; level sensitive + * IRQ 27 (EXT IRQ 2) CAN2; active low; level sensitive + * IRQ 28 (EXT IRQ 3) CAN3; active low; level sensitive + * IRQ 29 (EXT IRQ 4) unused; active low; level sensitive + * IRQ 30 (EXT IRQ 5) FPGA Timestamp; active low; level sensitive + * IRQ 31 (EXT IRQ 6) PCI Reset; active low; level sensitive + */ + mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ + mtdcr(uicer, 0x00000000); /* disable all ints */ + mtdcr(uiccr, 0x00000000); /* set all to be non-critical*/ + mtdcr(uicpr, 0xFFFFFF80); /* set int polarities */ + mtdcr(uictr, 0x10000000); /* set int trigger levels */ + mtdcr(uicvcr, 0x00000001); /* set vect base=0,INT0 highest priority*/ + mtdcr(uicsr, 0xFFFFFFFF); /* clear all ints */ + + /* + * Setup GPIO pins (IRQ4/GPIO21 as GPIO) + */ + cntrl0Reg = mfdcr(cntrl0); + mtdcr(cntrl0, cntrl0Reg | 0x00008000); + + return 0; +} + + +/* ------------------------------------------------------------------------- */ + +int misc_init_f (void) +{ + return 0; /* dummy implementation */ +} + + +int misc_init_r (void) +{ + unsigned char *dst; + ulong len = sizeof(fpgadata); + int status; + int index; + int i; + struct pci_config_regs *pci_regs; + + /* + * On PCI-405 the environment is saved in eeprom! + * FPGA can be gzip compressed (malloc) and booted this late. + */ + + dst = malloc(CFG_FPGA_MAX_SIZE); + if (gunzip (dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, (int *)&len) != 0) { + printf ("GUNZIP ERROR - must RESET board to recover\n"); + do_reset (NULL, 0, 0, NULL); + } + + status = fpga_boot(dst, len); + if (status != 0) { + printf("\nFPGA: Booting failed "); + switch (status) { + case ERROR_FPGA_PRG_INIT_LOW: + printf("(Timeout: INIT not low after asserting PROGRAM*)\n "); + break; + case ERROR_FPGA_PRG_INIT_HIGH: + printf("(Timeout: INIT not high after deasserting PROGRAM*)\n "); + break; + case ERROR_FPGA_PRG_DONE: + printf("(Timeout: DONE not high after programming FPGA)\n "); + break; + } + + /* display infos on fpgaimage */ + index = 15; + for (i=0; i<4; i++) { + len = dst[index]; + printf("FPGA: %s\n", &(dst[index+1])); + index += len+3; + } + putc ('\n'); + /* delayed reboot */ + for (i=20; i>0; i--) { + printf("Rebooting in %2d seconds \r",i); + for (index=0;index<1000;index++) + udelay(1000); + } + putc ('\n'); + do_reset(NULL, 0, 0, NULL); + } + + puts("FPGA: "); + + /* display infos on fpgaimage */ + index = 15; + for (i=0; i<4; i++) { + len = dst[index]; + printf("%s ", &(dst[index+1])); + index += len+3; + } + putc ('\n'); + + /* + * Rewrite pci config regs (only after soft-reset with magic set) + */ + pci_regs = (struct pci_config_regs *)0x10; + if (pci_regs->magic == PCI_RECONFIG_MAGIC) { + puts("PCI: Found magic, rewriting config regs...\n"); + pci_write_config_word(PCIDEVID_405GP, PCI_COMMAND, + pci_regs->command); + pci_write_config_byte(PCIDEVID_405GP, PCI_LATENCY_TIMER, + pci_regs->latency_timer); + pci_write_config_byte(PCIDEVID_405GP, PCI_INTERRUPT_LINE, + pci_regs->int_line); + pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_1, + pci_regs->bar1); + pci_write_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2, + pci_regs->bar2); + } + pci_regs->magic = 0; /* clear magic again */ + +#if 0 /* test-only */ + pci_read_config_word(PCIDEVID_405GP, PCI_COMMAND, &(pci_regs->command)); + pci_read_config_byte(PCIDEVID_405GP, PCI_LATENCY_TIMER, &(pci_regs->latency_timer)); + pci_read_config_byte(PCIDEVID_405GP, PCI_INTERRUPT_LINE, &(pci_regs->int_line)); + pci_read_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_1, &(pci_regs->bar1)); + pci_read_config_dword(PCIDEVID_405GP, PCI_BASE_ADDRESS_2, &(pci_regs->bar2)); + pci_regs->magic = PCI_RECONFIG_MAGIC; /* set magic */ +#endif + + free(dst); + return (0); +} + + +/* + * Check Board Identity: + */ + +int checkboard (void) +{ + unsigned char str[64]; + int i = getenv_r ("serial#", str, sizeof(str)); + + puts ("Board: "); + + if (i == -1) { + puts ("### No HW ID - assuming CPCI405"); + } else { + puts (str); + } + putc ('\n'); + + return 0; +} + +/* ------------------------------------------------------------------------- */ + +long int initdram (int board_type) +{ + unsigned long val; + + mtdcr(memcfga, mem_mb0cf); + val = mfdcr(memcfgd); + +#if 0 + printf("\nmb0cf=%x\n", val); /* test-only */ + printf("strap=%x\n", mfdcr(strap)); /* test-only */ +#endif + + return (4*1024*1024 << ((val & 0x000e0000) >> 17)); +} + +/* ------------------------------------------------------------------------- */ + +int testdram (void) +{ + /* TODO: XXX XXX XXX */ + printf ("test: 16 MB - ok\n"); + + return (0); +} + +/* ------------------------------------------------------------------------- */ |