diff options
37 files changed, 6866 insertions, 49 deletions
| @@ -2,6 +2,18 @@  Changes for U-Boot 1.0.2:  ====================================================================== +* Patch by Markus Pietrek, 24 Feb 2004: +  NS9750 DevBoard added + +* Patch by Pierre AUBERT, 24 Feb 2004 +  add USB support for MPC5200 + +* Patch by Steven Scholz, 24 Feb 2004: +  - fix MII commands to use values from last command + +* Patch by Torsten Demke, 24 Feb 2004: +  Add support for the eXalion platform (SPSW-8240, F-30, F-300) +  * Patch by Rahul Shanbhag, 19 Feb 2004:    Fixes for for OMAP1610 board:    - shift some IRQ specific code to platform.S file @@ -103,6 +103,11 @@ N: Dave Ellis  E: DGE@sixnetio.com  D: EEPROM Speedup, SXNI855T port +N: Thomas Elste +E: info@elste.org +D: Port for the ModNET50 Board, NET+50 CPU Port +W: http://www.imms.de +  N: Daniel Engström  E: daniel@omicron.se  D: x86 port, Support for sc520_cdp board diff --git a/MAINTAINERS b/MAINTAINERS index f23d9e2f6..b692c19bc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -49,6 +49,10 @@ Kári Davíđsson <kd@flaga.is>  	FLAGADM			MPC823 +Torsten Demke <torsten.demke@fci.com> + +	eXalion			MPC824x +  Wolfgang Denk <wd@denx.de>  	AMX860			MPC860 @@ -289,6 +293,10 @@ Unknown / orphaned boards:  #	Board			CPU					#  ######################################################################### +Thomas Elste <info@elste.org> + +	modnet50		ARM720T (NET+50) +  Peter Figuli <peposh@etc.sk>  	wepep250		xscale @@ -73,9 +73,9 @@ LIST_4xx="	\  LIST_824x="	\  	A3000		BMW		CPC45		CU824		\ -	debris		MOUSSE		MUSENKI		MVBLUE		\ -	OXC		PN62		Sandpoint8240	Sandpoint8245	\ -	SL8245		utx8245						\ +	debris		eXalion		MOUSSE		MUSENKI		\ +	MVBLUE		OXC		PN62		Sandpoint8240	\ +	Sandpoint8245	SL8245		utx8245				\  "  ######################################################################### @@ -671,6 +671,9 @@ CPC45_ROMBOOT_config:	unconfig  CU824_config: unconfig  	@./mkconfig $(@:_config=) ppc mpc824x cu824 +eXalion_config: unconfig +	@./mkconfig $(@:_config=) ppc mpc824x eXalion +  MOUSSE_config: unconfig  	@./mkconfig $(@:_config=) ppc mpc824x mousse diff --git a/board/eXalion/Makefile b/board/eXalion/Makefile new file mode 100644 index 000000000..110d09db7 --- /dev/null +++ b/board/eXalion/Makefile @@ -0,0 +1,41 @@ +# +# (C) Copyright 2001 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# 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 $(TOPDIR)/config.mk + +LIB	= lib$(BOARD).a + +OBJS	= $(BOARD).o +SOBJS	= + +$(LIB):	.depend $(OBJS) $(SOBJS) +	$(AR) crv $@ $^ + +######################################################################### + +.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) +		$(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/board/eXalion/config.mk b/board/eXalion/config.mk new file mode 100644 index 000000000..b3f65ebe5 --- /dev/null +++ b/board/eXalion/config.mk @@ -0,0 +1,31 @@ +# +# (C) Copyright 2000, 2001 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# 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 +# + +# +# Sandpoint boards +# + +#TEXT_BASE = 0x00090000 +TEXT_BASE = 0xFFF00000 + +PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) diff --git a/board/eXalion/eXalion.c b/board/eXalion/eXalion.c new file mode 100644 index 000000000..2e3f51998 --- /dev/null +++ b/board/eXalion/eXalion.c @@ -0,0 +1,292 @@ +/* + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * Torsten Demke, FORCE Computers GmbH. torsten.demke@fci.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 <mpc824x.h> +#include <asm/processor.h> +#include <asm/io.h> +#include <pci.h> +#include <ide.h> +#include "piix_pci.h" +#include "eXalion.h" + +int checkboard (void) +{ +	ulong busfreq = get_bus_freq (0); +	char buf[32]; + +	printf ("Board: eXalion MPC824x - CHRP (MAP B)\n"); +	printf ("Built: %s at %s\n", __DATE__, __TIME__); +	printf ("Local Bus:  %s MHz\n", strmhz (buf, busfreq)); + +	return 0; +} + +int checkflash (void) +{ +	printf ("checkflash\n"); +	flash_init (); +	return (0); +} + +long int initdram (int board_type) +{ +	int i, cnt; +	volatile uchar *base = CFG_SDRAM_BASE; +	volatile ulong *addr; +	ulong save[32]; +	ulong val, ret = 0; + +	for (i = 0, cnt = (CFG_MAX_RAM_SIZE / sizeof (long)) >> 1; cnt > 0; +	     cnt >>= 1) { +		addr = (volatile ulong *) base + cnt; +		save[i++] = *addr; +		*addr = ~cnt; +	} + +	addr = (volatile ulong *) base; +	save[i] = *addr; +	*addr = 0; + +	if (*addr != 0) { +		*addr = save[i]; +		goto Done; +	} + +	for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof (long); cnt <<= 1) { +		addr = (volatile ulong *) base + cnt; +		val = *addr; +		*addr = save[--i]; +		if (val != ~cnt) { +			ulong new_bank0_end = cnt * sizeof (long) - 1; +			ulong mear1 = mpc824x_mpc107_getreg (MEAR1); +			ulong emear1 = mpc824x_mpc107_getreg (EMEAR1); + +			mear1 = (mear1 & 0xFFFFFF00) | +				((new_bank0_end & MICR_ADDR_MASK) >> +				 MICR_ADDR_SHIFT); +			emear1 = (emear1 & 0xFFFFFF00) | +				((new_bank0_end & MICR_ADDR_MASK) >> +				 MICR_EADDR_SHIFT); +			mpc824x_mpc107_setreg (MEAR1, mear1); +			mpc824x_mpc107_setreg (EMEAR1, emear1); + +			ret = cnt * sizeof (long); +			goto Done; +		} +	} + +	ret = CFG_MAX_RAM_SIZE; +      Done: +	return ret; +} + +int misc_init_r (void) +{ +	pci_dev_t bdf; +	u32 val32; +	u8 val8; + +	puts ("ISA:   "); +	bdf = pci_find_device (PIIX4_VENDOR_ID, PIIX4_ISA_DEV_ID, 0); +	if (bdf == -1) { +		puts ("Unable to find PIIX4 ISA bridge !\n"); +		hang (); +	} + +	/* set device for normal ISA instead EIO */ +	pci_read_config_dword (bdf, PCI_CFG_PIIX4_GENCFG, &val32); +	val32 |= 0x00000001; +	pci_write_config_dword (bdf, PCI_CFG_PIIX4_GENCFG, val32); +	printf ("PIIX4 ISA bridge (%d,%d,%d)\n", PCI_BUS (bdf), +		PCI_DEV (bdf), PCI_FUNC (bdf)); + +	puts ("ISA:   "); +	bdf = pci_find_device (PIIX4_VENDOR_ID, PIIX4_IDE_DEV_ID, 0); +	if (bdf == -1) { +		puts ("Unable to find PIIX4 IDE controller !\n"); +		hang (); +	} + +	/* Init BMIBA register  */ +	/* pci_read_config_dword(bdf, PCI_CFG_PIIX4_BMIBA, &val32); */ +	/* val32 |= 0x1000; */ +	/* pci_write_config_dword(bdf, PCI_CFG_PIIX4_BMIBA, val32); */ + +	/* Enable BUS master and IO access  */ +	val32 = PCI_COMMAND_MASTER | PCI_COMMAND_IO; +	pci_write_config_dword (bdf, PCI_COMMAND, val32); + +	/* Set latency  */ +	pci_read_config_byte (bdf, PCI_LATENCY_TIMER, &val8); +	val8 = 0x40; +	pci_write_config_byte (bdf, PCI_LATENCY_TIMER, val8); + +	/* Enable Primary ATA/IDE  */ +	pci_read_config_dword (bdf, PCI_CFG_PIIX4_IDETIM, &val32); +	/* val32 = 0xa307a307; */ +	val32 = 0x00008000; +	pci_write_config_dword (bdf, PCI_CFG_PIIX4_IDETIM, val32); + + +	printf ("PIIX4 IDE controller (%d,%d,%d)\n", PCI_BUS (bdf), +		PCI_DEV (bdf), PCI_FUNC (bdf)); + +	/* Try to get FAT working... */ +	/* fat_register_read(ide_read); */ + + +	return (0); +} + +/* + * Show/Init PCI devices on the specified bus number. + */ + +void pci_eXalion_fixup_irq (struct pci_controller *hose, pci_dev_t dev) +{ +	unsigned char line; + +	switch (PCI_DEV (dev)) { +	case 16: +		line = PCI_INT_A; +		break; +	case 17: +		line = PCI_INT_B; +		break; +	case 18: +		line = PCI_INT_C; +		break; +	case 19: +		line = PCI_INT_D; +		break; +#if defined (CONFIG_MPC8245) +	case 20: +		line = PCI_INT_A; +		break; +	case 21: +		line = PCI_INT_B; +		break; +	case 22: +		line = PCI_INT_NA; +		break; +#endif +	default: +		line = PCI_INT_A; +		break; +	} +	pci_hose_write_config_byte (hose, dev, PCI_INTERRUPT_LINE, line); +} + + +/* + * Initialize PCI Devices, report devices found. + */ +#ifndef CONFIG_PCI_PNP +#if defined (CONFIG_MPC8240) +static struct pci_config_table pci_eXalion_config_table[] = { +	{ +	 /* Intel 82559ER ethernet controller */ +	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 18, 0x00, +	 pci_cfgfunc_config_device, {PCI_ENET0_IOADDR, +				     PCI_ENET0_MEMADDR, +				     PCI_COMMAND_MEMORY | +				     PCI_COMMAND_MASTER}}, +	{ +	 /* Intel 82371AB PIIX4 PCI to ISA bridge */ +	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 20, 0x00, +	 pci_cfgfunc_config_device, {0, +				     0, +				     PCI_COMMAND_IO | PCI_COMMAND_MASTER}}, +	{ +	 /* Intel 82371AB PIIX4 IDE controller */ +	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 20, 0x01, +	 pci_cfgfunc_config_device, {0, +				     0, +				     PCI_COMMAND_IO | PCI_COMMAND_MASTER}}, +	{} +}; +#elif defined (CONFIG_MPC8245) +static struct pci_config_table pci_eXalion_config_table[] = { +	{ +	 /* Intel 82559ER ethernet controller */ +	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 17, 0x00, +	 pci_cfgfunc_config_device, {PCI_ENET0_IOADDR, +				     PCI_ENET0_MEMADDR, +				     PCI_COMMAND_MEMORY | +				     PCI_COMMAND_MASTER}}, +	{ +	 /* Intel 82559ER ethernet controller */ +	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 18, 0x00, +	 pci_cfgfunc_config_device, {PCI_ENET1_IOADDR, +				     PCI_ENET1_MEMADDR, +				     PCI_COMMAND_MEMORY | +				     PCI_COMMAND_MASTER}}, +	{ +	 /* Broadcom BCM5690 Gigabit switch */ +	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 20, 0x00, +	 pci_cfgfunc_config_device, {PCI_ENET2_IOADDR, +				     PCI_ENET2_MEMADDR, +				     PCI_COMMAND_MEMORY | +				     PCI_COMMAND_MASTER}}, +	{ +	 /* Broadcom BCM5690 Gigabit switch */ +	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 21, 0x00, +	 pci_cfgfunc_config_device, {PCI_ENET3_IOADDR, +				     PCI_ENET3_MEMADDR, +				     PCI_COMMAND_MEMORY | +				     PCI_COMMAND_MASTER}}, +	{ +	 /* Intel 82371AB PIIX4 PCI to ISA bridge */ +	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 22, 0x00, +	 pci_cfgfunc_config_device, {0, +				     0, +				     PCI_COMMAND_IO | PCI_COMMAND_MASTER}}, +	{ +	 /* Intel 82371AB PIIX4 IDE controller */ +	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 22, 0x01, +	 pci_cfgfunc_config_device, {0, +				     0, +				     PCI_COMMAND_IO | PCI_COMMAND_MASTER}}, +	{} +}; +#else +#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240) +#endif + +#endif /* #ifndef CONFIG_PCI_PNP */ + +struct pci_controller hose = { +#ifndef CONFIG_PCI_PNP +	config_table:pci_eXalion_config_table, +	fixup_irq:pci_eXalion_fixup_irq, +#endif +}; + +void pci_init_board (void) +{ +	pci_mpc824x_init (&hose); +} diff --git a/board/eXalion/eXalion.h b/board/eXalion/eXalion.h new file mode 100644 index 000000000..8dccabb71 --- /dev/null +++ b/board/eXalion/eXalion.h @@ -0,0 +1,52 @@ +/* + * (C) Copyright 2002 + * Torsten Demke, FORCE Computers GmbH. torsten.demke@fci.com + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * James Dougherty (jfd@broadcom.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 + */ + +#ifndef __EXALION_H +#define __EXALION_H + +/* IRQ settings */ +#define  PCI_INT_NA (0xff)   /* PCI Intr. not used */ +#define  PCI_INT_A  (0x09)   /* PCI Intr. A Interrupt Request Line Nr. */ +#define  PCI_INT_B  (0x0a)   /* PCI Intr. B Interrupt Request Line Nr. */ +#define  PCI_INT_C  (0x0b)   /* PCI Intr. C Interrupt Request Line Nr. */ +#define  PCI_INT_D  (0x0c)   /* PCI Intr. D Interrupt Request Line Nr. */ +#if defined (CPU_MPC8245) +#define  LN_1_INT     PCI_INT_B  /* ethernet interrupt level */ +#define  LN_2_INT     PCI_INT_C  /* ethernet interrupt level */ +#define  BCM_1_INT    PCI_INT_A  /* BCM5690 interrupt level */ +#define  BCM_2_INT    PCI_INT_B  /* BCM5690 interrupt level */ +#elif defined (CPU_MPC8240) +#define  BCM_INT      PCI_INT_B  /* BCM5600 interrupt level */ +#define  LN_INT       PCI_INT_C  /* ethernet interrupt level */ +#endif + +#ifndef __ASSEMBLY__ +#endif /* !__ASSEMBLY__ */ + +#endif /* __EXALION_H */ diff --git a/board/eXalion/piix_pci.h b/board/eXalion/piix_pci.h new file mode 100644 index 000000000..b3c9c16cc --- /dev/null +++ b/board/eXalion/piix_pci.h @@ -0,0 +1,172 @@ +/* + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 + * Torsten Demke, FORCE Computers GmbH. torsten.demke@fci.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 + */ +#ifndef _PIIX4_PCI_H +#define _PIIX4_PCI_H + +#include <common.h> +#include <mpc824x.h> +#include <asm/processor.h> +#include <asm/io.h> +#include <pci.h> + +#define PIIX4_VENDOR_ID         0x8086 +#define PIIX4_ISA_DEV_ID        0x7110 +#define PIIX4_IDE_DEV_ID        0x7111 + +/* Function 0 ISA Bridge */ +#define PCI_CFG_PIIX4_IORT      0x4C    /* 8 bit ISA Recovery Timer Reg (default 0x4D) */ +#define PCI_CFG_PIIX4_XBCS      0x4E    /* 16 bit XBus Chip select reg (default 0x0003) */ +#define PCI_CFG_PIIX4_PIRQC     0x60    /* PCI IRQ Route Register 4 x 8bit (default )*/ +#define PCI_CFG_PIIX4_SERIRQ    0x64 +#define PCI_CFG_PIIX4_TOM       0x69 +#define PCI_CFG_PIIX4_MSTAT     0x6A +#define PCI_CFG_PIIX4_MBDMA     0x76 +#define PCI_CFG_PIIX4_APICBS    0x80 +#define PCI_CFG_PIIX4_DLC       0x82 +#define PCI_CFG_PIIX4_PDMACFG   0x90 +#define PCI_CFG_PIIX4_DDMABS    0x92 +#define PCI_CFG_PIIX4_GENCFG    0xB0 +#define PCI_CFG_PIIX4_RTCCFG    0xCB + +/* IO Addresses */ +#define PIIX4_ISA_DMA1_CH0BA    0x00 +#define PIIX4_ISA_DMA1_CH0CA    0x01 +#define PIIX4_ISA_DMA1_CH1BA    0x02 +#define PIIX4_ISA_DMA1_CH1CA    0x03 +#define PIIX4_ISA_DMA1_CH2BA    0x04 +#define PIIX4_ISA_DMA1_CH2CA    0x05 +#define PIIX4_ISA_DMA1_CH3BA    0x06 +#define PIIX4_ISA_DMA1_CH3CA    0x07 +#define PIIX4_ISA_DMA1_CMDST    0x08 +#define PIIX4_ISA_DMA1_REQ      0x09 +#define PIIX4_ISA_DMA1_WSBM     0x0A +#define PIIX4_ISA_DMA1_CH_MOD   0x0B +#define PIIX4_ISA_DMA1_CLR_PT   0x0C +#define PIIX4_ISA_DMA1_M_CLR    0x0D +#define PIIX4_ISA_DMA1_CLR_M    0x0E +#define PIIX4_ISA_DMA1_RWAMB    0x0F + +#define PIIX4_ISA_DMA2_CH0BA    0xC0 +#define PIIX4_ISA_DMA2_CH0CA    0xC1 +#define PIIX4_ISA_DMA2_CH1BA    0xC2 +#define PIIX4_ISA_DMA2_CH1CA    0xC3 +#define PIIX4_ISA_DMA2_CH2BA    0xC4 +#define PIIX4_ISA_DMA2_CH2CA    0xC5 +#define PIIX4_ISA_DMA2_CH3BA    0xC6 +#define PIIX4_ISA_DMA2_CH3CA    0xC7 +#define PIIX4_ISA_DMA2_CMDST    0xD0 +#define PIIX4_ISA_DMA2_REQ      0xD2 +#define PIIX4_ISA_DMA2_WSBM     0xD4 +#define PIIX4_ISA_DMA2_CH_MOD   0xD6 +#define PIIX4_ISA_DMA2_CLR_PT   0xD8 +#define PIIX4_ISA_DMA2_M_CLR    0xDA +#define PIIX4_ISA_DMA2_CLR_M    0xDC +#define PIIX4_ISA_DMA2_RWAMB    0xDE + +#define PIIX4_ISA_INT1_ICW1     0x20 +#define PIIX4_ISA_INT1_OCW2     0x20 +#define PIIX4_ISA_INT1_OCW3     0x20 +#define PIIX4_ISA_INT1_ICW2     0x21 +#define PIIX4_ISA_INT1_ICW3     0x21 +#define PIIX4_ISA_INT1_ICW4     0x21 +#define PIIX4_ISA_INT1_OCW1     0x21 + +#define PIIX4_ISA_INT1_ELCR     0x4D0 + +#define PIIX4_ISA_INT2_ICW1     0xA0 +#define PIIX4_ISA_INT2_OCW2     0xA0 +#define PIIX4_ISA_INT2_OCW3     0xA0 +#define PIIX4_ISA_INT2_ICW2     0xA1 +#define PIIX4_ISA_INT2_ICW3     0xA1 +#define PIIX4_ISA_INT2_ICW4     0xA1 +#define PIIX4_ISA_INT2_OCW1     0xA1 +#define PIIX4_ISA_INT2_IMR      0xA1 /* read only */ + +#define PIIX4_ISA_INT2_ELCR     0x4D1 + +#define PIIX4_ISA_TMR0_CNT_ST   0x40 +#define PIIX4_ISA_TMR1_CNT_ST   0x41 +#define PIIX4_ISA_TMR2_CNT_ST   0x42 +#define PIIX4_ISA_TMR_TCW       0x43 + +#define PIIX4_ISA_RST_XBUS      0x60 + +#define PIIX4_ISA_NMI_CNT_ST    0x61 +#define PIIX4_ISA_NMI_ENABLE    0x70 + +#define PIIX4_ISA_RTC_INDEX     0x70 +#define PIIX4_ISA_RTC_DATA      0x71 +#define PIIX4_ISA_RTCEXT_IND    0x70 +#define PIIX4_ISA_RTCEXT_DATA   0x71 + +#define PIIX4_ISA_DMA1_CH2LPG   0x81 +#define PIIX4_ISA_DMA1_CH3LPG   0x82 +#define PIIX4_ISA_DMA1_CH1LPG   0x83 +#define PIIX4_ISA_DMA1_CH0LPG   0x87 +#define PIIX4_ISA_DMA2_CH2LPG   0x89 +#define PIIX4_ISA_DMA2_CH3LPG   0x8A +#define PIIX4_ISA_DMA2_CH1LPG   0x8B +#define PIIX4_ISA_DMA2_LPGRFR   0x8F + +#define PIIX4_ISA_PORT_92       0x92 + +#define PIIX4_ISA_APM_CONTRL    0xB2 +#define PIIX4_ISA_APM_STATUS    0xB3 + +#define PIIX4_ISA_COCPU_ERROR   0xF0 + +/* Function 1 IDE Controller */ +#define PCI_CFG_PIIX4_BMIBA     0x20 +#define PCI_CFG_PIIX4_IDETIM    0x40 +#define PCI_CFG_PIIX4_SIDETIM   0x44 +#define PCI_CFG_PIIX4_UDMACTL   0x48 +#define PCI_CFG_PIIX4_UDMATIM   0x4A + +/* Function 2 USB Controller */ +#define PCI_CFG_PIIX4_SBRNUM    0x60 +#define PCI_CFG_PIIX4_LEGSUP    0xC0 + +/* Function 3 Power Management */ +#define PCI_CFG_PIIX4_PMAB      0x40 +#define PCI_CFG_PIIX4_CNTA      0x44 +#define PCI_CFG_PIIX4_CNTB      0x48 +#define PCI_CFG_PIIX4_GPICTL    0x4C +#define PCI_CFG_PIIX4_DEVRESD   0x50 +#define PCI_CFG_PIIX4_DEVACTA   0x54 +#define PCI_CFG_PIIX4_DEVACTB   0x58 +#define PCI_CFG_PIIX4_DEVRESA   0x5C +#define PCI_CFG_PIIX4_DEVRESB   0x60 +#define PCI_CFG_PIIX4_DEVRESC   0x64 +#define PCI_CFG_PIIX4_DEVRESE   0x68 +#define PCI_CFG_PIIX4_DEVRESF   0x6C +#define PCI_CFG_PIIX4_DEVRESG   0x70 +#define PCI_CFG_PIIX4_DEVRESH   0x74 +#define PCI_CFG_PIIX4_DEVRESI   0x78 +#define PCI_CFG_PIIX4_PMMISC    0x80 +#define PCI_CFG_PIIX4_SMBBA     0x90 + + +#endif  /* _PIIX4_PCI_H */ diff --git a/board/eXalion/u-boot.lds b/board/eXalion/u-boot.lds new file mode 100644 index 000000000..98584dcf0 --- /dev/null +++ b/board/eXalion/u-boot.lds @@ -0,0 +1,133 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * 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 + */ + +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? +   __DYNAMIC = 0;    */ +SECTIONS +{ +  /* Read-only sections, merged into text segment: */ +  . = + SIZEOF_HEADERS; +  .interp : { *(.interp) } +  .hash          : { *(.hash)		} +  .dynsym        : { *(.dynsym)		} +  .dynstr        : { *(.dynstr)		} +  .rel.text      : { *(.rel.text)	} +  .rela.text     : { *(.rela.text) 	} +  .rel.data      : { *(.rel.data)	} +  .rela.data     : { *(.rela.data) 	} +  .rel.rodata    : { *(.rel.rodata) 	} +  .rela.rodata   : { *(.rela.rodata) 	} +  .rel.got       : { *(.rel.got)	} +  .rela.got      : { *(.rela.got)	} +  .rel.ctors     : { *(.rel.ctors)	} +  .rela.ctors    : { *(.rela.ctors)	} +  .rel.dtors     : { *(.rel.dtors)	} +  .rela.dtors    : { *(.rela.dtors)	} +  .rel.bss       : { *(.rel.bss)	} +  .rela.bss      : { *(.rela.bss)	} +  .rel.plt       : { *(.rel.plt)	} +  .rela.plt      : { *(.rela.plt)	} +  .init          : { *(.init)		} +  .plt : { *(.plt) } +  .text      : +  { +    cpu/mpc824x/start.o		(.text) +    lib_ppc/board.o		(.text) +    lib_ppc/ppcstring.o		(.text) +    lib_generic/vsprintf.o	(.text) +    lib_generic/crc32.o		(.text) +    lib_generic/zlib.o		(.text) + +	. = DEFINED(env_offset) ? env_offset : .; +    common/environment.o (.text) + +	*(.text) + +    *(.fixup) +    *(.got1) +    . = ALIGN(16); +    *(.rodata) +    *(.rodata1) +    *(.rodata.str1.4) +  } +  .fini      : { *(.fini)    } =0 +  .ctors     : { *(.ctors)   } +  .dtors     : { *(.dtors)   } + +  /* Read-write section, merged into data segment: */ +  . = (. + 0x0FFF) & 0xFFFFF000; +  _erotext = .; +  PROVIDE (erotext = .); +  .reloc   : +  { +    *(.got) +    _GOT2_TABLE_ = .; +    *(.got2) +    _FIXUP_TABLE_ = .; +    *(.fixup) +  } +  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; +  __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + +  .data    : +  { +    *(.data) +    *(.data1) +    *(.sdata) +    *(.sdata2) +    *(.dynamic) +    CONSTRUCTORS +  } +  _edata  =  .; +  PROVIDE (edata = .); + +  __u_boot_cmd_start = .; +  .u_boot_cmd : { *(.u_boot_cmd) } +  __u_boot_cmd_end = .; + + +  __start___ex_table = .; +  __ex_table : { *(__ex_table) } +  __stop___ex_table = .; + +  . = ALIGN(4096); +  __init_begin = .; +  .text.init : { *(.text.init) } +  .data.init : { *(.data.init) } +  . = ALIGN(4096); +  __init_end = .; + +  __bss_start = .; +  .bss       : +  { +   *(.sbss) *(.scommon) +   *(.dynbss) +   *(.bss) +   *(COMMON) +  } + +  _end = . ; +  PROVIDE (end = .); +} diff --git a/board/ns9750dev/Makefile b/board/ns9750dev/Makefile new file mode 100644 index 000000000..d2718cc68 --- /dev/null +++ b/board/ns9750dev/Makefile @@ -0,0 +1,47 @@ +# +# (C) Copyright 2000, 2001, 2002 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# 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 $(TOPDIR)/config.mk + +LIB	= lib$(BOARD).a + +OBJS	:= ns9750dev.o flash.o led.o +SOBJS	:= platform.o + +$(LIB):	$(OBJS) $(SOBJS) +	$(AR) crv $@ $(OBJS) $(SOBJS) + +clean: +	rm -f $(SOBJS) $(OBJS) + +distclean:	clean +	rm -f $(LIB) core *.bak .depend + +######################################################################### + +.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c) +		$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@ + +-include .depend + +######################################################################### diff --git a/board/ns9750dev/config.mk b/board/ns9750dev/config.mk new file mode 100644 index 000000000..6a22cee51 --- /dev/null +++ b/board/ns9750dev/config.mk @@ -0,0 +1,16 @@ +####################################################################### +# +# Copyright (C) 2004 by FS Forth-Systeme GmbH. +# Markus Pietrek <mpietrek@fsforth.de> +# +# @TODO +# Linux-Kernel is expected to be at 0000'8000, entry 0000'8000 +# optionally with a ramdisk at 0080'0000 +# +# we load ourself to 0078'0000 +# +# download area is 0060'0000 +# + + +TEXT_BASE = 0x00780000 diff --git a/board/ns9750dev/flash.c b/board/ns9750dev/flash.c new file mode 100644 index 000000000..e7d65157f --- /dev/null +++ b/board/ns9750dev/flash.c @@ -0,0 +1,477 @@ +/* + * (C) Copyright 2001 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2003 + * Texas Instruments, <www.ti.com> + * Kshitij Gupta <Kshitij@ti.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 <linux/byteorder/swab.h> + +#define PHYS_FLASH_SECT_SIZE	0x00020000	/* 256 KB sectors (x2) */ +flash_info_t flash_info[CFG_MAX_FLASH_BANKS];	/* info for FLASH chips    */ + +/* Board support for 1 or 2 flash devices */ +#undef FLASH_PORT_WIDTH32 +#define FLASH_PORT_WIDTH16 + +#ifdef FLASH_PORT_WIDTH16 +#define FLASH_PORT_WIDTH		ushort +#define FLASH_PORT_WIDTHV		vu_short +#define SWAP(x)			__swab16(x) +#else +#define FLASH_PORT_WIDTH		ulong +#define FLASH_PORT_WIDTHV		vu_long +#define SWAP(x)			__swab32(x) +#endif + +#define FPW	FLASH_PORT_WIDTH +#define FPWV	FLASH_PORT_WIDTHV + +#define mb() __asm__ __volatile__ ("" : : : "memory") + + +/* Flash Organization Structure */ +typedef struct OrgDef { +	unsigned int sector_number; +	unsigned int sector_size; +} OrgDef; + + +/* Flash Organizations */ +OrgDef OrgIntel_28F256L18T[] = { +	{4, 32 * 1024},				/* 4 * 32kBytes sectors */ +	{255, 128 * 1024},			/* 255 * 128kBytes sectors */ +}; + + +/*----------------------------------------------------------------------- + * Functions + */ +unsigned long flash_init (void); +static ulong flash_get_size (FPW * addr, flash_info_t * info); +static int write_data (flash_info_t * info, ulong dest, FPW data); +static void flash_get_offsets (ulong base, flash_info_t * info); +void inline spin_wheel (void); +void flash_print_info (flash_info_t * info); +void flash_unprotect_sectors (FPWV * addr); +int flash_erase (flash_info_t * info, int s_first, int s_last); +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init (void) +{ +	int i; +	ulong size = 0; +	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) { +		switch (i) { +		case 0: +			flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[i]); +			flash_get_offsets (PHYS_FLASH_1, &flash_info[i]); +			break; +		default: +			panic ("configured too many flash banks!\n"); +			break; +		} +		size += flash_info[i].size; +	} + +	/* Protect monitor and environment sectors +	 */ +	flash_protect (FLAG_PROTECT_SET, +			CFG_FLASH_BASE, +			CFG_FLASH_BASE + monitor_flash_len - 1, &flash_info[0]); + +	flash_protect (FLAG_PROTECT_SET, +			CFG_ENV_ADDR, +			CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]); + +	return size; +} + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t * info) +{ +	int i; +	OrgDef *pOrgDef; + +	pOrgDef = OrgIntel_28F256L18T; +	if (info->flash_id == FLASH_UNKNOWN) { +		return; +	} + +	if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) { +		for (i = 0; i < info->sector_count; i++) { +			if (i > 255) { +				info->start[i] = base + (i * 0x8000); +				info->protect[i] = 0; +			} else { +				info->start[i] = base + +						(i * PHYS_FLASH_SECT_SIZE); +				info->protect[i] = 0; +			} +		} +	} +} + +/*----------------------------------------------------------------------- + */ +void flash_print_info (flash_info_t * info) +{ +	int i; + +	if (info->flash_id == FLASH_UNKNOWN) { +		printf ("missing or unknown FLASH type\n"); +		return; +	} + +	switch (info->flash_id & FLASH_VENDMASK) { +	case FLASH_MAN_INTEL: +		printf ("INTEL "); +		break; +	default: +		printf ("Unknown Vendor "); +		break; +	} + +	switch (info->flash_id & FLASH_TYPEMASK) { +	case FLASH_28F256L18T: +		printf ("FLASH 28F256L18T\n"); +		break; +	default: +		printf ("Unknown Chip Type\n"); +		break; +	} + +	printf ("  Size: %ld MB in %d Sectors\n", +			info->size >> 20, info->sector_count); + +	printf ("  Sector Start Addresses:"); +	for (i = 0; i < info->sector_count; ++i) { +		if ((i % 5) == 0) +			printf ("\n   "); +		printf (" %08lX%s", +			info->start[i], info->protect[i] ? " (RO)" : "     "); +	} +	printf ("\n"); +	return; +} + +/* + * The following code cannot be run from FLASH! + */ +static ulong flash_get_size (FPW * addr, flash_info_t * info) +{ +	volatile FPW value; + +	/* Write auto select command: read Manufacturer ID */ +	addr[0x5555] = (FPW) 0x00AA00AA; +	addr[0x2AAA] = (FPW) 0x00550055; +	addr[0x5555] = (FPW) 0x00900090; + +	mb (); +	value = addr[0]; + +	switch (value) { + +	case (FPW) INTEL_MANUFACT: +		info->flash_id = FLASH_MAN_INTEL; +		break; + +	default: +		info->flash_id = FLASH_UNKNOWN; +		info->sector_count = 0; +		info->size = 0; +		addr[0] = (FPW) 0x00FF00FF;	/* restore read mode */ +		return (0);		/* no or unknown flash  */ +	} + +	mb (); +	value = addr[1];	/* device ID        */ +	switch (value) { + +	case (FPW) (INTEL_ID_28F256L18T): +		info->flash_id += FLASH_28F256L18T; +		info->sector_count = 259; +		info->size = 0x02000000; +		break;			/* => 32 MB     */ + +	default: +		info->flash_id = FLASH_UNKNOWN; +		break; +	} + +	if (info->sector_count > CFG_MAX_FLASH_SECT) { +		printf ("** ERROR: sector count %d > max (%d) **\n", +				info->sector_count, CFG_MAX_FLASH_SECT); +		info->sector_count = CFG_MAX_FLASH_SECT; +	} + +	addr[0] = (FPW) 0x00FF00FF;	/* restore read mode */ + +	return (info->size); +} + + +/* unprotects a sector for write and erase + * on some intel parts, this unprotects the entire chip, but it + * wont hurt to call this additional times per sector... + */ +void flash_unprotect_sectors (FPWV * addr) +{ +#define PD_FINTEL_WSMS_READY_MASK    0x0080 + +	*addr = (FPW) 0x00500050;	/* clear status register */ + +	/* this sends the clear lock bit command */ +	*addr = (FPW) 0x00600060; +	*addr = (FPW) 0x00D000D0; +} + + +/*----------------------------------------------------------------------- + */ + +int flash_erase (flash_info_t * info, int s_first, int s_last) +{ +	int flag, prot, sect; +	ulong type, start, last; +	int rcode = 0; + +	if ((s_first < 0) || (s_first > s_last)) { +		if (info->flash_id == FLASH_UNKNOWN) { +			printf ("- missing\n"); +		} else { +			printf ("- no sectors to erase\n"); +		} +		return 1; +	} + +	type = (info->flash_id & FLASH_VENDMASK); +	if ((type != FLASH_MAN_INTEL)) { +		printf ("Can't erase unknown flash type %08lx - aborted\n", +				info->flash_id); +		return 1; +	} + +	prot = 0; +	for (sect = s_first; sect <= s_last; ++sect) { +		if (info->protect[sect]) { +			prot++; +		} +	} + +	if (prot) { +		printf ("- Warning: %d protected sectors will not be erased!\n", +				prot); +	} else { +		printf ("\n"); +	} + + +	start = get_timer (0); +	last = start; + +	/* Disable interrupts which might cause a timeout here */ +	flag = disable_interrupts (); + +	/* Start erase on unprotected sectors */ +	for (sect = s_first; sect <= s_last; sect++) { +		if (info->protect[sect] == 0) {	/* not protected */ +			FPWV *addr = (FPWV *) (info->start[sect]); +			FPW status; + +			printf ("Erasing sector %2d ... ", sect); + +			flash_unprotect_sectors (addr); + +			/* arm simple, non interrupt dependent timer */ +			reset_timer_masked (); + +			*addr = (FPW) 0x00500050;/* clear status register */ +			*addr = (FPW) 0x00200020;/* erase setup */ +			*addr = (FPW) 0x00D000D0;/* erase confirm */ + +			while (((status = +				*addr) & (FPW) 0x00800080) != +				(FPW) 0x00800080) { +					if (get_timer_masked () > +					CFG_FLASH_ERASE_TOUT) { +					printf ("Timeout\n"); +					/* suspend erase     */ +					*addr = (FPW) 0x00B000B0; +					/* reset to read mode */ +					*addr = (FPW) 0x00FF00FF; +					rcode = 1; +					break; +				} +			} + +			/* clear status register cmd.   */ +			*addr = (FPW) 0x00500050; +			*addr = (FPW) 0x00FF00FF;/* resest to read mode */ +			printf (" done\n"); +		} +	} +	return rcode; +} + +/*----------------------------------------------------------------------- + * Copy memory to flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + * 4 - Flash not identified + */ + +int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) +{ +	ulong cp, wp; +	FPW data; +	int count, i, l, rc, port_width; + +	if (info->flash_id == FLASH_UNKNOWN) { +		return 4; +	} +/* get lower word aligned address */ +#ifdef FLASH_PORT_WIDTH16 +	wp = (addr & ~1); +	port_width = 2; +#else +	wp = (addr & ~3); +	port_width = 4; +#endif + +	/* +	 * handle unaligned start bytes +	 */ +	if ((l = addr - wp) != 0) { +		data = 0; +		for (i = 0, cp = wp; i < l; ++i, ++cp) { +			data = (data << 8) | (*(uchar *) cp); +		} +		for (; i < port_width && cnt > 0; ++i) { +			data = (data << 8) | *src++; +			--cnt; +			++cp; +		} +		for (; cnt == 0 && i < port_width; ++i, ++cp) { +			data = (data << 8) | (*(uchar *) cp); +		} + +		if ((rc = write_data (info, wp, SWAP (data))) != 0) { +			return (rc); +		} +		wp += port_width; +	} + +	/* +	 * handle word aligned part +	 */ +	count = 0; +	while (cnt >= port_width) { +		data = 0; +		for (i = 0; i < port_width; ++i) { +			data = (data << 8) | *src++; +		} +		if ((rc = write_data (info, wp, SWAP (data))) != 0) { +			return (rc); +		} +		wp += port_width; +		cnt -= port_width; +		if (count++ > 0x800) { +			spin_wheel (); +			count = 0; +		} +	} + +	if (cnt == 0) { +		return (0); +	} + +	/* +	 * handle unaligned tail bytes +	 */ +	data = 0; +	for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) { +		data = (data << 8) | *src++; +		--cnt; +	} +	for (; i < port_width; ++i, ++cp) { +		data = (data << 8) | (*(uchar *) cp); +	} + +	return (write_data (info, wp, SWAP (data))); +} + +/*----------------------------------------------------------------------- + * Write a word or halfword to Flash, returns: + * 0 - OK + * 1 - write timeout + * 2 - Flash not erased + */ +static int write_data (flash_info_t * info, ulong dest, FPW data) +{ +	FPWV *addr = (FPWV *) dest; +	ulong status; +	int flag; + +	/* Check if Flash is (sufficiently) erased */ +	if ((*addr & data) != data) { +		printf ("not erased at %08lx (%x)\n", (ulong) addr, *addr); +		return (2); +	} +	flash_unprotect_sectors (addr); +	/* Disable interrupts which might cause a timeout here */ +	flag = disable_interrupts (); +	*addr = (FPW) 0x00400040;	/* write setup */ +	*addr = data; + +	/* arm simple, non interrupt dependent timer */ +	reset_timer_masked (); + +	/* wait while polling the status register */ +	while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) { +		if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) { +			*addr = (FPW) 0x00FF00FF;	/* restore read mode */ +			return (1); +		} +	} +	*addr = (FPW) 0x00FF00FF;	/* restore read mode */ +	return (0); +} + +void inline spin_wheel (void) +{ +	static int p = 0; +	static char w[] = "\\/-"; + +	printf ("\010%c", w[p]); +	(++p == 3) ? (p = 0) : 0; +} diff --git a/board/ns9750dev/led.c b/board/ns9750dev/led.c new file mode 100644 index 000000000..ab27f7b58 --- /dev/null +++ b/board/ns9750dev/led.c @@ -0,0 +1,46 @@ +/*********************************************************************** + * + * Copyright (C) 2004 by FS Forth-Systeme GmbH. + * All rights reserved. + * + * $Id: led.c,v 1.1 2004/02/16 10:37:20 mpietrek Exp $ + * @Author: Markus Pietrek + * @Descr: Defines helper functions for toggeling LEDs + * @Usage: + * @References: [1] + * + * 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 + *   + ***********************************************************************/ + +#ifdef CONFIG_STATUS_LED + +#include <ns9750_bbus.h> + +static inline void __led_init( led_id_t mask, int state ) +{ +	XXXX; +} + +static inline void __led_toggle( led_id_t mask ) +{ +} + +static inline void __led_set( led_id_t mask, int state ) +{ +} + +#endif /* CONFIG_STATUS_LED */ diff --git a/board/ns9750dev/ns9750dev.c b/board/ns9750dev/ns9750dev.c new file mode 100644 index 000000000..0ea89a5d8 --- /dev/null +++ b/board/ns9750dev/ns9750dev.c @@ -0,0 +1,127 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch> + * + * (C) Copyright 2003 + * Texas Instruments, <www.ti.com> + * Kshitij Gupta <Kshitij@ti.com> + * + * Copyright (C) 2004 by FS Forth-Systeme GmbH. + * All rights reserved. + * Markus Pietrek <mpietrek@fsforth.de> + * derived from omap1610innovator.c + * @References: [1] NS9750 Hardware Reference/December 2003 + * + * 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> +#if defined(CONFIG_NS9750DEV) +# include <./configs/ns9750dev.h> +# include <./ns9750_bbus.h> +#endif + +void flash__init( void ); +void ether__init( void ); + +static inline void delay( unsigned long loops ) +{ +	__asm__ volatile ("1:\n" +		"subs %0, %1, #1\n" +		"bne 1b":"=r" (loops):"0" (loops)); +} + + +/*********************************************************************** + * @Function: board_init + * @Return: 0 + * @Descr: Enables BBUS modules and other devices + ***********************************************************************/ + +int board_init( void ) +{ +	DECLARE_GLOBAL_DATA_PTR; + +	/* Active BBUS modules */ +	*get_bbus_reg_addr( NS9750_BBUS_MASTER_RESET ) = 0; + +#warning TODO check numbers +	/* arch number of OMAP 1510-Board */ +	/* to be changed for OMAP 1610 Board */ +	gd->bd->bi_arch_number = 234; + +	/* adress of boot parameters */ +	gd->bd->bi_boot_params = 0x10000100; + + +/* this speeds up your boot a quite a bit.  However to make it + *  work, you need make sure your kernel startup flush bug is fixed. + *  ... rkw ... + */ +	icache_enable(); + +	flash__init(); +	ether__init(); +	return 0; +} + + +int misc_init_r (void) +{ +	/* currently empty */ +	return (0); +} + +/****************************** + Routine: + Description: +******************************/ +void flash__init (void) +{ +} +/************************************************************* + Routine:ether__init + Description: take the Ethernet controller out of reset and wait +	  		   for the EEPROM load to complete. +*************************************************************/ +void ether__init (void) +{ +} + +/****************************** + Routine: + Description: +******************************/ +int dram_init (void) +{ +	DECLARE_GLOBAL_DATA_PTR; + +	gd->bd->bi_dram[0].start = PHYS_SDRAM_1; +	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + +#if CONFIG_NR_DRAM_BANKS > 1 +	gd->bd->bi_dram[1].start = PHYS_SDRAM_2; +	gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; +#endif +	return 0; +} diff --git a/board/ns9750dev/platform.S b/board/ns9750dev/platform.S new file mode 100644 index 000000000..11f9aef80 --- /dev/null +++ b/board/ns9750dev/platform.S @@ -0,0 +1,298 @@ +/* + * Board specific setup info + * + * (C) Copyright 2003 + * Texas Instruments, <www.ti.com> + * Kshitij Gupta <Kshitij@ti.com> + * + * Modified for the NS9750 DevBoard by + * (C) Copyright 2004 by FS Forth-Systeme GmbH. + * Markus Pietrek <mpietrek@fsforth.de> + * @References: [1] NS9750 Hardware Reference/December 2003 + *	        [2] ns9750_a.cmd from MAJIC configuration + * + * 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 <config.h> +#include <version.h> + +#if defined(CONFIG_NS9750DEV) +# ifdef CONFIG_INIT_CRITICAL +#  include <./ns9750_sys.h> +#  include <./ns9750_mem.h> +# endif +#endif + +/*********************************************************************** + * @Function: write_register_block + * @Return: nothing + * @Descr: Copies the register block of register_offset:register value to + *         the registers at base r0. The block is assumed to start in RAM at r1 + *         and end at r2. The linked RAM base address of U-Boot is assumed to be + *	   in r5 while the ROM base address we are running from is r6 + *         Uses r3 and r4 as tempory registers + ***********************************************************************/ + +.macro	write_register_block +	@@ map the addresses to high memory +	sub	r1, r1, r5 +	add	r1, r1, r6 +	sub	r2, r2, r5 +	add	r2, r2, r6 + +	@@ copy all +1: +	@@ Write register/value pair starting at [r1] to register base r0 +	ldr	r3, [r1], #4 +	ldr	r4, [r1], #4 +	str	r4, [r0,r3] +	cmp	r1, r2 +	blt	1b +.endm + +_TEXT_BASE: +	.word	TEXT_BASE	@ sdram load addr from config.mk +_PHYS_FLASH: +	.word	PHYS_FLASH_1    @ real flash address (without mirroring) +_CAS_LATENCY: +	.word	0x00022000	@ for CAS2 latency + +#ifdef CONFIG_INIT_CRITICAL +.globl platformsetup +platformsetup: + +	/* U-Boot may be linked to RAM at 0x780000. But this code will run in +	   flash from 0x0. But in order to enable RAM we have to disable the +	   mirror bit, therefore we have to jump to our real flash address +	   beginning at PHYS_FLASH_1 (CS4 Base). Therefore, +	   _run_at_real_flash_address may be 0x500003b0 while be linked to +	   0x7803b0. So we must modify our linked addresses */ + +	@@ branch to high memory address, away from 0x0 +	ldr	r5, _TEXT_BASE +	ldr	r6, _PHYS_FLASH +	ldr	r0, =_run_at_real_flash_address +	sub	r0, r0, r5 +	add	r0, r0, r6 +	mov	pc, r0 +	nop			@ for pipelining + +_run_at_real_flash_address: +	@@ now we are running > PHYS_FLASH_1, safe to enable memory controller + +	@@ Write Memory Configuration Registers + +	ldr	r0, _NS9750_MEM_MODULE_BASE +	ldr	r1, =_MEM_CONFIG_START +	ldr	r2, =_MEM_CONFIG_END + +	write_register_block + +	@@ Give SDRAM some time to settle +	@@ @TODO. According to [2] it should be 2 AHB cycles. Check + +	ldr	r1, =0x50 +_sdram_settle: +	subs	r1, r1, #1 +	bne	_sdram_settle + +_enable_mappings: +	@@ Enable SDRAM Mode + +	ldr	r1, =_MEM_MODE_START +	ldr	r2, =_MEM_MODE_END + +	write_register_block + +	ldr	r3, _CAS_LATENCY @ perform one read from SDRAM +	ldr	r3, [r3] + +	@@ Enable SDRAM and memory mappings + +	ldr	r1, =_MEM_ENABLE_START +	ldr	r2, =_MEM_ENABLE_END + +	write_register_block + +	@@ Activate AHB monitor + +	ldr	r0, =NS9750_SYS_MODULE_BASE +	ldr	r1, =_AHB_MONITOR_START +	ldr	r2, =_AHB_MONITOR_END + +	write_register_block +_relocate_lr: +	/* lr and ip (from cpu_init_crit) are still based on 0x0, relocate it to +	   PHYS_FLASH. */ +	mov	r1, ip +	add	r1, r1, r6 +	mov	ip, r1 + +	mov	r1, lr +	add	r1, r1, r6 +	mov	lr, r1 + +	@@ back to arch calling code +	mov	pc,	lr + +	.ltorg + +_NS9750_MEM_MODULE_BASE: +	.word	NS9750_MEM_MODULE_BASE + +_MEM_CONFIG_START: +	/* Table of 2 32bit entries. First word is register address offset +	   relative to NS9750_MEM_MODULE_BASE, second one is value. They are +	   written in order of appearance */ + +	@@ Register values taken from [2] +	.word	NS9750_MEM_CTRL +	.word	NS9750_MEM_CTRL_E + +	.word	NS9750_MEM_DYN_REFRESH +	.word	(0x6 & NS9750_MEM_DYN_REFRESH_MA) + +	.word	NS9750_MEM_DYN_READ_CFG +	.word	(0x1 & NS9750_MEM_DYN_READ_CFG_MA) + +	.word	NS9750_MEM_DYN_TRP +	.word	(0x1 & NS9750_MEM_DYN_TRP_MA) + +	.word	NS9750_MEM_DYN_TRAS +	.word	(0x4 & NS9750_MEM_DYN_TRAS_MA) + +	.word	NS9750_MEM_DYN_TAPR +	.word	(0x1 & NS9750_MEM_DYN_TRAS_MA) + +	.word	NS9750_MEM_DYN_TDAL +	.word	(0x5 & NS9750_MEM_DYN_TDAL_MA) + +	.word	NS9750_MEM_DYN_TWR +	.word	(0x1 & NS9750_MEM_DYN_TWR_MA) + +	.word	NS9750_MEM_DYN_TRC +	.word	(0x6 & NS9750_MEM_DYN_TRC_MA) + +	.word	NS9750_MEM_DYN_TRFC +	.word	(0x6 & NS9750_MEM_DYN_TRFC_MA) + +	.word	NS9750_MEM_DYN_TRRD +	.word	(0x1 & NS9750_MEM_DYN_TRRD_MA) + +	.word	NS9750_MEM_DYN_TMRD +	.word	(0x1 & NS9750_MEM_DYN_TMRD_MA) + +	@@ CS 4 +	.word	NS9750_MEM_DYN_CFG(0) +	.word	(NS9750_MEM_DYN_CFG_AM | \ +		 (0x280 & NS9750_MEM_DYN_CFG_AM_MA)) + +	.word	NS9750_MEM_DYN_RAS_CAS(0) +	.word	((0x200 & NS9750_MEM_DYN_RAS_CAS_CAS_MA) | \ +		 (0x03 & NS9750_MEM_DYN_RAS_CAS_RAS_MA)) + +	@@ CS 5 +	.word	NS9750_MEM_DYN_CFG(1) +	.word	(NS9750_MEM_DYN_CFG_AM | \ +		 (0x280 & NS9750_MEM_DYN_CFG_AM_MA)) + +	.word	NS9750_MEM_DYN_RAS_CAS(1) +	.word	((0x200 & NS9750_MEM_DYN_RAS_CAS_CAS_MA) | \ +		 (0x03 & NS9750_MEM_DYN_RAS_CAS_RAS_MA)) + +	@@ CS 6 +	.word	NS9750_MEM_DYN_CFG(2) +	.word	(NS9750_MEM_DYN_CFG_AM | \ +		 (0x280 & NS9750_MEM_DYN_CFG_AM_MA)) + +	.word	NS9750_MEM_DYN_RAS_CAS(2) +	.word	((0x200 & NS9750_MEM_DYN_RAS_CAS_CAS_MA) | \ +		 (0x03 & NS9750_MEM_DYN_RAS_CAS_RAS_MA)) + +	@@ CS 7 +	.word	NS9750_MEM_DYN_CFG(3) +	.word	(NS9750_MEM_DYN_CFG_AM | \ +		 (0x280 & NS9750_MEM_DYN_CFG_AM_MA)) + +	.word	NS9750_MEM_DYN_RAS_CAS(3) +	.word	((0x200 & NS9750_MEM_DYN_RAS_CAS_CAS_MA) | \ +		 (0x03 & NS9750_MEM_DYN_RAS_CAS_RAS_MA)) + +	.word	NS9750_MEM_DYN_CTRL +	.word	(NS9750_MEM_DYN_CTRL_I_PALL | \ +		 NS9750_MEM_DYN_CTRL_SR | \ +		 NS9750_MEM_DYN_CTRL_CE ) + +	.word	NS9750_MEM_DYN_REFRESH +	.word	(0x1 & NS9750_MEM_DYN_REFRESH_MA) +	@@ No further register settings after refresh +_MEM_CONFIG_END: + +_MEM_MODE_START: +	.word	NS9750_MEM_DYN_REFRESH +	.word	(0x30 & NS9750_MEM_DYN_REFRESH_MA) + +	.word	NS9750_MEM_DYN_CTRL +	.word	(NS9750_MEM_DYN_CTRL_I_MODE | \ +		 NS9750_MEM_DYN_CTRL_SR | \ +		 NS9750_MEM_DYN_CTRL_CE ) +_MEM_MODE_END: + +_MEM_ENABLE_START: +	.word	NS9750_MEM_DYN_CTRL +	.word	(NS9750_MEM_DYN_CTRL_I_NORMAL | \ +		 NS9750_MEM_DYN_CTRL_SR | \ +		 NS9750_MEM_DYN_CTRL_CE ) + +	@@ CS 4 +	.word	NS9750_MEM_DYN_CFG(0) +	.word	(NS9750_MEM_DYN_CFG_BDMC | \ +		 NS9750_MEM_DYN_CFG_AM | \ +		 (0x280 & NS9750_MEM_DYN_CFG_AM_MA)) + +	@@ CS 5 +	.word	NS9750_MEM_DYN_CFG(1) +	.word	(NS9750_MEM_DYN_CFG_BDMC | \ +		 NS9750_MEM_DYN_CFG_AM | \ +		 (0x280 & NS9750_MEM_DYN_CFG_AM_MA)) + +	@@ CS 6 +	.word	NS9750_MEM_DYN_CFG(2) +	.word	(NS9750_MEM_DYN_CFG_BDMC | \ +		 NS9750_MEM_DYN_CFG_AM | \ +		 (0x280 & NS9750_MEM_DYN_CFG_AM_MA)) + +	@@ CS 7 +	.word	NS9750_MEM_DYN_CFG(3) +	.word	(NS9750_MEM_DYN_CFG_BDMC | \ +		 NS9750_MEM_DYN_CFG_AM | \ +		 (0x280 & NS9750_MEM_DYN_CFG_AM_MA)) +_MEM_ENABLE_END: + +_AHB_MONITOR_START: +	.word	NS9750_SYS_AHB_TIMEOUT +	.word	0x01000100	@ @TODO not calculated yet + +	.word	NS9750_SYS_AHB_MON +	.word	(NS9750_SYS_AHB_MON_BMTC_GEN_IRQ | \ +		 NS9750_SYS_AHB_MON_BATC_GEN_IRQ) +_AHB_MONITOR_END: + +#endif /* CONFIG_INIT_CRITICAL */ diff --git a/board/ns9750dev/u-boot.lds b/board/ns9750dev/u-boot.lds new file mode 100644 index 000000000..8a05892af --- /dev/null +++ b/board/ns9750dev/u-boot.lds @@ -0,0 +1,58 @@ +/* + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * 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 + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/ +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ +	. = 0x00000000; + +	. = ALIGN(4); +	.text      : +	{ +	  cpu/arm926ejs/start.o	(.text) +	  *(.text) +	} + +	. = ALIGN(4); +	.rodata : { *(.rodata) } + +	. = ALIGN(4); +	.data : { *(.data) } + +	. = ALIGN(4); +	.got : { *(.got) } + +  __u_boot_cmd_start = .; +  .u_boot_cmd : { *(.u_boot_cmd) } +  __u_boot_cmd_end = .; + + +	. = ALIGN(4); +	__bss_start = .; +	.bss : { *(.bss) } +	_end = . ; + +} diff --git a/board/omap1610inn/platform.S b/board/omap1610inn/platform.S index 2fa4378b6..441edc28a 100644 --- a/board/omap1610inn/platform.S +++ b/board/omap1610inn/platform.S @@ -41,15 +41,15 @@ _TEXT_BASE:  platformsetup: -	/*------------------------------------------------------*  -	 *mask all IRQs by setting all bits in the INTMR default*  -	*------------------------------------------------------*/ +	/*------------------------------------------------------* +	 *mask all IRQs by setting all bits in the INTMR default* +	 *------------------------------------------------------*/  	mov	r1, #0xffffffff  	ldr	r0, =REG_IHL1_MIR  	str	r1, [r0]  	ldr	r0, =REG_IHL2_MIR  	str	r1, [r0] -	 +  	/*------------------------------------------------------*  	 * Set up ARM CLM registers (IDLECT1)                   *  	 *------------------------------------------------------*/ diff --git a/common/cmd_mii.c b/common/cmd_mii.c index f8ebef6af..abbdaa2be 100644 --- a/common/cmd_mii.c +++ b/common/cmd_mii.c @@ -129,6 +129,7 @@ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  	last_op = op;  	last_addr = addr;  	last_data = data; +	last_reg = reg;  	return rcode;  } diff --git a/common/usb_storage.c b/common/usb_storage.c index d99f25963..dbe9cd9b8 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -19,7 +19,7 @@   *   * 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 + * 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 @@ -53,10 +53,12 @@  #ifdef CONFIG_USB_STORAGE -#undef	USB_STOR_DEBUG +#undef USB_STOR_DEBUG +#undef BBB_COMDAT_TRACE +#undef BBB_XPORT_TRACE  #ifdef	USB_STOR_DEBUG -#define	USB_STOR_PRINTF(fmt,args...)	printf (fmt ,##args) +#define USB_STOR_PRINTF(fmt,args...)	printf (fmt ,##args)  #else  #define USB_STOR_PRINTF(fmt,args...)  #endif @@ -102,7 +104,7 @@ typedef struct {  #	define CBWCDBLENGTH	16  	__u8		CBWCDB[CBWCDBLENGTH];  } umass_bbb_cbw_t; -#define	UMASS_BBB_CBW_SIZE	31 +#define UMASS_BBB_CBW_SIZE	31  static __u32 CBWTag = 0;  /* Command Status Wrapper */ @@ -113,10 +115,10 @@ typedef struct {  	__u32		dCSWDataResidue;  	__u8		bCSWStatus;  #	define CSWSTATUS_GOOD	0x0 -#	define CSWSTATUS_FAILED	0x1 +#	define CSWSTATUS_FAILED 0x1  #	define CSWSTATUS_PHASE	0x2  } umass_bbb_csw_t; -#define	UMASS_BBB_CSW_SIZE	13 +#define UMASS_BBB_CSW_SIZE	13  #define USB_MAX_STOR_DEV 5  static int usb_max_devs; /* number of highest available usb device */ @@ -128,7 +130,7 @@ typedef int (*trans_cmnd)(ccb*, struct us_data*);  typedef int (*trans_reset)(struct us_data*);  struct us_data { -	struct usb_device	*pusb_dev;       /* this usb_device */ +	struct usb_device	*pusb_dev;	 /* this usb_device */  	unsigned int		flags;		 /* from filter initially */  	unsigned char		ifnum;		 /* interface number */  	unsigned char		ep_in;		 /* in endpoint */ @@ -136,14 +138,14 @@ struct us_data {  	unsigned char		ep_int;		 /* interrupt . */  	unsigned char		subclass;	 /* as in overview */  	unsigned char		protocol;	 /* .............. */ -	unsigned char		attention_done;  /* force attn on first cmd */ +	unsigned char		attention_done;	 /* force attn on first cmd */  	unsigned short	ip_data;	 /* interrupt data */  	int							action;		 /* what to do */  	int							ip_wanted; /* needed */  	int							*irq_handle;	 /* for USB int requests */  	unsigned int		irqpipe;	 /* pipe for release_irq */  	unsigned char		irqmaxp;	/* max packed for irq Pipe */ -	unsigned char   irqinterval; /* Intervall for IRQ Pipe */ +	unsigned char	irqinterval; /* Intervall for IRQ Pipe */  	ccb							*srb;		 /* current srb */  	trans_reset			transport_reset; /* reset routine */  	trans_cmnd			transport; /* transport routine */ @@ -152,7 +154,7 @@ struct us_data {  static struct us_data usb_stor[USB_MAX_STOR_DEV]; -#define USB_STOR_TRANSPORT_GOOD    0 +#define USB_STOR_TRANSPORT_GOOD	   0  #define USB_STOR_TRANSPORT_FAILED -1  #define USB_STOR_TRANSPORT_ERROR  -2 @@ -517,45 +519,47 @@ int usb_stor_CB_comdat(ccb *srb, struct us_data *us)  } -int usb_stor_CBI_get_status(ccb *srb, struct us_data *us) +int usb_stor_CBI_get_status (ccb * srb, struct us_data *us)  {  	int timeout; -	us->ip_wanted=1; -	submit_int_msg(us->pusb_dev,us->irqpipe, -			(void *)&us->ip_data,us->irqmaxp ,us->irqinterval); -  timeout=1000; -  while(timeout--) { -  	if((volatile int *)us->ip_wanted==0) +	us->ip_wanted = 1; +	submit_int_msg (us->pusb_dev, us->irqpipe, +			(void *) &us->ip_data, us->irqmaxp, us->irqinterval); +	timeout = 1000; +	while (timeout--) { +		if ((volatile int *) us->ip_wanted == 0)  			break; -		wait_ms(10); +		wait_ms (10);  	}  	if (us->ip_wanted) { -		printf("       Did not get interrupt on CBI\n"); +		printf ("	Did not get interrupt on CBI\n");  		us->ip_wanted = 0;  		return USB_STOR_TRANSPORT_ERROR;  	} -	USB_STOR_PRINTF("Got interrupt data 0x%x, transfered %d status 0x%lX\n", us->ip_data,us->pusb_dev->irq_act_len,us->pusb_dev->irq_status); +	USB_STOR_PRINTF +		("Got interrupt data 0x%x, transfered %d status 0x%lX\n", +		 us->ip_data, us->pusb_dev->irq_act_len, +		 us->pusb_dev->irq_status);  	/* UFI gives us ASC and ASCQ, like a request sense */  	if (us->subclass == US_SC_UFI) {  		if (srb->cmd[0] == SCSI_REQ_SENSE ||  		    srb->cmd[0] == SCSI_INQUIRY)  			return USB_STOR_TRANSPORT_GOOD; /* Good */ +		else if (us->ip_data) +			return USB_STOR_TRANSPORT_FAILED;  		else -			if (us->ip_data) -				return USB_STOR_TRANSPORT_FAILED; -			else -				return USB_STOR_TRANSPORT_GOOD; +			return USB_STOR_TRANSPORT_GOOD;  	}  	/* otherwise, we interpret the data normally */  	switch (us->ip_data) { -		case 0x0001: -			return USB_STOR_TRANSPORT_GOOD; -		case 0x0002: -			return USB_STOR_TRANSPORT_FAILED; -		default: -			return USB_STOR_TRANSPORT_ERROR; -	} /* switch */ +	case 0x0001: +		return USB_STOR_TRANSPORT_GOOD; +	case 0x0002: +		return USB_STOR_TRANSPORT_FAILED; +	default: +		return USB_STOR_TRANSPORT_ERROR; +	}			/* switch */  	return USB_STOR_TRANSPORT_ERROR;  } @@ -601,11 +605,11 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)  	pipein = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);  	pipeout = usb_sndbulkpipe(us->pusb_dev, us->ep_out);  	/* DATA phase + error handling */ -	USB_STOR_PRINTF("DATA phase\n");  	data_actlen = 0;  	/* no data, go immediately to the STATUS phase */  	if (srb->datalen == 0)  		goto st; +	USB_STOR_PRINTF("DATA phase\n");  	if (dir_in)  		pipe = pipein;  	else @@ -732,7 +736,7 @@ do_retry:  	}  	if((us->protocol==US_PR_CBI) &&  			((srb->cmd[0]==SCSI_REQ_SENSE) || -		 	(srb->cmd[0]==SCSI_INQUIRY))) { /* do not issue an autorequest after request sense */ +			(srb->cmd[0]==SCSI_INQUIRY))) { /* do not issue an autorequest after request sense */  		USB_STOR_PRINTF("No auto request and good\n");  		return USB_STOR_TRANSPORT_GOOD;  	} @@ -749,7 +753,7 @@ do_retry:  	USB_STOR_PRINTF("auto request returned %d\n",result);  	/* if this is an CBI Protocol, get IRQ */  	if(us->protocol==US_PR_CBI) { -	 	status=usb_stor_CBI_get_status(psrb,us); +		status=usb_stor_CBI_get_status(psrb,us);  	}  	if((result<0)&&!(us->pusb_dev->status & USB_ST_STALLED)) {  		USB_STOR_PRINTF(" AUTO REQUEST ERROR %d\n",us->pusb_dev->status); @@ -765,7 +769,7 @@ do_retry:  	switch(srb->sense_buf[2]) {  	case 0x01: /* Recovered Error */  		return USB_STOR_TRANSPORT_GOOD; -	 	break; +		break;  	case 0x02: /* Not Ready */  		if(notready++ > USB_TRANSPORT_NOT_READY_RETRY) {  			printf("cmd 0x%02X returned 0x%02X 0x%02X 0x%02X 0x%02X (NOT READY)\n", @@ -817,7 +821,7 @@ static int usb_inquiry(ccb *srb,struct us_data *ss)  static int usb_request_sense(ccb *srb,struct us_data *ss)  {  	char *ptr; -	return 0; +  	ptr=srb->pdata;  	memset(&srb->cmd[0],0,12);  	srb->cmd[0]=SCSI_REQ_SENSE; @@ -845,6 +849,8 @@ static int usb_test_unit_ready(ccb *srb,struct us_data *ss)  		if(ss->transport(srb,ss)==USB_STOR_TRANSPORT_GOOD) {  			return 0;  		} +		usb_request_sense (srb, ss); +		wait_ms (100);  	} while(retries--);  	return -1; @@ -1026,7 +1032,7 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data  		ss->transport_reset = usb_stor_BBB_reset;  		break;  	default: -		printf("USB Starage Transport unknown / not yet implemented\n"); +		printf("USB Storage Transport unknown / not yet implemented\n");  		return 0;  		break;  	} @@ -1069,8 +1075,10 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,struct us_data  	/* set class specific stuff */  	/* We only handle certain protocols.  Currently, these are  	 * the only ones. +	 * The SFF8070 accepts the requests used in u-boot  	 */ -	if (ss->subclass != US_SC_UFI && ss->subclass != US_SC_SCSI) { +	if (ss->subclass != US_SC_UFI && ss->subclass != US_SC_SCSI && +	    ss->subclass != US_SC_8070) {  		printf("Sorry, protocol %d not yet supported.\n",ss->subclass);  		return 0;  	} diff --git a/cpu/mpc5xxx/Makefile b/cpu/mpc5xxx/Makefile index a65bc2232..5b5a33bc7 100644 --- a/cpu/mpc5xxx/Makefile +++ b/cpu/mpc5xxx/Makefile @@ -28,7 +28,7 @@ LIB	= lib$(CPU).a  START	= start.o  ASOBJS	= io.o firmware_sc_task_bestcomm.impl.o firmware_sc_task.impl.o  OBJS	= i2c.o traps.o cpu.o cpu_init.o speed.o interrupts.o serial.o \ -	  loadtask.o fec.o pci_mpc5200.o +	  loadtask.o fec.o pci_mpc5200.o usb_ohci.o  all:	.depend $(START) $(ASOBJS) $(LIB) diff --git a/cpu/mpc5xxx/usb_ohci.c b/cpu/mpc5xxx/usb_ohci.c new file mode 100644 index 000000000..5b5eac208 --- /dev/null +++ b/cpu/mpc5xxx/usb_ohci.c @@ -0,0 +1,1602 @@ +/* + * URB OHCI HCD (Host Controller Driver) for USB on the MPC5200. + * + * (C) Copyright 2003-2004 + * Gary Jennejohn, DENX Software Engineering <gj@denx.de> + * + * (C) Copyright 2004 + * Pierre Aubert, Staubli Faverges <p.aubert@staubli.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 + * + * Note: Part of this code has been derived from linux + * + */ +/* + * IMPORTANT NOTES + * 1 - this driver is intended for use with USB Mass Storage Devices + *     (BBB) ONLY. There is NO support for Interrupt or Isochronous pipes! + */ + +#include <common.h> + +#ifdef CONFIG_USB_OHCI + +#include <malloc.h> +#include <usb.h> +#include "usb_ohci.h" + +#include <mpc5xxx.h> + +#define OHCI_USE_NPS		/* force NoPowerSwitching mode */ +#undef OHCI_VERBOSE_DEBUG	/* not always helpful */ +#undef DEBUG +#undef SHOW_INFO +#undef OHCI_FILL_TRACE + +/* For initializing controller (mask in an HCFS mode too) */ +#define OHCI_CONTROL_INIT \ +	(OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE + +#define readl(a) (*((vu_long *)(a))) +#define writel(a, b) (*((vu_long *)(b)) = ((vu_long)a)) + +#define min_t(type,x,y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) + +#ifdef DEBUG +#define dbg(format, arg...) printf("DEBUG: " format "\n", ## arg) +#else +#define dbg(format, arg...) do {} while(0) +#endif /* DEBUG */ +#define err(format, arg...) printf("ERROR: " format "\n", ## arg) +#ifdef SHOW_INFO +#define info(format, arg...) printf("INFO: " format "\n", ## arg) +#else +#define info(format, arg...) do {} while(0) +#endif + +#define m16_swap(x) swap_16(x) +#define m32_swap(x) swap_32(x) + +#ifdef CONFIG_MPC5200 +#define ohci_cpu_to_le16(x) (x) +#define ohci_cpu_to_le32(x) (x) +#else +#define ohci_cpu_to_le16(x) swap_16(x) +#define ohci_cpu_to_le32(x) swap_32(x) +#endif + +/* global ohci_t */ +static ohci_t gohci; +/* this must be aligned to a 256 byte boundary */ +struct ohci_hcca ghcca[1]; +/* a pointer to the aligned storage */ +struct ohci_hcca *phcca; +/* this allocates EDs for all possible endpoints */ +struct ohci_device ohci_dev; +/* urb_priv */ +urb_priv_t urb_priv; +/* RHSC flag */ +int got_rhsc; +/* device which was disconnected */ +struct usb_device *devgone; + +/*-------------------------------------------------------------------------*/ + +/* AMD-756 (D2 rev) reports corrupt register contents in some cases. + * The erratum (#4) description is incorrect.  AMD's workaround waits + * till some bits (mostly reserved) are clear; ok for all revs. + */ +#define OHCI_QUIRK_AMD756 0xabcd +#define read_roothub(hc, register, mask) ({ \ +	u32 temp = readl (&hc->regs->roothub.register); \ +	if (hc->flags & OHCI_QUIRK_AMD756) \ +		while (temp & mask) \ +			temp = readl (&hc->regs->roothub.register); \ +	temp; }) + +static u32 roothub_a (struct ohci *hc) +	{ return read_roothub (hc, a, 0xfc0fe000); } +static inline u32 roothub_b (struct ohci *hc) +	{ return readl (&hc->regs->roothub.b); } +static inline u32 roothub_status (struct ohci *hc) +	{ return readl (&hc->regs->roothub.status); } +static u32 roothub_portstatus (struct ohci *hc, int i) +	{ return read_roothub (hc, portstatus [i], 0xffe0fce0); } + + +/* forward declaration */ +static int hc_interrupt (void); +static void +td_submit_job (struct usb_device * dev, unsigned long pipe, void * buffer, +	int transfer_len, struct devrequest * setup, urb_priv_t * urb, int interval); + +/*-------------------------------------------------------------------------* + * URB support functions + *-------------------------------------------------------------------------*/ + +/* free HCD-private data associated with this URB */ + +static void urb_free_priv (urb_priv_t * urb) +{ +	int		i; +	int		last; +	struct td	* td; + +	last = urb->length - 1; +	if (last >= 0) { +		for (i = 0; i <= last; i++) { +			td = urb->td[i]; +			if (td) { +				td->usb_dev = NULL; +				urb->td[i] = NULL; +			} +		} +	} +} + +/*-------------------------------------------------------------------------*/ + +#ifdef DEBUG +static int sohci_get_current_frame_number (struct usb_device * dev); + +/* debug| print the main components of an URB + * small: 0) header + data packets 1) just header */ + +static void pkt_print (struct usb_device * dev, unsigned long pipe, void * buffer, +	int transfer_len, struct devrequest * setup, char * str, int small) +{ +	urb_priv_t * purb = &urb_priv; + +	dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,len:%d/%d stat:%#lx", +			str, +			sohci_get_current_frame_number (dev), +			usb_pipedevice (pipe), +			usb_pipeendpoint (pipe), +			usb_pipeout (pipe)? 'O': 'I', +			usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"): +				(usb_pipecontrol (pipe)? "CTRL": "BULK"), +			purb->actual_length, +			transfer_len, dev->status); +#ifdef	OHCI_VERBOSE_DEBUG +	if (!small) { +		int i, len; + +		if (usb_pipecontrol (pipe)) { +			printf (__FILE__ ": cmd(8):"); +			for (i = 0; i < 8 ; i++) +				printf (" %02x", ((__u8 *) setup) [i]); +			printf ("\n"); +		} +		if (transfer_len > 0 && buffer) { +			printf (__FILE__ ": data(%d/%d):", +				purb->actual_length, +				transfer_len); +			len = usb_pipeout (pipe)? +					transfer_len: purb->actual_length; +			for (i = 0; i < 16 && i < len; i++) +				printf (" %02x", ((__u8 *) buffer) [i]); +			printf ("%s\n", i < len? "...": ""); +		} +	} +#endif +} + +/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/ +void ep_print_int_eds (ohci_t *ohci, char * str) { +	int i, j; +	 __u32 * ed_p; +	for (i= 0; i < 32; i++) { +		j = 5; +		ed_p = &(ohci->hcca->int_table [i]); +		if (*ed_p == 0) +		    continue; +		printf (__FILE__ ": %s branch int %2d(%2x):", str, i, i); +		while (*ed_p != 0 && j--) { +			ed_t *ed = (ed_t *)ohci_cpu_to_le32(ed_p); +			printf (" ed: %4x;", ed->hwINFO); +			ed_p = &ed->hwNextED; +		} +		printf ("\n"); +	} +} + +static void ohci_dump_intr_mask (char *label, __u32 mask) +{ +	dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s", +		label, +		mask, +		(mask & OHCI_INTR_MIE) ? " MIE" : "", +		(mask & OHCI_INTR_OC) ? " OC" : "", +		(mask & OHCI_INTR_RHSC) ? " RHSC" : "", +		(mask & OHCI_INTR_FNO) ? " FNO" : "", +		(mask & OHCI_INTR_UE) ? " UE" : "", +		(mask & OHCI_INTR_RD) ? " RD" : "", +		(mask & OHCI_INTR_SF) ? " SF" : "", +		(mask & OHCI_INTR_WDH) ? " WDH" : "", +		(mask & OHCI_INTR_SO) ? " SO" : "" +		); +} + +static void maybe_print_eds (char *label, __u32 value) +{ +	ed_t *edp = (ed_t *)value; + +	if (value) { +		dbg ("%s %08x", label, value); +		dbg ("%08x", edp->hwINFO); +		dbg ("%08x", edp->hwTailP); +		dbg ("%08x", edp->hwHeadP); +		dbg ("%08x", edp->hwNextED); +	} +} + +static char * hcfs2string (int state) +{ +	switch (state) { +		case OHCI_USB_RESET:	return "reset"; +		case OHCI_USB_RESUME:	return "resume"; +		case OHCI_USB_OPER:	return "operational"; +		case OHCI_USB_SUSPEND:	return "suspend"; +	} +	return "?"; +} + +/* dump control and status registers */ +static void ohci_dump_status (ohci_t *controller) +{ +	struct ohci_regs	*regs = controller->regs; +	__u32			temp; + +	temp = readl (®s->revision) & 0xff; +	if (temp != 0x10) +		dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f)); + +	temp = readl (®s->control); +	dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp, +		(temp & OHCI_CTRL_RWE) ? " RWE" : "", +		(temp & OHCI_CTRL_RWC) ? " RWC" : "", +		(temp & OHCI_CTRL_IR) ? " IR" : "", +		hcfs2string (temp & OHCI_CTRL_HCFS), +		(temp & OHCI_CTRL_BLE) ? " BLE" : "", +		(temp & OHCI_CTRL_CLE) ? " CLE" : "", +		(temp & OHCI_CTRL_IE) ? " IE" : "", +		(temp & OHCI_CTRL_PLE) ? " PLE" : "", +		temp & OHCI_CTRL_CBSR +		); + +	temp = readl (®s->cmdstatus); +	dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp, +		(temp & OHCI_SOC) >> 16, +		(temp & OHCI_OCR) ? " OCR" : "", +		(temp & OHCI_BLF) ? " BLF" : "", +		(temp & OHCI_CLF) ? " CLF" : "", +		(temp & OHCI_HCR) ? " HCR" : "" +		); + +	ohci_dump_intr_mask ("intrstatus", readl (®s->intrstatus)); +	ohci_dump_intr_mask ("intrenable", readl (®s->intrenable)); + +	maybe_print_eds ("ed_periodcurrent", readl (®s->ed_periodcurrent)); + +	maybe_print_eds ("ed_controlhead", readl (®s->ed_controlhead)); +	maybe_print_eds ("ed_controlcurrent", readl (®s->ed_controlcurrent)); + +	maybe_print_eds ("ed_bulkhead", readl (®s->ed_bulkhead)); +	maybe_print_eds ("ed_bulkcurrent", readl (®s->ed_bulkcurrent)); + +	maybe_print_eds ("donehead", readl (®s->donehead)); +} + +static void ohci_dump_roothub (ohci_t *controller, int verbose) +{ +	__u32			temp, ndp, i; + +	temp = roothub_a (controller); +	ndp = (temp & RH_A_NDP); + +	if (verbose) { +		dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp, +			((temp & RH_A_POTPGT) >> 24) & 0xff, +			(temp & RH_A_NOCP) ? " NOCP" : "", +			(temp & RH_A_OCPM) ? " OCPM" : "", +			(temp & RH_A_DT) ? " DT" : "", +			(temp & RH_A_NPS) ? " NPS" : "", +			(temp & RH_A_PSM) ? " PSM" : "", +			ndp +			); +		temp = roothub_b (controller); +		dbg ("roothub.b: %08x PPCM=%04x DR=%04x", +			temp, +			(temp & RH_B_PPCM) >> 16, +			(temp & RH_B_DR) +			); +		temp = roothub_status (controller); +		dbg ("roothub.status: %08x%s%s%s%s%s%s", +			temp, +			(temp & RH_HS_CRWE) ? " CRWE" : "", +			(temp & RH_HS_OCIC) ? " OCIC" : "", +			(temp & RH_HS_LPSC) ? " LPSC" : "", +			(temp & RH_HS_DRWE) ? " DRWE" : "", +			(temp & RH_HS_OCI) ? " OCI" : "", +			(temp & RH_HS_LPS) ? " LPS" : "" +			); +	} + +	for (i = 0; i < ndp; i++) { +		temp = roothub_portstatus (controller, i); +		dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s", +			i, +			temp, +			(temp & RH_PS_PRSC) ? " PRSC" : "", +			(temp & RH_PS_OCIC) ? " OCIC" : "", +			(temp & RH_PS_PSSC) ? " PSSC" : "", +			(temp & RH_PS_PESC) ? " PESC" : "", +			(temp & RH_PS_CSC) ? " CSC" : "", + +			(temp & RH_PS_LSDA) ? " LSDA" : "", +			(temp & RH_PS_PPS) ? " PPS" : "", +			(temp & RH_PS_PRS) ? " PRS" : "", +			(temp & RH_PS_POCI) ? " POCI" : "", +			(temp & RH_PS_PSS) ? " PSS" : "", + +			(temp & RH_PS_PES) ? " PES" : "", +			(temp & RH_PS_CCS) ? " CCS" : "" +			); +	} +} + +static void ohci_dump (ohci_t *controller, int verbose) +{ +	dbg ("OHCI controller usb-%s state", controller->slot_name); + +	/* dumps some of the state we know about */ +	ohci_dump_status (controller); +	if (verbose) +		ep_print_int_eds (controller, "hcca"); +	dbg ("hcca frame #%04x", controller->hcca->frame_no); +	ohci_dump_roothub (controller, 1); +} + + +#endif /* DEBUG */ + +/*-------------------------------------------------------------------------* + * Interface functions (URB) + *-------------------------------------------------------------------------*/ + +/* get a transfer request */ + +int sohci_submit_job(struct usb_device *dev, unsigned long pipe, void *buffer, +		int transfer_len, struct devrequest *setup, int interval) +{ +	ohci_t *ohci; +	ed_t * ed; +	urb_priv_t *purb_priv; +	int i, size = 0; + +	ohci = &gohci; + +	/* when controller's hung, permit only roothub cleanup attempts +	 * such as powering down ports */ +	if (ohci->disabled) { +		err("sohci_submit_job: EPIPE"); +		return -1; +	} + +	/* every endpoint has a ed, locate and fill it */ +	if (!(ed = ep_add_ed (dev, pipe))) { +		err("sohci_submit_job: ENOMEM"); +		return -1; +	} + +	/* for the private part of the URB we need the number of TDs (size) */ +	switch (usb_pipetype (pipe)) { +		case PIPE_BULK: /* one TD for every 4096 Byte */ +			size = (transfer_len - 1) / 4096 + 1; +			break; +		case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */ +			size = (transfer_len == 0)? 2: +						(transfer_len - 1) / 4096 + 3; +			break; +	} + +	if (size >= (N_URB_TD - 1)) { +		err("need %d TDs, only have %d", size, N_URB_TD); +		return -1; +	} +	purb_priv = &urb_priv; +	purb_priv->pipe = pipe; + +	/* fill the private part of the URB */ +	purb_priv->length = size; +	purb_priv->ed = ed; +	purb_priv->actual_length = 0; + +	/* allocate the TDs */ +	/* note that td[0] was allocated in ep_add_ed */ +	for (i = 0; i < size; i++) { +		purb_priv->td[i] = td_alloc (dev); +		if (!purb_priv->td[i]) { +			purb_priv->length = i; +			urb_free_priv (purb_priv); +			err("sohci_submit_job: ENOMEM"); +			return -1; +		} +	} + +	if (ed->state == ED_NEW || (ed->state & ED_DEL)) { +		urb_free_priv (purb_priv); +		err("sohci_submit_job: EINVAL"); +		return -1; +	} + +	/* link the ed into a chain if is not already */ +	if (ed->state != ED_OPER) +		ep_link (ohci, ed); + +	/* fill the TDs and link it to the ed */ +	td_submit_job(dev, pipe, buffer, transfer_len, setup, purb_priv, interval); + +	return 0; +} + +/*-------------------------------------------------------------------------*/ + +#ifdef DEBUG +/* tell us the current USB frame number */ + +static int sohci_get_current_frame_number (struct usb_device *usb_dev) +{ +	ohci_t *ohci = &gohci; + +	return ohci_cpu_to_le16 (ohci->hcca->frame_no); +} +#endif + +/*-------------------------------------------------------------------------* + * ED handling functions + *-------------------------------------------------------------------------*/ + +/* link an ed into one of the HC chains */ + +static int ep_link (ohci_t *ohci, ed_t *edi) +{ +	volatile ed_t *ed = edi; + +	ed->state = ED_OPER; + +	switch (ed->type) { +	case PIPE_CONTROL: +		ed->hwNextED = 0; +		if (ohci->ed_controltail == NULL) { +			writel (ed, &ohci->regs->ed_controlhead); +		} else { +			ohci->ed_controltail->hwNextED = ohci_cpu_to_le32 (ed); +		} +		ed->ed_prev = ohci->ed_controltail; +		if (!ohci->ed_controltail && !ohci->ed_rm_list[0] && +			!ohci->ed_rm_list[1] && !ohci->sleeping) { +			ohci->hc_control |= OHCI_CTRL_CLE; +			writel (ohci->hc_control, &ohci->regs->control); +		} +		ohci->ed_controltail = edi; +		break; + +	case PIPE_BULK: +		ed->hwNextED = 0; +		if (ohci->ed_bulktail == NULL) { +			writel (ed, &ohci->regs->ed_bulkhead); +		} else { +			ohci->ed_bulktail->hwNextED = ohci_cpu_to_le32 (ed); +		} +		ed->ed_prev = ohci->ed_bulktail; +		if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] && +			!ohci->ed_rm_list[1] && !ohci->sleeping) { +			ohci->hc_control |= OHCI_CTRL_BLE; +			writel (ohci->hc_control, &ohci->regs->control); +		} +		ohci->ed_bulktail = edi; +		break; +	} +	return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* unlink an ed from one of the HC chains. + * just the link to the ed is unlinked. + * the link from the ed still points to another operational ed or 0 + * so the HC can eventually finish the processing of the unlinked ed */ + +static int ep_unlink (ohci_t *ohci, ed_t *edi) +{ +	volatile ed_t *ed = edi; + +	ed->hwINFO |= ohci_cpu_to_le32 (OHCI_ED_SKIP); + +	switch (ed->type) { +	case PIPE_CONTROL: +		if (ed->ed_prev == NULL) { +			if (!ed->hwNextED) { +				ohci->hc_control &= ~OHCI_CTRL_CLE; +				writel (ohci->hc_control, &ohci->regs->control); +			} +			writel (ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_controlhead); +		} else { +			ed->ed_prev->hwNextED = ed->hwNextED; +		} +		if (ohci->ed_controltail == ed) { +			ohci->ed_controltail = ed->ed_prev; +		} else { +			((ed_t *)ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev; +		} +		break; + +	case PIPE_BULK: +		if (ed->ed_prev == NULL) { +			if (!ed->hwNextED) { +				ohci->hc_control &= ~OHCI_CTRL_BLE; +				writel (ohci->hc_control, &ohci->regs->control); +			} +			writel (ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)), &ohci->regs->ed_bulkhead); +		} else { +			ed->ed_prev->hwNextED = ed->hwNextED; +		} +		if (ohci->ed_bulktail == ed) { +			ohci->ed_bulktail = ed->ed_prev; +		} else { +			((ed_t *)ohci_cpu_to_le32 (*((__u32 *)&ed->hwNextED)))->ed_prev = ed->ed_prev; +		} +		break; +	} +	ed->state = ED_UNLINK; +	return 0; +} + + +/*-------------------------------------------------------------------------*/ + +/* add/reinit an endpoint; this should be done once at the usb_set_configuration command, + * but the USB stack is a little bit stateless	so we do it at every transaction + * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK + * in all other cases the state is left unchanged + * the ed info fields are setted anyway even though most of them should not change */ + +static ed_t * ep_add_ed (struct usb_device *usb_dev, unsigned long pipe) +{ +	td_t *td; +	ed_t *ed_ret; +	volatile ed_t *ed; + +	ed = ed_ret = &ohci_dev.ed[(usb_pipeendpoint (pipe) << 1) | +			(usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))]; + +	if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) { +		err("ep_add_ed: pending delete"); +		/* pending delete request */ +		return NULL; +	} + +	if (ed->state == ED_NEW) { +		ed->hwINFO = ohci_cpu_to_le32 (OHCI_ED_SKIP); /* skip ed */ +		/* dummy td; end of td list for ed */ +		td = td_alloc (usb_dev); +		ed->hwTailP = ohci_cpu_to_le32 (td); +		ed->hwHeadP = ed->hwTailP; +		ed->state = ED_UNLINK; +		ed->type = usb_pipetype (pipe); +		ohci_dev.ed_cnt++; +	} + +	ed->hwINFO = ohci_cpu_to_le32 (usb_pipedevice (pipe) +			| usb_pipeendpoint (pipe) << 7 +			| (usb_pipeisoc (pipe)? 0x8000: 0) +			| (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000)) +			| usb_pipeslow (pipe) << 13 +			| usb_maxpacket (usb_dev, pipe) << 16); + +	return ed_ret; +} + +/*-------------------------------------------------------------------------* + * TD handling functions + *-------------------------------------------------------------------------*/ + +/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */ + +static void td_fill (ohci_t *ohci, unsigned int info, +	void *data, int len, +	struct usb_device *dev, int index, urb_priv_t *urb_priv) +{ +	volatile td_t  *td, *td_pt; +#ifdef OHCI_FILL_TRACE +	int i; +#endif + +	if (index > urb_priv->length) { +		err("index > length"); +		return; +	} +	/* use this td as the next dummy */ +	td_pt = urb_priv->td [index]; +	td_pt->hwNextTD = 0; + +	/* fill the old dummy TD */ +	td = urb_priv->td [index] = (td_t *)(ohci_cpu_to_le32 (urb_priv->ed->hwTailP) & ~0xf); + +	td->ed = urb_priv->ed; +	td->next_dl_td = NULL; +	td->index = index; +	td->data = (__u32)data; +#ifdef OHCI_FILL_TRACE +	if ((usb_pipetype(urb_priv->pipe) == PIPE_BULK) && usb_pipeout(urb_priv->pipe)) { +		for (i = 0; i < len; i++) +		printf("td->data[%d] %#2x ",i, ((unsigned char *)td->data)[i]); +		printf("\n"); +	} +#endif +	if (!len) +		data = 0; + +	td->hwINFO = ohci_cpu_to_le32 (info); +	td->hwCBP = ohci_cpu_to_le32 (data); +	if (data) +		td->hwBE = ohci_cpu_to_le32 (data + len - 1); +	else +		td->hwBE = 0; +	td->hwNextTD = ohci_cpu_to_le32 (td_pt); +	td->hwPSW [0] = ohci_cpu_to_le16 (((__u32)data & 0x0FFF) | 0xE000); + +	/* append to queue */ +	td->ed->hwTailP = td->hwNextTD; +} + +/*-------------------------------------------------------------------------*/ + +/* prepare all TDs of a transfer */ + +static void td_submit_job (struct usb_device *dev, unsigned long pipe, void *buffer, +	int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval) +{ +	ohci_t *ohci = &gohci; +	int data_len = transfer_len; +	void *data; +	int cnt = 0; +	__u32 info = 0; +	unsigned int toggle = 0; + +	/* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */ +	if(usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) { +		toggle = TD_T_TOGGLE; +	} else { +		toggle = TD_T_DATA0; +		usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 1); +	} +	urb->td_cnt = 0; +	if (data_len) +		data = buffer; +	else +		data = 0; + +	switch (usb_pipetype (pipe)) { +	case PIPE_BULK: +		info = usb_pipeout (pipe)? +			TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ; +		while(data_len > 4096) { +			td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, dev, cnt, urb); +			data += 4096; data_len -= 4096; cnt++; +		} +		info = usb_pipeout (pipe)? +			TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ; +		td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, dev, cnt, urb); +		cnt++; + +		if (!ohci->sleeping) +			writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */ +		break; + +	case PIPE_CONTROL: +		info = TD_CC | TD_DP_SETUP | TD_T_DATA0; +		td_fill (ohci, info, setup, 8, dev, cnt++, urb); +		if (data_len > 0) { +			info = usb_pipeout (pipe)? +				TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1; +			/* NOTE:  mishandles transfers >8K, some >4K */ +			td_fill (ohci, info, data, data_len, dev, cnt++, urb); +		} +		info = usb_pipeout (pipe)? +			TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1; +		td_fill (ohci, info, data, 0, dev, cnt++, urb); +		if (!ohci->sleeping) +			writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */ +		break; +	} +	if (urb->length != cnt) +		dbg("TD LENGTH %d != CNT %d", urb->length, cnt); +} + +/*-------------------------------------------------------------------------* + * Done List handling functions + *-------------------------------------------------------------------------*/ + + +/* calculate the transfer length and update the urb */ + +static void dl_transfer_length(td_t * td) +{ +	__u32 tdINFO, tdBE, tdCBP; +	urb_priv_t *lurb_priv = &urb_priv; + +	tdINFO = ohci_cpu_to_le32 (td->hwINFO); +	tdBE   = ohci_cpu_to_le32 (td->hwBE); +	tdCBP  = ohci_cpu_to_le32 (td->hwCBP); + + +	if (!(usb_pipetype (lurb_priv->pipe) == PIPE_CONTROL && +	    ((td->index == 0) || (td->index == lurb_priv->length - 1)))) { +		if (tdBE != 0) { +			if (td->hwCBP == 0) +				lurb_priv->actual_length += tdBE - td->data + 1; +			else +				lurb_priv->actual_length += tdCBP - td->data; +		} +	} +} + +/*-------------------------------------------------------------------------*/ + +/* replies to the request have to be on a FIFO basis so + * we reverse the reversed done-list */ + +static td_t * dl_reverse_done_list (ohci_t *ohci) +{ +	__u32 td_list_hc; +	td_t *td_rev = NULL; +	td_t *td_list = NULL; +	urb_priv_t *lurb_priv = NULL; + +	td_list_hc = ohci_cpu_to_le32 (ohci->hcca->done_head) & 0xfffffff0; +	ohci->hcca->done_head = 0; + +	while (td_list_hc) { +		td_list = (td_t *)td_list_hc; + +		if (TD_CC_GET (ohci_cpu_to_le32 (td_list->hwINFO))) { +			lurb_priv = &urb_priv; +			dbg(" USB-error/status: %x : %p", +					TD_CC_GET (ohci_cpu_to_le32 (td_list->hwINFO)), td_list); +			if (td_list->ed->hwHeadP & ohci_cpu_to_le32 (0x1)) { +				if (lurb_priv && ((td_list->index + 1) < lurb_priv->length)) { +					td_list->ed->hwHeadP = +						(lurb_priv->td[lurb_priv->length - 1]->hwNextTD & ohci_cpu_to_le32 (0xfffffff0)) | +									(td_list->ed->hwHeadP & ohci_cpu_to_le32 (0x2)); +					lurb_priv->td_cnt += lurb_priv->length - td_list->index - 1; +				} else +					td_list->ed->hwHeadP &= ohci_cpu_to_le32 (0xfffffff2); +			} +#ifdef CONFIG_MPC5200 +			td_list->hwNextTD = 0; +#endif +		} + +		td_list->next_dl_td = td_rev; +		td_rev = td_list; +		td_list_hc = ohci_cpu_to_le32 (td_list->hwNextTD) & 0xfffffff0; +	} +	return td_list; +} + +/*-------------------------------------------------------------------------*/ + +/* td done list */ +static int dl_done_list (ohci_t *ohci, td_t *td_list) +{ +	td_t *td_list_next = NULL; +	ed_t *ed; +	int cc = 0; +	int stat = 0xff; +	/* urb_t *urb; */ +	urb_priv_t *lurb_priv; +	__u32 tdINFO, edHeadP, edTailP; + +	while (td_list) { +		td_list_next = td_list->next_dl_td; + +		lurb_priv = &urb_priv; +		tdINFO = ohci_cpu_to_le32 (td_list->hwINFO); + +		ed = td_list->ed; + +		dl_transfer_length(td_list); + +		/* error code of transfer */ +		cc = TD_CC_GET (tdINFO); +		if (++(lurb_priv->td_cnt) == lurb_priv->length) { +			if ((ed->state & (ED_OPER | ED_UNLINK)) +					&& (lurb_priv->state != URB_DEL)) { +				dbg("ConditionCode %#x", cc); +				stat = cc_to_error[cc]; +			} +		} + +		if (ed->state != ED_NEW) { +			edHeadP = ohci_cpu_to_le32 (ed->hwHeadP) & 0xfffffff0; +			edTailP = ohci_cpu_to_le32 (ed->hwTailP); + +			/* unlink eds if they are not busy */ +			if ((edHeadP == edTailP) && (ed->state == ED_OPER)) +				ep_unlink (ohci, ed); +		} + +		td_list = td_list_next; +	} +	return stat; +} + +/*-------------------------------------------------------------------------* + * Virtual Root Hub + *-------------------------------------------------------------------------*/ + +/* Device descriptor */ +static __u8 root_hub_dev_des[] = +{ +	0x12,	    /*	__u8  bLength; */ +	0x01,	    /*	__u8  bDescriptorType; Device */ +	0x10,	    /*	__u16 bcdUSB; v1.1 */ +	0x01, +	0x09,	    /*	__u8  bDeviceClass; HUB_CLASSCODE */ +	0x00,	    /*	__u8  bDeviceSubClass; */ +	0x00,	    /*	__u8  bDeviceProtocol; */ +	0x08,	    /*	__u8  bMaxPacketSize0; 8 Bytes */ +	0x00,	    /*	__u16 idVendor; */ +	0x00, +	0x00,	    /*	__u16 idProduct; */ +	0x00, +	0x00,	    /*	__u16 bcdDevice; */ +	0x00, +	0x00,	    /*	__u8  iManufacturer; */ +	0x01,	    /*	__u8  iProduct; */ +	0x00,	    /*	__u8  iSerialNumber; */ +	0x01	    /*	__u8  bNumConfigurations; */ +}; + + +/* Configuration descriptor */ +static __u8 root_hub_config_des[] = +{ +	0x09,	    /*	__u8  bLength; */ +	0x02,	    /*	__u8  bDescriptorType; Configuration */ +	0x19,	    /*	__u16 wTotalLength; */ +	0x00, +	0x01,	    /*	__u8  bNumInterfaces; */ +	0x01,	    /*	__u8  bConfigurationValue; */ +	0x00,	    /*	__u8  iConfiguration; */ +	0x40,	    /*	__u8  bmAttributes; +		 Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */ +	0x00,	    /*	__u8  MaxPower; */ + +	/* interface */ +	0x09,	    /*	__u8  if_bLength; */ +	0x04,	    /*	__u8  if_bDescriptorType; Interface */ +	0x00,	    /*	__u8  if_bInterfaceNumber; */ +	0x00,	    /*	__u8  if_bAlternateSetting; */ +	0x01,	    /*	__u8  if_bNumEndpoints; */ +	0x09,	    /*	__u8  if_bInterfaceClass; HUB_CLASSCODE */ +	0x00,	    /*	__u8  if_bInterfaceSubClass; */ +	0x00,	    /*	__u8  if_bInterfaceProtocol; */ +	0x00,	    /*	__u8  if_iInterface; */ + +	/* endpoint */ +	0x07,	    /*	__u8  ep_bLength; */ +	0x05,	    /*	__u8  ep_bDescriptorType; Endpoint */ +	0x81,	    /*	__u8  ep_bEndpointAddress; IN Endpoint 1 */ +	0x03,	    /*	__u8  ep_bmAttributes; Interrupt */ +	0x02,	    /*	__u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */ +	0x00, +	0xff	    /*	__u8  ep_bInterval; 255 ms */ +}; + +static unsigned char root_hub_str_index0[] = +{ +	0x04,			/*  __u8  bLength; */ +	0x03,			/*  __u8  bDescriptorType; String-descriptor */ +	0x09,			/*  __u8  lang ID */ +	0x04,			/*  __u8  lang ID */ +}; + +static unsigned char root_hub_str_index1[] = +{ +	28,			/*  __u8  bLength; */ +	0x03,			/*  __u8  bDescriptorType; String-descriptor */ +	'O',			/*  __u8  Unicode */ +	0,				/*  __u8  Unicode */ +	'H',			/*  __u8  Unicode */ +	0,				/*  __u8  Unicode */ +	'C',			/*  __u8  Unicode */ +	0,				/*  __u8  Unicode */ +	'I',			/*  __u8  Unicode */ +	0,				/*  __u8  Unicode */ +	' ',			/*  __u8  Unicode */ +	0,				/*  __u8  Unicode */ +	'R',			/*  __u8  Unicode */ +	0,				/*  __u8  Unicode */ +	'o',			/*  __u8  Unicode */ +	0,				/*  __u8  Unicode */ +	'o',			/*  __u8  Unicode */ +	0,				/*  __u8  Unicode */ +	't',			/*  __u8  Unicode */ +	0,				/*  __u8  Unicode */ +	' ',			/*  __u8  Unicode */ +	0,				/*  __u8  Unicode */ +	'H',			/*  __u8  Unicode */ +	0,				/*  __u8  Unicode */ +	'u',			/*  __u8  Unicode */ +	0,				/*  __u8  Unicode */ +	'b',			/*  __u8  Unicode */ +	0,				/*  __u8  Unicode */ +}; + +/* Hub class-specific descriptor is constructed dynamically */ + + +/*-------------------------------------------------------------------------*/ + +#define OK(x)			len = (x); break +#ifdef DEBUG +#define WR_RH_STAT(x)		{info("WR:status %#8x", (x));writel((x), &gohci.regs->roothub.status);} +#define WR_RH_PORTSTAT(x)	{info("WR:portstatus[%d] %#8x", wIndex-1, (x));writel((x), &gohci.regs->roothub.portstatus[wIndex-1]);} +#else +#define WR_RH_STAT(x)		writel((x), &gohci.regs->roothub.status) +#define WR_RH_PORTSTAT(x)	writel((x), &gohci.regs->roothub.portstatus[wIndex-1]) +#endif +#define RD_RH_STAT		roothub_status(&gohci) +#define RD_RH_PORTSTAT		roothub_portstatus(&gohci,wIndex-1) + +/* request to virtual root hub */ + +int rh_check_port_status(ohci_t *controller) +{ +	__u32 temp, ndp, i; +	int res; + +	res = -1; +	temp = roothub_a (controller); +	ndp = (temp & RH_A_NDP); +	for (i = 0; i < ndp; i++) { +		temp = roothub_portstatus (controller, i); +		/* check for a device disconnect */ +		if (((temp & (RH_PS_PESC | RH_PS_CSC)) == +			(RH_PS_PESC | RH_PS_CSC)) && +			((temp & RH_PS_CCS) == 0)) { +			res = i; +			break; +		} +	} +	return res; +} + +static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, +		void *buffer, int transfer_len, struct devrequest *cmd) +{ +	void * data = buffer; +	int leni = transfer_len; +	int len = 0; +	int stat = 0; +	__u32 datab[4]; +	__u8 *data_buf = (__u8 *)datab; +	__u16 bmRType_bReq; +	__u16 wValue; +	__u16 wIndex; +	__u16 wLength; + +#ifdef DEBUG +urb_priv.actual_length = 0; +pkt_print(dev, pipe, buffer, transfer_len, cmd, "SUB(rh)", usb_pipein(pipe)); +#endif +	if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) { +		info("Root-Hub submit IRQ: NOT implemented"); +		return 0; +	} + +	bmRType_bReq  = cmd->requesttype | (cmd->request << 8); +	wValue	      = m16_swap (cmd->value); +	wIndex	      = m16_swap (cmd->index); +	wLength	      = m16_swap (cmd->length); + +	info("Root-Hub: adr: %2x cmd(%1x): %08x %04x %04x %04x", +		dev->devnum, 8, bmRType_bReq, wValue, wIndex, wLength); + +	switch (bmRType_bReq) { +	/* Request Destination: +	   without flags: Device, +	   RH_INTERFACE: interface, +	   RH_ENDPOINT: endpoint, +	   RH_CLASS means HUB here, +	   RH_OTHER | RH_CLASS	almost ever means HUB_PORT here +	*/ + +	case RH_GET_STATUS: +			*(__u16 *) data_buf = m16_swap (1); OK (2); +	case RH_GET_STATUS | RH_INTERFACE: +			*(__u16 *) data_buf = m16_swap (0); OK (2); +	case RH_GET_STATUS | RH_ENDPOINT: +			*(__u16 *) data_buf = m16_swap (0); OK (2); +	case RH_GET_STATUS | RH_CLASS: +			*(__u32 *) data_buf = m32_swap ( +				RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE)); +			OK (4); +	case RH_GET_STATUS | RH_OTHER | RH_CLASS: +			*(__u32 *) data_buf = m32_swap (RD_RH_PORTSTAT); OK (4); + +	case RH_CLEAR_FEATURE | RH_ENDPOINT: +		switch (wValue) { +			case (RH_ENDPOINT_STALL): OK (0); +		} +		break; + +	case RH_CLEAR_FEATURE | RH_CLASS: +		switch (wValue) { +			case RH_C_HUB_LOCAL_POWER: +				OK(0); +			case (RH_C_HUB_OVER_CURRENT): +					WR_RH_STAT(RH_HS_OCIC); OK (0); +		} +		break; + +	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS: +		switch (wValue) { +			case (RH_PORT_ENABLE): +					WR_RH_PORTSTAT (RH_PS_CCS ); OK (0); +			case (RH_PORT_SUSPEND): +					WR_RH_PORTSTAT (RH_PS_POCI); OK (0); +			case (RH_PORT_POWER): +					WR_RH_PORTSTAT (RH_PS_LSDA); OK (0); +			case (RH_C_PORT_CONNECTION): +					WR_RH_PORTSTAT (RH_PS_CSC ); OK (0); +			case (RH_C_PORT_ENABLE): +					WR_RH_PORTSTAT (RH_PS_PESC); OK (0); +			case (RH_C_PORT_SUSPEND): +					WR_RH_PORTSTAT (RH_PS_PSSC); OK (0); +			case (RH_C_PORT_OVER_CURRENT): +					WR_RH_PORTSTAT (RH_PS_OCIC); OK (0); +			case (RH_C_PORT_RESET): +					WR_RH_PORTSTAT (RH_PS_PRSC); OK (0); +		} +		break; + +	case RH_SET_FEATURE | RH_OTHER | RH_CLASS: +		switch (wValue) { +			case (RH_PORT_SUSPEND): +					WR_RH_PORTSTAT (RH_PS_PSS ); OK (0); +			case (RH_PORT_RESET): /* BUG IN HUP CODE *********/ +					if (RD_RH_PORTSTAT & RH_PS_CCS) +					    WR_RH_PORTSTAT (RH_PS_PRS); +					OK (0); +			case (RH_PORT_POWER): +					WR_RH_PORTSTAT (RH_PS_PPS ); OK (0); +			case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/ +					if (RD_RH_PORTSTAT & RH_PS_CCS) +					    WR_RH_PORTSTAT (RH_PS_PES ); +					OK (0); +		} +		break; + +	case RH_SET_ADDRESS: gohci.rh.devnum = wValue; OK(0); + +	case RH_GET_DESCRIPTOR: +		switch ((wValue & 0xff00) >> 8) { +			case (0x01): /* device descriptor */ +				len = min_t(unsigned int, +					  leni, +					  min_t(unsigned int, +					      sizeof (root_hub_dev_des), +					      wLength)); +				data_buf = root_hub_dev_des; OK(len); +			case (0x02): /* configuration descriptor */ +				len = min_t(unsigned int, +					  leni, +					  min_t(unsigned int, +					      sizeof (root_hub_config_des), +					      wLength)); +				data_buf = root_hub_config_des; OK(len); +			case (0x03): /* string descriptors */ +				if(wValue==0x0300) { +					len = min_t(unsigned int, +						  leni, +						  min_t(unsigned int, +						      sizeof (root_hub_str_index0), +						      wLength)); +					data_buf = root_hub_str_index0; +					OK(len); +				} +				if(wValue==0x0301) { +					len = min_t(unsigned int, +						  leni, +						  min_t(unsigned int, +						      sizeof (root_hub_str_index1), +						      wLength)); +					data_buf = root_hub_str_index1; +					OK(len); +			} +			default: +				stat = USB_ST_STALLED; +		} +		break; + +	case RH_GET_DESCRIPTOR | RH_CLASS: +	    { +		    __u32 temp = roothub_a (&gohci); + +		    data_buf [0] = 9;		/* min length; */ +		    data_buf [1] = 0x29; +		    data_buf [2] = temp & RH_A_NDP; +		    data_buf [3] = 0; +		    if (temp & RH_A_PSM)	/* per-port power switching? */ +			data_buf [3] |= 0x1; +		    if (temp & RH_A_NOCP)	/* no overcurrent reporting? */ +			data_buf [3] |= 0x10; +		    else if (temp & RH_A_OCPM)	/* per-port overcurrent reporting? */ +			data_buf [3] |= 0x8; + +		    /* corresponds to data_buf[4-7] */ +		    datab [1] = 0; +		    data_buf [5] = (temp & RH_A_POTPGT) >> 24; +		    temp = roothub_b (&gohci); +		    data_buf [7] = temp & RH_B_DR; +		    if (data_buf [2] < 7) { +			data_buf [8] = 0xff; +		    } else { +			data_buf [0] += 2; +			data_buf [8] = (temp & RH_B_DR) >> 8; +			data_buf [10] = data_buf [9] = 0xff; +		    } + +		    len = min_t(unsigned int, leni, +			      min_t(unsigned int, data_buf [0], wLength)); +		    OK (len); +		} + +	case RH_GET_CONFIGURATION:	*(__u8 *) data_buf = 0x01; OK (1); + +	case RH_SET_CONFIGURATION:	WR_RH_STAT (0x10000); OK (0); + +	default: +		dbg ("unsupported root hub command"); +		stat = USB_ST_STALLED; +	} + +#ifdef	DEBUG +	ohci_dump_roothub (&gohci, 1); +#endif + +	len = min_t(int, len, leni); +	if (data != data_buf) +	    memcpy (data, data_buf, len); +	dev->act_len = len; +	dev->status = stat; + +#ifdef DEBUG +	if (transfer_len) +		urb_priv.actual_length = transfer_len; +	pkt_print(dev, pipe, buffer, transfer_len, cmd, "RET(rh)", 0/*usb_pipein(pipe)*/); +#endif + +	return stat; +} + +/*-------------------------------------------------------------------------*/ + +/* common code for handling submit messages - used for all but root hub */ +/* accesses. */ +int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer, +		int transfer_len, struct devrequest *setup, int interval) +{ +	int stat = 0; +	int maxsize = usb_maxpacket(dev, pipe); +	int timeout; + +	/* device pulled? Shortcut the action. */ +	if (devgone == dev) { +		dev->status = USB_ST_CRC_ERR; +		return 0; +	} + +#ifdef DEBUG +	urb_priv.actual_length = 0; +	pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe)); +#endif +	if (!maxsize) { +		err("submit_common_message: pipesize for pipe %lx is zero", +			pipe); +		return -1; +	} + +	if (sohci_submit_job(dev, pipe, buffer, transfer_len, setup, interval) < 0) { +		err("sohci_submit_job failed"); +		return -1; +	} + +	/* allow more time for a BULK device to react - some are slow */ +#define BULK_TO	 5000	/* timeout in milliseconds */ +	if (usb_pipetype (pipe) == PIPE_BULK) +		timeout = BULK_TO; +	else +		timeout = 100; + +	/* wait for it to complete */ +	for (;;) { +		/* check whether the controller is done */ +		stat = hc_interrupt(); +		if (stat < 0) { +			stat = USB_ST_CRC_ERR; +			break; +		} +		if (stat >= 0 && stat < 0xff) { +			/* 0xff is returned for an SF-interrupt */ +			break; +		} +		if (--timeout) { +			wait_ms(1); +		} else { +			err("CTL:TIMEOUT "); +			stat = USB_ST_CRC_ERR; +			break; +		} +	} +	/* we got an Root Hub Status Change interrupt */ +	if (got_rhsc) { +#ifdef DEBUG +		ohci_dump_roothub (&gohci, 1); +#endif +		got_rhsc = 0; +		/* abuse timeout */ +		timeout = rh_check_port_status(&gohci); +		if (timeout >= 0) { +#if 0 /* this does nothing useful, but leave it here in case that changes */ +			/* the called routine adds 1 to the passed value */ +			usb_hub_port_connect_change(gohci.rh.dev, timeout - 1); +#endif +			/* +			 * XXX +			 * This is potentially dangerous because it assumes +			 * that only one device is ever plugged in! +			 */ +			devgone = dev; +		} +	} + +	dev->status = stat; +	dev->act_len = transfer_len; + +#ifdef DEBUG +	pkt_print(dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe)); +#endif + +	/* free TDs in urb_priv */ +	urb_free_priv (&urb_priv); +	return 0; +} + +/* submit routines called from usb.c */ +int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, +		int transfer_len) +{ +	info("submit_bulk_msg"); +	return submit_common_msg(dev, pipe, buffer, transfer_len, NULL, 0); +} + +int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, +		int transfer_len, struct devrequest *setup) +{ +	int maxsize = usb_maxpacket(dev, pipe); + +	info("submit_control_msg"); +#ifdef DEBUG +	urb_priv.actual_length = 0; +	pkt_print(dev, pipe, buffer, transfer_len, setup, "SUB", usb_pipein(pipe)); +#endif +	if (!maxsize) { +		err("submit_control_message: pipesize for pipe %lx is zero", +			pipe); +		return -1; +	} +	if (((pipe >> 8) & 0x7f) == gohci.rh.devnum) { +		gohci.rh.dev = dev; +		/* root hub - redirect */ +		return ohci_submit_rh_msg(dev, pipe, buffer, transfer_len, +			setup); +	} + +	return submit_common_msg(dev, pipe, buffer, transfer_len, setup, 0); +} + +int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, +		int transfer_len, int interval) +{ +	info("submit_int_msg"); +	return -1; +} + +/*-------------------------------------------------------------------------* + * HC functions + *-------------------------------------------------------------------------*/ + +/* reset the HC and BUS */ + +static int hc_reset (ohci_t *ohci) +{ +	int timeout = 30; +	int smm_timeout = 50; /* 0,5 sec */ + +	if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */ +		writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */ +		info("USB HC TakeOver from SMM"); +		while (readl (&ohci->regs->control) & OHCI_CTRL_IR) { +			wait_ms (10); +			if (--smm_timeout == 0) { +				err("USB HC TakeOver failed!"); +				return -1; +			} +		} +	} + +	/* Disable HC interrupts */ +	writel (OHCI_INTR_MIE, &ohci->regs->intrdisable); + +	dbg("USB HC reset_hc usb-%s: ctrl = 0x%X ;", +		ohci->slot_name, +		readl (&ohci->regs->control)); + +	/* Reset USB (needed by some controllers) */ +	ohci->hc_control = 0; +	writel (ohci->hc_control, &ohci->regs->control); + +	/* HC Reset requires max 10 us delay */ +	writel (OHCI_HCR,  &ohci->regs->cmdstatus); +	while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { +		if (--timeout == 0) { +			err("USB HC reset timed out!"); +			return -1; +		} +		udelay (1); +	} +	return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* Start an OHCI controller, set the BUS operational + * enable interrupts + * connect the virtual root hub */ + +static int hc_start (ohci_t * ohci) +{ +	__u32 mask; +	unsigned int fminterval; + +	ohci->disabled = 1; + +	/* Tell the controller where the control and bulk lists are +	 * The lists are empty now. */ + +	writel (0, &ohci->regs->ed_controlhead); +	writel (0, &ohci->regs->ed_bulkhead); + +	writel ((__u32)ohci->hcca, &ohci->regs->hcca); /* a reset clears this */ + +	fminterval = 0x2edf; +	writel ((fminterval * 9) / 10, &ohci->regs->periodicstart); +	fminterval |= ((((fminterval - 210) * 6) / 7) << 16); +	writel (fminterval, &ohci->regs->fminterval); +	writel (0x628, &ohci->regs->lsthresh); + +	/* start controller operations */ +	ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER; +	ohci->disabled = 0; +	writel (ohci->hc_control, &ohci->regs->control); + +	/* disable all interrupts */ +	mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD | +			OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC | +			OHCI_INTR_OC | OHCI_INTR_MIE); +	writel (mask, &ohci->regs->intrdisable); +	/* clear all interrupts */ +	mask &= ~OHCI_INTR_MIE; +	writel (mask, &ohci->regs->intrstatus); +	/* Choose the interrupts we care about now  - but w/o MIE */ +	mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO; +	writel (mask, &ohci->regs->intrenable); + +#ifdef	OHCI_USE_NPS +	/* required for AMD-756 and some Mac platforms */ +	writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM, +		&ohci->regs->roothub.a); +	writel (RH_HS_LPSC, &ohci->regs->roothub.status); +#endif	/* OHCI_USE_NPS */ + +#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);}) +	/* POTPGT delay is bits 24-31, in 2 ms units. */ +	mdelay ((roothub_a (ohci) >> 23) & 0x1fe); + +	/* connect the virtual root hub */ +	ohci->rh.devnum = 0; + +	return 0; +} + +/*-------------------------------------------------------------------------*/ + +/* an interrupt happens */ + +static int +hc_interrupt (void) +{ +	ohci_t *ohci = &gohci; +	struct ohci_regs *regs = ohci->regs; +	int ints; +	int stat = -1; + +	if ((ohci->hcca->done_head != 0) && !(ohci_cpu_to_le32 (ohci->hcca->done_head) & 0x01)) { +		ints =	OHCI_INTR_WDH; +	} else { +		ints = readl (®s->intrstatus); +	} + +	/* dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); */ + +	if (ints & OHCI_INTR_RHSC) { +		got_rhsc = 1; +	} + +	if (ints & OHCI_INTR_UE) { +		ohci->disabled++; +		err ("OHCI Unrecoverable Error, controller usb-%s disabled", +			ohci->slot_name); +		/* e.g. due to PCI Master/Target Abort */ + +#ifdef	DEBUG +		ohci_dump (ohci, 1); +#endif +		/* FIXME: be optimistic, hope that bug won't repeat often. */ +		/* Make some non-interrupt context restart the controller. */ +		/* Count and limit the retries though; either hardware or */ +		/* software errors can go forever... */ +		hc_reset (ohci); +		return -1; +	} + +	if (ints & OHCI_INTR_WDH) { +		writel (OHCI_INTR_WDH, ®s->intrdisable); +		stat = dl_done_list (&gohci, dl_reverse_done_list (&gohci)); +		writel (OHCI_INTR_WDH, ®s->intrenable); +	} + +	if (ints & OHCI_INTR_SO) { +		dbg("USB Schedule overrun\n"); +		writel (OHCI_INTR_SO, ®s->intrenable); +		stat = -1; +	} + +	/* FIXME:  this assumes SOF (1/ms) interrupts don't get lost... */ +	if (ints & OHCI_INTR_SF) { +		unsigned int frame = ohci_cpu_to_le16 (ohci->hcca->frame_no) & 1; +		writel (OHCI_INTR_SF, ®s->intrdisable); +		if (ohci->ed_rm_list[frame] != NULL) +			writel (OHCI_INTR_SF, ®s->intrenable); +		stat = 0xff; +	} + +	writel (ints, ®s->intrstatus); +	return stat; +} + +/*-------------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------------*/ + +/* De-allocate all resources.. */ + +static void hc_release_ohci (ohci_t *ohci) +{ +	dbg ("USB HC release ohci usb-%s", ohci->slot_name); + +	if (!ohci->disabled) +		hc_reset (ohci); +} + +/*-------------------------------------------------------------------------*/ + +/* + * low level initalisation routine, called from usb.c + */ +static char ohci_inited = 0; + +int usb_lowlevel_init(void) +{ + +	/* Set the USB Clock						     */ +	*(vu_long *)MPC5XXX_CDM_48_FDC = 0x0001bbbb; +	*(vu_long *)MPC5XXX_GPS_PORT_CONFIG &= ~0x00800000; +	/* Activate USB port						     */ +	*(vu_long *)MPC5XXX_GPS_PORT_CONFIG |= 0x00001000; + +	memset (&gohci, 0, sizeof (ohci_t)); +	memset (&urb_priv, 0, sizeof (urb_priv_t)); + +	/* align the storage */ +	if ((__u32)&ghcca[0] & 0xff) { +		err("HCCA not aligned!!"); +		return -1; +	} +	phcca = &ghcca[0]; +	info("aligned ghcca %p", phcca); +	memset(&ohci_dev, 0, sizeof(struct ohci_device)); +	if ((__u32)&ohci_dev.ed[0] & 0x7) { +		err("EDs not aligned!!"); +		return -1; +	} +	memset(gtd, 0, sizeof(td_t) * (NUM_TD + 1)); +	if ((__u32)gtd & 0x7) { +		err("TDs not aligned!!"); +		return -1; +	} +	ptd = gtd; +	gohci.hcca = phcca; +	memset (phcca, 0, sizeof (struct ohci_hcca)); + +	gohci.disabled = 1; +	gohci.sleeping = 0; +	gohci.irq = -1; +	gohci.regs = (struct ohci_regs *)MPC5XXX_USB; + +	gohci.flags = 0; +	gohci.slot_name = "mpc5200"; + +	if (hc_reset (&gohci) < 0) { +		hc_release_ohci (&gohci); +		return -1; +	} + +	if (hc_start (&gohci) < 0) { +		err ("can't start usb-%s", gohci.slot_name); +		hc_release_ohci (&gohci); +		return -1; +	} + +#ifdef	DEBUG +	ohci_dump (&gohci, 1); +#endif +	ohci_inited = 1; +	return 0; +} + +int usb_lowlevel_stop(void) +{ +	/* this gets called really early - before the controller has */ +	/* even been initialized! */ +	if (!ohci_inited) +		return 0; +	/* TODO release any interrupts, etc. */ +	/* call hc_release_ohci() here ? */ +	hc_reset (&gohci); +	return 0; +} + +#endif /* CONFIG_USB_OHCI */ diff --git a/cpu/mpc5xxx/usb_ohci.h b/cpu/mpc5xxx/usb_ohci.h new file mode 100644 index 000000000..11b361af0 --- /dev/null +++ b/cpu/mpc5xxx/usb_ohci.h @@ -0,0 +1,424 @@ +/* + * URB OHCI HCD (Host Controller Driver) for USB. + * + * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> + * (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net> + * + * usb-ohci.h + */ + + +static int cc_to_error[16] = { + +/* mapping of the OHCI CC status to error codes */ +	/* No  Error  */	       0, +	/* CRC Error  */	       USB_ST_CRC_ERR, +	/* Bit Stuff  */	       USB_ST_BIT_ERR, +	/* Data Togg  */	       USB_ST_CRC_ERR, +	/* Stall      */	       USB_ST_STALLED, +	/* DevNotResp */	       -1, +	/* PIDCheck   */	       USB_ST_BIT_ERR, +	/* UnExpPID   */	       USB_ST_BIT_ERR, +	/* DataOver   */	       USB_ST_BUF_ERR, +	/* DataUnder  */	       USB_ST_BUF_ERR, +	/* reservd    */	       -1, +	/* reservd    */	       -1, +	/* BufferOver */	       USB_ST_BUF_ERR, +	/* BuffUnder  */	       USB_ST_BUF_ERR, +	/* Not Access */	       -1, +	/* Not Access */	       -1 +}; + +/* ED States */ + +#define ED_NEW		0x00 +#define ED_UNLINK	0x01 +#define ED_OPER		0x02 +#define ED_DEL		0x04 +#define ED_URB_DEL	0x08 + +/* usb_ohci_ed */ +struct ed { +	__u32 hwINFO; +	__u32 hwTailP; +	__u32 hwHeadP; +	__u32 hwNextED; + +	struct ed *ed_prev; +	__u8 int_period; +	__u8 int_branch; +	__u8 int_load; +	__u8 int_interval; +	__u8 state; +	__u8 type; +	__u16 last_iso; +	struct ed *ed_rm_list; + +	struct usb_device *usb_dev; +	__u32 unused[3]; +} __attribute((aligned(16))); +typedef struct ed ed_t; + + +/* TD info field */ +#define TD_CC	    0xf0000000 +#define TD_CC_GET(td_p) ((td_p >>28) & 0x0f) +#define TD_CC_SET(td_p, cc) (td_p) = ((td_p) & 0x0fffffff) | (((cc) & 0x0f) << 28) +#define TD_EC	    0x0C000000 +#define TD_T	    0x03000000 +#define TD_T_DATA0  0x02000000 +#define TD_T_DATA1  0x03000000 +#define TD_T_TOGGLE 0x00000000 +#define TD_R	    0x00040000 +#define TD_DI	    0x00E00000 +#define TD_DI_SET(X) (((X) & 0x07)<< 21) +#define TD_DP	    0x00180000 +#define TD_DP_SETUP 0x00000000 +#define TD_DP_IN    0x00100000 +#define TD_DP_OUT   0x00080000 + +#define TD_ISO	    0x00010000 +#define TD_DEL	    0x00020000 + +/* CC Codes */ +#define TD_CC_NOERROR	   0x00 +#define TD_CC_CRC	   0x01 +#define TD_CC_BITSTUFFING  0x02 +#define TD_CC_DATATOGGLEM  0x03 +#define TD_CC_STALL	   0x04 +#define TD_DEVNOTRESP	   0x05 +#define TD_PIDCHECKFAIL	   0x06 +#define TD_UNEXPECTEDPID   0x07 +#define TD_DATAOVERRUN	   0x08 +#define TD_DATAUNDERRUN	   0x09 +#define TD_BUFFEROVERRUN   0x0C +#define TD_BUFFERUNDERRUN  0x0D +#define TD_NOTACCESSED	   0x0F + + +#define MAXPSW 1 + +struct td { +	__u32 hwINFO; +	__u32 hwCBP;		/* Current Buffer Pointer */ +	__u32 hwNextTD;		/* Next TD Pointer */ +	__u32 hwBE;		/* Memory Buffer End Pointer */ + +	__u16 hwPSW[MAXPSW]; +	__u8 unused; +	__u8 index; +	struct ed *ed; +	struct td *next_dl_td; +	struct usb_device *usb_dev; +	int transfer_len; +	__u32 data; + +	__u32 unused2[2]; +} __attribute((aligned(32))); +typedef struct td td_t; + +#define OHCI_ED_SKIP	(1 << 14) + +/* + * The HCCA (Host Controller Communications Area) is a 256 byte + * structure defined in the OHCI spec. that the host controller is + * told the base address of.  It must be 256-byte aligned. + */ + +#define NUM_INTS 32	/* part of the OHCI standard */ +struct ohci_hcca { +	__u32	int_table[NUM_INTS];	/* Interrupt ED table */ +#if defined(CONFIG_MPC5200) +	__u16	pad1;			/* set to 0 on each frame_no change */ +	__u16	frame_no;		/* current frame number */ +#else +	__u16	frame_no;		/* current frame number */ +	__u16	pad1;			/* set to 0 on each frame_no change */ +#endif +	__u32	done_head;		/* info returned for an interrupt */ +	u8		reserved_for_hc[116]; +} __attribute((aligned(256))); + + +/* + * Maximum number of root hub ports. + */ +#define MAX_ROOT_PORTS	15	/* maximum OHCI root hub ports */ + +/* + * This is the structure of the OHCI controller's memory mapped I/O + * region.  This is Memory Mapped I/O.	You must use the readl() and + * writel() macros defined in asm/io.h to access these!! + */ +struct ohci_regs { +	/* control and status registers */ +	__u32	revision; +	__u32	control; +	__u32	cmdstatus; +	__u32	intrstatus; +	__u32	intrenable; +	__u32	intrdisable; +	/* memory pointers */ +	__u32	hcca; +	__u32	ed_periodcurrent; +	__u32	ed_controlhead; +	__u32	ed_controlcurrent; +	__u32	ed_bulkhead; +	__u32	ed_bulkcurrent; +	__u32	donehead; +	/* frame counters */ +	__u32	fminterval; +	__u32	fmremaining; +	__u32	fmnumber; +	__u32	periodicstart; +	__u32	lsthresh; +	/* Root hub ports */ +	struct	ohci_roothub_regs { +		__u32	a; +		__u32	b; +		__u32	status; +		__u32	portstatus[MAX_ROOT_PORTS]; +	} roothub; +} __attribute((aligned(32))); + + +/* OHCI CONTROL AND STATUS REGISTER MASKS */ + +/* + * HcControl (control) register masks + */ +#define OHCI_CTRL_CBSR	(3 << 0)	/* control/bulk service ratio */ +#define OHCI_CTRL_PLE	(1 << 2)	/* periodic list enable */ +#define OHCI_CTRL_IE	(1 << 3)	/* isochronous enable */ +#define OHCI_CTRL_CLE	(1 << 4)	/* control list enable */ +#define OHCI_CTRL_BLE	(1 << 5)	/* bulk list enable */ +#define OHCI_CTRL_HCFS	(3 << 6)	/* host controller functional state */ +#define OHCI_CTRL_IR	(1 << 8)	/* interrupt routing */ +#define OHCI_CTRL_RWC	(1 << 9)	/* remote wakeup connected */ +#define OHCI_CTRL_RWE	(1 << 10)	/* remote wakeup enable */ + +/* pre-shifted values for HCFS */ +#	define OHCI_USB_RESET	(0 << 6) +#	define OHCI_USB_RESUME	(1 << 6) +#	define OHCI_USB_OPER	(2 << 6) +#	define OHCI_USB_SUSPEND (3 << 6) + +/* + * HcCommandStatus (cmdstatus) register masks + */ +#define OHCI_HCR	(1 << 0)	/* host controller reset */ +#define OHCI_CLF	(1 << 1)	/* control list filled */ +#define OHCI_BLF	(1 << 2)	/* bulk list filled */ +#define OHCI_OCR	(1 << 3)	/* ownership change request */ +#define OHCI_SOC	(3 << 16)	/* scheduling overrun count */ + +/* + * masks used with interrupt registers: + * HcInterruptStatus (intrstatus) + * HcInterruptEnable (intrenable) + * HcInterruptDisable (intrdisable) + */ +#define OHCI_INTR_SO	(1 << 0)	/* scheduling overrun */ +#define OHCI_INTR_WDH	(1 << 1)	/* writeback of done_head */ +#define OHCI_INTR_SF	(1 << 2)	/* start frame */ +#define OHCI_INTR_RD	(1 << 3)	/* resume detect */ +#define OHCI_INTR_UE	(1 << 4)	/* unrecoverable error */ +#define OHCI_INTR_FNO	(1 << 5)	/* frame number overflow */ +#define OHCI_INTR_RHSC	(1 << 6)	/* root hub status change */ +#define OHCI_INTR_OC	(1 << 30)	/* ownership change */ +#define OHCI_INTR_MIE	(1 << 31)	/* master interrupt enable */ + + +/* Virtual Root HUB */ +struct virt_root_hub { +	int devnum; /* Address of Root Hub endpoint */ +	void *dev;  /* was urb */ +	void *int_addr; +	int send; +	int interval; +}; + +/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */ + +/* destination of request */ +#define RH_INTERFACE		   0x01 +#define RH_ENDPOINT		   0x02 +#define RH_OTHER		   0x03 + +#define RH_CLASS		   0x20 +#define RH_VENDOR		   0x40 + +/* Requests: bRequest << 8 | bmRequestType */ +#define RH_GET_STATUS		0x0080 +#define RH_CLEAR_FEATURE	0x0100 +#define RH_SET_FEATURE		0x0300 +#define RH_SET_ADDRESS		0x0500 +#define RH_GET_DESCRIPTOR	0x0680 +#define RH_SET_DESCRIPTOR	0x0700 +#define RH_GET_CONFIGURATION	0x0880 +#define RH_SET_CONFIGURATION	0x0900 +#define RH_GET_STATE		0x0280 +#define RH_GET_INTERFACE	0x0A80 +#define RH_SET_INTERFACE	0x0B00 +#define RH_SYNC_FRAME		0x0C80 +/* Our Vendor Specific Request */ +#define RH_SET_EP		0x2000 + + +/* Hub port features */ +#define RH_PORT_CONNECTION	   0x00 +#define RH_PORT_ENABLE		   0x01 +#define RH_PORT_SUSPEND		   0x02 +#define RH_PORT_OVER_CURRENT	   0x03 +#define RH_PORT_RESET		   0x04 +#define RH_PORT_POWER		   0x08 +#define RH_PORT_LOW_SPEED	   0x09 + +#define RH_C_PORT_CONNECTION	   0x10 +#define RH_C_PORT_ENABLE	   0x11 +#define RH_C_PORT_SUSPEND	   0x12 +#define RH_C_PORT_OVER_CURRENT	   0x13 +#define RH_C_PORT_RESET		   0x14 + +/* Hub features */ +#define RH_C_HUB_LOCAL_POWER	   0x00 +#define RH_C_HUB_OVER_CURRENT	   0x01 + +#define RH_DEVICE_REMOTE_WAKEUP	   0x00 +#define RH_ENDPOINT_STALL	   0x01 + +#define RH_ACK			   0x01 +#define RH_REQ_ERR		   -1 +#define RH_NACK			   0x00 + + +/* OHCI ROOT HUB REGISTER MASKS */ + +/* roothub.portstatus [i] bits */ +#define RH_PS_CCS	     0x00000001		/* current connect status */ +#define RH_PS_PES	     0x00000002		/* port enable status*/ +#define RH_PS_PSS	     0x00000004		/* port suspend status */ +#define RH_PS_POCI	     0x00000008		/* port over current indicator */ +#define RH_PS_PRS	     0x00000010		/* port reset status */ +#define RH_PS_PPS	     0x00000100		/* port power status */ +#define RH_PS_LSDA	     0x00000200		/* low speed device attached */ +#define RH_PS_CSC	     0x00010000		/* connect status change */ +#define RH_PS_PESC	     0x00020000		/* port enable status change */ +#define RH_PS_PSSC	     0x00040000		/* port suspend status change */ +#define RH_PS_OCIC	     0x00080000		/* over current indicator change */ +#define RH_PS_PRSC	     0x00100000		/* port reset status change */ + +/* roothub.status bits */ +#define RH_HS_LPS	     0x00000001		/* local power status */ +#define RH_HS_OCI	     0x00000002		/* over current indicator */ +#define RH_HS_DRWE	     0x00008000		/* device remote wakeup enable */ +#define RH_HS_LPSC	     0x00010000		/* local power status change */ +#define RH_HS_OCIC	     0x00020000		/* over current indicator change */ +#define RH_HS_CRWE	     0x80000000		/* clear remote wakeup enable */ + +/* roothub.b masks */ +#define RH_B_DR		0x0000ffff		/* device removable flags */ +#define RH_B_PPCM	0xffff0000		/* port power control mask */ + +/* roothub.a masks */ +#define RH_A_NDP	(0xff << 0)		/* number of downstream ports */ +#define RH_A_PSM	(1 << 8)		/* power switching mode */ +#define RH_A_NPS	(1 << 9)		/* no power switching */ +#define RH_A_DT		(1 << 10)		/* device type (mbz) */ +#define RH_A_OCPM	(1 << 11)		/* over current protection mode */ +#define RH_A_NOCP	(1 << 12)		/* no over current protection */ +#define RH_A_POTPGT	(0xff << 24)		/* power on to power good time */ + +/* urb */ +#define N_URB_TD 48 +typedef struct +{ +	ed_t *ed; +	__u16 length;	/* number of tds associated with this request */ +	__u16 td_cnt;	/* number of tds already serviced */ +	int   state; +	unsigned long pipe; +	int actual_length; +	td_t *td[N_URB_TD];	/* list pointer to all corresponding TDs associated with this request */ +} urb_priv_t; +#define URB_DEL 1 + +/* + * This is the full ohci controller description + * + * Note how the "proper" USB information is just + * a subset of what the full implementation needs. (Linus) + */ + + +typedef struct ohci { +	struct ohci_hcca *hcca;		/* hcca */ +	/*dma_addr_t hcca_dma;*/ + +	int irq; +	int disabled;			/* e.g. got a UE, we're hung */ +	int sleeping; +	unsigned long flags;		/* for HC bugs */ + +	struct ohci_regs *regs; /* OHCI controller's memory */ + +	ed_t *ed_rm_list[2];	 /* lists of all endpoints to be removed */ +	ed_t *ed_bulktail;	 /* last endpoint of bulk list */ +	ed_t *ed_controltail;	 /* last endpoint of control list */ +	int intrstatus; +	__u32 hc_control;		/* copy of the hc control reg */ +	struct usb_device *dev[32]; +	struct virt_root_hub rh; + +	const char	*slot_name; +} ohci_t; + +#define NUM_EDS 8		/* num of preallocated endpoint descriptors */ + +struct ohci_device { +	ed_t	ed[NUM_EDS]; +	int ed_cnt; +}; + +/* hcd */ +/* endpoint */ +static int ep_link(ohci_t * ohci, ed_t * ed); +static int ep_unlink(ohci_t * ohci, ed_t * ed); +static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned long pipe); + +/*-------------------------------------------------------------------------*/ + +/* we need more TDs than EDs */ +#define NUM_TD 64 + +/* +1 so we can align the storage */ +td_t gtd[NUM_TD+1]; +/* pointers to aligned storage */ +td_t *ptd; + +/* TDs ... */ +static inline struct td * +td_alloc (struct usb_device *usb_dev) +{ +	int i; +	struct td	*td; + +	td = NULL; +	for (i = 0; i < NUM_TD; i++) +	{ +		if (ptd[i].usb_dev == NULL) +		{ +			td = &ptd[i]; +			td->usb_dev = usb_dev; +			break; +		} +	} + +	return td; +} + +static inline void +ed_free (struct ed *ed) +{ +	ed->usb_dev = NULL; +} diff --git a/doc/README.ns9750dev b/doc/README.ns9750dev new file mode 100644 index 000000000..29914406b --- /dev/null +++ b/doc/README.ns9750dev @@ -0,0 +1,36 @@ +U-Boot Port to the NS9750 DevKit from NetSilicon + +1 Overview +2 Board Configuration +3 Installation + + +1 Overview +---------- + +This port supports these NS9750 features. + +o one UART + +2 Board Configuration +--------------------- + +Switches: +SW10: 4 +SW11: 6,7 +SW16: 6,7,8 +SW17-SW20: 1 +SW4: 3, 6 +SW 1: 1 +SW2: 4 +SW3: 3 +SW8: 3 (rotated by 180 degree!!!!) + +Serial Console is Port B (bottom right port) + +3 Installation +-------------- + +Have fun, +-- +Markus Pietrek <mpietrek@fsforth.de> diff --git a/drivers/ns9750_eth.c b/drivers/ns9750_eth.c new file mode 100644 index 000000000..067ff8efa --- /dev/null +++ b/drivers/ns9750_eth.c @@ -0,0 +1,797 @@ +/*********************************************************************** + * + * Copyright (C) 2004 by FS Forth-Systeme GmbH. + * All rights reserved. + * + * $Id: ns9750_eth.c,v 1.2 2004/02/24 14:09:39 mpietrek Exp $ + * @Author: Markus Pietrek + * @Descr: Ethernet driver for the NS9750. Uses DMA Engine with polling + *	   interrupt status. But interrupts are not enabled. + *	   Only one tx buffer descriptor and the RXA buffer descriptor are used + *	   Currently no transmit lockup handling is included. eth_send has a 5s + *	   timeout for sending frames. No retransmits are performed when an + *	   error occurs. + * @References: [1] NS9750 Hardware Reference, December 2003 + *		[2] Intel LXT971 Datasheet #249414 Rev. 02 + *		[3] NS7520 Linux Ethernet Driver + * + * 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 <net.h>		/* NetSendPacket */ + +#include "ns9750_eth.h"		/* for Ethernet and PHY */ + +#ifdef CONFIG_DRIVER_NS9750_ETHERNET + +/* some definition to make transistion to linux easier */ + +#define NS9750_DRIVER_NAME	"eth" +#define KERN_WARNING		"Warning:" +#define KERN_ERR		"Error:" +#define KERN_INFO		"Info:" + +#if 0 +# define DEBUG +#endif + +#ifdef	DEBUG +# define printk			printf + +# define DEBUG_INIT		0x0001 +# define DEBUG_MINOR		0x0002 +# define DEBUG_RX		0x0004 +# define DEBUG_TX		0x0008 +# define DEBUG_INT		0x0010 +# define DEBUG_POLL		0x0020 +# define DEBUG_LINK		0x0040 +# define DEBUG_MII		0x0100 +# define DEBUG_MII_LOW		0x0200 +# define DEBUG_MEM		0x0400 +# define DEBUG_ERROR		0x4000 +# define DEBUG_ERROR_CRIT	0x8000 + +static int nDebugLvl = DEBUG_ERROR_CRIT; + +# define DEBUG_ARGS0( FLG, a0 ) if( ( nDebugLvl & (FLG) ) == (FLG) ) \ +		printf("%s: " a0, __FUNCTION__, 0, 0, 0, 0, 0, 0 ) +# define DEBUG_ARGS1( FLG, a0, a1 ) if( ( nDebugLvl & (FLG) ) == (FLG)) \ +		printf("%s: " a0, __FUNCTION__, (int)(a1), 0, 0, 0, 0, 0 ) +# define DEBUG_ARGS2( FLG, a0, a1, a2 ) if( (nDebugLvl & (FLG)) ==(FLG))\ +		printf("%s: " a0, __FUNCTION__, (int)(a1), (int)(a2), 0, 0,0,0 ) +# define DEBUG_ARGS3( FLG, a0, a1, a2, a3 ) if((nDebugLvl &(FLG))==(FLG))\ +		printf("%s: "a0,__FUNCTION__,(int)(a1),(int)(a2),(int)(a3),0,0,0) +# define DEBUG_FN( FLG ) if( (nDebugLvl & (FLG)) == (FLG) ) \ +		printf("\r%s:line %d\n", (int)__FUNCTION__, __LINE__, 0,0,0,0); +# define ASSERT( expr, func ) if( !( expr ) ) { \ +		printf( "Assertion failed! %s:line %d %s\n", \ +		(int)__FUNCTION__,__LINE__,(int)(#expr),0,0,0); \ +		func } +#else /* DEBUG */ +# define printk(...) +# define DEBUG_ARGS0( FLG, a0 ) +# define DEBUG_ARGS1( FLG, a0, a1 ) +# define DEBUG_ARGS2( FLG, a0, a1, a2 ) +# define DEBUG_ARGS3( FLG, a0, a1, a2, a3 ) +# define DEBUG_FN( n ) +# define ASSERT(expr, func) +#endif /* DEBUG */ + +#define NS9750_MII_NEG_DELAY		(5*CFG_HZ) /* in s */ +#define TX_TIMEOUT			(5*CFG_HZ) /* in s */ + +/* @TODO move it to eeprom.h */ +#define FS_EEPROM_AUTONEG_MASK		0x7 +#define FS_EEPROM_AUTONEG_SPEED_MASK	0x1 +#define FS_EEPROM_AUTONEG_SPEED_10	0x0 +#define FS_EEPROM_AUTONEG_SPEED_100	0x1 +#define FS_EEPROM_AUTONEG_DUPLEX_MASK	0x2 +#define FS_EEPROM_AUTONEG_DUPLEX_HALF	0x0 +#define FS_EEPROM_AUTONEG_DUPLEX_FULL	0x2 +#define FS_EEPROM_AUTONEG_ENABLE_MASK	0x4 +#define FS_EEPROM_AUTONEG_DISABLE	0x0 +#define FS_EEPROM_AUTONEG_ENABLE	0x4 + +/* buffer descriptors taken from [1] p.306 */ +typedef struct +{ +	unsigned int* punSrc; +	unsigned int unLen;	/* 11 bits */ +	unsigned int* punDest;	/* unused */ +	union { +		unsigned int unReg; +		struct { +			unsigned uStatus : 16; +			unsigned uRes : 12; +			unsigned uFull : 1; +			unsigned uEnable : 1; +			unsigned uInt : 1; +			unsigned uWrap : 1; +		} bits; +	} s; +} rx_buffer_desc_t; + +typedef struct +{ +	unsigned int* punSrc; +	unsigned int unLen;	/* 10 bits */ +	unsigned int* punDest;	/* unused */ +	union { +		unsigned int unReg; /* only 32bit accesses may done to NS9750 +				     * eth engine */ +		struct { +			unsigned uStatus : 16; +			unsigned uRes : 12; +			unsigned uFull : 1; +			unsigned uLast : 1; +			unsigned uInt : 1; +			unsigned uWrap : 1; +		} bits; +	} s; +} tx_buffer_desc_t; + +static int ns9750_eth_reset( void ); + +static void ns9750_link_force( void ); +static void ns9750_link_auto_negotiate( void ); +static void ns9750_link_update_egcr( void ); +static void ns9750_link_print_changed( void ); + +/* the PHY stuff */ + +static char ns9750_mii_identify_phy( void ); +static unsigned short ns9750_mii_read( unsigned short uiRegister ); +static void ns9750_mii_write( unsigned short uiRegister, unsigned short uiData ); +static unsigned int ns9750_mii_get_clock_divisor( unsigned int unMaxMDIOClk ); +static unsigned int ns9750_mii_poll_busy( void ); + +static unsigned int nPhyMaxMdioClock = PHY_MDIO_MAX_CLK; +static unsigned char ucLinkMode =      FS_EEPROM_AUTONEG_ENABLE; +static unsigned int uiLastLinkStatus; +static PhyType phyDetected = PHY_NONE; + +/* we use only one tx buffer descriptor */ +static tx_buffer_desc_t* pTxBufferDesc = +	(tx_buffer_desc_t*) get_eth_reg_addr( NS9750_ETH_TXBD ); + +/* we use only one rx buffer descriptor of the 4 */ +static rx_buffer_desc_t aRxBufferDesc[ 4 ]; + +/*********************************************************************** + * @Function: eth_init + * @Return: -1 on failure otherwise 0 + * @Descr: Initializes the ethernet engine and uses either FS Forth's default + *	   MAC addr or the one in environment + ***********************************************************************/ + +int eth_init (bd_t * pbis) +{ +	/* This default MAC Addr is reserved by FS Forth-Systeme for the case of +	   EEPROM failures */ +	unsigned char aucMACAddr[6] = { 0x00, 0x04, 0xf3, 0x00, 0x06, 0x35 }; +	char *pcTmp = getenv ("ethaddr"); +	char *pcEnd; +	int i; + +	DEBUG_FN (DEBUG_INIT); + +	/* no need to check for hardware */ + +	if (!ns9750_eth_reset ()) +		return -1; + +	if (pcTmp != NULL) +		for (i = 0; i < 6; i++) { +			aucMACAddr[i] = +				pcTmp ? simple_strtoul (pcTmp, &pcEnd, +							16) : 0; +			pcTmp = (*pcTmp) ? pcEnd + 1 : pcEnd; +		} + +	/* configure ethernet address */ + +	*get_eth_reg_addr (NS9750_ETH_SA1) = +		aucMACAddr[5] << 8 | aucMACAddr[4]; +	*get_eth_reg_addr (NS9750_ETH_SA2) = +		aucMACAddr[3] << 8 | aucMACAddr[2]; +	*get_eth_reg_addr (NS9750_ETH_SA3) = +		aucMACAddr[1] << 8 | aucMACAddr[0]; + +	/* enable hardware */ + +	*get_eth_reg_addr (NS9750_ETH_MAC1) = NS9750_ETH_MAC1_RXEN; + +	/* the linux kernel may give packets < 60 bytes, for example arp */ +	*get_eth_reg_addr (NS9750_ETH_MAC2) = NS9750_ETH_MAC2_CRCEN | +		NS9750_ETH_MAC2_PADEN | NS9750_ETH_MAC2_HUGE; + +	/* enable receive and transmit FIFO, use 10/100 Mbps MII */ +	*get_eth_reg_addr (NS9750_ETH_EGCR1) = +		NS9750_ETH_EGCR1_ETXWM | +		NS9750_ETH_EGCR1_ERX | +		NS9750_ETH_EGCR1_ERXDMA | +		NS9750_ETH_EGCR1_ETX | +		NS9750_ETH_EGCR1_ETXDMA | NS9750_ETH_EGCR1_ITXA; + +	/* prepare DMA descriptors */ +	for (i = 0; i < 4; i++) { +		aRxBufferDesc[i].punSrc = 0; +		aRxBufferDesc[i].unLen = 0; +		aRxBufferDesc[i].s.bits.uWrap = 1; +		aRxBufferDesc[i].s.bits.uInt = 1; +		aRxBufferDesc[i].s.bits.uEnable = 0; +		aRxBufferDesc[i].s.bits.uFull = 0; +	} + +	/* NetRxPackets[ 0 ] is initialized before eth_init is called and never +	   changes. NetRxPackets is 32bit aligned */ +	aRxBufferDesc[0].punSrc = (unsigned int *) NetRxPackets[0]; +	aRxBufferDesc[0].s.bits.uEnable = 1; +	aRxBufferDesc[0].unLen = 1522;	/* as stated in [1] p.307 */ + +	*get_eth_reg_addr (NS9750_ETH_RXAPTR) = +		(unsigned int) &aRxBufferDesc[0]; + +	/* [1] Tab. 221 states less than 5us */ +	*get_eth_reg_addr (NS9750_ETH_EGCR1) |= NS9750_ETH_EGCR1_ERXINIT; +	while (! +	       (*get_eth_reg_addr (NS9750_ETH_EGSR) & NS9750_ETH_EGSR_RXINIT)) +		/* wait for finish */ +		udelay (1); + +	/* @TODO do we need to clear RXINIT? */ +	*get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~NS9750_ETH_EGCR1_ERXINIT; + +	*get_eth_reg_addr (NS9750_ETH_RXFREE) = 0x1; + +	return 0; +} + +/*********************************************************************** + * @Function: eth_send + * @Return: -1 on timeout otherwise 1 + * @Descr: sends one frame by DMA + ***********************************************************************/ + +int eth_send (volatile void *pPacket, int nLen) +{ +	ulong ulTimeout; + +	DEBUG_FN (DEBUG_TX); + +	/* clear old status values */ +	*get_eth_reg_addr (NS9750_ETH_EINTR) &= +		*get_eth_reg_addr (NS9750_ETH_EINTR) & NS9750_ETH_EINTR_TX_MA; + +	/* prepare Tx Descriptors */ + +	pTxBufferDesc->punSrc = (unsigned int *) pPacket;	/* pPacket is 32bit +								 * aligned */ +	pTxBufferDesc->unLen = nLen; +	/* only 32bit accesses allowed. wrap, full, interrupt and enabled to 1 */ +	pTxBufferDesc->s.unReg = 0xf0000000; +	/* pTxBufferDesc is the first possible buffer descriptor */ +	*get_eth_reg_addr (NS9750_ETH_TXPTR) = 0x0; + +	/* enable processor for next frame */ + +	*get_eth_reg_addr (NS9750_ETH_EGCR2) &= ~NS9750_ETH_EGCR2_TCLER; +	*get_eth_reg_addr (NS9750_ETH_EGCR2) |= NS9750_ETH_EGCR2_TCLER; + +	ulTimeout = get_timer (0); + +	DEBUG_ARGS0 (DEBUG_TX | DEBUG_MINOR, +		     "Waiting for transmission to finish\n"); +	while (! +	       (*get_eth_reg_addr (NS9750_ETH_EINTR) & +		(NS9750_ETH_EINTR_TXDONE | NS9750_ETH_EINTR_TXERR))) { +		/* do nothing, wait for completion */ +		if (get_timer (0) - ulTimeout > TX_TIMEOUT) { +			DEBUG_ARGS0 (DEBUG_TX, "Transmit Timed out\n"); +			return -1; +		} +	} +	DEBUG_ARGS0 (DEBUG_TX | DEBUG_MINOR, "transmitted...\n"); + +	return 0; +} + +/*********************************************************************** + * @Function: eth_rx + * @Return: size of last frame in bytes or 0 if no frame available + * @Descr: gives one frame to U-Boot which has been copied by DMA engine already + *	   to NetRxPackets[ 0 ]. + ***********************************************************************/ + +int eth_rx (void) +{ +	int nLen = 0; +	unsigned int unStatus; + +	unStatus = +		*get_eth_reg_addr (NS9750_ETH_EINTR) & NS9750_ETH_EINTR_RX_MA; + +	if (!unStatus) +		/* no packet available, return immediately */ +		return 0; + +	DEBUG_FN (DEBUG_RX); + +	/* unLen always < max(nLen) and discard checksum */ +	nLen = (int) aRxBufferDesc[0].unLen - 4; + +	/* acknowledge status register */ +	*get_eth_reg_addr (NS9750_ETH_EINTR) = unStatus; + +	aRxBufferDesc[0].unLen = 1522; +	aRxBufferDesc[0].s.bits.uFull = 0; + +	/* Buffer A descriptor available again */ +	*get_eth_reg_addr (NS9750_ETH_RXFREE) |= 0x1; + +	/* NetReceive may call eth_send. Due to a possible bug of the NS9750 we +	 * have to acknowledge the received frame before sending a new one */ +	if (unStatus & NS9750_ETH_EINTR_RXDONEA) +		NetReceive (NetRxPackets[0], nLen); + +	return nLen; +} + +/*********************************************************************** + * @Function: eth_halt + * @Return: n/a + * @Descr: stops the ethernet engine + ***********************************************************************/ + +void eth_halt (void) +{ +	DEBUG_FN (DEBUG_INIT); + +	*get_eth_reg_addr (NS9750_ETH_MAC1) &= ~NS9750_ETH_MAC1_RXEN; +	*get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~(NS9750_ETH_EGCR1_ERX | +						  NS9750_ETH_EGCR1_ERXDMA | +						  NS9750_ETH_EGCR1_ETX | +						  NS9750_ETH_EGCR1_ETXDMA); +} + +/*********************************************************************** + * @Function: ns9750_eth_reset + * @Return: 0 on failure otherwise 1 + * @Descr: resets the ethernet interface and the PHY, + *	   performs auto negotiation or fixed modes + ***********************************************************************/ + +static int ns9750_eth_reset (void) +{ +	DEBUG_FN (DEBUG_MINOR); + +	/* Reset MAC */ +	*get_eth_reg_addr (NS9750_ETH_EGCR1) |= NS9750_ETH_EGCR1_MAC_HRST; +	udelay (5);		/* according to [1], p.322 */ +	*get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~NS9750_ETH_EGCR1_MAC_HRST; + +	/* reset and initialize PHY */ + +	*get_eth_reg_addr (NS9750_ETH_MAC1) &= ~NS9750_ETH_MAC1_SRST; + +	/* we don't support hot plugging of PHY, therefore we don't reset +	   phyDetected and nPhyMaxMdioClock here. The risk is if the setting is +	   incorrect the first open +	   may detect the PHY correctly but succeding will fail +	   For reseting the PHY and identifying we have to use the standard +	   MDIO CLOCK value 2.5 MHz only after hardware reset +	   After having identified the PHY we will do faster */ + +	*get_eth_reg_addr (NS9750_ETH_MCFG) = +		ns9750_mii_get_clock_divisor (nPhyMaxMdioClock); + +	/* reset PHY */ +	ns9750_mii_write (PHY_COMMON_CTRL, PHY_COMMON_CTRL_RESET); +	ns9750_mii_write (PHY_COMMON_CTRL, 0); + +	/* @TODO check time */ +	udelay (3000);		/* [2] p.70 says at least 300us reset recovery time. But +				   go sure, it didn't worked stable at higher timer +				   frequencies under LxNETES-2.x */ + +	/* MII clock has been setup to default, ns9750_mii_identify_phy should +	   work for all */ + +	if (!ns9750_mii_identify_phy ()) { +		printk (KERN_ERR NS9750_DRIVER_NAME +			": Unsupported PHY, aborting\n"); +		return 0; +	} + +	/* now take the highest MDIO clock possible after detection */ +	*get_eth_reg_addr (NS9750_ETH_MCFG) = +		ns9750_mii_get_clock_divisor (nPhyMaxMdioClock); + + +	/* PHY has been detected, so there can be no abort reason and we can +	   finish initializing ethernet */ + +	uiLastLinkStatus = 0xff;	/* undefined */ + +	if ((ucLinkMode & FS_EEPROM_AUTONEG_ENABLE_MASK) == +	    FS_EEPROM_AUTONEG_DISABLE) +		/* use parameters defined */ +		ns9750_link_force (); +	else +		ns9750_link_auto_negotiate (); + +	if (phyDetected == PHY_LXT971A) +		/* set LED2 to link mode */ +		ns9750_mii_write (PHY_LXT971_LED_CFG, +				  PHY_LXT971_LED_CFG_LINK_ACT << +				  PHY_LXT971_LED_CFG_SHIFT_LED2); + +	return 1; +} + +/*********************************************************************** + * @Function: ns9750_link_force + * @Return: void + * @Descr: configures eth and MII to use the link mode defined in + *	   ucLinkMode + ***********************************************************************/ + +static void ns9750_link_force (void) +{ +	unsigned short uiControl; + +	DEBUG_FN (DEBUG_LINK); + +	uiControl = ns9750_mii_read (PHY_COMMON_CTRL); +	uiControl &= ~(PHY_COMMON_CTRL_SPD_MA | +		       PHY_COMMON_CTRL_AUTO_NEG | PHY_COMMON_CTRL_DUPLEX); + +	uiLastLinkStatus = 0; + +	if ((ucLinkMode & FS_EEPROM_AUTONEG_SPEED_MASK) == +	    FS_EEPROM_AUTONEG_SPEED_100) { +		uiControl |= PHY_COMMON_CTRL_SPD_100; +		uiLastLinkStatus |= PHY_LXT971_STAT2_100BTX; +	} else +		uiControl |= PHY_COMMON_CTRL_SPD_10; + +	if ((ucLinkMode & FS_EEPROM_AUTONEG_DUPLEX_MASK) == +	    FS_EEPROM_AUTONEG_DUPLEX_FULL) { +		uiControl |= PHY_COMMON_CTRL_DUPLEX; +		uiLastLinkStatus |= PHY_LXT971_STAT2_DUPLEX_MODE; +	} + +	ns9750_mii_write (PHY_COMMON_CTRL, uiControl); + +	ns9750_link_print_changed (); +	ns9750_link_update_egcr (); +} + +/*********************************************************************** + * @Function: ns9750_link_auto_negotiate + * @Return: void + * @Descr: performs auto-negotation of link. + ***********************************************************************/ + +static void ns9750_link_auto_negotiate (void) +{ +	unsigned long ulStartJiffies; +	unsigned short uiStatus; + +	DEBUG_FN (DEBUG_LINK); + +	/* run auto-negotation */ +	/* define what we are capable of */ +	ns9750_mii_write (PHY_COMMON_AUTO_ADV, +			  PHY_COMMON_AUTO_ADV_100BTXFD | +			  PHY_COMMON_AUTO_ADV_100BTX | +			  PHY_COMMON_AUTO_ADV_10BTFD | +			  PHY_COMMON_AUTO_ADV_10BT | +			  PHY_COMMON_AUTO_ADV_802_3); +	/* start auto-negotiation */ +	ns9750_mii_write (PHY_COMMON_CTRL, +			  PHY_COMMON_CTRL_AUTO_NEG | +			  PHY_COMMON_CTRL_RES_AUTO); + +	/* wait for completion */ + +	ulStartJiffies = get_ticks (); +	while (get_ticks () < ulStartJiffies + NS9750_MII_NEG_DELAY) { +		uiStatus = ns9750_mii_read (PHY_COMMON_STAT); +		if ((uiStatus & +		     (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) == +		    (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) { +			/* lucky we are, auto-negotiation succeeded */ +			ns9750_link_print_changed (); +			ns9750_link_update_egcr (); +			return; +		} +	} + +	DEBUG_ARGS0 (DEBUG_LINK, "auto-negotiation timed out\n"); +	/* ignore invalid link settings */ +} + +/*********************************************************************** + * @Function: ns9750_link_update_egcr + * @Return: void + * @Descr: updates the EGCR and MAC2 link status after mode change or + *	   auto-negotation + ***********************************************************************/ + +static void ns9750_link_update_egcr (void) +{ +	unsigned int unEGCR; +	unsigned int unMAC2; +	unsigned int unIPGT; + +	DEBUG_FN (DEBUG_LINK); + +	unEGCR = *get_eth_reg_addr (NS9750_ETH_EGCR1); +	unMAC2 = *get_eth_reg_addr (NS9750_ETH_MAC2); +	unIPGT = *get_eth_reg_addr (NS9750_ETH_IPGT) & ~NS9750_ETH_IPGT_MA; + +	unMAC2 &= ~NS9750_ETH_MAC2_FULLD; +	if ((uiLastLinkStatus & PHY_LXT971_STAT2_DUPLEX_MODE) +	    == PHY_LXT971_STAT2_DUPLEX_MODE) { +		unMAC2 |= NS9750_ETH_MAC2_FULLD; +		unIPGT |= 0x15; /* see [1] p. 339 */ +	} else +		unIPGT |= 0x12; /* see [1] p. 339 */ + +	*get_eth_reg_addr (NS9750_ETH_MAC2) = unMAC2; +	*get_eth_reg_addr (NS9750_ETH_EGCR1) = unEGCR; +	*get_eth_reg_addr (NS9750_ETH_IPGT) = unIPGT; +} + +/*********************************************************************** + * @Function: ns9750_link_print_changed + * @Return: void + * @Descr: checks whether the link status has changed and if so prints + *	   the new mode + ***********************************************************************/ + +static void ns9750_link_print_changed (void) +{ +	unsigned short uiStatus; +	unsigned short uiControl; + +	DEBUG_FN (DEBUG_LINK); + +	uiControl = ns9750_mii_read (PHY_COMMON_CTRL); + +	if ((uiControl & PHY_COMMON_CTRL_AUTO_NEG) == +	    PHY_COMMON_CTRL_AUTO_NEG) { +		/* PHY_COMMON_STAT_LNK_STAT is only set on autonegotiation */ +		uiStatus = ns9750_mii_read (PHY_COMMON_STAT); + +		if (!(uiStatus & PHY_COMMON_STAT_LNK_STAT)) { +			printk (KERN_WARNING NS9750_DRIVER_NAME +				": link down\n"); +			/* @TODO Linux: carrier_off */ +		} else { +			/* @TODO Linux: carrier_on */ +			if (phyDetected == PHY_LXT971A) { +				uiStatus = ns9750_mii_read (PHY_LXT971_STAT2); +				uiStatus &= (PHY_LXT971_STAT2_100BTX | +					     PHY_LXT971_STAT2_DUPLEX_MODE | +					     PHY_LXT971_STAT2_AUTO_NEG); + +				/* mask out all uninteresting parts */ +			} +			/* other PHYs must store there link information in +			   uiStatus as PHY_LXT971 */ +		} +	} else { +		/* mode has been forced, so uiStatus should be the same as the +		   last link status, enforce printing */ +		uiStatus = uiLastLinkStatus; +		uiLastLinkStatus = 0xff; +	} + +	if (uiStatus != uiLastLinkStatus) { +		/* save current link status */ +		uiLastLinkStatus = uiStatus; + +		/* print new link status */ + +		printk (KERN_INFO NS9750_DRIVER_NAME +			": link mode %i Mbps %s duplex %s\n", +			(uiStatus & PHY_LXT971_STAT2_100BTX) ? 100 : 10, +			(uiStatus & PHY_LXT971_STAT2_DUPLEX_MODE) ? "full" : +			"half", +			(uiStatus & PHY_LXT971_STAT2_AUTO_NEG) ? "(auto)" : +			""); +	} +} + +/*********************************************************************** + * the MII low level stuff + ***********************************************************************/ + +/*********************************************************************** + * @Function: ns9750_mii_identify_phy + * @Return: 1 if supported PHY has been detected otherwise 0 + * @Descr: checks for supported PHY and prints the IDs. + ***********************************************************************/ + +static char ns9750_mii_identify_phy (void) +{ +	unsigned short uiID1; +	unsigned short uiID2; +	unsigned char *szName; +	char cRes = 0; + +	DEBUG_FN (DEBUG_MII); + +	phyDetected = (PhyType) uiID1 = ns9750_mii_read (PHY_COMMON_ID1); + +	switch (phyDetected) { +	case PHY_LXT971A: +		szName = "LXT971A"; +		uiID2 = ns9750_mii_read (PHY_COMMON_ID2); +		nPhyMaxMdioClock = PHY_LXT971_MDIO_MAX_CLK; +		cRes = 1; +		break; +	case PHY_NONE: +	default: +		/* in case uiID1 == 0 && uiID2 == 0 we may have the wrong +		   address or reset sets the wrong NS9750_ETH_MCFG_CLKS */ + +		uiID2 = 0; +		szName = "unknown"; +		nPhyMaxMdioClock = PHY_MDIO_MAX_CLK; +		phyDetected = PHY_NONE; +	} + +	printk (KERN_INFO NS9750_DRIVER_NAME +		": PHY (0x%x, 0x%x) = %s detected\n", uiID1, uiID2, szName); + +	return cRes; +} + +/*********************************************************************** + * @Function: ns9750_mii_read + * @Return: the data read from PHY register uiRegister + * @Descr: the data read may be invalid if timed out. If so, a message + *	   is printed but the invalid data is returned. + *	   The fixed device address is being used. + ***********************************************************************/ + +static unsigned short ns9750_mii_read (unsigned short uiRegister) +{ +	DEBUG_FN (DEBUG_MII_LOW); + +	/* write MII register to be read */ +	*get_eth_reg_addr (NS9750_ETH_MADR) = +		NS9750_ETH_PHY_ADDRESS << 8 | uiRegister; + +	*get_eth_reg_addr (NS9750_ETH_MCMD) = NS9750_ETH_MCMD_READ; + +	if (!ns9750_mii_poll_busy ()) +		printk (KERN_WARNING NS9750_DRIVER_NAME +			": MII still busy in read\n"); +	/* continue to read */ + +	*get_eth_reg_addr (NS9750_ETH_MCMD) = 0; + +	return (unsigned short) (*get_eth_reg_addr (NS9750_ETH_MRDD)); +} + + +/*********************************************************************** + * @Function: ns9750_mii_write + * @Return: nothing + * @Descr: writes the data to the PHY register. In case of a timeout, + *	   no special handling is performed but a message printed + *	   The fixed device address is being used. + ***********************************************************************/ + +static void ns9750_mii_write (unsigned short uiRegister, +			      unsigned short uiData) +{ +	DEBUG_FN (DEBUG_MII_LOW); + +	/* write MII register to be written */ +	*get_eth_reg_addr (NS9750_ETH_MADR) = +		NS9750_ETH_PHY_ADDRESS << 8 | uiRegister; + +	*get_eth_reg_addr (NS9750_ETH_MWTD) = uiData; + +	if (!ns9750_mii_poll_busy ()) { +		printf (KERN_WARNING NS9750_DRIVER_NAME +			": MII still busy in write\n"); +	} +} + + +/*********************************************************************** + * @Function: ns9750_mii_get_clock_divisor + * @Return: the clock divisor that should be used in NS9750_ETH_MCFG_CLKS + * @Descr: if no clock divisor can be calculated for the + *	   current SYSCLK and the maximum MDIO Clock, a warning is printed + *	   and the greatest divisor is taken + ***********************************************************************/ + +static unsigned int ns9750_mii_get_clock_divisor (unsigned int unMaxMDIOClk) +{ +	struct { +		unsigned int unSysClkDivisor; +		unsigned int unClks;	/* field for NS9750_ETH_MCFG_CLKS */ +	} PHYClockDivisors[] = { +		{ +		4, NS9750_ETH_MCFG_CLKS_4}, { +		6, NS9750_ETH_MCFG_CLKS_6}, { +		8, NS9750_ETH_MCFG_CLKS_8}, { +		10, NS9750_ETH_MCFG_CLKS_10}, { +		20, NS9750_ETH_MCFG_CLKS_20}, { +		30, NS9750_ETH_MCFG_CLKS_30}, { +		40, NS9750_ETH_MCFG_CLKS_40} +	}; + +	int nIndexSysClkDiv; +	int nArraySize = +		sizeof (PHYClockDivisors) / sizeof (PHYClockDivisors[0]); +	unsigned int unClks = NS9750_ETH_MCFG_CLKS_40;	/* defaults to +							   greatest div */ + +	DEBUG_FN (DEBUG_INIT); + +	for (nIndexSysClkDiv = 0; nIndexSysClkDiv < nArraySize; +	     nIndexSysClkDiv++) { +		/* find first sysclock divisor that isn't higher than 2.5 MHz +		   clock */ +		if (AHB_CLK_FREQ / +		    PHYClockDivisors[nIndexSysClkDiv].unSysClkDivisor <= +		    unMaxMDIOClk) { +			unClks = PHYClockDivisors[nIndexSysClkDiv].unClks; +			break; +		} +	} + +	DEBUG_ARGS2 (DEBUG_INIT, +		     "Taking MDIO Clock bit mask 0x%0x for max clock %i\n", +		     unClks, unMaxMDIOClk); + +	/* return greatest divisor */ +	return unClks; +} + +/*********************************************************************** + * @Function: ns9750_mii_poll_busy + * @Return: 0 if timed out otherwise the remaing timeout + * @Descr: waits until the MII has completed a command or it times out + *	   code may be interrupted by hard interrupts. + *	   It is not checked what happens on multiple actions when + *	   the first is still being busy and we timeout. + ***********************************************************************/ + +static unsigned int ns9750_mii_poll_busy (void) +{ +	unsigned int unTimeout = 10000; + +	DEBUG_FN (DEBUG_MII_LOW); + +	while (((*get_eth_reg_addr (NS9750_ETH_MIND) & NS9750_ETH_MIND_BUSY) +		== NS9750_ETH_MIND_BUSY) && unTimeout) +		unTimeout--; + +	return unTimeout; +} + +#endif /* CONFIG_DRIVER_NS9750_ETHERNET */ diff --git a/drivers/ns9750_serial.c b/drivers/ns9750_serial.c new file mode 100644 index 000000000..aced3dae8 --- /dev/null +++ b/drivers/ns9750_serial.c @@ -0,0 +1,212 @@ +/*********************************************************************** + * + * Copyright (C) 2004 by FS Forth-Systeme GmbH. + * All rights reserved. + * + * $Id: ns9750_serial.c,v 1.1 2004/02/16 10:37:20 mpietrek Exp $ + * @Author: Markus Pietrek + * @Descr: Serial driver for the NS9750. Only one UART is supported yet. + * @References: [1] NS9750 Hardware Reference/December 2003 + * @TODO: Implement Character GAP Timer when chip is fixed for PLL bypass + * + * 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> + +#ifdef CFG_NS9750_UART + +#include "ns9750_bbus.h"	/* for GPIOs */ +#include "ns9750_ser.h"		/* for serial configuration */ + +#define CONSOLE CONFIG_CONS_INDEX + +static unsigned int calcBitrateRegister( void ); +static unsigned int calcRxCharGapRegister( void ); + +static char cCharsAvailable; /* Numbers of chars in unCharCache */ +static unsigned int unCharCache; /* unCharCache is only valid if +				  * cCharsAvailable > 0 */ + +/*********************************************************************** + * @Function: serial_init + * @Return: 0 + * @Descr: configures GPIOs and UART. Requires BBUS Master Reset turned off + ***********************************************************************/ + +int serial_init( void ) +{ +	unsigned int aunGPIOTxD[] = { 0, 8, 40, 44 }; +	unsigned int aunGPIORxD[] = { 1, 9, 41, 45 }; + +	cCharsAvailable = 0; + +	/* configure TxD and RxD pins for their special function */ +	set_gpio_cfg_reg_val( aunGPIOTxD[ CONSOLE ], +			      NS9750_GPIO_CFG_FUNC_0 | NS9750_GPIO_CFG_OUTPUT ); +	set_gpio_cfg_reg_val( aunGPIORxD[ CONSOLE ], +			      NS9750_GPIO_CFG_FUNC_0 | NS9750_GPIO_CFG_INPUT ); + +	/* configure serial engine */ +	*get_ser_reg_addr_channel( NS9750_SER_CTRL_A, CONSOLE ) = +		NS9750_SER_CTRL_A_CE | +		NS9750_SER_CTRL_A_STOP | +		NS9750_SER_CTRL_A_WLS_8; + +	serial_setbrg(); + +	*get_ser_reg_addr_channel( NS9750_SER_CTRL_B, CONSOLE ) = +		NS9750_SER_CTRL_B_RCGT; + +	return 0; +} + +/*********************************************************************** + * @Function: serial_putc + * @Return: n/a + * @Descr: writes one character to the FIFO. Blocks until FIFO is not full + ***********************************************************************/ + +void serial_putc( const char c ) +{ +	if (c == '\n') +		serial_putc( '\r' ); + +	while (!(*get_ser_reg_addr_channel( NS9750_SER_STAT_A, CONSOLE) & +		 NS9750_SER_STAT_A_TRDY ) ) { +		/* do nothing, wait for characters in FIFO sent */ +	} + +	*(volatile char*) get_ser_reg_addr_channel( NS9750_SER_FIFO, +						    CONSOLE) = c; +} + +/*********************************************************************** + * @Function: serial_puts + * @Return: n/a + * @Descr: writes non-zero string to the FIFO. + ***********************************************************************/ + +void serial_puts( const char *s ) +{ +	while (*s) { +		serial_putc( *s++ ); +	} +} + +/*********************************************************************** + * @Function: serial_getc + * @Return: the character read + * @Descr: performs only 8bit accesses to the FIFO. No error handling + ***********************************************************************/ + +int serial_getc( void ) +{ +	int i; + +	while (!serial_tstc() ) { +		/* do nothing, wait for incoming characters */ +	} + +	/*  at least one character in unCharCache */ +	i = (int) (unCharCache & 0xff); + +	unCharCache >>= 8; +	cCharsAvailable--; + +	return i; +} + +/*********************************************************************** + * @Function: serial_tstc + * @Return: 0 if no input available, otherwise != 0 + * @Descr: checks for incoming FIFO not empty. Stores the incoming chars in + *	   unCharCache and the numbers of characters in cCharsAvailable + ***********************************************************************/ + +int serial_tstc( void ) +{ +	unsigned int unRegCache; + +	if ( cCharsAvailable ) +		return 1; + +	unRegCache = *get_ser_reg_addr_channel( NS9750_SER_STAT_A,CONSOLE ); +	if( unRegCache & NS9750_SER_STAT_A_RBC ) { +		*get_ser_reg_addr_channel( NS9750_SER_STAT_A, CONSOLE ) = +			NS9750_SER_STAT_A_RBC; +		unRegCache = *get_ser_reg_addr_channel( NS9750_SER_STAT_A, +							CONSOLE ); +	} + +	if ( unRegCache & NS9750_SER_STAT_A_RRDY ) { +		cCharsAvailable = (unRegCache & NS9750_SER_STAT_A_RXFDB_MA)>>20; +		if ( !cCharsAvailable ) +			cCharsAvailable = 4; + +		unCharCache = *get_ser_reg_addr_channel( NS9750_SER_FIFO, +							 CONSOLE ); +		return 1; +	} + +	/* no chars available */ +	return 0; +} + +void serial_setbrg( void ) +{ +	*get_ser_reg_addr_channel( NS9750_SER_BITRATE, CONSOLE ) = +		calcBitrateRegister(); +	*get_ser_reg_addr_channel( NS9750_SER_RX_CHAR_TIMER, CONSOLE ) = +		calcRxCharGapRegister(); +} + +/*********************************************************************** + * @Function: calcBitrateRegister + * @Return: value for the serial bitrate register + * @Descr: register value depends on clock frequency and baudrate + ***********************************************************************/ + +static unsigned int calcBitrateRegister( void ) +{ +	DECLARE_GLOBAL_DATA_PTR; + +	return ( NS9750_SER_BITRATE_EBIT | +		 NS9750_SER_BITRATE_CLKMUX_BCLK | +		 NS9750_SER_BITRATE_TMODE | +		 NS9750_SER_BITRATE_TCDR_16 | +		 NS9750_SER_BITRATE_RCDR_16 | +		 ( ( ( ( CONFIG_SYS_CLK_FREQ / 8 ) / /* BBUS clock,[1] Fig. 38 */ +		       ( gd->baudrate * 16 ) ) - 1 ) & +		   NS9750_SER_BITRATE_N_MA ) ); +} + +/*********************************************************************** + * @Function: calcRxCharGapRegister + * @Return: value for the character gap timer register + * @Descr: register value depends on clock frequency and baudrate. Currently 0 + *	   is used as there is a bug with the gap timer in PLL bypass mode. + ***********************************************************************/ + +static unsigned int calcRxCharGapRegister( void ) +{ +	DECLARE_GLOBAL_DATA_PTR; + +	return NS9750_SER_RX_CHAR_TIMER_TRUN; +} + +#endif /* CFG_NS9750_UART */ diff --git a/fs/fat/fat.c b/fs/fat/fat.c index daa70349d..6f1e57cbc 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -89,7 +89,8 @@ fat_register_device(block_dev_desc_t *dev_desc, int part_no)  		part_offset=0;  	}  	else { -#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI) +#if (CONFIG_COMMANDS & CFG_CMD_IDE) || (CONFIG_COMMANDS & CFG_CMD_SCSI) || \ +    (CONFIG_COMMANDS & CFG_CMD_USB)  		disk_partition_t info;  		if(!get_partition_info(dev_desc, part_no, &info)) {  			part_offset = info.start; diff --git a/include/configs/IceCube.h b/include/configs/IceCube.h index 888b16523..1dc992598 100644 --- a/include/configs/IceCube.h +++ b/include/configs/IceCube.h @@ -1,5 +1,5 @@  /* - * (C) Copyright 2003 + * (C) Copyright 2003-2004   * Wolfgang Denk, DENX Software Engineering, wd@denx.de.   *   * See file CREDITS for list of people who contributed to this @@ -81,11 +81,22 @@  #endif +/* USB */ +#if 1 +#define CONFIG_USB_OHCI +#define ADD_USB_CMD             CFG_CMD_USB | CFG_CMD_FAT +#define CONFIG_DOS_PARTITION +#define CONFIG_USB_STORAGE +#else +#define ADD_USB_CMD             0 +#endif +  /*   * Supported commands   */  #define CONFIG_COMMANDS		(CONFIG_CMD_DFL | ADD_PCI_CMD | \ -				 CFG_CMD_I2C | CFG_CMD_EEPROM) +				 CFG_CMD_I2C | CFG_CMD_EEPROM | \ +				 ADD_USB_CMD)  /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */  #include <cmd_confdefs.h> diff --git a/include/configs/eXalion.h b/include/configs/eXalion.h new file mode 100644 index 000000000..5ebc7a9cc --- /dev/null +++ b/include/configs/eXalion.h @@ -0,0 +1,454 @@ +/* + * (C) Copyright 2001 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * 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 + */ + +/* ------------------------------------------------------------------------- */ + +/* + * board/config.h - configuration options, board specific + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + * (easy to change) + */ + +#define CONFIG_MPC824X		1 +/* #define CONFIG_MPC8240	   1 */ +#define CONFIG_MPC8245		1 +#define CONFIG_EXALION		1 + +#if defined (CONFIG_MPC8240) +    /* #warning	 ---------- eXalion with MPC8240 --------------- */ +#elif defined (CONFIG_MPC8245) +    /* #warning	 ++++++++++ eXalion with MPC8245 +++++++++++++++ */ +#elif defined (CONFIG_MPC8245) && defined (CONFIG_MPC8245) +#error #### Both types of MPC824x defined (CONFIG_8240 and CONFIG_8245) +#else +#error #### Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240) +#endif +/* older kernels need clock in MHz newer in Hz */ +					/* #define CONFIG_CLOCKS_IN_MHZ 1 *//* clocks passsed to Linux in MHz	    */ +#undef CONFIG_CLOCKS_IN_MHZ + +#define CONFIG_BOOTDELAY	10 + + +						    /*#define CONFIG_DRAM_SPEED	      66   *//* MHz			     */ + +#define CONFIG_COMMANDS		(   CONFIG_CMD_DFL  | \ +				    CFG_CMD_FLASH   | \ +				    CFG_CMD_SDRAM   | \ +				    CFG_CMD_I2C	    | \ +				    CFG_CMD_IDE	    | \ +				    CFG_CMD_FAT	    | \ +				    CFG_CMD_ENV	    | \ +				    CFG_CMD_PCI ) + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any)	*/ +#include <cmd_confdefs.h> + + +/*----------------------------------------------------------------------- + * Miscellaneous configurable options + */ +#define CFG_LONGHELP		1	/* undef to save memory		*/ +#define CFG_PROMPT		"=> "	/* Monitor Command Prompt	*/ +#define CFG_CBSIZE		256	/* Console I/O Buffer Size	*/ +#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)	/* Print Buffer Size	*/ +#define CFG_MAXARGS		8	/* max number of command args	*/ +#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size	*/ +#define CFG_LOAD_ADDR		0x00100000	/* default load address		*/ + +#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 } + +#define CONFIG_MISC_INIT_R	1 + +/*----------------------------------------------------------------------- + * Start addresses for the final memory configuration + * (Set up by the startup code) + * Please note that CFG_SDRAM_BASE _must_ start at 0 + */ +#define CFG_SDRAM_BASE		0x00000000 +#define CFG_MAX_RAM_SIZE	0x10000000	/* 1 GBytes - initdram() will	   */ +					     /* return real value.		*/ + +#define CFG_RESET_ADDRESS	0xFFF00100 + +#undef	CFG_RAMBOOT +#define CFG_MONITOR_LEN		(256 << 10)	/* Reserve 256 kB for Monitor	    */ +#define CFG_MONITOR_BASE	TEXT_BASE + +/*----------------------------------------------------------------------- + * Definitions for initial stack pointer and data area + */ +#define CFG_INIT_DATA_SIZE	128 + +#define CFG_INIT_RAM_ADDR	0x40000000 +#define CFG_INIT_RAM_END	0x1000 +#define CFG_INIT_DATA_OFFSET	(CFG_INIT_RAM_END - CFG_INIT_DATA_SIZE) + +#define CFG_GBL_DATA_SIZE	 256	/* size in bytes reserved for initial data */ +#define CFG_GBL_DATA_OFFSET	(CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE) +#define CFG_INIT_SP_OFFSET	CFG_GBL_DATA_OFFSET + + +#if defined (CONFIG_MPC8240) +#define CFG_FLASH_BASE	    0xFFE00000 +#define CFG_FLASH_SIZE	    (2 * 1024 * 1024)	/* onboard 2MByte flash	    */ +#elif defined (CONFIG_MPC8245) +#define CFG_FLASH_BASE	    0xFFC00000 +#define CFG_FLASH_SIZE	    (4 * 1024 * 1024)	/* onboard 4MByte flash	    */ +#else +#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240) +#endif + +#define CFG_ENV_IS_IN_FLASH	1 +#define CFG_ENV_SECT_SIZE	0x20000 /* Size of one Flash sector */ +#define CFG_ENV_SIZE		CFG_ENV_SECT_SIZE	/* Use one Flash sector for enviroment	*/ +#define CFG_ENV_ADDR		0xFFFC0000 +#define CFG_ENV_OFFSET		0	/* starting right at the beginning  */ + +#define CFG_MALLOC_LEN		(128 * 1024)	/* Reserve 128 kB for malloc()	*/ + +#define CFG_ALT_MEMTEST		1	/* use real memory test	    */ +#define CFG_MEMTEST_START	0x00004000	/* memtest works on	    */ +#define CFG_MEMTEST_END		0x02000000	/* 0 ... 32 MB in DRAM	    */ + +#define CFG_EUMB_ADDR		0xFC000000 + +/* #define CFG_ISA_MEM		   0xFD000000 */ +#define CFG_ISA_IO		0xFE000000 + +/*----------------------------------------------------------------------- + * FLASH organization + */ +#define CFG_MAX_FLASH_BANKS	1	/* Max number of flash banks	    */ +#define CFG_MAX_FLASH_SECT	64	/* Max number of sectors per flash  */ + +#define CFG_FLASH_ERASE_TOUT	120000	/* Timeout for Flash Erase (in ms) */ +#define CFG_FLASH_WRITE_TOUT	500	/* Timeout for Flash Write (in ms) */ + +#define FLASH_BASE0_PRELIM	CFG_FLASH_BASE +#define FLASH_BASE1_PRELIM	0 + + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ + +#define CFG_FLASH_CFI		1	/* Flash is CFI conformant		*/ +#define CFG_FLASH_CFI_DRIVER	1	/* Use the common driver		*/ +#define CFG_MAX_FLASH_SECT	64	/* max number of sectors on one chip	*/ +#define CFG_MAX_FLASH_BANKS	1	/* max number of memory banks		*/ +#define CFG_FLASH_INCREMENT	0	/* there is only one bank		*/ +#define CFG_FLASH_PROTECTION	1	/* use hardware protection		*/ +#define CFG_FLASH_USE_BUFFER_WRITE 1	/* use buffered writes (20x faster)	*/ + + +/*----------------------------------------------------------------------- + * PCI stuff + */ +#define CONFIG_PCI		1	/* include pci support		*/ +#undef	CONFIG_PCI_PNP + +#define CONFIG_NET_MULTI	1	/* Multi ethernet cards support */ + +#define CONFIG_EEPRO100		1 + +#define PCI_ENET0_MEMADDR	0x80000000	/* Intel 82559ER */ +#define PCI_ENET0_IOADDR	0x80000000 +#define PCI_ENET1_MEMADDR	0x81000000	/* Intel 82559ER */ +#define PCI_ENET1_IOADDR	0x81000000 +#define PCI_ENET2_MEMADDR	0x82000000	/* Broadcom BCM569xx */ +#define PCI_ENET2_IOADDR	0x82000000 +#define PCI_ENET3_MEMADDR	0x83000000	/* Broadcom BCM56xx */ +#define PCI_ENET3_IOADDR	0x83000000 + +/*----------------------------------------------------------------------- + * NS16550 Configuration + */ +#define CFG_NS16550		1 +#define CFG_NS16550_SERIAL	1 + +#define CONFIG_CONS_INDEX	1 +#define CONFIG_BAUDRATE		38400 + +#define CFG_NS16550_REG_SIZE	1 + +#if (CONFIG_CONS_INDEX == 1) +#define CFG_NS16550_CLK		1843200 /* COM1 only !	*/ +#else +#define CFG_NS16550_CLK ({ extern ulong get_bus_freq (ulong); get_bus_freq (0); }) +#endif + +#define CFG_NS16550_COM1	(CFG_ISA_IO + 0x3F8) +#define CFG_NS16550_COM2	(CFG_EUMB_ADDR + 0x4500) +#define CFG_NS16550_COM3	(CFG_EUMB_ADDR + 0x4600) + +/*----------------------------------------------------------------------- + * select i2c support configuration + * + * Supported configurations are {none, software, hardware} drivers. + * If the software driver is chosen, there are some additional + * configuration items that the driver uses to drive the port pins. + */ +#define CONFIG_HARD_I2C		1	/* To enable I2C support	*/ +#undef	CONFIG_SOFT_I2C		/* I2C bit-banged		*/ +#define CFG_I2C_SPEED		400000	/* I2C speed and slave address	*/ +#define CFG_I2C_SLAVE		0x7F + +/*----------------------------------------------------------------------- + * Low Level Configuration Settings + * (address mappings, register initial values, etc.) + * You should know what you are doing if you make changes here. + */ +#define CFG_HZ			1000 + +#define CONFIG_SYS_CLK_FREQ	33333333	/* external frequency to pll	*/ +#define CONFIG_PLL_PCI_TO_MEM_MULTIPLIER  2	/* for MPC8240 only		*/ + +				       /*#define CONFIG_133MHZ_DRAM	 1 *//* For 133 MHZ DRAM only !!!!!!!!!!!    */ + +#if defined (CONFIG_MPC8245) +/* Bit-field values for PMCR2.							*/ +#if defined (CONFIG_133MHZ_DRAM) +#define CFG_DLL_EXTEND		0x80	/* use DLL extended range - 133MHz only */ +#define CFG_PCI_HOLD_DEL	0x20	/* delay and hold timing - 133MHz only	*/ +#endif + +/* Bit-field values for MIOCR1.							*/ +#if !defined (CONFIG_133MHZ_DRAM) +#define CFG_DLL_MAX_DELAY	0x04	/*  longer DLL delay line - 66MHz only	*/ +#endif +/* Bit-field values for MIOCR2.							*/ +#define CFG_SDRAM_DSCD		0x20	/* SDRAM data in sample clock delay	*/ +					/*	- note bottom 3 bits MUST be 0	*/ +#endif + +/* Bit-field values for MCCR1.							*/ +#define CFG_ROMNAL		7	/*rom/flash next access time		*/ +#define CFG_ROMFAL	       11	/*rom/flash access time			*/ + +/* Bit-field values for MCCR2.							*/ +#define CFG_TSWAIT		0x5	/* Transaction Start Wait States timer	*/ +#if defined (CONFIG_133MHZ_DRAM) +#define CFG_REFINT		1300	/* no of clock cycles between CBR	*/ +#else  /* refresh cycles */ +#define CFG_REFINT		750 +#endif + +/* Burst To Precharge. Bits of this value go to MCCR3 and MCCR4.		*/ +#if defined (CONFIG_133MHZ_DRAM) +#define CFG_BSTOPRE		1023 +#else +#define CFG_BSTOPRE		250 +#endif + +/* Bit-field values for MCCR3.							*/ +/* the following are for SDRAM only						*/ + +#if defined (CONFIG_133MHZ_DRAM) +#define CFG_REFREC		9	/* Refresh to activate interval		*/ +#else +#define CFG_REFREC		5	/* Refresh to activate interval		*/ +#endif +#if defined (CONFIG_MPC8240) +#define CFG_RDLAT		2	/* data latency from read command	*/ +#endif + +/* Bit-field values for MCCR4.	*/ +#if defined (CONFIG_133MHZ_DRAM) +#define CFG_PRETOACT		3	/* Precharge to activate interval	*/ +#define CFG_ACTTOPRE		7	/* Activate to Precharge interval	*/ +#define CFG_ACTORW		5	/* Activate to R/W			*/ +#define CFG_SDMODE_CAS_LAT	3	/* SDMODE CAS latency			*/ +#else +#if 0 +#define CFG_PRETOACT		2	/* Precharge to activate interval	*/ +#define CFG_ACTTOPRE		3	/* Activate to Precharge interval	*/ +#define CFG_ACTORW		3	/* Activate to R/W			*/ +#define CFG_SDMODE_CAS_LAT	2	/* SDMODE CAS latency			*/ +#endif +#define CFG_PRETOACT		2	/* Precharge to activate interval	*/ +#define CFG_ACTTOPRE		5	/* Activate to Precharge interval	*/ +#define CFG_ACTORW		3	/* Activate to R/W			*/ +#define CFG_SDMODE_CAS_LAT	3	/* SDMODE CAS latency			*/ +#endif +#define CFG_SDMODE_WRAP		0	/* SDMODE wrap type			*/ +#define CFG_SDMODE_BURSTLEN	2	/* SDMODE Burst length 2=4, 3=8		*/ +#define CFG_REGDIMM		0 +#if defined (CONFIG_MPC8240) +#define CFG_REGISTERD_TYPE_BUFFER   0 +#elif defined (CONFIG_MPC8245) +#define CFG_REGISTERD_TYPE_BUFFER   1 +#define CFG_EXTROM		    0 +#else +#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240) +#endif + + +/*----------------------------------------------------------------------- + memory bank settings + * only bits 20-29 are actually used from these vales to set the + * start/end address the upper two bits will be 0, and the lower 20 + * bits will be set to 0x00000 for a start address, or 0xfffff for an + * end address + */ +#define CFG_BANK0_START		0x00000000 +#define CFG_BANK0_END		(CFG_MAX_RAM_SIZE - 1) +#define CFG_BANK0_ENABLE	1 +#define CFG_BANK1_START		0x3ff00000 +#define CFG_BANK1_END		0x3fffffff +#define CFG_BANK1_ENABLE	0 +#define CFG_BANK2_START		0x3ff00000 +#define CFG_BANK2_END		0x3fffffff +#define CFG_BANK2_ENABLE	0 +#define CFG_BANK3_START		0x3ff00000 +#define CFG_BANK3_END		0x3fffffff +#define CFG_BANK3_ENABLE	0 +#define CFG_BANK4_START		0x00000000 +#define CFG_BANK4_END		0x00000000 +#define CFG_BANK4_ENABLE	0 +#define CFG_BANK5_START		0x00000000 +#define CFG_BANK5_END		0x00000000 +#define CFG_BANK5_ENABLE	0 +#define CFG_BANK6_START		0x00000000 +#define CFG_BANK6_END		0x00000000 +#define CFG_BANK6_ENABLE	0 +#define CFG_BANK7_START		0x00000000 +#define CFG_BANK7_END		0x00000000 +#define CFG_BANK7_ENABLE	0 + +/*----------------------------------------------------------------------- + * Memory bank enable bitmask, specifying which of the banks defined above + are actually present. MSB is for bank #7, LSB is for bank #0. + */ +#define CFG_BANK_ENABLE		0x01 + +#if defined (CONFIG_MPC8240) +#define CFG_ODCR		0xDF	/* configures line driver impedances,	*/ +					/* see 8240 book for bit definitions	*/ +#elif defined (CONFIG_MPC8245) +#if defined (CONFIG_133MHZ_DRAM) +#define CFG_ODCR		0xFE	/* configures line driver impedances - 133MHz	*/ +#else +#define CFG_ODCR		0xDE	/* configures line driver impedances - 66MHz	*/ +#endif +#else +#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240) +#endif + +#define CFG_PGMAX		0x32	/* how long the 8240 retains the	*/ +					/* currently accessed page in memory	*/ +					/* see 8240 book for details		*/ + +/*----------------------------------------------------------------------- + * Block Address Translation (BAT) register settings. + */ +/* SDRAM 0 - 256MB */ +#define CFG_IBAT0L	(CFG_SDRAM_BASE | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT0U	(CFG_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP) + +/* stack in DCACHE @ 1GB (no backing mem) */ +#define CFG_IBAT1L	(CFG_INIT_RAM_ADDR | BATL_PP_10 | BATL_MEMCOHERENCE) +#define CFG_IBAT1U	(CFG_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP) + +/* PCI memory */ +#define CFG_IBAT2L	(0x80000000 | BATL_PP_10 | BATL_CACHEINHIBIT) +#define CFG_IBAT2U	(0x80000000 | BATU_BL_256M | BATU_VS | BATU_VP) + +/* Flash, config addrs, etc */ +#define CFG_IBAT3L	(0xF0000000 | BATL_PP_10 | BATL_CACHEINHIBIT) +#define CFG_IBAT3U	(0xF0000000 | BATU_BL_256M | BATU_VS | BATU_VP) + +#define CFG_DBAT0L	CFG_IBAT0L +#define CFG_DBAT0U	CFG_IBAT0U +#define CFG_DBAT1L	CFG_IBAT1L +#define CFG_DBAT1U	CFG_IBAT1U +#define CFG_DBAT2L	CFG_IBAT2L +#define CFG_DBAT2U	CFG_IBAT2U +#define CFG_DBAT3L	CFG_IBAT3L +#define CFG_DBAT3U	CFG_IBAT3U + + +/*----------------------------------------------------------------------- + * Cache Configuration + */ +#define CFG_CACHELINE_SIZE	32 +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#  define CFG_CACHELINE_SHIFT	5	/* log base 2 of the above value */ +#endif + + +/*----------------------------------------------------------------------- + * Internal Definitions + * + * Boot Flags + */ +#define BOOTFLAG_COLD		0x01	/* Normal Power-On: Boot from FLASH	*/ +#define BOOTFLAG_WARM		0x02	/* Software reboot			*/ + + +/* values according to the manual */ +#define CONFIG_DRAM_50MHZ	1 +#define CONFIG_SDRAM_50MHZ + +#undef	NR_8259_INTS +#define NR_8259_INTS		1 + +/*----------------------------------------------------------------------- + * IDE/ATA stuff + */ +#define CFG_IDE_MAXBUS	    1	/* max. 2 IDE busses	*/ +#define CFG_IDE_MAXDEVICE   (CFG_IDE_MAXBUS*1)	/* max. 2 drives per IDE bus */ + +#define CFG_ATA_BASE_ADDR   CFG_ISA_IO	/* base address */ +#define CFG_ATA_IDE0_OFFSET 0x01F0	/* ide0 offste */ +#define CFG_ATA_IDE1_OFFSET 0x0170	/* ide1 offset */ +#define CFG_ATA_DATA_OFFSET 0	/* data reg offset  */ +#define CFG_ATA_REG_OFFSET  0	/* reg offset */ +#define CFG_ATA_ALT_OFFSET  0x200	/* alternate register offset */ + +#define CONFIG_ATAPI + +#undef	CONFIG_IDE_8xx_DIRECT	/* no pcmcia interface required */ +#undef	CONFIG_IDE_LED		/* no led for ide supported	*/ +#undef	CONFIG_IDE_RESET	/* reset for ide supported...	 */ +#undef	CONFIG_IDE_RESET_ROUTINE	/* with a special reset function */ + +/*----------------------------------------------------------------------- + * DISK Partition support + */ +#define CONFIG_DOS_PARTITION + +/*----------------------------------------------------------------------- + * For booting Linux, the board info and command line data + * have to be in the first 8 MB of memory, since this is + * the maximum mapped by the Linux kernel during initialization. + */ +#define CFG_BOOTMAPSZ		(8 << 20)	/* Initial Memory map for Linux */ + +#endif /* __CONFIG_H */ diff --git a/include/configs/ns9750dev.h b/include/configs/ns9750dev.h new file mode 100644 index 000000000..11d21b20d --- /dev/null +++ b/include/configs/ns9750dev.h @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2004 by FS Forth-Systeme GmbH. + * All rights reserved. + * Markus Pietrek <mpietrek@fsforth.de> + * + * Configuation settings for the NetSilicon NS9750 DevBoard + * + * 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 + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * If we are developing, we might want to start armboot from ram + * so we MUST NOT initialize critical regs like mem-timing ... + */ +#define CONFIG_INIT_CRITICAL		/* undef for developing */ + +/* + * High Level Configuration Options + * (easy to change) + */ +#define CONFIG_ARM926EJS	1	/* This is an ARM926EJS Core	*/ +#define	CONFIG_NS9750		1	/* in an NetSilicon NS9750 SoC     */ +#define CONFIG_NS9750DEV	1	/* on an NetSilicon NS9750 DevBoard  */ + +/* input clock of PLL */ +#define CONFIG_SYS_CLK_FREQ	324403200 /* Don't use PLL. SW11-4 off */ + +#define CPU_CLK_FREQ		(CONFIG_SYS_CLK_FREQ/2) +#define AHB_CLK_FREQ		(CONFIG_SYS_CLK_FREQ/4) +#define BBUS_CLK_FREQ		(CONFIG_SYS_CLK_FREQ/8) + +#undef CONFIG_USE_IRQ			/* we don't need IRQ/FIQ stuff */ +/*@TODO #define CONFIG_STATUS_LED*/ +#define CONFIG_USE_IRQ + +/* + * Size of malloc() pool + */ +#define CFG_MALLOC_LEN		(CFG_ENV_SIZE + 128*1024) +#define CFG_GBL_DATA_SIZE       128     /* size in bytes reserved for initial +					 * data */ + +/* + * Hardware drivers + */ +#define CFG_NS9750_UART			1	/* use on-chip UART */ +#define CONFIG_DRIVER_NS9750_ETHERNET	1	/* use on-chip ethernet */ + +/* + * select serial console configuration + */ +#define CONFIG_CONS_INDEX          1 		/* Port B */ + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_BAUDRATE		38400 + +/*********************************************************** + * Command definition + ***********************************************************/ +#if 0 /* @TODO */ +#define CONFIG_COMMANDS \ +			(CONFIG_CMD_DFL	 | \ +			CFG_CMD_CACHE	 | \ +			/*CFG_CMD_NAND	 |*/ \ +			/*CFG_CMD_EEPROM |*/ \ +			/*CFG_CMD_I2C	 |*/ \ +			/*CFG_CMD_USB	 |*/ \ +			CFG_CMD_REGINFO  | \ +			CFG_CMD_DATE	 | \ +			CFG_CMD_ELF) +#else +#define CONFIG_COMMANDS \ +			(CONFIG_CMD_BDI | \ +			CFG_CMD_NET | \ +			CFG_CMD_PING	 | \ +			CFG_CMD_CONSOLE	 | \ +			CFG_CMD_LOADB	 | \ +			CFG_CMD_LOADS	 | \ +			CFG_CMD_MEMORY) +#endif + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> + +#define CONFIG_BOOTDELAY	3 +/*#define CONFIG_BOOTARGS    	"root=ramfs devfs=mount console=ttySA0,9600" */ + +#define CONFIG_ETHADDR		00:04:f3:ff:ff:fb /*@TODO unset */ +#define CONFIG_NETMASK          255.255.255.0 +#define CONFIG_IPADDR		192.168.42.30 +#define CONFIG_SERVERIP		192.168.42.1 + +/*#define CONFIG_BOOTFILE	"elinos-lart" */ +/*#define CONFIG_BOOTCOMMAND	"tftp; bootm" */ + +#if (CONFIG_COMMANDS & CFG_CMD_KGDB) +#define CONFIG_KGDB_BAUDRATE	115200		/* speed to run kgdb serial port */ +/* what's this ? it's not used anywhere */ +#define CONFIG_KGDB_SER_INDEX	1		/* which serial port to use */ +#endif + +/* + * Miscellaneous configurable options + */ +#define	CFG_LONGHELP				/* undef to save memory		*/ +#define	CFG_PROMPT		"NS9750DEV # "	/* Monitor Command Prompt	*/ +#define	CFG_CBSIZE		256		/* Console I/O Buffer Size	*/ +#define	CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */ +#define	CFG_MAXARGS		16		/* max number of command args	*/ +#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size	*/ + +#define CFG_MEMTEST_START	0x00000000	/* memtest works on	*/ +#define CFG_MEMTEST_END		0x00780000	/* 7,5 MB in DRAM	*/ /* @TODO */ + +#undef  CFG_CLKS_IN_HZ		/* everything, incl board info, in Hz */ + +#define	CFG_LOAD_ADDR		0x00600000	/* default load address	*/ /* @TODO */ + +#define	CFG_HZ			(CPU_CLK_FREQ/64) + +/* valid baudrates */ +#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 } + +#define NS9750_ETH_PHY_ADDRESS	(0x0000) + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE	(128*1024)	/* regular stack */ +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ	(4*1024)	/* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ	(4*1024)	/* FIQ stack */ +#endif + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +/* TODO */ +#define CONFIG_NR_DRAM_BANKS	2	   /* we have 1 bank of DRAM */ +#define PHYS_SDRAM_1		0x00000000 /* SDRAM Bank #1 */ +#define PHYS_SDRAM_1_SIZE	0x00800000 /* 8 MB */ +#define PHYS_SDRAM_2		0x10000000 /* SDRAM Bank #1 */ +#define PHYS_SDRAM_2_SIZE	0x00800000 /* 8 MB */ + +#define PHYS_FLASH_1		0x50000000 /* Flash Bank #1 */ + +#define CFG_FLASH_BASE		PHYS_FLASH_1 + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ + +/* @TODO*/ +#define CONFIG_AMD_LV400	1	/* uncomment this if you have a LV400 flash */ +#if 0 +#define CONFIG_AMD_LV800	1	/* uncomment this if you have a LV800 flash */ +#endif + +#define CFG_MAX_FLASH_BANKS	1	/* max number of memory banks */ +#ifdef CONFIG_AMD_LV800 +#define PHYS_FLASH_SIZE		0x00100000 /* 1MB */ +#define CFG_MAX_FLASH_SECT	(19)	/* max number of sectors on one chip */ +#define CFG_ENV_ADDR		(CFG_FLASH_BASE + 0x0F0000) /* addr of environment */ +#endif +#ifdef CONFIG_AMD_LV400 +#define PHYS_FLASH_SIZE		0x00080000 /* 512KB */ +#define CFG_MAX_FLASH_SECT	(11)	/* max number of sectors on one chip */ +#define CFG_ENV_ADDR		(CFG_FLASH_BASE + 0x070000) /* addr of environment */ +#endif + +/* timeout values are in ticks */ +#define CFG_FLASH_ERASE_TOUT	(5*CFG_HZ) /* Timeout for Flash Erase */ +#define CFG_FLASH_WRITE_TOUT	(5*CFG_HZ) /* Timeout for Flash Write */ + +/* @TODO */ +/*#define	CFG_ENV_IS_IN_FLASH	1*/ +#define CFG_ENV_IS_NOWHERE +#define CFG_ENV_SIZE		0x10000	/* Total Size of Environment Sector */ + +#ifdef CONFIG_STATUS_LED + +extern void __led_init(led_id_t mask, int state); +extern void __led_toggle(led_id_t mask); +extern void __led_set(led_id_t mask, int state); + +#endif /* CONFIG_STATUS_LED */ + +#endif	/* __CONFIG_H */ diff --git a/include/mpc5xxx.h b/include/mpc5xxx.h index 49951f597..8d4013a16 100644 --- a/include/mpc5xxx.h +++ b/include/mpc5xxx.h @@ -90,6 +90,7 @@  #define MPC5XXX_GPT		(CFG_MBAR + 0x0600)  #define MPC5XXX_GPIO		(CFG_MBAR + 0x0b00)  #define MPC5XXX_PCI		(CFG_MBAR + 0x0d00) +#define MPC5XXX_USB		(CFG_MBAR + 0x1000)  #define MPC5XXX_SDMA		(CFG_MBAR + 0x1200)  #define MPC5XXX_XLBARB		(CFG_MBAR + 0x1f00) @@ -132,6 +133,7 @@  #define MPC5XXX_CDM_JTAGID	(MPC5XXX_CDM + 0x0000)  #define MPC5XXX_CDM_PORCFG	(MPC5XXX_CDM + 0x0004)  #define MPC5XXX_CDM_CFG		(MPC5XXX_CDM + 0x000c) +#define MPC5XXX_CDM_48_FDC	(MPC5XXX_CDM + 0x0010)  #define MPC5XXX_CDM_SRESET	(MPC5XXX_CDM + 0x0020)  /* Local Plus Bus interface */ diff --git a/include/ns9750_bbus.h b/include/ns9750_bbus.h new file mode 100644 index 000000000..0918931cb --- /dev/null +++ b/include/ns9750_bbus.h @@ -0,0 +1,125 @@ +/*********************************************************************** + * + * Copyright (C) 2004 by FS Forth-Systeme GmbH. + * All rights reserved. + * + * $Id: ns9750_bbus.h,v 1.1 2004/02/16 10:37:20 mpietrek Exp $ + * @Author: Markus Pietrek + * @Descr: Definitions for BBus usage + * @References: [1] NS9750 Hardware Reference Manual/December 2003 Chap. 10 + * + * 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 + * + * + ***********************************************************************/ + +#ifndef FS_NS9750_BBUS_H +#define FS_NS9750_BBUS_H + +#define NS9750_BBUS_MODULE_BASE		(0x90600000) + +#define get_bbus_reg_addr(c) \ +	((volatile unsigned int *)(NS9750_BBUS_MODULE_BASE+(unsigned int) (c))) + +/* We have support for 50 GPIO pins */ + +#define get_gpio_cfg_reg_addr(pin) \ +	get_bbus_reg_addr( NS9750_BBUS_GPIO_CFG_BASE + (((pin) >> 3) * 4) ) + +/* To Read/Modify/Write a pin configuration register, use it like +   set_gpio_cfg_reg_val( 12, NS9750_GPIO_CFG_FUNC_GPIO|NS9750_GPIO_CFG_OUTPUT ); +   They should be wrapped by cli()/sti() */ +#define set_gpio_cfg_reg_val(pin,cfg) \ +	*get_gpio_cfg_reg_addr(pin)=(*get_gpio_cfg_reg_addr((pin)) & \ +				 	~NS9750_GPIO_CFG_MASK((pin))) |\ +				NS9750_GPIO_CFG_VAL((pin),(cfg)); + +#define NS9750_GPIO_CFG_MASK(pin)	(NS9750_GPIO_CFG_VAL(pin, \ +					 NS9750_GPIO_CFG_MA)) +#define NS9750_GPIO_CFG_VAL(pin,cfg)	((cfg) << (((pin) % 8) * 4)) + +#define NS9750_GPIO_CFG_MA		(0x0F) +#define NS9750_GPIO_CFG_INPUT		(0x00) +#define NS9750_GPIO_CFG_OUTPUT		(0x08) +#define NS9750_GPIO_CFG_FUNC_GPIO	(0x03) +#define NS9750_GPIO_CFG_FUNC_2		(0x02) +#define NS9750_GPIO_CFG_FUNC_1		(0x01) +#define NS9750_GPIO_CFG_FUNC_0		(0x00) + +/* the register addresses */ + +#define NS9750_BBUS_MASTER_RESET	(0x00) +#define NS9750_BBUS_GPIO_CFG_BASE	(0x10) +#define NS9750_BBUS_GPIO_CTRL_BASE	(0x30) +#define NS9750_BBUS_GPIO_STAT_BASE	(0x40) +#define NS9750_BBUS_MONITOR		(0x50) +#define NS9750_BBUS_DMA_INT_STAT	(0x60) +#define NS9750_BBUS_DMA_INT_ENABLE	(0x64) +#define NS9750_BBUS_USB_CFG		(0x70) +#define NS9750_BBUS_ENDIAN_CFG		(0x80) +#define NS9750_BBUS_ARM_WAKE_UP		(0x90) + +/* register bit fields */ + +#define NS9750_BBUS_MASTER_RESET_UTIL	(0x00000100) +#define NS9750_BBUS_MASTER_RESET_I2C	(0x00000080) +#define NS9750_BBUS_MASTER_RESET_1284	(0x00000040) +#define NS9750_BBUS_MASTER_RESET_SER4	(0x00000020) +#define NS9750_BBUS_MASTER_RESET_SER3	(0x00000010) +#define NS9750_BBUS_MASTER_RESET_SER2	(0x00000008) +#define NS9750_BBUS_MASTER_RESET_SER1	(0x00000004) +#define NS9750_BBUS_MASTER_RESET_USB	(0x00000002) +#define NS9750_BBUS_MASTER_RESET_DMA	(0x00000001) + +/* BS9750_BBUS_DMA_INT_BINT* are valid for *DMA_INT_STAT and *DMA_INT_ENABLE */ + +#define NS9750_BBUS_DMA_INT_BINT16	(0x00010000) +#define NS9750_BBUS_DMA_INT_BINT15	(0x00008000) +#define NS9750_BBUS_DMA_INT_BINT14	(0x00004000) +#define NS9750_BBUS_DMA_INT_BINT13	(0x00002000) +#define NS9750_BBUS_DMA_INT_BINT12	(0x00001000) +#define NS9750_BBUS_DMA_INT_BINT11	(0x00000800) +#define NS9750_BBUS_DMA_INT_BINT10	(0x00000400) +#define NS9750_BBUS_DMA_INT_BINT9 	(0x00000200) +#define NS9750_BBUS_DMA_INT_BINT8 	(0x00000100) +#define NS9750_BBUS_DMA_INT_BINT7 	(0x00000080) +#define NS9750_BBUS_DMA_INT_BINT6 	(0x00000040) +#define NS9750_BBUS_DMA_INT_BINT5 	(0x00000020) +#define NS9750_BBUS_DMA_INT_BINT4 	(0x00000010) +#define NS9750_BBUS_DMA_INT_BINT3 	(0x00000008) +#define NS9750_BBUS_DMA_INT_BINT2 	(0x00000004) +#define NS9750_BBUS_DMA_INT_BINT1 	(0x00000002) +#define NS9750_BBUS_DMA_INT_BINT0 	(0x00000001) + +#define NS9750_BBUS_USB_CFG_OUTEN	(0x00000008) +#define NS9750_BBUS_USB_CFG_SPEED	(0x00000004) +#define NS9750_BBUS_USB_CFG_CFG_MA	(0x00000003) +#define NS9750_BBUS_USB_CFG_CFG_HOST_SOFT (0x00000003) +#define NS9750_BBUS_USB_CFG_CFG_DEVICE	(0x00000002) +#define NS9750_BBUS_USB_CFG_CFG_HOST	(0x00000001) +#define NS9750_BBUS_USB_CFG_CFG_DIS	(0x00000000) + +#define NS9750_BBUS_ENDIAN_CFG_AHBM	(0x00001000) +#define NS9750_BBUS_ENDIAN_CFG_I2C	(0x00000080) +#define NS9750_BBUS_ENDIAN_CFG_IEEE1284	(0x00000040) +#define NS9750_BBUS_ENDIAN_CFG_SER4	(0x00000020) +#define NS9750_BBUS_ENDIAN_CFG_SER3	(0x00000010) +#define NS9750_BBUS_ENDIAN_CFG_SER2	(0x00000008) +#define NS9750_BBUS_ENDIAN_CFG_SER1	(0x00000004) +#define NS9750_BBUS_ENDIAN_CFG_USB	(0x00000002) +#define NS9750_BBUS_ENDIAN_CFG_DMA	(0x00000001) + +#endif /* FS_NS9750_BBUS_H */ diff --git a/include/ns9750_eth.h b/include/ns9750_eth.h new file mode 100644 index 000000000..ce0c84183 --- /dev/null +++ b/include/ns9750_eth.h @@ -0,0 +1,526 @@ +/*********************************************************************** + * + * Copyright (C) 2004 by FS Forth-Systeme GmbH. + * All rights reserved. + * + * $Id: ns9750_eth.h,v 1.2 2004/02/24 13:25:39 mpietrek Exp $ + * @Author: Markus Pietrek + * @References: [1] NS9750 Hardware Reference, December 2003 + *              [2] Intel LXT971 Datasheet #249414 Rev. 02 + *              [3] NS7520 Linux Ethernet Driver + * + * 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 + * + ***********************************************************************/ + +#ifndef FS_NS9750_ETH_H +#define FS_NS9750_ETH_H + +#ifdef CONFIG_DRIVER_NS9750_ETHERNET + +#define	NS9750_ETH_MODULE_BASE	 	(0xA0600000) + +#define get_eth_reg_addr(c) \ +     ((volatile unsigned int*) ( NS9750_ETH_MODULE_BASE+(unsigned int) (c))) + +#define NS9750_ETH_EGCR1	 	(0x0000) +#define NS9750_ETH_EGCR2	 	(0x0004) +#define NS9750_ETH_EGSR		 	(0x0008) +#define NS9750_ETH_FIFORX	 	(0x000C) +#define NS9750_ETH_FIFOTX	 	(0x0010) +#define NS9750_ETH_FIFOTXS	 	(0x0014) +#define NS9750_ETH_ETSR		 	(0x0018) +#define NS9750_ETH_ERSR		 	(0x001C) +#define NS9750_ETH_MAC1			(0x0400) +#define NS9750_ETH_MAC2			(0x0404) +#define NS9750_ETH_IPGT			(0x0408) +#define NS9750_ETH_IPGR			(0x040C) +#define NS9750_ETH_CLRT			(0x0410) +#define NS9750_ETH_MAXF			(0x0414) +#define NS9750_ETH_SUPP			(0x0418) +#define NS9750_ETH_TEST			(0x041C) +#define NS9750_ETH_MCFG			(0x0420) +#define NS9750_ETH_MCMD			(0x0424) +#define NS9750_ETH_MADR			(0x0428) +#define NS9750_ETH_MWTD			(0x042C) +#define NS9750_ETH_MRDD			(0x0430) +#define NS9750_ETH_MIND			(0x0434) +#define NS9750_ETH_SA1			(0x0440) +#define NS9750_ETH_SA2			(0x0444) +#define NS9750_ETH_SA3			(0x0448) +#define NS9750_ETH_SAFR			(0x0500) +#define NS9750_ETH_HT1		 	(0x0504) +#define NS9750_ETH_HT2		 	(0x0508) +#define NS9750_ETH_STAT_BASE	 	(0x0680) +#define NS9750_ETH_RXAPTR		(0x0A00) +#define NS9750_ETH_RXBPTR		(0x0A04) +#define NS9750_ETH_RXCPTR		(0x0A08) +#define NS9750_ETH_RXDPTR		(0x0A0C) +#define NS9750_ETH_EINTR		(0x0A10) +#define NS9750_ETH_EINTREN		(0x0A14) +#define NS9750_ETH_TXPTR		(0x0A18) +#define NS9750_ETH_TXRPTR		(0x0A1C) +#define NS9750_ETH_TXERBD		(0x0A20) +#define NS9750_ETH_TXSPTR		(0x0A24) +#define NS9750_ETH_RXAOFF		(0x0A28) +#define NS9750_ETH_RXBOFF		(0x0A2C) +#define NS9750_ETH_RXCOFF		(0x0A30) +#define NS9750_ETH_RXDOFF		(0x0A34) +#define NS9750_ETH_TXOFF		(0x0A38) +#define NS9750_ETH_RXFREE		(0x0A3C) +#define NS9750_ETH_TXBD			(0x1000) + +/* register bit fields */ + +#define NS9750_ETH_EGCR1_ERX	 	(0x80000000) +#define NS9750_ETH_EGCR1_ERXDMA	 	(0x40000000) +#define NS9750_ETH_EGCR1_ERXSHT	 	(0x10000000) +#define NS9750_ETH_EGCR1_ERXSIZ	 	(0x08000000) +#define NS9750_ETH_EGCR1_ETXSIZ	 	(0x04000000) +#define NS9750_ETH_EGCR1_ETXDIAG	(0x02000000) +#define NS9750_ETH_EGCR1_ERXBAD	 	(0x01000000) +#define NS9750_ETH_EGCR1_ETX	 	(0x00800000) +#define NS9750_ETH_EGCR1_ETXDMA	 	(0x00400000) +#define NS9750_ETH_EGCR1_ETXWM	  	(0x00200000) +#define NS9750_ETH_EGCR1_ERXADV	 	(0x00100000) +#define NS9750_ETH_EGCR1_ERXINIT	(0x00080000) +#define NS9750_ETH_EGCR1_PHY_MODE_MA  	(0x0000C000) +#define NS9750_ETH_EGCR1_PHY_MODE_MII 	(0x00008000) +#define NS9750_ETH_EGCR1_PHY_MODE_RMII 	(0x00004000) +#define NS9750_ETH_EGCR1_RXCINV	 	(0x00001000) +#define NS9750_ETH_EGCR1_TXCINV	 	(0x00000800) +#define NS9750_ETH_EGCR1_RXALIGN	(0x00000400) +#define NS9750_ETH_EGCR1_MAC_HRST 	(0x00000200) +#define NS9750_ETH_EGCR1_ITXA	 	(0x00000100) + +#define NS9750_ETH_EGCR2_TPTV_MA	(0xFFFF0000) +#define NS9750_ETH_EGCR2_TPCF		(0x00000040) +#define NS9750_ETH_EGCR2_THPDF		(0x00000020) +#define NS9750_ETH_EGCR2_TCLER		(0x00000008) +#define NS9750_ETH_EGCR2_AUTOZ		(0x00000004) +#define NS9750_ETH_EGCR2_CLRCNT		(0x00000002) +#define NS9750_ETH_EGCR2_STEN		(0x00000001) + +#define NS9750_ETH_EGSR_RXINIT	 	(0x00100000) +#define NS9750_ETH_EGSR_TXFIFONF 	(0x00080000) +#define NS9750_ETH_EGSR_TXFIFOH	 	(0x00040000) +#define NS9750_ETH_EGSR_TXFIFOE	 	(0x00010000) + +#define NS9750_ETH_FIFOTXS_ALL		(0x00000055) +#define NS9750_ETH_FIFOTXS_3		(0x000000d5) +#define NS9750_ETH_FIFOTXS_2		(0x00000035) +#define NS9750_ETH_FIFOTXS_1		(0x0000000D) +#define NS9750_ETH_FIFOTXS_0		(0x00000003) + +#define NS9750_ETH_ETSR_TXOK	 	(0x00008000) +#define NS9750_ETH_ETSR_TXBR	 	(0x00004000) +#define NS9750_ETH_ETSR_TXMC	 	(0x00002000) +#define NS9750_ETH_ETSR_TXAL	 	(0x00001000) +#define NS9750_ETH_ETSR_TXAED	 	(0x00000800) +#define NS9750_ETH_ETSR_TXAEC	 	(0x00000400) +#define NS9750_ETH_ETSR_TXAUR	 	(0x00000200) +#define NS9750_ETH_ETSR_TXAJ	 	(0x00000100) +#define NS9750_ETH_ETSR_TXDEF	 	(0x00000040) +#define NS9750_ETH_ETSR_TXCRC	 	(0x00000020) +#define NS9750_ETH_ETSR_TXCOLC   	(0x0000000F) + +#define NS9750_ETH_ERSR_RXSIZE_MA	(0x0FFF0000) +#define NS9750_ETH_ERSR_RXCE	 	(0x00008000) +#define NS9750_ETH_ERSR_RXDV	 	(0x00004000) +#define NS9750_ETH_ERSR_RXOK	 	(0x00002000) +#define NS9750_ETH_ERSR_RXBR	 	(0x00001000) +#define NS9750_ETH_ERSR_RXMC	 	(0x00000800) +#define NS9750_ETH_ERSR_RXCRC	 	(0x00000400) +#define NS9750_ETH_ERSR_RXDR	 	(0x00000200) +#define NS9750_ETH_ERSR_RXCV	 	(0x00000100) +#define NS9750_ETH_ERSR_RXSHT	 	(0x00000040) + +#define NS9750_ETH_MAC1_SRST	 	(0x00008000) +#define NS9750_ETH_MAC1_SIMMRST	 	(0x00004000) +#define NS9750_ETH_MAC1_RPEMCSR	 	(0x00000800) +#define NS9750_ETH_MAC1_RPERFUN	 	(0x00000400) +#define NS9750_ETH_MAC1_RPEMCST	 	(0x00000200) +#define NS9750_ETH_MAC1_RPETFUN	 	(0x00000100) +#define NS9750_ETH_MAC1_LOOPBK	 	(0x00000010) +#define NS9750_ETH_MAC1_TXFLOW	 	(0x00000008) +#define NS9750_ETH_MAC1_RXFLOW	 	(0x00000004) +#define NS9750_ETH_MAC1_PALLRX	 	(0x00000002) +#define NS9750_ETH_MAC1_RXEN	 	(0x00000001) + +#define NS9750_ETH_MAC2_EDEFER	 	(0x00004000) +#define NS9750_ETH_MAC2_BACKP	 	(0x00002000) +#define NS9750_ETH_MAC2_NOBO	 	(0x00001000) +#define NS9750_ETH_MAC2_LONGP	 	(0x00000200) +#define NS9750_ETH_MAC2_PUREP	 	(0x00000100) +#define NS9750_ETH_MAC2_AUTOP	 	(0x00000080) +#define NS9750_ETH_MAC2_VLANP	 	(0x00000040) +#define NS9750_ETH_MAC2_PADEN  	 	(0x00000020) +#define NS9750_ETH_MAC2_CRCEN	 	(0x00000010) +#define NS9750_ETH_MAC2_DELCRC	 	(0x00000008) +#define NS9750_ETH_MAC2_HUGE	 	(0x00000004) +#define NS9750_ETH_MAC2_FLENC	 	(0x00000002) +#define NS9750_ETH_MAC2_FULLD	 	(0x00000001) + +#define NS9750_ETH_IPGT_MA	 	(0x0000007F) + +#define NS9750_ETH_IPGR_IPGR1	 	(0x00007F00) +#define NS9750_ETH_IPGR_IPGR2	 	(0x0000007F) + +#define NS9750_ETH_CLRT_CWIN	 	(0x00003F00) +#define	NS9750_ETH_CLRT_RETX	 	(0x0000000F) + +#define NS9750_ETH_MAXF_MAXF	 	(0x0000FFFF) + +#define NS9750_ETH_SUPP_RPERMII	 	(0x00008000) +#define NS9750_ETH_SUPP_SPEED  	 	(0x00000080) + +#define NS9750_ETH_TEST_TBACK	 	(0x00000004) +#define NS9750_ETH_TEST_TPAUSE	 	(0x00000002) +#define NS9750_ETH_TEST_SPQ	 	(0x00000001) + +#define NS9750_ETH_MCFG_RMIIM	 	(0x00008000) +#define NS9750_ETH_MCFG_CLKS_MA	 	(0x0000001C) +#define NS9750_ETH_MCFG_CLKS_4	 	(0x00000004) +#define NS9750_ETH_MCFG_CLKS_6	 	(0x00000008) +#define NS9750_ETH_MCFG_CLKS_8	 	(0x0000000C) +#define NS9750_ETH_MCFG_CLKS_10	 	(0x00000010) +#define NS9750_ETH_MCFG_CLKS_20	 	(0x00000014) +#define NS9750_ETH_MCFG_CLKS_30	 	(0x00000018) +#define NS9750_ETH_MCFG_CLKS_40	 	(0x0000001C) +#define NS9750_ETH_MCFG_SPRE	 	(0x00000002) +#define NS9750_ETH_MCFG_SCANI	 	(0x00000001) + +#define NS9750_ETH_MCMD_SCAN	 	(0x00000002) +#define NS9750_ETH_MCMD_READ	 	(0x00000001) + +#define NS9750_ETH_MADR_DADR_MA	 	(0x00001F00) +#define NS9750_ETH_MADR_RADR_MA	 	(0x0000001F) + +#define NS9750_ETH_MWTD_MA	 	(0x0000FFFF) + +#define NS9750_ETH_MRRD_MA	 	(0x0000FFFF) + +#define NS9750_ETH_MIND_MIILF		(0x00000008) +#define NS9750_ETH_MIND_NVALID		(0x00000004) +#define NS9750_ETH_MIND_SCAN	 	(0x00000002) +#define NS9750_ETH_MIND_BUSY	 	(0x00000001) + +#define NS9750_ETH_SA1_OCTET1_MA 	(0x0000FF00) +#define NS9750_ETH_SA1_OCTET2_MA 	(0x000000FF) + +#define NS9750_ETH_SA2_OCTET3_MA 	(0x0000FF00) +#define NS9750_ETH_SA2_OCTET4_MA 	(0x000000FF) + +#define NS9750_ETH_SA3_OCTET5_MA 	(0x0000FF00) +#define NS9750_ETH_SA3_OCTET6_MA 	(0x000000FF) + +#define NS9750_ETH_SAFR_PRO	 	(0x00000008) +#define NS9750_ETH_SAFR_PRM	 	(0x00000004) +#define NS9750_ETH_SAFR_PRA	 	(0x00000002) +#define NS9750_ETH_SAFR_BROAD	 	(0x00000001) + +#define NS9750_ETH_HT1_MA	 	(0x0000FFFF) + +#define NS9750_ETH_HT2_MA	 	(0x0000FFFF) + +/* also valid for EINTREN */ +#define NS9750_ETH_EINTR_RXOVL_DATA	(0x02000000) +#define NS9750_ETH_EINTR_RXOVL_STAT	(0x01000000) +#define NS9750_ETH_EINTR_RXBUFC		(0x00800000) +#define NS9750_ETH_EINTR_RXDONEA	(0x00400000) +#define NS9750_ETH_EINTR_RXDONEB	(0x00200000) +#define NS9750_ETH_EINTR_RXDONEC	(0x00100000) +#define NS9750_ETH_EINTR_RXDONED	(0x00080000) +#define NS9750_ETH_EINTR_RXNOBUF	(0x00040000) +#define NS9750_ETH_EINTR_RXBUFFUL	(0x00020000) +#define NS9750_ETH_EINTR_RXBR		(0x00010000) +#define NS9750_ETH_EINTR_STOVFL		(0x00000040) +#define NS9750_ETH_EINTR_TXPAUSE	(0x00000020) +#define NS9750_ETH_EINTR_TXBUFC		(0x00000010) +#define NS9750_ETH_EINTR_TXBUFNR	(0x00000008) +#define NS9750_ETH_EINTR_TXDONE		(0x00000004) +#define NS9750_ETH_EINTR_TXERR 		(0x00000002) +#define NS9750_ETH_EINTR_TXIDLE		(0x00000001) +#define NS9750_ETH_EINTR_RX_MA	\ +	(NS9750_ETH_EINTR_RXOVL_DATA | \ +	 NS9750_ETH_EINTR_RXOVL_STAT | \ +	 NS9750_ETH_EINTR_RXBUFC | \ +	 NS9750_ETH_EINTR_RXDONEA | \ +	 NS9750_ETH_EINTR_RXDONEB | \ +	 NS9750_ETH_EINTR_RXDONEC | \ +	 NS9750_ETH_EINTR_RXDONED | \ +	 NS9750_ETH_EINTR_RXNOBUF | \ +	 NS9750_ETH_EINTR_RXBUFFUL | \ +	 NS9750_ETH_EINTR_RXBR ) +#define NS9750_ETH_EINTR_TX_MA	\ +	(NS9750_ETH_EINTR_TXPAUSE | \ +	 NS9750_ETH_EINTR_TXBUFC | \ +	 NS9750_ETH_EINTR_TXBUFNR | \ +	 NS9750_ETH_EINTR_TXDONE | \ +	 NS9750_ETH_EINTR_TXERR | \ +	 NS9750_ETH_EINTR_TXIDLE) + +/* for TXPTR, TXRPTR, TXERBD and TXSPTR */ +#define NS9750_ETH_TXPTR_MA		(0x000000FF) + +/* for RXAOFF, RXBOFF, RXCOFF and RXDOFF */ +#define NS9750_ETH_RXOFF_MA		(0x000007FF) + +#define NS9750_ETH_TXOFF_MA		(0x000003FF) + +#define NS9750_ETH_RXFREE_D		(0x00000008) +#define NS9750_ETH_RXFREE_C		(0x00000004) +#define NS9750_ETH_RXFREE_B		(0x00000002) +#define NS9750_ETH_RXFREE_A		(0x00000001) + +/* PHY definitions (LXT971A) [2] */ + +#define PHY_COMMON_CTRL    	 	(0x00) +#define PHY_COMMON_STAT    	 	(0x01) +#define PHY_COMMON_ID1    	 	(0x02) +#define PHY_COMMON_ID2           	(0x03) +#define PHY_COMMON_AUTO_ADV      	(0x04) +#define PHY_COMMON_AUTO_LNKB     	(0x05) +#define PHY_COMMON_AUTO_EXP      	(0x06) +#define PHY_COMMON_AUTO_NEXT     	(0x07) +#define PHY_COMMON_AUTO_LNKN     	(0x08) +#define PHY_LXT971_PORT_CFG      	(0x10) +#define PHY_LXT971_STAT2         	(0x11) +#define PHY_LXT971_INT_ENABLE    	(0x12) +#define PHY_LXT971_INT_STATUS    	(0x13) +#define PHY_LXT971_LED_CFG       	(0x14) +#define PHY_LXT971_DIG_CFG       	(0x1A) +#define PHY_LXT971_TX_CTRL       	(0x1E) + +/* CTRL PHY Control Register Bit Fields */ + +#define PHY_COMMON_CTRL_RESET  	 	(0x8000) +#define PHY_COMMON_CTRL_LOOPBACK 	(0x4000) +#define PHY_COMMON_CTRL_SPD_MA   	(0x2040) +#define PHY_COMMON_CTRL_SPD_10   	(0x0000) +#define PHY_COMMON_CTRL_SPD_100  	(0x2000) +#define PHY_COMMON_CTRL_SPD_1000 	(0x0040) +#define PHY_COMMON_CTRL_SPD_RES  	(0x2040) +#define PHY_COMMON_CTRL_AUTO_NEG 	(0x1000) +#define PHY_COMMON_CTRL_POWER_DN 	(0x0800) +#define PHY_COMMON_CTRL_ISOLATE	 	(0x0400) +#define PHY_COMMON_CTRL_RES_AUTO 	(0x0200) +#define PHY_COMMON_CTRL_DUPLEX	 	(0x0100) +#define PHY_COMMON_CTRL_COL_TEST 	(0x0080) +#define PHY_COMMON_CTRL_RES1     	(0x003F) + +/* STAT Status Register Bit Fields */ + +#define PHY_COMMON_STAT_100BT4	 	(0x8000) +#define PHY_COMMON_STAT_100BXFD	 	(0x4000) +#define PHY_COMMON_STAT_100BXHD	 	(0x2000) +#define PHY_COMMON_STAT_10BTFD	 	(0x1000) +#define PHY_COMMON_STAT_10BTHD	 	(0x0800) +#define PHY_COMMON_STAT_100BT2FD 	(0x0400) +#define PHY_COMMON_STAT_100BT2HD 	(0x0200) +#define PHY_COMMON_STAT_EXT_STAT 	(0x0100) +#define PHY_COMMON_STAT_RES1	 	(0x0080) +#define PHY_COMMON_STAT_MF_PSUP	 	(0x0040) +#define PHY_COMMON_STAT_AN_COMP  	(0x0020) +#define PHY_COMMON_STAT_RMT_FLT	 	(0x0010) +#define PHY_COMMON_STAT_AN_CAP	 	(0x0008) +#define PHY_COMMON_STAT_LNK_STAT 	(0x0004) +#define PHY_COMMON_STAT_JAB_DTCT 	(0x0002) +#define PHY_COMMON_STAT_EXT_CAP	 	(0x0001) + + +/* AUTO_ADV Auto-neg Advert Register Bit Fields */ + +#define PHY_COMMON_AUTO_ADV_NP       	(0x8000) +#define PHY_COMMON_AUTO_ADV_RES1        (0x4000) +#define PHY_COMMON_AUTO_ADV_RMT_FLT     (0x2000) +#define PHY_COMMON_AUTO_ADV_RES2        (0x1000) +#define PHY_COMMON_AUTO_ADV_AS_PAUSE    (0x0800) +#define PHY_COMMON_AUTO_ADV_PAUSE       (0x0400) +#define PHY_COMMON_AUTO_ADV_100BT4      (0x0200) +#define PHY_COMMON_AUTO_ADV_100BTXFD   	(0x0100) +#define PHY_COMMON_AUTO_ADV_100BTX      (0x0080) +#define PHY_COMMON_AUTO_ADV_10BTFD   	(0x0040) +#define PHY_COMMON_AUTO_ADV_10BT     	(0x0020) +#define PHY_COMMON_AUTO_ADV_SEL_FLD_MA  (0x001F) +#define PHY_COMMON_AUTO_ADV_802_9       (0x0002) +#define PHY_COMMON_AUTO_ADV_802_3       (0x0001) + +/* AUTO_LNKB Auto-neg Link Ability Register Bit Fields */ + +#define PHY_COMMON_AUTO_LNKB_NP       	(0x8000) +#define PHY_COMMON_AUTO_LNKB_ACK        (0x4000) +#define PHY_COMMON_AUTO_LNKB_RMT_FLT    (0x2000) +#define PHY_COMMON_AUTO_LNKB_RES2       (0x1000) +#define PHY_COMMON_AUTO_LNKB_AS_PAUSE   (0x0800) +#define PHY_COMMON_AUTO_LNKB_PAUSE      (0x0400) +#define PHY_COMMON_AUTO_LNKB_100BT4     (0x0200) +#define PHY_COMMON_AUTO_LNKB_100BTXFD   (0x0100) +#define PHY_COMMON_AUTO_LNKB_100BTX     (0x0080) +#define PHY_COMMON_AUTO_LNKB_10BTFD   	(0x0040) +#define PHY_COMMON_AUTO_LNKB_10BT     	(0x0020) +#define PHY_COMMON_AUTO_LNKB_SEL_FLD_MA (0x001F) +#define PHY_COMMON_AUTO_LNKB_802_9      (0x0002) +#define PHY_COMMON_AUTO_LNKB_802_3      (0x0001) + +/* AUTO_EXP Auto-neg Expansion Register Bit Fields */ + +#define PHY_COMMON_AUTO_EXP_RES1        (0xFFC0) +#define PHY_COMMON_AUTO_EXP_BASE_PAGE   (0x0020) +#define PHY_COMMON_AUTO_EXP_PAR_DT_FLT  (0x0010) +#define PHY_COMMON_AUTO_EXP_LNK_NP_CAP  (0x0008) +#define PHY_COMMON_AUTO_EXP_NP_CAP      (0x0004) +#define PHY_COMMON_AUTO_EXP_PAGE_REC    (0x0002) +#define PHY_COMMON_AUTO_EXP_LNK_AN_CAP  (0x0001) + +/* AUTO_NEXT Aut-neg Next Page Tx Register Bit Fields */ + +#define PHY_COMMON_AUTO_NEXT_NP         (0x8000) +#define PHY_COMMON_AUTO_NEXT_RES1       (0x4000) +#define PHY_COMMON_AUTO_NEXT_MSG_PAGE   (0x2000) +#define PHY_COMMON_AUTO_NEXT_ACK_2      (0x1000) +#define PHY_COMMON_AUTO_NEXT_TOGGLE     (0x0800) +#define PHY_COMMON_AUTO_NEXT_MSG        (0x07FF) + +/* AUTO_LNKN Auto-neg Link Partner Rx Reg Bit Fields */ + +#define PHY_COMMON_AUTO_LNKN_NP         (0x8000) +#define PHY_COMMON_AUTO_LNKN_ACK        (0x4000) +#define PHY_COMMON_AUTO_LNKN_MSG_PAGE   (0x2000) +#define PHY_COMMON_AUTO_LNKN_ACK_2      (0x1000) +#define PHY_COMMON_AUTO_LNKN_TOGGLE     (0x0800) +#define PHY_COMMON_AUTO_LNKN_MSG        (0x07FF) + +/* PORT_CFG Port Configuration Register Bit Fields */ + +#define PHY_LXT971_PORT_CFG_RES1        (0x8000) +#define PHY_LXT971_PORT_CFG_FORCE_LNK   (0x4000) +#define PHY_LXT971_PORT_CFG_TX_DISABLE  (0x2000) +#define PHY_LXT971_PORT_CFG_BYPASS_SCR  (0x1000) +#define PHY_LXT971_PORT_CFG_RES2        (0x0800) +#define PHY_LXT971_PORT_CFG_JABBER      (0x0400) +#define PHY_LXT971_PORT_CFG_SQE	        (0x0200) +#define PHY_LXT971_PORT_CFG_TP_LOOPBACK (0x0100) +#define PHY_LXT971_PORT_CFG_CRS_SEL     (0x0080) +#define PHY_LXT971_PORT_CFG_SLEEP_MODE  (0x0040) +#define PHY_LXT971_PORT_CFG_PRE_EN      (0x0020) +#define PHY_LXT971_PORT_CFG_SLEEP_T_MA  (0x0018) +#define PHY_LXT971_PORT_CFG_SLEEP_T_104 (0x0010) +#define PHY_LXT971_PORT_CFG_SLEEP_T_200 (0x0001) +#define PHY_LXT971_PORT_CFG_SLEEP_T_304 (0x0000) +#define PHY_LXT971_PORT_CFG_FLT_CODE_EN (0x0004) +#define PHY_LXT971_PORT_CFG_ALT_NP      (0x0002) +#define PHY_LXT971_PORT_CFG_FIBER_SEL   (0x0001) + +/* STAT2 Status Register #2 Bit Fields */ + +#define PHY_LXT971_STAT2_RES1   	(0x8000) +#define PHY_LXT971_STAT2_100BTX 	(0x4000) +#define PHY_LXT971_STAT2_TX_STATUS	(0x2000) +#define PHY_LXT971_STAT2_RX_STATUS	(0x1000) +#define PHY_LXT971_STAT2_COL_STATUS	(0x0800) +#define PHY_LXT971_STAT2_LINK   	(0x0400) +#define PHY_LXT971_STAT2_DUPLEX_MODE	(0x0200) +#define PHY_LXT971_STAT2_AUTO_NEG	(0x0100) +#define PHY_LXT971_STAT2_AUTO_NEG_COMP 	(0x0080) +#define PHY_LXT971_STAT2_RES2   	(0x0040) +#define PHY_LXT971_STAT2_POLARITY	(0x0020) +#define PHY_LXT971_STAT2_PAUSE  	(0x0010) +#define PHY_LXT971_STAT2_ERROR  	(0x0008) +#define PHY_LXT971_STAT2_RES3   	(0x0007) + +/* INT_ENABLE Interrupt Enable Register Bit Fields */ + +#define PHY_LXT971_INT_ENABLE_RES1      (0xFF00) +#define PHY_LXT971_INT_ENABLE_ANMSK     (0x0080) +#define PHY_LXT971_INT_ENABLE_SPEEDMSK  (0x0040) +#define PHY_LXT971_INT_ENABLE_DUPLEXMSK (0x0020) +#define PHY_LXT971_INT_ENABLE_LINKMSK   (0x0010) +#define PHY_LXT971_INT_ENABLE_RES2      (0x000C) +#define PHY_LXT971_INT_ENABLE_INTEN     (0x0002) +#define PHY_LXT971_INT_ENABLE_TINT      (0x0001) + +/* INT_STATUS Interrupt Status Register Bit Fields */ + +#define PHY_LXT971_INT_STATUS_RES1      (0xFF00) +#define PHY_LXT971_INT_STATUS_ANDONE    (0x0080) +#define PHY_LXT971_INT_STATUS_SPEEDCHG  (0x0040) +#define PHY_LXT971_INT_STATUS_DUPLEXCHG (0x0020) +#define PHY_LXT971_INT_STATUS_LINKCHG   (0x0010) +#define PHY_LXT971_INT_STATUS_RES2      (0x0008) +#define PHY_LXT971_INT_STATUS_MDINT     (0x0004) +#define PHY_LXT971_INT_STATUS_RES3      (0x0003) + +/* LED_CFG Interrupt LED Configuration Register Bit Fields */ + +#define PHY_LXT971_LED_CFG_SHIFT_LED1   (0x000C) +#define PHY_LXT971_LED_CFG_SHIFT_LED2   (0x0008) +#define PHY_LXT971_LED_CFG_SHIFT_LED3   (0x0004) +#define PHY_LXT971_LED_CFG_LEDFREQ_MA	(0x000C) +#define PHY_LXT971_LED_CFG_LEDFREQ_RES	(0x000C) +#define PHY_LXT971_LED_CFG_LEDFREQ_100	(0x0008) +#define PHY_LXT971_LED_CFG_LEDFREQ_60	(0x0004) +#define PHY_LXT971_LED_CFG_LEDFREQ_30	(0x0000) +#define PHY_LXT971_LED_CFG_PULSE_STR    (0x0002) +#define PHY_LXT971_LED_CFG_RES1         (0x0001) + +/* only one of these values must be shifted for each SHIFT_LED?  */ + +#define PHY_LXT971_LED_CFG_UNUSED1      (0x000F) +#define PHY_LXT971_LED_CFG_DUPLEX_COL   (0x000E) +#define PHY_LXT971_LED_CFG_LINK_ACT     (0x000D) +#define PHY_LXT971_LED_CFG_LINK_RX      (0x000C) +#define PHY_LXT971_LED_CFG_TEST_BLK_SLW (0x000B) +#define PHY_LXT971_LED_CFG_TEST_BLK_FST (0x000A) +#define PHY_LXT971_LED_CFG_TEST_OFF     (0x0009) +#define PHY_LXT971_LED_CFG_TEST_ON      (0x0008) +#define PHY_LXT971_LED_CFG_RX_OR_TX     (0x0007) +#define PHY_LXT971_LED_CFG_UNUSED2      (0x0006) +#define PHY_LXT971_LED_CFG_DUPLEX       (0x0005) +#define PHY_LXT971_LED_CFG_LINK	        (0x0004) +#define PHY_LXT971_LED_CFG_COLLISION    (0x0003) +#define PHY_LXT971_LED_CFG_RECEIVE      (0x0002) +#define PHY_LXT971_LED_CFG_TRANSMIT     (0x0001) +#define PHY_LXT971_LED_CFG_SPEED        (0x0000) + +/* DIG_CFG Digitial Configuration Register Bit Fields */ + +#define PHY_LXT971_DIG_CFG_RES1 	(0xF000) +#define PHY_LXT971_DIG_CFG_MII_DRIVE	(0x0800) +#define PHY_LXT971_DIG_CFG_RES2 	(0x0400) +#define PHY_LXT971_DIG_CFG_SHOW_SYMBOL	(0x0200) +#define PHY_LXT971_DIG_CFG_RES3 	(0x01FF) + +#define PHY_LXT971_MDIO_MAX_CLK		(8000000) + +/* TX_CTRL Transmit Control Register Bit Fields +   documentation is buggy for this register, therefore setting not included */ + +typedef enum +{ +	PHY_NONE    = 0x0000, /* no PHY detected yet */ +	PHY_LXT971A = 0x0013 +} PhyType; + +#define PHY_MDIO_MAX_CLK		(2500000) + +#ifndef NS9750_ETH_PHY_ADDRESS +# define NS9750_ETH_PHY_ADDRESS	 	(0x0001) /* suitable for UNC20 */ +#endif /* NETARM_ETH_PHY_ADDRESS */ + +#endif /* CONFIG_DRIVER_NS9750_ETHERNET */ + +#endif /* FS_NS9750_ETH_H */ diff --git a/include/ns9750_mem.h b/include/ns9750_mem.h new file mode 100644 index 000000000..44c8ddcdd --- /dev/null +++ b/include/ns9750_mem.h @@ -0,0 +1,172 @@ +/*********************************************************************** + * + * Copyright (C) 2004 by FS Forth-Systeme GmbH. + * All rights reserved. + * + * $Id: ns9750_mem.h,v 1.1 2004/02/16 10:37:20 mpietrek Exp $ + * @Author: Markus Pietrek + * @Descr: Definitions for Memory Control Module + * @References: [1] NS9750 Hardware Reference Manual/December 2003 Chap. 5 + * + * 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 + * + ***********************************************************************/ + +#ifndef FS_NS9750_MEM_H +#define FS_NS9750_SYS_H + +#define NS9750_MEM_MODULE_BASE		(0xA0700000) + +#define get_mem_reg_addr(c) \ +	((volatile unsigned int *)(NS9750_MEM_MODULE_BASE+(unsigned int) (c))) + +/* the register addresses */ + +#define NS9750_MEM_CTRL     		(0x0000) +#define NS9750_MEM_STATUS     		(0x0004) +#define NS9750_MEM_CFG     		(0x0008) +#define NS9750_MEM_DYN_CTRL 		(0x0020) +#define NS9750_MEM_DYN_REFRESH 		(0x0024) +#define NS9750_MEM_DYN_READ_CFG		(0x0028) +#define NS9750_MEM_DYN_TRP     		(0x0030) +#define NS9750_MEM_DYN_TRAS    		(0x0034) +#define NS9750_MEM_DYN_TSREX   		(0x0038) +#define NS9750_MEM_DYN_TAPR   		(0x003C) +#define NS9750_MEM_DYN_TDAL    		(0x0040) +#define NS9750_MEM_DYN_TWR     		(0x0044) +#define NS9750_MEM_DYN_TRC     		(0x0048) +#define NS9750_MEM_DYN_TRFC    		(0x004C) +#define NS9750_MEM_DYN_TXSR    		(0x0050) +#define NS9750_MEM_DYN_TRRD    		(0x0054) +#define NS9750_MEM_DYN_TMRD    		(0x0058) +#define NS9750_MEM_STAT_EXT_WAIT	(0x0080) +#define NS9750_MEM_DYN_CFG_BASE		(0x0100) +#define NS9750_MEM_DYN_RAS_CAS_BASE	(0x0104) +#define NS9750_MEM_STAT_CFG_BASE	(0x0200) +#define NS9750_MEM_STAT_WAIT_WEN_BASE	(0x0204) +#define NS9750_MEM_STAT_WAIT_OEN_BASE	(0x0208) +#define NS9750_MEM_STAT_WAIT_RD_BASE	(0x020C) +#define NS9750_MEM_STAT_WAIT_PAGE_BASE	(0x0210) +#define NS9750_MEM_STAT_WAIR_WR_BASE	(0x0214) +#define NS9750_MEM_STAT_WAIT_TURN_BASE	(0x0218) + +/* the vectored register addresses */ + +#define NS9750_MEM_DYN_CFG(c)		(NS9750_MEM_DYN_CFG_BASE + (c)*0x20) +#define NS9750_MEM_DYN_RAS_CAS(c)	(NS9750_MEM_DYN_RAS_CAS_BASE + (c)*0x20) +#define NS9750_MEM_STAT_CFG(c)		(NS9750_MEM_STAT_CFG_BASE + (c)*0x20) +#define NS9750_MEM_STAT_WAIT_WEN(c)	(NS9750_MEM_STAT_WAIT_WEN_BASE+(c)*0x20) +#define NS9750_MEM_STAT_WAIT_OEN(c)	(NS9750_MEM_STAT_WAIT_OEN_BASE+(c)*0x20) +#define NS9750_MEM_STAT_RD(c)		(NS9750_MEM_STAT_WAIT_RD_BASE+(c)*0x20) +#define NS9750_MEM_STAT_PAGE(c)		(NS9750_MEM_STAT_WAIT_PAGE_BASE+(c)*0x20) +#define NS9750_MEM_STAT_WR(c)		(NS9750_MEM_STAT_WAIT_WR_BASE+(c)*0x20) +#define NS9750_MEM_STAT_TURN(c)		(NS9750_MEM_STAT_WAIT_TURN_BASE+(c)*0x20) + +/* register bit fields */ + +#define NS9750_MEM_CTRL_L		(0x00000004) +#define NS9750_MEM_CTRL_M		(0x00000002) +#define NS9750_MEM_CTRL_E		(0x00000001) + +#define NS9750_MEM_STAT_SA		(0x00000004) +#define NS9750_MEM_STAT_S		(0x00000002) +#define NS9750_MEM_STAT_B		(0x00000001) + +#define NS9750_MEM_CFG_CLK		(0x00000010) +#define NS9750_MEM_CFG_N		(0x00000001) + +#define NS9750_MEM_DYN_CTRL_NRP		(0x00004000) +#define NS9750_MEM_DYN_CTRL_DP		(0x00002000) +#define NS9750_MEM_DYN_CTRL_I_MA	(0x00000180) +#define NS9750_MEM_DYN_CTRL_I_NORMAL	(0x00000000) +#define NS9750_MEM_DYN_CTRL_I_MODE	(0x00000080) +#define NS9750_MEM_DYN_CTRL_I_PALL	(0x00000100) +#define NS9750_MEM_DYN_CTRL_I_NOP	(0x00000180) +#define NS9750_MEM_DYN_CTRL_SR		(0x00000002) +#define NS9750_MEM_DYN_CTRL_CE		(0x00000001) + + +#define NS9750_MEM_DYN_REFRESH_MA	(0x000007FF) + +#define NS9750_MEM_DYN_READ_CFG_MA	(0x00000003) +#define NS9750_MEM_DYN_READ_CFG_DELAY0 	(0x00000001) +#define NS9750_MEM_DYN_READ_CFG_DELAY1  (0x00000002) +#define NS9750_MEM_DYN_READ_CFG_DELAY2	(0x00000003) + +#define NS9750_MEM_DYN_TRP_MA		(0x0000000F) + +#define NS9750_MEM_DYN_TRAS_MA		(0x0000000F) + +#define NS9750_MEM_DYN_TSREX_MA		(0x0000000F) + +#define NS9750_MEM_DYN_TAPR_MA		(0x0000000F) + +#define NS9750_MEM_DYN_TDAL_MA		(0x0000000F) + +#define NS9750_MEM_DYN_TWR_MA		(0x0000000F) + +#define NS9750_MEM_DYN_TRC_MA		(0x0000001F) + +#define NS9750_MEM_DYN_TRFC_MA		(0x0000001F) + +#define NS9750_MEM_DYN_TXSR_MA		(0x0000001F) + +#define NS9750_MEM_DYN_TRRD_MA		(0x0000000F) + +#define NS9750_MEM_DYN_TMRD_MA		(0x0000000F) + +#define NS9750_MEM_STAT_EXTW_WAIT_MA	(0x0000003F) + +#define NS9750_MEM_DYN_CFG_P		(0x00100000) +#define NS9750_MEM_DYN_CFG_BDMC		(0x00080000) +#define NS9750_MEM_DYN_CFG_AM		(0x00004000) +#define NS9750_MEM_DYN_CFG_AM_MA	(0x00001F80) +#define NS9750_MEM_DYN_CFG_MD		(0x00000018) + +#define NS9750_MEM_DYN_RAS_CAS_CAS_MA	(0x00000300) +#define NS9750_MEM_DYN_RAS_CAS_CAS_1 	(0x00000100) +#define NS9750_MEM_DYN_RAS_CAS_CAS_2 	(0x00000200) +#define NS9750_MEM_DYN_RAS_CAS_CAS_3 	(0x00000300) +#define NS9750_MEM_DYN_RAS_CAS_RAS_MA	(0x00000003) +#define NS9750_MEM_DYN_RAS_CAS_RAS_1	(0x00000001) +#define NS9750_MEM_DYN_RAS_CAS_RAS_2 	(0x00000002) +#define NS9750_MEM_DYN_RAS_CAS_RAS_3 	(0x00000003) + +#define NS9750_MEM_STAT_CFG_PSMC	(0x00100000) +#define NS9750_MEM_STAT_CFG_BSMC	(0x00080000) +#define NS9750_MEM_STAT_CFG_EW		(0x00000100) +#define NS9750_MEM_STAT_CFG_PB		(0x00000080) +#define NS9750_MEM_STAT_CFG_PC		(0x00000040) +#define NS9750_MEM_STAT_CFG_PM		(0x00000008) +#define NS9750_MEM_STAT_CFG_MW_MA	(0x00000003) +#define NS9750_MEM_STAT_CFG_MW_8	(0x00000000) +#define NS9750_MEM_STAT_CFG_MW_16      	(0x00000001) +#define NS9750_MEM_STAT_CFG_MW_32	(0x00000002) + +#define NS9750_MEM_STAT_WAIT_WEN_MA	(0x0000000F) + +#define NS9750_MEM_STAT_WAIT_OEN_MA	(0x0000000F) + +#define NS9750_MEM_STAT_WAIT_RD_MA	(0x0000001F) + +#define NS9750_MEM_STAT_WAIT_PAGE_MA	(0x0000001F) + +#define NS9750_MEM_STAT_WAIT_WR_MA	(0x0000001F) + +#define NS9750_MEM_STAT_WAIT_TURN_MA	(0x0000000F) + + +#endif /* FS_NS9750_MEM_H */ diff --git a/include/ns9750_ser.h b/include/ns9750_ser.h new file mode 100644 index 000000000..e6ff3e172 --- /dev/null +++ b/include/ns9750_ser.h @@ -0,0 +1,202 @@ +/*********************************************************************** + * + * Copyright (C) 2004 by FS Forth-Systeme GmbH. + * All rights reserved. + * + * $Id: ns9750_ser.h,v 1.1 2004/02/16 10:37:20 mpietrek Exp $ + * @Author: Markus Pietrek + * @References: [1] NS9750 Hardware Reference, December 2003 + * + * 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 + * + ***********************************************************************/ + +#ifndef FS_NS9750_SER_H +#define FS_NS9750_SER_H + +#define NS9750_SER_MODULE_BASE		(0x90200000) + +#define get_ser_reg_addr(c) \ +	((volatile unsigned int *)(NS9750_SER_MODULE_BASE+(unsigned int) (c))) + +#define get_ser_reg_addr_channel(reg,chan) \ +	get_ser_reg_addr((reg)+(((chan)<2)?0:0x00100000)+(((chan)&1)?0x40:0)) + +/* the register addresses */ + +#define NS9750_SER_CTRL_A		(0x00) +#define NS9750_SER_CTRL_B		(0x04) +#define NS9750_SER_STAT_A		(0x08) +#define NS9750_SER_BITRATE		(0x0C) +#define NS9750_SER_FIFO			(0x10) +#define NS9750_SER_RX_BUF_TIMER		(0x14) +#define NS9750_SER_RX_CHAR_TIMER	(0x18) +#define NS9750_SER_RX_MATCH		(0x1C) +#define NS9750_SER_RX_MATCH_MASK	(0x20) +#define NS9750_SER_FLOW_CTRL		(0x34) +#define NS9750_SER_FLOW_CTRL_FORCE	(0x38) + +/* register bit fields */ + +/* control A register */ + +#define NS9750_SER_CTRL_A_CE		(0x80000000) +#define NS9750_SER_CTRL_A_BRK		(0x40000000) +#define NS9750_SER_CTRL_A_STICKP	(0x20000000) +#define NS9750_SER_CTRL_A_EPS		(0x10000000) +#define NS9750_SER_CTRL_A_PE		(0x08000000) +#define NS9750_SER_CTRL_A_STOP		(0x04000000) +#define NS9750_SER_CTRL_A_WLS_MA	(0x03000000) +#define NS9750_SER_CTRL_A_WLS_5		(0x00000000) +#define NS9750_SER_CTRL_A_WLS_6		(0x01000000) +#define NS9750_SER_CTRL_A_WLS_7		(0x02000000) +#define NS9750_SER_CTRL_A_WLS_8		(0x03000000) +#define NS9750_SER_CTRL_A_CTSTX		(0x00800000) +#define NS9750_SER_CTRL_A_RTSRX		(0x00400000) +#define NS9750_SER_CTRL_A_RL		(0x00200000) +#define NS9750_SER_CTRL_A_LL		(0x00100000) +#define NS9750_SER_CTRL_A_RES		(0x000CF000) +#define NS9750_SER_CTRL_A_DTR		(0x00020000) +#define NS9750_SER_CTRL_A_RTS		(0x00010000) +#define NS9750_SER_CTRL_A_RIE_MA	(0x00000E00) +#define NS9750_SER_CTRL_A_ERXDMA	(0x00000100) +#define NS9750_SER_CTRL_A_RIC_MA	(0x000000E0) +#define NS9750_SER_CTRL_A_TIC_MA	(0x0000001E) +#define NS9750_SER_CTRL_A_ETXDMA 	(0x00000001) + +/* control B register */ + +#define NS9750_SER_CTRL_B_RDM1		(0x80000000) +#define NS9750_SER_CTRL_B_RDM2		(0x40000000) +#define NS9750_SER_CTRL_B_RDM3		(0x20000000) +#define NS9750_SER_CTRL_B_RDM4		(0x10000000) +#define NS9750_SER_CTRL_B_RBGT		(0x08000000) +#define NS9750_SER_CTRL_B_RCGT		(0x04000000) +#define NS9750_SER_CTRL_B_MODE_MA	(0x00300000) +#define NS9750_SER_CTRL_B_MODE_UART	(0x00000000) +#define NS9750_SER_CTRL_B_MODE_HDLC	(0x00100000) +#define NS9750_SER_CTRL_B_MODE_SPI_M	(0x00200000) +#define NS9750_SER_CTRL_B_MODE_SPI_S	(0x00300000) +#define NS9750_SER_CTRL_B_BITORDR	(0x00080000) +#define NS9750_SER_CTRL_B_RES		(0x0007703F) +#define NS9750_SER_CTRL_B_RTSTX		(0x00008000) +#define NS9750_SER_CTRL_B_ENDEC_MA	(0x00000FC0) + +/* status A register */ + +#define NS9750_SER_STAT_A_MATCH1	(0x80000000) +#define NS9750_SER_STAT_A_MATCH2	(0x40000000) +#define NS9750_SER_STAT_A_MATCH3	(0x20000000) +#define NS9750_SER_STAT_A_MATCH4	(0x10000000) +#define NS9750_SER_STAT_A_BGAP		(0x08000000) +#define NS9750_SER_STAT_A_CGAP		(0x04000000) +#define NS9750_SER_STAT_A_RXFDB_MA	(0x00300000) +#define NS9750_SER_STAT_A_RXFDB_FULL	(0x00000000) +#define NS9750_SER_STAT_A_RXFDB_1	(0x00100000) +#define NS9750_SER_STAT_A_RXFDB_2	(0x00200000) +#define NS9750_SER_STAT_A_RXFDB_3	(0x00300000) +#define NS9750_SER_STAT_A_DCD		(0x00080000) +#define NS9750_SER_STAT_A_RI		(0x00040000) +#define NS9750_SER_STAT_A_DSR		(0x00020000) +#define NS9750_SER_STAT_A_CTS		(0x00010000) +#define NS9750_SER_STAT_A_RBRK		(0x00008000) +#define NS9750_SER_STAT_A_RFE		(0x00004000) +#define NS9750_SER_STAT_A_RPE		(0x00002000) +#define NS9750_SER_STAT_A_ROVER		(0x00001000) +#define NS9750_SER_STAT_A_RRDY		(0x00000800) +#define NS9750_SER_STAT_A_RHALF		(0x00000400) +#define NS9750_SER_STAT_A_RBC		(0x00000200) +#define NS9750_SER_STAT_A_RFULL		(0x00000100) +#define NS9750_SER_STAT_A_DCDI		(0x00000080) +#define NS9750_SER_STAT_A_RII		(0x00000040) +#define NS9750_SER_STAT_A_DSRI		(0x00000020) +#define NS9750_SER_STAT_A_CTSI		(0x00000010) +#define NS9750_SER_STAT_A_TRDY		(0x00000008) +#define NS9750_SER_STAT_A_THALF		(0x00000004) +#define NS9750_SER_STAT_A_TBC		(0x00000002) +#define NS9750_SER_STAT_A_TEMPTY	(0x00000001) + +#define NS9750_SER_STAT_A_RX_COND_ERR ( NS9750_SER_STAT_A_RFE | \ +		 		        NS9750_SER_STAT_A_ROVER | \ +				        NS9750_SER_STAT_A_RPE ) +#define NS9750_SER_STAT_A_RX_COND_ALL ( NS9750_SER_STAT_A_RX_COND_ERR | \ +				        NS9750_SER_STAT_A_RBRK | \ +				        NS9750_SER_STAT_A_RRDY | \ +				    	NS9750_SER_STAT_A_RHALF | \ +				    	NS9750_SER_STAT_A_RBC | \ +				    	NS9750_SER_STAT_A_DCDI | \ +				    	NS9750_SER_STAT_A_RII | \ +				    	NS9750_SER_STAT_A_DSRI | \ +				    	NS9750_SER_STAT_A_CTSI ) +#define NS9750_SER_STAT_A_TX_COND_ALL ( NS9750_SER_STAT_A_TRDY | \ +				        NS9750_SER_STAT_A_THALF | \ +				        NS9750_SER_STAT_A_TBC | \ +				    	NS9750_SER_STAT_A_TEMPTY ) +/* bit rate register */ + +#define NS9750_SER_BITRATE_EBIT		 (0x80000000) +#define NS9750_SER_BITRATE_TMODE	 (0x40000000) +#define NS9750_SER_BITRATE_RXSRC	 (0x20000000) +#define NS9750_SER_BITRATE_TXSRC	 (0x10000000) +#define NS9750_SER_BITRATE_RXEXT	 (0x08000000) +#define NS9750_SER_BITRATE_TXEXT	 (0x04000000) +#define NS9750_SER_BITRATE_CLKMUX_MA	 (0x03000000) +#define NS9750_SER_BITRATE_CLKMUX_XTAL	 (0x00000000) +#define NS9750_SER_BITRATE_CLKMUX_BCLK	 (0x01000000) +#define NS9750_SER_BITRATE_CLKMUX_OUT1	 (0x02000000) +#define NS9750_SER_BITRATE_CLKMUX_OUT2	 (0x03000000) +#define NS9750_SER_BITRATE_TXCINV	 (0x00800000) +#define NS9750_SER_BITRATE_RXCINV	 (0x00400000) +#define NS9750_SER_BITRATE_TCDR_MA	 (0x00180000) +#define NS9750_SER_BITRATE_TCDR_1 	 (0x00000000) +#define NS9750_SER_BITRATE_TCDR_8 	 (0x00080000) +#define NS9750_SER_BITRATE_TCDR_16	 (0x00100000) +#define NS9750_SER_BITRATE_TCDR_32	 (0x00180000) +#define NS9750_SER_BITRATE_RCDR_MA	 (0x00070000) +#define NS9750_SER_BITRATE_RCDR_1 	 (0x00000000) +#define NS9750_SER_BITRATE_RCDR_8 	 (0x00020000) +#define NS9750_SER_BITRATE_RCDR_16	 (0x00040000) +#define NS9750_SER_BITRATE_RCDR_32	 (0x00060000) +#define NS9750_SER_BITRATE_TICS		 (0x00010000) +#define NS9750_SER_BITRATE_RICS		 (0x00008000) +#define NS9750_SER_BITRATE_N_MA		 (0x00007FFF) + +/* receive buffer gap timer */ + +#define NS9750_SER_RX_BUF_TIMER_TRUN	 (0x80000000) /* UART and SPI */ +#define NS9750_SER_RX_BUF_TIMER_BT_MA	 (0x0000FFFF) /* UART and SPI */ +#define NS9750_SER_RX_BUF_TIMER_MAXLEN_MA (0x0000FFFF) /* HDLC only */ + +/* receive character gap timer */ + +#define NS9750_SER_RX_CHAR_TIMER_TRUN	 (0x80000000) +#define NS9750_SER_RX_CHAR_TIMER_CT_MA	 (0x000FFFFF) + +/* receive match */ + +#define NS9750_SER_RX_MATCH_RDMB1_MA	 (0xFF000000) +#define NS9750_SER_RX_MATCH_RDMB2_MA	 (0x00FF0000) +#define NS9750_SER_RX_MATCH_RDMB3_MA	 (0x0000FF00) +#define NS9750_SER_RX_MATCH_RDMB4_MA	 (0x000000FF) + +/* receive match mask */ + +#define NS9750_SER_RX_MATCH_MASK_RDMB1_MA (0xFF000000) +#define NS9750_SER_RX_MATCH_MASK_RDMB2_MA (0x00FF0000) +#define NS9750_SER_RX_MATCH_MASK_RDMB3_MA (0x0000FF00) +#define NS9750_SER_RX_MATCH_MASK_RDMB4_MA (0x000000FF) + +#endif /* FS_NS9750_SER_H */ diff --git a/include/ns9750_sys.h b/include/ns9750_sys.h new file mode 100644 index 000000000..c563cada0 --- /dev/null +++ b/include/ns9750_sys.h @@ -0,0 +1,215 @@ +/*********************************************************************** + * + * Copyright (C) 2004 by FS Forth-Systeme GmbH. + * All rights reserved. + * + * $Id: ns9750_sys.h,v 1.1 2004/02/16 10:37:20 mpietrek Exp $ + * @Author: Markus Pietrek + * @Descr: Definitions for SYS Control Module + * @References: [1] NS9750 Hardware Reference Manual/December 2003 Chap. 4 + * + * 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 + * + ***********************************************************************/ + +#ifndef FS_NS9750_SYS_H +#define FS_NS9750_SYS_H + +#define NS9750_SYS_MODULE_BASE		(0xA0900000) + +#define get_sys_reg_addr(c) \ +	((volatile unsigned int *)(NS9750_SYS_MODULE_BASE+(unsigned int) (c))) + +/* the register addresses */ + +#define NS9750_SYS_AHB_GEN		(0x0000) +#define NS9750_SYS_BRC_BASE		(0x0004) +#define NS9750_SYS_AHB_TIMEOUT		(0x0014) +#define NS9750_SYS_AHB_ERROR1   	(0x0018) +#define NS9750_SYS_AHB_ERROR2   	(0x001C) +#define NS9750_SYS_AHB_MON    		(0x0020) +#define NS9750_SYS_TIMER_COUNT_BASE	(0x0044) +#define NS9750_SYS_TIMER_READ_BASE	(0x0084) +#define NS9750_SYS_INT_VEC_ADR_BASE	(0x00C4) +#define NS9750_SYS_INT_CFG_BASE		(0x0144) +#define NS9750_SYS_ISRADDR		(0x0164) +#define NS9750_SYS_INT_STAT_ACTIVE	(0x0168) +#define NS9750_SYS_INT_STAT_RAW		(0x016C) +#define NS9750_SYS_TIMER_INT_STAT	(0x0170) +#define NS9750_SYS_SW_WDOG_CFG		(0x0174) +#define NS9750_SYS_SW_WDOG_TIMER	(0x0178) +#define NS9750_SYS_CLOCK		(0x017C) +#define NS9750_SYS_RESET		(0x0180) +#define NS9750_SYS_MISC			(0x0184) +#define NS9750_SYS_PLL			(0x0188) +#define NS9750_SYS_ACT_INT_STAT		(0x018C) +#define NS9750_SYS_TIMER_CTRL_BASE	(0x0190) +#define NS9750_SYS_CS_DYN_BASE_BASE	(0x01D0) +#define NS9750_SYS_CS_DYN_MASK_BASE	(0x01D4) +#define NS9750_SYS_CS_STATIC_BASE_BASE	(0x01F0) +#define NS9750_SYS_CS_STATIC_MASK_BASE	(0x01F4) +#define NS9750_SYS_GEN_ID		(0x0210) +#define NS9750_SYS_EXT_INT_CTRL_BASE	(0x0214) + +/* the vectored register addresses */ + +#define NS9750_SYS_TIMER_COUNT(c)	(NS9750_SYS_TIMER_COUNT_BASE + (c)) +#define NS9750_SYS_TIMER_READ(c)	(NS9750_SYS_TIMER_READ_BASE + (c)) +#define NS9750_SYS_INT_VEC_ADR(c)	(NS9750_SYS_INT_VEC_ADR_BASE + (c)) +#define NS9750_SYS_TIMER_CTRL(c)	(NS9750_SYS_TIMER_CTRL_BASE + (c)) +/* CS_DYN start with 4 */ +#define NS9750_SYS_CS_DYN_BASE(c)	(NS9750_SYS_CS_DYN_BASE_BASE + ((c)-4)*2) +#define NS9750_SYS_CS_DYN_MASK(c)	(NS9750_SYS_CS_DYN_MASK_BASE + ((c)-4)*2) +/* CS_STATIC start with 0 */ +#define NS9750_SYS_CS_STATIC_BASE(c)	(NS9750_SYS_CS_STATIC_BASE_BASE + (c)*2) +#define NS9750_SYS_CS_STATIC_MASK(c)	(NS9750_SYS_CS_STATIC_MASK_BASE + (c)*2) +#define NS9750_SYS_EXT_INT_CTRL(c)	(NS9750_SYS_EXT_INT_CTRL + (c)) + +/* register bit fields */ + +#define NS9750_SYS_AHB_GEN_EXMAM	(0x00000001) + +/* need to be n*8bit to BRC channel */ +#define NS9750_SYS_BRC_CEB		(0x00000080) +#define NS9750_SYS_BRC_BRF_MA		(0x00000030) +#define NS9750_SYS_BRC_BRF_100		(0x00000000) +#define NS9750_SYS_BRC_BRF_75		(0x00000010) +#define NS9750_SYS_BRC_BRF_50		(0x00000020) +#define NS9750_SYS_BRC_BRF_25		(0x00000030) + +#define NS9750_SYS_AHB_TIMEOUT_BAT_MA	(0xFFFF0000) +#define NS9750_SYS_AHB_TIMEOUT_BMT_MA	(0x0000FFFF) + +#define NS9750_SYS_AHB_ERROR2_ABL	(0x00040000) +#define NS9750_SYS_AHB_ERROR2_AER	(0x00020000) +#define NS9750_SYS_AHB_ERROR2_ABM	(0x00010000) +#define NS9750_SYS_AHB_ERROR2_ABA	(0x00008000) +#define NS9750_SYS_AHB_ERROR2_HWRT	(0x00004000) +#define NS9750_SYS_AHB_ERROR2_HMID_MA	(0x00003C00) +#define NS9750_SYS_AHB_ERROR2_HTPC_MA	(0x000003C0) +#define NS9750_SYS_AHB_ERROR2_HSZ_MA	(0x00000038) +#define NS9750_SYS_AHB_ERROR2_RR_MA	(0x00000007) + +#define NS9750_SYS_AHB_MON_EIC		(0x00800000) +#define NS9750_SYS_AHB_MON_MBII		(0x00400000) +#define NS9750_SYS_AHB_MON_MBL_MA	(0x003FFFC0) +#define NS9750_SYS_AHB_MON_MBLDC	(0x00000020) +#define NS9750_SYS_AHB_MON_SERDC	(0x00000010) +#define NS9750_SYS_AHB_MON_BMTC_MA	(0x0000000C) +#define NS9750_SYS_AHB_MON_BMTC_RECORD	(0x00000000) +#define NS9750_SYS_AHB_MON_BMTC_GEN_IRQ	(0x00000004) +#define NS9750_SYS_AHB_MON_BMTC_GEN_RES	(0x00000008) +#define NS9750_SYS_AHB_MON_BATC_MA	(0x00000003) +#define NS9750_SYS_AHB_MON_BATC_RECORD	(0x00000000) +#define NS9750_SYS_AHB_MON_BATC_GEN_IRQ	(0x00000001) +#define NS9750_SYS_AHB_MON_BATC_GEN_RES	(0x00000002) + +/* need to be n*8bit to Int Level */ + +#define NS9750_SYS_INT_CFG_IE		(0x00000080) +#define NS9750_SYS_INT_CFG_IT    	(0x00000020) +#define NS9750_SYS_INT_CFG_IAD_MA	(0x0000001F) + +#define NS9750_SYS_TIMER_INT_STAT_MA 	(0x0000FFFF) + +#define NS9750_SYS_SW_WDOG_CFG_SWWE	(0x00000080) +#define NS9750_SYS_SW_WDOG_CFG_SWWI	(0x00000020) +#define NS9750_SYS_SW_WDOG_CFG_SWWIC	(0x00000010) +#define NS9750_SYS_SW_WDOG_CFG_SWTCS_MA	(0x00000007) +#define NS9750_SYS_SW_WDOG_CFG_SWTCS_2 	(0x00000000) +#define NS9750_SYS_SW_WDOG_CFG_SWTCS_4 	(0x00000001) +#define NS9750_SYS_SW_WDOG_CFG_SWTCS_8 	(0x00000002) +#define NS9750_SYS_SW_WDOG_CFG_SWTCS_16	(0x00000003) +#define NS9750_SYS_SW_WDOG_CFG_SWTCS_32	(0x00000004) +#define NS9750_SYS_SW_WDOG_CFG_SWTCS_64	(0x00000005) + +#define NS9750_SYS_CLOCK_LPCS_MA	(0x00000380) +#define NS9750_SYS_CLOCK_LPCS_1 	(0x00000000) +#define NS9750_SYS_CLOCK_LPCS_2 	(0x00000080) +#define NS9750_SYS_CLOCK_LPCS_4 	(0x00000100) +#define NS9750_SYS_CLOCK_LPCS_8 	(0x00000180) +#define NS9750_SYS_CLOCK_LPCS_EXT	(0x00000200) +#define NS9750_SYS_CLOCK_BBC		(0x00000040) +#define NS9750_SYS_CLOCK_LCC		(0x00000020) +#define NS9750_SYS_CLOCK_MCC		(0x00000010) +#define NS9750_SYS_CLOCK_PARBC		(0x00000008) +#define NS9750_SYS_CLOCK_PC		(0x00000004) +#define NS9750_SYS_CLOCK_MACC		(0x00000001) + +#define NS9750_SYS_RESET_SR		(0x80000000) +#define NS9750_SYS_RESET_I2CW		(0x00100000) +#define NS9750_SYS_RESET_CSE		(0x00080000) +#define NS9750_SYS_RESET_SMWE		(0x00040000) +#define NS9750_SYS_RESET_EWE		(0x00020000) +#define NS9750_SYS_RESET_PI3WE		(0x00010000) +#define NS9750_SYS_RESET_BBT		(0x00000040) +#define NS9750_SYS_RESET_LCDC		(0x00000020) +#define NS9750_SYS_RESET_MEMC		(0x00000010) +#define NS9750_SYS_RESET_PCIAR		(0x00000008) +#define NS9750_SYS_RESET_PCIM		(0x00000004) +#define NS9750_SYS_RESET_MACM		(0x00000001) + +#define NS9750_SYS_MISC_REV_MA		(0xFF000000) +#define NS9750_SYS_MISC_PCIA		(0x00002000) +#define NS9750_SYS_MISC_VDIS		(0x00001000) +#define NS9750_SYS_MISC_BMM		(0x00000800) +#define NS9750_SYS_MISC_CS1DB		(0x00000400) +#define NS9750_SYS_MISC_CS1DW_MA	(0x00000300) +#define NS9750_SYS_MISC_MCCM		(0x00000080) +#define NS9750_SYS_MISC_PMSS		(0x00000040) +#define NS9750_SYS_MISC_CS1P		(0x00000020) +#define NS9750_SYS_MISC_ENDM		(0x00000008) +#define NS9750_SYS_MISC_MBAR		(0x00000004) +#define NS9750_SYS_MISC_IRAM0		(0x00000001) + +#define NS9750_SYS_PLL_PLLBS		(0x02000000) +#define NS9750_SYS_PLL_PLLFS_MA		(0x01800000) +#define NS9750_SYS_PLL_PLLIS_MA		(0x00600000) +#define NS9750_SYS_PLL_PLLND_MA		(0x001F0000) +#define NS9750_SYS_PLL_PLLSW		(0x00008000) +#define NS9750_SYS_PLL_PLLBSSW		(0x00000200) +#define NS9750_SYS_PLL_FSEL_MA		(0x00000180) +#define NS9750_SYS_PLL_CPCC_MA		(0x00000060) +#define NS9750_SYS_PLL_NDSW_MA		(0x0000001F) + +#define NS9750_SYS_ACT_INT_STAT_MA 	(0x0000FFFF) + +#define NS9750_SYS_TIMER_CTRL_TEN	(0x00008000) +#define NS9750_SYS_TIMER_CTRL_INTC	(0x00000200) +#define NS9750_SYS_TIMER_CTRL_TLCS_MA	(0x000001C0) +#define NS9750_SYS_TIMER_CTRL_TLCS_1 	(0x00000000) +#define NS9750_SYS_TIMER_CTRL_TLCS_2 	(0x00000040) +#define NS9750_SYS_TIMER_CTRL_TLCS_4 	(0x00000080) +#define NS9750_SYS_TIMER_CTRL_TLCS_8 	(0x000000C0) +#define NS9750_SYS_TIMER_CTRL_TLCS_16	(0x00000100) +#define NS9750_SYS_TIMER_CTRL_TLCS_32	(0x00000140) +#define NS9750_SYS_TIMER_CTRL_TLCS_64	(0x00000180) +#define NS9750_SYS_TIMER_CTRL_TLCS_EXT	(0x000001C0) +#define NS9750_SYS_TIMER_CTRL_TM_MA	(0x00000030) +#define NS9750_SYS_TIMER_CTRL_TM_INT  	(0x00000000) +#define NS9750_SYS_TIMER_CTRL_TM_LOW 	(0x00000010) +#define NS9750_SYS_TIMER_CTRL_TM_HIGH	(0x00000020) +#define NS9750_SYS_TIMER_CTRL_INTS	(0x00000008) +#define NS9750_SYS_TIMER_CTRL_UDS	(0x00000004) +#define NS9750_SYS_TIMER_CTRL_TSZ	(0x00000002) +#define NS9750_SYS_TIMER_CTRL_REN	(0x00000001) + +#define NS9750_SYS_EXT_INT_CTRL_STS	(0x00000008) +#define NS9750_SYS_EXT_INT_CTRL_CLR	(0x00000004) +#define NS9750_SYS_EXT_INT_CTRL_PLTY	(0x00000002) +#define NS9750_SYS_EXT_INT_CTRL_LVEDG	(0x00000001) + +#endif /* FS_NS9750_SYS_H */ |