diff options
Diffstat (limited to 'cpu')
| -rw-r--r-- | cpu/ppc4xx/44x_spd_ddr2.c | 274 | ||||
| -rw-r--r-- | cpu/ppc4xx/4xx_enet.c | 490 | ||||
| -rw-r--r-- | cpu/ppc4xx/4xx_uart.c | 2 | ||||
| -rw-r--r-- | cpu/ppc4xx/Makefile | 13 | ||||
| -rw-r--r-- | cpu/ppc4xx/cpu.c | 41 | ||||
| -rw-r--r-- | cpu/ppc4xx/cpu_init.c | 15 | ||||
| -rw-r--r-- | cpu/ppc4xx/interrupts.c | 235 | ||||
| -rw-r--r-- | cpu/ppc4xx/iop480_uart.c | 1 | ||||
| -rw-r--r-- | cpu/ppc4xx/speed.c | 9 | ||||
| -rw-r--r-- | cpu/ppc4xx/start.S | 19 | ||||
| -rw-r--r-- | cpu/ppc4xx/uic.c | 180 | ||||
| -rw-r--r-- | cpu/ppc4xx/usbdev.c | 4 | ||||
| -rw-r--r-- | cpu/ppc4xx/xilinx_irq.c | 100 | 
13 files changed, 691 insertions, 692 deletions
| diff --git a/cpu/ppc4xx/44x_spd_ddr2.c b/cpu/ppc4xx/44x_spd_ddr2.c index e9940e8e5..1c3632428 100644 --- a/cpu/ppc4xx/44x_spd_ddr2.c +++ b/cpu/ppc4xx/44x_spd_ddr2.c @@ -50,9 +50,19 @@  #include "ecc.h" -#if defined(CONFIG_SPD_EEPROM) &&				\ -	(defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ -	 defined(CONFIG_460EX) || defined(CONFIG_460GT)) +#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2) + +#define PPC4xx_IBM_DDR2_DUMP_REGISTER(mnemonic)				\ +	do {								\ +		u32 data;						\ +		mfsdram(SDRAM_##mnemonic, data);			\ +		printf("%20s[%02x] = 0x%08X\n",				\ +		       "SDRAM_" #mnemonic, SDRAM_##mnemonic, data);	\ +	} while (0) + +static inline void ppc4xx_ibm_ddr2_register_dump(void); + +#if defined(CONFIG_SPD_EEPROM)  /*-----------------------------------------------------------------------------+   * Defines @@ -257,7 +267,6 @@ static void	test(void);  #else  static void	DQS_calibration_process(void);  #endif -static void ppc440sp_sdram_register_dump(void);  int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);  void dcbz_area(u32 start_address, u32 num_bytes); @@ -607,7 +616,7 @@ phys_size_t initdram(int board_type)  	remove_tlb(0, dram_size);  	program_tlb(0, 0, dram_size, MY_TLB_WORD2_I_ENABLE); -	ppc440sp_sdram_register_dump(); +	ppc4xx_ibm_ddr2_register_dump();  	/*  	 * Clear potential errors resulting from auto-calibration. @@ -2760,7 +2769,7 @@ calibration_loop:  		printf("\nERROR: Cannot determine a common read delay for the "  		       "DIMM(s) installed.\n");  		debug("%s[%d] ERROR : \n", __FUNCTION__,__LINE__); -		ppc440sp_sdram_register_dump(); +		ppc4xx_ibm_ddr2_register_dump();  		spd_ddr_init_hang ();  	} @@ -2946,169 +2955,8 @@ static void test(void)  }  #endif -#if defined(DEBUG) -static void ppc440sp_sdram_register_dump(void) -{ -	unsigned int sdram_reg; -	unsigned int sdram_data; -	unsigned int dcr_data; +#else /* CONFIG_SPD_EEPROM */ -	printf("\n  Register Dump:\n"); -	sdram_reg = SDRAM_MCSTAT; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_MCSTAT    = 0x%08X", sdram_data); -	sdram_reg = SDRAM_MCOPT1; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_MCOPT1    = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_MCOPT2; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_MCOPT2    = 0x%08X", sdram_data); -	sdram_reg = SDRAM_MODT0; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_MODT0     = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_MODT1; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_MODT1     = 0x%08X", sdram_data); -	sdram_reg = SDRAM_MODT2; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_MODT2     = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_MODT3; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_MODT3     = 0x%08X", sdram_data); -	sdram_reg = SDRAM_CODT; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_CODT      = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_VVPR; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_VVPR      = 0x%08X", sdram_data); -	sdram_reg = SDRAM_OPARS; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_OPARS     = 0x%08X\n", sdram_data); -	/* -	 * OPAR2 is only used as a trigger register. -	 * No data is contained in this register, and reading or writing -	 * to is can cause bad things to happen (hangs).  Just skip it -	 * and report NA -	 * sdram_reg = SDRAM_OPAR2; -	 * mfsdram(sdram_reg, sdram_data); -	 * printf("        SDRAM_OPAR2     = 0x%08X\n", sdram_data); -	 */ -	printf("        SDRAM_OPART     = N/A       "); -	sdram_reg = SDRAM_RTR; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_RTR       = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_MB0CF; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_MB0CF     = 0x%08X", sdram_data); -	sdram_reg = SDRAM_MB1CF; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_MB1CF     = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_MB2CF; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_MB2CF     = 0x%08X", sdram_data); -	sdram_reg = SDRAM_MB3CF; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_MB3CF     = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_INITPLR0; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR0  = 0x%08X", sdram_data); -	sdram_reg = SDRAM_INITPLR1; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR1  = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_INITPLR2; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR2  = 0x%08X", sdram_data); -	sdram_reg = SDRAM_INITPLR3; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR3  = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_INITPLR4; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR4  = 0x%08X", sdram_data); -	sdram_reg = SDRAM_INITPLR5; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR5  = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_INITPLR6; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR6  = 0x%08X", sdram_data); -	sdram_reg = SDRAM_INITPLR7; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR7  = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_INITPLR8; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR8  = 0x%08X", sdram_data); -	sdram_reg = SDRAM_INITPLR9; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR9  = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_INITPLR10; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR10 = 0x%08X", sdram_data); -	sdram_reg = SDRAM_INITPLR11; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR11 = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_INITPLR12; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR12 = 0x%08X", sdram_data); -	sdram_reg = SDRAM_INITPLR13; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR13 = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_INITPLR14; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR14 = 0x%08X", sdram_data); -	sdram_reg = SDRAM_INITPLR15; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_INITPLR15 = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_RQDC; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_RQDC      = 0x%08X", sdram_data); -	sdram_reg = SDRAM_RFDC; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_RFDC      = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_RDCC; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_RDCC      = 0x%08X", sdram_data); -	sdram_reg = SDRAM_DLCR; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_DLCR      = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_CLKTR; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_CLKTR     = 0x%08X", sdram_data); -	sdram_reg = SDRAM_WRDTR; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_WRDTR     = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_SDTR1; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_SDTR1     = 0x%08X", sdram_data); -	sdram_reg = SDRAM_SDTR2; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_SDTR2     = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_SDTR3; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_SDTR3     = 0x%08X", sdram_data); -	sdram_reg = SDRAM_MMODE; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_MMODE     = 0x%08X\n", sdram_data); -	sdram_reg = SDRAM_MEMODE; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_MEMODE    = 0x%08X", sdram_data); -	sdram_reg = SDRAM_ECCCR; -	mfsdram(sdram_reg, sdram_data); -	printf("        SDRAM_ECCCR     = 0x%08X\n\n", sdram_data); - -	dcr_data = mfdcr(SDRAM_R0BAS); -	printf("        MQ0_B0BAS       = 0x%08X", dcr_data); -	dcr_data = mfdcr(SDRAM_R1BAS); -	printf("        MQ1_B0BAS       = 0x%08X\n", dcr_data); -	dcr_data = mfdcr(SDRAM_R2BAS); -	printf("        MQ2_B0BAS       = 0x%08X", dcr_data); -	dcr_data = mfdcr(SDRAM_R3BAS); -	printf("        MQ3_B0BAS       = 0x%08X\n", dcr_data); -} -#else /* !defined(DEBUG) */ -static void ppc440sp_sdram_register_dump(void) -{ -} -#endif /* defined(DEBUG) */ -#elif defined(CONFIG_405EX)  /*-----------------------------------------------------------------------------   * Function:	initdram   * Description: Configures the PPC405EX(r) DDR1/DDR2 SDRAM memory @@ -3222,8 +3070,96 @@ phys_size_t initdram(int board_type)  #if defined(CONFIG_DDR_ECC)  	ecc_init(CFG_SDRAM_BASE, CFG_MBYTES_SDRAM << 20);  #endif /* defined(CONFIG_DDR_ECC) */ + +	ppc4xx_ibm_ddr2_register_dump();  #endif /* !defined(CONFIG_NAND_U_BOOT) || defined(CONFIG_NAND_SPL) */  	return (CFG_MBYTES_SDRAM << 20);  } -#endif /* defined(CONFIG_SPD_EEPROM) && defined(CONFIG_440SP) || ... */ +#endif /* CONFIG_SPD_EEPROM */ + +static inline void ppc4xx_ibm_ddr2_register_dump(void) +{ +#if defined(DEBUG) +	printf("\nPPC4xx IBM DDR2 Register Dump:\n"); + +#if (defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ +     defined(CONFIG_460EX) || defined(CONFIG_460GT)) +	PPC4xx_IBM_DDR2_DUMP_REGISTER(R0BAS); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(R1BAS); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(R2BAS); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(R3BAS); +#endif /* (defined(CONFIG_440SP) || ... */ +#if defined(CONFIG_405EX) +	PPC4xx_IBM_DDR2_DUMP_REGISTER(BESR); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(BEARL); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(BEARH); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(WMIRQ); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(PLBOPT); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(PUABA); +#endif /* defined(CONFIG_405EX) */ +	PPC4xx_IBM_DDR2_DUMP_REGISTER(MB0CF); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(MB1CF); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(MB2CF); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(MB3CF); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(MCSTAT); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(MCOPT1); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(MCOPT2); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(MODT0); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(MODT1); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(MODT2); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(MODT3); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(CODT); +#if (defined(CONFIG_440SP) || defined(CONFIG_440SPE) ||	\ +     defined(CONFIG_460EX) || defined(CONFIG_460GT)) +	PPC4xx_IBM_DDR2_DUMP_REGISTER(VVPR); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(OPARS); +	/* +	 * OPART is only used as a trigger register. +	 * +	 * No data is contained in this register, and reading or writing +	 * to is can cause bad things to happen (hangs). Just skip it and +	 * report "N/A". +	 */ +	printf("%20s = N/A\n", "SDRAM_OPART"); +#endif /* defined(CONFIG_440SP) || ... */ +	PPC4xx_IBM_DDR2_DUMP_REGISTER(RTR); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR0); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR1); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR2); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR3); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR4); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR5); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR6); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR7); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR8); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR9); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR10); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR11); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR12); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR13); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR14); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(INITPLR15); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(RQDC); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(RFDC); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(RDCC); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(DLCR); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(CLKTR); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(WRDTR); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(SDTR1); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(SDTR2); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(SDTR3); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(MMODE); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(MEMODE); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(ECCCR); +#if (defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ +     defined(CONFIG_460EX) || defined(CONFIG_460GT)) +	PPC4xx_IBM_DDR2_DUMP_REGISTER(CID); +#endif /* defined(CONFIG_440SP) || ... */ +	PPC4xx_IBM_DDR2_DUMP_REGISTER(RID); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(FCSR); +	PPC4xx_IBM_DDR2_DUMP_REGISTER(RTSR); +#endif /* defined(DEBUG) */ +} + +#endif /* CONFIG_SDRAM_PPC4xx_IBM_DDR2 */ diff --git a/cpu/ppc4xx/4xx_enet.c b/cpu/ppc4xx/4xx_enet.c index 4e863dc91..8a3833513 100644 --- a/cpu/ppc4xx/4xx_enet.c +++ b/cpu/ppc4xx/4xx_enet.c @@ -90,7 +90,6 @@  #include <405_mal.h>  #include <miiphy.h>  #include <malloc.h> -#include <asm/ppc4xx-intvec.h>  /*   * Only compile for platform with AMCC EMAC ethernet controller and @@ -122,11 +121,65 @@   * Defines for MAL/EMAC interrupt conditions as reported in the UIC (Universal   * Interrupt Controller).   *-----------------------------------------------------------------------------*/ -#define MAL_UIC_ERR ( UIC_MAL_SERR | UIC_MAL_TXDE  | UIC_MAL_RXDE) -#define MAL_UIC_DEF  (UIC_MAL_RXEOB | MAL_UIC_ERR) -#define EMAC_UIC_DEF UIC_ENET -#define EMAC_UIC_DEF1 UIC_ENET1 -#define SEL_UIC_DEF(p) (p ? UIC_ENET1 : UIC_ENET ) +#define ETH_IRQ_NUM(dev)	(VECNUM_ETH0 + ((dev) * VECNUM_ETH1_OFFS)) + +#if defined(CONFIG_HAS_ETH3) +#if !defined(CONFIG_440GX) +#define UIC_ETHx	(UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1)) || \ +			 UIC_MASK(ETH_IRQ_NUM(2)) || UIC_MASK(ETH_IRQ_NUM(3))) +#else +/* Unfortunately 440GX spreads EMAC interrupts on multiple UIC's */ +#define UIC_ETHx	(UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1))) +#define UIC_ETHxB	(UIC_MASK(ETH_IRQ_NUM(2)) || UIC_MASK(ETH_IRQ_NUM(3))) +#endif /* !defined(CONFIG_440GX) */ +#elif defined(CONFIG_HAS_ETH2) +#define UIC_ETHx	(UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1)) || \ +			 UIC_MASK(ETH_IRQ_NUM(2))) +#elif defined(CONFIG_HAS_ETH1) +#define UIC_ETHx	(UIC_MASK(ETH_IRQ_NUM(0)) || UIC_MASK(ETH_IRQ_NUM(1))) +#else +#define UIC_ETHx	UIC_MASK(ETH_IRQ_NUM(0)) +#endif + +/* + * Define a default version for UIC_ETHxB for non 440GX so that we can + * use common code for all 4xx variants + */ +#if !defined(UIC_ETHxB) +#define UIC_ETHxB	0 +#endif + +#define UIC_MAL_SERR	UIC_MASK(VECNUM_MAL_SERR) +#define UIC_MAL_TXDE	UIC_MASK(VECNUM_MAL_TXDE) +#define UIC_MAL_RXDE	UIC_MASK(VECNUM_MAL_RXDE) +#define UIC_MAL_TXEOB	UIC_MASK(VECNUM_MAL_TXEOB) +#define UIC_MAL_RXEOB	UIC_MASK(VECNUM_MAL_RXEOB) + +#define MAL_UIC_ERR	(UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE) +#define MAL_UIC_DEF	(UIC_MAL_RXEOB | MAL_UIC_ERR) + +/* + * We have 3 different interrupt types: + * - MAL interrupts indicating successful transfer + * - MAL error interrupts indicating MAL related errors + * - EMAC interrupts indicating EMAC related errors + * + * All those interrupts can be on different UIC's, but since + * now at least all interrupts from one type are on the same + * UIC. Only exception is 440GX where the EMAC interrupts are + * spread over two UIC's! + */ +#if defined(CONFIG_440GX) +#define UIC_BASE_MAL	UIC1_DCR_BASE +#define UIC_BASE_MAL_ERR UIC2_DCR_BASE +#define UIC_BASE_EMAC	UIC2_DCR_BASE +#define UIC_BASE_EMAC_B	UIC3_DCR_BASE +#else +#define UIC_BASE_MAL	(UIC0_DCR_BASE + (UIC_NR(VECNUM_MAL_TXEOB) * 0x10)) +#define UIC_BASE_MAL_ERR (UIC0_DCR_BASE + (UIC_NR(VECNUM_MAL_SERR) * 0x10)) +#define UIC_BASE_EMAC	(UIC0_DCR_BASE + (UIC_NR(ETH_IRQ_NUM(0)) * 0x10)) +#define UIC_BASE_EMAC_B	(UIC0_DCR_BASE + (UIC_NR(ETH_IRQ_NUM(0)) * 0x10)) +#endif  #undef INFO_4XX_ENET @@ -166,9 +219,6 @@  /*-----------------------------------------------------------------------------+   * Global variables. TX and RX descriptors and buffers.   *-----------------------------------------------------------------------------*/ -/* IER globals */ -static uint32_t mal_ier; -  #if !defined(CONFIG_NET_MULTI)  struct eth_device *emac0_dev = NULL;  #endif @@ -200,12 +250,6 @@ struct eth_device *emac0_dev = NULL;  #define CONFIG_EMAC_NR_START	0  #endif -#if defined(CONFIG_405EX) || defined(CONFIG_440EPX) -#define ETH_IRQ_NUM(dev)	(VECNUM_ETH0 + ((dev))) -#else -#define ETH_IRQ_NUM(dev)	(VECNUM_ETH0 + ((dev) * 2)) -#endif -  #define MAL_RX_DESC_SIZE	2048  #define MAL_TX_DESC_SIZE	2048  #define MAL_ALLOC_SIZE		(MAL_TX_DESC_SIZE + MAL_RX_DESC_SIZE) @@ -465,30 +509,88 @@ int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)  #if defined(CONFIG_405EX)  int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)  { -	u32 gmiifer = 0; +	u32 rgmiifer = 0;  	/* -	 * Right now only 2*RGMII is supported. Please extend when needed. -	 * sr - 2007-09-19 +	 * The 405EX(r)'s RGMII bridge can operate in one of several +	 * modes, only one of which (2 x RGMII) allows the +	 * simultaneous use of both EMACs on the 405EX.  	 */ -	switch (1) { -	case 1: + +	switch (CONFIG_EMAC_PHY_MODE) { + +	case EMAC_PHY_MODE_NONE: +		/* No ports */ +		rgmiifer |= RGMII_FER_DIS	<< 0; +		rgmiifer |= RGMII_FER_DIS	<< 4; +		out_be32((void *)RGMII_FER, rgmiifer); +		bis->bi_phymode[0] = BI_PHYMODE_NONE; +		bis->bi_phymode[1] = BI_PHYMODE_NONE; +		break; +	case EMAC_PHY_MODE_NONE_RGMII: +		/* 1 x RGMII port on channel 0 */ +		rgmiifer |= RGMII_FER_RGMII	<< 0; +		rgmiifer |= RGMII_FER_DIS	<< 4; +		out_be32((void *)RGMII_FER, rgmiifer); +		bis->bi_phymode[0] = BI_PHYMODE_RGMII; +		bis->bi_phymode[1] = BI_PHYMODE_NONE; +		break; +	case EMAC_PHY_MODE_RGMII_NONE: +		/* 1 x RGMII port on channel 1 */ +		rgmiifer |= RGMII_FER_DIS	<< 0; +		rgmiifer |= RGMII_FER_RGMII	<< 4; +		out_be32((void *)RGMII_FER, rgmiifer); +		bis->bi_phymode[0] = BI_PHYMODE_NONE; +		bis->bi_phymode[1] = BI_PHYMODE_RGMII; +		break; +	case EMAC_PHY_MODE_RGMII_RGMII:  		/* 2 x RGMII ports */ -		out_be32((void *)RGMII_FER, 0x00000055); +		rgmiifer |= RGMII_FER_RGMII	<< 0; +		rgmiifer |= RGMII_FER_RGMII	<< 4; +		out_be32((void *)RGMII_FER, rgmiifer);  		bis->bi_phymode[0] = BI_PHYMODE_RGMII;  		bis->bi_phymode[1] = BI_PHYMODE_RGMII;  		break; -	case 2: -		/* 2 x SMII ports */ +	case EMAC_PHY_MODE_NONE_GMII: +		/* 1 x GMII port on channel 0 */ +		rgmiifer |= RGMII_FER_GMII	<< 0; +		rgmiifer |= RGMII_FER_DIS	<< 4; +		out_be32((void *)RGMII_FER, rgmiifer); +		bis->bi_phymode[0] = BI_PHYMODE_GMII; +		bis->bi_phymode[1] = BI_PHYMODE_NONE; +		break; +	case EMAC_PHY_MODE_NONE_MII: +		/* 1 x MII port on channel 0 */ +		rgmiifer |= RGMII_FER_MII	<< 0; +		rgmiifer |= RGMII_FER_DIS	<< 4; +		out_be32((void *)RGMII_FER, rgmiifer); +		bis->bi_phymode[0] = BI_PHYMODE_MII; +		bis->bi_phymode[1] = BI_PHYMODE_NONE; +		break; +	case EMAC_PHY_MODE_GMII_NONE: +		/* 1 x GMII port on channel 1 */ +		rgmiifer |= RGMII_FER_DIS	<< 0; +		rgmiifer |= RGMII_FER_GMII	<< 4; +		out_be32((void *)RGMII_FER, rgmiifer); +		bis->bi_phymode[0] = BI_PHYMODE_NONE; +		bis->bi_phymode[1] = BI_PHYMODE_GMII; +		break; +	case EMAC_PHY_MODE_MII_NONE: +		/* 1 x MII port on channel 1 */ +		rgmiifer |= RGMII_FER_DIS	<< 0; +		rgmiifer |= RGMII_FER_MII	<< 4; +		out_be32((void *)RGMII_FER, rgmiifer); +		bis->bi_phymode[0] = BI_PHYMODE_NONE; +		bis->bi_phymode[1] = BI_PHYMODE_MII;  		break;  	default:  		break;  	}  	/* Ensure we setup mdio for this devnum and ONLY this devnum */ -	gmiifer = in_be32((void *)RGMII_FER); -	gmiifer |= (1 << (19-devnum)); -	out_be32((void *)RGMII_FER, gmiifer); +	rgmiifer = in_be32((void *)RGMII_FER); +	rgmiifer |= (1 << (19-devnum)); +	out_be32((void *)RGMII_FER, rgmiifer);  	return ((int)0x0);  } @@ -1377,59 +1479,17 @@ static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr,  	}  } - -#if defined (CONFIG_440) || defined(CONFIG_405EX) - -#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) -/* - * Hack: On 440SP all enet irq sources are located on UIC1 - * Needs some cleanup. --sr - */ -#define UIC0MSR		uic1msr -#define UIC0SR		uic1sr -#define UIC1MSR		uic1msr -#define UIC1SR		uic1sr -#elif defined(CONFIG_460EX) || defined(CONFIG_460GT) -/* - * Hack: On 460EX/GT all enet irq sources are located on UIC2 - * Needs some cleanup. --ag - */ -#define UIC0MSR		uic2msr -#define UIC0SR		uic2sr -#define UIC1MSR		uic2msr -#define UIC1SR		uic2sr -#else -#define UIC0MSR		uic0msr -#define UIC0SR		uic0sr -#define UIC1MSR		uic1msr -#define UIC1SR		uic1sr -#endif - -#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ -    defined(CONFIG_405EX) -#define UICMSR_ETHX	uic0msr -#define UICSR_ETHX	uic0sr -#elif defined(CONFIG_460EX) || defined(CONFIG_460GT) -#define UICMSR_ETHX	uic2msr -#define UICSR_ETHX	uic2sr -#else -#define UICMSR_ETHX	uic1msr -#define UICSR_ETHX	uic1sr -#endif -  int enetInt (struct eth_device *dev)  {  	int serviced;  	int rc = -1;		/* default to not us */ -	unsigned long mal_isr; -	unsigned long emac_isr = 0; -	unsigned long mal_rx_eob; -	unsigned long my_uic0msr, my_uic1msr; -	unsigned long my_uicmsr_ethx; - -#if defined(CONFIG_440GX) -	unsigned long my_uic2msr; -#endif +	u32 mal_isr; +	u32 emac_isr = 0; +	u32 mal_eob; +	u32 uic_mal; +	u32 uic_mal_err; +	u32 uic_emac; +	u32 uic_emac_b;  	EMAC_4XX_HW_PST hw_p;  	/* @@ -1448,256 +1508,79 @@ int enetInt (struct eth_device *dev)  	do {  		serviced = 0; -		my_uic0msr = mfdcr (UIC0MSR); -		my_uic1msr = mfdcr (UIC1MSR); -#if defined(CONFIG_440GX) -		my_uic2msr = mfdcr (uic2msr); -#endif -		my_uicmsr_ethx = mfdcr (UICMSR_ETHX); +		uic_mal = mfdcr(UIC_BASE_MAL + UIC_MSR); +		uic_mal_err = mfdcr(UIC_BASE_MAL_ERR + UIC_MSR); +		uic_emac = mfdcr(UIC_BASE_EMAC + UIC_MSR); +		uic_emac_b = mfdcr(UIC_BASE_EMAC_B + UIC_MSR); -		if (!(my_uic0msr & (UIC_MRE | UIC_MTE)) -		    && !(my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE)) -		    && !(my_uicmsr_ethx & (UIC_ETH0 | UIC_ETH1))) { +		if (!(uic_mal & (UIC_MAL_RXEOB | UIC_MAL_TXEOB)) +		    && !(uic_mal_err & (UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE)) +		    && !(uic_emac & UIC_ETHx) && !(uic_emac_b & UIC_ETHxB)) {  			/* not for us */  			return (rc);  		} -#if defined (CONFIG_440GX) -		if (!(my_uic0msr & (UIC_MRE | UIC_MTE)) -		    && !(my_uic2msr & (UIC_ETH2 | UIC_ETH3))) { -			/* not for us */ -			return (rc); -		} -#endif +  		/* get and clear controller status interrupts */ -		/* look at Mal and EMAC interrupts */ -		if ((my_uic0msr & (UIC_MRE | UIC_MTE)) -		    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) { -			/* we have a MAL interrupt */ -			mal_isr = mfdcr (malesr); -			/* look for mal error */ -			if (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE)) { -				mal_err (dev, mal_isr, my_uic1msr, MAL_UIC_DEF, MAL_UIC_ERR); -				serviced = 1; -				rc = 0; -			} -		} +		/* look at MAL and EMAC error interrupts */ +		if (uic_mal_err & (UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE)) { +			/* we have a MAL error interrupt */ +			mal_isr = mfdcr(malesr); +			mal_err(dev, mal_isr, uic_mal_err, +				 MAL_UIC_DEF, MAL_UIC_ERR); -		/* port by port dispatch of emac interrupts */ -		if (hw_p->devnum == 0) { -			if (UIC_ETH0 & my_uicmsr_ethx) {	/* look for EMAC errors */ -				emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr); -				if ((hw_p->emac_ier & emac_isr) != 0) { -					emac_err (dev, emac_isr); -					serviced = 1; -					rc = 0; -				} -			} -			if ((hw_p->emac_ier & emac_isr) -			    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) { -				mtdcr (UIC0SR, UIC_MRE | UIC_MTE);	/* Clear */ -				mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */ -				mtdcr (UICSR_ETHX, UIC_ETH0); /* Clear */ -				return (rc);	/* we had errors so get out */ -			} -		} +			/* clear MAL error interrupt status bits */ +			mtdcr(UIC_BASE_MAL_ERR + UIC_SR, +			      UIC_MAL_SERR | UIC_MAL_TXDE | UIC_MAL_RXDE); -#if !defined(CONFIG_440SP) -		if (hw_p->devnum == 1) { -			if (UIC_ETH1 & my_uicmsr_ethx) {	/* look for EMAC errors */ -				emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr); -				if ((hw_p->emac_ier & emac_isr) != 0) { -					emac_err (dev, emac_isr); -					serviced = 1; -					rc = 0; -				} -			} -			if ((hw_p->emac_ier & emac_isr) -			    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) { -				mtdcr (UIC0SR, UIC_MRE | UIC_MTE);	/* Clear */ -				mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */ -				mtdcr (UICSR_ETHX, UIC_ETH1); /* Clear */ -				return (rc);	/* we had errors so get out */ -			} -		} -#if defined (CONFIG_440GX) -		if (hw_p->devnum == 2) { -			if (UIC_ETH2 & my_uic2msr) {	/* look for EMAC errors */ -				emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr); -				if ((hw_p->emac_ier & emac_isr) != 0) { -					emac_err (dev, emac_isr); -					serviced = 1; -					rc = 0; -				} -			} -			if ((hw_p->emac_ier & emac_isr) -			    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) { -				mtdcr (UIC0SR, UIC_MRE | UIC_MTE);	/* Clear */ -				mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */ -				mtdcr (uic2sr, UIC_ETH2); -				return (rc);	/* we had errors so get out */ -			} +			return -1;  		} -		if (hw_p->devnum == 3) { -			if (UIC_ETH3 & my_uic2msr) {	/* look for EMAC errors */ -				emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr); -				if ((hw_p->emac_ier & emac_isr) != 0) { -					emac_err (dev, emac_isr); -					serviced = 1; -					rc = 0; -				} -			} -			if ((hw_p->emac_ier & emac_isr) -			    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) { -				mtdcr (UIC0SR, UIC_MRE | UIC_MTE);	/* Clear */ -				mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */ -				mtdcr (uic2sr, UIC_ETH3); -				return (rc);	/* we had errors so get out */ -			} -		} -#endif /* CONFIG_440GX */ -#endif /* !CONFIG_440SP */ +		/* look for EMAC errors */ +		if ((uic_emac & UIC_ETHx) || (uic_emac_b & UIC_ETHxB)) { +			emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr); +			emac_err(dev, emac_isr); -		/* handle MAX TX EOB interrupt from a tx */ -		if (my_uic0msr & UIC_MTE) { -			mal_rx_eob = mfdcr (maltxeobisr); -			mtdcr (maltxeobisr, mal_rx_eob); -			mtdcr (UIC0SR, UIC_MTE); -		} -		/* handle MAL RX EOB  interupt from a receive */ -		/* check for EOB on valid channels	      */ -		if (my_uic0msr & UIC_MRE) { -			mal_rx_eob = mfdcr (malrxeobisr); -			if ((mal_rx_eob & -			     (0x80000000 >> (hw_p->devnum * MAL_RX_CHAN_MUL))) -			    != 0) { /* call emac routine for channel x */ -				/* clear EOB -				   mtdcr(malrxeobisr, mal_rx_eob); */ -				enet_rcv (dev, emac_isr); -				/* indicate that we serviced an interrupt */ -				serviced = 1; -				rc = 0; -			} -		} +			/* clear EMAC error interrupt status bits */ +			mtdcr(UIC_BASE_EMAC + UIC_SR, UIC_ETHx); +			mtdcr(UIC_BASE_EMAC_B + UIC_SR, UIC_ETHxB); -		mtdcr (UIC0SR, UIC_MRE);	/* Clear */ -		mtdcr (UIC1SR, UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */ -		switch (hw_p->devnum) { -		case 0: -			mtdcr (UICSR_ETHX, UIC_ETH0); -			break; -		case 1: -			mtdcr (UICSR_ETHX, UIC_ETH1); -			break; -#if defined (CONFIG_440GX) -		case 2: -			mtdcr (uic2sr, UIC_ETH2); -			break; -		case 3: -			mtdcr (uic2sr, UIC_ETH3); -			break; -#endif /* CONFIG_440GX */ -		default: -			break; +			return -1;  		} -	} while (serviced); - -	return (rc); -} - -#else /* CONFIG_440 */ - -int enetInt (struct eth_device *dev) -{ -	int serviced; -	int rc = -1;		/* default to not us */ -	unsigned long mal_isr; -	unsigned long emac_isr = 0; -	unsigned long mal_rx_eob; -	unsigned long my_uicmsr; - -	EMAC_4XX_HW_PST hw_p; - -	/* -	 * Because the mal is generic, we need to get the current -	 * eth device -	 */ -#if defined(CONFIG_NET_MULTI) -	dev = eth_get_dev(); -#else -	dev = emac0_dev; -#endif -	hw_p = dev->priv; - -	/* enter loop that stays in interrupt code until nothing to service */ -	do { -		serviced = 0; - -		my_uicmsr = mfdcr (uicmsr); +		/* handle MAX TX EOB interrupt from a tx */ +		if (uic_mal & UIC_MAL_TXEOB) { +			/* clear MAL interrupt status bits */ +			mal_eob = mfdcr(maltxeobisr); +			mtdcr(maltxeobisr, mal_eob); +			mtdcr(UIC_BASE_MAL + UIC_SR, UIC_MAL_TXEOB); -		if ((my_uicmsr & (MAL_UIC_DEF | EMAC_UIC_DEF)) == 0) {	/* not for us */ -			return (rc); -		} -		/* get and clear controller status interrupts */ -		/* look at Mal and EMAC interrupts */ -		if ((MAL_UIC_DEF & my_uicmsr) != 0) {	/* we have a MAL interrupt */ -			mal_isr = mfdcr (malesr); -			/* look for mal error */ -			if ((my_uicmsr & MAL_UIC_ERR) != 0) { -				mal_err (dev, mal_isr, my_uicmsr, MAL_UIC_DEF, MAL_UIC_ERR); -				serviced = 1; -				rc = 0; -			} +			/* indicate that we serviced an interrupt */ +			serviced = 1; +			rc = 0;  		} -		/* port by port dispatch of emac interrupts */ +		/* handle MAL RX EOB interupt from a receive */ +		/* check for EOB on valid channels	     */ +		if (uic_mal & UIC_MAL_RXEOB) { +			mal_eob = mfdcr(malrxeobisr); +			if (mal_eob & +			    (0x80000000 >> (hw_p->devnum * MAL_RX_CHAN_MUL))) { +				/* push packet to upper layer */ +				enet_rcv(dev, emac_isr); -		if ((SEL_UIC_DEF(hw_p->devnum) & my_uicmsr) != 0) {	/* look for EMAC errors */ -			emac_isr = in_be32((void *)EMAC_ISR + hw_p->hw_addr); -			if ((hw_p->emac_ier & emac_isr) != 0) { -				emac_err (dev, emac_isr); -				serviced = 1; -				rc = 0; -			} -		} -		if (((hw_p->emac_ier & emac_isr) != 0) || ((MAL_UIC_ERR & my_uicmsr) != 0)) { -			mtdcr (uicsr, MAL_UIC_DEF | SEL_UIC_DEF(hw_p->devnum)); /* Clear */ -			return (rc);		/* we had errors so get out */ -		} +				/* clear MAL interrupt status bits */ +				mtdcr(UIC_BASE_MAL + UIC_SR, UIC_MAL_RXEOB); -		/* handle MAX TX EOB interrupt from a tx */ -		if (my_uicmsr & UIC_MAL_TXEOB) { -			mal_rx_eob = mfdcr (maltxeobisr); -			mtdcr (maltxeobisr, mal_rx_eob); -			mtdcr (uicsr, UIC_MAL_TXEOB); -		} -		/* handle MAL RX EOB  interupt from a receive */ -		/* check for EOB on valid channels	      */ -		if (my_uicmsr & UIC_MAL_RXEOB) -		{ -			mal_rx_eob = mfdcr (malrxeobisr); -			if ((mal_rx_eob & (0x80000000 >> hw_p->devnum)) != 0) { /* call emac routine for channel x */ -				/* clear EOB -				 mtdcr(malrxeobisr, mal_rx_eob); */ -				enet_rcv (dev, emac_isr);  				/* indicate that we serviced an interrupt */  				serviced = 1;  				rc = 0;  			}  		} -		mtdcr (uicsr, MAL_UIC_DEF|EMAC_UIC_DEF|EMAC_UIC_DEF1);	/* Clear */ -#if defined(CONFIG_405EZ) -		mtsdr (sdricintstat, SDR_ICRX_STAT | SDR_ICTX0_STAT | SDR_ICTX1_STAT); -#endif	/* defined(CONFIG_405EZ) */ -	} -	while (serviced); +	} while (serviced);  	return (rc);  } -#endif /* CONFIG_440 */ -  /*-----------------------------------------------------------------------------+   *  MAL Error Routine   *-----------------------------------------------------------------------------*/ @@ -1883,6 +1766,7 @@ int ppc_4xx_eth_initialize (bd_t * bis)  	EMAC_4XX_HW_PST hw = NULL;  	u8 ethaddr[4 + CONFIG_EMAC_NR_START][6];  	u32 hw_addr[4]; +	u32 mal_ier;  #if defined(CONFIG_440GX)  	unsigned long pfc1; @@ -2020,19 +1904,19 @@ int ppc_4xx_eth_initialize (bd_t * bis)  			mtdcr (malier, mal_ier);  			/* install MAL interrupt handler */ -			irq_install_handler (VECNUM_MS, +			irq_install_handler (VECNUM_MAL_SERR,  					     (interrupt_handler_t *) enetInt,  					     dev); -			irq_install_handler (VECNUM_MTE, +			irq_install_handler (VECNUM_MAL_TXEOB,  					     (interrupt_handler_t *) enetInt,  					     dev); -			irq_install_handler (VECNUM_MRE, +			irq_install_handler (VECNUM_MAL_RXEOB,  					     (interrupt_handler_t *) enetInt,  					     dev); -			irq_install_handler (VECNUM_TXDE, +			irq_install_handler (VECNUM_MAL_TXDE,  					     (interrupt_handler_t *) enetInt,  					     dev); -			irq_install_handler (VECNUM_RXDE, +			irq_install_handler (VECNUM_MAL_RXDE,  					     (interrupt_handler_t *) enetInt,  					     dev);  			virgin = 1; diff --git a/cpu/ppc4xx/4xx_uart.c b/cpu/ppc4xx/4xx_uart.c index a7587d435..766e58680 100644 --- a/cpu/ppc4xx/4xx_uart.c +++ b/cpu/ppc4xx/4xx_uart.c @@ -46,7 +46,7 @@  #include <asm/processor.h>  #include <asm/io.h>  #include <watchdog.h> -#include <asm/ppc4xx-intvec.h> +#include <ppc4xx.h>  #ifdef CONFIG_SERIAL_MULTI  #include <serial.h> diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile index 800bb41d0..c773400a5 100644 --- a/cpu/ppc4xx/Makefile +++ b/cpu/ppc4xx/Makefile @@ -35,10 +35,8 @@ SOBJS	+= kgdb.o  COBJS	:= 40x_spd_sdram.o  COBJS	+= 44x_spd_ddr.o  COBJS	+= 44x_spd_ddr2.o -COBJS	+= 4xx_enet.o  COBJS	+= 4xx_pci.o  COBJS	+= 4xx_pcie.o -COBJS	+= 4xx_uart.o  COBJS	+= bedbug_405.o  COBJS	+= commproc.o  COBJS	+= cpu.o @@ -47,11 +45,9 @@ COBJS	+= denali_data_eye.o  COBJS	+= denali_spd_ddr2.o  COBJS	+= ecc.o  COBJS	+= fdt.o -COBJS	+= gpio.o  COBJS	+= i2c.o  COBJS	+= interrupts.o  COBJS	+= iop480_uart.o -COBJS	+= miiphy.o  COBJS	+= ndfc.o  COBJS	+= sdram.o  COBJS	+= speed.o @@ -60,6 +56,15 @@ COBJS	+= traps.o  COBJS	+= usb.o  COBJS	+= usb_ohci.o  COBJS	+= usbdev.o +ifndef CONFIG_XILINX_440 +COBJS	+= 4xx_enet.o +COBJS	+= 4xx_uart.o +COBJS	+= gpio.o +COBJS	+= miiphy.o +COBJS	+= uic.o +else +COBJS	+= xilinx_irq.o +endif  SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)  OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c index 39f439df9..bc9335a05 100644 --- a/cpu/ppc4xx/cpu.c +++ b/cpu/ppc4xx/cpu.c @@ -184,6 +184,19 @@ static char *bootstrap_str[] = {  static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G', 'F', 'H' };  #endif +#if defined(CONFIG_460SX) +#define SDR0_PINSTP_SHIFT	29 +static char *bootstrap_str[] = { +	"EBC (8 bits)", +	"EBC (16 bits)", +	"EBC (32 bits)", +	"NAND (8 bits)", +	"I2C (Addr 0x54)",      /* A8 */ +	"I2C (Addr 0x52)",      /* A4 */ +}; +static char bootstrap_char[] = { 'A', 'B', 'C', 'D', 'E', 'G' }; +#endif +  #if defined(CONFIG_405EZ)  #define SDR0_PINSTP_SHIFT	28  static char *bootstrap_str[] = { @@ -266,7 +279,11 @@ int checkcpu (void)  	get_sys_info(&sys_info); +#if defined(CONFIG_XILINX_440) +	puts("IBM PowerPC 4"); +#else  	puts("AMCC PowerPC 4"); +#endif  #if defined(CONFIG_405GP) || defined(CONFIG_405CR) || \      defined(CONFIG_405EP) || defined(CONFIG_405EZ) || \ @@ -509,6 +526,30 @@ int checkcpu (void)  		strcpy(addstr, "Security/Kasumi support");  		break; +	case PVR_460SX_RA: +		puts("SX Rev. A"); +		strcpy(addstr, "Security support"); +		break; + +	case PVR_460SX_RA_V1: +		puts("SX Rev. A"); +		strcpy(addstr, "No Security support"); +		break; + +	case PVR_460GX_RA: +		puts("GX Rev. A"); +		strcpy(addstr, "Security support"); +		break; + +	case PVR_460GX_RA_V1: +		puts("GX Rev. A"); +		strcpy(addstr, "No Security support"); +		break; + +	case PVR_VIRTEX5: +		puts("x5 VIRTEX5"); +		break; +  	default:  		printf (" UNKNOWN (PVR=%08x)", pvr);  		break; diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c index ac6427905..e2d040278 100644 --- a/cpu/ppc4xx/cpu_init.c +++ b/cpu/ppc4xx/cpu_init.c @@ -138,9 +138,10 @@ void reconfigure_pll(u32 new_cpu_freq)  void  cpu_init_f (void)  { -#if defined(CONFIG_WATCHDOG) || defined(CONFIG_460EX) +#if defined(CONFIG_WATCHDOG) || defined(CONFIG_440GX) || defined(CONFIG_460EX)  	u32 val;  #endif +  	reconfigure_pll(CFG_PLL_RECONFIG);  #if (defined(CONFIG_405EP) || defined (CONFIG_405EX)) && !defined(CFG_4xx_GPIO_TABLE) @@ -273,6 +274,18 @@ cpu_init_f (void)  	reset_4xx_watchdog();  #endif /* CONFIG_WATCHDOG */ +#if defined(CONFIG_440GX) +	/* Take the GX out of compatibility mode +	 * Travis Sawyer, 9 Mar 2004 +	 * NOTE: 440gx user manual inconsistency here +	 *       Compatibility mode and Ethernet Clock select are not +	 *       correct in the manual +	 */ +	mfsdr(sdr_mfr, val); +	val &= ~0x10000000; +	mtsdr(sdr_mfr,val); +#endif /* CONFIG_440GX */ +  #if defined(CONFIG_460EX)  	/*  	 * Set SDR0_AHB_CFG[A2P_INCR4] (bit 24) and diff --git a/cpu/ppc4xx/interrupts.c b/cpu/ppc4xx/interrupts.c index 8620e2b48..494bd8c9e 100644 --- a/cpu/ppc4xx/interrupts.c +++ b/cpu/ppc4xx/interrupts.c @@ -8,6 +8,10 @@   * (C) Copyright 2003 (440GX port)   * Travis B. Sawyer, Sandburst Corporation, tsawyer@sandburst.com   * + * (C) Copyright 2008 (PPC440X05 port for Virtex 5 FX) + * Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es + * Work supported by Qtechnology (htpp://qtec.com) + *   * See file CREDITS for list of people who contributed to this   * project.   * @@ -31,31 +35,14 @@  #include <watchdog.h>  #include <command.h>  #include <asm/processor.h> +#include <asm/interrupt.h>  #include <ppc4xx.h>  #include <ppc_asm.tmpl>  #include <commproc.h> -#include <asm/ppc4xx-intvec.h>  DECLARE_GLOBAL_DATA_PTR;  /* - * Define the number of UIC's - */ -#if defined(CONFIG_440SPE) || \ -    defined(CONFIG_460EX) || defined(CONFIG_460GT) -#define UIC_MAX		4 -#elif defined(CONFIG_440GX) || \ -    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \ -    defined(CONFIG_405EX) -#define UIC_MAX		3 -#elif defined(CONFIG_440GP) || defined(CONFIG_440SP) || \ -    defined(CONFIG_440EP) || defined(CONFIG_440GR) -#define UIC_MAX		2 -#else -#define UIC_MAX		1 -#endif - -/*   * CPM interrupt vector functions.   */  struct	irq_action { @@ -63,15 +50,7 @@ struct	irq_action {  	void *arg;  	int count;  }; - -static struct irq_action irq_vecs[UIC_MAX * 32]; - -u32 get_dcr(u16); -void set_dcr(u16, u32); - -#if (UIC_MAX > 1) && !defined(CONFIG_440GX) -static void uic_cascade_interrupt(void *para); -#endif +static struct irq_action irq_vecs[IRQ_MAX];  #if defined(CONFIG_440) @@ -112,7 +91,7 @@ int interrupt_init_cpu (unsigned *decrementer_count)  	/*  	 * Mark all irqs as free  	 */ -	for (vec = 0; vec < (UIC_MAX * 32); vec++) { +	for (vec = 0; vec < IRQ_MAX; vec++) {  		irq_vecs[vec].handler = NULL;  		irq_vecs[vec].arg = NULL;  		irq_vecs[vec].count = 0; @@ -156,160 +135,38 @@ int interrupt_init_cpu (unsigned *decrementer_count)  	 */  	set_evpr(0x00000000); -#if !defined(CONFIG_440GX) -#if (UIC_MAX > 1) -	/* Install the UIC1 handlers */ -	irq_install_handler(VECNUM_UIC1NC, uic_cascade_interrupt, 0); -	irq_install_handler(VECNUM_UIC1C, uic_cascade_interrupt, 0); -#endif -#if (UIC_MAX > 2) -	irq_install_handler(VECNUM_UIC2NC, uic_cascade_interrupt, 0); -	irq_install_handler(VECNUM_UIC2C, uic_cascade_interrupt, 0); -#endif -#if (UIC_MAX > 3) -	irq_install_handler(VECNUM_UIC3NC, uic_cascade_interrupt, 0); -	irq_install_handler(VECNUM_UIC3C, uic_cascade_interrupt, 0); -#endif -#else /* !defined(CONFIG_440GX) */ -	/* Take the GX out of compatibility mode -	 * Travis Sawyer, 9 Mar 2004 -	 * NOTE: 440gx user manual inconsistency here -	 *       Compatibility mode and Ethernet Clock select are not -	 *       correct in the manual +	/* +	 * Call uic or xilinx_irq pic_enable  	 */ -	mfsdr(sdr_mfr, val); -	val &= ~0x10000000; -	mtsdr(sdr_mfr,val); - -	/* Enable UIC interrupts via UIC Base Enable Register */ -	mtdcr(uicb0sr, UICB0_ALL); -	mtdcr(uicb0er, 0x54000000); -	/* None are critical */ -	mtdcr(uicb0cr, 0); -#endif /* !defined(CONFIG_440GX) */ +	pic_enable();  	return (0);  } -/* Handler for UIC interrupt */ -static void uic_interrupt(u32 uic_base, int vec_base) +void timer_interrupt_cpu(struct pt_regs *regs)  { -	u32 uic_msr; -	u32 msr_shift; -	int vec; - -	/* -	 * Read masked interrupt status register to determine interrupt source -	 */ -	uic_msr = get_dcr(uic_base + UIC_MSR); -	msr_shift = uic_msr; -	vec = vec_base; - -	while (msr_shift != 0) { -		if (msr_shift & 0x80000000) { -			/* -			 * Increment irq counter (for debug purpose only) -			 */ -			irq_vecs[vec].count++; - -			if (irq_vecs[vec].handler != NULL) { -				/* call isr */ -				(*irq_vecs[vec].handler)(irq_vecs[vec].arg); -			} else { -				set_dcr(uic_base + UIC_ER, -					get_dcr(uic_base + UIC_ER) & -					~(0x80000000 >> (vec & 0x1f))); -				printf("Masking bogus interrupt vector %d" -				       " (UIC_BASE=0x%x)\n", vec, uic_base); -			} - -			/* -			 * After servicing the interrupt, we have to remove the -			 * status indicator -			 */ -			set_dcr(uic_base + UIC_SR, (0x80000000 >> (vec & 0x1f))); -		} - -		/* -		 * Shift msr to next position and increment vector -		 */ -		msr_shift <<= 1; -		vec++; -	} +	/* nothing to do here */ +	return;  } -#if (UIC_MAX > 1) && !defined(CONFIG_440GX) -static void uic_cascade_interrupt(void *para) +void interrupt_run_handler(int vec)  { -	external_interrupt(para); -} -#endif - -#if defined(CONFIG_440) -#if defined(CONFIG_440GX) -/* 440GX uses base uic register */ -#define UIC_BMSR	uicb0msr -#define UIC_BSR		uicb0sr -#else -#define UIC_BMSR	uic0msr -#define UIC_BSR		uic0sr -#endif -#else /* CONFIG_440 */ -#define UIC_BMSR	uicmsr -#define UIC_BSR		uicsr -#endif /* CONFIG_440 */ +	irq_vecs[vec].count++; -/* - * Handle external interrupts - */ -void external_interrupt(struct pt_regs *regs) -{ -	u32 uic_msr; - -	/* -	 * Read masked interrupt status register to determine interrupt source -	 */ -	uic_msr = mfdcr(UIC_BMSR); - -#if (UIC_MAX > 1) -	if ((UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr)) -		uic_interrupt(UIC1_DCR_BASE, 32); -#endif - -#if (UIC_MAX > 2) -	if ((UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr)) -		uic_interrupt(UIC2_DCR_BASE, 64); -#endif - -#if (UIC_MAX > 3) -	if ((UICB0_UIC3CI & uic_msr) || (UICB0_UIC3NCI & uic_msr)) -		uic_interrupt(UIC3_DCR_BASE, 96); -#endif - -#if defined(CONFIG_440) -#if !defined(CONFIG_440GX) -	if (uic_msr & ~(UICB0_ALL)) -		uic_interrupt(UIC0_DCR_BASE, 0); -#else -	if ((UICB0_UIC0CI & uic_msr) || (UICB0_UIC0NCI & uic_msr)) -		uic_interrupt(UIC0_DCR_BASE, 0); -#endif -#else /* CONFIG_440 */ -	uic_interrupt(UIC0_DCR_BASE, 0); -#endif /* CONFIG_440 */ - -	mtdcr(UIC_BSR, uic_msr); +	if (irq_vecs[vec].handler != NULL) { +		/* call isr */ +		(*irq_vecs[vec].handler) (irq_vecs[vec].arg); +	} else { +		pic_irq_disable(vec); +		printf("Masking bogus interrupt vector %d\n", vec); +	} +	pic_irq_ack(vec);  	return;  } -/* - * Install and free a interrupt handler. - */  void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg)  { -	int i; -  	/*  	 * Print warning when replacing with a different irq vector  	 */ @@ -320,55 +177,19 @@ void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg)  	irq_vecs[vec].handler = handler;  	irq_vecs[vec].arg = arg; -	i = vec & 0x1f; -	if ((vec >= 0) && (vec < 32)) -		mtdcr(uicer, mfdcr(uicer) | (0x80000000 >> i)); -#if (UIC_MAX > 1) -	else if ((vec >= 32) && (vec < 64)) -		mtdcr(uic1er, mfdcr(uic1er) | (0x80000000 >> i)); -#endif -#if (UIC_MAX > 2) -	else if ((vec >= 64) && (vec < 96)) -		mtdcr(uic2er, mfdcr(uic2er) | (0x80000000 >> i)); -#endif -#if (UIC_MAX > 3) -	else if (vec >= 96) -		mtdcr(uic3er, mfdcr(uic3er) | (0x80000000 >> i)); -#endif - -	debug("Install interrupt for vector %d ==> %p\n", vec, handler); +	pic_irq_enable(vec); +	return;  } -void irq_free_handler (int vec) +void irq_free_handler(int vec)  { -	int i; -  	debug("Free interrupt for vector %d ==> %p\n",  	      vec, irq_vecs[vec].handler); -	i = vec & 0x1f; -	if ((vec >= 0) && (vec < 32)) -		mtdcr(uicer, mfdcr(uicer) & ~(0x80000000 >> i)); -#if (UIC_MAX > 1) -	else if ((vec >= 32) && (vec < 64)) -		mtdcr(uic1er, mfdcr(uic1er) & ~(0x80000000 >> i)); -#endif -#if (UIC_MAX > 2) -	else if ((vec >= 64) && (vec < 96)) -		mtdcr(uic2er, mfdcr(uic2er) & ~(0x80000000 >> i)); -#endif -#if (UIC_MAX > 3) -	else if (vec >= 96) -		mtdcr(uic3er, mfdcr(uic3er) & ~(0x80000000 >> i)); -#endif +	pic_irq_disable(vec);  	irq_vecs[vec].handler = NULL;  	irq_vecs[vec].arg = NULL; -} - -void timer_interrupt_cpu (struct pt_regs *regs) -{ -	/* nothing to do here */  	return;  } @@ -380,7 +201,7 @@ int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  	printf ("Interrupt-Information:\n");  	printf ("Nr  Routine   Arg       Count\n"); -	for (vec = 0; vec < (UIC_MAX * 32); vec++) { +	for (vec = 0; vec < IRQ_MAX; vec++) {  		if (irq_vecs[vec].handler != NULL) {  			printf ("%02d  %08lx  %08lx  %d\n",  				vec, diff --git a/cpu/ppc4xx/iop480_uart.c b/cpu/ppc4xx/iop480_uart.c index 3af0767c5..0e3423f7a 100644 --- a/cpu/ppc4xx/iop480_uart.c +++ b/cpu/ppc4xx/iop480_uart.c @@ -26,7 +26,6 @@  #include <asm/processor.h>  #include <asm/io.h>  #include <watchdog.h> -#include <asm/ppc4xx-intvec.h>  #ifdef CONFIG_SERIAL_MULTI  #include <serial.h> diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c index 34bd7214e..d21bd82dc 100644 --- a/cpu/ppc4xx/speed.c +++ b/cpu/ppc4xx/speed.c @@ -205,7 +205,8 @@ ulong get_PCI_freq (void)  #elif defined(CONFIG_440) -#if defined(CONFIG_460EX) || defined(CONFIG_460GT) +#if defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ +    defined(CONFIG_460SX)  static u8 pll_fwdv_multi_bits[] = {  	/* values for:  1 - 16 */  	0x00, 0x01, 0x0f, 0x04, 0x09, 0x0a, 0x0d, 0x0e, 0x03, 0x0c, @@ -415,7 +416,8 @@ ulong get_PCI_freq (void)  	return sys_info.freqPCI;  } -#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) +#elif !defined(CONFIG_440GX) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) \ +	&& !defined(CONFIG_XILINX_440)  void get_sys_info (sys_info_t * sysInfo)  {  	unsigned long strp0; @@ -448,6 +450,8 @@ void get_sys_info (sys_info_t * sysInfo)  	sysInfo->freqUART = sysInfo->freqPLB;  }  #else + +#if !defined(CONFIG_XILINX_440)  void get_sys_info (sys_info_t * sysInfo)  {  	unsigned long strp0; @@ -534,6 +538,7 @@ void get_sys_info (sys_info_t * sysInfo)  }  #endif +#endif /* CONFIG_XILINX_440 */  #if defined(CONFIG_YUCCA)  unsigned long determine_sysper(void) diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index 426bf3c6f..97411bdb9 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -677,7 +677,8 @@ _start:  	/* not all PPC's have internal SRAM usable as L2-cache */  #if defined(CONFIG_440GX) || \      defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ -    defined(CONFIG_460EX) || defined(CONFIG_460GT) +    defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ +    defined(CONFIG_460SX)  	mtdcr	l2_cache_cfg,r0		/* Ensure L2 Cache is off */  #endif @@ -720,6 +721,19 @@ _start:  	lis	r1,0x4000		/* BAS = 8000_0000 */  	ori	r1,r1,0x4580		/* 16k */  	mtdcr	isram0_sb0cr,r1 +#elif defined(CONFIG_460SX) +	lis     r1,0x0000               /* BAS = 0000_0000 */ +	ori     r1,r1,0x0B84            /* first 128k */ +	mtdcr   isram0_sb0cr,r1 +	lis     r1,0x0001 +	ori     r1,r1,0x0B84            /* second 128k */ +	mtdcr   isram0_sb1cr,r1 +	lis     r1, 0x0002 +	ori     r1,r1, 0x0B84           /* third 128k */ +	mtdcr   isram0_sb2cr,r1 +	lis     r1, 0x0003 +	ori     r1,r1, 0x0B84           /* fourth 128k */ +	mtdcr   isram0_sb3cr,r1  #elif defined(CONFIG_440GP)  	ori	r1,r1,0x0380		/* 8k rw */  	mtdcr	isram0_sb0cr,r1 @@ -1415,7 +1429,8 @@ relocate_code:  #if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \      defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \      defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \ -    defined(CONFIG_460EX) || defined(CONFIG_460GT) +    defined(CONFIG_460EX) || defined(CONFIG_460GT) || \ +    defined(CONFIG_460SX)  	/*  	 * On some 440er platforms the cache is enabled in the first TLB (Boot-CS)  	 * to speed up the boot process. Now this cache needs to be disabled. diff --git a/cpu/ppc4xx/uic.c b/cpu/ppc4xx/uic.c new file mode 100644 index 000000000..7944c6c3c --- /dev/null +++ b/cpu/ppc4xx/uic.c @@ -0,0 +1,180 @@ +/* + * (C) Copyright 2000-2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 (440 port) + * Scott McNutt, Artesyn Communication Producs, smcnutt@artsyncp.com + * + * (C) Copyright 2003 (440GX port) + * Travis B. Sawyer, Sandburst Corporation, tsawyer@sandburst.com + * + * (C) Copyright 2008 (PPC440X05 port for Virtex 5 FX) + * Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es + * Work supported by Qtechnology (htpp://qtec.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 <watchdog.h> +#include <command.h> +#include <asm/processor.h> +#include <asm/interrupt.h> +#include <ppc4xx.h> +#include <ppc_asm.tmpl> +#include <commproc.h> + +#if (UIC_MAX > 3) +#define UICB0_ALL	(UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI) | \ +			 UIC_MASK(VECNUM_UIC2CI) | UIC_MASK(VECNUM_UIC2NCI) | \ +			 UIC_MASK(VECNUM_UIC3CI) | UIC_MASK(VECNUM_UIC3NCI)) +#elif (UIC_MAX > 2) +#define UICB0_ALL	(UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI) | \ +			 UIC_MASK(VECNUM_UIC2CI) | UIC_MASK(VECNUM_UIC2NCI)) +#elif (UIC_MAX > 1) +#define UICB0_ALL	(UIC_MASK(VECNUM_UIC1CI) | UIC_MASK(VECNUM_UIC1NCI)) +#else +#define UICB0_ALL	0 +#endif + +u32 get_dcr(u16); + +DECLARE_GLOBAL_DATA_PTR; + +void pic_enable(void) +{ +#if (UIC_MAX > 1) +	/* Install the UIC1 handlers */ +	irq_install_handler(VECNUM_UIC1NCI, (void *)(void *)external_interrupt, 0); +	irq_install_handler(VECNUM_UIC1CI, (void *)(void *)external_interrupt, 0); +#endif +#if (UIC_MAX > 2) +	irq_install_handler(VECNUM_UIC2NCI, (void *)(void *)external_interrupt, 0); +	irq_install_handler(VECNUM_UIC2CI, (void *)(void *)external_interrupt, 0); +#endif +#if (UIC_MAX > 3) +	irq_install_handler(VECNUM_UIC3NCI, (void *)(void *)external_interrupt, 0); +	irq_install_handler(VECNUM_UIC3CI, (void *)(void *)external_interrupt, 0); +#endif +} + +/* Handler for UIC interrupt */ +static void uic_interrupt(u32 uic_base, int vec_base) +{ +	u32 uic_msr; +	u32 msr_shift; +	int vec; + +	/* +	 * Read masked interrupt status register to determine interrupt source +	 */ +	uic_msr = get_dcr(uic_base + UIC_MSR); +	msr_shift = uic_msr; +	vec = vec_base; + +	while (msr_shift != 0) { +		if (msr_shift & 0x80000000) +			interrupt_run_handler(vec); +		/* +		 * Shift msr to next position and increment vector +		 */ +		msr_shift <<= 1; +		vec++; +	} +} + +/* + * Handle external interrupts + */ +void external_interrupt(struct pt_regs *regs) +{ +	u32 uic_msr; + +	/* +	 * Read masked interrupt status register to determine interrupt source +	 */ +	uic_msr = mfdcr(uic0msr); + +#if (UIC_MAX > 1) +	if ((UIC_MASK(VECNUM_UIC1CI) & uic_msr) || +	    (UIC_MASK(VECNUM_UIC1NCI) & uic_msr)) +		uic_interrupt(UIC1_DCR_BASE, 32); +#endif + +#if (UIC_MAX > 2) +	if ((UIC_MASK(VECNUM_UIC2CI) & uic_msr) || +	    (UIC_MASK(VECNUM_UIC2NCI) & uic_msr)) +		uic_interrupt(UIC2_DCR_BASE, 64); +#endif + +#if (UIC_MAX > 3) +	if ((UIC_MASK(VECNUM_UIC3CI) & uic_msr) || +	    (UIC_MASK(VECNUM_UIC3NCI) & uic_msr)) +		uic_interrupt(UIC3_DCR_BASE, 96); +#endif + +	if (uic_msr & ~(UICB0_ALL)) +		uic_interrupt(UIC0_DCR_BASE, 0); + +	mtdcr(uic0sr, uic_msr); + +	return; +} + +void pic_irq_ack(unsigned int vec) +{ +	if ((vec >= 0) && (vec < 32)) +		mtdcr(uicsr, UIC_MASK(vec)); +	else if ((vec >= 32) && (vec < 64)) +		mtdcr(uic1sr, UIC_MASK(vec)); +	else if ((vec >= 64) && (vec < 96)) +		mtdcr(uic2sr, UIC_MASK(vec)); +	else if (vec >= 96) +		mtdcr(uic3sr, UIC_MASK(vec)); +} + +/* + * Install and free a interrupt handler. + */ +void pic_irq_enable(unsigned int vec) +{ + +	if ((vec >= 0) && (vec < 32)) +		mtdcr(uicer, mfdcr(uicer) | UIC_MASK(vec)); +	else if ((vec >= 32) && (vec < 64)) +		mtdcr(uic1er, mfdcr(uic1er) | UIC_MASK(vec)); +	else if ((vec >= 64) && (vec < 96)) +		mtdcr(uic2er, mfdcr(uic2er) | UIC_MASK(vec)); +	else if (vec >= 96) +		mtdcr(uic3er, mfdcr(uic3er) | UIC_MASK(vec)); + +	debug("Install interrupt for vector %d ==> %p\n", vec, handler); +} + +void pic_irq_disable(unsigned int vec) +{ +	if ((vec >= 0) && (vec < 32)) +		mtdcr(uicer, mfdcr(uicer) & ~UIC_MASK(vec)); +	else if ((vec >= 32) && (vec < 64)) +		mtdcr(uic1er, mfdcr(uic1er) & ~UIC_MASK(vec)); +	else if ((vec >= 64) && (vec < 96)) +		mtdcr(uic2er, mfdcr(uic2er) & ~UIC_MASK(vec)); +	else if (vec >= 96) +		mtdcr(uic3er, mfdcr(uic3er) & ~UIC_MASK(vec)); +} diff --git a/cpu/ppc4xx/usbdev.c b/cpu/ppc4xx/usbdev.c index d71ba7710..faf7f0878 100644 --- a/cpu/ppc4xx/usbdev.c +++ b/cpu/ppc4xx/usbdev.c @@ -6,8 +6,8 @@  #if (defined(CONFIG_440EP) || defined(CONFIG_440EPX)) && defined(CONFIG_CMD_USB)  #include <usb.h> +#include <asm/ppc4xx-uic.h>  #include "usbdev.h" -#include <asm/ppc4xx-intvec.h>  #define USB_DT_DEVICE        0x01  #define USB_DT_CONFIG        0x02 @@ -197,7 +197,7 @@ void usb_dev_init()  	/*enable interrupts */  	*(unsigned char *)USB2D0_INTRUSBE_8 = 0x0f; -	irq_install_handler(VECNUM_HSB2D, (interrupt_handler_t *) usbInt, +	irq_install_handler(VECNUM_USBDEV, (interrupt_handler_t *) usbInt,  			    NULL);  }  #else diff --git a/cpu/ppc4xx/xilinx_irq.c b/cpu/ppc4xx/xilinx_irq.c new file mode 100644 index 000000000..71087771c --- /dev/null +++ b/cpu/ppc4xx/xilinx_irq.c @@ -0,0 +1,100 @@ +/* + * (C) Copyright 2008 + * Ricado Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es + * This work has been supported by: QTechnology  http://qtec.com/ + * Based on interrupts.c Wolfgang Denk-DENX Software Engineering-wd@denx.de + * 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, see <http://www.gnu.org/licenses/>. +*/ +#include <common.h> +#include <watchdog.h> +#include <command.h> +#include <asm/processor.h> +#include <asm/interrupt.h> +#include <ppc4xx.h> +#include <ppc_asm.tmpl> +#include <commproc.h> +#include <asm/io.h> +#include <asm/xilinx_irq.h> + +DECLARE_GLOBAL_DATA_PTR; + +void pic_enable(void) +{ +	debug("Xilinx PIC at 0x%8x\n", intc); + +	/* +	 * Disable all external interrupts until they are +	 * explicitly requested. +	 */ +	out_be32((u32 *) IER, 0); + +	/* Acknowledge any pending interrupts just in case. */ +	out_be32((u32 *) IAR, 0xffffffff); + +	/* Turn on the Master Enable. */ +	out_be32((u32 *) MER, 0x3UL); + +	return; +} + +int xilinx_pic_irq_get(void) +{ +	u32 irq; +	irq = in_be32((u32 *) IVR); + +	/* If no interrupt is pending then all bits of the IVR are set to 1. As +	 * the IVR is as many bits wide as numbers of inputs are available. +	 * Therefore, if all bits of the IVR are set to one, its content will +	 * be bigger than XPAR_INTC_MAX_NUM_INTR_INPUTS. +	 */ +	if (irq >= XPAR_INTC_MAX_NUM_INTR_INPUTS) +		irq = -1;	/* report no pending interrupt. */ + +	debug("get_irq: %d\n", irq); +	return (irq); +} + +void pic_irq_enable(unsigned int irq) +{ +	u32 mask = IRQ_MASK(irq); +	debug("enable: %d\n", irq); +	out_be32((u32 *) SIE, mask); +} + +void pic_irq_disable(unsigned int irq) +{ +	u32 mask = IRQ_MASK(irq); +	debug("disable: %d\n", irq); +	out_be32((u32 *) CIE, mask); +} + +void pic_irq_ack(unsigned int irq) +{ +	u32 mask = IRQ_MASK(irq); +	debug("ack: %d\n", irq); +	out_be32((u32 *) IAR, mask); +} + +void external_interrupt(struct pt_regs *regs) +{ +	int irq; + +	irq = xilinx_pic_irq_get(); +	if (irq < 0) +		return; + +	interrupt_run_handler(irq); + +	return; +} |