diff options
41 files changed, 6158 insertions, 28 deletions
| @@ -2,6 +2,13 @@  Changes for U-Boot 1.1.3:  ====================================================================== +* Patches by Richard Woodruff, 01 Oct 2004: +  add support for the TI OMAP2420 processor and its H4 reference +  board + +* Patch by Christian Pellegrin, 24 Sep 2004: +  Added support for NE2000 compatible (DP8390, DP83902) NICs. +  * Patch by Leif Lindholm, 23 Sep 2004:    add support for the AMD db1550 board diff --git a/MAINTAINERS b/MAINTAINERS index f54501670..732f67f16 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -382,6 +382,10 @@ Rishi Bhattacharya <rishi@ti.com>  	omap5912osk		ARM926EJS +Richard Woodruff <r-woodruff2@ti.com> +	 +	omap2420h4		ARM1136EJS +  David Müller <d.mueller@elsoft.ch>  	smdk2410		ARM920T @@ -158,6 +158,11 @@ LIST_ARM9="	\  "  ######################################################################### +## ARM11 Systems +######################################################################### +LIST_ARM11="omap2420h4" + +#########################################################################  ## Xscale Systems  ######################################################################### @@ -170,7 +175,11 @@ LIST_pxa="	\  LIST_ixp="ixdp425" -LIST_arm="${LIST_SA} ${LIST_ARM7} ${LIST_ARM9} ${LIST_pxa} ${LIST_ixp}" +LIST_arm="	\ +	${LIST_SA}							\ +	${LIST_ARM7} ${LIST_ARM9} ${LIST_ARM11}				\ +	${LIST_pxa} ${LIST_ixp}						\ +"  #########################################################################  ## MIPS Systems @@ -238,7 +247,7 @@ for arg in $@  do  	case "$arg" in  	ppc|5xx|5xxx|8xx|8220|824x|8260|85xx|4xx|7xx|74xx| \ -	arm|SA|ARM7|ARM9|pxa|ixp| \ +	arm|SA|ARM7|ARM9|ARM11|pxa|ixp| \  	microblaze| \  	mips| \  	nios|nios2| \ @@ -1403,6 +1403,12 @@ xm250_config	:	unconfig  xsengine_config :	unconfig  	@./mkconfig $(@:_config=) arm pxa xsengine +######################################################################### +## ARM1136 Systems +######################################################################### +omap2420h4_config :    unconfig +	@./mkconfig $(@:_config=) arm arm1136 omap2420h4 +  #========================================================================  # i386  #======================================================================== @@ -130,6 +130,7 @@ Directory Hierarchy:      - s3c24x0	Files specific to Samsung S3C24X0 CPUs    - arm925t	Files specific to ARM 925 CPUs    - arm926ejs	Files specific to ARM 926 CPUs +  - arm1136	Files specific to ARM 1136 CPUs    - at91rm9200	Files specific to Atmel AT91RM9200 CPUs    - i386	Files specific to i386 CPUs    - ixp		Files specific to Intel XScale IXP CPUs @@ -301,13 +302,13 @@ The following options need to be configured:  		ARM based boards:  		----------------- -		CONFIG_AT91RM9200DK,		CONFIG_CERF250,		CONFIG_DNP1110, -		CONFIG_EP7312,			CONFIG_H2_OMAP1610,	CONFIG_HHP_CRADLE, -		CONFIG_IMPA7,		CONFIG_INNOVATOROMAP1510,	CONFIG_INNOVATOROMAP1610, -		CONFIG_LART,			CONFIG_LPD7A400		CONFIG_LUBBOCK, -		CONFIG_OSK_OMAP5912,		CONFIG_SHANNON,		CONFIG_P2_OMAP730, -		CONFIG_SMDK2400,		CONFIG_SMDK2410,	CONFIG_TRAB, -		CONFIG_VCMA9 +		CONFIG_AT91RM9200DK,	CONFIG_CERF250,		CONFIG_DNP1110, +		CONFIG_EP7312,		CONFIG_H2_OMAP1610,	CONFIG_HHP_CRADLE, +		CONFIG_IMPA7,		CONFIG_INNOVATOROMAP1510, CONFIG_INNOVATOROMAP1610, +		CONFIG_LART,		CONFIG_LPD7A400		CONFIG_LUBBOCK, +		CONFIG_OSK_OMAP5912,	CONFIG_OMAP2420H4,	CONFIG_SHANNON, +		CONFIG_P2_OMAP730,	CONFIG_SMDK2400,	CONFIG_SMDK2410, +		CONFIG_TRAB,		CONFIG_VCMA9  		MicroBlaze based boards:  		------------------------ @@ -2177,7 +2178,7 @@ configurations; the following names are supported:  	FADS850SAR_config	omap1610h2_config	TQM850L_config  	FADS860T_config		omap1610inn_config	TQM855L_config  	FPS850L_config		omap5912osk_config	TQM860L_config -							WALNUT405_config +				omap2420h4_config	WALNUT405_config  							Yukon8220_config  							ZPC1900_config diff --git a/board/omap2420h4/Makefile b/board/omap2420h4/Makefile new file mode 100644 index 000000000..deab6b6d1 --- /dev/null +++ b/board/omap2420h4/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	:= omap2420h4.o flash.o mem.o sys_info.o +SOBJS	:= platform.o + +$(LIB):	$(OBJS) $(SOBJS) +	$(AR) crv $@ $^ + +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/omap2420h4/config.mk b/board/omap2420h4/config.mk new file mode 100644 index 000000000..1c770f30a --- /dev/null +++ b/board/omap2420h4/config.mk @@ -0,0 +1,26 @@ +# +# (C) Copyright 2004 +# Texas Instruments, <www.ti.com> +# +# TI H4 board with OMAP2420 (ARM1136) cpu +# see http://www.ti.com/ for more information on Texas Instruments +# +# H4 has 1 bank of 32MB or 64MB mDDR-SDRAM on CS0 +# H4 has 1 bank of 32MB or 00MB mDDR-SDRAM on CS1 +# Physical Address: +# 8000'0000 (bank0) +# A000/0000 (bank1) ES2 will be configurable +# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000 +# (mem base + reserved) + +# For use with external or internal boots. +# CONFIG_PARTIAL_SRAM must be defined to use this. +TEXT_BASE = 0x80e80000 + +# Used with full SRAM boot. +# This is either with a GP system or a signed boot image. +# easiest, and safest way to go if you can. +# Comment out //CONFIG_PARTIAL_SRAM for this one. +# +#TEXT_BASE = 0x40280000 + diff --git a/board/omap2420h4/flash.c b/board/omap2420h4/flash.c new file mode 100644 index 000000000..3b6a69f57 --- /dev/null +++ b/board/omap2420h4/flash.c @@ -0,0 +1,536 @@ +/* + * (C) Copyright 2001 + * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net + * + * (C) Copyright 2001-2004 + * 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 <asm/arch/sizes.h> +#include <linux/byteorder/swab.h> + +#define PHYS_FLASH_SECT_SIZE	SZ_128K +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, SZ_32K},		/* 4 * 32kBytes sectors */ +	{255, SZ_128K},		/* 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); +void flash_unlock(flash_info_t * info, int bank); +int flash_probe(void); + +/*----------------------------------------------------------------------- + */ + +/* see if flash is ok */ +int flash_probe(void) +{ +	return(flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[0])); +} + +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]); +			/* to reset the lock bit */ +			flash_unlock(&flash_info[i],i); +			break; +		case 1: +			flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]); +			flash_get_offsets (PHYS_FLASH_2, &flash_info[i]); +			/* to reset the lock bit */ +			flash_unlock(&flash_info[i],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; +} + +/*----------------------------------------------------------------------- + */ +void flash_unlock(flash_info_t * info, int bank) +{ +	int j; +	if (!bank) +		j=2;	/* leave 0,1 locked for boot bank */ +	else +		j=0;	/* get the whole bank for #2 */ + +	for (;j<CFG_MAX_FLASH_SECT;j++) { +		FPWV *addr = (FPWV *) (info->start[j]); +		if (addr == NULL) { +			printf("Warning Flash probe failed\n"); +			break; +		} +		flash_unprotect_sectors (addr); +		*addr = (FPW) 0x00500050;/* clear status register */ +		*addr = (FPW) 0x00FF00FF;/* resest to read mode */ +	} +} + +/*----------------------------------------------------------------------- + */ +static void flash_get_offsets (ulong base, flash_info_t * info) +{ +	int i; +	volatile int r;	 /* gcc 3.4.0-1 strangeness, need to follow up.*/ + +	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 > 254) { /* 255,256,257,258 */ +				r=i; +				info->start[i] = base + (((r-(int)255) * SZ_32K) + (255*PHYS_FLASH_SECT_SIZE)); +				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; +	/* mb();  this one makes ARM11 err go away, but I want it :) as a guide to problems */ + +	/* Write auto select command: read Manufacturer ID */ +	addr[0x5555] = (FPW) 0x00AA00AA; +	addr[0x2AAA] = (FPW) 0x00550055; +	addr[0x5555] = (FPW) 0x00900090; + +	mb (); +	value = addr[0] & 0xFF;	/* just looking for 89 (8989 is hw pat)*/ + +	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):	 /* 880D */ +		info->flash_id += FLASH_28F256L18T; +		info->sector_count = 259;	/*0-258*/ +		info->size = SZ_32M; +		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 prot, sect; +	ulong type, start, last; +	int rcode = 0; +#ifdef CONFIG_USE_IRQ +	int iflag; +#endif + +	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; + +#ifdef CONFIG_USE_IRQ +	/* Disable interrupts which might cause a timeout here */ +	iflag = disable_interrupts (); +#endif + +	/* 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"); +		} +	} +#ifdef CONFIG_USE_IRQ +	if (iflag) +		enable_interrupts(); +#endif + +	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; +#ifdef CONFIG_USE_IRQ +	int iflag; +#endif + +	/* Check if Flash is (sufficiently) erased */ +	if ((*addr & data) != data) { +		printf ("not erased at %08lx (%x)\n", (ulong) addr, *addr); +		return(2); +	} +	/* Disable interrupts which might cause a timeout here */ +#ifdef CONFIG_USE_IRQ +	iflag = disable_interrupts (); +#endif +	*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 */ + +#ifdef CONFIG_USE_IRQ +	if (iflag) +		enable_interrupts(); +#endif + +	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/omap2420h4/mem.c b/board/omap2420h4/mem.c new file mode 100644 index 000000000..a3b345360 --- /dev/null +++ b/board/omap2420h4/mem.c @@ -0,0 +1,306 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/arch/omap2420.h> +#include <asm/io.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> + +/************************************************************ + * sdelay() - simple spin loop.  Will be constant time as + *  its generally used in 12MHz bypass conditions only.  This + *  is necessary until timers are accessible. + * + *  not inline to increase chances its in cache when called + *************************************************************/ +void sdelay (unsigned long loops) +{ +	__asm__ volatile ("1:\n" +					  "subs %0, %1, #1\n" +					  "bne 1b":"=r" (loops):"0" (loops)); +} + +/********************************************************************************* + * prcm_init() - inits clocks for PRCM as defined in clocks.h (config II default). + *   -- called from SRAM, or Flash (using temp SRAM stack). + *********************************************************************************/ +void prcm_init(void) +{ +	u32 rev,div; +#ifdef CONFIG_PARTIAL_SRAM +	void (*f_lock_pll) (u32, u32, u32, u32); +	extern void *_end_vect, *_start; + +	f_lock_pll = (void *)((u32)&_end_vect - (u32)&_start + SRAM_VECT_CODE); +#endif + +	__raw_writel(0, CM_FCLKEN1_CORE);	   /* stop all clocks to reduce ringing */ +	__raw_writel(0, CM_FCLKEN2_CORE);	   /* may not be necessary */ +	__raw_writel(0, CM_ICLKEN1_CORE); +	__raw_writel(0, CM_ICLKEN2_CORE); + +	__raw_writel(DPLL_OUT, CM_CLKSEL2_PLL);	/* set DPLL out */ +	__raw_writel(MPU_DIV, CM_CLKSEL_MPU);	/* set MPU divider */ +	__raw_writel(DSP_DIV, CM_CLKSEL_DSP);	/* set dsp and iva dividers */ +	__raw_writel(GFX_DIV, CM_CLKSEL_GFX);	/* set gfx dividers */ + +	rev  = get_cpu_rev(); +	if (rev == CPU_2420_ES1 || rev ==  CPU_2422_ES1) +		div = BUS_DIV_ES1; +	else +		div	= BUS_DIV; +	__raw_writel(div, CM_CLKSEL1_CORE);/* set L3/L4/USB/Display/Vlnc/SSi dividers */ +	sdelay(1000); + +#ifndef CONFIG_PARTIAL_SRAM +	/* If running fully from SRAM this is OK.  The Flash bus drops out for just a little. +	 * but then comes back.  If running from Flash this sequence kills you, thus you need +	 * to run it using CONFIG_PARTIAL_SRAM. +	 */ +	__raw_writel(MODE_BYPASS_FAST, CM_CLKEN_PLL); /* go to bypass, fast relock */ +	wait_on_value(BIT0|BIT1, BIT1, CM_IDLEST_CKGEN, LDELAY); /* wait till in bypass */ + +	/* set clock selection and dpll dividers. */ +	__raw_writel(DPLL_VAL, CM_CLKSEL1_PLL);	 /* set pll for target rate */ +	__raw_writel(COMMIT_DIVIDERS, PRCM_CLKCFG_CTRL); /* commit dividers */ +	sdelay(10000); +	__raw_writel(DPLL_LOCK, CM_CLKEN_PLL); /* enable dpll */ +	sdelay(10000); +	wait_on_value(BIT0|BIT1, BIT2, CM_IDLEST_CKGEN, LDELAY);  /*wait for dpll lock */ +#else +/* if running from flash, need to jump to small relocated code area in SRAM. + * This is the only safe spot to do configurations from. + */ +	(*f_lock_pll)(PRCM_CLKCFG_CTRL, CM_CLKEN_PLL, DPLL_LOCK, CM_IDLEST_CKGEN); +#endif + +	__raw_writel(DPLL_LOCK|APLL_LOCK, CM_CLKEN_PLL);   /* enable apll */ +	wait_on_value(BIT8, BIT8, CM_IDLEST_CKGEN, LDELAY);	/* wait for apll lock */ +	sdelay(1000); +} + +/*********************************************** + * memif_init() - init the gpmc and sdrc + *  - early init routines, called from flash or + *  SRAM. + ***********************************************/ +void memif_init(void) +{ +	sdrc_init(); +#ifndef CONFIG_PARTIAL_SRAM  /* don't init if calling from flash */ +	gpmc_init(); +#endif +} + +/******************************************************** + *  mem_ok() - test used to see if timings are correct + *             for a part. Helps in gussing which part + *             we are currently using. + *******************************************************/ +u32 mem_ok(void) +{  u32 val; +	__raw_writel(0x0,OMAP2420_SDRC_CS0+0x400);  /* clear pos A */ +	__raw_writel(0x12345678, OMAP2420_SDRC_CS0);/* pattern to pos B */ +	val = __raw_readl(OMAP2420_SDRC_CS0+0x400); /* get pos A value */ +	if (val != 0)                               /* see if pos A value changed*/ +		return(0); +	else +		return(1); +} + +/******************************************************** + *  sdrc_init() - init the sdrc chip selects CS0 and CS1 + *  - early init routines, called from flash or + *  SRAM. + *******************************************************/ +void sdrc_init(void) +{ +	#define EARLY_INIT 1 +	do_sdrc_init(SDRC_CS0_OSET, EARLY_INIT);  /* only init up first bank here */ +} + +/********************************************************** + * do_sdrc_init(): initialize the SDRAM for use. + *  -called from low level code with stack only. + *  -code sets up SDRAM timing and muxing for 2422 or 2420. + *  -optimal settings can be placed here, or redone after i2c + *      inspection of board info + * + * !!! When ES1 comes out need to conditionalize RFR value!!! + **********************************************************/ +void do_sdrc_init(u32 offset, u32 early) +{ +	u32 cpu, bug=0, rev, shared=0, cs0=0, pmask=0,first=1; +	sdrc_data_t *sdata;	 /* do not change type */ + +	static const sdrc_data_t sdrc_2422 = +	{ +		H4_2422_SDRC_SHARING, H4_2422_SDRC_MDCFG_0, H4_2422_SDRC_ACTIM_CTRLA_0, +		H4_2422_SDRC_ACTIM_CTRLB_0, H4_2422_SDRC_RFR_CTRL_ES1, H4_2422_SDRC_MR_0, +		H4_2422_SDRC_DLLA_CTRL, H4_2422_SDRC_DLLB_CTRL +	}; +	static const sdrc_data_t sdrc_2420 = +	{ +		H4_2420_SDRC_SHARING, H4_2420_SDRC_MDCFG_0, H4_2420_SDRC_ACTIM_CTRLA_0, +		H4_2420_SDRC_ACTIM_CTRLB_0, H4_2420_SDRC_RFR_CTRL_ES1, H4_2420_SDRC_MR_0, +		H4_2420_SDRC_DLLA_CTRL, H4_2420_SDRC_DLLB_CTRL +	}; + +	if (offset == SDRC_CS0_OSET) +		cs0 = shared = 1;  /* int regs shared between both chip select */ + +	cpu = get_cpu_type(); + +	/* warning generated, though code generation is correct. this may bite later, but is ok for now. +	 *  there is only so much C code you can do on stack only operation. +	 */ +	if (cpu == CPU_2422) +		sdata = &sdrc_2422; +	else +		sdata = &sdrc_2420; +	__asm__ __volatile__("": : :"memory"); +#ifdef CONFIG_PARTIAL_SRAM +	/* u-boot is compiled to run in DDR at 8xxxxxxx.  If we use data here which is not pc relative +	 * we need to get the address correct.  We need to find the current flash mapping to dress up +	 * the initial pointer load.  As long as this is const data we should be ok. +	 */ +	if(early) +		sdata = (sdrc_data_t *)(((u32)sdata & 0x0003FFFF) | get_gpmc0_base()); +#endif + +	men_combo: + +	if (!early && get_mem_type() == DDR_COMBO) { /* combo part has a shared CKE signal, can't use feature */ +		pmask = BIT2; +		first = 0;	/* trigger ddr_combo init */ +	} + +	if (shared) { +		__raw_writel(__raw_readl(SMS_SYSCONFIG)|SMART_IDLE, SMS_SYSCONFIG); +		__raw_writel(SMART_IDLE|SOFTRESET, SDRC_SYSCONFIG);	/* reset sdrc */ +		wait_on_value(BIT0, BIT0, SDRC_STATUS, 12000000);	/* wait till reset done set */ +		__raw_writel(SMART_IDLE, SDRC_SYSCONFIG);		/* clear soft reset */ +		__raw_writel(sdata->sdrc_sharing, SDRC_SHARING); +		__raw_writel((__raw_readl(SDRC_POWER)|SMART_IDLE) & ~pmask, SDRC_POWER); +	} +	if (first) +		__raw_writel(sdata->sdrc_mdcfg_0, SDRC_MCFG_0+offset); +	else { +		__raw_writel((__raw_readl(SDRC_POWER)|SMART_IDLE) & ~pmask, SDRC_POWER); +		__raw_writel(H4_2420_COMBO_MDCFG_0,SDRC_MCFG_0+offset); +	} + +	if (cs0) { +		__raw_writel(sdata->sdrc_actim_ctrla_0, SDRC_ACTIM_CTRLA_0); +		__raw_writel(sdata->sdrc_actim_ctrlb_0, SDRC_ACTIM_CTRLB_0); +	} else { +		__raw_writel(sdata->sdrc_actim_ctrla_0, SDRC_ACTIM_CTRLA_1); +		__raw_writel(sdata->sdrc_actim_ctrlb_0, SDRC_ACTIM_CTRLB_1); +	} + +	__raw_writel(sdata->sdrc_rfr_ctrl, SDRC_RFR_CTRL+offset); + +	/* init sequence for _mDDR_ using manual commands (DDR is a bit different) */ +	__raw_writel(CMD_NOP, SDRC_MANUAL_0+offset); +	sdelay(5000);  /* susposed to be 100us per design spec for mddr*/ +	__raw_writel(CMD_PRECHARGE, SDRC_MANUAL_0+offset); +	__raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0+offset); +	__raw_writel(CMD_AUTOREFRESH, SDRC_MANUAL_0+offset); + +	/* +	 * CSx SDRC Mode Register +	 * Burst length = 4 - DDR memory +	 * Serial mode +	 * CAS latency = x +	 */ +	__raw_writel(sdata->sdrc_mr_0, SDRC_MR_0+offset); + +	/* NOTE: ES1 242x _BUG_ DLL */ +	rev  = get_cpu_rev(); +	if (rev == CPU_2420_ES1 || rev ==  CPU_2422_ES1) +		bug = BIT0; +	/* enable & load up DLL with good value for 75MHz, and set phase to 90% */ +	if (shared) { +		__raw_writel(sdata->sdrc_dlla_ctrl, SDRC_DLLA_CTRL); +		__raw_writel(sdata->sdrc_dlla_ctrl & ~(BIT2|bug), SDRC_DLLA_CTRL); +		__raw_writel(sdata->sdrc_dllb_ctrl, SDRC_DLLB_CTRL); +		__raw_writel(sdata->sdrc_dllb_ctrl & ~(BIT2|bug) , SDRC_DLLB_CTRL); +	} +	sdelay(9000); +	if (!first || mem_ok())	/* passed test or 2nd bank init */ +		return; +	else { +		first = 0; +		goto men_combo; +	} +} + + +/***************************************************** + * gpmc_init(): init gpmc bus + * Init GPMC for x16, MuxMode (SDRAM in x32). + * This code can only be executed from SRAM or SDRAM. + *****************************************************/ +void gpmc_init(void) +{ +	u32 mux=0, mtype, mwidth; + +	/* global settings */ +	__raw_writel(0x10, GPMC_SYSCONFIG);	/* smart idle */ +	__raw_writel(0x0, GPMC_IRQENABLE);	/* isr's sources masked */ +	__raw_writel(0x1, GPMC_TIMEOUT_CONTROL);/* timeout disable */ +	__raw_writel(0x111, GPMC_CONFIG);	/* set nWP, disable limited addr */ + +	/* discover bus connection from sysboot */ +	if (is_gpmc_muxed() == GPMC_MUXED) +		mux = BIT9; +	mtype = get_gpmc0_type(); +	mwidth = get_gpmc0_width(); + +	/* setup cs0 */ +	__raw_writel(0x0, GPMC_CONFIG7_0);	/* disable current map */ +	sdelay(1000); +	__raw_writel(H4_24XX_GPMC_CONFIG1_0|mux|mtype|mwidth, GPMC_CONFIG1_0); +	//__raw_writel(H4_24XX_GPMC_CONFIG2_0, GPMC_CONFIG2_0); +	__raw_writel(H4_24XX_GPMC_CONFIG3_0, GPMC_CONFIG3_0); +	__raw_writel(H4_24XX_GPMC_CONFIG4_0, GPMC_CONFIG4_0); +	//__raw_writel(H4_24XX_GPMC_CONFIG5_0, GPMC_CONFIG5_0); +	__raw_writel(H4_24XX_GPMC_CONFIG7_0, GPMC_CONFIG7_0);/* enable new mapping */ +	sdelay(2000); + +	/* setup cs1 */ +	__raw_writel(0, GPMC_CONFIG7_1); /* disable any mapping */ +	sdelay(1000); +	__raw_writel(H4_24XX_GPMC_CONFIG1_1|mux, GPMC_CONFIG1_1); +	__raw_writel(H4_24XX_GPMC_CONFIG2_1, GPMC_CONFIG2_1); +	__raw_writel(H4_24XX_GPMC_CONFIG3_1, GPMC_CONFIG3_1); +	__raw_writel(H4_24XX_GPMC_CONFIG4_1, GPMC_CONFIG4_1); +	__raw_writel(H4_24XX_GPMC_CONFIG5_1, GPMC_CONFIG5_1); +	__raw_writel(H4_24XX_GPMC_CONFIG6_1, GPMC_CONFIG6_1); +	__raw_writel(H4_24XX_GPMC_CONFIG7_1, GPMC_CONFIG7_1); /* enable mapping */ +	sdelay(2000); +} + diff --git a/board/omap2420h4/omap2420h4.c b/board/omap2420h4/omap2420h4.c new file mode 100644 index 000000000..4696a7133 --- /dev/null +++ b/board/omap2420h4/omap2420h4.c @@ -0,0 +1,834 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 <asm/arch/omap2420.h> +#include <asm/io.h> +#include <asm/arch/bits.h> +#include <asm/arch/mux.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <asm/arch/mem.h> +#include <i2c.h> +#include <asm/mach-types.h> + +static void wait_for_command_complete(unsigned int wd_base); + +/******************************************************* + * Routine: delay + * Description: spinning delay to use before udelay works + ******************************************************/ +static inline void delay (unsigned long loops) +{ +	__asm__ volatile ("1:\n" +					  "subs %0, %1, #1\n" +					  "bne 1b":"=r" (loops):"0" (loops)); +} + +/***************************************** + * Routine: board_init + * Description: Early hardware init. + *****************************************/ +int board_init (void) +{ +	DECLARE_GLOBAL_DATA_PTR; +#ifndef CONFIG_PARTIAL_SRAM +	s_init(0x0);  /* full sram build, never skip clock and sdrc, no point */ +#else +	gpmc_init(); +#endif +	gd->bd->bi_arch_number = MACH_TYPE_OMAP_H4;		/* board id for linux */ +	gd->bd->bi_boot_params = (OMAP2420_SDRC_CS0+0x100);	/* adress of boot parameters */ + +	return 0; +} + +/********************************************************** + * Routine: s_init + * Description: Does early system init of muxing and clocks. + * - Called at time when only stack is available. + **********************************************************/ +void s_init(int skip) +{ +	watchdog_init(); +	set_muxconf_regs(); +	delay(100); + +	if (!skip) +		prcm_init(); + +	peripheral_enable(); +	icache_enable(); +#ifndef CONFIG_APTIX +	if (!skip) +		memif_init(); +#endif +} + +/******************************************************* + * Routine: misc_init_r + * Description: Init ethernet (done here so udelay works) + ********************************************************/ +int misc_init_r (void) +{ +	ether_init(); /* better done here so timers are init'ed */ +	return(0); +} + +/**************************************** + * Routine: watchdog_init + * Description: Shut down watch dogs + *****************************************/ +void watchdog_init(void) +{ +	int mode; +#define GP (BIT8|BIT9) + +	/* There are 4 watch dogs.  1 secure, and 3 general purpose. +	 * I would expect that the ROM takes care of the secure one, +	 * but we will try also.  Of the 3 GP ones, 1 can reset us +	 * directly, the other 2 only generate MPU interrupts. +	 */ +	mode = (__raw_readl(CONTROL_STATUS) & (BIT8|BIT9)); +	if (mode == GP) { +		__raw_writel(WD_UNLOCK1 ,WD1_BASE+WSPR); +		wait_for_command_complete(WD1_BASE); +		__raw_writel(WD_UNLOCK2 ,WD1_BASE+WSPR); +	} +	__raw_writel(WD_UNLOCK1 ,WD2_BASE+WSPR); +	wait_for_command_complete(WD2_BASE); +	__raw_writel(WD_UNLOCK2 ,WD2_BASE+WSPR); + +#if MPU_WD_CLOCKED /* value 0x10 stick on aptix, BIT4 polarity seems oppsite*/ +	__raw_writel(WD_UNLOCK1 ,WD3_BASE+WSPR); +	wait_for_command_complete(WD3_BASE); +	__raw_writel(WD_UNLOCK2 ,WD3_BASE+WSPR); + +	__raw_writel(WD_UNLOCK1 ,WD4_BASE+WSPR); +	wait_for_command_complete(WD4_BASE); +	__raw_writel(WD_UNLOCK2 ,WD4_BASE+WSPR); +#endif +} + +/****************************************************** + * Routine: wait_for_command_complete + * Description: Wait for posting to finish on watchdog + ******************************************************/ +static void wait_for_command_complete(unsigned int wd_base) +{ +	int pending = 1; +	do { +		pending = __raw_readl(wd_base+WWPS); +	} while (pending); +} + +/******************************************************************* + * Routine:ether_init + * Description: take the Ethernet controller out of reset and wait + *  		   for the EEPROM load to complete. + ******************************************************************/ +void ether_init (void) +{ +#ifdef CONFIG_DRIVER_LAN91C96 +	int cnt = 20; + +	__raw_writew(0x0, LAN_RESET_REGISTER); +	do { +		__raw_writew(0x1, LAN_RESET_REGISTER); +		udelay (100); +		if (cnt == 0) +			goto h4reset_err_out; +		--cnt; +	} while (__raw_readw(LAN_RESET_REGISTER) != 0x1); + +	cnt = 20; + +	do { +		__raw_writew(0x0, LAN_RESET_REGISTER); +		udelay (100); +		if (cnt == 0) +			goto h4reset_err_out; +		--cnt; +	} while (__raw_readw(LAN_RESET_REGISTER) != 0x0000); +	udelay (1000); + +	*((volatile unsigned char *) ETH_CONTROL_REG) &= ~0x01; +	udelay (1000); + +	h4reset_err_out: +	return; +#endif +} + +/********************************************** + * Routine: dram_init + * Description: sets uboots idea of sdram size + **********************************************/ +int dram_init (void) +{ +	DECLARE_GLOBAL_DATA_PTR; +	unsigned int size0=0,size1=0; +	u32 mtype, btype; +#define NOT_EARLY 0 + +	i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); /* need this a bit early */ + +	btype = get_board_type(); +	mtype = get_mem_type(); + +	display_board_info(btype); +	if (btype == BOARD_H4_MENELAUS) +		update_mux(btype,mtype); + +	if ((mtype == DDR_COMBO) || (mtype == DDR_STACKED)) { +		do_sdrc_init(SDRC_CS1_OSET, NOT_EARLY);	/* init other chip select */ +		size0 = size1 = SZ_32M; +	} else +		size0 = SZ_64M; + +	gd->bd->bi_dram[0].start = PHYS_SDRAM_1; +	gd->bd->bi_dram[0].size = size0; +	gd->bd->bi_dram[1].start = PHYS_SDRAM_2; +	gd->bd->bi_dram[1].size = size1; + +	return 0; +} + +/********************************************************** + * Routine: set_muxconf_regs + * Description: Setting up the configuration Mux registers + *              specific to the hardware + *********************************************************/ +void set_muxconf_regs (void) +{ +	muxSetupSDRC(); +	muxSetupGPMC(); +	muxSetupUsb0(); +	muxSetupUart3(); +	muxSetupI2C1(); +	muxSetupUART1(); +	muxSetupLCD(); +	muxSetupCamera(); +	muxSetupMMCSD(); +	muxSetupTouchScreen(); +	muxSetupHDQ(); +} + +/***************************************************************** + * Routine: peripheral_enable + * Description: Enable the clks & power for perifs (GPT2, UART1,...) + ******************************************************************/ +void peripheral_enable(void) +{ +	unsigned int v, if_clks=0, func_clks=0; + +	/* Enable GP2 timer.*/ +	if_clks |= BIT4; +	func_clks |= BIT4; +	v = __raw_readl(CM_CLKSEL2_CORE) | 0x4;	/* Sys_clk input OMAP2420_GPT2 */ +	__raw_writel(v, CM_CLKSEL2_CORE); +	__raw_writel(0x1, CM_CLKSEL_WKUP); + +#ifdef CFG_NS16550 +	/* Enable UART1 clock */ +	func_clks |= BIT21; +	if_clks |= BIT21; +#endif +	v = __raw_readl(CM_ICLKEN1_CORE) | if_clks;	/* Interface clocks on */ +	__raw_writel(v,CM_ICLKEN1_CORE ); +	v = __raw_readl(CM_FCLKEN1_CORE) | func_clks; /* Functional Clocks on */ +	__raw_writel(v, CM_FCLKEN1_CORE); +	delay(1000); + +#ifndef KERNEL_UPDATED +	{ +#define V1 0xffffffff +#define V2 0x00000007 + +		__raw_writel(V1, CM_FCLKEN1_CORE); +		__raw_writel(V2, CM_FCLKEN2_CORE); +		__raw_writel(V1, CM_ICLKEN1_CORE); +		__raw_writel(V1, CM_ICLKEN2_CORE); +	} +#endif +} + +/**************************************** + * Routine: muxSetupUsb0   (ostboot) + * Description: Setup usb muxing + *****************************************/ +void muxSetupUsb0(void) +{ +	volatile uint8   *MuxConfigReg; +	volatile uint32  *otgCtrlReg; + +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_PUEN; +	*MuxConfigReg &= (uint8)(~0x1F); + +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_VP; +	*MuxConfigReg &= (uint8)(~0x1F); + +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_VM; +	*MuxConfigReg &= (uint8)(~0x1F); + +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_RCV; +	*MuxConfigReg &= (uint8)(~0x1F); + +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_TXEN; +	*MuxConfigReg &= (uint8)(~0x1F); + +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_SE0; +	*MuxConfigReg &= (uint8)(~0x1F); + +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_USB0_DAT; +	*MuxConfigReg &= (uint8)(~0x1F); + +	/* setup for USB VBus detection */ +	otgCtrlReg = (volatile uint32 *)USB_OTG_CTRL; +	*otgCtrlReg |= 0x00040000; /* bit 18 */ +} + +/**************************************** + * Routine: muxSetupUart3   (ostboot) + * Description: Setup uart3 muxing + *****************************************/ +void muxSetupUart3(void) +{ +	volatile uint8 *MuxConfigReg; + +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_UART3_TX_IRTX; +	*MuxConfigReg &= (uint8)(~0x1F); + +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_UART3_RX_IRRX; +	*MuxConfigReg &= (uint8)(~0x1F); +} + +/**************************************** + * Routine: muxSetupI2C1   (ostboot) + * Description: Setup i2c muxing + *****************************************/ +void muxSetupI2C1(void) +{ +	volatile unsigned char  *MuxConfigReg; + +	/* I2C1 Clock pin configuration, PIN = M19 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_I2C1_SCL; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* I2C1 Data pin configuration, PIN = L15 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_I2C1_SDA; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* Pull-up required on data line */ +	/* external pull-up already present. */ +	/* *MuxConfigReg |= 0x18 ;*/ /* Mode = 0, PullTypeSel=PU, PullUDEnable=Enabled */ +} + +/**************************************** + * Routine: muxSetupUART1  (ostboot) + * Description: Set up uart1 muxing + *****************************************/ +void muxSetupUART1(void) +{ +	volatile unsigned char  *MuxConfigReg; + +	/* UART1_CTS pin configuration, PIN = D21 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_CTS; +	*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + +	/* UART1_RTS pin configuration, PIN = H21 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_RTS; +	*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + +	/* UART1_TX pin configuration, PIN = L20 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_TX; +	*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ + +	/* UART1_RX pin configuration, PIN = T21 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_UART1_RX; +	*MuxConfigReg = 0x00 ; /* Mode = 0, PUPD=Disabled */ +} + +/**************************************** + * Routine: muxSetupLCD   (ostboot) + * Description: Setup lcd muxing + *****************************************/ +void muxSetupLCD(void) +{ +	volatile unsigned char  *MuxConfigReg; + +	/* LCD_D0 pin configuration, PIN = Y7  */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D0; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D1 pin configuration, PIN = P10 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D1; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D2 pin configuration, PIN = V8  */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D2; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D3 pin configuration, PIN = Y8  */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D3; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D4 pin configuration, PIN = W8  */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D4; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D5 pin configuration, PIN = R10 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D5; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D6 pin configuration, PIN = Y9  */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D6; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D7 pin configuration, PIN = V9  */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D7; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D8 pin configuration, PIN = W9  */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D8; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D9 pin configuration, PIN = P11 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D9; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D10 pin configuration, PIN = V10 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D10; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D11 pin configuration, PIN = Y10 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D11; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D12 pin configuration, PIN = W10 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D12; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D13 pin configuration, PIN = R11 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D13; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D14 pin configuration, PIN = V11 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D14; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D15 pin configuration, PIN = W11 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D15; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D16 pin configuration, PIN = P12 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D16; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_D17 pin configuration, PIN = R12 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_D17; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_PCLK pin configuration,   PIN = W6   */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_PCLK; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_VSYNC pin configuration,  PIN = V7  */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_VSYNC; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_HSYNC pin configuration,  PIN = Y6  */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_HSYNC; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* LCD_ACBIAS pin configuration, PIN = W7 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_DSS_ACBIAS; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled +} + +/**************************************** + * Routine: muxSetupCamera  (ostboot) + * Description: Setup camera muxing + *****************************************/ +void muxSetupCamera(void) +{ +	volatile unsigned char  *MuxConfigReg; + +	/* CAMERA_RSTZ  pin configuration, PIN = Y16 */ +	/* CAM_RST is connected through the I2C IO expander.*/ +	/* MuxConfigReg = (volatile unsigned char *), CONTROL_PADCONF_SYS_NRESWARM*/ +	/* *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled   */ + +	/* CAMERA_XCLK  pin configuration, PIN = U3 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_XCLK; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* CAMERA_LCLK  pin configuration, PIN = V5 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_LCLK; +	*MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* CAMERA_VSYNC pin configuration, PIN = U2 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_VS, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* CAMERA_HSYNC pin configuration, PIN = T3 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_HS, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* CAMERA_DAT0 pin configuration, PIN = T4 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D0, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* CAMERA_DAT1 pin configuration, PIN = V2 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D1, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* CAMERA_DAT2 pin configuration, PIN = V3 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D2, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* CAMERA_DAT3 pin configuration, PIN = U4 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D3, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* CAMERA_DAT4 pin configuration, PIN = W2 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D4, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* CAMERA_DAT5 pin configuration, PIN = V4 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D5, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* CAMERA_DAT6 pin configuration, PIN = W3 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D6, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* CAMERA_DAT7 pin configuration, PIN = Y2 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D7, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* CAMERA_DAT8 pin configuration, PIN = Y4 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D8, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* CAMERA_DAT9 pin configuration, PIN = V6 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_CAM_D9, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled +} + +/**************************************** + * Routine: muxSetupMMCSD (ostboot) + * Description: set up MMC muxing + *****************************************/ +void muxSetupMMCSD(void) +{ +	volatile unsigned char  *MuxConfigReg; + +	/* SDMMC_CLKI pin configuration,  PIN = H15 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CLKI, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* SDMMC_CLKO pin configuration,  PIN = G19 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CLKO, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* SDMMC_CMD pin configuration,   PIN = H18 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CMD, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled +	// External pull-ups are present. +	// *MuxConfigReg |= 0x18 ; // PullUDEnable=Enabled, PullTypeSel=PU + +	/* SDMMC_DAT0 pin configuration,  PIN = F20 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT0, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled +	// External pull-ups are present. +	// *MuxConfigReg |= 0x18 ; // PullUDEnable=Enabled, PullTypeSel=PU + +	/* SDMMC_DAT1 pin configuration,  PIN = H14 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT1, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled +	// External pull-ups are present. +	// *MuxConfigReg |= 0x18 ; // PullUDEnable=Enabled, PullTypeSel=PU + +	/* SDMMC_DAT2 pin configuration,  PIN = E19 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT2, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled +	// External pull-ups are present. +	// *MuxConfigReg |= 0x18 ; // PullUDEnable=Enabled, PullTypeSel=PU + +	/* SDMMC_DAT3 pin configuration,  PIN = D19 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT3, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled +	// External pull-ups are present. +	// *MuxConfigReg |= 0x18 ; // PullUDEnable=Enabled, PullTypeSel=PU + +	/* SDMMC_DDIR0 pin configuration, PIN = F19 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR0, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* SDMMC_DDIR1 pin configuration, PIN = E20 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR1, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* SDMMC_DDIR2 pin configuration, PIN = F18 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR2, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* SDMMC_DDIR3 pin configuration, PIN = E18 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_DAT_DIR3, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* SDMMC_CDIR pin configuration,  PIN = G18 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MMC_CMD_DIR, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* MMC_CD pin configuration,      PIN = B3  ---2420IP ONLY---*/ +	/* MMC_CD for 2422IP=K1 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SDRC_A14, +				   *MuxConfigReg = 0x03 ; // Mode = 3, PUPD=Disabled + +	/* MMC_WP pin configuration,      PIN = B4  */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SDRC_A13, +				   *MuxConfigReg = 0x03 ; // Mode = 3, PUPD=Disabled +} + +/****************************************** + * Routine: muxSetupTouchScreen (ostboot) + * Description:  Set up touch screen muxing + *******************************************/ +void muxSetupTouchScreen(void) +{ +	volatile unsigned char  *MuxConfigReg; + +	/* SPI1_CLK pin configuration,  PIN = U18 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_CLK, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* SPI1_MOSI pin configuration, PIN = V20 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_SIMO, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* SPI1_MISO pin configuration, PIN = T18 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_SOMI, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* SPI1_nCS0 pin configuration, PIN = U19 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_SPI1_NCS0, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled + +	/* PEN_IRQ pin configuration,   PIN = P20 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_MCBSP1_FSR, +				   *MuxConfigReg = 0x03 ; // Mode = 3, PUPD=Disabled +} + +/**************************************** + * Routine: muxSetupHDQ (ostboot) + * Description: setup 1wire mux + *****************************************/ +void muxSetupHDQ(void) +{ +	volatile unsigned char  *MuxConfigReg; + +	/* HDQ_SIO pin configuration,  PIN = N18 */ +	MuxConfigReg = (volatile unsigned char *)CONTROL_PADCONF_HDQ_SIO, +				   *MuxConfigReg = 0x00 ; // Mode = 0, PUPD=Disabled +} + +/*************************************************************** + * Routine: muxSetupGPMC (ostboot) + * Description: Configures balls which cam up in protected mode + ***************************************************************/ +void muxSetupGPMC(void) +{ +	volatile uint8 *MuxConfigReg; +	volatile unsigned int *MCR = 0x4800008C; + +	/* gpmc_io_dir */ +	*MCR = 0x19000000; + +	/* NOR FLASH CS0 */ +	/* signal - Gpmc_clk; pin - J4; offset - 0x0088; mode - 0; Byte-3	Pull/up - N/A */ +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_D2_BYTE3, +				   *MuxConfigReg = 0x00 ; + +	/* signal - Gpmc_iodir; pin - n2; offset - 0x008C; mode - 1; Byte-3	Pull/up - N/A */ +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_NCS0_BYTE3, +				   *MuxConfigReg = 0x01 ; + +	/* MPDB(Multi Port Debug Port) CS1 */ +	/* signal - gpmc_ncs1; pin - N8; offset - 0x008C; mode - 0; Byte-1	Pull/up - N/A */ +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_NCS0_BYTE1, +				   *MuxConfigReg = 0x00 ; + +	/* signal - Gpmc_ncs2; pin - E2; offset - 0x008C; mode - 0; Byte-2	Pull/up - N/A */ +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_GPMC_NCS0_BYTE2, +				   *MuxConfigReg = 0x00 ; + + +} + +/**************************************************************** + * Routine: muxSetupSDRC  (ostboot) + * Description: Configures balls which come up in protected mode + ****************************************************************/ +void muxSetupSDRC(void) +{ +	volatile uint8 *MuxConfigReg; + +	/* signal - sdrc_ncs1; pin - C12; offset - 0x00A0; mode - 0; Byte-1	Pull/up - N/A */ +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_NCS0_BYTE1, +				   *MuxConfigReg = 0x00 ; + +	/* signal - sdrc_a12; pin - D11; offset - 0x0030; mode - 0; Byte-2	Pull/up - N/A */ +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_A14_BYTE2, +				   *MuxConfigReg = 0x00 ; + +	/* signal - sdrc_cke1; pin - B13; offset - 0x00A0; mode - 0; Byte-3	Pull/up - N/A */ +	MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_NCS0_BYTE3, +				   *MuxConfigReg = 0x00; + +	if (get_cpu_type() == CPU_2422) { +		MuxConfigReg = (volatile uint8 *)CONTROL_PADCONF_SDRC_A14_BYTE0, +					   *MuxConfigReg = 0x1b; +	} +} + +/***************************************************************************** + * Routine: update_mux() + * Description: Update balls which are different beween boards.  All should be + *              updated to match functionaly.  However, I'm only updating ones + *              which I'll be using for now.  When power comes into play they + *              all need updating. + *****************************************************************************/ +void update_mux(u32 btype,u32 mtype) +{ +	u32 cpu, base = OMAP2420_CTRL_BASE; +	cpu = get_cpu_type(); + +	if (btype == BOARD_H4_MENELAUS) { +		if (cpu == CPU_2420) { +			/* PIN = B3,  GPIO.0->KBR5,      mode 3,  (pun?),-DO-*/ +			__raw_writeb(0x3, base+0x30); +			/* PIN = B13, GPIO.38->KBC6,     mode 3,  (pun?)-DO-*/ +			__raw_writeb(0x3, base+0xa3); +			/* PIN = F1, GPIO.25->HSUSBxx    mode 3,  (for external HS USB)*/ +			/* PIN = H1, GPIO.26->HSUSBxx    mode 3,  (for external HS USB)*/ +			/* PIN = K1, GPMC_ncs6           mode 0,  (on board nand access)*/ +			/* PIN = L2, GPMC_ncs67          mode 0,  (for external HS USB)*/ +			/* PIN = M1 (HSUSBOTG) */ +			/* PIN = P1, GPIO.35->MEN_POK    mode 3,  (menelaus powerok)-DO-*/ +			__raw_writeb(0x3, base+0x9d); +			/* PIN = U32, (WLAN_CLKREQ) */ +			/* PIN = Y11, WLAN */ +			/* PIN = AA4, GPIO.15->KBC2,     mode 3,  -DO- */ +			__raw_writeb(0x3, base+0xe7); +			/* PIN = AA8, mDOC */ +			/* PIN = AA10, BT */ +			/* PIN = AA13, WLAN */ +			/* PIN = M18 GPIO.96->MMC2_WP    mode 3   -DO- */ +			__raw_writeb(0x3, base+0x10e); +			/* PIN = N19 GPIO.98->WLAN_INT   mode 3   -DO- */ +			__raw_writeb(0x3, base+0x110); +			/* PIN = J15 HHUSB */ +			/* PIN = H19 HSUSB */ +			/* PIN = W13, P13, R13, W16 ... */ +			/* PIN = V12 GPIO.25->I2C_CAMEN  mode 3   -DO- */ +			__raw_writeb(0x3, base+0xde); +			/* PIN = W19 sys_nirq->MENELAUS_INT mode 0 -DO- */ +			__raw_writeb(0x0, base+0x12c); +			/* PIN = AA17->sys_clkreq        mode 0   -DO- */ +			__raw_writeb(0x0, base+0x136); +		} else if (cpu == CPU_2422) { +			/* PIN = B3,  GPIO.0->nc,        mode 3,  set above (pun?)*/ +			/* PIN = B13, GPIO.cke1->nc,     mode 0,  set above, (pun?)*/ +			/* PIN = F1, GPIO.25->HSUSBxx    mode 3,  (for external HS USB)*/ +			/* PIN = H1, GPIO.26->HSUSBxx    mode 3,  (for external HS USB)*/ +			/* PIN = K1, GPMC_ncs6           mode 0,  (on board nand access)*/ +			__raw_writeb(0x0, base+0x92); +			/* PIN = L2, GPMC_ncs67          mode 0,  (for external HS USB)*/ +			/* PIN = M1 (HSUSBOTG) */ +			/* PIN = P1, GPIO.35->MEN_POK    mode 3,  (menelaus powerok)-DO-*/ +			__raw_writeb(0x3, base+0x10c); +			/* PIN = U32, (WLAN_CLKREQ) */ +			/* PIN = AA4, GPIO.15->KBC2,     mode 3,  -DO- */ +			__raw_writeb(0x3, base+0x30); +			/* PIN = AA8, mDOC */ +			/* PIN = AA10, BT */ +			/* PIN = AA12, WLAN */ +			/* PIN = M18 GPIO.96->MMC2_WP    mode 3   -DO- */ +			__raw_writeb(0x3, base+0x10e); +			/* PIN = N19 GPIO.98->WLAN_INT   mode 3   -DO- */ +			__raw_writeb(0x3, base+0x110); +			/* PIN = J15 HHUSB */ +			/* PIN = H19 HSUSB */ +			/* PIN = W13, P13, R13, W16 ... */ +			/* PIN = V12 GPIO.25->I2C_CAMEN  mode 3   -DO- */ +			__raw_writeb(0x3, base+0xde); +			/* PIN = W19 sys_nirq->MENELAUS_INT mode 0 -DO- */ +			__raw_writeb(0x0, base+0x12c); +			/* PIN = AA17->sys_clkreq        mode 0   -DO- */ +			__raw_writeb(0x0, base+0x136); +		} + +	} else if (btype == BOARD_H4_SDP) { +		if (cpu == CPU_2420) { +			/* PIN = B3,  GPIO.0->nc         mode 3,  set above (pun?)*/ +			/* PIN = B13, GPIO.cke1->nc,     mode 0,  set above, (pun?)*/ +			/* Pin = Y11 VLNQ */ +			/* Pin = AA4 VLNQ */ +			/* Pin = AA6 VLNQ */ +			/* Pin = AA8 VLNQ */ +			/* Pin = AA10 VLNQ */ +			/* Pin = AA12 VLNQ */ +			/* PIN = M18 GPIO.96->KBR5       mode 3   -DO- */ +			__raw_writeb(0x3, base+0x10e); +			/* PIN = N19 GPIO.98->KBC6       mode 3   -DO- */ +			__raw_writeb(0x3, base+0x110); +			/* PIN = J15 MDOC_nDMAREQ */ +			/* PIN = H19 GPIO.100->KBC2      mode 3   -DO- */ +			__raw_writeb(0x3, base+0x114); +			/* PIN = W13, V12, P13, R13, W19, W16 ... */ +			/* PIN = AA17 sys_clkreq->bt_clk_req  mode 0  */ +		} else if (cpu == CPU_2422) { +			/* PIN = B3,  GPIO.0->MMC_CD,    mode 3,  set above */ +			/* PIN = B13, GPIO.38->wlan_int, mode 3,  (pun?)*/ +			/* Pin = Y11 VLNQ */ +			/* Pin = AA4 VLNQ */ +			/* Pin = AA6 VLNQ */ +			/* Pin = AA8 VLNQ */ +			/* Pin = AA10 VLNQ */ +			/* Pin = AA12 VLNQ */ +			/* PIN = M18 GPIO.96->KBR5       mode 3   -DO- */ +			__raw_writeb(0x3, base+0x10e); +			/* PIN = N19 GPIO.98->KBC6       mode 3   -DO- */ +			__raw_writeb(0x3, base+0x110); +			/* PIN = J15 MDOC_nDMAREQ */ +			/* PIN = H19 GPIO.100->KBC2      mode 3   -DO- */ +			__raw_writeb(0x3, base+0x114); +			/* PIN = W13, V12, P13, R13, W19, W16 ... */ +			/* PIN = AA17 sys_clkreq->bt_clk_req  mode 0 */ +		} +	} +} + + diff --git a/board/omap2420h4/platform.S b/board/omap2420h4/platform.S new file mode 100644 index 000000000..3728e846c --- /dev/null +++ b/board/omap2420h4/platform.S @@ -0,0 +1,237 @@ +/* + * Board specific setup info + * + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 <config.h> +#include <version.h> +#include <asm/arch/omap2420.h> +#include <asm/arch/mem.h> +#include <asm/arch/clocks.h> + +_TEXT_BASE: +	.word	TEXT_BASE	/* sdram load addr from config.mk */ + +#ifdef CONFIG_PARTIAL_SRAM + +/************************************************************************** + * cpy_clk_code: relocates clock code into SRAM where its safer to execute + * R1 = SRAM destination address. + *************************************************************************/ +.global cpy_clk_code + cpy_clk_code: +        /* Copy DPLL code into SRAM */  +        adr     r0, go_to_speed         /* get addr of clock setting code */ +        mov     r2, #384                /* r2 size to copy (div by 32 bytes) */ +        mov     r1, r1                  /* r1 <- dest address (passed in) */ +        add     r2, r2, r0              /* r2 <- source end address */ +next2: +        ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */ +        stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */ +        cmp     r0, r2                  /* until source end address [r2]    */ +        bne     next2 +	mov	pc, lr                  /* back to caller */ + +/* ****************************************************************************  + *  go_to_speed: -Moves to bypass, -Commits clock dividers, -puts dpll at speed + *               -executed from SRAM. + *  R0 = PRCM_CLKCFG_CTRL - addr of valid reg + *  R1 = CM_CLKEN_PLL - addr dpll ctlr reg + *  R2 = dpll value + *  R3 = CM_IDLEST_CKGEN - addr dpll lock wait + ******************************************************************************/     +.global go_to_speed + go_to_speed: +        sub     sp, sp, #0x4 /* get some stack space */ +        str     r4, [sp]     /* save r4's value */ + +        /* move into fast relock bypass */ +        ldr     r8, pll_ctl_add +        mov     r4, #0x2 +        str     r4, [r8] +        ldr     r4, pll_stat +block: +        ldr     r8, [r4]	/* wait for bypass to take effect */ +        and     r8, r8, #0x3 +        cmp     r8, #0x1 +        bne     block + +	/* set new dpll dividers _after_ in bypass */ +	ldr     r4, pll_div_add +	ldr     r8, pll_div_val +        str     r8, [r4] +     +        /* now prepare GPMC (flash) for new dpll speed */ +	/* flash needs to be stable when we jump back to it */ +        ldr     r4, cfg3_0_addr +        ldr     r8, cfg3_0_val +        str     r8, [r4] +        ldr     r4, cfg4_0_addr +        ldr     r8, cfg4_0_val +        str     r8, [r4] +        ldr     r4, cfg1_0_addr +        ldr     r8, [r4] +        orr     r8, r8, #0x3     /* up gpmc divider */ +        str     r8, [r4] + +	/* setup to 2x loop though code.  The first loop pre-loads the  +         * icache, the 2nd commits the prcm config, and locks the dpll +         */ +        mov     r4, #0x1000      /* spin spin spin */ +        mov     r8, #0x4         /* first pass condition & set registers */ +        cmp     r8, #0x4 +2: +        ldrne   r8, [r3]         /* DPLL lock check */ +        and     r8, r8, #0x7 +        cmp     r8, #0x2 +        beq     4f +3: +        subeq   r8, r8, #0x1 +        streq   r8, [r0]         /* commit dividers (2nd time) */ +        nop +lloop1: +        sub     r4, r4, #0x1    /* Loop currently necessary else bad jumps */ +        nop +        cmp     r4, #0x0 +        bne     lloop1 +        mov     r4, #0x40000 +        cmp     r8, #0x1 +        nop +        streq   r2, [r1]        /* lock dpll (2nd time) */ +        nop +lloop2: +        sub     r4, r4, #0x1    /* loop currently necessary else bad jumps */ +        nop +        cmp     r4, #0x0 +        bne     lloop2 +        mov     r4, #0x40000 +        cmp     r8, #0x1 +        nop +        ldreq   r8, [r3]         /* get lock condition for dpll */ +        cmp     r8, #0x4         /* first time though? */ +        bne     2b +        moveq   r8, #0x2         /* set to dpll check condition. */ +        beq     3b               /* if condition not true branch */ +4:   +        ldr     r4, [sp] +        add     sp, sp, #0x4     /* return stack space */ +        mov     pc, lr           /* back to caller, locked */         + +_go_to_speed: .word go_to_speed + +/* these constants need to be close for PIC code */ +cfg3_0_addr: +    .word  GPMC_CONFIG3_0 +cfg3_0_val:  +    .word  H4_24XX_GPMC_CONFIG3_0 +cfg4_0_addr: +    .word  GPMC_CONFIG4_0 +cfg4_0_val: +    .word  H4_24XX_GPMC_CONFIG4_0 +cfg1_0_addr: +    .word  GPMC_CONFIG1_0 +pll_ctl_add: +    .word CM_CLKEN_PLL +pll_stat: +    .word CM_IDLEST_CKGEN +pll_div_add: +    .word CM_CLKSEL1_PLL  +pll_div_val: +    .word DPLL_VAL	/* DPLL setting (300MHz default) */ +#endif             + +.globl platformsetup +platformsetup: +	mov r3, r0     /* save skip information */ +#ifdef CONFIG_APTIX +	ldr	r0,	REG_SDRC_MCFG_0 +	ldr	r1,	VAL_SDRC_MCFG_0 +	str	r1,	[r0] +	ldr	r0,	REG_SDRC_MR_0 +	ldr	r1,	VAL_SDRC_MR_0 +	str	r1,	[r0] +	/* a ddr needs emr1 set here */ +	ldr	r0,	REG_SDRC_SHARING +	ldr	r1,	VAL_SDRC_SHARING +	str	r1,	[r0] +       	ldr	r0,	REG_SDRC_RFR_CTRL_0 +	ldr	r1,	VAL_SDRC_RFR_CTRL_0 +	str	r1,	[r0] + +       /* little delay after init */ +       mov r2, #0x1800                         +1:        +        subs r2, r2, #0x1 +        bne 1b +#endif +#ifdef CONFIG_PARTIAL_SRAM +	ldr	sp,	SRAM_STACK +        str     ip,	[sp]    /* stash old link register */ +	mov	ip,	lr	/* save link reg across call */ +        mov     r0,     r3      /* pass skip info to s_init */ +        bl      s_init          /* go setup pll,mux,memory */ +        ldr     ip,	[sp]    /* restore save ip */ +	mov	lr,	ip	/* restore link reg */ +#endif +	/* map interrupt controller */ +	ldr	r0,	VAL_INTH_SETUP +	mcr	p15, 0, r0, c15, c2, 4 + +	/* back to arch calling code */ +	mov	pc,	lr + +	/* the literal pools origin */ +	.ltorg + +REG_CONTROL_STATUS: +	.word CONTROL_STATUS +VAL_INTH_SETUP: +	.word PERIFERAL_PORT_BASE +SRAM_STACK: +	.word LOW_LEVEL_SRAM_STACK + +#ifdef CONFIG_APTIX +REG_SDRC_SHARING: +	.word SDRC_SHARING +REG_SDRC_MCFG_0: +	.word SDRC_MCFG_0 +REG_SDRC_MR_0: +	.word SDRC_MR_0 +REG_SDRC_RFR_CTRL_0: +        .word SDRC_RFR_CTRL +VAL_SDRC_SHARING: +	.word VAL_H4_SDRC_SHARING +VAL_SDRC_MCFG_0: +	.word VAL_H4_SDRC_MCFG_0 +VAL_SDRC_MR_0: +	.word VAL_H4_SDRC_MR_0 +VAL_SDRC_RFR_CTRL_0: +        .word VAL_H4_SDRC_RFR_CTRL_0 +#endif + + + + + + diff --git a/board/omap2420h4/sys_info.c b/board/omap2420h4/sys_info.c new file mode 100644 index 000000000..b5fe9e392 --- /dev/null +++ b/board/omap2420h4/sys_info.c @@ -0,0 +1,202 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <asm/arch/omap2420.h> +#include <asm/io.h> +#include <asm/arch/bits.h> +#include <asm/arch/mem.h>  /* get mem tables */ +#include <asm/arch/sys_proto.h> +#include <asm/arch/sys_info.h> +#include <i2c.h> + +/************************************************************************** + * get_cpu_type() - low level get cpu type + * - no C globals yet. + * - just looking to say if this is a 2422 or 2420 or ... + * - to start with we will look at switch settings.. + * - 2422 id's same as 2420 for ES1 will rely on H4 board characteristics + *   (mux for 2420, non-mux for 2422). + ***************************************************************************/ +u32 get_cpu_type(void) +{ +	u32 v; + +	v = __raw_readl(TAP_IDCODE_REG); +	v &= CPU_24XX_ID_MASK; +	if (v == CPU_2420_CHIPID) {	  /* currently 2420 and 2422 have same id */ +		if (is_gpmc_muxed() == GPMC_MUXED)	  /* if mux'ed */ +			return(CPU_2420); +		else +			return(CPU_2422); +	} else +		return(CPU_2420); /* don't know, say 2420 */ +} + +/****************************************** + * get_cpu_rev(void) - extract version info + ******************************************/ +u32 get_cpu_rev(void) +{ +	u32 v; +	v = __raw_readl(TAP_IDCODE_REG); +	v = v >> 28; +	return(v+1);  /* currently 2422 and 2420 match up */ +} + +/*********************************************************** + * get_mem_type() - identify type of mDDR part used. + * 2422 uses stacked DDR, 2 parts CS0/CS1. + * 2420 may have 1 or 2, no good way to know...only init 1... + * when eeprom data is up we can select 1 more. + *************************************************************/ +u32 get_mem_type(void) +{ +	if (get_cpu_type() == CPU_2422) +		return(DDR_STACKED); + +	if (get_board_type() == BOARD_H4_MENELAUS) +		return(DDR_COMBO); +	else +		return(DDR_DISCRETE); +} + +/*********************************************************************** + * get_board_type() - get board type based on current production stats. + *  --- NOTE: 2 I2C EEPROMs will someday be populated with proper info. + *      when they are available we can get info from there.  This should + *      be correct of all known boards up until today. + ************************************************************************/ +u32 get_board_type(void) +{ +	if (i2c_probe(I2C_MENELAUS) == 0) +		return(BOARD_H4_MENELAUS); +	else +		return(BOARD_H4_SDP); +} + +/****************************************************************** + * get_sysboot_value() - get init word settings (dip switch on h4) + ******************************************************************/ +u32 get_sysboot_value(void) +{ +	return(0x00000FFF & __raw_readl(CONTROL_STATUS)); +} + +/*************************************************************************** + *  get_gpmc0_base() - Return current address hardware will be + *     fetching from. The below effectively gives what is correct, its a bit + *   mis-leading compared to the TRM.  For the most general case the mask + *   needs to be also taken into account this does work in practice. + *   - for u-boot we currently map: + *       -- 0 to nothing, + *       -- 4 to flash + *       -- 8 to enent + *       -- c to wifi + ****************************************************************************/ +u32 get_gpmc0_base(void) +{ +	u32 b; + +	b = __raw_readl(GPMC_CONFIG7_0); +	b &= 0x1F;	 /* keep base [5:0] */ +	b = b << 24; /* ret 0x0b000000 */ +	return(b); +} + +/***************************************************************** + *  is_gpmc_muxed() - tells if address/data lines are multiplexed + *****************************************************************/ +u32 is_gpmc_muxed(void) +{ +	u32 mux; +	mux = get_sysboot_value(); +	if (mux & BIT1)	   /* if mux'ed */ +		return(GPMC_MUXED); +	else +		return(GPMC_NONMUXED); +} + +/************************************************************************ + *  get_gpmc0_type() - read sysboot lines to see type of memory attached + ************************************************************************/ +u32 get_gpmc0_type(void) +{ +	u32 type; +	type = get_sysboot_value(); +	if ((type & (BIT3|BIT2)) == (BIT3|BIT2)) +		return(TYPE_NAND); +	else +		return(TYPE_NOR); +} + +/******************************************************************* + * get_gpmc0_width() - See if bus is in x8 or x16 (mainly for nand) + *******************************************************************/ +u32 get_gpmc0_width(void) +{ +	u32 width; +	width = get_sysboot_value(); +	if ((width & 0xF) == (BIT3|BIT2)) +		return(WIDTH_8BIT); +	else +		return(WIDTH_16BIT); +} + +/********************************************************************* + * wait_on_value() - common routine to allow waiting for changes in + *   volatile regs. + *********************************************************************/ +u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound) +{ +	u32 i = 0, val; +	do { +		++i; +		val = __raw_readl(read_addr) & read_bit_mask; +		if (val == match_value) +			return(1); +		if (i==bound) +			return(0); +	} while (1); +} + +/********************************************************************* + *  display_board_info() - print banner with board info. + *********************************************************************/ +void display_board_info(u32 btype) +{ +	char cpu_2420[] = "2420"; +	char cpu_2422[] = "2422"; +	char db_men[] = "Menelaus"; +	char db_ip[]= "IP"; +	char *cpu_s, *db_s; +	u32 cpu = get_cpu_type(); + +	if(cpu == CPU_2420) +		cpu_s = cpu_2420; +	else +		cpu_s = cpu_2422; +	if(btype ==  BOARD_H4_MENELAUS) +		db_s = db_men; +	else +		db_s = db_ip; +	printf("TI H4 SDP Base Board with OMAP%s %s Daughter Board\n",cpu_s, db_s); +} diff --git a/board/omap2420h4/u-boot.lds b/board/omap2420h4/u-boot.lds new file mode 100644 index 000000000..724c1dd48 --- /dev/null +++ b/board/omap2420h4/u-boot.lds @@ -0,0 +1,58 @@ +/* + * January 2004 - Changed to support H4 device  + * Copyright (c) 2004 Texas Instruments  + * + * (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_ARCH(arm) +ENTRY(_start) +SECTIONS +{ +	. = 0x00000000; + +	. = ALIGN(4); +	.text      : +	{ +	  cpu/arm1136/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/common/env_flash.c b/common/env_flash.c index 4e42c8fee..d6257d07b 100644 --- a/common/env_flash.c +++ b/common/env_flash.c @@ -99,11 +99,7 @@ uchar env_get_char_spec (int index)  int  env_init(void)  {  	DECLARE_GLOBAL_DATA_PTR; - -	int crc1_ok = -		(crc32(0, flash_addr->data, ENV_SIZE) == flash_addr->crc); -	int crc2_ok = -		(crc32(0, flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc); +	int crc1_ok = 0, crc2_ok = 0;  	uchar flag1 = flash_addr->flags;  	uchar flag2 = flash_addr_new->flags; @@ -112,6 +108,16 @@ int  env_init(void)  	ulong addr1 = (ulong)&(flash_addr->data);  	ulong addr2 = (ulong)&(flash_addr_new->data); +#ifdef CONFIG_OMAP2420H4 +	int flash_probe(void); + +	if(flash_probe() == 0) +		goto bad_flash; +#endif + +	crc1_ok = (crc32(0, flash_addr->data, ENV_SIZE) == flash_addr->crc); +	crc2_ok = (crc32(0, flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc); +  	if (crc1_ok && ! crc2_ok) {  		gd->env_addr  = addr1;  		gd->env_valid = 1; @@ -138,6 +144,9 @@ int  env_init(void)  		gd->env_valid = 2;  	} +#ifdef CONFIG_OMAP2420H4 +bad_flash: +#endif  	return (0);  } @@ -252,15 +261,22 @@ Done:  int  env_init(void)  {  	DECLARE_GLOBAL_DATA_PTR; +#ifdef CONFIG_OMAP2420H4 +	int flash_probe(void); +	if(flash_probe() == 0) +		goto bad_flash; +#endif  	if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) {  		gd->env_addr  = (ulong)&(env_ptr->data);  		gd->env_valid = 1; -	} else { -		gd->env_addr  = (ulong)&default_environment[0]; -		gd->env_valid = 0; +		return(0);  	} - +#ifdef CONFIG_OMAP2420H4 +bad_flash: +#endif +	gd->env_addr  = (ulong)&default_environment[0]; +	gd->env_valid = 0;  	return (0);  } diff --git a/cpu/arm1136/Makefile b/cpu/arm1136/Makefile new file mode 100644 index 000000000..203278e9c --- /dev/null +++ b/cpu/arm1136/Makefile @@ -0,0 +1,43 @@ +# +# (C) Copyright 2000-2003 +# 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$(CPU).a + +START	= start.o +OBJS	= interrupts.o cpu.o + +all:	.depend $(START) $(LIB) + +$(LIB):	$(OBJS) +	$(AR) crv $@ $(OBJS) + +######################################################################### + +.depend:	Makefile $(START:.o=.S) $(OBJS:.o=.c) +		$(CC) -M $(CFLAGS) $(START:.o=.S) $(OBJS:.o=.c) > $@ + +sinclude .depend + +######################################################################### diff --git a/cpu/arm1136/config.mk b/cpu/arm1136/config.mk new file mode 100644 index 000000000..077514aa2 --- /dev/null +++ b/cpu/arm1136/config.mk @@ -0,0 +1,25 @@ +# +# (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 +# +PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8 \ + +PLATFORM_CPPFLAGS += -mapcs-32 -march=armv6 diff --git a/cpu/arm1136/cpu.c b/cpu/arm1136/cpu.c new file mode 100644 index 000000000..0db275335 --- /dev/null +++ b/cpu/arm1136/cpu.c @@ -0,0 +1,163 @@ +/* + * (C) Copyright 2004 Texas Insturments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (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 + */ + +/* + * CPU specific code + */ + +#include <common.h> +#include <command.h> +#include <asm/arch/omap2420.h> + +/* read co-processor 15, register #1 (control register) */ +static unsigned long read_p15_c1 (void) +{ +	unsigned long value; + +	__asm__ __volatile__( +						"mrc	p15, 0, %0, c1, c0, 0   @ read control reg\n" +						: "=r" (value) +						: +						: "memory"); +	return value; +} + +/* write to co-processor 15, register #1 (control register) */ +static void write_p15_c1 (unsigned long value) +{ +	__asm__ __volatile__( +						"mcr	p15, 0, %0, c1, c0, 0   @ write it back\n" +						: +						: "r" (value) +						: "memory"); + +	read_p15_c1 (); +} + +static void cp_delay (void) +{ +	volatile int i; + +	/* Many OMAP regs need at least 2 nops  */ +	for (i = 0; i < 100; i++); +} + +/* See also ARM Ref. Man. */ +#define C1_MMU		(1<<0)		/* mmu off/on */ +#define C1_ALIGN	(1<<1)		/* alignment faults off/on */ +#define C1_DC		(1<<2)		/* dcache off/on */ +#define C1_WB		(1<<3)		/* merging write buffer on/off */ +#define C1_BIG_ENDIAN	(1<<7)	/* big endian off/on */ +#define C1_SYS_PROT	(1<<8)		/* system protection */ +#define C1_ROM_PROT	(1<<9)		/* ROM protection */ +#define C1_IC		(1<<12)		/* icache off/on */ +#define C1_HIGH_VECTORS	(1<<13)	/* location of vectors: low/high addresses */ +#define RESERVED_1	(0xf << 3)	/* must be 111b for R/W */ + +int cpu_init (void) +{ +	/* +	 * setup up stacks if necessary +	 */ +#ifdef CONFIG_USE_IRQ +	DECLARE_GLOBAL_DATA_PTR; + +	IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4; +	FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ; +#endif +	return 0; +} + +int cleanup_before_linux (void) +{ +	/* +	 * this function is called just before we call linux +	 * it prepares the processor for linux +	 * +	 * we turn off caches etc ... +	 */ + +	unsigned long i; + +	disable_interrupts (); + +#ifdef CONFIG_LCD +	{ +		extern void lcd_disable(void); +		extern void lcd_panel_disable(void); + +		lcd_disable(); /* proper disable of lcd & panel */ +		lcd_panel_disable(); +	} +#endif + +	/* turn off I/D-cache */ +	asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i)); +	i &= ~(C1_DC | C1_IC); +	asm ("mcr p15, 0, %0, c1, c0, 0": :"r" (i)); + +	/* flush I/D-cache */ +	i = 0; +	asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));  // invalidate both caches and flush btb +	asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (i)); // mem barrier to sync things +	return(0); +} + +int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	extern void reset_cpu (ulong addr); + +	disable_interrupts (); +	reset_cpu (0); +	/*NOTREACHED*/ +	return(0); +} + +void icache_enable (void) +{ +	ulong reg; + +	reg = read_p15_c1 ();	/* get control reg. */ +	cp_delay (); +	write_p15_c1 (reg | C1_IC); +} + +void icache_disable (void) +{ +	ulong reg; + +	reg = read_p15_c1 (); +	cp_delay (); +	write_p15_c1 (reg & ~C1_IC); +} + +int icache_status (void) +{ +	return(read_p15_c1 () & C1_IC) != 0; +} diff --git a/cpu/arm1136/interrupts.c b/cpu/arm1136/interrupts.c new file mode 100644 index 000000000..bd7bb7c34 --- /dev/null +++ b/cpu/arm1136/interrupts.c @@ -0,0 +1,293 @@ +/* + * (C) Copyright 2004
 + * Texas Instruments
 + * Richard Woodruff <r-woodruff2@ti.com>
 + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + * + * (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 + */ + +#include <common.h> +#include <asm/arch/bits.h> +#include <asm/arch/omap2420.h> +#include <asm/proc-armv/ptrace.h> + +extern void reset_cpu(ulong addr); +#define TIMER_LOAD_VAL 0 + +/* macro to read the 32 bit timer */ +#define READ_TIMER (*(volatile ulong *)(CFG_TIMERBASE+TCRR)) + +#ifdef CONFIG_USE_IRQ +/* enable IRQ interrupts */ +void enable_interrupts (void) +{ +	unsigned long temp; +	__asm__ __volatile__("mrs %0, cpsr\n" +						 "bic %0, %0, #0x80\n" +						 "msr cpsr_c, %0" +						 : "=r" (temp) +						 : +						 : "memory"); +} + +/* + * disable IRQ/FIQ interrupts + * returns true if interrupts had been enabled before we disabled them + */ +int disable_interrupts (void) +{ +	unsigned long old,temp; +	__asm__ __volatile__("mrs %0, cpsr\n" +						 "orr %1, %0, #0xc0\n" +						 "msr cpsr_c, %1" +						 : "=r" (old), "=r" (temp) +						 : +						 : "memory"); +	return(old & 0x80) == 0; +} +#else +void enable_interrupts (void) +{ +	return; +} +int disable_interrupts (void) +{ +	return 0; +} +#endif + + +void bad_mode (void) +{ +	panic ("Resetting CPU ...\n"); +	reset_cpu (0); +} + +void show_regs (struct pt_regs *regs) +{ +	unsigned long flags; +	const char *processor_modes[] = { +		"USER_26",  "FIQ_26",   "IRQ_26",   "SVC_26", +		"UK4_26",   "UK5_26",   "UK6_26",   "UK7_26", +		"UK8_26",   "UK9_26",   "UK10_26",  "UK11_26", +		"UK12_26",  "UK13_26",  "UK14_26",  "UK15_26", +		"USER_32",  "FIQ_32",   "IRQ_32",   "SVC_32", +		"UK4_32",   "UK5_32",   "UK6_32",   "ABT_32", +		"UK8_32",   "UK9_32",   "UK10_32",  "UND_32", +		"UK12_32",  "UK13_32",  "UK14_32",  "SYS_32", +	}; + +	flags = condition_codes (regs); + +	printf ("pc : [<%08lx>]    lr : [<%08lx>]\n" +			"sp : %08lx  ip : %08lx  fp : %08lx\n", +			instruction_pointer (regs), +			regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp); +	printf ("r10: %08lx  r9 : %08lx  r8 : %08lx\n", +			regs->ARM_r10, regs->ARM_r9, regs->ARM_r8); +	printf ("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n", +			regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4); +	printf ("r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n", +			regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0); +	printf ("Flags: %c%c%c%c", +			flags & CC_N_BIT ? 'N' : 'n', +			flags & CC_Z_BIT ? 'Z' : 'z', +			flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v'); +	printf ("  IRQs %s  FIQs %s  Mode %s%s\n", +			interrupts_enabled (regs) ? "on" : "off", +			fast_interrupts_enabled (regs) ? "on" : "off", +			processor_modes[processor_mode (regs)], +			thumb_mode (regs) ? " (T)" : ""); +} + +void do_undefined_instruction (struct pt_regs *pt_regs) +{ +	printf ("undefined instruction\n"); +	show_regs (pt_regs); +	bad_mode (); +} + +void do_software_interrupt (struct pt_regs *pt_regs) +{ +	printf ("software interrupt\n"); +	show_regs (pt_regs); +	bad_mode (); +} + +void do_prefetch_abort (struct pt_regs *pt_regs) +{ +	printf ("prefetch abort\n"); +	show_regs (pt_regs); +	bad_mode (); +} + +void do_data_abort (struct pt_regs *pt_regs) +{ +	printf ("data abort\n"); +	show_regs (pt_regs); +	bad_mode (); +} + +void do_not_used (struct pt_regs *pt_regs) +{ +	printf ("not used\n"); +	show_regs (pt_regs); +	bad_mode (); +} + +void do_fiq (struct pt_regs *pt_regs) +{ +	printf ("fast interrupt request\n"); +	show_regs (pt_regs); +	bad_mode (); +} + +void do_irq (struct pt_regs *pt_regs) +{ +	printf ("interrupt request\n"); +	show_regs (pt_regs); +	bad_mode (); +} + +static ulong timestamp; +static ulong lastinc; + +/* nothing really to do with interrupts, just starts up a counter. */ +int interrupt_init (void) +{ +	int32_t val; + +	/* Start the counter ticking up */ +	*((int32_t *) (CFG_TIMERBASE + TLDR)) = TIMER_LOAD_VAL;	/* reload value on overflow*/ +	val = (CFG_PVT << 2) | BIT5 | BIT1 | BIT0;		/* mask to enable timer*/ +	*((int32_t *) (CFG_TIMERBASE + TCLR)) = val;	/* start timer */ + +	reset_timer_masked(); /* init the timestamp and lastinc value */ + +	return(0); +} + +/* + * timer without interrupts + */ +void reset_timer (void) +{ +	reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ +	return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ +	timestamp = t; +} + +/* delay x useconds AND perserve advance timstamp value */ +void udelay (unsigned long usec) +{ +	ulong tmo, tmp; + +	if (usec >= 1000) {			/* if "big" number, spread normalization to seconds */ +		tmo = usec / 1000;		/* start to normalize for usec to ticks per sec */ +		tmo *= CFG_HZ;			/* find number of "ticks" to wait to achieve target */ +		tmo /= 1000;			/* finish normalize. */ +	} else {					/* else small number, don't kill it prior to HZ multiply */ +		tmo = usec * CFG_HZ; +		tmo /= (1000*1000); +	} + +	tmp = get_timer (0);		/* get current timestamp */ +	if ( (tmo + tmp + 1) < tmp )/* if setting this forward will roll time stamp */ +		reset_timer_masked ();	/* reset "advancing" timestamp to 0, set lastinc value */ +	else +		tmo	+= tmp;				/* else, set advancing stamp wake up time */ +	while (get_timer_masked () < tmo)/* loop till event */ +		/*NOP*/; +} + +void reset_timer_masked (void) +{ +	/* reset time */ +	lastinc = READ_TIMER;		/* capture current incrementer value time */ +	timestamp = 0;				/* start "advancing" time stamp from 0 */ +} + +ulong get_timer_masked (void) +{ +	ulong now = READ_TIMER;		/* current tick value */ + +	if (now >= lastinc)			/* normal mode (non roll) */ +		timestamp += (now - lastinc); /* move stamp fordward with absoulte diff ticks */ +	else						/* we have rollover of incrementer */ +		timestamp += (0xFFFFFFFF - lastinc) + now; +	lastinc = now; +	return timestamp; +} + +/* waits specified delay value and resets timestamp */ +void udelay_masked (unsigned long usec) +{ +	ulong tmo; + +	if (usec >= 1000) {			/* if "big" number, spread normalization to seconds */ +		tmo = usec / 1000;		/* start to normalize for usec to ticks per sec */ +		tmo *= CFG_HZ;			/* find number of "ticks" to wait to achieve target */ +		tmo /= 1000;			/* finish normalize. */ +	} else {					/* else small number, don't kill it prior to HZ multiply */ +		tmo = usec * CFG_HZ; +		tmo /= (1000*1000); +	} +	reset_timer_masked ();		/* set "advancing" timestamp to 0, set lastinc vaule */ +	while (get_timer_masked () < tmo) /* wait for time stamp to overtake tick number.*/ +		/* NOP */; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ +	return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ +	ulong tbclk; +	tbclk = CFG_HZ; +	return tbclk; +} diff --git a/cpu/arm1136/start.S b/cpu/arm1136/start.S new file mode 100644 index 000000000..826c27e13 --- /dev/null +++ b/cpu/arm1136/start.S @@ -0,0 +1,414 @@ +/* + *  armboot - Startup Code for OMP2420/ARM1136 CPU-core + * + *  Copyright (c) 2004  Texas Instruments <r-woodruff2@ti.com> + * + *  Copyright (c) 2001	Marius Gröger <mag@sysgo.de> + *  Copyright (c) 2002	Alex Züpke <azu@sysgo.de> + *  Copyright (c) 2002	Gary Jennejohn <gj@denx.de> + *  Copyright (c) 2003	Richard Woodruff <r-woodruff2@ti.com> + *  Copyright (c) 2003	Kshitij <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 <config.h> +#include <version.h> +#include <asm/arch/omap2420.h> + +.globl _start +_start:	b       reset +	ldr	pc, _undefined_instruction +	ldr	pc, _software_interrupt +	ldr	pc, _prefetch_abort +	ldr	pc, _data_abort +	ldr	pc, _not_used +	ldr	pc, _irq +	ldr	pc, _fiq + +_undefined_instruction:	.word undefined_instruction +_software_interrupt:	.word software_interrupt +_prefetch_abort:	.word prefetch_abort +_data_abort:		.word data_abort +_not_used:		.word not_used +_irq:			.word irq +_fiq:			.word fiq +_pad:                   .word 0x12345678 /* now 16*4=64 */  +.global _end_vect +_end_vect: + +	.balignl 16,0xdeadbeef +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * setup Memory and board specific bits prior to relocation. + * relocate armboot to ram + * setup stack + * + ************************************************************************* + */ + +_TEXT_BASE: +	.word	TEXT_BASE + +.globl _armboot_start +_armboot_start: +	.word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: +	.word __bss_start + +.globl _bss_end +_bss_end: +	.word _end + +#ifdef CONFIG_USE_IRQ +/* IRQ stack memory (calculated at run-time) */ +.globl IRQ_STACK_START +IRQ_STACK_START: +	.word	0x0badc0de + +/* IRQ stack memory (calculated at run-time) */ +.globl FIQ_STACK_START +FIQ_STACK_START: +	.word 0x0badc0de +#endif + +/* + * the actual reset code + */ + +reset: +	/* +	 * set the cpu to SVC32 mode +	 */ +	mrs	r0,cpsr +	bic	r0,r0,#0x1f +	orr	r0,r0,#0xd3 +	msr	cpsr,r0 + +#ifdef CONFIG_OMAP2420H4 +       /* Copy vectors to mask ROM indirect addr */  +        adr     r0, _start              /* r0 <- current position of code   */ +        mov     r2, #64                 /* r2 <- size to copy  */ +        add     r2, r0, r2              /* r2 <- source end address         */ +        mov     r1, #SRAM_OFFSET0         /* build vect addr */ +        mov     r3, #SRAM_OFFSET1 +        add     r1, r1, r3 +        mov     r3, #SRAM_OFFSET2 +        add     r1, r1, r3 +next: +        ldmia   r0!, {r3-r10}           /* copy from source address [r0]    */ +        stmia   r1!, {r3-r10}           /* copy to   target address [r1]    */ +        cmp     r0, r2                  /* until source end address [r2]    */ +        bne     next                    /* loop until equal */ +#ifdef CONFIG_PARTIAL_SRAM +	bl	cpy_clk_code            /* put dpll adjust code behind vectors */ +#endif +#endif +	/* the mask ROM code should have PLL and others stable */ +	bl  cpu_init_crit + +relocate:				/* relocate U-Boot to RAM	    */ +	adr	r0, _start		/* r0 <- current position of code   */ +	ldr	r1, _TEXT_BASE		/* test if we run from flash or RAM */ +	cmp     r0, r1                  /* don't reloc during debug         */ +	beq     stack_setup + +	ldr	r2, _armboot_start +	ldr	r3, _bss_start +	sub	r2, r3, r2		/* r2 <- size of armboot            */ +	add	r2, r0, r2		/* r2 <- source end address         */ + +copy_loop: +	ldmia	r0!, {r3-r10}		/* copy from source address [r0]    */ +	stmia	r1!, {r3-r10}		/* copy to   target address [r1]    */ +	cmp	r0, r2			/* until source end addreee [r2]    */ +	ble	copy_loop + +	/* Set up the stack						    */ +stack_setup: +	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */ +	sub	r0, r0, #CFG_MALLOC_LEN	/* malloc area                      */ +	sub	r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */ +#ifdef CONFIG_USE_IRQ +	sub	r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) +#endif +	sub	sp, r0, #12		/* leave 3 words for abort-stack    */ + +clear_bss: +	ldr	r0, _bss_start		/* find start of bss segment        */ +	ldr	r1, _bss_end		/* stop here                        */ +	mov 	r2, #0x00000000		/* clear                            */ + +clbss_l:str	r2, [r0]		/* clear loop...                    */ +	add	r0, r0, #4 +	cmp	r0, r1 +	bne	clbss_l + +	ldr	pc, _start_armboot + +_start_armboot:	.word start_armboot + + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + * setup important registers + * setup memory timing + * + ************************************************************************* + */ +cpu_init_crit: +	/* +	 * flush v4 I/D caches +	 */ +	mov	r0, #0 +	mcr	p15, 0, r0, c7, c7, 0	/* flush v3/v4 cache */ +	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */ + +	/* +	 * disable MMU stuff and caches +	 */ +	mrc	p15, 0, r0, c1, c0, 0 +	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS) +	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM) +	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align +#ifndef CONFIG_ICACHE_OFF +	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache +#endif +	mcr	p15, 0, r0, c1, c0, 0 + +	/* +         * Jump to board specific initialization... The Mask ROM will have already initialized +         * basic memory.  Go here to bump up clock rate and handle wake up conditions. +	 */ +	adr	r0, _start		/* r0 <- current position of code   */ +	ldr	r1, _TEXT_BASE		/* test if we run from flash or RAM */ +	cmp     r0, r1                  /* pass on info about skipping some init portions */ +        moveq   r0,#0x1                 /* flag to skip prcm and sdrc setup */ +        movne   r0,#0x0                  +	mov	ip, lr          /* persevere link reg across call */ +	bl	platformsetup   /* go setup pll,mux,memory */ +	mov	lr, ip          /* restore link */ +	mov	pc, lr          /* back to my caller */ +/* + ************************************************************************* + * + * Interrupt handling + * + ************************************************************************* + */ +@ +@ IRQ stack frame. +@ +#define S_FRAME_SIZE	72 + +#define S_OLD_R0	68 +#define S_PSR		64 +#define S_PC		60 +#define S_LR		56 +#define S_SP		52 + +#define S_IP		48 +#define S_FP		44 +#define S_R10		40 +#define S_R9		36 +#define S_R8		32 +#define S_R7		28 +#define S_R6		24 +#define S_R5		20 +#define S_R4		16 +#define S_R3		12 +#define S_R2		8 +#define S_R1		4 +#define S_R0		0 + +#define MODE_SVC 0x13 +#define I_BIT	 0x80 + +/* + * use bad_save_user_regs for abort/prefetch/undef/swi ... + * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling + */ + +	.macro	bad_save_user_regs +	sub	sp, sp, #S_FRAME_SIZE           @ carve out a frame on current user stack +	stmia	sp, {r0 - r12}			@ Save user registers (now in svc mode) r0-r12 + +	ldr	r2, _armboot_start +	sub	r2, r2, #(CFG_MALLOC_LEN) +	sub	r2, r2, #(CFG_GBL_DATA_SIZE+8)  @ set base 2 words into abort stack +	ldmia	r2, {r2 - r3}                   @ get values for "aborted" pc and cpsr (into parm regs) +	add	r0, sp, #S_FRAME_SIZE		@ grab pointer to old stack + +	add	r5, sp, #S_SP +	mov	r1, lr +	stmia	r5, {r0 - r3}                   @ save sp_SVC, lr_SVC, pc, cpsr +	mov	r0, sp                          @ save current stack into r0 (param register) +	.endm + +	.macro	irq_save_user_regs +	sub	sp, sp, #S_FRAME_SIZE +	stmia	sp, {r0 - r12}			@ Calling r0-r12 +	add     r8, sp, #S_PC                   @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. +	stmdb   r8, {sp, lr}^                   @ Calling SP, LR +	str     lr, [r8, #0]                    @ Save calling PC +	mrs     r6, spsr +	str     r6, [r8, #4]                    @ Save CPSR +	str     r0, [r8, #8]                    @ Save OLD_R0 +	mov	r0, sp +	.endm + +	.macro	irq_restore_user_regs +	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr +	mov	r0, r0 +	ldr	lr, [sp, #S_PC]			@ Get PC +	add	sp, sp, #S_FRAME_SIZE +	subs	pc, lr, #4			@ return & move spsr_svc into cpsr +	.endm + +	.macro get_bad_stack +	ldr	r13, _armboot_start		@ setup our mode stack (enter in banked mode) +	sub	r13, r13, #(CFG_MALLOC_LEN)     @ move past malloc pool +	sub	r13, r13, #(CFG_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack + +	str	lr, [r13]			@ save caller lr in position 0 of saved stack +	mrs	lr, spsr                        @ get the spsr +	str     lr, [r13, #4]                   @ save spsr in position 1 of saved stack + +	mov	r13, #MODE_SVC			@ prepare SVC-Mode +	@ msr	spsr_c, r13 +	msr	spsr, r13                       @ switch modes, make sure moves will execute +	mov	lr, pc                          @ capture return pc +	movs	pc, lr                          @ jump to next instruction & switch modes. +	.endm + +	.macro get_bad_stack_swi +        sub     r13, r13, #4                    @ space on current stack for scratch reg. +        str     r0, [r13]                       @ save R0's value. +	ldr	r0, _armboot_start		@ get data regions start +	sub	r0, r0, #(CFG_MALLOC_LEN)       @ move past malloc pool +	sub	r0, r0, #(CFG_GBL_DATA_SIZE+8)  @ move past gbl and a couple spots for abort stack +	str	lr, [r0]			@ save caller lr in position 0 of saved stack +	mrs	r0, spsr                        @ get the spsr +	str     lr, [r0, #4]                    @ save spsr in position 1 of saved stack +        ldr     r0, [r13]                       @ restore r0 +        add     r13, r13, #4                    @ pop stack entry +	.endm + +	.macro get_irq_stack			@ setup IRQ stack +	ldr	sp, IRQ_STACK_START +	.endm + +	.macro get_fiq_stack			@ setup FIQ stack +	ldr	sp, FIQ_STACK_START +	.endm + +/* + * exception handlers + */ +	.align  5 +undefined_instruction: +	get_bad_stack +	bad_save_user_regs +	bl 	do_undefined_instruction + +	.align	5 +software_interrupt: +	get_bad_stack_swi +	bad_save_user_regs +	bl 	do_software_interrupt + +	.align	5 +prefetch_abort: +	get_bad_stack +	bad_save_user_regs +	bl 	do_prefetch_abort + +	.align	5 +data_abort: +	get_bad_stack +	bad_save_user_regs +	bl 	do_data_abort + +	.align	5 +not_used: +	get_bad_stack +	bad_save_user_regs +	bl 	do_not_used + +#ifdef CONFIG_USE_IRQ + +	.align	5 +irq: +	get_irq_stack +	irq_save_user_regs +	bl 	do_irq +	irq_restore_user_regs + +	.align	5 +fiq: +	get_fiq_stack +	/* someone ought to write a more effiction fiq_save_user_regs */ +	irq_save_user_regs +	bl 	do_fiq +	irq_restore_user_regs + +#else + +	.align	5 +irq: +	get_bad_stack +	bad_save_user_regs +	bl 	do_irq + +	.align	5 +fiq: +	get_bad_stack +	bad_save_user_regs +	bl 	do_fiq + +#endif +	.align 5 +.global arm1136_cache_flush +arm1136_cache_flush: +		mcr	p15, 0, r1, c7, c5, 0	@ invalidate I cache +		mov	pc, lr			@ back to caller + +	.align	5 +.globl reset_cpu +reset_cpu: +	ldr	r1, rstctl      /* get addr for global reset reg */ +	mov     r3, #0x3	/* full reset pll+mpu */ +	str	r3, [r1]        /* force reset */ +	mov	r0, r0 +_loop_forever: +	b	_loop_forever +rstctl: +	.word	PM_RSTCTRL_WKUP diff --git a/doc/README.ne2000 b/doc/README.ne2000 new file mode 100644 index 000000000..d5ae9a9eb --- /dev/null +++ b/doc/README.ne2000 @@ -0,0 +1,38 @@ +This driver supports NE2000 compatible cards (those based on DP8390, +DP83902 and similar). It can be used with PCMCIA/CF cards provided +that the CCR is correctly initialized. + +The code is based on sources from the Linux kernel (pcnet_cs.c, +8390.h) and eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 +wonderful world are GPL, so this is, of course, GPL. + +I developed and tested this driver on a custom PXA255 based system and +with a billionton CF network card connected to the PCMCIA interface of +the micro (have a look at README.PXA_CF for the support of this port). + +The options you have to specify in the config file are (with the +value for my board as an example): + +#define CONFIG_DRIVER_NE2000 + +- Enables the driver + +#define CONFIG_DRIVER_NE2000_BASE (0x20000000+0x300) + +- Address where the board is mapped + +#define CONFIG_DRIVER_NE2000_CCR (0x28000000+0x3f8) + +- Address of the CCR (card configuration register). It could be found +by enabling DEBUG in cmd_pcmcia.c. If this is not defined nothing is +done as far as PCMCIA support is concerned. + +#define CONFIG_DRIVER_NE2000_VAL (0x20) + +- The value to be written in the CCR. It selects among different I/O +spaces that could be used by the card. + + +Enjoy! + +Christian Pellegrin <chri@ascensit.com> diff --git a/drivers/8390.h b/drivers/8390.h new file mode 100644 index 000000000..4e3cdd217 --- /dev/null +++ b/drivers/8390.h @@ -0,0 +1,126 @@ +/* + +Ported to U-Boot  by Christian Pellegrin <chri@ascensit.com> + +Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and +eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world +are GPL, so this is, of course, GPL. + +*/ + +/* Generic NS8390 register definitions. */ +/* This file is part of Donald Becker's 8390 drivers, and is distributed +   under the same license. Auto-loading of 8390.o only in v2.2 - Paul G. +   Some of these names and comments originated from the Crynwr +   packet drivers, which are distributed under the GPL. */ + +#ifndef _8390_h +#define _8390_h + +/* Some generic ethernet register configurations. */ +#define E8390_TX_IRQ_MASK	0xa	/* For register EN0_ISR */ +#define E8390_RX_IRQ_MASK	0x5 +#define E8390_RXCONFIG		0x4	/* EN0_RXCR: broadcasts, no multicast,errors */ +#define E8390_RXOFF		0x20	/* EN0_RXCR: Accept no packets */ +#define E8390_TXCONFIG		0x00	/* EN0_TXCR: Normal transmit mode */ +#define E8390_TXOFF		0x02	/* EN0_TXCR: Transmitter off */ + +/*  Register accessed at EN_CMD, the 8390 base addr.  */ +#define E8390_STOP	0x01	/* Stop and reset the chip */ +#define E8390_START	0x02	/* Start the chip, clear reset */ +#define E8390_TRANS	0x04	/* Transmit a frame */ +#define E8390_RREAD	0x08	/* Remote read */ +#define E8390_RWRITE	0x10	/* Remote write  */ +#define E8390_NODMA	0x20	/* Remote DMA */ +#define E8390_PAGE0	0x00	/* Select page chip registers */ +#define E8390_PAGE1	0x40	/* using the two high-order bits */ +#define E8390_PAGE2	0x80	/* Page 3 is invalid. */ + +/* + *	Only generate indirect loads given a machine that needs them. + *      - removed AMIGA_PCMCIA from this list, handled as ISA io now + */ + +#define n2k_inb(port)   (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE))) +#define n2k_outb(val,port)  (*((volatile unsigned char *)(port+CONFIG_DRIVER_NE2000_BASE)) = val) + +#define EI_SHIFT(x)	(x) + +#define E8390_CMD	EI_SHIFT(0x00)  /* The command register (for all pages) */ +/* Page 0 register offsets. */ +#define EN0_CLDALO	EI_SHIFT(0x01)	/* Low byte of current local dma addr  RD */ +#define EN0_STARTPG	EI_SHIFT(0x01)	/* Starting page of ring bfr WR */ +#define EN0_CLDAHI	EI_SHIFT(0x02)	/* High byte of current local dma addr  RD */ +#define EN0_STOPPG	EI_SHIFT(0x02)	/* Ending page +1 of ring bfr WR */ +#define EN0_BOUNDARY	EI_SHIFT(0x03)	/* Boundary page of ring bfr RD WR */ +#define EN0_TSR		EI_SHIFT(0x04)	/* Transmit status reg RD */ +#define EN0_TPSR	EI_SHIFT(0x04)	/* Transmit starting page WR */ +#define EN0_NCR		EI_SHIFT(0x05)	/* Number of collision reg RD */ +#define EN0_TCNTLO	EI_SHIFT(0x05)	/* Low  byte of tx byte count WR */ +#define EN0_FIFO	EI_SHIFT(0x06)	/* FIFO RD */ +#define EN0_TCNTHI	EI_SHIFT(0x06)	/* High byte of tx byte count WR */ +#define EN0_ISR		EI_SHIFT(0x07)	/* Interrupt status reg RD WR */ +#define EN0_CRDALO	EI_SHIFT(0x08)	/* low byte of current remote dma address RD */ +#define EN0_RSARLO	EI_SHIFT(0x08)	/* Remote start address reg 0 */ +#define EN0_CRDAHI	EI_SHIFT(0x09)	/* high byte, current remote dma address RD */ +#define EN0_RSARHI	EI_SHIFT(0x09)	/* Remote start address reg 1 */ +#define EN0_RCNTLO	EI_SHIFT(0x0a)	/* Remote byte count reg WR */ +#define EN0_RCNTHI	EI_SHIFT(0x0b)	/* Remote byte count reg WR */ +#define EN0_RSR		EI_SHIFT(0x0c)	/* rx status reg RD */ +#define EN0_RXCR	EI_SHIFT(0x0c)	/* RX configuration reg WR */ +#define EN0_TXCR	EI_SHIFT(0x0d)	/* TX configuration reg WR */ +#define EN0_COUNTER0	EI_SHIFT(0x0d)	/* Rcv alignment error counter RD */ +#define EN0_DCFG	EI_SHIFT(0x0e)	/* Data configuration reg WR */ +#define EN0_COUNTER1	EI_SHIFT(0x0e)	/* Rcv CRC error counter RD */ +#define EN0_IMR		EI_SHIFT(0x0f)	/* Interrupt mask reg WR */ +#define EN0_COUNTER2	EI_SHIFT(0x0f)	/* Rcv missed frame error counter RD */ + +/* Bits in EN0_ISR - Interrupt status register */ +#define ENISR_RX	0x01	/* Receiver, no error */ +#define ENISR_TX	0x02	/* Transmitter, no error */ +#define ENISR_RX_ERR	0x04	/* Receiver, with error */ +#define ENISR_TX_ERR	0x08	/* Transmitter, with error */ +#define ENISR_OVER	0x10	/* Receiver overwrote the ring */ +#define ENISR_COUNTERS	0x20	/* Counters need emptying */ +#define ENISR_RDC	0x40	/* remote dma complete */ +#define ENISR_RESET	0x80	/* Reset completed */ +#define ENISR_ALL	0x3f	/* Interrupts we will enable */ + +/* Bits in EN0_DCFG - Data config register */ +#define ENDCFG_WTS	0x01	/* word transfer mode selection */ +#define ENDCFG_BOS	0x02	/* byte order selection */ +#define ENDCFG_AUTO_INIT   0x10        /* Auto-init to remove packets from ring */ +#define ENDCFG_FIFO		0x40	/* 8 bytes */ + + + +/* Page 1 register offsets. */ +#define EN1_PHYS   EI_SHIFT(0x01)	/* This board's physical enet addr RD WR */ +#define EN1_PHYS_SHIFT(i)  EI_SHIFT(i+1) /* Get and set mac address */ +#define EN1_CURPAG EI_SHIFT(0x07)	/* Current memory page RD WR */ +#define EN1_MULT   EI_SHIFT(0x08)	/* Multicast filter mask array (8 bytes) RD WR */ +#define EN1_MULT_SHIFT(i)  EI_SHIFT(8+i) /* Get and set multicast filter */ + +/* Bits in received packet status byte and EN0_RSR*/ +#define ENRSR_RXOK	0x01	/* Received a good packet */ +#define ENRSR_CRC	0x02	/* CRC error */ +#define ENRSR_FAE	0x04	/* frame alignment error */ +#define ENRSR_FO	0x08	/* FIFO overrun */ +#define ENRSR_MPA	0x10	/* missed pkt */ +#define ENRSR_PHY	0x20	/* physical/multicast address */ +#define ENRSR_DIS	0x40	/* receiver disable. set in monitor mode */ +#define ENRSR_DEF	0x80	/* deferring */ + +/* Transmitted packet status, EN0_TSR. */ +#define ENTSR_PTX 0x01	/* Packet transmitted without error */ +#define ENTSR_ND  0x02	/* The transmit wasn't deferred. */ +#define ENTSR_COL 0x04	/* The transmit collided at least once. */ +#define ENTSR_ABT 0x08  /* The transmit collided 16 times, and was deferred. */ +#define ENTSR_CRS 0x10	/* The carrier sense was lost. */ +#define ENTSR_FU  0x20  /* A "FIFO underrun" occurred during transmit. */ +#define ENTSR_CDH 0x40	/* The collision detect "heartbeat" signal was lost. */ +#define ENTSR_OWC 0x80  /* There was an out-of-window collision. */ + +#define NIC_RECEIVE_MONITOR_MODE 0x20 + +#endif /* _8390_h */ diff --git a/drivers/Makefile b/drivers/Makefile index 8b73d66d2..cc13a7f22 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -32,9 +32,10 @@ OBJS	= 3c589.o 5701rls.o ali512x.o \  	  cs8900.o ct69000.o dataflash.o dc2114x.o dm9000x.o \  	  e1000.o eepro100.o \  	  i8042.o i82365.o inca-ip_sw.o keyboard.o \ -	  lan91c96.o natsemi.o netarm_eth.o netconsole.o \ +	  lan91c96.o \ +	  natsemi.o ne2000.o netarm_eth.o netconsole.o \  	  ns16550.o ns8382x.o ns87308.o omap1510_i2c.o \ -	  pci.o pci_auto.o pci_indirect.o \ +	  omap24xx_i2c.o pci.o pci_auto.o pci_indirect.o \  	  pcnet.o plb2800_eth.o \  	  ps2ser.o ps2mult.o pc_keyb.o \  	  rtl8019.o rtl8139.o rtl8169.o \ diff --git a/drivers/ne2000.c b/drivers/ne2000.c new file mode 100644 index 000000000..b7ed87616 --- /dev/null +++ b/drivers/ne2000.c @@ -0,0 +1,963 @@ +/* +Ported to U-Boot  by Christian Pellegrin <chri@ascensit.com> + +Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and +eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world +are GPL, so this is, of course, GPL. + + +========================================================================== + +dev/if_dp83902a.c + +Ethernet device driver for NS DP83902a ethernet controller + +========================================================================== +####ECOSGPLCOPYRIGHTBEGIN#### +------------------------------------------- +This file is part of eCos, the Embedded Configurable Operating System. +Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + +eCos 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 or (at your option) any later version. + +eCos 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 eCos; if not, write to the Free Software Foundation, Inc., +59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + +As a special exception, if other files instantiate templates or use macros +or inline functions from this file, or you compile this file and link it +with other works to produce a work based on this file, this file does not +by itself cause the resulting work to be covered by the GNU General Public +License. However the source code for this file must still be made available +in accordance with section (3) of the GNU General Public License. + +This exception does not invalidate any other reasons why a work based on +this file might be covered by the GNU General Public License. + +Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +at http://sources.redhat.com/ecos/ecos-license/ +------------------------------------------- +####ECOSGPLCOPYRIGHTEND#### +####BSDCOPYRIGHTBEGIN#### + +------------------------------------------- + +Portions of this software may have been derived from OpenBSD or other sources, +and are covered by the appropriate copyright disclaimers included herein. + +------------------------------------------- + +####BSDCOPYRIGHTEND#### +========================================================================== +#####DESCRIPTIONBEGIN#### + +Author(s):    gthomas +Contributors: gthomas, jskov, rsandifo +Date:	      2001-06-13 +Purpose: +Description: + +FIXME:	      Will fail if pinged with large packets (1520 bytes) +Add promisc config +Add SNMP + +####DESCRIPTIONEND#### + + +========================================================================== + +*/ + +#include <common.h> +#include <command.h> +#include <net.h> +#include <malloc.h> + +#ifdef CONFIG_DRIVER_NE2000 + +/* wor around udelay resetting OCR */ +static void my_udelay(long us) { +	long tmo; + +	tmo = get_timer (0) + us * CFG_HZ / 1000000; /* will this be much greater than 0 ? */ +	while (get_timer (0) < tmo); +} + +#define mdelay(n)       my_udelay((n)*1000) + +/* forward definition of function used for the uboot interface */ +void uboot_push_packet_len(int len); +void uboot_push_tx_done(int key, int val); + +/* timeout for tx/rx in s */ +#define TOUT 5 + +#define ETHER_ADDR_LEN 6 + +/* +  ------------------------------------------------------------------------ +  Debugging details + +  Set to perms of: +  0 disables all debug output +  1 for process debug output +  2 for added data IO output: get_reg, put_reg +  4 for packet allocation/free output +  8 for only startup status, so we can tell we're installed OK +*/ +/*#define DEBUG 0xf*/ +#define DEBUG 0 + +#if DEBUG & 1 +#define DEBUG_FUNCTION() do { printf("%s\n", __FUNCTION__); } while (0) +#define DEBUG_LINE() do { printf("%d\n", __LINE__); } while (0) +#else +#define DEBUG_FUNCTION() do {} while(0) +#define DEBUG_LINE() do {} while(0) +#endif + +#include "ne2000.h" + +#if DEBUG & 1 +#define PRINTK(args...) printf(args) +#else +#define PRINTK(args...) +#endif + +static dp83902a_priv_data_t nic; /* just one instance of the card supported */ + +static bool +dp83902a_init(void) +{ +	dp83902a_priv_data_t *dp = &nic; +	cyg_uint8* base; +	int i; + +	DEBUG_FUNCTION(); + +	base = dp->base; +	if (!base) return false;  /* No device found */ + +	DEBUG_LINE(); + +	/* Prepare ESA */ +	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1);  /* Select page 1 */ +	/* Use the address from the serial EEPROM */ +	for (i = 0; i < 6; i++) +		DP_IN(base, DP_P1_PAR0+i, dp->esa[i]); +	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0);  /* Select page 0 */ + +	printf("NE2000 - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", +	       "eeprom", +	       dp->esa[0], +	       dp->esa[1], +	       dp->esa[2], +	       dp->esa[3], +	       dp->esa[4], +	       dp->esa[5] ); + +	return true; +} + +static void +dp83902a_stop(void) +{ +	dp83902a_priv_data_t *dp = &nic; +	cyg_uint8 *base = dp->base; + +	DEBUG_FUNCTION(); + +	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP);  /* Brutal */ +	DP_OUT(base, DP_ISR, 0xFF);		/* Clear any pending interrupts */ +	DP_OUT(base, DP_IMR, 0x00);		/* Disable all interrupts */ + +	dp->running = false; +} + +/* +  This function is called to "start up" the interface.  It may be called +  multiple times, even when the hardware is already running.  It will be +  called whenever something "hardware oriented" changes and should leave +  the hardware ready to send/receive packets. +*/ +static void +dp83902a_start(unsigned char * enaddr) +{ +	dp83902a_priv_data_t *dp = &nic; +	cyg_uint8 *base = dp->base; +	int i; + +	DEBUG_FUNCTION(); + +	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_STOP); /* Brutal */ +	DP_OUT(base, DP_DCR, DP_DCR_INIT); +	DP_OUT(base, DP_RBCH, 0);		/* Remote byte count */ +	DP_OUT(base, DP_RBCL, 0); +	DP_OUT(base, DP_RCR, DP_RCR_MON);	/* Accept no packets */ +	DP_OUT(base, DP_TCR, DP_TCR_LOCAL);	/* Transmitter [virtually] off */ +	DP_OUT(base, DP_TPSR, dp->tx_buf1);	/* Transmitter start page */ +	dp->tx1 = dp->tx2 = 0; +	dp->tx_next = dp->tx_buf1; +	dp->tx_started = false; +	DP_OUT(base, DP_PSTART, dp->rx_buf_start); /* Receive ring start page */ +	DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1); /* Receive ring boundary */ +	DP_OUT(base, DP_PSTOP, dp->rx_buf_end);	/* Receive ring end page */ +	dp->rx_next = dp->rx_buf_start-1; +	DP_OUT(base, DP_ISR, 0xFF);		/* Clear any pending interrupts */ +	DP_OUT(base, DP_IMR, DP_IMR_All);	/* Enable all interrupts */ +	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE1 | DP_CR_STOP);  /* Select page 1 */ +	DP_OUT(base, DP_P1_CURP, dp->rx_buf_start);   /* Current page - next free page for Rx */ +	for (i = 0;  i < ETHER_ADDR_LEN;  i++) { +		DP_OUT(base, DP_P1_PAR0+i, enaddr[i]); +	} +	/* Enable and start device */ +	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); +	DP_OUT(base, DP_TCR, DP_TCR_NORMAL); /* Normal transmit operations */ +	DP_OUT(base, DP_RCR, DP_RCR_AB);  /* Accept broadcast, no errors, no multicast */ +	dp->running = true; +} + +/* +  This routine is called to start the transmitter.  It is split out from the +  data handling routine so it may be called either when data becomes first +  available or when an Tx interrupt occurs +*/ + +static void +dp83902a_start_xmit(int start_page, int len) +{ +	dp83902a_priv_data_t *dp = (dp83902a_priv_data_t *) &nic; +	cyg_uint8 *base = dp->base; + +	DEBUG_FUNCTION(); + +#if DEBUG & 1 +	printf("Tx pkt %d len %d\n", start_page, len); +	if (dp->tx_started) +		printf("TX already started?!?\n"); +#endif + +	DP_OUT(base, DP_ISR, (DP_ISR_TxP | DP_ISR_TxE)); +	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); +	DP_OUT(base, DP_TBCL, len & 0xFF); +	DP_OUT(base, DP_TBCH, len >> 8); +	DP_OUT(base, DP_TPSR, start_page); +	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START); + +	dp->tx_started = true; +} + +/* +  This routine is called to send data to the hardware.  It is known a-priori +  that there is free buffer space (dp->tx_next). +*/ +static void +dp83902a_send(unsigned char *data, int total_len, unsigned long key) +{ +	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; +	cyg_uint8 *base = dp->base; +	int len, start_page, pkt_len, i, isr; +#if DEBUG & 4 +	int dx; +#endif + +	DEBUG_FUNCTION(); + +	len = pkt_len = total_len; +	if (pkt_len < IEEE_8023_MIN_FRAME) pkt_len = IEEE_8023_MIN_FRAME; + +	start_page = dp->tx_next; +	if (dp->tx_next == dp->tx_buf1) { +		dp->tx1 = start_page; +		dp->tx1_len = pkt_len; +		dp->tx1_key = key; +		dp->tx_next = dp->tx_buf2; +	} else { +		dp->tx2 = start_page; +		dp->tx2_len = pkt_len; +		dp->tx2_key = key; +		dp->tx_next = dp->tx_buf1; +	} + +#if DEBUG & 5 +	printf("TX prep page %d len %d\n", start_page, pkt_len); +#endif + +	DP_OUT(base, DP_ISR, DP_ISR_RDC);  /* Clear end of DMA */ +	{ +		/* Dummy read. The manual sez something slightly different, */ +		/* but the code is extended a bit to do what Hitachi's monitor */ +		/* does (i.e., also read data). */ + +		cyg_uint16 tmp; +		int len = 1; + +		DP_OUT(base, DP_RSAL, 0x100-len); +		DP_OUT(base, DP_RSAH, (start_page-1) & 0xff); +		DP_OUT(base, DP_RBCL, len); +		DP_OUT(base, DP_RBCH, 0); +		DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_RDMA | DP_CR_START); +		DP_IN_DATA(dp->data, tmp); +	} + +#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA +	/* Stall for a bit before continuing to work around random data */ +	/* corruption problems on some platforms. */ +	CYGACC_CALL_IF_DELAY_US(1); +#endif + +	/* Send data to device buffer(s) */ +	DP_OUT(base, DP_RSAL, 0); +	DP_OUT(base, DP_RSAH, start_page); +	DP_OUT(base, DP_RBCL, pkt_len & 0xFF); +	DP_OUT(base, DP_RBCH, pkt_len >> 8); +	DP_OUT(base, DP_CR, DP_CR_WDMA | DP_CR_START); + +	/* Put data into buffer */ +#if DEBUG & 4 +	printf(" sg buf %08lx len %08x\n ", (unsigned long) data, len); +	dx = 0; +#endif +	while (len > 0) { +#if DEBUG & 4 +		printf(" %02x", *data); +		if (0 == (++dx % 16)) printf("\n "); +#endif +		DP_OUT_DATA(dp->data, *data++); +		len--; +	} +#if DEBUG & 4 +	printf("\n"); +#endif +	if (total_len < pkt_len) { +#if DEBUG & 4 +		printf("  + %d bytes of padding\n", pkt_len - total_len); +#endif +		/* Padding to 802.3 length was required */ +		for (i = total_len;  i < pkt_len;) { +			i++; +			DP_OUT_DATA(dp->data, 0); +		} +	} + +#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA +	/* After last data write, delay for a bit before accessing the */ +	/* device again, or we may get random data corruption in the last */ +	/* datum (on some platforms). */ +	CYGACC_CALL_IF_DELAY_US(1); +#endif + +	/* Wait for DMA to complete */ +	do { +		DP_IN(base, DP_ISR, isr); +	} while ((isr & DP_ISR_RDC) == 0); +	/* Then disable DMA */ +	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); + +	/* Start transmit if not already going */ +	if (!dp->tx_started) { +		if (start_page == dp->tx1) { +			dp->tx_int = 1;  /* Expecting interrupt from BUF1 */ +		} else { +			dp->tx_int = 2;  /* Expecting interrupt from BUF2 */ +		} +		dp83902a_start_xmit(start_page, pkt_len); +	} +} + +/* +  This function is called when a packet has been received.  It's job is +  to prepare to unload the packet from the hardware.  Once the length of +  the packet is known, the upper layer of the driver can be told.  When +  the upper layer is ready to unload the packet, the internal function +  'dp83902a_recv' will be called to actually fetch it from the hardware. +*/ +static void +dp83902a_RxEvent(void) +{ +	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; +	cyg_uint8 *base = dp->base; +	unsigned char rsr; +	unsigned char rcv_hdr[4]; +	int i, len, pkt, cur; + +	DEBUG_FUNCTION(); + +	DP_IN(base, DP_RSR, rsr); +	while (true) { +		/* Read incoming packet header */ +		DP_OUT(base, DP_CR, DP_CR_PAGE1 | DP_CR_NODMA | DP_CR_START); +		DP_IN(base, DP_P1_CURP, cur); +		DP_OUT(base, DP_P1_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); +		DP_IN(base, DP_BNDRY, pkt); + +		pkt += 1; +		if (pkt == dp->rx_buf_end) +			pkt = dp->rx_buf_start; + +		if (pkt == cur) { +			break; +		} +		DP_OUT(base, DP_RBCL, sizeof(rcv_hdr)); +		DP_OUT(base, DP_RBCH, 0); +		DP_OUT(base, DP_RSAL, 0); +		DP_OUT(base, DP_RSAH, pkt); +		if (dp->rx_next == pkt) { +			if (cur == dp->rx_buf_start) +				DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1); +			else +				DP_OUT(base, DP_BNDRY, cur-1); /* Update pointer */ +			return; +		} +		dp->rx_next = pkt; +		DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ +		DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START); +#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA +		CYGACC_CALL_IF_DELAY_US(10); +#endif + +		for (i = 0;  i < sizeof(rcv_hdr);) { +			DP_IN_DATA(dp->data, rcv_hdr[i++]); +		} + +#if DEBUG & 5 +		printf("rx hdr %02x %02x %02x %02x\n", +		       rcv_hdr[0], rcv_hdr[1], rcv_hdr[2], rcv_hdr[3]); +#endif +		len = ((rcv_hdr[3] << 8) | rcv_hdr[2]) - sizeof(rcv_hdr); +		uboot_push_packet_len(len); +		if (rcv_hdr[1] == dp->rx_buf_start) +			DP_OUT(base, DP_BNDRY, dp->rx_buf_end-1); +		else +			DP_OUT(base, DP_BNDRY, rcv_hdr[1]-1); /* Update pointer */ +	} +} + +/* +  This function is called as a result of the "eth_drv_recv()" call above. +  It's job is to actually fetch data for a packet from the hardware once +  memory buffers have been allocated for the packet.  Note that the buffers +  may come in pieces, using a scatter-gather list.  This allows for more +  efficient processing in the upper layers of the stack. +*/ +static void +dp83902a_recv(unsigned char *data, int len) +{ +	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; +	cyg_uint8 *base = dp->base; +	int i, mlen; +	cyg_uint8 saved_char = 0; +	bool saved; +#if DEBUG & 4 +	int dx; +#endif + +	DEBUG_FUNCTION(); + +#if DEBUG & 5 +	printf("Rx packet %d length %d\n", dp->rx_next, len); +#endif + +	/* Read incoming packet data */ +	DP_OUT(base, DP_CR, DP_CR_PAGE0 | DP_CR_NODMA | DP_CR_START); +	DP_OUT(base, DP_RBCL, len & 0xFF); +	DP_OUT(base, DP_RBCH, len >> 8); +	DP_OUT(base, DP_RSAL, 4);		/* Past header */ +	DP_OUT(base, DP_RSAH, dp->rx_next); +	DP_OUT(base, DP_ISR, DP_ISR_RDC); /* Clear end of DMA */ +	DP_OUT(base, DP_CR, DP_CR_RDMA | DP_CR_START); +#ifdef CYGHWR_NS_DP83902A_PLF_BROKEN_RX_DMA +	CYGACC_CALL_IF_DELAY_US(10); +#endif + +	saved = false; +	for (i = 0;  i < 1;  i++) { +		if (data) { +			mlen = len; +#if DEBUG & 4 +			printf(" sg buf %08lx len %08x \n", (unsigned long) data, mlen); +			dx = 0; +#endif +			while (0 < mlen) { +				/* Saved byte from previous loop? */ +				if (saved) { +					*data++ = saved_char; +					mlen--; +					saved = false; +					continue; +				} + +				{ +					cyg_uint8 tmp; +					DP_IN_DATA(dp->data, tmp); +#if DEBUG & 4 +					printf(" %02x", tmp); +					if (0 == (++dx % 16)) printf("\n "); +#endif +					*data++ = tmp;; +					mlen--; +				} +			} +#if DEBUG & 4 +			printf("\n"); +#endif +		} +	} +} + +static void +dp83902a_TxEvent(void) +{ +	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; +	cyg_uint8 *base = dp->base; +	unsigned char tsr; +	unsigned long key; + +	DEBUG_FUNCTION(); + +	DP_IN(base, DP_TSR, tsr); +	if (dp->tx_int == 1) { +		key = dp->tx1_key; +		dp->tx1 = 0; +	} else { +		key = dp->tx2_key; +		dp->tx2 = 0; +	} +	/* Start next packet if one is ready */ +	dp->tx_started = false; +	if (dp->tx1) { +		dp83902a_start_xmit(dp->tx1, dp->tx1_len); +		dp->tx_int = 1; +	} else if (dp->tx2) { +		dp83902a_start_xmit(dp->tx2, dp->tx2_len); +		dp->tx_int = 2; +	} else { +		dp->tx_int = 0; +	} +	/* Tell higher level we sent this packet */ +	uboot_push_tx_done(key, 0); +} + +/* Read the tally counters to clear them.  Called in response to a CNT */ +/* interrupt. */ +static void +dp83902a_ClearCounters(void) +{ +	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; +	cyg_uint8 *base = dp->base; +	cyg_uint8 cnt1, cnt2, cnt3; + +	DP_IN(base, DP_FER, cnt1); +	DP_IN(base, DP_CER, cnt2); +	DP_IN(base, DP_MISSED, cnt3); +	DP_OUT(base, DP_ISR, DP_ISR_CNT); +} + +/* Deal with an overflow condition.  This code follows the procedure set */ +/* out in section 7.0 of the datasheet. */ +static void +dp83902a_Overflow(void) +{ +	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)&nic; +	cyg_uint8 *base = dp->base; +	cyg_uint8 isr; + +	/* Issue a stop command and wait 1.6ms for it to complete. */ +	DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA); +	CYGACC_CALL_IF_DELAY_US(1600); + +	/* Clear the remote byte counter registers. */ +	DP_OUT(base, DP_RBCL, 0); +	DP_OUT(base, DP_RBCH, 0); + +	/* Enter loopback mode while we clear the buffer. */ +	DP_OUT(base, DP_TCR, DP_TCR_LOCAL); +	DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA); + +	/* Read in as many packets as we can and acknowledge any and receive */ +	/* interrupts.  Since the buffer has overflowed, a receive event of */ +	/* some kind will have occured. */ +	dp83902a_RxEvent(); +	DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE); + +	/* Clear the overflow condition and leave loopback mode. */ +	DP_OUT(base, DP_ISR, DP_ISR_OFLW); +	DP_OUT(base, DP_TCR, DP_TCR_NORMAL); + +	/* If a transmit command was issued, but no transmit event has occured, */ +	/* restart it here. */ +	DP_IN(base, DP_ISR, isr); +	if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) { +		DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START); +	} +} + +static void +dp83902a_poll(void) +{ +	struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *) &nic; +	cyg_uint8 *base = dp->base; +	unsigned char isr; + +	DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_PAGE0 | DP_CR_START); +	DP_IN(base, DP_ISR, isr); +	while (0 != isr) { +		/* The CNT interrupt triggers when the MSB of one of the error */ +		/* counters is set.  We don't much care about these counters, but */ +		/* we should read their values to reset them. */ +		if (isr & DP_ISR_CNT) { +			dp83902a_ClearCounters(); +		} +		/* Check for overflow.  It's a special case, since there's a */ +		/* particular procedure that must be followed to get back into */ +		/* a running state.a */ +		if (isr & DP_ISR_OFLW) { +			dp83902a_Overflow(); +		} else { +			/* Other kinds of interrupts can be acknowledged simply by */ +			/* clearing the relevant bits of the ISR.  Do that now, then */ +			/* handle the interrupts we care about. */ +			DP_OUT(base, DP_ISR, isr);      /* Clear set bits */ +			if (!dp->running) break;	/* Is this necessary? */ +			/* Check for tx_started on TX event since these may happen */ +			/* spuriously it seems. */ +			if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) { +				dp83902a_TxEvent(); +			} +			if (isr & (DP_ISR_RxP|DP_ISR_RxE)) { +				dp83902a_RxEvent(); +			} +		} +		DP_IN(base, DP_ISR, isr); +	} +} + +/* find prom (taken from pc_net_cs.c from Linux) */ + +#include "8390.h" + +typedef struct hw_info_t { +	u_int	offset; +	u_char	a0, a1, a2; +	u_int	flags; +} hw_info_t; + +#define DELAY_OUTPUT	0x01 +#define HAS_MISC_REG	0x02 +#define USE_BIG_BUF	0x04 +#define HAS_IBM_MISC	0x08 +#define IS_DL10019	0x10 +#define IS_DL10022	0x20 +#define HAS_MII		0x40 +#define USE_SHMEM	0x80	/* autodetected */ + +#define AM79C9XX_HOME_PHY	0x00006B90  /* HomePNA PHY */ +#define AM79C9XX_ETH_PHY	0x00006B70  /* 10baseT PHY */ +#define MII_PHYID_REV_MASK	0xfffffff0 +#define MII_PHYID_REG1		0x02 +#define MII_PHYID_REG2		0x03 + +static hw_info_t hw_info[] = { +	{ /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT }, +	{ /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 }, +	{ /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 }, +	{ /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94, +	  DELAY_OUTPUT | HAS_IBM_MISC }, +	{ /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 }, +	{ /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 }, +	{ /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 }, +	{ /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 }, +	{ /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 }, +	{ /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 }, +	{ /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 }, +	{ /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 }, +	{ /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* IBM FME */ 0x0374, 0x00, 0x04, 0xac, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 }, +	{ /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 }, +	{ /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 }, +	{ /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 }, +	{ /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 }, +	{ /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 }, +	{ /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45, +	  HAS_MISC_REG | HAS_IBM_MISC }, +	{ /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 }, +	{ /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 }, +	{ /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 }, +	{ /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b, +	  DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF }, +	{ /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 }, +	{ /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 }, +	{ /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 }, +	{ /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 }, +	{ /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 } +}; + +#define NR_INFO		(sizeof(hw_info)/sizeof(hw_info_t)) + +static hw_info_t default_info = { 0, 0, 0, 0, 0 }; + +unsigned char dev_addr[6]; + +#define PCNET_CMD	0x00 +#define PCNET_DATAPORT	0x10	/* NatSemi-defined port window offset. */ +#define PCNET_RESET	0x1f	/* Issue a read to reset, a write to clear. */ +#define PCNET_MISC	0x18	/* For IBM CCAE and Socket EA cards */ + +unsigned long nic_base; + +static void pcnet_reset_8390(void) +{ +	int i, r; + +	PRINTK("nic base is %lx\n", nic_base); + +#if 1 +	n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); +	PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD)); +	n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD); +	PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD)); +	n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); +	PRINTK("cmd (at %lx) is %x\n", nic_base+ E8390_CMD, n2k_inb(E8390_CMD)); +#endif +	n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); + +	n2k_outb(n2k_inb(nic_base + PCNET_RESET), PCNET_RESET); + +	for (i = 0; i < 100; i++) { +		if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0) +			break; +		PRINTK("got %x in reset\n", r); +		my_udelay(100); +	} +	n2k_outb(ENISR_RESET, EN0_ISR); /* Ack intr. */ + +	if (i == 100) +		printf("pcnet_reset_8390() did not complete.\n"); +} /* pcnet_reset_8390 */ + +static hw_info_t * get_prom(void ) { +	unsigned char prom[32]; +	int i, j; +	struct { +		u_char value, offset; +	} program_seq[] = { +		{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ +		{0x48,	EN0_DCFG},	/* Set byte-wide (0x48) access. */ +		{0x00,	EN0_RCNTLO},	/* Clear the count regs. */ +		{0x00,	EN0_RCNTHI}, +		{0x00,	EN0_IMR},	/* Mask completion irq. */ +		{0xFF,	EN0_ISR}, +		{E8390_RXOFF, EN0_RXCR},	/* 0x20  Set to monitor */ +		{E8390_TXOFF, EN0_TXCR},	/* 0x02  and loopback mode. */ +		{32,	EN0_RCNTLO}, +		{0x00,	EN0_RCNTHI}, +		{0x00,	EN0_RSARLO},	/* DMA starting at 0x0000. */ +		{0x00,	EN0_RSARHI}, +		{E8390_RREAD+E8390_START, E8390_CMD}, +	}; + +	PRINTK("trying to get MAC via prom reading\n"); + +	pcnet_reset_8390(); + +	mdelay(10); + +	for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) +		n2k_outb(program_seq[i].value, program_seq[i].offset); + +	PRINTK("PROM:"); +	for (i = 0; i < 32; i++) { +		prom[i] = n2k_inb(PCNET_DATAPORT); +		PRINTK(" %02x", prom[i]); +	} +	PRINTK("\n"); +	for (i = 0; i < NR_INFO; i++) { +		if ((prom[0] == hw_info[i].a0) && +		    (prom[2] == hw_info[i].a1) && +		    (prom[4] == hw_info[i].a2)) { +			PRINTK("matched board %d\n", i); +			break; +		} +	} +	if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) { +		for (j = 0; j < 6; j++) +			dev_addr[j] = prom[j<<1]; +		PRINTK("on exit i is %d/%ld\n", i, NR_INFO); +		PRINTK("MAC address is %02x:%02x:%02x:%02x:%02x:%02x\n", +		       dev_addr[0],dev_addr[1],dev_addr[2],dev_addr[3],dev_addr[4],dev_addr[5]); +		return (i < NR_INFO) ? hw_info+i : &default_info; +	} +	return NULL; +} + +/* U-boot specific routines */ + +#define NB 5 + +static unsigned char *pbuf = NULL; +static int plen[NB]; +static int nrx = 0; + +static int pkey = -1; + +void uboot_push_packet_len(int len) { +	PRINTK("pushed len = %d, nrx = %d\n", len, nrx); +	if (len>=2000) { +		printf("NE2000: packet too big\n"); +		return; +	} +	if (nrx >= NB) { +		printf("losing packets in rx\n"); +		return; +	} +	plen[nrx] = len; +	dp83902a_recv(&pbuf[nrx*2000], len); +	nrx++; +} + +void uboot_push_tx_done(int key, int val) { +	PRINTK("pushed key = %d\n", key); +	pkey = key; +} + +int eth_init(bd_t *bd) { +	static hw_info_t * r; +	char ethaddr[20]; + +	PRINTK("### eth_init\n"); + +	if (!pbuf) { +		pbuf = malloc(NB*2000); +		if (!pbuf) { +			printf("Cannot allocate rx buffers\n"); +			return -1; +		} +	} + +#ifdef CONFIG_DRIVER_NE2000_CCR +	{ +		volatile unsigned char *p =  (volatile unsigned char *) CONFIG_DRIVER_NE2000_CCR; + +		PRINTK("CCR before is %x\n", *p); +		*p = CONFIG_DRIVER_NE2000_VAL; +		PRINTK("CCR after is %x\n", *p); +	} +#endif + +	nic_base = CONFIG_DRIVER_NE2000_BASE; +	nic.base = (cyg_uint8 *) CONFIG_DRIVER_NE2000_BASE; + +	r = get_prom(); +	if (!r) +		return -1; + +	sprintf (ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X", +		 dev_addr[0], dev_addr[1], +		 dev_addr[2], dev_addr[3], +		 dev_addr[4], dev_addr[5]) ; +	PRINTK("Set environment from HW MAC addr = \"%s\"\n", ethaddr); +	setenv ("ethaddr", ethaddr); + + +#define DP_DATA		0x10 +	nic.data = nic.base + DP_DATA; +	nic.tx_buf1 = 0x40; +	nic.tx_buf2 = 0x48; +	nic.rx_buf_start = 0x50; +	nic.rx_buf_end = 0x80; + +	if (dp83902a_init() == false) +		return -1; +	dp83902a_start(dev_addr); +	return 0; +} + +void eth_halt() { + +	PRINTK("### eth_halt\n"); + +	dp83902a_stop(); +} + +int eth_rx() { +	int j, tmo; + +	PRINTK("### eth_rx\n"); + +	tmo = get_timer (0) + TOUT * CFG_HZ; +	while(1) { +		dp83902a_poll(); +		if (nrx > 0) { +			for(j=0; j<nrx; j++) { +				NetReceive(&pbuf[j*2000], plen[j]); +			} +			nrx = 0; +			return 1; +		} +		if (get_timer (0) >= tmo) { +			printf("timeout during rx\n"); +			return 0; +		} +	} +	return 0; +} + +int eth_send(volatile void *packet, int length) { +	int tmo; + +	PRINTK("### eth_send\n"); + +	pkey = -1; + +	dp83902a_send((unsigned char *) packet, length, 666); +	tmo = get_timer (0) + TOUT * CFG_HZ; +	while(1) { +		dp83902a_poll(); +		if (pkey != -1) { +			PRINTK("Packet sucesfully sent\n"); +			return 0; +		} +		if (get_timer (0) >= tmo) { +			printf("transmission error (timoeut)\n"); +			return 0; +		} + +	} +	return 0; +} + +#endif diff --git a/drivers/ne2000.h b/drivers/ne2000.h new file mode 100644 index 000000000..2955533d7 --- /dev/null +++ b/drivers/ne2000.h @@ -0,0 +1,279 @@ +/* +Ported to U-Boot  by Christian Pellegrin <chri@ascensit.com> + +Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and +eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world +are GPL, so this is, of course, GPL. + + +========================================================================== + +      dev/dp83902a.h + +      National Semiconductor DP83902a ethernet chip + +========================================================================== +####ECOSGPLCOPYRIGHTBEGIN#### + ------------------------------------------- + This file is part of eCos, the Embedded Configurable Operating System. + Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. + + eCos 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 or (at your option) any later version. + + eCos 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 eCos; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + + As a special exception, if other files instantiate templates or use macros + or inline functions from this file, or you compile this file and link it + with other works to produce a work based on this file, this file does not + by itself cause the resulting work to be covered by the GNU General Public + License. However the source code for this file must still be made available + in accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work based on + this file might be covered by the GNU General Public License. + + Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. + at http://sources.redhat.com/ecos/ecos-license/ */ + ------------------------------------------- +####ECOSGPLCOPYRIGHTEND#### +####BSDCOPYRIGHTBEGIN#### + + ------------------------------------------- + + Portions of this software may have been derived from OpenBSD or other sources, + and are covered by the appropriate copyright disclaimers included herein. + + ------------------------------------------- + +####BSDCOPYRIGHTEND#### +========================================================================== +#####DESCRIPTIONBEGIN#### + + Author(s):    gthomas + Contributors: gthomas, jskov + Date:         2001-06-13 + Purpose: + Description: + +####DESCRIPTIONEND#### + +========================================================================== + +*/ + +/* + ------------------------------------------------------------------------ + Macros for accessing DP registers + These can be overridden by the platform header +*/ + +#define DP_IN(_b_, _o_, _d_)  (_d_) = *( (volatile unsigned char *) ((_b_)+(_o_))) +#define DP_OUT(_b_, _o_, _d_) *( (volatile unsigned char *) ((_b_)+(_o_))) = (_d_) + +#define DP_IN_DATA(_b_, _d_)  (_d_) = *( (volatile unsigned char *) ((_b_))) +#define DP_OUT_DATA(_b_, _d_) *( (volatile unsigned char *) ((_b_))) = (_d_) + + +/* here is all the data */ + +#define cyg_uint8 unsigned char +#define cyg_uint16 unsigned short +#define bool int + +#define false 0 +#define true 1 + +#define CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA 1 +#define CYGACC_CALL_IF_DELAY_US(X) my_udelay(X) + +typedef struct dp83902a_priv_data { +    cyg_uint8* base; +    cyg_uint8* data; +    cyg_uint8* reset; +    int tx_next;           /* First free Tx page */ +    int tx_int;            /* Expecting interrupt from this buffer */ +    int rx_next;           /* First free Rx page */ +    int tx1, tx2;          /* Page numbers for Tx buffers */ +    unsigned long tx1_key, tx2_key;   /* Used to ack when packet sent */ +    int tx1_len, tx2_len; +    bool tx_started, running, hardwired_esa; +    cyg_uint8 esa[6]; +    void* plf_priv; + +    /* Buffer allocation */ +    int tx_buf1, tx_buf2; +    int rx_buf_start, rx_buf_end; +} dp83902a_priv_data_t; + +/* + ------------------------------------------------------------------------ + Some forward declarations +*/ +static void dp83902a_poll(void); + +/* ------------------------------------------------------------------------ */ +/* Register offsets */ + +#define DP_CR          0x00 +#define DP_CLDA0       0x01 +#define DP_PSTART      0x01             /* write */ +#define DP_CLDA1       0x02 +#define DP_PSTOP       0x02             /* write */ +#define DP_BNDRY       0x03 +#define DP_TSR         0x04 +#define DP_TPSR        0x04             /* write */ +#define DP_NCR         0x05 +#define DP_TBCL        0x05             /* write */ +#define DP_FIFO        0x06 +#define DP_TBCH        0x06             /* write */ +#define DP_ISR         0x07 +#define DP_CRDA0       0x08 +#define DP_RSAL        0x08             /* write */ +#define DP_CRDA1       0x09 +#define DP_RSAH        0x09             /* write */ +#define DP_RBCL        0x0a             /* write */ +#define DP_RBCH        0x0b             /* write */ +#define DP_RSR         0x0c +#define DP_RCR         0x0c             /* write */ +#define DP_FER         0x0d +#define DP_TCR         0x0d             /* write */ +#define DP_CER         0x0e +#define DP_DCR         0x0e             /* write */ +#define DP_MISSED      0x0f +#define DP_IMR         0x0f             /* write */ +#define DP_DATAPORT    0x10             /* "eprom" data port */ + +#define DP_P1_CR       0x00 +#define DP_P1_PAR0     0x01 +#define DP_P1_PAR1     0x02 +#define DP_P1_PAR2     0x03 +#define DP_P1_PAR3     0x04 +#define DP_P1_PAR4     0x05 +#define DP_P1_PAR5     0x06 +#define DP_P1_CURP     0x07 +#define DP_P1_MAR0     0x08 +#define DP_P1_MAR1     0x09 +#define DP_P1_MAR2     0x0a +#define DP_P1_MAR3     0x0b +#define DP_P1_MAR4     0x0c +#define DP_P1_MAR5     0x0d +#define DP_P1_MAR6     0x0e +#define DP_P1_MAR7     0x0f + +#define DP_P2_CR       0x00 +#define DP_P2_PSTART   0x01 +#define DP_P2_CLDA0    0x01             /* write */ +#define DP_P2_PSTOP    0x02 +#define DP_P2_CLDA1    0x02             /* write */ +#define DP_P2_RNPP     0x03 +#define DP_P2_TPSR     0x04 +#define DP_P2_LNPP     0x05 +#define DP_P2_ACH      0x06 +#define DP_P2_ACL      0x07 +#define DP_P2_RCR      0x0c +#define DP_P2_TCR      0x0d +#define DP_P2_DCR      0x0e +#define DP_P2_IMR      0x0f + +/* Command register - common to all pages */ + +#define DP_CR_STOP    0x01   /* Stop: software reset */ +#define DP_CR_START   0x02   /* Start: initialize device */ +#define DP_CR_TXPKT   0x04   /* Transmit packet */ +#define DP_CR_RDMA    0x08   /* Read DMA  (recv data from device) */ +#define DP_CR_WDMA    0x10   /* Write DMA (send data to device) */ +#define DP_CR_SEND    0x18   /* Send packet */ +#define DP_CR_NODMA   0x20   /* Remote (or no) DMA */ +#define DP_CR_PAGE0   0x00   /* Page select */ +#define DP_CR_PAGE1   0x40 +#define DP_CR_PAGE2   0x80 +#define DP_CR_PAGEMSK 0x3F   /* Used to mask out page bits */ + +/* Data configuration register */ + +#define DP_DCR_WTS    0x01   /* 1=16 bit word transfers */ +#define DP_DCR_BOS    0x02   /* 1=Little Endian */ +#define DP_DCR_LAS    0x04   /* 1=Single 32 bit DMA mode */ +#define DP_DCR_LS     0x08   /* 1=normal mode, 0=loopback */ +#define DP_DCR_ARM    0x10   /* 0=no send command (program I/O) */ +#define DP_DCR_FIFO_1 0x00   /* FIFO threshold */ +#define DP_DCR_FIFO_2 0x20 +#define DP_DCR_FIFO_4 0x40 +#define DP_DCR_FIFO_6 0x60 + +#define DP_DCR_INIT   (DP_DCR_LS|DP_DCR_FIFO_4) + +/* Interrupt status register */ + +#define DP_ISR_RxP    0x01   /* Packet received */ +#define DP_ISR_TxP    0x02   /* Packet transmitted */ +#define DP_ISR_RxE    0x04   /* Receive error */ +#define DP_ISR_TxE    0x08   /* Transmit error */ +#define DP_ISR_OFLW   0x10   /* Receive overflow */ +#define DP_ISR_CNT    0x20   /* Tally counters need emptying */ +#define DP_ISR_RDC    0x40   /* Remote DMA complete */ +#define DP_ISR_RESET  0x80   /* Device has reset (shutdown, error) */ + +/* Interrupt mask register */ + +#define DP_IMR_RxP    0x01   /* Packet received */ +#define DP_IMR_TxP    0x02   /* Packet transmitted */ +#define DP_IMR_RxE    0x04   /* Receive error */ +#define DP_IMR_TxE    0x08   /* Transmit error */ +#define DP_IMR_OFLW   0x10   /* Receive overflow */ +#define DP_IMR_CNT    0x20   /* Tall counters need emptying */ +#define DP_IMR_RDC    0x40   /* Remote DMA complete */ + +#define DP_IMR_All    0x3F   /* Everything but remote DMA */ + +/* Receiver control register */ + +#define DP_RCR_SEP    0x01   /* Save bad(error) packets */ +#define DP_RCR_AR     0x02   /* Accept runt packets */ +#define DP_RCR_AB     0x04   /* Accept broadcast packets */ +#define DP_RCR_AM     0x08   /* Accept multicast packets */ +#define DP_RCR_PROM   0x10   /* Promiscuous mode */ +#define DP_RCR_MON    0x20   /* Monitor mode - 1=accept no packets */ + +/* Receiver status register */ + +#define DP_RSR_RxP    0x01   /* Packet received */ +#define DP_RSR_CRC    0x02   /* CRC error */ +#define DP_RSR_FRAME  0x04   /* Framing error */ +#define DP_RSR_FO     0x08   /* FIFO overrun */ +#define DP_RSR_MISS   0x10   /* Missed packet */ +#define DP_RSR_PHY    0x20   /* 0=pad match, 1=mad match */ +#define DP_RSR_DIS    0x40   /* Receiver disabled */ +#define DP_RSR_DFR    0x80   /* Receiver processing deferred */ + +/* Transmitter control register */ + +#define DP_TCR_NOCRC  0x01   /* 1=inhibit CRC */ +#define DP_TCR_NORMAL 0x00   /* Normal transmitter operation */ +#define DP_TCR_LOCAL  0x02   /* Internal NIC loopback */ +#define DP_TCR_INLOOP 0x04   /* Full internal loopback */ +#define DP_TCR_OUTLOOP 0x08  /* External loopback */ +#define DP_TCR_ATD    0x10   /* Auto transmit disable */ +#define DP_TCR_OFFSET 0x20   /* Collision offset adjust */ + +/* Transmit status register */ + +#define DP_TSR_TxP    0x01   /* Packet transmitted */ +#define DP_TSR_COL    0x04   /* Collision (at least one) */ +#define DP_TSR_ABT    0x08   /* Aborted because of too many collisions */ +#define DP_TSR_CRS    0x10   /* Lost carrier */ +#define DP_TSR_FU     0x20   /* FIFO underrun */ +#define DP_TSR_CDH    0x40   /* Collision Detect Heartbeat */ +#define DP_TSR_OWC    0x80   /* Collision outside normal window */ + +#define IEEE_8023_MAX_FRAME         1518    /* Largest possible ethernet frame */ +#define IEEE_8023_MIN_FRAME           64    /* Smallest possible ethernet frame */ diff --git a/drivers/ns16550.c b/drivers/ns16550.c index f9fe819c1..2429464d8 100644 --- a/drivers/ns16550.c +++ b/drivers/ns16550.c @@ -17,7 +17,7 @@  void NS16550_init (NS16550_t com_port, int baud_divisor)  {  	com_port->ier = 0x00; -#ifdef CONFIG_OMAP1510 +#ifdef CONFIG_OMAP  	com_port->mdr1 = 0x7;	/* mode select reset TL16C750*/  #endif  	com_port->lcr = LCR_BKSE | LCRVAL; @@ -26,8 +26,12 @@ void NS16550_init (NS16550_t com_port, int baud_divisor)  	com_port->lcr = LCRVAL;  	com_port->mcr = MCRVAL;  	com_port->fcr = FCRVAL; -#if defined(CONFIG_OMAP1510) || defined(CONFIG_OMAP1610) || defined(CONFIG_OMAP730) -	com_port->mdr1 = 0;	/* select uart mode */ +#if defined(CONFIG_OMAP) +#if defined(CONFIG_APTIX) +	com_port->mdr1 = 3;	/* /13 mode so Aptix 6MHz can hit 115200 */ +#else +	com_port->mdr1 = 0;	/* /16 is proper to hit 115200 with 48MHz */ +#endif  #endif  } diff --git a/drivers/omap24xx_i2c.c b/drivers/omap24xx_i2c.c new file mode 100644 index 000000000..74238633f --- /dev/null +++ b/drivers/omap24xx_i2c.c @@ -0,0 +1,317 @@ +/* + * Basic I2C functions + * + * Copyright (c) 2004 Texas Instruments + * + * This package is free software;  you can redistribute it and/or + * modify it under the terms of the license found in the file + * named COPYING that should have accompanied this file. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Jian Zhang jzhang@ti.com, Texas Instruments + * + * Copyright (c) 2003 Wolfgang Denk, wd@denx.de + * Rewritten to fit into the current U-Boot framework + * + * Adapted for OMAP2420 I2C, r-woodruff2@ti.com + * + */ + +#include <common.h> +#include <asm/arch/i2c.h> +#include <asm/io.h> + +#define inw(a) __raw_readw(a) +#define outw(a,v) __raw_writew(a,v) + +#ifdef CONFIG_DRIVER_OMAP24XX_I2C + +static void wait_for_bb (void); +static u16 wait_for_pin (void); +void flush_fifo(void); + +void i2c_init (int speed, int slaveadd) +{ +	u16 scl; + +	if (inw (I2C_CON) & I2C_CON_EN) { +		outw (0, I2C_CON); +		udelay (50000); +	} + +	/* 12Mhz I2C module clock */ +	outw (0, I2C_PSC); +        speed = speed/1000;                 /* 100 or 400 */ +        scl = ((12000/(speed*2)) - 7);  /* use 7 when PSC = 0 */ +	outw (scl, I2C_SCLL); +	outw (scl, I2C_SCLH); +	/* own address */ +	outw (slaveadd, I2C_OA); +	outw (I2C_CON_EN, I2C_CON); +	outw (0, I2C_CNT); +	/* have to enable intrrupts or OMAP i2c module doesn't work */ +	outw (I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | +	      I2C_IE_NACK_IE | I2C_IE_AL_IE, I2C_IE); +	udelay (1000); +} + +static int i2c_read_byte (u8 devaddr, u8 regoffset, u8 * value) +{ +	int i2c_error = 0; +	u16 status; + +	/* wait until bus not busy */ +	wait_for_bb (); + +	/* one byte only */ +	outw (1, I2C_CNT); +	/* set slave address */ +	outw (devaddr, I2C_SA); +	/* no stop bit needed here */ +	outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX, I2C_CON); + +	status = wait_for_pin (); + +	if (status & I2C_STAT_XRDY) { +		/* Important: have to use byte access */ +		*(volatile u8 *) (I2C_DATA) = regoffset; +		udelay (20000); +		if (inw (I2C_STAT) & I2C_STAT_NACK) { +			i2c_error = 1; +		} +	} else { +		i2c_error = 1; +	} + +	if (!i2c_error) { +		/* free bus, otherwise we can't use a combined transction */ +		outw (0, I2C_CON); +		while (inw (I2C_STAT) || (inw (I2C_CON) & I2C_CON_MST)) { +			udelay (10000); +			/* Have to clear pending interrupt to clear I2C_STAT */ +			outw (0xFFFF, I2C_STAT); +		} + +		wait_for_bb (); +		/* set slave address */ +		outw (devaddr, I2C_SA); +		/* read one byte from slave */ +		outw (1, I2C_CNT); +		/* need stop bit here */ +		outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, +		      I2C_CON); + +		status = wait_for_pin (); +		if (status & I2C_STAT_RRDY) { +			*value = inw (I2C_DATA); +			udelay (20000); +		} else { +			i2c_error = 1; +		} + +		if (!i2c_error) { +			outw (I2C_CON_EN, I2C_CON); +			while (inw (I2C_STAT) +			       || (inw (I2C_CON) & I2C_CON_MST)) { +				udelay (10000); +				outw (0xFFFF, I2C_STAT); +			} +		} +	} +	flush_fifo(); +	outw (0xFFFF, I2C_STAT); +	outw (0, I2C_CNT); +	return i2c_error; +} + +static int i2c_write_byte (u8 devaddr, u8 regoffset, u8 value) +{ +	int i2c_error = 0; +	u16 status, stat; + +	/* wait until bus not busy */ +	wait_for_bb (); + +	/* two bytes */ +	outw (2, I2C_CNT); +	/* set slave address */ +	outw (devaddr, I2C_SA); +	/* stop bit needed here */ +	outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | +	      I2C_CON_STP, I2C_CON); + +	/* wait until state change */ +	status = wait_for_pin (); + +	if (status & I2C_STAT_XRDY) { +		/* send out two bytes */ +		outw ((value << 8) + regoffset, I2C_DATA); +		/* must have enough delay to allow BB bit to go low */ +		udelay (50000); +		if (inw (I2C_STAT) & I2C_STAT_NACK) { +			i2c_error = 1; +		} +	} else { +		i2c_error = 1; +	} + +	if (!i2c_error) { +		outw (I2C_CON_EN, I2C_CON); +		while ((stat = inw (I2C_STAT)) || (inw (I2C_CON) & I2C_CON_MST)) { +			udelay (1000); +			/* have to read to clear intrrupt */ +			outw (0xFFFF, I2C_STAT); +		} +	} +	flush_fifo(); +	outw (0xFFFF, I2C_STAT); +	outw (0, I2C_CNT); +	return i2c_error; +} + +void flush_fifo(void) +{	u16 stat; +	 +	/* note: if you try and read data when its not there or ready  +         * you get a bus error +         */ +	while(1){ +		stat = inw(I2C_STAT); +		if(stat == I2C_STAT_RRDY){ +			inw(I2C_DATA); +			outw(I2C_STAT_RRDY,I2C_STAT); +			udelay(1000); +		}else +			break; +	} +} + +int i2c_probe (uchar chip) +{ +	int res = 1; /* default = fail */ + +	if (chip == inw (I2C_OA)) { +		return res; +	} + +	/* wait until bus not busy */ +	wait_for_bb (); + +	/* try to read one byte */ +	outw (1, I2C_CNT); +	/* set slave address */ +	outw (chip, I2C_SA); +	/* stop bit needed here */ +	outw (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP, I2C_CON); +	/* enough delay for the NACK bit set */ +	udelay (50000); + +	if (!(inw (I2C_STAT) & I2C_STAT_NACK)) { +		res = 0;      /* success case */  +		flush_fifo(); +		outw(0xFFFF, I2C_STAT); +	} else { +		outw(0xFFFF, I2C_STAT);  /* failue, clear sources*/ +		outw (inw (I2C_CON) | I2C_CON_STP, I2C_CON); /* finish up xfer */ +		udelay(20000); +		wait_for_bb (); +	} +	flush_fifo(); +	outw (0, I2C_CNT); /* don't allow any more data in...we don't want it.*/ +	outw(0xFFFF, I2C_STAT); +	return res; +} + +int i2c_read (uchar chip, uint addr, int alen, uchar * buffer, int len) +{ +	int i; + +	if (alen > 1) { +		printf ("I2C read: addr len %d not supported\n", alen); +		return 1; +	} + +	if (addr + len > 256) { +		printf ("I2C read: address out of range\n"); +		return 1; +	} + +	for (i = 0; i < len; i++) { +		if (i2c_read_byte (chip, addr + i, &buffer[i])) { +			printf ("I2C read: I/O error\n"); +			i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); +			return 1; +		} +	} + +	return 0; +} + +int i2c_write (uchar chip, uint addr, int alen, uchar * buffer, int len) +{ +	int i; + +	if (alen > 1) { +		printf ("I2C read: addr len %d not supported\n", alen); +		return 1; +	} + +	if (addr + len > 256) { +		printf ("I2C read: address out of range\n"); +		return 1; +	} + +	for (i = 0; i < len; i++) { +		if (i2c_write_byte (chip, addr + i, buffer[i])) { +			printf ("I2C read: I/O error\n"); +			i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE); +			return 1; +		} +	} + +	return 0; +} + +static void wait_for_bb (void) +{ +	int timeout = 10; +	u16 stat; + +	outw(0xFFFF, I2C_STAT);  /* clear current interruts...*/ +	while ((stat = inw (I2C_STAT) & I2C_STAT_BB) && timeout--) { +		outw (stat, I2C_STAT); +		udelay (50000); +	} + +	if (timeout <= 0) { +		printf ("timed out in wait_for_bb: I2C_STAT=%x\n", +			inw (I2C_STAT)); +	} +	outw(0xFFFF, I2C_STAT);  /* clear delayed stuff*/ +} + +static u16 wait_for_pin (void) +{ +	u16 status; +	int timeout = 10; + +	do { +		udelay (1000); +		status = inw (I2C_STAT); +	} while (  !(status & +		   (I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY | +		    I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK | +		    I2C_STAT_AL)) && timeout--); + +	if (timeout <= 0) { +		printf ("timed out in wait_for_pin: I2C_STAT=%x\n", +			inw (I2C_STAT)); +			outw(0xFFFF, I2C_STAT);	 +} +	return status; +} + +#endif /* CONFIG_DRIVER_OMAP24XX_I2C */ diff --git a/drivers/serial.c b/drivers/serial.c index f5b51d6b7..b13b05e11 100644 --- a/drivers/serial.c +++ b/drivers/serial.c @@ -59,7 +59,14 @@ static int calc_divisor (void)  		return (26);		/* return 26 for base divisor */  	}  #endif -	return (CFG_NS16550_CLK / 16 / gd->baudrate); + +#ifdef CONFIG_APTIX +#define MODE_X_DIV 13 +#else +#define MODE_X_DIV 16 +#endif +	return (CFG_NS16550_CLK / MODE_X_DIV / gd->baudrate); +  }  int serial_init (void) diff --git a/include/asm-arm/arch-arm1136/bits.h b/include/asm-arm/arch-arm1136/bits.h new file mode 100644 index 000000000..dc3273e2d --- /dev/null +++ b/include/asm-arm/arch-arm1136/bits.h @@ -0,0 +1,49 @@ +/* bits.h + * Copyright (c) 2004 Texas Instruments + * + * This package is free software;  you can redistribute it and/or + * modify it under the terms of the license found in the file + * named COPYING that should have accompanied this file. + * + * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +#ifndef __bits_h +#define __bits_h 1 + +#define BIT0  (1<<0) +#define BIT1  (1<<1) +#define BIT2  (1<<2) +#define BIT3  (1<<3) +#define BIT4  (1<<4) +#define BIT5  (1<<5) +#define BIT6  (1<<6) +#define BIT7  (1<<7) +#define BIT8  (1<<8) +#define BIT9  (1<<9) +#define BIT10 (1<<10) +#define BIT11 (1<<11) +#define BIT12 (1<<12) +#define BIT13 (1<<13) +#define BIT14 (1<<14) +#define BIT15 (1<<15) +#define BIT16 (1<<16) +#define BIT17 (1<<17) +#define BIT18 (1<<18) +#define BIT19 (1<<19) +#define BIT20 (1<<20) +#define BIT21 (1<<21) +#define BIT22 (1<<22) +#define BIT23 (1<<23) +#define BIT24 (1<<24) +#define BIT25 (1<<25) +#define BIT26 (1<<26) +#define BIT27 (1<<27) +#define BIT28 (1<<28) +#define BIT29 (1<<29) +#define BIT30 (1<<30) +#define BIT31 (1<<31) + +#endif + diff --git a/include/asm-arm/arch-arm1136/clocks.h b/include/asm-arm/arch-arm1136/clocks.h new file mode 100644 index 000000000..d94fdcf57 --- /dev/null +++ b/include/asm-arm/arch-arm1136/clocks.h @@ -0,0 +1,79 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * 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 _OMAP24XX_CLOCKS_H_ +#define _OMAP24XX_CLOCKS_H_ + +#define COMMIT_DIVIDERS  0x1 + +#define MODE_BYPASS_FAST 0x2 +#define APLL_LOCK        0xc +#ifdef CONFIG_APTIX +#define DPLL_LOCK        0x1   /* stay in bypass mode */ +#else +#define DPLL_LOCK        0x3   /* DPLL lock */ +#endif + +/****************************************************************************; +; PRCM Scheme II +; +; Enable clocks and DPLL for: +;  DPLL=300, 	DPLLout=600   	M=1,N=50   CM_CLKSEL1_PLL[21:8]  12/2*50 +;  Core=600  	(core domain)   DPLLx2     CM_CLKSEL2_PLL[1:0] +;  MPUF=300   	(mpu domain)    2          CM_CLKSEL_MPU[4:0] +;  DSPF=200    (dsp domain)    3          CM_CLKSEL_DSP[4:0] +;  DSPI=100                    6          CM_CLKSEL_DSP[6:5] +;  DSP_S          bypass	               CM_CLKSEL_DSP[7] +;  IVAF=200    (dsp domain)    3          CM_CLKSEL_DSP[12:8] +;  IVAF=100        auto +;  IVAI            auto +;  IVA_MPU         auto +;  IVA_S          bypass                  CM_CLKSEL_DSP[13] +;  GFXF=50      (gfx domain)	12         CM_CLKSEL_FGX[2:0] +;  SSI_SSRF=200                 3         CM_CLKSEL1_CORE[24:20] +;  SSI_SSTF=100     auto +;  L3=100Mhz (sdram)            6         CM_CLKSEL1_CORE[4:0] +;  L4=100Mhz                    6 +;  C_L4_USB=50                 12         CM_CLKSEL1_CORE[6:5] +***************************************************************************/ +#define II_DPLL_OUT_X2   0x2    /* x2 core out */ +#define II_MPU_DIV       0x2    /* mpu = core/2 */ +#define II_DSP_DIV       0x343  /* dsp & iva divider */ +#define II_GFX_DIV       0x2 +#define II_BUS_DIV       0x04600C26 +#define II_BUS_DIV_ES1   0x04601026 +#define II_DPLL_300      0x01832100 + +/* set defaults for boot up */ +#ifdef PRCM_CONFIG_II +#define DPLL_OUT         II_DPLL_OUT_X2 +#define MPU_DIV          II_MPU_DIV +#define DSP_DIV          II_DSP_DIV +#define GFX_DIV          II_GFX_DIV +#define BUS_DIV          II_BUS_DIV +#define BUS_DIV_ES1      II_BUS_DIV_ES1 +#define DPLL_VAL         II_DPLL_300 +#endif + +/* lock delay time out */ +#define LDELAY           12000000 + +#endif + diff --git a/include/asm-arm/arch-arm1136/i2c.h b/include/asm-arm/arch-arm1136/i2c.h new file mode 100644 index 000000000..3e37f4dab --- /dev/null +++ b/include/asm-arm/arch-arm1136/i2c.h @@ -0,0 +1,106 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.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 + */ +#ifndef _OMAP24XX_I2C_H_ +#define _OMAP24XX_I2C_H_ + +#define I2C_BASE                0x48070000 +#define I2C_BASE2               0x48072000 /* nothing hooked up on h4 */ + +#define I2C_REV                 (I2C_BASE + 0x00) +#define I2C_IE                  (I2C_BASE + 0x04) +#define I2C_STAT                (I2C_BASE + 0x08) +#define I2C_IV                  (I2C_BASE + 0x0c) +#define I2C_BUF                 (I2C_BASE + 0x14) +#define I2C_CNT                 (I2C_BASE + 0x18) +#define I2C_DATA                (I2C_BASE + 0x1c) +#define I2C_CON                 (I2C_BASE + 0x24) +#define I2C_OA                  (I2C_BASE + 0x28) +#define I2C_SA                  (I2C_BASE + 0x2c) +#define I2C_PSC                 (I2C_BASE + 0x30) +#define I2C_SCLL                (I2C_BASE + 0x34) +#define I2C_SCLH                (I2C_BASE + 0x38) +#define I2C_SYSTEST             (I2C_BASE + 0x3c) + +/* I2C masks */ + +/* I2C Interrupt Enable Register (I2C_IE): */ +#define I2C_IE_GC_IE    (1 << 5) +#define I2C_IE_XRDY_IE  (1 << 4)        /* Transmit data ready interrupt enable */ +#define I2C_IE_RRDY_IE  (1 << 3)        /* Receive data ready interrupt enable */ +#define I2C_IE_ARDY_IE  (1 << 2)        /* Register access ready interrupt enable */ +#define I2C_IE_NACK_IE  (1 << 1)        /* No acknowledgment interrupt enable */ +#define I2C_IE_AL_IE    (1 << 0)        /* Arbitration lost interrupt enable */ + +/* I2C Status Register (I2C_STAT): */ + +#define I2C_STAT_SBD    (1 << 15)       /* Single byte data */ +#define I2C_STAT_BB     (1 << 12)       /* Bus busy */ +#define I2C_STAT_ROVR   (1 << 11)       /* Receive overrun */ +#define I2C_STAT_XUDF   (1 << 10)       /* Transmit underflow */ +#define I2C_STAT_AAS    (1 << 9)        /* Address as slave */ +#define I2C_STAT_GC     (1 << 5) +#define I2C_STAT_XRDY   (1 << 4)        /* Transmit data ready */ +#define I2C_STAT_RRDY   (1 << 3)        /* Receive data ready */ +#define I2C_STAT_ARDY   (1 << 2)        /* Register access ready */ +#define I2C_STAT_NACK   (1 << 1)        /* No acknowledgment interrupt enable */ +#define I2C_STAT_AL     (1 << 0)        /* Arbitration lost interrupt enable */ + + +/* I2C Interrupt Code Register (I2C_INTCODE): */ + +#define I2C_INTCODE_MASK        7 +#define I2C_INTCODE_NONE        0 +#define I2C_INTCODE_AL          1       /* Arbitration lost */ +#define I2C_INTCODE_NAK         2       /* No acknowledgement/general call */ +#define I2C_INTCODE_ARDY        3       /* Register access ready */ +#define I2C_INTCODE_RRDY        4       /* Rcv data ready */ +#define I2C_INTCODE_XRDY        5       /* Xmit data ready */ + +/* I2C Buffer Configuration Register (I2C_BUF): */ + +#define I2C_BUF_RDMA_EN         (1 << 15)       /* Receive DMA channel enable */ +#define I2C_BUF_XDMA_EN         (1 << 7)        /* Transmit DMA channel enable */ + +/* I2C Configuration Register (I2C_CON): */ + +#define I2C_CON_EN      (1 << 15)       /* I2C module enable */ +#define I2C_CON_BE      (1 << 14)       /* Big endian mode */ +#define I2C_CON_STB     (1 << 11)       /* Start byte mode (master mode only) */ +#define I2C_CON_MST     (1 << 10)       /* Master/slave mode */ +#define I2C_CON_TRX     (1 << 9)        /* Transmitter/receiver mode (master mode only) */ +#define I2C_CON_XA      (1 << 8)        /* Expand address */ +#define I2C_CON_STP     (1 << 1)        /* Stop condition (master mode only) */ +#define I2C_CON_STT     (1 << 0)        /* Start condition (master mode only) */ + +/* I2C System Test Register (I2C_SYSTEST): */ + +#define I2C_SYSTEST_ST_EN       (1 << 15)       /* System test enable */ +#define I2C_SYSTEST_FREE        (1 << 14)       /* Free running mode (on breakpoint) */ +#define I2C_SYSTEST_TMODE_MASK  (3 << 12)       /* Test mode select */ +#define I2C_SYSTEST_TMODE_SHIFT (12)            /* Test mode select */ +#define I2C_SYSTEST_SCL_I       (1 << 3)        /* SCL line sense input value */ +#define I2C_SYSTEST_SCL_O       (1 << 2)        /* SCL line drive output value */ +#define I2C_SYSTEST_SDA_I       (1 << 1)        /* SDA line sense input value */ +#define I2C_SYSTEST_SDA_O       (1 << 0)        /* SDA line drive output value */ + +#endif diff --git a/include/asm-arm/arch-arm1136/mem.h b/include/asm-arm/arch-arm1136/mem.h new file mode 100644 index 000000000..bd6fd5022 --- /dev/null +++ b/include/asm-arm/arch-arm1136/mem.h @@ -0,0 +1,119 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 + */ + +#ifndef _OMAP24XX_MEM_H_ +#define _OMAP24XX_MEM_H_ + +#define SDRC_CS0_OSET    0x0 +#define SDRC_CS1_OSET    0x30  /* mirror CS1 regs appear offset 0x30 from CS0 */ + +#ifndef __ASSEMBLY__ +/* struct's for holding data tables for current boards, they are getting used +   early in init when NO global access are there */ +struct sdrc_data_s { +	u32    sdrc_sharing; +	u32    sdrc_mdcfg_0; +	u32    sdrc_actim_ctrla_0; +	u32    sdrc_actim_ctrlb_0; +	u32    sdrc_rfr_ctrl; +	u32    sdrc_mr_0; +	u32    sdrc_dlla_ctrl; +	u32    sdrc_dllb_ctrl; +} /*__attribute__ ((packed))*/; +typedef struct sdrc_data_s sdrc_data_t; +#endif + +/* Slower full frequency range default timings for x32 operation*/ +#define H4_2420_SDRC_SHARING               0x00000100 +#define H4_2420_SDRC_MDCFG_0               0x01702011 +#define H4_2420_SDRC_ACTIM_CTRLA_0         0x9bead909 +#define H4_2420_SDRC_ACTIM_CTRLB_0         0x00000014 +#define H4_2420_SDRC_RFR_CTRL_ES1          0x00002401 +#define H4_2420_SDRC_RFR_CTRL              0x0002da01 +#define H4_2420_SDRC_MR_0                  0x00000032 +#define H4_2420_SDRC_DLLA_CTRL             0x00007307 +#define H4_2420_SDRC_DLLB_CTRL             0x00007307 + +#define H4_2422_SDRC_SHARING               0x00004b00 +#define H4_2422_SDRC_MDCFG_0               0x00801011 +#define H4_2422_SDRC_ACTIM_CTRLA_0         0x9BEAD909 +#define H4_2422_SDRC_ACTIM_CTRLB_0         0x00000020 +#define H4_2422_SDRC_RFR_CTRL_ES1          0x00002401 +#define H4_2422_SDRC_RFR_CTRL              0x0002da03 +#define H4_2422_SDRC_MR_0                  0x00000032 +#define H4_2422_SDRC_DLLA_CTRL             0x00007307 +#define H4_2422_SDRC_DLLB_CTRL             0x00007307 + +#define H4_2420_COMBO_MDCFG_0              0x00801011 + +/* optimized timings */ +#define H4_2420_SDRC_ACTIM_CTRLA_0_100MHz  0x5A59B485 +#define H4_2420_SDRC_ACTIM_CTRLB_0_100MHz  0x0000000e + + +#ifdef PRCM_CONFIG_II        /* L3 at 100MHz */ +#define H4_24XX_GPMC_CONFIG1_0   0x3 +#define H4_24XX_GPMC_CONFIG2_0   0x001f1f01 +#define H4_24XX_GPMC_CONFIG3_0   0x00030301 +#define H4_24XX_GPMC_CONFIG4_0   0x0C030C03 +#define H4_24XX_GPMC_CONFIG5_0   0x01131F1F +#define H4_24XX_GPMC_CONFIG7_0   (0x00000C40|(H4_CS0_BASE >> 24)) + +#define H4_24XX_GPMC_CONFIG1_1   0x00011000 +#define H4_24XX_GPMC_CONFIG2_1   0x001F1F00 +#define H4_24XX_GPMC_CONFIG3_1   0x00080802 +#define H4_24XX_GPMC_CONFIG4_1   0x1C091C09 +#define H4_24XX_GPMC_CONFIG5_1   0x031A1F1F +#define H4_24XX_GPMC_CONFIG6_1   0x000003C2 +#define H4_24XX_GPMC_CONFIG7_1   (0x00000F40|(H4_CS1_BASE >> 24)) +#endif + +#ifdef PRCM_CONFIG_III  /* L3 at 133MHz */ +#define H4_24XX_GPMC_CONFIG1_0   0x3 +#define H4_24XX_GPMC_CONFIG2_0   0x001f1f01 +#define H4_24XX_GPMC_CONFIG3_0   0x001F1F00 +#define H4_24XX_GPMC_CONFIG4_0   0x16061606 +#define H4_24XX_GPMC_CONFIG5_0   0x01131F1F +#define H4_24XX_GPMC_CONFIG7_0   (0x00000C40|(H4_CS0_BASE >> 24)) + +#define H4_24XX_GPMC_CONFIG1_1   0x00011000 +#define H4_24XX_GPMC_CONFIG2_1   0x001f1f01 +#define H4_24XX_GPMC_CONFIG3_1   0x001F1F00 +#define H4_24XX_GPMC_CONFIG4_1   0x1A061A06 +#define H4_24XX_GPMC_CONFIG5_1   0x041F1F1F +#define H4_24XX_GPMC_CONFIG6_1   0x000004C4 +#define H4_24XX_GPMC_CONFIG7_1   (0x00000F40|(H4_CS1_BASE >> 24)) +#endif + +#ifdef CONFIG_APTIX /* SDRC-SDR for Aptix x16 */ +#define VAL_H4_SDRC_SHARING_16   0x00002400  /* No-Tristate, 16bit on D31-D16, CS1=dont care */ +#define VAL_H4_SDRC_SHARING      0x00000100 +#define VAL_H4_SDRC_MCFG_0_16    0x00901000  /* SDR-SDRAM,External,x16 bit */ +#define VAL_H4_SDRC_MCFG_0       0x01702011 +#define VAL_H4_SDRC_MR_0         0x00000029  /* Burst=2, Serial Mode, CAS 3*/ +#define VAL_H4_SDRC_RFR_CTRL_0   0x00001703  /* refresh time */ +#define VAL_H4_SDRC_DCDL2_CTRL   0x5A59B485 +#endif + +#endif diff --git a/include/asm-arm/arch-arm1136/mux.h b/include/asm-arm/arch-arm1136/mux.h new file mode 100644 index 000000000..67c841908 --- /dev/null +++ b/include/asm-arm/arch-arm1136/mux.h @@ -0,0 +1,158 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * 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 _OMAP2420_MUX_H_ +#define _OMAP2420_MUX_H_ + +#ifndef __ASSEMBLY__ +typedef  unsigned char uint8; +typedef  unsigned int uint32; + +void muxSetupSDRC(void); +void muxSetupGPMC(void); +void muxSetupUsb0(void); +void muxSetupUart3(void); +void muxSetupI2C1(void); +void muxSetupUART1(void); +void muxSetupLCD(void); +void muxSetupCamera(void); +void muxSetupMMCSD(void) ; +void muxSetupTouchScreen(void) ; +void muxSetupHDQ(void); +#endif + +#define USB_OTG_CTRL			        ((volatile uint32 *)0x4805E30C) + +/* Pin Muxing registers used for HDQ (Smart battery) */ +#define CONTROL_PADCONF_HDQ_SIO         ((volatile unsigned char *)0x48000115) + +/* Pin Muxing registers used for GPMC */ +#define CONTROL_PADCONF_GPMC_D2_BYTE0	((volatile unsigned char *)0x48000088) +#define CONTROL_PADCONF_GPMC_D2_BYTE1	((volatile unsigned char *)0x48000089) +#define CONTROL_PADCONF_GPMC_D2_BYTE2	((volatile unsigned char *)0x4800008A) +#define CONTROL_PADCONF_GPMC_D2_BYTE3	((volatile unsigned char *)0x4800008B) + +#define CONTROL_PADCONF_GPMC_NCS0_BYTE0	((volatile unsigned char *)0x4800008C) +#define CONTROL_PADCONF_GPMC_NCS0_BYTE1	((volatile unsigned char *)0x4800008D) +#define CONTROL_PADCONF_GPMC_NCS0_BYTE2	((volatile unsigned char *)0x4800008E) +#define CONTROL_PADCONF_GPMC_NCS0_BYTE3	((volatile unsigned char *)0x4800008F) + +/* Pin Muxing registers used for SDRC */ +#define CONTROL_PADCONF_SDRC_NCS0_BYTE0 ((volatile unsigned char *)0x480000A0) +#define CONTROL_PADCONF_SDRC_NCS0_BYTE1 ((volatile unsigned char *)0x480000A1) +#define CONTROL_PADCONF_SDRC_NCS0_BYTE2 ((volatile unsigned char *)0x480000A2) +#define CONTROL_PADCONF_SDRC_NCS0_BYTE3 ((volatile unsigned char *)0x480000A3) + +#define CONTROL_PADCONF_SDRC_A14_BYTE0	((volatile unsigned char *)0x48000030) +#define CONTROL_PADCONF_SDRC_A14_BYTE1	((volatile unsigned char *)0x48000031) +#define CONTROL_PADCONF_SDRC_A14_BYTE2	((volatile unsigned char *)0x48000032) +#define CONTROL_PADCONF_SDRC_A14_BYTE3	((volatile unsigned char *)0x48000033) + +/* Pin Muxing registers used for Touch Screen (SPI) */ +#define CONTROL_PADCONF_SPI1_CLK        ((volatile unsigned char *)0x480000FF) +#define CONTROL_PADCONF_SPI1_SIMO       ((volatile unsigned char *)0x48000100) +#define CONTROL_PADCONF_SPI1_SOMI       ((volatile unsigned char *)0x48000101) +#define CONTROL_PADCONF_SPI1_NCS0       ((volatile unsigned char *)0x48000102) + +#define CONTROL_PADCONF_MCBSP1_FSR      ((volatile unsigned char *)0x4800010B) + +/* Pin Muxing registers used for MMCSD */ +#define CONTROL_PADCONF_MMC_CLKI        ((volatile unsigned char *)0x480000FE) +#define CONTROL_PADCONF_MMC_CLKO        ((volatile unsigned char *)0x480000F3) +#define CONTROL_PADCONF_MMC_CMD         ((volatile unsigned char *)0x480000F4) +#define CONTROL_PADCONF_MMC_DAT0        ((volatile unsigned char *)0x480000F5) +#define CONTROL_PADCONF_MMC_DAT1        ((volatile unsigned char *)0x480000F6) +#define CONTROL_PADCONF_MMC_DAT2        ((volatile unsigned char *)0x480000F7) +#define CONTROL_PADCONF_MMC_DAT3        ((volatile unsigned char *)0x480000F8) +#define CONTROL_PADCONF_MMC_DAT_DIR0    ((volatile unsigned char *)0x480000F9) +#define CONTROL_PADCONF_MMC_DAT_DIR1    ((volatile unsigned char *)0x480000FA) +#define CONTROL_PADCONF_MMC_DAT_DIR2    ((volatile unsigned char *)0x480000FB) +#define CONTROL_PADCONF_MMC_DAT_DIR3    ((volatile unsigned char *)0x480000FC) +#define CONTROL_PADCONF_MMC_CMD_DIR     ((volatile unsigned char *)0x480000FD) + +#define CONTROL_PADCONF_SDRC_A14        ((volatile unsigned char *)0x48000030) +#define CONTROL_PADCONF_SDRC_A13        ((volatile unsigned char *)0x48000031) + +/* Pin Muxing registers used for CAMERA */ +#define CONTROL_PADCONF_SYS_NRESWARM    ((volatile unsigned char *)0x4800012B) + +#define CONTROL_PADCONF_CAM_XCLK        ((volatile unsigned char *)0x480000DC) +#define CONTROL_PADCONF_CAM_LCLK        ((volatile unsigned char *)0x480000DB) +#define CONTROL_PADCONF_CAM_VS          ((volatile unsigned char *)0x480000DA) +#define CONTROL_PADCONF_CAM_HS          ((volatile unsigned char *)0x480000D9) +#define CONTROL_PADCONF_CAM_D0          ((volatile unsigned char *)0x480000D8) +#define CONTROL_PADCONF_CAM_D1          ((volatile unsigned char *)0x480000D7) +#define CONTROL_PADCONF_CAM_D2          ((volatile unsigned char *)0x480000D6) +#define CONTROL_PADCONF_CAM_D3          ((volatile unsigned char *)0x480000D5) +#define CONTROL_PADCONF_CAM_D4          ((volatile unsigned char *)0x480000D4) +#define CONTROL_PADCONF_CAM_D5          ((volatile unsigned char *)0x480000D3) +#define CONTROL_PADCONF_CAM_D6          ((volatile unsigned char *)0x480000D2) +#define CONTROL_PADCONF_CAM_D7          ((volatile unsigned char *)0x480000D1) +#define CONTROL_PADCONF_CAM_D8          ((volatile unsigned char *)0x480000D0) +#define CONTROL_PADCONF_CAM_D9          ((volatile unsigned char *)0x480000CF) + +/* Pin Muxing registers used for LCD */ +#define CONTROL_PADCONF_DSS_D0          ((volatile unsigned char *)0x480000B3) +#define CONTROL_PADCONF_DSS_D1          ((volatile unsigned char *)0x480000B4) +#define CONTROL_PADCONF_DSS_D2          ((volatile unsigned char *)0x480000B5) +#define CONTROL_PADCONF_DSS_D3          ((volatile unsigned char *)0x480000B6) +#define CONTROL_PADCONF_DSS_D4          ((volatile unsigned char *)0x480000B7) +#define CONTROL_PADCONF_DSS_D5          ((volatile unsigned char *)0x480000B8) +#define CONTROL_PADCONF_DSS_D6          ((volatile unsigned char *)0x480000B9) +#define CONTROL_PADCONF_DSS_D7          ((volatile unsigned char *)0x480000BA) +#define CONTROL_PADCONF_DSS_D8          ((volatile unsigned char *)0x480000BB) +#define CONTROL_PADCONF_DSS_D9          ((volatile unsigned char *)0x480000BC) +#define CONTROL_PADCONF_DSS_D10         ((volatile unsigned char *)0x480000BD) +#define CONTROL_PADCONF_DSS_D11         ((volatile unsigned char *)0x480000BE) +#define CONTROL_PADCONF_DSS_D12         ((volatile unsigned char *)0x480000BF) +#define CONTROL_PADCONF_DSS_D13         ((volatile unsigned char *)0x480000C0) +#define CONTROL_PADCONF_DSS_D14         ((volatile unsigned char *)0x480000C1) +#define CONTROL_PADCONF_DSS_D15         ((volatile unsigned char *)0x480000C2) +#define CONTROL_PADCONF_DSS_D16         ((volatile unsigned char *)0x480000C3) +#define CONTROL_PADCONF_DSS_D17         ((volatile unsigned char *)0x480000C4) +#define CONTROL_PADCONF_DSS_PCLK        ((volatile unsigned char *)0x480000CB) +#define CONTROL_PADCONF_DSS_VSYNC       ((volatile unsigned char *)0x480000CC) +#define CONTROL_PADCONF_DSS_HSYNC       ((volatile unsigned char *)0x480000CD) +#define CONTROL_PADCONF_DSS_ACBIAS      ((volatile unsigned char *)0x480000CE) + +/* Pin Muxing registers used for UART1 */ +#define CONTROL_PADCONF_UART1_CTS       ((volatile unsigned char *)0x480000C5) +#define CONTROL_PADCONF_UART1_RTS       ((volatile unsigned char *)0x480000C6) +#define CONTROL_PADCONF_UART1_TX        ((volatile unsigned char *)0x480000C7) +#define CONTROL_PADCONF_UART1_RX        ((volatile unsigned char *)0x480000C8) + +/* Pin Muxing registers used for I2C1 */ +#define CONTROL_PADCONF_I2C1_SCL        ((volatile unsigned char *)0x48000111) +#define CONTROL_PADCONF_I2C1_SDA        ((volatile unsigned char *)0x48000112) + +/* Pin Muxing registres used for USB0. */ +#define CONTROL_PADCONF_USB0_PUEN		((volatile uint8 *)0x4800011D) +#define CONTROL_PADCONF_USB0_VP			((volatile uint8 *)0x4800011E) +#define CONTROL_PADCONF_USB0_VM			((volatile uint8 *)0x4800011F) +#define CONTROL_PADCONF_USB0_RCV		((volatile uint8 *)0x48000120) +#define CONTROL_PADCONF_USB0_TXEN		((volatile uint8 *)0x48000121) +#define CONTROL_PADCONF_USB0_SE0		((volatile uint8 *)0x48000122) +#define CONTROL_PADCONF_USB0_DAT		((volatile uint8 *)0x48000123) + +/* Pin Muxing registers used for UART3/IRDA */ +#define CONTROL_PADCONF_UART3_TX_IRTX	((volatile uint8 *)0x48000118) +#define CONTROL_PADCONF_UART3_RX_IRRX	((volatile uint8 *)0x48000119) + +#endif diff --git a/include/asm-arm/arch-arm1136/omap2420.h b/include/asm-arm/arch-arm1136/omap2420.h new file mode 100644 index 000000000..ae2549b4b --- /dev/null +++ b/include/asm-arm/arch-arm1136/omap2420.h @@ -0,0 +1,200 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 + */ + +#ifndef _OMAP2420_SYS_H_ +#define _OMAP2420_SYS_H_ + +#include <asm/arch/sizes.h> + +/* + * 2420 specific Section + */ + +/* CONTROL */ +#define OMAP2420_CTRL_BASE    (0x48000000) +#define CONTROL_STATUS        (OMAP2420_CTRL_BASE + 0x2F8) + +/* TAP information */ +#define OMAP2420_TAP_BASE     (0x48014000) +#define TAP_IDCODE_REG        (OMAP2420_TAP_BASE+0x204) + +/* GPMC */ +#define OMAP2420_GPMC_BASE    (0x6800A000) +#define GPMC_SYSCONFIG        (OMAP2420_GPMC_BASE+0x10) +#define GPMC_IRQENABLE        (OMAP2420_GPMC_BASE+0x1C) +#define GPMC_TIMEOUT_CONTROL  (OMAP2420_GPMC_BASE+0x40) +#define GPMC_CONFIG           (OMAP2420_GPMC_BASE+0x50) +#define GPMC_CONFIG1_0        (OMAP2420_GPMC_BASE+0x60) +#define GPMC_CONFIG2_0        (OMAP2420_GPMC_BASE+0x64) +#define GPMC_CONFIG3_0        (OMAP2420_GPMC_BASE+0x68) +#define GPMC_CONFIG4_0        (OMAP2420_GPMC_BASE+0x6C) +#define GPMC_CONFIG5_0        (OMAP2420_GPMC_BASE+0x70) +#define GPMC_CONFIG7_0	      (OMAP2420_GPMC_BASE+0x78) +#define GPMC_CONFIG1_1        (OMAP2420_GPMC_BASE+0x90) +#define GPMC_CONFIG2_1        (OMAP2420_GPMC_BASE+0x94) +#define GPMC_CONFIG3_1        (OMAP2420_GPMC_BASE+0x98) +#define GPMC_CONFIG4_1        (OMAP2420_GPMC_BASE+0x9C) +#define GPMC_CONFIG5_1        (OMAP2420_GPMC_BASE+0xA0) +#define GPMC_CONFIG6_1        (OMAP2420_GPMC_BASE+0xA4) +#define GPMC_CONFIG7_1	      (OMAP2420_GPMC_BASE+0xA8) + +/* SMS */ +#define OMAP2420_SMS_BASE 0x68008000 +#define SMS_SYSCONFIG     (OMAP2420_SMS_BASE+0x10) + +/* SDRC */ +#define OMAP2420_SDRC_BASE 0x68009000 +#define SDRC_SYSCONFIG     (OMAP2420_SDRC_BASE+0x10) +#define SDRC_STATUS        (OMAP2420_SDRC_BASE+0x14) +#define SDRC_SHARING       (OMAP2420_SDRC_BASE+0x44) +#define SDRC_DLLA_CTRL     (OMAP2420_SDRC_BASE+0x60) +#define SDRC_DLLB_CTRL     (OMAP2420_SDRC_BASE+0x68) +#define SDRC_POWER         (OMAP2420_SDRC_BASE+0x70) +#define SDRC_MCFG_0        (OMAP2420_SDRC_BASE+0x80) +#define SDRC_MR_0          (OMAP2420_SDRC_BASE+0x84) +#define SDRC_ACTIM_CTRLA_0 (OMAP2420_SDRC_BASE+0x9C) +#define SDRC_ACTIM_CTRLB_0 (OMAP2420_SDRC_BASE+0xA0) +#define SDRC_ACTIM_CTRLA_1 (OMAP2420_SDRC_BASE+0xC4) +#define SDRC_ACTIM_CTRLB_1 (OMAP2420_SDRC_BASE+0xC8) +#define SDRC_RFR_CTRL      (OMAP2420_SDRC_BASE+0xA4) +#define SDRC_MANUAL_0      (OMAP2420_SDRC_BASE+0xA8) +#define OMAP2420_SDRC_CS0  0x80000000 +#define OMAP2420_SDRC_CS1  0xA0000000 +#define CMD_NOP            0x0 +#define CMD_PRECHARGE      0x1 +#define CMD_AUTOREFRESH    0x2 +#define CMD_ENTR_PWRDOWN   0x3 +#define CMD_EXIT_PWRDOWN   0x4 +#define CMD_ENTR_SRFRSH    0x5 +#define CMD_CKE_HIGH       0x6 +#define CMD_CKE_LOW        0x7 +#define SOFTRESET          BIT1 +#define SMART_IDLE         (0x2 << 3) +#define REF_ON_IDLE        (0x1 << 6) + + +/* UART */ +#define OMAP2420_UART1	      0x4806A000 +#define OMAP2420_UART2	      0x4806C000 +#define OMAP2420_UART3        0x4806E000 + +/* General Purpose Timers */ +#define OMAP2420_GPT1         0x48028000 +#define OMAP2420_GPT2         0x4802A000 +#define OMAP2420_GPT3         0x48078000 +#define OMAP2420_GPT4         0x4807A000 +#define OMAP2420_GPT5         0x4807C000 +#define OMAP2420_GPT6         0x4807E000 +#define OMAP2420_GPT7         0x48080000 +#define OMAP2420_GPT8         0x48082000 +#define OMAP2420_GPT9         0x48084000 +#define OMAP2420_GPT10        0x48086000 +#define OMAP2420_GPT11        0x48088000 +#define OMAP2420_GPT12        0x4808A000 + +/* timer regs offsets (32 bit regs) */ +#define TIDR       0x0      /* r */ +#define TIOCP_CFG  0x10     /* rw */ +#define TISTAT     0x14     /* r */ +#define TISR       0x18     /* rw */ +#define TIER       0x1C     /* rw */ +#define TWER       0x20     /* rw */ +#define TCLR       0x24     /* rw */ +#define TCRR       0x28     /* rw */ +#define TLDR       0x2C     /* rw */ +#define TTGR       0x30     /* rw */ +#define TWPS       0x34     /* r */ +#define TMAR       0x38     /* rw */ +#define TCAR1      0x3c     /* r */ +#define TSICR      0x40     /* rw */ +#define TCAR2      0x44     /* r */ + +/* WatchDog Timers (1 secure, 3 GP) */ +#define WD1_BASE              0x48020000 +#define WD2_BASE              0x48022000 +#define WD3_BASE              0x48024000 +#define WD4_BASE              0x48026000 +#define WWPS       0x34     /* r */ +#define WSPR       0x48     /* rw */ +#define WD_UNLOCK1 0xAAAA +#define WD_UNLOCK2 0x5555 + +/* PRCM */ +#define OMAP2420_CM_BASE 0x48008000 +#define PRCM_CLKCFG_CTRL (OMAP2420_CM_BASE+0x080) +#define CM_CLKSEL_MPU    (OMAP2420_CM_BASE+0x140) +#define CM_FCLKEN1_CORE  (OMAP2420_CM_BASE+0x200) +#define CM_FCLKEN2_CORE  (OMAP2420_CM_BASE+0x204) +#define CM_ICLKEN1_CORE  (OMAP2420_CM_BASE+0x210) +#define CM_ICLKEN2_CORE  (OMAP2420_CM_BASE+0x214) +#define CM_CLKSEL1_CORE  (OMAP2420_CM_BASE+0x240) +#define CM_CLKSEL_WKUP   (OMAP2420_CM_BASE+0x440) +#define CM_CLKSEL2_CORE  (OMAP2420_CM_BASE+0x244) +#define CM_CLKSEL_GFX    (OMAP2420_CM_BASE+0x340) +#define PM_RSTCTRL_WKUP  (OMAP2420_CM_BASE+0x450) +#define CM_CLKEN_PLL     (OMAP2420_CM_BASE+0x500) +#define CM_IDLEST_CKGEN  (OMAP2420_CM_BASE+0x520) +#define CM_CLKSEL1_PLL   (OMAP2420_CM_BASE+0x540) +#define CM_CLKSEL2_PLL   (OMAP2420_CM_BASE+0x544) +#define CM_CLKSEL_DSP    (OMAP2420_CM_BASE+0x840) + +/* + * H4 specific Section + */ + +/* + *  The 2420's chip selects are programmable.  The mask ROM + *  does configure CS0 to 0x08000000 before dispatch.  So, if + *  you want your code to live below that address, you have to + *  be prepared to jump though hoops, to reset the base address. + */ +#if defined(CONFIG_OMAP2420H4) +/* GPMC */ +#ifdef CONFIG_VIRTIO_A        /* Pre version B */ +# define H4_CS0_BASE           0x08000000  /* flash (64 Meg aligned) */ +# define H4_CS1_BASE           0x04000000  /* debug board */ +# define H4_CS2_BASE           0x0A000000  /* wifi board */ +#else +# define H4_CS0_BASE           0x04000000  /* flash (64 Meg aligned) */ +# define H4_CS1_BASE           0x08000000  /* debug board */ +# define H4_CS2_BASE           0x0A000000  /* wifi board */ +#endif + +/* base address for indirect vectors (internal boot mode) */ +#define SRAM_OFFSET0          0x40000000 +#define SRAM_OFFSET1          0x00200000 +#define SRAM_OFFSET2          0x0000F800 +#define SRAM_VECT_CODE       (SRAM_OFFSET0|SRAM_OFFSET1|SRAM_OFFSET2) + +#define LOW_LEVEL_SRAM_STACK  0x4020FFFC + +#define PERIFERAL_PORT_BASE   0x480FE003 + +/* FPGA on Debug board.*/ +#define ETH_CONTROL_REG       (H4_CS1_BASE+0x30b) +#define LAN_RESET_REGISTER    (H4_CS1_BASE+0x1c) +#endif  /* endif CONFIG_2420H4 */ + +#endif + diff --git a/include/asm-arm/arch-arm1136/rev.h b/include/asm-arm/arch-arm1136/rev.h new file mode 100644 index 000000000..0dba25f7d --- /dev/null +++ b/include/asm-arm/arch-arm1136/rev.h @@ -0,0 +1,59 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 + */ + +#ifndef _OMAP24XX_REV_H_ +#define _OMAP24XX_REV_H_ + +typedef	struct	h4_system_data { +    /* base board info */ +    u32	   base_b_rev;         /* rev from base board i2c */ +    /* cpu board info */ +    u32	   cpu_b_rev;          /* rev from cpu board i2c */ +    u32    cpu_b_mux;          /* mux type on daughter board */ +    u32    cpu_b_ddr_type;     /* mem type */ +    u32    cpu_b_ddr_speed;    /* ddr speed rating */ +    u32    cpu_b_switches;     /* boot ctrl switch settings */ +    /* cpu info */ +    u32	   cpu_type;           /* type of cpu; 2420, 2422, 2430,...*/ +    u32    cpu_rev;            /* rev of given cpu; ES1, ES2,...*/ +} h4_sys_data; + +#define CDB_DDR_COMBO                   /* combo part on cpu daughter card */ +#define CDB_DDR_IPDB                    /* 2x16 parts on daughter card */ + +#define DDR_100         100             /* type found on most mem d-boards */ +#define DDR_111         111             /* some combo parts */ +#define DDR_133         133             /* most combo, some mem d-boards */ +#define DDR_165         165             /* future parts */ + +#define CPU_2420        0x2420 +#define CPU_2422        0x2422 + +#define CPU_2422_ES1    1 +#define CPU_2422_ES2    2 +#define CPU_2420_ES1    1 +#define CPU_2420_ES2    2 + +#endif + diff --git a/include/asm-arm/arch-arm1136/sizes.h b/include/asm-arm/arch-arm1136/sizes.h new file mode 100644 index 000000000..3dddd8e2e --- /dev/null +++ b/include/asm-arm/arch-arm1136/sizes.h @@ -0,0 +1,50 @@ +/* + * 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 + */ +/*  Size defintions + *  Copyright (C) ARM Limited 1998. All rights reserved. + */ + +#ifndef __sizes_h +#define __sizes_h			1 + +/* handy sizes */ +#define SZ_1K				0x00000400 +#define SZ_4K				0x00001000 +#define SZ_8K				0x00002000 +#define SZ_16K				0x00004000 +#define SZ_32K				0x00008000 +#define SZ_64K				0x00010000 +#define SZ_128K				0x00020000 +#define SZ_256K				0x00040000 +#define SZ_512K				0x00080000 + +#define SZ_1M				0x00100000 +#define SZ_2M				0x00200000 +#define SZ_4M				0x00400000 +#define SZ_8M				0x00800000 +#define SZ_16M				0x01000000 +#define SZ_31M				0x01F00000 +#define SZ_32M				0x02000000 +#define SZ_64M				0x04000000 +#define SZ_128M				0x08000000 +#define SZ_256M				0x10000000 +#define SZ_512M				0x20000000 + +#define SZ_1G				0x40000000 +#define SZ_2G				0x80000000 + +#endif	/* __sizes_h */ + diff --git a/include/asm-arm/arch-arm1136/sys_info.h b/include/asm-arm/arch-arm1136/sys_info.h new file mode 100644 index 000000000..3f77d3bfa --- /dev/null +++ b/include/asm-arm/arch-arm1136/sys_info.h @@ -0,0 +1,78 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@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 + */ + +#ifndef _OMAP24XX_SYS_INFO_H_ +#define _OMAP24XX_SYS_INFO_H_ + +typedef struct  h4_system_data { +	/* base board info */ +	u32 base_b_rev;		/* rev from base board i2c */ +	/* cpu board info */ +	u32 cpu_b_rev;		/* rev from cpu board i2c */ +	u32 cpu_b_mux;		/* mux type on daughter board */ +	u32 cpu_b_ddr_type;	/* mem type */ +	u32 cpu_b_ddr_speed;	/* ddr speed rating */ +	u32 cpu_b_switches;	/* boot ctrl switch settings */ +	/* cpu info */ +	u32 cpu_type;		/* type of cpu; 2420, 2422, 2430,...*/ +	u32 cpu_rev;		/* rev of given cpu; ES1, ES2,...*/ +} h4_sys_data; + +#define DDR_STACKED       3      /* stacked part on 2422 */ +#define DDR_COMBO         2      /* combo part on cpu daughter card (menalaeus) */ +#define DDR_DISCRETE      1      /* 2x16 parts on daughter card */ + +#define DDR_100           100    /* type found on most mem d-boards */ +#define DDR_111           111    /* some combo parts */ +#define DDR_133           133    /* most combo, some mem d-boards */ +#define DDR_165           165    /* future parts */ + +#define CPU_2420          0x2420 +#define CPU_2422          0x2422 + +#define CPU_2422_ES1      1 +#define CPU_2422_ES2      2 +#define CPU_2420_ES1      1 +#define CPU_2420_ES2      2 + +#define CPU_2420_CHIPID   0x0B5D9000 +#define CPU_24XX_ID_MASK  0x0FFFF000 +#define CPU_242X_REV_MASK 0xF0000000 + +#define BOARD_H4_MENELAUS 1 +#define BOARD_H4_SDP      2 + +#define GPMC_MUXED        1 +#define GPMC_NONMUXED     0 + +#define TYPE_NAND         0x800   /* bit pos for nand in gpmc reg */ +#define TYPE_NOR          0x000 + +#define WIDTH_8BIT        0x0000 +#define WIDTH_16BIT       0x1000  /* bit pos for 16 bit in gpmc */ + +#define I2C_MENELAUS 0x72	/* i2c id for companion chip */ + +#endif + diff --git a/include/asm-arm/arch-arm1136/sys_proto.h b/include/asm-arm/arch-arm1136/sys_proto.h new file mode 100644 index 000000000..67206f621 --- /dev/null +++ b/include/asm-arm/arch-arm1136/sys_proto.h @@ -0,0 +1,48 @@ +/* + * (C) Copyright 2004 + * Texas Instruments, <www.ti.com> + * Richard Woodruff <r-woodruff2@ti.com> + * + * 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 _OMAP24XX_SYS_PROTO_H_ +#define _OMAP24XX_SYS_PROTO_H_ + +void prcm_init(void); +void memif_init(void); +void sdrc_init(void); +void do_sdrc_init(u32,u32); +void gpmc_init(void); + +void ether_init(void); +void watchdog_init(void); +void set_muxconf_regs(void); +void peripheral_enable(void); + +u32 get_cpu_type(void); +u32 get_cpu_rev(void); +u32 get_mem_type(void); +u32 get_sysboot_value(void); +u32 get_gpmc0_base(void); +u32 is_gpmc_muxed(void); +u32 get_gpmc0_type(void); +u32 get_gpmc0_width(void); +u32 wait_on_value(u32 read_bit_mask, u32 match_value, u32 read_addr, u32 bound); +u32 get_board_type(void); +void display_board_info(u32); +void update_mux(u32,u32); +#endif + diff --git a/include/asm-arm/io.h b/include/asm-arm/io.h index 0f38e10d2..c2b69fb2d 100644 --- a/include/asm-arm/io.h +++ b/include/asm-arm/io.h @@ -35,10 +35,12 @@   * to the architecture specific code.   */  #define __arch_getb(a)			(*(volatile unsigned char *)(a)) -#define __arch_getl(a)			(*(volatile unsigned int  *)(a)) +#define __arch_getw(a)			(*(volatile unsigned short *)(a)) +#define __arch_getl(a)			(*(volatile unsigned int *)(a))  #define __arch_putb(v,a)		(*(volatile unsigned char *)(a) = (v)) -#define __arch_putl(v,a)		(*(volatile unsigned int  *)(a) = (v)) +#define __arch_putw(v,a)		(*(volatile unsigned short *)(a) = (v)) +#define __arch_putl(v,a)		(*(volatile unsigned int *)(a) = (v))  extern void __raw_writesb(unsigned int addr, const void *data, int bytelen);  extern void __raw_writesw(unsigned int addr, const void *data, int wordlen); diff --git a/include/configs/omap2420h4.h b/include/configs/omap2420h4.h new file mode 100644 index 000000000..b933c2498 --- /dev/null +++ b/include/configs/omap2420h4.h @@ -0,0 +1,213 @@ +/* + * (C) Copyright 2004 + * Texas Instruments. + * Richard Woodruff <r-woodruff2@ti.com> + * Kshitij Gupta <kshitij@ti.com> + * + * Configuration settings for the 242x TI H4 board. + * + * 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 + +/* + * High Level Configuration Options + */ +#define CONFIG_ARM1136           1    /* This is an arm1136 CPU core */ +#define CONFIG_OMAP              1    /* in a TI OMAP core */ +#define CONFIG_OMAP2420	         1    /* which is in a 2420 */ +#define CONFIG_OMAP2420H4        1    /* and on a H4 board */ +//#define CONFIG_APTIX           1    /* define if on APTIX test chip */ +//#define CONFIG_VIRTIO          1    /* Using Virtio simulator */ + +#define PRCM_CONFIG_II           1     +#define CONFIG_PARTIAL_SRAM      1 + +#include <asm/arch/omap2420.h>        /* get chip and board defs */ + +#ifdef CONFIG_APTIX +#define V_SCLK                   1500000 +#else +#define V_SCLK                   12000000 +#endif + +/* input clock of PLL */ +/* the OMAP2420 H4 has 12MHz, 13MHz, or 19.2Mhz crystal input */ +#define CONFIG_SYS_CLK_FREQ      V_SCLK + +#undef CONFIG_USE_IRQ                 /* no support for IRQs */ +#define CONFIG_MISC_INIT_R + +#define CONFIG_CMDLINE_TAG       1    /* enable passing of ATAGs */ +#define CONFIG_SETUP_MEMORY_TAGS 1 +#define CONFIG_INITRD_TAG        1 + +/* + * Size of malloc() pool + */ +#define CFG_ENV_SIZE             SZ_128K     /* Total Size of Environment Sector */ +#define CFG_MALLOC_LEN           (CFG_ENV_SIZE + SZ_128K) +#define CFG_GBL_DATA_SIZE        128  /* size in bytes reserved for initial data */ + +/* + * Hardware drivers + */ +  +/* + * SMC91c96 Etherent + */ +#define CONFIG_DRIVER_LAN91C96 +#define CONFIG_LAN91C96_BASE     (H4_CS1_BASE+0x300) +#define CONFIG_LAN91C96_EXT_PHY + +/* + * NS16550 Configuration + */ +#ifdef CONFIG_APTIX +#define V_NS16550_CLK            (6000000)   /* 6MHz in current MaxSet */ +#else +#define V_NS16550_CLK            (48000000)  /* 48MHz (APLL96/2) */ +#endif + +#define CFG_NS16550 +#define CFG_NS16550_SERIAL +#define CFG_NS16550_REG_SIZE     (-4) +#define CFG_NS16550_CLK          V_NS16550_CLK   /* 3MHz (1.5MHz*2) */ +#define CFG_NS16550_COM1         OMAP2420_UART1 + +/* + * select serial console configuration + */ +#define CONFIG_SERIAL1           1    /* UART1 on H4 */ + +  /* +   * I2C configuration +   */ +#define CONFIG_HARD_I2C +#define CFG_I2C_SPEED          100000 +#define CFG_I2C_SLAVE          1 +#define CONFIG_DRIVER_OMAP24XX_I2C + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE +#define CONFIG_CONS_INDEX        1 +#define CONFIG_BAUDRATE          115200 +#define CFG_BAUDRATE_TABLE       {9600, 19200, 38400, 57600, 115200} + +#define CONFIG_COMMANDS          (CONFIG_CMD_DFL | CFG_CMD_DHCP | CFG_CMD_I2C) + +// I'd like to get to these. Snap kernel loads if we make MMC go // +  // #define CONFIG_COMMANDS       (CONFIG_CMD_DFL | CFG_CMD_NAND | CFG_CMD_JFFS2 | CFG_CMD_DHCP | CFG_CMD_MMC | CFG_CMD_FAT | CFG_CMD_I2C) + +#define CONFIG_BOOTP_MASK        CONFIG_BOOTP_DEFAULT + +/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ +#include <cmd_confdefs.h> + +#define CONFIG_BOOTDELAY         3 + +#ifdef NFS_BOOT_DEFAULTS +#define CONFIG_BOOTARGS	         "mem=32M console=ttyS0,115200n8 noinitrd root=/dev/nfs rw nfsroot=128.247.77.158:/home/a0384864/wtbu/rootfs ip=dhcp" +#else +#define CONFIG_BOOTARGS          "root=/dev/ram0 rw mem=32M console=ttyS0,115200n8 initrd=0x80600000,8M ramdisk_size=8192" +#endif + +#define CONFIG_NETMASK           255.255.254.0 +#define CONFIG_IPADDR            128.247.77.90 +#define CONFIG_SERVERIP          128.247.77.158 +#define CONFIG_BOOTFILE          "uImage" + +/* + * Miscellaneous configurable options + */ +#ifdef CONFIG_APTIX +#define V_PROMPT                 "OMAP2420 Aptix # " +#else +#define V_PROMPT                 "OMAP242x H4 # " +#endif + +#define CFG_LONGHELP             /* undef to save memory */ +#define CFG_PROMPT               V_PROMPT +#define CFG_CBSIZE               256  /* Console I/O Buffer Size */ +/* Print Buffer Size */ +#define CFG_PBSIZE               (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) +#define CFG_MAXARGS              16          /* max number of command args */ +#define CFG_BARGSIZE             CFG_CBSIZE  /* Boot Argument Buffer Size */ + +#define CFG_MEMTEST_START        (OMAP2420_SDRC_CS0)  /* memtest works on */ +#define CFG_MEMTEST_END          (OMAP2420_SDRC_CS0+SZ_31M) + +#undef	CFG_CLKS_IN_HZ           /* everything, incl board info, in Hz */ + +#define CFG_LOAD_ADDR            (OMAP2420_SDRC_CS0) /* default load address */ + +/* The 2420 has 12 GP timers, they can be driven by the SysClk (12/13/19.2) or by + * 32KHz clk, or from external sig. This rate is divided by a local divisor. + */ +#ifdef CONFIG_APTIX +#define V_PVT                    3 +#else +#define V_PVT                    7  /* use with 12MHz/128 */ +#endif + +#define CFG_TIMERBASE            OMAP2420_GPT2 +#define CFG_PVT                  V_PVT  /* 2^(pvt+1) */ +#define CFG_HZ	                 ((CONFIG_SYS_CLK_FREQ)/(2 << CFG_PVT)) + +/*----------------------------------------------------------------------- + * Stack sizes + * + * The stack sizes are set up in start.S using the settings below + */ +#define CONFIG_STACKSIZE         SZ_128K /* regular stack */ +#ifdef CONFIG_USE_IRQ +#define CONFIG_STACKSIZE_IRQ     SZ_4K   /* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ     SZ_4K   /* FIQ stack */ +#endif + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ +#define CONFIG_NR_DRAM_BANKS     2                 /* CS1 may or may not be populated */ +#define PHYS_SDRAM_1             OMAP2420_SDRC_CS0 +#define PHYS_SDRAM_1_SIZE        SZ_32M            /* at least 32 meg */ +#define PHYS_SDRAM_2             OMAP2420_SDRC_CS1 + +#define PHYS_FLASH_1             H4_CS0_BASE	   /* Flash Bank #1 */ +#define PHYS_FLASH_SIZE_1        SZ_32M +#define PHYS_FLASH_2             (H4_CS0_BASE+SZ_32M) /* same cs, 2 chips in series */ +#define PHYS_FLASH_SIZE_2        SZ_32M +#define CFG_FLASH_BASE           PHYS_FLASH_1 + +/*----------------------------------------------------------------------- + * FLASH and environment organization + */ +#define CFG_MAX_FLASH_BANKS      2           /* max number of memory banks */ +#define CFG_MAX_FLASH_SECT       (259)	     /* max number of sectors on one chip */ + +#define CFG_ENV_ADDR             (CFG_FLASH_BASE + SZ_128K) +#define	CFG_ENV_IS_IN_FLASH      1 + +/* timeout values are in ticks */ +#define CFG_FLASH_ERASE_TOUT     (10*75*CFG_HZ) /* Timeout for Flash Erase */ +#define CFG_FLASH_WRITE_TOUT     (10*75*CFG_HZ) /* Timeout for Flash Write */ + +#endif							/* __CONFIG_H */ diff --git a/include/ns16550.h b/include/ns16550.h index 5890246a8..e17a11edc 100644 --- a/include/ns16550.h +++ b/include/ns16550.h @@ -72,7 +72,7 @@ struct NS16550 {  	int pad7:24;  	unsigned char scr;		/* 7 */  	int pad8:24; -#if defined(CONFIG_OMAP1510) || defined(CONFIG_OMAP1610) +#if defined(CONFIG_OMAP)  	unsigned char mdr1;		/* mode select reset TL16C750*/  #endif  #ifdef CONFIG_OMAP1510 diff --git a/lib_arm/cache.c b/lib_arm/cache.c index 4f3cbc229..61ee9d3b1 100644 --- a/lib_arm/cache.c +++ b/lib_arm/cache.c @@ -23,7 +23,14 @@  /* for now: just dummy functions to satisfy the linker */ +#include <common.h> +  void  flush_cache (unsigned long dummy1, unsigned long dummy2)  { +#ifdef CONFIG_OMAP2420 +	void arm1136_cache_flush(void); + +	arm1136_cache_flush(); +#endif  	return;  } |